Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Thomas Mchugh 2015-04-07 15:18:07 -05:00
Родитель 10ca07840c 1dba7e0a5a
Коммит 2efce394f5
40 изменённых файлов: 981 добавлений и 475 удалений

Просмотреть файл

@ -37,7 +37,7 @@
"rules": {
"no-cond-assign": 1, // disallow assignment in conditional expressions
"no-console": 0, // disallow use of console (off by default in the node environment)
"no-constant-condition": 1, // disallow use of constant expressions in conditions
"no-constant-condition": 0, // disallow use of constant expressions in conditions
"no-comma-dangle": 0, // disallow trailing commas in object literals
"no-control-regex": 1, // disallow control characters in regular expressions
"no-debugger": 1, // disallow use of debugger

Просмотреть файл

@ -7,23 +7,16 @@
objects = {
/* Begin PBXBuildFile section */
13ACB6741AC2117000FF4204 /* libRCTAnimation.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 13ACB6711AC2113600FF4204 /* libRCTAnimation.a */; };
13B07FBC1A68108700A75B9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.m */; };
13B07FBD1A68108700A75B9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB11A68108700A75B9A /* LaunchScreen.xib */; };
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; };
13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; };
1461632D1AC3E23900C2F5AD /* libReact.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1461632C1AC3E22900C2F5AD /* libReact.a */; };
58C1E40E1ACF54E9006D1A47 /* libRCTAnimationExperimental.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58C1E40B1ACF54B4006D1A47 /* libRCTAnimationExperimental.a */; };
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 832341B51AAA6A8300B99B32 /* libRCTText.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
13ACB6701AC2113600FF4204 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 13ACB66C1AC2113500FF4204 /* RCTAnimation.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTAnimation;
};
1461632B1AC3E22900C2F5AD /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 146163271AC3E22900C2F5AD /* React.xcodeproj */;
@ -31,6 +24,13 @@
remoteGlobalIDString = 83CBBA2E1A601D0E00E9B192;
remoteInfo = React;
};
58C1E40A1ACF54B4006D1A47 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 134814201AA4EA6300B7C361;
remoteInfo = RCTAnimationExperimental;
};
832341B41AAA6A8300B99B32 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */;
@ -41,7 +41,7 @@
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
13ACB66C1AC2113500FF4204 /* RCTAnimation.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimation.xcodeproj; path = ../../Libraries/Animation/RCTAnimation.xcodeproj; sourceTree = "<group>"; };
13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = RCTAnimationExperimental.xcodeproj; path = ../../Libraries/Animation/RCTAnimationExperimental.xcodeproj; sourceTree = "<group>"; };
13B07F961A680F5B00A75B9A /* 2048.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = 2048.app; sourceTree = BUILT_PRODUCTS_DIR; };
13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = 2048/AppDelegate.h; sourceTree = "<group>"; };
13B07FB01A68108700A75B9A /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = 2048/AppDelegate.m; sourceTree = "<group>"; };
@ -59,7 +59,7 @@
buildActionMask = 2147483647;
files = (
1461632D1AC3E23900C2F5AD /* libReact.a in Frameworks */,
13ACB6741AC2117000FF4204 /* libRCTAnimation.a in Frameworks */,
58C1E40E1ACF54E9006D1A47 /* libRCTAnimationExperimental.a in Frameworks */,
832341BD1AAA6AB300B99B32 /* libRCTText.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
@ -67,14 +67,6 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
13ACB66D1AC2113500FF4204 /* Products */ = {
isa = PBXGroup;
children = (
13ACB6711AC2113600FF4204 /* libRCTAnimation.a */,
);
name = Products;
sourceTree = "<group>";
};
13B07FAE1A68108700A75B9A /* 2048 */ = {
isa = PBXGroup;
children = (
@ -96,12 +88,20 @@
name = Products;
sourceTree = "<group>";
};
58C1E4071ACF54B4006D1A47 /* Products */ = {
isa = PBXGroup;
children = (
58C1E40B1ACF54B4006D1A47 /* libRCTAnimationExperimental.a */,
);
name = Products;
sourceTree = "<group>";
};
832341AE1AAA6A7D00B99B32 /* Libraries */ = {
isa = PBXGroup;
children = (
146163271AC3E22900C2F5AD /* React.xcodeproj */,
832341B01AAA6A8300B99B32 /* RCTText.xcodeproj */,
13ACB66C1AC2113500FF4204 /* RCTAnimation.xcodeproj */,
13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */,
);
name = Libraries;
sourceTree = "<group>";
@ -175,8 +175,8 @@
projectDirPath = "";
projectReferences = (
{
ProductGroup = 13ACB66D1AC2113500FF4204 /* Products */;
ProjectRef = 13ACB66C1AC2113500FF4204 /* RCTAnimation.xcodeproj */;
ProductGroup = 58C1E4071ACF54B4006D1A47 /* Products */;
ProjectRef = 13ACB66C1AC2113500FF4204 /* RCTAnimationExperimental.xcodeproj */;
},
{
ProductGroup = 832341B11AAA6A8300B99B32 /* Products */;
@ -195,13 +195,6 @@
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
13ACB6711AC2113600FF4204 /* libRCTAnimation.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTAnimation.a;
remoteRef = 13ACB6701AC2113600FF4204 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
1461632C1AC3E22900C2F5AD /* libReact.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
@ -209,6 +202,13 @@
remoteRef = 1461632B1AC3E22900C2F5AD /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
58C1E40B1ACF54B4006D1A47 /* libRCTAnimationExperimental.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libRCTAnimationExperimental.a;
remoteRef = 58C1E40A1ACF54B4006D1A47 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
832341B51AAA6A8300B99B32 /* libRCTText.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
@ -266,6 +266,10 @@
);
INFOPLIST_FILE = "$(SRCROOT)/2048/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"/Users/sahrens/src/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/Libraries/Animation/build/Debug-iphoneos",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = 2048;
};
@ -282,6 +286,10 @@
);
INFOPLIST_FILE = "$(SRCROOT)/2048/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"/Users/sahrens/src/fbobjc-hg/Libraries/FBReactKit/js/react-native-github/Libraries/Animation/build/Debug-iphoneos",
);
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = 2048;
};

Просмотреть файл

@ -18,13 +18,13 @@
var React = require('react-native');
var {
Animation,
AppRegistry,
StyleSheet,
Text,
View,
} = React;
var AnimationExperimental = require('AnimationExperimental');
var GameBoard = require('GameBoard');
var TouchableBounce = require('TouchableBounce');
@ -77,17 +77,15 @@ class Tile extends React.Component {
animationPosition(tile.toColumn()),
animationPosition(tile.toRow()),
];
Animation.startAnimation(this.refs['this'], 100, 0, 'easeInOutQuad', {position: point});
AnimationExperimental.startAnimation(this.refs['this'], 100, 0, 'easeInOutQuad', {position: point});
}
return offset;
}
componentDidMount() {
setTimeout(() => {
Animation.startAnimation(this.refs['this'], 300, 0, 'easeInOutQuad', {scaleXY: [1, 1]});
Animation.startAnimation(this.refs['this'], 100, 0, 'easeInOutQuad', {opacity: 1});
}, 0);
AnimationExperimental.startAnimation(this.refs['this'], 100, 0, 'easeInOutQuad', {opacity: 1});
}
render() {

Просмотреть файл

@ -52,26 +52,45 @@ var ROUTE_STACK = [
var INIT_ROUTE_INDEX = 1;
class JumpingNavBar extends React.Component {
constructor(props) {
super(props);
this.state = {
tabIndex: props.initTabIndex,
};
}
handleWillFocus(route) {
var tabIndex = ROUTE_STACK.indexOf(route);
this.setState({ tabIndex, });
}
render() {
return (
<View style={styles.tabs}>
<TabBarIOS>
<TabBarIOS.Item
icon={require('image!tabnav_notification')}
selected={this.props.tabIndex === 0}
onPress={() => { this.props.onTabIndex(0); }}>
selected={this.state.tabIndex === 0}
onPress={() => {
this.props.onTabIndex(0);
this.setState({ tabIndex: 0, });
}}>
<View />
</TabBarIOS.Item>
<TabBarIOS.Item
icon={require('image!tabnav_list')}
selected={this.props.tabIndex === 1}
onPress={() => { this.props.onTabIndex(1); }}>
selected={this.state.tabIndex === 1}
onPress={() => {
this.props.onTabIndex(1);
this.setState({ tabIndex: 1, });
}}>
<View />
</TabBarIOS.Item>
<TabBarIOS.Item
icon={require('image!tabnav_settings')}
selected={this.props.tabIndex === 2}
onPress={() => { this.props.onTabIndex(2); }}>
selected={this.state.tabIndex === 2}
onPress={() => {
this.props.onTabIndex(2);
this.setState({ tabIndex: 2, });
}}>
<View />
</TabBarIOS.Item>
</TabBarIOS>
@ -81,12 +100,6 @@ class JumpingNavBar extends React.Component {
}
var JumpingNavSample = React.createClass({
getInitialState: function() {
return {
tabIndex: INIT_ROUTE_INDEX,
};
},
render: function() {
return (
<Navigator
@ -98,23 +111,19 @@ var JumpingNavSample = React.createClass({
initialRoute={ROUTE_STACK[INIT_ROUTE_INDEX]}
initialRouteStack={ROUTE_STACK}
renderScene={this.renderScene}
configureScene={() => ({
...Navigator.SceneConfigs.HorizontalSwipeJump,
})}
navigationBar={
<JumpingNavBar
ref={(navBar) => { this.navBar = navBar; }}
initTabIndex={INIT_ROUTE_INDEX}
routeStack={ROUTE_STACK}
tabIndex={this.state.tabIndex}
onTabIndex={(index) => {
this.setState({ tabIndex: index }, () => {
this._navigator.jumpTo(ROUTE_STACK[index]);
});
this._navigator.jumpTo(ROUTE_STACK[index]);
}}
/>
}
onWillFocus={(route) => {
this.setState({
tabIndex: ROUTE_STACK.indexOf(route),
});
}}
shouldJumpOnBackstackPop={true}
/>
);
},

Просмотреть файл

@ -17,6 +17,7 @@
var React = require('react-native');
var ViewExample = require('./ViewExample');
var createExamplePage = require('./createExamplePage');
var {
PixelRatio,
ScrollView,
@ -77,7 +78,7 @@ var NavigatorIOSExample = React.createClass({
{this._renderRow('Push View Example', () => {
this.props.navigator.push({
title: 'Very Long Custom View Example Title',
component: ViewExample,
component: createExamplePage(null, ViewExample),
});
})}
{this._renderRow('Custom Right Button', () => {

Просмотреть файл

@ -38,7 +38,7 @@ var NavigatorIOSExample = React.createClass({
_previousLeft: 0,
_previousTop: 0,
_circleStyles: {},
circle: (null : ?React.Element),
circle: (null : ?{ setNativeProps(props: Object): void }),
componentWillMount: function() {
this._panResponder = PanResponder.create({

Просмотреть файл

@ -6,18 +6,25 @@
* 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 Animation
* @providesModule AnimationExperimental
* @flow
*/
'use strict';
var RCTAnimationManager = require('NativeModules').AnimationManager;
var RCTAnimationManager = require('NativeModules').AnimationExperimentalManager;
var AnimationUtils = require('AnimationUtils');
type EasingFunction = (t: number) => number;
var Animation = {
Mixin: require('AnimationMixin'),
/**
* This is an experimental module that is under development, incomplete,
* potentially buggy, not used in any production apps, and will probably change
* in non-backward compatible ways.
*
* Use at your own risk.
*/
var AnimationExperimental = {
Mixin: require('AnimationExperimentalMixin'),
startAnimation: function(
node: any,
@ -28,7 +35,14 @@ var Animation = {
): number {
var nodeHandle = +node.getNodeHandle();
var easingSample = AnimationUtils.evaluateEasingFunction(duration, easing);
var tag: number = RCTAnimationManager.startAnimation(nodeHandle, AnimationUtils.allocateTag(), duration, delay, easingSample, properties);
var tag: number = RCTAnimationManager.startAnimation(
nodeHandle,
AnimationUtils.allocateTag(),
duration,
delay,
easingSample,
properties
);
return tag;
},
@ -37,4 +51,4 @@ var Animation = {
},
};
module.exports = Animation;
module.exports = AnimationExperimental;

Просмотреть файл

@ -6,19 +6,26 @@
* 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 AnimationMixin
* @providesModule AnimationExperimentalMixin
* @flow
*/
'use strict';
var AnimationUtils = require('AnimationUtils');
var RCTAnimationManager = require('NativeModules').AnimationManager;
var RCTAnimationManager = require('NativeModules').AnimationExperimentalManager;
var invariant = require('invariant');
type EasingFunction = (t: number) => number;
var AnimationMixin = {
/**
* This is an experimental module that is under development, incomplete,
* potentially buggy, not used in any production apps, and will probably change
* in non-backward compatible ways.
*
* Use at your own risk.
*/
var AnimationExperimentalMixin = {
getInitialState: function(): Object {
return {};
},
@ -48,4 +55,4 @@ var AnimationMixin = {
},
};
module.exports = AnimationMixin;
module.exports = AnimationExperimentalMixin;

Просмотреть файл

@ -7,7 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
13BE3DEE1AC21097009241FE /* RCTAnimationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BE3DED1AC21097009241FE /* RCTAnimationManager.m */; };
13BE3DEE1AC21097009241FE /* RCTAnimationExperimentalManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BE3DED1AC21097009241FE /* RCTAnimationExperimentalManager.m */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@ -23,9 +23,9 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
134814201AA4EA6300B7C361 /* libRCTAnimation.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTAnimation.a; sourceTree = BUILT_PRODUCTS_DIR; };
13BE3DEC1AC21097009241FE /* RCTAnimationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAnimationManager.h; sourceTree = "<group>"; };
13BE3DED1AC21097009241FE /* RCTAnimationManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAnimationManager.m; sourceTree = "<group>"; };
134814201AA4EA6300B7C361 /* libRCTAnimationExperimental.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRCTAnimationExperimental.a; sourceTree = BUILT_PRODUCTS_DIR; };
13BE3DEC1AC21097009241FE /* RCTAnimationExperimentalManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTAnimationExperimentalManager.h; sourceTree = "<group>"; };
13BE3DED1AC21097009241FE /* RCTAnimationExperimentalManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTAnimationExperimentalManager.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -42,7 +42,7 @@
134814211AA4EA7D00B7C361 /* Products */ = {
isa = PBXGroup;
children = (
134814201AA4EA6300B7C361 /* libRCTAnimation.a */,
134814201AA4EA6300B7C361 /* libRCTAnimationExperimental.a */,
);
name = Products;
sourceTree = "<group>";
@ -50,8 +50,8 @@
58B511D21A9E6C8500147676 = {
isa = PBXGroup;
children = (
13BE3DEC1AC21097009241FE /* RCTAnimationManager.h */,
13BE3DED1AC21097009241FE /* RCTAnimationManager.m */,
13BE3DEC1AC21097009241FE /* RCTAnimationExperimentalManager.h */,
13BE3DED1AC21097009241FE /* RCTAnimationExperimentalManager.m */,
134814211AA4EA7D00B7C361 /* Products */,
);
sourceTree = "<group>";
@ -59,9 +59,9 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
58B511DA1A9E6C8500147676 /* RCTAnimation */ = {
58B511DA1A9E6C8500147676 /* RCTAnimationExperimental */ = {
isa = PBXNativeTarget;
buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTAnimation" */;
buildConfigurationList = 58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTAnimationExperimental" */;
buildPhases = (
58B511D71A9E6C8500147676 /* Sources */,
58B511D81A9E6C8500147676 /* Frameworks */,
@ -71,9 +71,9 @@
);
dependencies = (
);
name = RCTAnimation;
name = RCTAnimationExperimental;
productName = RCTDataManager;
productReference = 134814201AA4EA6300B7C361 /* libRCTAnimation.a */;
productReference = 134814201AA4EA6300B7C361 /* libRCTAnimationExperimental.a */;
productType = "com.apple.product-type.library.static";
};
/* End PBXNativeTarget section */
@ -90,7 +90,7 @@
};
};
};
buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTAnimation" */;
buildConfigurationList = 58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTAnimationExperimental" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
@ -102,7 +102,7 @@
projectDirPath = "";
projectRoot = "";
targets = (
58B511DA1A9E6C8500147676 /* RCTAnimation */,
58B511DA1A9E6C8500147676 /* RCTAnimationExperimental */,
);
};
/* End PBXProject section */
@ -112,7 +112,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
13BE3DEE1AC21097009241FE /* RCTAnimationManager.m in Sources */,
13BE3DEE1AC21097009241FE /* RCTAnimationExperimentalManager.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -203,7 +203,7 @@
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = RCTAnimation;
PRODUCT_NAME = RCTAnimationExperimental;
SKIP_INSTALL = YES;
};
name = Debug;
@ -218,7 +218,7 @@
);
LIBRARY_SEARCH_PATHS = "$(inherited)";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = RCTAnimation;
PRODUCT_NAME = RCTAnimationExperimental;
SKIP_INSTALL = YES;
};
name = Release;
@ -226,7 +226,7 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTAnimation" */ = {
58B511D61A9E6C8500147676 /* Build configuration list for PBXProject "RCTAnimationExperimental" */ = {
isa = XCConfigurationList;
buildConfigurations = (
58B511ED1A9E6C8500147676 /* Debug */,
@ -235,7 +235,7 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTAnimation" */ = {
58B511EF1A9E6C8500147676 /* Build configuration list for PBXNativeTarget "RCTAnimationExperimental" */ = {
isa = XCConfigurationList;
buildConfigurations = (
58B511F01A9E6C8500147676 /* Debug */,

Просмотреть файл

@ -12,6 +12,6 @@
#import "RCTBridgeModule.h"
@interface RCTAnimationManager : NSObject <RCTBridgeModule>
@interface RCTAnimationExperimentalManager : NSObject <RCTBridgeModule>
@end

Просмотреть файл

@ -7,7 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "RCTAnimationManager.h"
#import "RCTAnimationExperimentalManager.h"
#import <UIKit/UIKit.h>
@ -20,7 +20,7 @@
#define CG_APPEND(PREFIX, SUFFIX_F, SUFFIX_D) PREFIX##SUFFIX_F
#endif
@implementation RCTAnimationManager
@implementation RCTAnimationExperimentalManager
{
RCTSparseArray *_animationRegistry; // Main thread only; animation tag -> view tag
}
@ -65,9 +65,9 @@
{
RCT_EXPORT(startAnimation);
__weak RCTAnimationManager *weakSelf = self;
__weak RCTAnimationExperimentalManager *weakSelf = self;
[_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
RCTAnimationManager *strongSelf = weakSelf;
RCTAnimationExperimentalManager *strongSelf = weakSelf;
UIView *view = viewRegistry[reactTag];
if (!view) {
@ -182,9 +182,9 @@
{
RCT_EXPORT(stopAnimation);
__weak RCTAnimationManager *weakSelf = self;
__weak RCTAnimationExperimentalManager *weakSelf = self;
[_bridge.uiManager addUIBlock:^(RCTUIManager *uiManager, RCTSparseArray *viewRegistry) {
RCTAnimationManager *strongSelf = weakSelf;
RCTAnimationExperimentalManager *strongSelf = weakSelf;
NSNumber *reactTag = strongSelf->_animationRegistry[animationTag];
if (!reactTag) return;

Просмотреть файл

@ -364,10 +364,16 @@ var ScrollResponderMixin = {
/**
* This method should be used as the callback to onFocus in a TextInputs'
* parent view. Note that any module using this mixin needs to return
* the parent view's ref in getScrollViewRef() in order to use this method
* the parent view's ref in getScrollViewRef() in order to use this method.
* @param {any} nodeHandle The TextInput node handle
* @param {number} additionalOffset The scroll view's top "contentInset".
* Default is 0.
* @param {bool} preventNegativeScrolling Whether to allow pulling the content
* down to make it meet the keyboard's top. Default is false.
*/
scrollResponderScrollNativeHandleToKeyboard: function(nodeHandle: any, additionalOffset?: number) {
scrollResponderScrollNativeHandleToKeyboard: function(nodeHandle: any, additionalOffset?: number, preventNegativeScrollOffset?: bool) {
this.additionalScrollOffset = additionalOffset || 0;
this.preventNegativeScrollOffset = !!preventNegativeScrollOffset;
RCTUIManager.measureLayout(
nodeHandle,
this.getNodeHandle(),
@ -386,14 +392,23 @@ var ScrollResponderMixin = {
* @param {number} width Width of the text input.
* @param {number} height Height of the text input.
*/
scrollResponderInputMeasureAndScrollToKeyboard: function(left: number, top: number, width: number, height: number) {
scrollResponderInputMeasureAndScrollToKeyboard: function(left: number, top: number, width: number, height: number) {
if (this.keyboardWillOpenTo) {
var scrollOffsetY =
top - this.keyboardWillOpenTo.endCoordinates.screenY + height +
this.additionalScrollOffset;
// By default, this can scroll with negative offset, pulling the content
// down so that the target component's bottom meets the keyboard's top.
// If requested otherwise, cap the offset at 0 minimum to avoid content
// shifting down.
if (this.preventNegativeScrollOffset) {
scrollOffsetY = Math.max(0, scrollOffsetY);
}
this.scrollResponderScrollTo(0, scrollOffsetY);
}
this.additionalOffset = 0;
this.preventNegativeScrollOffset = false;
},
scrollResponderTextInputFocusError: function(e: Event) {

Просмотреть файл

@ -40,7 +40,7 @@ var SliderIOS = React.createClass({
* 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 it's inital value.
* the value, the component won't be reset to its inital value.
*/
value: PropTypes.number,
@ -82,6 +82,8 @@ var SliderIOS = React.createClass({
<RCTSlider
style={[styles.slider, this.props.style]}
value={this.props.value}
maximumValue={this.props.maximumValue}
minimumValue={this.props.minimumValue}
onChange={this._onValueChange}
/>
);
@ -94,8 +96,15 @@ var styles = StyleSheet.create({
},
});
var validAttributes = {
...ReactIOSViewAttributes.UIView,
value: true,
minimumValue: true,
maximumValue: true,
};
var RCTSlider = createReactIOSNativeComponentClass({
validAttributes: merge(ReactIOSViewAttributes.UIView, {value: true}),
validAttributes: validAttributes,
uiViewClassName: 'RCTSlider',
});

Просмотреть файл

@ -217,8 +217,6 @@ var TextInput = React.createClass({
*/
onFocus: PropTypes.func,
/**
* (text: string) => void
*
* Callback that is called when the text input's text changes.
*/
onChange: PropTypes.func,

Просмотреть файл

@ -14,7 +14,7 @@
var NativeMethodsMixin = require('NativeMethodsMixin');
var React = require('React');
var POPAnimation = require('POPAnimation');
var Animation = require('Animation');
var AnimationExperimental = require('AnimationExperimental');
var Touchable = require('Touchable');
var merge = require('merge');
@ -79,7 +79,7 @@ var TouchableBounce = React.createClass({
this.state.animationID = POPAnimation.createSpringAnimation(anim);
this.addAnimation(this.state.animationID, callback);
} else {
Animation.startAnimation(this, 300, 0, 'easeOutBack', {scaleXY: [value, value]});
AnimationExperimental.startAnimation(this, 300, 0, 'easeOutBack', {scaleXY: [value, value]});
if (fromValue && typeof fromValue === 'function') {
callback = fromValue;
}

Просмотреть файл

@ -13,7 +13,6 @@
var React = require('React');
var Touchable = require('Touchable');
var onlyChild = require('onlyChild');
/**
@ -78,10 +77,8 @@ var TouchableWithoutFeedback = React.createClass({
},
render: function(): ReactElement {
// Note(vjeux): use cloneWithProps once React has been upgraded
var child = onlyChild(this.props.children);
// Note(avik): remove dynamic typecast once Flow has been upgraded
return (React: any).cloneElement(child, {
return (React: any).cloneElement(onlyChild(this.props.children), {
accessible: true,
testID: this.props.testID,
onStartShouldSetResponder: this.touchableHandleStartShouldSetResponder,

Просмотреть файл

@ -7,6 +7,7 @@
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule View
* @flow
*/
'use strict';

Просмотреть файл

@ -32,38 +32,6 @@ var invariant = require('invariant');
var isEmpty = require('isEmpty');
var warning = require('warning');
/**
* ListViewDataSource - Provides efficient data processing and access to the
* ListView component. A ListViewDataSource is created with functions for
* extracting data from the input blob, and comparing elements (with default
* implementations for convenience). The input blob can be as simple as an
* array of strings, or an object with rows nested inside section objects.
*
* To update the data in the datasource, use `cloneWithRows` (or
* `cloneWithRowsAndSections` if you care about sections). The data in the
* data source is immutable, so you can't modify it directly. The clone methods
* suck in the new data and compute a diff for each row so ListView knows
* whether to re-render it or not.
*
* In this example, a component receives data in chunks, handled by
* `_onDataArrived`, which concats the new data onto the old data and updates the
* data source. We use `concat` to create a new array - mutating `this._data`,
* e.g. with `this._data.push(newRowData)`, would be an error. `_rowHasChanged`
* understands the shape of the row data and knows how to efficiently compare
* it.
*
* getInitialState: function() {
* var ds = new ListViewDataSource({rowHasChanged: this._rowHasChanged});
* return {ds};
* },
* _onDataArrived(newData) {
* this._data = this._data.concat(newData);
* this.setState({
* ds: this.state.ds.cloneWithRows(this._data)
* });
* }
*/
function defaultGetRowData(
dataBlob: any,
sectionID: number | string,
@ -88,15 +56,58 @@ type ParamType = {
getSectionHeaderData: ?typeof defaultGetSectionHeaderData;
}
/**
* Provides efficient data processing and access to the
* `ListView` component. A `ListViewDataSource` is created with functions for
* extracting data from the input blob, and comparing elements (with default
* implementations for convenience). The input blob can be as simple as an
* array of strings, or an object with rows nested inside section objects.
*
* To update the data in the datasource, use `cloneWithRows` (or
* `cloneWithRowsAndSections` if you care about sections). The data in the
* data source is immutable, so you can't modify it directly. The clone methods
* suck in the new data and compute a diff for each row so ListView knows
* whether to re-render it or not.
*
* In this example, a component receives data in chunks, handled by
* `_onDataArrived`, which concats the new data onto the old data and updates the
* data source. We use `concat` to create a new array - mutating `this._data`,
* e.g. with `this._data.push(newRowData)`, would be an error. `_rowHasChanged`
* understands the shape of the row data and knows how to efficiently compare
* it.
*
* ```
* getInitialState: function() {
* var ds = new ListViewDataSource({rowHasChanged: this._rowHasChanged});
* return {ds};
* },
* _onDataArrived(newData) {
* this._data = this._data.concat(newData);
* this.setState({
* ds: this.state.ds.cloneWithRows(this._data)
* });
* }
* ```
*/
class ListViewDataSource {
/**
* @param {ParamType} params
*
* You can provide custom extraction and 'hasChanged' functions for section
* You can provide custom extraction and `hasChanged` functions for section
* headers and rows. If absent, data will be extracted with the
* `defaultGetRowData` and `defaultGetSectionHeaderData` functions.
*
* The default extractor expects data of one of the following forms:
*
* { sectionID_1: { rowID_1: <rowData1>, ... }, ... }
*
* or
*
* [ [ <rowData1>, <rowData2>, ... ], ... ]
*
* The constructor takes in a params argument that can contain any of the
* following:
*
* - getRowData(dataBlob, sectionID, rowID);
* - getSectionHeaderData(dataBlob, sectionID);
* - rowHasChanged(prevRowData, nextRowData);
@ -125,14 +136,25 @@ class ListViewDataSource {
}
/**
* @param {object} dataBlob -- This is an arbitrary blob of data. An extractor
* function was defined at construction time. The default extractor assumes
* the data is a plain array or keyed object.
*/
cloneWithRows(
dataBlob: Array<any> | {[key: string]: any},
rowIdentities: ?Array<string>
): ListViewDataSource {
* Clones this `ListViewDataSource` with the specified `dataBlob` and
* `rowIdentities`. The `dataBlob` is just an aribitrary blob of data. At
* construction an extractor to get the interesting informatoin was defined
* (or the default was used).
*
* The `rowIdentities` is is a 2D array of identifiers for rows.
* ie. [['a1', 'a2'], ['b1', 'b2', 'b3'], ...]. If not provided, it's
* assumed that the keys of the section data are the row identities.
*
* Note: This function does NOT clone the data in this data source. It simply
* passes the functions defined at construction to a new data source with
* the data specified. If you wish to maintain the existing data you must
* handle merging of old and new data separately and then pass that into
* this function as the `dataBlob`.
*/
cloneWithRows(
dataBlob: Array<any> | {[key: string]: any},
rowIdentities: ?Array<string>
): ListViewDataSource {
var rowIds = rowIdentities ? [rowIdentities] : null;
if (!this._sectionHeaderHasChanged) {
this._sectionHeaderHasChanged = () => false;
@ -141,29 +163,20 @@ class ListViewDataSource {
}
/**
* @param {object} dataBlob -- This is an arbitrary blob of data. An extractor
* function was defined at construction time. The default extractor assumes
* the data is a nested array or keyed object of the form:
* This performs the same function as the `cloneWithRows` function but here
* you also specify what your `sectionIdentities` are. If you don't care
* about sections you should safely be able to use `cloneWithRows`.
*
* { sectionID_1: { rowID_1: <rowData1>, ... }, ... }
*
* or
*
* [ [ <rowData1>, <rowData2>, ... ], ... ]
*
* @param {array} sectionIdentities -- This is an array of identifiers for
* sections. ie. ['s1', 's2', ...]. If not provided, it's assumed that the
* keys of dataBlob are the section identities.
* @param {array} rowIdentities -- This is a 2D array of identifiers for rows.
* ie. [['a1', 'a2'], ['b1', 'b2', 'b3'], ...]. If not provided, it's
* assumed that the keys of the section data are the row identities.
* `sectionIdentities` is an array of identifiers for sections.
* ie. ['s1', 's2', ...]. If not provided, it's assumed that the
* keys of dataBlob are the section identities.
*
* Note: this returns a new object!
*/
cloneWithRowsAndSections(
dataBlob: any,
sectionIdentities: ?Array<string>,
rowIdentities: ?Array<Array<string>>
dataBlob: any,
sectionIdentities: ?Array<string>,
rowIdentities: ?Array<Array<string>>
): ListViewDataSource {
invariant(
typeof this._sectionHeaderHasChanged === 'function',
@ -205,9 +218,6 @@ class ListViewDataSource {
}
/**
* @param {number} sectionIndex
* @param {number} rowIndex
*
* Returns if the row is dirtied and needs to be rerendered
*/
rowShouldUpdate(sectionIndex: number, rowIndex: number): bool {
@ -218,9 +228,6 @@ class ListViewDataSource {
}
/**
* @param {number} sectionIndex
* @param {number} rowIndex
*
* Gets the data required to render the row.
*/
getRowData(sectionIndex: number, rowIndex: number): any {
@ -234,8 +241,6 @@ class ListViewDataSource {
}
/**
* @param {number} index
*
* Gets the rowID at index provided if the dataSource arrays were flattened,
* or null of out of range indexes.
*/
@ -252,8 +257,6 @@ class ListViewDataSource {
}
/**
* @param {number} index
*
* Gets the sectionID at index provided if the dataSource arrays were flattened,
* or null for out of range indexes.
*/
@ -281,8 +284,6 @@ class ListViewDataSource {
}
/**
* @param {number} sectionIndex
*
* Returns if the section header is dirtied and needs to be rerendered
*/
sectionHeaderShouldUpdate(sectionIndex: number): bool {
@ -293,8 +294,6 @@ class ListViewDataSource {
}
/**
* @param {number} sectionIndex
*
* Gets the data required to render the section header
*/
getSectionHeaderData(sectionIndex: number): any {

Просмотреть файл

@ -54,8 +54,6 @@ var SCREEN_HEIGHT = Dimensions.get('window').height;
var OFF_SCREEN = {style: {opacity: 0}};
var NAVIGATION_BAR_REF = 'navigationBar_ref';
var __uid = 0;
function getuid() {
return __uid++;
@ -94,6 +92,12 @@ var styles = StyleSheet.create({
}
});
var GESTURE_ACTIONS = [
'pop',
'jumpBack',
'jumpForward',
];
/**
* Use `Navigator` to transition between different scenes in your app. To
* accomplish this, provide route objects to the navigator to identify each
@ -314,6 +318,7 @@ var Navigator = React.createClass({
popToRoute: this.popToRoute,
popToTop: this.popToTop,
parentNavigator: this.props.navigator,
getCurrentRoutes: this.getCurrentRoutes,
// We want to bubble focused routes to the top navigation stack. If we
// are a child navigator, this allows us to call props.navigator.on*Focus
// of the topmost Navigator
@ -457,15 +462,18 @@ var Navigator = React.createClass({
_completeTransition: function() {
if (this.spring.getCurrentValue() === 1) {
var presentedIndex = this.state.toIndex;
this.state.fromIndex = presentedIndex;
this.state.presentedIndex = presentedIndex;
this.state.fromIndex = presentedIndex;
this._emitDidFocus(presentedIndex);
this._removePoppedRoutes();
if (AnimationsDebugModule) {
AnimationsDebugModule.stopRecordingFps(Date.now());
}
this._hideOtherScenes(presentedIndex);
} else {
this.state.fromIndex = this.state.presentedIndex;
this.state.toIndex = this.state.presentedIndex;
}
this._hideOtherScenes(presentedIndex);
},
_transitionToToIndexWithVelocity: function(v) {
@ -499,6 +507,10 @@ var Navigator = React.createClass({
_emitWillFocus: function(index) {
var route = this.state.routeStack[index];
var navBar = this._navBar;
if (navBar && navBar.handleWillFocus) {
navBar.handleWillFocus(route);
}
if (this.props.onWillFocus) {
this.props.onWillFocus(route);
} else if (this.props.navigator && this.props.navigator.onWillFocus) {
@ -532,95 +544,170 @@ var Navigator = React.createClass({
_handleMoveShouldSetPanResponder: function(e, gestureState) {
var currentRoute = this.state.routeStack[this.state.presentedIndex];
var animationConfig = this.state.sceneConfigStack[this.state.presentedIndex];
if (!animationConfig.enableGestures) {
return false;
}
var currentLoc = animationConfig.isVertical ? gestureState.moveY : gestureState.moveX;
var travelDist = animationConfig.isVertical ? gestureState.dy : gestureState.dx;
var oppositeAxisTravelDist =
animationConfig.isVertical ? gestureState.dx : gestureState.dy;
var moveStartedInRegion = currentLoc < animationConfig.edgeHitWidth;
var moveTravelledFarEnough =
travelDist >= animationConfig.gestureDetectMovement &&
travelDist > oppositeAxisTravelDist * animationConfig.directionRatio;
return (
!this.state.isResponderOnlyToBlockTouches &&
moveStartedInRegion &&
!this.state.isAnimating &&
this.state.presentedIndex > 0 &&
moveTravelledFarEnough
);
var sceneConfig = this.state.sceneConfigStack[this.state.presentedIndex];
this._expectingGestureGrant = this._matchGestureAction(sceneConfig.gestures, gestureState);
return !! this._expectingGestureGrant;
},
_doesGestureOverswipe: function(gestureName) {
var wouldOverswipeBack = this.state.presentedIndex <= 0 &&
(gestureName === 'pop' || gestureName === 'jumpBack');
var wouldOverswipeForward = this.state.presentedIndex >= this.state.routeStack.length - 1 &&
gestureName === 'jumpForward';
return wouldOverswipeForward || wouldOverswipeBack;
},
_handlePanResponderGrant: function(e, gestureState) {
invariant(
this._expectingGestureGrant,
'Responder granted unexpectedly.'
);
this._activeGestureAction = this._expectingGestureGrant;
this._expectingGestureGrant = null;
this.state.isResponderOnlyToBlockTouches = this.state.isAnimating;
if (!this.state.isAnimating) {
this.state.fromIndex = this.state.presentedIndex;
this.state.toIndex = this.state.presentedIndex - 1;
var gestureSceneDelta = this._deltaForGestureAction(this._activeGestureAction);
this.state.toIndex = this.state.presentedIndex + gestureSceneDelta;
}
},
_deltaForGestureAction: function(gestureAction) {
switch (gestureAction) {
case 'pop':
case 'jumpBack':
return -1;
case 'jumpForward':
return 1;
default:
invariant(false, 'Unsupported gesture action ' + gestureAction);
return;
}
},
_handlePanResponderRelease: function(e, gestureState) {
var sceneConfig = this.state.sceneConfigStack[this.state.presentedIndex];
var releaseGestureAction = this._activeGestureAction;
this._activeGestureAction = null;
if (this.state.isResponderOnlyToBlockTouches) {
this.state.isResponderOnlyToBlockTouches = false;
return;
}
var animationConfig = this.state.sceneConfigStack[this.state.presentedIndex];
var velocity = animationConfig.isVertical ? gestureState.vy : gestureState.vx;
// It's not the real location. There is no *real* location - that's the
// point of the pan gesture.
var pseudoLocation = animationConfig.isVertical ?
gestureState.y0 + gestureState.dy :
gestureState.x0 + gestureState.dx;
var still = Math.abs(velocity) < animationConfig.notMoving;
var releaseGesture = sceneConfig.gestures[releaseGestureAction];
if (this.spring.getCurrentValue() === 0) {
// The spring is at zero, so the gesture is already complete
this.spring.setCurrentValue(0).setAtRest();
this._completeTransition();
return;
}
var transitionVelocity =
still && animationConfig.pastPointOfNoReturn(pseudoLocation) ? animationConfig.snapVelocity :
still && !animationConfig.pastPointOfNoReturn(pseudoLocation) ? -animationConfig.snapVelocity :
clamp(-10, velocity, 10); // What are Rebound UoM?
var isTravelVertical = releaseGesture.direction === 'top-to-bottom' || releaseGesture.direction === 'bottom-to-top';
var isTravelInverted = releaseGesture.direction === 'right-to-left' || releaseGesture.direction === 'bottom-to-top';
var velocity, gestureDistance;
if (isTravelVertical) {
velocity = isTravelInverted ? -gestureState.vy : gestureState.vy;
gestureDistance = isTravelInverted ? -gestureState.dy : gestureState.dy;
} else {
velocity = isTravelInverted ? -gestureState.vx : gestureState.vx;
gestureDistance = isTravelInverted ? -gestureState.dx : gestureState.dx;
}
var transitionVelocity = clamp(-10, velocity, 10);
if (Math.abs(velocity) < releaseGesture.notMoving) {
// The gesture velocity is so slow, is "not moving"
var hasGesturedEnoughToComplete = gestureDistance > releaseGesture.fullDistance * releaseGesture.stillCompletionRatio;
transitionVelocity = hasGesturedEnoughToComplete ? releaseGesture.snapVelocity : -releaseGesture.snapVelocity;
}
this.spring.setOvershootClampingEnabled(true);
if (transitionVelocity < 0) {
if (transitionVelocity < 0 || this._doesGestureOverswipe(releaseGestureAction)) {
this._transitionToFromIndexWithVelocity(transitionVelocity);
} else {
this._manuallyPopBackstack(1);
this._transitionToToIndexWithVelocity(transitionVelocity);
}
},
_handlePanResponderTerminate: function(e, gestureState) {
this._activeGestureAction = null;
this.state.isResponderOnlyToBlockTouches = false;
this._transitionToFromIndexWithVelocity(0);
},
_handlePanResponderMove: function(e, gestureState) {
if (!this.state.isResponderOnlyToBlockTouches) {
var animationConfig = this.state.sceneConfigStack[this.state.presentedIndex];
var distance = animationConfig.isVertical ? gestureState.dy : gestureState.dx;
var gestureDetectMovement = animationConfig.gestureDetectMovement;
var sceneConfig = this.state.sceneConfigStack[this.state.presentedIndex];
var gesture = sceneConfig.gestures[this._activeGestureAction];
var isTravelVertical = gesture.direction === 'top-to-bottom' || gesture.direction === 'bottom-to-top';
var isTravelInverted = gesture.direction === 'right-to-left' || gesture.direction === 'bottom-to-top';
var distance = isTravelVertical ? gestureState.dy : gestureState.dx;
distance = isTravelInverted ? - distance : distance;
var gestureDetectMovement = gesture.gestureDetectMovement;
var nextProgress = (distance - gestureDetectMovement) /
(animationConfig.screenDimension - gestureDetectMovement);
(gesture.fullDistance - gestureDetectMovement);
if (this._doesGestureOverswipe(this._activeGestureAction)) {
var frictionConstant = gesture.overswipe.frictionConstant;
var frictionByDistance = gesture.overswipe.frictionByDistance;
var frictionRatio = 1 / ((frictionConstant) + (Math.abs(nextProgress) * frictionByDistance));
nextProgress *= frictionRatio;
}
this.spring.setCurrentValue(clamp(0, nextProgress, 1));
}
},
_matchGestureAction: function(gestures, gestureState) {
if (!gestures) {
return null;
}
if (this.state.isResponderOnlyToBlockTouches || this.state.isAnimating) {
return null;
}
var matchedGesture = null;
GESTURE_ACTIONS.some((gestureName) => {
var gesture = gestures[gestureName];
if (!gesture) {
return;
}
if (gesture.overswipe == null && this._doesGestureOverswipe(gestureName)) {
// cannot swipe past first or last scene without overswiping
return false;
}
var isTravelVertical = gesture.direction === 'top-to-bottom' || gesture.direction === 'bottom-to-top';
var isTravelInverted = gesture.direction === 'right-to-left' || gesture.direction === 'bottom-to-top';
var currentLoc = isTravelVertical ? gestureState.moveY : gestureState.moveX;
var travelDist = isTravelVertical ? gestureState.dy : gestureState.dx;
var oppositeAxisTravelDist =
isTravelVertical ? gestureState.dx : gestureState.dy;
if (isTravelInverted) {
currentLoc = -currentLoc;
travelDist = -travelDist;
oppositeAxisTravelDist = -oppositeAxisTravelDist;
}
var moveStartedInRegion = gesture.edgeHitWidth == null ||
currentLoc < gesture.edgeHitWidth;
var moveTravelledFarEnough =
travelDist >= gesture.gestureDetectMovement &&
travelDist > oppositeAxisTravelDist * gesture.directionRatio;
if (moveStartedInRegion && moveTravelledFarEnough) {
matchedGesture = gestureName;
return true;
}
});
return matchedGesture;
},
_transitionSceneStyle: function(fromIndex, toIndex, progress, index) {
var viewAtIndex = this.refs['scene_' + index];
if (viewAtIndex === null || viewAtIndex === undefined) {
return;
}
// Use toIndex animation when we move forwards. Use fromIndex when we move back
var animationIndex = this.state.presentedIndex < toIndex ? toIndex : fromIndex;
var animationConfig = this.state.sceneConfigStack[animationIndex];
var sceneConfigIndex = this.state.presentedIndex < toIndex ? toIndex : fromIndex;
var sceneConfig = this.state.sceneConfigStack[sceneConfigIndex];
// this happens for overswiping when there is no scene at toIndex
if (!sceneConfig) {
sceneConfig = this.state.sceneConfigStack[sceneConfigIndex - 1];
}
var styleToUse = {};
var useFn = index < fromIndex || index < toIndex ?
animationConfig.interpolators.out :
animationConfig.interpolators.into;
sceneConfig.animationInterpolators.out :
sceneConfig.animationInterpolators.into;
var directionAdjustedProgress = fromIndex < toIndex ? progress : 1 - progress;
var didChange = useFn(styleToUse, directionAdjustedProgress);
if (didChange) {
@ -631,7 +718,7 @@ var Navigator = React.createClass({
_transitionBetween: function(fromIndex, toIndex, progress) {
this._transitionSceneStyle(fromIndex, toIndex, progress, fromIndex);
this._transitionSceneStyle(fromIndex, toIndex, progress, toIndex);
var navBar = this.refs[NAVIGATION_BAR_REF];
var navBar = this._navBar;
if (navBar && navBar.updateProgress) {
navBar.updateProgress(progress, fromIndex, toIndex);
}
@ -912,6 +999,10 @@ var Navigator = React.createClass({
}
},
getCurrentRoutes: function() {
return this.state.routeStack;
},
_onItemRef: function(itemId, ref) {
this._itemRefs[itemId] = ref;
var itemIndex = this.state.idStack.indexOf(itemId);
@ -989,7 +1080,7 @@ var Navigator = React.createClass({
return null;
}
return React.cloneElement(this.props.navigationBar, {
ref: NAVIGATION_BAR_REF,
ref: (navBar) => { this._navBar = navBar; },
navigator: this.navigatorActions,
navState: this.state,
});

Просмотреть файл

@ -30,7 +30,6 @@ var Dimensions = require('Dimensions');
var PixelRatio = require('PixelRatio');
var buildStyleInterpolator = require('buildStyleInterpolator');
var merge = require('merge');
var SCREEN_WIDTH = Dimensions.get('window').width;
var SCREEN_HEIGHT = Dimensions.get('window').height;
@ -220,32 +219,12 @@ var FromTheFront = {
},
};
var Interpolators = {
Vertical: {
into: buildStyleInterpolator(FromTheFront),
out: buildStyleInterpolator(ToTheBack),
},
Horizontal: {
into: buildStyleInterpolator(FromTheRight),
out: buildStyleInterpolator(ToTheLeft),
},
var BaseOverswipeConfig = {
frictionConstant: 1,
frictionByDistance: 1.5,
};
// These are meant to mimic iOS default behavior
var PastPointOfNoReturn = {
horizontal: function(location) {
return location > SCREEN_WIDTH * 3 / 5;
},
vertical: function(location) {
return location > SCREEN_HEIGHT * 3 / 5;
},
};
var BaseConfig = {
// When false, all gestures are ignored for this scene
enableGestures: true,
var BaseLeftToRightGesture = {
// How far the swipe must drag to start transitioning
gestureDetectMovement: 2,
@ -253,48 +232,88 @@ var BaseConfig = {
// Amplitude of release velocity that is considered still
notMoving: 0.3,
// Velocity to start at when transitioning without gesture
defaultTransitionVelocity: 1.5,
// Fraction of directional move required.
directionRatio: 0.66,
// Velocity to transition with when the gesture release was "not moving"
snapVelocity: 2,
// Region that can trigger swipe. iOS default is 30px from the left edge
edgeHitWidth: 30,
// Ratio of gesture completion when non-velocity release will cause action
stillCompletionRatio: 3 / 5,
fullDistance: SCREEN_WIDTH,
direction: 'left-to-right',
};
var BaseRightToLeftGesture = {
...BaseLeftToRightGesture,
direction: 'right-to-left',
};
var BaseConfig = {
// A list of all gestures that are enabled on this scene
gestures: {
pop: BaseLeftToRightGesture,
},
// Rebound spring parameters when transitioning FROM this scene
springFriction: 26,
springTension: 200,
// Defaults for horizontal transitioning:
// Velocity to start at when transitioning without gesture
defaultTransitionVelocity: 1.5,
isVertical: false,
screenDimension: SCREEN_WIDTH,
// Region that can trigger swipe. iOS default is 30px from the left edge
edgeHitWidth: 30,
// Point at which a non-velocity release will cause nav pop
pastPointOfNoReturn: PastPointOfNoReturn.horizontal,
// Animation interpolators for this transition
interpolators: Interpolators.Horizontal,
// Animation interpolators for horizontal transitioning:
animationInterpolators: {
into: buildStyleInterpolator(FromTheRight),
out: buildStyleInterpolator(ToTheLeft),
},
};
var NavigatorSceneConfigs = {
PushFromRight: merge(BaseConfig, {
PushFromRight: {
...BaseConfig,
// We will want to customize this soon
}),
FloatFromRight: merge(BaseConfig, {
},
FloatFromRight: {
...BaseConfig,
// We will want to customize this soon
}),
FloatFromBottom: merge(BaseConfig, {
edgeHitWidth: 150,
interpolators: Interpolators.Vertical,
isVertical: true,
pastPointOfNoReturn: PastPointOfNoReturn.vertical,
screenDimension: SCREEN_HEIGHT,
}),
},
FloatFromBottom: {
...BaseConfig,
gestures: {
pop: {
...BaseLeftToRightGesture,
edgeHitWidth: 150,
direction: 'top-to-bottom',
fullDistance: SCREEN_HEIGHT,
}
},
animationInterpolators: {
into: buildStyleInterpolator(FromTheFront),
out: buildStyleInterpolator(ToTheBack),
},
},
HorizontalSwipeJump: {
...BaseConfig,
gestures: {
jumpBack: {
...BaseLeftToRightGesture,
overswipe: BaseOverswipeConfig,
edgeHitWidth: null,
},
jumpForward: {
...BaseRightToLeftGesture,
overswipe: BaseOverswipeConfig,
edgeHitWidth: null,
},
}
}
};
module.exports = NavigatorSceneConfigs;

Просмотреть файл

@ -1,70 +0,0 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*
* @providesModule Portal
* @flow
*/
'use strict';
var React = require('React');
var StyleSheet = require('StyleSheet');
var View = require('View');
var _portalRef: any;
/*
* A container that renders all the modals on top of everything else in the application.
*
* Portal makes it possible for application code to pass modal views all the way up to
* the root element created in `renderApplication`.
*
* Never use `<Portal>` in your code. There is only one Portal instance rendered
* by the top-level `renderApplication`.
*/
var Portal = React.createClass({
statics: {
showModal: function(component) {
if (!_portalRef) {
console.error('Calling showModal but no Portal has been rendered');
return;
}
_portalRef.setState({modal: component});
},
closeModal: function() {
if (!_portalRef) {
console.error('Calling closeModal but no Portal has been rendered');
return;
}
_portalRef.setState({modal: null});
},
},
getInitialState: function() {
return {modal: (null: any)};
},
render: function() {
_portalRef = this;
if (!this.state.modal) {
return <View />;
}
return (
<View style={styles.modalsContainer}>
{this.state.modal}
</View>
);
}
});
var styles = StyleSheet.create({
modalsContainer: {
position: 'absolute',
left: 0,
top: 0,
right: 0,
bottom: 0,
},
});
module.exports = Portal;

Просмотреть файл

@ -11,10 +11,7 @@
*/
'use strict';
var Portal = require('Portal');
var React = require('React');
var StyleSheet = require('StyleSheet');
var View = require('View');
var invariant = require('invariant');
@ -28,26 +25,11 @@ function renderApplication<D, P, S>(
'Expect to have a valid rootTag, instead got ', rootTag
);
React.render(
<View style={styles.appContainer}>
<RootComponent
{...initialProps}
/>
<Portal />
</View>,
<RootComponent
{...initialProps}
/>,
rootTag
);
}
var styles = StyleSheet.create({
// This is needed so the application covers the whole screen
// and therefore the contents of the Portal are not clipped.
appContainer: {
position: 'absolute',
left: 0,
top: 0,
right: 0,
bottom: 0,
},
});
module.exports = renderApplication;

Просмотреть файл

@ -20,32 +20,28 @@ var DEFAULT_BUTTON = {
};
/**
* AlertIOS manages native iOS alerts, option sheets, and share dialogs
* 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!')},
* ]
* )}
* ```
*/
class AlertIOS {
/**
* 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!')},
* ]
* )}
* ```
*/
static alert(
title: ?string,
message?: ?string,

1
Libraries/react-native/react-native.js поставляемый
Просмотреть файл

@ -41,7 +41,6 @@ var ReactNative = Object.assign(Object.create(require('React')), {
// APIs
AlertIOS: require('AlertIOS'),
Animation: require('Animation'),
AppRegistry: require('AppRegistry'),
AppStateIOS: require('AppStateIOS'),
AsyncStorage: require('AsyncStorage'),

Просмотреть файл

@ -44,9 +44,9 @@ Pod::Spec.new do |s|
ss.preserve_paths = "Libraries/AdSupport/*.js"
end
s.subspec 'RCTAnimation' do |ss|
s.subspec 'RCTAnimationExperimental' do |ss|
ss.dependency 'React/Core'
ss.source_files = "Libraries/Animation/*.{h,m}"
ss.source_files = "Libraries/Animation/RCTAnimationExperimental*.{h,m}"
ss.preserve_paths = "Libraries/Animation/*.js"
end

1
cli.js
Просмотреть файл

@ -1,4 +1,3 @@
/**
* Copyright 2004-present Facebook. All Rights Reserved.
*/

Просмотреть файл

@ -1,4 +1,4 @@
Displaying images is a fascinating subject, React Native uses some cool tricks to make it a better experience.
Displaying images is a fascinating subject; React Native uses some cool tricks to make it a better experience.
## No Automatic Sizing

Просмотреть файл

@ -15,7 +15,7 @@ This is a more advanced guide that shows how to build a native module. It assume
## iOS Calendar module example
This guide will use [iOS Calendar API](https://developer.apple.com/library/mac/documentation/DataManagement/Conceptual/EventKitProgGuide/Introduction/Introduction.html) example. Let's say we would like to be able to access iOS calendar from JavaScript.
This guide will use [iOS Calendar API](https://developer.apple.com/library/mac/documentation/DataManagement/Conceptual/EventKitProgGuide/Introduction/Introduction.html) example. Let's say we would like to be able to access the iOS calendar from JavaScript.
Native module is just an Objectve-C class that implements `RCTBridgeModule` protocol. If you are wondering, RCT is a shorthand for ReaCT.
@ -52,7 +52,7 @@ CalendarManager.addEventWithName('Birthday Party', '4 Privet Drive, Surrey');
Notice that the exported method name was generated from first part of Objective-C selector. Sometimes it results in a non-idiomatic JavaScript name (like the one in our example). You can change the name by supplying an optional argument to `RCT_EXPORT`, e.g. `RCT_EXPORT(addEvent)`.
The return type of the method should always be `void`. React Native bridge is asynchronous, so the only way to pass result to JavaScript is by using callbacks or emitting events (see below).
The return type of the method should always be `void`. React Native bridge is asynchronous, so the only way to pass a result to JavaScript is by using callbacks or emitting events (see below).
## Argument types
@ -109,7 +109,7 @@ CalendarManager.addEvent('Birthday Party', {
>
> This section is even more experimental than others, we don't have a set of best practices around callbacks yet.
Native module also supports a special kind of argument - callback. In most cases it is used to provide function call result to JavaScript.
Native module also supports a special kind of argument- a callback. In most cases it is used to provide the function call result to JavaScript.
```objective-c
- (void)findEvents:(RCTResponseSenderBlock)callback
@ -120,7 +120,7 @@ Native module also supports a special kind of argument - callback. In most cases
}
```
`RCTResponseSenderBlock` accepts only one argument - array of arguments to pass to JavaScript callback. In this case we use node's convention to set first argument to error and the rest - to the result of the function.
`RCTResponseSenderBlock` accepts only one argument - an array of arguments to pass to the JavaScript callback. In this case we use node's convention to set first argument to error and the rest - to the result of the function.
```javascript
CalendarManager.findEvents((error, events) => {
@ -132,7 +132,7 @@ CalendarManager.findEvents((error, events) => {
})
```
Native module is supposed to invoke callback only once. It can, however, store the callback as an ivar and invoke it later. This pattern is often used to wrap iOS APIs that require delegate. See [`RCTAlertManager`](https://github.com/facebook/react-native/blob/master/React/Modules/RCTAlertManager.m).
Native module is supposed to invoke its callback only once. It can, however, store the callback as an ivar and invoke it later. This pattern is often used to wrap iOS APIs that require delegate. See [`RCTAlertManager`](https://github.com/facebook/react-native/blob/master/React/Modules/RCTAlertManager.m).
If you want to pass error-like object to JavaScript, use `RCTMakeError` from [`RCTUtils.h`](https://github.com/facebook/react-native/blob/master/React/Base/RCTUtils.h).

Просмотреть файл

@ -7,7 +7,7 @@ permalink: docs/network.html
next: timers
---
One of React Native's goals is to be a playground where we can experiment with different architectures and crazy ideas. Since browsers are not flexible enough, we had no choice but to reimplement the entire stack. In the places that we did not intend to change, we tried to be as faithful as possible to the browser APIs. The networking stack is a great example.
One of React Native's goals is to be a playground where we can experiment with different architectures and crazy ideas. Since browsers are not flexible enough, we had no choice but to reimplement the entire stack. In the places that we did not intend to change anything, we tried to be as faithful as possible to the browser APIs. The networking stack is a great example.
## XMLHttpRequest

Просмотреть файл

@ -15,7 +15,7 @@ The React Native repo has several tests you can run to verify you haven't caused
[Jest](http://facebook.github.io/jest/) tests are JS-only tests run on the command line with node. The tests themselves live in the `__tests__` directories of the files they test, and there is a large emphasis on aggressively mocking out functionality that is not under test for failure isolation and maximum speed. You can run the existing React Native jest tests with `npm test` from the react-native root, and we encourage you to add your own tests for any components you want to contribute to. See [`getImageSource-test.js`](https://github.com/facebook/react-native/blob/master/Examples/Movies/__tests__/getImageSource-test.js) for a basic example.
## Integration Tests.
## Integration Tests
React Native provides facilities to make it easier to test integrated components that require both native and JS components to communicate across the bridge. The two main components are `RCTTestRunner` and `RCTTestModule`. `RCTTestRunner` sets up the ReactNative environment and provides facilities to run the tests as `XCTestCase`s in Xcode (`runTest:module` is the simplest method). `RCTTestModule` is exported to JS via `NativeModules` as `TestModule`. The tests themselves are written in JS, and must call `TestModule.markTestCompleted()` when they are done, otherwise the test will timeout and fail. Test failures are primarily indicated by throwing an exception. It is also possible to test error conditions with `runTest:module:initialProps:expectErrorRegex:` or `runTest:module:initialProps:expectErrorBlock:` which will expect an error to be thrown and verify the error matches the provided criteria. See [`IntegrationTestHarnessTest.js`](https://github.com/facebook/react-native/blob/master/IntegrationTests/IntegrationTestHarnessTest.js) and [`IntegrationTestsTests.m`](https://github.com/facebook/react-native/blob/master/IntegrationTests/IntegrationTestsTests/IntegrationTestsTests.m) for example usage.

Просмотреть файл

@ -44,7 +44,7 @@ Edit `AppDelegate.m` to use a different port.
## Watchman took too long to load
Permission settings prevent Watchman from loading. A recent update solves this, get a HEAD install of Watchman if you are experiening this error.
Permission settings prevent Watchman from loading. A recent update solves this, get a HEAD install of Watchman if you are experiencing this error.
```
brew uninstall watchman

Просмотреть файл

@ -47,6 +47,10 @@ function init(root, projectName) {
spawn(path.resolve(__dirname, 'init.sh'), [projectName], {stdio:'inherit'});
}
if (require.main === module) {
run();
}
module.exports = {
run: run,
init: init,

Просмотреть файл

@ -13,7 +13,7 @@ jest
.dontMock('path')
.dontMock('absolute-path')
.dontMock('../docblock')
.dontMock('../../requirePattern')
.dontMock('../../replacePatterns')
.setMock('../../../ModuleDescriptor', function(data) {return data;});
describe('DependencyGraph', function() {
@ -64,7 +64,7 @@ describe('DependencyGraph', function() {
});
});
pit('should get dependencies', function() {
pit('should get dependencies with deprecated assets', function() {
var root = '/root';
fs.__setMockFilesystem({
'root': {
@ -83,7 +83,7 @@ describe('DependencyGraph', function() {
var dgraph = new DependencyGraph({
roots: [root],
fileWatcher: fileWatcher,
assetRoots: ['/root/imgs']
assetRoots_DEPRECATED: ['/root/imgs'],
});
return dgraph.load().then(function() {
expect(dgraph.getOrderedDependencies('/root/index.js'))
@ -98,6 +98,97 @@ describe('DependencyGraph', function() {
});
});
pit('should get dependencies with relative assets', function() {
var root = '/root';
fs.__setMockFilesystem({
'root': {
'index.js': [
'/**',
' * @providesModule index',
' */',
'require("./imgs/a.png")'
].join('\n'),
'imgs': {
'a.png': ''
},
'package.json': JSON.stringify({
name: 'rootPackage'
}),
}
});
var dgraph = new DependencyGraph({
roots: [root],
fileWatcher: fileWatcher,
});
return dgraph.load().then(function() {
expect(dgraph.getOrderedDependencies('/root/index.js'))
.toEqual([
{
id: 'index',
altId: 'rootPackage/index',
path: '/root/index.js',
dependencies: ['./imgs/a.png']
},
{ id: 'rootPackage/imgs/a.png',
path: '/root/imgs/a.png',
dependencies: [],
isAsset: true
},
]);
});
});
pit('Deprecated and relative assets can live together', function() {
var root = '/root';
fs.__setMockFilesystem({
'root': {
'index.js': [
'/**',
' * @providesModule index',
' */',
'require("./imgs/a.png")',
'require("image!a")',
].join('\n'),
'imgs': {
'a.png': ''
},
'package.json': JSON.stringify({
name: 'rootPackage'
}),
}
});
var dgraph = new DependencyGraph({
roots: [root],
fileWatcher: fileWatcher,
assetRoots_DEPRECATED: ['/root/imgs'],
});
return dgraph.load().then(function() {
expect(dgraph.getOrderedDependencies('/root/index.js'))
.toEqual([
{
id: 'index',
altId: 'rootPackage/index',
path: '/root/index.js',
dependencies: ['./imgs/a.png', 'image!a']
},
{
id: 'rootPackage/imgs/a.png',
path: '/root/imgs/a.png',
dependencies: [],
isAsset: true
},
{
id: 'image!a',
path: '/root/imgs/a.png',
dependencies: [],
isAsset: true
},
]);
});
});
pit('should get recursive dependencies', function() {
var root = '/root';
fs.__setMockFilesystem({
@ -821,7 +912,7 @@ describe('DependencyGraph', function() {
});
});
pit('updates module dependencies on asset add', function() {
pit('updates module dependencies on deprecated asset add', function() {
var root = '/root';
var filesystem = fs.__setMockFilesystem({
'root': {
@ -836,7 +927,7 @@ describe('DependencyGraph', function() {
var dgraph = new DependencyGraph({
roots: [root],
assetRoots: [root],
assetRoots_DEPRECATED: [root],
assetExts: ['png'],
fileWatcher: fileWatcher
});
@ -870,6 +961,57 @@ describe('DependencyGraph', function() {
});
});
pit('updates module dependencies on relative asset add', function() {
var root = '/root';
var filesystem = fs.__setMockFilesystem({
'root': {
'index.js': [
'/**',
' * @providesModule index',
' */',
'require("./foo.png")'
].join('\n'),
'package.json': JSON.stringify({
name: 'aPackage'
}),
},
});
var dgraph = new DependencyGraph({
roots: [root],
assetExts: ['png'],
fileWatcher: fileWatcher
});
return dgraph.load().then(function() {
expect(dgraph.getOrderedDependencies('/root/index.js'))
.toEqual([
{ id: 'index', altId: 'aPackage/index',
path: '/root/index.js',
dependencies: ['./foo.png']
}
]);
filesystem.root['foo.png'] = '';
triggerFileChange('add', 'foo.png', root);
return dgraph.load().then(function() {
expect(dgraph.getOrderedDependencies('/root/index.js'))
.toEqual([
{ id: 'index', altId: 'aPackage/index',
path: '/root/index.js',
dependencies: ['./foo.png']
},
{ id: 'aPackage/foo.png',
path: '/root/foo.png',
dependencies: [],
isAsset: true,
},
]);
});
});
});
pit('runs changes through ignore filter', function() {
var root = '/root';
var filesystem = fs.__setMockFilesystem({

Просмотреть файл

@ -12,7 +12,7 @@ var ModuleDescriptor = require('../../ModuleDescriptor');
var Promise = require('bluebird');
var fs = require('fs');
var docblock = require('./docblock');
var requirePattern = require('../requirePattern');
var replacePatterns = require('../replacePatterns');
var path = require('path');
var isAbsolutePath = require('absolute-path');
var debug = require('debug')('DependecyGraph');
@ -37,7 +37,7 @@ var validateOpts = declareOpts({
type: 'object',
required: true,
},
assetRoots: {
assetRoots_DEPRECATED: {
type: 'array',
default: [],
},
@ -51,7 +51,7 @@ function DependecyGraph(options) {
var opts = validateOpts(options);
this._roots = opts.roots;
this._assetRoots = opts.assetRoots;
this._assetRoots_DEPRECATED = opts.assetRoots_DEPRECATED;
this._assetExts = opts.assetExts;
this._ignoreFilePath = opts.ignoreFilePath;
this._fileWatcher = options.fileWatcher;
@ -64,6 +64,10 @@ function DependecyGraph(options) {
this._moduleById = Object.create(null);
this._debugUpdateEvents = [];
this._moduleExtPattern = new RegExp(
'.' + ['js'].concat(this._assetExts).join('|') + '$'
);
// Kick off the search process to precompute the dependency graph.
this._init();
}
@ -75,7 +79,7 @@ DependecyGraph.prototype.load = function() {
this._loading = Promise.all([
this._search(),
this._buildAssetMap(),
this._buildAssetMap_DEPRECATED(),
]);
return this._loading;
@ -147,15 +151,15 @@ DependecyGraph.prototype.resolveDependency = function(
fromModule,
depModuleId
) {
if (this._assetMap != null) {
// Process asset requires.
if (this._assetMap_DEPRECATED != null) {
var assetMatch = depModuleId.match(/^image!(.+)/);
// Process DEPRECATED global asset requires.
if (assetMatch && assetMatch[1]) {
if (!this._assetMap[assetMatch[1]]) {
if (!this._assetMap_DEPRECATED[assetMatch[1]]) {
debug('WARINING: Cannot find asset:', assetMatch[1]);
return null;
}
return this._assetMap[assetMatch[1]];
return this._assetMap_DEPRECATED[assetMatch[1]];
}
}
@ -218,7 +222,11 @@ DependecyGraph.prototype.resolveDependency = function(
// fromModule.path: /x/y/z
// modulePath: /x/y/a/b
var dir = path.dirname(fromModule.path);
modulePath = withExtJs(path.join(dir, depModuleId));
modulePath = path.join(dir, depModuleId);
if (this._assetExts.indexOf(extname(modulePath)) === -1) {
modulePath = withExtJs(modulePath);
}
dep = this._graph[modulePath];
@ -287,7 +295,7 @@ DependecyGraph.prototype._search = function() {
return false;
}
return filePath.match(/\.js$/);
return filePath.match(self._moduleExtPattern);
});
var processing = self._findAndProcessPackage(files, dir)
@ -370,11 +378,21 @@ DependecyGraph.prototype._removePackageFromIndices = function(packageJson) {
* Parse a module and update indices.
*/
DependecyGraph.prototype._processModule = function(modulePath) {
var moduleData = { path: path.resolve(modulePath) };
var module;
if (this._assetExts.indexOf(extname(modulePath)) > -1) {
moduleData.id = this._lookupName(modulePath);
moduleData.isAsset = true;
moduleData.dependencies = [];
module = Promise.resolve(new ModuleDescriptor(moduleData));
this._updateGraphWithModule(module);
}
var self = this;
return readFile(modulePath, 'utf8')
.then(function(content) {
var moduleDocBlock = docblock.parseAsObject(content);
var moduleData = { path: path.resolve(modulePath) };
if (moduleDocBlock.providesModule || moduleDocBlock.provides) {
moduleData.id =
moduleDocBlock.providesModule || moduleDocBlock.provides;
@ -387,7 +405,7 @@ DependecyGraph.prototype._processModule = function(modulePath) {
}
moduleData.dependencies = extractRequires(content);
var module = new ModuleDescriptor(moduleData);
module = new ModuleDescriptor(moduleData);
self._updateGraphWithModule(module);
return module;
});
@ -497,8 +515,8 @@ DependecyGraph.prototype._processFileChange = function(
this._debugUpdateEvents.push({event: eventType, path: filePath});
if (this._assetExts.indexOf(extname(filePath)) > -1) {
this._processAssetChange(eventType, absPath);
return;
this._processAssetChange_DEPRECATED(eventType, absPath);
// Fall through because new-style assets are actually modules.
}
var isPackage = path.basename(filePath) === 'package.json';
@ -554,27 +572,28 @@ DependecyGraph.prototype._getAbsolutePath = function(filePath) {
return null;
};
DependecyGraph.prototype._buildAssetMap = function() {
if (this._assetRoots == null || this._assetRoots.length === 0) {
DependecyGraph.prototype._buildAssetMap_DEPRECATED = function() {
if (this._assetRoots_DEPRECATED == null ||
this._assetRoots_DEPRECATED.length === 0) {
return Promise.resolve();
}
this._assetMap = Object.create(null);
return buildAssetMap(
this._assetRoots,
this._processAsset.bind(this)
this._assetMap_DEPRECATED = Object.create(null);
return buildAssetMap_DEPRECATED(
this._assetRoots_DEPRECATED,
this._processAsset_DEPRECATED.bind(this)
);
};
DependecyGraph.prototype._processAsset = function(file) {
DependecyGraph.prototype._processAsset_DEPRECATED = function(file) {
var ext = extname(file);
if (this._assetExts.indexOf(ext) !== -1) {
var name = assetName(file, ext);
if (this._assetMap[name] != null) {
if (this._assetMap_DEPRECATED[name] != null) {
debug('Conflcting assets', name);
}
this._assetMap[name] = new ModuleDescriptor({
this._assetMap_DEPRECATED[name] = new ModuleDescriptor({
id: 'image!' + name,
path: path.resolve(file),
isAsset: true,
@ -583,18 +602,18 @@ DependecyGraph.prototype._processAsset = function(file) {
}
};
DependecyGraph.prototype._processAssetChange = function(eventType, file) {
if (this._assetMap == null) {
DependecyGraph.prototype._processAssetChange_DEPRECATED = function(eventType, file) {
if (this._assetMap_DEPRECATED == null) {
return;
}
var name = assetName(file, extname(file));
if (eventType === 'change' || eventType === 'delete') {
delete this._assetMap[name];
delete this._assetMap_DEPRECATED[name];
}
if (eventType === 'change' || eventType === 'add') {
this._processAsset(file);
this._processAsset_DEPRECATED(file);
}
};
@ -609,7 +628,11 @@ function extractRequires(code) {
code
.replace(blockCommentRe, '')
.replace(lineCommentRe, '')
.replace(requirePattern, function(match, _, dep) {
.replace(replacePatterns.IMPORT_RE, function(match, pre, quot, dep, post) {
deps.push(dep);
return match;
})
.replace(replacePatterns.REQUIRE_RE, function(match, pre, quot, dep, post) {
deps.push(dep);
});
@ -669,7 +692,7 @@ function readAndStatDir(dir) {
* Given a list of roots and list of extensions find all the files in
* the directory with that extension and build a map of those assets.
*/
function buildAssetMap(roots, processAsset) {
function buildAssetMap_DEPRECATED(roots, processAsset) {
var queue = roots.slice(0);
function search() {

Просмотреть файл

@ -10,7 +10,7 @@
jest.dontMock('../')
.dontMock('q')
.dontMock('../requirePattern')
.dontMock('../replacePatterns')
.setMock('../../ModuleDescriptor', function(data) {return data;});
var Promise = require('bluebird');
@ -228,13 +228,148 @@ describe('HasteDependencyResolver', function() {
var depGraph = depResolver._depGraph;
var dependencies = ['x', 'y', 'z', 'a', 'b'];
/*eslint-disable */
var code = [
"import'x';",
"import 'x';",
"import 'x' ;",
"import Default from 'x';",
"import * as All from 'x';",
"import {} from 'x';",
"import { } from 'x';",
"import {Foo} from 'x';",
"import { Foo } from 'x';",
"import { Foo, } from 'x';",
"import {Foo as Bar} from 'x';",
"import { Foo as Bar } from 'x';",
"import { Foo as Bar, } from 'x';",
"import { Foo, Bar } from 'x';",
"import { Foo, Bar, } from 'x';",
"import { Foo as Bar, Baz } from 'x';",
"import { Foo as Bar, Baz, } from 'x';",
"import { Foo, Bar as Baz } from 'x';",
"import { Foo, Bar as Baz, } from 'x';",
"import { Foo as Bar, Baz as Qux } from 'x';",
"import { Foo as Bar, Baz as Qux, } from 'x';",
"import { Foo, Bar, Baz } from 'x';",
"import { Foo, Bar, Baz, } from 'x';",
"import { Foo as Bar, Baz, Qux } from 'x';",
"import { Foo as Bar, Baz, Qux, } from 'x';",
"import { Foo, Bar as Baz, Qux } from 'x';",
"import { Foo, Bar as Baz, Qux, } from 'x';",
"import { Foo, Bar, Baz as Qux } from 'x';",
"import { Foo, Bar, Baz as Qux, } from 'x';",
"import { Foo as Bar, Baz as Qux, Norf } from 'x';",
"import { Foo as Bar, Baz as Qux, Norf, } from 'x';",
"import { Foo as Bar, Baz, Qux as Norf } from 'x';",
"import { Foo as Bar, Baz, Qux as Norf, } from 'x';",
"import { Foo, Bar as Baz, Qux as Norf } from 'x';",
"import { Foo, Bar as Baz, Qux as Norf, } from 'x';",
"import { Foo as Bar, Baz as Qux, Norf as Enuf } from 'x';",
"import { Foo as Bar, Baz as Qux, Norf as Enuf, } from 'x';",
"import Default, * as All from 'x';",
"import Default, { } from 'x';",
"import Default, { Foo } from 'x';",
"import Default, { Foo, } from 'x';",
"import Default, { Foo as Bar } from 'x';",
"import Default, { Foo as Bar, } from 'x';",
"import Default, { Foo, Bar } from 'x';",
"import Default, { Foo, Bar, } from 'x';",
"import Default, { Foo as Bar, Baz } from 'x';",
"import Default, { Foo as Bar, Baz, } from 'x';",
"import Default, { Foo, Bar as Baz } from 'x';",
"import Default, { Foo, Bar as Baz, } from 'x';",
"import Default, { Foo as Bar, Baz as Qux } from 'x';",
"import Default, { Foo as Bar, Baz as Qux, } from 'x';",
"import Default, { Foo, Bar, Baz } from 'x';",
"import Default, { Foo, Bar, Baz, } from 'x';",
"import Default, { Foo as Bar, Baz, Qux } from 'x';",
"import Default, { Foo as Bar, Baz, Qux, } from 'x';",
"import Default, { Foo, Bar as Baz, Qux } from 'x';",
"import Default, { Foo, Bar as Baz, Qux, } from 'x';",
"import Default, { Foo, Bar, Baz as Qux } from 'x';",
"import Default, { Foo, Bar, Baz as Qux, } from 'x';",
"import Default, { Foo as Bar, Baz as Qux, Norf } from 'x';",
"import Default, { Foo as Bar, Baz as Qux, Norf, } from 'x';",
"import Default, { Foo as Bar, Baz, Qux as Norf } from 'x';",
"import Default, { Foo as Bar, Baz, Qux as Norf, } from 'x';",
"import Default, { Foo, Bar as Baz, Qux as Norf } from 'x';",
"import Default, { Foo, Bar as Baz, Qux as Norf, } from 'x';",
"import Default, { Foo as Bar, Baz as Qux, Norf as NoMore } from 'x';",
"import Default, { Foo as Bar, Baz as Qux, Norf as NoMore, } from 'x';",
"import Default , { } from 'x';",
'import "x";',
'import Default from "x";',
'import * as All from "x";',
'import { } from "x";',
'import { Foo } from "x";',
'import { Foo, } from "x";',
'import { Foo as Bar } from "x";',
'import { Foo as Bar, } from "x";',
'import { Foo, Bar } from "x";',
'import { Foo, Bar, } from "x";',
'import { Foo as Bar, Baz } from "x";',
'import { Foo as Bar, Baz, } from "x";',
'import { Foo, Bar as Baz } from "x";',
'import { Foo, Bar as Baz, } from "x";',
'import { Foo as Bar, Baz as Qux } from "x";',
'import { Foo as Bar, Baz as Qux, } from "x";',
'import { Foo, Bar, Baz } from "x";',
'import { Foo, Bar, Baz, } from "x";',
'import { Foo as Bar, Baz, Qux } from "x";',
'import { Foo as Bar, Baz, Qux, } from "x";',
'import { Foo, Bar as Baz, Qux } from "x";',
'import { Foo, Bar as Baz, Qux, } from "x";',
'import { Foo, Bar, Baz as Qux } from "x";',
'import { Foo, Bar, Baz as Qux, } from "x";',
'import { Foo as Bar, Baz as Qux, Norf } from "x";',
'import { Foo as Bar, Baz as Qux, Norf, } from "x";',
'import { Foo as Bar, Baz, Qux as Norf } from "x";',
'import { Foo as Bar, Baz, Qux as Norf, } from "x";',
'import { Foo, Bar as Baz, Qux as Norf } from "x";',
'import { Foo, Bar as Baz, Qux as Norf, } from "x";',
'import { Foo as Bar, Baz as Qux, Norf as NoMore } from "x";',
'import { Foo as Bar, Baz as Qux, Norf as NoMore, } from "x";',
'import Default, * as All from "x";',
'import Default, { } from "x";',
'import Default, { Foo } from "x";',
'import Default, { Foo, } from "x";',
'import Default, { Foo as Bar } from "x";',
'import Default, { Foo as Bar, } from "x";',
'import Default, { Foo, Bar } from "x";',
'import Default, { Foo, Bar, } from "x";',
'import Default, { Foo as Bar, Baz } from "x";',
'import Default, { Foo as Bar, Baz, } from "x";',
'import Default, { Foo, Bar as Baz } from "x";',
'import Default, { Foo, Bar as Baz, } from "x";',
'import Default, { Foo as Bar, Baz as Qux } from "x";',
'import Default, { Foo as Bar, Baz as Qux, } from "x";',
'import Default, { Foo, Bar, Baz } from "x";',
'import Default, { Foo, Bar, Baz, } from "x";',
'import Default, { Foo as Bar, Baz, Qux } from "x";',
'import Default, { Foo as Bar, Baz, Qux, } from "x";',
'import Default, { Foo, Bar as Baz, Qux } from "x";',
'import Default, { Foo, Bar as Baz, Qux, } from "x";',
'import Default, { Foo, Bar, Baz as Qux } from "x";',
'import Default, { Foo, Bar, Baz as Qux, } from "x";',
'import Default, { Foo as Bar, Baz as Qux, Norf } from "x";',
'import Default, { Foo as Bar, Baz as Qux, Norf, } from "x";',
'import Default, { Foo as Bar, Baz, Qux as Norf } from "x";',
'import Default, { Foo as Bar, Baz, Qux as Norf, } from "x";',
'import Default, { Foo, Bar as Baz, Qux as Norf } from "x";',
'import Default, { Foo, Bar as Baz, Qux as Norf, } from "x";',
'import Default, { Foo as Bar, Baz as Qux, Norf as Enuf } from "x";',
'import Default, { Foo as Bar, Baz as Qux, Norf as Enuf, } from "x";',
'import Default from "y";',
'import * as All from \'z\';',
'require("x")',
'require("y")',
'require( "z" )',
'require( \'z\' )',
'require( "a")',
'require("b" )',
].join('\n');
/*eslint-disable */
depGraph.resolveDependency.mockImpl(function(fromModule, toModuleName) {
if (toModuleName === 'x') {
@ -242,7 +377,7 @@ describe('HasteDependencyResolver', function() {
id: 'changed'
};
} else if (toModuleName === 'y') {
return { id: 'y' };
return { id: 'Y' };
}
return null;
});
@ -254,13 +389,145 @@ describe('HasteDependencyResolver', function() {
}, code);
expect(processedCode).toEqual([
'__d(\'test module\',["changed","y"],function(global,' +
' require, requireDynamic, requireLazy, module, exports) {' +
' require(\'changed\')',
'require(\'y\')',
'require("z")',
'require("a")',
'require("b")});',
'__d(\'test module\',["changed","Y"],function(global,' +
' require, requireDynamic, requireLazy, module, exports) { ' +
"import'x';",
"import 'changed';",
"import 'changed' ;",
"import Default from 'changed';",
"import * as All from 'changed';",
"import {} from 'changed';",
"import { } from 'changed';",
"import {Foo} from 'changed';",
"import { Foo } from 'changed';",
"import { Foo, } from 'changed';",
"import {Foo as Bar} from 'changed';",
"import { Foo as Bar } from 'changed';",
"import { Foo as Bar, } from 'changed';",
"import { Foo, Bar } from 'changed';",
"import { Foo, Bar, } from 'changed';",
"import { Foo as Bar, Baz } from 'changed';",
"import { Foo as Bar, Baz, } from 'changed';",
"import { Foo, Bar as Baz } from 'changed';",
"import { Foo, Bar as Baz, } from 'changed';",
"import { Foo as Bar, Baz as Qux } from 'changed';",
"import { Foo as Bar, Baz as Qux, } from 'changed';",
"import { Foo, Bar, Baz } from 'changed';",
"import { Foo, Bar, Baz, } from 'changed';",
"import { Foo as Bar, Baz, Qux } from 'changed';",
"import { Foo as Bar, Baz, Qux, } from 'changed';",
"import { Foo, Bar as Baz, Qux } from 'changed';",
"import { Foo, Bar as Baz, Qux, } from 'changed';",
"import { Foo, Bar, Baz as Qux } from 'changed';",
"import { Foo, Bar, Baz as Qux, } from 'changed';",
"import { Foo as Bar, Baz as Qux, Norf } from 'changed';",
"import { Foo as Bar, Baz as Qux, Norf, } from 'changed';",
"import { Foo as Bar, Baz, Qux as Norf } from 'changed';",
"import { Foo as Bar, Baz, Qux as Norf, } from 'changed';",
"import { Foo, Bar as Baz, Qux as Norf } from 'changed';",
"import { Foo, Bar as Baz, Qux as Norf, } from 'changed';",
"import { Foo as Bar, Baz as Qux, Norf as Enuf } from 'changed';",
"import { Foo as Bar, Baz as Qux, Norf as Enuf, } from 'changed';",
"import Default, * as All from 'changed';",
"import Default, { } from 'changed';",
"import Default, { Foo } from 'changed';",
"import Default, { Foo, } from 'changed';",
"import Default, { Foo as Bar } from 'changed';",
"import Default, { Foo as Bar, } from 'changed';",
"import Default, { Foo, Bar } from 'changed';",
"import Default, { Foo, Bar, } from 'changed';",
"import Default, { Foo as Bar, Baz } from 'changed';",
"import Default, { Foo as Bar, Baz, } from 'changed';",
"import Default, { Foo, Bar as Baz } from 'changed';",
"import Default, { Foo, Bar as Baz, } from 'changed';",
"import Default, { Foo as Bar, Baz as Qux } from 'changed';",
"import Default, { Foo as Bar, Baz as Qux, } from 'changed';",
"import Default, { Foo, Bar, Baz } from 'changed';",
"import Default, { Foo, Bar, Baz, } from 'changed';",
"import Default, { Foo as Bar, Baz, Qux } from 'changed';",
"import Default, { Foo as Bar, Baz, Qux, } from 'changed';",
"import Default, { Foo, Bar as Baz, Qux } from 'changed';",
"import Default, { Foo, Bar as Baz, Qux, } from 'changed';",
"import Default, { Foo, Bar, Baz as Qux } from 'changed';",
"import Default, { Foo, Bar, Baz as Qux, } from 'changed';",
"import Default, { Foo as Bar, Baz as Qux, Norf } from 'changed';",
"import Default, { Foo as Bar, Baz as Qux, Norf, } from 'changed';",
"import Default, { Foo as Bar, Baz, Qux as Norf } from 'changed';",
"import Default, { Foo as Bar, Baz, Qux as Norf, } from 'changed';",
"import Default, { Foo, Bar as Baz, Qux as Norf } from 'changed';",
"import Default, { Foo, Bar as Baz, Qux as Norf, } from 'changed';",
"import Default, { Foo as Bar, Baz as Qux, Norf as NoMore } from 'changed';",
"import Default, { Foo as Bar, Baz as Qux, Norf as NoMore, } from 'changed';",
"import Default , { } from 'changed';",
'import "changed";',
'import Default from "changed";',
'import * as All from "changed";',
'import { } from "changed";',
'import { Foo } from "changed";',
'import { Foo, } from "changed";',
'import { Foo as Bar } from "changed";',
'import { Foo as Bar, } from "changed";',
'import { Foo, Bar } from "changed";',
'import { Foo, Bar, } from "changed";',
'import { Foo as Bar, Baz } from "changed";',
'import { Foo as Bar, Baz, } from "changed";',
'import { Foo, Bar as Baz } from "changed";',
'import { Foo, Bar as Baz, } from "changed";',
'import { Foo as Bar, Baz as Qux } from "changed";',
'import { Foo as Bar, Baz as Qux, } from "changed";',
'import { Foo, Bar, Baz } from "changed";',
'import { Foo, Bar, Baz, } from "changed";',
'import { Foo as Bar, Baz, Qux } from "changed";',
'import { Foo as Bar, Baz, Qux, } from "changed";',
'import { Foo, Bar as Baz, Qux } from "changed";',
'import { Foo, Bar as Baz, Qux, } from "changed";',
'import { Foo, Bar, Baz as Qux } from "changed";',
'import { Foo, Bar, Baz as Qux, } from "changed";',
'import { Foo as Bar, Baz as Qux, Norf } from "changed";',
'import { Foo as Bar, Baz as Qux, Norf, } from "changed";',
'import { Foo as Bar, Baz, Qux as Norf } from "changed";',
'import { Foo as Bar, Baz, Qux as Norf, } from "changed";',
'import { Foo, Bar as Baz, Qux as Norf } from "changed";',
'import { Foo, Bar as Baz, Qux as Norf, } from "changed";',
'import { Foo as Bar, Baz as Qux, Norf as NoMore } from "changed";',
'import { Foo as Bar, Baz as Qux, Norf as NoMore, } from "changed";',
'import Default, * as All from "changed";',
'import Default, { } from "changed";',
'import Default, { Foo } from "changed";',
'import Default, { Foo, } from "changed";',
'import Default, { Foo as Bar } from "changed";',
'import Default, { Foo as Bar, } from "changed";',
'import Default, { Foo, Bar } from "changed";',
'import Default, { Foo, Bar, } from "changed";',
'import Default, { Foo as Bar, Baz } from "changed";',
'import Default, { Foo as Bar, Baz, } from "changed";',
'import Default, { Foo, Bar as Baz } from "changed";',
'import Default, { Foo, Bar as Baz, } from "changed";',
'import Default, { Foo as Bar, Baz as Qux } from "changed";',
'import Default, { Foo as Bar, Baz as Qux, } from "changed";',
'import Default, { Foo, Bar, Baz } from "changed";',
'import Default, { Foo, Bar, Baz, } from "changed";',
'import Default, { Foo as Bar, Baz, Qux } from "changed";',
'import Default, { Foo as Bar, Baz, Qux, } from "changed";',
'import Default, { Foo, Bar as Baz, Qux } from "changed";',
'import Default, { Foo, Bar as Baz, Qux, } from "changed";',
'import Default, { Foo, Bar, Baz as Qux } from "changed";',
'import Default, { Foo, Bar, Baz as Qux, } from "changed";',
'import Default, { Foo as Bar, Baz as Qux, Norf } from "changed";',
'import Default, { Foo as Bar, Baz as Qux, Norf, } from "changed";',
'import Default, { Foo as Bar, Baz, Qux as Norf } from "changed";',
'import Default, { Foo as Bar, Baz, Qux as Norf, } from "changed";',
'import Default, { Foo, Bar as Baz, Qux as Norf } from "changed";',
'import Default, { Foo, Bar as Baz, Qux as Norf, } from "changed";',
'import Default, { Foo as Bar, Baz as Qux, Norf as Enuf } from "changed";',
'import Default, { Foo as Bar, Baz as Qux, Norf as Enuf, } from "changed";',
'import Default from "Y";',
'import * as All from \'z\';',
'require("changed")',
'require("Y")',
'require( \'z\' )',
'require( "a")',
'require("b" )});',
].join('\n'));
});
});

Просмотреть файл

@ -10,7 +10,7 @@
var path = require('path');
var DependencyGraph = require('./DependencyGraph');
var requirePattern = require('./requirePattern');
var replacePatterns = require('./replacePatterns');
var ModuleDescriptor = require('../ModuleDescriptor');
var declareOpts = require('../../lib/declareOpts');
@ -61,7 +61,7 @@ function HasteDependencyResolver(options) {
this._depGraph = new DependencyGraph({
roots: opts.projectRoots,
assetRoots: opts.assetRoots,
assetRoots_DEPRECATED: opts.assetRoots,
ignoreFilePath: function(filepath) {
return filepath.indexOf('__tests__') !== -1 ||
(opts.blacklistRE && opts.blacklistRE.test(filepath));
@ -144,20 +144,20 @@ HasteDependencyResolver.prototype.wrapModule = function(module, code) {
}
}
var relativizedCode =
code.replace(requirePattern, function(codeMatch, _, depName) {
var depId = resolvedDeps[depName];
if (depId != null) {
return 'require(\'' + depId + '\')';
} else {
return codeMatch.replace(/\s+/g, '');
}
});
var relativizeCode = function(codeMatch, pre, quot, depName, post) {
var depId = resolvedDeps[depName];
if (depId) {
return pre + quot + depId + post;
} else {
return codeMatch;
}
};
return DEFINE_MODULE_CODE.replace(DEFINE_MODULE_REPLACE_RE, function(key) {
return {
'_moduleName_': module.id,
'_code_': relativizedCode,
'_code_': code.replace(replacePatterns.IMPORT_RE, relativizeCode)
.replace(replacePatterns.REQUIRE_RE, relativizeCode),
'_deps_': JSON.stringify(resolvedDepsArr),
}[key];
});

Просмотреть файл

@ -9,6 +9,5 @@
'use strict';
var REQUIRE_RE = /\brequire\s*?\(\s*?([\'"])([^"\']+)\1\s*?\)/g;
module.exports = REQUIRE_RE;
exports.IMPORT_RE = /(\bimport\s+?(?:.+\s+?from\s+?)?)(['"])([^'"]+)(\2)/g;
exports.REQUIRE_RE = /(\brequire\s*?\(\s*?)(['"])([^'"]+)(\2\s*?\))/g;

Просмотреть файл

@ -61,9 +61,7 @@ function Transformer(options) {
projectRoots: options.projectRoots,
});
if (options.transformModulePath == null) {
this._failedToStart = Promise.reject(new Error('No transfrom module'));
} else {
if (options.transformModulePath != null) {
this._workers = workerFarm(
{autoStart: true, maxConcurrentCallsPerWorker: 1},
options.transformModulePath
@ -83,8 +81,8 @@ Transformer.prototype.invalidateFile = function(filePath) {
};
Transformer.prototype.loadFileAndTransform = function(filePath) {
if (this._failedToStart) {
return this._failedToStart;
if (this._transform == null) {
return Promise.reject(new Error('No transfrom module'));
}
var transform = this._transform;

Просмотреть файл

@ -240,7 +240,9 @@ var APIDoc = React.createClass({
render: function() {
var content = this.props.content;
if (!content.methods) {
return <div>Error</div>;
throw new Error(
'No component methods found for ' + content.componentName
);
}
return (
<div>

Просмотреть файл

@ -127,7 +127,6 @@ var components = [
var apis = [
'../Libraries/Utilities/AlertIOS.js',
'../Libraries/Animation/Animation.js',
'../Libraries/AppRegistry/AppRegistry.js',
'../Libraries/AppStateIOS/AppStateIOS.ios.js',
'../Libraries/Storage/AsyncStorage.ios.js',