From 8a74a9f7c333866842f30e25653faf9ef3373ebc Mon Sep 17 00:00:00 2001 From: Ryan Pastorelle Date: Tue, 5 May 2015 14:14:48 -0700 Subject: [PATCH 01/12] Force `responseHeaders` to lower case to respect case-insensitivity Summary: `XMLHttpRequest.getResponseHeader` is case-insensitive, therefor the React-Native implementation needs to mimic this behavior as to not break libraries that are dependent on this. There is a corresponding issue in `superagent` but this is the root cause (https://github.com/visionmedia/superagent/issues/636). Closes https://github.com/facebook/react-native/pull/1138 Github Author: Ryan Pastorelle Test Plan: Imported from GitHub, without a `Test Plan:` line. --- Libraries/Network/XMLHttpRequestBase.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Libraries/Network/XMLHttpRequestBase.js b/Libraries/Network/XMLHttpRequestBase.js index 4a4f16ac6..99a327b5f 100644 --- a/Libraries/Network/XMLHttpRequestBase.js +++ b/Libraries/Network/XMLHttpRequestBase.js @@ -66,7 +66,7 @@ class XMLHttpRequestBase { getResponseHeader(header: string): ?string { if (this.responseHeaders) { - var value = this.responseHeaders[header]; + var value = this.responseHeaders[header.toLowerCase()]; return value !== undefined ? value : null; } return null; @@ -132,7 +132,12 @@ class XMLHttpRequestBase { return; } this.status = status; - this.responseHeaders = responseHeaders || {}; + // Headers should be case-insensitive + var lcResponseHeaders = {}; + for (var header in responseHeaders) { + lcResponseHeaders[header.toLowerCase()] = responseHeaders[header]; + } + this.responseHeaders = lcResponseHeaders; this.responseText = responseText; this._setReadyState(this.DONE); this._sendLoad(); From 57348a4028c33c227f31de6c5cf0f93369bd4a86 Mon Sep 17 00:00:00 2001 From: Evgen Filatov Date: Tue, 5 May 2015 14:14:49 -0700 Subject: [PATCH 02/12] Fixed name of Chome window, Connects to #297 Summary: Hi! I have the same problem as described here https://github.com/facebook/react-native/issues/297 It could occurs after restarting `packager.sh` or `debuger-ui` page. I found simple solution that works for me, but I am not 100% sure it will works for any user with this problem. How could this be tested automatically? Closes https://github.com/facebook/react-native/pull/1101 Github Author: Evgen Filatov Test Plan: Imported from GitHub, without a `Test Plan:` line. --- packager/launchChromeDevTools.applescript | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packager/launchChromeDevTools.applescript b/packager/launchChromeDevTools.applescript index 1fe6f4b07..4b718f5bd 100755 --- a/packager/launchChromeDevTools.applescript +++ b/packager/launchChromeDevTools.applescript @@ -10,7 +10,7 @@ on run argv set theURL to item 1 of argv - tell application "Google Chrome" + tell application "Chrome" activate if (count every window) = 0 then From 86cfcbc77e428295f850bfc927b6eb3c6fdd30cf Mon Sep 17 00:00:00 2001 From: Eric Vicenti Date: Tue, 5 May 2015 14:31:41 -0700 Subject: [PATCH 03/12] [ReactNative] Navigator fix opacity reset for presented scene Summary: jumpN will call enableScene for the dest scene, which makes sure the scene can be made visible, but we need to avoid resetting the opacity for it when it is already the presented scene. There is already a check to make sure we don't reset opacity for the transitioningFrom scene. @public Test Plan: Fixes the issue on Android device when jumping to a scene that is already presented --- Libraries/CustomComponents/Navigator/Navigator.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Libraries/CustomComponents/Navigator/Navigator.js b/Libraries/CustomComponents/Navigator/Navigator.js index ad9ea0e8a..d4c97561b 100644 --- a/Libraries/CustomComponents/Navigator/Navigator.js +++ b/Libraries/CustomComponents/Navigator/Navigator.js @@ -689,7 +689,8 @@ var Navigator = React.createClass({ var enabledSceneNativeProps = { left: sceneStyle.left, }; - if (sceneIndex !== this.state.transitionFromIndex) { + if (sceneIndex !== this.state.transitionFromIndex && + sceneIndex !== this.state.presentedIndex) { // If we are not in a transition from this index, make sure opacity is 0 // to prevent the enabled scene from flashing over the presented scene enabledSceneNativeProps.opacity = 0; From 7362f11c2250ec394f18256ee4198df570a0e472 Mon Sep 17 00:00:00 2001 From: Amjad Masad Date: Tue, 5 May 2015 14:05:19 -0700 Subject: [PATCH 04/12] [react-packager] Use gracful-fs to avoid EMFILE errors Summary: @public Currently, every time we call into the packager we have to change the ulimit to make sure we don't hit the EMFILE error (the packager uses as much concurrency as possible). Using graceful-fs, the fs module -- with monkey patching -- becomes intelligent enough to recover from EMFILE errors. Test Plan: * set `ulimit -n 256* * start server * request from your browser: http://localhost:8081/RKJSModules/MainBundle/CatalystBundle.includeRequire.bundle * it works --- package.json | 1 + packager/react-packager/index.js | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/package.json b/package.json index 987347a1d..8e059c3fa 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "chalk": "^1.0.0", "connect": "2.8.3", "debug": "~2.1.0", + "graceful-fs": "^3.0.6", "image-size": "0.3.5", "joi": "~5.1.0", "jstransform": "10.1.0", diff --git a/packager/react-packager/index.js b/packager/react-packager/index.js index 3a70659cf..a7b6264b7 100644 --- a/packager/react-packager/index.js +++ b/packager/react-packager/index.js @@ -8,6 +8,8 @@ */ 'use strict'; +useGracefulFs(); + var Activity = require('./src/Activity'); var Server = require('./src/Server'); @@ -45,3 +47,16 @@ exports.getDependencies = function(options, main) { return r.dependencies; }); }; + +function useGracefulFs() { + var fs = require('fs'); + var gracefulFs = require('graceful-fs'); + + // A bit sneaky but it's not straightforward to update all the + // modules we depend on. + Object.keys(fs).forEach(function(method) { + if (typeof fs[method] === 'function' && gracefulFs[method]) { + fs[method] = gracefulFs[method]; + } + }); +} From 54974d63336e6d6d70bae313ba6cff5da622703f Mon Sep 17 00:00:00 2001 From: Nick Lockwood Date: Tue, 5 May 2015 17:38:32 -0700 Subject: [PATCH 05/12] +[RCTConvert UIFont:] tests --- React/Base/RCTConvert.h | 1 + React/Base/RCTConvert.m | 28 ++++++++++++++++------------ React/Base/RCTDevMenu.m | 2 -- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/React/Base/RCTConvert.h b/React/Base/RCTConvert.h index 71bf7b302..2412f715b 100644 --- a/React/Base/RCTConvert.h +++ b/React/Base/RCTConvert.h @@ -76,6 +76,7 @@ + (UIImage *)UIImage:(id)json; + (CGImageRef)CGImage:(id)json; ++ (UIFont *)UIFont:(id)json; + (UIFont *)UIFont:(UIFont *)font withSize:(id)json; + (UIFont *)UIFont:(UIFont *)font withWeight:(id)json; + (UIFont *)UIFont:(UIFont *)font withStyle:(id)json; diff --git a/React/Base/RCTConvert.m b/React/Base/RCTConvert.m index 9c27b95d9..2d0606b6f 100644 --- a/React/Base/RCTConvert.m +++ b/React/Base/RCTConvert.m @@ -679,6 +679,16 @@ static BOOL RCTFontIsCondensed(UIFont *font) return (symbolicTraits & UIFontDescriptorTraitCondensed) != 0; } ++ (UIFont *)UIFont:(id)json +{ + json = [self NSDictionary:json]; + return [self UIFont:nil + withFamily:json[@"fontFamily"] + size:json[@"fontSize"] + weight:json[@"fontWeight"] + style:json[@"fontStyle"]]; +} + + (UIFont *)UIFont:(UIFont *)font withSize:(id)json { return [self UIFont:font withFamily:nil size:json weight:nil style:nil]; @@ -728,11 +738,6 @@ static BOOL RCTFontIsCondensed(UIFont *font) // Get font family familyName = [self NSString:family] ?: familyName; - // Get font style - if (style) { - isItalic = [self RCTFontStyle:style]; - } - // Gracefully handle being given a font name rather than font family, for // example: "Helvetica Light Oblique" rather than just "Helvetica". if ([UIFont fontNamesForFamilyName:familyName].count == 0) { @@ -751,6 +756,11 @@ static BOOL RCTFontIsCondensed(UIFont *font) } } + // Get font style + if (style) { + isItalic = [self RCTFontStyle:style]; + } + // Get font weight if (weight) { fontWeight = [self RCTFontWeight:weight]; @@ -758,13 +768,7 @@ static BOOL RCTFontIsCondensed(UIFont *font) // Get the closest font that matches the given weight for the fontFamily UIFont *bestMatch = [UIFont fontWithName:font.fontName size: fontSize]; - CGFloat closestWeight; - - if (font && [font.familyName isEqualToString: familyName]) { - closestWeight = RCTWeightOfFont(font); - } else { - closestWeight = INFINITY; - } + CGFloat closestWeight = INFINITY; for (NSString *name in [UIFont fontNamesForFamilyName:familyName]) { UIFont *match = [UIFont fontWithName:name size:fontSize]; diff --git a/React/Base/RCTDevMenu.m b/React/Base/RCTDevMenu.m index d2e4b7416..cf5c6635a 100644 --- a/React/Base/RCTDevMenu.m +++ b/React/Base/RCTDevMenu.m @@ -66,9 +66,7 @@ RCT_EXPORT_MODULE() // We're swizzling here because it's poor form to override methods in a category, // however UIWindow doesn't actually implement motionEnded:withEvent:, so there's // no need to call the original implementation. -#if RCT_DEV RCTSwapInstanceMethods([UIWindow class], @selector(motionEnded:withEvent:), @selector(RCT_motionEnded:withEvent:)); -#endif } - (instancetype)init From 88a83084e4cc730cb420d6e70a5d0ec15809769f Mon Sep 17 00:00:00 2001 From: Nick Lockwood Date: Wed, 6 May 2015 00:11:31 -0700 Subject: [PATCH 06/12] Fixed UIExplorer in Catalyst shell --- .../SampleApp.xcodeproj/project.pbxproj | 34 ++++++++++++- Examples/SampleApp/index.ios.js | 2 +- Libraries/Settings/RCTSettingsManager.m | 7 ++- React/Base/RCTConvert.m | 18 ++++--- React/Base/RCTUtils.h | 3 ++ React/Base/RCTUtils.m | 51 +++++++++++++++++++ 6 files changed, 104 insertions(+), 11 deletions(-) diff --git a/Examples/SampleApp/SampleApp.xcodeproj/project.pbxproj b/Examples/SampleApp/SampleApp.xcodeproj/project.pbxproj index d2fc3eade..3928adc33 100644 --- a/Examples/SampleApp/SampleApp.xcodeproj/project.pbxproj +++ b/Examples/SampleApp/SampleApp.xcodeproj/project.pbxproj @@ -17,6 +17,7 @@ 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C302E41ABCB9EE00DB3ED1 /* libRCTVibration.a */; }; 00E356F31AD99517003FC87E /* SampleAppTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 00E356F21AD99517003FC87E /* SampleAppTests.m */; }; 133E29F31AD74F7200F7D852 /* libRCTLinking.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 78C398B91ACF4ADC00677621 /* libRCTLinking.a */; }; + 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */; }; 13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; }; 13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; }; 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; @@ -82,6 +83,13 @@ remoteGlobalIDString = 13B07F861A680F5B00A75B9A; remoteInfo = SampleApp; }; + 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 134814201AA4EA6300B7C361; + remoteInfo = RCTSettings; + }; 146834031AC3E56700842450 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 146833FF1AC3E56700842450 /* React.xcodeproj */; @@ -117,6 +125,7 @@ 00E356EE1AD99517003FC87E /* SampleAppTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SampleAppTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00E356F21AD99517003FC87E /* SampleAppTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SampleAppTests.m; sourceTree = ""; }; + 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = ../../Libraries/Settings/RCTSettings.xcodeproj; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* SampleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SampleApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = iOS/AppDelegate.h; sourceTree = ""; }; 13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = iOS/AppDelegate.m; sourceTree = ""; }; @@ -142,6 +151,7 @@ buildActionMask = 2147483647; files = ( 146834051AC3E58100842450 /* libReact.a in Frameworks */, + 139105C61AF99C1200B5F7CC /* libRCTSettings.a in Frameworks */, 00481BE81AC0C86700671115 /* libRCTWebSocketDebugger.a in Frameworks */, 00C302E51ABCBA2D00DB3ED1 /* libRCTActionSheet.a in Frameworks */, 00C302E61ABCBA2D00DB3ED1 /* libRCTAdSupport.a in Frameworks */, @@ -230,6 +240,14 @@ name = "Supporting Files"; sourceTree = ""; }; + 139105B71AF99BAD00B5F7CC /* Products */ = { + isa = PBXGroup; + children = ( + 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */, + ); + name = Products; + sourceTree = ""; + }; 13B07FAE1A68108700A75B9A /* SampleApp */ = { isa = PBXGroup; children = ( @@ -263,14 +281,15 @@ 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( - 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, 146833FF1AC3E56700842450 /* React.xcodeproj */, - 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */, 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, 00C302AF1ABCB8E700DB3ED1 /* RCTAdSupport.xcodeproj */, 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */, 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */, + 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */, 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */, + 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */, + 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */, 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */, 00481BDB1AC0C7FA00671115 /* RCTWebSocketDebugger.xcodeproj */, ); @@ -395,6 +414,10 @@ ProductGroup = 00C302D41ABCB9D200DB3ED1 /* Products */; ProjectRef = 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */; }, + { + ProductGroup = 139105B71AF99BAD00B5F7CC /* Products */; + ProjectRef = 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */; + }, { ProductGroup = 832341B11AAA6A8300B99B32 /* Products */; ProjectRef = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; @@ -470,6 +493,13 @@ remoteRef = 00C302E31ABCB9EE00DB3ED1 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + 139105C11AF99BAD00B5F7CC /* libRCTSettings.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libRCTSettings.a; + remoteRef = 139105C01AF99BAD00B5F7CC /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; 146834041AC3E56700842450 /* libReact.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; diff --git a/Examples/SampleApp/index.ios.js b/Examples/SampleApp/index.ios.js index 629118d10..46c0712bd 100644 --- a/Examples/SampleApp/index.ios.js +++ b/Examples/SampleApp/index.ios.js @@ -24,7 +24,7 @@ var SampleApp = React.createClass({ Press Cmd+R to reload,{'\n'} - Cmd+Control+Z for dev menu + Cmd+D or shake for dev menu ); diff --git a/Libraries/Settings/RCTSettingsManager.m b/Libraries/Settings/RCTSettingsManager.m index b17439eaf..6f8b146c1 100644 --- a/Libraries/Settings/RCTSettingsManager.m +++ b/Libraries/Settings/RCTSettingsManager.m @@ -12,6 +12,7 @@ #import "RCTBridge.h" #import "RCTConvert.h" #import "RCTEventDispatcher.h" +#import "RCTUtils.h" @implementation RCTSettingsManager { @@ -53,13 +54,15 @@ RCT_EXPORT_MODULE() return; } - [_bridge.eventDispatcher sendDeviceEventWithName:@"settingsUpdated" body:[_defaults dictionaryRepresentation]]; + [_bridge.eventDispatcher + sendDeviceEventWithName:@"settingsUpdated" + body:RCTJSONClean([_defaults dictionaryRepresentation])]; } - (NSDictionary *)constantsToExport { return @{ - @"settings": [_defaults dictionaryRepresentation] + @"settings": RCTJSONClean([_defaults dictionaryRepresentation]) }; } diff --git a/React/Base/RCTConvert.m b/React/Base/RCTConvert.m index 2d0606b6f..6f07feebd 100644 --- a/React/Base/RCTConvert.m +++ b/React/Base/RCTConvert.m @@ -838,7 +838,9 @@ static id RCTConvertPropertyListValue(id json) { if (!json || json == (id)kCFNull) { return nil; - } else if ([json isKindOfClass:[NSDictionary class]]) { + } + + if ([json isKindOfClass:[NSDictionary class]]) { __block BOOL copy = NO; NSMutableDictionary *values = [[NSMutableDictionary alloc] initWithCapacity:[json count]]; [json enumerateKeysAndObjectsUsingBlock:^(NSString *key, id jsonValue, BOOL *stop) { @@ -849,7 +851,9 @@ static id RCTConvertPropertyListValue(id json) copy |= value != jsonValue; }]; return copy ? values : json; - } else if ([json isKindOfClass:[NSArray class]]) { + } + + if ([json isKindOfClass:[NSArray class]]) { __block BOOL copy = NO; __block NSArray *values = json; [json enumerateObjectsUsingBlock:^(id jsonValue, NSUInteger idx, BOOL *stop) { @@ -864,15 +868,17 @@ static id RCTConvertPropertyListValue(id json) for (NSInteger i = 0; i < idx; i++) { [(NSMutableArray *)values addObject:json[i]]; } - [(NSMutableArray *)values addObject:value]; + if (value) { + [(NSMutableArray *)values addObject:value]; + } copy = YES; } }]; return values; - } else { - // All other JSON types are supported by property lists - return json; } + + // All other JSON types are supported by property lists + return json; } + (NSPropertyList)NSPropertyList:(id)json diff --git a/React/Base/RCTUtils.h b/React/Base/RCTUtils.h index 1c0412568..6c4b91464 100644 --- a/React/Base/RCTUtils.h +++ b/React/Base/RCTUtils.h @@ -19,6 +19,9 @@ RCT_EXTERN NSString *RCTJSONStringify(id jsonObject, NSError **error); RCT_EXTERN id RCTJSONParse(NSString *jsonString, NSError **error); +// Strip non JSON-safe values from an object graph +RCT_EXTERN id RCTJSONClean(id object); + // Get MD5 hash of a string (TODO: currently unused. Remove?) RCT_EXTERN NSString *RCTMD5Hash(NSString *string); diff --git a/React/Base/RCTUtils.m b/React/Base/RCTUtils.m index 3c644dbff..a74b4e114 100644 --- a/React/Base/RCTUtils.m +++ b/React/Base/RCTUtils.m @@ -42,6 +42,57 @@ id RCTJSONParse(NSString *jsonString, NSError **error) return [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:error]; } +id RCTJSONClean(id object) +{ + static dispatch_once_t onceToken; + static NSSet *validLeafTypes; + dispatch_once(&onceToken, ^{ + validLeafTypes = [[NSSet alloc] initWithArray:@[ + [NSString class], + [NSMutableString class], + [NSNumber class], + [NSNull class], + ]]; + }); + + if ([validLeafTypes containsObject:[object classForCoder]]) { + return object; + } + + if ([object isKindOfClass:[NSDictionary class]]) { + __block BOOL copy = NO; + NSMutableDictionary *values = [[NSMutableDictionary alloc] initWithCapacity:[object count]]; + [object enumerateKeysAndObjectsUsingBlock:^(NSString *key, id item, BOOL *stop) { + id value = RCTJSONClean(item); + values[key] = value; + copy |= value != item; + }]; + return copy ? values : object; + } + + if ([object isKindOfClass:[NSArray class]]) { + __block BOOL copy = NO; + __block NSArray *values = object; + [object enumerateObjectsUsingBlock:^(id item, NSUInteger idx, BOOL *stop) { + id value = RCTJSONClean(item); + if (copy) { + [(NSMutableArray *)values addObject:value]; + } else if (value != item) { + // Converted value is different, so we'll need to copy the array + values = [[NSMutableArray alloc] initWithCapacity:values.count]; + for (NSInteger i = 0; i < idx; i++) { + [(NSMutableArray *)values addObject:object[i]]; + } + [(NSMutableArray *)values addObject:value]; + copy = YES; + } + }]; + return values; + } + + return (id)kCFNull; +} + NSString *RCTMD5Hash(NSString *string) { const char *str = [string UTF8String]; From ea470408e2f02574c725a532e55484d3777806fb Mon Sep 17 00:00:00 2001 From: Tadeu Zagallo Date: Wed, 6 May 2015 05:44:48 -0700 Subject: [PATCH 07/12] [ReactNative] Allow JSON fragments on RCTJSONStringify --- React/Base/RCTUtils.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/React/Base/RCTUtils.m b/React/Base/RCTUtils.m index a74b4e114..ff11b5764 100644 --- a/React/Base/RCTUtils.m +++ b/React/Base/RCTUtils.m @@ -20,7 +20,7 @@ NSString *RCTJSONStringify(id jsonObject, NSError **error) { - NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonObject options:0 error:error]; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:jsonObject options:(NSJSONWritingOptions)NSJSONReadingAllowFragments error:error]; return jsonData ? [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding] : nil; } From 8c95de11e167d7f3a217619f7623eecf220dd711 Mon Sep 17 00:00:00 2001 From: Alex Kotliarskyi Date: Wed, 6 May 2015 09:57:50 -0700 Subject: [PATCH 08/12] [ReactNative] Re-record OSS snapshot tests --- .../testTextExampleSnapshot_1@2x.png | Bin 270778 -> 270812 bytes .../testViewExampleSnapshot_1@2x.png | Bin 89870 -> 89799 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/Examples/UIExplorer/UIExplorerTests/ReferenceImages/Examples-UIExplorer-UIExplorerApp/testTextExampleSnapshot_1@2x.png b/Examples/UIExplorer/UIExplorerTests/ReferenceImages/Examples-UIExplorer-UIExplorerApp/testTextExampleSnapshot_1@2x.png index d697ae5b5e3e17787331c45592ba574db67d4f7a..2c6675b7b4eeba914d0ee3fee1d82d18fcae9b85 100644 GIT binary patch delta 51641 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 Lt6HFJ`TYL^<^Zn; diff --git a/Examples/UIExplorer/UIExplorerTests/ReferenceImages/Examples-UIExplorer-UIExplorerApp/testViewExampleSnapshot_1@2x.png b/Examples/UIExplorer/UIExplorerTests/ReferenceImages/Examples-UIExplorer-UIExplorerApp/testViewExampleSnapshot_1@2x.png index 74e03581c464bc6a278eda27fb8ef9724f9a6bb5..161ddba986f2818fa61219fc48ae626b95c12d4a 100644 GIT binary patch delta 1818 zcmcJP{a4b59>;+*b}EBcna0}%qzkbenpZ9rvKJRx~7yOwJ zUVado{W$dMd*EX+)?EMQ9(Tdh5uW9UE(AQ1UygUpnUxi+_~i$?pP*#R05 zLw~zoUpjNyE%O2JmZp?9Ch8iDLYnuf*CCY?^+31&8B0{awaljR-$?Lw$#kSp6TC3B z{4?w1sS+cnMgQ5}wc{^1pE4?#)2cK`a+Eq%baZT=%T|2xC6X8&G4L?vJ|sYYzp1=}cJji}G;OWOE~{3@08 zaO*KfYp+#{weh+Z)My|tIItXW)VM@hsotQDB{HWfl1K*D1>RWa3LP+F=OQbmb2b&- zxFDH9@oUcx9WAoH6QhBmMTrM5Pz&nJ@8q!?RhIc&qNrD^dVd|;rEBjLnJ?9uMoBqR zK}abIK4g}ht;uL(Q)+PAy_WvY3CMm9Z!$May(BACh;t&Fb!55`Obpht<>?oqUH44# zAzKPQ{H{wYH?iV>_+>gsWrz;$`JfP4TX)i4ow*ujxCD$PLbRm;CLa)e+sSo(-x@VY z*EODZ^5Ki#eF;v+Ly8xLyG3?4xwju1a{L)!7(cd3-p-uvca~$j76lWW!2)NsW|{`( zCj_qxVZxS&SY0jF-!wC=Pd8CsV6P(|8Awsc{#djte2x#&#W=nwDa_6hRh5RgB~sLe9Y)>(~I#ia{4PwX?Uv zH#qN8bL8%ngViRg?B*3%`x=)6j_h35sqN*|x;XYHu~eI7Nl~n#Chdr1k^sP>dpOvE zIyj6Yl##ut&)X~;vP|1X^Rm~pced$9iDw4ncTgBc*q~Gk@rx&f)3gTvh?`wY!i5n) zRzGaU6ceMwM-sIAg>*j-7zT#58MY8|U(@66)0+Gv^3vpW zuX9u$|6%jxfePPB!gMZ>Rj^ZVlC0k6Aa%G4(erNnsBO7IElc5FxIVu6vd1BZpB6Ol z$`;&;kh!=;HW!40x5{ViSQYin5Gv-Yxho!JHz+1*blUy9v7biqAa7`j1Z^jzItP;f zjTMR1a8oS;J(Do(dN^u#y*nW58TVvQ5l6fGQ482Tj8vM~STM&+uIY1EBJl!o1g1AoWS7i-QCaaQ(T{noNvvV?4ApsD-{0Jd190JZ z$@Xi}PXZq<1mY0RKu)F{NLZ<8mB|qw9Ix)_IBUL5*e;xur2LuNyZuSxwrDRx&Gk z^f3xt*7Lkfu>$>Bi@g>n(DX^)2xRbleO>@gZX07p=83ywm9$Tj_v(f zVJE{>5YGr{l;A%&!wNZNbKer<3hV*oD(XaEs7(EXOJ(+49!&V8a&`_2gE#Vg=EdK! z2Cz`OFFx2>iN&8lR_3Brbgrnj8(PWAPJntsLs@TQp#Oj!hOm53KvVh2C!qJCtSmg# nm;W~s6bt?T?O7}O-#K?X;k_H#L7CF>Rc}WRM<03=ntbu!zVy7? delta 2054 zcmd^9`&ZHl76&$)o!TDLn66EuTc&BLIG7J?)6{$3E}0~vnG~U$>e}6kXPi`o#A|?A9;R22yUvP{W9y9^In*gdwd&^_ zKFY53#MPka?9KN!5hgA$$0U{+6Nw{RMVHzqNhW&`-TfLXDh70l)0#8mNbXk>+ z%{4vl>3>ckNjiWb$JJewRAn^*D_uQ$EDilgd9yw@Fq#EfuDT2eV|) z#~8>Ck54ljPJ=p>{j+dol{|-Op72SE(MN+_%dY)3T5miY$W!}P>S#hRlu~l-e8E~I zXCvYmg(kwRQX+r0&+}2o(Wi}G30}X|BKL5GH8GEe5@Q21aK#b}j5?M$lH^gmMpSkQ zdz#FRECQi9izrMqFsV>RpS$6_#27FZ<}}qA;~s-0`Rg%|d($YfMUE~9e%&Uo_%c*G zoaiySYvZ|j5aI9lwb-AwcT!($Qll1FG4q`;z|qsc?iCvdR{f&h+N~yr`|<8hqhy}h zlewktx@Bi^OPU%PnDE__AQZ`bI+}^hYC+pf0Huhq328P{BnUNkqB0&_c;rHep>_{1L%}7?ULj>J~CbRHM}M{m+zEcDI>`aHnS>C5N~@$9B>WjnOc<8 zmqg>{F3%6sCkhQ4lb{9te63AhONXr_#{|8#?LA1`>}%ZT+X0~rcJl%b{)?(;7&>sP zOe5!TJhU_oBJ{!BhO{~L#uWDJySO335ue-N^sW2!$;eTX{(UoR6XP+dJzk#Wp4$KH zX!Lo_S3sPWFn$>d^%4L3h+b8Xd<+<=8Py`mF{q*2k$#}@BDq5hK9UpdC_)`{N0gD=e zE<3B4wUq!(DVaEpJC$f`&n=*6kz32b^N&)|e{ljQ5A(Kca|L{K?jN%=Zr~7<3h}M5 zI3B6U$2JdXn$dE;MoGZS<2B~oFIiI$q1c&l;VWyXBdjRRNxyeP3GCfxqH1Pc&?~h+ zBDl5J2pQBLTNa;|1klE8rHW^Q{7crwDa_;ILl)wlQmsQCHZ0h$i^LBJdVYw3+Jee1 z{pZ@?I0E>=%*(#q(S5hnZZ^z13mcx^VYVc!IsKTlP(xl4?xY`kZ;yp4ZLq9qbf2U; z8!yz&t9dUQsJ}knG851Xo-jUc6mq^bU_9cmQz$XOwfK@M&_NKn{kmW7^-L6+v+~eF zmvptlUT=s6fHTWRvupQ;OW61eW|=sQ zxX_acZgn0+EhTiL1XvN)=3UspZO{39l6qjog z(LC4v1hMadUHTi@#327RJB2~)y^A8wr6pOTsKN@V#GxKmpE%P-&xr{ z7F+D%E1fj<)_HYB&dsKk#Qp74BTlG!=mW From 790cee6e26ef907520df45da66a9b5aa65255312 Mon Sep 17 00:00:00 2001 From: Nick Lockwood Date: Wed, 6 May 2015 10:46:45 -0700 Subject: [PATCH 09/12] Fixed broken listview header alignment --- React/Base/RCTConvert.h | 1 + React/Base/RCTConvert.m | 14 +++ React/Base/RCTDevMenu.m | 4 +- React/Views/RCTScrollView.h | 2 +- React/Views/RCTScrollView.m | 150 ++++++++++++----------------- React/Views/RCTScrollViewManager.m | 2 +- 6 files changed, 79 insertions(+), 94 deletions(-) diff --git a/React/Base/RCTConvert.h b/React/Base/RCTConvert.h index 2412f715b..dd99ac9fb 100644 --- a/React/Base/RCTConvert.h +++ b/React/Base/RCTConvert.h @@ -39,6 +39,7 @@ + (NSString *)NSString:(id)json; + (NSNumber *)NSNumber:(id)json; + (NSData *)NSData:(id)json; ++ (NSIndexSet *)NSIndexSet:(id)json; + (NSURL *)NSURL:(id)json; + (NSURLRequest *)NSURLRequest:(id)json; diff --git a/React/Base/RCTConvert.m b/React/Base/RCTConvert.m index 6f07feebd..06b5aa023 100644 --- a/React/Base/RCTConvert.m +++ b/React/Base/RCTConvert.m @@ -64,6 +64,20 @@ RCT_CONVERTER(NSString *, NSString, description) return [[self NSString:json] dataUsingEncoding:NSUTF8StringEncoding]; } ++ (NSIndexSet *)NSIndexSet:(id)json +{ + json = [self NSNumberArray:json]; + NSMutableIndexSet *indexSet = [[NSMutableIndexSet alloc] init]; + for (NSNumber *number in json) { + NSInteger index = number.integerValue; + if (RCT_DEBUG && index < 0) { + RCTLogError(@"Invalid index value %zd. Indices must be positive.", index); + } + [indexSet addIndex:index]; + } + return indexSet; +} + + (NSURL *)NSURL:(id)json { NSString *path = [self NSString:json]; diff --git a/React/Base/RCTDevMenu.m b/React/Base/RCTDevMenu.m index cf5c6635a..3d88caf55 100644 --- a/React/Base/RCTDevMenu.m +++ b/React/Base/RCTDevMenu.m @@ -119,8 +119,6 @@ RCT_EXPORT_MODULE() - (void)updateSettings { - _settings = [NSMutableDictionary dictionaryWithDictionary:[_defaults objectForKey:RCTDevMenuSettingsKey]]; - __weak RCTDevMenu *weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ RCTDevMenu *strongSelf = weakSelf; @@ -128,6 +126,8 @@ RCT_EXPORT_MODULE() return; } + strongSelf->_settings = [NSMutableDictionary dictionaryWithDictionary:[strongSelf->_defaults objectForKey:RCTDevMenuSettingsKey]]; + strongSelf.shakeToShow = [strongSelf->_settings[@"shakeToShow"] ?: @YES boolValue]; strongSelf.profilingEnabled = [strongSelf->_settings[@"profilingEnabled"] ?: @NO boolValue]; strongSelf.liveReloadEnabled = [strongSelf->_settings[@"liveReloadEnabled"] ?: @NO boolValue]; diff --git a/React/Views/RCTScrollView.h b/React/Views/RCTScrollView.h index f218ea6ea..0333a38a7 100644 --- a/React/Views/RCTScrollView.h +++ b/React/Views/RCTScrollView.h @@ -45,6 +45,6 @@ @property (nonatomic, assign) BOOL automaticallyAdjustContentInsets; @property (nonatomic, assign) NSTimeInterval scrollEventThrottle; @property (nonatomic, assign) BOOL centerContent; -@property (nonatomic, copy) NSArray *stickyHeaderIndices; +@property (nonatomic, copy) NSIndexSet *stickyHeaderIndices; @end diff --git a/React/Views/RCTScrollView.m b/React/Views/RCTScrollView.m index 1b3170064..ca8f94242 100644 --- a/React/Views/RCTScrollView.m +++ b/React/Views/RCTScrollView.m @@ -28,8 +28,8 @@ CGFloat const ZINDEX_STICKY_HEADER = 50; */ @interface RCTCustomScrollView : UIScrollView -@property (nonatomic, copy, readwrite) NSArray *stickyHeaderIndices; -@property (nonatomic, readwrite, assign) BOOL centerContent; +@property (nonatomic, copy) NSIndexSet *stickyHeaderIndices; +@property (nonatomic, assign) BOOL centerContent; @end @@ -155,97 +155,72 @@ CGFloat const ZINDEX_STICKY_HEADER = 50; [super setContentOffset:contentOffset]; } -- (void)setBounds:(CGRect)bounds -{ - [super setBounds:bounds]; - [self dockClosestSectionHeader]; -} - - (void)dockClosestSectionHeader { UIView *contentView = [self contentView]; - if (_stickyHeaderIndices.count == 0 || !contentView) { + CGFloat scrollTop = self.bounds.origin.y + self.contentInset.top; + + // Find the section headers that need to be docked + __block UIView *previousHeader = nil; + __block UIView *currentHeader = nil; + __block UIView *nextHeader = nil; + NSInteger subviewCount = contentView.reactSubviews.count; + [_stickyHeaderIndices enumerateIndexesWithOptions:0 usingBlock:^(NSUInteger idx, BOOL *stop) { + + if (idx >= subviewCount) { + RCTLogError(@"Sticky header index %zd was outside the range {0, %zd}", idx, subviewCount); + return; + } + + UIView *header = contentView.reactSubviews[idx]; + + // If nextHeader not yet found, search for docked headers + if (!nextHeader) { + CGFloat height = header.bounds.size.height; + CGFloat top = header.center.y - height * header.layer.anchorPoint.y; + if (top > scrollTop) { + nextHeader = header; + } else { + previousHeader = currentHeader; + currentHeader = header; + } + } + + // Reset transforms for header views + header.transform = CGAffineTransformIdentity; + header.layer.zPosition = ZINDEX_DEFAULT; + + }]; + + // If no docked header, bail out + if (!currentHeader) { return; } - // find the section header that needs to be docked - NSInteger firstIndexInView = [[_stickyHeaderIndices firstObject] integerValue] + 1; - CGRect scrollBounds = self.bounds; - scrollBounds.origin.x += self.contentInset.left; - scrollBounds.origin.y += self.contentInset.top; - - NSInteger i = 0; - for (UIView *subview in contentView.reactSubviews) { - CGRect rowFrame = [RCTCustomScrollView _calculateUntransformedFrame:subview]; - if (CGRectIntersectsRect(scrollBounds, rowFrame)) { - firstIndexInView = i; - break; - } - i++; + // Adjust current header to hug the top of the screen + CGFloat currentFrameHeight = currentHeader.bounds.size.height; + CGFloat currentFrameTop = currentHeader.center.y - currentFrameHeight * currentHeader.layer.anchorPoint.y; + CGFloat yOffset = scrollTop - currentFrameTop; + if (nextHeader) { + // The next header nudges the current header out of the way when it reaches + // the top of the screen + CGFloat nextFrameHeight = nextHeader.bounds.size.height; + CGFloat nextFrameTop = nextHeader.center.y - nextFrameHeight * nextHeader.layer.anchorPoint.y; + CGFloat overlap = currentFrameHeight - (nextFrameTop - scrollTop); + yOffset -= MAX(0, overlap); } - NSInteger stickyHeaderii = 0; - for (NSNumber *stickyHeaderI in _stickyHeaderIndices) { - if ([stickyHeaderI integerValue] > firstIndexInView) { - break; - } - stickyHeaderii++; - } - stickyHeaderii = MAX(0, stickyHeaderii - 1); - - // Set up transforms for the various section headers - NSInteger currentlyDockedIndex = [_stickyHeaderIndices[stickyHeaderii] integerValue]; - NSInteger previouslyDockedIndex = stickyHeaderii > 0 ? [_stickyHeaderIndices[stickyHeaderii-1] integerValue] : -1; - NSInteger nextDockedIndex = (stickyHeaderii < _stickyHeaderIndices.count - 1) ? - [_stickyHeaderIndices[stickyHeaderii + 1] integerValue] : -1; - - UIView *currentHeader = contentView.reactSubviews[currentlyDockedIndex]; - UIView *previousHeader = previouslyDockedIndex >= 0 ? contentView.reactSubviews[previouslyDockedIndex] : nil; - CGRect curFrame = [RCTCustomScrollView _calculateUntransformedFrame:currentHeader]; + currentHeader.transform = CGAffineTransformMakeTranslation(0, yOffset); + currentHeader.layer.zPosition = ZINDEX_STICKY_HEADER; if (previousHeader) { - // the previous header is offset to sit right above the currentlyDockedHeader's initial position - // (so it scrolls away nicely once the currentHeader locks into position) - CGRect previousFrame = [RCTCustomScrollView _calculateUntransformedFrame:previousHeader]; - CGFloat yOffset = curFrame.origin.y - previousFrame.origin.y - previousFrame.size.height; + // The previous header sits right above the currentHeader's initial position + // so it scrolls away nicely once the currentHeader has locked into place + CGFloat previousFrameHeight = previousHeader.bounds.size.height; + CGFloat targetCenter = currentFrameTop - previousFrameHeight * (1.0 - previousHeader.layer.anchorPoint.y); + yOffset = targetCenter - previousHeader.center.y; previousHeader.transform = CGAffineTransformMakeTranslation(0, yOffset); + previousHeader.layer.zPosition = ZINDEX_STICKY_HEADER; } - - UIView *nextHeader = nextDockedIndex >= 0 ? contentView.reactSubviews[nextDockedIndex] : nil; - CGRect nextFrame = [RCTCustomScrollView _calculateUntransformedFrame:nextHeader]; - - if (curFrame.origin.y < scrollBounds.origin.y) { - // scrolled off (or being scrolled off) the top of the screen - CGFloat yOffset = 0; - if (nextHeader && nextFrame.origin.y < scrollBounds.origin.y + curFrame.size.height) { - // next frame is bumping me off if scrolling down (or i'm bumping the next one off if scrolling up) - yOffset = nextFrame.origin.y - curFrame.origin.y - curFrame.size.height; - } else { - // standard sticky header position - yOffset = scrollBounds.origin.y - curFrame.origin.y; - } - currentHeader.transform = CGAffineTransformMakeTranslation(0, yOffset); - currentHeader.layer.zPosition = ZINDEX_STICKY_HEADER; - } else { - // i'm the current header but in the viewport, so just scroll in normal position - currentHeader.transform = CGAffineTransformIdentity; - currentHeader.layer.zPosition = ZINDEX_DEFAULT; - } - - // in our setup, 'next header' will always just scroll with the page - if (nextHeader) { - nextHeader.transform = CGAffineTransformIdentity; - nextHeader.layer.zPosition = ZINDEX_DEFAULT; - } -} - -+ (CGRect)_calculateUntransformedFrame:(UIView *)view -{ - CGRect frame = CGRectNull; - if (view) { - frame.size = view.bounds.size; - frame.origin = CGPointMake(view.layer.position.x - view.bounds.size.width * view.layer.anchorPoint.x, view.layer.position.y - view.bounds.size.height * view.layer.anchorPoint.y); - } - return frame; } @end @@ -312,7 +287,7 @@ CGFloat const ZINDEX_STICKY_HEADER = 50; _scrollView.centerContent = centerContent; } -- (void)setStickyHeaderIndices:(NSArray *)headerIndices +- (void)setStickyHeaderIndices:(NSIndexSet *)headerIndices { RCTAssert(_scrollView.contentSize.width <= self.frame.size.width, @"sticky headers are not supported with horizontal scrolled views"); @@ -340,14 +315,8 @@ CGFloat const ZINDEX_STICKY_HEADER = 50; - (void)setContentInset:(UIEdgeInsets)contentInset { - CGPoint contentOffset = _scrollView.contentOffset; - _contentInset = contentInset; - [RCTView autoAdjustInsetsForView:self - withScrollView:_scrollView - updateOffset:NO]; - - _scrollView.contentOffset = contentOffset; + [self setNeedsLayout]; } - (void)scrollToOffset:(CGPoint)offset @@ -390,6 +359,7 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, RCTScrollEventTypeMove) - (void)scrollViewDidScroll:(UIScrollView *)scrollView { + [_scrollView dockClosestSectionHeader]; [self updateClippedSubviews]; NSTimeInterval now = CACurrentMediaTime(); diff --git a/React/Views/RCTScrollViewManager.m b/React/Views/RCTScrollViewManager.m index ededf5f7f..8441de74d 100644 --- a/React/Views/RCTScrollViewManager.m +++ b/React/Views/RCTScrollViewManager.m @@ -41,7 +41,7 @@ RCT_EXPORT_VIEW_PROPERTY(scrollEnabled, BOOL) RCT_EXPORT_VIEW_PROPERTY(scrollsToTop, BOOL) RCT_EXPORT_VIEW_PROPERTY(showsHorizontalScrollIndicator, BOOL) RCT_EXPORT_VIEW_PROPERTY(showsVerticalScrollIndicator, BOOL) -RCT_EXPORT_VIEW_PROPERTY(stickyHeaderIndices, NSNumberArray) +RCT_EXPORT_VIEW_PROPERTY(stickyHeaderIndices, NSIndexSet) RCT_EXPORT_VIEW_PROPERTY(scrollEventThrottle, NSTimeInterval) RCT_EXPORT_VIEW_PROPERTY(zoomScale, CGFloat) RCT_EXPORT_VIEW_PROPERTY(contentInset, UIEdgeInsets) From 40e3f6ea8c17c0fcc43eab5a9e836b6a6be47d5c Mon Sep 17 00:00:00 2001 From: Eric Vicenti Date: Wed, 6 May 2015 12:17:23 -0700 Subject: [PATCH 10/12] [ReactNative] Navigator initialRoute default change Summary: The default initialRoute was the first route, but it makes more sense for the default initialRoute to be the last route in the initialRouteStack. Updated the docs to reflect that. @public Test Plan: Updated call sites and checked that they work. Not many places use initialRouteStack yet. --- .../CustomComponents/Navigator/Navigator.js | 29 +++++++++---------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/Libraries/CustomComponents/Navigator/Navigator.js b/Libraries/CustomComponents/Navigator/Navigator.js index d4c97561b..c009e8086 100644 --- a/Libraries/CustomComponents/Navigator/Navigator.js +++ b/Libraries/CustomComponents/Navigator/Navigator.js @@ -227,15 +227,17 @@ var Navigator = React.createClass({ renderScene: PropTypes.func.isRequired, /** - * Provide a single "route" to start on. A route is an arbitrary object - * that the navigator will use to identify each scene before rendering. - * Either initialRoute or initialRouteStack is required. + * Specify a route to start on. A route is an object that the navigator + * will use to identify each scene to render. `initialRoute` must be + * a route in the `initialRouteStack` if both props are provided. The + * `initialRoute` will default to the last item in the `initialRouteStack`. */ initialRoute: PropTypes.object, /** - * Provide a set of routes to initially mount the scenes for. Required if no - * initialRoute is provided + * Provide a set of routes to initially mount. Required if no initialRoute + * is provided. Otherwise, it will default to an array containing only the + * `initialRoute` */ initialRouteStack: PropTypes.arrayOf(PropTypes.object), @@ -295,21 +297,18 @@ var Navigator = React.createClass({ }, getInitialState: function() { - var routeStack = this.props.initialRouteStack || []; - var initialRouteIndex = 0; - if (this.props.initialRoute && routeStack.length) { + var routeStack = this.props.initialRouteStack || [this.props.initialRoute]; + invariant( + routeStack.length >= 1, + 'Navigator requires props.initialRoute or props.initialRouteStack.' + ); + var initialRouteIndex = routeStack.length - 1; + if (this.props.initialRoute) { initialRouteIndex = routeStack.indexOf(this.props.initialRoute); invariant( initialRouteIndex !== -1, 'initialRoute is not in initialRouteStack.' ); - } else if (this.props.initialRoute) { - routeStack = [this.props.initialRoute]; - } else { - invariant( - routeStack.length >= 1, - 'Navigator requires props.initialRoute or props.initialRouteStack.' - ); } return { sceneConfigStack: routeStack.map( From d177a45bdce124b635dbc31ab0949d2e9d139eb3 Mon Sep 17 00:00:00 2001 From: Peter Zich Date: Wed, 6 May 2015 14:28:05 -0700 Subject: [PATCH 11/12] [ReactNative] Pull transform properties out into TransformPropTypes --- .../Components/View/ViewStylePropTypes.js | 11 ++------ Libraries/Image/ImageStylePropTypes.js | 2 ++ Libraries/StyleSheet/TransformPropTypes.js | 28 +++++++++++++++++++ 3 files changed, 32 insertions(+), 9 deletions(-) create mode 100644 Libraries/StyleSheet/TransformPropTypes.js diff --git a/Libraries/Components/View/ViewStylePropTypes.js b/Libraries/Components/View/ViewStylePropTypes.js index a5b591a61..c1f6b4b1c 100644 --- a/Libraries/Components/View/ViewStylePropTypes.js +++ b/Libraries/Components/View/ViewStylePropTypes.js @@ -13,12 +13,14 @@ var LayoutPropTypes = require('LayoutPropTypes'); var ReactPropTypes = require('ReactPropTypes'); +var TransformPropTypes = require('TransformPropTypes'); /** * Warning: Some of these properties may not be supported in all releases. */ var ViewStylePropTypes = { ...LayoutPropTypes, + ...TransformPropTypes, backgroundColor: ReactPropTypes.string, borderColor: ReactPropTypes.string, borderTopColor: ReactPropTypes.string, @@ -34,15 +36,6 @@ var ViewStylePropTypes = { ), shadowOpacity: ReactPropTypes.number, shadowRadius: ReactPropTypes.number, - transform: ReactPropTypes.arrayOf(ReactPropTypes.object), - transformMatrix: ReactPropTypes.arrayOf(ReactPropTypes.number), - - // DEPRECATED - rotation: ReactPropTypes.number, - scaleX: ReactPropTypes.number, - scaleY: ReactPropTypes.number, - translateX: ReactPropTypes.number, - translateY: ReactPropTypes.number, }; module.exports = ViewStylePropTypes; diff --git a/Libraries/Image/ImageStylePropTypes.js b/Libraries/Image/ImageStylePropTypes.js index d46807ce7..c70bee73a 100644 --- a/Libraries/Image/ImageStylePropTypes.js +++ b/Libraries/Image/ImageStylePropTypes.js @@ -14,9 +14,11 @@ var ImageResizeMode = require('ImageResizeMode'); var LayoutPropTypes = require('LayoutPropTypes'); var ReactPropTypes = require('ReactPropTypes'); +var TransformPropTypes = require('TransformPropTypes'); var ImageStylePropTypes = { ...LayoutPropTypes, + ...TransformPropTypes, resizeMode: ReactPropTypes.oneOf(Object.keys(ImageResizeMode)), backgroundColor: ReactPropTypes.string, borderColor: ReactPropTypes.string, diff --git a/Libraries/StyleSheet/TransformPropTypes.js b/Libraries/StyleSheet/TransformPropTypes.js new file mode 100644 index 000000000..9338f7ff5 --- /dev/null +++ b/Libraries/StyleSheet/TransformPropTypes.js @@ -0,0 +1,28 @@ +/** + * 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 TransformPropTypes + * @flow + */ +'use strict'; + +var ReactPropTypes = require('ReactPropTypes'); + +var TransformPropTypes = { + transform: ReactPropTypes.arrayOf(ReactPropTypes.object), + transformMatrix: ReactPropTypes.arrayOf(ReactPropTypes.number), + + // DEPRECATED + rotation: ReactPropTypes.number, + scaleX: ReactPropTypes.number, + scaleY: ReactPropTypes.number, + translateX: ReactPropTypes.number, + translateY: ReactPropTypes.number, +}; + +module.exports = TransformPropTypes; From ee449301b66948bbdb983b9bbade382b8fb350c3 Mon Sep 17 00:00:00 2001 From: Alex Kotliarskyi Date: Wed, 6 May 2015 14:17:17 -0700 Subject: [PATCH 12/12] [ReactNative] Fail faster in OSS tests --- Examples/SampleApp/SampleAppTests/SampleAppTests.m | 4 ++-- Examples/UIExplorer/UIExplorerTests/UIExplorerTests.m | 5 +++-- Libraries/RCTTest/RCTTestRunner.m | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/Examples/SampleApp/SampleAppTests/SampleAppTests.m b/Examples/SampleApp/SampleAppTests/SampleAppTests.m index 647942713..d8dce811d 100644 --- a/Examples/SampleApp/SampleAppTests/SampleAppTests.m +++ b/Examples/SampleApp/SampleAppTests/SampleAppTests.m @@ -44,8 +44,8 @@ NSString *redboxError = nil; while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { - [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:date]; - [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:date]; + [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; redboxError = [[RCTRedBox sharedInstance] currentErrorMessage]; diff --git a/Examples/UIExplorer/UIExplorerTests/UIExplorerTests.m b/Examples/UIExplorer/UIExplorerTests/UIExplorerTests.m index 2c2359b44..df748ef03 100644 --- a/Examples/UIExplorer/UIExplorerTests/UIExplorerTests.m +++ b/Examples/UIExplorer/UIExplorerTests/UIExplorerTests.m @@ -69,8 +69,9 @@ NSString *redboxError = nil; while ([date timeIntervalSinceNow] > 0 && !foundElement && !redboxError) { - [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:date]; - [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:date]; + [[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:^(UIView *view) { if ([view respondsToSelector:@selector(attributedText)]) { diff --git a/Libraries/RCTTest/RCTTestRunner.m b/Libraries/RCTTest/RCTTestRunner.m index 0aa148fbc..9c0cacf70 100644 --- a/Libraries/RCTTest/RCTTestRunner.m +++ b/Libraries/RCTTest/RCTTestRunner.m @@ -84,8 +84,8 @@ NSDate *date = [NSDate dateWithTimeIntervalSinceNow:TIMEOUT_SECONDS]; NSString *error = [[RCTRedBox sharedInstance] currentErrorMessage]; while ([date timeIntervalSinceNow] > 0 && ![testModule isDone] && error == nil) { - [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:date]; - [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:date]; + [[NSRunLoop mainRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; + [[NSRunLoop mainRunLoop] runMode:NSRunLoopCommonModes beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; error = [[RCTRedBox sharedInstance] currentErrorMessage]; } [rootView removeFromSuperview];