Updates from Mon 6 Apr

- [ReactNative] Revert D1965911 | Christopher Chedeau
- [ReactNative] Remove experimental Portal only needed for android right now. | Spencer Ahrens
- [ReactNative] rename Animation to AnimationExperimental with warning docs | Spencer Ahrens
- navigator.getCurrentRoutes() | Eric Vicenti
- Fixing jsdoc parsing of functions that are defined over multiple lines (Fixes #410) | Christopher Chedeau
- Added constraint of child type to touchablewithoutfeedback | Christopher Chedeau
- [react-packager] Deprecate global image namespace in favor of CommonJS resolution | Amjad Masad
- [react-packager] Don't cache rejected promise | Amjad Masad
- [ReactNative] Start Navigator gesture config, disable gesture in AdsManager | Eric Vicenti
- [Flow] Clean react-native-github for Flow v0.8.0 | Gabe Levi
- add maximumValue and minimumValue as valid attributes for native Slider | Christopher Chedeau
- react-packager: Add ES6 import statement support to DependencyGraph. | Amjad Masad
- Remove false annotation | Christopher Chedeau
- [madman] prevent pulling the content down inconsistently when the keyboard shows up | Kevin Gozali
- add @flow back to View.js | Basil Hosmer
- [ReactNative] Turn of lint warning for constant conditions | Eric Vicenti
- [UIExplorer] Fixed 'Push View Example' in NavigatorIOS example | Christopher Chedeau
- SliderIOS.js comments - grammar correction | Christopher Chedeau
This commit is contained in:
Christopher Chedeau 2015-04-06 08:38:56 -07:00
parent 12698ed4af
commit 85e1ad6b61
32 changed files with 966 additions and 464 deletions

View File

@ -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

View File

@ -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;
};

View File

@ -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() {

View File

@ -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}
/>
);
},

View File

@ -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', () => {

View File

@ -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({

View File

@ -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;

View File

@ -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;

View File

@ -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 */,

View File

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

View File

@ -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;

View File

@ -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) {

View File

@ -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',
});

View File

@ -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,

View File

@ -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;
}

View File

@ -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,

View File

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

View File

@ -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 {

View File

@ -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,
});

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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,

View File

@ -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'),

View File

@ -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

View File

@ -99,7 +99,7 @@ middleware. Takes the following options:
* `projectRoots` array (required): Is the roots where your JavaScript
file will exist
* `blacklistRE` regexp: Is a pattern to ignore certain paths from the
* `blacklistRE` regexp: Is a patter to ignore certain paths from the
packager
* `polyfillModuleName` array: Paths to polyfills you want to be
included at the start of the bundle

View File

@ -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({

View File

@ -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() {

View File

@ -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'));
});
});

View File

@ -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];
});

View File

@ -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;

View File

@ -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;