From a86e03d6304eaf03c0fa2f6de7d101209e3bc23e Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Wed, 24 Jun 2015 00:15:49 -0700 Subject: [PATCH 01/16] Add React Native library stub --- HybridMobileDeploy.android.js | 17 ++ HybridMobileDeploy.h | 5 + HybridMobileDeploy.ios.js | 20 ++ HybridMobileDeploy.m | 12 + HybridMobileDeploy.xcodeproj/project.pbxproj | 252 ++++++++++++++++++ .../contents.xcworkspacedata | 7 + package.json | 8 + 7 files changed, 321 insertions(+) create mode 100644 HybridMobileDeploy.android.js create mode 100644 HybridMobileDeploy.h create mode 100644 HybridMobileDeploy.ios.js create mode 100644 HybridMobileDeploy.m create mode 100644 HybridMobileDeploy.xcodeproj/project.pbxproj create mode 100644 HybridMobileDeploy.xcodeproj/project.xcworkspace/contents.xcworkspacedata create mode 100644 package.json diff --git a/HybridMobileDeploy.android.js b/HybridMobileDeploy.android.js new file mode 100644 index 000000000..ccc6d7bfd --- /dev/null +++ b/HybridMobileDeploy.android.js @@ -0,0 +1,17 @@ +/** + * Stub of HybridMobileDeploy for Android. + * + * @providesModule HybridMobileDeploy + * @flow + */ +'use strict'; + +var warning = require('warning'); + +var HybridMobileDeploy = { + test: function() { + warning("Not yet implemented for Android."); + } +}; + +module.exports = HybridMobileDeploy; diff --git a/HybridMobileDeploy.h b/HybridMobileDeploy.h new file mode 100644 index 000000000..07197a08f --- /dev/null +++ b/HybridMobileDeploy.h @@ -0,0 +1,5 @@ +#import "RCTBridgeModule.h" + +@interface HybridMobileDeploy : NSObject + +@end diff --git a/HybridMobileDeploy.ios.js b/HybridMobileDeploy.ios.js new file mode 100644 index 000000000..932794a3e --- /dev/null +++ b/HybridMobileDeploy.ios.js @@ -0,0 +1,20 @@ +/** + * @providesModule HybridMobileDeploy + * @flow + */ +'use strict'; + +var NativeHybridMobileDeploy = require('NativeModules').HybridMobileDeploy; +var invariant = require('invariant'); + +/** + * High-level docs for the HybridMobileDeploy iOS API can be written here. + */ + +var HybridMobileDeploy = { + test: function() { + NativeHybridMobileDeploy.test(); + } +}; + +module.exports = HybridMobileDeploy; diff --git a/HybridMobileDeploy.m b/HybridMobileDeploy.m new file mode 100644 index 000000000..ac1182e94 --- /dev/null +++ b/HybridMobileDeploy.m @@ -0,0 +1,12 @@ +#import "HybridMobileDeploy.h" + +@implementation HybridMobileDeploy + +RCT_EXPORT_MODULE() + +RCT_EXPORT_METHOD(test) +{ + // Your implementation here +} + +@end diff --git a/HybridMobileDeploy.xcodeproj/project.pbxproj b/HybridMobileDeploy.xcodeproj/project.pbxproj new file mode 100644 index 000000000..170a64671 --- /dev/null +++ b/HybridMobileDeploy.xcodeproj/project.pbxproj @@ -0,0 +1,252 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 13BE3DEE1AC21097009241FE /* HybridMobileDeploy.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BE3DED1AC21097009241FE /* HybridMobileDeploy.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 58B511D91A9E6C8500147676 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "include/$(PRODUCT_NAME)"; + dstSubfolderSpec = 16; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 134814201AA4EA6300B7C361 /* libHybridMobileDeploy.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libHybridMobileDeploy.a; sourceTree = BUILT_PRODUCTS_DIR; }; + 13BE3DEC1AC21097009241FE /* HybridMobileDeploy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HybridMobileDeploy.h; sourceTree = ""; }; + 13BE3DED1AC21097009241FE /* HybridMobileDeploy.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HybridMobileDeploy.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 58B511D81A9E6C8500147676 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 134814211AA4EA7D00B7C361 /* Products */ = { + isa = PBXGroup; + children = ( + 134814201AA4EA6300B7C361 /* libHybridMobileDeploy.a */, + ); + name = Products; + sourceTree = ""; + }; + 58B511D21A9E6C8500147676 = { + isa = PBXGroup; + children = ( + 13BE3DEC1AC21097009241FE /* HybridMobileDeploy.h */, + 13BE3DED1AC21097009241FE /* HybridMobileDeploy.m */, + 134814211AA4EA7D00B7C361 /* Products */, + ); + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 58B511DA1A9E6C8500147676 /* HybridMobileDeploy */ = { + isa = PBXNativeTarget; + buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "HybridMobileDeploy" */; + buildPhases = ( + 58B511D71A9E6C8500147676 /* Sources */, + 58B511D81A9E6C8500147676 /* Frameworks */, + 58B511D91A9E6C8500147676 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = HybridMobileDeploy; + productName = RCTDataManager; + productReference = 134814201AA4EA6300B7C361 /* libHybridMobileDeploy.a */; + productType = "com.apple.product-type.library.static"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 58B511D31A9E6C8500147676 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0610; + ORGANIZATIONNAME = Facebook; + TargetAttributes = { + 58B511DA1A9E6C8500147676 = { + CreatedOnToolsVersion = 6.1.1; + }; + }; + }; + buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "HybridMobileDeploy" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 58B511D21A9E6C8500147676; + productRefGroup = 58B511D21A9E6C8500147676; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 58B511DA1A9E6C8500147676 /* HybridMobileDeploy */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 58B511D71A9E6C8500147676 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 13BE3DEE1AC21097009241FE /* HybridMobileDeploy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 58B511ED1A9E6C8500147676 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 58B511EE1A9E6C8500147676 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 58B511F01A9E6C8500147676 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + "$(SRCROOT)/../../React/**", + "$(SRCROOT)/../../node_modules/react-native/React/**", + "$(SRCROOT)/node_modules/react-native/React/**", + ); + LIBRARY_SEARCH_PATHS = "$(inherited)"; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = HybridMobileDeploy; + SKIP_INSTALL = YES; + }; + name = Debug; + }; + 58B511F11A9E6C8500147676 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + HEADER_SEARCH_PATHS = ( + "$(inherited)", + /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, + "$(SRCROOT)/../../React/**", + ); + LIBRARY_SEARCH_PATHS = "$(inherited)"; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = HybridMobileDeploy; + SKIP_INSTALL = YES; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "HybridMobileDeploy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 58B511ED1A9E6C8500147676 /* Debug */, + 58B511EE1A9E6C8500147676 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "HybridMobileDeploy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 58B511F01A9E6C8500147676 /* Debug */, + 58B511F11A9E6C8500147676 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 58B511D31A9E6C8500147676 /* Project object */; +} diff --git a/HybridMobileDeploy.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/HybridMobileDeploy.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..919434a62 --- /dev/null +++ b/HybridMobileDeploy.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/package.json b/package.json new file mode 100644 index 000000000..8cea13f03 --- /dev/null +++ b/package.json @@ -0,0 +1,8 @@ +{ + "name": "HybridMobileDeploy", + "version": "0.0.1", + "keywords": "react-native", + "dependencies": { + "react-native": "^0.5.0" + } +} From b4e1c5901e4890a4d8ba63c4a4b6cf3ac5f91336 Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Wed, 24 Jun 2015 11:36:05 -0700 Subject: [PATCH 02/16] Update code names from prototype --- HybridMobileDeploy.m | 97 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 95 insertions(+), 2 deletions(-) diff --git a/HybridMobileDeploy.m b/HybridMobileDeploy.m index ac1182e94..d1b1dc572 100644 --- a/HybridMobileDeploy.m +++ b/HybridMobileDeploy.m @@ -1,12 +1,105 @@ #import "HybridMobileDeploy.h" +#import "RCTRootView.h" +#import "RCTUtils.h" + @implementation HybridMobileDeploy RCT_EXPORT_MODULE() -RCT_EXPORT_METHOD(test) ++ (NSString *) getBundleFolderPath +{ + NSString* home = NSHomeDirectory(); + NSString* bundleFolder = [home stringByAppendingPathComponent:@"HybridMobileDeploy"]; + return bundleFolder; +} + ++ (NSString *) getBundlePath:(NSString*)bundleName +{ + NSString * bundleFolderPath = [self getBundleFolderPath]; + NSString* appBundleName = [bundleName stringByAppendingString:@".jsbundle"]; + return [bundleFolderPath stringByAppendingPathComponent:appBundleName]; +} + ++ (NSURL *) getNativeBundleURL:(NSString*)bundleName { - // Your implementation here + return [[NSBundle mainBundle] URLForResource:bundleName withExtension:@"jsbundle"]; +} + ++ (NSURL *) appBundleUrl:(NSString*)bundleName { + NSFileManager *fileManager = [NSFileManager defaultManager]; + + NSString *bundlePath = [self getBundlePath:bundleName]; + if ([fileManager fileExistsAtPath:bundlePath]) { + return [[NSURL alloc] initFileURLWithPath:bundlePath]; + } else { + return [self getNativeBundleURL:bundleName]; + } +} + ++ (void) loadBundle:(NSString*)moduleName +{ + dispatch_async(dispatch_get_main_queue(), ^{ + RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:[self appBundleUrl:moduleName] + moduleName:moduleName + launchOptions:nil]; + + UIViewController *rootViewController = [[UIViewController alloc] init]; + rootViewController.view = rootView; + [UIApplication sharedApplication].delegate.window.rootViewController = rootViewController; + }); +} + +RCT_EXPORT_METHOD(installUpdateFromUrl:(NSString*)updateUrl + bundleName:(NSString*)bundleName + failureCallback:(RCTResponseSenderBlock)failureCallback + successCallback:(RCTResponseSenderBlock)successCallback) +{ + NSError *parameterError; + NSMutableDictionary *errorData; + if (!updateUrl) { + errorData = [NSMutableDictionary dictionary]; + [errorData setValue:@"missing-updateUrl" forKey:NSLocalizedDescriptionKey]; + } else if (!bundleName) { + errorData = [NSMutableDictionary dictionary]; + [errorData setValue:@"missing-bundleName" forKey:NSLocalizedDescriptionKey]; + } + + if (errorData) { + parameterError = [NSError errorWithDomain:@"HybridMobileDeploy"code:200 userInfo:errorData]; + NSDictionary *rctError = RCTMakeError(@"Error with input to installUpdateFromUrl", parameterError, errorData); + failureCallback(@[rctError]); + } else { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + NSURL* url = [NSURL URLWithString:updateUrl]; + NSError *err; + + NSString *updateContents = [[NSString alloc] initWithContentsOfURL:url + encoding:NSUTF8StringEncoding + error:&err]; + if (err) { + failureCallback(@[err]); + } else { + dispatch_async(dispatch_get_main_queue(), ^{ + NSError *saveError; + NSString *bundleFolderPath = [HybridMobileDeploy getBundleFolderPath]; + if (![[NSFileManager defaultManager] fileExistsAtPath:bundleFolderPath]) { + [[NSFileManager defaultManager] createDirectoryAtPath:bundleFolderPath withIntermediateDirectories:YES attributes:nil error:&saveError]; + } + [updateContents writeToFile:[HybridMobileDeploy getBundlePath:bundleName] + atomically:YES + encoding:NSUTF8StringEncoding + error:&saveError]; + if (saveError) { + failureCallback(@[saveError]); + } else { + [HybridMobileDeploy loadBundle:bundleName]; + successCallback(@[]); + } + }); + } + }); + } } @end From 0e4663f831e9a094e5835d91dfe99d96d60d3ba8 Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Wed, 24 Jun 2015 14:48:57 -0700 Subject: [PATCH 03/16] Link HybridMobileDeploy module into HybridMobileDeployCompanion example app --- .../project.pbxproj | 54 +- .../iOS/AppDelegate.m | 8 +- .../iOS/main.jsbundle | 41375 +++++++++++++++- HybridMobileDeploy.h | 5 +- HybridMobileDeploy.m | 12 +- 5 files changed, 41430 insertions(+), 24 deletions(-) diff --git a/Examples/HybridMobileDeployCompanion/HybridMobileDeployCompanion.xcodeproj/project.pbxproj b/Examples/HybridMobileDeployCompanion/HybridMobileDeployCompanion.xcodeproj/project.pbxproj index 98e9369fa..6acd3c6ea 100644 --- a/Examples/HybridMobileDeployCompanion/HybridMobileDeployCompanion.xcodeproj/project.pbxproj +++ b/Examples/HybridMobileDeployCompanion/HybridMobileDeployCompanion.xcodeproj/project.pbxproj @@ -23,6 +23,7 @@ 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 146834051AC3E58100842450 /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 146834041AC3E56700842450 /* libReact.a */; }; + 81551E1B1B3B428000F5B9F1 /* libHybridMobileDeploy.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 81551E0F1B3B427200F5B9F1 /* libHybridMobileDeploy.a */; }; 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; }; /* End PBXBuildFile section */ @@ -104,6 +105,13 @@ remoteGlobalIDString = 134814201AA4EA6300B7C361; remoteInfo = RCTLinking; }; + 81551E0E1B3B427200F5B9F1 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 81551E0A1B3B427200F5B9F1 /* HybridMobileDeploy.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 134814201AA4EA6300B7C361; + remoteInfo = HybridMobileDeploy; + }; 832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */; @@ -115,17 +123,17 @@ /* Begin PBXFileReference section */ 008F07F21AC5B25A0029DE68 /* main.jsbundle */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = main.jsbundle; path = iOS/main.jsbundle; sourceTree = ""; }; - 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj; sourceTree = ""; }; - 00C302AF1ABCB8E700DB3ED1 /* RCTAdSupport.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAdSupport.xcodeproj; path = node_modules/react-native/Libraries/AdSupport/RCTAdSupport.xcodeproj; sourceTree = ""; }; - 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj; sourceTree = ""; }; - 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = node_modules/react-native/Libraries/Image/RCTImage.xcodeproj; sourceTree = ""; }; - 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj; sourceTree = ""; }; - 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj; sourceTree = ""; }; + 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTActionSheet.xcodeproj; path = "node_modules/react-native/Libraries/ActionSheetIOS/RCTActionSheet.xcodeproj"; sourceTree = ""; }; + 00C302AF1ABCB8E700DB3ED1 /* RCTAdSupport.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAdSupport.xcodeproj; path = "node_modules/react-native/Libraries/AdSupport/RCTAdSupport.xcodeproj"; sourceTree = ""; }; + 00C302B51ABCB90400DB3ED1 /* RCTGeolocation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTGeolocation.xcodeproj; path = "node_modules/react-native/Libraries/Geolocation/RCTGeolocation.xcodeproj"; sourceTree = ""; }; + 00C302BB1ABCB91800DB3ED1 /* RCTImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTImage.xcodeproj; path = "node_modules/react-native/Libraries/Image/RCTImage.xcodeproj"; sourceTree = ""; }; + 00C302D31ABCB9D200DB3ED1 /* RCTNetwork.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTNetwork.xcodeproj; path = "node_modules/react-native/Libraries/Network/RCTNetwork.xcodeproj"; sourceTree = ""; }; + 00C302DF1ABCB9EE00DB3ED1 /* RCTVibration.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTVibration.xcodeproj; path = "node_modules/react-native/Libraries/Vibration/RCTVibration.xcodeproj"; sourceTree = ""; }; 00E356EE1AD99517003FC87E /* HybridMobileDeployCompanionTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HybridMobileDeployCompanionTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 00E356F11AD99517003FC87E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 00E356F21AD99517003FC87E /* HybridMobileDeployCompanionTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HybridMobileDeployCompanionTests.m; sourceTree = ""; }; - 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj; sourceTree = ""; }; - 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj; sourceTree = ""; }; + 139105B61AF99BAD00B5F7CC /* RCTSettings.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTSettings.xcodeproj; path = "node_modules/react-native/Libraries/Settings/RCTSettings.xcodeproj"; sourceTree = ""; }; + 139FDEE61B06529A00C62182 /* RCTWebSocket.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTWebSocket.xcodeproj; path = "node_modules/react-native/Libraries/WebSocket/RCTWebSocket.xcodeproj"; sourceTree = ""; }; 13B07F961A680F5B00A75B9A /* HybridMobileDeployCompanion.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HybridMobileDeployCompanion.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 = ""; }; @@ -133,9 +141,10 @@ 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = iOS/Images.xcassets; sourceTree = ""; }; 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = iOS/Info.plist; sourceTree = ""; }; 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = iOS/main.m; sourceTree = ""; }; - 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = node_modules/react-native/React/React.xcodeproj; sourceTree = ""; }; - 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj; sourceTree = ""; }; - 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = node_modules/react-native/Libraries/Text/RCTText.xcodeproj; sourceTree = ""; }; + 146833FF1AC3E56700842450 /* React.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = React.xcodeproj; path = "node_modules/react-native/React/React.xcodeproj"; sourceTree = ""; }; + 78C398B01ACF4ADC00677621 /* RCTLinking.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTLinking.xcodeproj; path = "node_modules/react-native/Libraries/LinkingIOS/RCTLinking.xcodeproj"; sourceTree = ""; }; + 81551E0A1B3B427200F5B9F1 /* HybridMobileDeploy.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = HybridMobileDeploy.xcodeproj; path = ../../HybridMobileDeploy.xcodeproj; sourceTree = ""; }; + 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTText.xcodeproj; path = "node_modules/react-native/Libraries/Text/RCTText.xcodeproj"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -161,6 +170,7 @@ 832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */, 00C302EA1ABCBA2D00DB3ED1 /* libRCTVibration.a in Frameworks */, 139FDEF61B0652A700C62182 /* libRCTWebSocket.a in Frameworks */, + 81551E1B1B3B428000F5B9F1 /* libHybridMobileDeploy.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -278,9 +288,18 @@ name = Products; sourceTree = ""; }; + 81551E0B1B3B427200F5B9F1 /* Products */ = { + isa = PBXGroup; + children = ( + 81551E0F1B3B427200F5B9F1 /* libHybridMobileDeploy.a */, + ); + name = Products; + sourceTree = ""; + }; 832341AE1AAA6A7D00B99B32 /* Libraries */ = { isa = PBXGroup; children = ( + 81551E0A1B3B427200F5B9F1 /* HybridMobileDeploy.xcodeproj */, 146833FF1AC3E56700842450 /* React.xcodeproj */, 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */, 00C302AF1ABCB8E700DB3ED1 /* RCTAdSupport.xcodeproj */, @@ -390,6 +409,10 @@ productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; projectDirPath = ""; projectReferences = ( + { + ProductGroup = 81551E0B1B3B427200F5B9F1 /* Products */; + ProjectRef = 81551E0A1B3B427200F5B9F1 /* HybridMobileDeploy.xcodeproj */; + }, { ProductGroup = 00C302A81ABCB8CE00DB3ED1 /* Products */; ProjectRef = 00C302A71ABCB8CE00DB3ED1 /* RCTActionSheet.xcodeproj */; @@ -514,6 +537,13 @@ remoteRef = 78C398B81ACF4ADC00677621 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + 81551E0F1B3B427200F5B9F1 /* libHybridMobileDeploy.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libHybridMobileDeploy.a; + remoteRef = 81551E0E1B3B427200F5B9F1 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; 832341B51AAA6A8300B99B32 /* libRCTText.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -629,6 +659,7 @@ "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "$(SRCROOT)/node_modules/react-native/React/**", + "$(SRCROOT)/../..", ); INFOPLIST_FILE = "$(SRCROOT)/iOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -645,6 +676,7 @@ "$(inherited)", /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include, "$(SRCROOT)/node_modules/react-native/React/**", + "$(SRCROOT)/../..", ); INFOPLIST_FILE = "$(SRCROOT)/iOS/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; diff --git a/Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m b/Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m index d1c70518a..e87f1aedf 100644 --- a/Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m +++ b/Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m @@ -11,6 +11,8 @@ #import "RCTRootView.h" +#import "HybridMobileDeploy.h" + @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions @@ -31,7 +33,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( * on the same Wi-Fi network. */ - jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle"]; + //jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle"]; /** * OPTION 2 @@ -42,8 +44,8 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( * * see http://facebook.github.io/react-native/docs/runningondevice.html */ - -// jsCodeLocation = [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; + + jsCodeLocation = [HybridMobileDeploy appBundleUrl:@"HybridMobileDeployCompanion" nativeBundleName:@"main"]; RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"HybridMobileDeployCompanion" diff --git a/Examples/HybridMobileDeployCompanion/iOS/main.jsbundle b/Examples/HybridMobileDeployCompanion/iOS/main.jsbundle index b702b30c6..2451483a1 100644 --- a/Examples/HybridMobileDeployCompanion/iOS/main.jsbundle +++ b/Examples/HybridMobileDeployCompanion/iOS/main.jsbundle @@ -1,8 +1,41373 @@ -// Offline JS -// To re-generate the offline bundle, run this from the root of your project: +/* eslint global-strict:0 */ +__DEV__ = false; + +/* eslint global-strict:0,eqeqeq:0,no-bitwise:0,no-undef:0 */ +(function(global) { + + // avoid redefining require() + if (global.require) { + return; + } + + var __DEV__ = global.__DEV__; + + var toString = Object.prototype.toString; + + /** + * module index: { + * mod1: { + * exports: { ... }, + * id: 'mod1', + * dependencies: ['mod1', 'mod2'], + * factory: function() { ... }, + * waitingMap: { mod1: 1, mod3: 1, mod4: 1 }, + * waiting: 2 + * } + * } + */ + var modulesMap = {}, + /** + * inverse index: { + * mod1: [modules, waiting for mod1], + * mod2: [modules, waiting for mod2] + * } + */ + dependencyMap = {}, + /** + * modules whose reference counts are set out of order + */ + predefinedRefCounts = {}, + + _counter = 0, + + REQUIRE_WHEN_READY = 1, + USED_AS_TRANSPORT = 2, + + hop = Object.prototype.hasOwnProperty; + + function _debugUnresolvedDependencies(names) { + var unresolved = Array.prototype.slice.call(names); + var visited = {}; + var ii, name, module, dependency; + + while (unresolved.length) { + name = unresolved.shift(); + if (visited[name]) { + continue; + } + visited[name] = true; + + module = modulesMap[name]; + if (!module || !module.waiting) { + continue; + } + + for (ii = 0; ii < module.dependencies.length; ii++) { + dependency = module.dependencies[ii]; + if (!modulesMap[dependency] || modulesMap[dependency].waiting) { + unresolved.push(dependency); + } + } + } + + for (name in visited) if (hop.call(visited, name)) { + unresolved.push(name); + } + + var messages = []; + for (ii = 0; ii < unresolved.length; ii++) { + name = unresolved[ii]; + var message = name; + module = modulesMap[name]; + if (!module) { + message += ' is not defined'; + } else if (!module.waiting) { + message += ' is ready'; + } else { + var unresolvedDependencies = []; + for (var jj = 0; jj < module.dependencies.length; jj++) { + dependency = module.dependencies[jj]; + if (!modulesMap[dependency] || modulesMap[dependency].waiting) { + unresolvedDependencies.push(dependency); + } + } + message += ' is waiting for ' + unresolvedDependencies.join(', '); + } + messages.push(message); + } + return messages.join('\n'); + } + + /** + * This is mainly for logging in ModuleErrorLogger. + */ + function ModuleError(msg) { + this.name = 'ModuleError'; + this.message = msg; + this.stack = Error(msg).stack; + this.framesToPop = 2; + } + ModuleError.prototype = Object.create(Error.prototype); + ModuleError.prototype.constructor = ModuleError; + + var _performance = + global.performance || + global.msPerformance || + global.webkitPerformance || {}; + + if (!_performance.now) { + _performance = global.Date; + } + + var _now = _performance ? + _performance.now.bind(_performance) : function(){return 0;}; + + var _factoryStackCount = 0; + var _factoryTime = 0; + var _totalFactories = 0; + + /** + * The require function conforming to CommonJS spec: + * http://wiki.commonjs.org/wiki/Modules/1.1.1 + * + * To define a CommonJS-compliant module add the providesModule + * Haste header to your file instead of @provides. Your file is going + * to be executed in a separate context. Every variable/function you + * define will be local (private) to that module. To export local members + * use "exports" variable or return the exported value at the end of your + * file. Your code will have access to the "module" object. + * The "module" object will have an "id" property that is the id of your + * current module. "module" object will also have "exports" property that + * is the same as "exports" variable passed into your module context. + * You can require other modules using their ids. + * + * Haste will automatically pick dependencies from require() calls. So + * you don't have to manually specify @requires in your header. + * + * You cannot require() modules from non-CommonJS files. Write a legacy stub + * (@providesLegacy) and use @requires instead. + * + * @example + * + * / ** + * * @providesModule math + * * / + * exports.add = function() { + * var sum = 0, i = 0, args = arguments, l = args.length; + * while (i < l) { + * sum += args[i++]; + * } + * return sum; + * }; + * + * / ** + * * @providesModule increment + * * / + * var add = require('math').add; + * return function(val) { + * return add(val, 1); + * }; + * + * / ** + * * @providesModule program + * * / + * var inc = require('increment'); + * var a = 1; + * inc(a); // 2 + * + * module.id == "program"; + * + * + * @param {String} id + * @throws when module is not loaded or not ready to be required + */ + function require(id) { + var module = modulesMap[id], dep, i, msg; + if (module && module.exports) { + // If ref count is 1, this was the last call, so undefine the module. + // The ref count can be null or undefined, but those are never === 1. + if (module.refcount-- === 1) { + delete modulesMap[id]; + } + return module.exports; + } + + if (global.ErrorUtils && !global.ErrorUtils.inGuard()) { + return ErrorUtils.applyWithGuard(require, this, arguments); + } + + if (!module) { + msg = 'Requiring unknown module "' + id + '"'; + if (__DEV__) { + msg += '. If you are sure the module is there, try restarting the packager.'; + } + throw new ModuleError(msg); + } + + if (module.hasError) { + throw new ModuleError( + 'Requiring module "' + id + '" which threw an exception' + ); + } + + if (module.waiting) { + throw new ModuleError( + 'Requiring module "' + id + '" with unresolved dependencies: ' + + _debugUnresolvedDependencies([id]) + ); + } + + var exports = module.exports = {}; + var factory = module.factory; + if (toString.call(factory) === '[object Function]') { + var args = [], + dependencies = module.dependencies, + length = dependencies.length, + ret; + if (module.special & USED_AS_TRANSPORT) { + length = Math.min(length, factory.length); + } + try { + for (i = 0; args.length < length; i++) { + dep = dependencies[i]; + if (!module.inlineRequires[dep]) { + args.push(dep === 'module' ? module : + (dep === 'exports' ? exports : + require.call(null, dep))); + } + } + + ++_totalFactories; + if (_factoryStackCount++ === 0) { + _factoryTime -= _now(); + } + try { + ret = factory.apply(module.context || global, args); + } catch (e) { + if (modulesMap.ex && modulesMap.erx) { + // when ErrorUtils is ready, ex and erx are ready. otherwise, we + // don't append module id to the error message but still throw it + var ex = require.call(null, 'ex'); + var erx = require.call(null, 'erx'); + var messageWithParams = erx(e.message); + if (messageWithParams[0].indexOf(' from module "%s"') < 0) { + messageWithParams[0] += ' from module "%s"'; + messageWithParams[messageWithParams.length] = id; + } + e.message = ex.apply(null, messageWithParams); + } + throw e; + } finally { + if (--_factoryStackCount === 0) { + _factoryTime += _now(); + } + } + } catch (e) { + module.hasError = true; + module.exports = null; + throw e; + } + if (ret) { + if (__DEV__) { + if (typeof ret != 'object' && typeof ret != 'function') { + throw new ModuleError( + 'Factory for module "' + id + '" returned ' + + 'an invalid value "' + ret + '". ' + + 'Returned value should be either a function or an object.' + ); + } + } + module.exports = ret; + } + } else { + module.exports = factory; + } + + // If ref count is 1, this was the last call, so undefine the module. + // The ref count can be null or undefined, but those are never === 1. + if (module.refcount-- === 1) { + delete modulesMap[id]; + } + return module.exports; + } + + require.__getFactoryTime = function() { + return (_factoryStackCount ? _now() : 0) + _factoryTime; + }; + + require.__getTotalFactories = function() { + return _totalFactories; + }; + + /** + * The define function conforming to CommonJS proposal: + * http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition + * + * define() allows you to explicitly state dependencies of your module + * in javascript. It's most useful in non-CommonJS files. + * + * define() is used internally by haste as a transport for CommonJS + * modules. So there's no need to use define() if you use providesModule + * + * @example + * / ** + * * @provides alpha + * * / + * + * // Sets up the module with ID of "alpha", that uses require, + * // exports and the module with ID of "beta": + * define("alpha", ["require", "exports", "beta"], + * function (require, exports, beta) { + * exports.verb = function() { + * return beta.verb(); + * //Or: + * return require("beta").verb(); + * } + * }); + * + * / ** + * * @provides alpha + * * / + * // An anonymous module could be defined (module id derived from filename) + * // that returns an object literal: + * + * define(["alpha"], function (alpha) { + * return { + * verb: function(){ + * return alpha.verb() + 2; + * } + * }; + * }); + * + * / ** + * * @provides alpha + * * / + * // A dependency-free module can define a direct object literal: + * + * define({ + * add: function(x, y){ + * return x + y; + * } + * }); + * + * @param {String} id optional + * @param {Array} dependencies optional + * @param {Object|Function} factory + */ + function define(id, dependencies, factory, + _special, _context, _refCount, _inlineRequires) { + if (dependencies === undefined) { + dependencies = []; + factory = id; + id = _uid(); + } else if (factory === undefined) { + factory = dependencies; + if (toString.call(id) === '[object Array]') { + dependencies = id; + id = _uid(); + } else { + dependencies = []; + } + } + + // Non-standard: we allow modules to be undefined. This is designed for + // temporary modules. + var canceler = { cancel: _undefine.bind(this, id) }; + + var record = modulesMap[id]; + + // Nonstandard hack: we call define with null deps and factory, but a + // non-null reference count (e.g. define('name', null, null, 0, null, 4)) + // when this module is defined elsewhere and we just need to update the + // reference count. We use this hack to avoid having to expose another + // global function to increment ref counts. + if (record) { + if (_refCount) { + record.refcount += _refCount; + } + // Calling define() on a pre-existing module does not redefine it + return canceler; + } else if (!dependencies && !factory && _refCount) { + // If this module hasn't been defined yet, store the ref count. We'll use + // it when the module is defined later. + predefinedRefCounts[id] = (predefinedRefCounts[id] || 0) + _refCount; + return canceler; + } else { + // Defining a new module + record = { id: id }; + record.refcount = (predefinedRefCounts[id] || 0) + (_refCount || 0); + delete predefinedRefCounts[id]; + } + + if (__DEV__) { + if ( + !factory || + (typeof factory != 'object' && typeof factory != 'function' && + typeof factory != 'string')) { + throw new ModuleError( + 'Invalid factory "' + factory + '" for module "' + id + '". ' + + 'Factory should be either a function or an object.' + ); + } + + if (toString.call(dependencies) !== '[object Array]') { + throw new ModuleError( + 'Invalid dependencies for module "' + id + '". ' + + 'Dependencies must be passed as an array.' + ); + } + } + + record.factory = factory; + record.dependencies = dependencies; + record.context = _context; + record.special = _special; + record.inlineRequires = _inlineRequires || {}; + record.waitingMap = {}; + record.waiting = 0; + record.hasError = false; + modulesMap[id] = record; + _initDependencies(id); + + return canceler; + } + + function _undefine(id) { + if (!modulesMap[id]) { + return; + } + + var module = modulesMap[id]; + delete modulesMap[id]; + + for (var dep in module.waitingMap) { + if (module.waitingMap[dep]) { + delete dependencyMap[dep][id]; + } + } + + for (var ii = 0; ii < module.dependencies.length; ii++) { + dep = module.dependencies[ii]; + if (modulesMap[dep]) { + if (modulesMap[dep].refcount-- === 1) { + _undefine(dep); + } + } else if (predefinedRefCounts[dep]) { + predefinedRefCounts[dep]--; + } + // Subtle: we won't account for this one fewer reference if we don't have + // the dependency's definition or reference count yet. + } + } + + /** + * Special version of define that executes the factory as soon as all + * dependencies are met. + * + * define() does just that, defines a module. Module's factory will not be + * called until required by other module. This makes sense for most of our + * library modules: we do not want to execute the factory unless it's being + * used by someone. + * + * On the other hand there are modules, that you can call "entrance points". + * You want to run the "factory" method for them as soon as all dependencies + * are met. + * + * @example + * + * define('BaseClass', [], function() { return ... }); + * // ^^ factory for BaseClass was just stored in modulesMap + * + * define('SubClass', ['BaseClass'], function() { ... }); + * // SubClass module is marked as ready (waiting == 0), factory is just + * // stored + * + * define('OtherClass, ['BaseClass'], function() { ... }); + * // OtherClass module is marked as ready (waiting == 0), factory is just + * // stored + * + * requireLazy(['SubClass', 'ChatConfig'], + * function() { ... }); + * // ChatRunner is waiting for ChatConfig to come + * + * define('ChatConfig', [], { foo: 'bar' }); + * // at this point ChatRunner is marked as ready, and its factory + * // executed + all dependent factories are executed too: BaseClass, + * // SubClass, ChatConfig notice that OtherClass's factory won't be + * // executed unless explicitly required by someone + * + * @param {Array} dependencies + * @param {Object|Function} factory + */ + function requireLazy(dependencies, factory, context) { + return define( + dependencies, + factory, + undefined, + REQUIRE_WHEN_READY, + context, + 1 + ); + } + + function _uid() { + return '__mod__' + _counter++; + } + + function _addDependency(module, dep) { + // do not add duplicate dependencies and circ deps + if (!module.waitingMap[dep] && module.id !== dep) { + module.waiting++; + module.waitingMap[dep] = 1; + dependencyMap[dep] || (dependencyMap[dep] = {}); + dependencyMap[dep][module.id] = 1; + } + } + + function _initDependencies(id) { + var modulesToRequire = []; + var module = modulesMap[id]; + var dep, i, subdep; + + // initialize id's waitingMap + for (i = 0; i < module.dependencies.length; i++) { + dep = module.dependencies[i]; + if (!modulesMap[dep]) { + _addDependency(module, dep); + } else if (modulesMap[dep].waiting) { + for (subdep in modulesMap[dep].waitingMap) { + if (modulesMap[dep].waitingMap[subdep]) { + _addDependency(module, subdep); + } + } + } + } + if (module.waiting === 0 && module.special & REQUIRE_WHEN_READY) { + modulesToRequire.push(id); + } + + // update modules depending on id + if (dependencyMap[id]) { + var deps = dependencyMap[id]; + var submodule; + dependencyMap[id] = undefined; + for (dep in deps) { + submodule = modulesMap[dep]; + + // add all deps of id + for (subdep in module.waitingMap) { + if (module.waitingMap[subdep]) { + _addDependency(submodule, subdep); + } + } + // remove id itself + if (submodule.waitingMap[id]) { + submodule.waitingMap[id] = undefined; + submodule.waiting--; + } + if (submodule.waiting === 0 && + submodule.special & REQUIRE_WHEN_READY) { + modulesToRequire.push(dep); + } + } + } + + // run everything that's ready + for (i = 0; i < modulesToRequire.length; i++) { + require.call(null, modulesToRequire[i]); + } + } + + function _register(id, exports) { + var module = modulesMap[id] = { id: id }; + module.exports = exports; + module.refcount = 0; + } + + // pseudo name used in common-require + // see require() function for more info + _register('module', 0); + _register('exports', 0); + + _register('global', global); + _register('require', require); + _register('requireDynamic', require); + _register('requireLazy', requireLazy); + + global.require = require; + global.requireDynamic = require; + global.requireLazy = requireLazy; + + require.__debug = { + modules: modulesMap, + deps: dependencyMap, + printDependencyInfo: function() { + if (!global.console) { + return; + } + var names = Object.keys(require.__debug.deps); + global.console.log(_debugUnresolvedDependencies(names)); + } + }; + + /** + * All @providesModule files are wrapped by this function by makehaste. It + * is a convenience function around define() that prepends a bunch of required + * modules (global, require, module, etc) so that we don't have to spit that + * out for every module which would be a lot of extra bytes. + */ + global.__d = function(id, deps, factory, _special, _inlineRequires) { + var defaultDeps = ['global', 'require', 'requireDynamic', 'requireLazy', + 'module', 'exports']; + define(id, defaultDeps.concat(deps), factory, _special || USED_AS_TRANSPORT, + null, null, _inlineRequires); + }; + +})(this); + +/** + * 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. + * + * This pipes all of our console logging functions to native logging so that + * JavaScript errors in required modules show up in Xcode via NSLog. + * + * @provides Object.es6 + * @polyfill + */ + +// WARNING: This is an optimized version that fails on hasOwnProperty checks +// and non objects. It's not spec-compliant. It's a perf optimization. +/* eslint global-strict:0 */ +Object.assign = function(target, sources) { + if (__DEV__) { + if (target == null) { + throw new TypeError('Object.assign target cannot be null or undefined'); + } + if (typeof target !== 'object' && typeof target !== 'function') { + throw new TypeError( + 'In this environment the target of assign MUST be an object.' + + 'This error is a performance optimization and not spec compliant.' + ); + } + } + + for (var nextIndex = 1; nextIndex < arguments.length; nextIndex++) { + var nextSource = arguments[nextIndex]; + if (nextSource == null) { + continue; + } + + if (__DEV__) { + if (typeof nextSource !== 'object' && + typeof nextSource !== 'function') { + throw new TypeError( + 'In this environment the target of assign MUST be an object.' + + 'This error is a performance optimization and not spec compliant.' + ); + } + } + + // We don't currently support accessors nor proxies. Therefore this + // copy cannot throw. If we ever supported this then we must handle + // exceptions and side-effects. + + for (var key in nextSource) { + if (__DEV__) { + var hasOwnProperty = Object.prototype.hasOwnProperty; + if (!hasOwnProperty.call(nextSource, key)) { + throw new TypeError( + 'One of the sources to assign has an enumerable key on the ' + + 'prototype chain. This is an edge case that we do not support. ' + + 'This error is a performance optimization and not spec compliant.' + ); + } + } + target[key] = nextSource[key]; + } + } + + return target; +}; + +/** + * 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. + * + * This pipes all of our console logging functions to native logging so that + * JavaScript errors in required modules show up in Xcode via NSLog. + * + * @provides console + * @polyfill + */ + +/*eslint global-strict:0*/ +(function(global) { + 'use strict'; + + var OBJECT_COLUMN_NAME = '(index)'; + var LOG_LEVELS = { + trace: 0, + log: 1, + info: 2, + warn: 3, + error: 4 + }; + + function setupConsole(global) { + + if (!global.nativeLoggingHook) { + return; + } + + function getNativeLogFunction(level) { + return function() { + var str = Array.prototype.map.call(arguments, function(arg) { + var ret; + var type = typeof arg; + if (arg === null) { + ret = 'null'; + } else if (arg === undefined) { + ret = 'undefined'; + } else if (type === 'string') { + ret = '"' + arg + '"'; + } else if (type === 'function') { + try { + ret = arg.toString(); + } catch (e) { + ret = '[function unknown]'; + } + } else { + // Perform a try catch, just in case the object has a circular + // reference or stringify throws for some other reason. + try { + ret = JSON.stringify(arg); + } catch (e) { + if (typeof arg.toString === 'function') { + try { + ret = arg.toString(); + } catch (E) {} + } + } + } + return ret || '["' + type + '" failed to stringify]'; + }).join(', '); + global.nativeLoggingHook(str, level); + }; + } + + var repeat = function(element, n) { + return Array.apply(null, Array(n)).map(function() { return element; }); + }; + + function consoleTablePolyfill(rows) { + // convert object -> array + if (!Array.isArray(rows)) { + var data = rows; + rows = []; + for (var key in data) { + if (data.hasOwnProperty(key)) { + var row = data[key]; + row[OBJECT_COLUMN_NAME] = key; + rows.push(row); + } + } + } + if (rows.length === 0) { + global.nativeLoggingHook('', LOG_LEVELS.log); + return; + } + + var columns = Object.keys(rows[0]).sort(); + var stringRows = []; + var columnWidths = []; + + // Convert each cell to a string. Also + // figure out max cell width for each column + columns.forEach(function(k, i) { + columnWidths[i] = k.length; + for (var j = 0; j < rows.length; j++) { + var cellStr = rows[j][k].toString(); + stringRows[j] = stringRows[j] || []; + stringRows[j][i] = cellStr; + columnWidths[i] = Math.max(columnWidths[i], cellStr.length); + } + }); + + // Join all elements in the row into a single string with | separators + // (appends extra spaces to each cell to make separators | alligned) + var joinRow = function(row, space) { + var cells = row.map(function(cell, i) { + var extraSpaces = repeat(' ', columnWidths[i] - cell.length).join(''); + return cell + extraSpaces; + }); + space = space || ' '; + return cells.join(space + '|' + space); + }; + + var separators = columnWidths.map(function(columnWidth) { + return repeat('-', columnWidth).join(''); + }); + var separatorRow = joinRow(separators, '-'); + var header = joinRow(columns); + var table = [header, separatorRow]; + + for (var i = 0; i < rows.length; i++) { + table.push(joinRow(stringRows[i])); + } + + // Notice extra empty line at the beginning. + // Native logging hook adds "RCTLog >" at the front of every + // logged string, which would shift the header and screw up + // the table + global.nativeLoggingHook('\n' + table.join('\n'), LOG_LEVELS.log); + } + + global.console = { + error: getNativeLogFunction(LOG_LEVELS.error), + info: getNativeLogFunction(LOG_LEVELS.info), + log: getNativeLogFunction(LOG_LEVELS.log), + warn: getNativeLogFunction(LOG_LEVELS.warn), + trace: getNativeLogFunction(LOG_LEVELS.trace), + table: consoleTablePolyfill + }; + + } + + if (typeof module !== 'undefined') { + module.exports = setupConsole; + } else { + setupConsole(global); + } + +})(this); + +/** + * 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. + * + * The particular require runtime that we are using looks for a global + * `ErrorUtils` object and if it exists, then it requires modules with the + * error handler specified via ErrorUtils.setGlobalHandler by calling the + * require function with applyWithGuard. Since the require module is loaded + * before any of the modules, this ErrorUtils must be defined (and the handler + * set) globally before requiring anything. + */ +/* eslint global-strict:0 */ +(function(global) { + var ErrorUtils = { + _inGuard: 0, + _globalHandler: null, + setGlobalHandler: function(fun) { + ErrorUtils._globalHandler = fun; + }, + reportError: function(error) { + ErrorUtils._globalHandler && ErrorUtils._globalHandler(error); + }, + reportFatalError: function(error) { + ErrorUtils._globalHandler && ErrorUtils._globalHandler(error, true); + }, + applyWithGuard: function(fun, context, args) { + try { + ErrorUtils._inGuard++; + return fun.apply(context, args); + } catch (e) { + ErrorUtils.reportError(e); + } finally { + ErrorUtils._inGuard--; + } + }, + applyWithGuardIfNeeded: function(fun, context, args) { + if (ErrorUtils.inGuard()) { + return fun.apply(context, args); + } else { + ErrorUtils.applyWithGuard(fun, context, args); + } + }, + inGuard: function() { + return ErrorUtils._inGuard; + }, + guard: function(fun, name, context) { + if (typeof fun !== 'function') { + console.warn('A function must be passed to ErrorUtils.guard, got ', fun); + return null; + } + name = name || fun.name || ''; + function guarded() { + return ( + ErrorUtils.applyWithGuard( + fun, + context || this, + arguments, + null, + name + ) + ); + } + + return guarded; + } + }; + global.ErrorUtils = ErrorUtils; + + /** + * This is the error handler that is called when we encounter an exception + * when loading a module. + */ + function setupErrorGuard() { + var onError = function(e) { + global.console.error( + 'Error: ' + + '\n stack: ' + e.stack + + '\n line: ' + e.line + + '\n message: ' + e.message, + e + ); + }; + global.ErrorUtils.setGlobalHandler(onError); + } + + setupErrorGuard(); +})(this); + +/** + * @provides String.prototype.es6 + * @polyfill + */ + +/*eslint global-strict:0, no-extend-native:0, no-bitwise:0 */ +/*jshint bitwise:false*/ + +/* + * NOTE: We use (Number(x) || 0) to replace NaN values with zero. + */ + +if (!String.prototype.startsWith) { + String.prototype.startsWith = function(search) { + 'use strict'; + if (this == null) { + throw TypeError(); + } + var string = String(this); + var pos = arguments.length > 1 ? + (Number(arguments[1]) || 0) : 0; + var start = Math.min(Math.max(pos, 0), string.length); + return string.indexOf(String(search), pos) === start; + }; +} + +if (!String.prototype.endsWith) { + String.prototype.endsWith = function(search) { + 'use strict'; + if (this == null) { + throw TypeError(); + } + var string = String(this); + var stringLength = string.length; + var searchString = String(search); + var pos = arguments.length > 1 ? + (Number(arguments[1]) || 0) : stringLength; + var end = Math.min(Math.max(pos, 0), stringLength); + var start = end - searchString.length; + if (start < 0) { + return false; + } + return string.lastIndexOf(searchString, start) === start; + }; +} + +if (!String.prototype.contains) { + String.prototype.contains = function(search) { + 'use strict'; + if (this == null) { + throw TypeError(); + } + var string = String(this); + var pos = arguments.length > 1 ? + (Number(arguments[1]) || 0) : 0; + return string.indexOf(String(search), pos) !== -1; + }; +} + +if (!String.prototype.repeat) { + String.prototype.repeat = function(count) { + 'use strict'; + if (this == null) { + throw TypeError(); + } + var string = String(this); + count = Number(count) || 0; + if (count < 0 || count === Infinity) { + throw RangeError(); + } + if (count === 1) { + return string; + } + var result = ''; + while (count) { + if (count & 1) { + result += string; + } + if ((count >>= 1)) { + string += string; + } + } + return result; + }; +} + +/** + * Copyright 2004-present Facebook. All Rights Reserved. + * + * @provides Array.prototype.es6 + * @polyfill + */ + +/*eslint-disable */ +/*jslint bitwise: true */ + +(function(undefined) { + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex + function findIndex(predicate, context) { + if (this == null) { + throw new TypeError( + 'Array.prototype.findIndex called on null or undefined' + ); + } + if (typeof predicate !== 'function') { + throw new TypeError('predicate must be a function'); + } + var list = Object(this); + var length = list.length >>> 0; + for (var i = 0; i < length; i++) { + if (predicate.call(context, list[i], i, list)) { + return i; + } + } + return -1; + } + + if (!Array.prototype.findIndex) { + Object.defineProperty(Array.prototype, 'findIndex', { + enumerable: false, + writable: true, + configurable: true, + value: findIndex + }); + } + + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find + if (!Array.prototype.find) { + Object.defineProperty(Array.prototype, 'find', { + enumerable: false, + writable: true, + configurable: true, + value: function(predicate, context) { + if (this == null) { + throw new TypeError( + 'Array.prototype.find called on null or undefined' + ); + } + var index = findIndex.call(this, predicate, context); + return index === -1 ? undefined : this[index]; + } + }); + } +})(); + +__d('HybridMobileDeployCompanion/index.ios',["react-native/Libraries/react-native/react-native"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Sample React Native App + * https://github.com/facebook/react-native + */ +'use strict'; + +var React = require('react-native/Libraries/react-native/react-native'); +var $__0= + + + + + React,AppRegistry=$__0.AppRegistry,StyleSheet=$__0.StyleSheet,Text=$__0.Text,View=$__0.View; + +var HybridMobileDeployCompanion = React.createClass({displayName: "HybridMobileDeployCompanion", + render: function() { + return ( + React.createElement(View, {style: styles.container}, + React.createElement(Text, {style: styles.welcome}, + "Welcome to React Native!" + ), + React.createElement(Text, {style: styles.instructions}, + "To get started, edit index.ios.js" + ), + React.createElement(Text, {style: styles.instructions}, + "Press Cmd+R to reload,", '\n', + "Cmd+D or shake for dev menu" + ) + ) + ); + } +}); + +var styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: '#F5FCFF', + }, + welcome: { + fontSize: 20, + textAlign: 'center', + margin: 10, + }, + instructions: { + textAlign: 'center', + color: '#333333', + marginBottom: 5, + }, +}); + +AppRegistry.registerComponent('HybridMobileDeployCompanion', function() {return HybridMobileDeployCompanion;}); +}); +__d('react-native/Libraries/react-native/react-native',["React","ActivityIndicatorIOS","DatePickerIOS","Image","ListView","MapView","NavigatorIOS","PickerIOS","Navigator","SegmentedControlIOS","ScrollView","SliderIOS","SwitchIOS","TabBarIOS","Text","TextInput","TouchableHighlight","TouchableOpacity","TouchableWithoutFeedback","View","WebView","AlertIOS","AppRegistry","AppStateIOS","AsyncStorage","CameraRoll","InteractionManager","LinkingIOS","LayoutAnimation","NetInfo","PixelRatio","PushNotificationIOS","PanResponder","StatusBarIOS","StyleSheet","VibrationIOS","RCTDeviceEventEmitter","NativeModules","requireNativeComponent","LinkedStateMixin","ReactComponentWithPureRenderMixin","NativeModules","ReactUpdates","cloneWithProps","ReactFragment","update","ReactDefaultPerf","ReactTestUtils"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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. + * + * @flow + */ +'use strict'; + +// Export React, plus some native additions. +// +// The use of Object.create/assign is to work around a Flow bug (#6560135). +// Once that is fixed, change this back to // -// $ react-native bundle --minify +// var ReactNative = {...require('React'), /* additions */} // -// See http://facebook.github.io/react-native/docs/runningondevice.html for more details. +var ReactNative = Object.assign(Object.create(require('React')), { + // Components + ActivityIndicatorIOS: require('ActivityIndicatorIOS'), + DatePickerIOS: require('DatePickerIOS'), + Image: require('Image'), + ListView: require('ListView'), + MapView: require('MapView'), + NavigatorIOS: require('NavigatorIOS'), + PickerIOS: require('PickerIOS'), + Navigator: require('Navigator'), + SegmentedControlIOS: require('SegmentedControlIOS'), + ScrollView: require('ScrollView'), + SliderIOS: require('SliderIOS'), + SwitchIOS: require('SwitchIOS'), + TabBarIOS: require('TabBarIOS'), + Text: require('Text'), + TextInput: require('TextInput'), + TouchableHighlight: require('TouchableHighlight'), + TouchableOpacity: require('TouchableOpacity'), + TouchableWithoutFeedback: require('TouchableWithoutFeedback'), + View: require('View'), + WebView: require('WebView'), + + // APIs + AlertIOS: require('AlertIOS'), + AppRegistry: require('AppRegistry'), + AppStateIOS: require('AppStateIOS'), + AsyncStorage: require('AsyncStorage'), + CameraRoll: require('CameraRoll'), + InteractionManager: require('InteractionManager'), + LinkingIOS: require('LinkingIOS'), + LayoutAnimation: require('LayoutAnimation'), + NetInfo: require('NetInfo'), + PixelRatio: require('PixelRatio'), + PushNotificationIOS: require('PushNotificationIOS'), + PanResponder: require('PanResponder'), + StatusBarIOS: require('StatusBarIOS'), + StyleSheet: require('StyleSheet'), + VibrationIOS: require('VibrationIOS'), + + // Plugins + DeviceEventEmitter: require('RCTDeviceEventEmitter'), + NativeModules: require('NativeModules'), + requireNativeComponent: require('requireNativeComponent'), + + addons: { + LinkedStateMixin: require('LinkedStateMixin'), + Perf: undefined, + PureRenderMixin: require('ReactComponentWithPureRenderMixin'), + TestModule: require('NativeModules').TestModule, + TestUtils: undefined, + batchedUpdates: require('ReactUpdates').batchedUpdates, + cloneWithProps: require('cloneWithProps'), + createFragment: require('ReactFragment').create, + update: require('update'), + }, +}); + +if (__DEV__) { + ReactNative.addons.Perf = require('ReactDefaultPerf'); + ReactNative.addons.TestUtils = require('ReactTestUtils'); +} + +module.exports = ReactNative; +}); +__d('React',["ReactNative"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 React + * @flow + */ + +"use strict"; + +module.exports = require('ReactNative'); +}); +__d('ReactNative',["ReactChildren","ReactClass","ReactComponent","ReactContext","ReactCurrentOwner","ReactElement","ReactElementValidator","ReactInstanceHandles","ReactNativeDefaultInjection","ReactNativeMount","ReactPropTypes","deprecated","findNodeHandle","invariant","onlyChild","ReactReconciler","ReactNativeTextComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 ReactNative + * @flow + */ +"use strict"; + +var ReactChildren = require('ReactChildren'); +var ReactClass = require('ReactClass'); +var ReactComponent = require('ReactComponent'); +var ReactContext = require('ReactContext'); +var ReactCurrentOwner = require('ReactCurrentOwner'); +var ReactElement = require('ReactElement'); +var ReactElementValidator = require('ReactElementValidator'); +var ReactInstanceHandles = require('ReactInstanceHandles'); +var ReactNativeDefaultInjection = require('ReactNativeDefaultInjection'); +var ReactNativeMount = require('ReactNativeMount'); +var ReactPropTypes = require('ReactPropTypes'); + +var deprecated = require('deprecated'); +var findNodeHandle = require('findNodeHandle'); +var invariant = require('invariant'); +var onlyChild = require('onlyChild'); + +ReactNativeDefaultInjection.inject(); + +var createElement = ReactElement.createElement; +var createFactory = ReactElement.createFactory; +var cloneElement = ReactElement.cloneElement; + +if (__DEV__) { + createElement = ReactElementValidator.createElement; + createFactory = ReactElementValidator.createFactory; + cloneElement = ReactElementValidator.cloneElement; +} + +var resolveDefaultProps = function(element) { + // Could be optimized, but not currently in heavy use. + var defaultProps = element.type.defaultProps; + var props = element.props; + for (var propName in defaultProps) { + if (props[propName] === undefined) { + props[propName] = defaultProps[propName]; + } + } +}; + +// Experimental optimized element creation +var augmentElement = function(element ) { + if (__DEV__) { + invariant( + false, + 'This optimized path should never be used in DEV mode because ' + + 'it does not provide validation. Check your JSX transform.' + ); + } + element._owner = ReactCurrentOwner.current; + element._context = ReactContext.current; + if (element.type.defaultProps) { + resolveDefaultProps(element); + } + return element; +}; + +var render = function( + element , + mountInto , + callback +) { + return ReactNativeMount.renderComponent(element, mountInto, callback); +}; + +var ReactNative = { + hasReactNativeInitialized: false, + Children: { + map: ReactChildren.map, + forEach: ReactChildren.forEach, + count: ReactChildren.count, + only: onlyChild + }, + Component: ReactComponent, + PropTypes: ReactPropTypes, + createClass: ReactClass.createClass, + createElement: createElement, + createFactory: createFactory, + cloneElement: cloneElement, + _augmentElement: augmentElement, + findNodeHandle: findNodeHandle, + render: render, + unmountComponentAtNode: ReactNativeMount.unmountComponentAtNode, + + // Hook for JSX spread, don't use this for anything else. + __spread: Object.assign, + + unmountComponentAtNodeAndRemoveContainer: ReactNativeMount.unmountComponentAtNodeAndRemoveContainer, + isValidClass: ReactElement.isValidFactory, + isValidElement: ReactElement.isValidElement, + + // Deprecations (remove for 0.13) + renderComponent: deprecated( + 'React', + 'renderComponent', + 'render', + this, + render + ), + isValidComponent: deprecated( + 'React', + 'isValidComponent', + 'isValidElement', + this, + ReactElement.isValidElement + ) +}; + +// Inject the runtime into a devtools global hook regardless of browser. +// Allows for debugging when the hook is injected on the page. +/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__ */ +if ( + typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && + typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') { + __REACT_DEVTOOLS_GLOBAL_HOOK__.inject({ + CurrentOwner: ReactCurrentOwner, + InstanceHandles: ReactInstanceHandles, + Mount: ReactNativeMount, + Reconciler: require('ReactReconciler'), + TextComponent: require('ReactNativeTextComponent'), + }); +} + +module.exports = ReactNative; +}); +__d('ReactChildren',["PooledClass","ReactFragment","traverseAllChildren","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactChildren + */ + +'use strict'; + +var PooledClass = require('PooledClass'); +var ReactFragment = require('ReactFragment'); + +var traverseAllChildren = require('traverseAllChildren'); +var warning = require('warning'); + +var twoArgumentPooler = PooledClass.twoArgumentPooler; +var threeArgumentPooler = PooledClass.threeArgumentPooler; + +/** + * PooledClass representing the bookkeeping associated with performing a child + * traversal. Allows avoiding binding callbacks. + * + * @constructor ForEachBookKeeping + * @param {!function} forEachFunction Function to perform traversal with. + * @param {?*} forEachContext Context to perform context with. + */ +function ForEachBookKeeping(forEachFunction, forEachContext) { + this.forEachFunction = forEachFunction; + this.forEachContext = forEachContext; +} +PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler); + +function forEachSingleChild(traverseContext, child, name, i) { + var forEachBookKeeping = traverseContext; + forEachBookKeeping.forEachFunction.call( + forEachBookKeeping.forEachContext, child, i); +} + +/** + * Iterates through children that are typically specified as `props.children`. + * + * The provided forEachFunc(child, index) will be called for each + * leaf child. + * + * @param {?*} children Children tree container. + * @param {function(*, int)} forEachFunc. + * @param {*} forEachContext Context for forEachContext. + */ +function forEachChildren(children, forEachFunc, forEachContext) { + if (children == null) { + return children; + } + + var traverseContext = + ForEachBookKeeping.getPooled(forEachFunc, forEachContext); + traverseAllChildren(children, forEachSingleChild, traverseContext); + ForEachBookKeeping.release(traverseContext); +} + +/** + * PooledClass representing the bookkeeping associated with performing a child + * mapping. Allows avoiding binding callbacks. + * + * @constructor MapBookKeeping + * @param {!*} mapResult Object containing the ordered map of results. + * @param {!function} mapFunction Function to perform mapping with. + * @param {?*} mapContext Context to perform mapping with. + */ +function MapBookKeeping(mapResult, mapFunction, mapContext) { + this.mapResult = mapResult; + this.mapFunction = mapFunction; + this.mapContext = mapContext; +} +PooledClass.addPoolingTo(MapBookKeeping, threeArgumentPooler); + +function mapSingleChildIntoContext(traverseContext, child, name, i) { + var mapBookKeeping = traverseContext; + var mapResult = mapBookKeeping.mapResult; + + var keyUnique = !mapResult.hasOwnProperty(name); + if (__DEV__) { + warning( + keyUnique, + 'ReactChildren.map(...): Encountered two children with the same key, ' + + '`%s`. Child keys must be unique; when two children share a key, only ' + + 'the first child will be used.', + name + ); + } + + if (keyUnique) { + var mappedChild = + mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i); + mapResult[name] = mappedChild; + } +} + +/** + * Maps children that are typically specified as `props.children`. + * + * The provided mapFunction(child, key, index) will be called for each + * leaf child. + * + * TODO: This may likely break any calls to `ReactChildren.map` that were + * previously relying on the fact that we guarded against null children. + * + * @param {?*} children Children tree container. + * @param {function(*, int)} mapFunction. + * @param {*} mapContext Context for mapFunction. + * @return {object} Object containing the ordered map of results. + */ +function mapChildren(children, func, context) { + if (children == null) { + return children; + } + + var mapResult = {}; + var traverseContext = MapBookKeeping.getPooled(mapResult, func, context); + traverseAllChildren(children, mapSingleChildIntoContext, traverseContext); + MapBookKeeping.release(traverseContext); + return ReactFragment.create(mapResult); +} + +function forEachSingleChildDummy(traverseContext, child, name, i) { + return null; +} + +/** + * Count the number of children that are typically specified as + * `props.children`. + * + * @param {?*} children Children tree container. + * @return {number} The number of children. + */ +function countChildren(children, context) { + return traverseAllChildren(children, forEachSingleChildDummy, null); +} + +var ReactChildren = { + forEach: forEachChildren, + map: mapChildren, + count: countChildren +}; + +module.exports = ReactChildren; +}); +__d('PooledClass',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 PooledClass + */ + +'use strict'; + +var invariant = require('invariant'); + +/** + * Static poolers. Several custom versions for each potential number of + * arguments. A completely generic pooler is easy to implement, but would + * require accessing the `arguments` object. In each of these, `this` refers to + * the Class itself, not an instance. If any others are needed, simply add them + * here, or in their own files. + */ +var oneArgumentPooler = function(copyFieldsFrom) { + var Klass = this; + if (Klass.instancePool.length) { + var instance = Klass.instancePool.pop(); + Klass.call(instance, copyFieldsFrom); + return instance; + } else { + return new Klass(copyFieldsFrom); + } +}; + +var twoArgumentPooler = function(a1, a2) { + var Klass = this; + if (Klass.instancePool.length) { + var instance = Klass.instancePool.pop(); + Klass.call(instance, a1, a2); + return instance; + } else { + return new Klass(a1, a2); + } +}; + +var threeArgumentPooler = function(a1, a2, a3) { + var Klass = this; + if (Klass.instancePool.length) { + var instance = Klass.instancePool.pop(); + Klass.call(instance, a1, a2, a3); + return instance; + } else { + return new Klass(a1, a2, a3); + } +}; + +var fiveArgumentPooler = function(a1, a2, a3, a4, a5) { + var Klass = this; + if (Klass.instancePool.length) { + var instance = Klass.instancePool.pop(); + Klass.call(instance, a1, a2, a3, a4, a5); + return instance; + } else { + return new Klass(a1, a2, a3, a4, a5); + } +}; + +var standardReleaser = function(instance) { + var Klass = this; + invariant( + instance instanceof Klass, + 'Trying to release an instance into a pool of a different type.' + ); + if (instance.destructor) { + instance.destructor(); + } + if (Klass.instancePool.length < Klass.poolSize) { + Klass.instancePool.push(instance); + } +}; + +var DEFAULT_POOL_SIZE = 10; +var DEFAULT_POOLER = oneArgumentPooler; + +/** + * Augments `CopyConstructor` to be a poolable class, augmenting only the class + * itself (statically) not adding any prototypical fields. Any CopyConstructor + * you give this may have a `poolSize` property, and will look for a + * prototypical `destructor` on instances (optional). + * + * @param {Function} CopyConstructor Constructor that can be used to reset. + * @param {Function} pooler Customizable pooler. + */ +var addPoolingTo = function(CopyConstructor, pooler) { + var NewKlass = CopyConstructor; + NewKlass.instancePool = []; + NewKlass.getPooled = pooler || DEFAULT_POOLER; + if (!NewKlass.poolSize) { + NewKlass.poolSize = DEFAULT_POOL_SIZE; + } + NewKlass.release = standardReleaser; + return NewKlass; +}; + +var PooledClass = { + addPoolingTo: addPoolingTo, + oneArgumentPooler: oneArgumentPooler, + twoArgumentPooler: twoArgumentPooler, + threeArgumentPooler: threeArgumentPooler, + fiveArgumentPooler: fiveArgumentPooler +}; + +module.exports = PooledClass; +}); +__d('invariant',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 invariant + */ + +"use strict"; + +/** + * Use invariant() to assert state which your program assumes to be true. + * + * Provide sprintf-style format (only %s is supported) and arguments + * to provide information about what broke and what you were + * expecting. + * + * The invariant message will be stripped in production, but the invariant + * will remain to ensure logic does not differ in production. + */ + +var invariant = function(condition, format, a, b, c, d, e, f) { + if (__DEV__) { + if (format === undefined) { + throw new Error('invariant requires an error message argument'); + } + } + + if (!condition) { + var error; + if (format === undefined) { + error = new Error( + 'Minified exception occurred; use the non-minified dev environment ' + + 'for the full error message and additional helpful warnings.' + ); + } else { + var args = [a, b, c, d, e, f]; + var argIndex = 0; + error = new Error( + 'Invariant Violation: ' + + format.replace(/%s/g, function() { return args[argIndex++]; }) + ); + } + + error.framesToPop = 1; // we don't care about invariant's own frame + throw error; + } +}; + +module.exports = invariant; +}); +__d('ReactFragment',["ReactElement","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2015, 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 ReactFragment +*/ + +'use strict'; + +var ReactElement = require('ReactElement'); + +var warning = require('warning'); + +/** + * We used to allow keyed objects to serve as a collection of ReactElements, + * or nested sets. This allowed us a way to explicitly key a set a fragment of + * components. This is now being replaced with an opaque data structure. + * The upgrade path is to call React.addons.createFragment({ key: value }) to + * create a keyed fragment. The resulting data structure is opaque, for now. + */ + +if (__DEV__) { + var fragmentKey = '_reactFragment'; + var didWarnKey = '_reactDidWarn'; + var canWarnForReactFragment = false; + + try { + // Feature test. Don't even try to issue this warning if we can't use + // enumerable: false. + + var dummy = function() { + return 1; + }; + + Object.defineProperty( + {}, + fragmentKey, + {enumerable: false, value: true} + ); + + Object.defineProperty( + {}, + 'key', + {enumerable: true, get: dummy} + ); + + canWarnForReactFragment = true; + } catch (x) { } + + var proxyPropertyAccessWithWarning = function(obj, key) { + Object.defineProperty(obj, key, { + enumerable: true, + get: function() { + warning( + this[didWarnKey], + 'A ReactFragment is an opaque type. Accessing any of its ' + + 'properties is deprecated. Pass it to one of the React.Children ' + + 'helpers.' + ); + this[didWarnKey] = true; + return this[fragmentKey][key]; + }, + set: function(value) { + warning( + this[didWarnKey], + 'A ReactFragment is an immutable opaque type. Mutating its ' + + 'properties is deprecated.' + ); + this[didWarnKey] = true; + this[fragmentKey][key] = value; + } + }); + }; + + var issuedWarnings = {}; + + var didWarnForFragment = function(fragment) { + // We use the keys and the type of the value as a heuristic to dedupe the + // warning to avoid spamming too much. + var fragmentCacheKey = ''; + for (var key in fragment) { + fragmentCacheKey += key + ':' + (typeof fragment[key]) + ','; + } + var alreadyWarnedOnce = !!issuedWarnings[fragmentCacheKey]; + issuedWarnings[fragmentCacheKey] = true; + return alreadyWarnedOnce; + }; +} + +var ReactFragment = { + // Wrap a keyed object in an opaque proxy that warns you if you access any + // of its properties. + create: function(object) { + if (__DEV__) { + if (typeof object !== 'object' || !object || Array.isArray(object)) { + warning( + false, + 'React.addons.createFragment only accepts a single object.', + object + ); + return object; + } + if (ReactElement.isValidElement(object)) { + warning( + false, + 'React.addons.createFragment does not accept a ReactElement ' + + 'without a wrapper object.' + ); + return object; + } + if (canWarnForReactFragment) { + var proxy = {}; + Object.defineProperty(proxy, fragmentKey, { + enumerable: false, + value: object + }); + Object.defineProperty(proxy, didWarnKey, { + writable: true, + enumerable: false, + value: false + }); + for (var key in object) { + proxyPropertyAccessWithWarning(proxy, key); + } + Object.preventExtensions(proxy); + return proxy; + } + } + return object; + }, + // Extract the original keyed object from the fragment opaque type. Warn if + // a plain object is passed here. + extract: function(fragment) { + if (__DEV__) { + if (canWarnForReactFragment) { + if (!fragment[fragmentKey]) { + warning( + didWarnForFragment(fragment), + 'Any use of a keyed object should be wrapped in ' + + 'React.addons.createFragment(object) before being passed as a ' + + 'child.' + ); + return fragment; + } + return fragment[fragmentKey]; + } + } + return fragment; + }, + // Check if this is a fragment and if so, extract the keyed object. If it + // is a fragment-like object, warn that it should be wrapped. Ignore if we + // can't determine what kind of object this is. + extractIfFragment: function(fragment) { + if (__DEV__) { + if (canWarnForReactFragment) { + // If it is the opaque type, return the keyed object. + if (fragment[fragmentKey]) { + return fragment[fragmentKey]; + } + // Otherwise, check each property if it has an element, if it does + // it is probably meant as a fragment, so we can warn early. Defer, + // the warning to extract. + for (var key in fragment) { + if (fragment.hasOwnProperty(key) && + ReactElement.isValidElement(fragment[key])) { + // This looks like a fragment object, we should provide an + // early warning. + return ReactFragment.extract(fragment); + } + } + } + } + return fragment; + } +}; + +module.exports = ReactFragment; +}); +__d('ReactElement',["ReactContext","ReactCurrentOwner","Object.assign","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2014-2015, 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 ReactElement + */ + +'use strict'; + +var ReactContext = require('ReactContext'); +var ReactCurrentOwner = require('ReactCurrentOwner'); + +var assign = require('Object.assign'); +var warning = require('warning'); + +var RESERVED_PROPS = { + key: true, + ref: true +}; + +/** + * Warn for mutations. + * + * @internal + * @param {object} object + * @param {string} key + */ +function defineWarningProperty(object, key) { + Object.defineProperty(object, key, { + + configurable: false, + enumerable: true, + + get: function() { + if (!this._store) { + return null; + } + return this._store[key]; + }, + + set: function(value) { + warning( + false, + 'Don\'t set the %s property of the React element. Instead, ' + + 'specify the correct value when initially creating the element.', + key + ); + this._store[key] = value; + } + + }); +} + +/** + * This is updated to true if the membrane is successfully created. + */ +var useMutationMembrane = false; + +/** + * Warn for mutations. + * + * @internal + * @param {object} element + */ +function defineMutationMembrane(prototype) { + try { + var pseudoFrozenProperties = { + props: true + }; + for (var key in pseudoFrozenProperties) { + defineWarningProperty(prototype, key); + } + useMutationMembrane = true; + } catch (x) { + // IE will fail on defineProperty + } +} + +/** + * Base constructor for all React elements. This is only used to make this + * work with a dynamic instanceof check. Nothing should live on this prototype. + * + * @param {*} type + * @param {string|object} ref + * @param {*} key + * @param {*} props + * @internal + */ +var ReactElement = function(type, key, ref, owner, context, props) { + // Built-in properties that belong on the element + this.type = type; + this.key = key; + this.ref = ref; + + // Record the component responsible for creating this element. + this._owner = owner; + + // TODO: Deprecate withContext, and then the context becomes accessible + // through the owner. + this._context = context; + + if (__DEV__) { + // The validation flag and props are currently mutative. We put them on + // an external backing store so that we can freeze the whole object. + // This can be replaced with a WeakMap once they are implemented in + // commonly used development environments. + this._store = {props: props, originalProps: assign({}, props)}; + + // To make comparing ReactElements easier for testing purposes, we make + // the validation flag non-enumerable (where possible, which should + // include every environment we run tests in), so the test framework + // ignores it. + try { + Object.defineProperty(this._store, 'validated', { + configurable: false, + enumerable: false, + writable: true + }); + } catch (x) { + } + this._store.validated = false; + + // We're not allowed to set props directly on the object so we early + // return and rely on the prototype membrane to forward to the backing + // store. + if (useMutationMembrane) { + Object.freeze(this); + return; + } + } + + this.props = props; +}; + +// We intentionally don't expose the function on the constructor property. +// ReactElement should be indistinguishable from a plain object. +ReactElement.prototype = { + _isReactElement: true +}; + +if (__DEV__) { + defineMutationMembrane(ReactElement.prototype); +} + +ReactElement.createElement = function(type, config, children) { + var propName; + + // Reserved names are extracted + var props = {}; + + var key = null; + var ref = null; + + if (config != null) { + ref = config.ref === undefined ? null : config.ref; + key = config.key === undefined ? null : '' + config.key; + // Remaining properties are added to a new props object + for (propName in config) { + if (config.hasOwnProperty(propName) && + !RESERVED_PROPS.hasOwnProperty(propName)) { + props[propName] = config[propName]; + } + } + } + + // Children can be more than one argument, and those are transferred onto + // the newly allocated props object. + var childrenLength = arguments.length - 2; + if (childrenLength === 1) { + props.children = children; + } else if (childrenLength > 1) { + var childArray = Array(childrenLength); + for (var i = 0; i < childrenLength; i++) { + childArray[i] = arguments[i + 2]; + } + props.children = childArray; + } + + // Resolve default props + if (type && type.defaultProps) { + var defaultProps = type.defaultProps; + for (propName in defaultProps) { + if (typeof props[propName] === 'undefined') { + props[propName] = defaultProps[propName]; + } + } + } + + return new ReactElement( + type, + key, + ref, + ReactCurrentOwner.current, + ReactContext.current, + props + ); +}; + +ReactElement.createFactory = function(type) { + var factory = ReactElement.createElement.bind(null, type); + // Expose the type on the factory and the prototype so that it can be + // easily accessed on elements. E.g. .type === Foo.type. + // This should not be named `constructor` since this may not be the function + // that created the element, and it may not even be a constructor. + // Legacy hook TODO: Warn if this is accessed + factory.type = type; + return factory; +}; + +ReactElement.cloneAndReplaceProps = function(oldElement, newProps) { + var newElement = new ReactElement( + oldElement.type, + oldElement.key, + oldElement.ref, + oldElement._owner, + oldElement._context, + newProps + ); + + if (__DEV__) { + // If the key on the original is valid, then the clone is valid + newElement._store.validated = oldElement._store.validated; + } + return newElement; +}; + +ReactElement.cloneElement = function(element, config, children) { + var propName; + + // Original props are copied + var props = assign({}, element.props); + + // Reserved names are extracted + var key = element.key; + var ref = element.ref; + + // Owner will be preserved, unless ref is overridden + var owner = element._owner; + + if (config != null) { + if (config.ref !== undefined) { + // Silently steal the ref from the parent. + ref = config.ref; + owner = ReactCurrentOwner.current; + } + if (config.key !== undefined) { + key = '' + config.key; + } + // Remaining properties override existing props + for (propName in config) { + if (config.hasOwnProperty(propName) && + !RESERVED_PROPS.hasOwnProperty(propName)) { + props[propName] = config[propName]; + } + } + } + + // Children can be more than one argument, and those are transferred onto + // the newly allocated props object. + var childrenLength = arguments.length - 2; + if (childrenLength === 1) { + props.children = children; + } else if (childrenLength > 1) { + var childArray = Array(childrenLength); + for (var i = 0; i < childrenLength; i++) { + childArray[i] = arguments[i + 2]; + } + props.children = childArray; + } + + return new ReactElement( + element.type, + key, + ref, + owner, + element._context, + props + ); +}; + +/** + * @param {?object} object + * @return {boolean} True if `object` is a valid component. + * @final + */ +ReactElement.isValidElement = function(object) { + // ReactTestUtils is often used outside of beforeEach where as React is + // within it. This leads to two different instances of React on the same + // page. To identify a element from a different React instance we use + // a flag instead of an instanceof check. + var isElement = !!(object && object._isReactElement); + // if (isElement && !(object instanceof ReactElement)) { + // This is an indicator that you're using multiple versions of React at the + // same time. This will screw with ownership and stuff. Fix it, please. + // TODO: We could possibly warn here. + // } + return isElement; +}; + +module.exports = ReactElement; +}); +__d('ReactContext',["Object.assign","emptyObject","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactContext + */ + +'use strict'; + +var assign = require('Object.assign'); +var emptyObject = require('emptyObject'); +var warning = require('warning'); + +var didWarn = false; + +/** + * Keeps track of the current context. + * + * The context is automatically passed down the component ownership hierarchy + * and is accessible via `this.context` on ReactCompositeComponents. + */ +var ReactContext = { + + /** + * @internal + * @type {object} + */ + current: emptyObject, + + /** + * Temporarily extends the current context while executing scopedCallback. + * + * A typical use case might look like + * + * render: function() { + * var children = ReactContext.withContext({foo: 'foo'}, () => ( + * + * )); + * return
{children}
; + * } + * + * @param {object} newContext New context to merge into the existing context + * @param {function} scopedCallback Callback to run with the new context + * @return {ReactComponent|array} + */ + withContext: function(newContext, scopedCallback) { + if (__DEV__) { + warning( + didWarn, + 'withContext is deprecated and will be removed in a future version. ' + + 'Use a wrapper component with getChildContext instead.' + ); + + didWarn = true; + } + + var result; + var previousContext = ReactContext.current; + ReactContext.current = assign({}, previousContext, newContext); + try { + result = scopedCallback(); + } finally { + ReactContext.current = previousContext; + } + return result; + } + +}; + +module.exports = ReactContext; +}); +__d('Object.assign',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2014-2015, 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 Object.assign + */ + +// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign + +'use strict'; + +function assign(target, sources) { + if (target == null) { + throw new TypeError('Object.assign target cannot be null or undefined'); + } + + var to = Object(target); + var hasOwnProperty = Object.prototype.hasOwnProperty; + + for (var nextIndex = 1; nextIndex < arguments.length; nextIndex++) { + var nextSource = arguments[nextIndex]; + if (nextSource == null) { + continue; + } + + var from = Object(nextSource); + + // We don't currently support accessors nor proxies. Therefore this + // copy cannot throw. If we ever supported this then we must handle + // exceptions and side-effects. We don't support symbols so they won't + // be transferred. + + for (var key in from) { + if (hasOwnProperty.call(from, key)) { + to[key] = from[key]; + } + } + } + + return to; +} + +module.exports = assign; +}); +__d('emptyObject',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 emptyObject + */ + +"use strict"; + +var emptyObject = {}; + +if (__DEV__) { + Object.freeze(emptyObject); +} + +module.exports = emptyObject; +}); +__d('warning',["emptyFunction"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2014-2015, 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 warning + */ + +"use strict"; + +var emptyFunction = require('emptyFunction'); + +/** + * Similar to invariant but only logs a warning if the condition is not met. + * This can be used to log issues in development environments in critical + * paths. Removing the logging code for production environments will keep the + * same logic and follow the same code paths. + */ + +var warning = emptyFunction; + +if (__DEV__) { + warning = function(condition, format ) {for (var args=[],$__0=2,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); + if (format === undefined) { + throw new Error( + '`warning(condition, format, ...args)` requires a warning ' + + 'message argument' + ); + } + + if (format.length < 10 || /^[s\W]*$/.test(format)) { + throw new Error( + 'The warning format should be able to uniquely identify this ' + + 'warning. Please, use a more descriptive format than: ' + format + ); + } + + if (format.indexOf('Failed Composite propType: ') === 0) { + return; // Ignore CompositeComponent proptype check. + } + + if (!condition) { + var argIndex = 0; + var message = 'Warning: ' + format.replace(/%s/g, function() {return args[argIndex++];}); + console.warn(message); + try { + // --- Welcome to debugging React --- + // This error was thrown as a convenience so that you can use this stack + // to find the callsite that caused this warning to fire. + throw new Error(message); + } catch(x) {} + } + }; +} + +module.exports = warning; +}); +__d('emptyFunction',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 emptyFunction + */ + +function makeEmptyFunction(arg) { + return function() { + return arg; + }; +} + +/** + * This function accepts and discards inputs; it has no side effects. This is + * primarily useful idiomatically for overridable function endpoints which + * always need to be callable, since JS lacks a null-call idiom ala Cocoa. + */ +function emptyFunction() {} + +emptyFunction.thatReturns = makeEmptyFunction; +emptyFunction.thatReturnsFalse = makeEmptyFunction(false); +emptyFunction.thatReturnsTrue = makeEmptyFunction(true); +emptyFunction.thatReturnsNull = makeEmptyFunction(null); +emptyFunction.thatReturnsThis = function() { return this; }; +emptyFunction.thatReturnsArgument = function(arg) { return arg; }; + +module.exports = emptyFunction; +}); +__d('ReactCurrentOwner',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactCurrentOwner + */ + +'use strict'; + +/** + * Keeps track of the current owner. + * + * The current owner is the component who should own any components that are + * currently being constructed. + * + * The depth indicate how many composite components are above this render level. + */ +var ReactCurrentOwner = { + + /** + * @internal + * @type {ReactComponent} + */ + current: null + +}; + +module.exports = ReactCurrentOwner; +}); +__d('traverseAllChildren',["ReactElement","ReactFragment","ReactInstanceHandles","getIteratorFn","invariant","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 traverseAllChildren + */ + +'use strict'; + +var ReactElement = require('ReactElement'); +var ReactFragment = require('ReactFragment'); +var ReactInstanceHandles = require('ReactInstanceHandles'); + +var getIteratorFn = require('getIteratorFn'); +var invariant = require('invariant'); +var warning = require('warning'); + +var SEPARATOR = ReactInstanceHandles.SEPARATOR; +var SUBSEPARATOR = ':'; + +/** + * TODO: Test that a single child and an array with one item have the same key + * pattern. + */ + +var userProvidedKeyEscaperLookup = { + '=': '=0', + '.': '=1', + ':': '=2' +}; + +var userProvidedKeyEscapeRegex = /[=.:]/g; + +var didWarnAboutMaps = false; + +function userProvidedKeyEscaper(match) { + return userProvidedKeyEscaperLookup[match]; +} + +/** + * Generate a key string that identifies a component within a set. + * + * @param {*} component A component that could contain a manual key. + * @param {number} index Index that is used if a manual key is not provided. + * @return {string} + */ +function getComponentKey(component, index) { + if (component && component.key != null) { + // Explicit key + return wrapUserProvidedKey(component.key); + } + // Implicit key determined by the index in the set + return index.toString(36); +} + +/** + * Escape a component key so that it is safe to use in a reactid. + * + * @param {*} key Component key to be escaped. + * @return {string} An escaped string. + */ +function escapeUserProvidedKey(text) { + return ('' + text).replace( + userProvidedKeyEscapeRegex, + userProvidedKeyEscaper + ); +} + +/** + * Wrap a `key` value explicitly provided by the user to distinguish it from + * implicitly-generated keys generated by a component's index in its parent. + * + * @param {string} key Value of a user-provided `key` attribute + * @return {string} + */ +function wrapUserProvidedKey(key) { + return '$' + escapeUserProvidedKey(key); +} + +/** + * @param {?*} children Children tree container. + * @param {!string} nameSoFar Name of the key path so far. + * @param {!number} indexSoFar Number of children encountered until this point. + * @param {!function} callback Callback to invoke with each child found. + * @param {?*} traverseContext Used to pass information throughout the traversal + * process. + * @return {!number} The number of children in this subtree. + */ +function traverseAllChildrenImpl( + children, + nameSoFar, + indexSoFar, + callback, + traverseContext +) { + var type = typeof children; + + if (type === 'undefined' || type === 'boolean') { + // All of the above are perceived as null. + children = null; + } + + if (children === null || + type === 'string' || + type === 'number' || + ReactElement.isValidElement(children)) { + callback( + traverseContext, + children, + // If it's the only child, treat the name as if it was wrapped in an array + // so that it's consistent if the number of children grows. + nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar, + indexSoFar + ); + return 1; + } + + var child, nextName, nextIndex; + var subtreeCount = 0; // Count of children found in the current subtree. + + if (Array.isArray(children)) { + for (var i = 0; i < children.length; i++) { + child = children[i]; + nextName = ( + (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + + getComponentKey(child, i) + ); + nextIndex = indexSoFar + subtreeCount; + subtreeCount += traverseAllChildrenImpl( + child, + nextName, + nextIndex, + callback, + traverseContext + ); + } + } else { + var iteratorFn = getIteratorFn(children); + if (iteratorFn) { + var iterator = iteratorFn.call(children); + var step; + if (iteratorFn !== children.entries) { + var ii = 0; + while (!(step = iterator.next()).done) { + child = step.value; + nextName = ( + (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + + getComponentKey(child, ii++) + ); + nextIndex = indexSoFar + subtreeCount; + subtreeCount += traverseAllChildrenImpl( + child, + nextName, + nextIndex, + callback, + traverseContext + ); + } + } else { + if (__DEV__) { + warning( + didWarnAboutMaps, + 'Using Maps as children is not yet fully supported. It is an ' + + 'experimental feature that might be removed. Convert it to a ' + + 'sequence / iterable of keyed ReactElements instead.' + ); + didWarnAboutMaps = true; + } + // Iterator will provide entry [k,v] tuples rather than values. + while (!(step = iterator.next()).done) { + var entry = step.value; + if (entry) { + child = entry[1]; + nextName = ( + (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + + wrapUserProvidedKey(entry[0]) + SUBSEPARATOR + + getComponentKey(child, 0) + ); + nextIndex = indexSoFar + subtreeCount; + subtreeCount += traverseAllChildrenImpl( + child, + nextName, + nextIndex, + callback, + traverseContext + ); + } + } + } + } else if (type === 'object') { + invariant( + children.nodeType !== 1, + 'traverseAllChildren(...): Encountered an invalid child; DOM ' + + 'elements are not valid children of React components.' + ); + var fragment = ReactFragment.extract(children); + for (var key in fragment) { + if (fragment.hasOwnProperty(key)) { + child = fragment[key]; + nextName = ( + (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + + wrapUserProvidedKey(key) + SUBSEPARATOR + + getComponentKey(child, 0) + ); + nextIndex = indexSoFar + subtreeCount; + subtreeCount += traverseAllChildrenImpl( + child, + nextName, + nextIndex, + callback, + traverseContext + ); + } + } + } + } + + return subtreeCount; +} + +/** + * Traverses children that are typically specified as `props.children`, but + * might also be specified through attributes: + * + * - `traverseAllChildren(this.props.children, ...)` + * - `traverseAllChildren(this.props.leftPanelChildren, ...)` + * + * The `traverseContext` is an optional argument that is passed through the + * entire traversal. It can be used to store accumulations or anything else that + * the callback might find relevant. + * + * @param {?*} children Children tree object. + * @param {!function} callback To invoke upon traversing each child. + * @param {?*} traverseContext Context for traversal. + * @return {!number} The number of children in this subtree. + */ +function traverseAllChildren(children, callback, traverseContext) { + if (children == null) { + return 0; + } + + return traverseAllChildrenImpl(children, '', 0, callback, traverseContext); +} + +module.exports = traverseAllChildren; +}); +__d('ReactInstanceHandles',["ReactRootIndex","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2014 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @providesModule ReactInstanceHandles + * @typechecks static-only + */ + +"use strict"; + +var ReactRootIndex = require('ReactRootIndex'); + +var invariant = require('invariant'); + +var SEPARATOR = '.'; +var SEPARATOR_LENGTH = SEPARATOR.length; + +/** + * Maximum depth of traversals before we consider the possibility of a bad ID. + */ +var MAX_TREE_DEPTH = 100; + +/** + * Creates a DOM ID prefix to use when mounting React components. + * + * @param {number} index A unique integer + * @return {string} React root ID. + * @internal + */ +function getReactRootIDString(index) { + return SEPARATOR + index.toString(36); +} + +/** + * Checks if a character in the supplied ID is a separator or the end. + * + * @param {string} id A React DOM ID. + * @param {number} index Index of the character to check. + * @return {boolean} True if the character is a separator or end of the ID. + * @private + */ +function isBoundary(id, index) { + return id.charAt(index) === SEPARATOR || index === id.length; +} + +/** + * Checks if the supplied string is a valid React DOM ID. + * + * @param {string} id A React DOM ID, maybe. + * @return {boolean} True if the string is a valid React DOM ID. + * @private + */ +function isValidID(id) { + return id === '' || ( + id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR + ); +} + +/** + * Checks if the first ID is an ancestor of or equal to the second ID. + * + * @param {string} ancestorID + * @param {string} descendantID + * @return {boolean} True if `ancestorID` is an ancestor of `descendantID`. + * @internal + */ +function isAncestorIDOf(ancestorID, descendantID) { + return ( + descendantID.indexOf(ancestorID) === 0 && + isBoundary(descendantID, ancestorID.length) + ); +} + +/** + * Gets the parent ID of the supplied React DOM ID, `id`. + * + * @param {string} id ID of a component. + * @return {string} ID of the parent, or an empty string. + * @private + */ +function getParentID(id) { + return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : ''; +} + +/** + * Gets the next DOM ID on the tree path from the supplied `ancestorID` to the + * supplied `destinationID`. If they are equal, the ID is returned. + * + * @param {string} ancestorID ID of an ancestor node of `destinationID`. + * @param {string} destinationID ID of the destination node. + * @return {string} Next ID on the path from `ancestorID` to `destinationID`. + * @private + */ +function getNextDescendantID(ancestorID, destinationID) { + invariant( + isValidID(ancestorID) && isValidID(destinationID), + 'getNextDescendantID(%s, %s): Received an invalid React DOM ID.', + ancestorID, + destinationID + ); + invariant( + isAncestorIDOf(ancestorID, destinationID), + 'getNextDescendantID(...): React has made an invalid assumption about ' + + 'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.', + ancestorID, + destinationID + ); + if (ancestorID === destinationID) { + return ancestorID; + } + // Skip over the ancestor and the immediate separator. Traverse until we hit + // another separator or we reach the end of `destinationID`. + var start = ancestorID.length + SEPARATOR_LENGTH; + for (var i = start; i < destinationID.length; i++) { + if (isBoundary(destinationID, i)) { + break; + } + } + return destinationID.substr(0, i); +} + +/** + * Gets the nearest common ancestor ID of two IDs. + * + * Using this ID scheme, the nearest common ancestor ID is the longest common + * prefix of the two IDs that immediately preceded a "marker" in both strings. + * + * @param {string} oneID + * @param {string} twoID + * @return {string} Nearest common ancestor ID, or the empty string if none. + * @private + */ +function getFirstCommonAncestorID(oneID, twoID) { + var minLength = Math.min(oneID.length, twoID.length); + if (minLength === 0) { + return ''; + } + var lastCommonMarkerIndex = 0; + // Use `<=` to traverse until the "EOL" of the shorter string. + for (var i = 0; i <= minLength; i++) { + if (isBoundary(oneID, i) && isBoundary(twoID, i)) { + lastCommonMarkerIndex = i; + } else if (oneID.charAt(i) !== twoID.charAt(i)) { + break; + } + } + var longestCommonID = oneID.substr(0, lastCommonMarkerIndex); + invariant( + isValidID(longestCommonID), + 'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s', + oneID, + twoID, + longestCommonID + ); + return longestCommonID; +} + +/** + * Traverses the parent path between two IDs (either up or down). The IDs must + * not be the same, and there must exist a parent path between them. If the + * callback returns `false`, traversal is stopped. + * + * @param {?string} start ID at which to start traversal. + * @param {?string} stop ID at which to end traversal. + * @param {function} cb Callback to invoke each ID with. + * @param {?boolean} skipFirst Whether or not to skip the first node. + * @param {?boolean} skipLast Whether or not to skip the last node. + * @private + */ +function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) { + start = start || ''; + stop = stop || ''; + invariant( + start !== stop, + 'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.', + start + ); + var traverseUp = isAncestorIDOf(stop, start); + invariant( + traverseUp || isAncestorIDOf(start, stop), + 'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' + + 'not have a parent path.', + start, + stop + ); + // Traverse from `start` to `stop` one depth at a time. + var depth = 0; + var traverse = traverseUp ? getParentID : getNextDescendantID; + for (var id = start; /* until break */; id = traverse(id, stop)) { + var ret; + if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) { + ret = cb(id, traverseUp, arg); + } + if (ret === false || id === stop) { + // Only break //after// visiting `stop`. + break; + } + invariant( + depth++ < MAX_TREE_DEPTH, + 'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' + + 'traversing the React DOM ID tree. This may be due to malformed IDs: %s', + start, stop + ); + } +} + +/** + * Manages the IDs assigned to DOM representations of React components. This + * uses a specific scheme in order to traverse the DOM efficiently (e.g. in + * order to simulate events). + * + * @internal + */ +var ReactInstanceHandles = { + + /** + * Constructs a React root ID + * @return {string} A React root ID. + */ + createReactRootID: function() { + return getReactRootIDString(ReactRootIndex.createReactRootIndex()); + }, + + /** + * Constructs a React ID by joining a root ID with a name. + * + * @param {string} rootID Root ID of a parent component. + * @param {string} name A component's name (as flattened children). + * @return {string} A React ID. + * @internal + */ + createReactID: function(rootID, name) { + return rootID + name; + }, + + /** + * Gets the DOM ID of the React component that is the root of the tree that + * contains the React component with the supplied DOM ID. + * + * @param {string} id DOM ID of a React component. + * @return {?string} DOM ID of the React component that is the root. + * @internal + */ + getReactRootIDFromNodeID: function(id) { + if (id && id.charAt(0) === SEPARATOR && id.length > 1) { + var index = id.indexOf(SEPARATOR, 1); + return index > -1 ? id.substr(0, index) : id; + } + return null; + }, + + /** + * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that + * should would receive a `mouseEnter` or `mouseLeave` event. + * + * NOTE: Does not invoke the callback on the nearest common ancestor because + * nothing "entered" or "left" that element. + * + * @param {string} leaveID ID being left. + * @param {string} enterID ID being entered. + * @param {function} cb Callback to invoke on each entered/left ID. + * @param {*} upArg Argument to invoke the callback with on left IDs. + * @param {*} downArg Argument to invoke the callback with on entered IDs. + * @internal + */ + traverseEnterLeave: function(leaveID, enterID, cb, upArg, downArg) { + var ancestorID = getFirstCommonAncestorID(leaveID, enterID); + if (ancestorID !== leaveID) { + traverseParentPath(leaveID, ancestorID, cb, upArg, false, true); + } + if (ancestorID !== enterID) { + traverseParentPath(ancestorID, enterID, cb, downArg, true, false); + } + }, + + /** + * Simulates the traversal of a two-phase, capture/bubble event dispatch. + * + * NOTE: This traversal happens on IDs without touching the DOM. + * + * @param {string} targetID ID of the target node. + * @param {function} cb Callback to invoke. + * @param {*} arg Argument to invoke the callback with. + * @internal + */ + traverseTwoPhase: function(targetID, cb, arg) { + if (targetID) { + traverseParentPath('', targetID, cb, arg, true, false); + traverseParentPath(targetID, '', cb, arg, false, true); + } + }, + + /** + * Same as `traverseTwoPhase` but skips the `targetID`. + */ + traverseTwoPhaseSkipTarget: function(targetID, cb, arg) { + if (targetID) { + traverseParentPath('', targetID, cb, arg, true, true); + traverseParentPath(targetID, '', cb, arg, true, true); + } + }, + + /** + * Traverse a node ID, calling the supplied `cb` for each ancestor ID. For + * example, passing `.0.$row-0.1` would result in `cb` getting called + * with `.0`, `.0.$row-0`, and `.0.$row-0.1`. + * + * NOTE: This traversal happens on IDs without touching the DOM. + * + * @param {string} targetID ID of the target node. + * @param {function} cb Callback to invoke. + * @param {*} arg Argument to invoke the callback with. + * @internal + */ + traverseAncestors: function(targetID, cb, arg) { + traverseParentPath('', targetID, cb, arg, true, false); + }, + + /** + * Exposed for unit testing. + * @private + */ + _getFirstCommonAncestorID: getFirstCommonAncestorID, + + /** + * Exposed for unit testing. + * @private + */ + _getNextDescendantID: getNextDescendantID, + + isAncestorIDOf: isAncestorIDOf, + + SEPARATOR: SEPARATOR + +}; + +module.exports = ReactInstanceHandles; +}); +__d('ReactRootIndex',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactRootIndex + * @typechecks + */ + +'use strict'; + +var ReactRootIndexInjection = { + /** + * @param {function} _createReactRootIndex + */ + injectCreateReactRootIndex: function(_createReactRootIndex) { + ReactRootIndex.createReactRootIndex = _createReactRootIndex; + } +}; + +var ReactRootIndex = { + createReactRootIndex: null, + injection: ReactRootIndexInjection +}; + +module.exports = ReactRootIndex; +}); +__d('getIteratorFn',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 getIteratorFn + * @typechecks static-only + */ + +'use strict'; + +/* global Symbol */ +var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; +var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. + +/** + * Returns the iterator method function contained on the iterable object. + * + * Be sure to invoke the function with the iterable as context: + * + * var iteratorFn = getIteratorFn(myIterable); + * if (iteratorFn) { + * var iterator = iteratorFn.call(myIterable); + * ... + * } + * + * @param {?object} maybeIterable + * @return {?function} + */ +function getIteratorFn(maybeIterable) { + var iteratorFn = maybeIterable && ( + (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL]) || + maybeIterable[FAUX_ITERATOR_SYMBOL] + ); + if (typeof iteratorFn === 'function') { + return iteratorFn; + } +} + +module.exports = getIteratorFn; +}); +__d('ReactClass',["ReactComponent","ReactCurrentOwner","ReactElement","ReactErrorUtils","ReactInstanceMap","ReactLifeCycle","ReactPropTypeLocations","ReactPropTypeLocationNames","ReactUpdateQueue","Object.assign","invariant","keyMirror","keyOf","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactClass + */ + +'use strict'; + +var ReactComponent = require('ReactComponent'); +var ReactCurrentOwner = require('ReactCurrentOwner'); +var ReactElement = require('ReactElement'); +var ReactErrorUtils = require('ReactErrorUtils'); +var ReactInstanceMap = require('ReactInstanceMap'); +var ReactLifeCycle = require('ReactLifeCycle'); +var ReactPropTypeLocations = require('ReactPropTypeLocations'); +var ReactPropTypeLocationNames = require('ReactPropTypeLocationNames'); +var ReactUpdateQueue = require('ReactUpdateQueue'); + +var assign = require('Object.assign'); +var invariant = require('invariant'); +var keyMirror = require('keyMirror'); +var keyOf = require('keyOf'); +var warning = require('warning'); + +var MIXINS_KEY = keyOf({mixins: null}); + +/** + * Policies that describe methods in `ReactClassInterface`. + */ +var SpecPolicy = keyMirror({ + /** + * These methods may be defined only once by the class specification or mixin. + */ + DEFINE_ONCE: null, + /** + * These methods may be defined by both the class specification and mixins. + * Subsequent definitions will be chained. These methods must return void. + */ + DEFINE_MANY: null, + /** + * These methods are overriding the base class. + */ + OVERRIDE_BASE: null, + /** + * These methods are similar to DEFINE_MANY, except we assume they return + * objects. We try to merge the keys of the return values of all the mixed in + * functions. If there is a key conflict we throw. + */ + DEFINE_MANY_MERGED: null +}); + + +var injectedMixins = []; + +/** + * Composite components are higher-level components that compose other composite + * or native components. + * + * To create a new type of `ReactClass`, pass a specification of + * your new class to `React.createClass`. The only requirement of your class + * specification is that you implement a `render` method. + * + * var MyComponent = React.createClass({ + * render: function() { + * return
Hello World
; + * } + * }); + * + * The class specification supports a specific protocol of methods that have + * special meaning (e.g. `render`). See `ReactClassInterface` for + * more the comprehensive protocol. Any other properties and methods in the + * class specification will available on the prototype. + * + * @interface ReactClassInterface + * @internal + */ +var ReactClassInterface = { + + /** + * An array of Mixin objects to include when defining your component. + * + * @type {array} + * @optional + */ + mixins: SpecPolicy.DEFINE_MANY, + + /** + * An object containing properties and methods that should be defined on + * the component's constructor instead of its prototype (static methods). + * + * @type {object} + * @optional + */ + statics: SpecPolicy.DEFINE_MANY, + + /** + * Definition of prop types for this component. + * + * @type {object} + * @optional + */ + propTypes: SpecPolicy.DEFINE_MANY, + + /** + * Definition of context types for this component. + * + * @type {object} + * @optional + */ + contextTypes: SpecPolicy.DEFINE_MANY, + + /** + * Definition of context types this component sets for its children. + * + * @type {object} + * @optional + */ + childContextTypes: SpecPolicy.DEFINE_MANY, + + // ==== Definition methods ==== + + /** + * Invoked when the component is mounted. Values in the mapping will be set on + * `this.props` if that prop is not specified (i.e. using an `in` check). + * + * This method is invoked before `getInitialState` and therefore cannot rely + * on `this.state` or use `this.setState`. + * + * @return {object} + * @optional + */ + getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED, + + /** + * Invoked once before the component is mounted. The return value will be used + * as the initial value of `this.state`. + * + * getInitialState: function() { + * return { + * isOn: false, + * fooBaz: new BazFoo() + * } + * } + * + * @return {object} + * @optional + */ + getInitialState: SpecPolicy.DEFINE_MANY_MERGED, + + /** + * @return {object} + * @optional + */ + getChildContext: SpecPolicy.DEFINE_MANY_MERGED, + + /** + * Uses props from `this.props` and state from `this.state` to render the + * structure of the component. + * + * No guarantees are made about when or how often this method is invoked, so + * it must not have side effects. + * + * render: function() { + * var name = this.props.name; + * return
Hello, {name}!
; + * } + * + * @return {ReactComponent} + * @nosideeffects + * @required + */ + render: SpecPolicy.DEFINE_ONCE, + + + + // ==== Delegate methods ==== + + /** + * Invoked when the component is initially created and about to be mounted. + * This may have side effects, but any external subscriptions or data created + * by this method must be cleaned up in `componentWillUnmount`. + * + * @optional + */ + componentWillMount: SpecPolicy.DEFINE_MANY, + + /** + * Invoked when the component has been mounted and has a DOM representation. + * However, there is no guarantee that the DOM node is in the document. + * + * Use this as an opportunity to operate on the DOM when the component has + * been mounted (initialized and rendered) for the first time. + * + * @param {DOMElement} rootNode DOM element representing the component. + * @optional + */ + componentDidMount: SpecPolicy.DEFINE_MANY, + + /** + * Invoked before the component receives new props. + * + * Use this as an opportunity to react to a prop transition by updating the + * state using `this.setState`. Current props are accessed via `this.props`. + * + * componentWillReceiveProps: function(nextProps, nextContext) { + * this.setState({ + * likesIncreasing: nextProps.likeCount > this.props.likeCount + * }); + * } + * + * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop + * transition may cause a state change, but the opposite is not true. If you + * need it, you are probably looking for `componentWillUpdate`. + * + * @param {object} nextProps + * @optional + */ + componentWillReceiveProps: SpecPolicy.DEFINE_MANY, + + /** + * Invoked while deciding if the component should be updated as a result of + * receiving new props, state and/or context. + * + * Use this as an opportunity to `return false` when you're certain that the + * transition to the new props/state/context will not require a component + * update. + * + * shouldComponentUpdate: function(nextProps, nextState, nextContext) { + * return !equal(nextProps, this.props) || + * !equal(nextState, this.state) || + * !equal(nextContext, this.context); + * } + * + * @param {object} nextProps + * @param {?object} nextState + * @param {?object} nextContext + * @return {boolean} True if the component should update. + * @optional + */ + shouldComponentUpdate: SpecPolicy.DEFINE_ONCE, + + /** + * Invoked when the component is about to update due to a transition from + * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState` + * and `nextContext`. + * + * Use this as an opportunity to perform preparation before an update occurs. + * + * NOTE: You **cannot** use `this.setState()` in this method. + * + * @param {object} nextProps + * @param {?object} nextState + * @param {?object} nextContext + * @param {ReactReconcileTransaction} transaction + * @optional + */ + componentWillUpdate: SpecPolicy.DEFINE_MANY, + + /** + * Invoked when the component's DOM representation has been updated. + * + * Use this as an opportunity to operate on the DOM when the component has + * been updated. + * + * @param {object} prevProps + * @param {?object} prevState + * @param {?object} prevContext + * @param {DOMElement} rootNode DOM element representing the component. + * @optional + */ + componentDidUpdate: SpecPolicy.DEFINE_MANY, + + /** + * Invoked when the component is about to be removed from its parent and have + * its DOM representation destroyed. + * + * Use this as an opportunity to deallocate any external resources. + * + * NOTE: There is no `componentDidUnmount` since your component will have been + * destroyed by that point. + * + * @optional + */ + componentWillUnmount: SpecPolicy.DEFINE_MANY, + + + + // ==== Advanced methods ==== + + /** + * Updates the component's currently mounted DOM representation. + * + * By default, this implements React's rendering and reconciliation algorithm. + * Sophisticated clients may wish to override this. + * + * @param {ReactReconcileTransaction} transaction + * @internal + * @overridable + */ + updateComponent: SpecPolicy.OVERRIDE_BASE + +}; + +/** + * Mapping from class specification keys to special processing functions. + * + * Although these are declared like instance properties in the specification + * when defining classes using `React.createClass`, they are actually static + * and are accessible on the constructor instead of the prototype. Despite + * being static, they must be defined outside of the "statics" key under + * which all other static methods are defined. + */ +var RESERVED_SPEC_KEYS = { + displayName: function(Constructor, displayName) { + Constructor.displayName = displayName; + }, + mixins: function(Constructor, mixins) { + if (mixins) { + for (var i = 0; i < mixins.length; i++) { + mixSpecIntoComponent(Constructor, mixins[i]); + } + } + }, + childContextTypes: function(Constructor, childContextTypes) { + if (__DEV__) { + validateTypeDef( + Constructor, + childContextTypes, + ReactPropTypeLocations.childContext + ); + } + Constructor.childContextTypes = assign( + {}, + Constructor.childContextTypes, + childContextTypes + ); + }, + contextTypes: function(Constructor, contextTypes) { + if (__DEV__) { + validateTypeDef( + Constructor, + contextTypes, + ReactPropTypeLocations.context + ); + } + Constructor.contextTypes = assign( + {}, + Constructor.contextTypes, + contextTypes + ); + }, + /** + * Special case getDefaultProps which should move into statics but requires + * automatic merging. + */ + getDefaultProps: function(Constructor, getDefaultProps) { + if (Constructor.getDefaultProps) { + Constructor.getDefaultProps = createMergedResultFunction( + Constructor.getDefaultProps, + getDefaultProps + ); + } else { + Constructor.getDefaultProps = getDefaultProps; + } + }, + propTypes: function(Constructor, propTypes) { + if (__DEV__) { + validateTypeDef( + Constructor, + propTypes, + ReactPropTypeLocations.prop + ); + } + Constructor.propTypes = assign( + {}, + Constructor.propTypes, + propTypes + ); + }, + statics: function(Constructor, statics) { + mixStaticSpecIntoComponent(Constructor, statics); + } +}; + +function validateTypeDef(Constructor, typeDef, location) { + for (var propName in typeDef) { + if (typeDef.hasOwnProperty(propName)) { + // use a warning instead of an invariant so components + // don't show up in prod but not in __DEV__ + warning( + typeof typeDef[propName] === 'function', + '%s: %s type `%s` is invalid; it must be a function, usually from ' + + 'React.PropTypes.', + Constructor.displayName || 'ReactClass', + ReactPropTypeLocationNames[location], + propName + ); + } + } +} + +function validateMethodOverride(proto, name) { + var specPolicy = ReactClassInterface.hasOwnProperty(name) ? + ReactClassInterface[name] : + null; + + // Disallow overriding of base class methods unless explicitly allowed. + if (ReactClassMixin.hasOwnProperty(name)) { + invariant( + specPolicy === SpecPolicy.OVERRIDE_BASE, + 'ReactClassInterface: You are attempting to override ' + + '`%s` from your class specification. Ensure that your method names ' + + 'do not overlap with React methods.', + name + ); + } + + // Disallow defining methods more than once unless explicitly allowed. + if (proto.hasOwnProperty(name)) { + invariant( + specPolicy === SpecPolicy.DEFINE_MANY || + specPolicy === SpecPolicy.DEFINE_MANY_MERGED, + 'ReactClassInterface: You are attempting to define ' + + '`%s` on your component more than once. This conflict may be due ' + + 'to a mixin.', + name + ); + } +} + +/** + * Mixin helper which handles policy validation and reserved + * specification keys when building React classses. + */ +function mixSpecIntoComponent(Constructor, spec) { + if (!spec) { + return; + } + + invariant( + typeof spec !== 'function', + 'ReactClass: You\'re attempting to ' + + 'use a component class as a mixin. Instead, just use a regular object.' + ); + invariant( + !ReactElement.isValidElement(spec), + 'ReactClass: You\'re attempting to ' + + 'use a component as a mixin. Instead, just use a regular object.' + ); + + var proto = Constructor.prototype; + + // By handling mixins before any other properties, we ensure the same + // chaining order is applied to methods with DEFINE_MANY policy, whether + // mixins are listed before or after these methods in the spec. + if (spec.hasOwnProperty(MIXINS_KEY)) { + RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins); + } + + for (var name in spec) { + if (!spec.hasOwnProperty(name)) { + continue; + } + + if (name === MIXINS_KEY) { + // We have already handled mixins in a special case above + continue; + } + + var property = spec[name]; + validateMethodOverride(proto, name); + + if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) { + RESERVED_SPEC_KEYS[name](Constructor, property); + } else { + // Setup methods on prototype: + // The following member methods should not be automatically bound: + // 1. Expected ReactClass methods (in the "interface"). + // 2. Overridden methods (that were mixed in). + var isReactClassMethod = + ReactClassInterface.hasOwnProperty(name); + var isAlreadyDefined = proto.hasOwnProperty(name); + var markedDontBind = property && property.__reactDontBind; + var isFunction = typeof property === 'function'; + var shouldAutoBind = + isFunction && + !isReactClassMethod && + !isAlreadyDefined && + !markedDontBind; + + if (shouldAutoBind) { + if (!proto.__reactAutoBindMap) { + proto.__reactAutoBindMap = {}; + } + proto.__reactAutoBindMap[name] = property; + proto[name] = property; + } else { + if (isAlreadyDefined) { + var specPolicy = ReactClassInterface[name]; + + // These cases should already be caught by validateMethodOverride + invariant( + isReactClassMethod && ( + specPolicy === SpecPolicy.DEFINE_MANY_MERGED || + specPolicy === SpecPolicy.DEFINE_MANY + ), + 'ReactClass: Unexpected spec policy %s for key %s ' + + 'when mixing in component specs.', + specPolicy, + name + ); + + // For methods which are defined more than once, call the existing + // methods before calling the new property, merging if appropriate. + if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) { + proto[name] = createMergedResultFunction(proto[name], property); + } else if (specPolicy === SpecPolicy.DEFINE_MANY) { + proto[name] = createChainedFunction(proto[name], property); + } + } else { + proto[name] = property; + if (__DEV__) { + // Add verbose displayName to the function, which helps when looking + // at profiling tools. + if (typeof property === 'function' && spec.displayName) { + proto[name].displayName = spec.displayName + '_' + name; + } + } + } + } + } + } +} + +function mixStaticSpecIntoComponent(Constructor, statics) { + if (!statics) { + return; + } + for (var name in statics) { + var property = statics[name]; + if (!statics.hasOwnProperty(name)) { + continue; + } + + var isReserved = name in RESERVED_SPEC_KEYS; + invariant( + !isReserved, + 'ReactClass: You are attempting to define a reserved ' + + 'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' + + 'as an instance property instead; it will still be accessible on the ' + + 'constructor.', + name + ); + + var isInherited = name in Constructor; + invariant( + !isInherited, + 'ReactClass: You are attempting to define ' + + '`%s` on your component more than once. This conflict may be ' + + 'due to a mixin.', + name + ); + Constructor[name] = property; + } +} + +/** + * Merge two objects, but throw if both contain the same key. + * + * @param {object} one The first object, which is mutated. + * @param {object} two The second object + * @return {object} one after it has been mutated to contain everything in two. + */ +function mergeIntoWithNoDuplicateKeys(one, two) { + invariant( + one && two && typeof one === 'object' && typeof two === 'object', + 'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.' + ); + + for (var key in two) { + if (two.hasOwnProperty(key)) { + invariant( + one[key] === undefined, + 'mergeIntoWithNoDuplicateKeys(): ' + + 'Tried to merge two objects with the same key: `%s`. This conflict ' + + 'may be due to a mixin; in particular, this may be caused by two ' + + 'getInitialState() or getDefaultProps() methods returning objects ' + + 'with clashing keys.', + key + ); + one[key] = two[key]; + } + } + return one; +} + +/** + * Creates a function that invokes two functions and merges their return values. + * + * @param {function} one Function to invoke first. + * @param {function} two Function to invoke second. + * @return {function} Function that invokes the two argument functions. + * @private + */ +function createMergedResultFunction(one, two) { + return function mergedResult() { + var a = one.apply(this, arguments); + var b = two.apply(this, arguments); + if (a == null) { + return b; + } else if (b == null) { + return a; + } + var c = {}; + mergeIntoWithNoDuplicateKeys(c, a); + mergeIntoWithNoDuplicateKeys(c, b); + return c; + }; +} + +/** + * Creates a function that invokes two functions and ignores their return vales. + * + * @param {function} one Function to invoke first. + * @param {function} two Function to invoke second. + * @return {function} Function that invokes the two argument functions. + * @private + */ +function createChainedFunction(one, two) { + return function chainedFunction() { + one.apply(this, arguments); + two.apply(this, arguments); + }; +} + +/** + * Binds a method to the component. + * + * @param {object} component Component whose method is going to be bound. + * @param {function} method Method to be bound. + * @return {function} The bound method. + */ +function bindAutoBindMethod(component, method) { + var boundMethod = method.bind(component); + if (__DEV__) { + boundMethod.__reactBoundContext = component; + boundMethod.__reactBoundMethod = method; + boundMethod.__reactBoundArguments = null; + var componentName = component.constructor.displayName; + var _bind = boundMethod.bind; + /* eslint-disable block-scoped-var, no-undef */ + boundMethod.bind = function(newThis ) {for (var args=[],$__0=1,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); + // User is trying to bind() an autobound method; we effectively will + // ignore the value of "this" that the user is trying to use, so + // let's warn. + if (newThis !== component && newThis !== null) { + warning( + false, + 'bind(): React component methods may only be bound to the ' + + 'component instance. See %s', + componentName + ); + } else if (!args.length) { + warning( + false, + 'bind(): You are binding a component method to the component. ' + + 'React does this for you automatically in a high-performance ' + + 'way, so you can safely remove this call. See %s', + componentName + ); + return boundMethod; + } + var reboundMethod = _bind.apply(boundMethod, arguments); + reboundMethod.__reactBoundContext = component; + reboundMethod.__reactBoundMethod = method; + reboundMethod.__reactBoundArguments = args; + return reboundMethod; + /* eslint-enable */ + }; + } + return boundMethod; +} + +/** + * Binds all auto-bound methods in a component. + * + * @param {object} component Component whose method is going to be bound. + */ +function bindAutoBindMethods(component) { + for (var autoBindKey in component.__reactAutoBindMap) { + if (component.__reactAutoBindMap.hasOwnProperty(autoBindKey)) { + var method = component.__reactAutoBindMap[autoBindKey]; + component[autoBindKey] = bindAutoBindMethod( + component, + ReactErrorUtils.guard( + method, + component.constructor.displayName + '.' + autoBindKey + ) + ); + } + } +} + +var typeDeprecationDescriptor = { + enumerable: false, + get: function() { + var displayName = this.displayName || this.name || 'Component'; + warning( + false, + '%s.type is deprecated. Use %s directly to access the class.', + displayName, + displayName + ); + Object.defineProperty(this, 'type', { + value: this + }); + return this; + } +}; + +/** + * Add more to the ReactClass base class. These are all legacy features and + * therefore not already part of the modern ReactComponent. + */ +var ReactClassMixin = { + + /** + * TODO: This will be deprecated because state should always keep a consistent + * type signature and the only use case for this, is to avoid that. + */ + replaceState: function(newState, callback) { + ReactUpdateQueue.enqueueReplaceState(this, newState); + if (callback) { + ReactUpdateQueue.enqueueCallback(this, callback); + } + }, + + /** + * Checks whether or not this composite component is mounted. + * @return {boolean} True if mounted, false otherwise. + * @protected + * @final + */ + isMounted: function() { + if (__DEV__) { + var owner = ReactCurrentOwner.current; + if (owner !== null) { + warning( + owner._warnedAboutRefsInRender, + '%s is accessing isMounted inside its render() function. ' + + 'render() should be a pure function of props and state. It should ' + + 'never access something that requires stale data from the previous ' + + 'render, such as refs. Move this logic to componentDidMount and ' + + 'componentDidUpdate instead.', + owner.getName() || 'A component' + ); + owner._warnedAboutRefsInRender = true; + } + } + var internalInstance = ReactInstanceMap.get(this); + return ( + internalInstance && + internalInstance !== ReactLifeCycle.currentlyMountingInstance + ); + }, + + /** + * Sets a subset of the props. + * + * @param {object} partialProps Subset of the next props. + * @param {?function} callback Called after props are updated. + * @final + * @public + * @deprecated + */ + setProps: function(partialProps, callback) { + ReactUpdateQueue.enqueueSetProps(this, partialProps); + if (callback) { + ReactUpdateQueue.enqueueCallback(this, callback); + } + }, + + /** + * Replace all the props. + * + * @param {object} newProps Subset of the next props. + * @param {?function} callback Called after props are updated. + * @final + * @public + * @deprecated + */ + replaceProps: function(newProps, callback) { + ReactUpdateQueue.enqueueReplaceProps(this, newProps); + if (callback) { + ReactUpdateQueue.enqueueCallback(this, callback); + } + } +}; + +var ReactClassComponent = function() {}; +assign( + ReactClassComponent.prototype, + ReactComponent.prototype, + ReactClassMixin +); + +/** + * Module for creating composite components. + * + * @class ReactClass + */ +var ReactClass = { + + /** + * Creates a composite component class given a class specification. + * + * @param {object} spec Class specification (which must define `render`). + * @return {function} Component constructor function. + * @public + */ + createClass: function(spec) { + var Constructor = function(props, context) { + // This constructor is overridden by mocks. The argument is used + // by mocks to assert on what gets mounted. + + if (__DEV__) { + warning( + this instanceof Constructor, + 'Something is calling a React component directly. Use a factory or ' + + 'JSX instead. See: http://fb.me/react-legacyfactory' + ); + } + + // Wire up auto-binding + if (this.__reactAutoBindMap) { + bindAutoBindMethods(this); + } + + this.props = props; + this.context = context; + this.state = null; + + // ReactClasses doesn't have constructors. Instead, they use the + // getInitialState and componentWillMount methods for initialization. + + var initialState = this.getInitialState ? this.getInitialState() : null; + if (__DEV__) { + // We allow auto-mocks to proceed as if they're returning null. + if (typeof initialState === 'undefined' && + this.getInitialState._isMockFunction) { + // This is probably bad practice. Consider warning here and + // deprecating this convenience. + initialState = null; + } + } + invariant( + typeof initialState === 'object' && !Array.isArray(initialState), + '%s.getInitialState(): must return an object or null', + Constructor.displayName || 'ReactCompositeComponent' + ); + + this.state = initialState; + }; + Constructor.prototype = new ReactClassComponent(); + Constructor.prototype.constructor = Constructor; + + injectedMixins.forEach( + mixSpecIntoComponent.bind(null, Constructor) + ); + + mixSpecIntoComponent(Constructor, spec); + + // Initialize the defaultProps property after all mixins have been merged + if (Constructor.getDefaultProps) { + Constructor.defaultProps = Constructor.getDefaultProps(); + } + + if (__DEV__) { + // This is a tag to indicate that the use of these method names is ok, + // since it's used with createClass. If it's not, then it's likely a + // mistake so we'll warn you to use the static property, property + // initializer or constructor respectively. + if (Constructor.getDefaultProps) { + Constructor.getDefaultProps.isReactClassApproved = {}; + } + if (Constructor.prototype.getInitialState) { + Constructor.prototype.getInitialState.isReactClassApproved = {}; + } + } + + invariant( + Constructor.prototype.render, + 'createClass(...): Class specification must implement a `render` method.' + ); + + if (__DEV__) { + warning( + !Constructor.prototype.componentShouldUpdate, + '%s has a method called ' + + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + + 'The name is phrased as a question because the function is ' + + 'expected to return a value.', + spec.displayName || 'A component' + ); + } + + // Reduce time spent doing lookups by setting these on the prototype. + for (var methodName in ReactClassInterface) { + if (!Constructor.prototype[methodName]) { + Constructor.prototype[methodName] = null; + } + } + + // Legacy hook + Constructor.type = Constructor; + if (__DEV__) { + try { + Object.defineProperty(Constructor, 'type', typeDeprecationDescriptor); + } catch (x) { + // IE will fail on defineProperty (es5-shim/sham too) + } + } + + return Constructor; + }, + + injection: { + injectMixin: function(mixin) { + injectedMixins.push(mixin); + } + } + +}; + +module.exports = ReactClass; +}); +__d('ReactComponent',["ReactUpdateQueue","invariant","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactComponent + */ + +'use strict'; + +var ReactUpdateQueue = require('ReactUpdateQueue'); + +var invariant = require('invariant'); +var warning = require('warning'); + +/** + * Base class helpers for the updating state of a component. + */ +function ReactComponent(props, context) { + this.props = props; + this.context = context; +} + +/** + * Sets a subset of the state. Always use this to mutate + * state. You should treat `this.state` as immutable. + * + * There is no guarantee that `this.state` will be immediately updated, so + * accessing `this.state` after calling this method may return the old value. + * + * There is no guarantee that calls to `setState` will run synchronously, + * as they may eventually be batched together. You can provide an optional + * callback that will be executed when the call to setState is actually + * completed. + * + * When a function is provided to setState, it will be called at some point in + * the future (not synchronously). It will be called with the up to date + * component arguments (state, props, context). These values can be different + * from this.* because your function may be called after receiveProps but before + * shouldComponentUpdate, and this new state, props, and context will not yet be + * assigned to this. + * + * @param {object|function} partialState Next partial state or function to + * produce next partial state to be merged with current state. + * @param {?function} callback Called after state is updated. + * @final + * @protected + */ +ReactComponent.prototype.setState = function(partialState, callback) { + invariant( + typeof partialState === 'object' || + typeof partialState === 'function' || + partialState == null, + 'setState(...): takes an object of state variables to update or a ' + + 'function which returns an object of state variables.' + ); + if (__DEV__) { + warning( + partialState != null, + 'setState(...): You passed an undefined or null state object; ' + + 'instead, use forceUpdate().' + ); + } + ReactUpdateQueue.enqueueSetState(this, partialState); + if (callback) { + ReactUpdateQueue.enqueueCallback(this, callback); + } +}; + +/** + * Forces an update. This should only be invoked when it is known with + * certainty that we are **not** in a DOM transaction. + * + * You may want to call this when you know that some deeper aspect of the + * component's state has changed but `setState` was not called. + * + * This will not invoke `shouldComponentUpdate`, but it will invoke + * `componentWillUpdate` and `componentDidUpdate`. + * + * @param {?function} callback Called after update is complete. + * @final + * @protected + */ +ReactComponent.prototype.forceUpdate = function(callback) { + ReactUpdateQueue.enqueueForceUpdate(this); + if (callback) { + ReactUpdateQueue.enqueueCallback(this, callback); + } +}; + +/** + * Deprecated APIs. These APIs used to exist on classic React classes but since + * we would like to deprecate them, we're not going to move them over to this + * modern base class. Instead, we define a getter that warns if it's accessed. + */ +if (__DEV__) { + var deprecatedAPIs = { + getDOMNode: 'getDOMNode', + isMounted: 'isMounted', + replaceProps: 'replaceProps', + replaceState: 'replaceState', + setProps: 'setProps' + }; + var defineDeprecationWarning = function(methodName, displayName) { + try { + Object.defineProperty(ReactComponent.prototype, methodName, { + get: function() { + warning( + false, + '%s(...) is deprecated in plain JavaScript React classes.', + displayName + ); + return undefined; + } + }); + } catch (x) { + // IE will fail on defineProperty (es5-shim/sham too) + } + }; + for (var fnName in deprecatedAPIs) { + if (deprecatedAPIs.hasOwnProperty(fnName)) { + defineDeprecationWarning(fnName, deprecatedAPIs[fnName]); + } + } +} + +module.exports = ReactComponent; +}); +__d('ReactUpdateQueue',["ReactLifeCycle","ReactCurrentOwner","ReactElement","ReactInstanceMap","ReactUpdates","Object.assign","invariant","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2015, 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 ReactUpdateQueue + */ + +'use strict'; + +var ReactLifeCycle = require('ReactLifeCycle'); +var ReactCurrentOwner = require('ReactCurrentOwner'); +var ReactElement = require('ReactElement'); +var ReactInstanceMap = require('ReactInstanceMap'); +var ReactUpdates = require('ReactUpdates'); + +var assign = require('Object.assign'); +var invariant = require('invariant'); +var warning = require('warning'); + +function enqueueUpdate(internalInstance) { + if (internalInstance !== ReactLifeCycle.currentlyMountingInstance) { + // If we're in a componentWillMount handler, don't enqueue a rerender + // because ReactUpdates assumes we're in a browser context (which is + // wrong for server rendering) and we're about to do a render anyway. + // See bug in #1740. + ReactUpdates.enqueueUpdate(internalInstance); + } +} + +function getInternalInstanceReadyForUpdate(publicInstance, callerName) { + invariant( + ReactCurrentOwner.current == null, + '%s(...): Cannot update during an existing state transition ' + + '(such as within `render`). Render methods should be a pure function ' + + 'of props and state.', + callerName + ); + + var internalInstance = ReactInstanceMap.get(publicInstance); + if (!internalInstance) { + if (__DEV__) { + // Only warn when we have a callerName. Otherwise we should be silent. + // We're probably calling from enqueueCallback. We don't want to warn + // there because we already warned for the corresponding lifecycle method. + warning( + !callerName, + '%s(...): Can only update a mounted or mounting component. ' + + 'This usually means you called %s() on an unmounted ' + + 'component. This is a no-op.', + callerName, + callerName + ); + } + return null; + } + + if (internalInstance === ReactLifeCycle.currentlyUnmountingInstance) { + return null; + } + + return internalInstance; +} + +/** + * ReactUpdateQueue allows for state updates to be scheduled into a later + * reconciliation step. + */ +var ReactUpdateQueue = { + + /** + * Enqueue a callback that will be executed after all the pending updates + * have processed. + * + * @param {ReactClass} publicInstance The instance to use as `this` context. + * @param {?function} callback Called after state is updated. + * @internal + */ + enqueueCallback: function(publicInstance, callback) { + invariant( + typeof callback === 'function', + 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + + '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + + 'isn\'t callable.' + ); + var internalInstance = getInternalInstanceReadyForUpdate(publicInstance); + + // Previously we would throw an error if we didn't have an internal + // instance. Since we want to make it a no-op instead, we mirror the same + // behavior we have in other enqueue* methods. + // We also need to ignore callbacks in componentWillMount. See + // enqueueUpdates. + if (!internalInstance || + internalInstance === ReactLifeCycle.currentlyMountingInstance) { + return null; + } + + if (internalInstance._pendingCallbacks) { + internalInstance._pendingCallbacks.push(callback); + } else { + internalInstance._pendingCallbacks = [callback]; + } + // TODO: The callback here is ignored when setState is called from + // componentWillMount. Either fix it or disallow doing so completely in + // favor of getInitialState. Alternatively, we can disallow + // componentWillMount during server-side rendering. + enqueueUpdate(internalInstance); + }, + + enqueueCallbackInternal: function(internalInstance, callback) { + invariant( + typeof callback === 'function', + 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + + '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + + 'isn\'t callable.' + ); + if (internalInstance._pendingCallbacks) { + internalInstance._pendingCallbacks.push(callback); + } else { + internalInstance._pendingCallbacks = [callback]; + } + enqueueUpdate(internalInstance); + }, + + /** + * Forces an update. This should only be invoked when it is known with + * certainty that we are **not** in a DOM transaction. + * + * You may want to call this when you know that some deeper aspect of the + * component's state has changed but `setState` was not called. + * + * This will not invoke `shouldUpdateComponent`, but it will invoke + * `componentWillUpdate` and `componentDidUpdate`. + * + * @param {ReactClass} publicInstance The instance that should rerender. + * @internal + */ + enqueueForceUpdate: function(publicInstance) { + var internalInstance = getInternalInstanceReadyForUpdate( + publicInstance, + 'forceUpdate' + ); + + if (!internalInstance) { + return; + } + + internalInstance._pendingForceUpdate = true; + + enqueueUpdate(internalInstance); + }, + + /** + * Replaces all of the state. Always use this or `setState` to mutate state. + * You should treat `this.state` as immutable. + * + * There is no guarantee that `this.state` will be immediately updated, so + * accessing `this.state` after calling this method may return the old value. + * + * @param {ReactClass} publicInstance The instance that should rerender. + * @param {object} completeState Next state. + * @internal + */ + enqueueReplaceState: function(publicInstance, completeState) { + var internalInstance = getInternalInstanceReadyForUpdate( + publicInstance, + 'replaceState' + ); + + if (!internalInstance) { + return; + } + + internalInstance._pendingStateQueue = [completeState]; + internalInstance._pendingReplaceState = true; + + enqueueUpdate(internalInstance); + }, + + /** + * Sets a subset of the state. This only exists because _pendingState is + * internal. This provides a merging strategy that is not available to deep + * properties which is confusing. TODO: Expose pendingState or don't use it + * during the merge. + * + * @param {ReactClass} publicInstance The instance that should rerender. + * @param {object} partialState Next partial state to be merged with state. + * @internal + */ + enqueueSetState: function(publicInstance, partialState) { + var internalInstance = getInternalInstanceReadyForUpdate( + publicInstance, + 'setState' + ); + + if (!internalInstance) { + return; + } + + var queue = + internalInstance._pendingStateQueue || + (internalInstance._pendingStateQueue = []); + queue.push(partialState); + + enqueueUpdate(internalInstance); + }, + + /** + * Sets a subset of the props. + * + * @param {ReactClass} publicInstance The instance that should rerender. + * @param {object} partialProps Subset of the next props. + * @internal + */ + enqueueSetProps: function(publicInstance, partialProps) { + var internalInstance = getInternalInstanceReadyForUpdate( + publicInstance, + 'setProps' + ); + + if (!internalInstance) { + return; + } + + invariant( + internalInstance._isTopLevel, + 'setProps(...): You called `setProps` on a ' + + 'component with a parent. This is an anti-pattern since props will ' + + 'get reactively updated when rendered. Instead, change the owner\'s ' + + '`render` method to pass the correct value as props to the component ' + + 'where it is created.' + ); + + // Merge with the pending element if it exists, otherwise with existing + // element props. + var element = internalInstance._pendingElement || + internalInstance._currentElement; + var props = assign({}, element.props, partialProps); + internalInstance._pendingElement = ReactElement.cloneAndReplaceProps( + element, + props + ); + + enqueueUpdate(internalInstance); + }, + + /** + * Replaces all of the props. + * + * @param {ReactClass} publicInstance The instance that should rerender. + * @param {object} props New props. + * @internal + */ + enqueueReplaceProps: function(publicInstance, props) { + var internalInstance = getInternalInstanceReadyForUpdate( + publicInstance, + 'replaceProps' + ); + + if (!internalInstance) { + return; + } + + invariant( + internalInstance._isTopLevel, + 'replaceProps(...): You called `replaceProps` on a ' + + 'component with a parent. This is an anti-pattern since props will ' + + 'get reactively updated when rendered. Instead, change the owner\'s ' + + '`render` method to pass the correct value as props to the component ' + + 'where it is created.' + ); + + // Merge with the pending element if it exists, otherwise with existing + // element props. + var element = internalInstance._pendingElement || + internalInstance._currentElement; + internalInstance._pendingElement = ReactElement.cloneAndReplaceProps( + element, + props + ); + + enqueueUpdate(internalInstance); + }, + + enqueueElementInternal: function(internalInstance, newElement) { + internalInstance._pendingElement = newElement; + enqueueUpdate(internalInstance); + } + +}; + +module.exports = ReactUpdateQueue; +}); +__d('ReactLifeCycle',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2015, 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 ReactLifeCycle + */ + +'use strict'; + +/** + * This module manages the bookkeeping when a component is in the process + * of being mounted or being unmounted. This is used as a way to enforce + * invariants (or warnings) when it is not recommended to call + * setState/forceUpdate. + * + * currentlyMountingInstance: During the construction phase, it is not possible + * to trigger an update since the instance is not fully mounted yet. However, we + * currently allow this as a convenience for mutating the initial state. + * + * currentlyUnmountingInstance: During the unmounting phase, the instance is + * still mounted and can therefore schedule an update. However, this is not + * recommended and probably an error since it's about to be unmounted. + * Therefore we still want to trigger in an error for that case. + */ + +var ReactLifeCycle = { + currentlyMountingInstance: null, + currentlyUnmountingInstance: null +}; + +module.exports = ReactLifeCycle; +}); +__d('ReactInstanceMap',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactInstanceMap + */ + +'use strict'; + +/** + * `ReactInstanceMap` maintains a mapping from a public facing stateful + * instance (key) and the internal representation (value). This allows public + * methods to accept the user facing instance as an argument and map them back + * to internal methods. + */ + +// TODO: Replace this with ES6: var ReactInstanceMap = new Map(); +var ReactInstanceMap = { + + /** + * This API should be called `delete` but we'd have to make sure to always + * transform these to strings for IE support. When this transform is fully + * supported we can rename it. + */ + remove: function(key) { + key._reactInternalInstance = undefined; + }, + + get: function(key) { + return key._reactInternalInstance; + }, + + has: function(key) { + return key._reactInternalInstance !== undefined; + }, + + set: function(key, value) { + key._reactInternalInstance = value; + } + +}; + +module.exports = ReactInstanceMap; +}); +__d('ReactUpdates',["CallbackQueue","PooledClass","ReactCurrentOwner","ReactPerf","ReactReconciler","Transaction","Object.assign","invariant","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactUpdates + */ + +'use strict'; + +var CallbackQueue = require('CallbackQueue'); +var PooledClass = require('PooledClass'); +var ReactCurrentOwner = require('ReactCurrentOwner'); +var ReactPerf = require('ReactPerf'); +var ReactReconciler = require('ReactReconciler'); +var Transaction = require('Transaction'); + +var assign = require('Object.assign'); +var invariant = require('invariant'); +var warning = require('warning'); + +var dirtyComponents = []; +var asapCallbackQueue = CallbackQueue.getPooled(); +var asapEnqueued = false; + +var batchingStrategy = null; + +function ensureInjected() { + invariant( + ReactUpdates.ReactReconcileTransaction && batchingStrategy, + 'ReactUpdates: must inject a reconcile transaction class and batching ' + + 'strategy' + ); +} + +var NESTED_UPDATES = { + initialize: function() { + this.dirtyComponentsLength = dirtyComponents.length; + }, + close: function() { + if (this.dirtyComponentsLength !== dirtyComponents.length) { + // Additional updates were enqueued by componentDidUpdate handlers or + // similar; before our own UPDATE_QUEUEING wrapper closes, we want to run + // these new updates so that if A's componentDidUpdate calls setState on + // B, B will update before the callback A's updater provided when calling + // setState. + dirtyComponents.splice(0, this.dirtyComponentsLength); + flushBatchedUpdates(); + } else { + dirtyComponents.length = 0; + } + } +}; + +var UPDATE_QUEUEING = { + initialize: function() { + this.callbackQueue.reset(); + }, + close: function() { + this.callbackQueue.notifyAll(); + } +}; + +var TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING]; + +function ReactUpdatesFlushTransaction() { + this.reinitializeTransaction(); + this.dirtyComponentsLength = null; + this.callbackQueue = CallbackQueue.getPooled(); + this.reconcileTransaction = + ReactUpdates.ReactReconcileTransaction.getPooled(); +} + +assign( + ReactUpdatesFlushTransaction.prototype, + Transaction.Mixin, { + getTransactionWrappers: function() { + return TRANSACTION_WRAPPERS; + }, + + destructor: function() { + this.dirtyComponentsLength = null; + CallbackQueue.release(this.callbackQueue); + this.callbackQueue = null; + ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction); + this.reconcileTransaction = null; + }, + + perform: function(method, scope, a) { + // Essentially calls `this.reconcileTransaction.perform(method, scope, a)` + // with this transaction's wrappers around it. + return Transaction.Mixin.perform.call( + this, + this.reconcileTransaction.perform, + this.reconcileTransaction, + method, + scope, + a + ); + } +}); + +PooledClass.addPoolingTo(ReactUpdatesFlushTransaction); + +function batchedUpdates(callback, a, b, c, d) { + ensureInjected(); + batchingStrategy.batchedUpdates(callback, a, b, c, d); +} + +/** + * Array comparator for ReactComponents by mount ordering. + * + * @param {ReactComponent} c1 first component you're comparing + * @param {ReactComponent} c2 second component you're comparing + * @return {number} Return value usable by Array.prototype.sort(). + */ +function mountOrderComparator(c1, c2) { + return c1._mountOrder - c2._mountOrder; +} + +function runBatchedUpdates(transaction) { + var len = transaction.dirtyComponentsLength; + invariant( + len === dirtyComponents.length, + 'Expected flush transaction\'s stored dirty-components length (%s) to ' + + 'match dirty-components array length (%s).', + len, + dirtyComponents.length + ); + + // Since reconciling a component higher in the owner hierarchy usually (not + // always -- see shouldComponentUpdate()) will reconcile children, reconcile + // them before their children by sorting the array. + dirtyComponents.sort(mountOrderComparator); + + for (var i = 0; i < len; i++) { + // If a component is unmounted before pending changes apply, it will still + // be here, but we assume that it has cleared its _pendingCallbacks and + // that performUpdateIfNecessary is a noop. + var component = dirtyComponents[i]; + + // If performUpdateIfNecessary happens to enqueue any new updates, we + // shouldn't execute the callbacks until the next render happens, so + // stash the callbacks first + var callbacks = component._pendingCallbacks; + component._pendingCallbacks = null; + + ReactReconciler.performUpdateIfNecessary( + component, + transaction.reconcileTransaction + ); + + if (callbacks) { + for (var j = 0; j < callbacks.length; j++) { + transaction.callbackQueue.enqueue( + callbacks[j], + component.getPublicInstance() + ); + } + } + } +} + +var flushBatchedUpdates = function() { + // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents + // array and perform any updates enqueued by mount-ready handlers (i.e., + // componentDidUpdate) but we need to check here too in order to catch + // updates enqueued by setState callbacks and asap calls. + while (dirtyComponents.length || asapEnqueued) { + if (dirtyComponents.length) { + var transaction = ReactUpdatesFlushTransaction.getPooled(); + transaction.perform(runBatchedUpdates, null, transaction); + ReactUpdatesFlushTransaction.release(transaction); + } + + if (asapEnqueued) { + asapEnqueued = false; + var queue = asapCallbackQueue; + asapCallbackQueue = CallbackQueue.getPooled(); + queue.notifyAll(); + CallbackQueue.release(queue); + } + } +}; +flushBatchedUpdates = ReactPerf.measure( + 'ReactUpdates', + 'flushBatchedUpdates', + flushBatchedUpdates +); + +/** + * Mark a component as needing a rerender, adding an optional callback to a + * list of functions which will be executed once the rerender occurs. + */ +function enqueueUpdate(component) { + ensureInjected(); + + // Various parts of our code (such as ReactCompositeComponent's + // _renderValidatedComponent) assume that calls to render aren't nested; + // verify that that's the case. (This is called by each top-level update + // function, like setProps, setState, forceUpdate, etc.; creation and + // destruction of top-level components is guarded in ReactMount.) + warning( + ReactCurrentOwner.current == null, + 'enqueueUpdate(): Render methods should be a pure function of props ' + + 'and state; triggering nested component updates from render is not ' + + 'allowed. If necessary, trigger nested updates in ' + + 'componentDidUpdate.' + ); + + if (!batchingStrategy.isBatchingUpdates) { + batchingStrategy.batchedUpdates(enqueueUpdate, component); + return; + } + + dirtyComponents.push(component); +} + +/** + * Enqueue a callback to be run at the end of the current batching cycle. Throws + * if no updates are currently being performed. + */ +function asap(callback, context) { + invariant( + batchingStrategy.isBatchingUpdates, + 'ReactUpdates.asap: Can\'t enqueue an asap callback in a context where' + + 'updates are not being batched.' + ); + asapCallbackQueue.enqueue(callback, context); + asapEnqueued = true; +} + +var ReactUpdatesInjection = { + injectReconcileTransaction: function(ReconcileTransaction) { + invariant( + ReconcileTransaction, + 'ReactUpdates: must provide a reconcile transaction class' + ); + ReactUpdates.ReactReconcileTransaction = ReconcileTransaction; + }, + + injectBatchingStrategy: function(_batchingStrategy) { + invariant( + _batchingStrategy, + 'ReactUpdates: must provide a batching strategy' + ); + invariant( + typeof _batchingStrategy.batchedUpdates === 'function', + 'ReactUpdates: must provide a batchedUpdates() function' + ); + invariant( + typeof _batchingStrategy.isBatchingUpdates === 'boolean', + 'ReactUpdates: must provide an isBatchingUpdates boolean attribute' + ); + batchingStrategy = _batchingStrategy; + } +}; + +var ReactUpdates = { + /** + * React references `ReactReconcileTransaction` using this property in order + * to allow dependency injection. + * + * @internal + */ + ReactReconcileTransaction: null, + + batchedUpdates: batchedUpdates, + enqueueUpdate: enqueueUpdate, + flushBatchedUpdates: flushBatchedUpdates, + injection: ReactUpdatesInjection, + asap: asap +}; + +module.exports = ReactUpdates; +}); +__d('CallbackQueue',["PooledClass","Object.assign","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 CallbackQueue + */ + +'use strict'; + +var PooledClass = require('PooledClass'); + +var assign = require('Object.assign'); +var invariant = require('invariant'); + +/** + * A specialized pseudo-event module to help keep track of components waiting to + * be notified when their DOM representations are available for use. + * + * This implements `PooledClass`, so you should never need to instantiate this. + * Instead, use `CallbackQueue.getPooled()`. + * + * @class ReactMountReady + * @implements PooledClass + * @internal + */ +function CallbackQueue() { + this._callbacks = null; + this._contexts = null; +} + +assign(CallbackQueue.prototype, { + + /** + * Enqueues a callback to be invoked when `notifyAll` is invoked. + * + * @param {function} callback Invoked when `notifyAll` is invoked. + * @param {?object} context Context to call `callback` with. + * @internal + */ + enqueue: function(callback, context) { + this._callbacks = this._callbacks || []; + this._contexts = this._contexts || []; + this._callbacks.push(callback); + this._contexts.push(context); + }, + + /** + * Invokes all enqueued callbacks and clears the queue. This is invoked after + * the DOM representation of a component has been created or updated. + * + * @internal + */ + notifyAll: function() { + var callbacks = this._callbacks; + var contexts = this._contexts; + if (callbacks) { + invariant( + callbacks.length === contexts.length, + 'Mismatched list of contexts in callback queue' + ); + this._callbacks = null; + this._contexts = null; + for (var i = 0, l = callbacks.length; i < l; i++) { + callbacks[i].call(contexts[i]); + } + callbacks.length = 0; + contexts.length = 0; + } + }, + + /** + * Resets the internal queue. + * + * @internal + */ + reset: function() { + this._callbacks = null; + this._contexts = null; + }, + + /** + * `PooledClass` looks for this. + */ + destructor: function() { + this.reset(); + } + +}); + +PooledClass.addPoolingTo(CallbackQueue); + +module.exports = CallbackQueue; +}); +__d('ReactPerf',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactPerf + * @typechecks static-only + */ + +'use strict'; + +/** + * ReactPerf is a general AOP system designed to measure performance. This + * module only has the hooks: see ReactDefaultPerf for the analysis tool. + */ +var ReactPerf = { + /** + * Boolean to enable/disable measurement. Set to false by default to prevent + * accidental logging and perf loss. + */ + enableMeasure: false, + + /** + * Holds onto the measure function in use. By default, don't measure + * anything, but we'll override this if we inject a measure function. + */ + storedMeasure: _noMeasure, + + /** + * @param {object} object + * @param {string} objectName + * @param {object} methodNames + */ + measureMethods: function(object, objectName, methodNames) { + if (__DEV__) { + for (var key in methodNames) { + if (!methodNames.hasOwnProperty(key)) { + continue; + } + object[key] = ReactPerf.measure( + objectName, + methodNames[key], + object[key] + ); + } + } + }, + + /** + * Use this to wrap methods you want to measure. Zero overhead in production. + * + * @param {string} objName + * @param {string} fnName + * @param {function} func + * @return {function} + */ + measure: function(objName, fnName, func) { + if (__DEV__) { + var measuredFunc = null; + var wrapper = function() { + if (ReactPerf.enableMeasure) { + if (!measuredFunc) { + measuredFunc = ReactPerf.storedMeasure(objName, fnName, func); + } + return measuredFunc.apply(this, arguments); + } + return func.apply(this, arguments); + }; + wrapper.displayName = objName + '_' + fnName; + return wrapper; + } + return func; + }, + + injection: { + /** + * @param {function} measure + */ + injectMeasure: function(measure) { + ReactPerf.storedMeasure = measure; + } + } +}; + +/** + * Simply passes through the measured function, without measuring it. + * + * @param {string} objName + * @param {string} fnName + * @param {function} func + * @return {function} + */ +function _noMeasure(objName, fnName, func) { + return func; +} + +module.exports = ReactPerf; +}); +__d('ReactReconciler',["ReactRef","ReactElementValidator"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactReconciler + */ + +'use strict'; + +var ReactRef = require('ReactRef'); +var ReactElementValidator = require('ReactElementValidator'); + +/** + * Helper to call ReactRef.attachRefs with this composite component, split out + * to avoid allocations in the transaction mount-ready queue. + */ +function attachRefs() { + ReactRef.attachRefs(this, this._currentElement); +} + +var ReactReconciler = { + + /** + * Initializes the component, renders markup, and registers event listeners. + * + * @param {ReactComponent} internalInstance + * @param {string} rootID DOM ID of the root node. + * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction + * @return {?string} Rendered markup to be inserted into the DOM. + * @final + * @internal + */ + mountComponent: function(internalInstance, rootID, transaction, context) { + var markup = internalInstance.mountComponent(rootID, transaction, context); + if (__DEV__) { + ReactElementValidator.checkAndWarnForMutatedProps( + internalInstance._currentElement + ); + } + transaction.getReactMountReady().enqueue(attachRefs, internalInstance); + return markup; + }, + + /** + * Releases any resources allocated by `mountComponent`. + * + * @final + * @internal + */ + unmountComponent: function(internalInstance) { + ReactRef.detachRefs(internalInstance, internalInstance._currentElement); + internalInstance.unmountComponent(); + }, + + /** + * Update a component using a new element. + * + * @param {ReactComponent} internalInstance + * @param {ReactElement} nextElement + * @param {ReactReconcileTransaction} transaction + * @param {object} context + * @internal + */ + receiveComponent: function( + internalInstance, nextElement, transaction, context + ) { + var prevElement = internalInstance._currentElement; + + if (nextElement === prevElement && nextElement._owner != null) { + // Since elements are immutable after the owner is rendered, + // we can do a cheap identity compare here to determine if this is a + // superfluous reconcile. It's possible for state to be mutable but such + // change should trigger an update of the owner which would recreate + // the element. We explicitly check for the existence of an owner since + // it's possible for an element created outside a composite to be + // deeply mutated and reused. + return; + } + + if (__DEV__) { + ReactElementValidator.checkAndWarnForMutatedProps(nextElement); + } + + var refsChanged = ReactRef.shouldUpdateRefs( + prevElement, + nextElement + ); + + if (refsChanged) { + ReactRef.detachRefs(internalInstance, prevElement); + } + + internalInstance.receiveComponent(nextElement, transaction, context); + + if (refsChanged) { + transaction.getReactMountReady().enqueue(attachRefs, internalInstance); + } + }, + + /** + * Flush any dirty changes in a component. + * + * @param {ReactComponent} internalInstance + * @param {ReactReconcileTransaction} transaction + * @internal + */ + performUpdateIfNecessary: function( + internalInstance, + transaction + ) { + internalInstance.performUpdateIfNecessary(transaction); + } + +}; + +module.exports = ReactReconciler; +}); +__d('ReactRef',["ReactOwner"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactRef + */ + +'use strict'; + +var ReactOwner = require('ReactOwner'); + +var ReactRef = {}; + +function attachRef(ref, component, owner) { + if (typeof ref === 'function') { + ref(component.getPublicInstance()); + } else { + // Legacy ref + ReactOwner.addComponentAsRefTo(component, ref, owner); + } +} + +function detachRef(ref, component, owner) { + if (typeof ref === 'function') { + ref(null); + } else { + // Legacy ref + ReactOwner.removeComponentAsRefFrom(component, ref, owner); + } +} + +ReactRef.attachRefs = function(instance, element) { + var ref = element.ref; + if (ref != null) { + attachRef(ref, instance, element._owner); + } +}; + +ReactRef.shouldUpdateRefs = function(prevElement, nextElement) { + // If either the owner or a `ref` has changed, make sure the newest owner + // has stored a reference to `this`, and the previous owner (if different) + // has forgotten the reference to `this`. We use the element instead + // of the public this.props because the post processing cannot determine + // a ref. The ref conceptually lives on the element. + + // TODO: Should this even be possible? The owner cannot change because + // it's forbidden by shouldUpdateReactComponent. The ref can change + // if you swap the keys of but not the refs. Reconsider where this check + // is made. It probably belongs where the key checking and + // instantiateReactComponent is done. + + return ( + nextElement._owner !== prevElement._owner || + nextElement.ref !== prevElement.ref + ); +}; + +ReactRef.detachRefs = function(instance, element) { + var ref = element.ref; + if (ref != null) { + detachRef(ref, instance, element._owner); + } +}; + +module.exports = ReactRef; +}); +__d('ReactOwner',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactOwner + */ + +'use strict'; + +var invariant = require('invariant'); + +/** + * ReactOwners are capable of storing references to owned components. + * + * All components are capable of //being// referenced by owner components, but + * only ReactOwner components are capable of //referencing// owned components. + * The named reference is known as a "ref". + * + * Refs are available when mounted and updated during reconciliation. + * + * var MyComponent = React.createClass({ + * render: function() { + * return ( + *
+ * + *
+ * ); + * }, + * handleClick: function() { + * this.refs.custom.handleClick(); + * }, + * componentDidMount: function() { + * this.refs.custom.initialize(); + * } + * }); + * + * Refs should rarely be used. When refs are used, they should only be done to + * control data that is not handled by React's data flow. + * + * @class ReactOwner + */ +var ReactOwner = { + + /** + * @param {?object} object + * @return {boolean} True if `object` is a valid owner. + * @final + */ + isValidOwner: function(object) { + return !!( + object && + typeof object.attachRef === 'function' && + typeof object.detachRef === 'function' + ); + }, + + /** + * Adds a component by ref to an owner component. + * + * @param {ReactComponent} component Component to reference. + * @param {string} ref Name by which to refer to the component. + * @param {ReactOwner} owner Component on which to record the ref. + * @final + * @internal + */ + addComponentAsRefTo: function(component, ref, owner) { + invariant( + ReactOwner.isValidOwner(owner), + 'addComponentAsRefTo(...): Only a ReactOwner can have refs. This ' + + 'usually means that you\'re trying to add a ref to a component that ' + + 'doesn\'t have an owner (that is, was not created inside of another ' + + 'component\'s `render` method). Try rendering this component inside of ' + + 'a new top-level component which will hold the ref.' + ); + owner.attachRef(ref, component); + }, + + /** + * Removes a component by ref from an owner component. + * + * @param {ReactComponent} component Component to dereference. + * @param {string} ref Name of the ref to remove. + * @param {ReactOwner} owner Component on which the ref is recorded. + * @final + * @internal + */ + removeComponentAsRefFrom: function(component, ref, owner) { + invariant( + ReactOwner.isValidOwner(owner), + 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. This ' + + 'usually means that you\'re trying to remove a ref to a component that ' + + 'doesn\'t have an owner (that is, was not created inside of another ' + + 'component\'s `render` method). Try rendering this component inside of ' + + 'a new top-level component which will hold the ref.' + ); + // Check that `component` is still the current ref because we do not want to + // detach the ref if another component stole it. + if (owner.getPublicInstance().refs[ref] === component.getPublicInstance()) { + owner.detachRef(ref); + } + } + +}; + +module.exports = ReactOwner; +}); +__d('ReactElementValidator',["ReactElement","ReactFragment","ReactPropTypeLocations","ReactPropTypeLocationNames","ReactCurrentOwner","ReactNativeComponent","getIteratorFn","invariant","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2014-2015, 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 ReactElementValidator + */ + +/** + * ReactElementValidator provides a wrapper around a element factory + * which validates the props passed to the element. This is intended to be + * used only in DEV and could be replaced by a static type checker for languages + * that support it. + */ + +'use strict'; + +var ReactElement = require('ReactElement'); +var ReactFragment = require('ReactFragment'); +var ReactPropTypeLocations = require('ReactPropTypeLocations'); +var ReactPropTypeLocationNames = require('ReactPropTypeLocationNames'); +var ReactCurrentOwner = require('ReactCurrentOwner'); +var ReactNativeComponent = require('ReactNativeComponent'); + +var getIteratorFn = require('getIteratorFn'); +var invariant = require('invariant'); +var warning = require('warning'); + +function getDeclarationErrorAddendum() { + if (ReactCurrentOwner.current) { + var name = ReactCurrentOwner.current.getName(); + if (name) { + return ' Check the render method of `' + name + '`.'; + } + } + return ''; +} + +/** + * Warn if there's no key explicitly set on dynamic arrays of children or + * object keys are not valid. This allows us to keep track of children between + * updates. + */ +var ownerHasKeyUseWarning = {}; + +var loggedTypeFailures = {}; + +var NUMERIC_PROPERTY_REGEX = /^\d+$/; + +/** + * Gets the instance's name for use in warnings. + * + * @internal + * @return {?string} Display name or undefined + */ +function getName(instance) { + var publicInstance = instance && instance.getPublicInstance(); + if (!publicInstance) { + return undefined; + } + var constructor = publicInstance.constructor; + if (!constructor) { + return undefined; + } + return constructor.displayName || constructor.name || undefined; +} + +/** + * Gets the current owner's displayName for use in warnings. + * + * @internal + * @return {?string} Display name or undefined + */ +function getCurrentOwnerDisplayName() { + var current = ReactCurrentOwner.current; + return ( + current && getName(current) || undefined + ); +} + +/** + * Warn if the element doesn't have an explicit key assigned to it. + * This element is in an array. The array could grow and shrink or be + * reordered. All children that haven't already been validated are required to + * have a "key" property assigned to it. + * + * @internal + * @param {ReactElement} element Element that requires a key. + * @param {*} parentType element's parent's type. + */ +function validateExplicitKey(element, parentType) { + if (element._store.validated || element.key != null) { + return; + } + element._store.validated = true; + + warnAndMonitorForKeyUse( + 'Each child in an array or iterator should have a unique "key" prop.', + element, + parentType + ); +} + +/** + * Warn if the key is being defined as an object property but has an incorrect + * value. + * + * @internal + * @param {string} name Property name of the key. + * @param {ReactElement} element Component that requires a key. + * @param {*} parentType element's parent's type. + */ +function validatePropertyKey(name, element, parentType) { + if (!NUMERIC_PROPERTY_REGEX.test(name)) { + return; + } + warnAndMonitorForKeyUse( + 'Child objects should have non-numeric keys so ordering is preserved.', + element, + parentType + ); +} + +/** + * Shared warning and monitoring code for the key warnings. + * + * @internal + * @param {string} message The base warning that gets output. + * @param {ReactElement} element Component that requires a key. + * @param {*} parentType element's parent's type. + */ +function warnAndMonitorForKeyUse(message, element, parentType) { + var ownerName = getCurrentOwnerDisplayName(); + var parentName = typeof parentType === 'string' ? + parentType : parentType.displayName || parentType.name; + + var useName = ownerName || parentName; + var memoizer = ownerHasKeyUseWarning[message] || ( + ownerHasKeyUseWarning[message] = {} + ); + if (memoizer.hasOwnProperty(useName)) { + return; + } + memoizer[useName] = true; + + var parentOrOwnerAddendum = + ownerName ? (" Check the render method of " + ownerName + ".") : + parentName ? (" Check the React.render call using <" + parentName + ">.") : + ''; + + // Usually the current owner is the offender, but if it accepts children as a + // property, it may be the creator of the child that's responsible for + // assigning it a key. + var childOwnerAddendum = ''; + if (element && + element._owner && + element._owner !== ReactCurrentOwner.current) { + // Name of the component that originally created this child. + var childOwnerName = getName(element._owner); + + childOwnerAddendum = (" It was passed a child from " + childOwnerName + "."); + } + + warning( + false, + message + '%s%s See http://fb.me/react-warning-keys for more information.', + parentOrOwnerAddendum, + childOwnerAddendum + ); +} + +/** + * Ensure that every element either is passed in a static location, in an + * array with an explicit keys property defined, or in an object literal + * with valid key property. + * + * @internal + * @param {ReactNode} node Statically passed child of any type. + * @param {*} parentType node's parent's type. + */ +function validateChildKeys(node, parentType) { + if (Array.isArray(node)) { + for (var i = 0; i < node.length; i++) { + var child = node[i]; + if (ReactElement.isValidElement(child)) { + validateExplicitKey(child, parentType); + } + } + } else if (ReactElement.isValidElement(node)) { + // This element was passed in a valid location. + node._store.validated = true; + } else if (node) { + var iteratorFn = getIteratorFn(node); + // Entry iterators provide implicit keys. + if (iteratorFn) { + if (iteratorFn !== node.entries) { + var iterator = iteratorFn.call(node); + var step; + while (!(step = iterator.next()).done) { + if (ReactElement.isValidElement(step.value)) { + validateExplicitKey(step.value, parentType); + } + } + } + } else if (typeof node === 'object') { + var fragment = ReactFragment.extractIfFragment(node); + for (var key in fragment) { + if (fragment.hasOwnProperty(key)) { + validatePropertyKey(key, fragment[key], parentType); + } + } + } + } +} + +/** + * Assert that the props are valid + * + * @param {string} componentName Name of the component for error messages. + * @param {object} propTypes Map of prop name to a ReactPropType + * @param {object} props + * @param {string} location e.g. "prop", "context", "child context" + * @private + */ +function checkPropTypes(componentName, propTypes, props, location) { + for (var propName in propTypes) { + if (propTypes.hasOwnProperty(propName)) { + var error; + // Prop type validation may throw. In case they do, we don't want to + // fail the render phase where it didn't fail before. So we log it. + // After these have been cleaned up, we'll let them throw. + try { + // This is intentionally an invariant that gets caught. It's the same + // behavior as without this statement except with a better message. + invariant( + typeof propTypes[propName] === 'function', + '%s: %s type `%s` is invalid; it must be a function, usually from ' + + 'React.PropTypes.', + componentName || 'React class', + ReactPropTypeLocationNames[location], + propName + ); + error = propTypes[propName](props, propName, componentName, location); + } catch (ex) { + error = ex; + } + if (error instanceof Error && !(error.message in loggedTypeFailures)) { + // Only monitor this failure once because there tends to be a lot of the + // same error. + loggedTypeFailures[error.message] = true; + + var addendum = getDeclarationErrorAddendum(this); + warning(false, 'Failed propType: %s%s', error.message, addendum); + } + } + } +} + +var warnedPropsMutations = {}; + +/** + * Warn about mutating props when setting `propName` on `element`. + * + * @param {string} propName The string key within props that was set + * @param {ReactElement} element + */ +function warnForPropsMutation(propName, element) { + var type = element.type; + var elementName = typeof type === 'string' ? type : type.displayName; + var ownerName = element._owner ? + element._owner.getPublicInstance().constructor.displayName : null; + + var warningKey = propName + '|' + elementName + '|' + ownerName; + if (warnedPropsMutations.hasOwnProperty(warningKey)) { + return; + } + warnedPropsMutations[warningKey] = true; + + var elementInfo = ''; + if (elementName) { + elementInfo = ' <' + elementName + ' />'; + } + var ownerInfo = ''; + if (ownerName) { + ownerInfo = ' The element was created by ' + ownerName + '.'; + } + + warning( + false, + 'Don\'t set .props.%s of the React component%s. Instead, specify the ' + + 'correct value when initially creating the element or use ' + + 'React.cloneElement to make a new element with updated props.%s', + propName, + elementInfo, + ownerInfo + ); +} + +// Inline Object.is polyfill +function is(a, b) { + if (a !== a) { + // NaN + return b !== b; + } + if (a === 0 && b === 0) { + // +-0 + return 1 / a === 1 / b; + } + return a === b; +} + +/** + * Given an element, check if its props have been mutated since element + * creation (or the last call to this function). In particular, check if any + * new props have been added, which we can't directly catch by defining warning + * properties on the props object. + * + * @param {ReactElement} element + */ +function checkAndWarnForMutatedProps(element) { + if (!element._store) { + // Element was created using `new ReactElement` directly or with + // `ReactElement.createElement`; skip mutation checking + return; + } + + var originalProps = element._store.originalProps; + var props = element.props; + + for (var propName in props) { + if (props.hasOwnProperty(propName)) { + if (!originalProps.hasOwnProperty(propName) || + !is(originalProps[propName], props[propName])) { + warnForPropsMutation(propName, element); + + // Copy over the new value so that the two props objects match again + originalProps[propName] = props[propName]; + } + } + } +} + +/** + * Given an element, validate that its props follow the propTypes definition, + * provided by the type. + * + * @param {ReactElement} element + */ +function validatePropTypes(element) { + if (element.type == null) { + // This has already warned. Don't throw. + return; + } + // Extract the component class from the element. Converts string types + // to a composite class which may have propTypes. + // TODO: Validating a string's propTypes is not decoupled from the + // rendering target which is problematic. + var componentClass = ReactNativeComponent.getComponentClassForElement( + element + ); + var name = componentClass.displayName || componentClass.name; + if (componentClass.propTypes) { + checkPropTypes( + name, + componentClass.propTypes, + element.props, + ReactPropTypeLocations.prop + ); + } + if (typeof componentClass.getDefaultProps === 'function') { + warning( + componentClass.getDefaultProps.isReactClassApproved, + 'getDefaultProps is only used on classic React.createClass ' + + 'definitions. Use a static property named `defaultProps` instead.' + ); + } +} + +var ReactElementValidator = { + + checkAndWarnForMutatedProps: checkAndWarnForMutatedProps, + + createElement: function(type, props, children) { + // We warn in this case but don't throw. We expect the element creation to + // succeed and there will likely be errors in render. + warning( + type != null, + 'React.createElement: type should not be null or undefined. It should ' + + 'be a string (for DOM elements) or a ReactClass (for composite ' + + 'components).' + ); + + var element = ReactElement.createElement.apply(this, arguments); + + // The result can be nullish if a mock or a custom function is used. + // TODO: Drop this when these are no longer allowed as the type argument. + if (element == null) { + return element; + } + + for (var i = 2; i < arguments.length; i++) { + validateChildKeys(arguments[i], type); + } + + validatePropTypes(element); + + return element; + }, + + createFactory: function(type) { + var validatedFactory = ReactElementValidator.createElement.bind( + null, + type + ); + // Legacy hook TODO: Warn if this is accessed + validatedFactory.type = type; + + if (__DEV__) { + try { + Object.defineProperty( + validatedFactory, + 'type', + { + enumerable: false, + get: function() { + warning( + false, + 'Factory.type is deprecated. Access the class directly ' + + 'before passing it to createFactory.' + ); + Object.defineProperty(this, 'type', { + value: type + }); + return type; + } + } + ); + } catch (x) { + // IE will fail on defineProperty (es5-shim/sham too) + } + } + + + return validatedFactory; + }, + + cloneElement: function(element, props, children) { + var newElement = ReactElement.cloneElement.apply(this, arguments); + for (var i = 2; i < arguments.length; i++) { + validateChildKeys(arguments[i], newElement.type); + } + validatePropTypes(newElement); + return newElement; + } + +}; + +module.exports = ReactElementValidator; +}); +__d('ReactPropTypeLocations',["keyMirror"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactPropTypeLocations + */ + +'use strict'; + +var keyMirror = require('keyMirror'); + +var ReactPropTypeLocations = keyMirror({ + prop: null, + context: null, + childContext: null +}); + +module.exports = ReactPropTypeLocations; +}); +__d('keyMirror',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 keyMirror + * @typechecks static-only + */ + +'use strict'; + +var invariant = require('invariant'); + +/** + * Constructs an enumeration with keys equal to their value. + * + * For example: + * + * var COLORS = keyMirror({blue: null, red: null}); + * var myColor = COLORS.blue; + * var isColorValid = !!COLORS[myColor]; + * + * The last line could not be performed if the values of the generated enum were + * not equal to their keys. + * + * Input: {key1: val1, key2: val2} + * Output: {key1: key1, key2: key2} + * + * @param {object} obj + * @return {object} + */ +var keyMirror = function(obj) { + var ret = {}; + var key; + invariant( + obj instanceof Object && !Array.isArray(obj), + 'keyMirror(...): Argument must be an object.' + ); + for (key in obj) { + if (!obj.hasOwnProperty(key)) { + continue; + } + ret[key] = key; + } + return ret; +}; + +module.exports = keyMirror; +}); +__d('ReactPropTypeLocationNames',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactPropTypeLocationNames + */ + +'use strict'; + +var ReactPropTypeLocationNames = {}; + +if (__DEV__) { + ReactPropTypeLocationNames = { + prop: 'prop', + context: 'context', + childContext: 'child context' + }; +} + +module.exports = ReactPropTypeLocationNames; +}); +__d('ReactNativeComponent',["Object.assign","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2014-2015, 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 ReactNativeComponent + */ + +'use strict'; + +var assign = require('Object.assign'); +var invariant = require('invariant'); + +var autoGenerateWrapperClass = null; +var genericComponentClass = null; +// This registry keeps track of wrapper classes around native tags +var tagToComponentClass = {}; +var textComponentClass = null; + +var ReactNativeComponentInjection = { + // This accepts a class that receives the tag string. This is a catch all + // that can render any kind of tag. + injectGenericComponentClass: function(componentClass) { + genericComponentClass = componentClass; + }, + // This accepts a text component class that takes the text string to be + // rendered as props. + injectTextComponentClass: function(componentClass) { + textComponentClass = componentClass; + }, + // This accepts a keyed object with classes as values. Each key represents a + // tag. That particular tag will use this class instead of the generic one. + injectComponentClasses: function(componentClasses) { + assign(tagToComponentClass, componentClasses); + }, + // Temporary hack since we expect DOM refs to behave like composites, + // for this release. + injectAutoWrapper: function(wrapperFactory) { + autoGenerateWrapperClass = wrapperFactory; + } +}; + +/** + * Get a composite component wrapper class for a specific tag. + * + * @param {ReactElement} element The tag for which to get the class. + * @return {function} The React class constructor function. + */ +function getComponentClassForElement(element) { + if (typeof element.type === 'function') { + return element.type; + } + var tag = element.type; + var componentClass = tagToComponentClass[tag]; + if (componentClass == null) { + tagToComponentClass[tag] = componentClass = autoGenerateWrapperClass(tag); + } + return componentClass; +} + +/** + * Get a native internal component class for a specific tag. + * + * @param {ReactElement} element The element to create. + * @return {function} The internal class constructor function. + */ +function createInternalComponent(element) { + invariant( + genericComponentClass, + 'There is no registered component for the tag %s', + element.type + ); + return new genericComponentClass(element.type, element.props); +} + +/** + * @param {ReactText} text + * @return {ReactComponent} + */ +function createInstanceForText(text) { + return new textComponentClass(text); +} + +/** + * @param {ReactComponent} component + * @return {boolean} + */ +function isTextComponent(component) { + return component instanceof textComponentClass; +} + +var ReactNativeComponent = { + getComponentClassForElement: getComponentClassForElement, + createInternalComponent: createInternalComponent, + createInstanceForText: createInstanceForText, + isTextComponent: isTextComponent, + injection: ReactNativeComponentInjection +}; + +module.exports = ReactNativeComponent; +}); +__d('Transaction',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 Transaction + */ + +'use strict'; + +var invariant = require('invariant'); + +/** + * `Transaction` creates a black box that is able to wrap any method such that + * certain invariants are maintained before and after the method is invoked + * (Even if an exception is thrown while invoking the wrapped method). Whoever + * instantiates a transaction can provide enforcers of the invariants at + * creation time. The `Transaction` class itself will supply one additional + * automatic invariant for you - the invariant that any transaction instance + * should not be run while it is already being run. You would typically create a + * single instance of a `Transaction` for reuse multiple times, that potentially + * is used to wrap several different methods. Wrappers are extremely simple - + * they only require implementing two methods. + * + *
+ *                       wrappers (injected at creation time)
+ *                                      +        +
+ *                                      |        |
+ *                    +-----------------|--------|--------------+
+ *                    |                 v        |              |
+ *                    |      +---------------+   |              |
+ *                    |   +--|    wrapper1   |---|----+         |
+ *                    |   |  +---------------+   v    |         |
+ *                    |   |          +-------------+  |         |
+ *                    |   |     +----|   wrapper2  |--------+   |
+ *                    |   |     |    +-------------+  |     |   |
+ *                    |   |     |                     |     |   |
+ *                    |   v     v                     v     v   | wrapper
+ *                    | +---+ +---+   +---------+   +---+ +---+ | invariants
+ * perform(anyMethod) | |   | |   |   |         |   |   | |   | | maintained
+ * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->
+ *                    | |   | |   |   |         |   |   | |   | |
+ *                    | |   | |   |   |         |   |   | |   | |
+ *                    | |   | |   |   |         |   |   | |   | |
+ *                    | +---+ +---+   +---------+   +---+ +---+ |
+ *                    |  initialize                    close    |
+ *                    +-----------------------------------------+
+ * 
+ * + * Use cases: + * - Preserving the input selection ranges before/after reconciliation. + * Restoring selection even in the event of an unexpected error. + * - Deactivating events while rearranging the DOM, preventing blurs/focuses, + * while guaranteeing that afterwards, the event system is reactivated. + * - Flushing a queue of collected DOM mutations to the main UI thread after a + * reconciliation takes place in a worker thread. + * - Invoking any collected `componentDidUpdate` callbacks after rendering new + * content. + * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue + * to preserve the `scrollTop` (an automatic scroll aware DOM). + * - (Future use case): Layout calculations before and after DOM updates. + * + * Transactional plugin API: + * - A module that has an `initialize` method that returns any precomputation. + * - and a `close` method that accepts the precomputation. `close` is invoked + * when the wrapped process is completed, or has failed. + * + * @param {Array} transactionWrapper Wrapper modules + * that implement `initialize` and `close`. + * @return {Transaction} Single transaction for reuse in thread. + * + * @class Transaction + */ +var Mixin = { + /** + * Sets up this instance so that it is prepared for collecting metrics. Does + * so such that this setup method may be used on an instance that is already + * initialized, in a way that does not consume additional memory upon reuse. + * That can be useful if you decide to make your subclass of this mixin a + * "PooledClass". + */ + reinitializeTransaction: function() { + this.transactionWrappers = this.getTransactionWrappers(); + if (!this.wrapperInitData) { + this.wrapperInitData = []; + } else { + this.wrapperInitData.length = 0; + } + this._isInTransaction = false; + }, + + _isInTransaction: false, + + /** + * @abstract + * @return {Array} Array of transaction wrappers. + */ + getTransactionWrappers: null, + + isInTransaction: function() { + return !!this._isInTransaction; + }, + + /** + * Executes the function within a safety window. Use this for the top level + * methods that result in large amounts of computation/mutations that would + * need to be safety checked. + * + * @param {function} method Member of scope to call. + * @param {Object} scope Scope to invoke from. + * @param {Object?=} args... Arguments to pass to the method (optional). + * Helps prevent need to bind in many cases. + * @return Return value from `method`. + */ + perform: function(method, scope, a, b, c, d, e, f) { + invariant( + !this.isInTransaction(), + 'Transaction.perform(...): Cannot initialize a transaction when there ' + + 'is already an outstanding transaction.' + ); + var errorThrown; + var ret; + try { + this._isInTransaction = true; + // Catching errors makes debugging more difficult, so we start with + // errorThrown set to true before setting it to false after calling + // close -- if it's still set to true in the finally block, it means + // one of these calls threw. + errorThrown = true; + this.initializeAll(0); + ret = method.call(scope, a, b, c, d, e, f); + errorThrown = false; + } finally { + try { + if (errorThrown) { + // If `method` throws, prefer to show that stack trace over any thrown + // by invoking `closeAll`. + try { + this.closeAll(0); + } catch (err) { + } + } else { + // Since `method` didn't throw, we don't want to silence the exception + // here. + this.closeAll(0); + } + } finally { + this._isInTransaction = false; + } + } + return ret; + }, + + initializeAll: function(startIndex) { + var transactionWrappers = this.transactionWrappers; + for (var i = startIndex; i < transactionWrappers.length; i++) { + var wrapper = transactionWrappers[i]; + try { + // Catching errors makes debugging more difficult, so we start with the + // OBSERVED_ERROR state before overwriting it with the real return value + // of initialize -- if it's still set to OBSERVED_ERROR in the finally + // block, it means wrapper.initialize threw. + this.wrapperInitData[i] = Transaction.OBSERVED_ERROR; + this.wrapperInitData[i] = wrapper.initialize ? + wrapper.initialize.call(this) : + null; + } finally { + if (this.wrapperInitData[i] === Transaction.OBSERVED_ERROR) { + // The initializer for wrapper i threw an error; initialize the + // remaining wrappers but silence any exceptions from them to ensure + // that the first error is the one to bubble up. + try { + this.initializeAll(i + 1); + } catch (err) { + } + } + } + } + }, + + /** + * Invokes each of `this.transactionWrappers.close[i]` functions, passing into + * them the respective return values of `this.transactionWrappers.init[i]` + * (`close`rs that correspond to initializers that failed will not be + * invoked). + */ + closeAll: function(startIndex) { + invariant( + this.isInTransaction(), + 'Transaction.closeAll(): Cannot close transaction when none are open.' + ); + var transactionWrappers = this.transactionWrappers; + for (var i = startIndex; i < transactionWrappers.length; i++) { + var wrapper = transactionWrappers[i]; + var initData = this.wrapperInitData[i]; + var errorThrown; + try { + // Catching errors makes debugging more difficult, so we start with + // errorThrown set to true before setting it to false after calling + // close -- if it's still set to true in the finally block, it means + // wrapper.close threw. + errorThrown = true; + if (initData !== Transaction.OBSERVED_ERROR && wrapper.close) { + wrapper.close.call(this, initData); + } + errorThrown = false; + } finally { + if (errorThrown) { + // The closer for wrapper i threw an error; close the remaining + // wrappers but silence any exceptions from them to ensure that the + // first error is the one to bubble up. + try { + this.closeAll(i + 1); + } catch (e) { + } + } + } + } + this.wrapperInitData.length = 0; + } +}; + +var Transaction = { + + Mixin: Mixin, + + /** + * Token to look for to determine if an error occured. + */ + OBSERVED_ERROR: {} + +}; + +module.exports = Transaction; +}); +__d('ReactErrorUtils',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactErrorUtils + * @typechecks + */ + +"use strict"; + +var ReactErrorUtils = { + /** + * Creates a guarded version of a function. This is supposed to make debugging + * of event handlers easier. To aid debugging with the browser's debugger, + * this currently simply returns the original function. + * + * @param {function} func Function to be executed + * @param {string} name The name of the guard + * @return {function} + */ + guard: function(func, name) { + return func; + } +}; + +module.exports = ReactErrorUtils; +}); +__d('keyOf',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 keyOf + */ + +/** + * Allows extraction of a minified key. Let's the build system minify keys + * without loosing the ability to dynamically use key strings as values + * themselves. Pass in an object with a single key/val pair and it will return + * you the string key of that single record. Suppose you want to grab the + * value for a key 'className' inside of an object. Key/val minification may + * have aliased that key to be 'xa12'. keyOf({className: null}) will return + * 'xa12' in that case. Resolve keys you want to use once at startup time, then + * reuse those resolutions. + */ +var keyOf = function(oneKeyObj) { + var key; + for (key in oneKeyObj) { + if (!oneKeyObj.hasOwnProperty(key)) { + continue; + } + return key; + } + return null; +}; + + +module.exports = keyOf; +}); +__d('ReactNativeDefaultInjection',["InitializeJavaScriptAppEngine","EventPluginHub","EventPluginUtils","IOSDefaultEventPluginOrder","IOSNativeBridgeEventPlugin","NodeHandle","ReactClass","ReactComponentEnvironment","ReactDefaultBatchingStrategy","ReactEmptyComponent","ReactInstanceHandles","ReactNativeComponentEnvironment","ReactNativeGlobalInteractionHandler","ReactNativeGlobalResponderHandler","ReactNativeMount","ReactNativeTextComponent","ReactNativeComponent","ReactUpdates","ResponderEventPlugin","UniversalWorkerNodeHandle","createReactNativeComponentClass","invariant","RCTEventEmitter","RCTLog","RCTJSTimers"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 ReactNativeDefaultInjection + * @flow + */ + +"use strict"; + +/** + * Make sure `setTimeout`/`setInterval` are patched correctly. + */ +require('InitializeJavaScriptAppEngine'); +var EventPluginHub = require('EventPluginHub'); +var EventPluginUtils = require('EventPluginUtils'); +var IOSDefaultEventPluginOrder = require('IOSDefaultEventPluginOrder'); +var IOSNativeBridgeEventPlugin = require('IOSNativeBridgeEventPlugin'); +var NodeHandle = require('NodeHandle'); +var ReactClass = require('ReactClass'); +var ReactComponentEnvironment = require('ReactComponentEnvironment'); +var ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy'); +var ReactEmptyComponent = require('ReactEmptyComponent'); +var ReactInstanceHandles = require('ReactInstanceHandles'); +var ReactNativeComponentEnvironment = require('ReactNativeComponentEnvironment'); +var ReactNativeGlobalInteractionHandler = require('ReactNativeGlobalInteractionHandler'); +var ReactNativeGlobalResponderHandler = require('ReactNativeGlobalResponderHandler'); +var ReactNativeMount = require('ReactNativeMount'); +var ReactNativeTextComponent = require('ReactNativeTextComponent'); +var ReactNativeComponent = require('ReactNativeComponent'); +var ReactUpdates = require('ReactUpdates'); +var ResponderEventPlugin = require('ResponderEventPlugin'); +var UniversalWorkerNodeHandle = require('UniversalWorkerNodeHandle'); + +var createReactNativeComponentClass = require('createReactNativeComponentClass'); +var invariant = require('invariant'); + +// Just to ensure this gets packaged, since its only caller is from Native. +require('RCTEventEmitter'); +require('RCTLog'); +require('RCTJSTimers'); + +function inject() { + /** + * Inject module for resolving DOM hierarchy and plugin ordering. + */ + EventPluginHub.injection.injectEventPluginOrder(IOSDefaultEventPluginOrder); + EventPluginHub.injection.injectInstanceHandle(ReactInstanceHandles); + + ResponderEventPlugin.injection.injectGlobalResponderHandler( + ReactNativeGlobalResponderHandler + ); + + ResponderEventPlugin.injection.injectGlobalInteractionHandler( + ReactNativeGlobalInteractionHandler + ); + + /** + * Some important event plugins included by default (without having to require + * them). + */ + EventPluginHub.injection.injectEventPluginsByName({ + 'ResponderEventPlugin': ResponderEventPlugin, + 'IOSNativeBridgeEventPlugin': IOSNativeBridgeEventPlugin + }); + + ReactUpdates.injection.injectReconcileTransaction( + ReactNativeComponentEnvironment.ReactReconcileTransaction + ); + + ReactUpdates.injection.injectBatchingStrategy( + ReactDefaultBatchingStrategy + ); + + ReactComponentEnvironment.injection.injectEnvironment( + ReactNativeComponentEnvironment + ); + + // Can't import View here because it depends on React to make its composite + var RCTView = createReactNativeComponentClass({ + validAttributes: {}, + uiViewClassName: 'RCTView', + }); + ReactEmptyComponent.injection.injectEmptyComponent(RCTView); + + EventPluginUtils.injection.injectMount(ReactNativeMount); + + ReactNativeComponent.injection.injectTextComponentClass( + ReactNativeTextComponent + ); + ReactNativeComponent.injection.injectAutoWrapper(function(tag) { + // Show a nicer error message for non-function tags + var info = ''; + if (typeof tag === 'string' && /^[a-z]/.test(tag)) { + info += ' Each component name should start with an uppercase letter.'; + } + invariant(false, 'Expected a component class, got %s.%s', tag, info); + }); + + NodeHandle.injection.injectImplementation(UniversalWorkerNodeHandle); +} + +module.exports = { + inject: inject, +}; +}); +__d('InitializeJavaScriptAppEngine',["RCTDeviceEventEmitter","ExceptionsManager","ErrorUtils","ExceptionsManager","Platform","JSTimers","NativeModules","Promise","XMLHttpRequest","fetch","Geolocation","WebSocket"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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. + * + * Sets up global variables typical in most JavaScript environments. + * + * 1. Global timers (via `setTimeout` etc). + * 2. Global console object. + * 3. Hooks for printing stack traces with source maps. + * + * Leaves enough room in the environment for implementing your own: + * 1. Require system. + * 2. Bridged modules. + * + * @providesModule InitializeJavaScriptAppEngine + */ + +/* eslint global-strict: 0 */ +/* globals GLOBAL: true, window: true */ + +// Just to make sure the JS gets packaged up. +require('RCTDeviceEventEmitter'); + +if (typeof GLOBAL === 'undefined') { + GLOBAL = this; +} + +if (typeof window === 'undefined') { + window = GLOBAL; +} + +function handleErrorWithRedBox(e, isFatal) { + try { + require('ExceptionsManager').handleException(e, isFatal); + } catch(ee) { + console.log('Failed to print error: ', ee.message); + } +} + +function setUpRedBoxErrorHandler() { + var ErrorUtils = require('ErrorUtils'); + ErrorUtils.setGlobalHandler(handleErrorWithRedBox); +} + +function setUpRedBoxConsoleErrorHandler() { + // ExceptionsManager transitively requires Promise so we install it after + var ExceptionsManager = require('ExceptionsManager'); + var Platform = require('Platform'); + // TODO (#6925182): Enable console.error redbox on Android + if (__DEV__ && Platform.OS === 'ios') { + ExceptionsManager.installConsoleErrorReporter(); + } +} + +/** + * Sets up a set of window environment wrappers that ensure that the + * BatchedBridge is flushed after each tick. In both the case of the + * `UIWebView` based `RCTJavaScriptCaller` and `RCTContextCaller`, we + * implement our own custom timing bridge that should be immune to + * unexplainably dropped timing signals. + */ +function setUpTimers() { + var JSTimers = require('JSTimers'); + GLOBAL.setTimeout = JSTimers.setTimeout; + GLOBAL.setInterval = JSTimers.setInterval; + GLOBAL.setImmediate = JSTimers.setImmediate; + GLOBAL.clearTimeout = JSTimers.clearTimeout; + GLOBAL.clearInterval = JSTimers.clearInterval; + GLOBAL.clearImmediate = JSTimers.clearImmediate; + GLOBAL.cancelAnimationFrame = JSTimers.clearInterval; + GLOBAL.requestAnimationFrame = function(cb) { + /*requestAnimationFrame() { [native code] };*/ // Trick scroller library + return JSTimers.requestAnimationFrame(cb); // into thinking it's native + }; +} + +function setUpAlert() { + var RCTAlertManager = require('NativeModules').AlertManager; + if (!GLOBAL.alert) { + GLOBAL.alert = function(text) { + var alertOpts = { + title: 'Alert', + message: '' + text, + buttons: [{'cancel': 'Okay'}], + }; + RCTAlertManager.alertWithArgs(alertOpts, null); + }; + } +} + +function setUpPromise() { + // The native Promise implementation throws the following error: + // ERROR: Event loop not supported. + GLOBAL.Promise = require('Promise'); +} + +function setUpXHR() { + // The native XMLHttpRequest in Chrome dev tools is CORS aware and won't + // let you fetch anything from the internet + GLOBAL.XMLHttpRequest = require('XMLHttpRequest'); + + var fetchPolyfill = require('fetch'); + GLOBAL.fetch = fetchPolyfill.fetch; + GLOBAL.Headers = fetchPolyfill.Headers; + GLOBAL.Request = fetchPolyfill.Request; + GLOBAL.Response = fetchPolyfill.Response; +} + +function setUpGeolocation() { + GLOBAL.navigator = GLOBAL.navigator || {}; + GLOBAL.navigator.geolocation = require('Geolocation'); +} + +function setUpWebSockets() { + GLOBAL.WebSocket = require('WebSocket'); +} + +function setupProfile() { + console.profile = console.profile || GLOBAL.consoleProfile || function () {}; + console.profileEnd = console.profileEnd || GLOBAL.consoleProfileEnd || function () {}; +} + +setUpRedBoxErrorHandler(); +setUpTimers(); +setUpAlert(); +setUpPromise(); +setUpXHR(); +setUpRedBoxConsoleErrorHandler(); +setUpGeolocation(); +setUpWebSockets(); +setupProfile(); +}); +__d('RCTDeviceEventEmitter',["EventEmitter"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 RCTDeviceEventEmitter + * @flow + */ +'use strict'; + +var EventEmitter = require('EventEmitter'); + +var RCTDeviceEventEmitter = new EventEmitter(); + +module.exports = RCTDeviceEventEmitter; +}); +__d('EventEmitter',["EmitterSubscription","ErrorUtils","EventSubscriptionVendor","emptyFunction","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * @generated SignedSource<<494e66dea72a3e90b763a5ec50b1e0ca>> + * + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !! This file is a check-in of a static_upstream project! !! + * !! !! + * !! You should not modify this file directly. Instead: !! + * !! 1) Use `fjs use-upstream` to temporarily replace this with !! + * !! the latest version from upstream. !! + * !! 2) Make your changes, test them, etc. !! + * !! 3) Use `fjs push-upstream` to copy your changes back to !! + * !! static_upstream. !! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @providesModule EventEmitter + * @typechecks + */ + +var EmitterSubscription = require('EmitterSubscription'); +var ErrorUtils = require('ErrorUtils'); +var EventSubscriptionVendor = require('EventSubscriptionVendor'); +var emptyFunction = require('emptyFunction'); +var invariant = require('invariant'); + +/** + * @class EventEmitter + * @description + * An EventEmitter is responsible for managing a set of listeners and publishing + * events to them when it is told that such events happened. In addition to the + * data for the given event it also sends a event control object which allows + * the listeners/handlers to prevent the default behavior of the given event. + * + * The emitter is designed to be generic enough to support all the different + * contexts in which one might want to emit events. It is a simple multicast + * mechanism on top of which extra functionality can be composed. For example, a + * more advanced emitter may use an EventHolder and EventFactory. + */ + + /** + * @constructor + */ + function EventEmitter() {"use strict"; + this.$EventEmitter_subscriber = new EventSubscriptionVendor(); + } + + /** + * Adds a listener to be invoked when events of the specified type are + * emitted. An optional calling context may be provided. The data arguments + * emitted will be passed to the listener function. + * + * TODO: Annotate the listener arg's type. This is tricky because listeners + * can be invoked with varargs. + * + * @param {string} eventType - Name of the event to listen to + * @param {function} listener - Function to invoke when the specified event is + * emitted + * @param {*} context - Optional context object to use when invoking the + * listener + */ + EventEmitter.prototype.addListener=function( +eventType , listener, context ) {"use strict"; + return this.$EventEmitter_subscriber.addSubscription( + eventType, + new EmitterSubscription(this.$EventEmitter_subscriber, listener, context)); + }; + + /** + * Similar to addListener, except that the listener is removed after it is + * invoked once. + * + * @param {string} eventType - Name of the event to listen to + * @param {function} listener - Function to invoke only once when the + * specified event is emitted + * @param {*} context - Optional context object to use when invoking the + * listener + */ + EventEmitter.prototype.once=function(eventType , listener, context ) {"use strict"; + var emitter = this; + return this.addListener(eventType, function() { + emitter.removeCurrentListener(); + listener.apply(context, arguments); + }); + }; + + /** + * Removes all of the registered listeners, including those registered as + * listener maps. + * + * @param {?string} eventType - Optional name of the event whose registered + * listeners to remove + */ + EventEmitter.prototype.removeAllListeners=function(eventType ) {"use strict"; + this.$EventEmitter_subscriber.removeAllSubscriptions(eventType); + }; + + /** + * Provides an API that can be called during an eventing cycle to remove the + * last listener that was invoked. This allows a developer to provide an event + * object that can remove the listener (or listener map) during the + * invocation. + * + * If it is called when not inside of an emitting cycle it will throw. + * + * @throws {Error} When called not during an eventing cycle + * + * @example + * var subscription = emitter.addListenerMap({ + * someEvent: function(data, event) { + * console.log(data); + * emitter.removeCurrentListener(); + * } + * }); + * + * emitter.emit('someEvent', 'abc'); // logs 'abc' + * emitter.emit('someEvent', 'def'); // does not log anything + */ + EventEmitter.prototype.removeCurrentListener=function() {"use strict"; + invariant( + !!this.$EventEmitter_currentSubscription, + 'Not in an emitting cycle; there is no current subscription' + ); + this.$EventEmitter_subscriber.removeSubscription(this.$EventEmitter_currentSubscription); + }; + + /** + * Returns an array of listeners that are currently registered for the given + * event. + * + * @param {string} eventType - Name of the event to query + * @returns {array} + */ + EventEmitter.prototype.listeners=function(eventType ) /* TODO: Array */ {"use strict"; + var subscriptions = this.$EventEmitter_subscriber.getSubscriptionsForType(eventType); + return subscriptions + ? subscriptions.filter(emptyFunction.thatReturnsTrue).map( + function(subscription) { + return subscription.listener; + }) + : []; + }; + + /** + * Emits an event of the given type with the given data. All handlers of that + * particular type will be notified. + * + * @param {string} eventType - Name of the event to emit + * @param {...*} Arbitrary arguments to be passed to each registered listener + * + * @example + * emitter.addListener('someEvent', function(message) { + * console.log(message); + * }); + * + * emitter.emit('someEvent', 'abc'); // logs 'abc' + */ + EventEmitter.prototype.emit=function(eventType ) {"use strict"; + var subscriptions = this.$EventEmitter_subscriber.getSubscriptionsForType(eventType); + if (subscriptions) { + var keys = Object.keys(subscriptions); + for (var ii = 0; ii < keys.length; ii++) { + var key = keys[ii]; + var subscription = subscriptions[key]; + + // The subscription may have been removed during this event loop. + if (subscription) { + this.$EventEmitter_currentSubscription = subscription; + + ErrorUtils.applyWithGuard( + subscription.listener, + subscription.context, + Array.prototype.slice.call(arguments, 1), + null, + 'EventEmitter:' + eventType + ); + } + } + this.$EventEmitter_currentSubscription = null; + } + }; + + +module.exports = EventEmitter; +}); +__d('EmitterSubscription',["EventSubscription"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * @generated SignedSource<> + * + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !! This file is a check-in of a static_upstream project! !! + * !! !! + * !! You should not modify this file directly. Instead: !! + * !! 1) Use `fjs use-upstream` to temporarily replace this with !! + * !! the latest version from upstream. !! + * !! 2) Make your changes, test them, etc. !! + * !! 3) Use `fjs push-upstream` to copy your changes back to !! + * !! static_upstream. !! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @providesModule EmitterSubscription + * @typechecks + */ +'use strict'; + +var EventSubscription = require('EventSubscription'); + +/** + * EmitterSubscription represents a subscription with listener and context data. + */ +for(var EventSubscription____Key in EventSubscription){if(EventSubscription.hasOwnProperty(EventSubscription____Key)){EmitterSubscription[EventSubscription____Key]=EventSubscription[EventSubscription____Key];}}var ____SuperProtoOfEventSubscription=EventSubscription===null?null:EventSubscription.prototype;EmitterSubscription.prototype=Object.create(____SuperProtoOfEventSubscription);EmitterSubscription.prototype.constructor=EmitterSubscription;EmitterSubscription.__superConstructor__=EventSubscription; + + /** + * @param {EventSubscriptionVendor} subscriber - The subscriber that controls + * this subscription + * @param {function} listener - Function to invoke when the specified event is + * emitted + * @param {*} context - Optional context object to use when invoking the + * listener + */ + function EmitterSubscription(subscriber , listener, context ) { + EventSubscription.call(this,subscriber); + this.listener = listener; + this.context = context; + } + + +module.exports = EmitterSubscription; +}); +__d('EventSubscription',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * @generated SignedSource<<92108a17b1f3eee4b7e3dd7d484aa17a>> + * + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !! This file is a check-in of a static_upstream project! !! + * !! !! + * !! You should not modify this file directly. Instead: !! + * !! 1) Use `fjs use-upstream` to temporarily replace this with !! + * !! the latest version from upstream. !! + * !! 2) Make your changes, test them, etc. !! + * !! 3) Use `fjs push-upstream` to copy your changes back to !! + * !! static_upstream. !! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @providesModule EventSubscription + * @typechecks + */ +'use strict'; + +/** + * EventSubscription represents a subscription to a particular event. It can + * remove its own subscription. + */ + + + /** + * @param {EventSubscriptionVendor} subscriber the subscriber that controls + * this subscription. + */ + function EventSubscription(subscriber ) { + this.subscriber = subscriber; + } + + /** + * Removes this subscription from the subscriber that controls it. + */ + EventSubscription.prototype.remove=function() { + this.subscriber.removeSubscription(this); + }; + + +module.exports = EventSubscription; +}); +__d('ErrorUtils',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 ErrorUtils + */ + +var GLOBAL = this; + +/** + * The particular require runtime that we are using looks for a global + * `ErrorUtils` object and if it exists, then it requires modules with the + * error handler specified via ErrorUtils.setGlobalHandler by calling the + * require function with applyWithGuard. Since the require module is loaded + * before any of the modules, this ErrorUtils must be defined (and the handler + * set) globally before requiring anything. + * + * However, we still want to treat ErrorUtils as a module so that other modules + * that use it aren't just using a global variable, so simply export the global + * variable here. ErrorUtils is original defined in a file named error-guard.js. + */ +module.exports = GLOBAL.ErrorUtils; +}); +__d('EventSubscriptionVendor',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * @generated SignedSource<<24d5cc1cdd24704296686faf89dd36cf>> + * + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !! This file is a check-in of a static_upstream project! !! + * !! !! + * !! You should not modify this file directly. Instead: !! + * !! 1) Use `fjs use-upstream` to temporarily replace this with !! + * !! the latest version from upstream. !! + * !! 2) Make your changes, test them, etc. !! + * !! 3) Use `fjs push-upstream` to copy your changes back to !! + * !! static_upstream. !! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @providesModule EventSubscriptionVendor + * @typechecks + */ +'use strict'; + +var invariant = require('invariant'); + +/** + * EventSubscriptionVendor stores a set of EventSubscriptions that are + * subscribed to a particular event type. + */ + + + function EventSubscriptionVendor() { + this.$EventSubscriptionVendor_subscriptionsForType = {}; + this.$EventSubscriptionVendor_currentSubscription = null; + } + + /** + * Adds a subscription keyed by an event type. + * + * @param {string} eventType + * @param {EventSubscription} subscription + */ + EventSubscriptionVendor.prototype.addSubscription=function( +eventType , subscription ) { + invariant( + subscription.subscriber === this, + 'The subscriber of the subscription is incorrectly set.'); + if (!this.$EventSubscriptionVendor_subscriptionsForType[eventType]) { + this.$EventSubscriptionVendor_subscriptionsForType[eventType] = []; + } + var key = this.$EventSubscriptionVendor_subscriptionsForType[eventType].length; + this.$EventSubscriptionVendor_subscriptionsForType[eventType].push(subscription); + subscription.eventType = eventType; + subscription.key = key; + return subscription; + }; + + /** + * Removes a bulk set of the subscriptions. + * + * @param {?string} eventType - Optional name of the event type whose + * registered supscriptions to remove, if null remove all subscriptions. + */ + EventSubscriptionVendor.prototype.removeAllSubscriptions=function(eventType ) { + if (eventType === undefined) { + this.$EventSubscriptionVendor_subscriptionsForType = {}; + } else { + delete this.$EventSubscriptionVendor_subscriptionsForType[eventType]; + } + }; + + /** + * Removes a specific subscription. Instead of calling this function, call + * `subscription.remove()` directly. + * + * @param {object} subscription + */ + EventSubscriptionVendor.prototype.removeSubscription=function(subscription ) { + var eventType = subscription.eventType; + var key = subscription.key; + + var subscriptionsForType = this.$EventSubscriptionVendor_subscriptionsForType[eventType]; + if (subscriptionsForType) { + delete subscriptionsForType[key]; + } + }; + + /** + * Returns the array of subscriptions that are currently registered for the + * given event type. + * + * Note: This array can be potentially sparse as subscriptions are deleted + * from it when they are removed. + * + * TODO: This returns a nullable array. wat? + * + * @param {string} eventType + * @returns {?array} + */ + EventSubscriptionVendor.prototype.getSubscriptionsForType=function(eventType ) { + return this.$EventSubscriptionVendor_subscriptionsForType[eventType]; + }; + + +module.exports = EventSubscriptionVendor; +}); +__d('ExceptionsManager',["NativeModules","loadSourceMap","parseErrorStack","stringifySafe"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 ExceptionsManager + * @flow + */ +'use strict'; + +var RCTExceptionsManager = require('NativeModules').ExceptionsManager; + +var loadSourceMap = require('loadSourceMap'); +var parseErrorStack = require('parseErrorStack'); +var stringifySafe = require('stringifySafe'); + +var sourceMapPromise; + + + + + + + +function reportException(e , isFatal , stack ) { + if (RCTExceptionsManager) { + if (!stack) { + stack = parseErrorStack(e); + } + if (!RCTExceptionsManager.reportFatalException || + !RCTExceptionsManager.reportSoftException) { + // Backwards compatibility - no differentiation + // TODO(#7049989): deprecate reportUnhandledException on Android + RCTExceptionsManager.reportUnhandledException(e.message, stack); + } else { + if (isFatal) { + RCTExceptionsManager.reportFatalException(e.message, stack); + } else { + RCTExceptionsManager.reportSoftException(e.message, stack); + } + } + if (__DEV__) { + (sourceMapPromise = sourceMapPromise || loadSourceMap()) + .then(function(map) { + var prettyStack = parseErrorStack(e, map); + RCTExceptionsManager.updateExceptionMessage(e.message, prettyStack); + }) + ["catch"](function(error) { + // This can happen in a variety of normal situations, such as + // Network module not being available, or when running locally + console.warn('Unable to load source map: ' + error.message); + }); + } + } +} + +function handleException(e , isFatal ) { + var stack = parseErrorStack(e); + var msg = + 'Error: ' + e.message + + '\n stack: \n' + stackToString(stack) + + '\n URL: ' + e.sourceURL + + '\n line: ' + e.line + + '\n message: ' + e.message; + if (console.errorOriginal) { + console.errorOriginal(msg); + } else { + console.error(msg); + } + reportException(e, isFatal, stack); +} + +/** + * Shows a redbox with stacktrace for all console.error messages. Disable by + * setting `console.reportErrorsAsExceptions = false;` in your app. + */ +function installConsoleErrorReporter() { + if (console.reportException) { + return; // already installed + } + console.reportException = reportException; + console.errorOriginal = console.error.bind(console); + console.error = function reactConsoleError() { + console.errorOriginal.apply(null, arguments); + if (!console.reportErrorsAsExceptions) { + return; + } + var str = Array.prototype.map.call(arguments, stringifySafe).join(', '); + var error = new Error('console.error: ' + str); + error.framesToPop = 1; + reportException(error, /* isFatal */ false); + }; + if (console.reportErrorsAsExceptions === undefined) { + console.reportErrorsAsExceptions = true; // Individual apps can disable this + } +} + +function stackToString(stack) { + var maxLength = Math.max.apply(null, stack.map(function(frame) {return frame.methodName.length;})); + return stack.map(function(frame) {return stackFrameToString(frame, maxLength);}).join('\n'); +} + +function stackFrameToString(stackFrame, maxLength) { + var fileNameParts = stackFrame.file.split('/'); + var fileName = fileNameParts[fileNameParts.length - 1]; + + if (fileName.length > 18) { + fileName = fileName.substr(0, 17) + '\u2026' /* ... */; + } + + var spaces = fillSpaces(maxLength - stackFrame.methodName.length); + return ' ' + stackFrame.methodName + spaces + ' ' + fileName + ':' + stackFrame.lineNumber; +} + +function fillSpaces(n) { + return new Array(n + 1).join(' '); +} + +module.exports = { handleException:handleException, installConsoleErrorReporter:installConsoleErrorReporter }; +}); +__d('NativeModules',["BatchedBridge","nativeModulePrefixNormalizer"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 NativeModules + * @flow + */ +'use strict'; + +var NativeModules = require('BatchedBridge').RemoteModules; + +var nativeModulePrefixNormalizer = require('nativeModulePrefixNormalizer'); + +nativeModulePrefixNormalizer(NativeModules); + +module.exports = NativeModules; +}); +__d('BatchedBridge',["BatchedBridgeFactory","MessageQueue"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 BatchedBridge + */ +'use strict'; + +var BatchedBridgeFactory = require('BatchedBridgeFactory'); +var MessageQueue = require('MessageQueue'); + +/** + * Signature that matches the native IOS modules/methods that are exposed. We + * indicate which ones accept a callback. The order of modules and methods + * within them implicitly define their numerical *ID* that will be used to + * describe method calls across the wire. This is so that memory is used + * efficiently and we do not need to copy strings in native land - or across any + * wire. + */ + +var remoteModulesConfig = __fbBatchedBridgeConfig.remoteModuleConfig; +var localModulesConfig = __fbBatchedBridgeConfig.localModulesConfig; + + +var BatchedBridge = BatchedBridgeFactory.create( + MessageQueue, + remoteModulesConfig, + localModulesConfig +); + +BatchedBridge._config = remoteModulesConfig; + +module.exports = BatchedBridge; +}); +__d('BatchedBridgeFactory',["invariant","keyMirror","mapObject","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 BatchedBridgeFactory + */ +'use strict'; + +var invariant = require('invariant'); +var keyMirror = require('keyMirror'); +var mapObject = require('mapObject'); +var warning = require('warning'); + +var slice = Array.prototype.slice; + +var MethodTypes = keyMirror({ + remote: null, + local: null, +}); + +/** + * Creates remotely invokable modules. + */ +var BatchedBridgeFactory = { + MethodTypes: MethodTypes, + /** + * @param {MessageQueue} messageQueue Message queue that has been created with + * the `moduleConfig` (among others perhaps). + * @param {object} moduleConfig Configuration of module names/method + * names to callback types. + * @return {object} Remote representation of configured module. + */ + _createBridgedModule: function(messageQueue, moduleConfig, moduleName) { + var remoteModule = mapObject(moduleConfig.methods, function(methodConfig, memberName) { + return methodConfig.type === MethodTypes.local ? null : function() { + var lastArg = arguments.length > 0 ? arguments[arguments.length - 1] : null; + var secondLastArg = arguments.length > 1 ? arguments[arguments.length - 2] : null; + var hasSuccCB = typeof lastArg === 'function'; + var hasErrorCB = typeof secondLastArg === 'function'; + hasErrorCB && invariant( + hasSuccCB, + 'Cannot have a non-function arg after a function arg.' + ); + var numCBs = (hasSuccCB ? 1 : 0) + (hasErrorCB ? 1 : 0); + var args = slice.call(arguments, 0, arguments.length - numCBs); + var onSucc = hasSuccCB ? lastArg : null; + var onFail = hasErrorCB ? secondLastArg : null; + return messageQueue.call(moduleName, memberName, args, onFail, onSucc); + }; + }); + for (var constName in moduleConfig.constants) { + warning(!remoteModule[constName], 'saw constant and method named %s', constName); + remoteModule[constName] = moduleConfig.constants[constName]; + } + return remoteModule; + }, + + + create: function(MessageQueue, modulesConfig, localModulesConfig) { + var messageQueue = new MessageQueue(modulesConfig, localModulesConfig); + return { + callFunction: messageQueue.callFunction.bind(messageQueue), + callFunctionReturnFlushedQueue: + messageQueue.callFunctionReturnFlushedQueue.bind(messageQueue), + invokeCallback: messageQueue.invokeCallback.bind(messageQueue), + invokeCallbackAndReturnFlushedQueue: + messageQueue.invokeCallbackAndReturnFlushedQueue.bind(messageQueue), + flushedQueue: messageQueue.flushedQueue.bind(messageQueue), + RemoteModules: mapObject(modulesConfig, this._createBridgedModule.bind(this, messageQueue)), + setLoggingEnabled: messageQueue.setLoggingEnabled.bind(messageQueue), + getLoggedOutgoingItems: messageQueue.getLoggedOutgoingItems.bind(messageQueue), + getLoggedIncomingItems: messageQueue.getLoggedIncomingItems.bind(messageQueue), + replayPreviousLog: messageQueue.replayPreviousLog.bind(messageQueue), + processBatch: messageQueue.processBatch.bind(messageQueue), + }; + } +}; + +module.exports = BatchedBridgeFactory; +}); +__d('mapObject',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 mapObject + */ + +'use strict'; + +var hasOwnProperty = Object.prototype.hasOwnProperty; + +/** + * Executes the provided `callback` once for each enumerable own property in the + * object and constructs a new object from the results. The `callback` is + * invoked with three arguments: + * + * - the property value + * - the property name + * - the object being traversed + * + * Properties that are added after the call to `mapObject` will not be visited + * by `callback`. If the values of existing properties are changed, the value + * passed to `callback` will be the value at the time `mapObject` visits them. + * Properties that are deleted before being visited are not visited. + * + * @grep function objectMap() + * @grep function objMap() + * + * @param {?object} object + * @param {function} callback + * @param {*} context + * @return {?object} + */ +function mapObject(object, callback, context) { + if (!object) { + return null; + } + var result = {}; + for (var name in object) { + if (hasOwnProperty.call(object, name)) { + result[name] = callback.call(context, object[name], name, object); + } + } + return result; +} + +module.exports = mapObject; +}); +__d('MessageQueue',["ErrorUtils","ReactUpdates","invariant","warning","JSTimersExecution"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 MessageQueue + * @flow + */ +'use strict'; + +var ErrorUtils = require('ErrorUtils'); +var ReactUpdates = require('ReactUpdates'); + +var invariant = require('invariant'); +var warning = require('warning'); + +var JSTimersExecution = require('JSTimersExecution'); + +var INTERNAL_ERROR = 'Error in MessageQueue implementation'; + +// Prints all bridge traffic to console.log +var DEBUG_SPY_MODE = false; + + + + + + + + + + + + + +/** + * So as not to confuse static build system. + */ +var requireFunc = require; + +/** + * @param {Object!} module Module instance, must be loaded. + * @param {string} methodName Name of method in `module`. + * @param {array<*>} params Arguments to method. + * @returns {*} Return value of method invocation. + */ +var jsCall = function(module, methodName, params) { + return module[methodName].apply(module, params); +}; + +/** + * A utility for aggregating "work" to be done, and potentially transferring + * that work to another thread. Each instance of `MessageQueue` has the notion + * of a "target" thread - the thread that the work will be sent to. + * + * TODO: Long running callback results, and streaming callback results (ability + * for a callback to be invoked multiple times). + * + * @param {object} moduleNameToID Used to translate module/method names into + * efficient numeric IDs. + * @class MessageQueue + */ +var MessageQueue = function( + remoteModulesConfig , + localModulesConfig , + customRequire +) { + this._requireFunc = customRequire || requireFunc; + this._initBookeeping(); + this._initNamingMap(remoteModulesConfig, localModulesConfig); +}; + +// REQUEST: Parallell arrays: +var REQUEST_MODULE_IDS = 0; +var REQUEST_METHOD_IDS = 1; +var REQUEST_PARAMSS = 2; +// RESPONSE: Parallell arrays: +var RESPONSE_CBIDS = 3; +var RESPONSE_RETURN_VALUES = 4; + +var applyWithErrorReporter = function(fun , context , args ) { + try { + return fun.apply(context, args); + } catch (e) { + ErrorUtils.reportFatalError(e); + } +}; + +/** + * Utility to catch errors and prevent having to bind, or execute a bound + * function, while catching errors in a process and returning a resulting + * return value. This ensures that even if a process fails, we can still return + * *some* values (from `_flushedQueueUnguarded` for example). Glorified + * try/catch/finally that invokes the global `onerror`. + * + * @param {function} operation Function to execute, likely populates the + * message buffer. + * @param {Array<*>} operationArguments Arguments passed to `operation`. + * @param {function} getReturnValue Returns a return value - will be invoked + * even if the `operation` fails half way through completing its task. + * @return {object} Return value returned from `getReturnValue`. + */ +var guardReturn = function(operation, operationArguments, getReturnValue, context) { + if (operation) { + applyWithErrorReporter(operation, context, operationArguments); + } + if (getReturnValue) { + return applyWithErrorReporter(getReturnValue, context, null); + } + return null; +}; + +/** + * Bookkeeping logic for callbackIDs. We ensure that success and error + * callbacks are numerically adjacent. + * + * We could have also stored the association between success cbID and errorCBID + * in a map without relying on this adjacency, but the bookkeeping here avoids + * an additional two maps to associate in each direction, and avoids growing + * dictionaries (new fields). Instead, we compute pairs of callback IDs, by + * populating the `res` argument to `allocateCallbackIDs` (in conjunction with + * pooling). Behind this bookeeping API, we ensure that error and success + * callback IDs are always adjacent so that when one is invoked, we always know + * how to free the memory of the other. By using this API, it is impossible to + * create malformed callbackIDs that are not adjacent. + */ +var createBookkeeping = function() { + return { + /** + * Incrementing callback ID. Must start at 1 - otherwise converted null + * values which become zero are not distinguishable from a GUID of zero. + */ + GUID: 1, + errorCallbackIDForSuccessCallbackID: function(successID) { + return successID + 1; + }, + successCallbackIDForErrorCallbackID: function(errorID) { + return errorID - 1; + }, + allocateCallbackIDs: function(res) { + res.successCallbackID = this.GUID++; + res.errorCallbackID = this.GUID++; + }, + isSuccessCallback: function(id) { + return id % 2 === 1; + } + }; +}; + +var MessageQueueMixin = { + /** + * Creates an efficient wire protocol for communicating across a bridge. + * Avoids allocating strings. + * + * @param {object} remoteModulesConfig Configuration of modules and their + * methods. + */ + _initNamingMap: function( + remoteModulesConfig , + localModulesConfig + ) { + this._remoteModuleNameToModuleID = {}; + this._remoteModuleIDToModuleName = {}; // Reverse + + this._remoteModuleNameToMethodNameToID = {}; + this._remoteModuleNameToMethodIDToName = {}; // Reverse + + this._localModuleNameToModuleID = {}; + this._localModuleIDToModuleName = {}; // Reverse + + this._localModuleNameToMethodNameToID = {}; + this._localModuleNameToMethodIDToName = {}; // Reverse + + function fillMappings( + modulesConfig , + moduleNameToModuleID , + moduleIDToModuleName , + moduleNameToMethodNameToID , + moduleNameToMethodIDToName + ) { + for (var moduleName in modulesConfig) { + var moduleConfig = modulesConfig[moduleName]; + var moduleID = moduleConfig.moduleID; + moduleNameToModuleID[moduleName] = moduleID; + moduleIDToModuleName[moduleID] = moduleName; // Reverse + + moduleNameToMethodNameToID[moduleName] = {}; + moduleNameToMethodIDToName[moduleName] = {}; // Reverse + var methods = moduleConfig.methods; + for (var methodName in methods) { + var methodID = methods[methodName].methodID; + moduleNameToMethodNameToID[moduleName][methodName] = + methodID; + moduleNameToMethodIDToName[moduleName][methodID] = + methodName; // Reverse + } + } + } + fillMappings( + remoteModulesConfig, + this._remoteModuleNameToModuleID, + this._remoteModuleIDToModuleName, + this._remoteModuleNameToMethodNameToID, + this._remoteModuleNameToMethodIDToName + ); + + fillMappings( + localModulesConfig, + this._localModuleNameToModuleID, + this._localModuleIDToModuleName, + this._localModuleNameToMethodNameToID, + this._localModuleNameToMethodIDToName + ); + + }, + + _initBookeeping: function() { + this._POOLED_CBIDS = {errorCallbackID: null, successCallbackID: null}; + this._bookkeeping = createBookkeeping(); + + /** + * Stores callbacks so that we may simulate asynchronous return values from + * other threads. Remote invocations in other threads can pass return values + * back asynchronously to the requesting thread. + */ + this._threadLocalCallbacksByID = []; + this._threadLocalScopesByID = []; + + /** + * Memory efficient parallel arrays. Each index cuts through the three + * arrays and forms a remote invocation of methodName(params) whos return + * value will be reported back to the other thread by way of the + * corresponding id in cbIDs. Each entry (A-D in the graphic below), + * represents a work item of the following form: + * - moduleID: ID of module to invoke method from. + * - methodID: ID of method in module to invoke. + * - params: List of params to pass to method. + * - cbID: ID to respond back to originating thread with. + * + * TODO: We can make this even more efficient (memory) by creating a single + * array, that is always pushed `n` elements as a time. + */ + this._outgoingItems = [ + /*REQUEST_MODULE_IDS: */ [/* +-+ +-+ +-+ +-+ */], + /*REQUEST_METHOD_IDS: */ [/* |A| |B| |C| |D| */], + /*REQUEST_PARAMSS: */ [/* |-| |-| |-| |-| */], + + /*RESPONSE_CBIDS: */ [/* +-+ +-+ +-+ +-+ */], + /* |E| |F| |G| |H| */ + /*RESPONSE_RETURN_VALUES: */ [/* +-+ +-+ +-+ +-+ */] + ]; + + /** + * Used to allow returning the buffer, while at the same time clearing it in + * a memory efficient manner. + */ + this._outgoingItemsSwap = [[], [], [], [], []]; + }, + + invokeCallback: function(cbID, args) { + return guardReturn(this._invokeCallback, [cbID, args], null, this); + }, + + _invokeCallback: function(cbID, args) { + try { + var cb = this._threadLocalCallbacksByID[cbID]; + var scope = this._threadLocalScopesByID[cbID]; + warning( + cb, + 'Cannot find callback with CBID %s. Native module may have invoked ' + + 'both the success callback and the error callback.', + cbID + ); + if (DEBUG_SPY_MODE) { + console.log('N->JS: Callback#' + cbID + '(' + JSON.stringify(args) + ')'); + } + cb.apply(scope, args); + } catch(ie_requires_catch) { + throw ie_requires_catch; + } finally { + // Clear out the memory regardless of success or failure. + this._freeResourcesForCallbackID(cbID); + } + }, + + invokeCallbackAndReturnFlushedQueue: function(cbID, args) { + if (this._enableLogging) { + this._loggedIncomingItems.push([new Date().getTime(), cbID, args]); + } + return guardReturn( + this._invokeCallback, + [cbID, args], + this._flushedQueueUnguarded, + this + ); + }, + + callFunction: function(moduleID, methodID, params) { + return guardReturn(this._callFunction, [moduleID, methodID, params], null, this); + }, + + _callFunction: function(moduleID, methodID, params) { + var moduleName = this._localModuleIDToModuleName[moduleID]; + + var methodName = this._localModuleNameToMethodIDToName[moduleName][methodID]; + if (DEBUG_SPY_MODE) { + console.log( + 'N->JS: ' + moduleName + '.' + methodName + + '(' + JSON.stringify(params) + ')'); + } + var ret = jsCall(this._requireFunc(moduleName), methodName, params); + + return ret; + }, + + callFunctionReturnFlushedQueue: function(moduleID, methodID, params) { + if (this._enableLogging) { + this._loggedIncomingItems.push([new Date().getTime(), moduleID, methodID, params]); + } + return guardReturn( + this._callFunction, + [moduleID, methodID, params], + this._flushedQueueUnguarded, + this + ); + }, + + processBatch: function(batch) { + var self = this; + return guardReturn(function () { + ReactUpdates.batchedUpdates(function() { + batch.forEach(function(call) { + invariant( + call.module === 'BatchedBridge', + 'All the calls should pass through the BatchedBridge module' + ); + if (call.method === 'callFunctionReturnFlushedQueue') { + self._callFunction.apply(self, call.args); + } else if (call.method === 'invokeCallbackAndReturnFlushedQueue') { + self._invokeCallback.apply(self, call.args); + } else { + throw new Error( + 'Unrecognized method called on BatchedBridge: ' + call.method); + } + }); + }); + }, null, this._flushedQueueUnguarded, this); + }, + + setLoggingEnabled: function(enabled) { + this._enableLogging = enabled; + this._loggedIncomingItems = []; + this._loggedOutgoingItems = [[], [], [], [], []]; + }, + + getLoggedIncomingItems: function() { + return this._loggedIncomingItems; + }, + + getLoggedOutgoingItems: function() { + return this._loggedOutgoingItems; + }, + + replayPreviousLog: function(previousLog) { + this._outgoingItems = previousLog; + }, + + /** + * Simple helpers for clearing the queues. This doesn't handle the fact that + * memory in the current buffer is leaked until the next frame or update - but + * that will typically be on the order of < 500ms. + */ + _swapAndReinitializeBuffer: function() { + // Outgoing requests + var currentOutgoingItems = this._outgoingItems; + var nextOutgoingItems = this._outgoingItemsSwap; + + nextOutgoingItems[REQUEST_MODULE_IDS].length = 0; + nextOutgoingItems[REQUEST_METHOD_IDS].length = 0; + nextOutgoingItems[REQUEST_PARAMSS].length = 0; + + // Outgoing responses + nextOutgoingItems[RESPONSE_CBIDS].length = 0; + nextOutgoingItems[RESPONSE_RETURN_VALUES].length = 0; + + this._outgoingItemsSwap = currentOutgoingItems; + this._outgoingItems = nextOutgoingItems; + }, + + /** + * @param {string} moduleID JS module name. + * @param {methodName} methodName Method in module to invoke. + * @param {array<*>?} params Array representing arguments to method. + * @param {string} cbID Unique ID to pass back in potential response. + */ + _pushRequestToOutgoingItems: function(moduleID, methodName, params) { + this._outgoingItems[REQUEST_MODULE_IDS].push(moduleID); + this._outgoingItems[REQUEST_METHOD_IDS].push(methodName); + this._outgoingItems[REQUEST_PARAMSS].push(params); + + if (this._enableLogging) { + this._loggedOutgoingItems[REQUEST_MODULE_IDS].push(moduleID); + this._loggedOutgoingItems[REQUEST_METHOD_IDS].push(methodName); + this._loggedOutgoingItems[REQUEST_PARAMSS].push(params); + } + }, + + /** + * @param {string} cbID Unique ID that other side of bridge has remembered. + * @param {*} returnValue Return value to pass to callback on other side of + * bridge. + */ + _pushResponseToOutgoingItems: function(cbID, returnValue) { + this._outgoingItems[RESPONSE_CBIDS].push(cbID); + this._outgoingItems[RESPONSE_RETURN_VALUES].push(returnValue); + }, + + _freeResourcesForCallbackID: function(cbID) { + var correspondingCBID = this._bookkeeping.isSuccessCallback(cbID) ? + this._bookkeeping.errorCallbackIDForSuccessCallbackID(cbID) : + this._bookkeeping.successCallbackIDForErrorCallbackID(cbID); + this._threadLocalCallbacksByID[cbID] = null; + this._threadLocalScopesByID[cbID] = null; + if (this._threadLocalCallbacksByID[correspondingCBID]) { + this._threadLocalCallbacksByID[correspondingCBID] = null; + this._threadLocalScopesByID[correspondingCBID] = null; + } + }, + + /** + * @param {Function} onFail Function to store in current thread for later + * lookup, when request fails. + * @param {Function} onSucc Function to store in current thread for later + * lookup, when request succeeds. + * @param {Object?=} scope Scope to invoke `cb` with. + * @param {Object?=} res Resulting callback ids. Use `this._POOLED_CBIDS`. + */ + _storeCallbacksInCurrentThread: function(onFail, onSucc, scope) { + invariant(onFail || onSucc, INTERNAL_ERROR); + this._bookkeeping.allocateCallbackIDs(this._POOLED_CBIDS); + var succCBID = this._POOLED_CBIDS.successCallbackID; + var errorCBID = this._POOLED_CBIDS.errorCallbackID; + this._threadLocalCallbacksByID[errorCBID] = onFail; + this._threadLocalCallbacksByID[succCBID] = onSucc; + this._threadLocalScopesByID[errorCBID] = scope; + this._threadLocalScopesByID[succCBID] = scope; + }, + + + /** + * IMPORTANT: There is possibly a timing issue with this form of flushing. We + * are currently not seeing any problems but the potential issue to look out + * for is: + * - While flushing this._outgoingItems contains the work for the other thread + * to perform. + * - To mitigate this, we never allow enqueueing messages if the queue is + * already reserved - as long as it is reserved, it could be in the midst of + * a flush. + * + * If this ever occurs we can easily eliminate the race condition. We can + * completely solve any ambiguity by sending messages such that we'll never + * try to reserve the queue when already reserved. Here's the pseudocode: + * + * var defensiveCopy = efficientDefensiveCopy(this._outgoingItems); + * this._swapAndReinitializeBuffer(); + */ + flushedQueue: function() { + return guardReturn(null, null, this._flushedQueueUnguarded, this); + }, + + _flushedQueueUnguarded: function() { + // Call the functions registred via setImmediate + JSTimersExecution.callImmediates(); + + var currentOutgoingItems = this._outgoingItems; + this._swapAndReinitializeBuffer(); + var ret = currentOutgoingItems[REQUEST_MODULE_IDS].length || + currentOutgoingItems[RESPONSE_RETURN_VALUES].length ? currentOutgoingItems : null; + + if (DEBUG_SPY_MODE && ret) { + for (var i = 0; i < currentOutgoingItems[0].length; i++) { + var moduleName = this._remoteModuleIDToModuleName[currentOutgoingItems[0][i]]; + var methodName = + this._remoteModuleNameToMethodIDToName[moduleName][currentOutgoingItems[1][i]]; + console.log( + 'JS->N: ' + moduleName + '.' + methodName + + '(' + JSON.stringify(currentOutgoingItems[2][i]) + ')'); + } + } + + return ret; + }, + + call: function(moduleName, methodName, params, onFail, onSucc, scope) { + invariant( + (!onFail || typeof onFail === 'function') && + (!onSucc || typeof onSucc === 'function'), + 'Callbacks must be functions' + ); + // Store callback _before_ sending the request, just in case the MailBox + // returns the response in a blocking manner. + if (onSucc) { + this._storeCallbacksInCurrentThread(onFail, onSucc, scope, this._POOLED_CBIDS); + onFail && params.push(this._POOLED_CBIDS.errorCallbackID); + params.push(this._POOLED_CBIDS.successCallbackID); + } + var moduleID = this._remoteModuleNameToModuleID[moduleName]; + if (moduleID === undefined || moduleID === null) { + throw new Error('Unrecognized module name:' + moduleName); + } + var methodID = this._remoteModuleNameToMethodNameToID[moduleName][methodName]; + if (methodID === undefined || moduleID === null) { + throw new Error('Unrecognized method name:' + methodName); + } + this._pushRequestToOutgoingItems(moduleID, methodID, params); + }, + __numPendingCallbacksOnlyUseMeInTestCases: function() { + var callbacks = this._threadLocalCallbacksByID; + var total = 0; + for (var i = 0; i < callbacks.length; i++) { + if (callbacks[i]) { + total++; + } + } + return total; + } +}; + +Object.assign(MessageQueue.prototype, MessageQueueMixin); +module.exports = MessageQueue; +}); +__d('JSTimersExecution',["invariant","keyMirror","performanceNow","warning","JSTimers","JSTimers"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 JSTimersExecution + */ +'use strict'; + +var invariant = require('invariant'); +var keyMirror = require('keyMirror'); +var performanceNow = require('performanceNow'); +var warning = require('warning'); + +/** + * JS implementation of timer functions. Must be completely driven by an + * external clock signal, all that's stored here is timerID, timer type, and + * callback. + */ +var JSTimersExecution = { + GUID: 1, + Type: keyMirror({ + setTimeout: null, + setInterval: null, + requestAnimationFrame: null, + setImmediate: null, + }), + + // Parallel arrays: + callbacks: [], + types: [], + timerIDs: [], + immediates: [], + + /** + * Calls the callback associated with the ID. Also unregister that callback + * if it was a one time timer (setTimeout), and not unregister it if it was + * recurring (setInterval). + */ + callTimer: function(timerID) { + warning(timerID <= JSTimersExecution.GUID, 'Tried to call timer with ID ' + timerID + ' but no such timer exists'); + var timerIndex = JSTimersExecution.timerIDs.indexOf(timerID); + // timerIndex of -1 means that no timer with that ID exists. There are + // two situations when this happens, when a garbage timer ID was given + // and when a previously existing timer was deleted before this callback + // fired. In both cases we want to ignore the timer id, but in the former + // case we warn as well. + if (timerIndex === -1) { + return; + } + var type = JSTimersExecution.types[timerIndex]; + var callback = JSTimersExecution.callbacks[timerIndex]; + + // Clear the metadata + if (type === JSTimersExecution.Type.setTimeout || + type === JSTimersExecution.Type.setImmediate || + type === JSTimersExecution.Type.requestAnimationFrame) { + JSTimersExecution._clearIndex(timerIndex); + } + + try { + if (type === JSTimersExecution.Type.setTimeout || + type === JSTimersExecution.Type.setInterval || + type === JSTimersExecution.Type.setImmediate) { + callback(); + } else if (type === JSTimersExecution.Type.requestAnimationFrame) { + var currentTime = performanceNow(); + callback(currentTime); + } else { + console.error('Tried to call a callback with invalid type: ' + type); + return; + } + } catch (e) { + // Don't rethrow so that we can run every other timer. + JSTimersExecution.errors = JSTimersExecution.errors || []; + JSTimersExecution.errors.push(e); + } + }, + + /** + * This is called from the native side. We are passed an array of timerIDs, + * and + */ + callTimers: function(timerIDs) { + invariant(timerIDs.length !== 0, 'Probably shouldn\'t call "callTimers" with no timerIDs'); + + JSTimersExecution.errors = null; + timerIDs.forEach(JSTimersExecution.callTimer); + + var errors = JSTimersExecution.errors; + if (errors) { + var errorCount = errors.length; + if (errorCount > 1) { + // Throw all the other errors in a setTimeout, which will throw each + // error one at a time + for (var ii = 1; ii < errorCount; ii++) { + require('JSTimers').setTimeout( + (function(error) { throw error; }).bind(null, errors[ii]), + 0 + ); + } + } + throw errors[0]; + } + }, + + /** + * This is called after we execute any command we receive from native but + * before we hand control back to native. + */ + callImmediates: function() { + JSTimersExecution.errors = null; + while (JSTimersExecution.immediates.length !== 0) { + JSTimersExecution.callTimer(JSTimersExecution.immediates.shift()); + } + if (JSTimersExecution.errors) { + JSTimersExecution.errors.forEach(function(error) + {return require('JSTimers').setTimeout(function() { throw error; }, 0);} + ); + } + }, + + _clearIndex: function(i) { + JSTimersExecution.timerIDs[i] = null; + JSTimersExecution.callbacks[i] = null; + JSTimersExecution.types[i] = null; + }, +}; + +module.exports = JSTimersExecution; +}); +__d('performanceNow',["performance"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 performanceNow + * @typechecks + */ + +var performance = require('performance'); + +/** + * Detect if we can use `window.performance.now()` and gracefully fallback to + * `Date.now()` if it doesn't exist. We need to support Firefox < 15 for now + * because of Facebook's testing infrastructure. + */ +if (!performance || !performance.now) { + performance = Date; +} + +var performanceNow = performance.now.bind(performance); + +module.exports = performanceNow; +}); +__d('performance',["ExecutionEnvironment"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 performance + * @typechecks + */ + +"use strict"; + +var ExecutionEnvironment = require('ExecutionEnvironment'); + +var performance; + +if (ExecutionEnvironment.canUseDOM) { + performance = + window.performance || + window.msPerformance || + window.webkitPerformance; +} + +module.exports = performance || {}; +}); +__d('ExecutionEnvironment',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ExecutionEnvironment + */ + +/*jslint evil: true */ + +"use strict"; + +var canUseDOM = !!( + typeof window !== 'undefined' && + window.document && + window.document.createElement +); + +/** + * Simple, lightweight module assisting with the detection and context of + * Worker. Helps avoid circular dependencies and allows code to reason about + * whether or not they are in a Worker, even if they never include the main + * `ReactWorker` dependency. + */ +var ExecutionEnvironment = { + + canUseDOM: canUseDOM, + + canUseWorkers: typeof Worker !== 'undefined', + + canUseEventListeners: + canUseDOM && !!(window.addEventListener || window.attachEvent), + + canUseViewport: canUseDOM && !!window.screen, + + isInWorker: !canUseDOM // For now, this is true - might change in the future. + +}; + +module.exports = ExecutionEnvironment; +}); +__d('JSTimers',["NativeModules","JSTimersExecution"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 JSTimers + */ +'use strict'; + +// Note that the module JSTimers is split into two in order to solve a cycle +// in dependencies. NativeModules > BatchedBridge > MessageQueue > JSTimersExecution +var RCTTiming = require('NativeModules').Timing; +var JSTimersExecution = require('JSTimersExecution'); + +/** + * JS implementation of timer functions. Must be completely driven by an + * external clock signal, all that's stored here is timerID, timer type, and + * callback. + */ +var JSTimers = { + Types: JSTimersExecution.Types, + + /** + * Returns a free index if one is available, and the next consecutive index + * otherwise. + */ + _getFreeIndex: function() { + var freeIndex = JSTimersExecution.timerIDs.indexOf(null); + if (freeIndex === -1) { + freeIndex = JSTimersExecution.timerIDs.length; + } + return freeIndex; + }, + + /** + * @param {function} func Callback to be invoked after `duration` ms. + * @param {number} duration Number of milliseconds. + */ + setTimeout: function(func, duration ) {for (var args=[],$__0=2,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); + var newID = JSTimersExecution.GUID++; + var freeIndex = JSTimers._getFreeIndex(); + JSTimersExecution.timerIDs[freeIndex] = newID; + JSTimersExecution.callbacks[freeIndex] = func; + JSTimersExecution.callbacks[freeIndex] = function() { + return func.apply(undefined, args); + }; + JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.setTimeout; + RCTTiming.createTimer(newID, duration, Date.now(), /** recurring */ false); + return newID; + }, + + /** + * @param {function} func Callback to be invoked every `duration` ms. + * @param {number} duration Number of milliseconds. + */ + setInterval: function(func, duration ) {for (var args=[],$__0=2,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); + var newID = JSTimersExecution.GUID++; + var freeIndex = JSTimers._getFreeIndex(); + JSTimersExecution.timerIDs[freeIndex] = newID; + JSTimersExecution.callbacks[freeIndex] = func; + JSTimersExecution.callbacks[freeIndex] = function() { + return func.apply(undefined, args); + }; + JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.setInterval; + RCTTiming.createTimer(newID, duration, Date.now(), /** recurring */ true); + return newID; + }, + + /** + * @param {function} func Callback to be invoked before the end of the + * current JavaScript execution loop. + */ + setImmediate: function(func ) {for (var args=[],$__0=1,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); + var newID = JSTimersExecution.GUID++; + var freeIndex = JSTimers._getFreeIndex(); + JSTimersExecution.timerIDs[freeIndex] = newID; + JSTimersExecution.callbacks[freeIndex] = func; + JSTimersExecution.callbacks[freeIndex] = function() { + return func.apply(undefined, args); + }; + JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.setImmediate; + JSTimersExecution.immediates.push(newID); + return newID; + }, + + /** + * @param {function} func Callback to be invoked every frame. + */ + requestAnimationFrame: function(func) { + var newID = JSTimersExecution.GUID++; + var freeIndex = JSTimers._getFreeIndex(); + JSTimersExecution.timerIDs[freeIndex] = newID; + JSTimersExecution.callbacks[freeIndex] = func; + JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.requestAnimationFrame; + RCTTiming.createTimer(newID, 1, Date.now(), /** recurring */ false); + return newID; + }, + + clearTimeout: function(timerID) { + JSTimers._clearTimerID(timerID); + }, + + clearInterval: function(timerID) { + JSTimers._clearTimerID(timerID); + }, + + clearImmediate: function(timerID) { + JSTimers._clearTimerID(timerID); + JSTimersExecution.immediates.splice( + JSTimersExecution.immediates.indexOf(timerID), + 1 + ); + }, + + cancelAnimationFrame: function(timerID) { + JSTimers._clearTimerID(timerID); + }, + + _clearTimerID: function(timerID) { + // JSTimersExecution.timerIDs contains nulls after timers have been removed; + // ignore nulls upfront so indexOf doesn't find them + if (timerID == null) { + return; + } + + var index = JSTimersExecution.timerIDs.indexOf(timerID); + // See corresponding comment in `callTimers` for reasoning behind this + if (index !== -1) { + JSTimersExecution._clearIndex(index); + if (JSTimersExecution.types[index] !== JSTimersExecution.Type.setImmediate) { + RCTTiming.deleteTimer(timerID); + } + } + }, +}; + +module.exports = JSTimers; +}); +__d('nativeModulePrefixNormalizer',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 nativeModulePrefixNormalizer + * @flow + */ +'use strict'; + +// Dirty hack to support old (RK) and new (RCT) native module name conventions +function nativeModulePrefixNormalizer( + modules +) { + Object.keys(modules).forEach(function(moduleName) { + var strippedName = moduleName.replace(/^(RCT|RK)/, ''); + if (modules['RCT' + strippedName] && modules['RK' + strippedName]) { + throw new Error( + 'Module cannot be registered as both RCT and RK: ' + moduleName + ); + } + if (strippedName !== moduleName) { + modules[strippedName] = modules[moduleName]; + delete modules[moduleName]; + } + }); +} + +module.exports = nativeModulePrefixNormalizer; +}); +__d('loadSourceMap',["Promise","NativeModules","SourceMap","react-native/Libraries/JavaScriptAppEngine/Initialization/source-map-url"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 loadSourceMap + * @flow + */ + +'use strict'; + +var Promise = require('Promise'); +var NativeModules = require('NativeModules'); +var SourceMapConsumer = require('SourceMap').SourceMapConsumer; +var SourceMapURL = require('react-native/Libraries/JavaScriptAppEngine/Initialization/source-map-url'); + +var RCTSourceCode = NativeModules.SourceCode; +var RCTDataManager = NativeModules.DataManager; + +function loadSourceMap() { + return fetchSourceMap() + .then(function(map) {return new SourceMapConsumer(map);}); +} + +function fetchSourceMap() { + if (global.RAW_SOURCE_MAP) { + return Promise.resolve(global.RAW_SOURCE_MAP); + } + + if (!RCTSourceCode) { + return Promise.reject(new Error('RCTSourceCode module is not available')); + } + + if (!RCTDataManager) { + // Used internally by fetch + return Promise.reject(new Error('RCTDataManager module is not available')); + } + + return new Promise(RCTSourceCode.getScriptText) + .then(extractSourceMapURL) + .then(function(url) { + if (url === null) { + return Promise.reject(new Error('No source map URL found. May be running from bundled file.')); + } + return Promise.resolve(url); + }) + .then(fetch) + .then(function(response) {return response.text();}) +} + +function extractSourceMapURL($__0 ) {var url=$__0.url,text=$__0.text,fullSourceMappingURL=$__0.fullSourceMappingURL; + if (fullSourceMappingURL) { + return fullSourceMappingURL; + } + var mapURL = SourceMapURL.getFrom(text); + if (!mapURL) { + return null; + } + var baseURL = url.match(/(.+:\/\/.*?)\//)[1]; + return baseURL + mapURL; +} + +module.exports = loadSourceMap; +}); +__d('Promise',["setImmediate","promise/setimmediate/es6-extensions","promise/setimmediate/done"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * + * Copyright 2013-2014 Facebook, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * @providesModule Promise + * + * This module wraps and augments the minimally ES6-compliant Promise + * implementation provided by the promise npm package. + */ + +'use strict'; + +global.setImmediate = require('setImmediate'); +var Promise = require('promise/setimmediate/es6-extensions'); +require('promise/setimmediate/done'); + +/** + * Handle either fulfillment or rejection with the same callback. + */ +Promise.prototype["finally"] = function(onSettled) { + return this.then(onSettled, onSettled); +}; + + +module.exports = Promise; +}); +__d('setImmediate',["ImmediateImplementation"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * @generated SignedSource<<9715e66cd259f4d1a1c3d39c97cd0b92>> + * + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !! This file is a check-in of a static_upstream project! !! + * !! !! + * !! You should not modify this file directly. Instead: !! + * !! 1) Use `fjs use-upstream` to temporarily replace this with !! + * !! the latest version from upstream. !! + * !! 2) Make your changes, test them, etc. !! + * !! 3) Use `fjs push-upstream` to copy your changes back to !! + * !! static_upstream. !! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @providesModule setImmediate + */ + +module.exports = global.setImmediate || + require('ImmediateImplementation').setImmediate; +}); +__d('ImmediateImplementation',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * @generated SignedSource<<57d0446bbd1186485d372efe6b323dca>> + * + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !! This file is a check-in of a static_upstream project! !! + * !! !! + * !! You should not modify this file directly. Instead: !! + * !! 1) Use `fjs use-upstream` to temporarily replace this with !! + * !! the latest version from upstream. !! + * !! 2) Make your changes, test them, etc. !! + * !! 3) Use `fjs push-upstream` to copy your changes back to !! + * !! static_upstream. !! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * Copyright (c) 2012 Barnesandnoble.com, llc, Donavon West, and Domenic + * Denicola + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * 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 + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 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. + * + * @preserve-header + * @providesModule ImmediateImplementation + */ + +(function(global, undefined) { + "use strict"; + + var nextHandle = 1; // Spec says greater than zero + var tasksByHandle = {}; + var queueHead = {}; + var queueTail = queueHead; + var currentlyRunningATask = false; + var doc = global.document; + var setImmediate; + + function addFromSetImmediateArguments(args) { + var handler = args[0]; + args = Array.prototype.slice.call(args, 1); + tasksByHandle[nextHandle] = function() { + handler.apply(undefined, args); + }; + queueTail = (queueTail.next = { handle: nextHandle++ }); + return queueTail.handle; + } + + function flushQueue() { + var next, task; + while (!currentlyRunningATask && (next = queueHead.next)) { + queueHead = next; // If this task fails, don't retry it. + if ((task = tasksByHandle[next.handle])) { + currentlyRunningATask = true; + try { + task(); + currentlyRunningATask = false; + } finally { + clearImmediate(next.handle); + if (currentlyRunningATask) { + currentlyRunningATask = false; + // The call to task() must have thrown an + // exception if we reach this point, so, just in + // case there are tasks remaining to be executed, + // we schedule another flushQueue in a later tick + // of the event loop, and let the exception + // propagate uncaught. + if (queueHead.next) { + setImmediate(flushQueue); + } + } + } + } + } + } + + function clearImmediate(handle) { + delete tasksByHandle[handle]; + } + + function canUsePostMessage() { + // The test against `importScripts` prevents this implementation from being installed inside a web worker, + // where `global.postMessage` means something completely different and can't be used for this purpose. + if (global.postMessage && !global.importScripts) { + var postMessageIsAsynchronous = true; + + var onMessage = function() { + postMessageIsAsynchronous = false; + if (global.removeEventListener) { + global.removeEventListener("message", onMessage, false); + } else { + global.detachEvent("onmessage", onMessage); + } + }; + + if (global.addEventListener) { + global.addEventListener("message", onMessage, false); + } else if (global.attachEvent) { + global.attachEvent("onmessage", onMessage); + } else { + return false; + } + + global.postMessage("", "*"); + return postMessageIsAsynchronous; + } + } + + function installPostMessageImplementation() { + // Installs an event handler on `global` for the `message` event: see + // * https://developer.mozilla.org/en/DOM/window.postMessage + var messagePrefix = "setImmediate$" + Math.random() + "$"; + var onGlobalMessage = function(event) { + if (event.source === global && + typeof event.data === "string" && + event.data.indexOf(messagePrefix) === 0) { + flushQueue(); + } + }; + + if (global.addEventListener) { + global.addEventListener("message", onGlobalMessage, false); + } else { + global.attachEvent("onmessage", onGlobalMessage); + } + + setImmediate = function() { + var handle = addFromSetImmediateArguments(arguments); + global.postMessage(messagePrefix + handle, "*"); + return handle; + }; + } + + function installMessageChannelImplementation() { + var channel = new MessageChannel(); + channel.port1.onmessage = flushQueue; + setImmediate = function() { + var handle = addFromSetImmediateArguments(arguments); + channel.port2.postMessage(handle); + return handle; + }; + } + + function installReadyStateChangeImplementation() { + var html = doc.documentElement; + setImmediate = function() { + var handle = addFromSetImmediateArguments(arguments); + // Create a +// +// +// Here's how it works. +// +// ``` +// // Get a reference to the logo element. +// var el = document.getElementById('logo'); +// +// // create a SpringSystem and a Spring with a bouncy config. +// var springSystem = new rebound.SpringSystem(); +// var spring = springSystem.createSpring(50, 3); +// +// // Add a listener to the spring. Every time the physics +// // solver updates the Spring's value onSpringUpdate will +// // be called. +// spring.addListener({ +// onSpringUpdate: function(spring) { +// var val = spring.getCurrentValue(); +// val = rebound.MathUtil +// .mapValueInRange(val, 0, 1, 1, 0.5); +// scale(el, val); +// } +// }); +// +// // Listen for mouse down/up/out and toggle the +// //springs endValue from 0 to 1. +// el.addEventListener('mousedown', function() { +// spring.setEndValue(1); +// }); +// +// el.addEventListener('mouseout', function() { +// spring.setEndValue(0); +// }); +// +// el.addEventListener('mouseup', function() { +// spring.setEndValue(0); +// }); +// +// // Helper for scaling an element with css transforms. +// function scale(el, val) { +// el.style.mozTransform = +// el.style.msTransform = +// el.style.webkitTransform = +// el.style.transform = 'scale3d(' + +// val + ', ' + val + ', 1)'; +// } +// ``` + +(function() { + var rebound = {}; + var util = rebound.util = {}; + var concat = Array.prototype.concat; + var slice = Array.prototype.slice; + + // Bind a function to a context object. + util.bind = function bind(func, context) { + var args = slice.call(arguments, 2); + return function() { + func.apply(context, concat.call(args, slice.call(arguments))); + }; + }; + + // Add all the properties in the source to the target. + util.extend = function extend(target, source) { + for (var key in source) { + if (source.hasOwnProperty(key)) { + target[key] = source[key]; + } + } + }; + + // SpringSystem + // ------------ + // **SpringSystem** is a set of Springs that all run on the same physics + // timing loop. To get started with a Rebound animation you first + // create a new SpringSystem and then add springs to it. + var SpringSystem = rebound.SpringSystem = function SpringSystem(looper) { + this._springRegistry = {}; + this._activeSprings = []; + this.listeners = []; + this._idleSpringIndices = []; + this.looper = looper || new AnimationLooper(); + this.looper.springSystem = this; + }; + + util.extend(SpringSystem.prototype, { + + _springRegistry: null, + + _isIdle: true, + + _lastTimeMillis: -1, + + _activeSprings: null, + + listeners: null, + + _idleSpringIndices: null, + + // A SpringSystem is iterated by a looper. The looper is responsible + // for executing each frame as the SpringSystem is resolved to idle. + // There are three types of Loopers described below AnimationLooper, + // SimulationLooper, and SteppingSimulationLooper. AnimationLooper is + // the default as it is the most useful for common UI animations. + setLooper: function(looper) { + this.looper = looper; + looper.springSystem = this; + }, + + // Add a new spring to this SpringSystem. This Spring will now be solved for + // during the physics iteration loop. By default the spring will use the + // default Origami spring config with 40 tension and 7 friction, but you can + // also provide your own values here. + createSpring: function(tension, friction) { + var springConfig; + if (tension === undefined || friction === undefined) { + springConfig = SpringConfig.DEFAULT_ORIGAMI_SPRING_CONFIG; + } else { + springConfig = + SpringConfig.fromOrigamiTensionAndFriction(tension, friction); + } + return this.createSpringWithConfig(springConfig); + }, + + // Add a spring with a specified bounciness and speed. To replicate Origami + // compositions based on PopAnimation patches, use this factory method to + // create matching springs. + createSpringWithBouncinessAndSpeed: function(bounciness, speed) { + var springConfig; + if (bounciness === undefined || speed === undefined) { + springConfig = SpringConfig.DEFAULT_ORIGAMI_SPRING_CONFIG; + } else { + springConfig = + SpringConfig.fromBouncinessAndSpeed(bounciness, speed); + } + return this.createSpringWithConfig(springConfig); + }, + + // Add a spring with the provided SpringConfig. + createSpringWithConfig: function(springConfig) { + var spring = new Spring(this); + this.registerSpring(spring); + spring.setSpringConfig(springConfig); + return spring; + }, + + // You can check if a SpringSystem is idle or active by calling + // getIsIdle. If all of the Springs in the SpringSystem are at rest, + // i.e. the physics forces have reached equilibrium, then this + // method will return true. + getIsIdle: function() { + return this._isIdle; + }, + + // Retrieve a specific Spring from the SpringSystem by id. This + // can be useful for inspecting the state of a spring before + // or after an integration loop in the SpringSystem executes. + getSpringById: function (id) { + return this._springRegistry[id]; + }, + + // Get a listing of all the springs registered with this + // SpringSystem. + getAllSprings: function() { + var vals = []; + for (var id in this._springRegistry) { + if (this._springRegistry.hasOwnProperty(id)) { + vals.push(this._springRegistry[id]); + } + } + return vals; + }, + + // registerSpring is called automatically as soon as you create + // a Spring with SpringSystem#createSpring. This method sets the + // spring up in the registry so that it can be solved in the + // solver loop. + registerSpring: function(spring) { + this._springRegistry[spring.getId()] = spring; + }, + + // Deregister a spring with this SpringSystem. The SpringSystem will + // no longer consider this Spring during its integration loop once + // this is called. This is normally done automatically for you when + // you call Spring#destroy. + deregisterSpring: function(spring) { + removeFirst(this._activeSprings, spring); + delete this._springRegistry[spring.getId()]; + }, + + advance: function(time, deltaTime) { + while(this._idleSpringIndices.length > 0) this._idleSpringIndices.pop(); + for (var i = 0, len = this._activeSprings.length; i < len; i++) { + var spring = this._activeSprings[i]; + if (spring.systemShouldAdvance()) { + spring.advance(time / 1000.0, deltaTime / 1000.0); + } else { + this._idleSpringIndices.push(this._activeSprings.indexOf(spring)); + } + } + while(this._idleSpringIndices.length > 0) { + var idx = this._idleSpringIndices.pop(); + idx >= 0 && this._activeSprings.splice(idx, 1); + } + }, + + // This is our main solver loop called to move the simulation + // forward through time. Before each pass in the solver loop + // onBeforeIntegrate is called on an any listeners that have + // registered themeselves with the SpringSystem. This gives you + // an opportunity to apply any constraints or adjustments to + // the springs that should be enforced before each iteration + // loop. Next the advance method is called to move each Spring in + // the systemShouldAdvance forward to the current time. After the + // integration step runs in advance, onAfterIntegrate is called + // on any listeners that have registered themselves with the + // SpringSystem. This gives you an opportunity to run any post + // integration constraints or adjustments on the Springs in the + // SpringSystem. + loop: function(currentTimeMillis) { + var listener; + if (this._lastTimeMillis === -1) { + this._lastTimeMillis = currentTimeMillis -1; + } + var ellapsedMillis = currentTimeMillis - this._lastTimeMillis; + this._lastTimeMillis = currentTimeMillis; + + var i = 0, len = this.listeners.length; + for (i = 0; i < len; i++) { + listener = this.listeners[i]; + listener.onBeforeIntegrate && listener.onBeforeIntegrate(this); + } + + this.advance(currentTimeMillis, ellapsedMillis); + if (this._activeSprings.length === 0) { + this._isIdle = true; + this._lastTimeMillis = -1; + } + + for (i = 0; i < len; i++) { + listener = this.listeners[i]; + listener.onAfterIntegrate && listener.onAfterIntegrate(this); + } + + if (!this._isIdle) { + this.looper.run(); + } + }, + + // activateSpring is used to notify the SpringSystem that a Spring + // has become displaced. The system responds by starting its solver + // loop up if it is currently idle. + activateSpring: function(springId) { + var spring = this._springRegistry[springId]; + if (this._activeSprings.indexOf(spring) == -1) { + this._activeSprings.push(spring); + } + if (this.getIsIdle()) { + this._isIdle = false; + this.looper.run(); + } + }, + + // Add a listener to the SpringSystem so that you can receive + // before/after integration notifications allowing Springs to be + // constrained or adjusted. + addListener: function(listener) { + this.listeners.push(listener); + }, + + // Remove a previously added listener on the SpringSystem. + removeListener: function(listener) { + removeFirst(this.listeners, listener); + }, + + // Remove all previously added listeners on the SpringSystem. + removeAllListeners: function() { + this.listeners = []; + } + + }); + + // Spring + // ------ + // **Spring** provides a model of a classical spring acting to + // resolve a body to equilibrium. Springs have configurable + // tension which is a force multipler on the displacement of the + // spring from its rest point or `endValue` as defined by [Hooke's + // law](http://en.wikipedia.org/wiki/Hooke's_law). Springs also have + // configurable friction, which ensures that they do not oscillate + // infinitely. When a Spring is displaced by updating it's resting + // or `currentValue`, the SpringSystems that contain that Spring + // will automatically start looping to solve for equilibrium. As each + // timestep passes, `SpringListener` objects attached to the Spring + // will be notified of the updates providing a way to drive an + // animation off of the spring's resolution curve. + var Spring = rebound.Spring = function Spring(springSystem) { + this._id = 's' + Spring._ID++; + this._springSystem = springSystem; + this.listeners = []; + this._currentState = new PhysicsState(); + this._previousState = new PhysicsState(); + this._tempState = new PhysicsState(); + }; + + util.extend(Spring, { + _ID: 0, + + MAX_DELTA_TIME_SEC: 0.064, + + SOLVER_TIMESTEP_SEC: 0.001 + + }); + + util.extend(Spring.prototype, { + + _id: 0, + + _springConfig: null, + + _overshootClampingEnabled: false, + + _currentState: null, + + _previousState: null, + + _tempState: null, + + _startValue: 0, + + _endValue: 0, + + _wasAtRest: true, + + _restSpeedThreshold: 0.001, + + _displacementFromRestThreshold: 0.001, + + listeners: null, + + _timeAccumulator: 0, + + _springSystem: null, + + // Remove a Spring from simulation and clear its listeners. + destroy: function() { + this.listeners = []; + this.frames = []; + this._springSystem.deregisterSpring(this); + }, + + // Get the id of the spring, which can be used to retrieve it from + // the SpringSystems it participates in later. + getId: function() { + return this._id; + }, + + // Set the configuration values for this Spring. A SpringConfig + // contains the tension and friction values used to solve for the + // equilibrium of the Spring in the physics loop. + setSpringConfig: function(springConfig) { + this._springConfig = springConfig; + return this; + }, + + // Retrieve the SpringConfig used by this Spring. + getSpringConfig: function() { + return this._springConfig; + }, + + // Set the current position of this Spring. Listeners will be updated + // with this value immediately. If the rest or `endValue` is not + // updated to match this value, then the spring will be dispalced and + // the SpringSystem will start to loop to restore the spring to the + // `endValue`. + // + // A common pattern is to move a Spring around without animation by + // calling. + // + // ``` + // spring.setCurrentValue(n).setAtRest(); + // ``` + // + // This moves the Spring to a new position `n`, sets the endValue + // to `n`, and removes any velocity from the `Spring`. By doing + // this you can allow the `SpringListener` to manage the position + // of UI elements attached to the spring even when moving without + // animation. For example, when dragging an element you can + // update the position of an attached view through a spring + // by calling `spring.setCurrentValue(x)`. When + // the gesture ends you can update the Springs + // velocity and endValue + // `spring.setVelocity(gestureEndVelocity).setEndValue(flingTarget)` + // to cause it to naturally animate the UI element to the resting + // position taking into account existing velocity. The codepaths for + // synchronous movement and spring driven animation can + // be unified using this technique. + setCurrentValue: function(currentValue, skipSetAtRest) { + this._startValue = currentValue; + this._currentState.position = currentValue; + if (!skipSetAtRest) { + this.setAtRest(); + } + this.notifyPositionUpdated(false, false); + return this; + }, + + // Get the position that the most recent animation started at. This + // can be useful for determining the number off oscillations that + // have occurred. + getStartValue: function() { + return this._startValue; + }, + + // Retrieve the current value of the Spring. + getCurrentValue: function() { + return this._currentState.position; + }, + + // Get the absolute distance of the Spring from it's resting endValue + // position. + getCurrentDisplacementDistance: function() { + return this.getDisplacementDistanceForState(this._currentState); + }, + + getDisplacementDistanceForState: function(state) { + return Math.abs(this._endValue - state.position); + }, + + // Set the endValue or resting position of the spring. If this + // value is different than the current value, the SpringSystem will + // be notified and will begin running its solver loop to resolve + // the Spring to equilibrium. Any listeners that are registered + // for onSpringEndStateChange will also be notified of this update + // immediately. + setEndValue: function(endValue) { + if (this._endValue == endValue && this.isAtRest()) { + return this; + } + this._startValue = this.getCurrentValue(); + this._endValue = endValue; + this._springSystem.activateSpring(this.getId()); + for (var i = 0, len = this.listeners.length; i < len; i++) { + var listener = this.listeners[i]; + var onChange = listener.onSpringEndStateChange; + onChange && onChange(this); + } + return this; + }, + + // Retrieve the endValue or resting position of this spring. + getEndValue: function() { + return this._endValue; + }, + + // Set the current velocity of the Spring. As previously mentioned, + // this can be useful when you are performing a direct manipulation + // gesture. When a UI element is released you may call setVelocity + // on its animation Spring so that the Spring continues with the + // same velocity as the gesture ended with. The friction, tension, + // and displacement of the Spring will then govern its motion to + // return to rest on a natural feeling curve. + setVelocity: function(velocity) { + if (velocity === this._currentState.velocity) { + return this; + } + this._currentState.velocity = velocity; + this._springSystem.activateSpring(this.getId()); + return this; + }, + + // Get the current velocity of the Spring. + getVelocity: function() { + return this._currentState.velocity; + }, + + // Set a threshold value for the movement speed of the Spring below + // which it will be considered to be not moving or resting. + setRestSpeedThreshold: function(restSpeedThreshold) { + this._restSpeedThreshold = restSpeedThreshold; + return this; + }, + + // Retrieve the rest speed threshold for this Spring. + getRestSpeedThreshold: function() { + return this._restSpeedThreshold; + }, + + // Set a threshold value for displacement below which the Spring + // will be considered to be not displaced i.e. at its resting + // `endValue`. + setRestDisplacementThreshold: function(displacementFromRestThreshold) { + this._displacementFromRestThreshold = displacementFromRestThreshold; + }, + + // Retrieve the rest displacement threshold for this spring. + getRestDisplacementThreshold: function() { + return this._displacementFromRestThreshold; + }, + + // Enable overshoot clamping. This means that the Spring will stop + // immediately when it reaches its resting position regardless of + // any existing momentum it may have. This can be useful for certain + // types of animations that should not oscillate such as a scale + // down to 0 or alpha fade. + setOvershootClampingEnabled: function(enabled) { + this._overshootClampingEnabled = enabled; + return this; + }, + + // Check if overshoot clamping is enabled for this spring. + isOvershootClampingEnabled: function() { + return this._overshootClampingEnabled; + }, + + // Check if the Spring has gone past its end point by comparing + // the direction it was moving in when it started to the current + // position and end value. + isOvershooting: function() { + var start = this._startValue; + var end = this._endValue; + return this._springConfig.tension > 0 && + ((start < end && this.getCurrentValue() > end) || + (start > end && this.getCurrentValue() < end)); + }, + + // Spring.advance is the main solver method for the Spring. It takes + // the current time and delta since the last time step and performs + // an RK4 integration to get the new position and velocity state + // for the Spring based on the tension, friction, velocity, and + // displacement of the Spring. + advance: function(time, realDeltaTime) { + var isAtRest = this.isAtRest(); + + if (isAtRest && this._wasAtRest) { + return; + } + + var adjustedDeltaTime = realDeltaTime; + if (realDeltaTime > Spring.MAX_DELTA_TIME_SEC) { + adjustedDeltaTime = Spring.MAX_DELTA_TIME_SEC; + } + + this._timeAccumulator += adjustedDeltaTime; + + var tension = this._springConfig.tension, + friction = this._springConfig.friction, + + position = this._currentState.position, + velocity = this._currentState.velocity, + tempPosition = this._tempState.position, + tempVelocity = this._tempState.velocity, + + aVelocity, aAcceleration, + bVelocity, bAcceleration, + cVelocity, cAcceleration, + dVelocity, dAcceleration, + + dxdt, dvdt; + + while(this._timeAccumulator >= Spring.SOLVER_TIMESTEP_SEC) { + + this._timeAccumulator -= Spring.SOLVER_TIMESTEP_SEC; + + if (this._timeAccumulator < Spring.SOLVER_TIMESTEP_SEC) { + this._previousState.position = position; + this._previousState.velocity = velocity; + } + + aVelocity = velocity; + aAcceleration = + (tension * (this._endValue - tempPosition)) - friction * velocity; + + tempPosition = position + aVelocity * Spring.SOLVER_TIMESTEP_SEC * 0.5; + tempVelocity = + velocity + aAcceleration * Spring.SOLVER_TIMESTEP_SEC * 0.5; + bVelocity = tempVelocity; + bAcceleration = + (tension * (this._endValue - tempPosition)) - friction * tempVelocity; + + tempPosition = position + bVelocity * Spring.SOLVER_TIMESTEP_SEC * 0.5; + tempVelocity = + velocity + bAcceleration * Spring.SOLVER_TIMESTEP_SEC * 0.5; + cVelocity = tempVelocity; + cAcceleration = + (tension * (this._endValue - tempPosition)) - friction * tempVelocity; + + tempPosition = position + cVelocity * Spring.SOLVER_TIMESTEP_SEC * 0.5; + tempVelocity = + velocity + cAcceleration * Spring.SOLVER_TIMESTEP_SEC * 0.5; + dVelocity = tempVelocity; + dAcceleration = + (tension * (this._endValue - tempPosition)) - friction * tempVelocity; + + dxdt = + 1.0/6.0 * (aVelocity + 2.0 * (bVelocity + cVelocity) + dVelocity); + dvdt = 1.0/6.0 * ( + aAcceleration + 2.0 * (bAcceleration + cAcceleration) + dAcceleration + ); + + position += dxdt * Spring.SOLVER_TIMESTEP_SEC; + velocity += dvdt * Spring.SOLVER_TIMESTEP_SEC; + } + + this._tempState.position = tempPosition; + this._tempState.velocity = tempVelocity; + + this._currentState.position = position; + this._currentState.velocity = velocity; + + if (this._timeAccumulator > 0) { + this.interpolate(this._timeAccumulator / Spring.SOLVER_TIMESTEP_SEC); + } + + if (this.isAtRest() || + this._overshootClampingEnabled && this.isOvershooting()) { + + if (this._springConfig.tension > 0) { + this._startValue = this._endValue; + this._currentState.position = this._endValue; + } else { + this._endValue = this._currentState.position; + this._startValue = this._endValue; + } + this.setVelocity(0); + isAtRest = true; + } + + var notifyActivate = false; + if (this._wasAtRest) { + this._wasAtRest = false; + notifyActivate = true; + } + + var notifyAtRest = false; + if (isAtRest) { + this._wasAtRest = true; + notifyAtRest = true; + } + + this.notifyPositionUpdated(notifyActivate, notifyAtRest); + }, + + notifyPositionUpdated: function(notifyActivate, notifyAtRest) { + for (var i = 0, len = this.listeners.length; i < len; i++) { + var listener = this.listeners[i]; + if (notifyActivate && listener.onSpringActivate) { + listener.onSpringActivate(this); + } + + if (listener.onSpringUpdate) { + listener.onSpringUpdate(this); + } + + if (notifyAtRest && listener.onSpringAtRest) { + listener.onSpringAtRest(this); + } + } + }, + + + // Check if the SpringSystem should advance. Springs are advanced + // a final frame after they reach equilibrium to ensure that the + // currentValue is exactly the requested endValue regardless of the + // displacement threshold. + systemShouldAdvance: function() { + return !this.isAtRest() || !this.wasAtRest(); + }, + + wasAtRest: function() { + return this._wasAtRest; + }, + + // Check if the Spring is atRest meaning that it's currentValue and + // endValue are the same and that it has no velocity. The previously + // described thresholds for speed and displacement define the bounds + // of this equivalence check. If the Spring has 0 tension, then it will + // be considered at rest whenever its absolute velocity drops below the + // restSpeedThreshold. + isAtRest: function() { + return Math.abs(this._currentState.velocity) < this._restSpeedThreshold && + (this.getDisplacementDistanceForState(this._currentState) <= + this._displacementFromRestThreshold || + this._springConfig.tension === 0); + }, + + // Force the spring to be at rest at its current position. As + // described in the documentation for setCurrentValue, this method + // makes it easy to do synchronous non-animated updates to ui + // elements that are attached to springs via SpringListeners. + setAtRest: function() { + this._endValue = this._currentState.position; + this._tempState.position = this._currentState.position; + this._currentState.velocity = 0; + return this; + }, + + interpolate: function(alpha) { + this._currentState.position = this._currentState.position * + alpha + this._previousState.position * (1 - alpha); + this._currentState.velocity = this._currentState.velocity * + alpha + this._previousState.velocity * (1 - alpha); + }, + + getListeners: function() { + return this.listeners; + }, + + addListener: function(newListener) { + this.listeners.push(newListener); + return this; + }, + + removeListener: function(listenerToRemove) { + removeFirst(this.listeners, listenerToRemove); + return this; + }, + + removeAllListeners: function() { + this.listeners = []; + return this; + }, + + currentValueIsApproximately: function(value) { + return Math.abs(this.getCurrentValue() - value) <= + this.getRestDisplacementThreshold(); + } + + }); + + // PhysicsState + // ------------ + // **PhysicsState** consists of a position and velocity. A Spring uses + // this internally to keep track of its current and prior position and + // velocity values. + var PhysicsState = function PhysicsState() {}; + + util.extend(PhysicsState.prototype, { + position: 0, + velocity: 0 + }); + + // SpringConfig + // ------------ + // **SpringConfig** maintains a set of tension and friction constants + // for a Spring. You can use fromOrigamiTensionAndFriction to convert + // values from the [Origami](http://facebook.github.io/origami/) + // design tool directly to Rebound spring constants. + var SpringConfig = rebound.SpringConfig = + function SpringConfig(tension, friction) { + this.tension = tension; + this.friction = friction; + }; + + // Loopers + // ------- + // **AnimationLooper** plays each frame of the SpringSystem on animation + // timing loop. This is the default type of looper for a new spring system + // as it is the most common when developing UI. + var AnimationLooper = rebound.AnimationLooper = function AnimationLooper() { + this.springSystem = null; + var _this = this; + var _run = function() { + _this.springSystem.loop(Date.now()); + }; + + this.run = function() { + util.onFrame(_run); + }; + }; + + // **SimulationLooper** resolves the SpringSystem to a resting state in a + // tight and blocking loop. This is useful for synchronously generating + // pre-recorded animations that can then be played on a timing loop later. + // Sometimes this lead to better performance to pre-record a single spring + // curve and use it to drive many animations; however, it can make dynamic + // response to user input a bit trickier to implement. + rebound.SimulationLooper = function SimulationLooper(timestep) { + this.springSystem = null; + var time = 0; + var running = false; + timestep=timestep || 16.667; + + this.run = function() { + if (running) { + return; + } + running = true; + while(!this.springSystem.getIsIdle()) { + this.springSystem.loop(time+=timestep); + } + running = false; + }; + }; + + // **SteppingSimulationLooper** resolves the SpringSystem one step at a + // time controlled by an outside loop. This is useful for testing and + // verifying the behavior of a SpringSystem or if you want to control your own + // timing loop for some reason e.g. slowing down or speeding up the + // simulation. + rebound.SteppingSimulationLooper = function(timestep) { + this.springSystem = null; + var time = 0; + + // this.run is NOOP'd here to allow control from the outside using + // this.step. + this.run = function(){}; + + // Perform one step toward resolving the SpringSystem. + this.step = function(timestep) { + this.springSystem.loop(time+=timestep); + }; + }; + + // Math for converting from + // [Origami](http://facebook.github.io/origami/) to + // [Rebound](http://facebook.github.io/rebound). + // You mostly don't need to worry about this, just use + // SpringConfig.fromOrigamiTensionAndFriction(v, v); + var OrigamiValueConverter = rebound.OrigamiValueConverter = { + tensionFromOrigamiValue: function(oValue) { + return (oValue - 30.0) * 3.62 + 194.0; + }, + + origamiValueFromTension: function(tension) { + return (tension - 194.0) / 3.62 + 30.0; + }, + + frictionFromOrigamiValue: function(oValue) { + return (oValue - 8.0) * 3.0 + 25.0; + }, + + origamiFromFriction: function(friction) { + return (friction - 25.0) / 3.0 + 8.0; + } + }; + + // BouncyConversion provides math for converting from Origami PopAnimation + // config values to regular Origami tension and friction values. If you are + // trying to replicate prototypes made with PopAnimation patches in Origami, + // then you should create your springs with + // SpringSystem.createSpringWithBouncinessAndSpeed, which uses this Math + // internally to create a spring to match the provided PopAnimation + // configuration from Origami. + var BouncyConversion = rebound.BouncyConversion = function(bounciness, speed){ + this.bounciness = bounciness; + this.speed = speed; + var b = this.normalize(bounciness / 1.7, 0, 20.0); + b = this.projectNormal(b, 0.0, 0.8); + var s = this.normalize(speed / 1.7, 0, 20.0); + this.bouncyTension = this.projectNormal(s, 0.5, 200) + this.bouncyFriction = this.quadraticOutInterpolation( + b, + this.b3Nobounce(this.bouncyTension), + 0.01); + } + + util.extend(BouncyConversion.prototype, { + + normalize: function(value, startValue, endValue) { + return (value - startValue) / (endValue - startValue); + }, + + projectNormal: function(n, start, end) { + return start + (n * (end - start)); + }, + + linearInterpolation: function(t, start, end) { + return t * end + (1.0 - t) * start; + }, + + quadraticOutInterpolation: function(t, start, end) { + return this.linearInterpolation(2*t - t*t, start, end); + }, + + b3Friction1: function(x) { + return (0.0007 * Math.pow(x, 3)) - + (0.031 * Math.pow(x, 2)) + 0.64 * x + 1.28; + }, + + b3Friction2: function(x) { + return (0.000044 * Math.pow(x, 3)) - + (0.006 * Math.pow(x, 2)) + 0.36 * x + 2.; + }, + + b3Friction3: function(x) { + return (0.00000045 * Math.pow(x, 3)) - + (0.000332 * Math.pow(x, 2)) + 0.1078 * x + 5.84; + }, + + b3Nobounce: function(tension) { + var friction = 0; + if (tension <= 18) { + friction = this.b3Friction1(tension); + } else if (tension > 18 && tension <= 44) { + friction = this.b3Friction2(tension); + } else { + friction = this.b3Friction3(tension); + } + return friction; + } + }); + + util.extend(SpringConfig, { + // Convert an origami Spring tension and friction to Rebound spring + // constants. If you are prototyping a design with Origami, this + // makes it easy to make your springs behave exactly the same in + // Rebound. + fromOrigamiTensionAndFriction: function(tension, friction) { + return new SpringConfig( + OrigamiValueConverter.tensionFromOrigamiValue(tension), + OrigamiValueConverter.frictionFromOrigamiValue(friction)); + }, + + // Convert an origami PopAnimation Spring bounciness and speed to Rebound + // spring constants. If you are using PopAnimation patches in Origami, this + // utility will provide springs that match your prototype. + fromBouncinessAndSpeed: function(bounciness, speed) { + var bouncyConversion = new rebound.BouncyConversion(bounciness, speed); + return this.fromOrigamiTensionAndFriction( + bouncyConversion.bouncyTension, + bouncyConversion.bouncyFriction); + }, + + // Create a SpringConfig with no tension or a coasting spring with some + // amount of Friction so that it does not coast infininitely. + coastingConfigWithOrigamiFriction: function(friction) { + return new SpringConfig( + 0, + OrigamiValueConverter.frictionFromOrigamiValue(friction) + ); + } + }); + + SpringConfig.DEFAULT_ORIGAMI_SPRING_CONFIG = + SpringConfig.fromOrigamiTensionAndFriction(40, 7); + + util.extend(SpringConfig.prototype, {friction: 0, tension: 0}); + + // Here are a couple of function to convert colors between hex codes and RGB + // component values. These are handy when performing color + // tweening animations. + var colorCache = {}; + util.hexToRGB = function(color) { + if (colorCache[color]) { + return colorCache[color]; + } + color = color.replace('#', ''); + if (color.length === 3) { + color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2]; + } + var parts = color.match(/.{2}/g); + + var ret = { + r: parseInt(parts[0], 16), + g: parseInt(parts[1], 16), + b: parseInt(parts[2], 16) + }; + + colorCache[color] = ret; + return ret; + }; + + util.rgbToHex = function(r, g, b) { + r = r.toString(16); + g = g.toString(16); + b = b.toString(16); + r = r.length < 2 ? '0' + r : r; + g = g.length < 2 ? '0' + g : g; + b = b.length < 2 ? '0' + b : b; + return '#' + r + g + b; + }; + + var MathUtil = rebound.MathUtil = { + // This helper function does a linear interpolation of a value from + // one range to another. This can be very useful for converting the + // motion of a Spring to a range of UI property values. For example a + // spring moving from position 0 to 1 could be interpolated to move a + // view from pixel 300 to 350 and scale it from 0.5 to 1. The current + // position of the `Spring` just needs to be run through this method + // taking its input range in the _from_ parameters with the property + // animation range in the _to_ parameters. + mapValueInRange: function(value, fromLow, fromHigh, toLow, toHigh) { + var fromRangeSize = fromHigh - fromLow; + var toRangeSize = toHigh - toLow; + var valueScale = (value - fromLow) / fromRangeSize; + return toLow + (valueScale * toRangeSize); + }, + + // Interpolate two hex colors in a 0 - 1 range or optionally provide a + // custom range with fromLow,fromHight. The output will be in hex by default + // unless asRGB is true in which case it will be returned as an rgb string. + interpolateColor: + function(val, startColor, endColor, fromLow, fromHigh, asRGB) { + fromLow = fromLow === undefined ? 0 : fromLow; + fromHigh = fromHigh === undefined ? 1 : fromHigh; + startColor = util.hexToRGB(startColor); + endColor = util.hexToRGB(endColor); + var r = Math.floor( + util.mapValueInRange(val, fromLow, fromHigh, startColor.r, endColor.r) + ); + var g = Math.floor( + util.mapValueInRange(val, fromLow, fromHigh, startColor.g, endColor.g) + ); + var b = Math.floor( + util.mapValueInRange(val, fromLow, fromHigh, startColor.b, endColor.b) + ); + if (asRGB) { + return 'rgb(' + r + ',' + g + ',' + b + ')'; + } else { + return util.rgbToHex(r, g, b); + } + }, + + degreesToRadians: function(deg) { + return (deg * Math.PI) / 180; + }, + + radiansToDegrees: function(rad) { + return (rad * 180) / Math.PI; + } + + } + + util.extend(util, MathUtil); + + + // Utilities + // --------- + // Here are a few useful JavaScript utilities. + + // Lop off the first occurence of the reference in the Array. + function removeFirst(array, item) { + var idx = array.indexOf(item); + idx != -1 && array.splice(idx, 1); + } + + var _onFrame; + if (typeof window !== 'undefined') { + _onFrame = window.requestAnimationFrame || + window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.msRequestAnimationFrame || + window.oRequestAnimationFrame; + } + if (!_onFrame && typeof process !== 'undefined' && process.title === 'node') { + _onFrame = setImmediate; + } + + // Cross browser/node timer functions. + util.onFrame = function onFrame(func) { + return _onFrame(func); + }; + + // Export the public api using exports for common js or the window for + // normal browser inclusion. + if (typeof exports != 'undefined') { + util.extend(exports, rebound); + } else if (typeof window != 'undefined') { + window.rebound = rebound; + } +})(); + + +// Legal Stuff +// ----------- +/** + * Copyright (c) 2013, 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. + */ +}); +__d('SegmentedControlIOS',["NativeMethodsMixin","NativeModules","ReactPropTypes","React","StyleSheet","requireNativeComponent","verifyPropTypes"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 SegmentedControlIOS + * @flow + */ +'use strict'; + +var NativeMethodsMixin = require('NativeMethodsMixin'); +var NativeModules = require('NativeModules'); +var PropTypes = require('ReactPropTypes'); +var React = require('React'); +var StyleSheet = require('StyleSheet'); + +var requireNativeComponent = require('requireNativeComponent'); +var verifyPropTypes = require('verifyPropTypes'); + + + + + + +var SEGMENTED_CONTROL_REFERENCE = 'segmentedcontrol'; + + + +/** + * Use `SegmentedControlIOS` to render a UISegmentedControl iOS. + */ +var SegmentedControlIOS = React.createClass({displayName: "SegmentedControlIOS", + mixins: [NativeMethodsMixin], + + propTypes: { + /** + * The labels for the control's segment buttons, in order. + */ + values: PropTypes.arrayOf(PropTypes.string), + + /** + * The index in `props.values` of the segment to be pre-selected + */ + selectedIndex: PropTypes.number, + + /** + * Callback that is called when the user taps a segment; + * passes the segment's value as an argument + */ + onValueChange: PropTypes.func, + + /** + * Callback that is called when the user taps a segment; + * passes the event as an argument + */ + onChange: PropTypes.func, + + /** + * If false the user won't be able to interact with the control. + * Default value is true. + */ + enabled: PropTypes.bool, + + /** + * Accent color of the control. + */ + tintColor: PropTypes.string, + + /** + * If true, then selecting a segment won't persist visually. + * The `onValueChange` callback will still work as expected. + */ + momentary: PropTypes.bool + }, + + getDefaultProps: function() { + return { + values: [], + enabled: true + }; + }, + + _onChange: function(event ) { + this.props.onChange && this.props.onChange(event); + this.props.onValueChange && this.props.onValueChange(event.nativeEvent.value); + }, + + render: function() { + return ( + React.createElement(RCTSegmentedControl, React.__spread({}, + this.props, + {ref: SEGMENTED_CONTROL_REFERENCE, + style: [styles.segmentedControl, this.props.style], + onChange: this._onChange}) + ) + ); + } +}); + +var styles = StyleSheet.create({ + segmentedControl: { + height: NativeModules.SegmentedControlManager.ComponentHeight + }, +}); + +var RCTSegmentedControl = requireNativeComponent( + 'RCTSegmentedControl', + null +); +if (__DEV__) { + verifyPropTypes( + RCTSegmentedControl, + RCTSegmentedControl.viewConfig + ); +} + +module.exports = SegmentedControlIOS; +}); +__d('SliderIOS',["NativeMethodsMixin","ReactPropTypes","React","StyleSheet","View","requireNativeComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 SliderIOS + * @flow + */ +'use strict'; + +var NativeMethodsMixin = require('NativeMethodsMixin'); +var PropTypes = require('ReactPropTypes'); +var React = require('React'); +var StyleSheet = require('StyleSheet'); +var View = require('View'); + +var requireNativeComponent = require('requireNativeComponent'); + + + +var SliderIOS = React.createClass({displayName: "SliderIOS", + mixins: [NativeMethodsMixin], + + propTypes: { + /** + * Used to style and layout the `Slider`. See `StyleSheet.js` and + * `ViewStylePropTypes.js` for more info. + */ + style: View.propTypes.style, + + /** + * Initial value of the slider. The value should be between minimumValue + * and maximumValue, which default to 0 and 1 respectively. + * Default value is 0. + * + * *This is not a controlled component*, e.g. if you don't update + * the value, the component won't be reset to its inital value. + */ + value: PropTypes.number, + + /** + * Initial minimum value of the slider. Default value is 0. + */ + minimumValue: PropTypes.number, + + /** + * Initial maximum value of the slider. Default value is 1. + */ + maximumValue: PropTypes.number, + + /** + * The color used for the track to the left of the button. Overrides the + * default blue gradient image. + */ + minimumTrackTintColor: PropTypes.string, + + /** + * The color used for the track to the right of the button. Overrides the + * default blue gradient image. + */ + maximumTrackTintColor: PropTypes.string, + + /** + * Callback continuously called while the user is dragging the slider. + */ + onValueChange: PropTypes.func, + + /** + * Callback called when the user finishes changing the value (e.g. when + * the slider is released). + */ + onSlidingComplete: PropTypes.func, + }, + + _onValueChange: function(event ) { + this.props.onChange && this.props.onChange(event); + if (event.nativeEvent.continuous) { + this.props.onValueChange && + this.props.onValueChange(event.nativeEvent.value); + } else { + this.props.onSlidingComplete && event.nativeEvent.value !== undefined && + this.props.onSlidingComplete(event.nativeEvent.value); + } + }, + + render: function() { + return ( + React.createElement(RCTSlider, { + style: [styles.slider, this.props.style], + value: this.props.value, + maximumValue: this.props.maximumValue, + minimumValue: this.props.minimumValue, + minimumTrackTintColor: this.props.minimumTrackTintColor, + maximumTrackTintColor: this.props.maximumTrackTintColor, + onChange: this._onValueChange} + ) + ); + } +}); + +var styles = StyleSheet.create({ + slider: { + height: 40, + }, +}); + +var RCTSlider = requireNativeComponent('RCTSlider', SliderIOS); + +module.exports = SliderIOS; +}); +__d('SwitchIOS',["NativeMethodsMixin","ReactPropTypes","React","StyleSheet","requireNativeComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 SwitchIOS + * @flow + * + * This is a controlled component version of RCTSwitch. + */ +'use strict'; + +var NativeMethodsMixin = require('NativeMethodsMixin'); +var PropTypes = require('ReactPropTypes'); +var React = require('React'); +var StyleSheet = require('StyleSheet'); + +var requireNativeComponent = require('requireNativeComponent'); + +var SWITCH = 'switch'; + + + + + + + + +/** + * Use `SwitchIOS` to render a boolean input on iOS. This is + * a controlled component, so you must hook in to the `onValueChange` callback + * and update the `value` prop in order for the component to update, otherwise + * the user's change will be reverted immediately to reflect `props.value` as the + * source of truth. + */ +var SwitchIOS = React.createClass({displayName: "SwitchIOS", + mixins: [NativeMethodsMixin], + + propTypes: { + /** + * The value of the switch, if true the switch will be turned on. + * Default value is false. + */ + value: PropTypes.bool, + + /** + * If true the user won't be able to toggle the switch. + * Default value is false. + */ + disabled: PropTypes.bool, + + /** + * Callback that is called when the user toggles the switch. + */ + onValueChange: PropTypes.func, + + /** + * Background color when the switch is turned on. + */ + onTintColor: PropTypes.string, + + /** + * Background color for the switch round button. + */ + thumbTintColor: PropTypes.string, + + /** + * Background color when the switch is turned off. + */ + tintColor: PropTypes.string, + }, + + getDefaultProps: function() { + return { + value: false, + disabled: false, + }; + }, + + _onChange: function(event ) { + this.props.onChange && this.props.onChange(event); + this.props.onValueChange && this.props.onValueChange(event.nativeEvent.value); + + // The underlying switch might have changed, but we're controlled, + // and so want to ensure it represents our value. + this.refs[SWITCH].setNativeProps({value: this.props.value}); + }, + + render: function() { + return ( + React.createElement(RCTSwitch, React.__spread({}, + this.props, + {ref: SWITCH, + onChange: this._onChange, + style: [styles.rkSwitch, this.props.style]}) + ) + ); + } +}); + +var styles = StyleSheet.create({ + rkSwitch: { + height: 31, + width: 51, + }, +}); + +var RCTSwitch = requireNativeComponent('RCTSwitch', SwitchIOS); + +module.exports = SwitchIOS; +}); +__d('TabBarIOS',["React","StyleSheet","TabBarItemIOS","View","requireNativeComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 TabBarIOS + * @flow + */ +'use strict'; + +var React = require('React'); +var StyleSheet = require('StyleSheet'); +var TabBarItemIOS = require('TabBarItemIOS'); +var View = require('View'); + +var requireNativeComponent = require('requireNativeComponent'); + +var TabBarIOS = React.createClass({displayName: "TabBarIOS", + statics: { + Item: TabBarItemIOS, + }, + + propTypes: { + style: View.propTypes.style, + }, + + render: function() { + return ( + React.createElement(RCTTabBar, {style: [styles.tabGroup, this.props.style]}, + this.props.children + ) + ); + } +}); + +var styles = StyleSheet.create({ + tabGroup: { + flex: 1, + } +}); + +var RCTTabBar = requireNativeComponent('RCTTabBar', TabBarIOS); + +module.exports = TabBarIOS; +}); +__d('TabBarItemIOS',["Image","React","StaticContainer.react","StyleSheet","View","requireNativeComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 TabBarItemIOS + * @flow + */ +'use strict'; + +var Image = require('Image'); +var React = require('React'); +var StaticContainer = require('StaticContainer.react'); +var StyleSheet = require('StyleSheet'); +var View = require('View'); + +var requireNativeComponent = require('requireNativeComponent'); + +var TabBarItemIOS = React.createClass({displayName: "TabBarItemIOS", + propTypes: { + /** + * Little red bubble that sits at the top right of the icon. + */ + badge: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.number, + ]), + /** + * Items comes with a few predefined system icons. Note that if you are + * using them, the title and selectedIcon will be overriden with the + * system ones. + */ + systemIcon: React.PropTypes.oneOf([ + 'bookmarks', + 'contacts', + 'downloads', + 'favorites', + 'featured', + 'history', + 'more', + 'most-recent', + 'most-viewed', + 'recents', + 'search', + 'top-rated', + ]), + /** + * A custom icon for the tab. It is ignored when a system icon is defined. + */ + icon: Image.propTypes.source, + /** + * A custom icon when the tab is selected. It is ignored when a system + * icon is defined. If left empty, the icon will be tinted in blue. + */ + selectedIcon: Image.propTypes.source, + /** + * Callback when this tab is being selected, you should change the state of your + * component to set selected={true}. + */ + onPress: React.PropTypes.func, + /** + * It specifies whether the children are visible or not. If you see a + * blank content, you probably forgot to add a selected one. + */ + selected: React.PropTypes.bool, + /** + * React style object. + */ + style: View.propTypes.style, + /** + * Text that appears under the icon. It is ignored when a system icon + * is defined. + */ + title: React.PropTypes.string, + }, + + getInitialState: function() { + return { + hasBeenSelected: false, + }; + }, + + componentWillMount: function() { + if (this.props.selected) { + this.setState({hasBeenSelected: true}); + } + }, + + componentWillReceiveProps: function(nextProps ) { + if (this.state.hasBeenSelected || nextProps.selected) { + this.setState({hasBeenSelected: true}); + } + }, + + render: function() { + var tabContents = null; + // if the tab has already been shown once, always continue to show it so we + // preserve state between tab transitions + if (this.state.hasBeenSelected) { + tabContents = + React.createElement(StaticContainer, {shouldUpdate: this.props.selected}, + this.props.children + ); + } else { + tabContents = React.createElement(View, null); + } + + 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 ( + React.createElement(RCTTabBarItem, { + icon: icon, + selectedIcon: this.props.selectedIcon && this.props.selectedIcon.uri, + onPress: this.props.onPress, + selected: this.props.selected, + badge: badge, + title: this.props.title, + style: [styles.tab, this.props.style]}, + tabContents + ) + ); + } +}); + +var styles = StyleSheet.create({ + tab: { + position: 'absolute', + top: 0, + right: 0, + bottom: 0, + left: 0, + } +}); + +var RCTTabBarItem = requireNativeComponent('RCTTabBarItem', TabBarItemIOS); + +module.exports = TabBarItemIOS; +}); +__d('Text',["NativeMethodsMixin","React","ReactNativeViewAttributes","StyleSheetPropType","TextStylePropTypes","Touchable","createReactNativeComponentClass","merge"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 Text + * @flow + */ +'use strict'; + +var NativeMethodsMixin = require('NativeMethodsMixin'); +var React = require('React'); +var ReactNativeViewAttributes = require('ReactNativeViewAttributes'); +var StyleSheetPropType = require('StyleSheetPropType'); +var TextStylePropTypes = require('TextStylePropTypes'); +var Touchable = require('Touchable'); + +var createReactNativeComponentClass = + require('createReactNativeComponentClass'); +var merge = require('merge'); + +var stylePropType = StyleSheetPropType(TextStylePropTypes); + +var viewConfig = { + validAttributes: merge(ReactNativeViewAttributes.UIView, { + isHighlighted: true, + numberOfLines: true, + }), + uiViewClassName: 'RCTText', +}; + +/** + * A React component for displaying text which supports nesting, + * styling, and touch handling. In the following example, the nested title and + * body text will inherit the `fontFamily` from `styles.baseText`, but the title + * provides its own additional styles. The title and body will stack on top of + * each other on account of the literal newlines: + * + * ``` + * renderText: function() { + * return ( + * + * + * {this.state.titleText + '\n\n'} + * + * + * {this.state.bodyText} + * + * + * ); + * }, + * ... + * var styles = StyleSheet.create({ + * baseText: { + * fontFamily: 'Cochin', + * }, + * titleText: { + * fontSize: 20, + * fontWeight: 'bold', + * }, + * }; + * ``` + */ + +var Text = React.createClass({displayName: "Text", + + mixins: [Touchable.Mixin, NativeMethodsMixin], + + propTypes: { + /** + * Used to truncate the text with an elipsis after computing the text + * layout, including line wrapping, such that the total number of lines does + * not exceed this number. + */ + numberOfLines: React.PropTypes.number, + /** + * This function is called on press. Text intrinsically supports press + * handling with a default highlight state (which can be disabled with + * `suppressHighlighting`). + */ + onPress: React.PropTypes.func, + /** + * When true, no visual change is made when text is pressed down. By + * default, a gray oval highlights the text on press down. + */ + suppressHighlighting: React.PropTypes.bool, + style: stylePropType, + /** + * Used to locate this view in end-to-end tests. + */ + testID: React.PropTypes.string, + }, + + viewConfig: viewConfig, + + getInitialState: function() { + return merge(this.touchableGetInitialState(), { + isHighlighted: false, + }); + }, + + onStartShouldSetResponder: function() { + var shouldSetFromProps = this.props.onStartShouldSetResponder && + this.props.onStartShouldSetResponder(); + return shouldSetFromProps || !!this.props.onPress; + }, + + /* + * Returns true to allow responder termination + */ + handleResponderTerminationRequest: function() { + // Allow touchable or props.onResponderTerminationRequest to deny + // the request + var allowTermination = this.touchableHandleResponderTerminationRequest(); + if (allowTermination && this.props.onResponderTerminationRequest) { + allowTermination = this.props.onResponderTerminationRequest(); + } + return allowTermination; + }, + + handleResponderGrant: function(e , dispatchID ) { + this.touchableHandleResponderGrant(e, dispatchID); + this.props.onResponderGrant && + this.props.onResponderGrant.apply(this, arguments); + }, + + handleResponderMove: function(e ) { + this.touchableHandleResponderMove(e); + this.props.onResponderMove && + this.props.onResponderMove.apply(this, arguments); + }, + + handleResponderRelease: function(e ) { + this.touchableHandleResponderRelease(e); + this.props.onResponderRelease && + this.props.onResponderRelease.apply(this, arguments); + }, + + handleResponderTerminate: function(e ) { + this.touchableHandleResponderTerminate(e); + this.props.onResponderTerminate && + this.props.onResponderTerminate.apply(this, arguments); + }, + + touchableHandleActivePressIn: function() { + if (this.props.suppressHighlighting || !this.props.onPress) { + return; + } + this.setState({ + isHighlighted: true, + }); + }, + + touchableHandleActivePressOut: function() { + if (this.props.suppressHighlighting || !this.props.onPress) { + return; + } + this.setState({ + isHighlighted: false, + }); + }, + + touchableHandlePress: function() { + this.props.onPress && this.props.onPress(); + }, + + touchableGetPressRectOffset: function() { + return PRESS_RECT_OFFSET; + }, + + render: function() { + var props = {}; + for (var key in this.props) { + props[key] = this.props[key]; + } + // Text is accessible by default + if (props.accessible !== false) { + props.accessible = true; + } + props.isHighlighted = this.state.isHighlighted; + props.onStartShouldSetResponder = this.onStartShouldSetResponder; + props.onResponderTerminationRequest = + this.handleResponderTerminationRequest; + props.onResponderGrant = this.handleResponderGrant; + props.onResponderMove = this.handleResponderMove; + props.onResponderRelease = this.handleResponderRelease; + props.onResponderTerminate = this.handleResponderTerminate; + return React.createElement(RCTText, React.__spread({}, props)); + }, +}); + + + + + + + + +var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; + +var RCTText = createReactNativeComponentClass(viewConfig); + +module.exports = Text; +}); +__d('Touchable',["BoundingDimensions","Position","TouchEventUtils","keyMirror","queryLayoutByID"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * @providesModule Touchable + */ + +'use strict'; + +var BoundingDimensions = require('BoundingDimensions'); +var Position = require('Position'); +var TouchEventUtils = require('TouchEventUtils'); + +var keyMirror = require('keyMirror'); +var queryLayoutByID = require('queryLayoutByID'); + +/** + * `Touchable`: Taps done right. + * + * You hook your `ResponderEventPlugin` events into `Touchable`. `Touchable` + * will measure time/geometry and tells you when to give feedback to the user. + * + * ====================== Touchable Tutorial =============================== + * The `Touchable` mixin helps you handle the "press" interaction. It analyzes + * the geometry of elements, and observes when another responder (scroll view + * etc) has stolen the touch lock. It notifies your component when it should + * give feedback to the user. (bouncing/highlighting/unhighlighting). + * + * - When a touch was activated (typically you highlight) + * - When a touch was deactivated (typically you unhighlight) + * - When a touch was "pressed" - a touch ended while still within the geometry + * of the element, and no other element (like scroller) has "stolen" touch + * lock ("responder") (Typically you bounce the element). + * + * A good tap interaction isn't as simple as you might think. There should be a + * slight delay before showing a highlight when starting a touch. If a + * subsequent touch move exceeds the boundary of the elemement, it should + * unhighlight, but if that same touch is brought back within the boundary, it + * should rehighlight again. A touch can move in and out of that boundary + * several times, each time toggling highlighting, but a "press" is only + * triggered if that touch ends while within the element's boundary and no + * scroller (or anything else) has stolen the lock on touches. + * + * To create a new type of component that handles interaction using the + * `Touchable` mixin, do the following: + * + * - Initialize the `Touchable` state. + * + * getInitialState: function() { + * return merge(this.touchableGetInitialState(), yourComponentState); + * } + * + * - Choose the rendered component who's touches should start the interactive + * sequence. On that rendered node, forward all `Touchable` responder + * handlers. You can choose any rendered node you like. Choose a node who's + * hit target you'd like to instigate the interaction sequence: + * + * // In render function: + * return ( + *
+ *
+ * Even though the hit detection/interactions are triggered by the + * wrapping (typically larger) node, we usually end up implementing + * custom logic that highlights this inner one. + *
+ *
+ * ); + * + * - You may set up your own handlers for each of these events, so long as you + * also invoke the `touchable*` handlers inside of your custom handler. + * + * - Implement the handlers on your component class in order to provide + * feedback to the user. See documentation for each of these class methods + * that you should implement. + * + * touchableHandlePress: function() { + * this.performBounceAnimation(); // or whatever you want to do. + * }, + * touchableHandleActivePressIn: function() { + * this.beginHighlighting(...); // Whatever you like to convey activation + * }, + * touchableHandleActivePressOut: function() { + * this.endHighlighting(...); // Whatever you like to convey deactivation + * }, + * + * - There are more advanced methods you can implement (see documentation below): + * touchableGetHighlightDelayMS: function() { + * return 20; + * } + * // In practice, *always* use a predeclared constant (conserve memory). + * touchableGetPressRectOffset: function() { + * return {top: 20, left: 20, right: 20, bottom: 100}; + * } + */ + +/** + * Touchable states. + */ +var States = keyMirror({ + NOT_RESPONDER: null, // Not the responder + RESPONDER_INACTIVE_PRESS_IN: null, // Responder, inactive, in the `PressRect` + RESPONDER_INACTIVE_PRESS_OUT: null, // Responder, inactive, out of `PressRect` + RESPONDER_ACTIVE_PRESS_IN: null, // Responder, active, in the `PressRect` + RESPONDER_ACTIVE_PRESS_OUT: null, // Responder, active, out of `PressRect` + RESPONDER_ACTIVE_LONG_PRESS_IN: null, // Responder, active, in the `PressRect`, after long press threshold + RESPONDER_ACTIVE_LONG_PRESS_OUT: null, // Responder, active, out of `PressRect`, after long press threshold + ERROR: null +}); + +/** + * Quick lookup map for states that are considered to be "active" + */ +var IsActive = { + RESPONDER_ACTIVE_PRESS_OUT: true, + RESPONDER_ACTIVE_PRESS_IN: true +}; + +/** + * Quick lookup for states that are considered to be "pressing" and are + * therefore eligible to result in a "selection" if the press stops. + */ +var IsPressingIn = { + RESPONDER_INACTIVE_PRESS_IN: true, + RESPONDER_ACTIVE_PRESS_IN: true, + RESPONDER_ACTIVE_LONG_PRESS_IN: true, +}; + +var IsLongPressingIn = { + RESPONDER_ACTIVE_LONG_PRESS_IN: true, +}; + +/** + * Inputs to the state machine. + */ +var Signals = keyMirror({ + DELAY: null, + RESPONDER_GRANT: null, + RESPONDER_RELEASE: null, + RESPONDER_TERMINATED: null, + ENTER_PRESS_RECT: null, + LEAVE_PRESS_RECT: null, + LONG_PRESS_DETECTED: null, +}); + +/** + * Mapping from States x Signals => States + */ +var Transitions = { + NOT_RESPONDER: { + DELAY: States.ERROR, + RESPONDER_GRANT: States.RESPONDER_INACTIVE_PRESS_IN, + RESPONDER_RELEASE: States.ERROR, + RESPONDER_TERMINATED: States.ERROR, + ENTER_PRESS_RECT: States.ERROR, + LEAVE_PRESS_RECT: States.ERROR, + LONG_PRESS_DETECTED: States.ERROR, + }, + RESPONDER_INACTIVE_PRESS_IN: { + DELAY: States.RESPONDER_ACTIVE_PRESS_IN, + RESPONDER_GRANT: States.ERROR, + RESPONDER_RELEASE: States.NOT_RESPONDER, + RESPONDER_TERMINATED: States.NOT_RESPONDER, + ENTER_PRESS_RECT: States.RESPONDER_INACTIVE_PRESS_IN, + LEAVE_PRESS_RECT: States.RESPONDER_INACTIVE_PRESS_OUT, + LONG_PRESS_DETECTED: States.ERROR, + }, + RESPONDER_INACTIVE_PRESS_OUT: { + DELAY: States.RESPONDER_ACTIVE_PRESS_OUT, + RESPONDER_GRANT: States.ERROR, + RESPONDER_RELEASE: States.NOT_RESPONDER, + RESPONDER_TERMINATED: States.NOT_RESPONDER, + ENTER_PRESS_RECT: States.RESPONDER_INACTIVE_PRESS_IN, + LEAVE_PRESS_RECT: States.RESPONDER_INACTIVE_PRESS_OUT, + LONG_PRESS_DETECTED: States.ERROR, + }, + RESPONDER_ACTIVE_PRESS_IN: { + DELAY: States.ERROR, + RESPONDER_GRANT: States.ERROR, + RESPONDER_RELEASE: States.NOT_RESPONDER, + RESPONDER_TERMINATED: States.NOT_RESPONDER, + ENTER_PRESS_RECT: States.RESPONDER_ACTIVE_PRESS_IN, + LEAVE_PRESS_RECT: States.RESPONDER_ACTIVE_PRESS_OUT, + LONG_PRESS_DETECTED: States.RESPONDER_ACTIVE_LONG_PRESS_IN, + }, + RESPONDER_ACTIVE_PRESS_OUT: { + DELAY: States.ERROR, + RESPONDER_GRANT: States.ERROR, + RESPONDER_RELEASE: States.NOT_RESPONDER, + RESPONDER_TERMINATED: States.NOT_RESPONDER, + ENTER_PRESS_RECT: States.RESPONDER_ACTIVE_PRESS_IN, + LEAVE_PRESS_RECT: States.RESPONDER_ACTIVE_PRESS_OUT, + LONG_PRESS_DETECTED: States.ERROR, + }, + RESPONDER_ACTIVE_LONG_PRESS_IN: { + DELAY: States.ERROR, + RESPONDER_GRANT: States.ERROR, + RESPONDER_RELEASE: States.NOT_RESPONDER, + RESPONDER_TERMINATED: States.NOT_RESPONDER, + ENTER_PRESS_RECT: States.RESPONDER_ACTIVE_LONG_PRESS_IN, + LEAVE_PRESS_RECT: States.RESPONDER_ACTIVE_LONG_PRESS_OUT, + LONG_PRESS_DETECTED: States.RESPONDER_ACTIVE_LONG_PRESS_IN, + }, + RESPONDER_ACTIVE_LONG_PRESS_OUT: { + DELAY: States.ERROR, + RESPONDER_GRANT: States.ERROR, + RESPONDER_RELEASE: States.NOT_RESPONDER, + RESPONDER_TERMINATED: States.NOT_RESPONDER, + ENTER_PRESS_RECT: States.RESPONDER_ACTIVE_LONG_PRESS_IN, + LEAVE_PRESS_RECT: States.RESPONDER_ACTIVE_LONG_PRESS_OUT, + LONG_PRESS_DETECTED: States.ERROR, + }, + error: { + DELAY: States.NOT_RESPONDER, + RESPONDER_GRANT: States.RESPONDER_INACTIVE_PRESS_IN, + RESPONDER_RELEASE: States.NOT_RESPONDER, + RESPONDER_TERMINATED: States.NOT_RESPONDER, + ENTER_PRESS_RECT: States.NOT_RESPONDER, + LEAVE_PRESS_RECT: States.NOT_RESPONDER, + LONG_PRESS_DETECTED: States.NOT_RESPONDER, + } +}; + +// ==== Typical Constants for integrating into UI components ==== +// var HIT_EXPAND_PX = 20; +// var HIT_VERT_OFFSET_PX = 10; +var HIGHLIGHT_DELAY_MS = 130; + +var PRESS_EXPAND_PX = 20; + +var LONG_PRESS_THRESHOLD = 500; + +var LONG_PRESS_ALLOWED_MOVEMENT = 10; + +// Default amount "active" region protrudes beyond box + +/** + * By convention, methods prefixed with underscores are meant to be @private, + * and not @protected. Mixers shouldn't access them - not even to provide them + * as callback handlers. + * + * + * ========== Geometry ========= + * `Touchable` only assumes that there exists a `HitRect` node. The `PressRect` + * is an abstract box that is extended beyond the `HitRect`. + * + * +--------------------------+ + * | | - "Start" events in `HitRect` cause `HitRect` + * | +--------------------+ | to become the responder. + * | | +--------------+ | | - `HitRect` is typically expanded around + * | | | | | | the `VisualRect`, but shifted downward. + * | | | VisualRect | | | - After pressing down, after some delay, + * | | | | | | and before letting up, the Visual React + * | | +--------------+ | | will become "active". This makes it eligible + * | | HitRect | | for being highlighted (so long as the + * | +--------------------+ | press remains in the `PressRect`). + * | PressRect o | + * +----------------------|---+ + * Out Region | + * +-----+ This gap between the `HitRect` and + * `PressRect` allows a touch to move far away + * from the original hit rect, and remain + * highlighted, and eligible for a "Press". + * Customize this via + * `touchableGetPressRectOffset()`. + * + * + * + * ======= State Machine ======= + * + * +-------------+ <---+ RESPONDER_RELEASE + * |NOT_RESPONDER| + * +-------------+ <---+ RESPONDER_TERMINATED + * + + * | RESPONDER_GRANT (HitRect) + * v + * +---------------------------+ DELAY +-------------------------+ T - DELAY +------------------------------+ + * |RESPONDER_INACTIVE_PRESS_IN|+-------->|RESPONDER_ACTIVE_PRESS_IN| +------------> |RESPONDER_ACTIVE_LONG_PRESS_IN| + * +---------------------------+ +-------------------------+ +------------------------------+ + * + ^ + ^ + ^ + * |LEAVE_ |ENTER_ |LEAVE_ |ENTER_ |LEAVE_ |ENTER_ + * |PRESS_RECT |PRESS_RECT |PRESS_RECT |PRESS_RECT |PRESS_RECT |PRESS_RECT + * | | | | | | + * v + v + v + + * +----------------------------+ DELAY +--------------------------+ +-------------------------------+ + * |RESPONDER_INACTIVE_PRESS_OUT|+------->|RESPONDER_ACTIVE_PRESS_OUT| |RESPONDER_ACTIVE_LONG_PRESS_OUT| + * +----------------------------+ +--------------------------+ +-------------------------------+ + * + * T - DELAY => LONG_PRESS_THRESHOLD - DELAY + * + * Not drawn are the side effects of each transition. The most important side + * effect is the `touchableHandlePress` abstract method invocation that occurs + * when a responder is released while in either of the "Press" states. + * + * The other important side effects are the highlight abstract method + * invocations (internal callbacks) to be implemented by the mixer. + * + * + * @lends Touchable.prototype + */ +var TouchableMixin = { + /** + * It's prefer that mixins determine state in this way, having the class + * explicitly mix the state in the one and only `getInitialState` method. + * + * @return {object} State object to be placed inside of + * `this.state.touchable`. + */ + touchableGetInitialState: function() { + return { + touchable: {touchState: undefined, responderID: null} + }; + }, + + // ==== Hooks to Gesture Responder system ==== + /** + * Must return true if embedded in a native platform scroll view. + */ + touchableHandleResponderTerminationRequest: function() { + return !this.props.rejectResponderTermination; + }, + + /** + * Must return true to start the process of `Touchable`. + */ + touchableHandleStartShouldSetResponder: function() { + return true; + }, + + /** + * Return true to cancel press on long press. + */ + touchableLongPressCancelsPress: function () { + return true; + }, + + /** + * Place as callback for a DOM element's `onResponderGrant` event. + * @param {SyntheticEvent} e Synthetic event from event system. + * @param {string} dispatchID ID of node that e was dispatched to. + * + */ + touchableHandleResponderGrant: function(e, dispatchID) { + // Since e is used in a callback invoked on another event loop + // (as in setTimeout etc), we need to call e.persist() on the + // event to make sure it doesn't get reused in the event object pool. + e.persist(); + + this.state.touchable.touchState = States.NOT_RESPONDER; + this.state.touchable.responderID = dispatchID; + this._receiveSignal(Signals.RESPONDER_GRANT, e); + var delayMS = + this.touchableGetHighlightDelayMS !== undefined ? + this.touchableGetHighlightDelayMS() : HIGHLIGHT_DELAY_MS; + if (delayMS !== 0) { + this.touchableDelayTimeout = setTimeout( + this._handleDelay.bind(this, e), + delayMS + ); + } else { + this._handleDelay(e); + } + + this.longPressDelayTimeout = setTimeout( + this._handleLongDelay.bind(this, e), + LONG_PRESS_THRESHOLD - delayMS + ); + }, + + /** + * Place as callback for a DOM element's `onResponderRelease` event. + */ + touchableHandleResponderRelease: function(e) { + this._receiveSignal(Signals.RESPONDER_RELEASE, e); + }, + + /** + * Place as callback for a DOM element's `onResponderTerminate` event. + */ + touchableHandleResponderTerminate: function(e) { + this._receiveSignal(Signals.RESPONDER_TERMINATED, e); + }, + + /** + * Place as callback for a DOM element's `onResponderMove` event. + */ + touchableHandleResponderMove: function(e) { + // Not enough time elapsed yet, wait for highlight - + // this is just a perf optimization. + if (this.state.touchable.touchState === States.RESPONDER_INACTIVE_PRESS_IN) { + return; + } + + // Measurement may not have returned yet. + if (!this.state.touchable.positionOnActivate) { + return; + } + + var positionOnActivate = this.state.touchable.positionOnActivate; + var dimensionsOnActivate = this.state.touchable.dimensionsOnActivate; + var pressRectOffset = this.touchableGetPressRectOffset ? + this.touchableGetPressRectOffset() : null; + var pressExpandLeft = + pressRectOffset.left != null ? pressRectOffset.left : PRESS_EXPAND_PX; + var pressExpandTop = + pressRectOffset.top != null ? pressRectOffset.top : PRESS_EXPAND_PX; + var pressExpandRight = + pressRectOffset.right != null ? pressRectOffset.right : PRESS_EXPAND_PX; + var pressExpandBottom = + pressRectOffset.bottom != null ? pressRectOffset.bottom : PRESS_EXPAND_PX; + + var touch = TouchEventUtils.extractSingleTouch(e.nativeEvent); + var pageX = touch && touch.pageX; + var pageY = touch && touch.pageY; + + if (this.pressInLocation) { + var movedDistance = this._getDistanceBetweenPoints(pageX, pageY, this.pressInLocation.pageX, this.pressInLocation.pageY); + if (movedDistance > LONG_PRESS_ALLOWED_MOVEMENT) { + this._cancelLongPressDelayTimeout(); + } + } + + var isTouchWithinActive = + pageX > positionOnActivate.left - pressExpandLeft && + pageY > positionOnActivate.top - pressExpandTop && + pageX < + positionOnActivate.left + + dimensionsOnActivate.width + + pressExpandRight && + pageY < + positionOnActivate.top + + dimensionsOnActivate.height + + pressExpandBottom; + if (isTouchWithinActive) { + this._receiveSignal(Signals.ENTER_PRESS_RECT, e); + } else { + this._cancelLongPressDelayTimeout(); + this._receiveSignal(Signals.LEAVE_PRESS_RECT, e); + } + }, + + // ==== Abstract Application Callbacks ==== + + /** + * Invoked when the item should be highlighted. Mixers should implement this + * to visually distinguish the `VisualRect` so that the user knows that + * releasing a touch will result in a "selection" (analog to click). + * + * @abstract + * touchableHandleActivePressIn: function, + */ + + /** + * Invoked when the item is "active" (in that it is still eligible to become + * a "select") but the touch has left the `PressRect`. Usually the mixer will + * want to unhighlight the `VisualRect`. If the user (while pressing) moves + * back into the `PressRect` `touchableHandleActivePressIn` will be invoked + * again and the mixer should probably highlight the `VisualRect` again. This + * event will not fire on an `touchEnd/mouseUp` event, only move events while + * the user is depressing the mouse/touch. + * + * @abstract + * touchableHandleActivePressOut: function + */ + + /** + * Invoked when the item is "selected" - meaning the interaction ended by + * letting up while the item was either in the state + * `RESPONDER_ACTIVE_PRESS_IN` or `RESPONDER_INACTIVE_PRESS_IN`. + * + * @abstract + * touchableHandlePress: function + */ + + /** + * Invoked when the item is long pressed - meaning the interaction ended by + * letting up while the item was in `RESPONDER_ACTIVE_LONG_PRESS_IN`. If + * `touchableHandleLongPress` is *not* provided, `touchableHandlePress` will + * be called as it normally is. If `touchableHandleLongPress` is provided, by + * default any `touchableHandlePress` callback will not be invoked. To + * override this default behavior, override `touchableLongPressCancelsPress` + * to return false. As a result, `touchableHandlePress` will be called when + * lifting up, even if `touchableHandleLongPress` has also been called. + * + * @abstract + * touchableHandleLongPress: function + */ + + /** + * Returns the number of millis to wait before triggering a highlight. + * + * @abstract + * touchableGetHighlightDelayMS: function + */ + + /** + * Returns the amount to extend the `HitRect` into the `PressRect`. Positive + * numbers mean the size expands outwards. + * + * @abstract + * touchableGetPressRectOffset: function + */ + + + + // ==== Internal Logic ==== + + /** + * Measures the `HitRect` node on activation. The Bounding rectangle is with + * respect to viewport - not page, so adding the `pageXOffset/pageYOffset` + * should result in points that are in the same coordinate system as an + * event's `globalX/globalY` data values. + * + * - Consider caching this for the lifetime of the component, or possibly + * being able to share this cache between any `ScrollMap` view. + * + * @sideeffects + * @private + */ + _remeasureMetricsOnActivation: function() { + queryLayoutByID( + this.state.touchable.responderID, + null, + this._handleQueryLayout + ); + }, + + _handleQueryLayout: function(l, t, w, h, globalX, globalY) { + this.state.touchable.positionOnActivate && + Position.release(this.state.touchable.positionOnActivate); + this.state.touchable.dimensionsOnActivate && + BoundingDimensions.release(this.state.touchable.dimensionsOnActivate); + this.state.touchable.positionOnActivate = Position.getPooled(globalX, globalY); + this.state.touchable.dimensionsOnActivate = BoundingDimensions.getPooled(w, h); + }, + + _handleDelay: function(e) { + this.touchableDelayTimeout = null; + this._receiveSignal(Signals.DELAY, e); + }, + + _handleLongDelay: function(e) { + this.longPressDelayTimeout = null; + this._receiveSignal(Signals.LONG_PRESS_DETECTED, e); + }, + + /** + * Receives a state machine signal, performs side effects of the transition + * and stores the new state. Validates the transition as well. + * + * @param {Signals} signal State machine signal. + * @throws Error if invalid state transition or unrecognized signal. + * @sideeffects + */ + _receiveSignal: function(signal, e) { + var curState = this.state.touchable.touchState; + if (!(Transitions[curState] && Transitions[curState][signal])) { + throw new Error( + 'Unrecognized signal `' + signal + '` or state `' + curState + + '` for Touchable responder `' + this.state.touchable.responderID + '`' + ); + } + var nextState = Transitions[curState][signal]; + if (nextState === States.ERROR) { + throw new Error( + 'Touchable cannot transition from `' + curState + '` to `' + signal + + '` for responder `' + this.state.touchable.responderID + '`' + ); + } + if (curState !== nextState) { + this._performSideEffectsForTransition(curState, nextState, signal, e); + this.state.touchable.touchState = nextState; + } + }, + + _cancelLongPressDelayTimeout: function () { + this.longPressDelayTimeout && clearTimeout(this.longPressDelayTimeout); + this.longPressDelayTimeout = null; + }, + + _isHighlight: function (state) { + return state === States.RESPONDER_ACTIVE_PRESS_IN || + state === States.RESPONDER_ACTIVE_LONG_PRESS_IN; + }, + + _savePressInLocation: function(e) { + var touch = TouchEventUtils.extractSingleTouch(e.nativeEvent); + var pageX = touch && touch.pageX; + var pageY = touch && touch.pageY; + this.pressInLocation = {pageX: pageX, pageY: pageY}; + }, + + _getDistanceBetweenPoints: function (aX, aY, bX, bY) { + var deltaX = aX - bX; + var deltaY = aY - bY; + return Math.sqrt(deltaX * deltaX + deltaY * deltaY); + }, + + /** + * Will perform a transition between touchable states, and identify any + * highlighting or unhighlighting that must be performed for this particular + * transition. + * + * @param {States} curState Current Touchable state. + * @param {States} nextState Next Touchable state. + * @param {Signal} signal Signal that triggered the transition. + * @param {Event} e Native event. + * @sideeffects + */ + _performSideEffectsForTransition: function(curState, nextState, signal, e) { + var curIsHighlight = this._isHighlight(curState); + var newIsHighlight = this._isHighlight(nextState); + + var isFinalSignal = + signal === Signals.RESPONDER_TERMINATED || + signal === Signals.RESPONDER_RELEASE; + + if (isFinalSignal) { + this._cancelLongPressDelayTimeout(); + } + + if (!IsActive[curState] && IsActive[nextState]) { + this._remeasureMetricsOnActivation(); + } + + if (IsPressingIn[curState] && signal === Signals.LONG_PRESS_DETECTED) { + this.touchableHandleLongPress && this.touchableHandleLongPress(); + } + + if (newIsHighlight && !curIsHighlight) { + this._savePressInLocation(e); + this.touchableHandleActivePressIn && this.touchableHandleActivePressIn(); + } else if (!newIsHighlight && curIsHighlight) { + this.touchableHandleActivePressOut && this.touchableHandleActivePressOut(); + } + + if (IsPressingIn[curState] && signal === Signals.RESPONDER_RELEASE) { + var hasLongPressHandler = !!this.props.onLongPress; + var pressIsLongButStillCallOnPress = + IsLongPressingIn[curState] && ( // We *are* long pressing.. + !hasLongPressHandler || // But either has no long handler + !this.touchableLongPressCancelsPress() // or we're told to ignore it. + ); + + var shouldInvokePress = !IsLongPressingIn[curState] || pressIsLongButStillCallOnPress; + if (shouldInvokePress && this.touchableHandlePress) { + this.touchableHandlePress(e); + } + } + + this.touchableDelayTimeout && clearTimeout(this.touchableDelayTimeout); + this.touchableDelayTimeout = null; + } + +}; + +var Touchable = { + Mixin: TouchableMixin +}; + +module.exports = Touchable; +}); +__d('BoundingDimensions',["PooledClass"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * @providesModule BoundingDimensions + */ + +"use strict"; + +var PooledClass = require('PooledClass'); + +var twoArgumentPooler = PooledClass.twoArgumentPooler; + +/** + * PooledClass representing the bounding rectangle of a region. + * + * @param {number} width Width of bounding rectangle. + * @param {number} height Height of bounding rectangle. + * @constructor BoundingDimensions + */ +function BoundingDimensions(width, height) { + this.width = width; + this.height = height; +} + +/** + * @param {HTMLElement} element Element to return `BoundingDimensions` for. + * @return {BoundingDimensions} Bounding dimensions of `element`. + */ +BoundingDimensions.getPooledFromElement = function(element) { + return BoundingDimensions.getPooled( + element.offsetWidth, + element.offsetHeight + ); +}; + +PooledClass.addPoolingTo(BoundingDimensions, twoArgumentPooler); + +module.exports = BoundingDimensions; + +}); +__d('Position',["PooledClass"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * @providesModule Position + */ + +"use strict"; + +var PooledClass = require('PooledClass'); + +var twoArgumentPooler = PooledClass.twoArgumentPooler; + +/** + * Position does not expose methods for construction via an `HTMLDOMElement`, + * because it isn't meaningful to construct such a thing without first defining + * a frame of refrence. + * + * @param {number} windowStartKey Key that window starts at. + * @param {number} windowEndKey Key that window ends at. + */ +function Position(left, top) { + this.left = left; + this.top = top; +} + +PooledClass.addPoolingTo(Position, twoArgumentPooler); + +module.exports = Position; + +}); +__d('TouchEventUtils',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 TouchEventUtils + */ + +var TouchEventUtils = { + /** + * Utility function for common case of extracting out the primary touch from a + * touch event. + * - `touchEnd` events usually do not have the `touches` property. + * http://stackoverflow.com/questions/3666929/ + * mobile-sarai-touchend-event-not-firing-when-last-touch-is-removed + * + * @param {Event} nativeEvent Native event that may or may not be a touch. + * @return {TouchesObject?} an object with pageX and pageY or null. + */ + extractSingleTouch: function(nativeEvent) { + var touches = nativeEvent.touches; + var changedTouches = nativeEvent.changedTouches; + var hasTouches = touches && touches.length > 0; + var hasChangedTouches = changedTouches && changedTouches.length > 0; + + return !hasTouches && hasChangedTouches ? changedTouches[0] : + hasTouches ? touches[0] : + nativeEvent; + } +}; + +module.exports = TouchEventUtils; +}); +__d('queryLayoutByID',["ReactNativeTagHandles","NativeModules"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 queryLayoutByID + * @flow + */ +'use strict'; + +var ReactNativeTagHandles = require('ReactNativeTagHandles'); +var RCTUIManager = require('NativeModules').UIManager; + + + + + + + + + + +// I don't know what type error is... + + +/** + * Queries the layout of a view. The layout does not reflect the element as + * seen by the user, rather it reflects the position within the layout system, + * before any transforms are applied. + * + * The only other requirement is that the `pageX, pageY` values be in the same + * coordinate system that events' `pageX/Y` are reported. That means that for + * the web, `pageXOffset/pageYOffset` should be added to to + * getBoundingClientRect to make consistent with touches. + * + * var pageXOffset = window.pageXOffset; + * var pageYOffset = window.pageYOffset; + * + * This is an IOS specific implementation. + * + * @param {string} rootNodeID ID of the platform specific node to be measured. + * @param {function} onError `func(error)` + * @param {function} onSuccess `func(left, top, width, height, pageX, pageY)` + */ +var queryLayoutByID = function( + rootNodeID , + onError , + onSuccess +) { + // Native bridge doesn't *yet* surface errors. + RCTUIManager.measure( + ReactNativeTagHandles.rootNodeIDToTag[rootNodeID], + onSuccess + ); +}; + +module.exports = queryLayoutByID; + +}); +__d('TextInput',["DocumentSelectionState","EventEmitter","NativeMethodsMixin","NativeModules","Platform","ReactPropTypes","React","ReactChildren","ReactNativeViewAttributes","StyleSheet","Text","TextInputState","react-timer-mixin/TimerMixin","TouchableWithoutFeedback","createReactNativeComponentClass","emptyFunction","invariant","merge"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 TextInput + * @flow + */ +'use strict'; + +var DocumentSelectionState = require('DocumentSelectionState'); +var EventEmitter = require('EventEmitter'); +var NativeMethodsMixin = require('NativeMethodsMixin'); +var RCTUIManager = require('NativeModules').UIManager; +var Platform = require('Platform'); +var PropTypes = require('ReactPropTypes'); +var React = require('React'); +var ReactChildren = require('ReactChildren'); +var ReactNativeViewAttributes = require('ReactNativeViewAttributes'); +var StyleSheet = require('StyleSheet'); +var Text = require('Text'); +var TextInputState = require('TextInputState'); +var TimerMixin = require('react-timer-mixin/TimerMixin'); +var TouchableWithoutFeedback = require('TouchableWithoutFeedback'); + +var createReactNativeComponentClass = require('createReactNativeComponentClass'); +var emptyFunction = require('emptyFunction'); +var invariant = require('invariant'); +var merge = require('merge'); + +var autoCapitalizeConsts = RCTUIManager.UIText.AutocapitalizationType; +var keyboardTypeConsts = RCTUIManager.UIKeyboardType; +var returnKeyTypeConsts = RCTUIManager.UIReturnKeyType; + +var RCTTextViewAttributes = merge(ReactNativeViewAttributes.UIView, { + autoCorrect: true, + autoCapitalize: true, + clearTextOnFocus: true, + color: true, + editable: true, + fontFamily: true, + fontSize: true, + fontStyle: true, + fontWeight: true, + keyboardType: true, + returnKeyType: true, + enablesReturnKeyAutomatically: true, + secureTextEntry: true, + selectTextOnFocus: true, + mostRecentEventCounter: true, + placeholder: true, + placeholderTextColor: true, + text: true, +}); + +var RCTTextFieldAttributes = merge(RCTTextViewAttributes, { + caretHidden: true, + enabled: true, + clearButtonMode: true, + clearTextOnFocus: true, + selectTextOnFocus: true, +}); + +var onlyMultiline = { + onSelectionChange: true, + onTextInput: true, + children: true, +}; + +var notMultiline = { + onSubmitEditing: true, +}; + +var AndroidTextInputAttributes = { + autoCapitalize: true, + autoCorrect: true, + autoFocus: true, + keyboardType: true, + multiline: true, + password: true, + placeholder: true, + text: true, + testID: true, +}; + +var viewConfigIOS = { + uiViewClassName: 'RCTTextField', + validAttributes: RCTTextFieldAttributes, +}; + +var viewConfigAndroid = { + uiViewClassName: 'AndroidTextInput', + validAttributes: AndroidTextInputAttributes, +}; + +var crossPlatformKeyboardTypeMap = { + 'numeric': 'decimal-pad', +}; + + + + + + + +/** + * A foundational component for inputting text into the app via a + * keyboard. Props provide configurability for several features, such as auto- + * correction, auto-capitalization, placeholder text, and different keyboard + * types, such as a numeric keypad. + * + * The simplest use case is to plop down a `TextInput` and subscribe to the + * `onChangeText` events to read the user input. There are also other events, such + * as `onSubmitEditing` and `onFocus` that can be subscribed to. A simple + * example: + * + * ``` + * + * this.setState({input: text})} + * /> + * {'user input: ' + this.state.input} + * + * ``` + * + * The `value` prop can be used to set the value of the input in order to make + * the state of the component clear, but does not behave as a true + * controlled component by default because all operations are asynchronous. + * Setting `value` once is like setting the default value, but you can change it + * continuously based on `onChangeText` events as well. If you really want to + * force the component to always revert to the value you are setting, you can + * set `controlled={true}`. + * + * The `multiline` prop is not supported in all releases, and some props are + * multiline only. + */ + +var TextInput = React.createClass({displayName: "TextInput", + propTypes: { + /** + * Can tell TextInput to automatically capitalize certain characters. + * + * - characters: all characters, + * - words: first letter of each word + * - sentences: first letter of each sentence (default) + * - none: don't auto capitalize anything + */ + autoCapitalize: PropTypes.oneOf([ + 'none', + 'sentences', + 'words', + 'characters', + ]), + /** + * If false, disables auto-correct. Default value is true. + */ + autoCorrect: PropTypes.bool, + /** + * If true, focuses the input on componentDidMount. Default value is false. + */ + autoFocus: PropTypes.bool, + /** + * If false, text is not editable. Default value is true. + */ + editable: PropTypes.bool, + /** + * Determines which keyboard to open, e.g.`numeric`. + */ + keyboardType: PropTypes.oneOf([ + 'default', + // iOS + 'ascii-capable', + 'numbers-and-punctuation', + 'url', + 'number-pad', + 'phone-pad', + 'name-phone-pad', + 'email-address', + 'decimal-pad', + 'twitter', + 'web-search', + // Cross-platform + 'numeric', + ]), + /** + * Determines how the return key should look. + */ + returnKeyType: PropTypes.oneOf([ + 'default', + 'go', + 'google', + 'join', + 'next', + 'route', + 'search', + 'send', + 'yahoo', + 'done', + 'emergency-call', + ]), + /** + * If true, the keyboard disables the return key when there is no text and + * automatically enables it when there is text. Default value is false. + */ + enablesReturnKeyAutomatically: PropTypes.bool, + /** + * If true, the text input can be multiple lines. Default value is false. + */ + multiline: PropTypes.bool, + /** + * Callback that is called when the text input is blurred + */ + onBlur: PropTypes.func, + /** + * Callback that is called when the text input is focused + */ + onFocus: PropTypes.func, + /** + * Callback that is called when the text input's text changes. + */ + onChange: PropTypes.func, + onChangeText: PropTypes.func, + /** + * Callback that is called when text input ends. + */ + onEndEditing: PropTypes.func, + /** + * Callback that is called when the text input's submit button is pressed. + */ + onSubmitEditing: PropTypes.func, + /** + * Invoked on mount and layout changes with {x, y, width, height}. + */ + onLayout: PropTypes.func, + /** + * If true, the text input obscures the text entered so that sensitive text + * like passwords stay secure. Default value is false. + */ + password: PropTypes.bool, + /** + * The string that will be rendered before text input has been entered + */ + placeholder: PropTypes.string, + /** + * The text color of the placeholder string + */ + placeholderTextColor: PropTypes.string, + /** + * See DocumentSelectionState.js, some state that is responsible for + * maintaining selection information for a document + */ + selectionState: PropTypes.instanceOf(DocumentSelectionState), + /** + * The default value for the text input + */ + value: PropTypes.string, + /** + * This helps avoid drops characters due to race conditions between JS and + * the native text input. The default should be fine, but if you're + * potentially doing very slow operations on every keystroke then you may + * want to try increasing this. + */ + bufferDelay: PropTypes.number, + /** + * If you really want this to behave as a controlled component, you can set + * this true, but you will probably see flickering, dropped keystrokes, + * and/or laggy typing, depending on how you process onChange events. + */ + controlled: PropTypes.bool, + /** + * When the clear button should appear on the right side of the text view + */ + clearButtonMode: PropTypes.oneOf([ + 'never', + 'while-editing', + 'unless-editing', + 'always', + ]), + /** + * If true, clears the text field automatically when editing begins + */ + clearTextOnFocus: PropTypes.bool, + /** + * If true, selected the text automatically when editing begins + */ + selectTextOnFocus: PropTypes.bool, + /** + * Styles + */ + style: Text.propTypes.style, + /** + * Used to locate this view in end-to-end tests. + */ + testID: PropTypes.string, + }, + + /** + * `NativeMethodsMixin` will look for this when invoking `setNativeProps`. We + * make `this` look like an actual native component class. + */ + mixins: [NativeMethodsMixin, TimerMixin], + + viewConfig: ((Platform.OS === 'ios' ? viewConfigIOS : + (Platform.OS === 'android' ? viewConfigAndroid : {})) ), + + isFocused: function() { + return TextInputState.currentlyFocusedField() === + React.findNodeHandle(this.refs.input); + }, + + getDefaultProps: function() { + return { + bufferDelay: 100, + }; + }, + + getInitialState: function() { + return { + mostRecentEventCounter: 0, + bufferedValue: this.props.value, + }; + }, + + contextTypes: { + onFocusRequested: React.PropTypes.func, + focusEmitter: React.PropTypes.instanceOf(EventEmitter), + }, + + _focusSubscription: (undefined ), + + componentDidMount: function() { + if (!this.context.focusEmitter) { + if (this.props.autoFocus) { + this.requestAnimationFrame(this.focus); + } + return; + } + this._focusSubscription = this.context.focusEmitter.addListener( + 'focus', + function(el) { + if (this === el) { + this.requestAnimationFrame(this.focus); + } else if (this.isFocused()) { + this.blur(); + } + }.bind(this) + ); + if (this.props.autoFocus) { + this.context.onFocusRequested(this); + } + }, + + componentWillUnmount: function() { + this._focusSubscription && this._focusSubscription.remove(); + if (this.isFocused()) { + this.blur(); + } + }, + + _bufferTimeout: (undefined ), + + componentWillReceiveProps: function(newProps ) { + if (newProps.value !== this.props.value) { + if (!this.isFocused()) { + // Set the value immediately if the input is not focused since that + // means there is no risk of the user typing immediately. + this.setState({bufferedValue: newProps.value}); + } else { + // The following clear and setTimeout buffers the value such that if more + // characters are typed in quick succession, generating new values, the + // out of date values will get cancelled before they are ever sent to + // native. + // + // If we don't do this, it's likely the out of date values will blow + // away recently typed characters in the native input that JS was not + // yet aware of (since it is informed asynchronously), then the next + // character will be appended to the older value, dropping the + // characters in between. Here is a potential sequence of events + // (recall we have multiple independently serial, interleaved queues): + // + // 1) User types 'R' => send 'R' to JS queue. + // 2) User types 'e' => send 'Re' to JS queue. + // 3) JS processes 'R' and sends 'R' back to native. + // 4) Native recieves 'R' and changes input from 'Re' back to 'R'. + // 5) User types 'a' => send 'Ra' to JS queue. + // 6) JS processes 'Re' and sends 'Re' back to native. + // 7) Native recieves 'Re' and changes input from 'R' back to 'Re'. + // 8) JS processes 'Ra' and sends 'Ra' back to native. + // 9) Native recieves final 'Ra' from JS - 'e' has been dropped! + // + // This isn't 100% foolproop (e.g. if it takes longer than + // `props.bufferDelay` ms to process one keystroke), and there are of + // course other potential algorithms to deal with this, but this is a + // simple solution that seems to reduce the chance of dropped characters + // drastically without compromising native input responsiveness (e.g. by + // introducing delay from a synchronization protocol). + this.clearTimeout(this._bufferTimeout); + this._bufferTimeout = this.setTimeout( + function() {return this.setState({bufferedValue: newProps.value});}.bind(this), + this.props.bufferDelay + ); + } + } + }, + + render: function() { + if (Platform.OS === 'ios') { + return this._renderIOs(); + } else if (Platform.OS === 'android') { + return this._renderAndroid(); + } + }, + + _renderIOs: function() { + var textContainer; + + var autoCapitalize = autoCapitalizeConsts[this.props.autoCapitalize]; + var clearButtonMode = RCTUIManager.UITextField.clearButtonMode[this.props.clearButtonMode]; + + var keyboardType = keyboardTypeConsts[ + crossPlatformKeyboardTypeMap[this.props.keyboardType] || + this.props.keyboardType + ]; + var returnKeyType = returnKeyTypeConsts[this.props.returnKeyType]; + + if (!this.props.multiline) { + for (var propKey in onlyMultiline) { + if (this.props[propKey]) { + throw new Error( + 'TextInput prop `' + propKey + '` is only supported with multiline.' + ); + } + } + textContainer = + React.createElement(RCTTextField, { + ref: "input", + style: [styles.input, this.props.style], + enabled: this.props.editable, + keyboardType: keyboardType, + returnKeyType: returnKeyType, + enablesReturnKeyAutomatically: this.props.enablesReturnKeyAutomatically, + secureTextEntry: this.props.password || this.props.secureTextEntry, + onFocus: this._onFocus, + onBlur: this._onBlur, + onChange: this._onChange, + onEndEditing: this.props.onEndEditing, + onSubmitEditing: this.props.onSubmitEditing, + onSelectionChangeShouldSetResponder: function() {return true;}, + onLayout: this.props.onLayout, + placeholder: this.props.placeholder, + placeholderTextColor: this.props.placeholderTextColor, + text: this.state.bufferedValue, + autoCapitalize: autoCapitalize, + autoCorrect: this.props.autoCorrect, + clearButtonMode: clearButtonMode, + clearTextOnFocus: this.props.clearTextOnFocus, + selectTextOnFocus: this.props.selectTextOnFocus} + ); + } else { + for (var propKey in notMultiline) { + if (this.props[propKey]) { + throw new Error( + 'TextInput prop `' + propKey + '` cannot be used with multiline.' + ); + } + } + + var children = this.props.children; + var childCount = 0; + ReactChildren.forEach(children, function() {return ++childCount;}); + invariant( + !(this.props.value && childCount), + 'Cannot specify both value and children.' + ); + if (childCount > 1) { + children = React.createElement(Text, null, children); + } + if (this.props.inputView) { + children = [children, this.props.inputView]; + } + textContainer = + React.createElement(RCTTextView, { + ref: "input", + style: [styles.input, this.props.style], + children: children, + mostRecentEventCounter: this.state.mostRecentEventCounter, + editable: this.props.editable, + keyboardType: keyboardType, + returnKeyType: returnKeyType, + enablesReturnKeyAutomatically: this.props.enablesReturnKeyAutomatically, + secureTextEntry: this.props.password || this.props.secureTextEntry, + onFocus: this._onFocus, + onBlur: this._onBlur, + onChange: this._onChange, + onEndEditing: this.props.onEndEditing, + onSelectionChange: this._onSelectionChange, + onTextInput: this._onTextInput, + onSelectionChangeShouldSetResponder: emptyFunction.thatReturnsTrue, + onLayout: this.props.onLayout, + placeholder: this.props.placeholder, + placeholderTextColor: this.props.placeholderTextColor, + text: this.state.bufferedValue, + autoCapitalize: autoCapitalize, + autoCorrect: this.props.autoCorrect, + clearButtonMode: clearButtonMode, + selectTextOnFocus: this.props.selectTextOnFocus, + clearTextOnFocus: this.props.clearTextOnFocus} + ); + } + + return ( + React.createElement(TouchableWithoutFeedback, { + onPress: this._onPress, + rejectResponderTermination: true}, + textContainer + ) + ); + }, + + _renderAndroid: function() { + var autoCapitalize = autoCapitalizeConsts[this.props.autoCapitalize]; + var textContainer = + React.createElement(AndroidTextInput, { + ref: "input", + style: [this.props.style], + autoCapitalize: autoCapitalize, + autoCorrect: this.props.autoCorrect, + keyboardType: this.props.keyboardType, + multiline: this.props.multiline, + onFocus: this._onFocus, + onBlur: this._onBlur, + onChange: this._onChange, + onEndEditing: this.props.onEndEditing, + onSubmitEditing: this.props.onSubmitEditing, + onLayout: this.props.onLayout, + password: this.props.password || this.props.secureTextEntry, + placeholder: this.props.placeholder, + text: this.state.bufferedValue} + ); + + return ( + React.createElement(TouchableWithoutFeedback, { + onPress: this._onPress, + testID: this.props.testID}, + textContainer + ) + ); + }, + + _onFocus: function(event ) { + if (this.props.onFocus) { + this.props.onFocus(event); + } + }, + + _onPress: function(event ) { + this.focus(); + }, + + _onChange: function(event ) { + if (this.props.controlled && event.nativeEvent.text !== this.props.value) { + this.refs.input.setNativeProps({text: this.props.value}); + } + this.props.onChange && this.props.onChange(event); + this.props.onChangeText && this.props.onChangeText(event.nativeEvent.text); + }, + + _onBlur: function(event ) { + this.blur(); + if (this.props.onBlur) { + this.props.onBlur(event); + } + }, + + _onSelectionChange: function(event ) { + if (this.props.selectionState) { + var selection = event.nativeEvent.selection; + this.props.selectionState.update(selection.start, selection.end); + } + this.props.onSelectionChange && this.props.onSelectionChange(event); + }, + + _onTextInput: function(event ) { + this.props.onTextInput && this.props.onTextInput(event); + var counter = event.nativeEvent.eventCounter; + if (counter > this.state.mostRecentEventCounter) { + this.setState({mostRecentEventCounter: counter}); + } + }, +}); + +var styles = StyleSheet.create({ + input: { + alignSelf: 'stretch', + }, +}); + +var RCTTextView = createReactNativeComponentClass({ + validAttributes: RCTTextViewAttributes, + uiViewClassName: 'RCTTextView', +}); + +var RCTTextField = createReactNativeComponentClass({ + validAttributes: RCTTextFieldAttributes, + uiViewClassName: 'RCTTextField', +}); + +var AndroidTextInput = createReactNativeComponentClass({ + validAttributes: AndroidTextInputAttributes, + uiViewClassName: 'AndroidTextInput', +}); + +module.exports = TextInput; +}); +__d('DocumentSelectionState',["mixInEventEmitter"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * @generated SignedSource<<1f058815818e10d01d2ee1f2f70d0fb1>> + * + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !! This file is a check-in of a static_upstream project! !! + * !! !! + * !! You should not modify this file directly. Instead: !! + * !! 1) Use `fjs use-upstream` to temporarily replace this with !! + * !! the latest version from upstream. !! + * !! 2) Make your changes, test them, etc. !! + * !! 3) Use `fjs push-upstream` to copy your changes back to !! + * !! static_upstream. !! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @providesModule DocumentSelectionState + * @typechecks + */ + +var mixInEventEmitter = require('mixInEventEmitter'); + +/** + * DocumentSelectionState is responsible for maintaining selection information + * for a document. + * + * It is intended for use by AbstractTextEditor-based components for + * identifying the appropriate start/end positions to modify the + * DocumentContent, and for programatically setting browser selection when + * components re-render. + */ + + /** + * @param {number} anchor + * @param {number} focus + */ + function DocumentSelectionState(anchor, focus) {"use strict"; + this.$DocumentSelectionState_anchorOffset = anchor; + this.$DocumentSelectionState_focusOffset = focus; + this.$DocumentSelectionState_hasFocus = false; + } + + /** + * Apply an update to the state. If either offset value has changed, + * set the values and emit the `change` event. Otherwise no-op. + * + * @param {number} anchor + * @param {number} focus + */ + DocumentSelectionState.prototype.update=function(anchor, focus) {"use strict"; + if (this.$DocumentSelectionState_anchorOffset !== anchor || this.$DocumentSelectionState_focusOffset !== focus) { + this.$DocumentSelectionState_anchorOffset = anchor; + this.$DocumentSelectionState_focusOffset = focus; + this.emit('update'); + } + }; + + /** + * Given a max text length, constrain our selection offsets to ensure + * that the selection remains strictly within the text range. + * + * @param {number} maxLength + */ + DocumentSelectionState.prototype.constrainLength=function(maxLength) {"use strict"; + this.update( + Math.min(this.$DocumentSelectionState_anchorOffset, maxLength), + Math.min(this.$DocumentSelectionState_focusOffset, maxLength) + ); + }; + + DocumentSelectionState.prototype.focus=function() {"use strict"; + if (!this.$DocumentSelectionState_hasFocus) { + this.$DocumentSelectionState_hasFocus = true; + this.emit('focus'); + } + }; + + DocumentSelectionState.prototype.blur=function() {"use strict"; + if (this.$DocumentSelectionState_hasFocus) { + this.$DocumentSelectionState_hasFocus = false; + this.emit('blur'); + } + }; + + /** + * @return {boolean} + */ + DocumentSelectionState.prototype.hasFocus=function() {"use strict"; + return this.$DocumentSelectionState_hasFocus; + }; + + /** + * @return {boolean} + */ + DocumentSelectionState.prototype.isCollapsed=function() {"use strict"; + return this.$DocumentSelectionState_anchorOffset === this.$DocumentSelectionState_focusOffset; + }; + + /** + * @return {boolean} + */ + DocumentSelectionState.prototype.isBackward=function() {"use strict"; + return this.$DocumentSelectionState_anchorOffset > this.$DocumentSelectionState_focusOffset; + }; + + /** + * @return {?number} + */ + DocumentSelectionState.prototype.getAnchorOffset=function() {"use strict"; + return this.$DocumentSelectionState_hasFocus ? this.$DocumentSelectionState_anchorOffset : null; + }; + + /** + * @return {?number} + */ + DocumentSelectionState.prototype.getFocusOffset=function() {"use strict"; + return this.$DocumentSelectionState_hasFocus ? this.$DocumentSelectionState_focusOffset : null; + }; + + /** + * @return {?number} + */ + DocumentSelectionState.prototype.getStartOffset=function() {"use strict"; + return ( + this.$DocumentSelectionState_hasFocus ? Math.min(this.$DocumentSelectionState_anchorOffset, this.$DocumentSelectionState_focusOffset) : null + ); + }; + + /** + * @return {?number} + */ + DocumentSelectionState.prototype.getEndOffset=function() {"use strict"; + return ( + this.$DocumentSelectionState_hasFocus ? Math.max(this.$DocumentSelectionState_anchorOffset, this.$DocumentSelectionState_focusOffset) : null + ); + }; + + /** + * @param {number} start + * @param {number} end + * @return {boolean} + */ + DocumentSelectionState.prototype.overlaps=function(start, end) {"use strict"; + return ( + this.hasFocus() && + this.getStartOffset() <= end && start <= this.getEndOffset() + ); + }; + + +mixInEventEmitter(DocumentSelectionState, { + 'blur': true, + 'focus': true, + 'update': true +}); + +module.exports = DocumentSelectionState; + +}); +__d('mixInEventEmitter',["EventEmitter","EventEmitterWithHolding","EventHolder","EventValidator","copyProperties","invariant","keyOf"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * @generated SignedSource<> + * + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !! This file is a check-in of a static_upstream project! !! + * !! !! + * !! You should not modify this file directly. Instead: !! + * !! 1) Use `fjs use-upstream` to temporarily replace this with !! + * !! the latest version from upstream. !! + * !! 2) Make your changes, test them, etc. !! + * !! 3) Use `fjs push-upstream` to copy your changes back to !! + * !! static_upstream. !! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @providesModule mixInEventEmitter + */ + +var EventEmitter = require('EventEmitter'); +var EventEmitterWithHolding = require('EventEmitterWithHolding'); +var EventHolder = require('EventHolder'); +var EventValidator = require('EventValidator'); + +var copyProperties = require('copyProperties'); +var invariant = require('invariant'); +var keyOf = require('keyOf'); + +var TYPES_KEY = keyOf({__types: true}); + +/** + * API to setup an object or constructor to be able to emit data events. + * + * @example + * function Dog() { ...dog stuff... } + * mixInEventEmitter(Dog, {bark: true}); + * + * var puppy = new Dog(); + * puppy.addListener('bark', function (volume) { + * console.log('Puppy', this, 'barked at volume:', volume); + * }); + * puppy.emit('bark', 'quiet'); + * // Puppy barked at volume: quiet + * + * + * // A "singleton" object may also be commissioned: + * + * var Singleton = {}; + * mixInEventEmitter(Singleton, {lonely: true}); + * Singleton.emit('lonely', true); + */ +function mixInEventEmitter(klass, types) { + invariant(types, 'Must supply set of valid event types'); + invariant(!this.__eventEmitter, 'An active emitter is already mixed in'); + + // If this is a constructor, write to the prototype, otherwise write to the + // singleton object. + var target = klass.prototype || klass; + + var ctor = klass.constructor; + if (ctor) { + invariant( + ctor === Object || ctor === Function, + 'Mix EventEmitter into a class, not an instance' + ); + } + + // Keep track of the provided types, union the types if they already exist, + // which allows for prototype subclasses to provide more types. + if (target.hasOwnProperty(TYPES_KEY)) { + copyProperties(target.__types, types); + } else if (target.__types) { + target.__types = copyProperties({}, target.__types, types); + } else { + target.__types = types; + } + copyProperties(target, EventEmitterMixin); +} + +var EventEmitterMixin = { + emit: function(eventType, a, b, c, d, e, _) { + return this.__getEventEmitter().emit(eventType, a, b, c, d, e, _); + }, + + emitAndHold: function(eventType, a, b, c, d, e, _) { + return this.__getEventEmitter().emitAndHold(eventType, a, b, c, d, e, _); + }, + + addListener: function(eventType, listener, context) { + return this.__getEventEmitter().addListener(eventType, listener, context); + }, + + once: function(eventType, listener, context) { + return this.__getEventEmitter().once(eventType, listener, context); + }, + + addRetroactiveListener: function(eventType, listener, context) { + return this.__getEventEmitter().addRetroactiveListener( + eventType, + listener, + context + ); + }, + + addListenerMap: function(listenerMap, context) { + return this.__getEventEmitter().addListenerMap(listenerMap, context); + }, + + addRetroactiveListenerMap: function(listenerMap, context) { + return this.__getEventEmitter().addListenerMap(listenerMap, context); + }, + + removeAllListeners: function() { + this.__getEventEmitter().removeAllListeners(); + }, + + removeCurrentListener: function() { + this.__getEventEmitter().removeCurrentListener(); + }, + + releaseHeldEventType: function(eventType) { + this.__getEventEmitter().releaseHeldEventType(eventType); + }, + + __getEventEmitter: function() { + if (!this.__eventEmitter) { + var emitter = new EventEmitter(); + emitter = EventValidator.addValidation(emitter, this.__types); + + var holder = new EventHolder(); + this.__eventEmitter = new EventEmitterWithHolding(emitter, holder); + } + return this.__eventEmitter; + } +}; + +module.exports = mixInEventEmitter; +}); +__d('EventEmitterWithHolding',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * @generated SignedSource<> + * + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !! This file is a check-in of a static_upstream project! !! + * !! !! + * !! You should not modify this file directly. Instead: !! + * !! 1) Use `fjs use-upstream` to temporarily replace this with !! + * !! the latest version from upstream. !! + * !! 2) Make your changes, test them, etc. !! + * !! 3) Use `fjs push-upstream` to copy your changes back to !! + * !! static_upstream. !! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @providesModule EventEmitterWithHolding + * @typechecks + */ +'use strict'; + +/** + * @class EventEmitterWithHolding + * @description + * An EventEmitterWithHolding decorates an event emitter and enables one to + * "hold" or cache events and then have a handler register later to actually + * handle them. + * + * This is separated into its own decorator so that only those who want to use + * the holding functionality have to and others can just use an emitter. Since + * it implements the emitter interface it can also be combined with anything + * that uses an emitter. + */ + + /** + * @constructor + * @param {object} emitter - The object responsible for emitting the actual + * events. + * @param {object} holder - The event holder that is responsible for holding + * and then emitting held events. + */ + function EventEmitterWithHolding(emitter, holder) { + this.$EventEmitterWithHolding_emitter = emitter; + this.$EventEmitterWithHolding_eventHolder = holder; + this.$EventEmitterWithHolding_currentEventToken = null; + this.$EventEmitterWithHolding_emittingHeldEvents = false; + } + + /** + * @see EventEmitter#addListener + */ + EventEmitterWithHolding.prototype.addListener=function(eventType , listener, context ) { + return this.$EventEmitterWithHolding_emitter.addListener(eventType, listener, context); + }; + + /** + * @see EventEmitter#once + */ + EventEmitterWithHolding.prototype.once=function(eventType , listener, context ) { + return this.$EventEmitterWithHolding_emitter.once(eventType, listener, context); + }; + + /** + * Adds a listener to be invoked when events of the specified type are + * emitted. An optional calling context may be provided. The data arguments + * emitted will be passed to the listener function. In addition to subscribing + * to all subsequent events, this method will also handle any events that have + * already been emitted, held, and not released. + * + * @param {string} eventType - Name of the event to listen to + * @param {function} listener - Function to invoke when the specified event is + * emitted + * @param {*} context - Optional context object to use when invoking the + * listener + * + * @example + * emitter.emitAndHold('someEvent', 'abc'); + * + * emitter.addRetroactiveListener('someEvent', function(message) { + * console.log(message); + * }); // logs 'abc' + */ + EventEmitterWithHolding.prototype.addRetroactiveListener=function( +eventType , listener, context ) { + var subscription = this.$EventEmitterWithHolding_emitter.addListener(eventType, listener, context); + + this.$EventEmitterWithHolding_emittingHeldEvents = true; + this.$EventEmitterWithHolding_eventHolder.emitToListener(eventType, listener, context); + this.$EventEmitterWithHolding_emittingHeldEvents = false; + + return subscription; + }; + + /** + * @see EventEmitter#removeAllListeners + */ + EventEmitterWithHolding.prototype.removeAllListeners=function(eventType ) { + this.$EventEmitterWithHolding_emitter.removeAllListeners(eventType); + }; + + /** + * @see EventEmitter#removeCurrentListener + */ + EventEmitterWithHolding.prototype.removeCurrentListener=function() { + this.$EventEmitterWithHolding_emitter.removeCurrentListener(); + }; + + /** + * @see EventEmitter#listeners + */ + EventEmitterWithHolding.prototype.listeners=function(eventType ) /* TODO: Annotate return type here */ { + return this.$EventEmitterWithHolding_emitter.listeners(eventType); + }; + + /** + * @see EventEmitter#emit + */ + EventEmitterWithHolding.prototype.emit=function(eventType , a, b, c, d, e, $EventEmitterWithHolding_) { + this.$EventEmitterWithHolding_emitter.emit(eventType, a, b, c, d, e, $EventEmitterWithHolding_); + }; + + /** + * Emits an event of the given type with the given data, and holds that event + * in order to be able to dispatch it to a later subscriber when they say they + * want to handle held events. + * + * @param {string} eventType - Name of the event to emit + * @param {...*} Arbitrary arguments to be passed to each registered listener + * + * @example + * emitter.emitAndHold('someEvent', 'abc'); + * + * emitter.addRetroactiveListener('someEvent', function(message) { + * console.log(message); + * }); // logs 'abc' + */ + EventEmitterWithHolding.prototype.emitAndHold=function(eventType , a, b, c, d, e, $EventEmitterWithHolding_) { + this.$EventEmitterWithHolding_currentEventToken = this.$EventEmitterWithHolding_eventHolder.holdEvent( + eventType, + a, b, c, d, e, $EventEmitterWithHolding_ + ); + this.$EventEmitterWithHolding_emitter.emit(eventType, a, b, c, d, e, $EventEmitterWithHolding_); + this.$EventEmitterWithHolding_currentEventToken = null; + }; + + /** + * @see EventHolder#releaseCurrentEvent + */ + EventEmitterWithHolding.prototype.releaseCurrentEvent=function() { + if (this.$EventEmitterWithHolding_currentEventToken !== null) { + this.$EventEmitterWithHolding_eventHolder.releaseEvent(this.$EventEmitterWithHolding_currentEventToken); + } else if (this.$EventEmitterWithHolding_emittingHeldEvents) { + this.$EventEmitterWithHolding_eventHolder.releaseCurrentEvent(); + } + }; + + /** + * @see EventHolder#releaseEventType + * @param {string} eventType + */ + EventEmitterWithHolding.prototype.releaseHeldEventType=function(eventType ) { + this.$EventEmitterWithHolding_eventHolder.releaseEventType(eventType); + }; + + +module.exports = EventEmitterWithHolding; +}); +__d('EventHolder',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * @generated SignedSource<<0591836c443c735d24e61782320d3d16>> + * + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !! This file is a check-in of a static_upstream project! !! + * !! !! + * !! You should not modify this file directly. Instead: !! + * !! 1) Use `fjs use-upstream` to temporarily replace this with !! + * !! the latest version from upstream. !! + * !! 2) Make your changes, test them, etc. !! + * !! 3) Use `fjs push-upstream` to copy your changes back to !! + * !! static_upstream. !! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @providesModule EventHolder + * @typechecks + */ +'use strict'; + +var invariant = require('invariant'); + + + function EventHolder() { + this.$EventHolder_heldEvents = {}; + this.$EventHolder_currentEventKey = null; + } + + /** + * Holds a given event for processing later. + * + * TODO: Annotate return type better. The structural type of the return here + * is pretty obvious. + * + * @param {string} eventType - Name of the event to hold and later emit + * @param {...*} Arbitrary arguments to be passed to each registered listener + * @return {object} Token that can be used to release the held event + * + * @example + * + * holder.holdEvent({someEvent: 'abc'}); + * + * holder.emitToHandler({ + * someEvent: function(data, event) { + * console.log(data); + * } + * }); //logs 'abc' + * + */ + EventHolder.prototype.holdEvent=function(eventType , a, b, c, d, e, $EventHolder_) { + this.$EventHolder_heldEvents[eventType] = this.$EventHolder_heldEvents[eventType] || []; + var eventsOfType = this.$EventHolder_heldEvents[eventType]; + var key = { + eventType: eventType, + index: eventsOfType.length + }; + eventsOfType.push([a, b, c, d, e, $EventHolder_]); + return key; + }; + + /** + * Emits the held events of the specified type to the given listener. + * + * @param {?string} eventType - Optional name of the events to replay + * @param {function} listener - The listener to which to dispatch the event + * @param {?object} context - Optional context object to use when invoking + * the listener + */ + EventHolder.prototype.emitToListener=function(eventType , listener, context ) { + var eventsOfType = this.$EventHolder_heldEvents[eventType]; + if (!eventsOfType) { + return; + } + var origEventKey = this.$EventHolder_currentEventKey; + eventsOfType.forEach(function(/*?array*/ eventHeld, /*number*/ index) { + if (!eventHeld) { + return; + } + this.$EventHolder_currentEventKey = { + eventType: eventType, + index: index + }; + listener.apply(context, eventHeld); + }.bind(this)); + this.$EventHolder_currentEventKey = origEventKey; + }; + + /** + * Provides an API that can be called during an eventing cycle to release + * the last event that was invoked, so that it is no longer "held". + * + * If it is called when not inside of an emitting cycle it will throw. + * + * @throws {Error} When called not during an eventing cycle + */ + EventHolder.prototype.releaseCurrentEvent=function() { + invariant( + this.$EventHolder_currentEventKey !== null, + 'Not in an emitting cycle; there is no current event' + ); + this.releaseEvent(this.$EventHolder_currentEventKey); + }; + + /** + * Releases the event corresponding to the handle that was returned when the + * event was first held. + * + * @param {object} token - The token returned from holdEvent + */ + EventHolder.prototype.releaseEvent=function(token ) { + delete this.$EventHolder_heldEvents[token.eventType][token.index]; + }; + + /** + * Releases all events of a certain type. + * + * @param {string} type + */ + EventHolder.prototype.releaseEventType=function(type ) { + this.$EventHolder_heldEvents[type] = []; + }; + + +module.exports = EventHolder; +}); +__d('EventValidator',["copyProperties"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * @generated SignedSource<<7149bdac6fb48595f245ad6e76938e44>> + * + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !! This file is a check-in of a static_upstream project! !! + * !! !! + * !! You should not modify this file directly. Instead: !! + * !! 1) Use `fjs use-upstream` to temporarily replace this with !! + * !! the latest version from upstream. !! + * !! 2) Make your changes, test them, etc. !! + * !! 3) Use `fjs push-upstream` to copy your changes back to !! + * !! static_upstream. !! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @providesModule EventValidator + */ +'use strict'; + +var copyProperties = require('copyProperties'); + +/** + * EventValidator is designed to validate event types to make it easier to catch + * common mistakes. It accepts a map of all of the different types of events + * that the emitter can emit. Then, if a user attempts to emit an event that is + * not one of those specified types the emitter will throw an error. Also, it + * provides a relatively simple matcher so that if it thinks that you likely + * mistyped the event name it will suggest what you might have meant to type in + * the error message. + */ +var EventValidator = { + /** + * @param {Object} emitter - The object responsible for emitting the actual + * events + * @param {Object} types - The collection of valid types that will be used to + * check for errors + * @return {Object} A new emitter with event type validation + * @example + * var types = {someEvent: true, anotherEvent: true}; + * var emitter = EventValidator.addValidation(emitter, types); + */ + addValidation: function(emitter , types ) { + var eventTypes = Object.keys(types); + var emitterWithValidation = Object.create(emitter); + + copyProperties(emitterWithValidation, { + emit: function emit(type, a, b, c, d, e, _) { + assertAllowsEventType(type, eventTypes); + return emitter.emit.call(this, type, a, b, c, d, e, _); + } + }); + + return emitterWithValidation; + } +}; + +function assertAllowsEventType(type, allowedTypes) { + if (allowedTypes.indexOf(type) === -1) { + throw new TypeError(errorMessageFor(type, allowedTypes)); + } +} + +function errorMessageFor(type, allowedTypes) { + var message = 'Unknown event type "' + type + '". '; + if (__DEV__) { + message += recommendationFor(type, allowedTypes); + } + message += 'Known event types: ' + allowedTypes.join(', ') + '.'; + return message; +} + +// Allow for good error messages +if (__DEV__) { + var recommendationFor = function (type, allowedTypes) { + var closestTypeRecommendation = closestTypeFor(type, allowedTypes); + if (isCloseEnough(closestTypeRecommendation, type)) { + return 'Did you mean "' + closestTypeRecommendation.type + '"? '; + } else { + return ''; + } + }; + + var closestTypeFor = function (type, allowedTypes) { + var typeRecommendations = allowedTypes.map( + typeRecommendationFor.bind(this, type) + ); + return typeRecommendations.sort(recommendationSort)[0]; + }; + + var typeRecommendationFor = function (type, recomendedType) { + return { + type: recomendedType, + distance: damerauLevenshteinDistance(type, recomendedType) + }; + }; + + var recommendationSort = function (recommendationA, recommendationB) { + if (recommendationA.distance < recommendationB.distance) { + return -1; + } else if (recommendationA.distance > recommendationB.distance) { + return 1; + } else { + return 0; + } + }; + + var isCloseEnough = function (closestType, actualType) { + return (closestType.distance / actualType.length) < 0.334; + }; + + var damerauLevenshteinDistance = function (a, b) { + var i, j; + var d = []; + + for (i = 0; i <= a.length; i++) { + d[i] = [i]; + } + + for (j = 1; j <= b.length; j++) { + d[0][j] = j; + } + + for (i = 1; i <= a.length; i++) { + for (j = 1; j <= b.length; j++) { + var cost = a.charAt(i - 1) === b.charAt(j - 1) ? 0 : 1; + + d[i][j] = Math.min( + d[i - 1][j] + 1, + d[i][j - 1] + 1, + d[i - 1][j - 1] + cost + ); + + if (i > 1 && j > 1 && + a.charAt(i - 1) == b.charAt(j - 2) && + a.charAt(i - 2) == b.charAt(j - 1)) { + d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + cost); + } + } + } + + return d[a.length][b.length]; + }; +} + +module.exports = EventValidator; +}); +__d('copyProperties',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * @generated SignedSource<> + * + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !! This file is a check-in of a static_upstream project! !! + * !! !! + * !! You should not modify this file directly. Instead: !! + * !! 1) Use `fjs use-upstream` to temporarily replace this with !! + * !! the latest version from upstream. !! + * !! 2) Make your changes, test them, etc. !! + * !! 3) Use `fjs push-upstream` to copy your changes back to !! + * !! static_upstream. !! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @providesModule copyProperties + */ + +/** + * Copy properties from one or more objects (up to 5) into the first object. + * This is a shallow copy. It mutates the first object and also returns it. + * + * NOTE: `arguments` has a very significant performance penalty, which is why + * we don't support unlimited arguments. + */ +function copyProperties(obj, a, b, c, d, e, f) { + obj = obj || {}; + + if (__DEV__) { + if (f) { + throw new Error('Too many arguments passed to copyProperties'); + } + } + + var args = [a, b, c, d, e]; + var ii = 0, v; + while (args[ii]) { + v = args[ii++]; + for (var k in v) { + obj[k] = v[k]; + } + + // IE ignores toString in object iteration.. See: + // webreflection.blogspot.com/2007/07/quick-fix-internet-explorer-and.html + if (v.hasOwnProperty && v.hasOwnProperty('toString') && + (typeof v.toString != 'undefined') && (obj.toString !== v.toString)) { + obj.toString = v.toString; + } + } + + return obj; +} + +module.exports = copyProperties; +}); +__d('TouchableWithoutFeedback',["React","Touchable","onlyChild"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 TouchableWithoutFeedback + * @flow + */ +'use strict'; + +var React = require('React'); +var Touchable = require('Touchable'); +var onlyChild = require('onlyChild'); + +/** + * 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 + * moving it back and you'll see that the button is once again reactivated! + * Move it back and forth several times while the scroll view is disabled. + */ +var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; + + + +/** + * 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 + * one of the primary reason a "web" app doesn't feel "native". + */ +var TouchableWithoutFeedback = React.createClass({displayName: "TouchableWithoutFeedback", + mixins: [Touchable.Mixin], + + propTypes: { + /** + * Called when the touch is released, but not if cancelled (e.g. by a scroll + * that steals the responder lock). + */ + onPress: React.PropTypes.func, + onPressIn: React.PropTypes.func, + onPressOut: React.PropTypes.func, + onLongPress: React.PropTypes.func, + }, + + getInitialState: function() { + return this.touchableGetInitialState(); + }, + + /** + * `Touchable.Mixin` self callbacks. The mixin will invoke these if they are + * defined on your component. + */ + touchableHandlePress: function(e ) { + this.props.onPress && this.props.onPress(e); + }, + + touchableHandleActivePressIn: function() { + this.props.onPressIn && this.props.onPressIn(); + }, + + touchableHandleActivePressOut: function() { + this.props.onPressOut && this.props.onPressOut(); + }, + + touchableHandleLongPress: function() { + this.props.onLongPress && this.props.onLongPress(); + }, + + touchableGetPressRectOffset: function() { + return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant! + }, + + touchableGetHighlightDelayMS: function() { + return 0; + }, + + render: function() { + // Note(avik): remove dynamic typecast once Flow has been upgraded + return (React ).cloneElement(onlyChild(this.props.children), { + accessible: true, + testID: this.props.testID, + onStartShouldSetResponder: this.touchableHandleStartShouldSetResponder, + onResponderTerminationRequest: this.touchableHandleResponderTerminationRequest, + onResponderGrant: this.touchableHandleResponderGrant, + onResponderMove: this.touchableHandleResponderMove, + onResponderRelease: this.touchableHandleResponderRelease, + onResponderTerminate: this.touchableHandleResponderTerminate + }); + } +}); + +module.exports = TouchableWithoutFeedback; +}); +__d('TouchableHighlight',["NativeMethodsMixin","React","ReactNativeViewAttributes","StyleSheet","react-timer-mixin/TimerMixin","Touchable","TouchableWithoutFeedback","View","cloneWithProps","ensureComponentIsNative","keyOf","merge","onlyChild"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 TouchableHighlight + */ +'use strict'; + +// Note (avik): add @flow when Flow supports spread properties in propTypes + +var NativeMethodsMixin = require('NativeMethodsMixin'); +var React = require('React'); +var ReactNativeViewAttributes = require('ReactNativeViewAttributes'); +var StyleSheet = require('StyleSheet'); +var TimerMixin = require('react-timer-mixin/TimerMixin'); +var Touchable = require('Touchable'); +var TouchableWithoutFeedback = require('TouchableWithoutFeedback'); +var View = require('View'); + +var cloneWithProps = require('cloneWithProps'); +var ensureComponentIsNative = require('ensureComponentIsNative'); +var keyOf = require('keyOf'); +var merge = require('merge'); +var onlyChild = require('onlyChild'); + +var DEFAULT_PROPS = { + activeOpacity: 0.8, + underlayColor: 'black', +}; + +/** + * A wrapper for making views respond properly to touches. + * On press down, the opacity of the wrapped view is decreased, which allows + * the underlay color to show through, darkening or tinting the view. The + * underlay comes from adding a view to the view hierarchy, which can sometimes + * cause unwanted visual artifacts if not used correctly, for example if the + * backgroundColor of the wrapped view isn't explicitly set to an opaque color. + * + * Example: + * + * ``` + * renderButton: function() { + * return ( + * + * + * + * ); + * }, + * ``` + */ + +var TouchableHighlight = React.createClass({displayName: "TouchableHighlight", + propTypes: Object.assign({}, + TouchableWithoutFeedback.propTypes, + /** + * Determines what the opacity of the wrapped view should be when touch is + * active. + */ + {activeOpacity: React.PropTypes.number, + /** + * The color of the underlay that will show through when the touch is + * active. + */ + underlayColor: React.PropTypes.string, + style: View.propTypes.style + }), + + mixins: [NativeMethodsMixin, TimerMixin, Touchable.Mixin], + + getDefaultProps: function() {return DEFAULT_PROPS;}, + + // Performance optimization to avoid constantly re-generating these objects. + computeSyntheticState: function(props) { + return { + activeProps: { + style: { + opacity: props.activeOpacity, + } + }, + activeUnderlayProps: { + style: { + backgroundColor: props.underlayColor, + } + }, + underlayStyle: [ + INACTIVE_UNDERLAY_PROPS.style, + props.style, + ] + }; + }, + + getInitialState: function() { + return merge( + this.touchableGetInitialState(), this.computeSyntheticState(this.props) + ); + }, + + componentDidMount: function() { + ensureComponentIsNative(this.refs[CHILD_REF]); + }, + + componentDidUpdate: function() { + ensureComponentIsNative(this.refs[CHILD_REF]); + }, + + componentWillReceiveProps: function(nextProps) { + if (nextProps.activeOpacity !== this.props.activeOpacity || + nextProps.underlayColor !== this.props.underlayColor || + nextProps.style !== this.props.style) { + this.setState(this.computeSyntheticState(nextProps)); + } + }, + + viewConfig: { + uiViewClassName: 'RCTView', + validAttributes: ReactNativeViewAttributes.RCTView + }, + + /** + * `Touchable.Mixin` self callbacks. The mixin will invoke these if they are + * defined on your component. + */ + touchableHandleActivePressIn: function() { + this.clearTimeout(this._hideTimeout); + this._hideTimeout = null; + this._showUnderlay(); + this.props.onPressIn && this.props.onPressIn(); + }, + + touchableHandleActivePressOut: function() { + if (!this._hideTimeout) { + this._hideUnderlay(); + } + this.props.onPressOut && this.props.onPressOut(); + }, + + touchableHandlePress: function() { + this.clearTimeout(this._hideTimeout); + this._showUnderlay(); + this._hideTimeout = this.setTimeout(this._hideUnderlay, 100); + this.props.onPress && this.props.onPress(); + }, + + touchableHandleLongPress: function() { + this.props.onLongPress && this.props.onLongPress(); + }, + + touchableGetPressRectOffset: function() { + return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant! + }, + + _showUnderlay: function() { + this.refs[UNDERLAY_REF].setNativeProps(this.state.activeUnderlayProps); + this.refs[CHILD_REF].setNativeProps(this.state.activeProps); + }, + + _hideUnderlay: function() { + this.clearTimeout(this._hideTimeout); + this._hideTimeout = null; + if (this.refs[UNDERLAY_REF]) { + this.refs[CHILD_REF].setNativeProps(INACTIVE_CHILD_PROPS); + this.refs[UNDERLAY_REF].setNativeProps(Object.assign({}, + INACTIVE_UNDERLAY_PROPS, + {style: this.state.underlayStyle + })); + } + }, + + render: function() { + return ( + React.createElement(View, { + ref: UNDERLAY_REF, + style: this.state.underlayStyle, + onStartShouldSetResponder: this.touchableHandleStartShouldSetResponder, + onResponderTerminationRequest: this.touchableHandleResponderTerminationRequest, + onResponderGrant: this.touchableHandleResponderGrant, + onResponderMove: this.touchableHandleResponderMove, + onResponderRelease: this.touchableHandleResponderRelease, + onResponderTerminate: this.touchableHandleResponderTerminate}, + cloneWithProps( + onlyChild(this.props.children), + { + ref: CHILD_REF, + accessible: true, + testID: this.props.testID, + } + ) + ) + ); + } +}); + +var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; +var CHILD_REF = keyOf({childRef: null}); +var UNDERLAY_REF = keyOf({underlayRef: null}); +var INACTIVE_CHILD_PROPS = { + style: StyleSheet.create({x: {opacity: 1.0}}).x, +}; +var INACTIVE_UNDERLAY_PROPS = { + style: StyleSheet.create({x: {backgroundColor: 'transparent'}}).x, +}; + +module.exports = TouchableHighlight; +}); +__d('cloneWithProps',["ReactElement","ReactPropTransferer","keyOf","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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. + * + * @typechecks static-only + * @providesModule cloneWithProps + */ + +'use strict'; + +var ReactElement = require('ReactElement'); +var ReactPropTransferer = require('ReactPropTransferer'); + +var keyOf = require('keyOf'); +var warning = require('warning'); + +var CHILDREN_PROP = keyOf({children: null}); + +/** + * Sometimes you want to change the props of a child passed to you. Usually + * this is to add a CSS class. + * + * @param {ReactElement} child child element you'd like to clone + * @param {object} props props you'd like to modify. className and style will be + * merged automatically. + * @return {ReactElement} a clone of child with props merged in. + */ +function cloneWithProps(child, props) { + if (__DEV__) { + warning( + !child.ref, + 'You are calling cloneWithProps() on a child with a ref. This is ' + + 'dangerous because you\'re creating a new child which will not be ' + + 'added as a ref to its parent.' + ); + } + + var newProps = ReactPropTransferer.mergeProps(props, child.props); + + // Use `child.props.children` if it is provided. + if (!newProps.hasOwnProperty(CHILDREN_PROP) && + child.props.hasOwnProperty(CHILDREN_PROP)) { + newProps.children = child.props.children; + } + + // The current API doesn't retain _owner and _context, which is why this + // doesn't use ReactElement.cloneAndReplaceProps. + return ReactElement.createElement(child.type, newProps); +} + +module.exports = cloneWithProps; +}); +__d('ReactPropTransferer',["Object.assign","emptyFunction","joinClasses"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactPropTransferer + */ + +'use strict'; + +var assign = require('Object.assign'); +var emptyFunction = require('emptyFunction'); +var joinClasses = require('joinClasses'); + +/** + * Creates a transfer strategy that will merge prop values using the supplied + * `mergeStrategy`. If a prop was previously unset, this just sets it. + * + * @param {function} mergeStrategy + * @return {function} + */ +function createTransferStrategy(mergeStrategy) { + return function(props, key, value) { + if (!props.hasOwnProperty(key)) { + props[key] = value; + } else { + props[key] = mergeStrategy(props[key], value); + } + }; +} + +var transferStrategyMerge = createTransferStrategy(function(a, b) { + // `merge` overrides the first object's (`props[key]` above) keys using the + // second object's (`value`) keys. An object's style's existing `propA` would + // get overridden. Flip the order here. + return assign({}, b, a); +}); + +/** + * Transfer strategies dictate how props are transferred by `transferPropsTo`. + * NOTE: if you add any more exceptions to this list you should be sure to + * update `cloneWithProps()` accordingly. + */ +var TransferStrategies = { + /** + * Never transfer `children`. + */ + children: emptyFunction, + /** + * Transfer the `className` prop by merging them. + */ + className: createTransferStrategy(joinClasses), + /** + * Transfer the `style` prop (which is an object) by merging them. + */ + style: transferStrategyMerge +}; + +/** + * Mutates the first argument by transferring the properties from the second + * argument. + * + * @param {object} props + * @param {object} newProps + * @return {object} + */ +function transferInto(props, newProps) { + for (var thisKey in newProps) { + if (!newProps.hasOwnProperty(thisKey)) { + continue; + } + + var transferStrategy = TransferStrategies[thisKey]; + + if (transferStrategy && TransferStrategies.hasOwnProperty(thisKey)) { + transferStrategy(props, thisKey, newProps[thisKey]); + } else if (!props.hasOwnProperty(thisKey)) { + props[thisKey] = newProps[thisKey]; + } + } + return props; +} + +/** + * ReactPropTransferer are capable of transferring props to another component + * using a `transferPropsTo` method. + * + * @class ReactPropTransferer + */ +var ReactPropTransferer = { + + /** + * Merge two props objects using TransferStrategies. + * + * @param {object} oldProps original props (they take precedence) + * @param {object} newProps new props to merge in + * @return {object} a new object containing both sets of props merged. + */ + mergeProps: function(oldProps, newProps) { + return transferInto(assign({}, oldProps), newProps); + } + +}; + +module.exports = ReactPropTransferer; +}); +__d('joinClasses',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 joinClasses + * @typechecks static-only + */ + +'use strict'; + +/** + * Combines multiple className strings into one. + * http://jsperf.com/joinclasses-args-vs-array + * + * @param {...?string} classes + * @return {string} + */ +function joinClasses(className/* ... */) { + if (!className) { + className = ''; + } + var nextClass; + var argLength = arguments.length; + if (argLength > 1) { + for (var ii = 1; ii < argLength; ii++) { + nextClass = arguments[ii]; + if (nextClass) { + className = (className ? className + ' ' : '') + nextClass; + } + } + } + return className; +} + +module.exports = joinClasses; +}); +__d('ensureComponentIsNative',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 ensureComponentIsNative + * @flow + */ +'use strict'; + +var invariant = require('invariant'); + +var ensureComponentIsNative = function(component ) { + invariant( + component && typeof component.setNativeProps === 'function', + 'Touchable child must either be native or forward setNativeProps to a ' + + 'native component' + ); +}; + +module.exports = ensureComponentIsNative; +}); +__d('TouchableOpacity',["NativeMethodsMixin","POPAnimationMixin","React","Touchable","TouchableWithoutFeedback","cloneWithProps","ensureComponentIsNative","flattenStyle","keyOf","onlyChild"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 TouchableOpacity + */ +'use strict'; + +// Note (avik): add @flow when Flow supports spread properties in propTypes + +var NativeMethodsMixin = require('NativeMethodsMixin'); +var POPAnimationMixin = require('POPAnimationMixin'); +var React = require('React'); +var Touchable = require('Touchable'); +var TouchableWithoutFeedback = require('TouchableWithoutFeedback'); + +var cloneWithProps = require('cloneWithProps'); +var ensureComponentIsNative = require('ensureComponentIsNative'); +var flattenStyle = require('flattenStyle'); +var keyOf = require('keyOf'); +var onlyChild = require('onlyChild'); + +/** + * A wrapper for making views respond properly to touches. + * On press down, the opacity of the wrapped view is decreased, dimming it. + * This is done without actually changing the view hierarchy, and in general is + * easy to add to an app without weird side-effects. + * + * Example: + * + * ``` + * renderButton: function() { + * return ( + * + * + * + * ); + * }, + * ``` + */ + +var TouchableOpacity = React.createClass({displayName: "TouchableOpacity", + mixins: [Touchable.Mixin, NativeMethodsMixin, POPAnimationMixin], + + propTypes: Object.assign({}, + TouchableWithoutFeedback.propTypes, + /** + * Determines what the opacity of the wrapped view should be when touch is + * active. + */ + {activeOpacity: React.PropTypes.number + }), + + getDefaultProps: function() { + return { + activeOpacity: 0.2, + }; + }, + + getInitialState: function() { + return this.touchableGetInitialState(); + }, + + componentDidMount: function() { + ensureComponentIsNative(this.refs[CHILD_REF]); + }, + + componentDidUpdate: function() { + ensureComponentIsNative(this.refs[CHILD_REF]); + }, + + setOpacityTo: function(value) { + if (POPAnimationMixin) { + // Reset with animation if POP is available + this.stopAllAnimations(); + var anim = { + type: this.AnimationTypes.linear, + property: this.AnimationProperties.opacity, + toValue: value, + }; + this.startAnimation(CHILD_REF, anim); + } else { + // Reset immediately if POP is unavailable + this.refs[CHILD_REF].setNativeProps({ + opacity: value + }); + } + }, + + /** + * `Touchable.Mixin` self callbacks. The mixin will invoke these if they are + * defined on your component. + */ + touchableHandleActivePressIn: function() { + this.refs[CHILD_REF].setNativeProps({ + opacity: this.props.activeOpacity + }); + this.props.onPressIn && this.props.onPressIn(); + }, + + touchableHandleActivePressOut: function() { + var child = onlyChild(this.props.children); + var childStyle = flattenStyle(child.props.style) || {}; + this.setOpacityTo(childStyle.opacity === undefined ? 1 : childStyle.opacity); + this.props.onPressOut && this.props.onPressOut(); + }, + + touchableHandlePress: function() { + this.props.onPress && this.props.onPress(); + }, + + touchableHandleLongPress: function() { + this.props.onLongPress && this.props.onLongPress(); + }, + + touchableGetPressRectOffset: function() { + return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant! + }, + + touchableGetHighlightDelayMS: function() { + return 0; + }, + + render: function() { + return cloneWithProps(onlyChild(this.props.children), { + ref: CHILD_REF, + accessible: true, + testID: this.props.testID, + onStartShouldSetResponder: this.touchableHandleStartShouldSetResponder, + onResponderTerminationRequest: this.touchableHandleResponderTerminationRequest, + onResponderGrant: this.touchableHandleResponderGrant, + onResponderMove: this.touchableHandleResponderMove, + onResponderRelease: this.touchableHandleResponderRelease, + onResponderTerminate: this.touchableHandleResponderTerminate, + }); + }, +}); + +/** + * 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 + * moving it back and you'll see that the button is once again reactivated! + * Move it back and forth several times while the scroll view is disabled. + */ +var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; + +var CHILD_REF = keyOf({childRef: null}); + +module.exports = TouchableOpacity; +}); +__d('POPAnimationMixin',["POPAnimation","React","invariant","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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() { + return { + _currentAnimationsByNodeHandle: {}, + }; + }, + + _ensureBookkeepingSetup: function(nodeHandle ) { + 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 , + anim , + doneCallback + ) { + var animID = 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 , + animID , + doneCallback + ) { + this._ensureBookkeepingSetup(nodeHandle); + var animations = this.state._currentAnimationsByNodeHandle[nodeHandle]; + var animIndex = animations.length; + animations.push(animID); + var cleanupWrapper = function(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); + }.bind(this); + POPAnimation.addAnimation(nodeHandle, animID, cleanupWrapper); + }, + + /** + * 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 , + onSuccess , + onFailure + ) { + var numReturned = 0; + var numFinished = 0; + var numAnimations = animations.length; + var metaCallback = function(finished) { + if (finished) { + ++numFinished; + } + if (++numReturned === numAnimations) { + onSuccess && onSuccess(numFinished === numAnimations); + } + }; + animations.forEach(function(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); + } + }.bind(this)); + }, + + /** + * 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 ) { + 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 ) { + 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 , + frame , + type , + velocity , + doneCallback + ) { + 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(); + } +}; + +module.exports = POPAnimationMixin; + +} +}); +__d('POPAnimation',["NativeModules","ReactPropTypes","createStrictShapeTypeChecker","getObjectValues","invariant","merge"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 + * @flow + */ +'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, +}; + + + + + + + + + + + + + + + +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() { + return ++this.lastUsedTag; + }, + + createAnimation: function(typeName , attrs ) { + var tag = this.allocateTagForAnimation(); + + if (__DEV__) { + POPAnimation.attributeChecker( + {attrs:attrs}, + 'attrs', + 'POPAnimation.createAnimation' + ); + POPAnimation.attributeChecker( + {attrs: {type: typeName}}, + 'attrs', + 'POPAnimation.createAnimation' + ); + } + + RCTPOPAnimationManager.createAnimationInternal(tag, typeName, attrs); + return tag; + }, + + createSpringAnimation: function(attrs ) { + return this.createAnimation(this.Types.spring, attrs); + }, + + createDecayAnimation: function(attrs ) { + return this.createAnimation(this.Types.decay, attrs); + }, + + createLinearAnimation: function(attrs ) { + return this.createAnimation(this.Types.linear, attrs); + }, + + createEaseInAnimation: function(attrs ) { + return this.createAnimation(this.Types.easeIn, attrs); + }, + + createEaseOutAnimation: function(attrs ) { + return this.createAnimation(this.Types.easeOut, attrs); + }, + + createEaseInEaseOutAnimation: function(attrs ) { + return this.createAnimation(this.Types.easeInEaseOut, attrs); + }, + + addAnimation: function(nodeHandle , anim , callback ) { + RCTPOPAnimationManager.addAnimation(nodeHandle, anim, callback); + }, + + removeAnimation: function(nodeHandle , anim ) { + 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; + +} +}); +__d('getObjectValues',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * @generated SignedSource<> + * + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * !! This file is a check-in of a static_upstream project! !! + * !! !! + * !! You should not modify this file directly. Instead: !! + * !! 1) Use `fjs use-upstream` to temporarily replace this with !! + * !! the latest version from upstream. !! + * !! 2) Make your changes, test them, etc. !! + * !! 3) Use `fjs push-upstream` to copy your changes back to !! + * !! static_upstream. !! + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * @providesModule getObjectValues + * @typechecks + */ + +/** + * Retrieve an object's values as an array. + * + * If you are looking for a function that creates an Array instance based + * on an "Array-like" object, use createArrayFrom instead. + * + * @param {object} obj An object. + * @return {array} The object's values. + */ +function getObjectValues(obj) { + var values = []; + for (var key in obj) { + values.push(obj[key]); + } + return values; +} + +module.exports = getObjectValues; +}); +__d('WebView',["ActivityIndicatorIOS","EdgeInsetsPropType","React","ReactNativeViewAttributes","StyleSheet","Text","View","invariant","keyMirror","requireNativeComponent","NativeModules"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 WebView + * @flow + */ +'use strict'; + +var ActivityIndicatorIOS = require('ActivityIndicatorIOS'); +var EdgeInsetsPropType = require('EdgeInsetsPropType'); +var React = require('React'); +var ReactNativeViewAttributes = require('ReactNativeViewAttributes'); +var StyleSheet = require('StyleSheet'); +var Text = require('Text'); +var View = require('View'); + +var invariant = require('invariant'); +var keyMirror = require('keyMirror'); +var requireNativeComponent = require('requireNativeComponent'); + +var PropTypes = React.PropTypes; +var RCTWebViewManager = require('NativeModules').WebViewManager; + +var BGWASH = 'rgba(255,255,255,0.8)'; +var RCT_WEBVIEW_REF = 'webview'; + +var WebViewState = keyMirror({ + IDLE: null, + LOADING: null, + ERROR: null, +}); + +var NavigationType = { + click: RCTWebViewManager.NavigationType.LinkClicked, + formsubmit: RCTWebViewManager.NavigationType.FormSubmitted, + backforward: RCTWebViewManager.NavigationType.BackForward, + reload: RCTWebViewManager.NavigationType.Reload, + formresubmit: RCTWebViewManager.NavigationType.FormResubmitted, + other: RCTWebViewManager.NavigationType.Other, +}; + + + + + + + + + +var defaultRenderLoading = function() + {return React.createElement(View, {style: styles.loadingView}, + React.createElement(ActivityIndicatorIOS, null) + );} +; +var defaultRenderError = function(errorDomain, errorCode, errorDesc) + {return React.createElement(View, {style: styles.errorContainer}, + React.createElement(Text, {style: styles.errorTextTitle}, + "Error loading page" + ), + React.createElement(Text, {style: styles.errorText}, + 'Domain: ' + errorDomain + ), + React.createElement(Text, {style: styles.errorText}, + 'Error Code: ' + errorCode + ), + React.createElement(Text, {style: styles.errorText}, + 'Description: ' + errorDesc + ) + );} +; + +var WebView = React.createClass({displayName: "WebView", + statics: { + NavigationType: NavigationType, + }, + + propTypes: { + url: PropTypes.string, + html: PropTypes.string, + renderError: PropTypes.func, // view to show if there's an error + renderLoading: PropTypes.func, // loading indicator to show + bounces: PropTypes.bool, + scrollEnabled: PropTypes.bool, + automaticallyAdjustContentInsets: PropTypes.bool, + shouldInjectAJAXHandler: PropTypes.bool, + contentInset: EdgeInsetsPropType, + onNavigationStateChange: PropTypes.func, + startInLoadingState: PropTypes.bool, // force WebView to show loadingView on first load + style: View.propTypes.style, + /** + * Used for android only, JS is enabled by default for WebView on iOS + */ + javaScriptEnabledAndroid: PropTypes.bool, + }, + + getInitialState: function() { + return { + viewState: WebViewState.IDLE, + lastErrorEvent: (null ), + startInLoadingState: true, + }; + }, + + componentWillMount: function() { + if (this.props.startInLoadingState) { + this.setState({viewState: WebViewState.LOADING}); + } + }, + + render: function() { + var otherView = null; + + if (this.state.viewState === WebViewState.LOADING) { + otherView = (this.props.renderLoading || defaultRenderLoading)(); + } else if (this.state.viewState === WebViewState.ERROR) { + var errorEvent = this.state.lastErrorEvent; + invariant( + errorEvent != null, + 'lastErrorEvent expected to be non-null' + ); + otherView = (this.props.renderError || defaultRenderError)( + errorEvent.domain, + errorEvent.code, + errorEvent.description + ); + } else if (this.state.viewState !== WebViewState.IDLE) { + console.error( + 'RCTWebView invalid state encountered: ' + this.state.loading + ); + } + + var webViewStyles = [styles.container, styles.webView, this.props.style]; + if (this.state.viewState === WebViewState.LOADING || + this.state.viewState === WebViewState.ERROR) { + // if we're in either LOADING or ERROR states, don't show the webView + webViewStyles.push(styles.hidden); + } + + var webView = + React.createElement(RCTWebView, { + ref: RCT_WEBVIEW_REF, + key: "webViewKey", + style: webViewStyles, + url: this.props.url, + html: this.props.html, + bounces: this.props.bounces, + scrollEnabled: this.props.scrollEnabled, + shouldInjectAJAXHandler: this.props.shouldInjectAJAXHandler, + contentInset: this.props.contentInset, + automaticallyAdjustContentInsets: this.props.automaticallyAdjustContentInsets, + onLoadingStart: this.onLoadingStart, + onLoadingFinish: this.onLoadingFinish, + onLoadingError: this.onLoadingError} + ); + + return ( + React.createElement(View, {style: styles.container}, + webView, + otherView + ) + ); + }, + + goForward: function() { + RCTWebViewManager.goForward(this.getWebWiewHandle()); + }, + + goBack: function() { + RCTWebViewManager.goBack(this.getWebWiewHandle()); + }, + + reload: function() { + RCTWebViewManager.reload(this.getWebWiewHandle()); + }, + + /** + * We return an event with a bunch of fields including: + * url, title, loading, canGoBack, canGoForward + */ + updateNavigationState: function(event ) { + if (this.props.onNavigationStateChange) { + this.props.onNavigationStateChange(event.nativeEvent); + } + }, + + getWebWiewHandle: function() { + return React.findNodeHandle(this.refs[RCT_WEBVIEW_REF]); + }, + + onLoadingStart: function(event ) { + this.updateNavigationState(event); + }, + + onLoadingError: function(event ) { + event.persist(); // persist this event because we need to store it + console.error("encountered an error loading page", event.nativeEvent); + + this.setState({ + lastErrorEvent: event.nativeEvent, + viewState: WebViewState.ERROR + }); + }, + + onLoadingFinish: function(event ) { + this.setState({ + viewState: WebViewState.IDLE, + }); + this.updateNavigationState(event); + }, +}); + +var RCTWebView = requireNativeComponent('RCTWebView', WebView); + +var styles = StyleSheet.create({ + container: { + flex: 1, + }, + errorContainer: { + flex: 1, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: BGWASH, + }, + errorText: { + fontSize: 14, + textAlign: 'center', + marginBottom: 2, + }, + errorTextTitle: { + fontSize: 15, + fontWeight: '500', + marginBottom: 10, + }, + hidden: { + height: 0, + flex: 0, // disable 'flex:1' when hiding a View + }, + loadingView: { + backgroundColor: BGWASH, + flex: 1, + justifyContent: 'center', + alignItems: 'center', + }, + webView: { + backgroundColor: '#ffffff', + } +}); + +module.exports = WebView; +}); +__d('AlertIOS',["NativeModules","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 AlertIOS + * @flow + */ +'use strict'; + +var RCTAlertManager = require('NativeModules').AlertManager; +var invariant = require('invariant'); + +var DEFAULT_BUTTON_TEXT = 'OK'; +var DEFAULT_BUTTON = { + text: DEFAULT_BUTTON_TEXT, + onPress: null, +}; + +/** + * Launches an alert dialog with the specified title and message. + * + * Optionally provide a list of buttons. Tapping any button will fire the + * respective onPress callback and dismiss the alert. By default, the only + * button will be an 'OK' button + * + * The last button in the list will be considered the 'Primary' button and + * it will appear bold. + * + * ``` + * AlertIOS.alert( + * 'Foo Title', + * 'My Alert Msg', + * [ + * {text: 'Foo', onPress: () => console.log('Foo Pressed!')}, + * {text: 'Bar', onPress: () => console.log('Bar Pressed!')}, + * ] + * ) + * ``` + */ + +function AlertIOS(){} + AlertIOS.alert=function( +title , + message , + buttons + + + , + type + ) { + var callbacks = []; + var buttonsSpec = []; + title = title || ''; + message = message || ''; + buttons = buttons || [DEFAULT_BUTTON]; + type = type || ''; + + buttons.forEach(function(btn, index) { + callbacks[index] = btn.onPress; + var btnDef = {}; + btnDef[index] = btn.text || DEFAULT_BUTTON_TEXT; + buttonsSpec.push(btnDef); + }); + RCTAlertManager.alertWithArgs({ + title:title, + message:message, + buttons: buttonsSpec, + type:type, + }, function(id, value) { + var cb = callbacks[id]; + cb && cb(value); + }); + }; + + AlertIOS.prompt=function( +title , + value , + buttons + + + , + callback + ) { + if (arguments.length === 2) { + if (typeof value === 'object') { + buttons = value; + value = undefined; + } else if (typeof value === 'function') { + callback = value; + value = undefined; + } + } else if (arguments.length === 3 && typeof buttons === 'function') { + callback = buttons; + buttons = undefined; + } + + invariant( + !(callback && buttons) && (callback || buttons), + 'Must provide either a button list or a callback, but not both' + ); + + if (!buttons) { + buttons = [{ + text: 'Cancel', + }, { + text: 'OK', + onPress: callback + }]; + } + this.alert(title, value, buttons, 'plain-text'); + }; + + +module.exports = AlertIOS; +}); +__d('AppRegistry',["invariant","renderApplication","RCTRenderingPerf"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 AppRegistry + * @flow + */ +'use strict'; + +var invariant = require('invariant'); +var renderApplication = require('renderApplication'); + +if (__DEV__) { + // In order to use Cmd+P to record/dump perf data, we need to make sure + // this module is available in the bundle + require('RCTRenderingPerf'); +} + +var runnables = {}; + + + + + + + +/** + * `AppRegistry` is the JS entry point to running all React Native apps. App + * root components should register themselves with + * `AppRegistry.registerComponent`, then the native system can load the bundle + * for the app and then actually run the app when it's ready by invoking + * `AppRegistry.runApplication`. + * + * `AppRegistry` should be `require`d early in the `require` sequence to make + * sure the JS execution environment is setup before other modules are + * `require`d. + */ +var AppRegistry = { + registerConfig: function(config ) { + for (var i = 0; i < config.length; ++i) { + var appConfig = config[i]; + if (appConfig.run) { + AppRegistry.registerRunnable(appConfig.appKey, appConfig.run); + } else { + AppRegistry.registerComponent(appConfig.appKey, appConfig.component); + } + } + }, + + registerComponent: function(appKey , getComponentFunc ) { + runnables[appKey] = { + run: function(appParameters) + {return renderApplication(getComponentFunc(), appParameters.initialProps, appParameters.rootTag);} + }; + return appKey; + }, + + registerRunnable: function(appKey , func ) { + runnables[appKey] = {run: func}; + return appKey; + }, + + runApplication: function(appKey , appParameters ) { + console.log( + 'Running application "' + appKey + '" with appParams: ' + + JSON.stringify(appParameters) + '. ' + + '__DEV__ === ' + __DEV__ + + ', development-level warning are ' + (__DEV__ ? 'ON' : 'OFF') + + ', performance optimizations are ' + (__DEV__ ? 'OFF' : 'ON') + ); + invariant( + runnables[appKey] && runnables[appKey].run, + 'Application ' + appKey + ' has not been registered.' + ); + runnables[appKey].run(appParameters); + }, +}; + +module.exports = AppRegistry; +}); +__d('renderApplication',["React","StyleSheet","View","WarningBox","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 renderApplication + * @flow + */ +'use strict'; + +var React = require('React'); +var StyleSheet = require('StyleSheet'); +var View = require('View'); +var WarningBox = require('WarningBox'); + +var invariant = require('invariant'); + +function renderApplication ( + RootComponent , + initialProps , + rootTag +) { + invariant( + rootTag, + 'Expect to have a valid rootTag, instead got ', rootTag + ); + var shouldRenderWarningBox = __DEV__ && console.yellowBoxEnabled; + var warningBox = shouldRenderWarningBox ? React.createElement(WarningBox, null) : null; + React.render( + React.createElement(View, {style: styles.appContainer}, + React.createElement(RootComponent, React.__spread({}, + initialProps) + ), + warningBox + ), + rootTag + ); +} + +var styles = StyleSheet.create({ + appContainer: { + position: 'absolute', + left: 0, + top: 0, + right: 0, + bottom: 0, + }, +}); + +module.exports = renderApplication; +}); +__d('WarningBox',["AsyncStorage","EventEmitter","Map","PanResponder","React","StyleSheet","Text","TouchableOpacity","View","invariant","rebound/rebound","stringifySafe","Dimensions"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 WarningBox + */ +'use strict'; + +var AsyncStorage = require('AsyncStorage'); +var EventEmitter = require('EventEmitter'); +var Map = require('Map'); +var PanResponder = require('PanResponder'); +var React = require('React'); +var StyleSheet = require('StyleSheet'); +var Text = require('Text'); +var TouchableOpacity = require('TouchableOpacity'); +var View = require('View'); + +var invariant = require('invariant'); +var rebound = require('rebound/rebound'); +var stringifySafe = require('stringifySafe'); + +var SCREEN_WIDTH = require('Dimensions').get('window').width; +var IGNORED_WARNINGS_KEY = '__DEV_WARNINGS_IGNORED'; + +var consoleWarn = console.warn.bind(console); + +var warningCounts = new Map(); +var ignoredWarnings = []; +var totalWarningCount = 0; +var warningCountEvents = new EventEmitter(); + +/** + * WarningBox renders warnings on top of the app being developed. Warnings help + * guard against subtle yet significant issues that can impact the quality of + * your application, such as accessibility and memory leaks. This "in your + * face" style of warning allows developers to notice and correct these issues + * as quickly as possible. + * + * The warning box is currently opt-in. Set the following flag to enable it: + * + * `console.yellowBoxEnabled = true;` + * + * If "ignore" is tapped on a warning, the WarningBox will record that warning + * and will not display it again. This is useful for hiding errors that already + * exist or have been introduced elsewhere. To re-enable all of the errors, set + * the following: + * + * `console.yellowBoxResetIgnored = true;` + * + * This can also be set permanently, and ignore will only silence the warnings + * until the next refresh. + */ + +if (__DEV__) { + console.warn = function() { + consoleWarn.apply(null, arguments); + if (!console.yellowBoxEnabled) { + return; + } + var warning = Array.prototype.map.call(arguments, stringifySafe).join(' '); + if (!console.yellowBoxResetIgnored && + ignoredWarnings.indexOf(warning) !== -1) { + return; + } + var count = warningCounts.has(warning) ? warningCounts.get(warning) + 1 : 1; + warningCounts.set(warning, count); + totalWarningCount += 1; + warningCountEvents.emit('count', totalWarningCount); + }; +} + +function saveIgnoredWarnings() { + AsyncStorage.setItem( + IGNORED_WARNINGS_KEY, + JSON.stringify(ignoredWarnings), + function(err) { + if (err) { + console.warn('Could not save ignored warnings.', err); + } + } + ); +} + +AsyncStorage.getItem(IGNORED_WARNINGS_KEY, function(err, data) { + if (!err && data && !console.yellowBoxResetIgnored) { + ignoredWarnings = JSON.parse(data); + } +}); + +var WarningRow = React.createClass({displayName: "WarningRow", + componentWillMount: function() { + this.springSystem = new rebound.SpringSystem(); + this.dismissalSpring = this.springSystem.createSpring(); + this.dismissalSpring.setRestSpeedThreshold(0.05); + this.dismissalSpring.setCurrentValue(0); + this.dismissalSpring.addListener({ + onSpringUpdate: function() { + var val = this.dismissalSpring.getCurrentValue(); + this.text && this.text.setNativeProps({ + left: SCREEN_WIDTH * val, + }); + this.container && this.container.setNativeProps({ + opacity: 1 - val, + }); + this.closeButton && this.closeButton.setNativeProps({ + opacity: 1 - (val * 5), + }); + }.bind(this), + onSpringAtRest: function() { + if (this.dismissalSpring.getCurrentValue()) { + this.collapseSpring.setEndValue(1); + } + }.bind(this), + }); + this.collapseSpring = this.springSystem.createSpring(); + this.collapseSpring.setRestSpeedThreshold(0.05); + this.collapseSpring.setCurrentValue(0); + this.collapseSpring.getSpringConfig().friction = 20; + this.collapseSpring.getSpringConfig().tension = 200; + this.collapseSpring.addListener({ + onSpringUpdate: function() { + var val = this.collapseSpring.getCurrentValue(); + this.container && this.container.setNativeProps({ + height: Math.abs(46 - (val * 46)), + }); + }.bind(this), + onSpringAtRest: function() { + this.props.onDismissed(); + }.bind(this), + }); + this.panGesture = PanResponder.create({ + onStartShouldSetPanResponder: function() { + return !! this.dismissalSpring.getCurrentValue(); + }.bind(this), + onMoveShouldSetPanResponder: function() {return true;}, + onPanResponderGrant: function() { + this.isResponderOnlyToBlockTouches = + !! this.dismissalSpring.getCurrentValue(); + }.bind(this), + onPanResponderMove: function(e, gestureState) { + if (this.isResponderOnlyToBlockTouches) { + return; + } + this.dismissalSpring.setCurrentValue(gestureState.dx / SCREEN_WIDTH); + }.bind(this), + onPanResponderRelease: function(e, gestureState) { + if (this.isResponderOnlyToBlockTouches) { + return; + } + var gestureCompletion = gestureState.dx / SCREEN_WIDTH; + var doesGestureRelease = (gestureState.vx + gestureCompletion) > 0.5; + this.dismissalSpring.setEndValue(doesGestureRelease ? 1 : 0); + }.bind(this) + }); + }, + render: function() { + var countText; + if (warningCounts.get(this.props.warning) > 1) { + countText = ( + React.createElement(Text, {style: styles.bold}, + "(", warningCounts.get(this.props.warning), ")", " " + ) + ); + } + return ( + React.createElement(View, React.__spread({ + style: styles.warningBox, + ref: function(container) { this.container = container; }.bind(this)}, + this.panGesture.panHandlers), + React.createElement(TouchableOpacity, { + onPress: this.props.onOpened}, + React.createElement(View, null, + React.createElement(Text, { + style: styles.warningText, + numberOfLines: 2, + ref: function(text) { this.text = text; }.bind(this)}, + countText, + this.props.warning + ) + ) + ), + React.createElement(View, { + ref: function(closeButton) { this.closeButton = closeButton; }.bind(this), + style: styles.closeButton}, + React.createElement(TouchableOpacity, { + onPress: function() { + this.dismissalSpring.setEndValue(1); + }.bind(this)}, + React.createElement(Text, {style: styles.closeButtonText}, "✕") + ) + ) + ) + ); + } +}); + +var WarningBoxOpened = React.createClass({displayName: "WarningBoxOpened", + render: function() { + var countText; + if (warningCounts.get(this.props.warning) > 1) { + countText = ( + React.createElement(Text, {style: styles.bold}, + "(", warningCounts.get(this.props.warning), ")", " " + ) + ); + } + return ( + React.createElement(TouchableOpacity, { + activeOpacity: 0.9, + onPress: this.props.onClose}, + React.createElement(View, {style: styles.yellowBox}, + React.createElement(Text, {style: styles.yellowBoxText}, + countText, + this.props.warning + ), + React.createElement(View, {style: styles.yellowBoxButtons}, + React.createElement(View, {style: styles.yellowBoxButton}, + React.createElement(TouchableOpacity, { + onPress: this.props.onDismissed}, + React.createElement(Text, {style: styles.yellowBoxButtonText}, + "Dismiss" + ) + ) + ), + React.createElement(View, {style: styles.yellowBoxButton}, + React.createElement(TouchableOpacity, { + onPress: this.props.onIgnored}, + React.createElement(Text, {style: styles.yellowBoxButtonText}, + "Ignore" + ) + ) + ) + ) + ) + ) + ); + }, +}); + +var canMountWarningBox = true; + +var WarningBox = React.createClass({displayName: "WarningBox", + getInitialState: function() { + return { + totalWarningCount:totalWarningCount, + openWarning: null, + }; + }, + componentWillMount: function() { + if (console.yellowBoxResetIgnored) { + AsyncStorage.setItem(IGNORED_WARNINGS_KEY, '[]', function(err) { + if (err) { + console.warn('Could not reset ignored warnings.', err); + } + }); + ignoredWarnings = []; + } + }, + componentDidMount: function() { + invariant( + canMountWarningBox, + 'There can only be one WarningBox' + ); + canMountWarningBox = false; + warningCountEvents.addListener( + 'count', + this._onWarningCount + ); + }, + componentWillUnmount: function() { + warningCountEvents.removeAllListeners(); + canMountWarningBox = true; + }, + _onWarningCount: function(totalWarningCount) { + // Must use setImmediate because warnings often happen during render and + // state cannot be set while rendering + setImmediate(function() { + this.setState({ totalWarningCount:totalWarningCount, }); + }.bind(this)); + }, + _onDismiss: function(warning) { + warningCounts["delete"](warning); + this.setState({ + openWarning: null, + }); + }, + render: function() { + if (warningCounts.size === 0) { + return React.createElement(View, null); + } + if (this.state.openWarning) { + return ( + React.createElement(WarningBoxOpened, { + warning: this.state.openWarning, + onClose: function() { + this.setState({ openWarning: null }); + }.bind(this), + onDismissed: this._onDismiss.bind(this, this.state.openWarning), + onIgnored: function() { + ignoredWarnings.push(this.state.openWarning); + saveIgnoredWarnings(); + this._onDismiss(this.state.openWarning); + }.bind(this)} + ) + ); + } + var warningRows = []; + warningCounts.forEach(function(count, warning) { + warningRows.push( + React.createElement(WarningRow, { + key: warning, + onOpened: function() { + this.setState({ openWarning: warning }); + }.bind(this), + onDismissed: this._onDismiss.bind(this, warning), + warning: warning} + ) + ); + }.bind(this)); + return ( + React.createElement(View, {style: styles.warningContainer}, + warningRows + ) + ); + }, +}); + +var styles = StyleSheet.create({ + bold: { + fontWeight: 'bold', + }, + closeButton: { + position: 'absolute', + right: 0, + height: 46, + width: 46, + }, + closeButtonText: { + color: 'white', + fontSize: 32, + position: 'relative', + left: 8, + }, + warningContainer: { + position: 'absolute', + left: 0, + right: 0, + bottom: 0 + }, + warningBox: { + position: 'relative', + backgroundColor: 'rgba(171, 124, 36, 0.9)', + flex: 1, + height: 46, + }, + warningText: { + color: 'white', + position: 'absolute', + left: 0, + marginLeft: 15, + marginRight: 46, + top: 7, + }, + yellowBox: { + backgroundColor: 'rgba(171, 124, 36, 0.9)', + position: 'absolute', + left: 0, + right: 0, + top: 0, + bottom: 0, + padding: 15, + paddingTop: 35, + }, + yellowBoxText: { + color: 'white', + fontSize: 20, + }, + yellowBoxButtons: { + flexDirection: 'row', + position: 'absolute', + bottom: 0, + }, + yellowBoxButton: { + flex: 1, + padding: 25, + }, + yellowBoxButtonText: { + color: 'white', + fontSize: 16, + } +}); + +module.exports = WarningBox; +}); +__d('AsyncStorage',["NativeModules"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 AsyncStorage + * @flow-weak + */ +'use strict'; + +var NativeModules = require('NativeModules'); +var RCTAsyncLocalStorage = NativeModules.AsyncLocalStorage; +var RCTAsyncRocksDBStorage = NativeModules.AsyncRocksDBStorage; + +// We use RocksDB if available. +var RCTAsyncStorage = RCTAsyncRocksDBStorage || RCTAsyncLocalStorage; + +/** + * AsyncStorage is a simple, asynchronous, persistent, global, key-value storage + * system. It should be used instead of LocalStorage. + * + * It is recommended that you use an abstraction on top of AsyncStorage instead + * of AsyncStorage directly for anything more than light usage since it + * operates globally. + * + * This JS code is a simple facad over the native iOS implementation to provide + * a clear JS API, real Error objects, and simple non-multi functions. Each + * method returns a `Promise` object. + */ +var AsyncStorage = { + /** + * Fetches `key` and passes the result to `callback`, along with an `Error` if + * there is any. Returns a `Promise` object. + */ + getItem: function( + key , + callback + ) { + return new Promise(function(resolve, reject) { + RCTAsyncStorage.multiGet([key], function(errors, result) { + // Unpack result to get value from [[key,value]] + var value = (result && result[0] && result[0][1]) ? result[0][1] : null; + callback && callback((errors && convertError(errors[0])) || null, value); + if (errors) { + reject(convertError(errors[0])); + } else { + resolve(value); + } + }); + }); + }, + + /** + * Sets `value` for `key` and calls `callback` on completion, along with an + * `Error` if there is any. Returns a `Promise` object. + */ + setItem: function( + key , + value , + callback + ) { + return new Promise(function(resolve, reject) { + RCTAsyncStorage.multiSet([[key,value]], function(errors) { + callback && callback((errors && convertError(errors[0])) || null); + if (errors) { + reject(convertError(errors[0])); + } else { + resolve(null); + } + }); + }); + }, + /** + * Returns a `Promise` object. + */ + removeItem: function( + key , + callback + ) { + return new Promise(function(resolve, reject) { + RCTAsyncStorage.multiRemove([key], function(errors) { + callback && callback((errors && convertError(errors[0])) || null); + if (errors) { + reject(convertError(errors[0])); + } else { + resolve(null); + } + }); + }); + }, + + /** + * Merges existing value with input value, assuming they are stringified json. Returns a `Promise` object. + * + * Not supported by all native implementations. + */ + mergeItem: function( + key , + value , + callback + ) { + return new Promise(function(resolve, reject) { + RCTAsyncStorage.multiMerge([[key,value]], function(errors) { + callback && callback((errors && convertError(errors[0])) || null); + if (errors) { + reject(convertError(errors[0])); + } else { + resolve(null); + } + }); + }); + }, + + /** + * Erases *all* AsyncStorage for all clients, libraries, etc. You probably + * don't want to call this - use removeItem or multiRemove to clear only your + * own keys instead. Returns a `Promise` object. + */ + clear: function(callback ) { + return new Promise(function(resolve, reject) { + RCTAsyncStorage.clear(function(error) { + callback && callback(convertError(error)); + if (error && convertError(error)){ + reject(convertError(error)); + } else { + resolve(null); + } + }); + }); + }, + + /** + * Gets *all* keys known to the system, for all callers, libraries, etc. Returns a `Promise` object. + */ + getAllKeys: function(callback ) { + return new Promise(function(resolve, reject) { + RCTAsyncStorage.getAllKeys(function(error, keys) { + callback && callback(convertError(error), keys); + if (error) { + reject(convertError(error)); + } else { + resolve(keys); + } + }); + }); + }, + + /** + * The following batched functions are useful for executing a lot of + * operations at once, allowing for native optimizations and provide the + * convenience of a single callback after all operations are complete. + * + * These functions return arrays of errors, potentially one for every key. + * For key-specific errors, the Error object will have a key property to + * indicate which key caused the error. + */ + + /** + * multiGet invokes callback with an array of key-value pair arrays that + * matches the input format of multiSet. Returns a `Promise` object. + * + * multiGet(['k1', 'k2'], cb) -> cb([['k1', 'val1'], ['k2', 'val2']]) + */ + multiGet: function( + keys , + callback + ) { + return new Promise(function(resolve, reject) { + RCTAsyncStorage.multiGet(keys, function(errors, result) { + var error = (errors && errors.map(function(error) {return convertError(error);})) || null; + callback && callback(error, result); + if (errors) { + reject(error); + } else { + resolve(result); + } + }); + }); + }, + + /** + * multiSet and multiMerge take arrays of key-value array pairs that match + * the output of multiGet, e.g. Returns a `Promise` object. + * + * multiSet([['k1', 'val1'], ['k2', 'val2']], cb); + */ + multiSet: function( + keyValuePairs , + callback + ) { + return new Promise(function(resolve, reject) { + RCTAsyncStorage.multiSet(keyValuePairs, function(errors) { + var error = (errors && errors.map(function(error) {return convertError(error);})) || null; + callback && callback(error); + if (errors) { + reject(error); + } else { + resolve(null); + } + }); + }); + }, + + /** + * Delete all the keys in the `keys` array. Returns a `Promise` object. + */ + multiRemove: function( + keys , + callback + ) { + return new Promise(function(resolve, reject) { + RCTAsyncStorage.multiRemove(keys, function(errors) { + var error = (errors && errors.map(function(error) {return convertError(error);})) || null; + callback && callback(error); + if (errors) { + reject(error); + } else { + resolve(null); + } + }); + }); + }, + + /** + * Merges existing values with input values, assuming they are stringified + * json. Returns a `Promise` object. + * + * Not supported by all native implementations. + */ + multiMerge: function( + keyValuePairs , + callback + ) { + return new Promise(function(resolve, reject) { + RCTAsyncStorage.multiMerge(keyValuePairs, function(errors) { + var error = (errors && errors.map(function(error) {return convertError(error);})) || null; + callback && callback(error); + if (errors) { + reject(error); + } else { + resolve(null); + } + }); + }); + }, +}; + +// Not all native implementations support merge. +if (!RCTAsyncStorage.multiMerge) { + delete AsyncStorage.mergeItem; + delete AsyncStorage.multiMerge; +} + +function convertError(error) { + if (!error) { + return null; + } + var out = new Error(error.message); + out.key = error.key; // flow doesn't like this :( + return out; +} + +module.exports = AsyncStorage; +}); +__d('RCTRenderingPerf',["ReactDefaultPerf","ReactPerf","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 RCTRenderingPerf + * @flow + */ +'use strict'; + +var ReactDefaultPerf = require('ReactDefaultPerf'); +var ReactPerf = require('ReactPerf'); + +var invariant = require('invariant'); + + + + + + +var perfModules = []; +var enabled = false; + +var RCTRenderingPerf = { + // Once perf is enabled, it stays enabled + toggle: function() { + console.log('Render perfomance measurements enabled'); + enabled = true; + }, + + start: function() { + if (!enabled) { + return; + } + + ReactDefaultPerf.start(); + perfModules.forEach(function(module) {return module.start();}); + }, + + stop: function() { + if (!enabled) { + return; + } + + ReactDefaultPerf.stop(); + ReactDefaultPerf.printInclusive(); + ReactDefaultPerf.printWasted(); + + var totalRender = 0; + var totalTime = 0; + var measurements = ReactDefaultPerf.getLastMeasurements(); + for (var ii = 0; ii < measurements.length; ii++) { + var render = measurements[ii].render; + for (var nodeName in render) { + totalRender += render[nodeName]; + } + totalTime += measurements[ii].totalTime; + } + console.log('Total time spent in render(): ' + totalRender + 'ms'); + + perfModules.forEach(function(module) {return module.stop();}); + }, + + register: function(module ) { + invariant( + typeof module.start === 'function', + 'Perf module should have start() function' + ); + invariant( + typeof module.stop === 'function', + 'Perf module should have stop() function' + ); + perfModules.push(module); + } +}; + +module.exports = RCTRenderingPerf; +}); +__d('ReactDefaultPerf',["DOMProperty","ReactDefaultPerfAnalysis","ReactMount","ReactPerf","performanceNow"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactDefaultPerf + * @typechecks static-only + */ + +'use strict'; + +var DOMProperty = require('DOMProperty'); +var ReactDefaultPerfAnalysis = require('ReactDefaultPerfAnalysis'); +var ReactMount = require('ReactMount'); +var ReactPerf = require('ReactPerf'); + +var performanceNow = require('performanceNow'); + +function roundFloat(val) { + return Math.floor(val * 100) / 100; +} + +function addValue(obj, key, val) { + obj[key] = (obj[key] || 0) + val; +} + +var ReactDefaultPerf = { + _allMeasurements: [], // last item in the list is the current one + _mountStack: [0], + _injected: false, + + start: function() { + if (!ReactDefaultPerf._injected) { + ReactPerf.injection.injectMeasure(ReactDefaultPerf.measure); + } + + ReactDefaultPerf._allMeasurements.length = 0; + ReactPerf.enableMeasure = true; + }, + + stop: function() { + ReactPerf.enableMeasure = false; + }, + + getLastMeasurements: function() { + return ReactDefaultPerf._allMeasurements; + }, + + printExclusive: function(measurements) { + measurements = measurements || ReactDefaultPerf._allMeasurements; + var summary = ReactDefaultPerfAnalysis.getExclusiveSummary(measurements); + console.table(summary.map(function(item) { + return { + 'Component class name': item.componentName, + 'Total inclusive time (ms)': roundFloat(item.inclusive), + 'Exclusive mount time (ms)': roundFloat(item.exclusive), + 'Exclusive render time (ms)': roundFloat(item.render), + 'Mount time per instance (ms)': roundFloat(item.exclusive / item.count), + 'Render time per instance (ms)': roundFloat(item.render / item.count), + 'Instances': item.count + }; + })); + // TODO: ReactDefaultPerfAnalysis.getTotalTime() does not return the correct + // number. + }, + + printInclusive: function(measurements) { + measurements = measurements || ReactDefaultPerf._allMeasurements; + var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(measurements); + console.table(summary.map(function(item) { + return { + 'Owner > component': item.componentName, + 'Inclusive time (ms)': roundFloat(item.time), + 'Instances': item.count + }; + })); + console.log( + 'Total time:', + ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' + ); + }, + + getMeasurementsSummaryMap: function(measurements) { + var summary = ReactDefaultPerfAnalysis.getInclusiveSummary( + measurements, + true + ); + return summary.map(function(item) { + return { + 'Owner > component': item.componentName, + 'Wasted time (ms)': item.time, + 'Instances': item.count + }; + }); + }, + + printWasted: function(measurements) { + measurements = measurements || ReactDefaultPerf._allMeasurements; + console.table(ReactDefaultPerf.getMeasurementsSummaryMap(measurements)); + console.log( + 'Total time:', + ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' + ); + }, + + printDOM: function(measurements) { + measurements = measurements || ReactDefaultPerf._allMeasurements; + var summary = ReactDefaultPerfAnalysis.getDOMSummary(measurements); + console.table(summary.map(function(item) { + var result = {}; + result[DOMProperty.ID_ATTRIBUTE_NAME] = item.id; + result['type'] = item.type; + result['args'] = JSON.stringify(item.args); + return result; + })); + console.log( + 'Total time:', + ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' + ); + }, + + _recordWrite: function(id, fnName, totalTime, args) { + // TODO: totalTime isn't that useful since it doesn't count paints/reflows + var writes = + ReactDefaultPerf + ._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1] + .writes; + writes[id] = writes[id] || []; + writes[id].push({ + type: fnName, + time: totalTime, + args: args + }); + }, + + measure: function(moduleName, fnName, func) { + return function() {for (var args=[],$__0=0,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); + var totalTime; + var rv; + var start; + + if (fnName === '_renderNewRootComponent' || + fnName === 'flushBatchedUpdates') { + // A "measurement" is a set of metrics recorded for each flush. We want + // to group the metrics for a given flush together so we can look at the + // components that rendered and the DOM operations that actually + // happened to determine the amount of "wasted work" performed. + ReactDefaultPerf._allMeasurements.push({ + exclusive: {}, + inclusive: {}, + render: {}, + counts: {}, + writes: {}, + displayNames: {}, + totalTime: 0 + }); + start = performanceNow(); + rv = func.apply(this, args); + ReactDefaultPerf._allMeasurements[ + ReactDefaultPerf._allMeasurements.length - 1 + ].totalTime = performanceNow() - start; + return rv; + } else if (fnName === '_mountImageIntoNode' || + moduleName === 'ReactDOMIDOperations') { + start = performanceNow(); + rv = func.apply(this, args); + totalTime = performanceNow() - start; + + if (fnName === '_mountImageIntoNode') { + var mountID = ReactMount.getID(args[1]); + ReactDefaultPerf._recordWrite(mountID, fnName, totalTime, args[0]); + } else if (fnName === 'dangerouslyProcessChildrenUpdates') { + // special format + args[0].forEach(function(update) { + var writeArgs = {}; + if (update.fromIndex !== null) { + writeArgs.fromIndex = update.fromIndex; + } + if (update.toIndex !== null) { + writeArgs.toIndex = update.toIndex; + } + if (update.textContent !== null) { + writeArgs.textContent = update.textContent; + } + if (update.markupIndex !== null) { + writeArgs.markup = args[1][update.markupIndex]; + } + ReactDefaultPerf._recordWrite( + update.parentID, + update.type, + totalTime, + writeArgs + ); + }); + } else { + // basic format + ReactDefaultPerf._recordWrite( + args[0], + fnName, + totalTime, + Array.prototype.slice.call(args, 1) + ); + } + return rv; + } else if (moduleName === 'ReactCompositeComponent' && ( + fnName === 'mountComponent' || + fnName === 'updateComponent' || // TODO: receiveComponent()? + fnName === '_renderValidatedComponent')) { + + if (typeof this._currentElement.type === 'string') { + return func.apply(this, args); + } + + var rootNodeID = fnName === 'mountComponent' ? + args[0] : + this._rootNodeID; + var isRender = fnName === '_renderValidatedComponent'; + var isMount = fnName === 'mountComponent'; + + var mountStack = ReactDefaultPerf._mountStack; + var entry = ReactDefaultPerf._allMeasurements[ + ReactDefaultPerf._allMeasurements.length - 1 + ]; + + if (isRender) { + addValue(entry.counts, rootNodeID, 1); + } else if (isMount) { + mountStack.push(0); + } + + start = performanceNow(); + rv = func.apply(this, args); + totalTime = performanceNow() - start; + + if (isRender) { + addValue(entry.render, rootNodeID, totalTime); + } else if (isMount) { + var subMountTime = mountStack.pop(); + mountStack[mountStack.length - 1] += totalTime; + addValue(entry.exclusive, rootNodeID, totalTime - subMountTime); + addValue(entry.inclusive, rootNodeID, totalTime); + } else { + addValue(entry.inclusive, rootNodeID, totalTime); + } + + entry.displayNames[rootNodeID] = { + current: this.getName(), + owner: this._currentElement._owner ? + this._currentElement._owner.getName() : + '' + }; + + return rv; + } else { + return func.apply(this, args); + } + }; + } +}; + +module.exports = ReactDefaultPerf; +}); +__d('DOMProperty',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 DOMProperty + * @typechecks static-only + */ + +/*jslint bitwise: true */ + +'use strict'; + +var invariant = require('invariant'); + +function checkMask(value, bitmask) { + return (value & bitmask) === bitmask; +} + +var DOMPropertyInjection = { + /** + * Mapping from normalized, camelcased property names to a configuration that + * specifies how the associated DOM property should be accessed or rendered. + */ + MUST_USE_ATTRIBUTE: 0x1, + MUST_USE_PROPERTY: 0x2, + HAS_SIDE_EFFECTS: 0x4, + HAS_BOOLEAN_VALUE: 0x8, + HAS_NUMERIC_VALUE: 0x10, + HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10, + HAS_OVERLOADED_BOOLEAN_VALUE: 0x40, + + /** + * Inject some specialized knowledge about the DOM. This takes a config object + * with the following properties: + * + * isCustomAttribute: function that given an attribute name will return true + * if it can be inserted into the DOM verbatim. Useful for data-* or aria-* + * attributes where it's impossible to enumerate all of the possible + * attribute names, + * + * Properties: object mapping DOM property name to one of the + * DOMPropertyInjection constants or null. If your attribute isn't in here, + * it won't get written to the DOM. + * + * DOMAttributeNames: object mapping React attribute name to the DOM + * attribute name. Attribute names not specified use the **lowercase** + * normalized name. + * + * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. + * Property names not specified use the normalized name. + * + * DOMMutationMethods: Properties that require special mutation methods. If + * `value` is undefined, the mutation method should unset the property. + * + * @param {object} domPropertyConfig the config as described above. + */ + injectDOMPropertyConfig: function(domPropertyConfig) { + var Properties = domPropertyConfig.Properties || {}; + var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; + var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; + var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; + + if (domPropertyConfig.isCustomAttribute) { + DOMProperty._isCustomAttributeFunctions.push( + domPropertyConfig.isCustomAttribute + ); + } + + for (var propName in Properties) { + invariant( + !DOMProperty.isStandardName.hasOwnProperty(propName), + 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + + '\'%s\' which has already been injected. You may be accidentally ' + + 'injecting the same DOM property config twice, or you may be ' + + 'injecting two configs that have conflicting property names.', + propName + ); + + DOMProperty.isStandardName[propName] = true; + + var lowerCased = propName.toLowerCase(); + DOMProperty.getPossibleStandardName[lowerCased] = propName; + + if (DOMAttributeNames.hasOwnProperty(propName)) { + var attributeName = DOMAttributeNames[propName]; + DOMProperty.getPossibleStandardName[attributeName] = propName; + DOMProperty.getAttributeName[propName] = attributeName; + } else { + DOMProperty.getAttributeName[propName] = lowerCased; + } + + DOMProperty.getPropertyName[propName] = + DOMPropertyNames.hasOwnProperty(propName) ? + DOMPropertyNames[propName] : + propName; + + if (DOMMutationMethods.hasOwnProperty(propName)) { + DOMProperty.getMutationMethod[propName] = DOMMutationMethods[propName]; + } else { + DOMProperty.getMutationMethod[propName] = null; + } + + var propConfig = Properties[propName]; + DOMProperty.mustUseAttribute[propName] = + checkMask(propConfig, DOMPropertyInjection.MUST_USE_ATTRIBUTE); + DOMProperty.mustUseProperty[propName] = + checkMask(propConfig, DOMPropertyInjection.MUST_USE_PROPERTY); + DOMProperty.hasSideEffects[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_SIDE_EFFECTS); + DOMProperty.hasBooleanValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_BOOLEAN_VALUE); + DOMProperty.hasNumericValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_NUMERIC_VALUE); + DOMProperty.hasPositiveNumericValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE); + DOMProperty.hasOverloadedBooleanValue[propName] = + checkMask(propConfig, DOMPropertyInjection.HAS_OVERLOADED_BOOLEAN_VALUE); + + invariant( + !DOMProperty.mustUseAttribute[propName] || + !DOMProperty.mustUseProperty[propName], + 'DOMProperty: Cannot require using both attribute and property: %s', + propName + ); + invariant( + DOMProperty.mustUseProperty[propName] || + !DOMProperty.hasSideEffects[propName], + 'DOMProperty: Properties that have side effects must use property: %s', + propName + ); + invariant( + !!DOMProperty.hasBooleanValue[propName] + + !!DOMProperty.hasNumericValue[propName] + + !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1, + 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + + 'numeric value, but not a combination: %s', + propName + ); + } + } +}; +var defaultValueCache = {}; + +/** + * DOMProperty exports lookup objects that can be used like functions: + * + * > DOMProperty.isValid['id'] + * true + * > DOMProperty.isValid['foobar'] + * undefined + * + * Although this may be confusing, it performs better in general. + * + * @see http://jsperf.com/key-exists + * @see http://jsperf.com/key-missing + */ +var DOMProperty = { + + ID_ATTRIBUTE_NAME: 'data-reactid', + + /** + * Checks whether a property name is a standard property. + * @type {Object} + */ + isStandardName: {}, + + /** + * Mapping from lowercase property names to the properly cased version, used + * to warn in the case of missing properties. + * @type {Object} + */ + getPossibleStandardName: {}, + + /** + * Mapping from normalized names to attribute names that differ. Attribute + * names are used when rendering markup or with `*Attribute()`. + * @type {Object} + */ + getAttributeName: {}, + + /** + * Mapping from normalized names to properties on DOM node instances. + * (This includes properties that mutate due to external factors.) + * @type {Object} + */ + getPropertyName: {}, + + /** + * Mapping from normalized names to mutation methods. This will only exist if + * mutation cannot be set simply by the property or `setAttribute()`. + * @type {Object} + */ + getMutationMethod: {}, + + /** + * Whether the property must be accessed and mutated as an object property. + * @type {Object} + */ + mustUseAttribute: {}, + + /** + * Whether the property must be accessed and mutated using `*Attribute()`. + * (This includes anything that fails ` in `.) + * @type {Object} + */ + mustUseProperty: {}, + + /** + * Whether or not setting a value causes side effects such as triggering + * resources to be loaded or text selection changes. We must ensure that + * the value is only set if it has changed. + * @type {Object} + */ + hasSideEffects: {}, + + /** + * Whether the property should be removed when set to a falsey value. + * @type {Object} + */ + hasBooleanValue: {}, + + /** + * Whether the property must be numeric or parse as a + * numeric and should be removed when set to a falsey value. + * @type {Object} + */ + hasNumericValue: {}, + + /** + * Whether the property must be positive numeric or parse as a positive + * numeric and should be removed when set to a falsey value. + * @type {Object} + */ + hasPositiveNumericValue: {}, + + /** + * Whether the property can be used as a flag as well as with a value. Removed + * when strictly equal to false; present without a value when strictly equal + * to true; present with a value otherwise. + * @type {Object} + */ + hasOverloadedBooleanValue: {}, + + /** + * All of the isCustomAttribute() functions that have been injected. + */ + _isCustomAttributeFunctions: [], + + /** + * Checks whether a property name is a custom attribute. + * @method + */ + isCustomAttribute: function(attributeName) { + for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { + var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; + if (isCustomAttributeFn(attributeName)) { + return true; + } + } + return false; + }, + + /** + * Returns the default property value for a DOM property (i.e., not an + * attribute). Most default values are '' or false, but not all. Worse yet, + * some (in particular, `type`) vary depending on the type of element. + * + * TODO: Is it better to grab all the possible properties when creating an + * element to avoid having to create the same element twice? + */ + getDefaultValueForProperty: function(nodeName, prop) { + var nodeDefaults = defaultValueCache[nodeName]; + var testElement; + if (!nodeDefaults) { + defaultValueCache[nodeName] = nodeDefaults = {}; + } + if (!(prop in nodeDefaults)) { + testElement = document.createElement(nodeName); + nodeDefaults[prop] = testElement[prop]; + } + return nodeDefaults[prop]; + }, + + injection: DOMPropertyInjection +}; + +module.exports = DOMProperty; +}); +__d('ReactDefaultPerfAnalysis',["Object.assign"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactDefaultPerfAnalysis + */ + +var assign = require('Object.assign'); + +// Don't try to save users less than 1.2ms (a number I made up) +var DONT_CARE_THRESHOLD = 1.2; +var DOM_OPERATION_TYPES = { + '_mountImageIntoNode': 'set innerHTML', + INSERT_MARKUP: 'set innerHTML', + MOVE_EXISTING: 'move', + REMOVE_NODE: 'remove', + TEXT_CONTENT: 'set textContent', + 'updatePropertyByID': 'update attribute', + 'deletePropertyByID': 'delete attribute', + 'updateStylesByID': 'update styles', + 'updateInnerHTMLByID': 'set innerHTML', + 'dangerouslyReplaceNodeWithMarkupByID': 'replace' +}; + +function getTotalTime(measurements) { + // TODO: return number of DOM ops? could be misleading. + // TODO: measure dropped frames after reconcile? + // TODO: log total time of each reconcile and the top-level component + // class that triggered it. + var totalTime = 0; + for (var i = 0; i < measurements.length; i++) { + var measurement = measurements[i]; + totalTime += measurement.totalTime; + } + return totalTime; +} + +function getDOMSummary(measurements) { + var items = []; + for (var i = 0; i < measurements.length; i++) { + var measurement = measurements[i]; + var id; + + for (id in measurement.writes) { + measurement.writes[id].forEach(function(write) { + items.push({ + id: id, + type: DOM_OPERATION_TYPES[write.type] || write.type, + args: write.args + }); + }); + } + } + return items; +} + +function getExclusiveSummary(measurements) { + var candidates = {}; + var displayName; + + for (var i = 0; i < measurements.length; i++) { + var measurement = measurements[i]; + var allIDs = assign( + {}, + measurement.exclusive, + measurement.inclusive + ); + + for (var id in allIDs) { + displayName = measurement.displayNames[id].current; + + candidates[displayName] = candidates[displayName] || { + componentName: displayName, + inclusive: 0, + exclusive: 0, + render: 0, + count: 0 + }; + if (measurement.render[id]) { + candidates[displayName].render += measurement.render[id]; + } + if (measurement.exclusive[id]) { + candidates[displayName].exclusive += measurement.exclusive[id]; + } + if (measurement.inclusive[id]) { + candidates[displayName].inclusive += measurement.inclusive[id]; + } + if (measurement.counts[id]) { + candidates[displayName].count += measurement.counts[id]; + } + } + } + + // Now make a sorted array with the results. + var arr = []; + for (displayName in candidates) { + if (candidates[displayName].exclusive >= DONT_CARE_THRESHOLD) { + arr.push(candidates[displayName]); + } + } + + arr.sort(function(a, b) { + return b.exclusive - a.exclusive; + }); + + return arr; +} + +function getInclusiveSummary(measurements, onlyClean) { + var candidates = {}; + var inclusiveKey; + + for (var i = 0; i < measurements.length; i++) { + var measurement = measurements[i]; + var allIDs = assign( + {}, + measurement.exclusive, + measurement.inclusive + ); + var cleanComponents; + + if (onlyClean) { + cleanComponents = getUnchangedComponents(measurement); + } + + for (var id in allIDs) { + if (onlyClean && !cleanComponents[id]) { + continue; + } + + var displayName = measurement.displayNames[id]; + + // Inclusive time is not useful for many components without knowing where + // they are instantiated. So we aggregate inclusive time with both the + // owner and current displayName as the key. + inclusiveKey = displayName.owner + ' > ' + displayName.current; + + candidates[inclusiveKey] = candidates[inclusiveKey] || { + componentName: inclusiveKey, + time: 0, + count: 0 + }; + + if (measurement.inclusive[id]) { + candidates[inclusiveKey].time += measurement.inclusive[id]; + } + if (measurement.counts[id]) { + candidates[inclusiveKey].count += measurement.counts[id]; + } + } + } + + // Now make a sorted array with the results. + var arr = []; + for (inclusiveKey in candidates) { + if (candidates[inclusiveKey].time >= DONT_CARE_THRESHOLD) { + arr.push(candidates[inclusiveKey]); + } + } + + arr.sort(function(a, b) { + return b.time - a.time; + }); + + return arr; +} + +function getUnchangedComponents(measurement) { + // For a given reconcile, look at which components did not actually + // render anything to the DOM and return a mapping of their ID to + // the amount of time it took to render the entire subtree. + var cleanComponents = {}; + var dirtyLeafIDs = Object.keys(measurement.writes); + var allIDs = assign({}, measurement.exclusive, measurement.inclusive); + + for (var id in allIDs) { + var isDirty = false; + // For each component that rendered, see if a component that triggered + // a DOM op is in its subtree. + for (var i = 0; i < dirtyLeafIDs.length; i++) { + if (dirtyLeafIDs[i].indexOf(id) === 0) { + isDirty = true; + break; + } + } + if (!isDirty && measurement.counts[id] > 0) { + cleanComponents[id] = true; + } + } + return cleanComponents; +} + +var ReactDefaultPerfAnalysis = { + getExclusiveSummary: getExclusiveSummary, + getInclusiveSummary: getInclusiveSummary, + getDOMSummary: getDOMSummary, + getTotalTime: getTotalTime +}; + +module.exports = ReactDefaultPerfAnalysis; +}); +__d('ReactMount',["DOMProperty","ReactBrowserEventEmitter","ReactCurrentOwner","ReactElement","ReactElementValidator","ReactEmptyComponent","ReactInstanceHandles","ReactInstanceMap","ReactMarkupChecksum","ReactPerf","ReactReconciler","ReactUpdateQueue","ReactUpdates","emptyObject","containsNode","getReactRootElementInContainer","instantiateReactComponent","invariant","setInnerHTML","shouldUpdateReactComponent","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactMount + */ + +'use strict'; + +var DOMProperty = require('DOMProperty'); +var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter'); +var ReactCurrentOwner = require('ReactCurrentOwner'); +var ReactElement = require('ReactElement'); +var ReactElementValidator = require('ReactElementValidator'); +var ReactEmptyComponent = require('ReactEmptyComponent'); +var ReactInstanceHandles = require('ReactInstanceHandles'); +var ReactInstanceMap = require('ReactInstanceMap'); +var ReactMarkupChecksum = require('ReactMarkupChecksum'); +var ReactPerf = require('ReactPerf'); +var ReactReconciler = require('ReactReconciler'); +var ReactUpdateQueue = require('ReactUpdateQueue'); +var ReactUpdates = require('ReactUpdates'); + +var emptyObject = require('emptyObject'); +var containsNode = require('containsNode'); +var getReactRootElementInContainer = require('getReactRootElementInContainer'); +var instantiateReactComponent = require('instantiateReactComponent'); +var invariant = require('invariant'); +var setInnerHTML = require('setInnerHTML'); +var shouldUpdateReactComponent = require('shouldUpdateReactComponent'); +var warning = require('warning'); + +var SEPARATOR = ReactInstanceHandles.SEPARATOR; + +var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; +var nodeCache = {}; + +var ELEMENT_NODE_TYPE = 1; +var DOC_NODE_TYPE = 9; + +/** Mapping from reactRootID to React component instance. */ +var instancesByReactRootID = {}; + +/** Mapping from reactRootID to `container` nodes. */ +var containersByReactRootID = {}; + +if (__DEV__) { + /** __DEV__-only mapping from reactRootID to root elements. */ + var rootElementsByReactRootID = {}; +} + +// Used to store breadth-first search state in findComponentRoot. +var findComponentRootReusableArray = []; + +/** + * Finds the index of the first character + * that's not common between the two given strings. + * + * @return {number} the index of the character where the strings diverge + */ +function firstDifferenceIndex(string1, string2) { + var minLen = Math.min(string1.length, string2.length); + for (var i = 0; i < minLen; i++) { + if (string1.charAt(i) !== string2.charAt(i)) { + return i; + } + } + return string1.length === string2.length ? -1 : minLen; +} + +/** + * @param {DOMElement} container DOM element that may contain a React component. + * @return {?string} A "reactRoot" ID, if a React component is rendered. + */ +function getReactRootID(container) { + var rootElement = getReactRootElementInContainer(container); + return rootElement && ReactMount.getID(rootElement); +} + +/** + * Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form + * element can return its control whose name or ID equals ATTR_NAME. All + * DOM nodes support `getAttributeNode` but this can also get called on + * other objects so just return '' if we're given something other than a + * DOM node (such as window). + * + * @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node. + * @return {string} ID of the supplied `domNode`. + */ +function getID(node) { + var id = internalGetID(node); + if (id) { + if (nodeCache.hasOwnProperty(id)) { + var cached = nodeCache[id]; + if (cached !== node) { + invariant( + !isValid(cached, id), + 'ReactMount: Two valid but unequal nodes with the same `%s`: %s', + ATTR_NAME, id + ); + + nodeCache[id] = node; + } + } else { + nodeCache[id] = node; + } + } + + return id; +} + +function internalGetID(node) { + // If node is something like a window, document, or text node, none of + // which support attributes or a .getAttribute method, gracefully return + // the empty string, as if the attribute were missing. + return node && node.getAttribute && node.getAttribute(ATTR_NAME) || ''; +} + +/** + * Sets the React-specific ID of the given node. + * + * @param {DOMElement} node The DOM node whose ID will be set. + * @param {string} id The value of the ID attribute. + */ +function setID(node, id) { + var oldID = internalGetID(node); + if (oldID !== id) { + delete nodeCache[oldID]; + } + node.setAttribute(ATTR_NAME, id); + nodeCache[id] = node; +} + +/** + * Finds the node with the supplied React-generated DOM ID. + * + * @param {string} id A React-generated DOM ID. + * @return {DOMElement} DOM node with the suppled `id`. + * @internal + */ +function getNode(id) { + if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) { + nodeCache[id] = ReactMount.findReactNodeByID(id); + } + return nodeCache[id]; +} + +/** + * Finds the node with the supplied public React instance. + * + * @param {*} instance A public React instance. + * @return {?DOMElement} DOM node with the suppled `id`. + * @internal + */ +function getNodeFromInstance(instance) { + var id = ReactInstanceMap.get(instance)._rootNodeID; + if (ReactEmptyComponent.isNullComponentID(id)) { + return null; + } + if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) { + nodeCache[id] = ReactMount.findReactNodeByID(id); + } + return nodeCache[id]; +} + +/** + * A node is "valid" if it is contained by a currently mounted container. + * + * This means that the node does not have to be contained by a document in + * order to be considered valid. + * + * @param {?DOMElement} node The candidate DOM node. + * @param {string} id The expected ID of the node. + * @return {boolean} Whether the node is contained by a mounted container. + */ +function isValid(node, id) { + if (node) { + invariant( + internalGetID(node) === id, + 'ReactMount: Unexpected modification of `%s`', + ATTR_NAME + ); + + var container = ReactMount.findReactContainerForID(id); + if (container && containsNode(container, node)) { + return true; + } + } + + return false; +} + +/** + * Causes the cache to forget about one React-specific ID. + * + * @param {string} id The ID to forget. + */ +function purgeID(id) { + delete nodeCache[id]; +} + +var deepestNodeSoFar = null; +function findDeepestCachedAncestorImpl(ancestorID) { + var ancestor = nodeCache[ancestorID]; + if (ancestor && isValid(ancestor, ancestorID)) { + deepestNodeSoFar = ancestor; + } else { + // This node isn't populated in the cache, so presumably none of its + // descendants are. Break out of the loop. + return false; + } +} + +/** + * Return the deepest cached node whose ID is a prefix of `targetID`. + */ +function findDeepestCachedAncestor(targetID) { + deepestNodeSoFar = null; + ReactInstanceHandles.traverseAncestors( + targetID, + findDeepestCachedAncestorImpl + ); + + var foundNode = deepestNodeSoFar; + deepestNodeSoFar = null; + return foundNode; +} + +/** + * Mounts this component and inserts it into the DOM. + * + * @param {ReactComponent} componentInstance The instance to mount. + * @param {string} rootID DOM ID of the root node. + * @param {DOMElement} container DOM element to mount into. + * @param {ReactReconcileTransaction} transaction + * @param {boolean} shouldReuseMarkup If true, do not insert markup + */ +function mountComponentIntoNode( + componentInstance, + rootID, + container, + transaction, + shouldReuseMarkup) { + var markup = ReactReconciler.mountComponent( + componentInstance, rootID, transaction, emptyObject + ); + componentInstance._isTopLevel = true; + ReactMount._mountImageIntoNode(markup, container, shouldReuseMarkup); +} + +/** + * Batched mount. + * + * @param {ReactComponent} componentInstance The instance to mount. + * @param {string} rootID DOM ID of the root node. + * @param {DOMElement} container DOM element to mount into. + * @param {boolean} shouldReuseMarkup If true, do not insert markup + */ +function batchedMountComponentIntoNode( + componentInstance, + rootID, + container, + shouldReuseMarkup) { + var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(); + transaction.perform( + mountComponentIntoNode, + null, + componentInstance, + rootID, + container, + transaction, + shouldReuseMarkup + ); + ReactUpdates.ReactReconcileTransaction.release(transaction); +} + +/** + * Mounting is the process of initializing a React component by creating its + * representative DOM elements and inserting them into a supplied `container`. + * Any prior content inside `container` is destroyed in the process. + * + * ReactMount.render( + * component, + * document.getElementById('container') + * ); + * + *
<-- Supplied `container`. + *
<-- Rendered reactRoot of React + * // ... component. + *
+ *
+ * + * Inside of `container`, the first element rendered is the "reactRoot". + */ +var ReactMount = { + /** Exposed for debugging purposes **/ + _instancesByReactRootID: instancesByReactRootID, + + /** + * This is a hook provided to support rendering React components while + * ensuring that the apparent scroll position of its `container` does not + * change. + * + * @param {DOMElement} container The `container` being rendered into. + * @param {function} renderCallback This must be called once to do the render. + */ + scrollMonitor: function(container, renderCallback) { + renderCallback(); + }, + + /** + * Take a component that's already mounted into the DOM and replace its props + * @param {ReactComponent} prevComponent component instance already in the DOM + * @param {ReactElement} nextElement component instance to render + * @param {DOMElement} container container to render into + * @param {?function} callback function triggered on completion + */ + _updateRootComponent: function( + prevComponent, + nextElement, + container, + callback) { + if (__DEV__) { + ReactElementValidator.checkAndWarnForMutatedProps(nextElement); + } + + ReactMount.scrollMonitor(container, function() { + ReactUpdateQueue.enqueueElementInternal(prevComponent, nextElement); + if (callback) { + ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback); + } + }); + + if (__DEV__) { + // Record the root element in case it later gets transplanted. + rootElementsByReactRootID[getReactRootID(container)] = + getReactRootElementInContainer(container); + } + + return prevComponent; + }, + + /** + * Register a component into the instance map and starts scroll value + * monitoring + * @param {ReactComponent} nextComponent component instance to render + * @param {DOMElement} container container to render into + * @return {string} reactRoot ID prefix + */ + _registerComponent: function(nextComponent, container) { + invariant( + container && ( + container.nodeType === ELEMENT_NODE_TYPE || + container.nodeType === DOC_NODE_TYPE + ), + '_registerComponent(...): Target container is not a DOM element.' + ); + + ReactBrowserEventEmitter.ensureScrollValueMonitoring(); + + var reactRootID = ReactMount.registerContainer(container); + instancesByReactRootID[reactRootID] = nextComponent; + return reactRootID; + }, + + /** + * Render a new component into the DOM. + * @param {ReactElement} nextElement element to render + * @param {DOMElement} container container to render into + * @param {boolean} shouldReuseMarkup if we should skip the markup insertion + * @return {ReactComponent} nextComponent + */ + _renderNewRootComponent: function( + nextElement, + container, + shouldReuseMarkup + ) { + // Various parts of our code (such as ReactCompositeComponent's + // _renderValidatedComponent) assume that calls to render aren't nested; + // verify that that's the case. + warning( + ReactCurrentOwner.current == null, + '_renderNewRootComponent(): Render methods should be a pure function ' + + 'of props and state; triggering nested component updates from ' + + 'render is not allowed. If necessary, trigger nested updates in ' + + 'componentDidUpdate.' + ); + + var componentInstance = instantiateReactComponent(nextElement, null); + var reactRootID = ReactMount._registerComponent( + componentInstance, + container + ); + + // The initial render is synchronous but any updates that happen during + // rendering, in componentWillMount or componentDidMount, will be batched + // according to the current batching strategy. + + ReactUpdates.batchedUpdates( + batchedMountComponentIntoNode, + componentInstance, + reactRootID, + container, + shouldReuseMarkup + ); + + if (__DEV__) { + // Record the root element in case it later gets transplanted. + rootElementsByReactRootID[reactRootID] = + getReactRootElementInContainer(container); + } + + return componentInstance; + }, + + /** + * Renders a React component into the DOM in the supplied `container`. + * + * If the React component was previously rendered into `container`, this will + * perform an update on it and only mutate the DOM as necessary to reflect the + * latest React component. + * + * @param {ReactElement} nextElement Component element to render. + * @param {DOMElement} container DOM element to render into. + * @param {?function} callback function triggered on completion + * @return {ReactComponent} Component instance rendered in `container`. + */ + render: function(nextElement, container, callback) { + invariant( + ReactElement.isValidElement(nextElement), + 'React.render(): Invalid component element.%s', + ( + typeof nextElement === 'string' ? + ' Instead of passing an element string, make sure to instantiate ' + + 'it by passing it to React.createElement.' : + typeof nextElement === 'function' ? + ' Instead of passing a component class, make sure to instantiate ' + + 'it by passing it to React.createElement.' : + // Check if it quacks like an element + nextElement != null && nextElement.props !== undefined ? + ' This may be caused by unintentionally loading two independent ' + + 'copies of React.' : + '' + ) + ); + + var prevComponent = instancesByReactRootID[getReactRootID(container)]; + + if (prevComponent) { + var prevElement = prevComponent._currentElement; + if (shouldUpdateReactComponent(prevElement, nextElement)) { + return ReactMount._updateRootComponent( + prevComponent, + nextElement, + container, + callback + ).getPublicInstance(); + } else { + ReactMount.unmountComponentAtNode(container); + } + } + + var reactRootElement = getReactRootElementInContainer(container); + var containerHasReactMarkup = + reactRootElement && ReactMount.isRenderedByReact(reactRootElement); + + if (__DEV__) { + if (!containerHasReactMarkup || reactRootElement.nextSibling) { + var rootElementSibling = reactRootElement; + while (rootElementSibling) { + if (ReactMount.isRenderedByReact(rootElementSibling)) { + warning( + false, + 'render(): Target node has markup rendered by React, but there ' + + 'are unrelated nodes as well. This is most commonly caused by ' + + 'white-space inserted around server-rendered markup.' + ); + break; + } + + rootElementSibling = rootElementSibling.nextSibling; + } + } + } + + var shouldReuseMarkup = containerHasReactMarkup && !prevComponent; + + var component = ReactMount._renderNewRootComponent( + nextElement, + container, + shouldReuseMarkup + ).getPublicInstance(); + if (callback) { + callback.call(component); + } + return component; + }, + + /** + * Constructs a component instance of `constructor` with `initialProps` and + * renders it into the supplied `container`. + * + * @param {function} constructor React component constructor. + * @param {?object} props Initial props of the component instance. + * @param {DOMElement} container DOM element to render into. + * @return {ReactComponent} Component instance rendered in `container`. + */ + constructAndRenderComponent: function(constructor, props, container) { + var element = ReactElement.createElement(constructor, props); + return ReactMount.render(element, container); + }, + + /** + * Constructs a component instance of `constructor` with `initialProps` and + * renders it into a container node identified by supplied `id`. + * + * @param {function} componentConstructor React component constructor + * @param {?object} props Initial props of the component instance. + * @param {string} id ID of the DOM element to render into. + * @return {ReactComponent} Component instance rendered in the container node. + */ + constructAndRenderComponentByID: function(constructor, props, id) { + var domNode = document.getElementById(id); + invariant( + domNode, + 'Tried to get element with id of "%s" but it is not present on the page.', + id + ); + return ReactMount.constructAndRenderComponent(constructor, props, domNode); + }, + + /** + * Registers a container node into which React components will be rendered. + * This also creates the "reactRoot" ID that will be assigned to the element + * rendered within. + * + * @param {DOMElement} container DOM element to register as a container. + * @return {string} The "reactRoot" ID of elements rendered within. + */ + registerContainer: function(container) { + var reactRootID = getReactRootID(container); + if (reactRootID) { + // If one exists, make sure it is a valid "reactRoot" ID. + reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID); + } + if (!reactRootID) { + // No valid "reactRoot" ID found, create one. + reactRootID = ReactInstanceHandles.createReactRootID(); + } + containersByReactRootID[reactRootID] = container; + return reactRootID; + }, + + /** + * Unmounts and destroys the React component rendered in the `container`. + * + * @param {DOMElement} container DOM element containing a React component. + * @return {boolean} True if a component was found in and unmounted from + * `container` + */ + unmountComponentAtNode: function(container) { + // Various parts of our code (such as ReactCompositeComponent's + // _renderValidatedComponent) assume that calls to render aren't nested; + // verify that that's the case. (Strictly speaking, unmounting won't cause a + // render but we still don't expect to be in a render call here.) + warning( + ReactCurrentOwner.current == null, + 'unmountComponentAtNode(): Render methods should be a pure function of ' + + 'props and state; triggering nested component updates from render is ' + + 'not allowed. If necessary, trigger nested updates in ' + + 'componentDidUpdate.' + ); + + invariant( + container && ( + container.nodeType === ELEMENT_NODE_TYPE || + container.nodeType === DOC_NODE_TYPE + ), + 'unmountComponentAtNode(...): Target container is not a DOM element.' + ); + + var reactRootID = getReactRootID(container); + var component = instancesByReactRootID[reactRootID]; + if (!component) { + return false; + } + ReactMount.unmountComponentFromNode(component, container); + delete instancesByReactRootID[reactRootID]; + delete containersByReactRootID[reactRootID]; + if (__DEV__) { + delete rootElementsByReactRootID[reactRootID]; + } + return true; + }, + + /** + * Unmounts a component and removes it from the DOM. + * + * @param {ReactComponent} instance React component instance. + * @param {DOMElement} container DOM element to unmount from. + * @final + * @internal + * @see {ReactMount.unmountComponentAtNode} + */ + unmountComponentFromNode: function(instance, container) { + ReactReconciler.unmountComponent(instance); + + if (container.nodeType === DOC_NODE_TYPE) { + container = container.documentElement; + } + + // http://jsperf.com/emptying-a-node + while (container.lastChild) { + container.removeChild(container.lastChild); + } + }, + + /** + * Finds the container DOM element that contains React component to which the + * supplied DOM `id` belongs. + * + * @param {string} id The ID of an element rendered by a React component. + * @return {?DOMElement} DOM element that contains the `id`. + */ + findReactContainerForID: function(id) { + var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id); + var container = containersByReactRootID[reactRootID]; + + if (__DEV__) { + var rootElement = rootElementsByReactRootID[reactRootID]; + if (rootElement && rootElement.parentNode !== container) { + invariant( + // Call internalGetID here because getID calls isValid which calls + // findReactContainerForID (this function). + internalGetID(rootElement) === reactRootID, + 'ReactMount: Root element ID differed from reactRootID.' + ); + + var containerChild = container.firstChild; + if (containerChild && + reactRootID === internalGetID(containerChild)) { + // If the container has a new child with the same ID as the old + // root element, then rootElementsByReactRootID[reactRootID] is + // just stale and needs to be updated. The case that deserves a + // warning is when the container is empty. + rootElementsByReactRootID[reactRootID] = containerChild; + } else { + warning( + false, + 'ReactMount: Root element has been removed from its original ' + + 'container. New container:', rootElement.parentNode + ); + } + } + } + + return container; + }, + + /** + * Finds an element rendered by React with the supplied ID. + * + * @param {string} id ID of a DOM node in the React component. + * @return {DOMElement} Root DOM node of the React component. + */ + findReactNodeByID: function(id) { + var reactRoot = ReactMount.findReactContainerForID(id); + return ReactMount.findComponentRoot(reactRoot, id); + }, + + /** + * True if the supplied `node` is rendered by React. + * + * @param {*} node DOM Element to check. + * @return {boolean} True if the DOM Element appears to be rendered by React. + * @internal + */ + isRenderedByReact: function(node) { + if (node.nodeType !== 1) { + // Not a DOMElement, therefore not a React component + return false; + } + var id = ReactMount.getID(node); + return id ? id.charAt(0) === SEPARATOR : false; + }, + + /** + * Traverses up the ancestors of the supplied node to find a node that is a + * DOM representation of a React component. + * + * @param {*} node + * @return {?DOMEventTarget} + * @internal + */ + getFirstReactDOM: function(node) { + var current = node; + while (current && current.parentNode !== current) { + if (ReactMount.isRenderedByReact(current)) { + return current; + } + current = current.parentNode; + } + return null; + }, + + /** + * Finds a node with the supplied `targetID` inside of the supplied + * `ancestorNode`. Exploits the ID naming scheme to perform the search + * quickly. + * + * @param {DOMEventTarget} ancestorNode Search from this root. + * @pararm {string} targetID ID of the DOM representation of the component. + * @return {DOMEventTarget} DOM node with the supplied `targetID`. + * @internal + */ + findComponentRoot: function(ancestorNode, targetID) { + var firstChildren = findComponentRootReusableArray; + var childIndex = 0; + + var deepestAncestor = findDeepestCachedAncestor(targetID) || ancestorNode; + + firstChildren[0] = deepestAncestor.firstChild; + firstChildren.length = 1; + + while (childIndex < firstChildren.length) { + var child = firstChildren[childIndex++]; + var targetChild; + + while (child) { + var childID = ReactMount.getID(child); + if (childID) { + // Even if we find the node we're looking for, we finish looping + // through its siblings to ensure they're cached so that we don't have + // to revisit this node again. Otherwise, we make n^2 calls to getID + // when visiting the many children of a single node in order. + + if (targetID === childID) { + targetChild = child; + } else if (ReactInstanceHandles.isAncestorIDOf(childID, targetID)) { + // If we find a child whose ID is an ancestor of the given ID, + // then we can be sure that we only want to search the subtree + // rooted at this child, so we can throw out the rest of the + // search state. + firstChildren.length = childIndex = 0; + firstChildren.push(child.firstChild); + } + + } else { + // If this child had no ID, then there's a chance that it was + // injected automatically by the browser, as when a `` + // element sprouts an extra `` child as a side effect of + // `.innerHTML` parsing. Optimistically continue down this + // branch, but not before examining the other siblings. + firstChildren.push(child.firstChild); + } + + child = child.nextSibling; + } + + if (targetChild) { + // Emptying firstChildren/findComponentRootReusableArray is + // not necessary for correctness, but it helps the GC reclaim + // any nodes that were left at the end of the search. + firstChildren.length = 0; + + return targetChild; + } + } + + firstChildren.length = 0; + + invariant( + false, + 'findComponentRoot(..., %s): Unable to find element. This probably ' + + 'means the DOM was unexpectedly mutated (e.g., by the browser), ' + + 'usually due to forgetting a when using tables, nesting tags ' + + 'like ,

, or , or using non-SVG elements in an ' + + 'parent. ' + + 'Try inspecting the child nodes of the element with React ID `%s`.', + targetID, + ReactMount.getID(ancestorNode) + ); + }, + + _mountImageIntoNode: function(markup, container, shouldReuseMarkup) { + invariant( + container && ( + container.nodeType === ELEMENT_NODE_TYPE || + container.nodeType === DOC_NODE_TYPE + ), + 'mountComponentIntoNode(...): Target container is not valid.' + ); + + if (shouldReuseMarkup) { + var rootElement = getReactRootElementInContainer(container); + if (ReactMarkupChecksum.canReuseMarkup(markup, rootElement)) { + return; + } else { + var checksum = rootElement.getAttribute( + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + ); + rootElement.removeAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME); + + var rootMarkup = rootElement.outerHTML; + rootElement.setAttribute( + ReactMarkupChecksum.CHECKSUM_ATTR_NAME, + checksum + ); + + var diffIndex = firstDifferenceIndex(markup, rootMarkup); + var difference = ' (client) ' + + markup.substring(diffIndex - 20, diffIndex + 20) + + '\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20); + + invariant( + container.nodeType !== DOC_NODE_TYPE, + 'You\'re trying to render a component to the document using ' + + 'server rendering but the checksum was invalid. This usually ' + + 'means you rendered a different component type or props on ' + + 'the client from the one on the server, or your render() ' + + 'methods are impure. React cannot handle this case due to ' + + 'cross-browser quirks by rendering at the document root. You ' + + 'should look for environment dependent code in your components ' + + 'and ensure the props are the same client and server side:\n%s', + difference + ); + + if (__DEV__) { + warning( + false, + 'React attempted to reuse markup in a container but the ' + + 'checksum was invalid. This generally means that you are ' + + 'using server rendering and the markup generated on the ' + + 'server was not what the client was expecting. React injected ' + + 'new markup to compensate which works but you have lost many ' + + 'of the benefits of server rendering. Instead, figure out ' + + 'why the markup being generated is different on the client ' + + 'or server:\n%s', + difference + ); + } + } + } + + invariant( + container.nodeType !== DOC_NODE_TYPE, + 'You\'re trying to render a component to the document but ' + + 'you didn\'t use server rendering. We can\'t do this ' + + 'without using server rendering due to cross-browser quirks. ' + + 'See React.renderToString() for server rendering.' + ); + + setInnerHTML(container, markup); + }, + + /** + * React ID utilities. + */ + + getReactRootID: getReactRootID, + + getID: getID, + + setID: setID, + + getNode: getNode, + + getNodeFromInstance: getNodeFromInstance, + + purgeID: purgeID +}; + +ReactPerf.measureMethods(ReactMount, 'ReactMount', { + _renderNewRootComponent: '_renderNewRootComponent', + _mountImageIntoNode: '_mountImageIntoNode' +}); + +module.exports = ReactMount; +}); +__d('ReactBrowserEventEmitter',["EventConstants","EventPluginHub","EventPluginRegistry","ReactEventEmitterMixin","ViewportMetrics","Object.assign","isEventSupported"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactBrowserEventEmitter + * @typechecks static-only + */ + +'use strict'; + +var EventConstants = require('EventConstants'); +var EventPluginHub = require('EventPluginHub'); +var EventPluginRegistry = require('EventPluginRegistry'); +var ReactEventEmitterMixin = require('ReactEventEmitterMixin'); +var ViewportMetrics = require('ViewportMetrics'); + +var assign = require('Object.assign'); +var isEventSupported = require('isEventSupported'); + +/** + * Summary of `ReactBrowserEventEmitter` event handling: + * + * - Top-level delegation is used to trap most native browser events. This + * may only occur in the main thread and is the responsibility of + * ReactEventListener, which is injected and can therefore support pluggable + * event sources. This is the only work that occurs in the main thread. + * + * - We normalize and de-duplicate events to account for browser quirks. This + * may be done in the worker thread. + * + * - Forward these native events (with the associated top-level type used to + * trap it) to `EventPluginHub`, which in turn will ask plugins if they want + * to extract any synthetic events. + * + * - The `EventPluginHub` will then process each event by annotating them with + * "dispatches", a sequence of listeners and IDs that care about that event. + * + * - The `EventPluginHub` then dispatches the events. + * + * Overview of React and the event system: + * + * +------------+ . + * | DOM | . + * +------------+ . + * | . + * v . + * +------------+ . + * | ReactEvent | . + * | Listener | . + * +------------+ . +-----------+ + * | . +--------+|SimpleEvent| + * | . | |Plugin | + * +-----|------+ . v +-----------+ + * | | | . +--------------+ +------------+ + * | +-----------.--->|EventPluginHub| | Event | + * | | . | | +-----------+ | Propagators| + * | ReactEvent | . | | |TapEvent | |------------| + * | Emitter | . | |<---+|Plugin | |other plugin| + * | | . | | +-----------+ | utilities | + * | +-----------.--->| | +------------+ + * | | | . +--------------+ + * +-----|------+ . ^ +-----------+ + * | . | |Enter/Leave| + * + . +-------+|Plugin | + * +-------------+ . +-----------+ + * | application | . + * |-------------| . + * | | . + * | | . + * +-------------+ . + * . + * React Core . General Purpose Event Plugin System + */ + +var alreadyListeningTo = {}; +var isMonitoringScrollValue = false; +var reactTopListenersCounter = 0; + +// For events like 'submit' which don't consistently bubble (which we trap at a +// lower node than `document`), binding at `document` would cause duplicate +// events so we don't include them here +var topEventMapping = { + topBlur: 'blur', + topChange: 'change', + topClick: 'click', + topCompositionEnd: 'compositionend', + topCompositionStart: 'compositionstart', + topCompositionUpdate: 'compositionupdate', + topContextMenu: 'contextmenu', + topCopy: 'copy', + topCut: 'cut', + topDoubleClick: 'dblclick', + topDrag: 'drag', + topDragEnd: 'dragend', + topDragEnter: 'dragenter', + topDragExit: 'dragexit', + topDragLeave: 'dragleave', + topDragOver: 'dragover', + topDragStart: 'dragstart', + topDrop: 'drop', + topFocus: 'focus', + topInput: 'input', + topKeyDown: 'keydown', + topKeyPress: 'keypress', + topKeyUp: 'keyup', + topMouseDown: 'mousedown', + topMouseMove: 'mousemove', + topMouseOut: 'mouseout', + topMouseOver: 'mouseover', + topMouseUp: 'mouseup', + topPaste: 'paste', + topScroll: 'scroll', + topSelectionChange: 'selectionchange', + topTextInput: 'textInput', + topTouchCancel: 'touchcancel', + topTouchEnd: 'touchend', + topTouchMove: 'touchmove', + topTouchStart: 'touchstart', + topWheel: 'wheel' +}; + +/** + * To ensure no conflicts with other potential React instances on the page + */ +var topListenersIDKey = '_reactListenersID' + String(Math.random()).slice(2); + +function getListeningForDocument(mountAt) { + // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty` + // directly. + if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) { + mountAt[topListenersIDKey] = reactTopListenersCounter++; + alreadyListeningTo[mountAt[topListenersIDKey]] = {}; + } + return alreadyListeningTo[mountAt[topListenersIDKey]]; +} + +/** + * `ReactBrowserEventEmitter` is used to attach top-level event listeners. For + * example: + * + * ReactBrowserEventEmitter.putListener('myID', 'onClick', myFunction); + * + * This would allocate a "registration" of `('onClick', myFunction)` on 'myID'. + * + * @internal + */ +var ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, { + + /** + * Injectable event backend + */ + ReactEventListener: null, + + injection: { + /** + * @param {object} ReactEventListener + */ + injectReactEventListener: function(ReactEventListener) { + ReactEventListener.setHandleTopLevel( + ReactBrowserEventEmitter.handleTopLevel + ); + ReactBrowserEventEmitter.ReactEventListener = ReactEventListener; + } + }, + + /** + * Sets whether or not any created callbacks should be enabled. + * + * @param {boolean} enabled True if callbacks should be enabled. + */ + setEnabled: function(enabled) { + if (ReactBrowserEventEmitter.ReactEventListener) { + ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled); + } + }, + + /** + * @return {boolean} True if callbacks are enabled. + */ + isEnabled: function() { + return !!( + ReactBrowserEventEmitter.ReactEventListener && + ReactBrowserEventEmitter.ReactEventListener.isEnabled() + ); + }, + + /** + * We listen for bubbled touch events on the document object. + * + * Firefox v8.01 (and possibly others) exhibited strange behavior when + * mounting `onmousemove` events at some node that was not the document + * element. The symptoms were that if your mouse is not moving over something + * contained within that mount point (for example on the background) the + * top-level listeners for `onmousemove` won't be called. However, if you + * register the `mousemove` on the document object, then it will of course + * catch all `mousemove`s. This along with iOS quirks, justifies restricting + * top-level listeners to the document object only, at least for these + * movement types of events and possibly all events. + * + * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html + * + * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but + * they bubble to document. + * + * @param {string} registrationName Name of listener (e.g. `onClick`). + * @param {object} contentDocumentHandle Document which owns the container + */ + listenTo: function(registrationName, contentDocumentHandle) { + var mountAt = contentDocumentHandle; + var isListening = getListeningForDocument(mountAt); + var dependencies = EventPluginRegistry. + registrationNameDependencies[registrationName]; + + var topLevelTypes = EventConstants.topLevelTypes; + for (var i = 0, l = dependencies.length; i < l; i++) { + var dependency = dependencies[i]; + if (!( + isListening.hasOwnProperty(dependency) && + isListening[dependency] + )) { + if (dependency === topLevelTypes.topWheel) { + if (isEventSupported('wheel')) { + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( + topLevelTypes.topWheel, + 'wheel', + mountAt + ); + } else if (isEventSupported('mousewheel')) { + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( + topLevelTypes.topWheel, + 'mousewheel', + mountAt + ); + } else { + // Firefox needs to capture a different mouse scroll event. + // @see http://www.quirksmode.org/dom/events/tests/scroll.html + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( + topLevelTypes.topWheel, + 'DOMMouseScroll', + mountAt + ); + } + } else if (dependency === topLevelTypes.topScroll) { + + if (isEventSupported('scroll', true)) { + ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( + topLevelTypes.topScroll, + 'scroll', + mountAt + ); + } else { + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( + topLevelTypes.topScroll, + 'scroll', + ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE + ); + } + } else if (dependency === topLevelTypes.topFocus || + dependency === topLevelTypes.topBlur) { + + if (isEventSupported('focus', true)) { + ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( + topLevelTypes.topFocus, + 'focus', + mountAt + ); + ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( + topLevelTypes.topBlur, + 'blur', + mountAt + ); + } else if (isEventSupported('focusin')) { + // IE has `focusin` and `focusout` events which bubble. + // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( + topLevelTypes.topFocus, + 'focusin', + mountAt + ); + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( + topLevelTypes.topBlur, + 'focusout', + mountAt + ); + } + + // to make sure blur and focus event listeners are only attached once + isListening[topLevelTypes.topBlur] = true; + isListening[topLevelTypes.topFocus] = true; + } else if (topEventMapping.hasOwnProperty(dependency)) { + ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( + dependency, + topEventMapping[dependency], + mountAt + ); + } + + isListening[dependency] = true; + } + } + }, + + trapBubbledEvent: function(topLevelType, handlerBaseName, handle) { + return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( + topLevelType, + handlerBaseName, + handle + ); + }, + + trapCapturedEvent: function(topLevelType, handlerBaseName, handle) { + return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( + topLevelType, + handlerBaseName, + handle + ); + }, + + /** + * Listens to window scroll and resize events. We cache scroll values so that + * application code can access them without triggering reflows. + * + * NOTE: Scroll events do not bubble. + * + * @see http://www.quirksmode.org/dom/events/scroll.html + */ + ensureScrollValueMonitoring: function() { + if (!isMonitoringScrollValue) { + var refresh = ViewportMetrics.refreshScrollValues; + ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh); + isMonitoringScrollValue = true; + } + }, + + eventNameDispatchConfigs: EventPluginHub.eventNameDispatchConfigs, + + registrationNameModules: EventPluginHub.registrationNameModules, + + putListener: EventPluginHub.putListener, + + getListener: EventPluginHub.getListener, + + deleteListener: EventPluginHub.deleteListener, + + deleteAllListeners: EventPluginHub.deleteAllListeners + +}); + +module.exports = ReactBrowserEventEmitter; +}); +__d('ViewportMetrics',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ViewportMetrics + */ + +'use strict'; + +var ViewportMetrics = { + + currentScrollLeft: 0, + + currentScrollTop: 0, + + refreshScrollValues: function(scrollPosition) { + ViewportMetrics.currentScrollLeft = scrollPosition.x; + ViewportMetrics.currentScrollTop = scrollPosition.y; + } + +}; + +module.exports = ViewportMetrics; +}); +__d('isEventSupported',["ExecutionEnvironment"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 isEventSupported + */ + +'use strict'; + +var ExecutionEnvironment = require('ExecutionEnvironment'); + +var useHasFeature; +if (ExecutionEnvironment.canUseDOM) { + useHasFeature = + document.implementation && + document.implementation.hasFeature && + // always returns true in newer browsers as per the standard. + // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature + document.implementation.hasFeature('', '') !== true; +} + +/** + * Checks if an event is supported in the current execution environment. + * + * NOTE: This will not work correctly for non-generic events such as `change`, + * `reset`, `load`, `error`, and `select`. + * + * Borrows from Modernizr. + * + * @param {string} eventNameSuffix Event name, e.g. "click". + * @param {?boolean} capture Check if the capture phase is supported. + * @return {boolean} True if the event is supported. + * @internal + * @license Modernizr 3.0.0pre (Custom Build) | MIT + */ +function isEventSupported(eventNameSuffix, capture) { + if (!ExecutionEnvironment.canUseDOM || + capture && !('addEventListener' in document)) { + return false; + } + + var eventName = 'on' + eventNameSuffix; + var isSupported = eventName in document; + + if (!isSupported) { + var element = document.createElement('div'); + element.setAttribute(eventName, 'return;'); + isSupported = typeof element[eventName] === 'function'; + } + + if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') { + // This is the only way to test support for the `wheel` event in IE9+. + isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); + } + + return isSupported; +} + +module.exports = isEventSupported; +}); +__d('ReactMarkupChecksum',["adler32"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactMarkupChecksum + */ + +'use strict'; + +var adler32 = require('adler32'); + +var ReactMarkupChecksum = { + CHECKSUM_ATTR_NAME: 'data-react-checksum', + + /** + * @param {string} markup Markup string + * @return {string} Markup string with checksum attribute attached + */ + addChecksumToMarkup: function(markup) { + var checksum = adler32(markup); + return markup.replace( + '>', + ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '">' + ); + }, + + /** + * @param {string} markup to use + * @param {DOMElement} element root React element + * @returns {boolean} whether or not the markup is the same + */ + canReuseMarkup: function(markup, element) { + var existingChecksum = element.getAttribute( + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + ); + existingChecksum = existingChecksum && parseInt(existingChecksum, 10); + var markupChecksum = adler32(markup); + return markupChecksum === existingChecksum; + } +}; + +module.exports = ReactMarkupChecksum; +}); +__d('adler32',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 adler32 + */ + +/* jslint bitwise:true */ + +'use strict'; + +var MOD = 65521; + +// This is a clean-room implementation of adler32 designed for detecting +// if markup is not what we expect it to be. It does not need to be +// cryptographically strong, only reasonably good at detecting if markup +// generated on the server is different than that on the client. +function adler32(data) { + var a = 1; + var b = 0; + for (var i = 0; i < data.length; i++) { + a = (a + data.charCodeAt(i)) % MOD; + b = (b + a) % MOD; + } + return a | (b << 16); +} + +module.exports = adler32; +}); +__d('containsNode',["isTextNode"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 containsNode + * @typechecks + */ + +var isTextNode = require('isTextNode'); + +/*jslint bitwise:true */ + +/** + * Checks if a given DOM node contains or is another DOM node. + * + * @param {?DOMNode} outerNode Outer DOM node. + * @param {?DOMNode} innerNode Inner DOM node. + * @return {boolean} True if `outerNode` contains or is `innerNode`. + */ +function containsNode(outerNode, innerNode) { + if (!outerNode || !innerNode) { + return false; + } else if (outerNode === innerNode) { + return true; + } else if (isTextNode(outerNode)) { + return false; + } else if (isTextNode(innerNode)) { + return containsNode(outerNode, innerNode.parentNode); + } else if (outerNode.contains) { + return outerNode.contains(innerNode); + } else if (outerNode.compareDocumentPosition) { + return !!(outerNode.compareDocumentPosition(innerNode) & 16); + } else { + return false; + } +} + +module.exports = containsNode; +}); +__d('isTextNode',["isNode"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 isTextNode + * @typechecks + */ + +var isNode = require('isNode'); + +/** + * @param {*} object The object to check. + * @return {boolean} Whether or not the object is a DOM text node. + */ +function isTextNode(object) { + return isNode(object) && object.nodeType == 3; +} + +module.exports = isTextNode; +}); +__d('getReactRootElementInContainer',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 getReactRootElementInContainer + */ + +'use strict'; + +var DOC_NODE_TYPE = 9; + +/** + * @param {DOMElement|DOMDocument} container DOM element that may contain + * a React component + * @return {?*} DOM element that may have the reactRoot ID, or null. + */ +function getReactRootElementInContainer(container) { + if (!container) { + return null; + } + + if (container.nodeType === DOC_NODE_TYPE) { + return container.documentElement; + } else { + return container.firstChild; + } +} + +module.exports = getReactRootElementInContainer; +}); +__d('setInnerHTML',["ExecutionEnvironment"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 setInnerHTML + */ + +/* globals MSApp */ + +'use strict'; + +var ExecutionEnvironment = require('ExecutionEnvironment'); + +var WHITESPACE_TEST = /^[ \r\n\t\f]/; +var NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/; + +/** + * Set the innerHTML property of a node, ensuring that whitespace is preserved + * even in IE8. + * + * @param {DOMElement} node + * @param {string} html + * @internal + */ +var setInnerHTML = function(node, html) { + node.innerHTML = html; +}; + +// Win8 apps: Allow all html to be inserted +if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) { + setInnerHTML = function(node, html) { + MSApp.execUnsafeLocalFunction(function() { + node.innerHTML = html; + }); + }; +} + +if (ExecutionEnvironment.canUseDOM) { + // IE8: When updating a just created node with innerHTML only leading + // whitespace is removed. When updating an existing node with innerHTML + // whitespace in root TextNodes is also collapsed. + // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html + + // Feature detection; only IE8 is known to behave improperly like this. + var testElement = document.createElement('div'); + testElement.innerHTML = ' '; + if (testElement.innerHTML === '') { + setInnerHTML = function(node, html) { + // Magic theory: IE8 supposedly differentiates between added and updated + // nodes when processing innerHTML, innerHTML on updated nodes suffers + // from worse whitespace behavior. Re-adding a node like this triggers + // the initial and more favorable whitespace behavior. + // TODO: What to do on a detached node? + if (node.parentNode) { + node.parentNode.replaceChild(node, node); + } + + // We also implement a workaround for non-visible tags disappearing into + // thin air on IE8, this only happens if there is no visible text + // in-front of the non-visible tags. Piggyback on the whitespace fix + // and simply check if any non-visible tags appear in the source. + if (WHITESPACE_TEST.test(html) || + html[0] === '<' && NONVISIBLE_TEST.test(html)) { + // Recover leading whitespace by temporarily prepending any character. + // \uFEFF has the potential advantage of being zero-width/invisible. + node.innerHTML = '\uFEFF' + html; + + // deleteData leaves an empty `TextNode` which offsets the index of all + // children. Definitely want to avoid this. + var textNode = node.firstChild; + if (textNode.data.length === 1) { + node.removeChild(textNode); + } else { + textNode.deleteData(0, 1); + } + } else { + node.innerHTML = html; + } + }; + } +} + +module.exports = setInnerHTML; +}); +__d('AppStateIOS',["NativeModules","RCTDeviceEventEmitter","logError"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 AppStateIOS + * @flow + */ +'use strict'; + +var NativeModules = require('NativeModules'); +var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); +var RCTAppState = NativeModules.AppState; + +var logError = require('logError'); + +var DEVICE_APPSTATE_EVENT = 'appStateDidChange'; + +var _appStateHandlers = {}; + +/** + * `AppStateIOS` can tell you if the app is in the foreground or background, + * and notify you when the state changes. + * + * AppStateIOS is frequently used to determine the intent and proper behavior when + * handling push notifications. + * + * ### iOS App States + * + * - `active` - The app is running in the foreground + * - `background` - The app is running in the background. The user is either + * in another app or on the home screen + * - `inactive` - This is a transition state that currently never happens for + * typical React Native apps. + * + * For more information, see + * [Apple's documentation](https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html) + * + * ### Basic Usage + * + * To see the current state, you can check `AppStateIOS.currentState`, which + * will be kept up-to-date. However, `currentState` will be null at launch + * while `AppStateIOS` retrieves it over the bridge. + * + * ``` + * getInitialState: function() { + * return { + * currentAppState: AppStateIOS.currentState, + * }; + * }, + * componentDidMount: function() { + * AppStateIOS.addEventListener('change', this._handleAppStateChange); + * }, + * componentWillUnmount: function() { + * AppStateIOS.removeEventListener('change', this._handleAppStateChange); + * }, + * _handleAppStateChange: function(currentAppState) { + * this.setState({ currentAppState, }); + * }, + * render: function() { + * return ( + * Current state is: {this.state.currentAppState} + * ); + * }, + * ``` + * + * This example will only ever appear to say "Current state is: active" because + * the app is only visible to the user when in the `active` state, and the null + * state will happen only momentarily. + */ + +var AppStateIOS = { + + /** + * Add a handler to AppState changes by listening to the `change` event type + * and providing the handler + */ + addEventListener: function( + type , + handler + ) { + _appStateHandlers[handler] = RCTDeviceEventEmitter.addListener( + DEVICE_APPSTATE_EVENT, + function(appStateData) { + handler(appStateData.app_state); + } + ); + }, + + /** + * Remove a handler by passing the `change` event type and the handler + */ + removeEventListener: function( + type , + handler + ) { + if (!_appStateHandlers[handler]) { + return; + } + _appStateHandlers[handler].remove(); + _appStateHandlers[handler] = null; + }, + + currentState: (null ), + +}; + +RCTDeviceEventEmitter.addListener( + DEVICE_APPSTATE_EVENT, + function(appStateData) { + AppStateIOS.currentState = appStateData.app_state; + } +); + +RCTAppState.getCurrentAppState( + function(appStateData) { + AppStateIOS.currentState = appStateData.app_state; + }, + logError +); + +module.exports = AppStateIOS; +}); +__d('CameraRoll',["ReactPropTypes","NativeModules","createStrictShapeTypeChecker","deepFreezeAndThrowOnMutationInDev","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 CameraRoll + * @flow + */ +'use strict'; + +var ReactPropTypes = require('ReactPropTypes'); +var RCTCameraRollManager = require('NativeModules').CameraRollManager; + +var createStrictShapeTypeChecker = require('createStrictShapeTypeChecker'); +var deepFreezeAndThrowOnMutationInDev = + require('deepFreezeAndThrowOnMutationInDev'); +var invariant = require('invariant'); + +var GROUP_TYPES_OPTIONS = [ + 'Album', + 'All', + 'Event', + 'Faces', + 'Library', + 'PhotoStream', + 'SavedPhotos', // default +]; + +// Flow treats Object and Array as disjoint types, currently. +deepFreezeAndThrowOnMutationInDev((GROUP_TYPES_OPTIONS )); + +/** + * Shape of the param arg for the `getPhotos` function. + */ +var getPhotosParamChecker = createStrictShapeTypeChecker({ + /** + * The number of photos wanted in reverse order of the photo application + * (i.e. most recent first for SavedPhotos). + */ + first: ReactPropTypes.number.isRequired, + + /** + * A cursor that matches `page_info { end_cursor }` returned from a previous + * call to `getPhotos` + */ + after: ReactPropTypes.string, + + /** + * Specifies which group types to filter the results to. + */ + groupTypes: ReactPropTypes.oneOf(GROUP_TYPES_OPTIONS), + + /** + * Specifies filter on group names, like 'Recent Photos' or custom album + * titles. + */ + groupName: ReactPropTypes.string, +}); + +/** + * Shape of the return value of the `getPhotos` function. + */ +var getPhotosReturnChecker = createStrictShapeTypeChecker({ + edges: ReactPropTypes.arrayOf(createStrictShapeTypeChecker({ + node: createStrictShapeTypeChecker({ + type: ReactPropTypes.string.isRequired, + group_name: ReactPropTypes.string.isRequired, + image: createStrictShapeTypeChecker({ + uri: ReactPropTypes.string.isRequired, + height: ReactPropTypes.number.isRequired, + width: ReactPropTypes.number.isRequired, + isStored: ReactPropTypes.bool, + }).isRequired, + timestamp: ReactPropTypes.number.isRequired, + location: createStrictShapeTypeChecker({ + latitude: ReactPropTypes.number, + longitude: ReactPropTypes.number, + altitude: ReactPropTypes.number, + heading: ReactPropTypes.number, + speed: ReactPropTypes.number, + }), + }).isRequired, + })).isRequired, + page_info: createStrictShapeTypeChecker({ + has_next_page: ReactPropTypes.bool.isRequired, + start_cursor: ReactPropTypes.string, + end_cursor: ReactPropTypes.string, + }).isRequired, +}); + +function CameraRoll(){} + + + /** + * Saves the image with tag `tag` to the camera roll. + * + * @param {string} tag - Can be any of the three kinds of tags we accept: + * 1. URL + * 2. assets-library tag + * 3. tag returned from storing an image in memory + */ + CameraRoll.saveImageWithTag=function(tag, successCallback, errorCallback) { + invariant( + typeof tag === 'string', + 'CameraRoll.saveImageWithTag tag must be a valid string.' + ); + RCTCameraRollManager.saveImageWithTag( + tag, + function(imageTag) { + successCallback && successCallback(imageTag); + }, + function(errorMessage) { + errorCallback && errorCallback(errorMessage); + }); + }; + + /** + * Invokes `callback` with photo identifier objects from the local camera + * roll of the device matching shape defined by `getPhotosReturnChecker`. + * + * @param {object} params - See `getPhotosParamChecker`. + * @param {function} callback - Invoked with arg of shape defined by + * `getPhotosReturnChecker` on success. + * @param {function} errorCallback - Invoked with error message on error. + */ + CameraRoll.getPhotos=function(params, callback, errorCallback) { + var metaCallback = callback; + if (__DEV__) { + getPhotosParamChecker({params:params}, 'params', 'CameraRoll.getPhotos'); + invariant( + typeof callback === 'function', + 'CameraRoll.getPhotos callback must be a valid function.' + ); + invariant( + typeof errorCallback === 'function', + 'CameraRoll.getPhotos errorCallback must be a valid function.' + ); + } + if (__DEV__) { + metaCallback = function(response) { + getPhotosReturnChecker( + {response:response}, + 'response', + 'CameraRoll.getPhotos callback' + ); + callback(response); + }; + } + RCTCameraRollManager.getPhotos(params, metaCallback, errorCallback); + }; + + +CameraRoll.GroupTypesOptions = GROUP_TYPES_OPTIONS; + +module.exports = CameraRoll; +}); +__d('LinkingIOS',["RCTDeviceEventEmitter","NativeModules","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 LinkingIOS + * @flow + */ +'use strict'; + +var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); +var RCTLinkingManager = require('NativeModules').LinkingManager; +var invariant = require('invariant'); + +var _notifHandlers = {}; +var _initialURL = RCTLinkingManager && + RCTLinkingManager.initialURL; + +var DEVICE_NOTIF_EVENT = 'openURL'; + +/** + * `LinkingIOS` gives you a general interface to interact with both, incoming + * and outgoing app links. + * + * ### Basic Usage + * + * #### Handling deep links + * + * If your app was launched from a external url registered to your app you can + * access and handle it from any component you want with + * + * ``` + * componentDidMount() { + * var url = LinkingIOS.popInitialURL(); + * } + * ``` + * + * In case you also want to listen to incoming app links during your app's + * execution you'll need to add the following lines to you `*AppDelegate.m`: + * + * ``` + * - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { + * return [RCTLinkingManager application:application openURL:url sourceApplication:sourceApplication annotation:annotation]; + * } + * ``` + * + * And then on your React component you'll be able to listen to the events on + * `LinkingIOS` as follows + * + * ``` + * componentDidMount() { + * LinkingIOS.addEventListener('url', this._handleOpenURL); + * }, + * componentWillUnmount() { + * LinkingIOS.removeEventListener('url', this._handleOpenURL); + * }, + * _handleOpenURL(event) { + * console.log(event.url); + * } + * ``` + * + * #### Triggering App links + * + * To trigger an app link (browser, email or custom schemas) you call + * + * ``` + * LinkingIOS.openURL(url) + * ``` + * + * If you want to check if any installed app can handle a given url beforehand you can call + * ``` + * LinkingIOS.canOpenURL(url, (supported) => { + * if (!supported) { + * AlertIOS.alert('Can\'t handle url: ' + url); + * } else { + * LinkingIOS.openURL(url); + * } + * }); + * ``` + * + * _The iOS simulator does not support the `mailto:` and `tel:` schemas + * because the Mail and Phone apps are not installed - you will need to test + * them on a device._ + */ +function LinkingIOS(){} + /** + * Add a handler to LinkingIOS changes by listening to the `url` event type + * and providing the handler + */ + LinkingIOS.addEventListener=function(type , handler ) { + invariant( + type === 'url', + 'LinkingIOS only supports `url` events' + ); + _notifHandlers[handler] = RCTDeviceEventEmitter.addListener( + DEVICE_NOTIF_EVENT, + handler + ); + }; + + /** + * Remove a handler by passing the `url` event type and the handler + */ + LinkingIOS.removeEventListener=function(type , handler ) { + invariant( + type === 'url', + 'LinkingIOS only supports `url` events' + ); + if (!_notifHandlers[handler]) { + return; + } + _notifHandlers[handler].remove(); + _notifHandlers[handler] = null; + }; + + /** + * Try to open the given `url` with any of the installed apps. + */ + LinkingIOS.openURL=function(url ) { + invariant( + typeof url === 'string', + 'Invalid url: should be a string' + ); + RCTLinkingManager.openURL(url); + }; + + /** + * Determine wether or not the an installed app can handle a given `url` + * The callback function will be called with `bool supported` as the only argument + */ + LinkingIOS.canOpenURL=function(url , callback ) { + invariant( + typeof url === 'string', + 'Invalid url: should be a string' + ); + invariant( + typeof callback === 'function', + 'A valid callback function is required' + ); + RCTLinkingManager.canOpenURL(url, callback); + }; + + /** + * If the app launch was triggered by an app link, it will pop the link url, + * otherwise it will return `null` + */ + LinkingIOS.popInitialURL=function() { + var initialURL = _initialURL; + _initialURL = null; + return initialURL; + }; + + +module.exports = LinkingIOS; +}); +__d('LayoutAnimation',["ReactPropTypes","NativeModules","createStrictShapeTypeChecker","keyMirror"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 LayoutAnimation + * @flow + */ +'use strict'; + +var PropTypes = require('ReactPropTypes'); +var RCTUIManager = require('NativeModules').UIManager; + +var createStrictShapeTypeChecker = require('createStrictShapeTypeChecker'); +var keyMirror = require('keyMirror'); + +var TypesEnum = { + spring: true, + linear: true, + easeInEaseOut: true, + easeIn: true, + easeOut: true, +}; +var Types = keyMirror(TypesEnum); + +var PropertiesEnum = { + opacity: true, + scaleXY: true, +}; +var Properties = keyMirror(PropertiesEnum); + +var animChecker = createStrictShapeTypeChecker({ + duration: PropTypes.number, + delay: PropTypes.number, + springDamping: PropTypes.number, + initialVelocity: PropTypes.number, + type: PropTypes.oneOf( + Object.keys(Types) + ), + property: PropTypes.oneOf( // Only applies to create/delete + Object.keys(Properties) + ), +}); + + + + + + + + + + +var configChecker = createStrictShapeTypeChecker({ + duration: PropTypes.number.isRequired, + create: animChecker, + update: animChecker, + "delete": animChecker, +}); + + + + + + + + +function configureNext(config , onAnimationDidEnd , onError ) { + configChecker({config:config}, 'config', 'LayoutAnimation.configureNext'); + RCTUIManager.configureNextLayoutAnimation(config, onAnimationDidEnd, onError); +} + +function create(duration , type, creationProp) { + return { + duration:duration, + create: { + type:type, + property: creationProp, + }, + update: { + type:type, + }, + }; +} + +var LayoutAnimation = { + configureNext:configureNext, + create:create, + Types:Types, + Properties:Properties, + configChecker: configChecker, + Presets: { + easeInEaseOut: create( + 300, Types.easeInEaseOut, Properties.opacity + ), + linear: create( + 500, Types.linear, Properties.opacity + ), + spring: { + duration: 700, + create: { + type: Types.linear, + property: Properties.opacity, + }, + update: { + type: Types.spring, + springDamping: 0.4, + }, + }, + } +}; + +module.exports = LayoutAnimation; +}); +__d('NetInfo',["NativeModules","RCTDeviceEventEmitter"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 NetInfo + * @flow + */ +'use strict'; + +var NativeModules = require('NativeModules'); +var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); +var RCTReachability = NativeModules.Reachability; + +var DEVICE_REACHABILITY_EVENT = 'reachabilityDidChange'; + + + + + + + + + + + + + +/** + * NetInfo exposes info about online/offline status + * + * ### reachabilityIOS + * + * Asynchronously determine if the device is online and on a cellular network. + * + * - `none` - device is offline + * - `wifi` - device is online and connected via wifi, or is the iOS simulator + * - `cell` - device is connected via Edge, 3G, WiMax, or LTE + * - `unknown` - error case and the network status is unknown + * + * ``` + * NetInfo.reachabilityIOS.fetch().done((reach) => { + * console.log('Initial: ' + reach); + * }); + * function handleFirstReachabilityChange(reach) { + * console.log('First change: ' + reach); + * NetInfo.reachabilityIOS.removeEventListener( + * 'change', + * handleFirstReachabilityChange + * ); + * } + * NetInfo.reachabilityIOS.addEventListener( + * 'change', + * handleFirstReachabilityChange + * ); + * ``` + * + * ### isConnected + * + * Available on all platforms. Asynchronously fetch a boolean to determine + * internet connectivity. + * + * ``` + * NetInfo.isConnected.fetch().done((isConnected) => { + * console.log('First, is ' + (isConnected ? 'online' : 'offline')); + * }); + * function handleFirstConnectivityChange(isConnected) { + * console.log('Then, is ' + (isConnected ? 'online' : 'offline')); + * NetInfo.isConnected.removeEventListener( + * 'change', + * handleFirstConnectivityChange + * ); + * } + * NetInfo.isConnected.addEventListener( + * 'change', + * handleFirstConnectivityChange + * ); + * ``` + */ + +var NetInfo = {}; + +if (RCTReachability) { + + // RCTReachability is exposed, so this is an iOS-like environment and we will + // expose reachabilityIOS + + var _reachabilitySubscriptions = {}; + + NetInfo.reachabilityIOS = { + addEventListener: function ( + eventName , + handler + ) { + _reachabilitySubscriptions[handler] = RCTDeviceEventEmitter.addListener( + DEVICE_REACHABILITY_EVENT, + function(appStateData) { + handler(appStateData.network_reachability); + } + ); + }, + + removeEventListener: function( + eventName , + handler + ) { + if (!_reachabilitySubscriptions[handler]) { + return; + } + _reachabilitySubscriptions[handler].remove(); + _reachabilitySubscriptions[handler] = null; + }, + + fetch: function() { + return new Promise(function(resolve, reject) { + RCTReachability.getCurrentReachability( + function(resp) { + resolve(resp.network_reachability); + }, + reject + ); + }); + }, + }; + + var _isConnectedSubscriptions = {}; + + var _iosReachabilityIsConnected = function( + reachability + ) { + return reachability !== 'none' && + reachability !== 'unknown'; + }; + + NetInfo.isConnected = { + addEventListener: function ( + eventName , + handler + ) { + _isConnectedSubscriptions[handler] = function(reachability) { + handler(_iosReachabilityIsConnected(reachability)); + }; + NetInfo.reachabilityIOS.addEventListener( + eventName, + _isConnectedSubscriptions[handler] + ); + }, + + removeEventListener: function( + eventName , + handler + ) { + NetInfo.reachabilityIOS.removeEventListener( + eventName, + _isConnectedSubscriptions[handler] + ); + }, + + fetch: function() { + return NetInfo.reachabilityIOS.fetch().then( + function(reachability) {return _iosReachabilityIsConnected(reachability);} + ); + }, + }; +} + +module.exports = NetInfo; +}); +__d('PushNotificationIOS',["NativeModules","RCTDeviceEventEmitter","NativeModules","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 PushNotificationIOS + * @flow + */ +'use strict'; + +var NativeModules = require('NativeModules'); +var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); +var RCTPushNotificationManager = require('NativeModules').PushNotificationManager; +var invariant = require('invariant'); + +var _notifHandlers = {}; +var _initialNotification = RCTPushNotificationManager && + RCTPushNotificationManager.initialNotification; + +var DEVICE_NOTIF_EVENT = 'remoteNotificationReceived'; + +/** + * Handle push notifications for your app, including permission handling and + * icon badge number. + * + * To get up and running, [configure your notifications with Apple](https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/ConfiguringPushNotifications/ConfiguringPushNotifications.html) + * and your server-side system. To get an idea, [this is the Parse guide](https://parse.com/tutorials/ios-push-notifications). + */ + + + + + + + /** + * Sets the badge number for the app icon on the home screen + */ + PushNotificationIOS.setApplicationIconBadgeNumber=function(number ) { + RCTPushNotificationManager.setApplicationIconBadgeNumber(number); + }; + + /** + * Gets the current badge number for the app icon on the home screen + */ + PushNotificationIOS.getApplicationIconBadgeNumber=function(callback ) { + RCTPushNotificationManager.getApplicationIconBadgeNumber(callback); + }; + + /** + * Attaches a listener to remote notifications while the app is running in the + * foreground or the background. + * + * The handler will get be invoked with an instance of `PushNotificationIOS` + */ + PushNotificationIOS.addEventListener=function(type , handler ) { + invariant( + type === 'notification', + 'PushNotificationIOS only supports `notification` events' + ); + _notifHandlers[handler] = RCTDeviceEventEmitter.addListener( + DEVICE_NOTIF_EVENT, + function(notifData) { + handler(new PushNotificationIOS(notifData)); + } + ); + }; + + /** + * Requests all notification permissions from iOS, prompting the user's + * dialog box. + */ + PushNotificationIOS.requestPermissions=function() { + RCTPushNotificationManager.requestPermissions(); + }; + + /** + * See what push permissions are currently enabled. `callback` will be + * invoked with a `permissions` object: + * + * - `alert` :boolean + * - `badge` :boolean + * - `sound` :boolean + */ + PushNotificationIOS.checkPermissions=function(callback ) { + invariant( + typeof callback === 'function', + 'Must provide a valid callback' + ); + RCTPushNotificationManager.checkPermissions(callback); + }; + + /** + * Removes the event listener. Do this in `componentWillUnmount` to prevent + * memory leaks + */ + PushNotificationIOS.removeEventListener=function(type , handler ) { + invariant( + type === 'notification', + 'PushNotificationIOS only supports `notification` events' + ); + if (!_notifHandlers[handler]) { + return; + } + _notifHandlers[handler].remove(); + _notifHandlers[handler] = null; + }; + + + /** + * An initial notification will be available if the app was cold-launched + * from a notification. + * + * The first caller of `popInitialNotification` will get the initial + * notification object, or `null`. Subsequent invocations will return null. + */ + PushNotificationIOS.popInitialNotification=function() { + var initialNotification = _initialNotification && + new PushNotificationIOS(_initialNotification); + _initialNotification = null; + return initialNotification; + }; + + /** + * You will never need to instansiate `PushNotificationIOS` yourself. + * Listening to the `notification` event and invoking + * `popInitialNotification` is sufficient + */ + function PushNotificationIOS(nativeNotif) { + this.$PushNotificationIOS_data = {}; + + // Extract data from Apple's `aps` dict as defined: + + // https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html + + Object.keys(nativeNotif).forEach(function(notifKey) { + var notifVal = nativeNotif[notifKey]; + if (notifKey === 'aps') { + this.$PushNotificationIOS_alert = notifVal.alert; + this.$PushNotificationIOS_sound = notifVal.sound; + this.$PushNotificationIOS_badgeCount = notifVal.badge; + } else { + this.$PushNotificationIOS_data[notifKey] = notifVal; + } + }.bind(this)); + } + + /** + * An alias for `getAlert` to get the notification's main message string + */ + PushNotificationIOS.prototype.getMessage=function() { + // alias because "alert" is an ambiguous name + return this.$PushNotificationIOS_alert; + }; + + /** + * Gets the sound string from the `aps` object + */ + PushNotificationIOS.prototype.getSound=function() { + return this.$PushNotificationIOS_sound; + }; + + /** + * Gets the notification's main message from the `aps` object + */ + PushNotificationIOS.prototype.getAlert=function() { + return this.$PushNotificationIOS_alert; + }; + + /** + * Gets the badge count number from the `aps` object + */ + PushNotificationIOS.prototype.getBadgeCount=function() { + return this.$PushNotificationIOS_badgeCount; + }; + + /** + * Gets the data object on the notif + */ + PushNotificationIOS.prototype.getData=function() { + return this.$PushNotificationIOS_data; + }; + + +module.exports = PushNotificationIOS; +}); +__d('StatusBarIOS',["NativeModules"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 StatusBarIOS + * @flow + */ +'use strict'; + +var RCTStatusBarManager = require('NativeModules').StatusBarManager; + +var StatusBarIOS = { + + Style: { + "default": RCTStatusBarManager.Style["default"], + lightContent: RCTStatusBarManager.Style.lightContent + }, + + Animation: { + none: RCTStatusBarManager.Animation.none, + fade: RCTStatusBarManager.Animation.fade, + slide: RCTStatusBarManager.Animation.slide, + }, + + setStyle:function(style , animated ) { + animated = animated || false; + RCTStatusBarManager.setStyle(style, animated); + }, + + setHidden:function(hidden , animation ) { + animation = animation || StatusBarIOS.Animation.none; + RCTStatusBarManager.setHidden(hidden, animation); + }, +}; + +module.exports = StatusBarIOS; +}); +__d('VibrationIOS',["NativeModules","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 VibrationIOS + * @flow + */ +'use strict'; + +var RCTVibration = require('NativeModules').Vibration; + +var invariant = require('invariant'); + +/** + * The Vibration API is exposed at `VibrationIOS.vibrate()`. On iOS, calling this + * function will trigger a one second vibration. The vibration is asynchronous + * so this method will return immediately. + * + * There will be no effect on devices that do not support Vibration, eg. the iOS + * simulator. + * + * Vibration patterns are currently unsupported. + */ + +var VibrationIOS = { + vibrate: function() { + invariant( + arguments[0] === undefined, + 'Vibration patterns not supported.' + ); + RCTVibration.vibrate(); + } +}; + +module.exports = VibrationIOS; +}); +__d('LinkedStateMixin',["ReactLink","ReactStateSetters"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 LinkedStateMixin + * @typechecks static-only + */ + +'use strict'; + +var ReactLink = require('ReactLink'); +var ReactStateSetters = require('ReactStateSetters'); + +/** + * A simple mixin around ReactLink.forState(). + */ +var LinkedStateMixin = { + /** + * Create a ReactLink that's linked to part of this component's state. The + * ReactLink will have the current value of this.state[key] and will call + * setState() when a change is requested. + * + * @param {string} key state key to update. Note: you may want to use keyOf() + * if you're using Google Closure Compiler advanced mode. + * @return {ReactLink} ReactLink instance linking to the state. + */ + linkState: function(key) { + return new ReactLink( + this.state[key], + ReactStateSetters.createStateKeySetter(this, key) + ); + } +}; + +module.exports = LinkedStateMixin; +}); +__d('ReactLink',["React"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactLink + * @typechecks static-only + */ + +'use strict'; + +/** + * ReactLink encapsulates a common pattern in which a component wants to modify + * a prop received from its parent. ReactLink allows the parent to pass down a + * value coupled with a callback that, when invoked, expresses an intent to + * modify that value. For example: + * + * React.createClass({ + * getInitialState: function() { + * return {value: ''}; + * }, + * render: function() { + * var valueLink = new ReactLink(this.state.value, this._handleValueChange); + * return ; + * }, + * this._handleValueChange: function(newValue) { + * this.setState({value: newValue}); + * } + * }); + * + * We have provided some sugary mixins to make the creation and + * consumption of ReactLink easier; see LinkedValueUtils and LinkedStateMixin. + */ + +var React = require('React'); + +/** + * @param {*} value current value of the link + * @param {function} requestChange callback to request a change + */ +function ReactLink(value, requestChange) { + this.value = value; + this.requestChange = requestChange; +} + +/** + * Creates a PropType that enforces the ReactLink API and optionally checks the + * type of the value being passed inside the link. Example: + * + * MyComponent.propTypes = { + * tabIndexLink: ReactLink.PropTypes.link(React.PropTypes.number) + * } + */ +function createLinkTypeChecker(linkType) { + var shapes = { + value: typeof linkType === 'undefined' ? + React.PropTypes.any.isRequired : + linkType.isRequired, + requestChange: React.PropTypes.func.isRequired + }; + return React.PropTypes.shape(shapes); +} + +ReactLink.PropTypes = { + link: createLinkTypeChecker +}; + +module.exports = ReactLink; +}); +__d('ReactStateSetters',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactStateSetters + */ + +'use strict'; + +var ReactStateSetters = { + /** + * Returns a function that calls the provided function, and uses the result + * of that to set the component's state. + * + * @param {ReactCompositeComponent} component + * @param {function} funcReturningState Returned callback uses this to + * determine how to update state. + * @return {function} callback that when invoked uses funcReturningState to + * determined the object literal to setState. + */ + createStateSetter: function(component, funcReturningState) { + return function(a, b, c, d, e, f) { + var partialState = funcReturningState.call(component, a, b, c, d, e, f); + if (partialState) { + component.setState(partialState); + } + }; + }, + + /** + * Returns a single-argument callback that can be used to update a single + * key in the component's state. + * + * Note: this is memoized function, which makes it inexpensive to call. + * + * @param {ReactCompositeComponent} component + * @param {string} key The key in the state that you should update. + * @return {function} callback of 1 argument which calls setState() with + * the provided keyName and callback argument. + */ + createStateKeySetter: function(component, key) { + // Memoize the setters. + var cache = component.__keySetters || (component.__keySetters = {}); + return cache[key] || (cache[key] = createStateKeySetter(component, key)); + } +}; + +function createStateKeySetter(component, key) { + // Partial state is allocated outside of the function closure so it can be + // reused with every call, avoiding memory allocation when this function + // is called. + var partialState = {}; + return function stateKeySetter(value) { + partialState[key] = value; + component.setState(partialState); + }; +} + +ReactStateSetters.Mixin = { + /** + * Returns a function that calls the provided function, and uses the result + * of that to set the component's state. + * + * For example, these statements are equivalent: + * + * this.setState({x: 1}); + * this.createStateSetter(function(xValue) { + * return {x: xValue}; + * })(1); + * + * @param {function} funcReturningState Returned callback uses this to + * determine how to update state. + * @return {function} callback that when invoked uses funcReturningState to + * determined the object literal to setState. + */ + createStateSetter: function(funcReturningState) { + return ReactStateSetters.createStateSetter(this, funcReturningState); + }, + + /** + * Returns a single-argument callback that can be used to update a single + * key in the component's state. + * + * For example, these statements are equivalent: + * + * this.setState({x: 1}); + * this.createStateKeySetter('x')(1); + * + * Note: this is memoized function, which makes it inexpensive to call. + * + * @param {string} key The key in the state that you should update. + * @return {function} callback of 1 argument which calls setState() with + * the provided keyName and callback argument. + */ + createStateKeySetter: function(key) { + return ReactStateSetters.createStateKeySetter(this, key); + } +}; + +module.exports = ReactStateSetters; +}); +__d('ReactComponentWithPureRenderMixin',["shallowEqual"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactComponentWithPureRenderMixin +*/ + +'use strict'; + +var shallowEqual = require('shallowEqual'); + +/** + * If your React component's render function is "pure", e.g. it will render the + * same result given the same props and state, provide this Mixin for a + * considerable performance boost. + * + * Most React components have pure render functions. + * + * Example: + * + * var ReactComponentWithPureRenderMixin = + * require('ReactComponentWithPureRenderMixin'); + * React.createClass({ + * mixins: [ReactComponentWithPureRenderMixin], + * + * render: function() { + * return

; + * } + * }); + * + * Note: This only checks shallow equality for props and state. If these contain + * complex data structures this mixin may have false-negatives for deeper + * differences. Only mixin to components which have simple props and state, or + * use `forceUpdate()` when you know deep data structures have changed. + */ +var ReactComponentWithPureRenderMixin = { + shouldComponentUpdate: function(nextProps, nextState) { + return !shallowEqual(this.props, nextProps) || + !shallowEqual(this.state, nextState); + } +}; + +module.exports = ReactComponentWithPureRenderMixin; +}); +__d('shallowEqual',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 shallowEqual + */ + +'use strict'; + +/** + * Performs equality by iterating through keys on an object and returning + * false when any key has values which are not strictly equal between + * objA and objB. Returns true when the values of all keys are strictly equal. + * + * @return {boolean} + */ +function shallowEqual(objA, objB) { + if (objA === objB) { + return true; + } + var key; + // Test for A's keys different from B. + for (key in objA) { + if (objA.hasOwnProperty(key) && + (!objB.hasOwnProperty(key) || objA[key] !== objB[key])) { + return false; + } + } + // Test for B's keys missing from A. + for (key in objB) { + if (objB.hasOwnProperty(key) && !objA.hasOwnProperty(key)) { + return false; + } + } + return true; +} + +module.exports = shallowEqual; +}); +__d('update',["Object.assign","keyOf","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 update + */ + + /* global hasOwnProperty:true */ + +'use strict'; + +var assign = require('Object.assign'); +var keyOf = require('keyOf'); +var invariant = require('invariant'); +var hasOwnProperty = {}.hasOwnProperty; + +function shallowCopy(x) { + if (Array.isArray(x)) { + return x.concat(); + } else if (x && typeof x === 'object') { + return assign(new x.constructor(), x); + } else { + return x; + } +} + +var COMMAND_PUSH = keyOf({$push: null}); +var COMMAND_UNSHIFT = keyOf({$unshift: null}); +var COMMAND_SPLICE = keyOf({$splice: null}); +var COMMAND_SET = keyOf({$set: null}); +var COMMAND_MERGE = keyOf({$merge: null}); +var COMMAND_APPLY = keyOf({$apply: null}); + +var ALL_COMMANDS_LIST = [ + COMMAND_PUSH, + COMMAND_UNSHIFT, + COMMAND_SPLICE, + COMMAND_SET, + COMMAND_MERGE, + COMMAND_APPLY +]; + +var ALL_COMMANDS_SET = {}; + +ALL_COMMANDS_LIST.forEach(function(command) { + ALL_COMMANDS_SET[command] = true; +}); + +function invariantArrayCase(value, spec, command) { + invariant( + Array.isArray(value), + 'update(): expected target of %s to be an array; got %s.', + command, + value + ); + var specValue = spec[command]; + invariant( + Array.isArray(specValue), + 'update(): expected spec of %s to be an array; got %s. ' + + 'Did you forget to wrap your parameter in an array?', + command, + specValue + ); +} + +function update(value, spec) { + invariant( + typeof spec === 'object', + 'update(): You provided a key path to update() that did not contain one ' + + 'of %s. Did you forget to include {%s: ...}?', + ALL_COMMANDS_LIST.join(', '), + COMMAND_SET + ); + + if (hasOwnProperty.call(spec, COMMAND_SET)) { + invariant( + Object.keys(spec).length === 1, + 'Cannot have more than one key in an object with %s', + COMMAND_SET + ); + + return spec[COMMAND_SET]; + } + + var nextValue = shallowCopy(value); + + if (hasOwnProperty.call(spec, COMMAND_MERGE)) { + var mergeObj = spec[COMMAND_MERGE]; + invariant( + mergeObj && typeof mergeObj === 'object', + 'update(): %s expects a spec of type \'object\'; got %s', + COMMAND_MERGE, + mergeObj + ); + invariant( + nextValue && typeof nextValue === 'object', + 'update(): %s expects a target of type \'object\'; got %s', + COMMAND_MERGE, + nextValue + ); + assign(nextValue, spec[COMMAND_MERGE]); + } + + if (hasOwnProperty.call(spec, COMMAND_PUSH)) { + invariantArrayCase(value, spec, COMMAND_PUSH); + spec[COMMAND_PUSH].forEach(function(item) { + nextValue.push(item); + }); + } + + if (hasOwnProperty.call(spec, COMMAND_UNSHIFT)) { + invariantArrayCase(value, spec, COMMAND_UNSHIFT); + spec[COMMAND_UNSHIFT].forEach(function(item) { + nextValue.unshift(item); + }); + } + + if (hasOwnProperty.call(spec, COMMAND_SPLICE)) { + invariant( + Array.isArray(value), + 'Expected %s target to be an array; got %s', + COMMAND_SPLICE, + value + ); + invariant( + Array.isArray(spec[COMMAND_SPLICE]), + 'update(): expected spec of %s to be an array of arrays; got %s. ' + + 'Did you forget to wrap your parameters in an array?', + COMMAND_SPLICE, + spec[COMMAND_SPLICE] + ); + spec[COMMAND_SPLICE].forEach(function(args) { + invariant( + Array.isArray(args), + 'update(): expected spec of %s to be an array of arrays; got %s. ' + + 'Did you forget to wrap your parameters in an array?', + COMMAND_SPLICE, + spec[COMMAND_SPLICE] + ); + nextValue.splice.apply(nextValue, args); + }); + } + + if (hasOwnProperty.call(spec, COMMAND_APPLY)) { + invariant( + typeof spec[COMMAND_APPLY] === 'function', + 'update(): expected spec of %s to be a function; got %s.', + COMMAND_APPLY, + spec[COMMAND_APPLY] + ); + nextValue = spec[COMMAND_APPLY](nextValue); + } + + for (var k in spec) { + if (!(ALL_COMMANDS_SET.hasOwnProperty(k) && ALL_COMMANDS_SET[k])) { + nextValue[k] = update(value[k], spec[k]); + } + } + + return nextValue; +} + +module.exports = update; +}); +__d('ReactTestUtils',["EventConstants","EventPluginHub","EventPropagators","React","ReactElement","ReactEmptyComponent","ReactBrowserEventEmitter","ReactCompositeComponent","ReactInstanceHandles","ReactInstanceMap","ReactMount","ReactUpdates","SyntheticEvent","Object.assign"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * Copyright 2013-2015, 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 ReactTestUtils + */ + +'use strict'; + +var EventConstants = require('EventConstants'); +var EventPluginHub = require('EventPluginHub'); +var EventPropagators = require('EventPropagators'); +var React = require('React'); +var ReactElement = require('ReactElement'); +var ReactEmptyComponent = require('ReactEmptyComponent'); +var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter'); +var ReactCompositeComponent = require('ReactCompositeComponent'); +var ReactInstanceHandles = require('ReactInstanceHandles'); +var ReactInstanceMap = require('ReactInstanceMap'); +var ReactMount = require('ReactMount'); +var ReactUpdates = require('ReactUpdates'); +var SyntheticEvent = require('SyntheticEvent'); + +var assign = require('Object.assign'); + +var topLevelTypes = EventConstants.topLevelTypes; + +function Event(suffix) {} + +/** + * @class ReactTestUtils + */ + +/** + * Todo: Support the entire DOM.scry query syntax. For now, these simple + * utilities will suffice for testing purposes. + * @lends ReactTestUtils + */ +var ReactTestUtils = { + renderIntoDocument: function(instance) { + var div = document.createElement('div'); + // None of our tests actually require attaching the container to the + // DOM, and doing so creates a mess that we rely on test isolation to + // clean up, so we're going to stop honoring the name of this method + // (and probably rename it eventually) if no problems arise. + // document.documentElement.appendChild(div); + return React.render(instance, div); + }, + + isElement: function(element) { + return ReactElement.isValidElement(element); + }, + + isElementOfType: function(inst, convenienceConstructor) { + return ( + ReactElement.isValidElement(inst) && + inst.type === convenienceConstructor + ); + }, + + isDOMComponent: function(inst) { + // TODO: Fix this heuristic. It's just here because composites can currently + // pretend to be DOM components. + return !!(inst && inst.tagName && inst.getDOMNode); + }, + + isDOMComponentElement: function(inst) { + return !!(inst && + ReactElement.isValidElement(inst) && + !!inst.tagName); + }, + + isCompositeComponent: function(inst) { + return typeof inst.render === 'function' && + typeof inst.setState === 'function'; + }, + + isCompositeComponentWithType: function(inst, type) { + return !!(ReactTestUtils.isCompositeComponent(inst) && + (inst.constructor === type)); + }, + + isCompositeComponentElement: function(inst) { + if (!ReactElement.isValidElement(inst)) { + return false; + } + // We check the prototype of the type that will get mounted, not the + // instance itself. This is a future proof way of duck typing. + var prototype = inst.type.prototype; + return ( + typeof prototype.render === 'function' && + typeof prototype.setState === 'function' + ); + }, + + isCompositeComponentElementWithType: function(inst, type) { + return !!(ReactTestUtils.isCompositeComponentElement(inst) && + (inst.constructor === type)); + }, + + getRenderedChildOfCompositeComponent: function(inst) { + if (!ReactTestUtils.isCompositeComponent(inst)) { + return null; + } + var internalInstance = ReactInstanceMap.get(inst); + return internalInstance._renderedComponent.getPublicInstance(); + }, + + findAllInRenderedTree: function(inst, test) { + if (!inst) { + return []; + } + var ret = test(inst) ? [inst] : []; + if (ReactTestUtils.isDOMComponent(inst)) { + var internalInstance = ReactInstanceMap.get(inst); + var renderedChildren = internalInstance + ._renderedComponent + ._renderedChildren; + var key; + for (key in renderedChildren) { + if (!renderedChildren.hasOwnProperty(key)) { + continue; + } + if (!renderedChildren[key].getPublicInstance) { + continue; + } + ret = ret.concat( + ReactTestUtils.findAllInRenderedTree( + renderedChildren[key].getPublicInstance(), + test + ) + ); + } + } else if (ReactTestUtils.isCompositeComponent(inst)) { + ret = ret.concat( + ReactTestUtils.findAllInRenderedTree( + ReactTestUtils.getRenderedChildOfCompositeComponent(inst), + test + ) + ); + } + return ret; + }, + + /** + * Finds all instance of components in the rendered tree that are DOM + * components with the class name matching `className`. + * @return an array of all the matches. + */ + scryRenderedDOMComponentsWithClass: function(root, className) { + return ReactTestUtils.findAllInRenderedTree(root, function(inst) { + var instClassName = inst.props.className; + return ReactTestUtils.isDOMComponent(inst) && ( + instClassName && + (' ' + instClassName + ' ').indexOf(' ' + className + ' ') !== -1 + ); + }); + }, + + /** + * Like scryRenderedDOMComponentsWithClass but expects there to be one result, + * and returns that one result, or throws exception if there is any other + * number of matches besides one. + * @return {!ReactDOMComponent} The one match. + */ + findRenderedDOMComponentWithClass: function(root, className) { + var all = + ReactTestUtils.scryRenderedDOMComponentsWithClass(root, className); + if (all.length !== 1) { + throw new Error('Did not find exactly one match ' + + '(found: ' + all.length + ') for class:' + className + ); + } + return all[0]; + }, + + + /** + * Finds all instance of components in the rendered tree that are DOM + * components with the tag name matching `tagName`. + * @return an array of all the matches. + */ + scryRenderedDOMComponentsWithTag: function(root, tagName) { + return ReactTestUtils.findAllInRenderedTree(root, function(inst) { + return ReactTestUtils.isDOMComponent(inst) && + inst.tagName === tagName.toUpperCase(); + }); + }, + + /** + * Like scryRenderedDOMComponentsWithTag but expects there to be one result, + * and returns that one result, or throws exception if there is any other + * number of matches besides one. + * @return {!ReactDOMComponent} The one match. + */ + findRenderedDOMComponentWithTag: function(root, tagName) { + var all = ReactTestUtils.scryRenderedDOMComponentsWithTag(root, tagName); + if (all.length !== 1) { + throw new Error('Did not find exactly one match for tag:' + tagName); + } + return all[0]; + }, + + + /** + * Finds all instances of components with type equal to `componentType`. + * @return an array of all the matches. + */ + scryRenderedComponentsWithType: function(root, componentType) { + return ReactTestUtils.findAllInRenderedTree(root, function(inst) { + return ReactTestUtils.isCompositeComponentWithType( + inst, + componentType + ); + }); + }, + + /** + * Same as `scryRenderedComponentsWithType` but expects there to be one result + * and returns that one result, or throws exception if there is any other + * number of matches besides one. + * @return {!ReactComponent} The one match. + */ + findRenderedComponentWithType: function(root, componentType) { + var all = ReactTestUtils.scryRenderedComponentsWithType( + root, + componentType + ); + if (all.length !== 1) { + throw new Error( + 'Did not find exactly one match for componentType:' + componentType + ); + } + return all[0]; + }, + + /** + * Pass a mocked component module to this method to augment it with + * useful methods that allow it to be used as a dummy React component. + * Instead of rendering as usual, the component will become a simple + *
containing any provided children. + * + * @param {object} module the mock function object exported from a + * module that defines the component to be mocked + * @param {?string} mockTagName optional dummy root tag name to return + * from render method (overrides + * module.mockTagName if provided) + * @return {object} the ReactTestUtils object (for chaining) + */ + mockComponent: function(module, mockTagName) { + mockTagName = mockTagName || module.mockTagName || "div"; + + module.prototype.render.mockImplementation(function() { + return React.createElement( + mockTagName, + null, + this.props.children + ); + }); + + return this; + }, + + /** + * Simulates a top level event being dispatched from a raw event that occured + * on an `Element` node. + * @param topLevelType {Object} A type from `EventConstants.topLevelTypes` + * @param {!Element} node The dom to simulate an event occurring on. + * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent. + */ + simulateNativeEventOnNode: function(topLevelType, node, fakeNativeEvent) { + fakeNativeEvent.target = node; + ReactBrowserEventEmitter.ReactEventListener.dispatchEvent( + topLevelType, + fakeNativeEvent + ); + }, + + /** + * Simulates a top level event being dispatched from a raw event that occured + * on the `ReactDOMComponent` `comp`. + * @param topLevelType {Object} A type from `EventConstants.topLevelTypes`. + * @param comp {!ReactDOMComponent} + * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent. + */ + simulateNativeEventOnDOMComponent: function( + topLevelType, + comp, + fakeNativeEvent) { + ReactTestUtils.simulateNativeEventOnNode( + topLevelType, + comp.getDOMNode(), + fakeNativeEvent + ); + }, + + nativeTouchData: function(x, y) { + return { + touches: [ + {pageX: x, pageY: y} + ] + }; + }, + + createRenderer: function() { + return new ReactShallowRenderer(); + }, + + Simulate: null, + SimulateNative: {} +}; + +/** + * @class ReactShallowRenderer + */ +var ReactShallowRenderer = function() { + this._instance = null; +}; + +ReactShallowRenderer.prototype.getRenderOutput = function() { + return ( + (this._instance && this._instance._renderedComponent && + this._instance._renderedComponent._renderedOutput) + || null + ); +}; + +var NoopInternalComponent = function(element) { + this._renderedOutput = element; + this._currentElement = element === null || element === false ? + ReactEmptyComponent.emptyElement : + element; +}; + +NoopInternalComponent.prototype = { + + mountComponent: function() { + }, + + receiveComponent: function(element) { + this._renderedOutput = element; + this._currentElement = element === null || element === false ? + ReactEmptyComponent.emptyElement : + element; + }, + + unmountComponent: function() { + } + +}; + +var ShallowComponentWrapper = function() { }; +assign( + ShallowComponentWrapper.prototype, + ReactCompositeComponent.Mixin, { + _instantiateReactComponent: function(element) { + return new NoopInternalComponent(element); + }, + _replaceNodeWithMarkupByID: function() {}, + _renderValidatedComponent: + ReactCompositeComponent.Mixin. + _renderValidatedComponentWithoutOwnerOrContext + } +); + +ReactShallowRenderer.prototype.render = function(element, context) { + var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(); + this._render(element, transaction, context); + ReactUpdates.ReactReconcileTransaction.release(transaction); +}; + +ReactShallowRenderer.prototype.unmount = function() { + if (this._instance) { + this._instance.unmountComponent(); + } +}; + +ReactShallowRenderer.prototype._render = function(element, transaction, context) { + if (!this._instance) { + var rootID = ReactInstanceHandles.createReactRootID(); + var instance = new ShallowComponentWrapper(element.type); + instance.construct(element); + + instance.mountComponent(rootID, transaction, context); + + this._instance = instance; + } else { + this._instance.receiveComponent(element, transaction, context); + } +}; + +/** + * Exports: + * + * - `ReactTestUtils.Simulate.click(Element/ReactDOMComponent)` + * - `ReactTestUtils.Simulate.mouseMove(Element/ReactDOMComponent)` + * - `ReactTestUtils.Simulate.change(Element/ReactDOMComponent)` + * - ... (All keys from event plugin `eventTypes` objects) + */ +function makeSimulator(eventType) { + return function(domComponentOrNode, eventData) { + var node; + if (ReactTestUtils.isDOMComponent(domComponentOrNode)) { + node = domComponentOrNode.getDOMNode(); + } else if (domComponentOrNode.tagName) { + node = domComponentOrNode; + } + + var fakeNativeEvent = new Event(); + fakeNativeEvent.target = node; + // We don't use SyntheticEvent.getPooled in order to not have to worry about + // properly destroying any properties assigned from `eventData` upon release + var event = new SyntheticEvent( + ReactBrowserEventEmitter.eventNameDispatchConfigs[eventType], + ReactMount.getID(node), + fakeNativeEvent + ); + assign(event, eventData); + EventPropagators.accumulateTwoPhaseDispatches(event); + + ReactUpdates.batchedUpdates(function() { + EventPluginHub.enqueueEvents(event); + EventPluginHub.processEventQueue(); + }); + }; +} + +function buildSimulators() { + ReactTestUtils.Simulate = {}; + + var eventType; + for (eventType in ReactBrowserEventEmitter.eventNameDispatchConfigs) { + /** + * @param {!Element || ReactDOMComponent} domComponentOrNode + * @param {?object} eventData Fake event data to use in SyntheticEvent. + */ + ReactTestUtils.Simulate[eventType] = makeSimulator(eventType); + } +} + +// Rebuild ReactTestUtils.Simulate whenever event plugins are injected +var oldInjectEventPluginOrder = EventPluginHub.injection.injectEventPluginOrder; +EventPluginHub.injection.injectEventPluginOrder = function() { + oldInjectEventPluginOrder.apply(this, arguments); + buildSimulators(); +}; +var oldInjectEventPlugins = EventPluginHub.injection.injectEventPluginsByName; +EventPluginHub.injection.injectEventPluginsByName = function() { + oldInjectEventPlugins.apply(this, arguments); + buildSimulators(); +}; + +buildSimulators(); + +/** + * Exports: + * + * - `ReactTestUtils.SimulateNative.click(Element/ReactDOMComponent)` + * - `ReactTestUtils.SimulateNative.mouseMove(Element/ReactDOMComponent)` + * - `ReactTestUtils.SimulateNative.mouseIn/ReactDOMComponent)` + * - `ReactTestUtils.SimulateNative.mouseOut(Element/ReactDOMComponent)` + * - ... (All keys from `EventConstants.topLevelTypes`) + * + * Note: Top level event types are a subset of the entire set of handler types + * (which include a broader set of "synthetic" events). For example, onDragDone + * is a synthetic event. Except when testing an event plugin or React's event + * handling code specifically, you probably want to use ReactTestUtils.Simulate + * to dispatch synthetic events. + */ + +function makeNativeSimulator(eventType) { + return function(domComponentOrNode, nativeEventData) { + var fakeNativeEvent = new Event(eventType); + assign(fakeNativeEvent, nativeEventData); + if (ReactTestUtils.isDOMComponent(domComponentOrNode)) { + ReactTestUtils.simulateNativeEventOnDOMComponent( + eventType, + domComponentOrNode, + fakeNativeEvent + ); + } else if (!!domComponentOrNode.tagName) { + // Will allow on actual dom nodes. + ReactTestUtils.simulateNativeEventOnNode( + eventType, + domComponentOrNode, + fakeNativeEvent + ); + } + }; +} + +var eventType; +for (eventType in topLevelTypes) { + // Event type is stored as 'topClick' - we transform that to 'click' + var convenienceName = eventType.indexOf('top') === 0 ? + eventType.charAt(3).toLowerCase() + eventType.substr(4) : eventType; + /** + * @param {!Element || ReactDOMComponent} domComponentOrNode + * @param {?Event} nativeEventData Fake native event to use in SyntheticEvent. + */ + ReactTestUtils.SimulateNative[convenienceName] = + makeNativeSimulator(eventType); +} -throw new Error('Offline JS file is empty. See iOS/main.jsbundle for instructions'); +module.exports = ReactTestUtils; +}); +;require("HybridMobileDeployCompanion/index.ios"); +//@ sourceMappingURL=/index.ios.map \ No newline at end of file diff --git a/HybridMobileDeploy.h b/HybridMobileDeploy.h index 07197a08f..5aef7c440 100644 --- a/HybridMobileDeploy.h +++ b/HybridMobileDeploy.h @@ -1,5 +1,8 @@ #import "RCTBridgeModule.h" @interface HybridMobileDeploy : NSObject - ++ (NSString *) getBundleFolderPath:(NSString*)bundleName; ++ (NSURL *) getNativeBundleURL:(NSString*)bundleName; ++ (NSURL *)appBundleUrl:(NSString*)bundleName + nativeBundleName:(NSString*)nativeBundleName; @end diff --git a/HybridMobileDeploy.m b/HybridMobileDeploy.m index d1b1dc572..1079c08c6 100644 --- a/HybridMobileDeploy.m +++ b/HybridMobileDeploy.m @@ -26,21 +26,24 @@ + (NSURL *) getNativeBundleURL:(NSString*)bundleName return [[NSBundle mainBundle] URLForResource:bundleName withExtension:@"jsbundle"]; } -+ (NSURL *) appBundleUrl:(NSString*)bundleName { ++ (NSURL *) appBundleUrl:(NSString*)bundleName + nativeBundleName:(NSString*)nativeBundleName +{ NSFileManager *fileManager = [NSFileManager defaultManager]; NSString *bundlePath = [self getBundlePath:bundleName]; if ([fileManager fileExistsAtPath:bundlePath]) { return [[NSURL alloc] initFileURLWithPath:bundlePath]; } else { - return [self getNativeBundleURL:bundleName]; + return [self getNativeBundleURL:nativeBundleName]; } } + (void) loadBundle:(NSString*)moduleName + nativeBundleName:(NSString*)nativeBundleName { dispatch_async(dispatch_get_main_queue(), ^{ - RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:[self appBundleUrl:moduleName] + RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:[self appBundleUrl:moduleName nativeBundleName:nativeBundleName] moduleName:moduleName launchOptions:nil]; @@ -52,6 +55,7 @@ + (void) loadBundle:(NSString*)moduleName RCT_EXPORT_METHOD(installUpdateFromUrl:(NSString*)updateUrl bundleName:(NSString*)bundleName + nativeBundleName:(NSString*)nativeBundleName failureCallback:(RCTResponseSenderBlock)failureCallback successCallback:(RCTResponseSenderBlock)successCallback) { @@ -93,7 +97,7 @@ + (void) loadBundle:(NSString*)moduleName if (saveError) { failureCallback(@[saveError]); } else { - [HybridMobileDeploy loadBundle:bundleName]; + [HybridMobileDeploy loadBundle:bundleName nativeBundleName:nativeBundleName]; successCallback(@[]); } }); From 3037634d0d40d90b828f2aee70178db916c8fcbb Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Fri, 26 Jun 2015 10:18:27 -0700 Subject: [PATCH 04/16] Integrate module with Companion example app --- .../.npmignore => .npmignore | 3 + .../iOS/AppDelegate.m | 4 +- .../iOS/main.jsbundle | 327 +++++++++++++----- .../HybridMobileDeployCompanion/index.ios.js | 2 + .../HybridMobileDeployCompanion/package.json | 3 +- HybridMobileDeploy.android.js | 4 +- HybridMobileDeploy.ios.js | 62 +++- package.json | 6 +- 8 files changed, 300 insertions(+), 111 deletions(-) rename Examples/HybridMobileDeployCompanion/.npmignore => .npmignore (87%) diff --git a/Examples/HybridMobileDeployCompanion/.npmignore b/.npmignore similarity index 87% rename from Examples/HybridMobileDeployCompanion/.npmignore rename to .npmignore index c39012e9e..2fd920548 100644 --- a/Examples/HybridMobileDeployCompanion/.npmignore +++ b/.npmignore @@ -25,3 +25,6 @@ DerivedData # node_modules/ npm-debug.log + +# Don't publish example apps +Examples/ diff --git a/Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m b/Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m index e87f1aedf..ddc214318 100644 --- a/Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m +++ b/Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m @@ -33,7 +33,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( * on the same Wi-Fi network. */ - //jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle"]; + jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle"]; /** * OPTION 2 @@ -45,7 +45,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( * see http://facebook.github.io/react-native/docs/runningondevice.html */ - jsCodeLocation = [HybridMobileDeploy appBundleUrl:@"HybridMobileDeployCompanion" nativeBundleName:@"main"]; + //jsCodeLocation = [HybridMobileDeploy appBundleUrl:@"HybridMobileDeployCompanion" nativeBundleName:@"main"]; RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"HybridMobileDeployCompanion" diff --git a/Examples/HybridMobileDeployCompanion/iOS/main.jsbundle b/Examples/HybridMobileDeployCompanion/iOS/main.jsbundle index 2451483a1..09db1d6b2 100644 --- a/Examples/HybridMobileDeployCompanion/iOS/main.jsbundle +++ b/Examples/HybridMobileDeployCompanion/iOS/main.jsbundle @@ -1101,6 +1101,8 @@ var $__0= React,AppRegistry=$__0.AppRegistry,StyleSheet=$__0.StyleSheet,Text=$__0.Text,View=$__0.View; +var HybridMobileDeploy = require('hybrid-mobile-deploy-react-native'); + var HybridMobileDeployCompanion = React.createClass({displayName: "HybridMobileDeployCompanion", render: function() { return ( @@ -1141,7 +1143,7 @@ var styles = StyleSheet.create({ AppRegistry.registerComponent('HybridMobileDeployCompanion', function() {return HybridMobileDeployCompanion;}); }); -__d('react-native/Libraries/react-native/react-native',["React","ActivityIndicatorIOS","DatePickerIOS","Image","ListView","MapView","NavigatorIOS","PickerIOS","Navigator","SegmentedControlIOS","ScrollView","SliderIOS","SwitchIOS","TabBarIOS","Text","TextInput","TouchableHighlight","TouchableOpacity","TouchableWithoutFeedback","View","WebView","AlertIOS","AppRegistry","AppStateIOS","AsyncStorage","CameraRoll","InteractionManager","LinkingIOS","LayoutAnimation","NetInfo","PixelRatio","PushNotificationIOS","PanResponder","StatusBarIOS","StyleSheet","VibrationIOS","RCTDeviceEventEmitter","NativeModules","requireNativeComponent","LinkedStateMixin","ReactComponentWithPureRenderMixin","NativeModules","ReactUpdates","cloneWithProps","ReactFragment","update","ReactDefaultPerf","ReactTestUtils"],function(global, require, requireDynamic, requireLazy, module, exports) { /** +__d('react-native/Libraries/react-native/react-native',["React","ActivityIndicatorIOS","DatePickerIOS","Image","ListView","MapView","NavigatorIOS","PickerIOS","Navigator","SegmentedControlIOS","ScrollView","SliderIOS","SwitchIOS","TabBarIOS","Text","TextInput","TouchableHighlight","TouchableOpacity","TouchableWithoutFeedback","View","WebView","AlertIOS","AppRegistry","AppStateIOS","AsyncStorage","CameraRoll","InteractionManager","LinkingIOS","LayoutAnimation","NetInfo","PixelRatio","PushNotificationIOS","PanResponder","StatusBarIOS","StyleSheet","VibrationIOS","RCTDeviceEventEmitter","RCTNativeAppEventEmitter","NativeModules","requireNativeComponent","LinkedStateMixin","ReactComponentWithPureRenderMixin","NativeModules","ReactUpdates","cloneWithProps","ReactFragment","update","ReactDefaultPerf","ReactTestUtils"],function(global, require, requireDynamic, requireLazy, module, exports) { /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * @@ -1202,6 +1204,7 @@ var ReactNative = Object.assign(Object.create(require('React')), { // Plugins DeviceEventEmitter: require('RCTDeviceEventEmitter'), + NativeAppEventEmitter: require('RCTNativeAppEventEmitter'), NativeModules: require('NativeModules'), requireNativeComponent: require('requireNativeComponent'), @@ -1236,8 +1239,7 @@ __d('React',["ReactNative"],function(global, require, requireDynamic, requireLaz * @providesModule React * @flow */ - -"use strict"; +'use strict'; module.exports = require('ReactNative'); }); @@ -1252,7 +1254,7 @@ __d('ReactNative',["ReactChildren","ReactClass","ReactComponent","ReactContext", * @providesModule ReactNative * @flow */ -"use strict"; +'use strict'; var ReactChildren = require('ReactChildren'); var ReactClass = require('ReactClass'); @@ -6326,7 +6328,7 @@ var keyOf = function(oneKeyObj) { module.exports = keyOf; }); -__d('ReactNativeDefaultInjection',["InitializeJavaScriptAppEngine","EventPluginHub","EventPluginUtils","IOSDefaultEventPluginOrder","IOSNativeBridgeEventPlugin","NodeHandle","ReactClass","ReactComponentEnvironment","ReactDefaultBatchingStrategy","ReactEmptyComponent","ReactInstanceHandles","ReactNativeComponentEnvironment","ReactNativeGlobalInteractionHandler","ReactNativeGlobalResponderHandler","ReactNativeMount","ReactNativeTextComponent","ReactNativeComponent","ReactUpdates","ResponderEventPlugin","UniversalWorkerNodeHandle","createReactNativeComponentClass","invariant","RCTEventEmitter","RCTLog","RCTJSTimers"],function(global, require, requireDynamic, requireLazy, module, exports) { /** +__d('ReactNativeDefaultInjection',["InitializeJavaScriptAppEngine","EventPluginHub","EventPluginUtils","IOSDefaultEventPluginOrder","IOSNativeBridgeEventPlugin","NodeHandle","ReactComponentEnvironment","ReactDefaultBatchingStrategy","ReactEmptyComponent","ReactInstanceHandles","ReactNativeComponentEnvironment","ReactNativeGlobalInteractionHandler","ReactNativeGlobalResponderHandler","ReactNativeMount","ReactNativeTextComponent","ReactNativeComponent","ReactUpdates","ResponderEventPlugin","UniversalWorkerNodeHandle","createReactNativeComponentClass","invariant","RCTEventEmitter","RCTLog","RCTJSTimers"],function(global, require, requireDynamic, requireLazy, module, exports) { /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * @@ -6337,8 +6339,7 @@ __d('ReactNativeDefaultInjection',["InitializeJavaScriptAppEngine","EventPluginH * @providesModule ReactNativeDefaultInjection * @flow */ - -"use strict"; +'use strict'; /** * Make sure `setTimeout`/`setInterval` are patched correctly. @@ -6349,7 +6350,6 @@ var EventPluginUtils = require('EventPluginUtils'); var IOSDefaultEventPluginOrder = require('IOSDefaultEventPluginOrder'); var IOSNativeBridgeEventPlugin = require('IOSNativeBridgeEventPlugin'); var NodeHandle = require('NodeHandle'); -var ReactClass = require('ReactClass'); var ReactComponentEnvironment = require('ReactComponentEnvironment'); var ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy'); var ReactEmptyComponent = require('ReactEmptyComponent'); @@ -6870,6 +6870,7 @@ __d('ErrorUtils',[],function(global, require, requireDynamic, requireLazy, modul * * @providesModule ErrorUtils */ +/* eslint-disable consistent-this, global-strict */ var GLOBAL = this; @@ -8118,7 +8119,6 @@ var JSTimers = { var newID = JSTimersExecution.GUID++; var freeIndex = JSTimers._getFreeIndex(); JSTimersExecution.timerIDs[freeIndex] = newID; - JSTimersExecution.callbacks[freeIndex] = func; JSTimersExecution.callbacks[freeIndex] = function() { return func.apply(undefined, args); }; @@ -8135,12 +8135,15 @@ var JSTimers = { var newID = JSTimersExecution.GUID++; var freeIndex = JSTimers._getFreeIndex(); JSTimersExecution.timerIDs[freeIndex] = newID; - JSTimersExecution.callbacks[freeIndex] = func; JSTimersExecution.callbacks[freeIndex] = function() { - return func.apply(undefined, args); + var startTime = Date.now(); + var ret = func.apply(undefined, args); + var endTime = Date.now(); + RCTTiming.createTimer(newID, Math.max(0, duration - (endTime - startTime)), endTime, false); + return ret; }; JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.setInterval; - RCTTiming.createTimer(newID, duration, Date.now(), /** recurring */ true); + RCTTiming.createTimer(newID, duration, Date.now(), /** recurring */ false); return newID; }, @@ -8152,7 +8155,6 @@ var JSTimers = { var newID = JSTimersExecution.GUID++; var freeIndex = JSTimers._getFreeIndex(); JSTimersExecution.timerIDs[freeIndex] = newID; - JSTimersExecution.callbacks[freeIndex] = func; JSTimersExecution.callbacks[freeIndex] = function() { return func.apply(undefined, args); }; @@ -8593,9 +8595,9 @@ var ZERO = valuePromise(0); var EMPTYSTRING = valuePromise(''); function valuePromise(value) { - var p = new Promise(Promise._83); - p._32 = 1; - p._8 = value; + var p = new Promise(Promise._1); + p._41 = 1; + p._86 = value; return p; } Promise.resolve = function (value) { @@ -8632,11 +8634,11 @@ Promise.all = function (arr) { function res(i, val) { if (val && (typeof val === 'object' || typeof val === 'function')) { if (val instanceof Promise && val.then === Promise.prototype.then) { - while (val._32 === 3) { - val = val._8; + while (val._41 === 3) { + val = val._86; } - if (val._32 === 1) return res(i, val._8); - if (val._32 === 2) reject(val._8); + if (val._41 === 1) return res(i, val._86); + if (val._41 === 2) reject(val._86); val.then(function (val) { res(i, val); }, reject); @@ -8743,13 +8745,13 @@ function Promise(fn) { if (typeof fn !== 'function') { throw new TypeError('not a function'); } - this._32 = 0; - this._8 = null; - this._89 = []; + this._41 = 0; + this._86 = null; + this._17 = []; if (fn === noop) return; doResolve(fn, this); } -Promise._83 = noop; +Promise._1 = noop; Promise.prototype.then = function(onFulfilled, onRejected) { if (this.constructor !== Promise) { @@ -8768,24 +8770,24 @@ function safeThen(self, onFulfilled, onRejected) { }); }; function handle(self, deferred) { - while (self._32 === 3) { - self = self._8; + while (self._41 === 3) { + self = self._86; } - if (self._32 === 0) { - self._89.push(deferred); + if (self._41 === 0) { + self._17.push(deferred); return; } setImmediate(function() { - var cb = self._32 === 1 ? deferred.onFulfilled : deferred.onRejected; + var cb = self._41 === 1 ? deferred.onFulfilled : deferred.onRejected; if (cb === null) { - if (self._32 === 1) { - resolve(deferred.promise, self._8); + if (self._41 === 1) { + resolve(deferred.promise, self._86); } else { - reject(deferred.promise, self._8); + reject(deferred.promise, self._86); } return; } - var ret = tryCallOne(cb, self._8); + var ret = tryCallOne(cb, self._86); if (ret === IS_ERROR) { reject(deferred.promise, LAST_ERROR); } else { @@ -8813,8 +8815,8 @@ function resolve(self, newValue) { then === self.then && newValue instanceof Promise ) { - self._32 = 3; - self._8 = newValue; + self._41 = 3; + self._86 = newValue; finale(self); return; } else if (typeof then === 'function') { @@ -8822,21 +8824,21 @@ function resolve(self, newValue) { return; } } - self._32 = 1; - self._8 = newValue; + self._41 = 1; + self._86 = newValue; finale(self); } function reject(self, newValue) { - self._32 = 2; - self._8 = newValue; + self._41 = 2; + self._86 = newValue; finale(self); } function finale(self) { - for (var i = 0; i < self._89.length; i++) { - handle(self, self._89[i]); + for (var i = 0; i < self._17.length; i++) { + handle(self, self._17[i]); } - self._89 = null; + self._17 = null; } function Handler(onFulfilled, onRejected, promise){ @@ -8902,6 +8904,7 @@ __d('SourceMap',[],function(global, require, requireDynamic, requireLazy, module * and wrapping resulting file into `wrapper` function. * */ +/*eslint-disable */ var scope = {}; wrapper.call(scope); @@ -10859,6 +10862,7 @@ __d('react-native/Libraries/JavaScriptAppEngine/Initialization/source-map-url',[ * * @nolint */ +/* eslint-disable */ (function() { var define = null; // Hack to make it work with our packager @@ -11406,6 +11410,7 @@ __d('fetch',[],function(global, require, requireDynamic, requireLazy, module, ex * @providesModule fetch * @nolint */ +/* eslint-disable */ 'use strict'; var self = {}; @@ -11895,7 +11900,7 @@ var Geolocation = { subscriptions = []; } } -} +}; module.exports = Geolocation; }); @@ -13092,8 +13097,7 @@ __d('IOSNativeBridgeEventPlugin',["EventPropagators","NativeModules","SyntheticE * @providesModule IOSNativeBridgeEventPlugin * @flow */ - -"use strict"; +'use strict'; var EventPropagators = require('EventPropagators'); var NativeModules = require('NativeModules'); @@ -13116,7 +13120,7 @@ for (var bubblingTypeName in customBubblingEventTypes) { for (var directTypeName in customDirectEventTypes) { warning( !customBubblingEventTypes[directTypeName], - "Event cannot be both direct and bubbling: %s", + 'Event cannot be both direct and bubbling: %s', directTypeName ); allTypesByEventName[directTypeName] = customDirectEventTypes[directTypeName]; @@ -13159,7 +13163,6 @@ var IOSNativeBridgeEventPlugin = { }; module.exports = IOSNativeBridgeEventPlugin; - }); __d('EventPropagators',["EventConstants","EventPluginHub","accumulateInto","forEachAccumulated"],function(global, require, requireDynamic, requireLazy, module, exports) { /** * Copyright 2013-2014 Facebook, Inc. @@ -14152,8 +14155,7 @@ __d('ReactNativeDOMIDOperations',["ReactNativeTagHandles","ReactMultiChildUpdate * @providesModule ReactNativeDOMIDOperations * @flow */ - -"use strict"; +'use strict'; var ReactNativeTagHandles = require('ReactNativeTagHandles'); var ReactMultiChildUpdateTypes = require('ReactMultiChildUpdateTypes'); @@ -14390,8 +14392,7 @@ __d('ReactNativeReconcileTransaction',["CallbackQueue","PooledClass","Transactio * @providesModule ReactNativeReconcileTransaction * @flow */ - -"use strict"; +'use strict'; var CallbackQueue = require('CallbackQueue'); var PooledClass = require('PooledClass'); @@ -14539,6 +14540,13 @@ var invariant = require('invariant'); var keyMirror = require('keyMirror'); var setImmediate = require('setImmediate'); + + +/** + * Maximum time a handle can be open before warning in DEV. + */ +var DEV_TIMEOUT = 2000; + var _emitter = new EventEmitter(); var _interactionSet = new Set(); var _addInteractionSet = new Set(); @@ -14607,6 +14615,14 @@ var InteractionManager = { scheduleUpdate(); var handle = ++_inc; _addInteractionSet.add(handle); + if (__DEV__) { + // Capture the stack trace of what created the handle. + var error = new Error( + 'InteractionManager: interaction handle not cleared within ' + + DEV_TIMEOUT + ' ms.' + ); + setDevTimeoutHandle(handle, error, DEV_TIMEOUT); + } return handle; }, @@ -14671,6 +14687,21 @@ function processUpdate() { _deleteInteractionSet.clear(); } +/** + * Wait until `timeout` has passed and warn if the handle has not been cleared. + */ +function setDevTimeoutHandle( + handle , + error , + timeout +) { + setTimeout(function() { + if (_interactionSet.has(handle)) { + console.warn(error.message + '\n' + error.stack); + } + }, timeout); +} + module.exports = InteractionManager; }); __d('Set',["Map","toIterator","_shouldPolyfillES6Collection"],function(global, require, requireDynamic, requireLazy, module, exports) { /** @@ -15851,7 +15882,7 @@ var ReactNativeGlobalResponderHandler = { module.exports = ReactNativeGlobalResponderHandler; }); -__d('ReactNativeMount',["NativeModules","ReactNativeTagHandles","ReactPerf","ReactReconciler","ReactUpdateQueue","ReactUpdates","emptyObject","instantiateReactComponent","invariant","shouldUpdateReactComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /** +__d('ReactNativeMount',["NativeModules","ReactNativeTagHandles","ReactPerf","ReactReconciler","ReactUpdateQueue","ReactUpdates","emptyObject","instantiateReactComponent","shouldUpdateReactComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * @@ -15874,7 +15905,6 @@ var ReactUpdates = require('ReactUpdates'); var emptyObject = require('emptyObject'); var instantiateReactComponent = require('instantiateReactComponent'); -var invariant = require('invariant'); var shouldUpdateReactComponent = require('shouldUpdateReactComponent'); function instanceNumberToChildRootID(rootNodeID, instanceNumber) { @@ -18185,7 +18215,7 @@ var UniversalWorkerNodeHandle = { module.exports = UniversalWorkerNodeHandle; }); -__d('createReactNativeComponentClass',["ReactElement","ReactNativeBaseComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /** +__d('createReactNativeComponentClass',["ReactNativeBaseComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * @@ -18197,9 +18227,8 @@ __d('createReactNativeComponentClass',["ReactElement","ReactNativeBaseComponent" * @flow */ -"use strict"; +'use strict'; -var ReactElement = require('ReactElement'); var ReactNativeBaseComponent = require('ReactNativeBaseComponent'); // See also ReactNativeBaseComponent @@ -18295,7 +18324,8 @@ var cachedIndexArray = function(size) { for (var i = 0; i < size; i++) { arr[i] = i; } - return cachedIndexArray._cache[size] = arr; + cachedIndexArray._cache[size] = arr; + return arr; } else { return cachedResult; } @@ -18460,7 +18490,7 @@ ReactNativeBaseComponent.Mixin = { */ _reconcileListenersUponUpdate: function(prevProps, nextProps) { for (var key in nextProps) { - if (registrationNames[key] && (nextProps[key] != prevProps[key])) { + if (registrationNames[key] && (nextProps[key] !== prevProps[key])) { putListener(this._rootNodeID, key, nextProps[key]); } } @@ -19210,6 +19240,7 @@ __d('MatrixMath',["invariant"],function(global, require, requireDynamic, require * * @providesModule MatrixMath */ +/* eslint-disable space-infix-ops */ 'use strict'; var invariant = require('invariant'); @@ -19814,8 +19845,7 @@ __d('ReactNativeEventEmitter',["EventPluginHub","ReactEventEmitterMixin","ReactN * @providesModule ReactNativeEventEmitter * @flow */ - -"use strict"; +'use strict'; var EventPluginHub = require('EventPluginHub'); var ReactEventEmitterMixin = require('ReactEventEmitterMixin'); @@ -21713,7 +21743,6 @@ __d('RCTLog',["invariant"],function(global, require, requireDynamic, requireLazy * @providesModule RCTLog * @flow */ - /* globals nativeLoggingHook */ 'use strict'; var invariant = require('invariant'); @@ -21856,7 +21885,7 @@ function onlyChild(children) { module.exports = onlyChild; }); -__d('ActivityIndicatorIOS',["NativeMethodsMixin","NativeModules","ReactPropTypes","React","StyleSheet","View","requireNativeComponent","verifyPropTypes"],function(global, require, requireDynamic, requireLazy, module, exports) { /** +__d('ActivityIndicatorIOS',["NativeMethodsMixin","ReactPropTypes","React","StyleSheet","View","requireNativeComponent","verifyPropTypes"],function(global, require, requireDynamic, requireLazy, module, exports) { /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * @@ -21870,7 +21899,6 @@ __d('ActivityIndicatorIOS',["NativeMethodsMixin","NativeModules","ReactPropTypes 'use strict'; var NativeMethodsMixin = require('NativeMethodsMixin'); -var NativeModules = require('NativeModules'); var PropTypes = require('ReactPropTypes'); var React = require('React'); var StyleSheet = require('StyleSheet'); @@ -21911,6 +21939,12 @@ var ActivityIndicatorIOS = React.createClass({displayName: "ActivityIndicatorIOS 'small', 'large', ]), + /** + * Invoked on mount and layout changes with + * + * {nativeEvent: { layout: {x, y, width, height}}}. + */ + onLayout: PropTypes.func, }, getDefaultProps: function() { @@ -21923,10 +21957,12 @@ var ActivityIndicatorIOS = React.createClass({displayName: "ActivityIndicatorIOS }, render: function() { - var $__0= this.props,style=$__0.style,props=(function(source, exclusion) {var rest = {};var hasOwn = Object.prototype.hasOwnProperty;if (source == null) {throw new TypeError();}for (var key in source) {if (hasOwn.call(source, key) && !hasOwn.call(exclusion, key)) {rest[key] = source[key];}}return rest;})($__0,{style:1}); + var $__0= this.props,onLayout=$__0.onLayout,style=$__0.style,props=(function(source, exclusion) {var rest = {};var hasOwn = Object.prototype.hasOwnProperty;if (source == null) {throw new TypeError();}for (var key in source) {if (hasOwn.call(source, key) && !hasOwn.call(exclusion, key)) {rest[key] = source[key];}}return rest;})($__0,{onLayout:1,style:1}); var sizeStyle = (this.props.size === 'large') ? styles.sizeLarge : styles.sizeSmall; return ( - React.createElement(View, {style: [styles.container, sizeStyle, style]}, + React.createElement(View, { + onLayout: onLayout, + style: [styles.container, sizeStyle, style]}, React.createElement(RCTActivityIndicatorView, React.__spread({}, props)) ) ); @@ -22139,6 +22175,26 @@ var createReactNativeComponentClass = require('createReactNativeComponentClass') var stylePropType = StyleSheetPropType(ViewStylePropTypes); +var AccessibilityTraits = [ + 'none', + 'button', + 'link', + 'header', + 'search', + 'image', + 'selected', + 'plays', + 'key', + 'text', + 'summary', + 'disabled', + 'frequentUpdates', + 'startsMedia', + 'adjustable', + 'allowsDirectInteraction', + 'pageTurn', +]; + /** * The most fundamental component for building UI, `View` is a * container that supports layout with flexbox, style, some touch handling, and @@ -22185,6 +22241,27 @@ var View = React.createClass({displayName: "View", */ accessibilityLabel: PropTypes.string, + /** + * Provides additional traits to screen reader. By default no traits are + * provided unless specified otherwise in element + */ + accessibilityTraits: PropTypes.oneOfType([ + PropTypes.oneOf(AccessibilityTraits), + PropTypes.arrayOf(PropTypes.oneOf(AccessibilityTraits)), + ]), + + /** + * When `accessible` is true, the system will try to invoke this function + * when the user performs accessibility tap gesture. + */ + onAcccessibilityTap: PropTypes.func, + + /** + * When `accessible` is true, the system will invoke this function when the + * user performs the magic tap gesture. + */ + onMagicTap: PropTypes.func, + /** * Used to locate this view in end-to-end tests. */ @@ -22206,7 +22283,9 @@ var View = React.createClass({displayName: "View", onStartShouldSetResponderCapture: PropTypes.func, /** - * Invoked on mount and layout changes with {x, y, width, height}. + * Invoked on mount and layout changes with + * + * {nativeEvent: { layout: {x, y, width, height}}}. */ onLayout: PropTypes.func, @@ -22323,8 +22402,11 @@ ReactNativeViewAttributes.UIView = { pointerEvents: true, accessible: true, accessibilityLabel: true, + accessibilityTraits: true, testID: true, onLayout: true, + onAccessibilityTap: true, + onMagicTap: true, }; ReactNativeViewAttributes.RCTView = merge( @@ -22665,6 +22747,13 @@ function verifyPropTypes( if (!viewConfig) { return; // This happens for UnimplementedView. } + var componentName = component.name || component.displayName; + if (!component.propTypes) { + throw new Error( + '`' + componentName + '` has no propTypes defined`' + ); + } + var nativeProps = viewConfig.nativeProps; for (var prop in nativeProps) { if (!component.propTypes[prop] && @@ -22672,9 +22761,9 @@ function verifyPropTypes( !ReactNativeStyleAttributes[prop] && (!nativePropsToIgnore || !nativePropsToIgnore[prop])) { throw new Error( - '`' + component.displayName + '` has no propType for native prop `' + + '`' + componentName + '` has no propType for native prop `' + viewConfig.uiViewClassName + '.' + prop + '` of native type `' + - nativeProps[prop].type + '`' + nativeProps[prop] + '`' ); } } @@ -22895,7 +22984,7 @@ var Image = React.createClass({displayName: "Image", /** * `uri` is a string representing the resource identifier for the image, which * could be an http address, a local file path, or the name of a static image - * resource (which should be wrapped in the `required('image!name')` function). + * resource (which should be wrapped in the `require('image!name')` function). */ source: PropTypes.shape({ uri: PropTypes.string, @@ -22934,6 +23023,12 @@ var Image = React.createClass({displayName: "Image", * testing scripts. */ testID: PropTypes.string, + /** + * Invoked on mount and layout changes with + * + * {nativeEvent: { layout: {x, y, width, height}}}. + */ + onLayout: PropTypes.func, }, statics: { @@ -23025,7 +23120,7 @@ if (__DEV__) { module.exports = Image; }); -__d('EdgeInsetsPropType',["ReactPropTypes","createStrictShapeTypeChecker","insetsDiffer"],function(global, require, requireDynamic, requireLazy, module, exports) { /** +__d('EdgeInsetsPropType',["ReactPropTypes","createStrictShapeTypeChecker"],function(global, require, requireDynamic, requireLazy, module, exports) { /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * @@ -23036,12 +23131,11 @@ __d('EdgeInsetsPropType',["ReactPropTypes","createStrictShapeTypeChecker","inset * @providesModule EdgeInsetsPropType * @flow */ -'use strict' +'use strict'; var PropTypes = require('ReactPropTypes'); var createStrictShapeTypeChecker = require('createStrictShapeTypeChecker'); -var insetsDiffer = require('insetsDiffer'); var EdgeInsetsPropType = createStrictShapeTypeChecker({ top: PropTypes.number, @@ -24683,7 +24777,7 @@ if (Platform.OS === 'android') { module.exports = ScrollView; }); -__d('PointPropType',["ReactPropTypes","createStrictShapeTypeChecker","pointsDiffer"],function(global, require, requireDynamic, requireLazy, module, exports) { /** +__d('PointPropType',["ReactPropTypes","createStrictShapeTypeChecker"],function(global, require, requireDynamic, requireLazy, module, exports) { /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * @@ -24694,12 +24788,11 @@ __d('PointPropType',["ReactPropTypes","createStrictShapeTypeChecker","pointsDiff * @providesModule PointPropType * @flow */ -'use strict' +'use strict'; var PropTypes = require('ReactPropTypes'); var createStrictShapeTypeChecker = require('createStrictShapeTypeChecker'); -var pointsDiffer = require('pointsDiffer'); var PointPropType = createStrictShapeTypeChecker({ x: PropTypes.number, @@ -24893,7 +24986,7 @@ var ScrollResponderMixin = { var currentlyFocusedTextInput = TextInputState.currentlyFocusedField(); if (!this.props.keyboardShouldPersistTaps && currentlyFocusedTextInput != null && - e.target != currentlyFocusedTextInput) { + e.target !== currentlyFocusedTextInput) { return true; } return this.scrollResponderIsAnimating(); @@ -24954,7 +25047,7 @@ var ScrollResponderMixin = { var currentlyFocusedTextInput = TextInputState.currentlyFocusedField(); if (!this.props.keyboardShouldPersistTaps && currentlyFocusedTextInput != null && - e.target != currentlyFocusedTextInput && + e.target !== currentlyFocusedTextInput && !this.state.observedScrollSinceBecomingResponder && !this.state.becameResponderWhileAnimating) { this.props.onScrollResponderKeyboardDismissed && @@ -25210,7 +25303,7 @@ __d('Subscribable',["EventEmitter"],function(global, require, requireDynamic, re */ 'use strict'; -var EventEmitter = require('EventEmitter'); + /** * Subscribable provides a mixin for safely subscribing a component to an @@ -26411,7 +26504,7 @@ var RCTPickerIOS = createReactNativeComponentClass({ module.exports = PickerIOS; }); -__d('Navigator',["NativeModules","BackAndroid","Dimensions","InteractionMixin","NavigatorBreadcrumbNavigationBar","NavigatorInterceptor","NavigatorNavigationBar","NavigatorSceneConfigs","NavigatorStaticContextContainer","PanResponder","Platform","React","StaticContainer.react","StyleSheet","Subscribable","react-timer-mixin/TimerMixin","View","clamp","flattenStyle","getNavigatorContext","invariant","keyMirror","merge","rebound/rebound"],function(global, require, requireDynamic, requireLazy, module, exports) { /** +__d('Navigator',["NativeModules","BackAndroid","Dimensions","InteractionMixin","NavigatorBreadcrumbNavigationBar","NavigatorInterceptor","NavigatorNavigationBar","NavigatorSceneConfigs","NavigatorStaticContextContainer","PanResponder","Platform","React","StaticContainer.react","StyleSheet","Subscribable","react-timer-mixin/TimerMixin","View","clamp","flattenStyle","getNavigatorContext","invariant","rebound/rebound"],function(global, require, requireDynamic, requireLazy, module, exports) { /** * Copyright (c) 2015, Facebook, Inc. All rights reserved. * * Facebook, Inc. (“Facebook”) owns all right, title and interest, including @@ -26437,6 +26530,7 @@ __d('Navigator',["NativeModules","BackAndroid","Dimensions","InteractionMixin"," * * @providesModule Navigator */ + /* eslint-disable no-extra-boolean-cast*/ 'use strict'; var AnimationsDebugModule = require('NativeModules').AnimationsDebugModule; @@ -26461,8 +26555,6 @@ var clamp = require('clamp'); var flattenStyle = require('flattenStyle'); var getNavigatorContext = require('getNavigatorContext'); var invariant = require('invariant'); -var keyMirror = require('keyMirror'); -var merge = require('merge'); var rebound = require('rebound/rebound'); var PropTypes = React.PropTypes; @@ -27102,7 +27194,7 @@ var Navigator = React.createClass({displayName: "Navigator", */ _enableScene: function(sceneIndex) { // First, determine what the defined styles are for scenes in this navigator - var sceneStyle = flattenStyle(this.props.sceneStyle); + var sceneStyle = flattenStyle([styles.baseScene, this.props.sceneStyle]); // Then restore the left value for this scene var enabledSceneNativeProps = { left: sceneStyle.left, @@ -27158,7 +27250,6 @@ var Navigator = React.createClass({displayName: "Navigator", }, _handleMoveShouldSetPanResponder: function(e, gestureState) { - var currentRoute = this.state.routeStack[this.state.presentedIndex]; var sceneConfig = this.state.sceneConfigStack[this.state.presentedIndex]; this._expectingGestureGrant = this._matchGestureAction(this._eligibleGestures, sceneConfig.gestures, gestureState); return !! this._expectingGestureGrant; @@ -27242,7 +27333,16 @@ var Navigator = React.createClass({displayName: "Navigator", } } else { // The gesture has enough velocity to complete, so we transition to the gesture's destination - this._transitionTo(destIndex, transitionVelocity); + this._transitionTo( + destIndex, + transitionVelocity, + null, + function() { + if (releaseGestureAction === 'pop') { + this._cleanScenesPastIndex(destIndex); + } + }.bind(this) + ); } this._detachGesture(); }, @@ -27704,6 +27804,14 @@ var Navigator = React.createClass({displayName: "Navigator", if (i !== this.state.presentedIndex) { disabledSceneStyle = styles.disabledScene; } + var originalRef = child.ref; + if (originalRef != null && typeof originalRef !== 'function') { + console.warn( + 'String refs are not supported for navigator scenes. Use a callback ' + + 'ref instead. Ignoring ref: ' + originalRef + ); + originalRef = null; + } return ( React.createElement(View, { key: this.state.idStack[i], @@ -27713,7 +27821,12 @@ var Navigator = React.createClass({displayName: "Navigator", }.bind(this), style: [styles.baseScene, this.props.sceneStyle, disabledSceneStyle]}, React.cloneElement(child, { - ref: this._handleItemRef.bind(null, this.state.idStack[i], route), + ref: function(component) { + this._handleItemRef(this.state.idStack[i], route, component); + if (originalRef) { + originalRef(component); + } + }.bind(this) }) ) ); @@ -28532,6 +28645,7 @@ __d('buildStyleInterpolator',["keyOf"],function(global, require, requireDynamic, /** * Cannot "use strict" because we must use eval in this file. */ +/* eslint-disable global-strict */ var keyOf = require('keyOf'); @@ -28897,7 +29011,7 @@ var MatrixOpsInitial = { var setNextValAndDetectChange = function(name, tmpVarName) { return ( ' if (!didChange) {\n' + - ' var prevVal = result.' + name +';\n' + + ' var prevVal = result.' + name + ';\n' + ' result.' + name + ' = ' + tmpVarName + ';\n' + ' didChange = didChange || (' + tmpVarName + ' !== prevVal);\n' + ' } else {\n' + @@ -29635,7 +29749,7 @@ var FromTheLeft = Object.assign({}, translateX: { from: -SCREEN_WIDTH, to: 0, - min: 0, + min: 0, max: 1, type: 'linear', extrapolate: true, @@ -32245,6 +32359,12 @@ var Text = React.createClass({displayName: "Text", * Used to locate this view in end-to-end tests. */ testID: React.PropTypes.string, + /** + * Invoked on mount and layout changes with + * + * {nativeEvent: { layout: {x, y, width, height}}}. + */ + onLayout: React.PropTypes.func, }, viewConfig: viewConfig, @@ -33184,7 +33304,6 @@ var queryLayoutByID = function( }; module.exports = queryLayoutByID; - }); __d('TextInput',["DocumentSelectionState","EventEmitter","NativeMethodsMixin","NativeModules","Platform","ReactPropTypes","React","ReactChildren","ReactNativeViewAttributes","StyleSheet","Text","TextInputState","react-timer-mixin/TimerMixin","TouchableWithoutFeedback","createReactNativeComponentClass","emptyFunction","invariant","merge"],function(global, require, requireDynamic, requireLazy, module, exports) { /** * Copyright (c) 2015-present, Facebook, Inc. @@ -33367,12 +33486,12 @@ var TextInput = React.createClass({displayName: "TextInput", 'number-pad', 'phone-pad', 'name-phone-pad', - 'email-address', 'decimal-pad', 'twitter', 'web-search', // Cross-platform 'numeric', + 'email-address', ]), /** * Determines how the return key should look. @@ -35764,7 +35883,7 @@ function getObjectValues(obj) { module.exports = getObjectValues; }); -__d('WebView',["ActivityIndicatorIOS","EdgeInsetsPropType","React","ReactNativeViewAttributes","StyleSheet","Text","View","invariant","keyMirror","requireNativeComponent","NativeModules"],function(global, require, requireDynamic, requireLazy, module, exports) { /** +__d('WebView',["ActivityIndicatorIOS","EdgeInsetsPropType","React","StyleSheet","Text","View","invariant","keyMirror","requireNativeComponent","NativeModules"],function(global, require, requireDynamic, requireLazy, module, exports) { /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * @@ -35780,7 +35899,6 @@ __d('WebView',["ActivityIndicatorIOS","EdgeInsetsPropType","React","ReactNativeV var ActivityIndicatorIOS = require('ActivityIndicatorIOS'); var EdgeInsetsPropType = require('EdgeInsetsPropType'); var React = require('React'); -var ReactNativeViewAttributes = require('ReactNativeViewAttributes'); var StyleSheet = require('StyleSheet'); var Text = require('Text'); var View = require('View'); @@ -35964,7 +36082,7 @@ var WebView = React.createClass({displayName: "WebView", onLoadingError: function(event ) { event.persist(); // persist this event because we need to store it - console.error("encountered an error loading page", event.nativeEvent); + console.error('Encountered an error loading page', event.nativeEvent); this.setState({ lastErrorEvent: event.nativeEvent, @@ -36942,7 +37060,7 @@ function convertError(error) { module.exports = AsyncStorage; }); -__d('RCTRenderingPerf',["ReactDefaultPerf","ReactPerf","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** +__d('RCTRenderingPerf',["ReactDefaultPerf","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * @@ -36956,7 +37074,6 @@ __d('RCTRenderingPerf',["ReactDefaultPerf","ReactPerf","invariant"],function(glo 'use strict'; var ReactDefaultPerf = require('ReactDefaultPerf'); -var ReactPerf = require('ReactPerf'); var invariant = require('invariant'); @@ -40114,7 +40231,7 @@ if (RCTReachability) { module.exports = NetInfo; }); -__d('PushNotificationIOS',["NativeModules","RCTDeviceEventEmitter","NativeModules","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** +__d('PushNotificationIOS',["RCTDeviceEventEmitter","NativeModules","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** * Copyright (c) 2015-present, Facebook, Inc. * All rights reserved. * @@ -40127,7 +40244,6 @@ __d('PushNotificationIOS',["NativeModules","RCTDeviceEventEmitter","NativeModule */ 'use strict'; -var NativeModules = require('NativeModules'); var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); var RCTPushNotificationManager = require('NativeModules').PushNotificationManager; var invariant = require('invariant'); @@ -40383,6 +40499,25 @@ var VibrationIOS = { module.exports = VibrationIOS; }); +__d('RCTNativeAppEventEmitter',["EventEmitter"],function(global, require, requireDynamic, requireLazy, module, exports) { /** + * 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 RCTNativeAppEventEmitter + * @flow + */ +'use strict'; + +var EventEmitter = require('EventEmitter'); + +var RCTNativeAppEventEmitter = new EventEmitter(); + +module.exports = RCTNativeAppEventEmitter; +}); __d('LinkedStateMixin',["ReactLink","ReactStateSetters"],function(global, require, requireDynamic, requireLazy, module, exports) { /** * Copyright 2013-2015, Facebook, Inc. * All rights reserved. diff --git a/Examples/HybridMobileDeployCompanion/index.ios.js b/Examples/HybridMobileDeployCompanion/index.ios.js index 4e993bf5b..b34cc0a5a 100644 --- a/Examples/HybridMobileDeployCompanion/index.ios.js +++ b/Examples/HybridMobileDeployCompanion/index.ios.js @@ -12,6 +12,8 @@ var { View, } = React; +var HybridMobileDeploy = require('react-native-hybrid-mobile-deploy')('http://localhost:3000/', 'HybridMobileDeployCompanion'); + var HybridMobileDeployCompanion = React.createClass({ render: function() { return ( diff --git a/Examples/HybridMobileDeployCompanion/package.json b/Examples/HybridMobileDeployCompanion/package.json index be56a244f..af59b6343 100644 --- a/Examples/HybridMobileDeployCompanion/package.json +++ b/Examples/HybridMobileDeployCompanion/package.json @@ -6,6 +6,7 @@ "start": "node_modules/react-native/packager/packager.sh" }, "dependencies": { - "react-native": "^0.4.4" + "react-native": "^0.4.4", + "react-native-hybrid-mobile-deploy": "file:../.." } } diff --git a/HybridMobileDeploy.android.js b/HybridMobileDeploy.android.js index ccc6d7bfd..5536c5747 100644 --- a/HybridMobileDeploy.android.js +++ b/HybridMobileDeploy.android.js @@ -1,7 +1,7 @@ /** - * Stub of HybridMobileDeploy for Android. + * Stub of UpdateManager for Android. * - * @providesModule HybridMobileDeploy + * @providesModule UpdateManager * @flow */ 'use strict'; diff --git a/HybridMobileDeploy.ios.js b/HybridMobileDeploy.ios.js index 932794a3e..6ffe08cce 100644 --- a/HybridMobileDeploy.ios.js +++ b/HybridMobileDeploy.ios.js @@ -2,19 +2,65 @@ * @providesModule HybridMobileDeploy * @flow */ + 'use strict'; var NativeHybridMobileDeploy = require('NativeModules').HybridMobileDeploy; -var invariant = require('invariant'); - -/** - * High-level docs for the HybridMobileDeploy iOS API can be written here. - */ +var semver = require('semver'); +var serverUrl; +var appName; var HybridMobileDeploy = { - test: function() { - NativeHybridMobileDeploy.test(); + checkForUpdate: function(version, callback) { + var url = serverUrl + 'latest/' + appName; + fetch(url) + .then(response => response.json()) + .done(latest => { + if (semver.gt(latest.version, version)) { + callback(undefined, latest); + } else { + callback(undefined, false); + } + }, err => { + callback(err); + }); + }, + pollForUpdate: function(version, intervalDelay, callback) { + var interval; + var checkUpdate = () => { + this.checkForUpdate(version, (err, update) => { + if (err) { + callback(err); + } else if (update) { + interval && clearInterval(interval); + callback(undefined, update); + } + }); + }; + interval = setInterval(checkUpdate, intervalDelay); + checkUpdate(); + }, + getAvailableUpdates: function(callback) { + var url = serverUrl + 'updates/' + appName; + console.log(url); + fetch(url) + .then((response) => { + console.log(response); + return response.json() + }) + .then((value) => { + console.log(value); + return value; + }) + .then(callback); + }, + installUpdate: function(update) { + NativeHybridMobileDeploy.installUpdateFromUrl(update.updateUrl, update.bundleName, (err) => console.log(err), () => console.log("success")); } }; -module.exports = HybridMobileDeploy; +module.exports = function(server, app) { + serverUrl = server; + appName = app; + return HybridMobileDeploy; +}; diff --git a/package.json b/package.json index 8cea13f03..39732233d 100644 --- a/package.json +++ b/package.json @@ -1,8 +1,10 @@ { - "name": "HybridMobileDeploy", + "name": "react-native-hybrid-mobile-deploy", "version": "0.0.1", + "main": "HybridMobileDeploy.ios.js", "keywords": "react-native", "dependencies": { - "react-native": "^0.5.0" + "react-native": "^0.5.0", + "semver": "^4.3.6" } } From 495eec170b4d8abf1a786d203da8766d9425e21d Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Thu, 16 Jul 2015 15:25:03 -0700 Subject: [PATCH 05/16] Update react-native to 0.8.0-rc --- Examples/HybridMobileDeployCompanion/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/HybridMobileDeployCompanion/package.json b/Examples/HybridMobileDeployCompanion/package.json index af59b6343..fb3edc0cb 100644 --- a/Examples/HybridMobileDeployCompanion/package.json +++ b/Examples/HybridMobileDeployCompanion/package.json @@ -6,7 +6,7 @@ "start": "node_modules/react-native/packager/packager.sh" }, "dependencies": { - "react-native": "^0.4.4", + "react-native": "^0.8.0-rc", "react-native-hybrid-mobile-deploy": "file:../.." } } From 3a685460f70d4f25bae4ad46575e8d2fd357e92b Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Thu, 16 Jul 2015 15:26:35 -0700 Subject: [PATCH 06/16] Remove generated main.jsbundle and ignore it --- .../HybridMobileDeployCompanion/.gitignore | 2 + .../iOS/main.jsbundle | 41508 ---------------- 2 files changed, 2 insertions(+), 41508 deletions(-) delete mode 100644 Examples/HybridMobileDeployCompanion/iOS/main.jsbundle diff --git a/Examples/HybridMobileDeployCompanion/.gitignore b/Examples/HybridMobileDeployCompanion/.gitignore index c39012e9e..231273bb1 100644 --- a/Examples/HybridMobileDeployCompanion/.gitignore +++ b/Examples/HybridMobileDeployCompanion/.gitignore @@ -25,3 +25,5 @@ DerivedData # node_modules/ npm-debug.log + +main.jsbundle diff --git a/Examples/HybridMobileDeployCompanion/iOS/main.jsbundle b/Examples/HybridMobileDeployCompanion/iOS/main.jsbundle deleted file mode 100644 index 09db1d6b2..000000000 --- a/Examples/HybridMobileDeployCompanion/iOS/main.jsbundle +++ /dev/null @@ -1,41508 +0,0 @@ -/* eslint global-strict:0 */ -__DEV__ = false; - -/* eslint global-strict:0,eqeqeq:0,no-bitwise:0,no-undef:0 */ -(function(global) { - - // avoid redefining require() - if (global.require) { - return; - } - - var __DEV__ = global.__DEV__; - - var toString = Object.prototype.toString; - - /** - * module index: { - * mod1: { - * exports: { ... }, - * id: 'mod1', - * dependencies: ['mod1', 'mod2'], - * factory: function() { ... }, - * waitingMap: { mod1: 1, mod3: 1, mod4: 1 }, - * waiting: 2 - * } - * } - */ - var modulesMap = {}, - /** - * inverse index: { - * mod1: [modules, waiting for mod1], - * mod2: [modules, waiting for mod2] - * } - */ - dependencyMap = {}, - /** - * modules whose reference counts are set out of order - */ - predefinedRefCounts = {}, - - _counter = 0, - - REQUIRE_WHEN_READY = 1, - USED_AS_TRANSPORT = 2, - - hop = Object.prototype.hasOwnProperty; - - function _debugUnresolvedDependencies(names) { - var unresolved = Array.prototype.slice.call(names); - var visited = {}; - var ii, name, module, dependency; - - while (unresolved.length) { - name = unresolved.shift(); - if (visited[name]) { - continue; - } - visited[name] = true; - - module = modulesMap[name]; - if (!module || !module.waiting) { - continue; - } - - for (ii = 0; ii < module.dependencies.length; ii++) { - dependency = module.dependencies[ii]; - if (!modulesMap[dependency] || modulesMap[dependency].waiting) { - unresolved.push(dependency); - } - } - } - - for (name in visited) if (hop.call(visited, name)) { - unresolved.push(name); - } - - var messages = []; - for (ii = 0; ii < unresolved.length; ii++) { - name = unresolved[ii]; - var message = name; - module = modulesMap[name]; - if (!module) { - message += ' is not defined'; - } else if (!module.waiting) { - message += ' is ready'; - } else { - var unresolvedDependencies = []; - for (var jj = 0; jj < module.dependencies.length; jj++) { - dependency = module.dependencies[jj]; - if (!modulesMap[dependency] || modulesMap[dependency].waiting) { - unresolvedDependencies.push(dependency); - } - } - message += ' is waiting for ' + unresolvedDependencies.join(', '); - } - messages.push(message); - } - return messages.join('\n'); - } - - /** - * This is mainly for logging in ModuleErrorLogger. - */ - function ModuleError(msg) { - this.name = 'ModuleError'; - this.message = msg; - this.stack = Error(msg).stack; - this.framesToPop = 2; - } - ModuleError.prototype = Object.create(Error.prototype); - ModuleError.prototype.constructor = ModuleError; - - var _performance = - global.performance || - global.msPerformance || - global.webkitPerformance || {}; - - if (!_performance.now) { - _performance = global.Date; - } - - var _now = _performance ? - _performance.now.bind(_performance) : function(){return 0;}; - - var _factoryStackCount = 0; - var _factoryTime = 0; - var _totalFactories = 0; - - /** - * The require function conforming to CommonJS spec: - * http://wiki.commonjs.org/wiki/Modules/1.1.1 - * - * To define a CommonJS-compliant module add the providesModule - * Haste header to your file instead of @provides. Your file is going - * to be executed in a separate context. Every variable/function you - * define will be local (private) to that module. To export local members - * use "exports" variable or return the exported value at the end of your - * file. Your code will have access to the "module" object. - * The "module" object will have an "id" property that is the id of your - * current module. "module" object will also have "exports" property that - * is the same as "exports" variable passed into your module context. - * You can require other modules using their ids. - * - * Haste will automatically pick dependencies from require() calls. So - * you don't have to manually specify @requires in your header. - * - * You cannot require() modules from non-CommonJS files. Write a legacy stub - * (@providesLegacy) and use @requires instead. - * - * @example - * - * / ** - * * @providesModule math - * * / - * exports.add = function() { - * var sum = 0, i = 0, args = arguments, l = args.length; - * while (i < l) { - * sum += args[i++]; - * } - * return sum; - * }; - * - * / ** - * * @providesModule increment - * * / - * var add = require('math').add; - * return function(val) { - * return add(val, 1); - * }; - * - * / ** - * * @providesModule program - * * / - * var inc = require('increment'); - * var a = 1; - * inc(a); // 2 - * - * module.id == "program"; - * - * - * @param {String} id - * @throws when module is not loaded or not ready to be required - */ - function require(id) { - var module = modulesMap[id], dep, i, msg; - if (module && module.exports) { - // If ref count is 1, this was the last call, so undefine the module. - // The ref count can be null or undefined, but those are never === 1. - if (module.refcount-- === 1) { - delete modulesMap[id]; - } - return module.exports; - } - - if (global.ErrorUtils && !global.ErrorUtils.inGuard()) { - return ErrorUtils.applyWithGuard(require, this, arguments); - } - - if (!module) { - msg = 'Requiring unknown module "' + id + '"'; - if (__DEV__) { - msg += '. If you are sure the module is there, try restarting the packager.'; - } - throw new ModuleError(msg); - } - - if (module.hasError) { - throw new ModuleError( - 'Requiring module "' + id + '" which threw an exception' - ); - } - - if (module.waiting) { - throw new ModuleError( - 'Requiring module "' + id + '" with unresolved dependencies: ' + - _debugUnresolvedDependencies([id]) - ); - } - - var exports = module.exports = {}; - var factory = module.factory; - if (toString.call(factory) === '[object Function]') { - var args = [], - dependencies = module.dependencies, - length = dependencies.length, - ret; - if (module.special & USED_AS_TRANSPORT) { - length = Math.min(length, factory.length); - } - try { - for (i = 0; args.length < length; i++) { - dep = dependencies[i]; - if (!module.inlineRequires[dep]) { - args.push(dep === 'module' ? module : - (dep === 'exports' ? exports : - require.call(null, dep))); - } - } - - ++_totalFactories; - if (_factoryStackCount++ === 0) { - _factoryTime -= _now(); - } - try { - ret = factory.apply(module.context || global, args); - } catch (e) { - if (modulesMap.ex && modulesMap.erx) { - // when ErrorUtils is ready, ex and erx are ready. otherwise, we - // don't append module id to the error message but still throw it - var ex = require.call(null, 'ex'); - var erx = require.call(null, 'erx'); - var messageWithParams = erx(e.message); - if (messageWithParams[0].indexOf(' from module "%s"') < 0) { - messageWithParams[0] += ' from module "%s"'; - messageWithParams[messageWithParams.length] = id; - } - e.message = ex.apply(null, messageWithParams); - } - throw e; - } finally { - if (--_factoryStackCount === 0) { - _factoryTime += _now(); - } - } - } catch (e) { - module.hasError = true; - module.exports = null; - throw e; - } - if (ret) { - if (__DEV__) { - if (typeof ret != 'object' && typeof ret != 'function') { - throw new ModuleError( - 'Factory for module "' + id + '" returned ' + - 'an invalid value "' + ret + '". ' + - 'Returned value should be either a function or an object.' - ); - } - } - module.exports = ret; - } - } else { - module.exports = factory; - } - - // If ref count is 1, this was the last call, so undefine the module. - // The ref count can be null or undefined, but those are never === 1. - if (module.refcount-- === 1) { - delete modulesMap[id]; - } - return module.exports; - } - - require.__getFactoryTime = function() { - return (_factoryStackCount ? _now() : 0) + _factoryTime; - }; - - require.__getTotalFactories = function() { - return _totalFactories; - }; - - /** - * The define function conforming to CommonJS proposal: - * http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition - * - * define() allows you to explicitly state dependencies of your module - * in javascript. It's most useful in non-CommonJS files. - * - * define() is used internally by haste as a transport for CommonJS - * modules. So there's no need to use define() if you use providesModule - * - * @example - * / ** - * * @provides alpha - * * / - * - * // Sets up the module with ID of "alpha", that uses require, - * // exports and the module with ID of "beta": - * define("alpha", ["require", "exports", "beta"], - * function (require, exports, beta) { - * exports.verb = function() { - * return beta.verb(); - * //Or: - * return require("beta").verb(); - * } - * }); - * - * / ** - * * @provides alpha - * * / - * // An anonymous module could be defined (module id derived from filename) - * // that returns an object literal: - * - * define(["alpha"], function (alpha) { - * return { - * verb: function(){ - * return alpha.verb() + 2; - * } - * }; - * }); - * - * / ** - * * @provides alpha - * * / - * // A dependency-free module can define a direct object literal: - * - * define({ - * add: function(x, y){ - * return x + y; - * } - * }); - * - * @param {String} id optional - * @param {Array} dependencies optional - * @param {Object|Function} factory - */ - function define(id, dependencies, factory, - _special, _context, _refCount, _inlineRequires) { - if (dependencies === undefined) { - dependencies = []; - factory = id; - id = _uid(); - } else if (factory === undefined) { - factory = dependencies; - if (toString.call(id) === '[object Array]') { - dependencies = id; - id = _uid(); - } else { - dependencies = []; - } - } - - // Non-standard: we allow modules to be undefined. This is designed for - // temporary modules. - var canceler = { cancel: _undefine.bind(this, id) }; - - var record = modulesMap[id]; - - // Nonstandard hack: we call define with null deps and factory, but a - // non-null reference count (e.g. define('name', null, null, 0, null, 4)) - // when this module is defined elsewhere and we just need to update the - // reference count. We use this hack to avoid having to expose another - // global function to increment ref counts. - if (record) { - if (_refCount) { - record.refcount += _refCount; - } - // Calling define() on a pre-existing module does not redefine it - return canceler; - } else if (!dependencies && !factory && _refCount) { - // If this module hasn't been defined yet, store the ref count. We'll use - // it when the module is defined later. - predefinedRefCounts[id] = (predefinedRefCounts[id] || 0) + _refCount; - return canceler; - } else { - // Defining a new module - record = { id: id }; - record.refcount = (predefinedRefCounts[id] || 0) + (_refCount || 0); - delete predefinedRefCounts[id]; - } - - if (__DEV__) { - if ( - !factory || - (typeof factory != 'object' && typeof factory != 'function' && - typeof factory != 'string')) { - throw new ModuleError( - 'Invalid factory "' + factory + '" for module "' + id + '". ' + - 'Factory should be either a function or an object.' - ); - } - - if (toString.call(dependencies) !== '[object Array]') { - throw new ModuleError( - 'Invalid dependencies for module "' + id + '". ' + - 'Dependencies must be passed as an array.' - ); - } - } - - record.factory = factory; - record.dependencies = dependencies; - record.context = _context; - record.special = _special; - record.inlineRequires = _inlineRequires || {}; - record.waitingMap = {}; - record.waiting = 0; - record.hasError = false; - modulesMap[id] = record; - _initDependencies(id); - - return canceler; - } - - function _undefine(id) { - if (!modulesMap[id]) { - return; - } - - var module = modulesMap[id]; - delete modulesMap[id]; - - for (var dep in module.waitingMap) { - if (module.waitingMap[dep]) { - delete dependencyMap[dep][id]; - } - } - - for (var ii = 0; ii < module.dependencies.length; ii++) { - dep = module.dependencies[ii]; - if (modulesMap[dep]) { - if (modulesMap[dep].refcount-- === 1) { - _undefine(dep); - } - } else if (predefinedRefCounts[dep]) { - predefinedRefCounts[dep]--; - } - // Subtle: we won't account for this one fewer reference if we don't have - // the dependency's definition or reference count yet. - } - } - - /** - * Special version of define that executes the factory as soon as all - * dependencies are met. - * - * define() does just that, defines a module. Module's factory will not be - * called until required by other module. This makes sense for most of our - * library modules: we do not want to execute the factory unless it's being - * used by someone. - * - * On the other hand there are modules, that you can call "entrance points". - * You want to run the "factory" method for them as soon as all dependencies - * are met. - * - * @example - * - * define('BaseClass', [], function() { return ... }); - * // ^^ factory for BaseClass was just stored in modulesMap - * - * define('SubClass', ['BaseClass'], function() { ... }); - * // SubClass module is marked as ready (waiting == 0), factory is just - * // stored - * - * define('OtherClass, ['BaseClass'], function() { ... }); - * // OtherClass module is marked as ready (waiting == 0), factory is just - * // stored - * - * requireLazy(['SubClass', 'ChatConfig'], - * function() { ... }); - * // ChatRunner is waiting for ChatConfig to come - * - * define('ChatConfig', [], { foo: 'bar' }); - * // at this point ChatRunner is marked as ready, and its factory - * // executed + all dependent factories are executed too: BaseClass, - * // SubClass, ChatConfig notice that OtherClass's factory won't be - * // executed unless explicitly required by someone - * - * @param {Array} dependencies - * @param {Object|Function} factory - */ - function requireLazy(dependencies, factory, context) { - return define( - dependencies, - factory, - undefined, - REQUIRE_WHEN_READY, - context, - 1 - ); - } - - function _uid() { - return '__mod__' + _counter++; - } - - function _addDependency(module, dep) { - // do not add duplicate dependencies and circ deps - if (!module.waitingMap[dep] && module.id !== dep) { - module.waiting++; - module.waitingMap[dep] = 1; - dependencyMap[dep] || (dependencyMap[dep] = {}); - dependencyMap[dep][module.id] = 1; - } - } - - function _initDependencies(id) { - var modulesToRequire = []; - var module = modulesMap[id]; - var dep, i, subdep; - - // initialize id's waitingMap - for (i = 0; i < module.dependencies.length; i++) { - dep = module.dependencies[i]; - if (!modulesMap[dep]) { - _addDependency(module, dep); - } else if (modulesMap[dep].waiting) { - for (subdep in modulesMap[dep].waitingMap) { - if (modulesMap[dep].waitingMap[subdep]) { - _addDependency(module, subdep); - } - } - } - } - if (module.waiting === 0 && module.special & REQUIRE_WHEN_READY) { - modulesToRequire.push(id); - } - - // update modules depending on id - if (dependencyMap[id]) { - var deps = dependencyMap[id]; - var submodule; - dependencyMap[id] = undefined; - for (dep in deps) { - submodule = modulesMap[dep]; - - // add all deps of id - for (subdep in module.waitingMap) { - if (module.waitingMap[subdep]) { - _addDependency(submodule, subdep); - } - } - // remove id itself - if (submodule.waitingMap[id]) { - submodule.waitingMap[id] = undefined; - submodule.waiting--; - } - if (submodule.waiting === 0 && - submodule.special & REQUIRE_WHEN_READY) { - modulesToRequire.push(dep); - } - } - } - - // run everything that's ready - for (i = 0; i < modulesToRequire.length; i++) { - require.call(null, modulesToRequire[i]); - } - } - - function _register(id, exports) { - var module = modulesMap[id] = { id: id }; - module.exports = exports; - module.refcount = 0; - } - - // pseudo name used in common-require - // see require() function for more info - _register('module', 0); - _register('exports', 0); - - _register('global', global); - _register('require', require); - _register('requireDynamic', require); - _register('requireLazy', requireLazy); - - global.require = require; - global.requireDynamic = require; - global.requireLazy = requireLazy; - - require.__debug = { - modules: modulesMap, - deps: dependencyMap, - printDependencyInfo: function() { - if (!global.console) { - return; - } - var names = Object.keys(require.__debug.deps); - global.console.log(_debugUnresolvedDependencies(names)); - } - }; - - /** - * All @providesModule files are wrapped by this function by makehaste. It - * is a convenience function around define() that prepends a bunch of required - * modules (global, require, module, etc) so that we don't have to spit that - * out for every module which would be a lot of extra bytes. - */ - global.__d = function(id, deps, factory, _special, _inlineRequires) { - var defaultDeps = ['global', 'require', 'requireDynamic', 'requireLazy', - 'module', 'exports']; - define(id, defaultDeps.concat(deps), factory, _special || USED_AS_TRANSPORT, - null, null, _inlineRequires); - }; - -})(this); - -/** - * 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. - * - * This pipes all of our console logging functions to native logging so that - * JavaScript errors in required modules show up in Xcode via NSLog. - * - * @provides Object.es6 - * @polyfill - */ - -// WARNING: This is an optimized version that fails on hasOwnProperty checks -// and non objects. It's not spec-compliant. It's a perf optimization. -/* eslint global-strict:0 */ -Object.assign = function(target, sources) { - if (__DEV__) { - if (target == null) { - throw new TypeError('Object.assign target cannot be null or undefined'); - } - if (typeof target !== 'object' && typeof target !== 'function') { - throw new TypeError( - 'In this environment the target of assign MUST be an object.' + - 'This error is a performance optimization and not spec compliant.' - ); - } - } - - for (var nextIndex = 1; nextIndex < arguments.length; nextIndex++) { - var nextSource = arguments[nextIndex]; - if (nextSource == null) { - continue; - } - - if (__DEV__) { - if (typeof nextSource !== 'object' && - typeof nextSource !== 'function') { - throw new TypeError( - 'In this environment the target of assign MUST be an object.' + - 'This error is a performance optimization and not spec compliant.' - ); - } - } - - // We don't currently support accessors nor proxies. Therefore this - // copy cannot throw. If we ever supported this then we must handle - // exceptions and side-effects. - - for (var key in nextSource) { - if (__DEV__) { - var hasOwnProperty = Object.prototype.hasOwnProperty; - if (!hasOwnProperty.call(nextSource, key)) { - throw new TypeError( - 'One of the sources to assign has an enumerable key on the ' + - 'prototype chain. This is an edge case that we do not support. ' + - 'This error is a performance optimization and not spec compliant.' - ); - } - } - target[key] = nextSource[key]; - } - } - - return target; -}; - -/** - * 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. - * - * This pipes all of our console logging functions to native logging so that - * JavaScript errors in required modules show up in Xcode via NSLog. - * - * @provides console - * @polyfill - */ - -/*eslint global-strict:0*/ -(function(global) { - 'use strict'; - - var OBJECT_COLUMN_NAME = '(index)'; - var LOG_LEVELS = { - trace: 0, - log: 1, - info: 2, - warn: 3, - error: 4 - }; - - function setupConsole(global) { - - if (!global.nativeLoggingHook) { - return; - } - - function getNativeLogFunction(level) { - return function() { - var str = Array.prototype.map.call(arguments, function(arg) { - var ret; - var type = typeof arg; - if (arg === null) { - ret = 'null'; - } else if (arg === undefined) { - ret = 'undefined'; - } else if (type === 'string') { - ret = '"' + arg + '"'; - } else if (type === 'function') { - try { - ret = arg.toString(); - } catch (e) { - ret = '[function unknown]'; - } - } else { - // Perform a try catch, just in case the object has a circular - // reference or stringify throws for some other reason. - try { - ret = JSON.stringify(arg); - } catch (e) { - if (typeof arg.toString === 'function') { - try { - ret = arg.toString(); - } catch (E) {} - } - } - } - return ret || '["' + type + '" failed to stringify]'; - }).join(', '); - global.nativeLoggingHook(str, level); - }; - } - - var repeat = function(element, n) { - return Array.apply(null, Array(n)).map(function() { return element; }); - }; - - function consoleTablePolyfill(rows) { - // convert object -> array - if (!Array.isArray(rows)) { - var data = rows; - rows = []; - for (var key in data) { - if (data.hasOwnProperty(key)) { - var row = data[key]; - row[OBJECT_COLUMN_NAME] = key; - rows.push(row); - } - } - } - if (rows.length === 0) { - global.nativeLoggingHook('', LOG_LEVELS.log); - return; - } - - var columns = Object.keys(rows[0]).sort(); - var stringRows = []; - var columnWidths = []; - - // Convert each cell to a string. Also - // figure out max cell width for each column - columns.forEach(function(k, i) { - columnWidths[i] = k.length; - for (var j = 0; j < rows.length; j++) { - var cellStr = rows[j][k].toString(); - stringRows[j] = stringRows[j] || []; - stringRows[j][i] = cellStr; - columnWidths[i] = Math.max(columnWidths[i], cellStr.length); - } - }); - - // Join all elements in the row into a single string with | separators - // (appends extra spaces to each cell to make separators | alligned) - var joinRow = function(row, space) { - var cells = row.map(function(cell, i) { - var extraSpaces = repeat(' ', columnWidths[i] - cell.length).join(''); - return cell + extraSpaces; - }); - space = space || ' '; - return cells.join(space + '|' + space); - }; - - var separators = columnWidths.map(function(columnWidth) { - return repeat('-', columnWidth).join(''); - }); - var separatorRow = joinRow(separators, '-'); - var header = joinRow(columns); - var table = [header, separatorRow]; - - for (var i = 0; i < rows.length; i++) { - table.push(joinRow(stringRows[i])); - } - - // Notice extra empty line at the beginning. - // Native logging hook adds "RCTLog >" at the front of every - // logged string, which would shift the header and screw up - // the table - global.nativeLoggingHook('\n' + table.join('\n'), LOG_LEVELS.log); - } - - global.console = { - error: getNativeLogFunction(LOG_LEVELS.error), - info: getNativeLogFunction(LOG_LEVELS.info), - log: getNativeLogFunction(LOG_LEVELS.log), - warn: getNativeLogFunction(LOG_LEVELS.warn), - trace: getNativeLogFunction(LOG_LEVELS.trace), - table: consoleTablePolyfill - }; - - } - - if (typeof module !== 'undefined') { - module.exports = setupConsole; - } else { - setupConsole(global); - } - -})(this); - -/** - * 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. - * - * The particular require runtime that we are using looks for a global - * `ErrorUtils` object and if it exists, then it requires modules with the - * error handler specified via ErrorUtils.setGlobalHandler by calling the - * require function with applyWithGuard. Since the require module is loaded - * before any of the modules, this ErrorUtils must be defined (and the handler - * set) globally before requiring anything. - */ -/* eslint global-strict:0 */ -(function(global) { - var ErrorUtils = { - _inGuard: 0, - _globalHandler: null, - setGlobalHandler: function(fun) { - ErrorUtils._globalHandler = fun; - }, - reportError: function(error) { - ErrorUtils._globalHandler && ErrorUtils._globalHandler(error); - }, - reportFatalError: function(error) { - ErrorUtils._globalHandler && ErrorUtils._globalHandler(error, true); - }, - applyWithGuard: function(fun, context, args) { - try { - ErrorUtils._inGuard++; - return fun.apply(context, args); - } catch (e) { - ErrorUtils.reportError(e); - } finally { - ErrorUtils._inGuard--; - } - }, - applyWithGuardIfNeeded: function(fun, context, args) { - if (ErrorUtils.inGuard()) { - return fun.apply(context, args); - } else { - ErrorUtils.applyWithGuard(fun, context, args); - } - }, - inGuard: function() { - return ErrorUtils._inGuard; - }, - guard: function(fun, name, context) { - if (typeof fun !== 'function') { - console.warn('A function must be passed to ErrorUtils.guard, got ', fun); - return null; - } - name = name || fun.name || ''; - function guarded() { - return ( - ErrorUtils.applyWithGuard( - fun, - context || this, - arguments, - null, - name - ) - ); - } - - return guarded; - } - }; - global.ErrorUtils = ErrorUtils; - - /** - * This is the error handler that is called when we encounter an exception - * when loading a module. - */ - function setupErrorGuard() { - var onError = function(e) { - global.console.error( - 'Error: ' + - '\n stack: ' + e.stack + - '\n line: ' + e.line + - '\n message: ' + e.message, - e - ); - }; - global.ErrorUtils.setGlobalHandler(onError); - } - - setupErrorGuard(); -})(this); - -/** - * @provides String.prototype.es6 - * @polyfill - */ - -/*eslint global-strict:0, no-extend-native:0, no-bitwise:0 */ -/*jshint bitwise:false*/ - -/* - * NOTE: We use (Number(x) || 0) to replace NaN values with zero. - */ - -if (!String.prototype.startsWith) { - String.prototype.startsWith = function(search) { - 'use strict'; - if (this == null) { - throw TypeError(); - } - var string = String(this); - var pos = arguments.length > 1 ? - (Number(arguments[1]) || 0) : 0; - var start = Math.min(Math.max(pos, 0), string.length); - return string.indexOf(String(search), pos) === start; - }; -} - -if (!String.prototype.endsWith) { - String.prototype.endsWith = function(search) { - 'use strict'; - if (this == null) { - throw TypeError(); - } - var string = String(this); - var stringLength = string.length; - var searchString = String(search); - var pos = arguments.length > 1 ? - (Number(arguments[1]) || 0) : stringLength; - var end = Math.min(Math.max(pos, 0), stringLength); - var start = end - searchString.length; - if (start < 0) { - return false; - } - return string.lastIndexOf(searchString, start) === start; - }; -} - -if (!String.prototype.contains) { - String.prototype.contains = function(search) { - 'use strict'; - if (this == null) { - throw TypeError(); - } - var string = String(this); - var pos = arguments.length > 1 ? - (Number(arguments[1]) || 0) : 0; - return string.indexOf(String(search), pos) !== -1; - }; -} - -if (!String.prototype.repeat) { - String.prototype.repeat = function(count) { - 'use strict'; - if (this == null) { - throw TypeError(); - } - var string = String(this); - count = Number(count) || 0; - if (count < 0 || count === Infinity) { - throw RangeError(); - } - if (count === 1) { - return string; - } - var result = ''; - while (count) { - if (count & 1) { - result += string; - } - if ((count >>= 1)) { - string += string; - } - } - return result; - }; -} - -/** - * Copyright 2004-present Facebook. All Rights Reserved. - * - * @provides Array.prototype.es6 - * @polyfill - */ - -/*eslint-disable */ -/*jslint bitwise: true */ - -(function(undefined) { - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex - function findIndex(predicate, context) { - if (this == null) { - throw new TypeError( - 'Array.prototype.findIndex called on null or undefined' - ); - } - if (typeof predicate !== 'function') { - throw new TypeError('predicate must be a function'); - } - var list = Object(this); - var length = list.length >>> 0; - for (var i = 0; i < length; i++) { - if (predicate.call(context, list[i], i, list)) { - return i; - } - } - return -1; - } - - if (!Array.prototype.findIndex) { - Object.defineProperty(Array.prototype, 'findIndex', { - enumerable: false, - writable: true, - configurable: true, - value: findIndex - }); - } - - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find - if (!Array.prototype.find) { - Object.defineProperty(Array.prototype, 'find', { - enumerable: false, - writable: true, - configurable: true, - value: function(predicate, context) { - if (this == null) { - throw new TypeError( - 'Array.prototype.find called on null or undefined' - ); - } - var index = findIndex.call(this, predicate, context); - return index === -1 ? undefined : this[index]; - } - }); - } -})(); - -__d('HybridMobileDeployCompanion/index.ios',["react-native/Libraries/react-native/react-native"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Sample React Native App - * https://github.com/facebook/react-native - */ -'use strict'; - -var React = require('react-native/Libraries/react-native/react-native'); -var $__0= - - - - - React,AppRegistry=$__0.AppRegistry,StyleSheet=$__0.StyleSheet,Text=$__0.Text,View=$__0.View; - -var HybridMobileDeploy = require('hybrid-mobile-deploy-react-native'); - -var HybridMobileDeployCompanion = React.createClass({displayName: "HybridMobileDeployCompanion", - render: function() { - return ( - React.createElement(View, {style: styles.container}, - React.createElement(Text, {style: styles.welcome}, - "Welcome to React Native!" - ), - React.createElement(Text, {style: styles.instructions}, - "To get started, edit index.ios.js" - ), - React.createElement(Text, {style: styles.instructions}, - "Press Cmd+R to reload,", '\n', - "Cmd+D or shake for dev menu" - ) - ) - ); - } -}); - -var styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - backgroundColor: '#F5FCFF', - }, - welcome: { - fontSize: 20, - textAlign: 'center', - margin: 10, - }, - instructions: { - textAlign: 'center', - color: '#333333', - marginBottom: 5, - }, -}); - -AppRegistry.registerComponent('HybridMobileDeployCompanion', function() {return HybridMobileDeployCompanion;}); -}); -__d('react-native/Libraries/react-native/react-native',["React","ActivityIndicatorIOS","DatePickerIOS","Image","ListView","MapView","NavigatorIOS","PickerIOS","Navigator","SegmentedControlIOS","ScrollView","SliderIOS","SwitchIOS","TabBarIOS","Text","TextInput","TouchableHighlight","TouchableOpacity","TouchableWithoutFeedback","View","WebView","AlertIOS","AppRegistry","AppStateIOS","AsyncStorage","CameraRoll","InteractionManager","LinkingIOS","LayoutAnimation","NetInfo","PixelRatio","PushNotificationIOS","PanResponder","StatusBarIOS","StyleSheet","VibrationIOS","RCTDeviceEventEmitter","RCTNativeAppEventEmitter","NativeModules","requireNativeComponent","LinkedStateMixin","ReactComponentWithPureRenderMixin","NativeModules","ReactUpdates","cloneWithProps","ReactFragment","update","ReactDefaultPerf","ReactTestUtils"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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. - * - * @flow - */ -'use strict'; - -// Export React, plus some native additions. -// -// The use of Object.create/assign is to work around a Flow bug (#6560135). -// Once that is fixed, change this back to -// -// var ReactNative = {...require('React'), /* additions */} -// -var ReactNative = Object.assign(Object.create(require('React')), { - // Components - ActivityIndicatorIOS: require('ActivityIndicatorIOS'), - DatePickerIOS: require('DatePickerIOS'), - Image: require('Image'), - ListView: require('ListView'), - MapView: require('MapView'), - NavigatorIOS: require('NavigatorIOS'), - PickerIOS: require('PickerIOS'), - Navigator: require('Navigator'), - SegmentedControlIOS: require('SegmentedControlIOS'), - ScrollView: require('ScrollView'), - SliderIOS: require('SliderIOS'), - SwitchIOS: require('SwitchIOS'), - TabBarIOS: require('TabBarIOS'), - Text: require('Text'), - TextInput: require('TextInput'), - TouchableHighlight: require('TouchableHighlight'), - TouchableOpacity: require('TouchableOpacity'), - TouchableWithoutFeedback: require('TouchableWithoutFeedback'), - View: require('View'), - WebView: require('WebView'), - - // APIs - AlertIOS: require('AlertIOS'), - AppRegistry: require('AppRegistry'), - AppStateIOS: require('AppStateIOS'), - AsyncStorage: require('AsyncStorage'), - CameraRoll: require('CameraRoll'), - InteractionManager: require('InteractionManager'), - LinkingIOS: require('LinkingIOS'), - LayoutAnimation: require('LayoutAnimation'), - NetInfo: require('NetInfo'), - PixelRatio: require('PixelRatio'), - PushNotificationIOS: require('PushNotificationIOS'), - PanResponder: require('PanResponder'), - StatusBarIOS: require('StatusBarIOS'), - StyleSheet: require('StyleSheet'), - VibrationIOS: require('VibrationIOS'), - - // Plugins - DeviceEventEmitter: require('RCTDeviceEventEmitter'), - NativeAppEventEmitter: require('RCTNativeAppEventEmitter'), - NativeModules: require('NativeModules'), - requireNativeComponent: require('requireNativeComponent'), - - addons: { - LinkedStateMixin: require('LinkedStateMixin'), - Perf: undefined, - PureRenderMixin: require('ReactComponentWithPureRenderMixin'), - TestModule: require('NativeModules').TestModule, - TestUtils: undefined, - batchedUpdates: require('ReactUpdates').batchedUpdates, - cloneWithProps: require('cloneWithProps'), - createFragment: require('ReactFragment').create, - update: require('update'), - }, -}); - -if (__DEV__) { - ReactNative.addons.Perf = require('ReactDefaultPerf'); - ReactNative.addons.TestUtils = require('ReactTestUtils'); -} - -module.exports = ReactNative; -}); -__d('React',["ReactNative"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 React - * @flow - */ -'use strict'; - -module.exports = require('ReactNative'); -}); -__d('ReactNative',["ReactChildren","ReactClass","ReactComponent","ReactContext","ReactCurrentOwner","ReactElement","ReactElementValidator","ReactInstanceHandles","ReactNativeDefaultInjection","ReactNativeMount","ReactPropTypes","deprecated","findNodeHandle","invariant","onlyChild","ReactReconciler","ReactNativeTextComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 ReactNative - * @flow - */ -'use strict'; - -var ReactChildren = require('ReactChildren'); -var ReactClass = require('ReactClass'); -var ReactComponent = require('ReactComponent'); -var ReactContext = require('ReactContext'); -var ReactCurrentOwner = require('ReactCurrentOwner'); -var ReactElement = require('ReactElement'); -var ReactElementValidator = require('ReactElementValidator'); -var ReactInstanceHandles = require('ReactInstanceHandles'); -var ReactNativeDefaultInjection = require('ReactNativeDefaultInjection'); -var ReactNativeMount = require('ReactNativeMount'); -var ReactPropTypes = require('ReactPropTypes'); - -var deprecated = require('deprecated'); -var findNodeHandle = require('findNodeHandle'); -var invariant = require('invariant'); -var onlyChild = require('onlyChild'); - -ReactNativeDefaultInjection.inject(); - -var createElement = ReactElement.createElement; -var createFactory = ReactElement.createFactory; -var cloneElement = ReactElement.cloneElement; - -if (__DEV__) { - createElement = ReactElementValidator.createElement; - createFactory = ReactElementValidator.createFactory; - cloneElement = ReactElementValidator.cloneElement; -} - -var resolveDefaultProps = function(element) { - // Could be optimized, but not currently in heavy use. - var defaultProps = element.type.defaultProps; - var props = element.props; - for (var propName in defaultProps) { - if (props[propName] === undefined) { - props[propName] = defaultProps[propName]; - } - } -}; - -// Experimental optimized element creation -var augmentElement = function(element ) { - if (__DEV__) { - invariant( - false, - 'This optimized path should never be used in DEV mode because ' + - 'it does not provide validation. Check your JSX transform.' - ); - } - element._owner = ReactCurrentOwner.current; - element._context = ReactContext.current; - if (element.type.defaultProps) { - resolveDefaultProps(element); - } - return element; -}; - -var render = function( - element , - mountInto , - callback -) { - return ReactNativeMount.renderComponent(element, mountInto, callback); -}; - -var ReactNative = { - hasReactNativeInitialized: false, - Children: { - map: ReactChildren.map, - forEach: ReactChildren.forEach, - count: ReactChildren.count, - only: onlyChild - }, - Component: ReactComponent, - PropTypes: ReactPropTypes, - createClass: ReactClass.createClass, - createElement: createElement, - createFactory: createFactory, - cloneElement: cloneElement, - _augmentElement: augmentElement, - findNodeHandle: findNodeHandle, - render: render, - unmountComponentAtNode: ReactNativeMount.unmountComponentAtNode, - - // Hook for JSX spread, don't use this for anything else. - __spread: Object.assign, - - unmountComponentAtNodeAndRemoveContainer: ReactNativeMount.unmountComponentAtNodeAndRemoveContainer, - isValidClass: ReactElement.isValidFactory, - isValidElement: ReactElement.isValidElement, - - // Deprecations (remove for 0.13) - renderComponent: deprecated( - 'React', - 'renderComponent', - 'render', - this, - render - ), - isValidComponent: deprecated( - 'React', - 'isValidComponent', - 'isValidElement', - this, - ReactElement.isValidElement - ) -}; - -// Inject the runtime into a devtools global hook regardless of browser. -// Allows for debugging when the hook is injected on the page. -/* globals __REACT_DEVTOOLS_GLOBAL_HOOK__ */ -if ( - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' && - typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.inject === 'function') { - __REACT_DEVTOOLS_GLOBAL_HOOK__.inject({ - CurrentOwner: ReactCurrentOwner, - InstanceHandles: ReactInstanceHandles, - Mount: ReactNativeMount, - Reconciler: require('ReactReconciler'), - TextComponent: require('ReactNativeTextComponent'), - }); -} - -module.exports = ReactNative; -}); -__d('ReactChildren',["PooledClass","ReactFragment","traverseAllChildren","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactChildren - */ - -'use strict'; - -var PooledClass = require('PooledClass'); -var ReactFragment = require('ReactFragment'); - -var traverseAllChildren = require('traverseAllChildren'); -var warning = require('warning'); - -var twoArgumentPooler = PooledClass.twoArgumentPooler; -var threeArgumentPooler = PooledClass.threeArgumentPooler; - -/** - * PooledClass representing the bookkeeping associated with performing a child - * traversal. Allows avoiding binding callbacks. - * - * @constructor ForEachBookKeeping - * @param {!function} forEachFunction Function to perform traversal with. - * @param {?*} forEachContext Context to perform context with. - */ -function ForEachBookKeeping(forEachFunction, forEachContext) { - this.forEachFunction = forEachFunction; - this.forEachContext = forEachContext; -} -PooledClass.addPoolingTo(ForEachBookKeeping, twoArgumentPooler); - -function forEachSingleChild(traverseContext, child, name, i) { - var forEachBookKeeping = traverseContext; - forEachBookKeeping.forEachFunction.call( - forEachBookKeeping.forEachContext, child, i); -} - -/** - * Iterates through children that are typically specified as `props.children`. - * - * The provided forEachFunc(child, index) will be called for each - * leaf child. - * - * @param {?*} children Children tree container. - * @param {function(*, int)} forEachFunc. - * @param {*} forEachContext Context for forEachContext. - */ -function forEachChildren(children, forEachFunc, forEachContext) { - if (children == null) { - return children; - } - - var traverseContext = - ForEachBookKeeping.getPooled(forEachFunc, forEachContext); - traverseAllChildren(children, forEachSingleChild, traverseContext); - ForEachBookKeeping.release(traverseContext); -} - -/** - * PooledClass representing the bookkeeping associated with performing a child - * mapping. Allows avoiding binding callbacks. - * - * @constructor MapBookKeeping - * @param {!*} mapResult Object containing the ordered map of results. - * @param {!function} mapFunction Function to perform mapping with. - * @param {?*} mapContext Context to perform mapping with. - */ -function MapBookKeeping(mapResult, mapFunction, mapContext) { - this.mapResult = mapResult; - this.mapFunction = mapFunction; - this.mapContext = mapContext; -} -PooledClass.addPoolingTo(MapBookKeeping, threeArgumentPooler); - -function mapSingleChildIntoContext(traverseContext, child, name, i) { - var mapBookKeeping = traverseContext; - var mapResult = mapBookKeeping.mapResult; - - var keyUnique = !mapResult.hasOwnProperty(name); - if (__DEV__) { - warning( - keyUnique, - 'ReactChildren.map(...): Encountered two children with the same key, ' + - '`%s`. Child keys must be unique; when two children share a key, only ' + - 'the first child will be used.', - name - ); - } - - if (keyUnique) { - var mappedChild = - mapBookKeeping.mapFunction.call(mapBookKeeping.mapContext, child, i); - mapResult[name] = mappedChild; - } -} - -/** - * Maps children that are typically specified as `props.children`. - * - * The provided mapFunction(child, key, index) will be called for each - * leaf child. - * - * TODO: This may likely break any calls to `ReactChildren.map` that were - * previously relying on the fact that we guarded against null children. - * - * @param {?*} children Children tree container. - * @param {function(*, int)} mapFunction. - * @param {*} mapContext Context for mapFunction. - * @return {object} Object containing the ordered map of results. - */ -function mapChildren(children, func, context) { - if (children == null) { - return children; - } - - var mapResult = {}; - var traverseContext = MapBookKeeping.getPooled(mapResult, func, context); - traverseAllChildren(children, mapSingleChildIntoContext, traverseContext); - MapBookKeeping.release(traverseContext); - return ReactFragment.create(mapResult); -} - -function forEachSingleChildDummy(traverseContext, child, name, i) { - return null; -} - -/** - * Count the number of children that are typically specified as - * `props.children`. - * - * @param {?*} children Children tree container. - * @return {number} The number of children. - */ -function countChildren(children, context) { - return traverseAllChildren(children, forEachSingleChildDummy, null); -} - -var ReactChildren = { - forEach: forEachChildren, - map: mapChildren, - count: countChildren -}; - -module.exports = ReactChildren; -}); -__d('PooledClass',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 PooledClass - */ - -'use strict'; - -var invariant = require('invariant'); - -/** - * Static poolers. Several custom versions for each potential number of - * arguments. A completely generic pooler is easy to implement, but would - * require accessing the `arguments` object. In each of these, `this` refers to - * the Class itself, not an instance. If any others are needed, simply add them - * here, or in their own files. - */ -var oneArgumentPooler = function(copyFieldsFrom) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, copyFieldsFrom); - return instance; - } else { - return new Klass(copyFieldsFrom); - } -}; - -var twoArgumentPooler = function(a1, a2) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2); - return instance; - } else { - return new Klass(a1, a2); - } -}; - -var threeArgumentPooler = function(a1, a2, a3) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2, a3); - return instance; - } else { - return new Klass(a1, a2, a3); - } -}; - -var fiveArgumentPooler = function(a1, a2, a3, a4, a5) { - var Klass = this; - if (Klass.instancePool.length) { - var instance = Klass.instancePool.pop(); - Klass.call(instance, a1, a2, a3, a4, a5); - return instance; - } else { - return new Klass(a1, a2, a3, a4, a5); - } -}; - -var standardReleaser = function(instance) { - var Klass = this; - invariant( - instance instanceof Klass, - 'Trying to release an instance into a pool of a different type.' - ); - if (instance.destructor) { - instance.destructor(); - } - if (Klass.instancePool.length < Klass.poolSize) { - Klass.instancePool.push(instance); - } -}; - -var DEFAULT_POOL_SIZE = 10; -var DEFAULT_POOLER = oneArgumentPooler; - -/** - * Augments `CopyConstructor` to be a poolable class, augmenting only the class - * itself (statically) not adding any prototypical fields. Any CopyConstructor - * you give this may have a `poolSize` property, and will look for a - * prototypical `destructor` on instances (optional). - * - * @param {Function} CopyConstructor Constructor that can be used to reset. - * @param {Function} pooler Customizable pooler. - */ -var addPoolingTo = function(CopyConstructor, pooler) { - var NewKlass = CopyConstructor; - NewKlass.instancePool = []; - NewKlass.getPooled = pooler || DEFAULT_POOLER; - if (!NewKlass.poolSize) { - NewKlass.poolSize = DEFAULT_POOL_SIZE; - } - NewKlass.release = standardReleaser; - return NewKlass; -}; - -var PooledClass = { - addPoolingTo: addPoolingTo, - oneArgumentPooler: oneArgumentPooler, - twoArgumentPooler: twoArgumentPooler, - threeArgumentPooler: threeArgumentPooler, - fiveArgumentPooler: fiveArgumentPooler -}; - -module.exports = PooledClass; -}); -__d('invariant',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 invariant - */ - -"use strict"; - -/** - * Use invariant() to assert state which your program assumes to be true. - * - * Provide sprintf-style format (only %s is supported) and arguments - * to provide information about what broke and what you were - * expecting. - * - * The invariant message will be stripped in production, but the invariant - * will remain to ensure logic does not differ in production. - */ - -var invariant = function(condition, format, a, b, c, d, e, f) { - if (__DEV__) { - if (format === undefined) { - throw new Error('invariant requires an error message argument'); - } - } - - if (!condition) { - var error; - if (format === undefined) { - error = new Error( - 'Minified exception occurred; use the non-minified dev environment ' + - 'for the full error message and additional helpful warnings.' - ); - } else { - var args = [a, b, c, d, e, f]; - var argIndex = 0; - error = new Error( - 'Invariant Violation: ' + - format.replace(/%s/g, function() { return args[argIndex++]; }) - ); - } - - error.framesToPop = 1; // we don't care about invariant's own frame - throw error; - } -}; - -module.exports = invariant; -}); -__d('ReactFragment',["ReactElement","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2015, 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 ReactFragment -*/ - -'use strict'; - -var ReactElement = require('ReactElement'); - -var warning = require('warning'); - -/** - * We used to allow keyed objects to serve as a collection of ReactElements, - * or nested sets. This allowed us a way to explicitly key a set a fragment of - * components. This is now being replaced with an opaque data structure. - * The upgrade path is to call React.addons.createFragment({ key: value }) to - * create a keyed fragment. The resulting data structure is opaque, for now. - */ - -if (__DEV__) { - var fragmentKey = '_reactFragment'; - var didWarnKey = '_reactDidWarn'; - var canWarnForReactFragment = false; - - try { - // Feature test. Don't even try to issue this warning if we can't use - // enumerable: false. - - var dummy = function() { - return 1; - }; - - Object.defineProperty( - {}, - fragmentKey, - {enumerable: false, value: true} - ); - - Object.defineProperty( - {}, - 'key', - {enumerable: true, get: dummy} - ); - - canWarnForReactFragment = true; - } catch (x) { } - - var proxyPropertyAccessWithWarning = function(obj, key) { - Object.defineProperty(obj, key, { - enumerable: true, - get: function() { - warning( - this[didWarnKey], - 'A ReactFragment is an opaque type. Accessing any of its ' + - 'properties is deprecated. Pass it to one of the React.Children ' + - 'helpers.' - ); - this[didWarnKey] = true; - return this[fragmentKey][key]; - }, - set: function(value) { - warning( - this[didWarnKey], - 'A ReactFragment is an immutable opaque type. Mutating its ' + - 'properties is deprecated.' - ); - this[didWarnKey] = true; - this[fragmentKey][key] = value; - } - }); - }; - - var issuedWarnings = {}; - - var didWarnForFragment = function(fragment) { - // We use the keys and the type of the value as a heuristic to dedupe the - // warning to avoid spamming too much. - var fragmentCacheKey = ''; - for (var key in fragment) { - fragmentCacheKey += key + ':' + (typeof fragment[key]) + ','; - } - var alreadyWarnedOnce = !!issuedWarnings[fragmentCacheKey]; - issuedWarnings[fragmentCacheKey] = true; - return alreadyWarnedOnce; - }; -} - -var ReactFragment = { - // Wrap a keyed object in an opaque proxy that warns you if you access any - // of its properties. - create: function(object) { - if (__DEV__) { - if (typeof object !== 'object' || !object || Array.isArray(object)) { - warning( - false, - 'React.addons.createFragment only accepts a single object.', - object - ); - return object; - } - if (ReactElement.isValidElement(object)) { - warning( - false, - 'React.addons.createFragment does not accept a ReactElement ' + - 'without a wrapper object.' - ); - return object; - } - if (canWarnForReactFragment) { - var proxy = {}; - Object.defineProperty(proxy, fragmentKey, { - enumerable: false, - value: object - }); - Object.defineProperty(proxy, didWarnKey, { - writable: true, - enumerable: false, - value: false - }); - for (var key in object) { - proxyPropertyAccessWithWarning(proxy, key); - } - Object.preventExtensions(proxy); - return proxy; - } - } - return object; - }, - // Extract the original keyed object from the fragment opaque type. Warn if - // a plain object is passed here. - extract: function(fragment) { - if (__DEV__) { - if (canWarnForReactFragment) { - if (!fragment[fragmentKey]) { - warning( - didWarnForFragment(fragment), - 'Any use of a keyed object should be wrapped in ' + - 'React.addons.createFragment(object) before being passed as a ' + - 'child.' - ); - return fragment; - } - return fragment[fragmentKey]; - } - } - return fragment; - }, - // Check if this is a fragment and if so, extract the keyed object. If it - // is a fragment-like object, warn that it should be wrapped. Ignore if we - // can't determine what kind of object this is. - extractIfFragment: function(fragment) { - if (__DEV__) { - if (canWarnForReactFragment) { - // If it is the opaque type, return the keyed object. - if (fragment[fragmentKey]) { - return fragment[fragmentKey]; - } - // Otherwise, check each property if it has an element, if it does - // it is probably meant as a fragment, so we can warn early. Defer, - // the warning to extract. - for (var key in fragment) { - if (fragment.hasOwnProperty(key) && - ReactElement.isValidElement(fragment[key])) { - // This looks like a fragment object, we should provide an - // early warning. - return ReactFragment.extract(fragment); - } - } - } - } - return fragment; - } -}; - -module.exports = ReactFragment; -}); -__d('ReactElement',["ReactContext","ReactCurrentOwner","Object.assign","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2014-2015, 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 ReactElement - */ - -'use strict'; - -var ReactContext = require('ReactContext'); -var ReactCurrentOwner = require('ReactCurrentOwner'); - -var assign = require('Object.assign'); -var warning = require('warning'); - -var RESERVED_PROPS = { - key: true, - ref: true -}; - -/** - * Warn for mutations. - * - * @internal - * @param {object} object - * @param {string} key - */ -function defineWarningProperty(object, key) { - Object.defineProperty(object, key, { - - configurable: false, - enumerable: true, - - get: function() { - if (!this._store) { - return null; - } - return this._store[key]; - }, - - set: function(value) { - warning( - false, - 'Don\'t set the %s property of the React element. Instead, ' + - 'specify the correct value when initially creating the element.', - key - ); - this._store[key] = value; - } - - }); -} - -/** - * This is updated to true if the membrane is successfully created. - */ -var useMutationMembrane = false; - -/** - * Warn for mutations. - * - * @internal - * @param {object} element - */ -function defineMutationMembrane(prototype) { - try { - var pseudoFrozenProperties = { - props: true - }; - for (var key in pseudoFrozenProperties) { - defineWarningProperty(prototype, key); - } - useMutationMembrane = true; - } catch (x) { - // IE will fail on defineProperty - } -} - -/** - * Base constructor for all React elements. This is only used to make this - * work with a dynamic instanceof check. Nothing should live on this prototype. - * - * @param {*} type - * @param {string|object} ref - * @param {*} key - * @param {*} props - * @internal - */ -var ReactElement = function(type, key, ref, owner, context, props) { - // Built-in properties that belong on the element - this.type = type; - this.key = key; - this.ref = ref; - - // Record the component responsible for creating this element. - this._owner = owner; - - // TODO: Deprecate withContext, and then the context becomes accessible - // through the owner. - this._context = context; - - if (__DEV__) { - // The validation flag and props are currently mutative. We put them on - // an external backing store so that we can freeze the whole object. - // This can be replaced with a WeakMap once they are implemented in - // commonly used development environments. - this._store = {props: props, originalProps: assign({}, props)}; - - // To make comparing ReactElements easier for testing purposes, we make - // the validation flag non-enumerable (where possible, which should - // include every environment we run tests in), so the test framework - // ignores it. - try { - Object.defineProperty(this._store, 'validated', { - configurable: false, - enumerable: false, - writable: true - }); - } catch (x) { - } - this._store.validated = false; - - // We're not allowed to set props directly on the object so we early - // return and rely on the prototype membrane to forward to the backing - // store. - if (useMutationMembrane) { - Object.freeze(this); - return; - } - } - - this.props = props; -}; - -// We intentionally don't expose the function on the constructor property. -// ReactElement should be indistinguishable from a plain object. -ReactElement.prototype = { - _isReactElement: true -}; - -if (__DEV__) { - defineMutationMembrane(ReactElement.prototype); -} - -ReactElement.createElement = function(type, config, children) { - var propName; - - // Reserved names are extracted - var props = {}; - - var key = null; - var ref = null; - - if (config != null) { - ref = config.ref === undefined ? null : config.ref; - key = config.key === undefined ? null : '' + config.key; - // Remaining properties are added to a new props object - for (propName in config) { - if (config.hasOwnProperty(propName) && - !RESERVED_PROPS.hasOwnProperty(propName)) { - props[propName] = config[propName]; - } - } - } - - // Children can be more than one argument, and those are transferred onto - // the newly allocated props object. - var childrenLength = arguments.length - 2; - if (childrenLength === 1) { - props.children = children; - } else if (childrenLength > 1) { - var childArray = Array(childrenLength); - for (var i = 0; i < childrenLength; i++) { - childArray[i] = arguments[i + 2]; - } - props.children = childArray; - } - - // Resolve default props - if (type && type.defaultProps) { - var defaultProps = type.defaultProps; - for (propName in defaultProps) { - if (typeof props[propName] === 'undefined') { - props[propName] = defaultProps[propName]; - } - } - } - - return new ReactElement( - type, - key, - ref, - ReactCurrentOwner.current, - ReactContext.current, - props - ); -}; - -ReactElement.createFactory = function(type) { - var factory = ReactElement.createElement.bind(null, type); - // Expose the type on the factory and the prototype so that it can be - // easily accessed on elements. E.g. .type === Foo.type. - // This should not be named `constructor` since this may not be the function - // that created the element, and it may not even be a constructor. - // Legacy hook TODO: Warn if this is accessed - factory.type = type; - return factory; -}; - -ReactElement.cloneAndReplaceProps = function(oldElement, newProps) { - var newElement = new ReactElement( - oldElement.type, - oldElement.key, - oldElement.ref, - oldElement._owner, - oldElement._context, - newProps - ); - - if (__DEV__) { - // If the key on the original is valid, then the clone is valid - newElement._store.validated = oldElement._store.validated; - } - return newElement; -}; - -ReactElement.cloneElement = function(element, config, children) { - var propName; - - // Original props are copied - var props = assign({}, element.props); - - // Reserved names are extracted - var key = element.key; - var ref = element.ref; - - // Owner will be preserved, unless ref is overridden - var owner = element._owner; - - if (config != null) { - if (config.ref !== undefined) { - // Silently steal the ref from the parent. - ref = config.ref; - owner = ReactCurrentOwner.current; - } - if (config.key !== undefined) { - key = '' + config.key; - } - // Remaining properties override existing props - for (propName in config) { - if (config.hasOwnProperty(propName) && - !RESERVED_PROPS.hasOwnProperty(propName)) { - props[propName] = config[propName]; - } - } - } - - // Children can be more than one argument, and those are transferred onto - // the newly allocated props object. - var childrenLength = arguments.length - 2; - if (childrenLength === 1) { - props.children = children; - } else if (childrenLength > 1) { - var childArray = Array(childrenLength); - for (var i = 0; i < childrenLength; i++) { - childArray[i] = arguments[i + 2]; - } - props.children = childArray; - } - - return new ReactElement( - element.type, - key, - ref, - owner, - element._context, - props - ); -}; - -/** - * @param {?object} object - * @return {boolean} True if `object` is a valid component. - * @final - */ -ReactElement.isValidElement = function(object) { - // ReactTestUtils is often used outside of beforeEach where as React is - // within it. This leads to two different instances of React on the same - // page. To identify a element from a different React instance we use - // a flag instead of an instanceof check. - var isElement = !!(object && object._isReactElement); - // if (isElement && !(object instanceof ReactElement)) { - // This is an indicator that you're using multiple versions of React at the - // same time. This will screw with ownership and stuff. Fix it, please. - // TODO: We could possibly warn here. - // } - return isElement; -}; - -module.exports = ReactElement; -}); -__d('ReactContext',["Object.assign","emptyObject","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactContext - */ - -'use strict'; - -var assign = require('Object.assign'); -var emptyObject = require('emptyObject'); -var warning = require('warning'); - -var didWarn = false; - -/** - * Keeps track of the current context. - * - * The context is automatically passed down the component ownership hierarchy - * and is accessible via `this.context` on ReactCompositeComponents. - */ -var ReactContext = { - - /** - * @internal - * @type {object} - */ - current: emptyObject, - - /** - * Temporarily extends the current context while executing scopedCallback. - * - * A typical use case might look like - * - * render: function() { - * var children = ReactContext.withContext({foo: 'foo'}, () => ( - * - * )); - * return
{children}
; - * } - * - * @param {object} newContext New context to merge into the existing context - * @param {function} scopedCallback Callback to run with the new context - * @return {ReactComponent|array} - */ - withContext: function(newContext, scopedCallback) { - if (__DEV__) { - warning( - didWarn, - 'withContext is deprecated and will be removed in a future version. ' + - 'Use a wrapper component with getChildContext instead.' - ); - - didWarn = true; - } - - var result; - var previousContext = ReactContext.current; - ReactContext.current = assign({}, previousContext, newContext); - try { - result = scopedCallback(); - } finally { - ReactContext.current = previousContext; - } - return result; - } - -}; - -module.exports = ReactContext; -}); -__d('Object.assign',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2014-2015, 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 Object.assign - */ - -// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-object.assign - -'use strict'; - -function assign(target, sources) { - if (target == null) { - throw new TypeError('Object.assign target cannot be null or undefined'); - } - - var to = Object(target); - var hasOwnProperty = Object.prototype.hasOwnProperty; - - for (var nextIndex = 1; nextIndex < arguments.length; nextIndex++) { - var nextSource = arguments[nextIndex]; - if (nextSource == null) { - continue; - } - - var from = Object(nextSource); - - // We don't currently support accessors nor proxies. Therefore this - // copy cannot throw. If we ever supported this then we must handle - // exceptions and side-effects. We don't support symbols so they won't - // be transferred. - - for (var key in from) { - if (hasOwnProperty.call(from, key)) { - to[key] = from[key]; - } - } - } - - return to; -} - -module.exports = assign; -}); -__d('emptyObject',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 emptyObject - */ - -"use strict"; - -var emptyObject = {}; - -if (__DEV__) { - Object.freeze(emptyObject); -} - -module.exports = emptyObject; -}); -__d('warning',["emptyFunction"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2014-2015, 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 warning - */ - -"use strict"; - -var emptyFunction = require('emptyFunction'); - -/** - * Similar to invariant but only logs a warning if the condition is not met. - * This can be used to log issues in development environments in critical - * paths. Removing the logging code for production environments will keep the - * same logic and follow the same code paths. - */ - -var warning = emptyFunction; - -if (__DEV__) { - warning = function(condition, format ) {for (var args=[],$__0=2,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); - if (format === undefined) { - throw new Error( - '`warning(condition, format, ...args)` requires a warning ' + - 'message argument' - ); - } - - if (format.length < 10 || /^[s\W]*$/.test(format)) { - throw new Error( - 'The warning format should be able to uniquely identify this ' + - 'warning. Please, use a more descriptive format than: ' + format - ); - } - - if (format.indexOf('Failed Composite propType: ') === 0) { - return; // Ignore CompositeComponent proptype check. - } - - if (!condition) { - var argIndex = 0; - var message = 'Warning: ' + format.replace(/%s/g, function() {return args[argIndex++];}); - console.warn(message); - try { - // --- Welcome to debugging React --- - // This error was thrown as a convenience so that you can use this stack - // to find the callsite that caused this warning to fire. - throw new Error(message); - } catch(x) {} - } - }; -} - -module.exports = warning; -}); -__d('emptyFunction',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 emptyFunction - */ - -function makeEmptyFunction(arg) { - return function() { - return arg; - }; -} - -/** - * This function accepts and discards inputs; it has no side effects. This is - * primarily useful idiomatically for overridable function endpoints which - * always need to be callable, since JS lacks a null-call idiom ala Cocoa. - */ -function emptyFunction() {} - -emptyFunction.thatReturns = makeEmptyFunction; -emptyFunction.thatReturnsFalse = makeEmptyFunction(false); -emptyFunction.thatReturnsTrue = makeEmptyFunction(true); -emptyFunction.thatReturnsNull = makeEmptyFunction(null); -emptyFunction.thatReturnsThis = function() { return this; }; -emptyFunction.thatReturnsArgument = function(arg) { return arg; }; - -module.exports = emptyFunction; -}); -__d('ReactCurrentOwner',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactCurrentOwner - */ - -'use strict'; - -/** - * Keeps track of the current owner. - * - * The current owner is the component who should own any components that are - * currently being constructed. - * - * The depth indicate how many composite components are above this render level. - */ -var ReactCurrentOwner = { - - /** - * @internal - * @type {ReactComponent} - */ - current: null - -}; - -module.exports = ReactCurrentOwner; -}); -__d('traverseAllChildren',["ReactElement","ReactFragment","ReactInstanceHandles","getIteratorFn","invariant","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 traverseAllChildren - */ - -'use strict'; - -var ReactElement = require('ReactElement'); -var ReactFragment = require('ReactFragment'); -var ReactInstanceHandles = require('ReactInstanceHandles'); - -var getIteratorFn = require('getIteratorFn'); -var invariant = require('invariant'); -var warning = require('warning'); - -var SEPARATOR = ReactInstanceHandles.SEPARATOR; -var SUBSEPARATOR = ':'; - -/** - * TODO: Test that a single child and an array with one item have the same key - * pattern. - */ - -var userProvidedKeyEscaperLookup = { - '=': '=0', - '.': '=1', - ':': '=2' -}; - -var userProvidedKeyEscapeRegex = /[=.:]/g; - -var didWarnAboutMaps = false; - -function userProvidedKeyEscaper(match) { - return userProvidedKeyEscaperLookup[match]; -} - -/** - * Generate a key string that identifies a component within a set. - * - * @param {*} component A component that could contain a manual key. - * @param {number} index Index that is used if a manual key is not provided. - * @return {string} - */ -function getComponentKey(component, index) { - if (component && component.key != null) { - // Explicit key - return wrapUserProvidedKey(component.key); - } - // Implicit key determined by the index in the set - return index.toString(36); -} - -/** - * Escape a component key so that it is safe to use in a reactid. - * - * @param {*} key Component key to be escaped. - * @return {string} An escaped string. - */ -function escapeUserProvidedKey(text) { - return ('' + text).replace( - userProvidedKeyEscapeRegex, - userProvidedKeyEscaper - ); -} - -/** - * Wrap a `key` value explicitly provided by the user to distinguish it from - * implicitly-generated keys generated by a component's index in its parent. - * - * @param {string} key Value of a user-provided `key` attribute - * @return {string} - */ -function wrapUserProvidedKey(key) { - return '$' + escapeUserProvidedKey(key); -} - -/** - * @param {?*} children Children tree container. - * @param {!string} nameSoFar Name of the key path so far. - * @param {!number} indexSoFar Number of children encountered until this point. - * @param {!function} callback Callback to invoke with each child found. - * @param {?*} traverseContext Used to pass information throughout the traversal - * process. - * @return {!number} The number of children in this subtree. - */ -function traverseAllChildrenImpl( - children, - nameSoFar, - indexSoFar, - callback, - traverseContext -) { - var type = typeof children; - - if (type === 'undefined' || type === 'boolean') { - // All of the above are perceived as null. - children = null; - } - - if (children === null || - type === 'string' || - type === 'number' || - ReactElement.isValidElement(children)) { - callback( - traverseContext, - children, - // If it's the only child, treat the name as if it was wrapped in an array - // so that it's consistent if the number of children grows. - nameSoFar === '' ? SEPARATOR + getComponentKey(children, 0) : nameSoFar, - indexSoFar - ); - return 1; - } - - var child, nextName, nextIndex; - var subtreeCount = 0; // Count of children found in the current subtree. - - if (Array.isArray(children)) { - for (var i = 0; i < children.length; i++) { - child = children[i]; - nextName = ( - (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + - getComponentKey(child, i) - ); - nextIndex = indexSoFar + subtreeCount; - subtreeCount += traverseAllChildrenImpl( - child, - nextName, - nextIndex, - callback, - traverseContext - ); - } - } else { - var iteratorFn = getIteratorFn(children); - if (iteratorFn) { - var iterator = iteratorFn.call(children); - var step; - if (iteratorFn !== children.entries) { - var ii = 0; - while (!(step = iterator.next()).done) { - child = step.value; - nextName = ( - (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + - getComponentKey(child, ii++) - ); - nextIndex = indexSoFar + subtreeCount; - subtreeCount += traverseAllChildrenImpl( - child, - nextName, - nextIndex, - callback, - traverseContext - ); - } - } else { - if (__DEV__) { - warning( - didWarnAboutMaps, - 'Using Maps as children is not yet fully supported. It is an ' + - 'experimental feature that might be removed. Convert it to a ' + - 'sequence / iterable of keyed ReactElements instead.' - ); - didWarnAboutMaps = true; - } - // Iterator will provide entry [k,v] tuples rather than values. - while (!(step = iterator.next()).done) { - var entry = step.value; - if (entry) { - child = entry[1]; - nextName = ( - (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + - wrapUserProvidedKey(entry[0]) + SUBSEPARATOR + - getComponentKey(child, 0) - ); - nextIndex = indexSoFar + subtreeCount; - subtreeCount += traverseAllChildrenImpl( - child, - nextName, - nextIndex, - callback, - traverseContext - ); - } - } - } - } else if (type === 'object') { - invariant( - children.nodeType !== 1, - 'traverseAllChildren(...): Encountered an invalid child; DOM ' + - 'elements are not valid children of React components.' - ); - var fragment = ReactFragment.extract(children); - for (var key in fragment) { - if (fragment.hasOwnProperty(key)) { - child = fragment[key]; - nextName = ( - (nameSoFar !== '' ? nameSoFar + SUBSEPARATOR : SEPARATOR) + - wrapUserProvidedKey(key) + SUBSEPARATOR + - getComponentKey(child, 0) - ); - nextIndex = indexSoFar + subtreeCount; - subtreeCount += traverseAllChildrenImpl( - child, - nextName, - nextIndex, - callback, - traverseContext - ); - } - } - } - } - - return subtreeCount; -} - -/** - * Traverses children that are typically specified as `props.children`, but - * might also be specified through attributes: - * - * - `traverseAllChildren(this.props.children, ...)` - * - `traverseAllChildren(this.props.leftPanelChildren, ...)` - * - * The `traverseContext` is an optional argument that is passed through the - * entire traversal. It can be used to store accumulations or anything else that - * the callback might find relevant. - * - * @param {?*} children Children tree object. - * @param {!function} callback To invoke upon traversing each child. - * @param {?*} traverseContext Context for traversal. - * @return {!number} The number of children in this subtree. - */ -function traverseAllChildren(children, callback, traverseContext) { - if (children == null) { - return 0; - } - - return traverseAllChildrenImpl(children, '', 0, callback, traverseContext); -} - -module.exports = traverseAllChildren; -}); -__d('ReactInstanceHandles',["ReactRootIndex","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2014 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @providesModule ReactInstanceHandles - * @typechecks static-only - */ - -"use strict"; - -var ReactRootIndex = require('ReactRootIndex'); - -var invariant = require('invariant'); - -var SEPARATOR = '.'; -var SEPARATOR_LENGTH = SEPARATOR.length; - -/** - * Maximum depth of traversals before we consider the possibility of a bad ID. - */ -var MAX_TREE_DEPTH = 100; - -/** - * Creates a DOM ID prefix to use when mounting React components. - * - * @param {number} index A unique integer - * @return {string} React root ID. - * @internal - */ -function getReactRootIDString(index) { - return SEPARATOR + index.toString(36); -} - -/** - * Checks if a character in the supplied ID is a separator or the end. - * - * @param {string} id A React DOM ID. - * @param {number} index Index of the character to check. - * @return {boolean} True if the character is a separator or end of the ID. - * @private - */ -function isBoundary(id, index) { - return id.charAt(index) === SEPARATOR || index === id.length; -} - -/** - * Checks if the supplied string is a valid React DOM ID. - * - * @param {string} id A React DOM ID, maybe. - * @return {boolean} True if the string is a valid React DOM ID. - * @private - */ -function isValidID(id) { - return id === '' || ( - id.charAt(0) === SEPARATOR && id.charAt(id.length - 1) !== SEPARATOR - ); -} - -/** - * Checks if the first ID is an ancestor of or equal to the second ID. - * - * @param {string} ancestorID - * @param {string} descendantID - * @return {boolean} True if `ancestorID` is an ancestor of `descendantID`. - * @internal - */ -function isAncestorIDOf(ancestorID, descendantID) { - return ( - descendantID.indexOf(ancestorID) === 0 && - isBoundary(descendantID, ancestorID.length) - ); -} - -/** - * Gets the parent ID of the supplied React DOM ID, `id`. - * - * @param {string} id ID of a component. - * @return {string} ID of the parent, or an empty string. - * @private - */ -function getParentID(id) { - return id ? id.substr(0, id.lastIndexOf(SEPARATOR)) : ''; -} - -/** - * Gets the next DOM ID on the tree path from the supplied `ancestorID` to the - * supplied `destinationID`. If they are equal, the ID is returned. - * - * @param {string} ancestorID ID of an ancestor node of `destinationID`. - * @param {string} destinationID ID of the destination node. - * @return {string} Next ID on the path from `ancestorID` to `destinationID`. - * @private - */ -function getNextDescendantID(ancestorID, destinationID) { - invariant( - isValidID(ancestorID) && isValidID(destinationID), - 'getNextDescendantID(%s, %s): Received an invalid React DOM ID.', - ancestorID, - destinationID - ); - invariant( - isAncestorIDOf(ancestorID, destinationID), - 'getNextDescendantID(...): React has made an invalid assumption about ' + - 'the DOM hierarchy. Expected `%s` to be an ancestor of `%s`.', - ancestorID, - destinationID - ); - if (ancestorID === destinationID) { - return ancestorID; - } - // Skip over the ancestor and the immediate separator. Traverse until we hit - // another separator or we reach the end of `destinationID`. - var start = ancestorID.length + SEPARATOR_LENGTH; - for (var i = start; i < destinationID.length; i++) { - if (isBoundary(destinationID, i)) { - break; - } - } - return destinationID.substr(0, i); -} - -/** - * Gets the nearest common ancestor ID of two IDs. - * - * Using this ID scheme, the nearest common ancestor ID is the longest common - * prefix of the two IDs that immediately preceded a "marker" in both strings. - * - * @param {string} oneID - * @param {string} twoID - * @return {string} Nearest common ancestor ID, or the empty string if none. - * @private - */ -function getFirstCommonAncestorID(oneID, twoID) { - var minLength = Math.min(oneID.length, twoID.length); - if (minLength === 0) { - return ''; - } - var lastCommonMarkerIndex = 0; - // Use `<=` to traverse until the "EOL" of the shorter string. - for (var i = 0; i <= minLength; i++) { - if (isBoundary(oneID, i) && isBoundary(twoID, i)) { - lastCommonMarkerIndex = i; - } else if (oneID.charAt(i) !== twoID.charAt(i)) { - break; - } - } - var longestCommonID = oneID.substr(0, lastCommonMarkerIndex); - invariant( - isValidID(longestCommonID), - 'getFirstCommonAncestorID(%s, %s): Expected a valid React DOM ID: %s', - oneID, - twoID, - longestCommonID - ); - return longestCommonID; -} - -/** - * Traverses the parent path between two IDs (either up or down). The IDs must - * not be the same, and there must exist a parent path between them. If the - * callback returns `false`, traversal is stopped. - * - * @param {?string} start ID at which to start traversal. - * @param {?string} stop ID at which to end traversal. - * @param {function} cb Callback to invoke each ID with. - * @param {?boolean} skipFirst Whether or not to skip the first node. - * @param {?boolean} skipLast Whether or not to skip the last node. - * @private - */ -function traverseParentPath(start, stop, cb, arg, skipFirst, skipLast) { - start = start || ''; - stop = stop || ''; - invariant( - start !== stop, - 'traverseParentPath(...): Cannot traverse from and to the same ID, `%s`.', - start - ); - var traverseUp = isAncestorIDOf(stop, start); - invariant( - traverseUp || isAncestorIDOf(start, stop), - 'traverseParentPath(%s, %s, ...): Cannot traverse from two IDs that do ' + - 'not have a parent path.', - start, - stop - ); - // Traverse from `start` to `stop` one depth at a time. - var depth = 0; - var traverse = traverseUp ? getParentID : getNextDescendantID; - for (var id = start; /* until break */; id = traverse(id, stop)) { - var ret; - if ((!skipFirst || id !== start) && (!skipLast || id !== stop)) { - ret = cb(id, traverseUp, arg); - } - if (ret === false || id === stop) { - // Only break //after// visiting `stop`. - break; - } - invariant( - depth++ < MAX_TREE_DEPTH, - 'traverseParentPath(%s, %s, ...): Detected an infinite loop while ' + - 'traversing the React DOM ID tree. This may be due to malformed IDs: %s', - start, stop - ); - } -} - -/** - * Manages the IDs assigned to DOM representations of React components. This - * uses a specific scheme in order to traverse the DOM efficiently (e.g. in - * order to simulate events). - * - * @internal - */ -var ReactInstanceHandles = { - - /** - * Constructs a React root ID - * @return {string} A React root ID. - */ - createReactRootID: function() { - return getReactRootIDString(ReactRootIndex.createReactRootIndex()); - }, - - /** - * Constructs a React ID by joining a root ID with a name. - * - * @param {string} rootID Root ID of a parent component. - * @param {string} name A component's name (as flattened children). - * @return {string} A React ID. - * @internal - */ - createReactID: function(rootID, name) { - return rootID + name; - }, - - /** - * Gets the DOM ID of the React component that is the root of the tree that - * contains the React component with the supplied DOM ID. - * - * @param {string} id DOM ID of a React component. - * @return {?string} DOM ID of the React component that is the root. - * @internal - */ - getReactRootIDFromNodeID: function(id) { - if (id && id.charAt(0) === SEPARATOR && id.length > 1) { - var index = id.indexOf(SEPARATOR, 1); - return index > -1 ? id.substr(0, index) : id; - } - return null; - }, - - /** - * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that - * should would receive a `mouseEnter` or `mouseLeave` event. - * - * NOTE: Does not invoke the callback on the nearest common ancestor because - * nothing "entered" or "left" that element. - * - * @param {string} leaveID ID being left. - * @param {string} enterID ID being entered. - * @param {function} cb Callback to invoke on each entered/left ID. - * @param {*} upArg Argument to invoke the callback with on left IDs. - * @param {*} downArg Argument to invoke the callback with on entered IDs. - * @internal - */ - traverseEnterLeave: function(leaveID, enterID, cb, upArg, downArg) { - var ancestorID = getFirstCommonAncestorID(leaveID, enterID); - if (ancestorID !== leaveID) { - traverseParentPath(leaveID, ancestorID, cb, upArg, false, true); - } - if (ancestorID !== enterID) { - traverseParentPath(ancestorID, enterID, cb, downArg, true, false); - } - }, - - /** - * Simulates the traversal of a two-phase, capture/bubble event dispatch. - * - * NOTE: This traversal happens on IDs without touching the DOM. - * - * @param {string} targetID ID of the target node. - * @param {function} cb Callback to invoke. - * @param {*} arg Argument to invoke the callback with. - * @internal - */ - traverseTwoPhase: function(targetID, cb, arg) { - if (targetID) { - traverseParentPath('', targetID, cb, arg, true, false); - traverseParentPath(targetID, '', cb, arg, false, true); - } - }, - - /** - * Same as `traverseTwoPhase` but skips the `targetID`. - */ - traverseTwoPhaseSkipTarget: function(targetID, cb, arg) { - if (targetID) { - traverseParentPath('', targetID, cb, arg, true, true); - traverseParentPath(targetID, '', cb, arg, true, true); - } - }, - - /** - * Traverse a node ID, calling the supplied `cb` for each ancestor ID. For - * example, passing `.0.$row-0.1` would result in `cb` getting called - * with `.0`, `.0.$row-0`, and `.0.$row-0.1`. - * - * NOTE: This traversal happens on IDs without touching the DOM. - * - * @param {string} targetID ID of the target node. - * @param {function} cb Callback to invoke. - * @param {*} arg Argument to invoke the callback with. - * @internal - */ - traverseAncestors: function(targetID, cb, arg) { - traverseParentPath('', targetID, cb, arg, true, false); - }, - - /** - * Exposed for unit testing. - * @private - */ - _getFirstCommonAncestorID: getFirstCommonAncestorID, - - /** - * Exposed for unit testing. - * @private - */ - _getNextDescendantID: getNextDescendantID, - - isAncestorIDOf: isAncestorIDOf, - - SEPARATOR: SEPARATOR - -}; - -module.exports = ReactInstanceHandles; -}); -__d('ReactRootIndex',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactRootIndex - * @typechecks - */ - -'use strict'; - -var ReactRootIndexInjection = { - /** - * @param {function} _createReactRootIndex - */ - injectCreateReactRootIndex: function(_createReactRootIndex) { - ReactRootIndex.createReactRootIndex = _createReactRootIndex; - } -}; - -var ReactRootIndex = { - createReactRootIndex: null, - injection: ReactRootIndexInjection -}; - -module.exports = ReactRootIndex; -}); -__d('getIteratorFn',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 getIteratorFn - * @typechecks static-only - */ - -'use strict'; - -/* global Symbol */ -var ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator; -var FAUX_ITERATOR_SYMBOL = '@@iterator'; // Before Symbol spec. - -/** - * Returns the iterator method function contained on the iterable object. - * - * Be sure to invoke the function with the iterable as context: - * - * var iteratorFn = getIteratorFn(myIterable); - * if (iteratorFn) { - * var iterator = iteratorFn.call(myIterable); - * ... - * } - * - * @param {?object} maybeIterable - * @return {?function} - */ -function getIteratorFn(maybeIterable) { - var iteratorFn = maybeIterable && ( - (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL]) || - maybeIterable[FAUX_ITERATOR_SYMBOL] - ); - if (typeof iteratorFn === 'function') { - return iteratorFn; - } -} - -module.exports = getIteratorFn; -}); -__d('ReactClass',["ReactComponent","ReactCurrentOwner","ReactElement","ReactErrorUtils","ReactInstanceMap","ReactLifeCycle","ReactPropTypeLocations","ReactPropTypeLocationNames","ReactUpdateQueue","Object.assign","invariant","keyMirror","keyOf","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactClass - */ - -'use strict'; - -var ReactComponent = require('ReactComponent'); -var ReactCurrentOwner = require('ReactCurrentOwner'); -var ReactElement = require('ReactElement'); -var ReactErrorUtils = require('ReactErrorUtils'); -var ReactInstanceMap = require('ReactInstanceMap'); -var ReactLifeCycle = require('ReactLifeCycle'); -var ReactPropTypeLocations = require('ReactPropTypeLocations'); -var ReactPropTypeLocationNames = require('ReactPropTypeLocationNames'); -var ReactUpdateQueue = require('ReactUpdateQueue'); - -var assign = require('Object.assign'); -var invariant = require('invariant'); -var keyMirror = require('keyMirror'); -var keyOf = require('keyOf'); -var warning = require('warning'); - -var MIXINS_KEY = keyOf({mixins: null}); - -/** - * Policies that describe methods in `ReactClassInterface`. - */ -var SpecPolicy = keyMirror({ - /** - * These methods may be defined only once by the class specification or mixin. - */ - DEFINE_ONCE: null, - /** - * These methods may be defined by both the class specification and mixins. - * Subsequent definitions will be chained. These methods must return void. - */ - DEFINE_MANY: null, - /** - * These methods are overriding the base class. - */ - OVERRIDE_BASE: null, - /** - * These methods are similar to DEFINE_MANY, except we assume they return - * objects. We try to merge the keys of the return values of all the mixed in - * functions. If there is a key conflict we throw. - */ - DEFINE_MANY_MERGED: null -}); - - -var injectedMixins = []; - -/** - * Composite components are higher-level components that compose other composite - * or native components. - * - * To create a new type of `ReactClass`, pass a specification of - * your new class to `React.createClass`. The only requirement of your class - * specification is that you implement a `render` method. - * - * var MyComponent = React.createClass({ - * render: function() { - * return
Hello World
; - * } - * }); - * - * The class specification supports a specific protocol of methods that have - * special meaning (e.g. `render`). See `ReactClassInterface` for - * more the comprehensive protocol. Any other properties and methods in the - * class specification will available on the prototype. - * - * @interface ReactClassInterface - * @internal - */ -var ReactClassInterface = { - - /** - * An array of Mixin objects to include when defining your component. - * - * @type {array} - * @optional - */ - mixins: SpecPolicy.DEFINE_MANY, - - /** - * An object containing properties and methods that should be defined on - * the component's constructor instead of its prototype (static methods). - * - * @type {object} - * @optional - */ - statics: SpecPolicy.DEFINE_MANY, - - /** - * Definition of prop types for this component. - * - * @type {object} - * @optional - */ - propTypes: SpecPolicy.DEFINE_MANY, - - /** - * Definition of context types for this component. - * - * @type {object} - * @optional - */ - contextTypes: SpecPolicy.DEFINE_MANY, - - /** - * Definition of context types this component sets for its children. - * - * @type {object} - * @optional - */ - childContextTypes: SpecPolicy.DEFINE_MANY, - - // ==== Definition methods ==== - - /** - * Invoked when the component is mounted. Values in the mapping will be set on - * `this.props` if that prop is not specified (i.e. using an `in` check). - * - * This method is invoked before `getInitialState` and therefore cannot rely - * on `this.state` or use `this.setState`. - * - * @return {object} - * @optional - */ - getDefaultProps: SpecPolicy.DEFINE_MANY_MERGED, - - /** - * Invoked once before the component is mounted. The return value will be used - * as the initial value of `this.state`. - * - * getInitialState: function() { - * return { - * isOn: false, - * fooBaz: new BazFoo() - * } - * } - * - * @return {object} - * @optional - */ - getInitialState: SpecPolicy.DEFINE_MANY_MERGED, - - /** - * @return {object} - * @optional - */ - getChildContext: SpecPolicy.DEFINE_MANY_MERGED, - - /** - * Uses props from `this.props` and state from `this.state` to render the - * structure of the component. - * - * No guarantees are made about when or how often this method is invoked, so - * it must not have side effects. - * - * render: function() { - * var name = this.props.name; - * return
Hello, {name}!
; - * } - * - * @return {ReactComponent} - * @nosideeffects - * @required - */ - render: SpecPolicy.DEFINE_ONCE, - - - - // ==== Delegate methods ==== - - /** - * Invoked when the component is initially created and about to be mounted. - * This may have side effects, but any external subscriptions or data created - * by this method must be cleaned up in `componentWillUnmount`. - * - * @optional - */ - componentWillMount: SpecPolicy.DEFINE_MANY, - - /** - * Invoked when the component has been mounted and has a DOM representation. - * However, there is no guarantee that the DOM node is in the document. - * - * Use this as an opportunity to operate on the DOM when the component has - * been mounted (initialized and rendered) for the first time. - * - * @param {DOMElement} rootNode DOM element representing the component. - * @optional - */ - componentDidMount: SpecPolicy.DEFINE_MANY, - - /** - * Invoked before the component receives new props. - * - * Use this as an opportunity to react to a prop transition by updating the - * state using `this.setState`. Current props are accessed via `this.props`. - * - * componentWillReceiveProps: function(nextProps, nextContext) { - * this.setState({ - * likesIncreasing: nextProps.likeCount > this.props.likeCount - * }); - * } - * - * NOTE: There is no equivalent `componentWillReceiveState`. An incoming prop - * transition may cause a state change, but the opposite is not true. If you - * need it, you are probably looking for `componentWillUpdate`. - * - * @param {object} nextProps - * @optional - */ - componentWillReceiveProps: SpecPolicy.DEFINE_MANY, - - /** - * Invoked while deciding if the component should be updated as a result of - * receiving new props, state and/or context. - * - * Use this as an opportunity to `return false` when you're certain that the - * transition to the new props/state/context will not require a component - * update. - * - * shouldComponentUpdate: function(nextProps, nextState, nextContext) { - * return !equal(nextProps, this.props) || - * !equal(nextState, this.state) || - * !equal(nextContext, this.context); - * } - * - * @param {object} nextProps - * @param {?object} nextState - * @param {?object} nextContext - * @return {boolean} True if the component should update. - * @optional - */ - shouldComponentUpdate: SpecPolicy.DEFINE_ONCE, - - /** - * Invoked when the component is about to update due to a transition from - * `this.props`, `this.state` and `this.context` to `nextProps`, `nextState` - * and `nextContext`. - * - * Use this as an opportunity to perform preparation before an update occurs. - * - * NOTE: You **cannot** use `this.setState()` in this method. - * - * @param {object} nextProps - * @param {?object} nextState - * @param {?object} nextContext - * @param {ReactReconcileTransaction} transaction - * @optional - */ - componentWillUpdate: SpecPolicy.DEFINE_MANY, - - /** - * Invoked when the component's DOM representation has been updated. - * - * Use this as an opportunity to operate on the DOM when the component has - * been updated. - * - * @param {object} prevProps - * @param {?object} prevState - * @param {?object} prevContext - * @param {DOMElement} rootNode DOM element representing the component. - * @optional - */ - componentDidUpdate: SpecPolicy.DEFINE_MANY, - - /** - * Invoked when the component is about to be removed from its parent and have - * its DOM representation destroyed. - * - * Use this as an opportunity to deallocate any external resources. - * - * NOTE: There is no `componentDidUnmount` since your component will have been - * destroyed by that point. - * - * @optional - */ - componentWillUnmount: SpecPolicy.DEFINE_MANY, - - - - // ==== Advanced methods ==== - - /** - * Updates the component's currently mounted DOM representation. - * - * By default, this implements React's rendering and reconciliation algorithm. - * Sophisticated clients may wish to override this. - * - * @param {ReactReconcileTransaction} transaction - * @internal - * @overridable - */ - updateComponent: SpecPolicy.OVERRIDE_BASE - -}; - -/** - * Mapping from class specification keys to special processing functions. - * - * Although these are declared like instance properties in the specification - * when defining classes using `React.createClass`, they are actually static - * and are accessible on the constructor instead of the prototype. Despite - * being static, they must be defined outside of the "statics" key under - * which all other static methods are defined. - */ -var RESERVED_SPEC_KEYS = { - displayName: function(Constructor, displayName) { - Constructor.displayName = displayName; - }, - mixins: function(Constructor, mixins) { - if (mixins) { - for (var i = 0; i < mixins.length; i++) { - mixSpecIntoComponent(Constructor, mixins[i]); - } - } - }, - childContextTypes: function(Constructor, childContextTypes) { - if (__DEV__) { - validateTypeDef( - Constructor, - childContextTypes, - ReactPropTypeLocations.childContext - ); - } - Constructor.childContextTypes = assign( - {}, - Constructor.childContextTypes, - childContextTypes - ); - }, - contextTypes: function(Constructor, contextTypes) { - if (__DEV__) { - validateTypeDef( - Constructor, - contextTypes, - ReactPropTypeLocations.context - ); - } - Constructor.contextTypes = assign( - {}, - Constructor.contextTypes, - contextTypes - ); - }, - /** - * Special case getDefaultProps which should move into statics but requires - * automatic merging. - */ - getDefaultProps: function(Constructor, getDefaultProps) { - if (Constructor.getDefaultProps) { - Constructor.getDefaultProps = createMergedResultFunction( - Constructor.getDefaultProps, - getDefaultProps - ); - } else { - Constructor.getDefaultProps = getDefaultProps; - } - }, - propTypes: function(Constructor, propTypes) { - if (__DEV__) { - validateTypeDef( - Constructor, - propTypes, - ReactPropTypeLocations.prop - ); - } - Constructor.propTypes = assign( - {}, - Constructor.propTypes, - propTypes - ); - }, - statics: function(Constructor, statics) { - mixStaticSpecIntoComponent(Constructor, statics); - } -}; - -function validateTypeDef(Constructor, typeDef, location) { - for (var propName in typeDef) { - if (typeDef.hasOwnProperty(propName)) { - // use a warning instead of an invariant so components - // don't show up in prod but not in __DEV__ - warning( - typeof typeDef[propName] === 'function', - '%s: %s type `%s` is invalid; it must be a function, usually from ' + - 'React.PropTypes.', - Constructor.displayName || 'ReactClass', - ReactPropTypeLocationNames[location], - propName - ); - } - } -} - -function validateMethodOverride(proto, name) { - var specPolicy = ReactClassInterface.hasOwnProperty(name) ? - ReactClassInterface[name] : - null; - - // Disallow overriding of base class methods unless explicitly allowed. - if (ReactClassMixin.hasOwnProperty(name)) { - invariant( - specPolicy === SpecPolicy.OVERRIDE_BASE, - 'ReactClassInterface: You are attempting to override ' + - '`%s` from your class specification. Ensure that your method names ' + - 'do not overlap with React methods.', - name - ); - } - - // Disallow defining methods more than once unless explicitly allowed. - if (proto.hasOwnProperty(name)) { - invariant( - specPolicy === SpecPolicy.DEFINE_MANY || - specPolicy === SpecPolicy.DEFINE_MANY_MERGED, - 'ReactClassInterface: You are attempting to define ' + - '`%s` on your component more than once. This conflict may be due ' + - 'to a mixin.', - name - ); - } -} - -/** - * Mixin helper which handles policy validation and reserved - * specification keys when building React classses. - */ -function mixSpecIntoComponent(Constructor, spec) { - if (!spec) { - return; - } - - invariant( - typeof spec !== 'function', - 'ReactClass: You\'re attempting to ' + - 'use a component class as a mixin. Instead, just use a regular object.' - ); - invariant( - !ReactElement.isValidElement(spec), - 'ReactClass: You\'re attempting to ' + - 'use a component as a mixin. Instead, just use a regular object.' - ); - - var proto = Constructor.prototype; - - // By handling mixins before any other properties, we ensure the same - // chaining order is applied to methods with DEFINE_MANY policy, whether - // mixins are listed before or after these methods in the spec. - if (spec.hasOwnProperty(MIXINS_KEY)) { - RESERVED_SPEC_KEYS.mixins(Constructor, spec.mixins); - } - - for (var name in spec) { - if (!spec.hasOwnProperty(name)) { - continue; - } - - if (name === MIXINS_KEY) { - // We have already handled mixins in a special case above - continue; - } - - var property = spec[name]; - validateMethodOverride(proto, name); - - if (RESERVED_SPEC_KEYS.hasOwnProperty(name)) { - RESERVED_SPEC_KEYS[name](Constructor, property); - } else { - // Setup methods on prototype: - // The following member methods should not be automatically bound: - // 1. Expected ReactClass methods (in the "interface"). - // 2. Overridden methods (that were mixed in). - var isReactClassMethod = - ReactClassInterface.hasOwnProperty(name); - var isAlreadyDefined = proto.hasOwnProperty(name); - var markedDontBind = property && property.__reactDontBind; - var isFunction = typeof property === 'function'; - var shouldAutoBind = - isFunction && - !isReactClassMethod && - !isAlreadyDefined && - !markedDontBind; - - if (shouldAutoBind) { - if (!proto.__reactAutoBindMap) { - proto.__reactAutoBindMap = {}; - } - proto.__reactAutoBindMap[name] = property; - proto[name] = property; - } else { - if (isAlreadyDefined) { - var specPolicy = ReactClassInterface[name]; - - // These cases should already be caught by validateMethodOverride - invariant( - isReactClassMethod && ( - specPolicy === SpecPolicy.DEFINE_MANY_MERGED || - specPolicy === SpecPolicy.DEFINE_MANY - ), - 'ReactClass: Unexpected spec policy %s for key %s ' + - 'when mixing in component specs.', - specPolicy, - name - ); - - // For methods which are defined more than once, call the existing - // methods before calling the new property, merging if appropriate. - if (specPolicy === SpecPolicy.DEFINE_MANY_MERGED) { - proto[name] = createMergedResultFunction(proto[name], property); - } else if (specPolicy === SpecPolicy.DEFINE_MANY) { - proto[name] = createChainedFunction(proto[name], property); - } - } else { - proto[name] = property; - if (__DEV__) { - // Add verbose displayName to the function, which helps when looking - // at profiling tools. - if (typeof property === 'function' && spec.displayName) { - proto[name].displayName = spec.displayName + '_' + name; - } - } - } - } - } - } -} - -function mixStaticSpecIntoComponent(Constructor, statics) { - if (!statics) { - return; - } - for (var name in statics) { - var property = statics[name]; - if (!statics.hasOwnProperty(name)) { - continue; - } - - var isReserved = name in RESERVED_SPEC_KEYS; - invariant( - !isReserved, - 'ReactClass: You are attempting to define a reserved ' + - 'property, `%s`, that shouldn\'t be on the "statics" key. Define it ' + - 'as an instance property instead; it will still be accessible on the ' + - 'constructor.', - name - ); - - var isInherited = name in Constructor; - invariant( - !isInherited, - 'ReactClass: You are attempting to define ' + - '`%s` on your component more than once. This conflict may be ' + - 'due to a mixin.', - name - ); - Constructor[name] = property; - } -} - -/** - * Merge two objects, but throw if both contain the same key. - * - * @param {object} one The first object, which is mutated. - * @param {object} two The second object - * @return {object} one after it has been mutated to contain everything in two. - */ -function mergeIntoWithNoDuplicateKeys(one, two) { - invariant( - one && two && typeof one === 'object' && typeof two === 'object', - 'mergeIntoWithNoDuplicateKeys(): Cannot merge non-objects.' - ); - - for (var key in two) { - if (two.hasOwnProperty(key)) { - invariant( - one[key] === undefined, - 'mergeIntoWithNoDuplicateKeys(): ' + - 'Tried to merge two objects with the same key: `%s`. This conflict ' + - 'may be due to a mixin; in particular, this may be caused by two ' + - 'getInitialState() or getDefaultProps() methods returning objects ' + - 'with clashing keys.', - key - ); - one[key] = two[key]; - } - } - return one; -} - -/** - * Creates a function that invokes two functions and merges their return values. - * - * @param {function} one Function to invoke first. - * @param {function} two Function to invoke second. - * @return {function} Function that invokes the two argument functions. - * @private - */ -function createMergedResultFunction(one, two) { - return function mergedResult() { - var a = one.apply(this, arguments); - var b = two.apply(this, arguments); - if (a == null) { - return b; - } else if (b == null) { - return a; - } - var c = {}; - mergeIntoWithNoDuplicateKeys(c, a); - mergeIntoWithNoDuplicateKeys(c, b); - return c; - }; -} - -/** - * Creates a function that invokes two functions and ignores their return vales. - * - * @param {function} one Function to invoke first. - * @param {function} two Function to invoke second. - * @return {function} Function that invokes the two argument functions. - * @private - */ -function createChainedFunction(one, two) { - return function chainedFunction() { - one.apply(this, arguments); - two.apply(this, arguments); - }; -} - -/** - * Binds a method to the component. - * - * @param {object} component Component whose method is going to be bound. - * @param {function} method Method to be bound. - * @return {function} The bound method. - */ -function bindAutoBindMethod(component, method) { - var boundMethod = method.bind(component); - if (__DEV__) { - boundMethod.__reactBoundContext = component; - boundMethod.__reactBoundMethod = method; - boundMethod.__reactBoundArguments = null; - var componentName = component.constructor.displayName; - var _bind = boundMethod.bind; - /* eslint-disable block-scoped-var, no-undef */ - boundMethod.bind = function(newThis ) {for (var args=[],$__0=1,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); - // User is trying to bind() an autobound method; we effectively will - // ignore the value of "this" that the user is trying to use, so - // let's warn. - if (newThis !== component && newThis !== null) { - warning( - false, - 'bind(): React component methods may only be bound to the ' + - 'component instance. See %s', - componentName - ); - } else if (!args.length) { - warning( - false, - 'bind(): You are binding a component method to the component. ' + - 'React does this for you automatically in a high-performance ' + - 'way, so you can safely remove this call. See %s', - componentName - ); - return boundMethod; - } - var reboundMethod = _bind.apply(boundMethod, arguments); - reboundMethod.__reactBoundContext = component; - reboundMethod.__reactBoundMethod = method; - reboundMethod.__reactBoundArguments = args; - return reboundMethod; - /* eslint-enable */ - }; - } - return boundMethod; -} - -/** - * Binds all auto-bound methods in a component. - * - * @param {object} component Component whose method is going to be bound. - */ -function bindAutoBindMethods(component) { - for (var autoBindKey in component.__reactAutoBindMap) { - if (component.__reactAutoBindMap.hasOwnProperty(autoBindKey)) { - var method = component.__reactAutoBindMap[autoBindKey]; - component[autoBindKey] = bindAutoBindMethod( - component, - ReactErrorUtils.guard( - method, - component.constructor.displayName + '.' + autoBindKey - ) - ); - } - } -} - -var typeDeprecationDescriptor = { - enumerable: false, - get: function() { - var displayName = this.displayName || this.name || 'Component'; - warning( - false, - '%s.type is deprecated. Use %s directly to access the class.', - displayName, - displayName - ); - Object.defineProperty(this, 'type', { - value: this - }); - return this; - } -}; - -/** - * Add more to the ReactClass base class. These are all legacy features and - * therefore not already part of the modern ReactComponent. - */ -var ReactClassMixin = { - - /** - * TODO: This will be deprecated because state should always keep a consistent - * type signature and the only use case for this, is to avoid that. - */ - replaceState: function(newState, callback) { - ReactUpdateQueue.enqueueReplaceState(this, newState); - if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); - } - }, - - /** - * Checks whether or not this composite component is mounted. - * @return {boolean} True if mounted, false otherwise. - * @protected - * @final - */ - isMounted: function() { - if (__DEV__) { - var owner = ReactCurrentOwner.current; - if (owner !== null) { - warning( - owner._warnedAboutRefsInRender, - '%s is accessing isMounted inside its render() function. ' + - 'render() should be a pure function of props and state. It should ' + - 'never access something that requires stale data from the previous ' + - 'render, such as refs. Move this logic to componentDidMount and ' + - 'componentDidUpdate instead.', - owner.getName() || 'A component' - ); - owner._warnedAboutRefsInRender = true; - } - } - var internalInstance = ReactInstanceMap.get(this); - return ( - internalInstance && - internalInstance !== ReactLifeCycle.currentlyMountingInstance - ); - }, - - /** - * Sets a subset of the props. - * - * @param {object} partialProps Subset of the next props. - * @param {?function} callback Called after props are updated. - * @final - * @public - * @deprecated - */ - setProps: function(partialProps, callback) { - ReactUpdateQueue.enqueueSetProps(this, partialProps); - if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); - } - }, - - /** - * Replace all the props. - * - * @param {object} newProps Subset of the next props. - * @param {?function} callback Called after props are updated. - * @final - * @public - * @deprecated - */ - replaceProps: function(newProps, callback) { - ReactUpdateQueue.enqueueReplaceProps(this, newProps); - if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); - } - } -}; - -var ReactClassComponent = function() {}; -assign( - ReactClassComponent.prototype, - ReactComponent.prototype, - ReactClassMixin -); - -/** - * Module for creating composite components. - * - * @class ReactClass - */ -var ReactClass = { - - /** - * Creates a composite component class given a class specification. - * - * @param {object} spec Class specification (which must define `render`). - * @return {function} Component constructor function. - * @public - */ - createClass: function(spec) { - var Constructor = function(props, context) { - // This constructor is overridden by mocks. The argument is used - // by mocks to assert on what gets mounted. - - if (__DEV__) { - warning( - this instanceof Constructor, - 'Something is calling a React component directly. Use a factory or ' + - 'JSX instead. See: http://fb.me/react-legacyfactory' - ); - } - - // Wire up auto-binding - if (this.__reactAutoBindMap) { - bindAutoBindMethods(this); - } - - this.props = props; - this.context = context; - this.state = null; - - // ReactClasses doesn't have constructors. Instead, they use the - // getInitialState and componentWillMount methods for initialization. - - var initialState = this.getInitialState ? this.getInitialState() : null; - if (__DEV__) { - // We allow auto-mocks to proceed as if they're returning null. - if (typeof initialState === 'undefined' && - this.getInitialState._isMockFunction) { - // This is probably bad practice. Consider warning here and - // deprecating this convenience. - initialState = null; - } - } - invariant( - typeof initialState === 'object' && !Array.isArray(initialState), - '%s.getInitialState(): must return an object or null', - Constructor.displayName || 'ReactCompositeComponent' - ); - - this.state = initialState; - }; - Constructor.prototype = new ReactClassComponent(); - Constructor.prototype.constructor = Constructor; - - injectedMixins.forEach( - mixSpecIntoComponent.bind(null, Constructor) - ); - - mixSpecIntoComponent(Constructor, spec); - - // Initialize the defaultProps property after all mixins have been merged - if (Constructor.getDefaultProps) { - Constructor.defaultProps = Constructor.getDefaultProps(); - } - - if (__DEV__) { - // This is a tag to indicate that the use of these method names is ok, - // since it's used with createClass. If it's not, then it's likely a - // mistake so we'll warn you to use the static property, property - // initializer or constructor respectively. - if (Constructor.getDefaultProps) { - Constructor.getDefaultProps.isReactClassApproved = {}; - } - if (Constructor.prototype.getInitialState) { - Constructor.prototype.getInitialState.isReactClassApproved = {}; - } - } - - invariant( - Constructor.prototype.render, - 'createClass(...): Class specification must implement a `render` method.' - ); - - if (__DEV__) { - warning( - !Constructor.prototype.componentShouldUpdate, - '%s has a method called ' + - 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + - 'The name is phrased as a question because the function is ' + - 'expected to return a value.', - spec.displayName || 'A component' - ); - } - - // Reduce time spent doing lookups by setting these on the prototype. - for (var methodName in ReactClassInterface) { - if (!Constructor.prototype[methodName]) { - Constructor.prototype[methodName] = null; - } - } - - // Legacy hook - Constructor.type = Constructor; - if (__DEV__) { - try { - Object.defineProperty(Constructor, 'type', typeDeprecationDescriptor); - } catch (x) { - // IE will fail on defineProperty (es5-shim/sham too) - } - } - - return Constructor; - }, - - injection: { - injectMixin: function(mixin) { - injectedMixins.push(mixin); - } - } - -}; - -module.exports = ReactClass; -}); -__d('ReactComponent',["ReactUpdateQueue","invariant","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactComponent - */ - -'use strict'; - -var ReactUpdateQueue = require('ReactUpdateQueue'); - -var invariant = require('invariant'); -var warning = require('warning'); - -/** - * Base class helpers for the updating state of a component. - */ -function ReactComponent(props, context) { - this.props = props; - this.context = context; -} - -/** - * Sets a subset of the state. Always use this to mutate - * state. You should treat `this.state` as immutable. - * - * There is no guarantee that `this.state` will be immediately updated, so - * accessing `this.state` after calling this method may return the old value. - * - * There is no guarantee that calls to `setState` will run synchronously, - * as they may eventually be batched together. You can provide an optional - * callback that will be executed when the call to setState is actually - * completed. - * - * When a function is provided to setState, it will be called at some point in - * the future (not synchronously). It will be called with the up to date - * component arguments (state, props, context). These values can be different - * from this.* because your function may be called after receiveProps but before - * shouldComponentUpdate, and this new state, props, and context will not yet be - * assigned to this. - * - * @param {object|function} partialState Next partial state or function to - * produce next partial state to be merged with current state. - * @param {?function} callback Called after state is updated. - * @final - * @protected - */ -ReactComponent.prototype.setState = function(partialState, callback) { - invariant( - typeof partialState === 'object' || - typeof partialState === 'function' || - partialState == null, - 'setState(...): takes an object of state variables to update or a ' + - 'function which returns an object of state variables.' - ); - if (__DEV__) { - warning( - partialState != null, - 'setState(...): You passed an undefined or null state object; ' + - 'instead, use forceUpdate().' - ); - } - ReactUpdateQueue.enqueueSetState(this, partialState); - if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); - } -}; - -/** - * Forces an update. This should only be invoked when it is known with - * certainty that we are **not** in a DOM transaction. - * - * You may want to call this when you know that some deeper aspect of the - * component's state has changed but `setState` was not called. - * - * This will not invoke `shouldComponentUpdate`, but it will invoke - * `componentWillUpdate` and `componentDidUpdate`. - * - * @param {?function} callback Called after update is complete. - * @final - * @protected - */ -ReactComponent.prototype.forceUpdate = function(callback) { - ReactUpdateQueue.enqueueForceUpdate(this); - if (callback) { - ReactUpdateQueue.enqueueCallback(this, callback); - } -}; - -/** - * Deprecated APIs. These APIs used to exist on classic React classes but since - * we would like to deprecate them, we're not going to move them over to this - * modern base class. Instead, we define a getter that warns if it's accessed. - */ -if (__DEV__) { - var deprecatedAPIs = { - getDOMNode: 'getDOMNode', - isMounted: 'isMounted', - replaceProps: 'replaceProps', - replaceState: 'replaceState', - setProps: 'setProps' - }; - var defineDeprecationWarning = function(methodName, displayName) { - try { - Object.defineProperty(ReactComponent.prototype, methodName, { - get: function() { - warning( - false, - '%s(...) is deprecated in plain JavaScript React classes.', - displayName - ); - return undefined; - } - }); - } catch (x) { - // IE will fail on defineProperty (es5-shim/sham too) - } - }; - for (var fnName in deprecatedAPIs) { - if (deprecatedAPIs.hasOwnProperty(fnName)) { - defineDeprecationWarning(fnName, deprecatedAPIs[fnName]); - } - } -} - -module.exports = ReactComponent; -}); -__d('ReactUpdateQueue',["ReactLifeCycle","ReactCurrentOwner","ReactElement","ReactInstanceMap","ReactUpdates","Object.assign","invariant","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2015, 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 ReactUpdateQueue - */ - -'use strict'; - -var ReactLifeCycle = require('ReactLifeCycle'); -var ReactCurrentOwner = require('ReactCurrentOwner'); -var ReactElement = require('ReactElement'); -var ReactInstanceMap = require('ReactInstanceMap'); -var ReactUpdates = require('ReactUpdates'); - -var assign = require('Object.assign'); -var invariant = require('invariant'); -var warning = require('warning'); - -function enqueueUpdate(internalInstance) { - if (internalInstance !== ReactLifeCycle.currentlyMountingInstance) { - // If we're in a componentWillMount handler, don't enqueue a rerender - // because ReactUpdates assumes we're in a browser context (which is - // wrong for server rendering) and we're about to do a render anyway. - // See bug in #1740. - ReactUpdates.enqueueUpdate(internalInstance); - } -} - -function getInternalInstanceReadyForUpdate(publicInstance, callerName) { - invariant( - ReactCurrentOwner.current == null, - '%s(...): Cannot update during an existing state transition ' + - '(such as within `render`). Render methods should be a pure function ' + - 'of props and state.', - callerName - ); - - var internalInstance = ReactInstanceMap.get(publicInstance); - if (!internalInstance) { - if (__DEV__) { - // Only warn when we have a callerName. Otherwise we should be silent. - // We're probably calling from enqueueCallback. We don't want to warn - // there because we already warned for the corresponding lifecycle method. - warning( - !callerName, - '%s(...): Can only update a mounted or mounting component. ' + - 'This usually means you called %s() on an unmounted ' + - 'component. This is a no-op.', - callerName, - callerName - ); - } - return null; - } - - if (internalInstance === ReactLifeCycle.currentlyUnmountingInstance) { - return null; - } - - return internalInstance; -} - -/** - * ReactUpdateQueue allows for state updates to be scheduled into a later - * reconciliation step. - */ -var ReactUpdateQueue = { - - /** - * Enqueue a callback that will be executed after all the pending updates - * have processed. - * - * @param {ReactClass} publicInstance The instance to use as `this` context. - * @param {?function} callback Called after state is updated. - * @internal - */ - enqueueCallback: function(publicInstance, callback) { - invariant( - typeof callback === 'function', - 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + - '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + - 'isn\'t callable.' - ); - var internalInstance = getInternalInstanceReadyForUpdate(publicInstance); - - // Previously we would throw an error if we didn't have an internal - // instance. Since we want to make it a no-op instead, we mirror the same - // behavior we have in other enqueue* methods. - // We also need to ignore callbacks in componentWillMount. See - // enqueueUpdates. - if (!internalInstance || - internalInstance === ReactLifeCycle.currentlyMountingInstance) { - return null; - } - - if (internalInstance._pendingCallbacks) { - internalInstance._pendingCallbacks.push(callback); - } else { - internalInstance._pendingCallbacks = [callback]; - } - // TODO: The callback here is ignored when setState is called from - // componentWillMount. Either fix it or disallow doing so completely in - // favor of getInitialState. Alternatively, we can disallow - // componentWillMount during server-side rendering. - enqueueUpdate(internalInstance); - }, - - enqueueCallbackInternal: function(internalInstance, callback) { - invariant( - typeof callback === 'function', - 'enqueueCallback(...): You called `setProps`, `replaceProps`, ' + - '`setState`, `replaceState`, or `forceUpdate` with a callback that ' + - 'isn\'t callable.' - ); - if (internalInstance._pendingCallbacks) { - internalInstance._pendingCallbacks.push(callback); - } else { - internalInstance._pendingCallbacks = [callback]; - } - enqueueUpdate(internalInstance); - }, - - /** - * Forces an update. This should only be invoked when it is known with - * certainty that we are **not** in a DOM transaction. - * - * You may want to call this when you know that some deeper aspect of the - * component's state has changed but `setState` was not called. - * - * This will not invoke `shouldUpdateComponent`, but it will invoke - * `componentWillUpdate` and `componentDidUpdate`. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @internal - */ - enqueueForceUpdate: function(publicInstance) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'forceUpdate' - ); - - if (!internalInstance) { - return; - } - - internalInstance._pendingForceUpdate = true; - - enqueueUpdate(internalInstance); - }, - - /** - * Replaces all of the state. Always use this or `setState` to mutate state. - * You should treat `this.state` as immutable. - * - * There is no guarantee that `this.state` will be immediately updated, so - * accessing `this.state` after calling this method may return the old value. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} completeState Next state. - * @internal - */ - enqueueReplaceState: function(publicInstance, completeState) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'replaceState' - ); - - if (!internalInstance) { - return; - } - - internalInstance._pendingStateQueue = [completeState]; - internalInstance._pendingReplaceState = true; - - enqueueUpdate(internalInstance); - }, - - /** - * Sets a subset of the state. This only exists because _pendingState is - * internal. This provides a merging strategy that is not available to deep - * properties which is confusing. TODO: Expose pendingState or don't use it - * during the merge. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} partialState Next partial state to be merged with state. - * @internal - */ - enqueueSetState: function(publicInstance, partialState) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'setState' - ); - - if (!internalInstance) { - return; - } - - var queue = - internalInstance._pendingStateQueue || - (internalInstance._pendingStateQueue = []); - queue.push(partialState); - - enqueueUpdate(internalInstance); - }, - - /** - * Sets a subset of the props. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} partialProps Subset of the next props. - * @internal - */ - enqueueSetProps: function(publicInstance, partialProps) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'setProps' - ); - - if (!internalInstance) { - return; - } - - invariant( - internalInstance._isTopLevel, - 'setProps(...): You called `setProps` on a ' + - 'component with a parent. This is an anti-pattern since props will ' + - 'get reactively updated when rendered. Instead, change the owner\'s ' + - '`render` method to pass the correct value as props to the component ' + - 'where it is created.' - ); - - // Merge with the pending element if it exists, otherwise with existing - // element props. - var element = internalInstance._pendingElement || - internalInstance._currentElement; - var props = assign({}, element.props, partialProps); - internalInstance._pendingElement = ReactElement.cloneAndReplaceProps( - element, - props - ); - - enqueueUpdate(internalInstance); - }, - - /** - * Replaces all of the props. - * - * @param {ReactClass} publicInstance The instance that should rerender. - * @param {object} props New props. - * @internal - */ - enqueueReplaceProps: function(publicInstance, props) { - var internalInstance = getInternalInstanceReadyForUpdate( - publicInstance, - 'replaceProps' - ); - - if (!internalInstance) { - return; - } - - invariant( - internalInstance._isTopLevel, - 'replaceProps(...): You called `replaceProps` on a ' + - 'component with a parent. This is an anti-pattern since props will ' + - 'get reactively updated when rendered. Instead, change the owner\'s ' + - '`render` method to pass the correct value as props to the component ' + - 'where it is created.' - ); - - // Merge with the pending element if it exists, otherwise with existing - // element props. - var element = internalInstance._pendingElement || - internalInstance._currentElement; - internalInstance._pendingElement = ReactElement.cloneAndReplaceProps( - element, - props - ); - - enqueueUpdate(internalInstance); - }, - - enqueueElementInternal: function(internalInstance, newElement) { - internalInstance._pendingElement = newElement; - enqueueUpdate(internalInstance); - } - -}; - -module.exports = ReactUpdateQueue; -}); -__d('ReactLifeCycle',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2015, 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 ReactLifeCycle - */ - -'use strict'; - -/** - * This module manages the bookkeeping when a component is in the process - * of being mounted or being unmounted. This is used as a way to enforce - * invariants (or warnings) when it is not recommended to call - * setState/forceUpdate. - * - * currentlyMountingInstance: During the construction phase, it is not possible - * to trigger an update since the instance is not fully mounted yet. However, we - * currently allow this as a convenience for mutating the initial state. - * - * currentlyUnmountingInstance: During the unmounting phase, the instance is - * still mounted and can therefore schedule an update. However, this is not - * recommended and probably an error since it's about to be unmounted. - * Therefore we still want to trigger in an error for that case. - */ - -var ReactLifeCycle = { - currentlyMountingInstance: null, - currentlyUnmountingInstance: null -}; - -module.exports = ReactLifeCycle; -}); -__d('ReactInstanceMap',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactInstanceMap - */ - -'use strict'; - -/** - * `ReactInstanceMap` maintains a mapping from a public facing stateful - * instance (key) and the internal representation (value). This allows public - * methods to accept the user facing instance as an argument and map them back - * to internal methods. - */ - -// TODO: Replace this with ES6: var ReactInstanceMap = new Map(); -var ReactInstanceMap = { - - /** - * This API should be called `delete` but we'd have to make sure to always - * transform these to strings for IE support. When this transform is fully - * supported we can rename it. - */ - remove: function(key) { - key._reactInternalInstance = undefined; - }, - - get: function(key) { - return key._reactInternalInstance; - }, - - has: function(key) { - return key._reactInternalInstance !== undefined; - }, - - set: function(key, value) { - key._reactInternalInstance = value; - } - -}; - -module.exports = ReactInstanceMap; -}); -__d('ReactUpdates',["CallbackQueue","PooledClass","ReactCurrentOwner","ReactPerf","ReactReconciler","Transaction","Object.assign","invariant","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactUpdates - */ - -'use strict'; - -var CallbackQueue = require('CallbackQueue'); -var PooledClass = require('PooledClass'); -var ReactCurrentOwner = require('ReactCurrentOwner'); -var ReactPerf = require('ReactPerf'); -var ReactReconciler = require('ReactReconciler'); -var Transaction = require('Transaction'); - -var assign = require('Object.assign'); -var invariant = require('invariant'); -var warning = require('warning'); - -var dirtyComponents = []; -var asapCallbackQueue = CallbackQueue.getPooled(); -var asapEnqueued = false; - -var batchingStrategy = null; - -function ensureInjected() { - invariant( - ReactUpdates.ReactReconcileTransaction && batchingStrategy, - 'ReactUpdates: must inject a reconcile transaction class and batching ' + - 'strategy' - ); -} - -var NESTED_UPDATES = { - initialize: function() { - this.dirtyComponentsLength = dirtyComponents.length; - }, - close: function() { - if (this.dirtyComponentsLength !== dirtyComponents.length) { - // Additional updates were enqueued by componentDidUpdate handlers or - // similar; before our own UPDATE_QUEUEING wrapper closes, we want to run - // these new updates so that if A's componentDidUpdate calls setState on - // B, B will update before the callback A's updater provided when calling - // setState. - dirtyComponents.splice(0, this.dirtyComponentsLength); - flushBatchedUpdates(); - } else { - dirtyComponents.length = 0; - } - } -}; - -var UPDATE_QUEUEING = { - initialize: function() { - this.callbackQueue.reset(); - }, - close: function() { - this.callbackQueue.notifyAll(); - } -}; - -var TRANSACTION_WRAPPERS = [NESTED_UPDATES, UPDATE_QUEUEING]; - -function ReactUpdatesFlushTransaction() { - this.reinitializeTransaction(); - this.dirtyComponentsLength = null; - this.callbackQueue = CallbackQueue.getPooled(); - this.reconcileTransaction = - ReactUpdates.ReactReconcileTransaction.getPooled(); -} - -assign( - ReactUpdatesFlushTransaction.prototype, - Transaction.Mixin, { - getTransactionWrappers: function() { - return TRANSACTION_WRAPPERS; - }, - - destructor: function() { - this.dirtyComponentsLength = null; - CallbackQueue.release(this.callbackQueue); - this.callbackQueue = null; - ReactUpdates.ReactReconcileTransaction.release(this.reconcileTransaction); - this.reconcileTransaction = null; - }, - - perform: function(method, scope, a) { - // Essentially calls `this.reconcileTransaction.perform(method, scope, a)` - // with this transaction's wrappers around it. - return Transaction.Mixin.perform.call( - this, - this.reconcileTransaction.perform, - this.reconcileTransaction, - method, - scope, - a - ); - } -}); - -PooledClass.addPoolingTo(ReactUpdatesFlushTransaction); - -function batchedUpdates(callback, a, b, c, d) { - ensureInjected(); - batchingStrategy.batchedUpdates(callback, a, b, c, d); -} - -/** - * Array comparator for ReactComponents by mount ordering. - * - * @param {ReactComponent} c1 first component you're comparing - * @param {ReactComponent} c2 second component you're comparing - * @return {number} Return value usable by Array.prototype.sort(). - */ -function mountOrderComparator(c1, c2) { - return c1._mountOrder - c2._mountOrder; -} - -function runBatchedUpdates(transaction) { - var len = transaction.dirtyComponentsLength; - invariant( - len === dirtyComponents.length, - 'Expected flush transaction\'s stored dirty-components length (%s) to ' + - 'match dirty-components array length (%s).', - len, - dirtyComponents.length - ); - - // Since reconciling a component higher in the owner hierarchy usually (not - // always -- see shouldComponentUpdate()) will reconcile children, reconcile - // them before their children by sorting the array. - dirtyComponents.sort(mountOrderComparator); - - for (var i = 0; i < len; i++) { - // If a component is unmounted before pending changes apply, it will still - // be here, but we assume that it has cleared its _pendingCallbacks and - // that performUpdateIfNecessary is a noop. - var component = dirtyComponents[i]; - - // If performUpdateIfNecessary happens to enqueue any new updates, we - // shouldn't execute the callbacks until the next render happens, so - // stash the callbacks first - var callbacks = component._pendingCallbacks; - component._pendingCallbacks = null; - - ReactReconciler.performUpdateIfNecessary( - component, - transaction.reconcileTransaction - ); - - if (callbacks) { - for (var j = 0; j < callbacks.length; j++) { - transaction.callbackQueue.enqueue( - callbacks[j], - component.getPublicInstance() - ); - } - } - } -} - -var flushBatchedUpdates = function() { - // ReactUpdatesFlushTransaction's wrappers will clear the dirtyComponents - // array and perform any updates enqueued by mount-ready handlers (i.e., - // componentDidUpdate) but we need to check here too in order to catch - // updates enqueued by setState callbacks and asap calls. - while (dirtyComponents.length || asapEnqueued) { - if (dirtyComponents.length) { - var transaction = ReactUpdatesFlushTransaction.getPooled(); - transaction.perform(runBatchedUpdates, null, transaction); - ReactUpdatesFlushTransaction.release(transaction); - } - - if (asapEnqueued) { - asapEnqueued = false; - var queue = asapCallbackQueue; - asapCallbackQueue = CallbackQueue.getPooled(); - queue.notifyAll(); - CallbackQueue.release(queue); - } - } -}; -flushBatchedUpdates = ReactPerf.measure( - 'ReactUpdates', - 'flushBatchedUpdates', - flushBatchedUpdates -); - -/** - * Mark a component as needing a rerender, adding an optional callback to a - * list of functions which will be executed once the rerender occurs. - */ -function enqueueUpdate(component) { - ensureInjected(); - - // Various parts of our code (such as ReactCompositeComponent's - // _renderValidatedComponent) assume that calls to render aren't nested; - // verify that that's the case. (This is called by each top-level update - // function, like setProps, setState, forceUpdate, etc.; creation and - // destruction of top-level components is guarded in ReactMount.) - warning( - ReactCurrentOwner.current == null, - 'enqueueUpdate(): Render methods should be a pure function of props ' + - 'and state; triggering nested component updates from render is not ' + - 'allowed. If necessary, trigger nested updates in ' + - 'componentDidUpdate.' - ); - - if (!batchingStrategy.isBatchingUpdates) { - batchingStrategy.batchedUpdates(enqueueUpdate, component); - return; - } - - dirtyComponents.push(component); -} - -/** - * Enqueue a callback to be run at the end of the current batching cycle. Throws - * if no updates are currently being performed. - */ -function asap(callback, context) { - invariant( - batchingStrategy.isBatchingUpdates, - 'ReactUpdates.asap: Can\'t enqueue an asap callback in a context where' + - 'updates are not being batched.' - ); - asapCallbackQueue.enqueue(callback, context); - asapEnqueued = true; -} - -var ReactUpdatesInjection = { - injectReconcileTransaction: function(ReconcileTransaction) { - invariant( - ReconcileTransaction, - 'ReactUpdates: must provide a reconcile transaction class' - ); - ReactUpdates.ReactReconcileTransaction = ReconcileTransaction; - }, - - injectBatchingStrategy: function(_batchingStrategy) { - invariant( - _batchingStrategy, - 'ReactUpdates: must provide a batching strategy' - ); - invariant( - typeof _batchingStrategy.batchedUpdates === 'function', - 'ReactUpdates: must provide a batchedUpdates() function' - ); - invariant( - typeof _batchingStrategy.isBatchingUpdates === 'boolean', - 'ReactUpdates: must provide an isBatchingUpdates boolean attribute' - ); - batchingStrategy = _batchingStrategy; - } -}; - -var ReactUpdates = { - /** - * React references `ReactReconcileTransaction` using this property in order - * to allow dependency injection. - * - * @internal - */ - ReactReconcileTransaction: null, - - batchedUpdates: batchedUpdates, - enqueueUpdate: enqueueUpdate, - flushBatchedUpdates: flushBatchedUpdates, - injection: ReactUpdatesInjection, - asap: asap -}; - -module.exports = ReactUpdates; -}); -__d('CallbackQueue',["PooledClass","Object.assign","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 CallbackQueue - */ - -'use strict'; - -var PooledClass = require('PooledClass'); - -var assign = require('Object.assign'); -var invariant = require('invariant'); - -/** - * A specialized pseudo-event module to help keep track of components waiting to - * be notified when their DOM representations are available for use. - * - * This implements `PooledClass`, so you should never need to instantiate this. - * Instead, use `CallbackQueue.getPooled()`. - * - * @class ReactMountReady - * @implements PooledClass - * @internal - */ -function CallbackQueue() { - this._callbacks = null; - this._contexts = null; -} - -assign(CallbackQueue.prototype, { - - /** - * Enqueues a callback to be invoked when `notifyAll` is invoked. - * - * @param {function} callback Invoked when `notifyAll` is invoked. - * @param {?object} context Context to call `callback` with. - * @internal - */ - enqueue: function(callback, context) { - this._callbacks = this._callbacks || []; - this._contexts = this._contexts || []; - this._callbacks.push(callback); - this._contexts.push(context); - }, - - /** - * Invokes all enqueued callbacks and clears the queue. This is invoked after - * the DOM representation of a component has been created or updated. - * - * @internal - */ - notifyAll: function() { - var callbacks = this._callbacks; - var contexts = this._contexts; - if (callbacks) { - invariant( - callbacks.length === contexts.length, - 'Mismatched list of contexts in callback queue' - ); - this._callbacks = null; - this._contexts = null; - for (var i = 0, l = callbacks.length; i < l; i++) { - callbacks[i].call(contexts[i]); - } - callbacks.length = 0; - contexts.length = 0; - } - }, - - /** - * Resets the internal queue. - * - * @internal - */ - reset: function() { - this._callbacks = null; - this._contexts = null; - }, - - /** - * `PooledClass` looks for this. - */ - destructor: function() { - this.reset(); - } - -}); - -PooledClass.addPoolingTo(CallbackQueue); - -module.exports = CallbackQueue; -}); -__d('ReactPerf',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactPerf - * @typechecks static-only - */ - -'use strict'; - -/** - * ReactPerf is a general AOP system designed to measure performance. This - * module only has the hooks: see ReactDefaultPerf for the analysis tool. - */ -var ReactPerf = { - /** - * Boolean to enable/disable measurement. Set to false by default to prevent - * accidental logging and perf loss. - */ - enableMeasure: false, - - /** - * Holds onto the measure function in use. By default, don't measure - * anything, but we'll override this if we inject a measure function. - */ - storedMeasure: _noMeasure, - - /** - * @param {object} object - * @param {string} objectName - * @param {object} methodNames - */ - measureMethods: function(object, objectName, methodNames) { - if (__DEV__) { - for (var key in methodNames) { - if (!methodNames.hasOwnProperty(key)) { - continue; - } - object[key] = ReactPerf.measure( - objectName, - methodNames[key], - object[key] - ); - } - } - }, - - /** - * Use this to wrap methods you want to measure. Zero overhead in production. - * - * @param {string} objName - * @param {string} fnName - * @param {function} func - * @return {function} - */ - measure: function(objName, fnName, func) { - if (__DEV__) { - var measuredFunc = null; - var wrapper = function() { - if (ReactPerf.enableMeasure) { - if (!measuredFunc) { - measuredFunc = ReactPerf.storedMeasure(objName, fnName, func); - } - return measuredFunc.apply(this, arguments); - } - return func.apply(this, arguments); - }; - wrapper.displayName = objName + '_' + fnName; - return wrapper; - } - return func; - }, - - injection: { - /** - * @param {function} measure - */ - injectMeasure: function(measure) { - ReactPerf.storedMeasure = measure; - } - } -}; - -/** - * Simply passes through the measured function, without measuring it. - * - * @param {string} objName - * @param {string} fnName - * @param {function} func - * @return {function} - */ -function _noMeasure(objName, fnName, func) { - return func; -} - -module.exports = ReactPerf; -}); -__d('ReactReconciler',["ReactRef","ReactElementValidator"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactReconciler - */ - -'use strict'; - -var ReactRef = require('ReactRef'); -var ReactElementValidator = require('ReactElementValidator'); - -/** - * Helper to call ReactRef.attachRefs with this composite component, split out - * to avoid allocations in the transaction mount-ready queue. - */ -function attachRefs() { - ReactRef.attachRefs(this, this._currentElement); -} - -var ReactReconciler = { - - /** - * Initializes the component, renders markup, and registers event listeners. - * - * @param {ReactComponent} internalInstance - * @param {string} rootID DOM ID of the root node. - * @param {ReactReconcileTransaction|ReactServerRenderingTransaction} transaction - * @return {?string} Rendered markup to be inserted into the DOM. - * @final - * @internal - */ - mountComponent: function(internalInstance, rootID, transaction, context) { - var markup = internalInstance.mountComponent(rootID, transaction, context); - if (__DEV__) { - ReactElementValidator.checkAndWarnForMutatedProps( - internalInstance._currentElement - ); - } - transaction.getReactMountReady().enqueue(attachRefs, internalInstance); - return markup; - }, - - /** - * Releases any resources allocated by `mountComponent`. - * - * @final - * @internal - */ - unmountComponent: function(internalInstance) { - ReactRef.detachRefs(internalInstance, internalInstance._currentElement); - internalInstance.unmountComponent(); - }, - - /** - * Update a component using a new element. - * - * @param {ReactComponent} internalInstance - * @param {ReactElement} nextElement - * @param {ReactReconcileTransaction} transaction - * @param {object} context - * @internal - */ - receiveComponent: function( - internalInstance, nextElement, transaction, context - ) { - var prevElement = internalInstance._currentElement; - - if (nextElement === prevElement && nextElement._owner != null) { - // Since elements are immutable after the owner is rendered, - // we can do a cheap identity compare here to determine if this is a - // superfluous reconcile. It's possible for state to be mutable but such - // change should trigger an update of the owner which would recreate - // the element. We explicitly check for the existence of an owner since - // it's possible for an element created outside a composite to be - // deeply mutated and reused. - return; - } - - if (__DEV__) { - ReactElementValidator.checkAndWarnForMutatedProps(nextElement); - } - - var refsChanged = ReactRef.shouldUpdateRefs( - prevElement, - nextElement - ); - - if (refsChanged) { - ReactRef.detachRefs(internalInstance, prevElement); - } - - internalInstance.receiveComponent(nextElement, transaction, context); - - if (refsChanged) { - transaction.getReactMountReady().enqueue(attachRefs, internalInstance); - } - }, - - /** - * Flush any dirty changes in a component. - * - * @param {ReactComponent} internalInstance - * @param {ReactReconcileTransaction} transaction - * @internal - */ - performUpdateIfNecessary: function( - internalInstance, - transaction - ) { - internalInstance.performUpdateIfNecessary(transaction); - } - -}; - -module.exports = ReactReconciler; -}); -__d('ReactRef',["ReactOwner"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactRef - */ - -'use strict'; - -var ReactOwner = require('ReactOwner'); - -var ReactRef = {}; - -function attachRef(ref, component, owner) { - if (typeof ref === 'function') { - ref(component.getPublicInstance()); - } else { - // Legacy ref - ReactOwner.addComponentAsRefTo(component, ref, owner); - } -} - -function detachRef(ref, component, owner) { - if (typeof ref === 'function') { - ref(null); - } else { - // Legacy ref - ReactOwner.removeComponentAsRefFrom(component, ref, owner); - } -} - -ReactRef.attachRefs = function(instance, element) { - var ref = element.ref; - if (ref != null) { - attachRef(ref, instance, element._owner); - } -}; - -ReactRef.shouldUpdateRefs = function(prevElement, nextElement) { - // If either the owner or a `ref` has changed, make sure the newest owner - // has stored a reference to `this`, and the previous owner (if different) - // has forgotten the reference to `this`. We use the element instead - // of the public this.props because the post processing cannot determine - // a ref. The ref conceptually lives on the element. - - // TODO: Should this even be possible? The owner cannot change because - // it's forbidden by shouldUpdateReactComponent. The ref can change - // if you swap the keys of but not the refs. Reconsider where this check - // is made. It probably belongs where the key checking and - // instantiateReactComponent is done. - - return ( - nextElement._owner !== prevElement._owner || - nextElement.ref !== prevElement.ref - ); -}; - -ReactRef.detachRefs = function(instance, element) { - var ref = element.ref; - if (ref != null) { - detachRef(ref, instance, element._owner); - } -}; - -module.exports = ReactRef; -}); -__d('ReactOwner',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactOwner - */ - -'use strict'; - -var invariant = require('invariant'); - -/** - * ReactOwners are capable of storing references to owned components. - * - * All components are capable of //being// referenced by owner components, but - * only ReactOwner components are capable of //referencing// owned components. - * The named reference is known as a "ref". - * - * Refs are available when mounted and updated during reconciliation. - * - * var MyComponent = React.createClass({ - * render: function() { - * return ( - *
- * - *
- * ); - * }, - * handleClick: function() { - * this.refs.custom.handleClick(); - * }, - * componentDidMount: function() { - * this.refs.custom.initialize(); - * } - * }); - * - * Refs should rarely be used. When refs are used, they should only be done to - * control data that is not handled by React's data flow. - * - * @class ReactOwner - */ -var ReactOwner = { - - /** - * @param {?object} object - * @return {boolean} True if `object` is a valid owner. - * @final - */ - isValidOwner: function(object) { - return !!( - object && - typeof object.attachRef === 'function' && - typeof object.detachRef === 'function' - ); - }, - - /** - * Adds a component by ref to an owner component. - * - * @param {ReactComponent} component Component to reference. - * @param {string} ref Name by which to refer to the component. - * @param {ReactOwner} owner Component on which to record the ref. - * @final - * @internal - */ - addComponentAsRefTo: function(component, ref, owner) { - invariant( - ReactOwner.isValidOwner(owner), - 'addComponentAsRefTo(...): Only a ReactOwner can have refs. This ' + - 'usually means that you\'re trying to add a ref to a component that ' + - 'doesn\'t have an owner (that is, was not created inside of another ' + - 'component\'s `render` method). Try rendering this component inside of ' + - 'a new top-level component which will hold the ref.' - ); - owner.attachRef(ref, component); - }, - - /** - * Removes a component by ref from an owner component. - * - * @param {ReactComponent} component Component to dereference. - * @param {string} ref Name of the ref to remove. - * @param {ReactOwner} owner Component on which the ref is recorded. - * @final - * @internal - */ - removeComponentAsRefFrom: function(component, ref, owner) { - invariant( - ReactOwner.isValidOwner(owner), - 'removeComponentAsRefFrom(...): Only a ReactOwner can have refs. This ' + - 'usually means that you\'re trying to remove a ref to a component that ' + - 'doesn\'t have an owner (that is, was not created inside of another ' + - 'component\'s `render` method). Try rendering this component inside of ' + - 'a new top-level component which will hold the ref.' - ); - // Check that `component` is still the current ref because we do not want to - // detach the ref if another component stole it. - if (owner.getPublicInstance().refs[ref] === component.getPublicInstance()) { - owner.detachRef(ref); - } - } - -}; - -module.exports = ReactOwner; -}); -__d('ReactElementValidator',["ReactElement","ReactFragment","ReactPropTypeLocations","ReactPropTypeLocationNames","ReactCurrentOwner","ReactNativeComponent","getIteratorFn","invariant","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2014-2015, 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 ReactElementValidator - */ - -/** - * ReactElementValidator provides a wrapper around a element factory - * which validates the props passed to the element. This is intended to be - * used only in DEV and could be replaced by a static type checker for languages - * that support it. - */ - -'use strict'; - -var ReactElement = require('ReactElement'); -var ReactFragment = require('ReactFragment'); -var ReactPropTypeLocations = require('ReactPropTypeLocations'); -var ReactPropTypeLocationNames = require('ReactPropTypeLocationNames'); -var ReactCurrentOwner = require('ReactCurrentOwner'); -var ReactNativeComponent = require('ReactNativeComponent'); - -var getIteratorFn = require('getIteratorFn'); -var invariant = require('invariant'); -var warning = require('warning'); - -function getDeclarationErrorAddendum() { - if (ReactCurrentOwner.current) { - var name = ReactCurrentOwner.current.getName(); - if (name) { - return ' Check the render method of `' + name + '`.'; - } - } - return ''; -} - -/** - * Warn if there's no key explicitly set on dynamic arrays of children or - * object keys are not valid. This allows us to keep track of children between - * updates. - */ -var ownerHasKeyUseWarning = {}; - -var loggedTypeFailures = {}; - -var NUMERIC_PROPERTY_REGEX = /^\d+$/; - -/** - * Gets the instance's name for use in warnings. - * - * @internal - * @return {?string} Display name or undefined - */ -function getName(instance) { - var publicInstance = instance && instance.getPublicInstance(); - if (!publicInstance) { - return undefined; - } - var constructor = publicInstance.constructor; - if (!constructor) { - return undefined; - } - return constructor.displayName || constructor.name || undefined; -} - -/** - * Gets the current owner's displayName for use in warnings. - * - * @internal - * @return {?string} Display name or undefined - */ -function getCurrentOwnerDisplayName() { - var current = ReactCurrentOwner.current; - return ( - current && getName(current) || undefined - ); -} - -/** - * Warn if the element doesn't have an explicit key assigned to it. - * This element is in an array. The array could grow and shrink or be - * reordered. All children that haven't already been validated are required to - * have a "key" property assigned to it. - * - * @internal - * @param {ReactElement} element Element that requires a key. - * @param {*} parentType element's parent's type. - */ -function validateExplicitKey(element, parentType) { - if (element._store.validated || element.key != null) { - return; - } - element._store.validated = true; - - warnAndMonitorForKeyUse( - 'Each child in an array or iterator should have a unique "key" prop.', - element, - parentType - ); -} - -/** - * Warn if the key is being defined as an object property but has an incorrect - * value. - * - * @internal - * @param {string} name Property name of the key. - * @param {ReactElement} element Component that requires a key. - * @param {*} parentType element's parent's type. - */ -function validatePropertyKey(name, element, parentType) { - if (!NUMERIC_PROPERTY_REGEX.test(name)) { - return; - } - warnAndMonitorForKeyUse( - 'Child objects should have non-numeric keys so ordering is preserved.', - element, - parentType - ); -} - -/** - * Shared warning and monitoring code for the key warnings. - * - * @internal - * @param {string} message The base warning that gets output. - * @param {ReactElement} element Component that requires a key. - * @param {*} parentType element's parent's type. - */ -function warnAndMonitorForKeyUse(message, element, parentType) { - var ownerName = getCurrentOwnerDisplayName(); - var parentName = typeof parentType === 'string' ? - parentType : parentType.displayName || parentType.name; - - var useName = ownerName || parentName; - var memoizer = ownerHasKeyUseWarning[message] || ( - ownerHasKeyUseWarning[message] = {} - ); - if (memoizer.hasOwnProperty(useName)) { - return; - } - memoizer[useName] = true; - - var parentOrOwnerAddendum = - ownerName ? (" Check the render method of " + ownerName + ".") : - parentName ? (" Check the React.render call using <" + parentName + ">.") : - ''; - - // Usually the current owner is the offender, but if it accepts children as a - // property, it may be the creator of the child that's responsible for - // assigning it a key. - var childOwnerAddendum = ''; - if (element && - element._owner && - element._owner !== ReactCurrentOwner.current) { - // Name of the component that originally created this child. - var childOwnerName = getName(element._owner); - - childOwnerAddendum = (" It was passed a child from " + childOwnerName + "."); - } - - warning( - false, - message + '%s%s See http://fb.me/react-warning-keys for more information.', - parentOrOwnerAddendum, - childOwnerAddendum - ); -} - -/** - * Ensure that every element either is passed in a static location, in an - * array with an explicit keys property defined, or in an object literal - * with valid key property. - * - * @internal - * @param {ReactNode} node Statically passed child of any type. - * @param {*} parentType node's parent's type. - */ -function validateChildKeys(node, parentType) { - if (Array.isArray(node)) { - for (var i = 0; i < node.length; i++) { - var child = node[i]; - if (ReactElement.isValidElement(child)) { - validateExplicitKey(child, parentType); - } - } - } else if (ReactElement.isValidElement(node)) { - // This element was passed in a valid location. - node._store.validated = true; - } else if (node) { - var iteratorFn = getIteratorFn(node); - // Entry iterators provide implicit keys. - if (iteratorFn) { - if (iteratorFn !== node.entries) { - var iterator = iteratorFn.call(node); - var step; - while (!(step = iterator.next()).done) { - if (ReactElement.isValidElement(step.value)) { - validateExplicitKey(step.value, parentType); - } - } - } - } else if (typeof node === 'object') { - var fragment = ReactFragment.extractIfFragment(node); - for (var key in fragment) { - if (fragment.hasOwnProperty(key)) { - validatePropertyKey(key, fragment[key], parentType); - } - } - } - } -} - -/** - * Assert that the props are valid - * - * @param {string} componentName Name of the component for error messages. - * @param {object} propTypes Map of prop name to a ReactPropType - * @param {object} props - * @param {string} location e.g. "prop", "context", "child context" - * @private - */ -function checkPropTypes(componentName, propTypes, props, location) { - for (var propName in propTypes) { - if (propTypes.hasOwnProperty(propName)) { - var error; - // Prop type validation may throw. In case they do, we don't want to - // fail the render phase where it didn't fail before. So we log it. - // After these have been cleaned up, we'll let them throw. - try { - // This is intentionally an invariant that gets caught. It's the same - // behavior as without this statement except with a better message. - invariant( - typeof propTypes[propName] === 'function', - '%s: %s type `%s` is invalid; it must be a function, usually from ' + - 'React.PropTypes.', - componentName || 'React class', - ReactPropTypeLocationNames[location], - propName - ); - error = propTypes[propName](props, propName, componentName, location); - } catch (ex) { - error = ex; - } - if (error instanceof Error && !(error.message in loggedTypeFailures)) { - // Only monitor this failure once because there tends to be a lot of the - // same error. - loggedTypeFailures[error.message] = true; - - var addendum = getDeclarationErrorAddendum(this); - warning(false, 'Failed propType: %s%s', error.message, addendum); - } - } - } -} - -var warnedPropsMutations = {}; - -/** - * Warn about mutating props when setting `propName` on `element`. - * - * @param {string} propName The string key within props that was set - * @param {ReactElement} element - */ -function warnForPropsMutation(propName, element) { - var type = element.type; - var elementName = typeof type === 'string' ? type : type.displayName; - var ownerName = element._owner ? - element._owner.getPublicInstance().constructor.displayName : null; - - var warningKey = propName + '|' + elementName + '|' + ownerName; - if (warnedPropsMutations.hasOwnProperty(warningKey)) { - return; - } - warnedPropsMutations[warningKey] = true; - - var elementInfo = ''; - if (elementName) { - elementInfo = ' <' + elementName + ' />'; - } - var ownerInfo = ''; - if (ownerName) { - ownerInfo = ' The element was created by ' + ownerName + '.'; - } - - warning( - false, - 'Don\'t set .props.%s of the React component%s. Instead, specify the ' + - 'correct value when initially creating the element or use ' + - 'React.cloneElement to make a new element with updated props.%s', - propName, - elementInfo, - ownerInfo - ); -} - -// Inline Object.is polyfill -function is(a, b) { - if (a !== a) { - // NaN - return b !== b; - } - if (a === 0 && b === 0) { - // +-0 - return 1 / a === 1 / b; - } - return a === b; -} - -/** - * Given an element, check if its props have been mutated since element - * creation (or the last call to this function). In particular, check if any - * new props have been added, which we can't directly catch by defining warning - * properties on the props object. - * - * @param {ReactElement} element - */ -function checkAndWarnForMutatedProps(element) { - if (!element._store) { - // Element was created using `new ReactElement` directly or with - // `ReactElement.createElement`; skip mutation checking - return; - } - - var originalProps = element._store.originalProps; - var props = element.props; - - for (var propName in props) { - if (props.hasOwnProperty(propName)) { - if (!originalProps.hasOwnProperty(propName) || - !is(originalProps[propName], props[propName])) { - warnForPropsMutation(propName, element); - - // Copy over the new value so that the two props objects match again - originalProps[propName] = props[propName]; - } - } - } -} - -/** - * Given an element, validate that its props follow the propTypes definition, - * provided by the type. - * - * @param {ReactElement} element - */ -function validatePropTypes(element) { - if (element.type == null) { - // This has already warned. Don't throw. - return; - } - // Extract the component class from the element. Converts string types - // to a composite class which may have propTypes. - // TODO: Validating a string's propTypes is not decoupled from the - // rendering target which is problematic. - var componentClass = ReactNativeComponent.getComponentClassForElement( - element - ); - var name = componentClass.displayName || componentClass.name; - if (componentClass.propTypes) { - checkPropTypes( - name, - componentClass.propTypes, - element.props, - ReactPropTypeLocations.prop - ); - } - if (typeof componentClass.getDefaultProps === 'function') { - warning( - componentClass.getDefaultProps.isReactClassApproved, - 'getDefaultProps is only used on classic React.createClass ' + - 'definitions. Use a static property named `defaultProps` instead.' - ); - } -} - -var ReactElementValidator = { - - checkAndWarnForMutatedProps: checkAndWarnForMutatedProps, - - createElement: function(type, props, children) { - // We warn in this case but don't throw. We expect the element creation to - // succeed and there will likely be errors in render. - warning( - type != null, - 'React.createElement: type should not be null or undefined. It should ' + - 'be a string (for DOM elements) or a ReactClass (for composite ' + - 'components).' - ); - - var element = ReactElement.createElement.apply(this, arguments); - - // The result can be nullish if a mock or a custom function is used. - // TODO: Drop this when these are no longer allowed as the type argument. - if (element == null) { - return element; - } - - for (var i = 2; i < arguments.length; i++) { - validateChildKeys(arguments[i], type); - } - - validatePropTypes(element); - - return element; - }, - - createFactory: function(type) { - var validatedFactory = ReactElementValidator.createElement.bind( - null, - type - ); - // Legacy hook TODO: Warn if this is accessed - validatedFactory.type = type; - - if (__DEV__) { - try { - Object.defineProperty( - validatedFactory, - 'type', - { - enumerable: false, - get: function() { - warning( - false, - 'Factory.type is deprecated. Access the class directly ' + - 'before passing it to createFactory.' - ); - Object.defineProperty(this, 'type', { - value: type - }); - return type; - } - } - ); - } catch (x) { - // IE will fail on defineProperty (es5-shim/sham too) - } - } - - - return validatedFactory; - }, - - cloneElement: function(element, props, children) { - var newElement = ReactElement.cloneElement.apply(this, arguments); - for (var i = 2; i < arguments.length; i++) { - validateChildKeys(arguments[i], newElement.type); - } - validatePropTypes(newElement); - return newElement; - } - -}; - -module.exports = ReactElementValidator; -}); -__d('ReactPropTypeLocations',["keyMirror"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactPropTypeLocations - */ - -'use strict'; - -var keyMirror = require('keyMirror'); - -var ReactPropTypeLocations = keyMirror({ - prop: null, - context: null, - childContext: null -}); - -module.exports = ReactPropTypeLocations; -}); -__d('keyMirror',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 keyMirror - * @typechecks static-only - */ - -'use strict'; - -var invariant = require('invariant'); - -/** - * Constructs an enumeration with keys equal to their value. - * - * For example: - * - * var COLORS = keyMirror({blue: null, red: null}); - * var myColor = COLORS.blue; - * var isColorValid = !!COLORS[myColor]; - * - * The last line could not be performed if the values of the generated enum were - * not equal to their keys. - * - * Input: {key1: val1, key2: val2} - * Output: {key1: key1, key2: key2} - * - * @param {object} obj - * @return {object} - */ -var keyMirror = function(obj) { - var ret = {}; - var key; - invariant( - obj instanceof Object && !Array.isArray(obj), - 'keyMirror(...): Argument must be an object.' - ); - for (key in obj) { - if (!obj.hasOwnProperty(key)) { - continue; - } - ret[key] = key; - } - return ret; -}; - -module.exports = keyMirror; -}); -__d('ReactPropTypeLocationNames',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactPropTypeLocationNames - */ - -'use strict'; - -var ReactPropTypeLocationNames = {}; - -if (__DEV__) { - ReactPropTypeLocationNames = { - prop: 'prop', - context: 'context', - childContext: 'child context' - }; -} - -module.exports = ReactPropTypeLocationNames; -}); -__d('ReactNativeComponent',["Object.assign","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2014-2015, 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 ReactNativeComponent - */ - -'use strict'; - -var assign = require('Object.assign'); -var invariant = require('invariant'); - -var autoGenerateWrapperClass = null; -var genericComponentClass = null; -// This registry keeps track of wrapper classes around native tags -var tagToComponentClass = {}; -var textComponentClass = null; - -var ReactNativeComponentInjection = { - // This accepts a class that receives the tag string. This is a catch all - // that can render any kind of tag. - injectGenericComponentClass: function(componentClass) { - genericComponentClass = componentClass; - }, - // This accepts a text component class that takes the text string to be - // rendered as props. - injectTextComponentClass: function(componentClass) { - textComponentClass = componentClass; - }, - // This accepts a keyed object with classes as values. Each key represents a - // tag. That particular tag will use this class instead of the generic one. - injectComponentClasses: function(componentClasses) { - assign(tagToComponentClass, componentClasses); - }, - // Temporary hack since we expect DOM refs to behave like composites, - // for this release. - injectAutoWrapper: function(wrapperFactory) { - autoGenerateWrapperClass = wrapperFactory; - } -}; - -/** - * Get a composite component wrapper class for a specific tag. - * - * @param {ReactElement} element The tag for which to get the class. - * @return {function} The React class constructor function. - */ -function getComponentClassForElement(element) { - if (typeof element.type === 'function') { - return element.type; - } - var tag = element.type; - var componentClass = tagToComponentClass[tag]; - if (componentClass == null) { - tagToComponentClass[tag] = componentClass = autoGenerateWrapperClass(tag); - } - return componentClass; -} - -/** - * Get a native internal component class for a specific tag. - * - * @param {ReactElement} element The element to create. - * @return {function} The internal class constructor function. - */ -function createInternalComponent(element) { - invariant( - genericComponentClass, - 'There is no registered component for the tag %s', - element.type - ); - return new genericComponentClass(element.type, element.props); -} - -/** - * @param {ReactText} text - * @return {ReactComponent} - */ -function createInstanceForText(text) { - return new textComponentClass(text); -} - -/** - * @param {ReactComponent} component - * @return {boolean} - */ -function isTextComponent(component) { - return component instanceof textComponentClass; -} - -var ReactNativeComponent = { - getComponentClassForElement: getComponentClassForElement, - createInternalComponent: createInternalComponent, - createInstanceForText: createInstanceForText, - isTextComponent: isTextComponent, - injection: ReactNativeComponentInjection -}; - -module.exports = ReactNativeComponent; -}); -__d('Transaction',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 Transaction - */ - -'use strict'; - -var invariant = require('invariant'); - -/** - * `Transaction` creates a black box that is able to wrap any method such that - * certain invariants are maintained before and after the method is invoked - * (Even if an exception is thrown while invoking the wrapped method). Whoever - * instantiates a transaction can provide enforcers of the invariants at - * creation time. The `Transaction` class itself will supply one additional - * automatic invariant for you - the invariant that any transaction instance - * should not be run while it is already being run. You would typically create a - * single instance of a `Transaction` for reuse multiple times, that potentially - * is used to wrap several different methods. Wrappers are extremely simple - - * they only require implementing two methods. - * - *
- *                       wrappers (injected at creation time)
- *                                      +        +
- *                                      |        |
- *                    +-----------------|--------|--------------+
- *                    |                 v        |              |
- *                    |      +---------------+   |              |
- *                    |   +--|    wrapper1   |---|----+         |
- *                    |   |  +---------------+   v    |         |
- *                    |   |          +-------------+  |         |
- *                    |   |     +----|   wrapper2  |--------+   |
- *                    |   |     |    +-------------+  |     |   |
- *                    |   |     |                     |     |   |
- *                    |   v     v                     v     v   | wrapper
- *                    | +---+ +---+   +---------+   +---+ +---+ | invariants
- * perform(anyMethod) | |   | |   |   |         |   |   | |   | | maintained
- * +----------------->|-|---|-|---|-->|anyMethod|---|---|-|---|-|-------->
- *                    | |   | |   |   |         |   |   | |   | |
- *                    | |   | |   |   |         |   |   | |   | |
- *                    | |   | |   |   |         |   |   | |   | |
- *                    | +---+ +---+   +---------+   +---+ +---+ |
- *                    |  initialize                    close    |
- *                    +-----------------------------------------+
- * 
- * - * Use cases: - * - Preserving the input selection ranges before/after reconciliation. - * Restoring selection even in the event of an unexpected error. - * - Deactivating events while rearranging the DOM, preventing blurs/focuses, - * while guaranteeing that afterwards, the event system is reactivated. - * - Flushing a queue of collected DOM mutations to the main UI thread after a - * reconciliation takes place in a worker thread. - * - Invoking any collected `componentDidUpdate` callbacks after rendering new - * content. - * - (Future use case): Wrapping particular flushes of the `ReactWorker` queue - * to preserve the `scrollTop` (an automatic scroll aware DOM). - * - (Future use case): Layout calculations before and after DOM updates. - * - * Transactional plugin API: - * - A module that has an `initialize` method that returns any precomputation. - * - and a `close` method that accepts the precomputation. `close` is invoked - * when the wrapped process is completed, or has failed. - * - * @param {Array} transactionWrapper Wrapper modules - * that implement `initialize` and `close`. - * @return {Transaction} Single transaction for reuse in thread. - * - * @class Transaction - */ -var Mixin = { - /** - * Sets up this instance so that it is prepared for collecting metrics. Does - * so such that this setup method may be used on an instance that is already - * initialized, in a way that does not consume additional memory upon reuse. - * That can be useful if you decide to make your subclass of this mixin a - * "PooledClass". - */ - reinitializeTransaction: function() { - this.transactionWrappers = this.getTransactionWrappers(); - if (!this.wrapperInitData) { - this.wrapperInitData = []; - } else { - this.wrapperInitData.length = 0; - } - this._isInTransaction = false; - }, - - _isInTransaction: false, - - /** - * @abstract - * @return {Array} Array of transaction wrappers. - */ - getTransactionWrappers: null, - - isInTransaction: function() { - return !!this._isInTransaction; - }, - - /** - * Executes the function within a safety window. Use this for the top level - * methods that result in large amounts of computation/mutations that would - * need to be safety checked. - * - * @param {function} method Member of scope to call. - * @param {Object} scope Scope to invoke from. - * @param {Object?=} args... Arguments to pass to the method (optional). - * Helps prevent need to bind in many cases. - * @return Return value from `method`. - */ - perform: function(method, scope, a, b, c, d, e, f) { - invariant( - !this.isInTransaction(), - 'Transaction.perform(...): Cannot initialize a transaction when there ' + - 'is already an outstanding transaction.' - ); - var errorThrown; - var ret; - try { - this._isInTransaction = true; - // Catching errors makes debugging more difficult, so we start with - // errorThrown set to true before setting it to false after calling - // close -- if it's still set to true in the finally block, it means - // one of these calls threw. - errorThrown = true; - this.initializeAll(0); - ret = method.call(scope, a, b, c, d, e, f); - errorThrown = false; - } finally { - try { - if (errorThrown) { - // If `method` throws, prefer to show that stack trace over any thrown - // by invoking `closeAll`. - try { - this.closeAll(0); - } catch (err) { - } - } else { - // Since `method` didn't throw, we don't want to silence the exception - // here. - this.closeAll(0); - } - } finally { - this._isInTransaction = false; - } - } - return ret; - }, - - initializeAll: function(startIndex) { - var transactionWrappers = this.transactionWrappers; - for (var i = startIndex; i < transactionWrappers.length; i++) { - var wrapper = transactionWrappers[i]; - try { - // Catching errors makes debugging more difficult, so we start with the - // OBSERVED_ERROR state before overwriting it with the real return value - // of initialize -- if it's still set to OBSERVED_ERROR in the finally - // block, it means wrapper.initialize threw. - this.wrapperInitData[i] = Transaction.OBSERVED_ERROR; - this.wrapperInitData[i] = wrapper.initialize ? - wrapper.initialize.call(this) : - null; - } finally { - if (this.wrapperInitData[i] === Transaction.OBSERVED_ERROR) { - // The initializer for wrapper i threw an error; initialize the - // remaining wrappers but silence any exceptions from them to ensure - // that the first error is the one to bubble up. - try { - this.initializeAll(i + 1); - } catch (err) { - } - } - } - } - }, - - /** - * Invokes each of `this.transactionWrappers.close[i]` functions, passing into - * them the respective return values of `this.transactionWrappers.init[i]` - * (`close`rs that correspond to initializers that failed will not be - * invoked). - */ - closeAll: function(startIndex) { - invariant( - this.isInTransaction(), - 'Transaction.closeAll(): Cannot close transaction when none are open.' - ); - var transactionWrappers = this.transactionWrappers; - for (var i = startIndex; i < transactionWrappers.length; i++) { - var wrapper = transactionWrappers[i]; - var initData = this.wrapperInitData[i]; - var errorThrown; - try { - // Catching errors makes debugging more difficult, so we start with - // errorThrown set to true before setting it to false after calling - // close -- if it's still set to true in the finally block, it means - // wrapper.close threw. - errorThrown = true; - if (initData !== Transaction.OBSERVED_ERROR && wrapper.close) { - wrapper.close.call(this, initData); - } - errorThrown = false; - } finally { - if (errorThrown) { - // The closer for wrapper i threw an error; close the remaining - // wrappers but silence any exceptions from them to ensure that the - // first error is the one to bubble up. - try { - this.closeAll(i + 1); - } catch (e) { - } - } - } - } - this.wrapperInitData.length = 0; - } -}; - -var Transaction = { - - Mixin: Mixin, - - /** - * Token to look for to determine if an error occured. - */ - OBSERVED_ERROR: {} - -}; - -module.exports = Transaction; -}); -__d('ReactErrorUtils',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactErrorUtils - * @typechecks - */ - -"use strict"; - -var ReactErrorUtils = { - /** - * Creates a guarded version of a function. This is supposed to make debugging - * of event handlers easier. To aid debugging with the browser's debugger, - * this currently simply returns the original function. - * - * @param {function} func Function to be executed - * @param {string} name The name of the guard - * @return {function} - */ - guard: function(func, name) { - return func; - } -}; - -module.exports = ReactErrorUtils; -}); -__d('keyOf',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 keyOf - */ - -/** - * Allows extraction of a minified key. Let's the build system minify keys - * without loosing the ability to dynamically use key strings as values - * themselves. Pass in an object with a single key/val pair and it will return - * you the string key of that single record. Suppose you want to grab the - * value for a key 'className' inside of an object. Key/val minification may - * have aliased that key to be 'xa12'. keyOf({className: null}) will return - * 'xa12' in that case. Resolve keys you want to use once at startup time, then - * reuse those resolutions. - */ -var keyOf = function(oneKeyObj) { - var key; - for (key in oneKeyObj) { - if (!oneKeyObj.hasOwnProperty(key)) { - continue; - } - return key; - } - return null; -}; - - -module.exports = keyOf; -}); -__d('ReactNativeDefaultInjection',["InitializeJavaScriptAppEngine","EventPluginHub","EventPluginUtils","IOSDefaultEventPluginOrder","IOSNativeBridgeEventPlugin","NodeHandle","ReactComponentEnvironment","ReactDefaultBatchingStrategy","ReactEmptyComponent","ReactInstanceHandles","ReactNativeComponentEnvironment","ReactNativeGlobalInteractionHandler","ReactNativeGlobalResponderHandler","ReactNativeMount","ReactNativeTextComponent","ReactNativeComponent","ReactUpdates","ResponderEventPlugin","UniversalWorkerNodeHandle","createReactNativeComponentClass","invariant","RCTEventEmitter","RCTLog","RCTJSTimers"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 ReactNativeDefaultInjection - * @flow - */ -'use strict'; - -/** - * Make sure `setTimeout`/`setInterval` are patched correctly. - */ -require('InitializeJavaScriptAppEngine'); -var EventPluginHub = require('EventPluginHub'); -var EventPluginUtils = require('EventPluginUtils'); -var IOSDefaultEventPluginOrder = require('IOSDefaultEventPluginOrder'); -var IOSNativeBridgeEventPlugin = require('IOSNativeBridgeEventPlugin'); -var NodeHandle = require('NodeHandle'); -var ReactComponentEnvironment = require('ReactComponentEnvironment'); -var ReactDefaultBatchingStrategy = require('ReactDefaultBatchingStrategy'); -var ReactEmptyComponent = require('ReactEmptyComponent'); -var ReactInstanceHandles = require('ReactInstanceHandles'); -var ReactNativeComponentEnvironment = require('ReactNativeComponentEnvironment'); -var ReactNativeGlobalInteractionHandler = require('ReactNativeGlobalInteractionHandler'); -var ReactNativeGlobalResponderHandler = require('ReactNativeGlobalResponderHandler'); -var ReactNativeMount = require('ReactNativeMount'); -var ReactNativeTextComponent = require('ReactNativeTextComponent'); -var ReactNativeComponent = require('ReactNativeComponent'); -var ReactUpdates = require('ReactUpdates'); -var ResponderEventPlugin = require('ResponderEventPlugin'); -var UniversalWorkerNodeHandle = require('UniversalWorkerNodeHandle'); - -var createReactNativeComponentClass = require('createReactNativeComponentClass'); -var invariant = require('invariant'); - -// Just to ensure this gets packaged, since its only caller is from Native. -require('RCTEventEmitter'); -require('RCTLog'); -require('RCTJSTimers'); - -function inject() { - /** - * Inject module for resolving DOM hierarchy and plugin ordering. - */ - EventPluginHub.injection.injectEventPluginOrder(IOSDefaultEventPluginOrder); - EventPluginHub.injection.injectInstanceHandle(ReactInstanceHandles); - - ResponderEventPlugin.injection.injectGlobalResponderHandler( - ReactNativeGlobalResponderHandler - ); - - ResponderEventPlugin.injection.injectGlobalInteractionHandler( - ReactNativeGlobalInteractionHandler - ); - - /** - * Some important event plugins included by default (without having to require - * them). - */ - EventPluginHub.injection.injectEventPluginsByName({ - 'ResponderEventPlugin': ResponderEventPlugin, - 'IOSNativeBridgeEventPlugin': IOSNativeBridgeEventPlugin - }); - - ReactUpdates.injection.injectReconcileTransaction( - ReactNativeComponentEnvironment.ReactReconcileTransaction - ); - - ReactUpdates.injection.injectBatchingStrategy( - ReactDefaultBatchingStrategy - ); - - ReactComponentEnvironment.injection.injectEnvironment( - ReactNativeComponentEnvironment - ); - - // Can't import View here because it depends on React to make its composite - var RCTView = createReactNativeComponentClass({ - validAttributes: {}, - uiViewClassName: 'RCTView', - }); - ReactEmptyComponent.injection.injectEmptyComponent(RCTView); - - EventPluginUtils.injection.injectMount(ReactNativeMount); - - ReactNativeComponent.injection.injectTextComponentClass( - ReactNativeTextComponent - ); - ReactNativeComponent.injection.injectAutoWrapper(function(tag) { - // Show a nicer error message for non-function tags - var info = ''; - if (typeof tag === 'string' && /^[a-z]/.test(tag)) { - info += ' Each component name should start with an uppercase letter.'; - } - invariant(false, 'Expected a component class, got %s.%s', tag, info); - }); - - NodeHandle.injection.injectImplementation(UniversalWorkerNodeHandle); -} - -module.exports = { - inject: inject, -}; -}); -__d('InitializeJavaScriptAppEngine',["RCTDeviceEventEmitter","ExceptionsManager","ErrorUtils","ExceptionsManager","Platform","JSTimers","NativeModules","Promise","XMLHttpRequest","fetch","Geolocation","WebSocket"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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. - * - * Sets up global variables typical in most JavaScript environments. - * - * 1. Global timers (via `setTimeout` etc). - * 2. Global console object. - * 3. Hooks for printing stack traces with source maps. - * - * Leaves enough room in the environment for implementing your own: - * 1. Require system. - * 2. Bridged modules. - * - * @providesModule InitializeJavaScriptAppEngine - */ - -/* eslint global-strict: 0 */ -/* globals GLOBAL: true, window: true */ - -// Just to make sure the JS gets packaged up. -require('RCTDeviceEventEmitter'); - -if (typeof GLOBAL === 'undefined') { - GLOBAL = this; -} - -if (typeof window === 'undefined') { - window = GLOBAL; -} - -function handleErrorWithRedBox(e, isFatal) { - try { - require('ExceptionsManager').handleException(e, isFatal); - } catch(ee) { - console.log('Failed to print error: ', ee.message); - } -} - -function setUpRedBoxErrorHandler() { - var ErrorUtils = require('ErrorUtils'); - ErrorUtils.setGlobalHandler(handleErrorWithRedBox); -} - -function setUpRedBoxConsoleErrorHandler() { - // ExceptionsManager transitively requires Promise so we install it after - var ExceptionsManager = require('ExceptionsManager'); - var Platform = require('Platform'); - // TODO (#6925182): Enable console.error redbox on Android - if (__DEV__ && Platform.OS === 'ios') { - ExceptionsManager.installConsoleErrorReporter(); - } -} - -/** - * Sets up a set of window environment wrappers that ensure that the - * BatchedBridge is flushed after each tick. In both the case of the - * `UIWebView` based `RCTJavaScriptCaller` and `RCTContextCaller`, we - * implement our own custom timing bridge that should be immune to - * unexplainably dropped timing signals. - */ -function setUpTimers() { - var JSTimers = require('JSTimers'); - GLOBAL.setTimeout = JSTimers.setTimeout; - GLOBAL.setInterval = JSTimers.setInterval; - GLOBAL.setImmediate = JSTimers.setImmediate; - GLOBAL.clearTimeout = JSTimers.clearTimeout; - GLOBAL.clearInterval = JSTimers.clearInterval; - GLOBAL.clearImmediate = JSTimers.clearImmediate; - GLOBAL.cancelAnimationFrame = JSTimers.clearInterval; - GLOBAL.requestAnimationFrame = function(cb) { - /*requestAnimationFrame() { [native code] };*/ // Trick scroller library - return JSTimers.requestAnimationFrame(cb); // into thinking it's native - }; -} - -function setUpAlert() { - var RCTAlertManager = require('NativeModules').AlertManager; - if (!GLOBAL.alert) { - GLOBAL.alert = function(text) { - var alertOpts = { - title: 'Alert', - message: '' + text, - buttons: [{'cancel': 'Okay'}], - }; - RCTAlertManager.alertWithArgs(alertOpts, null); - }; - } -} - -function setUpPromise() { - // The native Promise implementation throws the following error: - // ERROR: Event loop not supported. - GLOBAL.Promise = require('Promise'); -} - -function setUpXHR() { - // The native XMLHttpRequest in Chrome dev tools is CORS aware and won't - // let you fetch anything from the internet - GLOBAL.XMLHttpRequest = require('XMLHttpRequest'); - - var fetchPolyfill = require('fetch'); - GLOBAL.fetch = fetchPolyfill.fetch; - GLOBAL.Headers = fetchPolyfill.Headers; - GLOBAL.Request = fetchPolyfill.Request; - GLOBAL.Response = fetchPolyfill.Response; -} - -function setUpGeolocation() { - GLOBAL.navigator = GLOBAL.navigator || {}; - GLOBAL.navigator.geolocation = require('Geolocation'); -} - -function setUpWebSockets() { - GLOBAL.WebSocket = require('WebSocket'); -} - -function setupProfile() { - console.profile = console.profile || GLOBAL.consoleProfile || function () {}; - console.profileEnd = console.profileEnd || GLOBAL.consoleProfileEnd || function () {}; -} - -setUpRedBoxErrorHandler(); -setUpTimers(); -setUpAlert(); -setUpPromise(); -setUpXHR(); -setUpRedBoxConsoleErrorHandler(); -setUpGeolocation(); -setUpWebSockets(); -setupProfile(); -}); -__d('RCTDeviceEventEmitter',["EventEmitter"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 RCTDeviceEventEmitter - * @flow - */ -'use strict'; - -var EventEmitter = require('EventEmitter'); - -var RCTDeviceEventEmitter = new EventEmitter(); - -module.exports = RCTDeviceEventEmitter; -}); -__d('EventEmitter',["EmitterSubscription","ErrorUtils","EventSubscriptionVendor","emptyFunction","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * @generated SignedSource<<494e66dea72a3e90b763a5ec50b1e0ca>> - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !! This file is a check-in of a static_upstream project! !! - * !! !! - * !! You should not modify this file directly. Instead: !! - * !! 1) Use `fjs use-upstream` to temporarily replace this with !! - * !! the latest version from upstream. !! - * !! 2) Make your changes, test them, etc. !! - * !! 3) Use `fjs push-upstream` to copy your changes back to !! - * !! static_upstream. !! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * @providesModule EventEmitter - * @typechecks - */ - -var EmitterSubscription = require('EmitterSubscription'); -var ErrorUtils = require('ErrorUtils'); -var EventSubscriptionVendor = require('EventSubscriptionVendor'); -var emptyFunction = require('emptyFunction'); -var invariant = require('invariant'); - -/** - * @class EventEmitter - * @description - * An EventEmitter is responsible for managing a set of listeners and publishing - * events to them when it is told that such events happened. In addition to the - * data for the given event it also sends a event control object which allows - * the listeners/handlers to prevent the default behavior of the given event. - * - * The emitter is designed to be generic enough to support all the different - * contexts in which one might want to emit events. It is a simple multicast - * mechanism on top of which extra functionality can be composed. For example, a - * more advanced emitter may use an EventHolder and EventFactory. - */ - - /** - * @constructor - */ - function EventEmitter() {"use strict"; - this.$EventEmitter_subscriber = new EventSubscriptionVendor(); - } - - /** - * Adds a listener to be invoked when events of the specified type are - * emitted. An optional calling context may be provided. The data arguments - * emitted will be passed to the listener function. - * - * TODO: Annotate the listener arg's type. This is tricky because listeners - * can be invoked with varargs. - * - * @param {string} eventType - Name of the event to listen to - * @param {function} listener - Function to invoke when the specified event is - * emitted - * @param {*} context - Optional context object to use when invoking the - * listener - */ - EventEmitter.prototype.addListener=function( -eventType , listener, context ) {"use strict"; - return this.$EventEmitter_subscriber.addSubscription( - eventType, - new EmitterSubscription(this.$EventEmitter_subscriber, listener, context)); - }; - - /** - * Similar to addListener, except that the listener is removed after it is - * invoked once. - * - * @param {string} eventType - Name of the event to listen to - * @param {function} listener - Function to invoke only once when the - * specified event is emitted - * @param {*} context - Optional context object to use when invoking the - * listener - */ - EventEmitter.prototype.once=function(eventType , listener, context ) {"use strict"; - var emitter = this; - return this.addListener(eventType, function() { - emitter.removeCurrentListener(); - listener.apply(context, arguments); - }); - }; - - /** - * Removes all of the registered listeners, including those registered as - * listener maps. - * - * @param {?string} eventType - Optional name of the event whose registered - * listeners to remove - */ - EventEmitter.prototype.removeAllListeners=function(eventType ) {"use strict"; - this.$EventEmitter_subscriber.removeAllSubscriptions(eventType); - }; - - /** - * Provides an API that can be called during an eventing cycle to remove the - * last listener that was invoked. This allows a developer to provide an event - * object that can remove the listener (or listener map) during the - * invocation. - * - * If it is called when not inside of an emitting cycle it will throw. - * - * @throws {Error} When called not during an eventing cycle - * - * @example - * var subscription = emitter.addListenerMap({ - * someEvent: function(data, event) { - * console.log(data); - * emitter.removeCurrentListener(); - * } - * }); - * - * emitter.emit('someEvent', 'abc'); // logs 'abc' - * emitter.emit('someEvent', 'def'); // does not log anything - */ - EventEmitter.prototype.removeCurrentListener=function() {"use strict"; - invariant( - !!this.$EventEmitter_currentSubscription, - 'Not in an emitting cycle; there is no current subscription' - ); - this.$EventEmitter_subscriber.removeSubscription(this.$EventEmitter_currentSubscription); - }; - - /** - * Returns an array of listeners that are currently registered for the given - * event. - * - * @param {string} eventType - Name of the event to query - * @returns {array} - */ - EventEmitter.prototype.listeners=function(eventType ) /* TODO: Array */ {"use strict"; - var subscriptions = this.$EventEmitter_subscriber.getSubscriptionsForType(eventType); - return subscriptions - ? subscriptions.filter(emptyFunction.thatReturnsTrue).map( - function(subscription) { - return subscription.listener; - }) - : []; - }; - - /** - * Emits an event of the given type with the given data. All handlers of that - * particular type will be notified. - * - * @param {string} eventType - Name of the event to emit - * @param {...*} Arbitrary arguments to be passed to each registered listener - * - * @example - * emitter.addListener('someEvent', function(message) { - * console.log(message); - * }); - * - * emitter.emit('someEvent', 'abc'); // logs 'abc' - */ - EventEmitter.prototype.emit=function(eventType ) {"use strict"; - var subscriptions = this.$EventEmitter_subscriber.getSubscriptionsForType(eventType); - if (subscriptions) { - var keys = Object.keys(subscriptions); - for (var ii = 0; ii < keys.length; ii++) { - var key = keys[ii]; - var subscription = subscriptions[key]; - - // The subscription may have been removed during this event loop. - if (subscription) { - this.$EventEmitter_currentSubscription = subscription; - - ErrorUtils.applyWithGuard( - subscription.listener, - subscription.context, - Array.prototype.slice.call(arguments, 1), - null, - 'EventEmitter:' + eventType - ); - } - } - this.$EventEmitter_currentSubscription = null; - } - }; - - -module.exports = EventEmitter; -}); -__d('EmitterSubscription',["EventSubscription"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * @generated SignedSource<> - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !! This file is a check-in of a static_upstream project! !! - * !! !! - * !! You should not modify this file directly. Instead: !! - * !! 1) Use `fjs use-upstream` to temporarily replace this with !! - * !! the latest version from upstream. !! - * !! 2) Make your changes, test them, etc. !! - * !! 3) Use `fjs push-upstream` to copy your changes back to !! - * !! static_upstream. !! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * @providesModule EmitterSubscription - * @typechecks - */ -'use strict'; - -var EventSubscription = require('EventSubscription'); - -/** - * EmitterSubscription represents a subscription with listener and context data. - */ -for(var EventSubscription____Key in EventSubscription){if(EventSubscription.hasOwnProperty(EventSubscription____Key)){EmitterSubscription[EventSubscription____Key]=EventSubscription[EventSubscription____Key];}}var ____SuperProtoOfEventSubscription=EventSubscription===null?null:EventSubscription.prototype;EmitterSubscription.prototype=Object.create(____SuperProtoOfEventSubscription);EmitterSubscription.prototype.constructor=EmitterSubscription;EmitterSubscription.__superConstructor__=EventSubscription; - - /** - * @param {EventSubscriptionVendor} subscriber - The subscriber that controls - * this subscription - * @param {function} listener - Function to invoke when the specified event is - * emitted - * @param {*} context - Optional context object to use when invoking the - * listener - */ - function EmitterSubscription(subscriber , listener, context ) { - EventSubscription.call(this,subscriber); - this.listener = listener; - this.context = context; - } - - -module.exports = EmitterSubscription; -}); -__d('EventSubscription',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * @generated SignedSource<<92108a17b1f3eee4b7e3dd7d484aa17a>> - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !! This file is a check-in of a static_upstream project! !! - * !! !! - * !! You should not modify this file directly. Instead: !! - * !! 1) Use `fjs use-upstream` to temporarily replace this with !! - * !! the latest version from upstream. !! - * !! 2) Make your changes, test them, etc. !! - * !! 3) Use `fjs push-upstream` to copy your changes back to !! - * !! static_upstream. !! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * @providesModule EventSubscription - * @typechecks - */ -'use strict'; - -/** - * EventSubscription represents a subscription to a particular event. It can - * remove its own subscription. - */ - - - /** - * @param {EventSubscriptionVendor} subscriber the subscriber that controls - * this subscription. - */ - function EventSubscription(subscriber ) { - this.subscriber = subscriber; - } - - /** - * Removes this subscription from the subscriber that controls it. - */ - EventSubscription.prototype.remove=function() { - this.subscriber.removeSubscription(this); - }; - - -module.exports = EventSubscription; -}); -__d('ErrorUtils',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 ErrorUtils - */ -/* eslint-disable consistent-this, global-strict */ - -var GLOBAL = this; - -/** - * The particular require runtime that we are using looks for a global - * `ErrorUtils` object and if it exists, then it requires modules with the - * error handler specified via ErrorUtils.setGlobalHandler by calling the - * require function with applyWithGuard. Since the require module is loaded - * before any of the modules, this ErrorUtils must be defined (and the handler - * set) globally before requiring anything. - * - * However, we still want to treat ErrorUtils as a module so that other modules - * that use it aren't just using a global variable, so simply export the global - * variable here. ErrorUtils is original defined in a file named error-guard.js. - */ -module.exports = GLOBAL.ErrorUtils; -}); -__d('EventSubscriptionVendor',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * @generated SignedSource<<24d5cc1cdd24704296686faf89dd36cf>> - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !! This file is a check-in of a static_upstream project! !! - * !! !! - * !! You should not modify this file directly. Instead: !! - * !! 1) Use `fjs use-upstream` to temporarily replace this with !! - * !! the latest version from upstream. !! - * !! 2) Make your changes, test them, etc. !! - * !! 3) Use `fjs push-upstream` to copy your changes back to !! - * !! static_upstream. !! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * @providesModule EventSubscriptionVendor - * @typechecks - */ -'use strict'; - -var invariant = require('invariant'); - -/** - * EventSubscriptionVendor stores a set of EventSubscriptions that are - * subscribed to a particular event type. - */ - - - function EventSubscriptionVendor() { - this.$EventSubscriptionVendor_subscriptionsForType = {}; - this.$EventSubscriptionVendor_currentSubscription = null; - } - - /** - * Adds a subscription keyed by an event type. - * - * @param {string} eventType - * @param {EventSubscription} subscription - */ - EventSubscriptionVendor.prototype.addSubscription=function( -eventType , subscription ) { - invariant( - subscription.subscriber === this, - 'The subscriber of the subscription is incorrectly set.'); - if (!this.$EventSubscriptionVendor_subscriptionsForType[eventType]) { - this.$EventSubscriptionVendor_subscriptionsForType[eventType] = []; - } - var key = this.$EventSubscriptionVendor_subscriptionsForType[eventType].length; - this.$EventSubscriptionVendor_subscriptionsForType[eventType].push(subscription); - subscription.eventType = eventType; - subscription.key = key; - return subscription; - }; - - /** - * Removes a bulk set of the subscriptions. - * - * @param {?string} eventType - Optional name of the event type whose - * registered supscriptions to remove, if null remove all subscriptions. - */ - EventSubscriptionVendor.prototype.removeAllSubscriptions=function(eventType ) { - if (eventType === undefined) { - this.$EventSubscriptionVendor_subscriptionsForType = {}; - } else { - delete this.$EventSubscriptionVendor_subscriptionsForType[eventType]; - } - }; - - /** - * Removes a specific subscription. Instead of calling this function, call - * `subscription.remove()` directly. - * - * @param {object} subscription - */ - EventSubscriptionVendor.prototype.removeSubscription=function(subscription ) { - var eventType = subscription.eventType; - var key = subscription.key; - - var subscriptionsForType = this.$EventSubscriptionVendor_subscriptionsForType[eventType]; - if (subscriptionsForType) { - delete subscriptionsForType[key]; - } - }; - - /** - * Returns the array of subscriptions that are currently registered for the - * given event type. - * - * Note: This array can be potentially sparse as subscriptions are deleted - * from it when they are removed. - * - * TODO: This returns a nullable array. wat? - * - * @param {string} eventType - * @returns {?array} - */ - EventSubscriptionVendor.prototype.getSubscriptionsForType=function(eventType ) { - return this.$EventSubscriptionVendor_subscriptionsForType[eventType]; - }; - - -module.exports = EventSubscriptionVendor; -}); -__d('ExceptionsManager',["NativeModules","loadSourceMap","parseErrorStack","stringifySafe"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 ExceptionsManager - * @flow - */ -'use strict'; - -var RCTExceptionsManager = require('NativeModules').ExceptionsManager; - -var loadSourceMap = require('loadSourceMap'); -var parseErrorStack = require('parseErrorStack'); -var stringifySafe = require('stringifySafe'); - -var sourceMapPromise; - - - - - - - -function reportException(e , isFatal , stack ) { - if (RCTExceptionsManager) { - if (!stack) { - stack = parseErrorStack(e); - } - if (!RCTExceptionsManager.reportFatalException || - !RCTExceptionsManager.reportSoftException) { - // Backwards compatibility - no differentiation - // TODO(#7049989): deprecate reportUnhandledException on Android - RCTExceptionsManager.reportUnhandledException(e.message, stack); - } else { - if (isFatal) { - RCTExceptionsManager.reportFatalException(e.message, stack); - } else { - RCTExceptionsManager.reportSoftException(e.message, stack); - } - } - if (__DEV__) { - (sourceMapPromise = sourceMapPromise || loadSourceMap()) - .then(function(map) { - var prettyStack = parseErrorStack(e, map); - RCTExceptionsManager.updateExceptionMessage(e.message, prettyStack); - }) - ["catch"](function(error) { - // This can happen in a variety of normal situations, such as - // Network module not being available, or when running locally - console.warn('Unable to load source map: ' + error.message); - }); - } - } -} - -function handleException(e , isFatal ) { - var stack = parseErrorStack(e); - var msg = - 'Error: ' + e.message + - '\n stack: \n' + stackToString(stack) + - '\n URL: ' + e.sourceURL + - '\n line: ' + e.line + - '\n message: ' + e.message; - if (console.errorOriginal) { - console.errorOriginal(msg); - } else { - console.error(msg); - } - reportException(e, isFatal, stack); -} - -/** - * Shows a redbox with stacktrace for all console.error messages. Disable by - * setting `console.reportErrorsAsExceptions = false;` in your app. - */ -function installConsoleErrorReporter() { - if (console.reportException) { - return; // already installed - } - console.reportException = reportException; - console.errorOriginal = console.error.bind(console); - console.error = function reactConsoleError() { - console.errorOriginal.apply(null, arguments); - if (!console.reportErrorsAsExceptions) { - return; - } - var str = Array.prototype.map.call(arguments, stringifySafe).join(', '); - var error = new Error('console.error: ' + str); - error.framesToPop = 1; - reportException(error, /* isFatal */ false); - }; - if (console.reportErrorsAsExceptions === undefined) { - console.reportErrorsAsExceptions = true; // Individual apps can disable this - } -} - -function stackToString(stack) { - var maxLength = Math.max.apply(null, stack.map(function(frame) {return frame.methodName.length;})); - return stack.map(function(frame) {return stackFrameToString(frame, maxLength);}).join('\n'); -} - -function stackFrameToString(stackFrame, maxLength) { - var fileNameParts = stackFrame.file.split('/'); - var fileName = fileNameParts[fileNameParts.length - 1]; - - if (fileName.length > 18) { - fileName = fileName.substr(0, 17) + '\u2026' /* ... */; - } - - var spaces = fillSpaces(maxLength - stackFrame.methodName.length); - return ' ' + stackFrame.methodName + spaces + ' ' + fileName + ':' + stackFrame.lineNumber; -} - -function fillSpaces(n) { - return new Array(n + 1).join(' '); -} - -module.exports = { handleException:handleException, installConsoleErrorReporter:installConsoleErrorReporter }; -}); -__d('NativeModules',["BatchedBridge","nativeModulePrefixNormalizer"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 NativeModules - * @flow - */ -'use strict'; - -var NativeModules = require('BatchedBridge').RemoteModules; - -var nativeModulePrefixNormalizer = require('nativeModulePrefixNormalizer'); - -nativeModulePrefixNormalizer(NativeModules); - -module.exports = NativeModules; -}); -__d('BatchedBridge',["BatchedBridgeFactory","MessageQueue"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 BatchedBridge - */ -'use strict'; - -var BatchedBridgeFactory = require('BatchedBridgeFactory'); -var MessageQueue = require('MessageQueue'); - -/** - * Signature that matches the native IOS modules/methods that are exposed. We - * indicate which ones accept a callback. The order of modules and methods - * within them implicitly define their numerical *ID* that will be used to - * describe method calls across the wire. This is so that memory is used - * efficiently and we do not need to copy strings in native land - or across any - * wire. - */ - -var remoteModulesConfig = __fbBatchedBridgeConfig.remoteModuleConfig; -var localModulesConfig = __fbBatchedBridgeConfig.localModulesConfig; - - -var BatchedBridge = BatchedBridgeFactory.create( - MessageQueue, - remoteModulesConfig, - localModulesConfig -); - -BatchedBridge._config = remoteModulesConfig; - -module.exports = BatchedBridge; -}); -__d('BatchedBridgeFactory',["invariant","keyMirror","mapObject","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 BatchedBridgeFactory - */ -'use strict'; - -var invariant = require('invariant'); -var keyMirror = require('keyMirror'); -var mapObject = require('mapObject'); -var warning = require('warning'); - -var slice = Array.prototype.slice; - -var MethodTypes = keyMirror({ - remote: null, - local: null, -}); - -/** - * Creates remotely invokable modules. - */ -var BatchedBridgeFactory = { - MethodTypes: MethodTypes, - /** - * @param {MessageQueue} messageQueue Message queue that has been created with - * the `moduleConfig` (among others perhaps). - * @param {object} moduleConfig Configuration of module names/method - * names to callback types. - * @return {object} Remote representation of configured module. - */ - _createBridgedModule: function(messageQueue, moduleConfig, moduleName) { - var remoteModule = mapObject(moduleConfig.methods, function(methodConfig, memberName) { - return methodConfig.type === MethodTypes.local ? null : function() { - var lastArg = arguments.length > 0 ? arguments[arguments.length - 1] : null; - var secondLastArg = arguments.length > 1 ? arguments[arguments.length - 2] : null; - var hasSuccCB = typeof lastArg === 'function'; - var hasErrorCB = typeof secondLastArg === 'function'; - hasErrorCB && invariant( - hasSuccCB, - 'Cannot have a non-function arg after a function arg.' - ); - var numCBs = (hasSuccCB ? 1 : 0) + (hasErrorCB ? 1 : 0); - var args = slice.call(arguments, 0, arguments.length - numCBs); - var onSucc = hasSuccCB ? lastArg : null; - var onFail = hasErrorCB ? secondLastArg : null; - return messageQueue.call(moduleName, memberName, args, onFail, onSucc); - }; - }); - for (var constName in moduleConfig.constants) { - warning(!remoteModule[constName], 'saw constant and method named %s', constName); - remoteModule[constName] = moduleConfig.constants[constName]; - } - return remoteModule; - }, - - - create: function(MessageQueue, modulesConfig, localModulesConfig) { - var messageQueue = new MessageQueue(modulesConfig, localModulesConfig); - return { - callFunction: messageQueue.callFunction.bind(messageQueue), - callFunctionReturnFlushedQueue: - messageQueue.callFunctionReturnFlushedQueue.bind(messageQueue), - invokeCallback: messageQueue.invokeCallback.bind(messageQueue), - invokeCallbackAndReturnFlushedQueue: - messageQueue.invokeCallbackAndReturnFlushedQueue.bind(messageQueue), - flushedQueue: messageQueue.flushedQueue.bind(messageQueue), - RemoteModules: mapObject(modulesConfig, this._createBridgedModule.bind(this, messageQueue)), - setLoggingEnabled: messageQueue.setLoggingEnabled.bind(messageQueue), - getLoggedOutgoingItems: messageQueue.getLoggedOutgoingItems.bind(messageQueue), - getLoggedIncomingItems: messageQueue.getLoggedIncomingItems.bind(messageQueue), - replayPreviousLog: messageQueue.replayPreviousLog.bind(messageQueue), - processBatch: messageQueue.processBatch.bind(messageQueue), - }; - } -}; - -module.exports = BatchedBridgeFactory; -}); -__d('mapObject',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 mapObject - */ - -'use strict'; - -var hasOwnProperty = Object.prototype.hasOwnProperty; - -/** - * Executes the provided `callback` once for each enumerable own property in the - * object and constructs a new object from the results. The `callback` is - * invoked with three arguments: - * - * - the property value - * - the property name - * - the object being traversed - * - * Properties that are added after the call to `mapObject` will not be visited - * by `callback`. If the values of existing properties are changed, the value - * passed to `callback` will be the value at the time `mapObject` visits them. - * Properties that are deleted before being visited are not visited. - * - * @grep function objectMap() - * @grep function objMap() - * - * @param {?object} object - * @param {function} callback - * @param {*} context - * @return {?object} - */ -function mapObject(object, callback, context) { - if (!object) { - return null; - } - var result = {}; - for (var name in object) { - if (hasOwnProperty.call(object, name)) { - result[name] = callback.call(context, object[name], name, object); - } - } - return result; -} - -module.exports = mapObject; -}); -__d('MessageQueue',["ErrorUtils","ReactUpdates","invariant","warning","JSTimersExecution"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 MessageQueue - * @flow - */ -'use strict'; - -var ErrorUtils = require('ErrorUtils'); -var ReactUpdates = require('ReactUpdates'); - -var invariant = require('invariant'); -var warning = require('warning'); - -var JSTimersExecution = require('JSTimersExecution'); - -var INTERNAL_ERROR = 'Error in MessageQueue implementation'; - -// Prints all bridge traffic to console.log -var DEBUG_SPY_MODE = false; - - - - - - - - - - - - - -/** - * So as not to confuse static build system. - */ -var requireFunc = require; - -/** - * @param {Object!} module Module instance, must be loaded. - * @param {string} methodName Name of method in `module`. - * @param {array<*>} params Arguments to method. - * @returns {*} Return value of method invocation. - */ -var jsCall = function(module, methodName, params) { - return module[methodName].apply(module, params); -}; - -/** - * A utility for aggregating "work" to be done, and potentially transferring - * that work to another thread. Each instance of `MessageQueue` has the notion - * of a "target" thread - the thread that the work will be sent to. - * - * TODO: Long running callback results, and streaming callback results (ability - * for a callback to be invoked multiple times). - * - * @param {object} moduleNameToID Used to translate module/method names into - * efficient numeric IDs. - * @class MessageQueue - */ -var MessageQueue = function( - remoteModulesConfig , - localModulesConfig , - customRequire -) { - this._requireFunc = customRequire || requireFunc; - this._initBookeeping(); - this._initNamingMap(remoteModulesConfig, localModulesConfig); -}; - -// REQUEST: Parallell arrays: -var REQUEST_MODULE_IDS = 0; -var REQUEST_METHOD_IDS = 1; -var REQUEST_PARAMSS = 2; -// RESPONSE: Parallell arrays: -var RESPONSE_CBIDS = 3; -var RESPONSE_RETURN_VALUES = 4; - -var applyWithErrorReporter = function(fun , context , args ) { - try { - return fun.apply(context, args); - } catch (e) { - ErrorUtils.reportFatalError(e); - } -}; - -/** - * Utility to catch errors and prevent having to bind, or execute a bound - * function, while catching errors in a process and returning a resulting - * return value. This ensures that even if a process fails, we can still return - * *some* values (from `_flushedQueueUnguarded` for example). Glorified - * try/catch/finally that invokes the global `onerror`. - * - * @param {function} operation Function to execute, likely populates the - * message buffer. - * @param {Array<*>} operationArguments Arguments passed to `operation`. - * @param {function} getReturnValue Returns a return value - will be invoked - * even if the `operation` fails half way through completing its task. - * @return {object} Return value returned from `getReturnValue`. - */ -var guardReturn = function(operation, operationArguments, getReturnValue, context) { - if (operation) { - applyWithErrorReporter(operation, context, operationArguments); - } - if (getReturnValue) { - return applyWithErrorReporter(getReturnValue, context, null); - } - return null; -}; - -/** - * Bookkeeping logic for callbackIDs. We ensure that success and error - * callbacks are numerically adjacent. - * - * We could have also stored the association between success cbID and errorCBID - * in a map without relying on this adjacency, but the bookkeeping here avoids - * an additional two maps to associate in each direction, and avoids growing - * dictionaries (new fields). Instead, we compute pairs of callback IDs, by - * populating the `res` argument to `allocateCallbackIDs` (in conjunction with - * pooling). Behind this bookeeping API, we ensure that error and success - * callback IDs are always adjacent so that when one is invoked, we always know - * how to free the memory of the other. By using this API, it is impossible to - * create malformed callbackIDs that are not adjacent. - */ -var createBookkeeping = function() { - return { - /** - * Incrementing callback ID. Must start at 1 - otherwise converted null - * values which become zero are not distinguishable from a GUID of zero. - */ - GUID: 1, - errorCallbackIDForSuccessCallbackID: function(successID) { - return successID + 1; - }, - successCallbackIDForErrorCallbackID: function(errorID) { - return errorID - 1; - }, - allocateCallbackIDs: function(res) { - res.successCallbackID = this.GUID++; - res.errorCallbackID = this.GUID++; - }, - isSuccessCallback: function(id) { - return id % 2 === 1; - } - }; -}; - -var MessageQueueMixin = { - /** - * Creates an efficient wire protocol for communicating across a bridge. - * Avoids allocating strings. - * - * @param {object} remoteModulesConfig Configuration of modules and their - * methods. - */ - _initNamingMap: function( - remoteModulesConfig , - localModulesConfig - ) { - this._remoteModuleNameToModuleID = {}; - this._remoteModuleIDToModuleName = {}; // Reverse - - this._remoteModuleNameToMethodNameToID = {}; - this._remoteModuleNameToMethodIDToName = {}; // Reverse - - this._localModuleNameToModuleID = {}; - this._localModuleIDToModuleName = {}; // Reverse - - this._localModuleNameToMethodNameToID = {}; - this._localModuleNameToMethodIDToName = {}; // Reverse - - function fillMappings( - modulesConfig , - moduleNameToModuleID , - moduleIDToModuleName , - moduleNameToMethodNameToID , - moduleNameToMethodIDToName - ) { - for (var moduleName in modulesConfig) { - var moduleConfig = modulesConfig[moduleName]; - var moduleID = moduleConfig.moduleID; - moduleNameToModuleID[moduleName] = moduleID; - moduleIDToModuleName[moduleID] = moduleName; // Reverse - - moduleNameToMethodNameToID[moduleName] = {}; - moduleNameToMethodIDToName[moduleName] = {}; // Reverse - var methods = moduleConfig.methods; - for (var methodName in methods) { - var methodID = methods[methodName].methodID; - moduleNameToMethodNameToID[moduleName][methodName] = - methodID; - moduleNameToMethodIDToName[moduleName][methodID] = - methodName; // Reverse - } - } - } - fillMappings( - remoteModulesConfig, - this._remoteModuleNameToModuleID, - this._remoteModuleIDToModuleName, - this._remoteModuleNameToMethodNameToID, - this._remoteModuleNameToMethodIDToName - ); - - fillMappings( - localModulesConfig, - this._localModuleNameToModuleID, - this._localModuleIDToModuleName, - this._localModuleNameToMethodNameToID, - this._localModuleNameToMethodIDToName - ); - - }, - - _initBookeeping: function() { - this._POOLED_CBIDS = {errorCallbackID: null, successCallbackID: null}; - this._bookkeeping = createBookkeeping(); - - /** - * Stores callbacks so that we may simulate asynchronous return values from - * other threads. Remote invocations in other threads can pass return values - * back asynchronously to the requesting thread. - */ - this._threadLocalCallbacksByID = []; - this._threadLocalScopesByID = []; - - /** - * Memory efficient parallel arrays. Each index cuts through the three - * arrays and forms a remote invocation of methodName(params) whos return - * value will be reported back to the other thread by way of the - * corresponding id in cbIDs. Each entry (A-D in the graphic below), - * represents a work item of the following form: - * - moduleID: ID of module to invoke method from. - * - methodID: ID of method in module to invoke. - * - params: List of params to pass to method. - * - cbID: ID to respond back to originating thread with. - * - * TODO: We can make this even more efficient (memory) by creating a single - * array, that is always pushed `n` elements as a time. - */ - this._outgoingItems = [ - /*REQUEST_MODULE_IDS: */ [/* +-+ +-+ +-+ +-+ */], - /*REQUEST_METHOD_IDS: */ [/* |A| |B| |C| |D| */], - /*REQUEST_PARAMSS: */ [/* |-| |-| |-| |-| */], - - /*RESPONSE_CBIDS: */ [/* +-+ +-+ +-+ +-+ */], - /* |E| |F| |G| |H| */ - /*RESPONSE_RETURN_VALUES: */ [/* +-+ +-+ +-+ +-+ */] - ]; - - /** - * Used to allow returning the buffer, while at the same time clearing it in - * a memory efficient manner. - */ - this._outgoingItemsSwap = [[], [], [], [], []]; - }, - - invokeCallback: function(cbID, args) { - return guardReturn(this._invokeCallback, [cbID, args], null, this); - }, - - _invokeCallback: function(cbID, args) { - try { - var cb = this._threadLocalCallbacksByID[cbID]; - var scope = this._threadLocalScopesByID[cbID]; - warning( - cb, - 'Cannot find callback with CBID %s. Native module may have invoked ' + - 'both the success callback and the error callback.', - cbID - ); - if (DEBUG_SPY_MODE) { - console.log('N->JS: Callback#' + cbID + '(' + JSON.stringify(args) + ')'); - } - cb.apply(scope, args); - } catch(ie_requires_catch) { - throw ie_requires_catch; - } finally { - // Clear out the memory regardless of success or failure. - this._freeResourcesForCallbackID(cbID); - } - }, - - invokeCallbackAndReturnFlushedQueue: function(cbID, args) { - if (this._enableLogging) { - this._loggedIncomingItems.push([new Date().getTime(), cbID, args]); - } - return guardReturn( - this._invokeCallback, - [cbID, args], - this._flushedQueueUnguarded, - this - ); - }, - - callFunction: function(moduleID, methodID, params) { - return guardReturn(this._callFunction, [moduleID, methodID, params], null, this); - }, - - _callFunction: function(moduleID, methodID, params) { - var moduleName = this._localModuleIDToModuleName[moduleID]; - - var methodName = this._localModuleNameToMethodIDToName[moduleName][methodID]; - if (DEBUG_SPY_MODE) { - console.log( - 'N->JS: ' + moduleName + '.' + methodName + - '(' + JSON.stringify(params) + ')'); - } - var ret = jsCall(this._requireFunc(moduleName), methodName, params); - - return ret; - }, - - callFunctionReturnFlushedQueue: function(moduleID, methodID, params) { - if (this._enableLogging) { - this._loggedIncomingItems.push([new Date().getTime(), moduleID, methodID, params]); - } - return guardReturn( - this._callFunction, - [moduleID, methodID, params], - this._flushedQueueUnguarded, - this - ); - }, - - processBatch: function(batch) { - var self = this; - return guardReturn(function () { - ReactUpdates.batchedUpdates(function() { - batch.forEach(function(call) { - invariant( - call.module === 'BatchedBridge', - 'All the calls should pass through the BatchedBridge module' - ); - if (call.method === 'callFunctionReturnFlushedQueue') { - self._callFunction.apply(self, call.args); - } else if (call.method === 'invokeCallbackAndReturnFlushedQueue') { - self._invokeCallback.apply(self, call.args); - } else { - throw new Error( - 'Unrecognized method called on BatchedBridge: ' + call.method); - } - }); - }); - }, null, this._flushedQueueUnguarded, this); - }, - - setLoggingEnabled: function(enabled) { - this._enableLogging = enabled; - this._loggedIncomingItems = []; - this._loggedOutgoingItems = [[], [], [], [], []]; - }, - - getLoggedIncomingItems: function() { - return this._loggedIncomingItems; - }, - - getLoggedOutgoingItems: function() { - return this._loggedOutgoingItems; - }, - - replayPreviousLog: function(previousLog) { - this._outgoingItems = previousLog; - }, - - /** - * Simple helpers for clearing the queues. This doesn't handle the fact that - * memory in the current buffer is leaked until the next frame or update - but - * that will typically be on the order of < 500ms. - */ - _swapAndReinitializeBuffer: function() { - // Outgoing requests - var currentOutgoingItems = this._outgoingItems; - var nextOutgoingItems = this._outgoingItemsSwap; - - nextOutgoingItems[REQUEST_MODULE_IDS].length = 0; - nextOutgoingItems[REQUEST_METHOD_IDS].length = 0; - nextOutgoingItems[REQUEST_PARAMSS].length = 0; - - // Outgoing responses - nextOutgoingItems[RESPONSE_CBIDS].length = 0; - nextOutgoingItems[RESPONSE_RETURN_VALUES].length = 0; - - this._outgoingItemsSwap = currentOutgoingItems; - this._outgoingItems = nextOutgoingItems; - }, - - /** - * @param {string} moduleID JS module name. - * @param {methodName} methodName Method in module to invoke. - * @param {array<*>?} params Array representing arguments to method. - * @param {string} cbID Unique ID to pass back in potential response. - */ - _pushRequestToOutgoingItems: function(moduleID, methodName, params) { - this._outgoingItems[REQUEST_MODULE_IDS].push(moduleID); - this._outgoingItems[REQUEST_METHOD_IDS].push(methodName); - this._outgoingItems[REQUEST_PARAMSS].push(params); - - if (this._enableLogging) { - this._loggedOutgoingItems[REQUEST_MODULE_IDS].push(moduleID); - this._loggedOutgoingItems[REQUEST_METHOD_IDS].push(methodName); - this._loggedOutgoingItems[REQUEST_PARAMSS].push(params); - } - }, - - /** - * @param {string} cbID Unique ID that other side of bridge has remembered. - * @param {*} returnValue Return value to pass to callback on other side of - * bridge. - */ - _pushResponseToOutgoingItems: function(cbID, returnValue) { - this._outgoingItems[RESPONSE_CBIDS].push(cbID); - this._outgoingItems[RESPONSE_RETURN_VALUES].push(returnValue); - }, - - _freeResourcesForCallbackID: function(cbID) { - var correspondingCBID = this._bookkeeping.isSuccessCallback(cbID) ? - this._bookkeeping.errorCallbackIDForSuccessCallbackID(cbID) : - this._bookkeeping.successCallbackIDForErrorCallbackID(cbID); - this._threadLocalCallbacksByID[cbID] = null; - this._threadLocalScopesByID[cbID] = null; - if (this._threadLocalCallbacksByID[correspondingCBID]) { - this._threadLocalCallbacksByID[correspondingCBID] = null; - this._threadLocalScopesByID[correspondingCBID] = null; - } - }, - - /** - * @param {Function} onFail Function to store in current thread for later - * lookup, when request fails. - * @param {Function} onSucc Function to store in current thread for later - * lookup, when request succeeds. - * @param {Object?=} scope Scope to invoke `cb` with. - * @param {Object?=} res Resulting callback ids. Use `this._POOLED_CBIDS`. - */ - _storeCallbacksInCurrentThread: function(onFail, onSucc, scope) { - invariant(onFail || onSucc, INTERNAL_ERROR); - this._bookkeeping.allocateCallbackIDs(this._POOLED_CBIDS); - var succCBID = this._POOLED_CBIDS.successCallbackID; - var errorCBID = this._POOLED_CBIDS.errorCallbackID; - this._threadLocalCallbacksByID[errorCBID] = onFail; - this._threadLocalCallbacksByID[succCBID] = onSucc; - this._threadLocalScopesByID[errorCBID] = scope; - this._threadLocalScopesByID[succCBID] = scope; - }, - - - /** - * IMPORTANT: There is possibly a timing issue with this form of flushing. We - * are currently not seeing any problems but the potential issue to look out - * for is: - * - While flushing this._outgoingItems contains the work for the other thread - * to perform. - * - To mitigate this, we never allow enqueueing messages if the queue is - * already reserved - as long as it is reserved, it could be in the midst of - * a flush. - * - * If this ever occurs we can easily eliminate the race condition. We can - * completely solve any ambiguity by sending messages such that we'll never - * try to reserve the queue when already reserved. Here's the pseudocode: - * - * var defensiveCopy = efficientDefensiveCopy(this._outgoingItems); - * this._swapAndReinitializeBuffer(); - */ - flushedQueue: function() { - return guardReturn(null, null, this._flushedQueueUnguarded, this); - }, - - _flushedQueueUnguarded: function() { - // Call the functions registred via setImmediate - JSTimersExecution.callImmediates(); - - var currentOutgoingItems = this._outgoingItems; - this._swapAndReinitializeBuffer(); - var ret = currentOutgoingItems[REQUEST_MODULE_IDS].length || - currentOutgoingItems[RESPONSE_RETURN_VALUES].length ? currentOutgoingItems : null; - - if (DEBUG_SPY_MODE && ret) { - for (var i = 0; i < currentOutgoingItems[0].length; i++) { - var moduleName = this._remoteModuleIDToModuleName[currentOutgoingItems[0][i]]; - var methodName = - this._remoteModuleNameToMethodIDToName[moduleName][currentOutgoingItems[1][i]]; - console.log( - 'JS->N: ' + moduleName + '.' + methodName + - '(' + JSON.stringify(currentOutgoingItems[2][i]) + ')'); - } - } - - return ret; - }, - - call: function(moduleName, methodName, params, onFail, onSucc, scope) { - invariant( - (!onFail || typeof onFail === 'function') && - (!onSucc || typeof onSucc === 'function'), - 'Callbacks must be functions' - ); - // Store callback _before_ sending the request, just in case the MailBox - // returns the response in a blocking manner. - if (onSucc) { - this._storeCallbacksInCurrentThread(onFail, onSucc, scope, this._POOLED_CBIDS); - onFail && params.push(this._POOLED_CBIDS.errorCallbackID); - params.push(this._POOLED_CBIDS.successCallbackID); - } - var moduleID = this._remoteModuleNameToModuleID[moduleName]; - if (moduleID === undefined || moduleID === null) { - throw new Error('Unrecognized module name:' + moduleName); - } - var methodID = this._remoteModuleNameToMethodNameToID[moduleName][methodName]; - if (methodID === undefined || moduleID === null) { - throw new Error('Unrecognized method name:' + methodName); - } - this._pushRequestToOutgoingItems(moduleID, methodID, params); - }, - __numPendingCallbacksOnlyUseMeInTestCases: function() { - var callbacks = this._threadLocalCallbacksByID; - var total = 0; - for (var i = 0; i < callbacks.length; i++) { - if (callbacks[i]) { - total++; - } - } - return total; - } -}; - -Object.assign(MessageQueue.prototype, MessageQueueMixin); -module.exports = MessageQueue; -}); -__d('JSTimersExecution',["invariant","keyMirror","performanceNow","warning","JSTimers","JSTimers"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 JSTimersExecution - */ -'use strict'; - -var invariant = require('invariant'); -var keyMirror = require('keyMirror'); -var performanceNow = require('performanceNow'); -var warning = require('warning'); - -/** - * JS implementation of timer functions. Must be completely driven by an - * external clock signal, all that's stored here is timerID, timer type, and - * callback. - */ -var JSTimersExecution = { - GUID: 1, - Type: keyMirror({ - setTimeout: null, - setInterval: null, - requestAnimationFrame: null, - setImmediate: null, - }), - - // Parallel arrays: - callbacks: [], - types: [], - timerIDs: [], - immediates: [], - - /** - * Calls the callback associated with the ID. Also unregister that callback - * if it was a one time timer (setTimeout), and not unregister it if it was - * recurring (setInterval). - */ - callTimer: function(timerID) { - warning(timerID <= JSTimersExecution.GUID, 'Tried to call timer with ID ' + timerID + ' but no such timer exists'); - var timerIndex = JSTimersExecution.timerIDs.indexOf(timerID); - // timerIndex of -1 means that no timer with that ID exists. There are - // two situations when this happens, when a garbage timer ID was given - // and when a previously existing timer was deleted before this callback - // fired. In both cases we want to ignore the timer id, but in the former - // case we warn as well. - if (timerIndex === -1) { - return; - } - var type = JSTimersExecution.types[timerIndex]; - var callback = JSTimersExecution.callbacks[timerIndex]; - - // Clear the metadata - if (type === JSTimersExecution.Type.setTimeout || - type === JSTimersExecution.Type.setImmediate || - type === JSTimersExecution.Type.requestAnimationFrame) { - JSTimersExecution._clearIndex(timerIndex); - } - - try { - if (type === JSTimersExecution.Type.setTimeout || - type === JSTimersExecution.Type.setInterval || - type === JSTimersExecution.Type.setImmediate) { - callback(); - } else if (type === JSTimersExecution.Type.requestAnimationFrame) { - var currentTime = performanceNow(); - callback(currentTime); - } else { - console.error('Tried to call a callback with invalid type: ' + type); - return; - } - } catch (e) { - // Don't rethrow so that we can run every other timer. - JSTimersExecution.errors = JSTimersExecution.errors || []; - JSTimersExecution.errors.push(e); - } - }, - - /** - * This is called from the native side. We are passed an array of timerIDs, - * and - */ - callTimers: function(timerIDs) { - invariant(timerIDs.length !== 0, 'Probably shouldn\'t call "callTimers" with no timerIDs'); - - JSTimersExecution.errors = null; - timerIDs.forEach(JSTimersExecution.callTimer); - - var errors = JSTimersExecution.errors; - if (errors) { - var errorCount = errors.length; - if (errorCount > 1) { - // Throw all the other errors in a setTimeout, which will throw each - // error one at a time - for (var ii = 1; ii < errorCount; ii++) { - require('JSTimers').setTimeout( - (function(error) { throw error; }).bind(null, errors[ii]), - 0 - ); - } - } - throw errors[0]; - } - }, - - /** - * This is called after we execute any command we receive from native but - * before we hand control back to native. - */ - callImmediates: function() { - JSTimersExecution.errors = null; - while (JSTimersExecution.immediates.length !== 0) { - JSTimersExecution.callTimer(JSTimersExecution.immediates.shift()); - } - if (JSTimersExecution.errors) { - JSTimersExecution.errors.forEach(function(error) - {return require('JSTimers').setTimeout(function() { throw error; }, 0);} - ); - } - }, - - _clearIndex: function(i) { - JSTimersExecution.timerIDs[i] = null; - JSTimersExecution.callbacks[i] = null; - JSTimersExecution.types[i] = null; - }, -}; - -module.exports = JSTimersExecution; -}); -__d('performanceNow',["performance"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 performanceNow - * @typechecks - */ - -var performance = require('performance'); - -/** - * Detect if we can use `window.performance.now()` and gracefully fallback to - * `Date.now()` if it doesn't exist. We need to support Firefox < 15 for now - * because of Facebook's testing infrastructure. - */ -if (!performance || !performance.now) { - performance = Date; -} - -var performanceNow = performance.now.bind(performance); - -module.exports = performanceNow; -}); -__d('performance',["ExecutionEnvironment"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 performance - * @typechecks - */ - -"use strict"; - -var ExecutionEnvironment = require('ExecutionEnvironment'); - -var performance; - -if (ExecutionEnvironment.canUseDOM) { - performance = - window.performance || - window.msPerformance || - window.webkitPerformance; -} - -module.exports = performance || {}; -}); -__d('ExecutionEnvironment',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ExecutionEnvironment - */ - -/*jslint evil: true */ - -"use strict"; - -var canUseDOM = !!( - typeof window !== 'undefined' && - window.document && - window.document.createElement -); - -/** - * Simple, lightweight module assisting with the detection and context of - * Worker. Helps avoid circular dependencies and allows code to reason about - * whether or not they are in a Worker, even if they never include the main - * `ReactWorker` dependency. - */ -var ExecutionEnvironment = { - - canUseDOM: canUseDOM, - - canUseWorkers: typeof Worker !== 'undefined', - - canUseEventListeners: - canUseDOM && !!(window.addEventListener || window.attachEvent), - - canUseViewport: canUseDOM && !!window.screen, - - isInWorker: !canUseDOM // For now, this is true - might change in the future. - -}; - -module.exports = ExecutionEnvironment; -}); -__d('JSTimers',["NativeModules","JSTimersExecution"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 JSTimers - */ -'use strict'; - -// Note that the module JSTimers is split into two in order to solve a cycle -// in dependencies. NativeModules > BatchedBridge > MessageQueue > JSTimersExecution -var RCTTiming = require('NativeModules').Timing; -var JSTimersExecution = require('JSTimersExecution'); - -/** - * JS implementation of timer functions. Must be completely driven by an - * external clock signal, all that's stored here is timerID, timer type, and - * callback. - */ -var JSTimers = { - Types: JSTimersExecution.Types, - - /** - * Returns a free index if one is available, and the next consecutive index - * otherwise. - */ - _getFreeIndex: function() { - var freeIndex = JSTimersExecution.timerIDs.indexOf(null); - if (freeIndex === -1) { - freeIndex = JSTimersExecution.timerIDs.length; - } - return freeIndex; - }, - - /** - * @param {function} func Callback to be invoked after `duration` ms. - * @param {number} duration Number of milliseconds. - */ - setTimeout: function(func, duration ) {for (var args=[],$__0=2,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); - var newID = JSTimersExecution.GUID++; - var freeIndex = JSTimers._getFreeIndex(); - JSTimersExecution.timerIDs[freeIndex] = newID; - JSTimersExecution.callbacks[freeIndex] = function() { - return func.apply(undefined, args); - }; - JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.setTimeout; - RCTTiming.createTimer(newID, duration, Date.now(), /** recurring */ false); - return newID; - }, - - /** - * @param {function} func Callback to be invoked every `duration` ms. - * @param {number} duration Number of milliseconds. - */ - setInterval: function(func, duration ) {for (var args=[],$__0=2,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); - var newID = JSTimersExecution.GUID++; - var freeIndex = JSTimers._getFreeIndex(); - JSTimersExecution.timerIDs[freeIndex] = newID; - JSTimersExecution.callbacks[freeIndex] = function() { - var startTime = Date.now(); - var ret = func.apply(undefined, args); - var endTime = Date.now(); - RCTTiming.createTimer(newID, Math.max(0, duration - (endTime - startTime)), endTime, false); - return ret; - }; - JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.setInterval; - RCTTiming.createTimer(newID, duration, Date.now(), /** recurring */ false); - return newID; - }, - - /** - * @param {function} func Callback to be invoked before the end of the - * current JavaScript execution loop. - */ - setImmediate: function(func ) {for (var args=[],$__0=1,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); - var newID = JSTimersExecution.GUID++; - var freeIndex = JSTimers._getFreeIndex(); - JSTimersExecution.timerIDs[freeIndex] = newID; - JSTimersExecution.callbacks[freeIndex] = function() { - return func.apply(undefined, args); - }; - JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.setImmediate; - JSTimersExecution.immediates.push(newID); - return newID; - }, - - /** - * @param {function} func Callback to be invoked every frame. - */ - requestAnimationFrame: function(func) { - var newID = JSTimersExecution.GUID++; - var freeIndex = JSTimers._getFreeIndex(); - JSTimersExecution.timerIDs[freeIndex] = newID; - JSTimersExecution.callbacks[freeIndex] = func; - JSTimersExecution.types[freeIndex] = JSTimersExecution.Type.requestAnimationFrame; - RCTTiming.createTimer(newID, 1, Date.now(), /** recurring */ false); - return newID; - }, - - clearTimeout: function(timerID) { - JSTimers._clearTimerID(timerID); - }, - - clearInterval: function(timerID) { - JSTimers._clearTimerID(timerID); - }, - - clearImmediate: function(timerID) { - JSTimers._clearTimerID(timerID); - JSTimersExecution.immediates.splice( - JSTimersExecution.immediates.indexOf(timerID), - 1 - ); - }, - - cancelAnimationFrame: function(timerID) { - JSTimers._clearTimerID(timerID); - }, - - _clearTimerID: function(timerID) { - // JSTimersExecution.timerIDs contains nulls after timers have been removed; - // ignore nulls upfront so indexOf doesn't find them - if (timerID == null) { - return; - } - - var index = JSTimersExecution.timerIDs.indexOf(timerID); - // See corresponding comment in `callTimers` for reasoning behind this - if (index !== -1) { - JSTimersExecution._clearIndex(index); - if (JSTimersExecution.types[index] !== JSTimersExecution.Type.setImmediate) { - RCTTiming.deleteTimer(timerID); - } - } - }, -}; - -module.exports = JSTimers; -}); -__d('nativeModulePrefixNormalizer',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 nativeModulePrefixNormalizer - * @flow - */ -'use strict'; - -// Dirty hack to support old (RK) and new (RCT) native module name conventions -function nativeModulePrefixNormalizer( - modules -) { - Object.keys(modules).forEach(function(moduleName) { - var strippedName = moduleName.replace(/^(RCT|RK)/, ''); - if (modules['RCT' + strippedName] && modules['RK' + strippedName]) { - throw new Error( - 'Module cannot be registered as both RCT and RK: ' + moduleName - ); - } - if (strippedName !== moduleName) { - modules[strippedName] = modules[moduleName]; - delete modules[moduleName]; - } - }); -} - -module.exports = nativeModulePrefixNormalizer; -}); -__d('loadSourceMap',["Promise","NativeModules","SourceMap","react-native/Libraries/JavaScriptAppEngine/Initialization/source-map-url"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 loadSourceMap - * @flow - */ - -'use strict'; - -var Promise = require('Promise'); -var NativeModules = require('NativeModules'); -var SourceMapConsumer = require('SourceMap').SourceMapConsumer; -var SourceMapURL = require('react-native/Libraries/JavaScriptAppEngine/Initialization/source-map-url'); - -var RCTSourceCode = NativeModules.SourceCode; -var RCTDataManager = NativeModules.DataManager; - -function loadSourceMap() { - return fetchSourceMap() - .then(function(map) {return new SourceMapConsumer(map);}); -} - -function fetchSourceMap() { - if (global.RAW_SOURCE_MAP) { - return Promise.resolve(global.RAW_SOURCE_MAP); - } - - if (!RCTSourceCode) { - return Promise.reject(new Error('RCTSourceCode module is not available')); - } - - if (!RCTDataManager) { - // Used internally by fetch - return Promise.reject(new Error('RCTDataManager module is not available')); - } - - return new Promise(RCTSourceCode.getScriptText) - .then(extractSourceMapURL) - .then(function(url) { - if (url === null) { - return Promise.reject(new Error('No source map URL found. May be running from bundled file.')); - } - return Promise.resolve(url); - }) - .then(fetch) - .then(function(response) {return response.text();}) -} - -function extractSourceMapURL($__0 ) {var url=$__0.url,text=$__0.text,fullSourceMappingURL=$__0.fullSourceMappingURL; - if (fullSourceMappingURL) { - return fullSourceMappingURL; - } - var mapURL = SourceMapURL.getFrom(text); - if (!mapURL) { - return null; - } - var baseURL = url.match(/(.+:\/\/.*?)\//)[1]; - return baseURL + mapURL; -} - -module.exports = loadSourceMap; -}); -__d('Promise',["setImmediate","promise/setimmediate/es6-extensions","promise/setimmediate/done"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * - * Copyright 2013-2014 Facebook, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @providesModule Promise - * - * This module wraps and augments the minimally ES6-compliant Promise - * implementation provided by the promise npm package. - */ - -'use strict'; - -global.setImmediate = require('setImmediate'); -var Promise = require('promise/setimmediate/es6-extensions'); -require('promise/setimmediate/done'); - -/** - * Handle either fulfillment or rejection with the same callback. - */ -Promise.prototype["finally"] = function(onSettled) { - return this.then(onSettled, onSettled); -}; - - -module.exports = Promise; -}); -__d('setImmediate',["ImmediateImplementation"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * @generated SignedSource<<9715e66cd259f4d1a1c3d39c97cd0b92>> - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !! This file is a check-in of a static_upstream project! !! - * !! !! - * !! You should not modify this file directly. Instead: !! - * !! 1) Use `fjs use-upstream` to temporarily replace this with !! - * !! the latest version from upstream. !! - * !! 2) Make your changes, test them, etc. !! - * !! 3) Use `fjs push-upstream` to copy your changes back to !! - * !! static_upstream. !! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * @providesModule setImmediate - */ - -module.exports = global.setImmediate || - require('ImmediateImplementation').setImmediate; -}); -__d('ImmediateImplementation',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * @generated SignedSource<<57d0446bbd1186485d372efe6b323dca>> - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !! This file is a check-in of a static_upstream project! !! - * !! !! - * !! You should not modify this file directly. Instead: !! - * !! 1) Use `fjs use-upstream` to temporarily replace this with !! - * !! the latest version from upstream. !! - * !! 2) Make your changes, test them, etc. !! - * !! 3) Use `fjs push-upstream` to copy your changes back to !! - * !! static_upstream. !! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * Copyright (c) 2012 Barnesandnoble.com, llc, Donavon West, and Domenic - * Denicola - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * 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 - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 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. - * - * @preserve-header - * @providesModule ImmediateImplementation - */ - -(function(global, undefined) { - "use strict"; - - var nextHandle = 1; // Spec says greater than zero - var tasksByHandle = {}; - var queueHead = {}; - var queueTail = queueHead; - var currentlyRunningATask = false; - var doc = global.document; - var setImmediate; - - function addFromSetImmediateArguments(args) { - var handler = args[0]; - args = Array.prototype.slice.call(args, 1); - tasksByHandle[nextHandle] = function() { - handler.apply(undefined, args); - }; - queueTail = (queueTail.next = { handle: nextHandle++ }); - return queueTail.handle; - } - - function flushQueue() { - var next, task; - while (!currentlyRunningATask && (next = queueHead.next)) { - queueHead = next; // If this task fails, don't retry it. - if ((task = tasksByHandle[next.handle])) { - currentlyRunningATask = true; - try { - task(); - currentlyRunningATask = false; - } finally { - clearImmediate(next.handle); - if (currentlyRunningATask) { - currentlyRunningATask = false; - // The call to task() must have thrown an - // exception if we reach this point, so, just in - // case there are tasks remaining to be executed, - // we schedule another flushQueue in a later tick - // of the event loop, and let the exception - // propagate uncaught. - if (queueHead.next) { - setImmediate(flushQueue); - } - } - } - } - } - } - - function clearImmediate(handle) { - delete tasksByHandle[handle]; - } - - function canUsePostMessage() { - // The test against `importScripts` prevents this implementation from being installed inside a web worker, - // where `global.postMessage` means something completely different and can't be used for this purpose. - if (global.postMessage && !global.importScripts) { - var postMessageIsAsynchronous = true; - - var onMessage = function() { - postMessageIsAsynchronous = false; - if (global.removeEventListener) { - global.removeEventListener("message", onMessage, false); - } else { - global.detachEvent("onmessage", onMessage); - } - }; - - if (global.addEventListener) { - global.addEventListener("message", onMessage, false); - } else if (global.attachEvent) { - global.attachEvent("onmessage", onMessage); - } else { - return false; - } - - global.postMessage("", "*"); - return postMessageIsAsynchronous; - } - } - - function installPostMessageImplementation() { - // Installs an event handler on `global` for the `message` event: see - // * https://developer.mozilla.org/en/DOM/window.postMessage - var messagePrefix = "setImmediate$" + Math.random() + "$"; - var onGlobalMessage = function(event) { - if (event.source === global && - typeof event.data === "string" && - event.data.indexOf(messagePrefix) === 0) { - flushQueue(); - } - }; - - if (global.addEventListener) { - global.addEventListener("message", onGlobalMessage, false); - } else { - global.attachEvent("onmessage", onGlobalMessage); - } - - setImmediate = function() { - var handle = addFromSetImmediateArguments(arguments); - global.postMessage(messagePrefix + handle, "*"); - return handle; - }; - } - - function installMessageChannelImplementation() { - var channel = new MessageChannel(); - channel.port1.onmessage = flushQueue; - setImmediate = function() { - var handle = addFromSetImmediateArguments(arguments); - channel.port2.postMessage(handle); - return handle; - }; - } - - function installReadyStateChangeImplementation() { - var html = doc.documentElement; - setImmediate = function() { - var handle = addFromSetImmediateArguments(arguments); - // Create a -// -// -// Here's how it works. -// -// ``` -// // Get a reference to the logo element. -// var el = document.getElementById('logo'); -// -// // create a SpringSystem and a Spring with a bouncy config. -// var springSystem = new rebound.SpringSystem(); -// var spring = springSystem.createSpring(50, 3); -// -// // Add a listener to the spring. Every time the physics -// // solver updates the Spring's value onSpringUpdate will -// // be called. -// spring.addListener({ -// onSpringUpdate: function(spring) { -// var val = spring.getCurrentValue(); -// val = rebound.MathUtil -// .mapValueInRange(val, 0, 1, 1, 0.5); -// scale(el, val); -// } -// }); -// -// // Listen for mouse down/up/out and toggle the -// //springs endValue from 0 to 1. -// el.addEventListener('mousedown', function() { -// spring.setEndValue(1); -// }); -// -// el.addEventListener('mouseout', function() { -// spring.setEndValue(0); -// }); -// -// el.addEventListener('mouseup', function() { -// spring.setEndValue(0); -// }); -// -// // Helper for scaling an element with css transforms. -// function scale(el, val) { -// el.style.mozTransform = -// el.style.msTransform = -// el.style.webkitTransform = -// el.style.transform = 'scale3d(' + -// val + ', ' + val + ', 1)'; -// } -// ``` - -(function() { - var rebound = {}; - var util = rebound.util = {}; - var concat = Array.prototype.concat; - var slice = Array.prototype.slice; - - // Bind a function to a context object. - util.bind = function bind(func, context) { - var args = slice.call(arguments, 2); - return function() { - func.apply(context, concat.call(args, slice.call(arguments))); - }; - }; - - // Add all the properties in the source to the target. - util.extend = function extend(target, source) { - for (var key in source) { - if (source.hasOwnProperty(key)) { - target[key] = source[key]; - } - } - }; - - // SpringSystem - // ------------ - // **SpringSystem** is a set of Springs that all run on the same physics - // timing loop. To get started with a Rebound animation you first - // create a new SpringSystem and then add springs to it. - var SpringSystem = rebound.SpringSystem = function SpringSystem(looper) { - this._springRegistry = {}; - this._activeSprings = []; - this.listeners = []; - this._idleSpringIndices = []; - this.looper = looper || new AnimationLooper(); - this.looper.springSystem = this; - }; - - util.extend(SpringSystem.prototype, { - - _springRegistry: null, - - _isIdle: true, - - _lastTimeMillis: -1, - - _activeSprings: null, - - listeners: null, - - _idleSpringIndices: null, - - // A SpringSystem is iterated by a looper. The looper is responsible - // for executing each frame as the SpringSystem is resolved to idle. - // There are three types of Loopers described below AnimationLooper, - // SimulationLooper, and SteppingSimulationLooper. AnimationLooper is - // the default as it is the most useful for common UI animations. - setLooper: function(looper) { - this.looper = looper; - looper.springSystem = this; - }, - - // Add a new spring to this SpringSystem. This Spring will now be solved for - // during the physics iteration loop. By default the spring will use the - // default Origami spring config with 40 tension and 7 friction, but you can - // also provide your own values here. - createSpring: function(tension, friction) { - var springConfig; - if (tension === undefined || friction === undefined) { - springConfig = SpringConfig.DEFAULT_ORIGAMI_SPRING_CONFIG; - } else { - springConfig = - SpringConfig.fromOrigamiTensionAndFriction(tension, friction); - } - return this.createSpringWithConfig(springConfig); - }, - - // Add a spring with a specified bounciness and speed. To replicate Origami - // compositions based on PopAnimation patches, use this factory method to - // create matching springs. - createSpringWithBouncinessAndSpeed: function(bounciness, speed) { - var springConfig; - if (bounciness === undefined || speed === undefined) { - springConfig = SpringConfig.DEFAULT_ORIGAMI_SPRING_CONFIG; - } else { - springConfig = - SpringConfig.fromBouncinessAndSpeed(bounciness, speed); - } - return this.createSpringWithConfig(springConfig); - }, - - // Add a spring with the provided SpringConfig. - createSpringWithConfig: function(springConfig) { - var spring = new Spring(this); - this.registerSpring(spring); - spring.setSpringConfig(springConfig); - return spring; - }, - - // You can check if a SpringSystem is idle or active by calling - // getIsIdle. If all of the Springs in the SpringSystem are at rest, - // i.e. the physics forces have reached equilibrium, then this - // method will return true. - getIsIdle: function() { - return this._isIdle; - }, - - // Retrieve a specific Spring from the SpringSystem by id. This - // can be useful for inspecting the state of a spring before - // or after an integration loop in the SpringSystem executes. - getSpringById: function (id) { - return this._springRegistry[id]; - }, - - // Get a listing of all the springs registered with this - // SpringSystem. - getAllSprings: function() { - var vals = []; - for (var id in this._springRegistry) { - if (this._springRegistry.hasOwnProperty(id)) { - vals.push(this._springRegistry[id]); - } - } - return vals; - }, - - // registerSpring is called automatically as soon as you create - // a Spring with SpringSystem#createSpring. This method sets the - // spring up in the registry so that it can be solved in the - // solver loop. - registerSpring: function(spring) { - this._springRegistry[spring.getId()] = spring; - }, - - // Deregister a spring with this SpringSystem. The SpringSystem will - // no longer consider this Spring during its integration loop once - // this is called. This is normally done automatically for you when - // you call Spring#destroy. - deregisterSpring: function(spring) { - removeFirst(this._activeSprings, spring); - delete this._springRegistry[spring.getId()]; - }, - - advance: function(time, deltaTime) { - while(this._idleSpringIndices.length > 0) this._idleSpringIndices.pop(); - for (var i = 0, len = this._activeSprings.length; i < len; i++) { - var spring = this._activeSprings[i]; - if (spring.systemShouldAdvance()) { - spring.advance(time / 1000.0, deltaTime / 1000.0); - } else { - this._idleSpringIndices.push(this._activeSprings.indexOf(spring)); - } - } - while(this._idleSpringIndices.length > 0) { - var idx = this._idleSpringIndices.pop(); - idx >= 0 && this._activeSprings.splice(idx, 1); - } - }, - - // This is our main solver loop called to move the simulation - // forward through time. Before each pass in the solver loop - // onBeforeIntegrate is called on an any listeners that have - // registered themeselves with the SpringSystem. This gives you - // an opportunity to apply any constraints or adjustments to - // the springs that should be enforced before each iteration - // loop. Next the advance method is called to move each Spring in - // the systemShouldAdvance forward to the current time. After the - // integration step runs in advance, onAfterIntegrate is called - // on any listeners that have registered themselves with the - // SpringSystem. This gives you an opportunity to run any post - // integration constraints or adjustments on the Springs in the - // SpringSystem. - loop: function(currentTimeMillis) { - var listener; - if (this._lastTimeMillis === -1) { - this._lastTimeMillis = currentTimeMillis -1; - } - var ellapsedMillis = currentTimeMillis - this._lastTimeMillis; - this._lastTimeMillis = currentTimeMillis; - - var i = 0, len = this.listeners.length; - for (i = 0; i < len; i++) { - listener = this.listeners[i]; - listener.onBeforeIntegrate && listener.onBeforeIntegrate(this); - } - - this.advance(currentTimeMillis, ellapsedMillis); - if (this._activeSprings.length === 0) { - this._isIdle = true; - this._lastTimeMillis = -1; - } - - for (i = 0; i < len; i++) { - listener = this.listeners[i]; - listener.onAfterIntegrate && listener.onAfterIntegrate(this); - } - - if (!this._isIdle) { - this.looper.run(); - } - }, - - // activateSpring is used to notify the SpringSystem that a Spring - // has become displaced. The system responds by starting its solver - // loop up if it is currently idle. - activateSpring: function(springId) { - var spring = this._springRegistry[springId]; - if (this._activeSprings.indexOf(spring) == -1) { - this._activeSprings.push(spring); - } - if (this.getIsIdle()) { - this._isIdle = false; - this.looper.run(); - } - }, - - // Add a listener to the SpringSystem so that you can receive - // before/after integration notifications allowing Springs to be - // constrained or adjusted. - addListener: function(listener) { - this.listeners.push(listener); - }, - - // Remove a previously added listener on the SpringSystem. - removeListener: function(listener) { - removeFirst(this.listeners, listener); - }, - - // Remove all previously added listeners on the SpringSystem. - removeAllListeners: function() { - this.listeners = []; - } - - }); - - // Spring - // ------ - // **Spring** provides a model of a classical spring acting to - // resolve a body to equilibrium. Springs have configurable - // tension which is a force multipler on the displacement of the - // spring from its rest point or `endValue` as defined by [Hooke's - // law](http://en.wikipedia.org/wiki/Hooke's_law). Springs also have - // configurable friction, which ensures that they do not oscillate - // infinitely. When a Spring is displaced by updating it's resting - // or `currentValue`, the SpringSystems that contain that Spring - // will automatically start looping to solve for equilibrium. As each - // timestep passes, `SpringListener` objects attached to the Spring - // will be notified of the updates providing a way to drive an - // animation off of the spring's resolution curve. - var Spring = rebound.Spring = function Spring(springSystem) { - this._id = 's' + Spring._ID++; - this._springSystem = springSystem; - this.listeners = []; - this._currentState = new PhysicsState(); - this._previousState = new PhysicsState(); - this._tempState = new PhysicsState(); - }; - - util.extend(Spring, { - _ID: 0, - - MAX_DELTA_TIME_SEC: 0.064, - - SOLVER_TIMESTEP_SEC: 0.001 - - }); - - util.extend(Spring.prototype, { - - _id: 0, - - _springConfig: null, - - _overshootClampingEnabled: false, - - _currentState: null, - - _previousState: null, - - _tempState: null, - - _startValue: 0, - - _endValue: 0, - - _wasAtRest: true, - - _restSpeedThreshold: 0.001, - - _displacementFromRestThreshold: 0.001, - - listeners: null, - - _timeAccumulator: 0, - - _springSystem: null, - - // Remove a Spring from simulation and clear its listeners. - destroy: function() { - this.listeners = []; - this.frames = []; - this._springSystem.deregisterSpring(this); - }, - - // Get the id of the spring, which can be used to retrieve it from - // the SpringSystems it participates in later. - getId: function() { - return this._id; - }, - - // Set the configuration values for this Spring. A SpringConfig - // contains the tension and friction values used to solve for the - // equilibrium of the Spring in the physics loop. - setSpringConfig: function(springConfig) { - this._springConfig = springConfig; - return this; - }, - - // Retrieve the SpringConfig used by this Spring. - getSpringConfig: function() { - return this._springConfig; - }, - - // Set the current position of this Spring. Listeners will be updated - // with this value immediately. If the rest or `endValue` is not - // updated to match this value, then the spring will be dispalced and - // the SpringSystem will start to loop to restore the spring to the - // `endValue`. - // - // A common pattern is to move a Spring around without animation by - // calling. - // - // ``` - // spring.setCurrentValue(n).setAtRest(); - // ``` - // - // This moves the Spring to a new position `n`, sets the endValue - // to `n`, and removes any velocity from the `Spring`. By doing - // this you can allow the `SpringListener` to manage the position - // of UI elements attached to the spring even when moving without - // animation. For example, when dragging an element you can - // update the position of an attached view through a spring - // by calling `spring.setCurrentValue(x)`. When - // the gesture ends you can update the Springs - // velocity and endValue - // `spring.setVelocity(gestureEndVelocity).setEndValue(flingTarget)` - // to cause it to naturally animate the UI element to the resting - // position taking into account existing velocity. The codepaths for - // synchronous movement and spring driven animation can - // be unified using this technique. - setCurrentValue: function(currentValue, skipSetAtRest) { - this._startValue = currentValue; - this._currentState.position = currentValue; - if (!skipSetAtRest) { - this.setAtRest(); - } - this.notifyPositionUpdated(false, false); - return this; - }, - - // Get the position that the most recent animation started at. This - // can be useful for determining the number off oscillations that - // have occurred. - getStartValue: function() { - return this._startValue; - }, - - // Retrieve the current value of the Spring. - getCurrentValue: function() { - return this._currentState.position; - }, - - // Get the absolute distance of the Spring from it's resting endValue - // position. - getCurrentDisplacementDistance: function() { - return this.getDisplacementDistanceForState(this._currentState); - }, - - getDisplacementDistanceForState: function(state) { - return Math.abs(this._endValue - state.position); - }, - - // Set the endValue or resting position of the spring. If this - // value is different than the current value, the SpringSystem will - // be notified and will begin running its solver loop to resolve - // the Spring to equilibrium. Any listeners that are registered - // for onSpringEndStateChange will also be notified of this update - // immediately. - setEndValue: function(endValue) { - if (this._endValue == endValue && this.isAtRest()) { - return this; - } - this._startValue = this.getCurrentValue(); - this._endValue = endValue; - this._springSystem.activateSpring(this.getId()); - for (var i = 0, len = this.listeners.length; i < len; i++) { - var listener = this.listeners[i]; - var onChange = listener.onSpringEndStateChange; - onChange && onChange(this); - } - return this; - }, - - // Retrieve the endValue or resting position of this spring. - getEndValue: function() { - return this._endValue; - }, - - // Set the current velocity of the Spring. As previously mentioned, - // this can be useful when you are performing a direct manipulation - // gesture. When a UI element is released you may call setVelocity - // on its animation Spring so that the Spring continues with the - // same velocity as the gesture ended with. The friction, tension, - // and displacement of the Spring will then govern its motion to - // return to rest on a natural feeling curve. - setVelocity: function(velocity) { - if (velocity === this._currentState.velocity) { - return this; - } - this._currentState.velocity = velocity; - this._springSystem.activateSpring(this.getId()); - return this; - }, - - // Get the current velocity of the Spring. - getVelocity: function() { - return this._currentState.velocity; - }, - - // Set a threshold value for the movement speed of the Spring below - // which it will be considered to be not moving or resting. - setRestSpeedThreshold: function(restSpeedThreshold) { - this._restSpeedThreshold = restSpeedThreshold; - return this; - }, - - // Retrieve the rest speed threshold for this Spring. - getRestSpeedThreshold: function() { - return this._restSpeedThreshold; - }, - - // Set a threshold value for displacement below which the Spring - // will be considered to be not displaced i.e. at its resting - // `endValue`. - setRestDisplacementThreshold: function(displacementFromRestThreshold) { - this._displacementFromRestThreshold = displacementFromRestThreshold; - }, - - // Retrieve the rest displacement threshold for this spring. - getRestDisplacementThreshold: function() { - return this._displacementFromRestThreshold; - }, - - // Enable overshoot clamping. This means that the Spring will stop - // immediately when it reaches its resting position regardless of - // any existing momentum it may have. This can be useful for certain - // types of animations that should not oscillate such as a scale - // down to 0 or alpha fade. - setOvershootClampingEnabled: function(enabled) { - this._overshootClampingEnabled = enabled; - return this; - }, - - // Check if overshoot clamping is enabled for this spring. - isOvershootClampingEnabled: function() { - return this._overshootClampingEnabled; - }, - - // Check if the Spring has gone past its end point by comparing - // the direction it was moving in when it started to the current - // position and end value. - isOvershooting: function() { - var start = this._startValue; - var end = this._endValue; - return this._springConfig.tension > 0 && - ((start < end && this.getCurrentValue() > end) || - (start > end && this.getCurrentValue() < end)); - }, - - // Spring.advance is the main solver method for the Spring. It takes - // the current time and delta since the last time step and performs - // an RK4 integration to get the new position and velocity state - // for the Spring based on the tension, friction, velocity, and - // displacement of the Spring. - advance: function(time, realDeltaTime) { - var isAtRest = this.isAtRest(); - - if (isAtRest && this._wasAtRest) { - return; - } - - var adjustedDeltaTime = realDeltaTime; - if (realDeltaTime > Spring.MAX_DELTA_TIME_SEC) { - adjustedDeltaTime = Spring.MAX_DELTA_TIME_SEC; - } - - this._timeAccumulator += adjustedDeltaTime; - - var tension = this._springConfig.tension, - friction = this._springConfig.friction, - - position = this._currentState.position, - velocity = this._currentState.velocity, - tempPosition = this._tempState.position, - tempVelocity = this._tempState.velocity, - - aVelocity, aAcceleration, - bVelocity, bAcceleration, - cVelocity, cAcceleration, - dVelocity, dAcceleration, - - dxdt, dvdt; - - while(this._timeAccumulator >= Spring.SOLVER_TIMESTEP_SEC) { - - this._timeAccumulator -= Spring.SOLVER_TIMESTEP_SEC; - - if (this._timeAccumulator < Spring.SOLVER_TIMESTEP_SEC) { - this._previousState.position = position; - this._previousState.velocity = velocity; - } - - aVelocity = velocity; - aAcceleration = - (tension * (this._endValue - tempPosition)) - friction * velocity; - - tempPosition = position + aVelocity * Spring.SOLVER_TIMESTEP_SEC * 0.5; - tempVelocity = - velocity + aAcceleration * Spring.SOLVER_TIMESTEP_SEC * 0.5; - bVelocity = tempVelocity; - bAcceleration = - (tension * (this._endValue - tempPosition)) - friction * tempVelocity; - - tempPosition = position + bVelocity * Spring.SOLVER_TIMESTEP_SEC * 0.5; - tempVelocity = - velocity + bAcceleration * Spring.SOLVER_TIMESTEP_SEC * 0.5; - cVelocity = tempVelocity; - cAcceleration = - (tension * (this._endValue - tempPosition)) - friction * tempVelocity; - - tempPosition = position + cVelocity * Spring.SOLVER_TIMESTEP_SEC * 0.5; - tempVelocity = - velocity + cAcceleration * Spring.SOLVER_TIMESTEP_SEC * 0.5; - dVelocity = tempVelocity; - dAcceleration = - (tension * (this._endValue - tempPosition)) - friction * tempVelocity; - - dxdt = - 1.0/6.0 * (aVelocity + 2.0 * (bVelocity + cVelocity) + dVelocity); - dvdt = 1.0/6.0 * ( - aAcceleration + 2.0 * (bAcceleration + cAcceleration) + dAcceleration - ); - - position += dxdt * Spring.SOLVER_TIMESTEP_SEC; - velocity += dvdt * Spring.SOLVER_TIMESTEP_SEC; - } - - this._tempState.position = tempPosition; - this._tempState.velocity = tempVelocity; - - this._currentState.position = position; - this._currentState.velocity = velocity; - - if (this._timeAccumulator > 0) { - this.interpolate(this._timeAccumulator / Spring.SOLVER_TIMESTEP_SEC); - } - - if (this.isAtRest() || - this._overshootClampingEnabled && this.isOvershooting()) { - - if (this._springConfig.tension > 0) { - this._startValue = this._endValue; - this._currentState.position = this._endValue; - } else { - this._endValue = this._currentState.position; - this._startValue = this._endValue; - } - this.setVelocity(0); - isAtRest = true; - } - - var notifyActivate = false; - if (this._wasAtRest) { - this._wasAtRest = false; - notifyActivate = true; - } - - var notifyAtRest = false; - if (isAtRest) { - this._wasAtRest = true; - notifyAtRest = true; - } - - this.notifyPositionUpdated(notifyActivate, notifyAtRest); - }, - - notifyPositionUpdated: function(notifyActivate, notifyAtRest) { - for (var i = 0, len = this.listeners.length; i < len; i++) { - var listener = this.listeners[i]; - if (notifyActivate && listener.onSpringActivate) { - listener.onSpringActivate(this); - } - - if (listener.onSpringUpdate) { - listener.onSpringUpdate(this); - } - - if (notifyAtRest && listener.onSpringAtRest) { - listener.onSpringAtRest(this); - } - } - }, - - - // Check if the SpringSystem should advance. Springs are advanced - // a final frame after they reach equilibrium to ensure that the - // currentValue is exactly the requested endValue regardless of the - // displacement threshold. - systemShouldAdvance: function() { - return !this.isAtRest() || !this.wasAtRest(); - }, - - wasAtRest: function() { - return this._wasAtRest; - }, - - // Check if the Spring is atRest meaning that it's currentValue and - // endValue are the same and that it has no velocity. The previously - // described thresholds for speed and displacement define the bounds - // of this equivalence check. If the Spring has 0 tension, then it will - // be considered at rest whenever its absolute velocity drops below the - // restSpeedThreshold. - isAtRest: function() { - return Math.abs(this._currentState.velocity) < this._restSpeedThreshold && - (this.getDisplacementDistanceForState(this._currentState) <= - this._displacementFromRestThreshold || - this._springConfig.tension === 0); - }, - - // Force the spring to be at rest at its current position. As - // described in the documentation for setCurrentValue, this method - // makes it easy to do synchronous non-animated updates to ui - // elements that are attached to springs via SpringListeners. - setAtRest: function() { - this._endValue = this._currentState.position; - this._tempState.position = this._currentState.position; - this._currentState.velocity = 0; - return this; - }, - - interpolate: function(alpha) { - this._currentState.position = this._currentState.position * - alpha + this._previousState.position * (1 - alpha); - this._currentState.velocity = this._currentState.velocity * - alpha + this._previousState.velocity * (1 - alpha); - }, - - getListeners: function() { - return this.listeners; - }, - - addListener: function(newListener) { - this.listeners.push(newListener); - return this; - }, - - removeListener: function(listenerToRemove) { - removeFirst(this.listeners, listenerToRemove); - return this; - }, - - removeAllListeners: function() { - this.listeners = []; - return this; - }, - - currentValueIsApproximately: function(value) { - return Math.abs(this.getCurrentValue() - value) <= - this.getRestDisplacementThreshold(); - } - - }); - - // PhysicsState - // ------------ - // **PhysicsState** consists of a position and velocity. A Spring uses - // this internally to keep track of its current and prior position and - // velocity values. - var PhysicsState = function PhysicsState() {}; - - util.extend(PhysicsState.prototype, { - position: 0, - velocity: 0 - }); - - // SpringConfig - // ------------ - // **SpringConfig** maintains a set of tension and friction constants - // for a Spring. You can use fromOrigamiTensionAndFriction to convert - // values from the [Origami](http://facebook.github.io/origami/) - // design tool directly to Rebound spring constants. - var SpringConfig = rebound.SpringConfig = - function SpringConfig(tension, friction) { - this.tension = tension; - this.friction = friction; - }; - - // Loopers - // ------- - // **AnimationLooper** plays each frame of the SpringSystem on animation - // timing loop. This is the default type of looper for a new spring system - // as it is the most common when developing UI. - var AnimationLooper = rebound.AnimationLooper = function AnimationLooper() { - this.springSystem = null; - var _this = this; - var _run = function() { - _this.springSystem.loop(Date.now()); - }; - - this.run = function() { - util.onFrame(_run); - }; - }; - - // **SimulationLooper** resolves the SpringSystem to a resting state in a - // tight and blocking loop. This is useful for synchronously generating - // pre-recorded animations that can then be played on a timing loop later. - // Sometimes this lead to better performance to pre-record a single spring - // curve and use it to drive many animations; however, it can make dynamic - // response to user input a bit trickier to implement. - rebound.SimulationLooper = function SimulationLooper(timestep) { - this.springSystem = null; - var time = 0; - var running = false; - timestep=timestep || 16.667; - - this.run = function() { - if (running) { - return; - } - running = true; - while(!this.springSystem.getIsIdle()) { - this.springSystem.loop(time+=timestep); - } - running = false; - }; - }; - - // **SteppingSimulationLooper** resolves the SpringSystem one step at a - // time controlled by an outside loop. This is useful for testing and - // verifying the behavior of a SpringSystem or if you want to control your own - // timing loop for some reason e.g. slowing down or speeding up the - // simulation. - rebound.SteppingSimulationLooper = function(timestep) { - this.springSystem = null; - var time = 0; - - // this.run is NOOP'd here to allow control from the outside using - // this.step. - this.run = function(){}; - - // Perform one step toward resolving the SpringSystem. - this.step = function(timestep) { - this.springSystem.loop(time+=timestep); - }; - }; - - // Math for converting from - // [Origami](http://facebook.github.io/origami/) to - // [Rebound](http://facebook.github.io/rebound). - // You mostly don't need to worry about this, just use - // SpringConfig.fromOrigamiTensionAndFriction(v, v); - var OrigamiValueConverter = rebound.OrigamiValueConverter = { - tensionFromOrigamiValue: function(oValue) { - return (oValue - 30.0) * 3.62 + 194.0; - }, - - origamiValueFromTension: function(tension) { - return (tension - 194.0) / 3.62 + 30.0; - }, - - frictionFromOrigamiValue: function(oValue) { - return (oValue - 8.0) * 3.0 + 25.0; - }, - - origamiFromFriction: function(friction) { - return (friction - 25.0) / 3.0 + 8.0; - } - }; - - // BouncyConversion provides math for converting from Origami PopAnimation - // config values to regular Origami tension and friction values. If you are - // trying to replicate prototypes made with PopAnimation patches in Origami, - // then you should create your springs with - // SpringSystem.createSpringWithBouncinessAndSpeed, which uses this Math - // internally to create a spring to match the provided PopAnimation - // configuration from Origami. - var BouncyConversion = rebound.BouncyConversion = function(bounciness, speed){ - this.bounciness = bounciness; - this.speed = speed; - var b = this.normalize(bounciness / 1.7, 0, 20.0); - b = this.projectNormal(b, 0.0, 0.8); - var s = this.normalize(speed / 1.7, 0, 20.0); - this.bouncyTension = this.projectNormal(s, 0.5, 200) - this.bouncyFriction = this.quadraticOutInterpolation( - b, - this.b3Nobounce(this.bouncyTension), - 0.01); - } - - util.extend(BouncyConversion.prototype, { - - normalize: function(value, startValue, endValue) { - return (value - startValue) / (endValue - startValue); - }, - - projectNormal: function(n, start, end) { - return start + (n * (end - start)); - }, - - linearInterpolation: function(t, start, end) { - return t * end + (1.0 - t) * start; - }, - - quadraticOutInterpolation: function(t, start, end) { - return this.linearInterpolation(2*t - t*t, start, end); - }, - - b3Friction1: function(x) { - return (0.0007 * Math.pow(x, 3)) - - (0.031 * Math.pow(x, 2)) + 0.64 * x + 1.28; - }, - - b3Friction2: function(x) { - return (0.000044 * Math.pow(x, 3)) - - (0.006 * Math.pow(x, 2)) + 0.36 * x + 2.; - }, - - b3Friction3: function(x) { - return (0.00000045 * Math.pow(x, 3)) - - (0.000332 * Math.pow(x, 2)) + 0.1078 * x + 5.84; - }, - - b3Nobounce: function(tension) { - var friction = 0; - if (tension <= 18) { - friction = this.b3Friction1(tension); - } else if (tension > 18 && tension <= 44) { - friction = this.b3Friction2(tension); - } else { - friction = this.b3Friction3(tension); - } - return friction; - } - }); - - util.extend(SpringConfig, { - // Convert an origami Spring tension and friction to Rebound spring - // constants. If you are prototyping a design with Origami, this - // makes it easy to make your springs behave exactly the same in - // Rebound. - fromOrigamiTensionAndFriction: function(tension, friction) { - return new SpringConfig( - OrigamiValueConverter.tensionFromOrigamiValue(tension), - OrigamiValueConverter.frictionFromOrigamiValue(friction)); - }, - - // Convert an origami PopAnimation Spring bounciness and speed to Rebound - // spring constants. If you are using PopAnimation patches in Origami, this - // utility will provide springs that match your prototype. - fromBouncinessAndSpeed: function(bounciness, speed) { - var bouncyConversion = new rebound.BouncyConversion(bounciness, speed); - return this.fromOrigamiTensionAndFriction( - bouncyConversion.bouncyTension, - bouncyConversion.bouncyFriction); - }, - - // Create a SpringConfig with no tension or a coasting spring with some - // amount of Friction so that it does not coast infininitely. - coastingConfigWithOrigamiFriction: function(friction) { - return new SpringConfig( - 0, - OrigamiValueConverter.frictionFromOrigamiValue(friction) - ); - } - }); - - SpringConfig.DEFAULT_ORIGAMI_SPRING_CONFIG = - SpringConfig.fromOrigamiTensionAndFriction(40, 7); - - util.extend(SpringConfig.prototype, {friction: 0, tension: 0}); - - // Here are a couple of function to convert colors between hex codes and RGB - // component values. These are handy when performing color - // tweening animations. - var colorCache = {}; - util.hexToRGB = function(color) { - if (colorCache[color]) { - return colorCache[color]; - } - color = color.replace('#', ''); - if (color.length === 3) { - color = color[0] + color[0] + color[1] + color[1] + color[2] + color[2]; - } - var parts = color.match(/.{2}/g); - - var ret = { - r: parseInt(parts[0], 16), - g: parseInt(parts[1], 16), - b: parseInt(parts[2], 16) - }; - - colorCache[color] = ret; - return ret; - }; - - util.rgbToHex = function(r, g, b) { - r = r.toString(16); - g = g.toString(16); - b = b.toString(16); - r = r.length < 2 ? '0' + r : r; - g = g.length < 2 ? '0' + g : g; - b = b.length < 2 ? '0' + b : b; - return '#' + r + g + b; - }; - - var MathUtil = rebound.MathUtil = { - // This helper function does a linear interpolation of a value from - // one range to another. This can be very useful for converting the - // motion of a Spring to a range of UI property values. For example a - // spring moving from position 0 to 1 could be interpolated to move a - // view from pixel 300 to 350 and scale it from 0.5 to 1. The current - // position of the `Spring` just needs to be run through this method - // taking its input range in the _from_ parameters with the property - // animation range in the _to_ parameters. - mapValueInRange: function(value, fromLow, fromHigh, toLow, toHigh) { - var fromRangeSize = fromHigh - fromLow; - var toRangeSize = toHigh - toLow; - var valueScale = (value - fromLow) / fromRangeSize; - return toLow + (valueScale * toRangeSize); - }, - - // Interpolate two hex colors in a 0 - 1 range or optionally provide a - // custom range with fromLow,fromHight. The output will be in hex by default - // unless asRGB is true in which case it will be returned as an rgb string. - interpolateColor: - function(val, startColor, endColor, fromLow, fromHigh, asRGB) { - fromLow = fromLow === undefined ? 0 : fromLow; - fromHigh = fromHigh === undefined ? 1 : fromHigh; - startColor = util.hexToRGB(startColor); - endColor = util.hexToRGB(endColor); - var r = Math.floor( - util.mapValueInRange(val, fromLow, fromHigh, startColor.r, endColor.r) - ); - var g = Math.floor( - util.mapValueInRange(val, fromLow, fromHigh, startColor.g, endColor.g) - ); - var b = Math.floor( - util.mapValueInRange(val, fromLow, fromHigh, startColor.b, endColor.b) - ); - if (asRGB) { - return 'rgb(' + r + ',' + g + ',' + b + ')'; - } else { - return util.rgbToHex(r, g, b); - } - }, - - degreesToRadians: function(deg) { - return (deg * Math.PI) / 180; - }, - - radiansToDegrees: function(rad) { - return (rad * 180) / Math.PI; - } - - } - - util.extend(util, MathUtil); - - - // Utilities - // --------- - // Here are a few useful JavaScript utilities. - - // Lop off the first occurence of the reference in the Array. - function removeFirst(array, item) { - var idx = array.indexOf(item); - idx != -1 && array.splice(idx, 1); - } - - var _onFrame; - if (typeof window !== 'undefined') { - _onFrame = window.requestAnimationFrame || - window.webkitRequestAnimationFrame || - window.mozRequestAnimationFrame || - window.msRequestAnimationFrame || - window.oRequestAnimationFrame; - } - if (!_onFrame && typeof process !== 'undefined' && process.title === 'node') { - _onFrame = setImmediate; - } - - // Cross browser/node timer functions. - util.onFrame = function onFrame(func) { - return _onFrame(func); - }; - - // Export the public api using exports for common js or the window for - // normal browser inclusion. - if (typeof exports != 'undefined') { - util.extend(exports, rebound); - } else if (typeof window != 'undefined') { - window.rebound = rebound; - } -})(); - - -// Legal Stuff -// ----------- -/** - * Copyright (c) 2013, 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. - */ -}); -__d('SegmentedControlIOS',["NativeMethodsMixin","NativeModules","ReactPropTypes","React","StyleSheet","requireNativeComponent","verifyPropTypes"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 SegmentedControlIOS - * @flow - */ -'use strict'; - -var NativeMethodsMixin = require('NativeMethodsMixin'); -var NativeModules = require('NativeModules'); -var PropTypes = require('ReactPropTypes'); -var React = require('React'); -var StyleSheet = require('StyleSheet'); - -var requireNativeComponent = require('requireNativeComponent'); -var verifyPropTypes = require('verifyPropTypes'); - - - - - - -var SEGMENTED_CONTROL_REFERENCE = 'segmentedcontrol'; - - - -/** - * Use `SegmentedControlIOS` to render a UISegmentedControl iOS. - */ -var SegmentedControlIOS = React.createClass({displayName: "SegmentedControlIOS", - mixins: [NativeMethodsMixin], - - propTypes: { - /** - * The labels for the control's segment buttons, in order. - */ - values: PropTypes.arrayOf(PropTypes.string), - - /** - * The index in `props.values` of the segment to be pre-selected - */ - selectedIndex: PropTypes.number, - - /** - * Callback that is called when the user taps a segment; - * passes the segment's value as an argument - */ - onValueChange: PropTypes.func, - - /** - * Callback that is called when the user taps a segment; - * passes the event as an argument - */ - onChange: PropTypes.func, - - /** - * If false the user won't be able to interact with the control. - * Default value is true. - */ - enabled: PropTypes.bool, - - /** - * Accent color of the control. - */ - tintColor: PropTypes.string, - - /** - * If true, then selecting a segment won't persist visually. - * The `onValueChange` callback will still work as expected. - */ - momentary: PropTypes.bool - }, - - getDefaultProps: function() { - return { - values: [], - enabled: true - }; - }, - - _onChange: function(event ) { - this.props.onChange && this.props.onChange(event); - this.props.onValueChange && this.props.onValueChange(event.nativeEvent.value); - }, - - render: function() { - return ( - React.createElement(RCTSegmentedControl, React.__spread({}, - this.props, - {ref: SEGMENTED_CONTROL_REFERENCE, - style: [styles.segmentedControl, this.props.style], - onChange: this._onChange}) - ) - ); - } -}); - -var styles = StyleSheet.create({ - segmentedControl: { - height: NativeModules.SegmentedControlManager.ComponentHeight - }, -}); - -var RCTSegmentedControl = requireNativeComponent( - 'RCTSegmentedControl', - null -); -if (__DEV__) { - verifyPropTypes( - RCTSegmentedControl, - RCTSegmentedControl.viewConfig - ); -} - -module.exports = SegmentedControlIOS; -}); -__d('SliderIOS',["NativeMethodsMixin","ReactPropTypes","React","StyleSheet","View","requireNativeComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 SliderIOS - * @flow - */ -'use strict'; - -var NativeMethodsMixin = require('NativeMethodsMixin'); -var PropTypes = require('ReactPropTypes'); -var React = require('React'); -var StyleSheet = require('StyleSheet'); -var View = require('View'); - -var requireNativeComponent = require('requireNativeComponent'); - - - -var SliderIOS = React.createClass({displayName: "SliderIOS", - mixins: [NativeMethodsMixin], - - propTypes: { - /** - * Used to style and layout the `Slider`. See `StyleSheet.js` and - * `ViewStylePropTypes.js` for more info. - */ - style: View.propTypes.style, - - /** - * Initial value of the slider. The value should be between minimumValue - * and maximumValue, which default to 0 and 1 respectively. - * Default value is 0. - * - * *This is not a controlled component*, e.g. if you don't update - * the value, the component won't be reset to its inital value. - */ - value: PropTypes.number, - - /** - * Initial minimum value of the slider. Default value is 0. - */ - minimumValue: PropTypes.number, - - /** - * Initial maximum value of the slider. Default value is 1. - */ - maximumValue: PropTypes.number, - - /** - * The color used for the track to the left of the button. Overrides the - * default blue gradient image. - */ - minimumTrackTintColor: PropTypes.string, - - /** - * The color used for the track to the right of the button. Overrides the - * default blue gradient image. - */ - maximumTrackTintColor: PropTypes.string, - - /** - * Callback continuously called while the user is dragging the slider. - */ - onValueChange: PropTypes.func, - - /** - * Callback called when the user finishes changing the value (e.g. when - * the slider is released). - */ - onSlidingComplete: PropTypes.func, - }, - - _onValueChange: function(event ) { - this.props.onChange && this.props.onChange(event); - if (event.nativeEvent.continuous) { - this.props.onValueChange && - this.props.onValueChange(event.nativeEvent.value); - } else { - this.props.onSlidingComplete && event.nativeEvent.value !== undefined && - this.props.onSlidingComplete(event.nativeEvent.value); - } - }, - - render: function() { - return ( - React.createElement(RCTSlider, { - style: [styles.slider, this.props.style], - value: this.props.value, - maximumValue: this.props.maximumValue, - minimumValue: this.props.minimumValue, - minimumTrackTintColor: this.props.minimumTrackTintColor, - maximumTrackTintColor: this.props.maximumTrackTintColor, - onChange: this._onValueChange} - ) - ); - } -}); - -var styles = StyleSheet.create({ - slider: { - height: 40, - }, -}); - -var RCTSlider = requireNativeComponent('RCTSlider', SliderIOS); - -module.exports = SliderIOS; -}); -__d('SwitchIOS',["NativeMethodsMixin","ReactPropTypes","React","StyleSheet","requireNativeComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 SwitchIOS - * @flow - * - * This is a controlled component version of RCTSwitch. - */ -'use strict'; - -var NativeMethodsMixin = require('NativeMethodsMixin'); -var PropTypes = require('ReactPropTypes'); -var React = require('React'); -var StyleSheet = require('StyleSheet'); - -var requireNativeComponent = require('requireNativeComponent'); - -var SWITCH = 'switch'; - - - - - - - - -/** - * Use `SwitchIOS` to render a boolean input on iOS. This is - * a controlled component, so you must hook in to the `onValueChange` callback - * and update the `value` prop in order for the component to update, otherwise - * the user's change will be reverted immediately to reflect `props.value` as the - * source of truth. - */ -var SwitchIOS = React.createClass({displayName: "SwitchIOS", - mixins: [NativeMethodsMixin], - - propTypes: { - /** - * The value of the switch, if true the switch will be turned on. - * Default value is false. - */ - value: PropTypes.bool, - - /** - * If true the user won't be able to toggle the switch. - * Default value is false. - */ - disabled: PropTypes.bool, - - /** - * Callback that is called when the user toggles the switch. - */ - onValueChange: PropTypes.func, - - /** - * Background color when the switch is turned on. - */ - onTintColor: PropTypes.string, - - /** - * Background color for the switch round button. - */ - thumbTintColor: PropTypes.string, - - /** - * Background color when the switch is turned off. - */ - tintColor: PropTypes.string, - }, - - getDefaultProps: function() { - return { - value: false, - disabled: false, - }; - }, - - _onChange: function(event ) { - this.props.onChange && this.props.onChange(event); - this.props.onValueChange && this.props.onValueChange(event.nativeEvent.value); - - // The underlying switch might have changed, but we're controlled, - // and so want to ensure it represents our value. - this.refs[SWITCH].setNativeProps({value: this.props.value}); - }, - - render: function() { - return ( - React.createElement(RCTSwitch, React.__spread({}, - this.props, - {ref: SWITCH, - onChange: this._onChange, - style: [styles.rkSwitch, this.props.style]}) - ) - ); - } -}); - -var styles = StyleSheet.create({ - rkSwitch: { - height: 31, - width: 51, - }, -}); - -var RCTSwitch = requireNativeComponent('RCTSwitch', SwitchIOS); - -module.exports = SwitchIOS; -}); -__d('TabBarIOS',["React","StyleSheet","TabBarItemIOS","View","requireNativeComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 TabBarIOS - * @flow - */ -'use strict'; - -var React = require('React'); -var StyleSheet = require('StyleSheet'); -var TabBarItemIOS = require('TabBarItemIOS'); -var View = require('View'); - -var requireNativeComponent = require('requireNativeComponent'); - -var TabBarIOS = React.createClass({displayName: "TabBarIOS", - statics: { - Item: TabBarItemIOS, - }, - - propTypes: { - style: View.propTypes.style, - }, - - render: function() { - return ( - React.createElement(RCTTabBar, {style: [styles.tabGroup, this.props.style]}, - this.props.children - ) - ); - } -}); - -var styles = StyleSheet.create({ - tabGroup: { - flex: 1, - } -}); - -var RCTTabBar = requireNativeComponent('RCTTabBar', TabBarIOS); - -module.exports = TabBarIOS; -}); -__d('TabBarItemIOS',["Image","React","StaticContainer.react","StyleSheet","View","requireNativeComponent"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 TabBarItemIOS - * @flow - */ -'use strict'; - -var Image = require('Image'); -var React = require('React'); -var StaticContainer = require('StaticContainer.react'); -var StyleSheet = require('StyleSheet'); -var View = require('View'); - -var requireNativeComponent = require('requireNativeComponent'); - -var TabBarItemIOS = React.createClass({displayName: "TabBarItemIOS", - propTypes: { - /** - * Little red bubble that sits at the top right of the icon. - */ - badge: React.PropTypes.oneOfType([ - React.PropTypes.string, - React.PropTypes.number, - ]), - /** - * Items comes with a few predefined system icons. Note that if you are - * using them, the title and selectedIcon will be overriden with the - * system ones. - */ - systemIcon: React.PropTypes.oneOf([ - 'bookmarks', - 'contacts', - 'downloads', - 'favorites', - 'featured', - 'history', - 'more', - 'most-recent', - 'most-viewed', - 'recents', - 'search', - 'top-rated', - ]), - /** - * A custom icon for the tab. It is ignored when a system icon is defined. - */ - icon: Image.propTypes.source, - /** - * A custom icon when the tab is selected. It is ignored when a system - * icon is defined. If left empty, the icon will be tinted in blue. - */ - selectedIcon: Image.propTypes.source, - /** - * Callback when this tab is being selected, you should change the state of your - * component to set selected={true}. - */ - onPress: React.PropTypes.func, - /** - * It specifies whether the children are visible or not. If you see a - * blank content, you probably forgot to add a selected one. - */ - selected: React.PropTypes.bool, - /** - * React style object. - */ - style: View.propTypes.style, - /** - * Text that appears under the icon. It is ignored when a system icon - * is defined. - */ - title: React.PropTypes.string, - }, - - getInitialState: function() { - return { - hasBeenSelected: false, - }; - }, - - componentWillMount: function() { - if (this.props.selected) { - this.setState({hasBeenSelected: true}); - } - }, - - componentWillReceiveProps: function(nextProps ) { - if (this.state.hasBeenSelected || nextProps.selected) { - this.setState({hasBeenSelected: true}); - } - }, - - render: function() { - var tabContents = null; - // if the tab has already been shown once, always continue to show it so we - // preserve state between tab transitions - if (this.state.hasBeenSelected) { - tabContents = - React.createElement(StaticContainer, {shouldUpdate: this.props.selected}, - this.props.children - ); - } else { - tabContents = React.createElement(View, null); - } - - 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 ( - React.createElement(RCTTabBarItem, { - icon: icon, - selectedIcon: this.props.selectedIcon && this.props.selectedIcon.uri, - onPress: this.props.onPress, - selected: this.props.selected, - badge: badge, - title: this.props.title, - style: [styles.tab, this.props.style]}, - tabContents - ) - ); - } -}); - -var styles = StyleSheet.create({ - tab: { - position: 'absolute', - top: 0, - right: 0, - bottom: 0, - left: 0, - } -}); - -var RCTTabBarItem = requireNativeComponent('RCTTabBarItem', TabBarItemIOS); - -module.exports = TabBarItemIOS; -}); -__d('Text',["NativeMethodsMixin","React","ReactNativeViewAttributes","StyleSheetPropType","TextStylePropTypes","Touchable","createReactNativeComponentClass","merge"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 Text - * @flow - */ -'use strict'; - -var NativeMethodsMixin = require('NativeMethodsMixin'); -var React = require('React'); -var ReactNativeViewAttributes = require('ReactNativeViewAttributes'); -var StyleSheetPropType = require('StyleSheetPropType'); -var TextStylePropTypes = require('TextStylePropTypes'); -var Touchable = require('Touchable'); - -var createReactNativeComponentClass = - require('createReactNativeComponentClass'); -var merge = require('merge'); - -var stylePropType = StyleSheetPropType(TextStylePropTypes); - -var viewConfig = { - validAttributes: merge(ReactNativeViewAttributes.UIView, { - isHighlighted: true, - numberOfLines: true, - }), - uiViewClassName: 'RCTText', -}; - -/** - * A React component for displaying text which supports nesting, - * styling, and touch handling. In the following example, the nested title and - * body text will inherit the `fontFamily` from `styles.baseText`, but the title - * provides its own additional styles. The title and body will stack on top of - * each other on account of the literal newlines: - * - * ``` - * renderText: function() { - * return ( - * - * - * {this.state.titleText + '\n\n'} - * - * - * {this.state.bodyText} - * - * - * ); - * }, - * ... - * var styles = StyleSheet.create({ - * baseText: { - * fontFamily: 'Cochin', - * }, - * titleText: { - * fontSize: 20, - * fontWeight: 'bold', - * }, - * }; - * ``` - */ - -var Text = React.createClass({displayName: "Text", - - mixins: [Touchable.Mixin, NativeMethodsMixin], - - propTypes: { - /** - * Used to truncate the text with an elipsis after computing the text - * layout, including line wrapping, such that the total number of lines does - * not exceed this number. - */ - numberOfLines: React.PropTypes.number, - /** - * This function is called on press. Text intrinsically supports press - * handling with a default highlight state (which can be disabled with - * `suppressHighlighting`). - */ - onPress: React.PropTypes.func, - /** - * When true, no visual change is made when text is pressed down. By - * default, a gray oval highlights the text on press down. - */ - suppressHighlighting: React.PropTypes.bool, - style: stylePropType, - /** - * Used to locate this view in end-to-end tests. - */ - testID: React.PropTypes.string, - /** - * Invoked on mount and layout changes with - * - * {nativeEvent: { layout: {x, y, width, height}}}. - */ - onLayout: React.PropTypes.func, - }, - - viewConfig: viewConfig, - - getInitialState: function() { - return merge(this.touchableGetInitialState(), { - isHighlighted: false, - }); - }, - - onStartShouldSetResponder: function() { - var shouldSetFromProps = this.props.onStartShouldSetResponder && - this.props.onStartShouldSetResponder(); - return shouldSetFromProps || !!this.props.onPress; - }, - - /* - * Returns true to allow responder termination - */ - handleResponderTerminationRequest: function() { - // Allow touchable or props.onResponderTerminationRequest to deny - // the request - var allowTermination = this.touchableHandleResponderTerminationRequest(); - if (allowTermination && this.props.onResponderTerminationRequest) { - allowTermination = this.props.onResponderTerminationRequest(); - } - return allowTermination; - }, - - handleResponderGrant: function(e , dispatchID ) { - this.touchableHandleResponderGrant(e, dispatchID); - this.props.onResponderGrant && - this.props.onResponderGrant.apply(this, arguments); - }, - - handleResponderMove: function(e ) { - this.touchableHandleResponderMove(e); - this.props.onResponderMove && - this.props.onResponderMove.apply(this, arguments); - }, - - handleResponderRelease: function(e ) { - this.touchableHandleResponderRelease(e); - this.props.onResponderRelease && - this.props.onResponderRelease.apply(this, arguments); - }, - - handleResponderTerminate: function(e ) { - this.touchableHandleResponderTerminate(e); - this.props.onResponderTerminate && - this.props.onResponderTerminate.apply(this, arguments); - }, - - touchableHandleActivePressIn: function() { - if (this.props.suppressHighlighting || !this.props.onPress) { - return; - } - this.setState({ - isHighlighted: true, - }); - }, - - touchableHandleActivePressOut: function() { - if (this.props.suppressHighlighting || !this.props.onPress) { - return; - } - this.setState({ - isHighlighted: false, - }); - }, - - touchableHandlePress: function() { - this.props.onPress && this.props.onPress(); - }, - - touchableGetPressRectOffset: function() { - return PRESS_RECT_OFFSET; - }, - - render: function() { - var props = {}; - for (var key in this.props) { - props[key] = this.props[key]; - } - // Text is accessible by default - if (props.accessible !== false) { - props.accessible = true; - } - props.isHighlighted = this.state.isHighlighted; - props.onStartShouldSetResponder = this.onStartShouldSetResponder; - props.onResponderTerminationRequest = - this.handleResponderTerminationRequest; - props.onResponderGrant = this.handleResponderGrant; - props.onResponderMove = this.handleResponderMove; - props.onResponderRelease = this.handleResponderRelease; - props.onResponderTerminate = this.handleResponderTerminate; - return React.createElement(RCTText, React.__spread({}, props)); - }, -}); - - - - - - - - -var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; - -var RCTText = createReactNativeComponentClass(viewConfig); - -module.exports = Text; -}); -__d('Touchable',["BoundingDimensions","Position","TouchEventUtils","keyMirror","queryLayoutByID"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * @providesModule Touchable - */ - -'use strict'; - -var BoundingDimensions = require('BoundingDimensions'); -var Position = require('Position'); -var TouchEventUtils = require('TouchEventUtils'); - -var keyMirror = require('keyMirror'); -var queryLayoutByID = require('queryLayoutByID'); - -/** - * `Touchable`: Taps done right. - * - * You hook your `ResponderEventPlugin` events into `Touchable`. `Touchable` - * will measure time/geometry and tells you when to give feedback to the user. - * - * ====================== Touchable Tutorial =============================== - * The `Touchable` mixin helps you handle the "press" interaction. It analyzes - * the geometry of elements, and observes when another responder (scroll view - * etc) has stolen the touch lock. It notifies your component when it should - * give feedback to the user. (bouncing/highlighting/unhighlighting). - * - * - When a touch was activated (typically you highlight) - * - When a touch was deactivated (typically you unhighlight) - * - When a touch was "pressed" - a touch ended while still within the geometry - * of the element, and no other element (like scroller) has "stolen" touch - * lock ("responder") (Typically you bounce the element). - * - * A good tap interaction isn't as simple as you might think. There should be a - * slight delay before showing a highlight when starting a touch. If a - * subsequent touch move exceeds the boundary of the elemement, it should - * unhighlight, but if that same touch is brought back within the boundary, it - * should rehighlight again. A touch can move in and out of that boundary - * several times, each time toggling highlighting, but a "press" is only - * triggered if that touch ends while within the element's boundary and no - * scroller (or anything else) has stolen the lock on touches. - * - * To create a new type of component that handles interaction using the - * `Touchable` mixin, do the following: - * - * - Initialize the `Touchable` state. - * - * getInitialState: function() { - * return merge(this.touchableGetInitialState(), yourComponentState); - * } - * - * - Choose the rendered component who's touches should start the interactive - * sequence. On that rendered node, forward all `Touchable` responder - * handlers. You can choose any rendered node you like. Choose a node who's - * hit target you'd like to instigate the interaction sequence: - * - * // In render function: - * return ( - *
- *
- * Even though the hit detection/interactions are triggered by the - * wrapping (typically larger) node, we usually end up implementing - * custom logic that highlights this inner one. - *
- *
- * ); - * - * - You may set up your own handlers for each of these events, so long as you - * also invoke the `touchable*` handlers inside of your custom handler. - * - * - Implement the handlers on your component class in order to provide - * feedback to the user. See documentation for each of these class methods - * that you should implement. - * - * touchableHandlePress: function() { - * this.performBounceAnimation(); // or whatever you want to do. - * }, - * touchableHandleActivePressIn: function() { - * this.beginHighlighting(...); // Whatever you like to convey activation - * }, - * touchableHandleActivePressOut: function() { - * this.endHighlighting(...); // Whatever you like to convey deactivation - * }, - * - * - There are more advanced methods you can implement (see documentation below): - * touchableGetHighlightDelayMS: function() { - * return 20; - * } - * // In practice, *always* use a predeclared constant (conserve memory). - * touchableGetPressRectOffset: function() { - * return {top: 20, left: 20, right: 20, bottom: 100}; - * } - */ - -/** - * Touchable states. - */ -var States = keyMirror({ - NOT_RESPONDER: null, // Not the responder - RESPONDER_INACTIVE_PRESS_IN: null, // Responder, inactive, in the `PressRect` - RESPONDER_INACTIVE_PRESS_OUT: null, // Responder, inactive, out of `PressRect` - RESPONDER_ACTIVE_PRESS_IN: null, // Responder, active, in the `PressRect` - RESPONDER_ACTIVE_PRESS_OUT: null, // Responder, active, out of `PressRect` - RESPONDER_ACTIVE_LONG_PRESS_IN: null, // Responder, active, in the `PressRect`, after long press threshold - RESPONDER_ACTIVE_LONG_PRESS_OUT: null, // Responder, active, out of `PressRect`, after long press threshold - ERROR: null -}); - -/** - * Quick lookup map for states that are considered to be "active" - */ -var IsActive = { - RESPONDER_ACTIVE_PRESS_OUT: true, - RESPONDER_ACTIVE_PRESS_IN: true -}; - -/** - * Quick lookup for states that are considered to be "pressing" and are - * therefore eligible to result in a "selection" if the press stops. - */ -var IsPressingIn = { - RESPONDER_INACTIVE_PRESS_IN: true, - RESPONDER_ACTIVE_PRESS_IN: true, - RESPONDER_ACTIVE_LONG_PRESS_IN: true, -}; - -var IsLongPressingIn = { - RESPONDER_ACTIVE_LONG_PRESS_IN: true, -}; - -/** - * Inputs to the state machine. - */ -var Signals = keyMirror({ - DELAY: null, - RESPONDER_GRANT: null, - RESPONDER_RELEASE: null, - RESPONDER_TERMINATED: null, - ENTER_PRESS_RECT: null, - LEAVE_PRESS_RECT: null, - LONG_PRESS_DETECTED: null, -}); - -/** - * Mapping from States x Signals => States - */ -var Transitions = { - NOT_RESPONDER: { - DELAY: States.ERROR, - RESPONDER_GRANT: States.RESPONDER_INACTIVE_PRESS_IN, - RESPONDER_RELEASE: States.ERROR, - RESPONDER_TERMINATED: States.ERROR, - ENTER_PRESS_RECT: States.ERROR, - LEAVE_PRESS_RECT: States.ERROR, - LONG_PRESS_DETECTED: States.ERROR, - }, - RESPONDER_INACTIVE_PRESS_IN: { - DELAY: States.RESPONDER_ACTIVE_PRESS_IN, - RESPONDER_GRANT: States.ERROR, - RESPONDER_RELEASE: States.NOT_RESPONDER, - RESPONDER_TERMINATED: States.NOT_RESPONDER, - ENTER_PRESS_RECT: States.RESPONDER_INACTIVE_PRESS_IN, - LEAVE_PRESS_RECT: States.RESPONDER_INACTIVE_PRESS_OUT, - LONG_PRESS_DETECTED: States.ERROR, - }, - RESPONDER_INACTIVE_PRESS_OUT: { - DELAY: States.RESPONDER_ACTIVE_PRESS_OUT, - RESPONDER_GRANT: States.ERROR, - RESPONDER_RELEASE: States.NOT_RESPONDER, - RESPONDER_TERMINATED: States.NOT_RESPONDER, - ENTER_PRESS_RECT: States.RESPONDER_INACTIVE_PRESS_IN, - LEAVE_PRESS_RECT: States.RESPONDER_INACTIVE_PRESS_OUT, - LONG_PRESS_DETECTED: States.ERROR, - }, - RESPONDER_ACTIVE_PRESS_IN: { - DELAY: States.ERROR, - RESPONDER_GRANT: States.ERROR, - RESPONDER_RELEASE: States.NOT_RESPONDER, - RESPONDER_TERMINATED: States.NOT_RESPONDER, - ENTER_PRESS_RECT: States.RESPONDER_ACTIVE_PRESS_IN, - LEAVE_PRESS_RECT: States.RESPONDER_ACTIVE_PRESS_OUT, - LONG_PRESS_DETECTED: States.RESPONDER_ACTIVE_LONG_PRESS_IN, - }, - RESPONDER_ACTIVE_PRESS_OUT: { - DELAY: States.ERROR, - RESPONDER_GRANT: States.ERROR, - RESPONDER_RELEASE: States.NOT_RESPONDER, - RESPONDER_TERMINATED: States.NOT_RESPONDER, - ENTER_PRESS_RECT: States.RESPONDER_ACTIVE_PRESS_IN, - LEAVE_PRESS_RECT: States.RESPONDER_ACTIVE_PRESS_OUT, - LONG_PRESS_DETECTED: States.ERROR, - }, - RESPONDER_ACTIVE_LONG_PRESS_IN: { - DELAY: States.ERROR, - RESPONDER_GRANT: States.ERROR, - RESPONDER_RELEASE: States.NOT_RESPONDER, - RESPONDER_TERMINATED: States.NOT_RESPONDER, - ENTER_PRESS_RECT: States.RESPONDER_ACTIVE_LONG_PRESS_IN, - LEAVE_PRESS_RECT: States.RESPONDER_ACTIVE_LONG_PRESS_OUT, - LONG_PRESS_DETECTED: States.RESPONDER_ACTIVE_LONG_PRESS_IN, - }, - RESPONDER_ACTIVE_LONG_PRESS_OUT: { - DELAY: States.ERROR, - RESPONDER_GRANT: States.ERROR, - RESPONDER_RELEASE: States.NOT_RESPONDER, - RESPONDER_TERMINATED: States.NOT_RESPONDER, - ENTER_PRESS_RECT: States.RESPONDER_ACTIVE_LONG_PRESS_IN, - LEAVE_PRESS_RECT: States.RESPONDER_ACTIVE_LONG_PRESS_OUT, - LONG_PRESS_DETECTED: States.ERROR, - }, - error: { - DELAY: States.NOT_RESPONDER, - RESPONDER_GRANT: States.RESPONDER_INACTIVE_PRESS_IN, - RESPONDER_RELEASE: States.NOT_RESPONDER, - RESPONDER_TERMINATED: States.NOT_RESPONDER, - ENTER_PRESS_RECT: States.NOT_RESPONDER, - LEAVE_PRESS_RECT: States.NOT_RESPONDER, - LONG_PRESS_DETECTED: States.NOT_RESPONDER, - } -}; - -// ==== Typical Constants for integrating into UI components ==== -// var HIT_EXPAND_PX = 20; -// var HIT_VERT_OFFSET_PX = 10; -var HIGHLIGHT_DELAY_MS = 130; - -var PRESS_EXPAND_PX = 20; - -var LONG_PRESS_THRESHOLD = 500; - -var LONG_PRESS_ALLOWED_MOVEMENT = 10; - -// Default amount "active" region protrudes beyond box - -/** - * By convention, methods prefixed with underscores are meant to be @private, - * and not @protected. Mixers shouldn't access them - not even to provide them - * as callback handlers. - * - * - * ========== Geometry ========= - * `Touchable` only assumes that there exists a `HitRect` node. The `PressRect` - * is an abstract box that is extended beyond the `HitRect`. - * - * +--------------------------+ - * | | - "Start" events in `HitRect` cause `HitRect` - * | +--------------------+ | to become the responder. - * | | +--------------+ | | - `HitRect` is typically expanded around - * | | | | | | the `VisualRect`, but shifted downward. - * | | | VisualRect | | | - After pressing down, after some delay, - * | | | | | | and before letting up, the Visual React - * | | +--------------+ | | will become "active". This makes it eligible - * | | HitRect | | for being highlighted (so long as the - * | +--------------------+ | press remains in the `PressRect`). - * | PressRect o | - * +----------------------|---+ - * Out Region | - * +-----+ This gap between the `HitRect` and - * `PressRect` allows a touch to move far away - * from the original hit rect, and remain - * highlighted, and eligible for a "Press". - * Customize this via - * `touchableGetPressRectOffset()`. - * - * - * - * ======= State Machine ======= - * - * +-------------+ <---+ RESPONDER_RELEASE - * |NOT_RESPONDER| - * +-------------+ <---+ RESPONDER_TERMINATED - * + - * | RESPONDER_GRANT (HitRect) - * v - * +---------------------------+ DELAY +-------------------------+ T - DELAY +------------------------------+ - * |RESPONDER_INACTIVE_PRESS_IN|+-------->|RESPONDER_ACTIVE_PRESS_IN| +------------> |RESPONDER_ACTIVE_LONG_PRESS_IN| - * +---------------------------+ +-------------------------+ +------------------------------+ - * + ^ + ^ + ^ - * |LEAVE_ |ENTER_ |LEAVE_ |ENTER_ |LEAVE_ |ENTER_ - * |PRESS_RECT |PRESS_RECT |PRESS_RECT |PRESS_RECT |PRESS_RECT |PRESS_RECT - * | | | | | | - * v + v + v + - * +----------------------------+ DELAY +--------------------------+ +-------------------------------+ - * |RESPONDER_INACTIVE_PRESS_OUT|+------->|RESPONDER_ACTIVE_PRESS_OUT| |RESPONDER_ACTIVE_LONG_PRESS_OUT| - * +----------------------------+ +--------------------------+ +-------------------------------+ - * - * T - DELAY => LONG_PRESS_THRESHOLD - DELAY - * - * Not drawn are the side effects of each transition. The most important side - * effect is the `touchableHandlePress` abstract method invocation that occurs - * when a responder is released while in either of the "Press" states. - * - * The other important side effects are the highlight abstract method - * invocations (internal callbacks) to be implemented by the mixer. - * - * - * @lends Touchable.prototype - */ -var TouchableMixin = { - /** - * It's prefer that mixins determine state in this way, having the class - * explicitly mix the state in the one and only `getInitialState` method. - * - * @return {object} State object to be placed inside of - * `this.state.touchable`. - */ - touchableGetInitialState: function() { - return { - touchable: {touchState: undefined, responderID: null} - }; - }, - - // ==== Hooks to Gesture Responder system ==== - /** - * Must return true if embedded in a native platform scroll view. - */ - touchableHandleResponderTerminationRequest: function() { - return !this.props.rejectResponderTermination; - }, - - /** - * Must return true to start the process of `Touchable`. - */ - touchableHandleStartShouldSetResponder: function() { - return true; - }, - - /** - * Return true to cancel press on long press. - */ - touchableLongPressCancelsPress: function () { - return true; - }, - - /** - * Place as callback for a DOM element's `onResponderGrant` event. - * @param {SyntheticEvent} e Synthetic event from event system. - * @param {string} dispatchID ID of node that e was dispatched to. - * - */ - touchableHandleResponderGrant: function(e, dispatchID) { - // Since e is used in a callback invoked on another event loop - // (as in setTimeout etc), we need to call e.persist() on the - // event to make sure it doesn't get reused in the event object pool. - e.persist(); - - this.state.touchable.touchState = States.NOT_RESPONDER; - this.state.touchable.responderID = dispatchID; - this._receiveSignal(Signals.RESPONDER_GRANT, e); - var delayMS = - this.touchableGetHighlightDelayMS !== undefined ? - this.touchableGetHighlightDelayMS() : HIGHLIGHT_DELAY_MS; - if (delayMS !== 0) { - this.touchableDelayTimeout = setTimeout( - this._handleDelay.bind(this, e), - delayMS - ); - } else { - this._handleDelay(e); - } - - this.longPressDelayTimeout = setTimeout( - this._handleLongDelay.bind(this, e), - LONG_PRESS_THRESHOLD - delayMS - ); - }, - - /** - * Place as callback for a DOM element's `onResponderRelease` event. - */ - touchableHandleResponderRelease: function(e) { - this._receiveSignal(Signals.RESPONDER_RELEASE, e); - }, - - /** - * Place as callback for a DOM element's `onResponderTerminate` event. - */ - touchableHandleResponderTerminate: function(e) { - this._receiveSignal(Signals.RESPONDER_TERMINATED, e); - }, - - /** - * Place as callback for a DOM element's `onResponderMove` event. - */ - touchableHandleResponderMove: function(e) { - // Not enough time elapsed yet, wait for highlight - - // this is just a perf optimization. - if (this.state.touchable.touchState === States.RESPONDER_INACTIVE_PRESS_IN) { - return; - } - - // Measurement may not have returned yet. - if (!this.state.touchable.positionOnActivate) { - return; - } - - var positionOnActivate = this.state.touchable.positionOnActivate; - var dimensionsOnActivate = this.state.touchable.dimensionsOnActivate; - var pressRectOffset = this.touchableGetPressRectOffset ? - this.touchableGetPressRectOffset() : null; - var pressExpandLeft = - pressRectOffset.left != null ? pressRectOffset.left : PRESS_EXPAND_PX; - var pressExpandTop = - pressRectOffset.top != null ? pressRectOffset.top : PRESS_EXPAND_PX; - var pressExpandRight = - pressRectOffset.right != null ? pressRectOffset.right : PRESS_EXPAND_PX; - var pressExpandBottom = - pressRectOffset.bottom != null ? pressRectOffset.bottom : PRESS_EXPAND_PX; - - var touch = TouchEventUtils.extractSingleTouch(e.nativeEvent); - var pageX = touch && touch.pageX; - var pageY = touch && touch.pageY; - - if (this.pressInLocation) { - var movedDistance = this._getDistanceBetweenPoints(pageX, pageY, this.pressInLocation.pageX, this.pressInLocation.pageY); - if (movedDistance > LONG_PRESS_ALLOWED_MOVEMENT) { - this._cancelLongPressDelayTimeout(); - } - } - - var isTouchWithinActive = - pageX > positionOnActivate.left - pressExpandLeft && - pageY > positionOnActivate.top - pressExpandTop && - pageX < - positionOnActivate.left + - dimensionsOnActivate.width + - pressExpandRight && - pageY < - positionOnActivate.top + - dimensionsOnActivate.height + - pressExpandBottom; - if (isTouchWithinActive) { - this._receiveSignal(Signals.ENTER_PRESS_RECT, e); - } else { - this._cancelLongPressDelayTimeout(); - this._receiveSignal(Signals.LEAVE_PRESS_RECT, e); - } - }, - - // ==== Abstract Application Callbacks ==== - - /** - * Invoked when the item should be highlighted. Mixers should implement this - * to visually distinguish the `VisualRect` so that the user knows that - * releasing a touch will result in a "selection" (analog to click). - * - * @abstract - * touchableHandleActivePressIn: function, - */ - - /** - * Invoked when the item is "active" (in that it is still eligible to become - * a "select") but the touch has left the `PressRect`. Usually the mixer will - * want to unhighlight the `VisualRect`. If the user (while pressing) moves - * back into the `PressRect` `touchableHandleActivePressIn` will be invoked - * again and the mixer should probably highlight the `VisualRect` again. This - * event will not fire on an `touchEnd/mouseUp` event, only move events while - * the user is depressing the mouse/touch. - * - * @abstract - * touchableHandleActivePressOut: function - */ - - /** - * Invoked when the item is "selected" - meaning the interaction ended by - * letting up while the item was either in the state - * `RESPONDER_ACTIVE_PRESS_IN` or `RESPONDER_INACTIVE_PRESS_IN`. - * - * @abstract - * touchableHandlePress: function - */ - - /** - * Invoked when the item is long pressed - meaning the interaction ended by - * letting up while the item was in `RESPONDER_ACTIVE_LONG_PRESS_IN`. If - * `touchableHandleLongPress` is *not* provided, `touchableHandlePress` will - * be called as it normally is. If `touchableHandleLongPress` is provided, by - * default any `touchableHandlePress` callback will not be invoked. To - * override this default behavior, override `touchableLongPressCancelsPress` - * to return false. As a result, `touchableHandlePress` will be called when - * lifting up, even if `touchableHandleLongPress` has also been called. - * - * @abstract - * touchableHandleLongPress: function - */ - - /** - * Returns the number of millis to wait before triggering a highlight. - * - * @abstract - * touchableGetHighlightDelayMS: function - */ - - /** - * Returns the amount to extend the `HitRect` into the `PressRect`. Positive - * numbers mean the size expands outwards. - * - * @abstract - * touchableGetPressRectOffset: function - */ - - - - // ==== Internal Logic ==== - - /** - * Measures the `HitRect` node on activation. The Bounding rectangle is with - * respect to viewport - not page, so adding the `pageXOffset/pageYOffset` - * should result in points that are in the same coordinate system as an - * event's `globalX/globalY` data values. - * - * - Consider caching this for the lifetime of the component, or possibly - * being able to share this cache between any `ScrollMap` view. - * - * @sideeffects - * @private - */ - _remeasureMetricsOnActivation: function() { - queryLayoutByID( - this.state.touchable.responderID, - null, - this._handleQueryLayout - ); - }, - - _handleQueryLayout: function(l, t, w, h, globalX, globalY) { - this.state.touchable.positionOnActivate && - Position.release(this.state.touchable.positionOnActivate); - this.state.touchable.dimensionsOnActivate && - BoundingDimensions.release(this.state.touchable.dimensionsOnActivate); - this.state.touchable.positionOnActivate = Position.getPooled(globalX, globalY); - this.state.touchable.dimensionsOnActivate = BoundingDimensions.getPooled(w, h); - }, - - _handleDelay: function(e) { - this.touchableDelayTimeout = null; - this._receiveSignal(Signals.DELAY, e); - }, - - _handleLongDelay: function(e) { - this.longPressDelayTimeout = null; - this._receiveSignal(Signals.LONG_PRESS_DETECTED, e); - }, - - /** - * Receives a state machine signal, performs side effects of the transition - * and stores the new state. Validates the transition as well. - * - * @param {Signals} signal State machine signal. - * @throws Error if invalid state transition or unrecognized signal. - * @sideeffects - */ - _receiveSignal: function(signal, e) { - var curState = this.state.touchable.touchState; - if (!(Transitions[curState] && Transitions[curState][signal])) { - throw new Error( - 'Unrecognized signal `' + signal + '` or state `' + curState + - '` for Touchable responder `' + this.state.touchable.responderID + '`' - ); - } - var nextState = Transitions[curState][signal]; - if (nextState === States.ERROR) { - throw new Error( - 'Touchable cannot transition from `' + curState + '` to `' + signal + - '` for responder `' + this.state.touchable.responderID + '`' - ); - } - if (curState !== nextState) { - this._performSideEffectsForTransition(curState, nextState, signal, e); - this.state.touchable.touchState = nextState; - } - }, - - _cancelLongPressDelayTimeout: function () { - this.longPressDelayTimeout && clearTimeout(this.longPressDelayTimeout); - this.longPressDelayTimeout = null; - }, - - _isHighlight: function (state) { - return state === States.RESPONDER_ACTIVE_PRESS_IN || - state === States.RESPONDER_ACTIVE_LONG_PRESS_IN; - }, - - _savePressInLocation: function(e) { - var touch = TouchEventUtils.extractSingleTouch(e.nativeEvent); - var pageX = touch && touch.pageX; - var pageY = touch && touch.pageY; - this.pressInLocation = {pageX: pageX, pageY: pageY}; - }, - - _getDistanceBetweenPoints: function (aX, aY, bX, bY) { - var deltaX = aX - bX; - var deltaY = aY - bY; - return Math.sqrt(deltaX * deltaX + deltaY * deltaY); - }, - - /** - * Will perform a transition between touchable states, and identify any - * highlighting or unhighlighting that must be performed for this particular - * transition. - * - * @param {States} curState Current Touchable state. - * @param {States} nextState Next Touchable state. - * @param {Signal} signal Signal that triggered the transition. - * @param {Event} e Native event. - * @sideeffects - */ - _performSideEffectsForTransition: function(curState, nextState, signal, e) { - var curIsHighlight = this._isHighlight(curState); - var newIsHighlight = this._isHighlight(nextState); - - var isFinalSignal = - signal === Signals.RESPONDER_TERMINATED || - signal === Signals.RESPONDER_RELEASE; - - if (isFinalSignal) { - this._cancelLongPressDelayTimeout(); - } - - if (!IsActive[curState] && IsActive[nextState]) { - this._remeasureMetricsOnActivation(); - } - - if (IsPressingIn[curState] && signal === Signals.LONG_PRESS_DETECTED) { - this.touchableHandleLongPress && this.touchableHandleLongPress(); - } - - if (newIsHighlight && !curIsHighlight) { - this._savePressInLocation(e); - this.touchableHandleActivePressIn && this.touchableHandleActivePressIn(); - } else if (!newIsHighlight && curIsHighlight) { - this.touchableHandleActivePressOut && this.touchableHandleActivePressOut(); - } - - if (IsPressingIn[curState] && signal === Signals.RESPONDER_RELEASE) { - var hasLongPressHandler = !!this.props.onLongPress; - var pressIsLongButStillCallOnPress = - IsLongPressingIn[curState] && ( // We *are* long pressing.. - !hasLongPressHandler || // But either has no long handler - !this.touchableLongPressCancelsPress() // or we're told to ignore it. - ); - - var shouldInvokePress = !IsLongPressingIn[curState] || pressIsLongButStillCallOnPress; - if (shouldInvokePress && this.touchableHandlePress) { - this.touchableHandlePress(e); - } - } - - this.touchableDelayTimeout && clearTimeout(this.touchableDelayTimeout); - this.touchableDelayTimeout = null; - } - -}; - -var Touchable = { - Mixin: TouchableMixin -}; - -module.exports = Touchable; -}); -__d('BoundingDimensions',["PooledClass"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * @providesModule BoundingDimensions - */ - -"use strict"; - -var PooledClass = require('PooledClass'); - -var twoArgumentPooler = PooledClass.twoArgumentPooler; - -/** - * PooledClass representing the bounding rectangle of a region. - * - * @param {number} width Width of bounding rectangle. - * @param {number} height Height of bounding rectangle. - * @constructor BoundingDimensions - */ -function BoundingDimensions(width, height) { - this.width = width; - this.height = height; -} - -/** - * @param {HTMLElement} element Element to return `BoundingDimensions` for. - * @return {BoundingDimensions} Bounding dimensions of `element`. - */ -BoundingDimensions.getPooledFromElement = function(element) { - return BoundingDimensions.getPooled( - element.offsetWidth, - element.offsetHeight - ); -}; - -PooledClass.addPoolingTo(BoundingDimensions, twoArgumentPooler); - -module.exports = BoundingDimensions; - -}); -__d('Position',["PooledClass"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * @providesModule Position - */ - -"use strict"; - -var PooledClass = require('PooledClass'); - -var twoArgumentPooler = PooledClass.twoArgumentPooler; - -/** - * Position does not expose methods for construction via an `HTMLDOMElement`, - * because it isn't meaningful to construct such a thing without first defining - * a frame of refrence. - * - * @param {number} windowStartKey Key that window starts at. - * @param {number} windowEndKey Key that window ends at. - */ -function Position(left, top) { - this.left = left; - this.top = top; -} - -PooledClass.addPoolingTo(Position, twoArgumentPooler); - -module.exports = Position; - -}); -__d('TouchEventUtils',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 TouchEventUtils - */ - -var TouchEventUtils = { - /** - * Utility function for common case of extracting out the primary touch from a - * touch event. - * - `touchEnd` events usually do not have the `touches` property. - * http://stackoverflow.com/questions/3666929/ - * mobile-sarai-touchend-event-not-firing-when-last-touch-is-removed - * - * @param {Event} nativeEvent Native event that may or may not be a touch. - * @return {TouchesObject?} an object with pageX and pageY or null. - */ - extractSingleTouch: function(nativeEvent) { - var touches = nativeEvent.touches; - var changedTouches = nativeEvent.changedTouches; - var hasTouches = touches && touches.length > 0; - var hasChangedTouches = changedTouches && changedTouches.length > 0; - - return !hasTouches && hasChangedTouches ? changedTouches[0] : - hasTouches ? touches[0] : - nativeEvent; - } -}; - -module.exports = TouchEventUtils; -}); -__d('queryLayoutByID',["ReactNativeTagHandles","NativeModules"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 queryLayoutByID - * @flow - */ -'use strict'; - -var ReactNativeTagHandles = require('ReactNativeTagHandles'); -var RCTUIManager = require('NativeModules').UIManager; - - - - - - - - - - -// I don't know what type error is... - - -/** - * Queries the layout of a view. The layout does not reflect the element as - * seen by the user, rather it reflects the position within the layout system, - * before any transforms are applied. - * - * The only other requirement is that the `pageX, pageY` values be in the same - * coordinate system that events' `pageX/Y` are reported. That means that for - * the web, `pageXOffset/pageYOffset` should be added to to - * getBoundingClientRect to make consistent with touches. - * - * var pageXOffset = window.pageXOffset; - * var pageYOffset = window.pageYOffset; - * - * This is an IOS specific implementation. - * - * @param {string} rootNodeID ID of the platform specific node to be measured. - * @param {function} onError `func(error)` - * @param {function} onSuccess `func(left, top, width, height, pageX, pageY)` - */ -var queryLayoutByID = function( - rootNodeID , - onError , - onSuccess -) { - // Native bridge doesn't *yet* surface errors. - RCTUIManager.measure( - ReactNativeTagHandles.rootNodeIDToTag[rootNodeID], - onSuccess - ); -}; - -module.exports = queryLayoutByID; -}); -__d('TextInput',["DocumentSelectionState","EventEmitter","NativeMethodsMixin","NativeModules","Platform","ReactPropTypes","React","ReactChildren","ReactNativeViewAttributes","StyleSheet","Text","TextInputState","react-timer-mixin/TimerMixin","TouchableWithoutFeedback","createReactNativeComponentClass","emptyFunction","invariant","merge"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 TextInput - * @flow - */ -'use strict'; - -var DocumentSelectionState = require('DocumentSelectionState'); -var EventEmitter = require('EventEmitter'); -var NativeMethodsMixin = require('NativeMethodsMixin'); -var RCTUIManager = require('NativeModules').UIManager; -var Platform = require('Platform'); -var PropTypes = require('ReactPropTypes'); -var React = require('React'); -var ReactChildren = require('ReactChildren'); -var ReactNativeViewAttributes = require('ReactNativeViewAttributes'); -var StyleSheet = require('StyleSheet'); -var Text = require('Text'); -var TextInputState = require('TextInputState'); -var TimerMixin = require('react-timer-mixin/TimerMixin'); -var TouchableWithoutFeedback = require('TouchableWithoutFeedback'); - -var createReactNativeComponentClass = require('createReactNativeComponentClass'); -var emptyFunction = require('emptyFunction'); -var invariant = require('invariant'); -var merge = require('merge'); - -var autoCapitalizeConsts = RCTUIManager.UIText.AutocapitalizationType; -var keyboardTypeConsts = RCTUIManager.UIKeyboardType; -var returnKeyTypeConsts = RCTUIManager.UIReturnKeyType; - -var RCTTextViewAttributes = merge(ReactNativeViewAttributes.UIView, { - autoCorrect: true, - autoCapitalize: true, - clearTextOnFocus: true, - color: true, - editable: true, - fontFamily: true, - fontSize: true, - fontStyle: true, - fontWeight: true, - keyboardType: true, - returnKeyType: true, - enablesReturnKeyAutomatically: true, - secureTextEntry: true, - selectTextOnFocus: true, - mostRecentEventCounter: true, - placeholder: true, - placeholderTextColor: true, - text: true, -}); - -var RCTTextFieldAttributes = merge(RCTTextViewAttributes, { - caretHidden: true, - enabled: true, - clearButtonMode: true, - clearTextOnFocus: true, - selectTextOnFocus: true, -}); - -var onlyMultiline = { - onSelectionChange: true, - onTextInput: true, - children: true, -}; - -var notMultiline = { - onSubmitEditing: true, -}; - -var AndroidTextInputAttributes = { - autoCapitalize: true, - autoCorrect: true, - autoFocus: true, - keyboardType: true, - multiline: true, - password: true, - placeholder: true, - text: true, - testID: true, -}; - -var viewConfigIOS = { - uiViewClassName: 'RCTTextField', - validAttributes: RCTTextFieldAttributes, -}; - -var viewConfigAndroid = { - uiViewClassName: 'AndroidTextInput', - validAttributes: AndroidTextInputAttributes, -}; - -var crossPlatformKeyboardTypeMap = { - 'numeric': 'decimal-pad', -}; - - - - - - - -/** - * A foundational component for inputting text into the app via a - * keyboard. Props provide configurability for several features, such as auto- - * correction, auto-capitalization, placeholder text, and different keyboard - * types, such as a numeric keypad. - * - * The simplest use case is to plop down a `TextInput` and subscribe to the - * `onChangeText` events to read the user input. There are also other events, such - * as `onSubmitEditing` and `onFocus` that can be subscribed to. A simple - * example: - * - * ``` - * - * this.setState({input: text})} - * /> - * {'user input: ' + this.state.input} - * - * ``` - * - * The `value` prop can be used to set the value of the input in order to make - * the state of the component clear, but does not behave as a true - * controlled component by default because all operations are asynchronous. - * Setting `value` once is like setting the default value, but you can change it - * continuously based on `onChangeText` events as well. If you really want to - * force the component to always revert to the value you are setting, you can - * set `controlled={true}`. - * - * The `multiline` prop is not supported in all releases, and some props are - * multiline only. - */ - -var TextInput = React.createClass({displayName: "TextInput", - propTypes: { - /** - * Can tell TextInput to automatically capitalize certain characters. - * - * - characters: all characters, - * - words: first letter of each word - * - sentences: first letter of each sentence (default) - * - none: don't auto capitalize anything - */ - autoCapitalize: PropTypes.oneOf([ - 'none', - 'sentences', - 'words', - 'characters', - ]), - /** - * If false, disables auto-correct. Default value is true. - */ - autoCorrect: PropTypes.bool, - /** - * If true, focuses the input on componentDidMount. Default value is false. - */ - autoFocus: PropTypes.bool, - /** - * If false, text is not editable. Default value is true. - */ - editable: PropTypes.bool, - /** - * Determines which keyboard to open, e.g.`numeric`. - */ - keyboardType: PropTypes.oneOf([ - 'default', - // iOS - 'ascii-capable', - 'numbers-and-punctuation', - 'url', - 'number-pad', - 'phone-pad', - 'name-phone-pad', - 'decimal-pad', - 'twitter', - 'web-search', - // Cross-platform - 'numeric', - 'email-address', - ]), - /** - * Determines how the return key should look. - */ - returnKeyType: PropTypes.oneOf([ - 'default', - 'go', - 'google', - 'join', - 'next', - 'route', - 'search', - 'send', - 'yahoo', - 'done', - 'emergency-call', - ]), - /** - * If true, the keyboard disables the return key when there is no text and - * automatically enables it when there is text. Default value is false. - */ - enablesReturnKeyAutomatically: PropTypes.bool, - /** - * If true, the text input can be multiple lines. Default value is false. - */ - multiline: PropTypes.bool, - /** - * Callback that is called when the text input is blurred - */ - onBlur: PropTypes.func, - /** - * Callback that is called when the text input is focused - */ - onFocus: PropTypes.func, - /** - * Callback that is called when the text input's text changes. - */ - onChange: PropTypes.func, - onChangeText: PropTypes.func, - /** - * Callback that is called when text input ends. - */ - onEndEditing: PropTypes.func, - /** - * Callback that is called when the text input's submit button is pressed. - */ - onSubmitEditing: PropTypes.func, - /** - * Invoked on mount and layout changes with {x, y, width, height}. - */ - onLayout: PropTypes.func, - /** - * If true, the text input obscures the text entered so that sensitive text - * like passwords stay secure. Default value is false. - */ - password: PropTypes.bool, - /** - * The string that will be rendered before text input has been entered - */ - placeholder: PropTypes.string, - /** - * The text color of the placeholder string - */ - placeholderTextColor: PropTypes.string, - /** - * See DocumentSelectionState.js, some state that is responsible for - * maintaining selection information for a document - */ - selectionState: PropTypes.instanceOf(DocumentSelectionState), - /** - * The default value for the text input - */ - value: PropTypes.string, - /** - * This helps avoid drops characters due to race conditions between JS and - * the native text input. The default should be fine, but if you're - * potentially doing very slow operations on every keystroke then you may - * want to try increasing this. - */ - bufferDelay: PropTypes.number, - /** - * If you really want this to behave as a controlled component, you can set - * this true, but you will probably see flickering, dropped keystrokes, - * and/or laggy typing, depending on how you process onChange events. - */ - controlled: PropTypes.bool, - /** - * When the clear button should appear on the right side of the text view - */ - clearButtonMode: PropTypes.oneOf([ - 'never', - 'while-editing', - 'unless-editing', - 'always', - ]), - /** - * If true, clears the text field automatically when editing begins - */ - clearTextOnFocus: PropTypes.bool, - /** - * If true, selected the text automatically when editing begins - */ - selectTextOnFocus: PropTypes.bool, - /** - * Styles - */ - style: Text.propTypes.style, - /** - * Used to locate this view in end-to-end tests. - */ - testID: PropTypes.string, - }, - - /** - * `NativeMethodsMixin` will look for this when invoking `setNativeProps`. We - * make `this` look like an actual native component class. - */ - mixins: [NativeMethodsMixin, TimerMixin], - - viewConfig: ((Platform.OS === 'ios' ? viewConfigIOS : - (Platform.OS === 'android' ? viewConfigAndroid : {})) ), - - isFocused: function() { - return TextInputState.currentlyFocusedField() === - React.findNodeHandle(this.refs.input); - }, - - getDefaultProps: function() { - return { - bufferDelay: 100, - }; - }, - - getInitialState: function() { - return { - mostRecentEventCounter: 0, - bufferedValue: this.props.value, - }; - }, - - contextTypes: { - onFocusRequested: React.PropTypes.func, - focusEmitter: React.PropTypes.instanceOf(EventEmitter), - }, - - _focusSubscription: (undefined ), - - componentDidMount: function() { - if (!this.context.focusEmitter) { - if (this.props.autoFocus) { - this.requestAnimationFrame(this.focus); - } - return; - } - this._focusSubscription = this.context.focusEmitter.addListener( - 'focus', - function(el) { - if (this === el) { - this.requestAnimationFrame(this.focus); - } else if (this.isFocused()) { - this.blur(); - } - }.bind(this) - ); - if (this.props.autoFocus) { - this.context.onFocusRequested(this); - } - }, - - componentWillUnmount: function() { - this._focusSubscription && this._focusSubscription.remove(); - if (this.isFocused()) { - this.blur(); - } - }, - - _bufferTimeout: (undefined ), - - componentWillReceiveProps: function(newProps ) { - if (newProps.value !== this.props.value) { - if (!this.isFocused()) { - // Set the value immediately if the input is not focused since that - // means there is no risk of the user typing immediately. - this.setState({bufferedValue: newProps.value}); - } else { - // The following clear and setTimeout buffers the value such that if more - // characters are typed in quick succession, generating new values, the - // out of date values will get cancelled before they are ever sent to - // native. - // - // If we don't do this, it's likely the out of date values will blow - // away recently typed characters in the native input that JS was not - // yet aware of (since it is informed asynchronously), then the next - // character will be appended to the older value, dropping the - // characters in between. Here is a potential sequence of events - // (recall we have multiple independently serial, interleaved queues): - // - // 1) User types 'R' => send 'R' to JS queue. - // 2) User types 'e' => send 'Re' to JS queue. - // 3) JS processes 'R' and sends 'R' back to native. - // 4) Native recieves 'R' and changes input from 'Re' back to 'R'. - // 5) User types 'a' => send 'Ra' to JS queue. - // 6) JS processes 'Re' and sends 'Re' back to native. - // 7) Native recieves 'Re' and changes input from 'R' back to 'Re'. - // 8) JS processes 'Ra' and sends 'Ra' back to native. - // 9) Native recieves final 'Ra' from JS - 'e' has been dropped! - // - // This isn't 100% foolproop (e.g. if it takes longer than - // `props.bufferDelay` ms to process one keystroke), and there are of - // course other potential algorithms to deal with this, but this is a - // simple solution that seems to reduce the chance of dropped characters - // drastically without compromising native input responsiveness (e.g. by - // introducing delay from a synchronization protocol). - this.clearTimeout(this._bufferTimeout); - this._bufferTimeout = this.setTimeout( - function() {return this.setState({bufferedValue: newProps.value});}.bind(this), - this.props.bufferDelay - ); - } - } - }, - - render: function() { - if (Platform.OS === 'ios') { - return this._renderIOs(); - } else if (Platform.OS === 'android') { - return this._renderAndroid(); - } - }, - - _renderIOs: function() { - var textContainer; - - var autoCapitalize = autoCapitalizeConsts[this.props.autoCapitalize]; - var clearButtonMode = RCTUIManager.UITextField.clearButtonMode[this.props.clearButtonMode]; - - var keyboardType = keyboardTypeConsts[ - crossPlatformKeyboardTypeMap[this.props.keyboardType] || - this.props.keyboardType - ]; - var returnKeyType = returnKeyTypeConsts[this.props.returnKeyType]; - - if (!this.props.multiline) { - for (var propKey in onlyMultiline) { - if (this.props[propKey]) { - throw new Error( - 'TextInput prop `' + propKey + '` is only supported with multiline.' - ); - } - } - textContainer = - React.createElement(RCTTextField, { - ref: "input", - style: [styles.input, this.props.style], - enabled: this.props.editable, - keyboardType: keyboardType, - returnKeyType: returnKeyType, - enablesReturnKeyAutomatically: this.props.enablesReturnKeyAutomatically, - secureTextEntry: this.props.password || this.props.secureTextEntry, - onFocus: this._onFocus, - onBlur: this._onBlur, - onChange: this._onChange, - onEndEditing: this.props.onEndEditing, - onSubmitEditing: this.props.onSubmitEditing, - onSelectionChangeShouldSetResponder: function() {return true;}, - onLayout: this.props.onLayout, - placeholder: this.props.placeholder, - placeholderTextColor: this.props.placeholderTextColor, - text: this.state.bufferedValue, - autoCapitalize: autoCapitalize, - autoCorrect: this.props.autoCorrect, - clearButtonMode: clearButtonMode, - clearTextOnFocus: this.props.clearTextOnFocus, - selectTextOnFocus: this.props.selectTextOnFocus} - ); - } else { - for (var propKey in notMultiline) { - if (this.props[propKey]) { - throw new Error( - 'TextInput prop `' + propKey + '` cannot be used with multiline.' - ); - } - } - - var children = this.props.children; - var childCount = 0; - ReactChildren.forEach(children, function() {return ++childCount;}); - invariant( - !(this.props.value && childCount), - 'Cannot specify both value and children.' - ); - if (childCount > 1) { - children = React.createElement(Text, null, children); - } - if (this.props.inputView) { - children = [children, this.props.inputView]; - } - textContainer = - React.createElement(RCTTextView, { - ref: "input", - style: [styles.input, this.props.style], - children: children, - mostRecentEventCounter: this.state.mostRecentEventCounter, - editable: this.props.editable, - keyboardType: keyboardType, - returnKeyType: returnKeyType, - enablesReturnKeyAutomatically: this.props.enablesReturnKeyAutomatically, - secureTextEntry: this.props.password || this.props.secureTextEntry, - onFocus: this._onFocus, - onBlur: this._onBlur, - onChange: this._onChange, - onEndEditing: this.props.onEndEditing, - onSelectionChange: this._onSelectionChange, - onTextInput: this._onTextInput, - onSelectionChangeShouldSetResponder: emptyFunction.thatReturnsTrue, - onLayout: this.props.onLayout, - placeholder: this.props.placeholder, - placeholderTextColor: this.props.placeholderTextColor, - text: this.state.bufferedValue, - autoCapitalize: autoCapitalize, - autoCorrect: this.props.autoCorrect, - clearButtonMode: clearButtonMode, - selectTextOnFocus: this.props.selectTextOnFocus, - clearTextOnFocus: this.props.clearTextOnFocus} - ); - } - - return ( - React.createElement(TouchableWithoutFeedback, { - onPress: this._onPress, - rejectResponderTermination: true}, - textContainer - ) - ); - }, - - _renderAndroid: function() { - var autoCapitalize = autoCapitalizeConsts[this.props.autoCapitalize]; - var textContainer = - React.createElement(AndroidTextInput, { - ref: "input", - style: [this.props.style], - autoCapitalize: autoCapitalize, - autoCorrect: this.props.autoCorrect, - keyboardType: this.props.keyboardType, - multiline: this.props.multiline, - onFocus: this._onFocus, - onBlur: this._onBlur, - onChange: this._onChange, - onEndEditing: this.props.onEndEditing, - onSubmitEditing: this.props.onSubmitEditing, - onLayout: this.props.onLayout, - password: this.props.password || this.props.secureTextEntry, - placeholder: this.props.placeholder, - text: this.state.bufferedValue} - ); - - return ( - React.createElement(TouchableWithoutFeedback, { - onPress: this._onPress, - testID: this.props.testID}, - textContainer - ) - ); - }, - - _onFocus: function(event ) { - if (this.props.onFocus) { - this.props.onFocus(event); - } - }, - - _onPress: function(event ) { - this.focus(); - }, - - _onChange: function(event ) { - if (this.props.controlled && event.nativeEvent.text !== this.props.value) { - this.refs.input.setNativeProps({text: this.props.value}); - } - this.props.onChange && this.props.onChange(event); - this.props.onChangeText && this.props.onChangeText(event.nativeEvent.text); - }, - - _onBlur: function(event ) { - this.blur(); - if (this.props.onBlur) { - this.props.onBlur(event); - } - }, - - _onSelectionChange: function(event ) { - if (this.props.selectionState) { - var selection = event.nativeEvent.selection; - this.props.selectionState.update(selection.start, selection.end); - } - this.props.onSelectionChange && this.props.onSelectionChange(event); - }, - - _onTextInput: function(event ) { - this.props.onTextInput && this.props.onTextInput(event); - var counter = event.nativeEvent.eventCounter; - if (counter > this.state.mostRecentEventCounter) { - this.setState({mostRecentEventCounter: counter}); - } - }, -}); - -var styles = StyleSheet.create({ - input: { - alignSelf: 'stretch', - }, -}); - -var RCTTextView = createReactNativeComponentClass({ - validAttributes: RCTTextViewAttributes, - uiViewClassName: 'RCTTextView', -}); - -var RCTTextField = createReactNativeComponentClass({ - validAttributes: RCTTextFieldAttributes, - uiViewClassName: 'RCTTextField', -}); - -var AndroidTextInput = createReactNativeComponentClass({ - validAttributes: AndroidTextInputAttributes, - uiViewClassName: 'AndroidTextInput', -}); - -module.exports = TextInput; -}); -__d('DocumentSelectionState',["mixInEventEmitter"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * @generated SignedSource<<1f058815818e10d01d2ee1f2f70d0fb1>> - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !! This file is a check-in of a static_upstream project! !! - * !! !! - * !! You should not modify this file directly. Instead: !! - * !! 1) Use `fjs use-upstream` to temporarily replace this with !! - * !! the latest version from upstream. !! - * !! 2) Make your changes, test them, etc. !! - * !! 3) Use `fjs push-upstream` to copy your changes back to !! - * !! static_upstream. !! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * @providesModule DocumentSelectionState - * @typechecks - */ - -var mixInEventEmitter = require('mixInEventEmitter'); - -/** - * DocumentSelectionState is responsible for maintaining selection information - * for a document. - * - * It is intended for use by AbstractTextEditor-based components for - * identifying the appropriate start/end positions to modify the - * DocumentContent, and for programatically setting browser selection when - * components re-render. - */ - - /** - * @param {number} anchor - * @param {number} focus - */ - function DocumentSelectionState(anchor, focus) {"use strict"; - this.$DocumentSelectionState_anchorOffset = anchor; - this.$DocumentSelectionState_focusOffset = focus; - this.$DocumentSelectionState_hasFocus = false; - } - - /** - * Apply an update to the state. If either offset value has changed, - * set the values and emit the `change` event. Otherwise no-op. - * - * @param {number} anchor - * @param {number} focus - */ - DocumentSelectionState.prototype.update=function(anchor, focus) {"use strict"; - if (this.$DocumentSelectionState_anchorOffset !== anchor || this.$DocumentSelectionState_focusOffset !== focus) { - this.$DocumentSelectionState_anchorOffset = anchor; - this.$DocumentSelectionState_focusOffset = focus; - this.emit('update'); - } - }; - - /** - * Given a max text length, constrain our selection offsets to ensure - * that the selection remains strictly within the text range. - * - * @param {number} maxLength - */ - DocumentSelectionState.prototype.constrainLength=function(maxLength) {"use strict"; - this.update( - Math.min(this.$DocumentSelectionState_anchorOffset, maxLength), - Math.min(this.$DocumentSelectionState_focusOffset, maxLength) - ); - }; - - DocumentSelectionState.prototype.focus=function() {"use strict"; - if (!this.$DocumentSelectionState_hasFocus) { - this.$DocumentSelectionState_hasFocus = true; - this.emit('focus'); - } - }; - - DocumentSelectionState.prototype.blur=function() {"use strict"; - if (this.$DocumentSelectionState_hasFocus) { - this.$DocumentSelectionState_hasFocus = false; - this.emit('blur'); - } - }; - - /** - * @return {boolean} - */ - DocumentSelectionState.prototype.hasFocus=function() {"use strict"; - return this.$DocumentSelectionState_hasFocus; - }; - - /** - * @return {boolean} - */ - DocumentSelectionState.prototype.isCollapsed=function() {"use strict"; - return this.$DocumentSelectionState_anchorOffset === this.$DocumentSelectionState_focusOffset; - }; - - /** - * @return {boolean} - */ - DocumentSelectionState.prototype.isBackward=function() {"use strict"; - return this.$DocumentSelectionState_anchorOffset > this.$DocumentSelectionState_focusOffset; - }; - - /** - * @return {?number} - */ - DocumentSelectionState.prototype.getAnchorOffset=function() {"use strict"; - return this.$DocumentSelectionState_hasFocus ? this.$DocumentSelectionState_anchorOffset : null; - }; - - /** - * @return {?number} - */ - DocumentSelectionState.prototype.getFocusOffset=function() {"use strict"; - return this.$DocumentSelectionState_hasFocus ? this.$DocumentSelectionState_focusOffset : null; - }; - - /** - * @return {?number} - */ - DocumentSelectionState.prototype.getStartOffset=function() {"use strict"; - return ( - this.$DocumentSelectionState_hasFocus ? Math.min(this.$DocumentSelectionState_anchorOffset, this.$DocumentSelectionState_focusOffset) : null - ); - }; - - /** - * @return {?number} - */ - DocumentSelectionState.prototype.getEndOffset=function() {"use strict"; - return ( - this.$DocumentSelectionState_hasFocus ? Math.max(this.$DocumentSelectionState_anchorOffset, this.$DocumentSelectionState_focusOffset) : null - ); - }; - - /** - * @param {number} start - * @param {number} end - * @return {boolean} - */ - DocumentSelectionState.prototype.overlaps=function(start, end) {"use strict"; - return ( - this.hasFocus() && - this.getStartOffset() <= end && start <= this.getEndOffset() - ); - }; - - -mixInEventEmitter(DocumentSelectionState, { - 'blur': true, - 'focus': true, - 'update': true -}); - -module.exports = DocumentSelectionState; - -}); -__d('mixInEventEmitter',["EventEmitter","EventEmitterWithHolding","EventHolder","EventValidator","copyProperties","invariant","keyOf"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * @generated SignedSource<> - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !! This file is a check-in of a static_upstream project! !! - * !! !! - * !! You should not modify this file directly. Instead: !! - * !! 1) Use `fjs use-upstream` to temporarily replace this with !! - * !! the latest version from upstream. !! - * !! 2) Make your changes, test them, etc. !! - * !! 3) Use `fjs push-upstream` to copy your changes back to !! - * !! static_upstream. !! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * @providesModule mixInEventEmitter - */ - -var EventEmitter = require('EventEmitter'); -var EventEmitterWithHolding = require('EventEmitterWithHolding'); -var EventHolder = require('EventHolder'); -var EventValidator = require('EventValidator'); - -var copyProperties = require('copyProperties'); -var invariant = require('invariant'); -var keyOf = require('keyOf'); - -var TYPES_KEY = keyOf({__types: true}); - -/** - * API to setup an object or constructor to be able to emit data events. - * - * @example - * function Dog() { ...dog stuff... } - * mixInEventEmitter(Dog, {bark: true}); - * - * var puppy = new Dog(); - * puppy.addListener('bark', function (volume) { - * console.log('Puppy', this, 'barked at volume:', volume); - * }); - * puppy.emit('bark', 'quiet'); - * // Puppy barked at volume: quiet - * - * - * // A "singleton" object may also be commissioned: - * - * var Singleton = {}; - * mixInEventEmitter(Singleton, {lonely: true}); - * Singleton.emit('lonely', true); - */ -function mixInEventEmitter(klass, types) { - invariant(types, 'Must supply set of valid event types'); - invariant(!this.__eventEmitter, 'An active emitter is already mixed in'); - - // If this is a constructor, write to the prototype, otherwise write to the - // singleton object. - var target = klass.prototype || klass; - - var ctor = klass.constructor; - if (ctor) { - invariant( - ctor === Object || ctor === Function, - 'Mix EventEmitter into a class, not an instance' - ); - } - - // Keep track of the provided types, union the types if they already exist, - // which allows for prototype subclasses to provide more types. - if (target.hasOwnProperty(TYPES_KEY)) { - copyProperties(target.__types, types); - } else if (target.__types) { - target.__types = copyProperties({}, target.__types, types); - } else { - target.__types = types; - } - copyProperties(target, EventEmitterMixin); -} - -var EventEmitterMixin = { - emit: function(eventType, a, b, c, d, e, _) { - return this.__getEventEmitter().emit(eventType, a, b, c, d, e, _); - }, - - emitAndHold: function(eventType, a, b, c, d, e, _) { - return this.__getEventEmitter().emitAndHold(eventType, a, b, c, d, e, _); - }, - - addListener: function(eventType, listener, context) { - return this.__getEventEmitter().addListener(eventType, listener, context); - }, - - once: function(eventType, listener, context) { - return this.__getEventEmitter().once(eventType, listener, context); - }, - - addRetroactiveListener: function(eventType, listener, context) { - return this.__getEventEmitter().addRetroactiveListener( - eventType, - listener, - context - ); - }, - - addListenerMap: function(listenerMap, context) { - return this.__getEventEmitter().addListenerMap(listenerMap, context); - }, - - addRetroactiveListenerMap: function(listenerMap, context) { - return this.__getEventEmitter().addListenerMap(listenerMap, context); - }, - - removeAllListeners: function() { - this.__getEventEmitter().removeAllListeners(); - }, - - removeCurrentListener: function() { - this.__getEventEmitter().removeCurrentListener(); - }, - - releaseHeldEventType: function(eventType) { - this.__getEventEmitter().releaseHeldEventType(eventType); - }, - - __getEventEmitter: function() { - if (!this.__eventEmitter) { - var emitter = new EventEmitter(); - emitter = EventValidator.addValidation(emitter, this.__types); - - var holder = new EventHolder(); - this.__eventEmitter = new EventEmitterWithHolding(emitter, holder); - } - return this.__eventEmitter; - } -}; - -module.exports = mixInEventEmitter; -}); -__d('EventEmitterWithHolding',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * @generated SignedSource<> - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !! This file is a check-in of a static_upstream project! !! - * !! !! - * !! You should not modify this file directly. Instead: !! - * !! 1) Use `fjs use-upstream` to temporarily replace this with !! - * !! the latest version from upstream. !! - * !! 2) Make your changes, test them, etc. !! - * !! 3) Use `fjs push-upstream` to copy your changes back to !! - * !! static_upstream. !! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * @providesModule EventEmitterWithHolding - * @typechecks - */ -'use strict'; - -/** - * @class EventEmitterWithHolding - * @description - * An EventEmitterWithHolding decorates an event emitter and enables one to - * "hold" or cache events and then have a handler register later to actually - * handle them. - * - * This is separated into its own decorator so that only those who want to use - * the holding functionality have to and others can just use an emitter. Since - * it implements the emitter interface it can also be combined with anything - * that uses an emitter. - */ - - /** - * @constructor - * @param {object} emitter - The object responsible for emitting the actual - * events. - * @param {object} holder - The event holder that is responsible for holding - * and then emitting held events. - */ - function EventEmitterWithHolding(emitter, holder) { - this.$EventEmitterWithHolding_emitter = emitter; - this.$EventEmitterWithHolding_eventHolder = holder; - this.$EventEmitterWithHolding_currentEventToken = null; - this.$EventEmitterWithHolding_emittingHeldEvents = false; - } - - /** - * @see EventEmitter#addListener - */ - EventEmitterWithHolding.prototype.addListener=function(eventType , listener, context ) { - return this.$EventEmitterWithHolding_emitter.addListener(eventType, listener, context); - }; - - /** - * @see EventEmitter#once - */ - EventEmitterWithHolding.prototype.once=function(eventType , listener, context ) { - return this.$EventEmitterWithHolding_emitter.once(eventType, listener, context); - }; - - /** - * Adds a listener to be invoked when events of the specified type are - * emitted. An optional calling context may be provided. The data arguments - * emitted will be passed to the listener function. In addition to subscribing - * to all subsequent events, this method will also handle any events that have - * already been emitted, held, and not released. - * - * @param {string} eventType - Name of the event to listen to - * @param {function} listener - Function to invoke when the specified event is - * emitted - * @param {*} context - Optional context object to use when invoking the - * listener - * - * @example - * emitter.emitAndHold('someEvent', 'abc'); - * - * emitter.addRetroactiveListener('someEvent', function(message) { - * console.log(message); - * }); // logs 'abc' - */ - EventEmitterWithHolding.prototype.addRetroactiveListener=function( -eventType , listener, context ) { - var subscription = this.$EventEmitterWithHolding_emitter.addListener(eventType, listener, context); - - this.$EventEmitterWithHolding_emittingHeldEvents = true; - this.$EventEmitterWithHolding_eventHolder.emitToListener(eventType, listener, context); - this.$EventEmitterWithHolding_emittingHeldEvents = false; - - return subscription; - }; - - /** - * @see EventEmitter#removeAllListeners - */ - EventEmitterWithHolding.prototype.removeAllListeners=function(eventType ) { - this.$EventEmitterWithHolding_emitter.removeAllListeners(eventType); - }; - - /** - * @see EventEmitter#removeCurrentListener - */ - EventEmitterWithHolding.prototype.removeCurrentListener=function() { - this.$EventEmitterWithHolding_emitter.removeCurrentListener(); - }; - - /** - * @see EventEmitter#listeners - */ - EventEmitterWithHolding.prototype.listeners=function(eventType ) /* TODO: Annotate return type here */ { - return this.$EventEmitterWithHolding_emitter.listeners(eventType); - }; - - /** - * @see EventEmitter#emit - */ - EventEmitterWithHolding.prototype.emit=function(eventType , a, b, c, d, e, $EventEmitterWithHolding_) { - this.$EventEmitterWithHolding_emitter.emit(eventType, a, b, c, d, e, $EventEmitterWithHolding_); - }; - - /** - * Emits an event of the given type with the given data, and holds that event - * in order to be able to dispatch it to a later subscriber when they say they - * want to handle held events. - * - * @param {string} eventType - Name of the event to emit - * @param {...*} Arbitrary arguments to be passed to each registered listener - * - * @example - * emitter.emitAndHold('someEvent', 'abc'); - * - * emitter.addRetroactiveListener('someEvent', function(message) { - * console.log(message); - * }); // logs 'abc' - */ - EventEmitterWithHolding.prototype.emitAndHold=function(eventType , a, b, c, d, e, $EventEmitterWithHolding_) { - this.$EventEmitterWithHolding_currentEventToken = this.$EventEmitterWithHolding_eventHolder.holdEvent( - eventType, - a, b, c, d, e, $EventEmitterWithHolding_ - ); - this.$EventEmitterWithHolding_emitter.emit(eventType, a, b, c, d, e, $EventEmitterWithHolding_); - this.$EventEmitterWithHolding_currentEventToken = null; - }; - - /** - * @see EventHolder#releaseCurrentEvent - */ - EventEmitterWithHolding.prototype.releaseCurrentEvent=function() { - if (this.$EventEmitterWithHolding_currentEventToken !== null) { - this.$EventEmitterWithHolding_eventHolder.releaseEvent(this.$EventEmitterWithHolding_currentEventToken); - } else if (this.$EventEmitterWithHolding_emittingHeldEvents) { - this.$EventEmitterWithHolding_eventHolder.releaseCurrentEvent(); - } - }; - - /** - * @see EventHolder#releaseEventType - * @param {string} eventType - */ - EventEmitterWithHolding.prototype.releaseHeldEventType=function(eventType ) { - this.$EventEmitterWithHolding_eventHolder.releaseEventType(eventType); - }; - - -module.exports = EventEmitterWithHolding; -}); -__d('EventHolder',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * @generated SignedSource<<0591836c443c735d24e61782320d3d16>> - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !! This file is a check-in of a static_upstream project! !! - * !! !! - * !! You should not modify this file directly. Instead: !! - * !! 1) Use `fjs use-upstream` to temporarily replace this with !! - * !! the latest version from upstream. !! - * !! 2) Make your changes, test them, etc. !! - * !! 3) Use `fjs push-upstream` to copy your changes back to !! - * !! static_upstream. !! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * @providesModule EventHolder - * @typechecks - */ -'use strict'; - -var invariant = require('invariant'); - - - function EventHolder() { - this.$EventHolder_heldEvents = {}; - this.$EventHolder_currentEventKey = null; - } - - /** - * Holds a given event for processing later. - * - * TODO: Annotate return type better. The structural type of the return here - * is pretty obvious. - * - * @param {string} eventType - Name of the event to hold and later emit - * @param {...*} Arbitrary arguments to be passed to each registered listener - * @return {object} Token that can be used to release the held event - * - * @example - * - * holder.holdEvent({someEvent: 'abc'}); - * - * holder.emitToHandler({ - * someEvent: function(data, event) { - * console.log(data); - * } - * }); //logs 'abc' - * - */ - EventHolder.prototype.holdEvent=function(eventType , a, b, c, d, e, $EventHolder_) { - this.$EventHolder_heldEvents[eventType] = this.$EventHolder_heldEvents[eventType] || []; - var eventsOfType = this.$EventHolder_heldEvents[eventType]; - var key = { - eventType: eventType, - index: eventsOfType.length - }; - eventsOfType.push([a, b, c, d, e, $EventHolder_]); - return key; - }; - - /** - * Emits the held events of the specified type to the given listener. - * - * @param {?string} eventType - Optional name of the events to replay - * @param {function} listener - The listener to which to dispatch the event - * @param {?object} context - Optional context object to use when invoking - * the listener - */ - EventHolder.prototype.emitToListener=function(eventType , listener, context ) { - var eventsOfType = this.$EventHolder_heldEvents[eventType]; - if (!eventsOfType) { - return; - } - var origEventKey = this.$EventHolder_currentEventKey; - eventsOfType.forEach(function(/*?array*/ eventHeld, /*number*/ index) { - if (!eventHeld) { - return; - } - this.$EventHolder_currentEventKey = { - eventType: eventType, - index: index - }; - listener.apply(context, eventHeld); - }.bind(this)); - this.$EventHolder_currentEventKey = origEventKey; - }; - - /** - * Provides an API that can be called during an eventing cycle to release - * the last event that was invoked, so that it is no longer "held". - * - * If it is called when not inside of an emitting cycle it will throw. - * - * @throws {Error} When called not during an eventing cycle - */ - EventHolder.prototype.releaseCurrentEvent=function() { - invariant( - this.$EventHolder_currentEventKey !== null, - 'Not in an emitting cycle; there is no current event' - ); - this.releaseEvent(this.$EventHolder_currentEventKey); - }; - - /** - * Releases the event corresponding to the handle that was returned when the - * event was first held. - * - * @param {object} token - The token returned from holdEvent - */ - EventHolder.prototype.releaseEvent=function(token ) { - delete this.$EventHolder_heldEvents[token.eventType][token.index]; - }; - - /** - * Releases all events of a certain type. - * - * @param {string} type - */ - EventHolder.prototype.releaseEventType=function(type ) { - this.$EventHolder_heldEvents[type] = []; - }; - - -module.exports = EventHolder; -}); -__d('EventValidator',["copyProperties"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * @generated SignedSource<<7149bdac6fb48595f245ad6e76938e44>> - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !! This file is a check-in of a static_upstream project! !! - * !! !! - * !! You should not modify this file directly. Instead: !! - * !! 1) Use `fjs use-upstream` to temporarily replace this with !! - * !! the latest version from upstream. !! - * !! 2) Make your changes, test them, etc. !! - * !! 3) Use `fjs push-upstream` to copy your changes back to !! - * !! static_upstream. !! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * @providesModule EventValidator - */ -'use strict'; - -var copyProperties = require('copyProperties'); - -/** - * EventValidator is designed to validate event types to make it easier to catch - * common mistakes. It accepts a map of all of the different types of events - * that the emitter can emit. Then, if a user attempts to emit an event that is - * not one of those specified types the emitter will throw an error. Also, it - * provides a relatively simple matcher so that if it thinks that you likely - * mistyped the event name it will suggest what you might have meant to type in - * the error message. - */ -var EventValidator = { - /** - * @param {Object} emitter - The object responsible for emitting the actual - * events - * @param {Object} types - The collection of valid types that will be used to - * check for errors - * @return {Object} A new emitter with event type validation - * @example - * var types = {someEvent: true, anotherEvent: true}; - * var emitter = EventValidator.addValidation(emitter, types); - */ - addValidation: function(emitter , types ) { - var eventTypes = Object.keys(types); - var emitterWithValidation = Object.create(emitter); - - copyProperties(emitterWithValidation, { - emit: function emit(type, a, b, c, d, e, _) { - assertAllowsEventType(type, eventTypes); - return emitter.emit.call(this, type, a, b, c, d, e, _); - } - }); - - return emitterWithValidation; - } -}; - -function assertAllowsEventType(type, allowedTypes) { - if (allowedTypes.indexOf(type) === -1) { - throw new TypeError(errorMessageFor(type, allowedTypes)); - } -} - -function errorMessageFor(type, allowedTypes) { - var message = 'Unknown event type "' + type + '". '; - if (__DEV__) { - message += recommendationFor(type, allowedTypes); - } - message += 'Known event types: ' + allowedTypes.join(', ') + '.'; - return message; -} - -// Allow for good error messages -if (__DEV__) { - var recommendationFor = function (type, allowedTypes) { - var closestTypeRecommendation = closestTypeFor(type, allowedTypes); - if (isCloseEnough(closestTypeRecommendation, type)) { - return 'Did you mean "' + closestTypeRecommendation.type + '"? '; - } else { - return ''; - } - }; - - var closestTypeFor = function (type, allowedTypes) { - var typeRecommendations = allowedTypes.map( - typeRecommendationFor.bind(this, type) - ); - return typeRecommendations.sort(recommendationSort)[0]; - }; - - var typeRecommendationFor = function (type, recomendedType) { - return { - type: recomendedType, - distance: damerauLevenshteinDistance(type, recomendedType) - }; - }; - - var recommendationSort = function (recommendationA, recommendationB) { - if (recommendationA.distance < recommendationB.distance) { - return -1; - } else if (recommendationA.distance > recommendationB.distance) { - return 1; - } else { - return 0; - } - }; - - var isCloseEnough = function (closestType, actualType) { - return (closestType.distance / actualType.length) < 0.334; - }; - - var damerauLevenshteinDistance = function (a, b) { - var i, j; - var d = []; - - for (i = 0; i <= a.length; i++) { - d[i] = [i]; - } - - for (j = 1; j <= b.length; j++) { - d[0][j] = j; - } - - for (i = 1; i <= a.length; i++) { - for (j = 1; j <= b.length; j++) { - var cost = a.charAt(i - 1) === b.charAt(j - 1) ? 0 : 1; - - d[i][j] = Math.min( - d[i - 1][j] + 1, - d[i][j - 1] + 1, - d[i - 1][j - 1] + cost - ); - - if (i > 1 && j > 1 && - a.charAt(i - 1) == b.charAt(j - 2) && - a.charAt(i - 2) == b.charAt(j - 1)) { - d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + cost); - } - } - } - - return d[a.length][b.length]; - }; -} - -module.exports = EventValidator; -}); -__d('copyProperties',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * @generated SignedSource<> - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !! This file is a check-in of a static_upstream project! !! - * !! !! - * !! You should not modify this file directly. Instead: !! - * !! 1) Use `fjs use-upstream` to temporarily replace this with !! - * !! the latest version from upstream. !! - * !! 2) Make your changes, test them, etc. !! - * !! 3) Use `fjs push-upstream` to copy your changes back to !! - * !! static_upstream. !! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * @providesModule copyProperties - */ - -/** - * Copy properties from one or more objects (up to 5) into the first object. - * This is a shallow copy. It mutates the first object and also returns it. - * - * NOTE: `arguments` has a very significant performance penalty, which is why - * we don't support unlimited arguments. - */ -function copyProperties(obj, a, b, c, d, e, f) { - obj = obj || {}; - - if (__DEV__) { - if (f) { - throw new Error('Too many arguments passed to copyProperties'); - } - } - - var args = [a, b, c, d, e]; - var ii = 0, v; - while (args[ii]) { - v = args[ii++]; - for (var k in v) { - obj[k] = v[k]; - } - - // IE ignores toString in object iteration.. See: - // webreflection.blogspot.com/2007/07/quick-fix-internet-explorer-and.html - if (v.hasOwnProperty && v.hasOwnProperty('toString') && - (typeof v.toString != 'undefined') && (obj.toString !== v.toString)) { - obj.toString = v.toString; - } - } - - return obj; -} - -module.exports = copyProperties; -}); -__d('TouchableWithoutFeedback',["React","Touchable","onlyChild"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 TouchableWithoutFeedback - * @flow - */ -'use strict'; - -var React = require('React'); -var Touchable = require('Touchable'); -var onlyChild = require('onlyChild'); - -/** - * 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 - * moving it back and you'll see that the button is once again reactivated! - * Move it back and forth several times while the scroll view is disabled. - */ -var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; - - - -/** - * 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 - * one of the primary reason a "web" app doesn't feel "native". - */ -var TouchableWithoutFeedback = React.createClass({displayName: "TouchableWithoutFeedback", - mixins: [Touchable.Mixin], - - propTypes: { - /** - * Called when the touch is released, but not if cancelled (e.g. by a scroll - * that steals the responder lock). - */ - onPress: React.PropTypes.func, - onPressIn: React.PropTypes.func, - onPressOut: React.PropTypes.func, - onLongPress: React.PropTypes.func, - }, - - getInitialState: function() { - return this.touchableGetInitialState(); - }, - - /** - * `Touchable.Mixin` self callbacks. The mixin will invoke these if they are - * defined on your component. - */ - touchableHandlePress: function(e ) { - this.props.onPress && this.props.onPress(e); - }, - - touchableHandleActivePressIn: function() { - this.props.onPressIn && this.props.onPressIn(); - }, - - touchableHandleActivePressOut: function() { - this.props.onPressOut && this.props.onPressOut(); - }, - - touchableHandleLongPress: function() { - this.props.onLongPress && this.props.onLongPress(); - }, - - touchableGetPressRectOffset: function() { - return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant! - }, - - touchableGetHighlightDelayMS: function() { - return 0; - }, - - render: function() { - // Note(avik): remove dynamic typecast once Flow has been upgraded - return (React ).cloneElement(onlyChild(this.props.children), { - accessible: true, - testID: this.props.testID, - onStartShouldSetResponder: this.touchableHandleStartShouldSetResponder, - onResponderTerminationRequest: this.touchableHandleResponderTerminationRequest, - onResponderGrant: this.touchableHandleResponderGrant, - onResponderMove: this.touchableHandleResponderMove, - onResponderRelease: this.touchableHandleResponderRelease, - onResponderTerminate: this.touchableHandleResponderTerminate - }); - } -}); - -module.exports = TouchableWithoutFeedback; -}); -__d('TouchableHighlight',["NativeMethodsMixin","React","ReactNativeViewAttributes","StyleSheet","react-timer-mixin/TimerMixin","Touchable","TouchableWithoutFeedback","View","cloneWithProps","ensureComponentIsNative","keyOf","merge","onlyChild"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 TouchableHighlight - */ -'use strict'; - -// Note (avik): add @flow when Flow supports spread properties in propTypes - -var NativeMethodsMixin = require('NativeMethodsMixin'); -var React = require('React'); -var ReactNativeViewAttributes = require('ReactNativeViewAttributes'); -var StyleSheet = require('StyleSheet'); -var TimerMixin = require('react-timer-mixin/TimerMixin'); -var Touchable = require('Touchable'); -var TouchableWithoutFeedback = require('TouchableWithoutFeedback'); -var View = require('View'); - -var cloneWithProps = require('cloneWithProps'); -var ensureComponentIsNative = require('ensureComponentIsNative'); -var keyOf = require('keyOf'); -var merge = require('merge'); -var onlyChild = require('onlyChild'); - -var DEFAULT_PROPS = { - activeOpacity: 0.8, - underlayColor: 'black', -}; - -/** - * A wrapper for making views respond properly to touches. - * On press down, the opacity of the wrapped view is decreased, which allows - * the underlay color to show through, darkening or tinting the view. The - * underlay comes from adding a view to the view hierarchy, which can sometimes - * cause unwanted visual artifacts if not used correctly, for example if the - * backgroundColor of the wrapped view isn't explicitly set to an opaque color. - * - * Example: - * - * ``` - * renderButton: function() { - * return ( - * - * - * - * ); - * }, - * ``` - */ - -var TouchableHighlight = React.createClass({displayName: "TouchableHighlight", - propTypes: Object.assign({}, - TouchableWithoutFeedback.propTypes, - /** - * Determines what the opacity of the wrapped view should be when touch is - * active. - */ - {activeOpacity: React.PropTypes.number, - /** - * The color of the underlay that will show through when the touch is - * active. - */ - underlayColor: React.PropTypes.string, - style: View.propTypes.style - }), - - mixins: [NativeMethodsMixin, TimerMixin, Touchable.Mixin], - - getDefaultProps: function() {return DEFAULT_PROPS;}, - - // Performance optimization to avoid constantly re-generating these objects. - computeSyntheticState: function(props) { - return { - activeProps: { - style: { - opacity: props.activeOpacity, - } - }, - activeUnderlayProps: { - style: { - backgroundColor: props.underlayColor, - } - }, - underlayStyle: [ - INACTIVE_UNDERLAY_PROPS.style, - props.style, - ] - }; - }, - - getInitialState: function() { - return merge( - this.touchableGetInitialState(), this.computeSyntheticState(this.props) - ); - }, - - componentDidMount: function() { - ensureComponentIsNative(this.refs[CHILD_REF]); - }, - - componentDidUpdate: function() { - ensureComponentIsNative(this.refs[CHILD_REF]); - }, - - componentWillReceiveProps: function(nextProps) { - if (nextProps.activeOpacity !== this.props.activeOpacity || - nextProps.underlayColor !== this.props.underlayColor || - nextProps.style !== this.props.style) { - this.setState(this.computeSyntheticState(nextProps)); - } - }, - - viewConfig: { - uiViewClassName: 'RCTView', - validAttributes: ReactNativeViewAttributes.RCTView - }, - - /** - * `Touchable.Mixin` self callbacks. The mixin will invoke these if they are - * defined on your component. - */ - touchableHandleActivePressIn: function() { - this.clearTimeout(this._hideTimeout); - this._hideTimeout = null; - this._showUnderlay(); - this.props.onPressIn && this.props.onPressIn(); - }, - - touchableHandleActivePressOut: function() { - if (!this._hideTimeout) { - this._hideUnderlay(); - } - this.props.onPressOut && this.props.onPressOut(); - }, - - touchableHandlePress: function() { - this.clearTimeout(this._hideTimeout); - this._showUnderlay(); - this._hideTimeout = this.setTimeout(this._hideUnderlay, 100); - this.props.onPress && this.props.onPress(); - }, - - touchableHandleLongPress: function() { - this.props.onLongPress && this.props.onLongPress(); - }, - - touchableGetPressRectOffset: function() { - return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant! - }, - - _showUnderlay: function() { - this.refs[UNDERLAY_REF].setNativeProps(this.state.activeUnderlayProps); - this.refs[CHILD_REF].setNativeProps(this.state.activeProps); - }, - - _hideUnderlay: function() { - this.clearTimeout(this._hideTimeout); - this._hideTimeout = null; - if (this.refs[UNDERLAY_REF]) { - this.refs[CHILD_REF].setNativeProps(INACTIVE_CHILD_PROPS); - this.refs[UNDERLAY_REF].setNativeProps(Object.assign({}, - INACTIVE_UNDERLAY_PROPS, - {style: this.state.underlayStyle - })); - } - }, - - render: function() { - return ( - React.createElement(View, { - ref: UNDERLAY_REF, - style: this.state.underlayStyle, - onStartShouldSetResponder: this.touchableHandleStartShouldSetResponder, - onResponderTerminationRequest: this.touchableHandleResponderTerminationRequest, - onResponderGrant: this.touchableHandleResponderGrant, - onResponderMove: this.touchableHandleResponderMove, - onResponderRelease: this.touchableHandleResponderRelease, - onResponderTerminate: this.touchableHandleResponderTerminate}, - cloneWithProps( - onlyChild(this.props.children), - { - ref: CHILD_REF, - accessible: true, - testID: this.props.testID, - } - ) - ) - ); - } -}); - -var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; -var CHILD_REF = keyOf({childRef: null}); -var UNDERLAY_REF = keyOf({underlayRef: null}); -var INACTIVE_CHILD_PROPS = { - style: StyleSheet.create({x: {opacity: 1.0}}).x, -}; -var INACTIVE_UNDERLAY_PROPS = { - style: StyleSheet.create({x: {backgroundColor: 'transparent'}}).x, -}; - -module.exports = TouchableHighlight; -}); -__d('cloneWithProps',["ReactElement","ReactPropTransferer","keyOf","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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. - * - * @typechecks static-only - * @providesModule cloneWithProps - */ - -'use strict'; - -var ReactElement = require('ReactElement'); -var ReactPropTransferer = require('ReactPropTransferer'); - -var keyOf = require('keyOf'); -var warning = require('warning'); - -var CHILDREN_PROP = keyOf({children: null}); - -/** - * Sometimes you want to change the props of a child passed to you. Usually - * this is to add a CSS class. - * - * @param {ReactElement} child child element you'd like to clone - * @param {object} props props you'd like to modify. className and style will be - * merged automatically. - * @return {ReactElement} a clone of child with props merged in. - */ -function cloneWithProps(child, props) { - if (__DEV__) { - warning( - !child.ref, - 'You are calling cloneWithProps() on a child with a ref. This is ' + - 'dangerous because you\'re creating a new child which will not be ' + - 'added as a ref to its parent.' - ); - } - - var newProps = ReactPropTransferer.mergeProps(props, child.props); - - // Use `child.props.children` if it is provided. - if (!newProps.hasOwnProperty(CHILDREN_PROP) && - child.props.hasOwnProperty(CHILDREN_PROP)) { - newProps.children = child.props.children; - } - - // The current API doesn't retain _owner and _context, which is why this - // doesn't use ReactElement.cloneAndReplaceProps. - return ReactElement.createElement(child.type, newProps); -} - -module.exports = cloneWithProps; -}); -__d('ReactPropTransferer',["Object.assign","emptyFunction","joinClasses"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactPropTransferer - */ - -'use strict'; - -var assign = require('Object.assign'); -var emptyFunction = require('emptyFunction'); -var joinClasses = require('joinClasses'); - -/** - * Creates a transfer strategy that will merge prop values using the supplied - * `mergeStrategy`. If a prop was previously unset, this just sets it. - * - * @param {function} mergeStrategy - * @return {function} - */ -function createTransferStrategy(mergeStrategy) { - return function(props, key, value) { - if (!props.hasOwnProperty(key)) { - props[key] = value; - } else { - props[key] = mergeStrategy(props[key], value); - } - }; -} - -var transferStrategyMerge = createTransferStrategy(function(a, b) { - // `merge` overrides the first object's (`props[key]` above) keys using the - // second object's (`value`) keys. An object's style's existing `propA` would - // get overridden. Flip the order here. - return assign({}, b, a); -}); - -/** - * Transfer strategies dictate how props are transferred by `transferPropsTo`. - * NOTE: if you add any more exceptions to this list you should be sure to - * update `cloneWithProps()` accordingly. - */ -var TransferStrategies = { - /** - * Never transfer `children`. - */ - children: emptyFunction, - /** - * Transfer the `className` prop by merging them. - */ - className: createTransferStrategy(joinClasses), - /** - * Transfer the `style` prop (which is an object) by merging them. - */ - style: transferStrategyMerge -}; - -/** - * Mutates the first argument by transferring the properties from the second - * argument. - * - * @param {object} props - * @param {object} newProps - * @return {object} - */ -function transferInto(props, newProps) { - for (var thisKey in newProps) { - if (!newProps.hasOwnProperty(thisKey)) { - continue; - } - - var transferStrategy = TransferStrategies[thisKey]; - - if (transferStrategy && TransferStrategies.hasOwnProperty(thisKey)) { - transferStrategy(props, thisKey, newProps[thisKey]); - } else if (!props.hasOwnProperty(thisKey)) { - props[thisKey] = newProps[thisKey]; - } - } - return props; -} - -/** - * ReactPropTransferer are capable of transferring props to another component - * using a `transferPropsTo` method. - * - * @class ReactPropTransferer - */ -var ReactPropTransferer = { - - /** - * Merge two props objects using TransferStrategies. - * - * @param {object} oldProps original props (they take precedence) - * @param {object} newProps new props to merge in - * @return {object} a new object containing both sets of props merged. - */ - mergeProps: function(oldProps, newProps) { - return transferInto(assign({}, oldProps), newProps); - } - -}; - -module.exports = ReactPropTransferer; -}); -__d('joinClasses',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 joinClasses - * @typechecks static-only - */ - -'use strict'; - -/** - * Combines multiple className strings into one. - * http://jsperf.com/joinclasses-args-vs-array - * - * @param {...?string} classes - * @return {string} - */ -function joinClasses(className/* ... */) { - if (!className) { - className = ''; - } - var nextClass; - var argLength = arguments.length; - if (argLength > 1) { - for (var ii = 1; ii < argLength; ii++) { - nextClass = arguments[ii]; - if (nextClass) { - className = (className ? className + ' ' : '') + nextClass; - } - } - } - return className; -} - -module.exports = joinClasses; -}); -__d('ensureComponentIsNative',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 ensureComponentIsNative - * @flow - */ -'use strict'; - -var invariant = require('invariant'); - -var ensureComponentIsNative = function(component ) { - invariant( - component && typeof component.setNativeProps === 'function', - 'Touchable child must either be native or forward setNativeProps to a ' + - 'native component' - ); -}; - -module.exports = ensureComponentIsNative; -}); -__d('TouchableOpacity',["NativeMethodsMixin","POPAnimationMixin","React","Touchable","TouchableWithoutFeedback","cloneWithProps","ensureComponentIsNative","flattenStyle","keyOf","onlyChild"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 TouchableOpacity - */ -'use strict'; - -// Note (avik): add @flow when Flow supports spread properties in propTypes - -var NativeMethodsMixin = require('NativeMethodsMixin'); -var POPAnimationMixin = require('POPAnimationMixin'); -var React = require('React'); -var Touchable = require('Touchable'); -var TouchableWithoutFeedback = require('TouchableWithoutFeedback'); - -var cloneWithProps = require('cloneWithProps'); -var ensureComponentIsNative = require('ensureComponentIsNative'); -var flattenStyle = require('flattenStyle'); -var keyOf = require('keyOf'); -var onlyChild = require('onlyChild'); - -/** - * A wrapper for making views respond properly to touches. - * On press down, the opacity of the wrapped view is decreased, dimming it. - * This is done without actually changing the view hierarchy, and in general is - * easy to add to an app without weird side-effects. - * - * Example: - * - * ``` - * renderButton: function() { - * return ( - * - * - * - * ); - * }, - * ``` - */ - -var TouchableOpacity = React.createClass({displayName: "TouchableOpacity", - mixins: [Touchable.Mixin, NativeMethodsMixin, POPAnimationMixin], - - propTypes: Object.assign({}, - TouchableWithoutFeedback.propTypes, - /** - * Determines what the opacity of the wrapped view should be when touch is - * active. - */ - {activeOpacity: React.PropTypes.number - }), - - getDefaultProps: function() { - return { - activeOpacity: 0.2, - }; - }, - - getInitialState: function() { - return this.touchableGetInitialState(); - }, - - componentDidMount: function() { - ensureComponentIsNative(this.refs[CHILD_REF]); - }, - - componentDidUpdate: function() { - ensureComponentIsNative(this.refs[CHILD_REF]); - }, - - setOpacityTo: function(value) { - if (POPAnimationMixin) { - // Reset with animation if POP is available - this.stopAllAnimations(); - var anim = { - type: this.AnimationTypes.linear, - property: this.AnimationProperties.opacity, - toValue: value, - }; - this.startAnimation(CHILD_REF, anim); - } else { - // Reset immediately if POP is unavailable - this.refs[CHILD_REF].setNativeProps({ - opacity: value - }); - } - }, - - /** - * `Touchable.Mixin` self callbacks. The mixin will invoke these if they are - * defined on your component. - */ - touchableHandleActivePressIn: function() { - this.refs[CHILD_REF].setNativeProps({ - opacity: this.props.activeOpacity - }); - this.props.onPressIn && this.props.onPressIn(); - }, - - touchableHandleActivePressOut: function() { - var child = onlyChild(this.props.children); - var childStyle = flattenStyle(child.props.style) || {}; - this.setOpacityTo(childStyle.opacity === undefined ? 1 : childStyle.opacity); - this.props.onPressOut && this.props.onPressOut(); - }, - - touchableHandlePress: function() { - this.props.onPress && this.props.onPress(); - }, - - touchableHandleLongPress: function() { - this.props.onLongPress && this.props.onLongPress(); - }, - - touchableGetPressRectOffset: function() { - return PRESS_RECT_OFFSET; // Always make sure to predeclare a constant! - }, - - touchableGetHighlightDelayMS: function() { - return 0; - }, - - render: function() { - return cloneWithProps(onlyChild(this.props.children), { - ref: CHILD_REF, - accessible: true, - testID: this.props.testID, - onStartShouldSetResponder: this.touchableHandleStartShouldSetResponder, - onResponderTerminationRequest: this.touchableHandleResponderTerminationRequest, - onResponderGrant: this.touchableHandleResponderGrant, - onResponderMove: this.touchableHandleResponderMove, - onResponderRelease: this.touchableHandleResponderRelease, - onResponderTerminate: this.touchableHandleResponderTerminate, - }); - }, -}); - -/** - * 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 - * moving it back and you'll see that the button is once again reactivated! - * Move it back and forth several times while the scroll view is disabled. - */ -var PRESS_RECT_OFFSET = {top: 20, left: 20, right: 20, bottom: 30}; - -var CHILD_REF = keyOf({childRef: null}); - -module.exports = TouchableOpacity; -}); -__d('POPAnimationMixin',["POPAnimation","React","invariant","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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() { - return { - _currentAnimationsByNodeHandle: {}, - }; - }, - - _ensureBookkeepingSetup: function(nodeHandle ) { - 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 , - anim , - doneCallback - ) { - var animID = 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 , - animID , - doneCallback - ) { - this._ensureBookkeepingSetup(nodeHandle); - var animations = this.state._currentAnimationsByNodeHandle[nodeHandle]; - var animIndex = animations.length; - animations.push(animID); - var cleanupWrapper = function(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); - }.bind(this); - POPAnimation.addAnimation(nodeHandle, animID, cleanupWrapper); - }, - - /** - * 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 , - onSuccess , - onFailure - ) { - var numReturned = 0; - var numFinished = 0; - var numAnimations = animations.length; - var metaCallback = function(finished) { - if (finished) { - ++numFinished; - } - if (++numReturned === numAnimations) { - onSuccess && onSuccess(numFinished === numAnimations); - } - }; - animations.forEach(function(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); - } - }.bind(this)); - }, - - /** - * 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 ) { - 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 ) { - 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 , - frame , - type , - velocity , - doneCallback - ) { - 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(); - } -}; - -module.exports = POPAnimationMixin; - -} -}); -__d('POPAnimation',["NativeModules","ReactPropTypes","createStrictShapeTypeChecker","getObjectValues","invariant","merge"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 - * @flow - */ -'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, -}; - - - - - - - - - - - - - - - -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() { - return ++this.lastUsedTag; - }, - - createAnimation: function(typeName , attrs ) { - var tag = this.allocateTagForAnimation(); - - if (__DEV__) { - POPAnimation.attributeChecker( - {attrs:attrs}, - 'attrs', - 'POPAnimation.createAnimation' - ); - POPAnimation.attributeChecker( - {attrs: {type: typeName}}, - 'attrs', - 'POPAnimation.createAnimation' - ); - } - - RCTPOPAnimationManager.createAnimationInternal(tag, typeName, attrs); - return tag; - }, - - createSpringAnimation: function(attrs ) { - return this.createAnimation(this.Types.spring, attrs); - }, - - createDecayAnimation: function(attrs ) { - return this.createAnimation(this.Types.decay, attrs); - }, - - createLinearAnimation: function(attrs ) { - return this.createAnimation(this.Types.linear, attrs); - }, - - createEaseInAnimation: function(attrs ) { - return this.createAnimation(this.Types.easeIn, attrs); - }, - - createEaseOutAnimation: function(attrs ) { - return this.createAnimation(this.Types.easeOut, attrs); - }, - - createEaseInEaseOutAnimation: function(attrs ) { - return this.createAnimation(this.Types.easeInEaseOut, attrs); - }, - - addAnimation: function(nodeHandle , anim , callback ) { - RCTPOPAnimationManager.addAnimation(nodeHandle, anim, callback); - }, - - removeAnimation: function(nodeHandle , anim ) { - 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; - -} -}); -__d('getObjectValues',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * @generated SignedSource<> - * - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * !! This file is a check-in of a static_upstream project! !! - * !! !! - * !! You should not modify this file directly. Instead: !! - * !! 1) Use `fjs use-upstream` to temporarily replace this with !! - * !! the latest version from upstream. !! - * !! 2) Make your changes, test them, etc. !! - * !! 3) Use `fjs push-upstream` to copy your changes back to !! - * !! static_upstream. !! - * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - * - * @providesModule getObjectValues - * @typechecks - */ - -/** - * Retrieve an object's values as an array. - * - * If you are looking for a function that creates an Array instance based - * on an "Array-like" object, use createArrayFrom instead. - * - * @param {object} obj An object. - * @return {array} The object's values. - */ -function getObjectValues(obj) { - var values = []; - for (var key in obj) { - values.push(obj[key]); - } - return values; -} - -module.exports = getObjectValues; -}); -__d('WebView',["ActivityIndicatorIOS","EdgeInsetsPropType","React","StyleSheet","Text","View","invariant","keyMirror","requireNativeComponent","NativeModules"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 WebView - * @flow - */ -'use strict'; - -var ActivityIndicatorIOS = require('ActivityIndicatorIOS'); -var EdgeInsetsPropType = require('EdgeInsetsPropType'); -var React = require('React'); -var StyleSheet = require('StyleSheet'); -var Text = require('Text'); -var View = require('View'); - -var invariant = require('invariant'); -var keyMirror = require('keyMirror'); -var requireNativeComponent = require('requireNativeComponent'); - -var PropTypes = React.PropTypes; -var RCTWebViewManager = require('NativeModules').WebViewManager; - -var BGWASH = 'rgba(255,255,255,0.8)'; -var RCT_WEBVIEW_REF = 'webview'; - -var WebViewState = keyMirror({ - IDLE: null, - LOADING: null, - ERROR: null, -}); - -var NavigationType = { - click: RCTWebViewManager.NavigationType.LinkClicked, - formsubmit: RCTWebViewManager.NavigationType.FormSubmitted, - backforward: RCTWebViewManager.NavigationType.BackForward, - reload: RCTWebViewManager.NavigationType.Reload, - formresubmit: RCTWebViewManager.NavigationType.FormResubmitted, - other: RCTWebViewManager.NavigationType.Other, -}; - - - - - - - - - -var defaultRenderLoading = function() - {return React.createElement(View, {style: styles.loadingView}, - React.createElement(ActivityIndicatorIOS, null) - );} -; -var defaultRenderError = function(errorDomain, errorCode, errorDesc) - {return React.createElement(View, {style: styles.errorContainer}, - React.createElement(Text, {style: styles.errorTextTitle}, - "Error loading page" - ), - React.createElement(Text, {style: styles.errorText}, - 'Domain: ' + errorDomain - ), - React.createElement(Text, {style: styles.errorText}, - 'Error Code: ' + errorCode - ), - React.createElement(Text, {style: styles.errorText}, - 'Description: ' + errorDesc - ) - );} -; - -var WebView = React.createClass({displayName: "WebView", - statics: { - NavigationType: NavigationType, - }, - - propTypes: { - url: PropTypes.string, - html: PropTypes.string, - renderError: PropTypes.func, // view to show if there's an error - renderLoading: PropTypes.func, // loading indicator to show - bounces: PropTypes.bool, - scrollEnabled: PropTypes.bool, - automaticallyAdjustContentInsets: PropTypes.bool, - shouldInjectAJAXHandler: PropTypes.bool, - contentInset: EdgeInsetsPropType, - onNavigationStateChange: PropTypes.func, - startInLoadingState: PropTypes.bool, // force WebView to show loadingView on first load - style: View.propTypes.style, - /** - * Used for android only, JS is enabled by default for WebView on iOS - */ - javaScriptEnabledAndroid: PropTypes.bool, - }, - - getInitialState: function() { - return { - viewState: WebViewState.IDLE, - lastErrorEvent: (null ), - startInLoadingState: true, - }; - }, - - componentWillMount: function() { - if (this.props.startInLoadingState) { - this.setState({viewState: WebViewState.LOADING}); - } - }, - - render: function() { - var otherView = null; - - if (this.state.viewState === WebViewState.LOADING) { - otherView = (this.props.renderLoading || defaultRenderLoading)(); - } else if (this.state.viewState === WebViewState.ERROR) { - var errorEvent = this.state.lastErrorEvent; - invariant( - errorEvent != null, - 'lastErrorEvent expected to be non-null' - ); - otherView = (this.props.renderError || defaultRenderError)( - errorEvent.domain, - errorEvent.code, - errorEvent.description - ); - } else if (this.state.viewState !== WebViewState.IDLE) { - console.error( - 'RCTWebView invalid state encountered: ' + this.state.loading - ); - } - - var webViewStyles = [styles.container, styles.webView, this.props.style]; - if (this.state.viewState === WebViewState.LOADING || - this.state.viewState === WebViewState.ERROR) { - // if we're in either LOADING or ERROR states, don't show the webView - webViewStyles.push(styles.hidden); - } - - var webView = - React.createElement(RCTWebView, { - ref: RCT_WEBVIEW_REF, - key: "webViewKey", - style: webViewStyles, - url: this.props.url, - html: this.props.html, - bounces: this.props.bounces, - scrollEnabled: this.props.scrollEnabled, - shouldInjectAJAXHandler: this.props.shouldInjectAJAXHandler, - contentInset: this.props.contentInset, - automaticallyAdjustContentInsets: this.props.automaticallyAdjustContentInsets, - onLoadingStart: this.onLoadingStart, - onLoadingFinish: this.onLoadingFinish, - onLoadingError: this.onLoadingError} - ); - - return ( - React.createElement(View, {style: styles.container}, - webView, - otherView - ) - ); - }, - - goForward: function() { - RCTWebViewManager.goForward(this.getWebWiewHandle()); - }, - - goBack: function() { - RCTWebViewManager.goBack(this.getWebWiewHandle()); - }, - - reload: function() { - RCTWebViewManager.reload(this.getWebWiewHandle()); - }, - - /** - * We return an event with a bunch of fields including: - * url, title, loading, canGoBack, canGoForward - */ - updateNavigationState: function(event ) { - if (this.props.onNavigationStateChange) { - this.props.onNavigationStateChange(event.nativeEvent); - } - }, - - getWebWiewHandle: function() { - return React.findNodeHandle(this.refs[RCT_WEBVIEW_REF]); - }, - - onLoadingStart: function(event ) { - this.updateNavigationState(event); - }, - - onLoadingError: function(event ) { - event.persist(); // persist this event because we need to store it - console.error('Encountered an error loading page', event.nativeEvent); - - this.setState({ - lastErrorEvent: event.nativeEvent, - viewState: WebViewState.ERROR - }); - }, - - onLoadingFinish: function(event ) { - this.setState({ - viewState: WebViewState.IDLE, - }); - this.updateNavigationState(event); - }, -}); - -var RCTWebView = requireNativeComponent('RCTWebView', WebView); - -var styles = StyleSheet.create({ - container: { - flex: 1, - }, - errorContainer: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - backgroundColor: BGWASH, - }, - errorText: { - fontSize: 14, - textAlign: 'center', - marginBottom: 2, - }, - errorTextTitle: { - fontSize: 15, - fontWeight: '500', - marginBottom: 10, - }, - hidden: { - height: 0, - flex: 0, // disable 'flex:1' when hiding a View - }, - loadingView: { - backgroundColor: BGWASH, - flex: 1, - justifyContent: 'center', - alignItems: 'center', - }, - webView: { - backgroundColor: '#ffffff', - } -}); - -module.exports = WebView; -}); -__d('AlertIOS',["NativeModules","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 AlertIOS - * @flow - */ -'use strict'; - -var RCTAlertManager = require('NativeModules').AlertManager; -var invariant = require('invariant'); - -var DEFAULT_BUTTON_TEXT = 'OK'; -var DEFAULT_BUTTON = { - text: DEFAULT_BUTTON_TEXT, - onPress: null, -}; - -/** - * Launches an alert dialog with the specified title and message. - * - * Optionally provide a list of buttons. Tapping any button will fire the - * respective onPress callback and dismiss the alert. By default, the only - * button will be an 'OK' button - * - * The last button in the list will be considered the 'Primary' button and - * it will appear bold. - * - * ``` - * AlertIOS.alert( - * 'Foo Title', - * 'My Alert Msg', - * [ - * {text: 'Foo', onPress: () => console.log('Foo Pressed!')}, - * {text: 'Bar', onPress: () => console.log('Bar Pressed!')}, - * ] - * ) - * ``` - */ - -function AlertIOS(){} - AlertIOS.alert=function( -title , - message , - buttons - - - , - type - ) { - var callbacks = []; - var buttonsSpec = []; - title = title || ''; - message = message || ''; - buttons = buttons || [DEFAULT_BUTTON]; - type = type || ''; - - buttons.forEach(function(btn, index) { - callbacks[index] = btn.onPress; - var btnDef = {}; - btnDef[index] = btn.text || DEFAULT_BUTTON_TEXT; - buttonsSpec.push(btnDef); - }); - RCTAlertManager.alertWithArgs({ - title:title, - message:message, - buttons: buttonsSpec, - type:type, - }, function(id, value) { - var cb = callbacks[id]; - cb && cb(value); - }); - }; - - AlertIOS.prompt=function( -title , - value , - buttons - - - , - callback - ) { - if (arguments.length === 2) { - if (typeof value === 'object') { - buttons = value; - value = undefined; - } else if (typeof value === 'function') { - callback = value; - value = undefined; - } - } else if (arguments.length === 3 && typeof buttons === 'function') { - callback = buttons; - buttons = undefined; - } - - invariant( - !(callback && buttons) && (callback || buttons), - 'Must provide either a button list or a callback, but not both' - ); - - if (!buttons) { - buttons = [{ - text: 'Cancel', - }, { - text: 'OK', - onPress: callback - }]; - } - this.alert(title, value, buttons, 'plain-text'); - }; - - -module.exports = AlertIOS; -}); -__d('AppRegistry',["invariant","renderApplication","RCTRenderingPerf"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 AppRegistry - * @flow - */ -'use strict'; - -var invariant = require('invariant'); -var renderApplication = require('renderApplication'); - -if (__DEV__) { - // In order to use Cmd+P to record/dump perf data, we need to make sure - // this module is available in the bundle - require('RCTRenderingPerf'); -} - -var runnables = {}; - - - - - - - -/** - * `AppRegistry` is the JS entry point to running all React Native apps. App - * root components should register themselves with - * `AppRegistry.registerComponent`, then the native system can load the bundle - * for the app and then actually run the app when it's ready by invoking - * `AppRegistry.runApplication`. - * - * `AppRegistry` should be `require`d early in the `require` sequence to make - * sure the JS execution environment is setup before other modules are - * `require`d. - */ -var AppRegistry = { - registerConfig: function(config ) { - for (var i = 0; i < config.length; ++i) { - var appConfig = config[i]; - if (appConfig.run) { - AppRegistry.registerRunnable(appConfig.appKey, appConfig.run); - } else { - AppRegistry.registerComponent(appConfig.appKey, appConfig.component); - } - } - }, - - registerComponent: function(appKey , getComponentFunc ) { - runnables[appKey] = { - run: function(appParameters) - {return renderApplication(getComponentFunc(), appParameters.initialProps, appParameters.rootTag);} - }; - return appKey; - }, - - registerRunnable: function(appKey , func ) { - runnables[appKey] = {run: func}; - return appKey; - }, - - runApplication: function(appKey , appParameters ) { - console.log( - 'Running application "' + appKey + '" with appParams: ' + - JSON.stringify(appParameters) + '. ' + - '__DEV__ === ' + __DEV__ + - ', development-level warning are ' + (__DEV__ ? 'ON' : 'OFF') + - ', performance optimizations are ' + (__DEV__ ? 'OFF' : 'ON') - ); - invariant( - runnables[appKey] && runnables[appKey].run, - 'Application ' + appKey + ' has not been registered.' - ); - runnables[appKey].run(appParameters); - }, -}; - -module.exports = AppRegistry; -}); -__d('renderApplication',["React","StyleSheet","View","WarningBox","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 renderApplication - * @flow - */ -'use strict'; - -var React = require('React'); -var StyleSheet = require('StyleSheet'); -var View = require('View'); -var WarningBox = require('WarningBox'); - -var invariant = require('invariant'); - -function renderApplication ( - RootComponent , - initialProps , - rootTag -) { - invariant( - rootTag, - 'Expect to have a valid rootTag, instead got ', rootTag - ); - var shouldRenderWarningBox = __DEV__ && console.yellowBoxEnabled; - var warningBox = shouldRenderWarningBox ? React.createElement(WarningBox, null) : null; - React.render( - React.createElement(View, {style: styles.appContainer}, - React.createElement(RootComponent, React.__spread({}, - initialProps) - ), - warningBox - ), - rootTag - ); -} - -var styles = StyleSheet.create({ - appContainer: { - position: 'absolute', - left: 0, - top: 0, - right: 0, - bottom: 0, - }, -}); - -module.exports = renderApplication; -}); -__d('WarningBox',["AsyncStorage","EventEmitter","Map","PanResponder","React","StyleSheet","Text","TouchableOpacity","View","invariant","rebound/rebound","stringifySafe","Dimensions"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 WarningBox - */ -'use strict'; - -var AsyncStorage = require('AsyncStorage'); -var EventEmitter = require('EventEmitter'); -var Map = require('Map'); -var PanResponder = require('PanResponder'); -var React = require('React'); -var StyleSheet = require('StyleSheet'); -var Text = require('Text'); -var TouchableOpacity = require('TouchableOpacity'); -var View = require('View'); - -var invariant = require('invariant'); -var rebound = require('rebound/rebound'); -var stringifySafe = require('stringifySafe'); - -var SCREEN_WIDTH = require('Dimensions').get('window').width; -var IGNORED_WARNINGS_KEY = '__DEV_WARNINGS_IGNORED'; - -var consoleWarn = console.warn.bind(console); - -var warningCounts = new Map(); -var ignoredWarnings = []; -var totalWarningCount = 0; -var warningCountEvents = new EventEmitter(); - -/** - * WarningBox renders warnings on top of the app being developed. Warnings help - * guard against subtle yet significant issues that can impact the quality of - * your application, such as accessibility and memory leaks. This "in your - * face" style of warning allows developers to notice and correct these issues - * as quickly as possible. - * - * The warning box is currently opt-in. Set the following flag to enable it: - * - * `console.yellowBoxEnabled = true;` - * - * If "ignore" is tapped on a warning, the WarningBox will record that warning - * and will not display it again. This is useful for hiding errors that already - * exist or have been introduced elsewhere. To re-enable all of the errors, set - * the following: - * - * `console.yellowBoxResetIgnored = true;` - * - * This can also be set permanently, and ignore will only silence the warnings - * until the next refresh. - */ - -if (__DEV__) { - console.warn = function() { - consoleWarn.apply(null, arguments); - if (!console.yellowBoxEnabled) { - return; - } - var warning = Array.prototype.map.call(arguments, stringifySafe).join(' '); - if (!console.yellowBoxResetIgnored && - ignoredWarnings.indexOf(warning) !== -1) { - return; - } - var count = warningCounts.has(warning) ? warningCounts.get(warning) + 1 : 1; - warningCounts.set(warning, count); - totalWarningCount += 1; - warningCountEvents.emit('count', totalWarningCount); - }; -} - -function saveIgnoredWarnings() { - AsyncStorage.setItem( - IGNORED_WARNINGS_KEY, - JSON.stringify(ignoredWarnings), - function(err) { - if (err) { - console.warn('Could not save ignored warnings.', err); - } - } - ); -} - -AsyncStorage.getItem(IGNORED_WARNINGS_KEY, function(err, data) { - if (!err && data && !console.yellowBoxResetIgnored) { - ignoredWarnings = JSON.parse(data); - } -}); - -var WarningRow = React.createClass({displayName: "WarningRow", - componentWillMount: function() { - this.springSystem = new rebound.SpringSystem(); - this.dismissalSpring = this.springSystem.createSpring(); - this.dismissalSpring.setRestSpeedThreshold(0.05); - this.dismissalSpring.setCurrentValue(0); - this.dismissalSpring.addListener({ - onSpringUpdate: function() { - var val = this.dismissalSpring.getCurrentValue(); - this.text && this.text.setNativeProps({ - left: SCREEN_WIDTH * val, - }); - this.container && this.container.setNativeProps({ - opacity: 1 - val, - }); - this.closeButton && this.closeButton.setNativeProps({ - opacity: 1 - (val * 5), - }); - }.bind(this), - onSpringAtRest: function() { - if (this.dismissalSpring.getCurrentValue()) { - this.collapseSpring.setEndValue(1); - } - }.bind(this), - }); - this.collapseSpring = this.springSystem.createSpring(); - this.collapseSpring.setRestSpeedThreshold(0.05); - this.collapseSpring.setCurrentValue(0); - this.collapseSpring.getSpringConfig().friction = 20; - this.collapseSpring.getSpringConfig().tension = 200; - this.collapseSpring.addListener({ - onSpringUpdate: function() { - var val = this.collapseSpring.getCurrentValue(); - this.container && this.container.setNativeProps({ - height: Math.abs(46 - (val * 46)), - }); - }.bind(this), - onSpringAtRest: function() { - this.props.onDismissed(); - }.bind(this), - }); - this.panGesture = PanResponder.create({ - onStartShouldSetPanResponder: function() { - return !! this.dismissalSpring.getCurrentValue(); - }.bind(this), - onMoveShouldSetPanResponder: function() {return true;}, - onPanResponderGrant: function() { - this.isResponderOnlyToBlockTouches = - !! this.dismissalSpring.getCurrentValue(); - }.bind(this), - onPanResponderMove: function(e, gestureState) { - if (this.isResponderOnlyToBlockTouches) { - return; - } - this.dismissalSpring.setCurrentValue(gestureState.dx / SCREEN_WIDTH); - }.bind(this), - onPanResponderRelease: function(e, gestureState) { - if (this.isResponderOnlyToBlockTouches) { - return; - } - var gestureCompletion = gestureState.dx / SCREEN_WIDTH; - var doesGestureRelease = (gestureState.vx + gestureCompletion) > 0.5; - this.dismissalSpring.setEndValue(doesGestureRelease ? 1 : 0); - }.bind(this) - }); - }, - render: function() { - var countText; - if (warningCounts.get(this.props.warning) > 1) { - countText = ( - React.createElement(Text, {style: styles.bold}, - "(", warningCounts.get(this.props.warning), ")", " " - ) - ); - } - return ( - React.createElement(View, React.__spread({ - style: styles.warningBox, - ref: function(container) { this.container = container; }.bind(this)}, - this.panGesture.panHandlers), - React.createElement(TouchableOpacity, { - onPress: this.props.onOpened}, - React.createElement(View, null, - React.createElement(Text, { - style: styles.warningText, - numberOfLines: 2, - ref: function(text) { this.text = text; }.bind(this)}, - countText, - this.props.warning - ) - ) - ), - React.createElement(View, { - ref: function(closeButton) { this.closeButton = closeButton; }.bind(this), - style: styles.closeButton}, - React.createElement(TouchableOpacity, { - onPress: function() { - this.dismissalSpring.setEndValue(1); - }.bind(this)}, - React.createElement(Text, {style: styles.closeButtonText}, "✕") - ) - ) - ) - ); - } -}); - -var WarningBoxOpened = React.createClass({displayName: "WarningBoxOpened", - render: function() { - var countText; - if (warningCounts.get(this.props.warning) > 1) { - countText = ( - React.createElement(Text, {style: styles.bold}, - "(", warningCounts.get(this.props.warning), ")", " " - ) - ); - } - return ( - React.createElement(TouchableOpacity, { - activeOpacity: 0.9, - onPress: this.props.onClose}, - React.createElement(View, {style: styles.yellowBox}, - React.createElement(Text, {style: styles.yellowBoxText}, - countText, - this.props.warning - ), - React.createElement(View, {style: styles.yellowBoxButtons}, - React.createElement(View, {style: styles.yellowBoxButton}, - React.createElement(TouchableOpacity, { - onPress: this.props.onDismissed}, - React.createElement(Text, {style: styles.yellowBoxButtonText}, - "Dismiss" - ) - ) - ), - React.createElement(View, {style: styles.yellowBoxButton}, - React.createElement(TouchableOpacity, { - onPress: this.props.onIgnored}, - React.createElement(Text, {style: styles.yellowBoxButtonText}, - "Ignore" - ) - ) - ) - ) - ) - ) - ); - }, -}); - -var canMountWarningBox = true; - -var WarningBox = React.createClass({displayName: "WarningBox", - getInitialState: function() { - return { - totalWarningCount:totalWarningCount, - openWarning: null, - }; - }, - componentWillMount: function() { - if (console.yellowBoxResetIgnored) { - AsyncStorage.setItem(IGNORED_WARNINGS_KEY, '[]', function(err) { - if (err) { - console.warn('Could not reset ignored warnings.', err); - } - }); - ignoredWarnings = []; - } - }, - componentDidMount: function() { - invariant( - canMountWarningBox, - 'There can only be one WarningBox' - ); - canMountWarningBox = false; - warningCountEvents.addListener( - 'count', - this._onWarningCount - ); - }, - componentWillUnmount: function() { - warningCountEvents.removeAllListeners(); - canMountWarningBox = true; - }, - _onWarningCount: function(totalWarningCount) { - // Must use setImmediate because warnings often happen during render and - // state cannot be set while rendering - setImmediate(function() { - this.setState({ totalWarningCount:totalWarningCount, }); - }.bind(this)); - }, - _onDismiss: function(warning) { - warningCounts["delete"](warning); - this.setState({ - openWarning: null, - }); - }, - render: function() { - if (warningCounts.size === 0) { - return React.createElement(View, null); - } - if (this.state.openWarning) { - return ( - React.createElement(WarningBoxOpened, { - warning: this.state.openWarning, - onClose: function() { - this.setState({ openWarning: null }); - }.bind(this), - onDismissed: this._onDismiss.bind(this, this.state.openWarning), - onIgnored: function() { - ignoredWarnings.push(this.state.openWarning); - saveIgnoredWarnings(); - this._onDismiss(this.state.openWarning); - }.bind(this)} - ) - ); - } - var warningRows = []; - warningCounts.forEach(function(count, warning) { - warningRows.push( - React.createElement(WarningRow, { - key: warning, - onOpened: function() { - this.setState({ openWarning: warning }); - }.bind(this), - onDismissed: this._onDismiss.bind(this, warning), - warning: warning} - ) - ); - }.bind(this)); - return ( - React.createElement(View, {style: styles.warningContainer}, - warningRows - ) - ); - }, -}); - -var styles = StyleSheet.create({ - bold: { - fontWeight: 'bold', - }, - closeButton: { - position: 'absolute', - right: 0, - height: 46, - width: 46, - }, - closeButtonText: { - color: 'white', - fontSize: 32, - position: 'relative', - left: 8, - }, - warningContainer: { - position: 'absolute', - left: 0, - right: 0, - bottom: 0 - }, - warningBox: { - position: 'relative', - backgroundColor: 'rgba(171, 124, 36, 0.9)', - flex: 1, - height: 46, - }, - warningText: { - color: 'white', - position: 'absolute', - left: 0, - marginLeft: 15, - marginRight: 46, - top: 7, - }, - yellowBox: { - backgroundColor: 'rgba(171, 124, 36, 0.9)', - position: 'absolute', - left: 0, - right: 0, - top: 0, - bottom: 0, - padding: 15, - paddingTop: 35, - }, - yellowBoxText: { - color: 'white', - fontSize: 20, - }, - yellowBoxButtons: { - flexDirection: 'row', - position: 'absolute', - bottom: 0, - }, - yellowBoxButton: { - flex: 1, - padding: 25, - }, - yellowBoxButtonText: { - color: 'white', - fontSize: 16, - } -}); - -module.exports = WarningBox; -}); -__d('AsyncStorage',["NativeModules"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 AsyncStorage - * @flow-weak - */ -'use strict'; - -var NativeModules = require('NativeModules'); -var RCTAsyncLocalStorage = NativeModules.AsyncLocalStorage; -var RCTAsyncRocksDBStorage = NativeModules.AsyncRocksDBStorage; - -// We use RocksDB if available. -var RCTAsyncStorage = RCTAsyncRocksDBStorage || RCTAsyncLocalStorage; - -/** - * AsyncStorage is a simple, asynchronous, persistent, global, key-value storage - * system. It should be used instead of LocalStorage. - * - * It is recommended that you use an abstraction on top of AsyncStorage instead - * of AsyncStorage directly for anything more than light usage since it - * operates globally. - * - * This JS code is a simple facad over the native iOS implementation to provide - * a clear JS API, real Error objects, and simple non-multi functions. Each - * method returns a `Promise` object. - */ -var AsyncStorage = { - /** - * Fetches `key` and passes the result to `callback`, along with an `Error` if - * there is any. Returns a `Promise` object. - */ - getItem: function( - key , - callback - ) { - return new Promise(function(resolve, reject) { - RCTAsyncStorage.multiGet([key], function(errors, result) { - // Unpack result to get value from [[key,value]] - var value = (result && result[0] && result[0][1]) ? result[0][1] : null; - callback && callback((errors && convertError(errors[0])) || null, value); - if (errors) { - reject(convertError(errors[0])); - } else { - resolve(value); - } - }); - }); - }, - - /** - * Sets `value` for `key` and calls `callback` on completion, along with an - * `Error` if there is any. Returns a `Promise` object. - */ - setItem: function( - key , - value , - callback - ) { - return new Promise(function(resolve, reject) { - RCTAsyncStorage.multiSet([[key,value]], function(errors) { - callback && callback((errors && convertError(errors[0])) || null); - if (errors) { - reject(convertError(errors[0])); - } else { - resolve(null); - } - }); - }); - }, - /** - * Returns a `Promise` object. - */ - removeItem: function( - key , - callback - ) { - return new Promise(function(resolve, reject) { - RCTAsyncStorage.multiRemove([key], function(errors) { - callback && callback((errors && convertError(errors[0])) || null); - if (errors) { - reject(convertError(errors[0])); - } else { - resolve(null); - } - }); - }); - }, - - /** - * Merges existing value with input value, assuming they are stringified json. Returns a `Promise` object. - * - * Not supported by all native implementations. - */ - mergeItem: function( - key , - value , - callback - ) { - return new Promise(function(resolve, reject) { - RCTAsyncStorage.multiMerge([[key,value]], function(errors) { - callback && callback((errors && convertError(errors[0])) || null); - if (errors) { - reject(convertError(errors[0])); - } else { - resolve(null); - } - }); - }); - }, - - /** - * Erases *all* AsyncStorage for all clients, libraries, etc. You probably - * don't want to call this - use removeItem or multiRemove to clear only your - * own keys instead. Returns a `Promise` object. - */ - clear: function(callback ) { - return new Promise(function(resolve, reject) { - RCTAsyncStorage.clear(function(error) { - callback && callback(convertError(error)); - if (error && convertError(error)){ - reject(convertError(error)); - } else { - resolve(null); - } - }); - }); - }, - - /** - * Gets *all* keys known to the system, for all callers, libraries, etc. Returns a `Promise` object. - */ - getAllKeys: function(callback ) { - return new Promise(function(resolve, reject) { - RCTAsyncStorage.getAllKeys(function(error, keys) { - callback && callback(convertError(error), keys); - if (error) { - reject(convertError(error)); - } else { - resolve(keys); - } - }); - }); - }, - - /** - * The following batched functions are useful for executing a lot of - * operations at once, allowing for native optimizations and provide the - * convenience of a single callback after all operations are complete. - * - * These functions return arrays of errors, potentially one for every key. - * For key-specific errors, the Error object will have a key property to - * indicate which key caused the error. - */ - - /** - * multiGet invokes callback with an array of key-value pair arrays that - * matches the input format of multiSet. Returns a `Promise` object. - * - * multiGet(['k1', 'k2'], cb) -> cb([['k1', 'val1'], ['k2', 'val2']]) - */ - multiGet: function( - keys , - callback - ) { - return new Promise(function(resolve, reject) { - RCTAsyncStorage.multiGet(keys, function(errors, result) { - var error = (errors && errors.map(function(error) {return convertError(error);})) || null; - callback && callback(error, result); - if (errors) { - reject(error); - } else { - resolve(result); - } - }); - }); - }, - - /** - * multiSet and multiMerge take arrays of key-value array pairs that match - * the output of multiGet, e.g. Returns a `Promise` object. - * - * multiSet([['k1', 'val1'], ['k2', 'val2']], cb); - */ - multiSet: function( - keyValuePairs , - callback - ) { - return new Promise(function(resolve, reject) { - RCTAsyncStorage.multiSet(keyValuePairs, function(errors) { - var error = (errors && errors.map(function(error) {return convertError(error);})) || null; - callback && callback(error); - if (errors) { - reject(error); - } else { - resolve(null); - } - }); - }); - }, - - /** - * Delete all the keys in the `keys` array. Returns a `Promise` object. - */ - multiRemove: function( - keys , - callback - ) { - return new Promise(function(resolve, reject) { - RCTAsyncStorage.multiRemove(keys, function(errors) { - var error = (errors && errors.map(function(error) {return convertError(error);})) || null; - callback && callback(error); - if (errors) { - reject(error); - } else { - resolve(null); - } - }); - }); - }, - - /** - * Merges existing values with input values, assuming they are stringified - * json. Returns a `Promise` object. - * - * Not supported by all native implementations. - */ - multiMerge: function( - keyValuePairs , - callback - ) { - return new Promise(function(resolve, reject) { - RCTAsyncStorage.multiMerge(keyValuePairs, function(errors) { - var error = (errors && errors.map(function(error) {return convertError(error);})) || null; - callback && callback(error); - if (errors) { - reject(error); - } else { - resolve(null); - } - }); - }); - }, -}; - -// Not all native implementations support merge. -if (!RCTAsyncStorage.multiMerge) { - delete AsyncStorage.mergeItem; - delete AsyncStorage.multiMerge; -} - -function convertError(error) { - if (!error) { - return null; - } - var out = new Error(error.message); - out.key = error.key; // flow doesn't like this :( - return out; -} - -module.exports = AsyncStorage; -}); -__d('RCTRenderingPerf',["ReactDefaultPerf","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 RCTRenderingPerf - * @flow - */ -'use strict'; - -var ReactDefaultPerf = require('ReactDefaultPerf'); - -var invariant = require('invariant'); - - - - - - -var perfModules = []; -var enabled = false; - -var RCTRenderingPerf = { - // Once perf is enabled, it stays enabled - toggle: function() { - console.log('Render perfomance measurements enabled'); - enabled = true; - }, - - start: function() { - if (!enabled) { - return; - } - - ReactDefaultPerf.start(); - perfModules.forEach(function(module) {return module.start();}); - }, - - stop: function() { - if (!enabled) { - return; - } - - ReactDefaultPerf.stop(); - ReactDefaultPerf.printInclusive(); - ReactDefaultPerf.printWasted(); - - var totalRender = 0; - var totalTime = 0; - var measurements = ReactDefaultPerf.getLastMeasurements(); - for (var ii = 0; ii < measurements.length; ii++) { - var render = measurements[ii].render; - for (var nodeName in render) { - totalRender += render[nodeName]; - } - totalTime += measurements[ii].totalTime; - } - console.log('Total time spent in render(): ' + totalRender + 'ms'); - - perfModules.forEach(function(module) {return module.stop();}); - }, - - register: function(module ) { - invariant( - typeof module.start === 'function', - 'Perf module should have start() function' - ); - invariant( - typeof module.stop === 'function', - 'Perf module should have stop() function' - ); - perfModules.push(module); - } -}; - -module.exports = RCTRenderingPerf; -}); -__d('ReactDefaultPerf',["DOMProperty","ReactDefaultPerfAnalysis","ReactMount","ReactPerf","performanceNow"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactDefaultPerf - * @typechecks static-only - */ - -'use strict'; - -var DOMProperty = require('DOMProperty'); -var ReactDefaultPerfAnalysis = require('ReactDefaultPerfAnalysis'); -var ReactMount = require('ReactMount'); -var ReactPerf = require('ReactPerf'); - -var performanceNow = require('performanceNow'); - -function roundFloat(val) { - return Math.floor(val * 100) / 100; -} - -function addValue(obj, key, val) { - obj[key] = (obj[key] || 0) + val; -} - -var ReactDefaultPerf = { - _allMeasurements: [], // last item in the list is the current one - _mountStack: [0], - _injected: false, - - start: function() { - if (!ReactDefaultPerf._injected) { - ReactPerf.injection.injectMeasure(ReactDefaultPerf.measure); - } - - ReactDefaultPerf._allMeasurements.length = 0; - ReactPerf.enableMeasure = true; - }, - - stop: function() { - ReactPerf.enableMeasure = false; - }, - - getLastMeasurements: function() { - return ReactDefaultPerf._allMeasurements; - }, - - printExclusive: function(measurements) { - measurements = measurements || ReactDefaultPerf._allMeasurements; - var summary = ReactDefaultPerfAnalysis.getExclusiveSummary(measurements); - console.table(summary.map(function(item) { - return { - 'Component class name': item.componentName, - 'Total inclusive time (ms)': roundFloat(item.inclusive), - 'Exclusive mount time (ms)': roundFloat(item.exclusive), - 'Exclusive render time (ms)': roundFloat(item.render), - 'Mount time per instance (ms)': roundFloat(item.exclusive / item.count), - 'Render time per instance (ms)': roundFloat(item.render / item.count), - 'Instances': item.count - }; - })); - // TODO: ReactDefaultPerfAnalysis.getTotalTime() does not return the correct - // number. - }, - - printInclusive: function(measurements) { - measurements = measurements || ReactDefaultPerf._allMeasurements; - var summary = ReactDefaultPerfAnalysis.getInclusiveSummary(measurements); - console.table(summary.map(function(item) { - return { - 'Owner > component': item.componentName, - 'Inclusive time (ms)': roundFloat(item.time), - 'Instances': item.count - }; - })); - console.log( - 'Total time:', - ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' - ); - }, - - getMeasurementsSummaryMap: function(measurements) { - var summary = ReactDefaultPerfAnalysis.getInclusiveSummary( - measurements, - true - ); - return summary.map(function(item) { - return { - 'Owner > component': item.componentName, - 'Wasted time (ms)': item.time, - 'Instances': item.count - }; - }); - }, - - printWasted: function(measurements) { - measurements = measurements || ReactDefaultPerf._allMeasurements; - console.table(ReactDefaultPerf.getMeasurementsSummaryMap(measurements)); - console.log( - 'Total time:', - ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' - ); - }, - - printDOM: function(measurements) { - measurements = measurements || ReactDefaultPerf._allMeasurements; - var summary = ReactDefaultPerfAnalysis.getDOMSummary(measurements); - console.table(summary.map(function(item) { - var result = {}; - result[DOMProperty.ID_ATTRIBUTE_NAME] = item.id; - result['type'] = item.type; - result['args'] = JSON.stringify(item.args); - return result; - })); - console.log( - 'Total time:', - ReactDefaultPerfAnalysis.getTotalTime(measurements).toFixed(2) + ' ms' - ); - }, - - _recordWrite: function(id, fnName, totalTime, args) { - // TODO: totalTime isn't that useful since it doesn't count paints/reflows - var writes = - ReactDefaultPerf - ._allMeasurements[ReactDefaultPerf._allMeasurements.length - 1] - .writes; - writes[id] = writes[id] || []; - writes[id].push({ - type: fnName, - time: totalTime, - args: args - }); - }, - - measure: function(moduleName, fnName, func) { - return function() {for (var args=[],$__0=0,$__1=arguments.length;$__0<$__1;$__0++) args.push(arguments[$__0]); - var totalTime; - var rv; - var start; - - if (fnName === '_renderNewRootComponent' || - fnName === 'flushBatchedUpdates') { - // A "measurement" is a set of metrics recorded for each flush. We want - // to group the metrics for a given flush together so we can look at the - // components that rendered and the DOM operations that actually - // happened to determine the amount of "wasted work" performed. - ReactDefaultPerf._allMeasurements.push({ - exclusive: {}, - inclusive: {}, - render: {}, - counts: {}, - writes: {}, - displayNames: {}, - totalTime: 0 - }); - start = performanceNow(); - rv = func.apply(this, args); - ReactDefaultPerf._allMeasurements[ - ReactDefaultPerf._allMeasurements.length - 1 - ].totalTime = performanceNow() - start; - return rv; - } else if (fnName === '_mountImageIntoNode' || - moduleName === 'ReactDOMIDOperations') { - start = performanceNow(); - rv = func.apply(this, args); - totalTime = performanceNow() - start; - - if (fnName === '_mountImageIntoNode') { - var mountID = ReactMount.getID(args[1]); - ReactDefaultPerf._recordWrite(mountID, fnName, totalTime, args[0]); - } else if (fnName === 'dangerouslyProcessChildrenUpdates') { - // special format - args[0].forEach(function(update) { - var writeArgs = {}; - if (update.fromIndex !== null) { - writeArgs.fromIndex = update.fromIndex; - } - if (update.toIndex !== null) { - writeArgs.toIndex = update.toIndex; - } - if (update.textContent !== null) { - writeArgs.textContent = update.textContent; - } - if (update.markupIndex !== null) { - writeArgs.markup = args[1][update.markupIndex]; - } - ReactDefaultPerf._recordWrite( - update.parentID, - update.type, - totalTime, - writeArgs - ); - }); - } else { - // basic format - ReactDefaultPerf._recordWrite( - args[0], - fnName, - totalTime, - Array.prototype.slice.call(args, 1) - ); - } - return rv; - } else if (moduleName === 'ReactCompositeComponent' && ( - fnName === 'mountComponent' || - fnName === 'updateComponent' || // TODO: receiveComponent()? - fnName === '_renderValidatedComponent')) { - - if (typeof this._currentElement.type === 'string') { - return func.apply(this, args); - } - - var rootNodeID = fnName === 'mountComponent' ? - args[0] : - this._rootNodeID; - var isRender = fnName === '_renderValidatedComponent'; - var isMount = fnName === 'mountComponent'; - - var mountStack = ReactDefaultPerf._mountStack; - var entry = ReactDefaultPerf._allMeasurements[ - ReactDefaultPerf._allMeasurements.length - 1 - ]; - - if (isRender) { - addValue(entry.counts, rootNodeID, 1); - } else if (isMount) { - mountStack.push(0); - } - - start = performanceNow(); - rv = func.apply(this, args); - totalTime = performanceNow() - start; - - if (isRender) { - addValue(entry.render, rootNodeID, totalTime); - } else if (isMount) { - var subMountTime = mountStack.pop(); - mountStack[mountStack.length - 1] += totalTime; - addValue(entry.exclusive, rootNodeID, totalTime - subMountTime); - addValue(entry.inclusive, rootNodeID, totalTime); - } else { - addValue(entry.inclusive, rootNodeID, totalTime); - } - - entry.displayNames[rootNodeID] = { - current: this.getName(), - owner: this._currentElement._owner ? - this._currentElement._owner.getName() : - '' - }; - - return rv; - } else { - return func.apply(this, args); - } - }; - } -}; - -module.exports = ReactDefaultPerf; -}); -__d('DOMProperty',["invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 DOMProperty - * @typechecks static-only - */ - -/*jslint bitwise: true */ - -'use strict'; - -var invariant = require('invariant'); - -function checkMask(value, bitmask) { - return (value & bitmask) === bitmask; -} - -var DOMPropertyInjection = { - /** - * Mapping from normalized, camelcased property names to a configuration that - * specifies how the associated DOM property should be accessed or rendered. - */ - MUST_USE_ATTRIBUTE: 0x1, - MUST_USE_PROPERTY: 0x2, - HAS_SIDE_EFFECTS: 0x4, - HAS_BOOLEAN_VALUE: 0x8, - HAS_NUMERIC_VALUE: 0x10, - HAS_POSITIVE_NUMERIC_VALUE: 0x20 | 0x10, - HAS_OVERLOADED_BOOLEAN_VALUE: 0x40, - - /** - * Inject some specialized knowledge about the DOM. This takes a config object - * with the following properties: - * - * isCustomAttribute: function that given an attribute name will return true - * if it can be inserted into the DOM verbatim. Useful for data-* or aria-* - * attributes where it's impossible to enumerate all of the possible - * attribute names, - * - * Properties: object mapping DOM property name to one of the - * DOMPropertyInjection constants or null. If your attribute isn't in here, - * it won't get written to the DOM. - * - * DOMAttributeNames: object mapping React attribute name to the DOM - * attribute name. Attribute names not specified use the **lowercase** - * normalized name. - * - * DOMPropertyNames: similar to DOMAttributeNames but for DOM properties. - * Property names not specified use the normalized name. - * - * DOMMutationMethods: Properties that require special mutation methods. If - * `value` is undefined, the mutation method should unset the property. - * - * @param {object} domPropertyConfig the config as described above. - */ - injectDOMPropertyConfig: function(domPropertyConfig) { - var Properties = domPropertyConfig.Properties || {}; - var DOMAttributeNames = domPropertyConfig.DOMAttributeNames || {}; - var DOMPropertyNames = domPropertyConfig.DOMPropertyNames || {}; - var DOMMutationMethods = domPropertyConfig.DOMMutationMethods || {}; - - if (domPropertyConfig.isCustomAttribute) { - DOMProperty._isCustomAttributeFunctions.push( - domPropertyConfig.isCustomAttribute - ); - } - - for (var propName in Properties) { - invariant( - !DOMProperty.isStandardName.hasOwnProperty(propName), - 'injectDOMPropertyConfig(...): You\'re trying to inject DOM property ' + - '\'%s\' which has already been injected. You may be accidentally ' + - 'injecting the same DOM property config twice, or you may be ' + - 'injecting two configs that have conflicting property names.', - propName - ); - - DOMProperty.isStandardName[propName] = true; - - var lowerCased = propName.toLowerCase(); - DOMProperty.getPossibleStandardName[lowerCased] = propName; - - if (DOMAttributeNames.hasOwnProperty(propName)) { - var attributeName = DOMAttributeNames[propName]; - DOMProperty.getPossibleStandardName[attributeName] = propName; - DOMProperty.getAttributeName[propName] = attributeName; - } else { - DOMProperty.getAttributeName[propName] = lowerCased; - } - - DOMProperty.getPropertyName[propName] = - DOMPropertyNames.hasOwnProperty(propName) ? - DOMPropertyNames[propName] : - propName; - - if (DOMMutationMethods.hasOwnProperty(propName)) { - DOMProperty.getMutationMethod[propName] = DOMMutationMethods[propName]; - } else { - DOMProperty.getMutationMethod[propName] = null; - } - - var propConfig = Properties[propName]; - DOMProperty.mustUseAttribute[propName] = - checkMask(propConfig, DOMPropertyInjection.MUST_USE_ATTRIBUTE); - DOMProperty.mustUseProperty[propName] = - checkMask(propConfig, DOMPropertyInjection.MUST_USE_PROPERTY); - DOMProperty.hasSideEffects[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_SIDE_EFFECTS); - DOMProperty.hasBooleanValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_BOOLEAN_VALUE); - DOMProperty.hasNumericValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_NUMERIC_VALUE); - DOMProperty.hasPositiveNumericValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_POSITIVE_NUMERIC_VALUE); - DOMProperty.hasOverloadedBooleanValue[propName] = - checkMask(propConfig, DOMPropertyInjection.HAS_OVERLOADED_BOOLEAN_VALUE); - - invariant( - !DOMProperty.mustUseAttribute[propName] || - !DOMProperty.mustUseProperty[propName], - 'DOMProperty: Cannot require using both attribute and property: %s', - propName - ); - invariant( - DOMProperty.mustUseProperty[propName] || - !DOMProperty.hasSideEffects[propName], - 'DOMProperty: Properties that have side effects must use property: %s', - propName - ); - invariant( - !!DOMProperty.hasBooleanValue[propName] + - !!DOMProperty.hasNumericValue[propName] + - !!DOMProperty.hasOverloadedBooleanValue[propName] <= 1, - 'DOMProperty: Value can be one of boolean, overloaded boolean, or ' + - 'numeric value, but not a combination: %s', - propName - ); - } - } -}; -var defaultValueCache = {}; - -/** - * DOMProperty exports lookup objects that can be used like functions: - * - * > DOMProperty.isValid['id'] - * true - * > DOMProperty.isValid['foobar'] - * undefined - * - * Although this may be confusing, it performs better in general. - * - * @see http://jsperf.com/key-exists - * @see http://jsperf.com/key-missing - */ -var DOMProperty = { - - ID_ATTRIBUTE_NAME: 'data-reactid', - - /** - * Checks whether a property name is a standard property. - * @type {Object} - */ - isStandardName: {}, - - /** - * Mapping from lowercase property names to the properly cased version, used - * to warn in the case of missing properties. - * @type {Object} - */ - getPossibleStandardName: {}, - - /** - * Mapping from normalized names to attribute names that differ. Attribute - * names are used when rendering markup or with `*Attribute()`. - * @type {Object} - */ - getAttributeName: {}, - - /** - * Mapping from normalized names to properties on DOM node instances. - * (This includes properties that mutate due to external factors.) - * @type {Object} - */ - getPropertyName: {}, - - /** - * Mapping from normalized names to mutation methods. This will only exist if - * mutation cannot be set simply by the property or `setAttribute()`. - * @type {Object} - */ - getMutationMethod: {}, - - /** - * Whether the property must be accessed and mutated as an object property. - * @type {Object} - */ - mustUseAttribute: {}, - - /** - * Whether the property must be accessed and mutated using `*Attribute()`. - * (This includes anything that fails ` in `.) - * @type {Object} - */ - mustUseProperty: {}, - - /** - * Whether or not setting a value causes side effects such as triggering - * resources to be loaded or text selection changes. We must ensure that - * the value is only set if it has changed. - * @type {Object} - */ - hasSideEffects: {}, - - /** - * Whether the property should be removed when set to a falsey value. - * @type {Object} - */ - hasBooleanValue: {}, - - /** - * Whether the property must be numeric or parse as a - * numeric and should be removed when set to a falsey value. - * @type {Object} - */ - hasNumericValue: {}, - - /** - * Whether the property must be positive numeric or parse as a positive - * numeric and should be removed when set to a falsey value. - * @type {Object} - */ - hasPositiveNumericValue: {}, - - /** - * Whether the property can be used as a flag as well as with a value. Removed - * when strictly equal to false; present without a value when strictly equal - * to true; present with a value otherwise. - * @type {Object} - */ - hasOverloadedBooleanValue: {}, - - /** - * All of the isCustomAttribute() functions that have been injected. - */ - _isCustomAttributeFunctions: [], - - /** - * Checks whether a property name is a custom attribute. - * @method - */ - isCustomAttribute: function(attributeName) { - for (var i = 0; i < DOMProperty._isCustomAttributeFunctions.length; i++) { - var isCustomAttributeFn = DOMProperty._isCustomAttributeFunctions[i]; - if (isCustomAttributeFn(attributeName)) { - return true; - } - } - return false; - }, - - /** - * Returns the default property value for a DOM property (i.e., not an - * attribute). Most default values are '' or false, but not all. Worse yet, - * some (in particular, `type`) vary depending on the type of element. - * - * TODO: Is it better to grab all the possible properties when creating an - * element to avoid having to create the same element twice? - */ - getDefaultValueForProperty: function(nodeName, prop) { - var nodeDefaults = defaultValueCache[nodeName]; - var testElement; - if (!nodeDefaults) { - defaultValueCache[nodeName] = nodeDefaults = {}; - } - if (!(prop in nodeDefaults)) { - testElement = document.createElement(nodeName); - nodeDefaults[prop] = testElement[prop]; - } - return nodeDefaults[prop]; - }, - - injection: DOMPropertyInjection -}; - -module.exports = DOMProperty; -}); -__d('ReactDefaultPerfAnalysis',["Object.assign"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactDefaultPerfAnalysis - */ - -var assign = require('Object.assign'); - -// Don't try to save users less than 1.2ms (a number I made up) -var DONT_CARE_THRESHOLD = 1.2; -var DOM_OPERATION_TYPES = { - '_mountImageIntoNode': 'set innerHTML', - INSERT_MARKUP: 'set innerHTML', - MOVE_EXISTING: 'move', - REMOVE_NODE: 'remove', - TEXT_CONTENT: 'set textContent', - 'updatePropertyByID': 'update attribute', - 'deletePropertyByID': 'delete attribute', - 'updateStylesByID': 'update styles', - 'updateInnerHTMLByID': 'set innerHTML', - 'dangerouslyReplaceNodeWithMarkupByID': 'replace' -}; - -function getTotalTime(measurements) { - // TODO: return number of DOM ops? could be misleading. - // TODO: measure dropped frames after reconcile? - // TODO: log total time of each reconcile and the top-level component - // class that triggered it. - var totalTime = 0; - for (var i = 0; i < measurements.length; i++) { - var measurement = measurements[i]; - totalTime += measurement.totalTime; - } - return totalTime; -} - -function getDOMSummary(measurements) { - var items = []; - for (var i = 0; i < measurements.length; i++) { - var measurement = measurements[i]; - var id; - - for (id in measurement.writes) { - measurement.writes[id].forEach(function(write) { - items.push({ - id: id, - type: DOM_OPERATION_TYPES[write.type] || write.type, - args: write.args - }); - }); - } - } - return items; -} - -function getExclusiveSummary(measurements) { - var candidates = {}; - var displayName; - - for (var i = 0; i < measurements.length; i++) { - var measurement = measurements[i]; - var allIDs = assign( - {}, - measurement.exclusive, - measurement.inclusive - ); - - for (var id in allIDs) { - displayName = measurement.displayNames[id].current; - - candidates[displayName] = candidates[displayName] || { - componentName: displayName, - inclusive: 0, - exclusive: 0, - render: 0, - count: 0 - }; - if (measurement.render[id]) { - candidates[displayName].render += measurement.render[id]; - } - if (measurement.exclusive[id]) { - candidates[displayName].exclusive += measurement.exclusive[id]; - } - if (measurement.inclusive[id]) { - candidates[displayName].inclusive += measurement.inclusive[id]; - } - if (measurement.counts[id]) { - candidates[displayName].count += measurement.counts[id]; - } - } - } - - // Now make a sorted array with the results. - var arr = []; - for (displayName in candidates) { - if (candidates[displayName].exclusive >= DONT_CARE_THRESHOLD) { - arr.push(candidates[displayName]); - } - } - - arr.sort(function(a, b) { - return b.exclusive - a.exclusive; - }); - - return arr; -} - -function getInclusiveSummary(measurements, onlyClean) { - var candidates = {}; - var inclusiveKey; - - for (var i = 0; i < measurements.length; i++) { - var measurement = measurements[i]; - var allIDs = assign( - {}, - measurement.exclusive, - measurement.inclusive - ); - var cleanComponents; - - if (onlyClean) { - cleanComponents = getUnchangedComponents(measurement); - } - - for (var id in allIDs) { - if (onlyClean && !cleanComponents[id]) { - continue; - } - - var displayName = measurement.displayNames[id]; - - // Inclusive time is not useful for many components without knowing where - // they are instantiated. So we aggregate inclusive time with both the - // owner and current displayName as the key. - inclusiveKey = displayName.owner + ' > ' + displayName.current; - - candidates[inclusiveKey] = candidates[inclusiveKey] || { - componentName: inclusiveKey, - time: 0, - count: 0 - }; - - if (measurement.inclusive[id]) { - candidates[inclusiveKey].time += measurement.inclusive[id]; - } - if (measurement.counts[id]) { - candidates[inclusiveKey].count += measurement.counts[id]; - } - } - } - - // Now make a sorted array with the results. - var arr = []; - for (inclusiveKey in candidates) { - if (candidates[inclusiveKey].time >= DONT_CARE_THRESHOLD) { - arr.push(candidates[inclusiveKey]); - } - } - - arr.sort(function(a, b) { - return b.time - a.time; - }); - - return arr; -} - -function getUnchangedComponents(measurement) { - // For a given reconcile, look at which components did not actually - // render anything to the DOM and return a mapping of their ID to - // the amount of time it took to render the entire subtree. - var cleanComponents = {}; - var dirtyLeafIDs = Object.keys(measurement.writes); - var allIDs = assign({}, measurement.exclusive, measurement.inclusive); - - for (var id in allIDs) { - var isDirty = false; - // For each component that rendered, see if a component that triggered - // a DOM op is in its subtree. - for (var i = 0; i < dirtyLeafIDs.length; i++) { - if (dirtyLeafIDs[i].indexOf(id) === 0) { - isDirty = true; - break; - } - } - if (!isDirty && measurement.counts[id] > 0) { - cleanComponents[id] = true; - } - } - return cleanComponents; -} - -var ReactDefaultPerfAnalysis = { - getExclusiveSummary: getExclusiveSummary, - getInclusiveSummary: getInclusiveSummary, - getDOMSummary: getDOMSummary, - getTotalTime: getTotalTime -}; - -module.exports = ReactDefaultPerfAnalysis; -}); -__d('ReactMount',["DOMProperty","ReactBrowserEventEmitter","ReactCurrentOwner","ReactElement","ReactElementValidator","ReactEmptyComponent","ReactInstanceHandles","ReactInstanceMap","ReactMarkupChecksum","ReactPerf","ReactReconciler","ReactUpdateQueue","ReactUpdates","emptyObject","containsNode","getReactRootElementInContainer","instantiateReactComponent","invariant","setInnerHTML","shouldUpdateReactComponent","warning"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactMount - */ - -'use strict'; - -var DOMProperty = require('DOMProperty'); -var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter'); -var ReactCurrentOwner = require('ReactCurrentOwner'); -var ReactElement = require('ReactElement'); -var ReactElementValidator = require('ReactElementValidator'); -var ReactEmptyComponent = require('ReactEmptyComponent'); -var ReactInstanceHandles = require('ReactInstanceHandles'); -var ReactInstanceMap = require('ReactInstanceMap'); -var ReactMarkupChecksum = require('ReactMarkupChecksum'); -var ReactPerf = require('ReactPerf'); -var ReactReconciler = require('ReactReconciler'); -var ReactUpdateQueue = require('ReactUpdateQueue'); -var ReactUpdates = require('ReactUpdates'); - -var emptyObject = require('emptyObject'); -var containsNode = require('containsNode'); -var getReactRootElementInContainer = require('getReactRootElementInContainer'); -var instantiateReactComponent = require('instantiateReactComponent'); -var invariant = require('invariant'); -var setInnerHTML = require('setInnerHTML'); -var shouldUpdateReactComponent = require('shouldUpdateReactComponent'); -var warning = require('warning'); - -var SEPARATOR = ReactInstanceHandles.SEPARATOR; - -var ATTR_NAME = DOMProperty.ID_ATTRIBUTE_NAME; -var nodeCache = {}; - -var ELEMENT_NODE_TYPE = 1; -var DOC_NODE_TYPE = 9; - -/** Mapping from reactRootID to React component instance. */ -var instancesByReactRootID = {}; - -/** Mapping from reactRootID to `container` nodes. */ -var containersByReactRootID = {}; - -if (__DEV__) { - /** __DEV__-only mapping from reactRootID to root elements. */ - var rootElementsByReactRootID = {}; -} - -// Used to store breadth-first search state in findComponentRoot. -var findComponentRootReusableArray = []; - -/** - * Finds the index of the first character - * that's not common between the two given strings. - * - * @return {number} the index of the character where the strings diverge - */ -function firstDifferenceIndex(string1, string2) { - var minLen = Math.min(string1.length, string2.length); - for (var i = 0; i < minLen; i++) { - if (string1.charAt(i) !== string2.charAt(i)) { - return i; - } - } - return string1.length === string2.length ? -1 : minLen; -} - -/** - * @param {DOMElement} container DOM element that may contain a React component. - * @return {?string} A "reactRoot" ID, if a React component is rendered. - */ -function getReactRootID(container) { - var rootElement = getReactRootElementInContainer(container); - return rootElement && ReactMount.getID(rootElement); -} - -/** - * Accessing node[ATTR_NAME] or calling getAttribute(ATTR_NAME) on a form - * element can return its control whose name or ID equals ATTR_NAME. All - * DOM nodes support `getAttributeNode` but this can also get called on - * other objects so just return '' if we're given something other than a - * DOM node (such as window). - * - * @param {?DOMElement|DOMWindow|DOMDocument|DOMTextNode} node DOM node. - * @return {string} ID of the supplied `domNode`. - */ -function getID(node) { - var id = internalGetID(node); - if (id) { - if (nodeCache.hasOwnProperty(id)) { - var cached = nodeCache[id]; - if (cached !== node) { - invariant( - !isValid(cached, id), - 'ReactMount: Two valid but unequal nodes with the same `%s`: %s', - ATTR_NAME, id - ); - - nodeCache[id] = node; - } - } else { - nodeCache[id] = node; - } - } - - return id; -} - -function internalGetID(node) { - // If node is something like a window, document, or text node, none of - // which support attributes or a .getAttribute method, gracefully return - // the empty string, as if the attribute were missing. - return node && node.getAttribute && node.getAttribute(ATTR_NAME) || ''; -} - -/** - * Sets the React-specific ID of the given node. - * - * @param {DOMElement} node The DOM node whose ID will be set. - * @param {string} id The value of the ID attribute. - */ -function setID(node, id) { - var oldID = internalGetID(node); - if (oldID !== id) { - delete nodeCache[oldID]; - } - node.setAttribute(ATTR_NAME, id); - nodeCache[id] = node; -} - -/** - * Finds the node with the supplied React-generated DOM ID. - * - * @param {string} id A React-generated DOM ID. - * @return {DOMElement} DOM node with the suppled `id`. - * @internal - */ -function getNode(id) { - if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) { - nodeCache[id] = ReactMount.findReactNodeByID(id); - } - return nodeCache[id]; -} - -/** - * Finds the node with the supplied public React instance. - * - * @param {*} instance A public React instance. - * @return {?DOMElement} DOM node with the suppled `id`. - * @internal - */ -function getNodeFromInstance(instance) { - var id = ReactInstanceMap.get(instance)._rootNodeID; - if (ReactEmptyComponent.isNullComponentID(id)) { - return null; - } - if (!nodeCache.hasOwnProperty(id) || !isValid(nodeCache[id], id)) { - nodeCache[id] = ReactMount.findReactNodeByID(id); - } - return nodeCache[id]; -} - -/** - * A node is "valid" if it is contained by a currently mounted container. - * - * This means that the node does not have to be contained by a document in - * order to be considered valid. - * - * @param {?DOMElement} node The candidate DOM node. - * @param {string} id The expected ID of the node. - * @return {boolean} Whether the node is contained by a mounted container. - */ -function isValid(node, id) { - if (node) { - invariant( - internalGetID(node) === id, - 'ReactMount: Unexpected modification of `%s`', - ATTR_NAME - ); - - var container = ReactMount.findReactContainerForID(id); - if (container && containsNode(container, node)) { - return true; - } - } - - return false; -} - -/** - * Causes the cache to forget about one React-specific ID. - * - * @param {string} id The ID to forget. - */ -function purgeID(id) { - delete nodeCache[id]; -} - -var deepestNodeSoFar = null; -function findDeepestCachedAncestorImpl(ancestorID) { - var ancestor = nodeCache[ancestorID]; - if (ancestor && isValid(ancestor, ancestorID)) { - deepestNodeSoFar = ancestor; - } else { - // This node isn't populated in the cache, so presumably none of its - // descendants are. Break out of the loop. - return false; - } -} - -/** - * Return the deepest cached node whose ID is a prefix of `targetID`. - */ -function findDeepestCachedAncestor(targetID) { - deepestNodeSoFar = null; - ReactInstanceHandles.traverseAncestors( - targetID, - findDeepestCachedAncestorImpl - ); - - var foundNode = deepestNodeSoFar; - deepestNodeSoFar = null; - return foundNode; -} - -/** - * Mounts this component and inserts it into the DOM. - * - * @param {ReactComponent} componentInstance The instance to mount. - * @param {string} rootID DOM ID of the root node. - * @param {DOMElement} container DOM element to mount into. - * @param {ReactReconcileTransaction} transaction - * @param {boolean} shouldReuseMarkup If true, do not insert markup - */ -function mountComponentIntoNode( - componentInstance, - rootID, - container, - transaction, - shouldReuseMarkup) { - var markup = ReactReconciler.mountComponent( - componentInstance, rootID, transaction, emptyObject - ); - componentInstance._isTopLevel = true; - ReactMount._mountImageIntoNode(markup, container, shouldReuseMarkup); -} - -/** - * Batched mount. - * - * @param {ReactComponent} componentInstance The instance to mount. - * @param {string} rootID DOM ID of the root node. - * @param {DOMElement} container DOM element to mount into. - * @param {boolean} shouldReuseMarkup If true, do not insert markup - */ -function batchedMountComponentIntoNode( - componentInstance, - rootID, - container, - shouldReuseMarkup) { - var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(); - transaction.perform( - mountComponentIntoNode, - null, - componentInstance, - rootID, - container, - transaction, - shouldReuseMarkup - ); - ReactUpdates.ReactReconcileTransaction.release(transaction); -} - -/** - * Mounting is the process of initializing a React component by creating its - * representative DOM elements and inserting them into a supplied `container`. - * Any prior content inside `container` is destroyed in the process. - * - * ReactMount.render( - * component, - * document.getElementById('container') - * ); - * - *
<-- Supplied `container`. - *
<-- Rendered reactRoot of React - * // ... component. - *
- *
- * - * Inside of `container`, the first element rendered is the "reactRoot". - */ -var ReactMount = { - /** Exposed for debugging purposes **/ - _instancesByReactRootID: instancesByReactRootID, - - /** - * This is a hook provided to support rendering React components while - * ensuring that the apparent scroll position of its `container` does not - * change. - * - * @param {DOMElement} container The `container` being rendered into. - * @param {function} renderCallback This must be called once to do the render. - */ - scrollMonitor: function(container, renderCallback) { - renderCallback(); - }, - - /** - * Take a component that's already mounted into the DOM and replace its props - * @param {ReactComponent} prevComponent component instance already in the DOM - * @param {ReactElement} nextElement component instance to render - * @param {DOMElement} container container to render into - * @param {?function} callback function triggered on completion - */ - _updateRootComponent: function( - prevComponent, - nextElement, - container, - callback) { - if (__DEV__) { - ReactElementValidator.checkAndWarnForMutatedProps(nextElement); - } - - ReactMount.scrollMonitor(container, function() { - ReactUpdateQueue.enqueueElementInternal(prevComponent, nextElement); - if (callback) { - ReactUpdateQueue.enqueueCallbackInternal(prevComponent, callback); - } - }); - - if (__DEV__) { - // Record the root element in case it later gets transplanted. - rootElementsByReactRootID[getReactRootID(container)] = - getReactRootElementInContainer(container); - } - - return prevComponent; - }, - - /** - * Register a component into the instance map and starts scroll value - * monitoring - * @param {ReactComponent} nextComponent component instance to render - * @param {DOMElement} container container to render into - * @return {string} reactRoot ID prefix - */ - _registerComponent: function(nextComponent, container) { - invariant( - container && ( - container.nodeType === ELEMENT_NODE_TYPE || - container.nodeType === DOC_NODE_TYPE - ), - '_registerComponent(...): Target container is not a DOM element.' - ); - - ReactBrowserEventEmitter.ensureScrollValueMonitoring(); - - var reactRootID = ReactMount.registerContainer(container); - instancesByReactRootID[reactRootID] = nextComponent; - return reactRootID; - }, - - /** - * Render a new component into the DOM. - * @param {ReactElement} nextElement element to render - * @param {DOMElement} container container to render into - * @param {boolean} shouldReuseMarkup if we should skip the markup insertion - * @return {ReactComponent} nextComponent - */ - _renderNewRootComponent: function( - nextElement, - container, - shouldReuseMarkup - ) { - // Various parts of our code (such as ReactCompositeComponent's - // _renderValidatedComponent) assume that calls to render aren't nested; - // verify that that's the case. - warning( - ReactCurrentOwner.current == null, - '_renderNewRootComponent(): Render methods should be a pure function ' + - 'of props and state; triggering nested component updates from ' + - 'render is not allowed. If necessary, trigger nested updates in ' + - 'componentDidUpdate.' - ); - - var componentInstance = instantiateReactComponent(nextElement, null); - var reactRootID = ReactMount._registerComponent( - componentInstance, - container - ); - - // The initial render is synchronous but any updates that happen during - // rendering, in componentWillMount or componentDidMount, will be batched - // according to the current batching strategy. - - ReactUpdates.batchedUpdates( - batchedMountComponentIntoNode, - componentInstance, - reactRootID, - container, - shouldReuseMarkup - ); - - if (__DEV__) { - // Record the root element in case it later gets transplanted. - rootElementsByReactRootID[reactRootID] = - getReactRootElementInContainer(container); - } - - return componentInstance; - }, - - /** - * Renders a React component into the DOM in the supplied `container`. - * - * If the React component was previously rendered into `container`, this will - * perform an update on it and only mutate the DOM as necessary to reflect the - * latest React component. - * - * @param {ReactElement} nextElement Component element to render. - * @param {DOMElement} container DOM element to render into. - * @param {?function} callback function triggered on completion - * @return {ReactComponent} Component instance rendered in `container`. - */ - render: function(nextElement, container, callback) { - invariant( - ReactElement.isValidElement(nextElement), - 'React.render(): Invalid component element.%s', - ( - typeof nextElement === 'string' ? - ' Instead of passing an element string, make sure to instantiate ' + - 'it by passing it to React.createElement.' : - typeof nextElement === 'function' ? - ' Instead of passing a component class, make sure to instantiate ' + - 'it by passing it to React.createElement.' : - // Check if it quacks like an element - nextElement != null && nextElement.props !== undefined ? - ' This may be caused by unintentionally loading two independent ' + - 'copies of React.' : - '' - ) - ); - - var prevComponent = instancesByReactRootID[getReactRootID(container)]; - - if (prevComponent) { - var prevElement = prevComponent._currentElement; - if (shouldUpdateReactComponent(prevElement, nextElement)) { - return ReactMount._updateRootComponent( - prevComponent, - nextElement, - container, - callback - ).getPublicInstance(); - } else { - ReactMount.unmountComponentAtNode(container); - } - } - - var reactRootElement = getReactRootElementInContainer(container); - var containerHasReactMarkup = - reactRootElement && ReactMount.isRenderedByReact(reactRootElement); - - if (__DEV__) { - if (!containerHasReactMarkup || reactRootElement.nextSibling) { - var rootElementSibling = reactRootElement; - while (rootElementSibling) { - if (ReactMount.isRenderedByReact(rootElementSibling)) { - warning( - false, - 'render(): Target node has markup rendered by React, but there ' + - 'are unrelated nodes as well. This is most commonly caused by ' + - 'white-space inserted around server-rendered markup.' - ); - break; - } - - rootElementSibling = rootElementSibling.nextSibling; - } - } - } - - var shouldReuseMarkup = containerHasReactMarkup && !prevComponent; - - var component = ReactMount._renderNewRootComponent( - nextElement, - container, - shouldReuseMarkup - ).getPublicInstance(); - if (callback) { - callback.call(component); - } - return component; - }, - - /** - * Constructs a component instance of `constructor` with `initialProps` and - * renders it into the supplied `container`. - * - * @param {function} constructor React component constructor. - * @param {?object} props Initial props of the component instance. - * @param {DOMElement} container DOM element to render into. - * @return {ReactComponent} Component instance rendered in `container`. - */ - constructAndRenderComponent: function(constructor, props, container) { - var element = ReactElement.createElement(constructor, props); - return ReactMount.render(element, container); - }, - - /** - * Constructs a component instance of `constructor` with `initialProps` and - * renders it into a container node identified by supplied `id`. - * - * @param {function} componentConstructor React component constructor - * @param {?object} props Initial props of the component instance. - * @param {string} id ID of the DOM element to render into. - * @return {ReactComponent} Component instance rendered in the container node. - */ - constructAndRenderComponentByID: function(constructor, props, id) { - var domNode = document.getElementById(id); - invariant( - domNode, - 'Tried to get element with id of "%s" but it is not present on the page.', - id - ); - return ReactMount.constructAndRenderComponent(constructor, props, domNode); - }, - - /** - * Registers a container node into which React components will be rendered. - * This also creates the "reactRoot" ID that will be assigned to the element - * rendered within. - * - * @param {DOMElement} container DOM element to register as a container. - * @return {string} The "reactRoot" ID of elements rendered within. - */ - registerContainer: function(container) { - var reactRootID = getReactRootID(container); - if (reactRootID) { - // If one exists, make sure it is a valid "reactRoot" ID. - reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(reactRootID); - } - if (!reactRootID) { - // No valid "reactRoot" ID found, create one. - reactRootID = ReactInstanceHandles.createReactRootID(); - } - containersByReactRootID[reactRootID] = container; - return reactRootID; - }, - - /** - * Unmounts and destroys the React component rendered in the `container`. - * - * @param {DOMElement} container DOM element containing a React component. - * @return {boolean} True if a component was found in and unmounted from - * `container` - */ - unmountComponentAtNode: function(container) { - // Various parts of our code (such as ReactCompositeComponent's - // _renderValidatedComponent) assume that calls to render aren't nested; - // verify that that's the case. (Strictly speaking, unmounting won't cause a - // render but we still don't expect to be in a render call here.) - warning( - ReactCurrentOwner.current == null, - 'unmountComponentAtNode(): Render methods should be a pure function of ' + - 'props and state; triggering nested component updates from render is ' + - 'not allowed. If necessary, trigger nested updates in ' + - 'componentDidUpdate.' - ); - - invariant( - container && ( - container.nodeType === ELEMENT_NODE_TYPE || - container.nodeType === DOC_NODE_TYPE - ), - 'unmountComponentAtNode(...): Target container is not a DOM element.' - ); - - var reactRootID = getReactRootID(container); - var component = instancesByReactRootID[reactRootID]; - if (!component) { - return false; - } - ReactMount.unmountComponentFromNode(component, container); - delete instancesByReactRootID[reactRootID]; - delete containersByReactRootID[reactRootID]; - if (__DEV__) { - delete rootElementsByReactRootID[reactRootID]; - } - return true; - }, - - /** - * Unmounts a component and removes it from the DOM. - * - * @param {ReactComponent} instance React component instance. - * @param {DOMElement} container DOM element to unmount from. - * @final - * @internal - * @see {ReactMount.unmountComponentAtNode} - */ - unmountComponentFromNode: function(instance, container) { - ReactReconciler.unmountComponent(instance); - - if (container.nodeType === DOC_NODE_TYPE) { - container = container.documentElement; - } - - // http://jsperf.com/emptying-a-node - while (container.lastChild) { - container.removeChild(container.lastChild); - } - }, - - /** - * Finds the container DOM element that contains React component to which the - * supplied DOM `id` belongs. - * - * @param {string} id The ID of an element rendered by a React component. - * @return {?DOMElement} DOM element that contains the `id`. - */ - findReactContainerForID: function(id) { - var reactRootID = ReactInstanceHandles.getReactRootIDFromNodeID(id); - var container = containersByReactRootID[reactRootID]; - - if (__DEV__) { - var rootElement = rootElementsByReactRootID[reactRootID]; - if (rootElement && rootElement.parentNode !== container) { - invariant( - // Call internalGetID here because getID calls isValid which calls - // findReactContainerForID (this function). - internalGetID(rootElement) === reactRootID, - 'ReactMount: Root element ID differed from reactRootID.' - ); - - var containerChild = container.firstChild; - if (containerChild && - reactRootID === internalGetID(containerChild)) { - // If the container has a new child with the same ID as the old - // root element, then rootElementsByReactRootID[reactRootID] is - // just stale and needs to be updated. The case that deserves a - // warning is when the container is empty. - rootElementsByReactRootID[reactRootID] = containerChild; - } else { - warning( - false, - 'ReactMount: Root element has been removed from its original ' + - 'container. New container:', rootElement.parentNode - ); - } - } - } - - return container; - }, - - /** - * Finds an element rendered by React with the supplied ID. - * - * @param {string} id ID of a DOM node in the React component. - * @return {DOMElement} Root DOM node of the React component. - */ - findReactNodeByID: function(id) { - var reactRoot = ReactMount.findReactContainerForID(id); - return ReactMount.findComponentRoot(reactRoot, id); - }, - - /** - * True if the supplied `node` is rendered by React. - * - * @param {*} node DOM Element to check. - * @return {boolean} True if the DOM Element appears to be rendered by React. - * @internal - */ - isRenderedByReact: function(node) { - if (node.nodeType !== 1) { - // Not a DOMElement, therefore not a React component - return false; - } - var id = ReactMount.getID(node); - return id ? id.charAt(0) === SEPARATOR : false; - }, - - /** - * Traverses up the ancestors of the supplied node to find a node that is a - * DOM representation of a React component. - * - * @param {*} node - * @return {?DOMEventTarget} - * @internal - */ - getFirstReactDOM: function(node) { - var current = node; - while (current && current.parentNode !== current) { - if (ReactMount.isRenderedByReact(current)) { - return current; - } - current = current.parentNode; - } - return null; - }, - - /** - * Finds a node with the supplied `targetID` inside of the supplied - * `ancestorNode`. Exploits the ID naming scheme to perform the search - * quickly. - * - * @param {DOMEventTarget} ancestorNode Search from this root. - * @pararm {string} targetID ID of the DOM representation of the component. - * @return {DOMEventTarget} DOM node with the supplied `targetID`. - * @internal - */ - findComponentRoot: function(ancestorNode, targetID) { - var firstChildren = findComponentRootReusableArray; - var childIndex = 0; - - var deepestAncestor = findDeepestCachedAncestor(targetID) || ancestorNode; - - firstChildren[0] = deepestAncestor.firstChild; - firstChildren.length = 1; - - while (childIndex < firstChildren.length) { - var child = firstChildren[childIndex++]; - var targetChild; - - while (child) { - var childID = ReactMount.getID(child); - if (childID) { - // Even if we find the node we're looking for, we finish looping - // through its siblings to ensure they're cached so that we don't have - // to revisit this node again. Otherwise, we make n^2 calls to getID - // when visiting the many children of a single node in order. - - if (targetID === childID) { - targetChild = child; - } else if (ReactInstanceHandles.isAncestorIDOf(childID, targetID)) { - // If we find a child whose ID is an ancestor of the given ID, - // then we can be sure that we only want to search the subtree - // rooted at this child, so we can throw out the rest of the - // search state. - firstChildren.length = childIndex = 0; - firstChildren.push(child.firstChild); - } - - } else { - // If this child had no ID, then there's a chance that it was - // injected automatically by the browser, as when a `
` - // element sprouts an extra `` child as a side effect of - // `.innerHTML` parsing. Optimistically continue down this - // branch, but not before examining the other siblings. - firstChildren.push(child.firstChild); - } - - child = child.nextSibling; - } - - if (targetChild) { - // Emptying firstChildren/findComponentRootReusableArray is - // not necessary for correctness, but it helps the GC reclaim - // any nodes that were left at the end of the search. - firstChildren.length = 0; - - return targetChild; - } - } - - firstChildren.length = 0; - - invariant( - false, - 'findComponentRoot(..., %s): Unable to find element. This probably ' + - 'means the DOM was unexpectedly mutated (e.g., by the browser), ' + - 'usually due to forgetting a when using tables, nesting tags ' + - 'like ,

, or , or using non-SVG elements in an ' + - 'parent. ' + - 'Try inspecting the child nodes of the element with React ID `%s`.', - targetID, - ReactMount.getID(ancestorNode) - ); - }, - - _mountImageIntoNode: function(markup, container, shouldReuseMarkup) { - invariant( - container && ( - container.nodeType === ELEMENT_NODE_TYPE || - container.nodeType === DOC_NODE_TYPE - ), - 'mountComponentIntoNode(...): Target container is not valid.' - ); - - if (shouldReuseMarkup) { - var rootElement = getReactRootElementInContainer(container); - if (ReactMarkupChecksum.canReuseMarkup(markup, rootElement)) { - return; - } else { - var checksum = rootElement.getAttribute( - ReactMarkupChecksum.CHECKSUM_ATTR_NAME - ); - rootElement.removeAttribute(ReactMarkupChecksum.CHECKSUM_ATTR_NAME); - - var rootMarkup = rootElement.outerHTML; - rootElement.setAttribute( - ReactMarkupChecksum.CHECKSUM_ATTR_NAME, - checksum - ); - - var diffIndex = firstDifferenceIndex(markup, rootMarkup); - var difference = ' (client) ' + - markup.substring(diffIndex - 20, diffIndex + 20) + - '\n (server) ' + rootMarkup.substring(diffIndex - 20, diffIndex + 20); - - invariant( - container.nodeType !== DOC_NODE_TYPE, - 'You\'re trying to render a component to the document using ' + - 'server rendering but the checksum was invalid. This usually ' + - 'means you rendered a different component type or props on ' + - 'the client from the one on the server, or your render() ' + - 'methods are impure. React cannot handle this case due to ' + - 'cross-browser quirks by rendering at the document root. You ' + - 'should look for environment dependent code in your components ' + - 'and ensure the props are the same client and server side:\n%s', - difference - ); - - if (__DEV__) { - warning( - false, - 'React attempted to reuse markup in a container but the ' + - 'checksum was invalid. This generally means that you are ' + - 'using server rendering and the markup generated on the ' + - 'server was not what the client was expecting. React injected ' + - 'new markup to compensate which works but you have lost many ' + - 'of the benefits of server rendering. Instead, figure out ' + - 'why the markup being generated is different on the client ' + - 'or server:\n%s', - difference - ); - } - } - } - - invariant( - container.nodeType !== DOC_NODE_TYPE, - 'You\'re trying to render a component to the document but ' + - 'you didn\'t use server rendering. We can\'t do this ' + - 'without using server rendering due to cross-browser quirks. ' + - 'See React.renderToString() for server rendering.' - ); - - setInnerHTML(container, markup); - }, - - /** - * React ID utilities. - */ - - getReactRootID: getReactRootID, - - getID: getID, - - setID: setID, - - getNode: getNode, - - getNodeFromInstance: getNodeFromInstance, - - purgeID: purgeID -}; - -ReactPerf.measureMethods(ReactMount, 'ReactMount', { - _renderNewRootComponent: '_renderNewRootComponent', - _mountImageIntoNode: '_mountImageIntoNode' -}); - -module.exports = ReactMount; -}); -__d('ReactBrowserEventEmitter',["EventConstants","EventPluginHub","EventPluginRegistry","ReactEventEmitterMixin","ViewportMetrics","Object.assign","isEventSupported"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactBrowserEventEmitter - * @typechecks static-only - */ - -'use strict'; - -var EventConstants = require('EventConstants'); -var EventPluginHub = require('EventPluginHub'); -var EventPluginRegistry = require('EventPluginRegistry'); -var ReactEventEmitterMixin = require('ReactEventEmitterMixin'); -var ViewportMetrics = require('ViewportMetrics'); - -var assign = require('Object.assign'); -var isEventSupported = require('isEventSupported'); - -/** - * Summary of `ReactBrowserEventEmitter` event handling: - * - * - Top-level delegation is used to trap most native browser events. This - * may only occur in the main thread and is the responsibility of - * ReactEventListener, which is injected and can therefore support pluggable - * event sources. This is the only work that occurs in the main thread. - * - * - We normalize and de-duplicate events to account for browser quirks. This - * may be done in the worker thread. - * - * - Forward these native events (with the associated top-level type used to - * trap it) to `EventPluginHub`, which in turn will ask plugins if they want - * to extract any synthetic events. - * - * - The `EventPluginHub` will then process each event by annotating them with - * "dispatches", a sequence of listeners and IDs that care about that event. - * - * - The `EventPluginHub` then dispatches the events. - * - * Overview of React and the event system: - * - * +------------+ . - * | DOM | . - * +------------+ . - * | . - * v . - * +------------+ . - * | ReactEvent | . - * | Listener | . - * +------------+ . +-----------+ - * | . +--------+|SimpleEvent| - * | . | |Plugin | - * +-----|------+ . v +-----------+ - * | | | . +--------------+ +------------+ - * | +-----------.--->|EventPluginHub| | Event | - * | | . | | +-----------+ | Propagators| - * | ReactEvent | . | | |TapEvent | |------------| - * | Emitter | . | |<---+|Plugin | |other plugin| - * | | . | | +-----------+ | utilities | - * | +-----------.--->| | +------------+ - * | | | . +--------------+ - * +-----|------+ . ^ +-----------+ - * | . | |Enter/Leave| - * + . +-------+|Plugin | - * +-------------+ . +-----------+ - * | application | . - * |-------------| . - * | | . - * | | . - * +-------------+ . - * . - * React Core . General Purpose Event Plugin System - */ - -var alreadyListeningTo = {}; -var isMonitoringScrollValue = false; -var reactTopListenersCounter = 0; - -// For events like 'submit' which don't consistently bubble (which we trap at a -// lower node than `document`), binding at `document` would cause duplicate -// events so we don't include them here -var topEventMapping = { - topBlur: 'blur', - topChange: 'change', - topClick: 'click', - topCompositionEnd: 'compositionend', - topCompositionStart: 'compositionstart', - topCompositionUpdate: 'compositionupdate', - topContextMenu: 'contextmenu', - topCopy: 'copy', - topCut: 'cut', - topDoubleClick: 'dblclick', - topDrag: 'drag', - topDragEnd: 'dragend', - topDragEnter: 'dragenter', - topDragExit: 'dragexit', - topDragLeave: 'dragleave', - topDragOver: 'dragover', - topDragStart: 'dragstart', - topDrop: 'drop', - topFocus: 'focus', - topInput: 'input', - topKeyDown: 'keydown', - topKeyPress: 'keypress', - topKeyUp: 'keyup', - topMouseDown: 'mousedown', - topMouseMove: 'mousemove', - topMouseOut: 'mouseout', - topMouseOver: 'mouseover', - topMouseUp: 'mouseup', - topPaste: 'paste', - topScroll: 'scroll', - topSelectionChange: 'selectionchange', - topTextInput: 'textInput', - topTouchCancel: 'touchcancel', - topTouchEnd: 'touchend', - topTouchMove: 'touchmove', - topTouchStart: 'touchstart', - topWheel: 'wheel' -}; - -/** - * To ensure no conflicts with other potential React instances on the page - */ -var topListenersIDKey = '_reactListenersID' + String(Math.random()).slice(2); - -function getListeningForDocument(mountAt) { - // In IE8, `mountAt` is a host object and doesn't have `hasOwnProperty` - // directly. - if (!Object.prototype.hasOwnProperty.call(mountAt, topListenersIDKey)) { - mountAt[topListenersIDKey] = reactTopListenersCounter++; - alreadyListeningTo[mountAt[topListenersIDKey]] = {}; - } - return alreadyListeningTo[mountAt[topListenersIDKey]]; -} - -/** - * `ReactBrowserEventEmitter` is used to attach top-level event listeners. For - * example: - * - * ReactBrowserEventEmitter.putListener('myID', 'onClick', myFunction); - * - * This would allocate a "registration" of `('onClick', myFunction)` on 'myID'. - * - * @internal - */ -var ReactBrowserEventEmitter = assign({}, ReactEventEmitterMixin, { - - /** - * Injectable event backend - */ - ReactEventListener: null, - - injection: { - /** - * @param {object} ReactEventListener - */ - injectReactEventListener: function(ReactEventListener) { - ReactEventListener.setHandleTopLevel( - ReactBrowserEventEmitter.handleTopLevel - ); - ReactBrowserEventEmitter.ReactEventListener = ReactEventListener; - } - }, - - /** - * Sets whether or not any created callbacks should be enabled. - * - * @param {boolean} enabled True if callbacks should be enabled. - */ - setEnabled: function(enabled) { - if (ReactBrowserEventEmitter.ReactEventListener) { - ReactBrowserEventEmitter.ReactEventListener.setEnabled(enabled); - } - }, - - /** - * @return {boolean} True if callbacks are enabled. - */ - isEnabled: function() { - return !!( - ReactBrowserEventEmitter.ReactEventListener && - ReactBrowserEventEmitter.ReactEventListener.isEnabled() - ); - }, - - /** - * We listen for bubbled touch events on the document object. - * - * Firefox v8.01 (and possibly others) exhibited strange behavior when - * mounting `onmousemove` events at some node that was not the document - * element. The symptoms were that if your mouse is not moving over something - * contained within that mount point (for example on the background) the - * top-level listeners for `onmousemove` won't be called. However, if you - * register the `mousemove` on the document object, then it will of course - * catch all `mousemove`s. This along with iOS quirks, justifies restricting - * top-level listeners to the document object only, at least for these - * movement types of events and possibly all events. - * - * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html - * - * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but - * they bubble to document. - * - * @param {string} registrationName Name of listener (e.g. `onClick`). - * @param {object} contentDocumentHandle Document which owns the container - */ - listenTo: function(registrationName, contentDocumentHandle) { - var mountAt = contentDocumentHandle; - var isListening = getListeningForDocument(mountAt); - var dependencies = EventPluginRegistry. - registrationNameDependencies[registrationName]; - - var topLevelTypes = EventConstants.topLevelTypes; - for (var i = 0, l = dependencies.length; i < l; i++) { - var dependency = dependencies[i]; - if (!( - isListening.hasOwnProperty(dependency) && - isListening[dependency] - )) { - if (dependency === topLevelTypes.topWheel) { - if (isEventSupported('wheel')) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topWheel, - 'wheel', - mountAt - ); - } else if (isEventSupported('mousewheel')) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topWheel, - 'mousewheel', - mountAt - ); - } else { - // Firefox needs to capture a different mouse scroll event. - // @see http://www.quirksmode.org/dom/events/tests/scroll.html - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topWheel, - 'DOMMouseScroll', - mountAt - ); - } - } else if (dependency === topLevelTypes.topScroll) { - - if (isEventSupported('scroll', true)) { - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelTypes.topScroll, - 'scroll', - mountAt - ); - } else { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topScroll, - 'scroll', - ReactBrowserEventEmitter.ReactEventListener.WINDOW_HANDLE - ); - } - } else if (dependency === topLevelTypes.topFocus || - dependency === topLevelTypes.topBlur) { - - if (isEventSupported('focus', true)) { - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelTypes.topFocus, - 'focus', - mountAt - ); - ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelTypes.topBlur, - 'blur', - mountAt - ); - } else if (isEventSupported('focusin')) { - // IE has `focusin` and `focusout` events which bubble. - // @see http://www.quirksmode.org/blog/archives/2008/04/delegating_the.html - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topFocus, - 'focusin', - mountAt - ); - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelTypes.topBlur, - 'focusout', - mountAt - ); - } - - // to make sure blur and focus event listeners are only attached once - isListening[topLevelTypes.topBlur] = true; - isListening[topLevelTypes.topFocus] = true; - } else if (topEventMapping.hasOwnProperty(dependency)) { - ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - dependency, - topEventMapping[dependency], - mountAt - ); - } - - isListening[dependency] = true; - } - } - }, - - trapBubbledEvent: function(topLevelType, handlerBaseName, handle) { - return ReactBrowserEventEmitter.ReactEventListener.trapBubbledEvent( - topLevelType, - handlerBaseName, - handle - ); - }, - - trapCapturedEvent: function(topLevelType, handlerBaseName, handle) { - return ReactBrowserEventEmitter.ReactEventListener.trapCapturedEvent( - topLevelType, - handlerBaseName, - handle - ); - }, - - /** - * Listens to window scroll and resize events. We cache scroll values so that - * application code can access them without triggering reflows. - * - * NOTE: Scroll events do not bubble. - * - * @see http://www.quirksmode.org/dom/events/scroll.html - */ - ensureScrollValueMonitoring: function() { - if (!isMonitoringScrollValue) { - var refresh = ViewportMetrics.refreshScrollValues; - ReactBrowserEventEmitter.ReactEventListener.monitorScrollValue(refresh); - isMonitoringScrollValue = true; - } - }, - - eventNameDispatchConfigs: EventPluginHub.eventNameDispatchConfigs, - - registrationNameModules: EventPluginHub.registrationNameModules, - - putListener: EventPluginHub.putListener, - - getListener: EventPluginHub.getListener, - - deleteListener: EventPluginHub.deleteListener, - - deleteAllListeners: EventPluginHub.deleteAllListeners - -}); - -module.exports = ReactBrowserEventEmitter; -}); -__d('ViewportMetrics',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ViewportMetrics - */ - -'use strict'; - -var ViewportMetrics = { - - currentScrollLeft: 0, - - currentScrollTop: 0, - - refreshScrollValues: function(scrollPosition) { - ViewportMetrics.currentScrollLeft = scrollPosition.x; - ViewportMetrics.currentScrollTop = scrollPosition.y; - } - -}; - -module.exports = ViewportMetrics; -}); -__d('isEventSupported',["ExecutionEnvironment"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 isEventSupported - */ - -'use strict'; - -var ExecutionEnvironment = require('ExecutionEnvironment'); - -var useHasFeature; -if (ExecutionEnvironment.canUseDOM) { - useHasFeature = - document.implementation && - document.implementation.hasFeature && - // always returns true in newer browsers as per the standard. - // @see http://dom.spec.whatwg.org/#dom-domimplementation-hasfeature - document.implementation.hasFeature('', '') !== true; -} - -/** - * Checks if an event is supported in the current execution environment. - * - * NOTE: This will not work correctly for non-generic events such as `change`, - * `reset`, `load`, `error`, and `select`. - * - * Borrows from Modernizr. - * - * @param {string} eventNameSuffix Event name, e.g. "click". - * @param {?boolean} capture Check if the capture phase is supported. - * @return {boolean} True if the event is supported. - * @internal - * @license Modernizr 3.0.0pre (Custom Build) | MIT - */ -function isEventSupported(eventNameSuffix, capture) { - if (!ExecutionEnvironment.canUseDOM || - capture && !('addEventListener' in document)) { - return false; - } - - var eventName = 'on' + eventNameSuffix; - var isSupported = eventName in document; - - if (!isSupported) { - var element = document.createElement('div'); - element.setAttribute(eventName, 'return;'); - isSupported = typeof element[eventName] === 'function'; - } - - if (!isSupported && useHasFeature && eventNameSuffix === 'wheel') { - // This is the only way to test support for the `wheel` event in IE9+. - isSupported = document.implementation.hasFeature('Events.wheel', '3.0'); - } - - return isSupported; -} - -module.exports = isEventSupported; -}); -__d('ReactMarkupChecksum',["adler32"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactMarkupChecksum - */ - -'use strict'; - -var adler32 = require('adler32'); - -var ReactMarkupChecksum = { - CHECKSUM_ATTR_NAME: 'data-react-checksum', - - /** - * @param {string} markup Markup string - * @return {string} Markup string with checksum attribute attached - */ - addChecksumToMarkup: function(markup) { - var checksum = adler32(markup); - return markup.replace( - '>', - ' ' + ReactMarkupChecksum.CHECKSUM_ATTR_NAME + '="' + checksum + '">' - ); - }, - - /** - * @param {string} markup to use - * @param {DOMElement} element root React element - * @returns {boolean} whether or not the markup is the same - */ - canReuseMarkup: function(markup, element) { - var existingChecksum = element.getAttribute( - ReactMarkupChecksum.CHECKSUM_ATTR_NAME - ); - existingChecksum = existingChecksum && parseInt(existingChecksum, 10); - var markupChecksum = adler32(markup); - return markupChecksum === existingChecksum; - } -}; - -module.exports = ReactMarkupChecksum; -}); -__d('adler32',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 adler32 - */ - -/* jslint bitwise:true */ - -'use strict'; - -var MOD = 65521; - -// This is a clean-room implementation of adler32 designed for detecting -// if markup is not what we expect it to be. It does not need to be -// cryptographically strong, only reasonably good at detecting if markup -// generated on the server is different than that on the client. -function adler32(data) { - var a = 1; - var b = 0; - for (var i = 0; i < data.length; i++) { - a = (a + data.charCodeAt(i)) % MOD; - b = (b + a) % MOD; - } - return a | (b << 16); -} - -module.exports = adler32; -}); -__d('containsNode',["isTextNode"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 containsNode - * @typechecks - */ - -var isTextNode = require('isTextNode'); - -/*jslint bitwise:true */ - -/** - * Checks if a given DOM node contains or is another DOM node. - * - * @param {?DOMNode} outerNode Outer DOM node. - * @param {?DOMNode} innerNode Inner DOM node. - * @return {boolean} True if `outerNode` contains or is `innerNode`. - */ -function containsNode(outerNode, innerNode) { - if (!outerNode || !innerNode) { - return false; - } else if (outerNode === innerNode) { - return true; - } else if (isTextNode(outerNode)) { - return false; - } else if (isTextNode(innerNode)) { - return containsNode(outerNode, innerNode.parentNode); - } else if (outerNode.contains) { - return outerNode.contains(innerNode); - } else if (outerNode.compareDocumentPosition) { - return !!(outerNode.compareDocumentPosition(innerNode) & 16); - } else { - return false; - } -} - -module.exports = containsNode; -}); -__d('isTextNode',["isNode"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 isTextNode - * @typechecks - */ - -var isNode = require('isNode'); - -/** - * @param {*} object The object to check. - * @return {boolean} Whether or not the object is a DOM text node. - */ -function isTextNode(object) { - return isNode(object) && object.nodeType == 3; -} - -module.exports = isTextNode; -}); -__d('getReactRootElementInContainer',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 getReactRootElementInContainer - */ - -'use strict'; - -var DOC_NODE_TYPE = 9; - -/** - * @param {DOMElement|DOMDocument} container DOM element that may contain - * a React component - * @return {?*} DOM element that may have the reactRoot ID, or null. - */ -function getReactRootElementInContainer(container) { - if (!container) { - return null; - } - - if (container.nodeType === DOC_NODE_TYPE) { - return container.documentElement; - } else { - return container.firstChild; - } -} - -module.exports = getReactRootElementInContainer; -}); -__d('setInnerHTML',["ExecutionEnvironment"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 setInnerHTML - */ - -/* globals MSApp */ - -'use strict'; - -var ExecutionEnvironment = require('ExecutionEnvironment'); - -var WHITESPACE_TEST = /^[ \r\n\t\f]/; -var NONVISIBLE_TEST = /<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/; - -/** - * Set the innerHTML property of a node, ensuring that whitespace is preserved - * even in IE8. - * - * @param {DOMElement} node - * @param {string} html - * @internal - */ -var setInnerHTML = function(node, html) { - node.innerHTML = html; -}; - -// Win8 apps: Allow all html to be inserted -if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) { - setInnerHTML = function(node, html) { - MSApp.execUnsafeLocalFunction(function() { - node.innerHTML = html; - }); - }; -} - -if (ExecutionEnvironment.canUseDOM) { - // IE8: When updating a just created node with innerHTML only leading - // whitespace is removed. When updating an existing node with innerHTML - // whitespace in root TextNodes is also collapsed. - // @see quirksmode.org/bugreports/archives/2004/11/innerhtml_and_t.html - - // Feature detection; only IE8 is known to behave improperly like this. - var testElement = document.createElement('div'); - testElement.innerHTML = ' '; - if (testElement.innerHTML === '') { - setInnerHTML = function(node, html) { - // Magic theory: IE8 supposedly differentiates between added and updated - // nodes when processing innerHTML, innerHTML on updated nodes suffers - // from worse whitespace behavior. Re-adding a node like this triggers - // the initial and more favorable whitespace behavior. - // TODO: What to do on a detached node? - if (node.parentNode) { - node.parentNode.replaceChild(node, node); - } - - // We also implement a workaround for non-visible tags disappearing into - // thin air on IE8, this only happens if there is no visible text - // in-front of the non-visible tags. Piggyback on the whitespace fix - // and simply check if any non-visible tags appear in the source. - if (WHITESPACE_TEST.test(html) || - html[0] === '<' && NONVISIBLE_TEST.test(html)) { - // Recover leading whitespace by temporarily prepending any character. - // \uFEFF has the potential advantage of being zero-width/invisible. - node.innerHTML = '\uFEFF' + html; - - // deleteData leaves an empty `TextNode` which offsets the index of all - // children. Definitely want to avoid this. - var textNode = node.firstChild; - if (textNode.data.length === 1) { - node.removeChild(textNode); - } else { - textNode.deleteData(0, 1); - } - } else { - node.innerHTML = html; - } - }; - } -} - -module.exports = setInnerHTML; -}); -__d('AppStateIOS',["NativeModules","RCTDeviceEventEmitter","logError"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 AppStateIOS - * @flow - */ -'use strict'; - -var NativeModules = require('NativeModules'); -var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); -var RCTAppState = NativeModules.AppState; - -var logError = require('logError'); - -var DEVICE_APPSTATE_EVENT = 'appStateDidChange'; - -var _appStateHandlers = {}; - -/** - * `AppStateIOS` can tell you if the app is in the foreground or background, - * and notify you when the state changes. - * - * AppStateIOS is frequently used to determine the intent and proper behavior when - * handling push notifications. - * - * ### iOS App States - * - * - `active` - The app is running in the foreground - * - `background` - The app is running in the background. The user is either - * in another app or on the home screen - * - `inactive` - This is a transition state that currently never happens for - * typical React Native apps. - * - * For more information, see - * [Apple's documentation](https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/TheAppLifeCycle/TheAppLifeCycle.html) - * - * ### Basic Usage - * - * To see the current state, you can check `AppStateIOS.currentState`, which - * will be kept up-to-date. However, `currentState` will be null at launch - * while `AppStateIOS` retrieves it over the bridge. - * - * ``` - * getInitialState: function() { - * return { - * currentAppState: AppStateIOS.currentState, - * }; - * }, - * componentDidMount: function() { - * AppStateIOS.addEventListener('change', this._handleAppStateChange); - * }, - * componentWillUnmount: function() { - * AppStateIOS.removeEventListener('change', this._handleAppStateChange); - * }, - * _handleAppStateChange: function(currentAppState) { - * this.setState({ currentAppState, }); - * }, - * render: function() { - * return ( - * Current state is: {this.state.currentAppState} - * ); - * }, - * ``` - * - * This example will only ever appear to say "Current state is: active" because - * the app is only visible to the user when in the `active` state, and the null - * state will happen only momentarily. - */ - -var AppStateIOS = { - - /** - * Add a handler to AppState changes by listening to the `change` event type - * and providing the handler - */ - addEventListener: function( - type , - handler - ) { - _appStateHandlers[handler] = RCTDeviceEventEmitter.addListener( - DEVICE_APPSTATE_EVENT, - function(appStateData) { - handler(appStateData.app_state); - } - ); - }, - - /** - * Remove a handler by passing the `change` event type and the handler - */ - removeEventListener: function( - type , - handler - ) { - if (!_appStateHandlers[handler]) { - return; - } - _appStateHandlers[handler].remove(); - _appStateHandlers[handler] = null; - }, - - currentState: (null ), - -}; - -RCTDeviceEventEmitter.addListener( - DEVICE_APPSTATE_EVENT, - function(appStateData) { - AppStateIOS.currentState = appStateData.app_state; - } -); - -RCTAppState.getCurrentAppState( - function(appStateData) { - AppStateIOS.currentState = appStateData.app_state; - }, - logError -); - -module.exports = AppStateIOS; -}); -__d('CameraRoll',["ReactPropTypes","NativeModules","createStrictShapeTypeChecker","deepFreezeAndThrowOnMutationInDev","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 CameraRoll - * @flow - */ -'use strict'; - -var ReactPropTypes = require('ReactPropTypes'); -var RCTCameraRollManager = require('NativeModules').CameraRollManager; - -var createStrictShapeTypeChecker = require('createStrictShapeTypeChecker'); -var deepFreezeAndThrowOnMutationInDev = - require('deepFreezeAndThrowOnMutationInDev'); -var invariant = require('invariant'); - -var GROUP_TYPES_OPTIONS = [ - 'Album', - 'All', - 'Event', - 'Faces', - 'Library', - 'PhotoStream', - 'SavedPhotos', // default -]; - -// Flow treats Object and Array as disjoint types, currently. -deepFreezeAndThrowOnMutationInDev((GROUP_TYPES_OPTIONS )); - -/** - * Shape of the param arg for the `getPhotos` function. - */ -var getPhotosParamChecker = createStrictShapeTypeChecker({ - /** - * The number of photos wanted in reverse order of the photo application - * (i.e. most recent first for SavedPhotos). - */ - first: ReactPropTypes.number.isRequired, - - /** - * A cursor that matches `page_info { end_cursor }` returned from a previous - * call to `getPhotos` - */ - after: ReactPropTypes.string, - - /** - * Specifies which group types to filter the results to. - */ - groupTypes: ReactPropTypes.oneOf(GROUP_TYPES_OPTIONS), - - /** - * Specifies filter on group names, like 'Recent Photos' or custom album - * titles. - */ - groupName: ReactPropTypes.string, -}); - -/** - * Shape of the return value of the `getPhotos` function. - */ -var getPhotosReturnChecker = createStrictShapeTypeChecker({ - edges: ReactPropTypes.arrayOf(createStrictShapeTypeChecker({ - node: createStrictShapeTypeChecker({ - type: ReactPropTypes.string.isRequired, - group_name: ReactPropTypes.string.isRequired, - image: createStrictShapeTypeChecker({ - uri: ReactPropTypes.string.isRequired, - height: ReactPropTypes.number.isRequired, - width: ReactPropTypes.number.isRequired, - isStored: ReactPropTypes.bool, - }).isRequired, - timestamp: ReactPropTypes.number.isRequired, - location: createStrictShapeTypeChecker({ - latitude: ReactPropTypes.number, - longitude: ReactPropTypes.number, - altitude: ReactPropTypes.number, - heading: ReactPropTypes.number, - speed: ReactPropTypes.number, - }), - }).isRequired, - })).isRequired, - page_info: createStrictShapeTypeChecker({ - has_next_page: ReactPropTypes.bool.isRequired, - start_cursor: ReactPropTypes.string, - end_cursor: ReactPropTypes.string, - }).isRequired, -}); - -function CameraRoll(){} - - - /** - * Saves the image with tag `tag` to the camera roll. - * - * @param {string} tag - Can be any of the three kinds of tags we accept: - * 1. URL - * 2. assets-library tag - * 3. tag returned from storing an image in memory - */ - CameraRoll.saveImageWithTag=function(tag, successCallback, errorCallback) { - invariant( - typeof tag === 'string', - 'CameraRoll.saveImageWithTag tag must be a valid string.' - ); - RCTCameraRollManager.saveImageWithTag( - tag, - function(imageTag) { - successCallback && successCallback(imageTag); - }, - function(errorMessage) { - errorCallback && errorCallback(errorMessage); - }); - }; - - /** - * Invokes `callback` with photo identifier objects from the local camera - * roll of the device matching shape defined by `getPhotosReturnChecker`. - * - * @param {object} params - See `getPhotosParamChecker`. - * @param {function} callback - Invoked with arg of shape defined by - * `getPhotosReturnChecker` on success. - * @param {function} errorCallback - Invoked with error message on error. - */ - CameraRoll.getPhotos=function(params, callback, errorCallback) { - var metaCallback = callback; - if (__DEV__) { - getPhotosParamChecker({params:params}, 'params', 'CameraRoll.getPhotos'); - invariant( - typeof callback === 'function', - 'CameraRoll.getPhotos callback must be a valid function.' - ); - invariant( - typeof errorCallback === 'function', - 'CameraRoll.getPhotos errorCallback must be a valid function.' - ); - } - if (__DEV__) { - metaCallback = function(response) { - getPhotosReturnChecker( - {response:response}, - 'response', - 'CameraRoll.getPhotos callback' - ); - callback(response); - }; - } - RCTCameraRollManager.getPhotos(params, metaCallback, errorCallback); - }; - - -CameraRoll.GroupTypesOptions = GROUP_TYPES_OPTIONS; - -module.exports = CameraRoll; -}); -__d('LinkingIOS',["RCTDeviceEventEmitter","NativeModules","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 LinkingIOS - * @flow - */ -'use strict'; - -var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); -var RCTLinkingManager = require('NativeModules').LinkingManager; -var invariant = require('invariant'); - -var _notifHandlers = {}; -var _initialURL = RCTLinkingManager && - RCTLinkingManager.initialURL; - -var DEVICE_NOTIF_EVENT = 'openURL'; - -/** - * `LinkingIOS` gives you a general interface to interact with both, incoming - * and outgoing app links. - * - * ### Basic Usage - * - * #### Handling deep links - * - * If your app was launched from a external url registered to your app you can - * access and handle it from any component you want with - * - * ``` - * componentDidMount() { - * var url = LinkingIOS.popInitialURL(); - * } - * ``` - * - * In case you also want to listen to incoming app links during your app's - * execution you'll need to add the following lines to you `*AppDelegate.m`: - * - * ``` - * - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { - * return [RCTLinkingManager application:application openURL:url sourceApplication:sourceApplication annotation:annotation]; - * } - * ``` - * - * And then on your React component you'll be able to listen to the events on - * `LinkingIOS` as follows - * - * ``` - * componentDidMount() { - * LinkingIOS.addEventListener('url', this._handleOpenURL); - * }, - * componentWillUnmount() { - * LinkingIOS.removeEventListener('url', this._handleOpenURL); - * }, - * _handleOpenURL(event) { - * console.log(event.url); - * } - * ``` - * - * #### Triggering App links - * - * To trigger an app link (browser, email or custom schemas) you call - * - * ``` - * LinkingIOS.openURL(url) - * ``` - * - * If you want to check if any installed app can handle a given url beforehand you can call - * ``` - * LinkingIOS.canOpenURL(url, (supported) => { - * if (!supported) { - * AlertIOS.alert('Can\'t handle url: ' + url); - * } else { - * LinkingIOS.openURL(url); - * } - * }); - * ``` - * - * _The iOS simulator does not support the `mailto:` and `tel:` schemas - * because the Mail and Phone apps are not installed - you will need to test - * them on a device._ - */ -function LinkingIOS(){} - /** - * Add a handler to LinkingIOS changes by listening to the `url` event type - * and providing the handler - */ - LinkingIOS.addEventListener=function(type , handler ) { - invariant( - type === 'url', - 'LinkingIOS only supports `url` events' - ); - _notifHandlers[handler] = RCTDeviceEventEmitter.addListener( - DEVICE_NOTIF_EVENT, - handler - ); - }; - - /** - * Remove a handler by passing the `url` event type and the handler - */ - LinkingIOS.removeEventListener=function(type , handler ) { - invariant( - type === 'url', - 'LinkingIOS only supports `url` events' - ); - if (!_notifHandlers[handler]) { - return; - } - _notifHandlers[handler].remove(); - _notifHandlers[handler] = null; - }; - - /** - * Try to open the given `url` with any of the installed apps. - */ - LinkingIOS.openURL=function(url ) { - invariant( - typeof url === 'string', - 'Invalid url: should be a string' - ); - RCTLinkingManager.openURL(url); - }; - - /** - * Determine wether or not the an installed app can handle a given `url` - * The callback function will be called with `bool supported` as the only argument - */ - LinkingIOS.canOpenURL=function(url , callback ) { - invariant( - typeof url === 'string', - 'Invalid url: should be a string' - ); - invariant( - typeof callback === 'function', - 'A valid callback function is required' - ); - RCTLinkingManager.canOpenURL(url, callback); - }; - - /** - * If the app launch was triggered by an app link, it will pop the link url, - * otherwise it will return `null` - */ - LinkingIOS.popInitialURL=function() { - var initialURL = _initialURL; - _initialURL = null; - return initialURL; - }; - - -module.exports = LinkingIOS; -}); -__d('LayoutAnimation',["ReactPropTypes","NativeModules","createStrictShapeTypeChecker","keyMirror"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 LayoutAnimation - * @flow - */ -'use strict'; - -var PropTypes = require('ReactPropTypes'); -var RCTUIManager = require('NativeModules').UIManager; - -var createStrictShapeTypeChecker = require('createStrictShapeTypeChecker'); -var keyMirror = require('keyMirror'); - -var TypesEnum = { - spring: true, - linear: true, - easeInEaseOut: true, - easeIn: true, - easeOut: true, -}; -var Types = keyMirror(TypesEnum); - -var PropertiesEnum = { - opacity: true, - scaleXY: true, -}; -var Properties = keyMirror(PropertiesEnum); - -var animChecker = createStrictShapeTypeChecker({ - duration: PropTypes.number, - delay: PropTypes.number, - springDamping: PropTypes.number, - initialVelocity: PropTypes.number, - type: PropTypes.oneOf( - Object.keys(Types) - ), - property: PropTypes.oneOf( // Only applies to create/delete - Object.keys(Properties) - ), -}); - - - - - - - - - - -var configChecker = createStrictShapeTypeChecker({ - duration: PropTypes.number.isRequired, - create: animChecker, - update: animChecker, - "delete": animChecker, -}); - - - - - - - - -function configureNext(config , onAnimationDidEnd , onError ) { - configChecker({config:config}, 'config', 'LayoutAnimation.configureNext'); - RCTUIManager.configureNextLayoutAnimation(config, onAnimationDidEnd, onError); -} - -function create(duration , type, creationProp) { - return { - duration:duration, - create: { - type:type, - property: creationProp, - }, - update: { - type:type, - }, - }; -} - -var LayoutAnimation = { - configureNext:configureNext, - create:create, - Types:Types, - Properties:Properties, - configChecker: configChecker, - Presets: { - easeInEaseOut: create( - 300, Types.easeInEaseOut, Properties.opacity - ), - linear: create( - 500, Types.linear, Properties.opacity - ), - spring: { - duration: 700, - create: { - type: Types.linear, - property: Properties.opacity, - }, - update: { - type: Types.spring, - springDamping: 0.4, - }, - }, - } -}; - -module.exports = LayoutAnimation; -}); -__d('NetInfo',["NativeModules","RCTDeviceEventEmitter"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 NetInfo - * @flow - */ -'use strict'; - -var NativeModules = require('NativeModules'); -var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); -var RCTReachability = NativeModules.Reachability; - -var DEVICE_REACHABILITY_EVENT = 'reachabilityDidChange'; - - - - - - - - - - - - - -/** - * NetInfo exposes info about online/offline status - * - * ### reachabilityIOS - * - * Asynchronously determine if the device is online and on a cellular network. - * - * - `none` - device is offline - * - `wifi` - device is online and connected via wifi, or is the iOS simulator - * - `cell` - device is connected via Edge, 3G, WiMax, or LTE - * - `unknown` - error case and the network status is unknown - * - * ``` - * NetInfo.reachabilityIOS.fetch().done((reach) => { - * console.log('Initial: ' + reach); - * }); - * function handleFirstReachabilityChange(reach) { - * console.log('First change: ' + reach); - * NetInfo.reachabilityIOS.removeEventListener( - * 'change', - * handleFirstReachabilityChange - * ); - * } - * NetInfo.reachabilityIOS.addEventListener( - * 'change', - * handleFirstReachabilityChange - * ); - * ``` - * - * ### isConnected - * - * Available on all platforms. Asynchronously fetch a boolean to determine - * internet connectivity. - * - * ``` - * NetInfo.isConnected.fetch().done((isConnected) => { - * console.log('First, is ' + (isConnected ? 'online' : 'offline')); - * }); - * function handleFirstConnectivityChange(isConnected) { - * console.log('Then, is ' + (isConnected ? 'online' : 'offline')); - * NetInfo.isConnected.removeEventListener( - * 'change', - * handleFirstConnectivityChange - * ); - * } - * NetInfo.isConnected.addEventListener( - * 'change', - * handleFirstConnectivityChange - * ); - * ``` - */ - -var NetInfo = {}; - -if (RCTReachability) { - - // RCTReachability is exposed, so this is an iOS-like environment and we will - // expose reachabilityIOS - - var _reachabilitySubscriptions = {}; - - NetInfo.reachabilityIOS = { - addEventListener: function ( - eventName , - handler - ) { - _reachabilitySubscriptions[handler] = RCTDeviceEventEmitter.addListener( - DEVICE_REACHABILITY_EVENT, - function(appStateData) { - handler(appStateData.network_reachability); - } - ); - }, - - removeEventListener: function( - eventName , - handler - ) { - if (!_reachabilitySubscriptions[handler]) { - return; - } - _reachabilitySubscriptions[handler].remove(); - _reachabilitySubscriptions[handler] = null; - }, - - fetch: function() { - return new Promise(function(resolve, reject) { - RCTReachability.getCurrentReachability( - function(resp) { - resolve(resp.network_reachability); - }, - reject - ); - }); - }, - }; - - var _isConnectedSubscriptions = {}; - - var _iosReachabilityIsConnected = function( - reachability - ) { - return reachability !== 'none' && - reachability !== 'unknown'; - }; - - NetInfo.isConnected = { - addEventListener: function ( - eventName , - handler - ) { - _isConnectedSubscriptions[handler] = function(reachability) { - handler(_iosReachabilityIsConnected(reachability)); - }; - NetInfo.reachabilityIOS.addEventListener( - eventName, - _isConnectedSubscriptions[handler] - ); - }, - - removeEventListener: function( - eventName , - handler - ) { - NetInfo.reachabilityIOS.removeEventListener( - eventName, - _isConnectedSubscriptions[handler] - ); - }, - - fetch: function() { - return NetInfo.reachabilityIOS.fetch().then( - function(reachability) {return _iosReachabilityIsConnected(reachability);} - ); - }, - }; -} - -module.exports = NetInfo; -}); -__d('PushNotificationIOS',["RCTDeviceEventEmitter","NativeModules","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 PushNotificationIOS - * @flow - */ -'use strict'; - -var RCTDeviceEventEmitter = require('RCTDeviceEventEmitter'); -var RCTPushNotificationManager = require('NativeModules').PushNotificationManager; -var invariant = require('invariant'); - -var _notifHandlers = {}; -var _initialNotification = RCTPushNotificationManager && - RCTPushNotificationManager.initialNotification; - -var DEVICE_NOTIF_EVENT = 'remoteNotificationReceived'; - -/** - * Handle push notifications for your app, including permission handling and - * icon badge number. - * - * To get up and running, [configure your notifications with Apple](https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/ConfiguringPushNotifications/ConfiguringPushNotifications.html) - * and your server-side system. To get an idea, [this is the Parse guide](https://parse.com/tutorials/ios-push-notifications). - */ - - - - - - - /** - * Sets the badge number for the app icon on the home screen - */ - PushNotificationIOS.setApplicationIconBadgeNumber=function(number ) { - RCTPushNotificationManager.setApplicationIconBadgeNumber(number); - }; - - /** - * Gets the current badge number for the app icon on the home screen - */ - PushNotificationIOS.getApplicationIconBadgeNumber=function(callback ) { - RCTPushNotificationManager.getApplicationIconBadgeNumber(callback); - }; - - /** - * Attaches a listener to remote notifications while the app is running in the - * foreground or the background. - * - * The handler will get be invoked with an instance of `PushNotificationIOS` - */ - PushNotificationIOS.addEventListener=function(type , handler ) { - invariant( - type === 'notification', - 'PushNotificationIOS only supports `notification` events' - ); - _notifHandlers[handler] = RCTDeviceEventEmitter.addListener( - DEVICE_NOTIF_EVENT, - function(notifData) { - handler(new PushNotificationIOS(notifData)); - } - ); - }; - - /** - * Requests all notification permissions from iOS, prompting the user's - * dialog box. - */ - PushNotificationIOS.requestPermissions=function() { - RCTPushNotificationManager.requestPermissions(); - }; - - /** - * See what push permissions are currently enabled. `callback` will be - * invoked with a `permissions` object: - * - * - `alert` :boolean - * - `badge` :boolean - * - `sound` :boolean - */ - PushNotificationIOS.checkPermissions=function(callback ) { - invariant( - typeof callback === 'function', - 'Must provide a valid callback' - ); - RCTPushNotificationManager.checkPermissions(callback); - }; - - /** - * Removes the event listener. Do this in `componentWillUnmount` to prevent - * memory leaks - */ - PushNotificationIOS.removeEventListener=function(type , handler ) { - invariant( - type === 'notification', - 'PushNotificationIOS only supports `notification` events' - ); - if (!_notifHandlers[handler]) { - return; - } - _notifHandlers[handler].remove(); - _notifHandlers[handler] = null; - }; - - - /** - * An initial notification will be available if the app was cold-launched - * from a notification. - * - * The first caller of `popInitialNotification` will get the initial - * notification object, or `null`. Subsequent invocations will return null. - */ - PushNotificationIOS.popInitialNotification=function() { - var initialNotification = _initialNotification && - new PushNotificationIOS(_initialNotification); - _initialNotification = null; - return initialNotification; - }; - - /** - * You will never need to instansiate `PushNotificationIOS` yourself. - * Listening to the `notification` event and invoking - * `popInitialNotification` is sufficient - */ - function PushNotificationIOS(nativeNotif) { - this.$PushNotificationIOS_data = {}; - - // Extract data from Apple's `aps` dict as defined: - - // https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/ApplePushService.html - - Object.keys(nativeNotif).forEach(function(notifKey) { - var notifVal = nativeNotif[notifKey]; - if (notifKey === 'aps') { - this.$PushNotificationIOS_alert = notifVal.alert; - this.$PushNotificationIOS_sound = notifVal.sound; - this.$PushNotificationIOS_badgeCount = notifVal.badge; - } else { - this.$PushNotificationIOS_data[notifKey] = notifVal; - } - }.bind(this)); - } - - /** - * An alias for `getAlert` to get the notification's main message string - */ - PushNotificationIOS.prototype.getMessage=function() { - // alias because "alert" is an ambiguous name - return this.$PushNotificationIOS_alert; - }; - - /** - * Gets the sound string from the `aps` object - */ - PushNotificationIOS.prototype.getSound=function() { - return this.$PushNotificationIOS_sound; - }; - - /** - * Gets the notification's main message from the `aps` object - */ - PushNotificationIOS.prototype.getAlert=function() { - return this.$PushNotificationIOS_alert; - }; - - /** - * Gets the badge count number from the `aps` object - */ - PushNotificationIOS.prototype.getBadgeCount=function() { - return this.$PushNotificationIOS_badgeCount; - }; - - /** - * Gets the data object on the notif - */ - PushNotificationIOS.prototype.getData=function() { - return this.$PushNotificationIOS_data; - }; - - -module.exports = PushNotificationIOS; -}); -__d('StatusBarIOS',["NativeModules"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 StatusBarIOS - * @flow - */ -'use strict'; - -var RCTStatusBarManager = require('NativeModules').StatusBarManager; - -var StatusBarIOS = { - - Style: { - "default": RCTStatusBarManager.Style["default"], - lightContent: RCTStatusBarManager.Style.lightContent - }, - - Animation: { - none: RCTStatusBarManager.Animation.none, - fade: RCTStatusBarManager.Animation.fade, - slide: RCTStatusBarManager.Animation.slide, - }, - - setStyle:function(style , animated ) { - animated = animated || false; - RCTStatusBarManager.setStyle(style, animated); - }, - - setHidden:function(hidden , animation ) { - animation = animation || StatusBarIOS.Animation.none; - RCTStatusBarManager.setHidden(hidden, animation); - }, -}; - -module.exports = StatusBarIOS; -}); -__d('VibrationIOS',["NativeModules","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 VibrationIOS - * @flow - */ -'use strict'; - -var RCTVibration = require('NativeModules').Vibration; - -var invariant = require('invariant'); - -/** - * The Vibration API is exposed at `VibrationIOS.vibrate()`. On iOS, calling this - * function will trigger a one second vibration. The vibration is asynchronous - * so this method will return immediately. - * - * There will be no effect on devices that do not support Vibration, eg. the iOS - * simulator. - * - * Vibration patterns are currently unsupported. - */ - -var VibrationIOS = { - vibrate: function() { - invariant( - arguments[0] === undefined, - 'Vibration patterns not supported.' - ); - RCTVibration.vibrate(); - } -}; - -module.exports = VibrationIOS; -}); -__d('RCTNativeAppEventEmitter',["EventEmitter"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * 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 RCTNativeAppEventEmitter - * @flow - */ -'use strict'; - -var EventEmitter = require('EventEmitter'); - -var RCTNativeAppEventEmitter = new EventEmitter(); - -module.exports = RCTNativeAppEventEmitter; -}); -__d('LinkedStateMixin',["ReactLink","ReactStateSetters"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 LinkedStateMixin - * @typechecks static-only - */ - -'use strict'; - -var ReactLink = require('ReactLink'); -var ReactStateSetters = require('ReactStateSetters'); - -/** - * A simple mixin around ReactLink.forState(). - */ -var LinkedStateMixin = { - /** - * Create a ReactLink that's linked to part of this component's state. The - * ReactLink will have the current value of this.state[key] and will call - * setState() when a change is requested. - * - * @param {string} key state key to update. Note: you may want to use keyOf() - * if you're using Google Closure Compiler advanced mode. - * @return {ReactLink} ReactLink instance linking to the state. - */ - linkState: function(key) { - return new ReactLink( - this.state[key], - ReactStateSetters.createStateKeySetter(this, key) - ); - } -}; - -module.exports = LinkedStateMixin; -}); -__d('ReactLink',["React"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactLink - * @typechecks static-only - */ - -'use strict'; - -/** - * ReactLink encapsulates a common pattern in which a component wants to modify - * a prop received from its parent. ReactLink allows the parent to pass down a - * value coupled with a callback that, when invoked, expresses an intent to - * modify that value. For example: - * - * React.createClass({ - * getInitialState: function() { - * return {value: ''}; - * }, - * render: function() { - * var valueLink = new ReactLink(this.state.value, this._handleValueChange); - * return ; - * }, - * this._handleValueChange: function(newValue) { - * this.setState({value: newValue}); - * } - * }); - * - * We have provided some sugary mixins to make the creation and - * consumption of ReactLink easier; see LinkedValueUtils and LinkedStateMixin. - */ - -var React = require('React'); - -/** - * @param {*} value current value of the link - * @param {function} requestChange callback to request a change - */ -function ReactLink(value, requestChange) { - this.value = value; - this.requestChange = requestChange; -} - -/** - * Creates a PropType that enforces the ReactLink API and optionally checks the - * type of the value being passed inside the link. Example: - * - * MyComponent.propTypes = { - * tabIndexLink: ReactLink.PropTypes.link(React.PropTypes.number) - * } - */ -function createLinkTypeChecker(linkType) { - var shapes = { - value: typeof linkType === 'undefined' ? - React.PropTypes.any.isRequired : - linkType.isRequired, - requestChange: React.PropTypes.func.isRequired - }; - return React.PropTypes.shape(shapes); -} - -ReactLink.PropTypes = { - link: createLinkTypeChecker -}; - -module.exports = ReactLink; -}); -__d('ReactStateSetters',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactStateSetters - */ - -'use strict'; - -var ReactStateSetters = { - /** - * Returns a function that calls the provided function, and uses the result - * of that to set the component's state. - * - * @param {ReactCompositeComponent} component - * @param {function} funcReturningState Returned callback uses this to - * determine how to update state. - * @return {function} callback that when invoked uses funcReturningState to - * determined the object literal to setState. - */ - createStateSetter: function(component, funcReturningState) { - return function(a, b, c, d, e, f) { - var partialState = funcReturningState.call(component, a, b, c, d, e, f); - if (partialState) { - component.setState(partialState); - } - }; - }, - - /** - * Returns a single-argument callback that can be used to update a single - * key in the component's state. - * - * Note: this is memoized function, which makes it inexpensive to call. - * - * @param {ReactCompositeComponent} component - * @param {string} key The key in the state that you should update. - * @return {function} callback of 1 argument which calls setState() with - * the provided keyName and callback argument. - */ - createStateKeySetter: function(component, key) { - // Memoize the setters. - var cache = component.__keySetters || (component.__keySetters = {}); - return cache[key] || (cache[key] = createStateKeySetter(component, key)); - } -}; - -function createStateKeySetter(component, key) { - // Partial state is allocated outside of the function closure so it can be - // reused with every call, avoiding memory allocation when this function - // is called. - var partialState = {}; - return function stateKeySetter(value) { - partialState[key] = value; - component.setState(partialState); - }; -} - -ReactStateSetters.Mixin = { - /** - * Returns a function that calls the provided function, and uses the result - * of that to set the component's state. - * - * For example, these statements are equivalent: - * - * this.setState({x: 1}); - * this.createStateSetter(function(xValue) { - * return {x: xValue}; - * })(1); - * - * @param {function} funcReturningState Returned callback uses this to - * determine how to update state. - * @return {function} callback that when invoked uses funcReturningState to - * determined the object literal to setState. - */ - createStateSetter: function(funcReturningState) { - return ReactStateSetters.createStateSetter(this, funcReturningState); - }, - - /** - * Returns a single-argument callback that can be used to update a single - * key in the component's state. - * - * For example, these statements are equivalent: - * - * this.setState({x: 1}); - * this.createStateKeySetter('x')(1); - * - * Note: this is memoized function, which makes it inexpensive to call. - * - * @param {string} key The key in the state that you should update. - * @return {function} callback of 1 argument which calls setState() with - * the provided keyName and callback argument. - */ - createStateKeySetter: function(key) { - return ReactStateSetters.createStateKeySetter(this, key); - } -}; - -module.exports = ReactStateSetters; -}); -__d('ReactComponentWithPureRenderMixin',["shallowEqual"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactComponentWithPureRenderMixin -*/ - -'use strict'; - -var shallowEqual = require('shallowEqual'); - -/** - * If your React component's render function is "pure", e.g. it will render the - * same result given the same props and state, provide this Mixin for a - * considerable performance boost. - * - * Most React components have pure render functions. - * - * Example: - * - * var ReactComponentWithPureRenderMixin = - * require('ReactComponentWithPureRenderMixin'); - * React.createClass({ - * mixins: [ReactComponentWithPureRenderMixin], - * - * render: function() { - * return

; - * } - * }); - * - * Note: This only checks shallow equality for props and state. If these contain - * complex data structures this mixin may have false-negatives for deeper - * differences. Only mixin to components which have simple props and state, or - * use `forceUpdate()` when you know deep data structures have changed. - */ -var ReactComponentWithPureRenderMixin = { - shouldComponentUpdate: function(nextProps, nextState) { - return !shallowEqual(this.props, nextProps) || - !shallowEqual(this.state, nextState); - } -}; - -module.exports = ReactComponentWithPureRenderMixin; -}); -__d('shallowEqual',[],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 shallowEqual - */ - -'use strict'; - -/** - * Performs equality by iterating through keys on an object and returning - * false when any key has values which are not strictly equal between - * objA and objB. Returns true when the values of all keys are strictly equal. - * - * @return {boolean} - */ -function shallowEqual(objA, objB) { - if (objA === objB) { - return true; - } - var key; - // Test for A's keys different from B. - for (key in objA) { - if (objA.hasOwnProperty(key) && - (!objB.hasOwnProperty(key) || objA[key] !== objB[key])) { - return false; - } - } - // Test for B's keys missing from A. - for (key in objB) { - if (objB.hasOwnProperty(key) && !objA.hasOwnProperty(key)) { - return false; - } - } - return true; -} - -module.exports = shallowEqual; -}); -__d('update',["Object.assign","keyOf","invariant"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 update - */ - - /* global hasOwnProperty:true */ - -'use strict'; - -var assign = require('Object.assign'); -var keyOf = require('keyOf'); -var invariant = require('invariant'); -var hasOwnProperty = {}.hasOwnProperty; - -function shallowCopy(x) { - if (Array.isArray(x)) { - return x.concat(); - } else if (x && typeof x === 'object') { - return assign(new x.constructor(), x); - } else { - return x; - } -} - -var COMMAND_PUSH = keyOf({$push: null}); -var COMMAND_UNSHIFT = keyOf({$unshift: null}); -var COMMAND_SPLICE = keyOf({$splice: null}); -var COMMAND_SET = keyOf({$set: null}); -var COMMAND_MERGE = keyOf({$merge: null}); -var COMMAND_APPLY = keyOf({$apply: null}); - -var ALL_COMMANDS_LIST = [ - COMMAND_PUSH, - COMMAND_UNSHIFT, - COMMAND_SPLICE, - COMMAND_SET, - COMMAND_MERGE, - COMMAND_APPLY -]; - -var ALL_COMMANDS_SET = {}; - -ALL_COMMANDS_LIST.forEach(function(command) { - ALL_COMMANDS_SET[command] = true; -}); - -function invariantArrayCase(value, spec, command) { - invariant( - Array.isArray(value), - 'update(): expected target of %s to be an array; got %s.', - command, - value - ); - var specValue = spec[command]; - invariant( - Array.isArray(specValue), - 'update(): expected spec of %s to be an array; got %s. ' + - 'Did you forget to wrap your parameter in an array?', - command, - specValue - ); -} - -function update(value, spec) { - invariant( - typeof spec === 'object', - 'update(): You provided a key path to update() that did not contain one ' + - 'of %s. Did you forget to include {%s: ...}?', - ALL_COMMANDS_LIST.join(', '), - COMMAND_SET - ); - - if (hasOwnProperty.call(spec, COMMAND_SET)) { - invariant( - Object.keys(spec).length === 1, - 'Cannot have more than one key in an object with %s', - COMMAND_SET - ); - - return spec[COMMAND_SET]; - } - - var nextValue = shallowCopy(value); - - if (hasOwnProperty.call(spec, COMMAND_MERGE)) { - var mergeObj = spec[COMMAND_MERGE]; - invariant( - mergeObj && typeof mergeObj === 'object', - 'update(): %s expects a spec of type \'object\'; got %s', - COMMAND_MERGE, - mergeObj - ); - invariant( - nextValue && typeof nextValue === 'object', - 'update(): %s expects a target of type \'object\'; got %s', - COMMAND_MERGE, - nextValue - ); - assign(nextValue, spec[COMMAND_MERGE]); - } - - if (hasOwnProperty.call(spec, COMMAND_PUSH)) { - invariantArrayCase(value, spec, COMMAND_PUSH); - spec[COMMAND_PUSH].forEach(function(item) { - nextValue.push(item); - }); - } - - if (hasOwnProperty.call(spec, COMMAND_UNSHIFT)) { - invariantArrayCase(value, spec, COMMAND_UNSHIFT); - spec[COMMAND_UNSHIFT].forEach(function(item) { - nextValue.unshift(item); - }); - } - - if (hasOwnProperty.call(spec, COMMAND_SPLICE)) { - invariant( - Array.isArray(value), - 'Expected %s target to be an array; got %s', - COMMAND_SPLICE, - value - ); - invariant( - Array.isArray(spec[COMMAND_SPLICE]), - 'update(): expected spec of %s to be an array of arrays; got %s. ' + - 'Did you forget to wrap your parameters in an array?', - COMMAND_SPLICE, - spec[COMMAND_SPLICE] - ); - spec[COMMAND_SPLICE].forEach(function(args) { - invariant( - Array.isArray(args), - 'update(): expected spec of %s to be an array of arrays; got %s. ' + - 'Did you forget to wrap your parameters in an array?', - COMMAND_SPLICE, - spec[COMMAND_SPLICE] - ); - nextValue.splice.apply(nextValue, args); - }); - } - - if (hasOwnProperty.call(spec, COMMAND_APPLY)) { - invariant( - typeof spec[COMMAND_APPLY] === 'function', - 'update(): expected spec of %s to be a function; got %s.', - COMMAND_APPLY, - spec[COMMAND_APPLY] - ); - nextValue = spec[COMMAND_APPLY](nextValue); - } - - for (var k in spec) { - if (!(ALL_COMMANDS_SET.hasOwnProperty(k) && ALL_COMMANDS_SET[k])) { - nextValue[k] = update(value[k], spec[k]); - } - } - - return nextValue; -} - -module.exports = update; -}); -__d('ReactTestUtils',["EventConstants","EventPluginHub","EventPropagators","React","ReactElement","ReactEmptyComponent","ReactBrowserEventEmitter","ReactCompositeComponent","ReactInstanceHandles","ReactInstanceMap","ReactMount","ReactUpdates","SyntheticEvent","Object.assign"],function(global, require, requireDynamic, requireLazy, module, exports) { /** - * Copyright 2013-2015, 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 ReactTestUtils - */ - -'use strict'; - -var EventConstants = require('EventConstants'); -var EventPluginHub = require('EventPluginHub'); -var EventPropagators = require('EventPropagators'); -var React = require('React'); -var ReactElement = require('ReactElement'); -var ReactEmptyComponent = require('ReactEmptyComponent'); -var ReactBrowserEventEmitter = require('ReactBrowserEventEmitter'); -var ReactCompositeComponent = require('ReactCompositeComponent'); -var ReactInstanceHandles = require('ReactInstanceHandles'); -var ReactInstanceMap = require('ReactInstanceMap'); -var ReactMount = require('ReactMount'); -var ReactUpdates = require('ReactUpdates'); -var SyntheticEvent = require('SyntheticEvent'); - -var assign = require('Object.assign'); - -var topLevelTypes = EventConstants.topLevelTypes; - -function Event(suffix) {} - -/** - * @class ReactTestUtils - */ - -/** - * Todo: Support the entire DOM.scry query syntax. For now, these simple - * utilities will suffice for testing purposes. - * @lends ReactTestUtils - */ -var ReactTestUtils = { - renderIntoDocument: function(instance) { - var div = document.createElement('div'); - // None of our tests actually require attaching the container to the - // DOM, and doing so creates a mess that we rely on test isolation to - // clean up, so we're going to stop honoring the name of this method - // (and probably rename it eventually) if no problems arise. - // document.documentElement.appendChild(div); - return React.render(instance, div); - }, - - isElement: function(element) { - return ReactElement.isValidElement(element); - }, - - isElementOfType: function(inst, convenienceConstructor) { - return ( - ReactElement.isValidElement(inst) && - inst.type === convenienceConstructor - ); - }, - - isDOMComponent: function(inst) { - // TODO: Fix this heuristic. It's just here because composites can currently - // pretend to be DOM components. - return !!(inst && inst.tagName && inst.getDOMNode); - }, - - isDOMComponentElement: function(inst) { - return !!(inst && - ReactElement.isValidElement(inst) && - !!inst.tagName); - }, - - isCompositeComponent: function(inst) { - return typeof inst.render === 'function' && - typeof inst.setState === 'function'; - }, - - isCompositeComponentWithType: function(inst, type) { - return !!(ReactTestUtils.isCompositeComponent(inst) && - (inst.constructor === type)); - }, - - isCompositeComponentElement: function(inst) { - if (!ReactElement.isValidElement(inst)) { - return false; - } - // We check the prototype of the type that will get mounted, not the - // instance itself. This is a future proof way of duck typing. - var prototype = inst.type.prototype; - return ( - typeof prototype.render === 'function' && - typeof prototype.setState === 'function' - ); - }, - - isCompositeComponentElementWithType: function(inst, type) { - return !!(ReactTestUtils.isCompositeComponentElement(inst) && - (inst.constructor === type)); - }, - - getRenderedChildOfCompositeComponent: function(inst) { - if (!ReactTestUtils.isCompositeComponent(inst)) { - return null; - } - var internalInstance = ReactInstanceMap.get(inst); - return internalInstance._renderedComponent.getPublicInstance(); - }, - - findAllInRenderedTree: function(inst, test) { - if (!inst) { - return []; - } - var ret = test(inst) ? [inst] : []; - if (ReactTestUtils.isDOMComponent(inst)) { - var internalInstance = ReactInstanceMap.get(inst); - var renderedChildren = internalInstance - ._renderedComponent - ._renderedChildren; - var key; - for (key in renderedChildren) { - if (!renderedChildren.hasOwnProperty(key)) { - continue; - } - if (!renderedChildren[key].getPublicInstance) { - continue; - } - ret = ret.concat( - ReactTestUtils.findAllInRenderedTree( - renderedChildren[key].getPublicInstance(), - test - ) - ); - } - } else if (ReactTestUtils.isCompositeComponent(inst)) { - ret = ret.concat( - ReactTestUtils.findAllInRenderedTree( - ReactTestUtils.getRenderedChildOfCompositeComponent(inst), - test - ) - ); - } - return ret; - }, - - /** - * Finds all instance of components in the rendered tree that are DOM - * components with the class name matching `className`. - * @return an array of all the matches. - */ - scryRenderedDOMComponentsWithClass: function(root, className) { - return ReactTestUtils.findAllInRenderedTree(root, function(inst) { - var instClassName = inst.props.className; - return ReactTestUtils.isDOMComponent(inst) && ( - instClassName && - (' ' + instClassName + ' ').indexOf(' ' + className + ' ') !== -1 - ); - }); - }, - - /** - * Like scryRenderedDOMComponentsWithClass but expects there to be one result, - * and returns that one result, or throws exception if there is any other - * number of matches besides one. - * @return {!ReactDOMComponent} The one match. - */ - findRenderedDOMComponentWithClass: function(root, className) { - var all = - ReactTestUtils.scryRenderedDOMComponentsWithClass(root, className); - if (all.length !== 1) { - throw new Error('Did not find exactly one match ' + - '(found: ' + all.length + ') for class:' + className - ); - } - return all[0]; - }, - - - /** - * Finds all instance of components in the rendered tree that are DOM - * components with the tag name matching `tagName`. - * @return an array of all the matches. - */ - scryRenderedDOMComponentsWithTag: function(root, tagName) { - return ReactTestUtils.findAllInRenderedTree(root, function(inst) { - return ReactTestUtils.isDOMComponent(inst) && - inst.tagName === tagName.toUpperCase(); - }); - }, - - /** - * Like scryRenderedDOMComponentsWithTag but expects there to be one result, - * and returns that one result, or throws exception if there is any other - * number of matches besides one. - * @return {!ReactDOMComponent} The one match. - */ - findRenderedDOMComponentWithTag: function(root, tagName) { - var all = ReactTestUtils.scryRenderedDOMComponentsWithTag(root, tagName); - if (all.length !== 1) { - throw new Error('Did not find exactly one match for tag:' + tagName); - } - return all[0]; - }, - - - /** - * Finds all instances of components with type equal to `componentType`. - * @return an array of all the matches. - */ - scryRenderedComponentsWithType: function(root, componentType) { - return ReactTestUtils.findAllInRenderedTree(root, function(inst) { - return ReactTestUtils.isCompositeComponentWithType( - inst, - componentType - ); - }); - }, - - /** - * Same as `scryRenderedComponentsWithType` but expects there to be one result - * and returns that one result, or throws exception if there is any other - * number of matches besides one. - * @return {!ReactComponent} The one match. - */ - findRenderedComponentWithType: function(root, componentType) { - var all = ReactTestUtils.scryRenderedComponentsWithType( - root, - componentType - ); - if (all.length !== 1) { - throw new Error( - 'Did not find exactly one match for componentType:' + componentType - ); - } - return all[0]; - }, - - /** - * Pass a mocked component module to this method to augment it with - * useful methods that allow it to be used as a dummy React component. - * Instead of rendering as usual, the component will become a simple - *
containing any provided children. - * - * @param {object} module the mock function object exported from a - * module that defines the component to be mocked - * @param {?string} mockTagName optional dummy root tag name to return - * from render method (overrides - * module.mockTagName if provided) - * @return {object} the ReactTestUtils object (for chaining) - */ - mockComponent: function(module, mockTagName) { - mockTagName = mockTagName || module.mockTagName || "div"; - - module.prototype.render.mockImplementation(function() { - return React.createElement( - mockTagName, - null, - this.props.children - ); - }); - - return this; - }, - - /** - * Simulates a top level event being dispatched from a raw event that occured - * on an `Element` node. - * @param topLevelType {Object} A type from `EventConstants.topLevelTypes` - * @param {!Element} node The dom to simulate an event occurring on. - * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent. - */ - simulateNativeEventOnNode: function(topLevelType, node, fakeNativeEvent) { - fakeNativeEvent.target = node; - ReactBrowserEventEmitter.ReactEventListener.dispatchEvent( - topLevelType, - fakeNativeEvent - ); - }, - - /** - * Simulates a top level event being dispatched from a raw event that occured - * on the `ReactDOMComponent` `comp`. - * @param topLevelType {Object} A type from `EventConstants.topLevelTypes`. - * @param comp {!ReactDOMComponent} - * @param {?Event} fakeNativeEvent Fake native event to use in SyntheticEvent. - */ - simulateNativeEventOnDOMComponent: function( - topLevelType, - comp, - fakeNativeEvent) { - ReactTestUtils.simulateNativeEventOnNode( - topLevelType, - comp.getDOMNode(), - fakeNativeEvent - ); - }, - - nativeTouchData: function(x, y) { - return { - touches: [ - {pageX: x, pageY: y} - ] - }; - }, - - createRenderer: function() { - return new ReactShallowRenderer(); - }, - - Simulate: null, - SimulateNative: {} -}; - -/** - * @class ReactShallowRenderer - */ -var ReactShallowRenderer = function() { - this._instance = null; -}; - -ReactShallowRenderer.prototype.getRenderOutput = function() { - return ( - (this._instance && this._instance._renderedComponent && - this._instance._renderedComponent._renderedOutput) - || null - ); -}; - -var NoopInternalComponent = function(element) { - this._renderedOutput = element; - this._currentElement = element === null || element === false ? - ReactEmptyComponent.emptyElement : - element; -}; - -NoopInternalComponent.prototype = { - - mountComponent: function() { - }, - - receiveComponent: function(element) { - this._renderedOutput = element; - this._currentElement = element === null || element === false ? - ReactEmptyComponent.emptyElement : - element; - }, - - unmountComponent: function() { - } - -}; - -var ShallowComponentWrapper = function() { }; -assign( - ShallowComponentWrapper.prototype, - ReactCompositeComponent.Mixin, { - _instantiateReactComponent: function(element) { - return new NoopInternalComponent(element); - }, - _replaceNodeWithMarkupByID: function() {}, - _renderValidatedComponent: - ReactCompositeComponent.Mixin. - _renderValidatedComponentWithoutOwnerOrContext - } -); - -ReactShallowRenderer.prototype.render = function(element, context) { - var transaction = ReactUpdates.ReactReconcileTransaction.getPooled(); - this._render(element, transaction, context); - ReactUpdates.ReactReconcileTransaction.release(transaction); -}; - -ReactShallowRenderer.prototype.unmount = function() { - if (this._instance) { - this._instance.unmountComponent(); - } -}; - -ReactShallowRenderer.prototype._render = function(element, transaction, context) { - if (!this._instance) { - var rootID = ReactInstanceHandles.createReactRootID(); - var instance = new ShallowComponentWrapper(element.type); - instance.construct(element); - - instance.mountComponent(rootID, transaction, context); - - this._instance = instance; - } else { - this._instance.receiveComponent(element, transaction, context); - } -}; - -/** - * Exports: - * - * - `ReactTestUtils.Simulate.click(Element/ReactDOMComponent)` - * - `ReactTestUtils.Simulate.mouseMove(Element/ReactDOMComponent)` - * - `ReactTestUtils.Simulate.change(Element/ReactDOMComponent)` - * - ... (All keys from event plugin `eventTypes` objects) - */ -function makeSimulator(eventType) { - return function(domComponentOrNode, eventData) { - var node; - if (ReactTestUtils.isDOMComponent(domComponentOrNode)) { - node = domComponentOrNode.getDOMNode(); - } else if (domComponentOrNode.tagName) { - node = domComponentOrNode; - } - - var fakeNativeEvent = new Event(); - fakeNativeEvent.target = node; - // We don't use SyntheticEvent.getPooled in order to not have to worry about - // properly destroying any properties assigned from `eventData` upon release - var event = new SyntheticEvent( - ReactBrowserEventEmitter.eventNameDispatchConfigs[eventType], - ReactMount.getID(node), - fakeNativeEvent - ); - assign(event, eventData); - EventPropagators.accumulateTwoPhaseDispatches(event); - - ReactUpdates.batchedUpdates(function() { - EventPluginHub.enqueueEvents(event); - EventPluginHub.processEventQueue(); - }); - }; -} - -function buildSimulators() { - ReactTestUtils.Simulate = {}; - - var eventType; - for (eventType in ReactBrowserEventEmitter.eventNameDispatchConfigs) { - /** - * @param {!Element || ReactDOMComponent} domComponentOrNode - * @param {?object} eventData Fake event data to use in SyntheticEvent. - */ - ReactTestUtils.Simulate[eventType] = makeSimulator(eventType); - } -} - -// Rebuild ReactTestUtils.Simulate whenever event plugins are injected -var oldInjectEventPluginOrder = EventPluginHub.injection.injectEventPluginOrder; -EventPluginHub.injection.injectEventPluginOrder = function() { - oldInjectEventPluginOrder.apply(this, arguments); - buildSimulators(); -}; -var oldInjectEventPlugins = EventPluginHub.injection.injectEventPluginsByName; -EventPluginHub.injection.injectEventPluginsByName = function() { - oldInjectEventPlugins.apply(this, arguments); - buildSimulators(); -}; - -buildSimulators(); - -/** - * Exports: - * - * - `ReactTestUtils.SimulateNative.click(Element/ReactDOMComponent)` - * - `ReactTestUtils.SimulateNative.mouseMove(Element/ReactDOMComponent)` - * - `ReactTestUtils.SimulateNative.mouseIn/ReactDOMComponent)` - * - `ReactTestUtils.SimulateNative.mouseOut(Element/ReactDOMComponent)` - * - ... (All keys from `EventConstants.topLevelTypes`) - * - * Note: Top level event types are a subset of the entire set of handler types - * (which include a broader set of "synthetic" events). For example, onDragDone - * is a synthetic event. Except when testing an event plugin or React's event - * handling code specifically, you probably want to use ReactTestUtils.Simulate - * to dispatch synthetic events. - */ - -function makeNativeSimulator(eventType) { - return function(domComponentOrNode, nativeEventData) { - var fakeNativeEvent = new Event(eventType); - assign(fakeNativeEvent, nativeEventData); - if (ReactTestUtils.isDOMComponent(domComponentOrNode)) { - ReactTestUtils.simulateNativeEventOnDOMComponent( - eventType, - domComponentOrNode, - fakeNativeEvent - ); - } else if (!!domComponentOrNode.tagName) { - // Will allow on actual dom nodes. - ReactTestUtils.simulateNativeEventOnNode( - eventType, - domComponentOrNode, - fakeNativeEvent - ); - } - }; -} - -var eventType; -for (eventType in topLevelTypes) { - // Event type is stored as 'topClick' - we transform that to 'click' - var convenienceName = eventType.indexOf('top') === 0 ? - eventType.charAt(3).toLowerCase() + eventType.substr(4) : eventType; - /** - * @param {!Element || ReactDOMComponent} domComponentOrNode - * @param {?Event} nativeEventData Fake native event to use in SyntheticEvent. - */ - ReactTestUtils.SimulateNative[convenienceName] = - makeNativeSimulator(eventType); -} - -module.exports = ReactTestUtils; -}); -;require("HybridMobileDeployCompanion/index.ios"); -//@ sourceMappingURL=/index.ios.map \ No newline at end of file From 701dc580c92dfda2fa3481d267ab07f4886d86b2 Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Thu, 16 Jul 2015 15:27:18 -0700 Subject: [PATCH 07/16] Fix typo in HybridMobileDeploy.ios.js --- HybridMobileDeploy.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HybridMobileDeploy.h b/HybridMobileDeploy.h index 5aef7c440..9c9fb4235 100644 --- a/HybridMobileDeploy.h +++ b/HybridMobileDeploy.h @@ -1,7 +1,7 @@ #import "RCTBridgeModule.h" @interface HybridMobileDeploy : NSObject -+ (NSString *) getBundleFolderPath:(NSString*)bundleName; ++ (NSString *) getBundlePath:(NSString*)bundleName; + (NSURL *) getNativeBundleURL:(NSString*)bundleName; + (NSURL *)appBundleUrl:(NSString*)bundleName nativeBundleName:(NSString*)nativeBundleName; From 99d2aed17123e433370dab7224221a8f00e2c90a Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Thu, 16 Jul 2015 15:28:16 -0700 Subject: [PATCH 08/16] Add (hacky) reference to SDK package --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 39732233d..0b439733c 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "main": "HybridMobileDeploy.ios.js", "keywords": "react-native", "dependencies": { - "react-native": "^0.5.0", + "hybrid-mobile-deploy-sdk": "file:../website/sdk/bin", "semver": "^4.3.6" } } From 2e39fbf680249c94529f485fc0d17395ae2172ea Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Thu, 16 Jul 2015 15:29:15 -0700 Subject: [PATCH 09/16] Add temporary fetch adapter for use by the SDK --- request-fetch-adapter.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 request-fetch-adapter.js diff --git a/request-fetch-adapter.js b/request-fetch-adapter.js new file mode 100644 index 000000000..c3efb8895 --- /dev/null +++ b/request-fetch-adapter.js @@ -0,0 +1,30 @@ +module.exports.request = function request(verb, url, body, callback) { + if (typeof body === "function") { + callback = body; + body = null; + } + + var headers = { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }; + + if (body && typeof body === "object") { + body = JSON.stringify(body); + } + + var statusCode; + + fetch(url, { + method: verb, + headers: headers, + body: body + }).then(function(response) { + statusCode = response.status; + return response.text(); + }).then(function(body) { + callback(null, {statusCode: statusCode, body: body}); + }).catch(function(err) { + callback(err); + }); +} From 45048f57dd66b1957e17740619f525ec8464837a Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Thu, 16 Jul 2015 15:30:59 -0700 Subject: [PATCH 10/16] Update HybridMobileDeploy js api with basic update query --- HybridMobileDeploy.ios.js | 57 +++++++++------------------------------ 1 file changed, 12 insertions(+), 45 deletions(-) diff --git a/HybridMobileDeploy.ios.js b/HybridMobileDeploy.ios.js index 6ffe08cce..694ab1630 100644 --- a/HybridMobileDeploy.ios.js +++ b/HybridMobileDeploy.ios.js @@ -6,61 +6,28 @@ 'use strict'; var NativeHybridMobileDeploy = require('NativeModules').HybridMobileDeploy; +var requestFetchAdapter = require("./request-fetch-adapter.js"); var semver = require('semver'); +var Sdk = require("hybrid-mobile-deploy-sdk/script/acquisition-sdk"); var serverUrl; var appName; +var sdk; var HybridMobileDeploy = { - checkForUpdate: function(version, callback) { - var url = serverUrl + 'latest/' + appName; - fetch(url) - .then(response => response.json()) - .done(latest => { - if (semver.gt(latest.version, version)) { - callback(undefined, latest); - } else { - callback(undefined, false); - } - }, err => { - callback(err); - }); - }, - pollForUpdate: function(version, intervalDelay, callback) { - var interval; - var checkUpdate = () => { - this.checkForUpdate(version, (err, update) => { - if (err) { - callback(err); - } else if (update) { - interval && clearInterval(interval); - callback(undefined, update); - } - }); - }; - interval = setInterval(checkUpdate, intervalDelay); - checkUpdate(); - }, - getAvailableUpdates: function(callback) { - var url = serverUrl + 'updates/' + appName; - console.log(url); - fetch(url) - .then((response) => { - console.log(response); - return response.json() - }) - .then((value) => { - console.log(value); - return value; - }) - .then(callback); + queryUpdate: function(cb) { + var pkg = {nativeVersion: "1.2.3", scriptVersion: "1.2.0"}; + sdk.queryUpdateWithCurrentPackage(pkg, cb); }, installUpdate: function(update) { NativeHybridMobileDeploy.installUpdateFromUrl(update.updateUrl, update.bundleName, (err) => console.log(err), () => console.log("success")); } }; -module.exports = function(server, app) { - serverUrl = server; - appName = app; +module.exports = function(serverUrl, deploymentKey, ignoreNativeVersion) { + sdk = new Sdk(requestFetchAdapter, { + serverUrl: serverUrl, + deploymentKey: deploymentKey, + ignoreNativeVersion: ignoreNativeVersion + }); return HybridMobileDeploy; }; From d07b96a47caa65d6af12414be632fb4a2c215c3a Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Thu, 16 Jul 2015 15:31:34 -0700 Subject: [PATCH 11/16] Update example to use new HybridMobileDeploy implementation --- .../HybridMobileDeployCompanion/index.ios.js | 31 ++++++++++++++++++- .../HybridMobileDeployCompanion/package.json | 3 +- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/Examples/HybridMobileDeployCompanion/index.ios.js b/Examples/HybridMobileDeployCompanion/index.ios.js index b34cc0a5a..f053099f6 100644 --- a/Examples/HybridMobileDeployCompanion/index.ios.js +++ b/Examples/HybridMobileDeployCompanion/index.ios.js @@ -9,13 +9,41 @@ var { AppRegistry, StyleSheet, Text, + TouchableOpacity, View, } = React; -var HybridMobileDeploy = require('react-native-hybrid-mobile-deploy')('http://localhost:3000/', 'HybridMobileDeployCompanion'); +var Button = require("react-native-button"); + +var HybridMobileDeploy = require('react-native-hybrid-mobile-deploy')('http://localhost:3000/', ''); var HybridMobileDeployCompanion = React.createClass({ + componentDidMount: function() { + this.fetchData(); + }, + fetchData: function() { + HybridMobileDeploy.queryUpdate((err, update) => { + this.setState({ update: update, updateString: JSON.stringify(update) }); + }); + }, + getInitialState: function() { + return { update: false, updateString: "" }; + }, + handlePress: function() { + console.log("pressed"); + }, render: function() { + var updateView; + if (this.state.update) { + updateView = ( + + Update Available: {'\n'} {this.state.update.scriptVersion} - {this.state.update.description} + + + ); + }; return ( @@ -28,6 +56,7 @@ var HybridMobileDeployCompanion = React.createClass({ Press Cmd+R to reload,{'\n'} Cmd+D or shake for dev menu + {updateView} ); } diff --git a/Examples/HybridMobileDeployCompanion/package.json b/Examples/HybridMobileDeployCompanion/package.json index fb3edc0cb..d1ccfeaef 100644 --- a/Examples/HybridMobileDeployCompanion/package.json +++ b/Examples/HybridMobileDeployCompanion/package.json @@ -7,6 +7,7 @@ }, "dependencies": { "react-native": "^0.8.0-rc", - "react-native-hybrid-mobile-deploy": "file:../.." + "react-native-hybrid-mobile-deploy": "file:../..", + "react-native-button": "^1.2.0" } } From 97be98646a24f3ff3a29a1a0d1d7cf99ce98f4e5 Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Thu, 16 Jul 2015 15:39:18 -0700 Subject: [PATCH 12/16] Add basic readme --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 000000000..e8801b5d6 --- /dev/null +++ b/README.md @@ -0,0 +1,14 @@ +hybrid-mobile-deploy-react-native +=== + +React Native module for deploying script updates + +Running the Example +--- + +* Make sure you have https://github.com/Microsoft/hybrid-mobile-deploy cloned beside the react-native project in a folder called `website`. This is hacky, and will be cleaned up as soon as React Native's packager supports symlinks. +* Start the server with `gulp serve`, after installing the prerequisites described in the [project readme](https://github.com/Microsoft/hybrid-mobile-deploy/blob/master/README.md) +* `cd` into `Examples/HybridMobileDeployCompanion` and run `npm install` +* Open `index.ios.js` and add a deployment key (generate one using the UI at http://localhost:4000/) +* Open `HybridMobileDeployCompanion.xcodeproj` in Xcode +* Launch the project From 896eb36500c9404142b4b8c48f45f88f9e0397e4 Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Thu, 16 Jul 2015 17:05:17 -0700 Subject: [PATCH 13/16] Update appBundleUrl so it can be called with no params --- Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m | 4 ++-- HybridMobileDeploy.h | 1 + HybridMobileDeploy.m | 6 ++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m b/Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m index ddc214318..67cdc4dcb 100644 --- a/Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m +++ b/Examples/HybridMobileDeployCompanion/iOS/AppDelegate.m @@ -33,7 +33,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( * on the same Wi-Fi network. */ - jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle"]; + //jsCodeLocation = [NSURL URLWithString:@"http://localhost:8081/index.ios.bundle"]; /** * OPTION 2 @@ -45,7 +45,7 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( * see http://facebook.github.io/react-native/docs/runningondevice.html */ - //jsCodeLocation = [HybridMobileDeploy appBundleUrl:@"HybridMobileDeployCompanion" nativeBundleName:@"main"]; + jsCodeLocation = [HybridMobileDeploy appBundleUrl]; RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation moduleName:@"HybridMobileDeployCompanion" diff --git a/HybridMobileDeploy.h b/HybridMobileDeploy.h index 9c9fb4235..417e23e37 100644 --- a/HybridMobileDeploy.h +++ b/HybridMobileDeploy.h @@ -3,6 +3,7 @@ @interface HybridMobileDeploy : NSObject + (NSString *) getBundlePath:(NSString*)bundleName; + (NSURL *) getNativeBundleURL:(NSString*)bundleName; ++ (NSURL *)appBundleUrl; + (NSURL *)appBundleUrl:(NSString*)bundleName nativeBundleName:(NSString*)nativeBundleName; @end diff --git a/HybridMobileDeploy.m b/HybridMobileDeploy.m index 1079c08c6..905eee00b 100644 --- a/HybridMobileDeploy.m +++ b/HybridMobileDeploy.m @@ -26,6 +26,12 @@ + (NSURL *) getNativeBundleURL:(NSString*)bundleName return [[NSBundle mainBundle] URLForResource:bundleName withExtension:@"jsbundle"]; } ++ (NSURL *) appBundleUrl +{ + return [self appBundleUrl:@"bundle" + nativeBundleName:@"main"]; +} + + (NSURL *) appBundleUrl:(NSString*)bundleName nativeBundleName:(NSString*)nativeBundleName { From 03965e95e0c2a398a3680397c43579c78751f065 Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Fri, 17 Jul 2015 10:55:57 -0700 Subject: [PATCH 14/16] Use new method for requiring NativeModules --- HybridMobileDeploy.ios.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HybridMobileDeploy.ios.js b/HybridMobileDeploy.ios.js index 694ab1630..3af5a05ac 100644 --- a/HybridMobileDeploy.ios.js +++ b/HybridMobileDeploy.ios.js @@ -5,7 +5,7 @@ 'use strict'; -var NativeHybridMobileDeploy = require('NativeModules').HybridMobileDeploy; +var NativeHybridMobileDeploy = require('react-native').NativeModules.HybridMobileDeploy; var requestFetchAdapter = require("./request-fetch-adapter.js"); var semver = require('semver'); var Sdk = require("hybrid-mobile-deploy-sdk/script/acquisition-sdk"); From 568ab4b6609de7f3c9bc23cd3ab5670aa12116ff Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Fri, 17 Jul 2015 10:57:51 -0700 Subject: [PATCH 15/16] Update how example app loads react-native-hybrid-mobile-deploy --- Examples/HybridMobileDeployCompanion/package.json | 3 +-- package.json | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Examples/HybridMobileDeployCompanion/package.json b/Examples/HybridMobileDeployCompanion/package.json index d1ccfeaef..9f292ba3b 100644 --- a/Examples/HybridMobileDeployCompanion/package.json +++ b/Examples/HybridMobileDeployCompanion/package.json @@ -3,11 +3,10 @@ "version": "0.0.1", "private": true, "scripts": { - "start": "node_modules/react-native/packager/packager.sh" + "start": "node_modules/react-native/packager/packager.sh --root ../../" }, "dependencies": { "react-native": "^0.8.0-rc", - "react-native-hybrid-mobile-deploy": "file:../..", "react-native-button": "^1.2.0" } } diff --git a/package.json b/package.json index 0b439733c..11c7304fd 100644 --- a/package.json +++ b/package.json @@ -6,5 +6,8 @@ "dependencies": { "hybrid-mobile-deploy-sdk": "file:../website/sdk/bin", "semver": "^4.3.6" + }, + "devDependencies": { + "react-native": "^0.8.0-rc" } } From 053c7860261249bde449cd58461a3553f0d5d3e2 Mon Sep 17 00:00:00 2001 From: Will Anderson Date: Fri, 17 Jul 2015 10:59:47 -0700 Subject: [PATCH 16/16] Update readme setup instructions --- README.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e8801b5d6..dc9aa628e 100644 --- a/README.md +++ b/README.md @@ -7,8 +7,10 @@ Running the Example --- * Make sure you have https://github.com/Microsoft/hybrid-mobile-deploy cloned beside the react-native project in a folder called `website`. This is hacky, and will be cleaned up as soon as React Native's packager supports symlinks. -* Start the server with `gulp serve`, after installing the prerequisites described in the [project readme](https://github.com/Microsoft/hybrid-mobile-deploy/blob/master/README.md) -* `cd` into `Examples/HybridMobileDeployCompanion` and run `npm install` +* Start the Hybrid Mobile Deploy server with `gulp serve`, after installing the prerequisites described in the [project readme](https://github.com/Microsoft/hybrid-mobile-deploy/blob/master/README.md) +* From the root of this project, run `npm install` +* `cd` into `Examples/HybridMobileDeployCompanion` * Open `index.ios.js` and add a deployment key (generate one using the UI at http://localhost:4000/) +* Run `npm start` to launch the packager * Open `HybridMobileDeployCompanion.xcodeproj` in Xcode * Launch the project