Skip to content

Commit b01fe77

Browse files
authored
Merge branch 'master' into animated-super
2 parents 6d1de4e + b53d76e commit b01fe77

File tree

64 files changed

+1048
-532
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+1048
-532
lines changed

Examples/UIExplorer/js/TextInputExample.ios.js

Lines changed: 9 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -103,34 +103,6 @@ class TextEventsExample extends React.Component {
103103
}
104104
}
105105

106-
class AutoExpandingTextInput extends React.Component {
107-
state: any;
108-
109-
constructor(props) {
110-
super(props);
111-
this.state = {
112-
text: 'React Native enables you to build world-class application experiences on native platforms using a consistent developer experience based on JavaScript and React. The focus of React Native is on developer efficiency across all the platforms you care about — learn once, write anywhere. Facebook uses React Native in multiple production apps and will continue investing in React Native.',
113-
height: 0,
114-
};
115-
}
116-
render() {
117-
return (
118-
<TextInput
119-
{...this.props}
120-
multiline={true}
121-
onChangeText={(text) => {
122-
this.setState({text});
123-
}}
124-
onContentSizeChange={(event) => {
125-
this.setState({height: event.nativeEvent.contentSize.height});
126-
}}
127-
style={[styles.default, {height: Math.max(35, this.state.height)}]}
128-
value={this.state.text}
129-
/>
130-
);
131-
}
132-
}
133-
134106
class RewriteExample extends React.Component {
135107
state: any;
136108

@@ -403,6 +375,10 @@ var styles = StyleSheet.create({
403375
padding: 4,
404376
marginBottom: 4,
405377
},
378+
multilineExpandable: {
379+
height: 'auto',
380+
maxHeight: 100,
381+
},
406382
multilineWithFontStyles: {
407383
color: 'blue',
408384
fontWeight: 'bold',
@@ -801,10 +777,13 @@ exports.examples = [
801777
render: function() {
802778
return (
803779
<View>
804-
<AutoExpandingTextInput
780+
<TextInput
805781
placeholder="height increases with content"
782+
defaultValue="React Native enables you to build world-class application experiences on native platforms using a consistent developer experience based on JavaScript and React. The focus of React Native is on developer efficiency across all the platforms you care about - learn once, write anywhere. Facebook uses React Native in multiple production apps and will continue investing in React Native."
783+
multiline={true}
806784
enablesReturnKeyAutomatically={true}
807-
returnKeyType="default"
785+
returnKeyType="go"
786+
style={[styles.multiline, styles.multilineExpandable]}
808787
/>
809788
</View>
810789
);

Libraries/Animated/src/AnimatedImplementation.js

Lines changed: 35 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,9 +1513,9 @@ class AnimatedStyle extends AnimatedWithChildren {
15131513
15141514
// Recursively get values for nested styles (like iOS's shadowOffset)
15151515
__walkStyleAndGetValues(style) {
1516-
let updatedStyle = {};
1517-
for (let key in style) {
1518-
let value = style[key];
1516+
const updatedStyle = {};
1517+
for (const key in style) {
1518+
const value = style[key];
15191519
if (value instanceof Animated) {
15201520
if (!value.__isNative) {
15211521
// We cannot use value of natively driven nodes this way as the value we have access from
@@ -1538,9 +1538,9 @@ class AnimatedStyle extends AnimatedWithChildren {
15381538
15391539
// Recursively get animated values for nested styles (like iOS's shadowOffset)
15401540
__walkStyleAndGetAnimatedValues(style) {
1541-
let updatedStyle = {};
1542-
for (let key in style) {
1543-
let value = style[key];
1541+
const updatedStyle = {};
1542+
for (const key in style) {
1543+
const value = style[key];
15441544
if (value instanceof Animated) {
15451545
updatedStyle[key] = value.__getAnimatedValue();
15461546
} else if (value && !Array.isArray(value) && typeof value === 'object') {
@@ -1694,7 +1694,9 @@ class AnimatedProps extends Animated {
16941694
}
16951695
16961696
setNativeView(animatedView: any): void {
1697-
invariant(this._animatedView === undefined, 'Animated view already set.');
1697+
if (this._animatedView === animatedView) {
1698+
return;
1699+
}
16981700
this._animatedView = animatedView;
16991701
if (this.__isNative) {
17001702
this.__connectAnimatedView();
@@ -1733,7 +1735,9 @@ class AnimatedProps extends Animated {
17331735
function createAnimatedComponent(Component: any): any {
17341736
class AnimatedComponent extends React.Component {
17351737
_component: any;
1738+
_prevComponent: any;
17361739
_propsAnimated: AnimatedProps;
1740+
_eventDetachers: Array<Function> = [];
17371741
_setComponentRef: Function;
17381742
17391743
constructor(props: Object) {
@@ -1743,7 +1747,7 @@ function createAnimatedComponent(Component: any): any {
17431747
17441748
componentWillUnmount() {
17451749
this._propsAnimated && this._propsAnimated.__detach();
1746-
this._detachNativeEvents(this.props);
1750+
this._detachNativeEvents();
17471751
}
17481752
17491753
setNativeProps(props) {
@@ -1756,42 +1760,28 @@ function createAnimatedComponent(Component: any): any {
17561760
17571761
componentDidMount() {
17581762
this._propsAnimated.setNativeView(this._component);
1759-
1760-
this._attachNativeEvents(this.props);
1763+
this._attachNativeEvents();
17611764
}
17621765
1763-
_attachNativeEvents(newProps) {
1764-
if (newProps !== this.props) {
1765-
this._detachNativeEvents(this.props);
1766-
}
1767-
1766+
_attachNativeEvents() {
17681767
// Make sure to get the scrollable node for components that implement
17691768
// `ScrollResponder.Mixin`.
1770-
const ref = this._component.getScrollableNode ?
1769+
const scrollableNode = this._component.getScrollableNode ?
17711770
this._component.getScrollableNode() :
17721771
this._component;
17731772
1774-
for (const key in newProps) {
1775-
const prop = newProps[key];
1773+
for (const key in this.props) {
1774+
const prop = this.props[key];
17761775
if (prop instanceof AnimatedEvent && prop.__isNative) {
1777-
prop.__attach(ref, key);
1776+
prop.__attach(scrollableNode, key);
1777+
this._eventDetachers.push(() => prop.__detach(scrollableNode, key));
17781778
}
17791779
}
17801780
}
17811781
1782-
_detachNativeEvents(props) {
1783-
// Make sure to get the scrollable node for components that implement
1784-
// `ScrollResponder.Mixin`.
1785-
const ref = this._component.getScrollableNode ?
1786-
this._component.getScrollableNode() :
1787-
this._component;
1788-
1789-
for (const key in props) {
1790-
const prop = props[key];
1791-
if (prop instanceof AnimatedEvent && prop.__isNative) {
1792-
prop.__detach(ref, key);
1793-
}
1794-
}
1782+
_detachNativeEvents() {
1783+
this._eventDetachers.forEach(remove => remove());
1784+
this._eventDetachers = [];
17951785
}
17961786
17971787
_attachProps(nextProps) {
@@ -1824,10 +1814,6 @@ function createAnimatedComponent(Component: any): any {
18241814
callback,
18251815
);
18261816
1827-
if (this._component) {
1828-
this._propsAnimated.setNativeView(this._component);
1829-
}
1830-
18311817
// When you call detach, it removes the element from the parent list
18321818
// of children. If it goes to 0, then the parent also detaches itself
18331819
// and so on.
@@ -1839,9 +1825,18 @@ function createAnimatedComponent(Component: any): any {
18391825
oldPropsAnimated && oldPropsAnimated.__detach();
18401826
}
18411827
1842-
componentWillReceiveProps(nextProps) {
1843-
this._attachProps(nextProps);
1844-
this._attachNativeEvents(nextProps);
1828+
componentWillReceiveProps(newProps) {
1829+
this._attachProps(newProps);
1830+
}
1831+
1832+
componentDidUpdate(prevProps) {
1833+
if (this._component !== this._prevComponent) {
1834+
this._propsAnimated.setNativeView(this._component);
1835+
}
1836+
if (this._component !== this._prevComponent || prevProps !== this.props) {
1837+
this._detachNativeEvents();
1838+
this._attachNativeEvents();
1839+
}
18451840
}
18461841
18471842
render() {
@@ -1854,6 +1849,7 @@ function createAnimatedComponent(Component: any): any {
18541849
}
18551850
18561851
_setComponentRef(c) {
1852+
this._prevComponent = this._component;
18571853
this._component = c;
18581854
}
18591855

Libraries/Components/TextInput/TextInput.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,7 @@ const TextInput = React.createClass({
678678
if (props.inputView) {
679679
children = [children, props.inputView];
680680
}
681+
props.style.unshift(styles.multilineInput);
681682
textContainer =
682683
<RCTTextView
683684
ref={this._setNativeRef}
@@ -867,6 +868,12 @@ var styles = StyleSheet.create({
867868
input: {
868869
alignSelf: 'stretch',
869870
},
871+
multilineInput: {
872+
// This default top inset makes RCTTextView seem as close as possible
873+
// to single-line RCTTextField defaults, using the system defaults
874+
// of font size 17 and a height of 31 points.
875+
paddingTop: 5,
876+
},
870877
});
871878

872879
module.exports = TextInput;

Libraries/CustomComponents/Lists/FlatList.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ type OptionalProps<ItemT> = {
103103
*/
104104
keyExtractor: (item: ItemT, index: number) => string,
105105
/**
106-
* Multiple columns can only be rendered with `horizontal={false}`` and will zig-zag like a
106+
* Multiple columns can only be rendered with `horizontal={false}` and will zig-zag like a
107107
* `flexWrap` layout. Items should all be the same height - masonry layouts are not supported.
108108
*/
109109
numColumns: number,

Libraries/Image/RCTLocalAssetImageLoader.m

Lines changed: 2 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -36,36 +36,6 @@ - (BOOL)shouldCacheLoadedImages
3636
return NO;
3737
}
3838

39-
static NSString *bundleName(NSBundle *bundle)
40-
{
41-
NSString *name = bundle.infoDictionary[@"CFBundleName"];
42-
if (!name) {
43-
name = [[bundle.bundlePath lastPathComponent] stringByDeletingPathExtension];
44-
}
45-
return name;
46-
}
47-
48-
static NSBundle *bundleForPath(NSString *key)
49-
{
50-
static NSMutableDictionary *bundleCache;
51-
if (!bundleCache) {
52-
bundleCache = [NSMutableDictionary new];
53-
bundleCache[@"main"] = [NSBundle mainBundle];
54-
55-
// Initialize every bundle in the array
56-
for (NSString *path in [[NSBundle mainBundle] pathsForResourcesOfType:@"bundle" inDirectory:nil]) {
57-
[NSBundle bundleWithPath:path];
58-
}
59-
60-
// The bundles initialized above will now also be in `allBundles`
61-
for (NSBundle *bundle in [NSBundle allBundles]) {
62-
bundleCache[bundleName(bundle)] = bundle;
63-
}
64-
}
65-
66-
return bundleCache[key];
67-
}
68-
6939
- (RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL
7040
size:(CGSize)size
7141
scale:(CGFloat)scale
@@ -80,31 +50,14 @@ - (RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL
8050
return;
8151
}
8252

83-
NSString *imageName = RCTBundlePathForURL(imageURL);
84-
85-
NSBundle *bundle;
86-
NSArray *imagePathComponents = [imageName pathComponents];
87-
if ([imagePathComponents count] > 1 &&
88-
[[[imagePathComponents firstObject] pathExtension] isEqualToString:@"bundle"]) {
89-
NSString *bundlePath = [imagePathComponents firstObject];
90-
bundle = bundleForPath([bundlePath stringByDeletingPathExtension]);
91-
imageName = [imageName substringFromIndex:(bundlePath.length + 1)];
92-
}
93-
94-
UIImage *image;
95-
if (bundle) {
96-
image = [UIImage imageNamed:imageName inBundle:bundle compatibleWithTraitCollection:nil];
97-
} else {
98-
image = [UIImage imageNamed:imageName];
99-
}
100-
53+
UIImage *image = RCTImageFromLocalAssetURL(imageURL);
10154
if (image) {
10255
if (progressHandler) {
10356
progressHandler(1, 1);
10457
}
10558
completionHandler(nil, image);
10659
} else {
107-
NSString *message = [NSString stringWithFormat:@"Could not find image named %@", imageName];
60+
NSString *message = [NSString stringWithFormat:@"Could not find image %@", imageURL];
10861
RCTLogWarn(@"%@", message);
10962
completionHandler(RCTErrorWithMessage(message), nil);
11063
}

Libraries/Renderer/src/renderers/native/ReactNativeEventEmitter.js

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,11 +103,6 @@ var ReactNativeEventEmitter = {
103103
) {
104104
var nativeEvent = nativeEventParam || EMPTY_NATIVE_EVENT;
105105
var inst = ReactNativeComponentTree.getInstanceFromNode(rootNodeID);
106-
if (!inst) {
107-
// If the original instance is already gone, we don't have to dispatch
108-
// any events.
109-
return;
110-
}
111106
ReactGenericBatching.batchedUpdates(function() {
112107
ReactNativeEventEmitter.handleTopLevel(
113108
topLevelType,

Libraries/Renderer/src/renderers/shared/shared/event/EventPropagators.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ function accumulateTwoPhaseDispatchesSingleSkipTarget(event) {
9393
* requiring that the `dispatchMarker` be the same as the dispatched ID.
9494
*/
9595
function accumulateDispatches(inst, ignoredDirection, event) {
96-
if (event && event.dispatchConfig.registrationName) {
96+
if (inst && event && event.dispatchConfig.registrationName) {
9797
var registrationName = event.dispatchConfig.registrationName;
9898
var listener = getListener(inst, registrationName);
9999
if (listener) {

Libraries/Text/RCTText.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
58B511D01A9E6C5C00147676 /* RCTShadowText.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B511CB1A9E6C5C00147676 /* RCTShadowText.m */; };
2828
58B511D11A9E6C5C00147676 /* RCTTextManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B511CD1A9E6C5C00147676 /* RCTTextManager.m */; };
2929
58B512161A9E6EFF00147676 /* RCTText.m in Sources */ = {isa = PBXBuildFile; fileRef = 58B512141A9E6EFF00147676 /* RCTText.m */; };
30+
59B125C91E6E4E15004E2A67 /* RCTUITextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59B125C81E6E4E15004E2A67 /* RCTUITextView.m */; };
31+
59B125CA1E6E4E15004E2A67 /* RCTUITextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59B125C81E6E4E15004E2A67 /* RCTUITextView.m */; };
3032
59F60E911E661BDD0081153B /* RCTShadowTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 59F60E8E1E661BDD0081153B /* RCTShadowTextField.m */; };
3133
59F60E921E661BDD0081153B /* RCTShadowTextField.m in Sources */ = {isa = PBXBuildFile; fileRef = 59F60E8E1E661BDD0081153B /* RCTShadowTextField.m */; };
3234
59F60E931E661BDD0081153B /* RCTShadowTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 59F60E901E661BDD0081153B /* RCTShadowTextView.m */; };
@@ -58,6 +60,8 @@
5860
58B511CD1A9E6C5C00147676 /* RCTTextManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTTextManager.m; sourceTree = "<group>"; };
5961
58B512141A9E6EFF00147676 /* RCTText.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTText.m; sourceTree = "<group>"; };
6062
58B512151A9E6EFF00147676 /* RCTText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTText.h; sourceTree = "<group>"; };
63+
59B125C71E6E4E15004E2A67 /* RCTUITextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTUITextView.h; sourceTree = "<group>"; };
64+
59B125C81E6E4E15004E2A67 /* RCTUITextView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTUITextView.m; sourceTree = "<group>"; };
6165
59F60E8D1E661BDD0081153B /* RCTShadowTextField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTShadowTextField.h; sourceTree = "<group>"; };
6266
59F60E8E1E661BDD0081153B /* RCTShadowTextField.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RCTShadowTextField.m; sourceTree = "<group>"; };
6367
59F60E8F1E661BDD0081153B /* RCTShadowTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RCTShadowTextView.h; sourceTree = "<group>"; };
@@ -97,6 +101,8 @@
97101
131B6ABD1AF0CD0600FFC3E0 /* RCTTextView.m */,
98102
131B6ABE1AF0CD0600FFC3E0 /* RCTTextViewManager.h */,
99103
131B6ABF1AF0CD0600FFC3E0 /* RCTTextViewManager.m */,
104+
59B125C71E6E4E15004E2A67 /* RCTUITextView.h */,
105+
59B125C81E6E4E15004E2A67 /* RCTUITextView.m */,
100106
);
101107
indentWidth = 2;
102108
sourceTree = "<group>";
@@ -194,6 +200,7 @@
194200
2D3B5F341D9B103100451313 /* RCTRawTextManager.m in Sources */,
195201
59F60E921E661BDD0081153B /* RCTShadowTextField.m in Sources */,
196202
AF3225FA1DE5574F00D3E7E7 /* RCTConvert+Text.m in Sources */,
203+
59B125CA1E6E4E15004E2A67 /* RCTUITextView.m in Sources */,
197204
2D3B5F3C1D9B106F00451313 /* RCTTextViewManager.m in Sources */,
198205
59F60E941E661BDD0081153B /* RCTShadowTextView.m in Sources */,
199206
2D3B5F331D9B102D00451313 /* RCTTextSelection.m in Sources */,
@@ -214,6 +221,7 @@
214221
1362F1011B4D51F400E06D8C /* RCTTextFieldManager.m in Sources */,
215222
59F60E911E661BDD0081153B /* RCTShadowTextField.m in Sources */,
216223
AF3225F91DE5574F00D3E7E7 /* RCTConvert+Text.m in Sources */,
224+
59B125C91E6E4E15004E2A67 /* RCTUITextView.m in Sources */,
217225
131B6AC11AF0CD0600FFC3E0 /* RCTTextViewManager.m in Sources */,
218226
59F60E931E661BDD0081153B /* RCTShadowTextView.m in Sources */,
219227
58B511CF1A9E6C5C00147676 /* RCTShadowRawText.m in Sources */,

0 commit comments

Comments
 (0)