diff --git a/Libraries/Text/Text.js b/Libraries/Text/Text.js
index c9ca8357d..69dc800de 100644
--- a/Libraries/Text/Text.js
+++ b/Libraries/Text/Text.js
@@ -11,22 +11,22 @@
*/
'use strict';
-var NativeMethodsMixin = require('NativeMethodsMixin');
-var Platform = require('Platform');
-var React = require('React');
-var ReactInstanceMap = require('ReactInstanceMap');
-var ReactNativeViewAttributes = require('ReactNativeViewAttributes');
-var StyleSheetPropType = require('StyleSheetPropType');
-var TextStylePropTypes = require('TextStylePropTypes');
-var Touchable = require('Touchable');
+const NativeMethodsMixin = require('NativeMethodsMixin');
+const Platform = require('Platform');
+const React = require('React');
+const ReactInstanceMap = require('ReactInstanceMap');
+const ReactNativeViewAttributes = require('ReactNativeViewAttributes');
+const StyleSheetPropType = require('StyleSheetPropType');
+const TextStylePropTypes = require('TextStylePropTypes');
+const Touchable = require('Touchable');
-var createReactNativeComponentClass =
+const createReactNativeComponentClass =
require('createReactNativeComponentClass');
-var merge = require('merge');
+const merge = require('merge');
-var stylePropType = StyleSheetPropType(TextStylePropTypes);
+const stylePropType = StyleSheetPropType(TextStylePropTypes);
-var viewConfig = {
+const viewConfig = {
validAttributes: merge(ReactNativeViewAttributes.UIView, {
isHighlighted: true,
numberOfLines: true,
@@ -68,10 +68,7 @@ var viewConfig = {
* ```
*/
-var Text = React.createClass({
-
- mixins: [Touchable.Mixin, NativeMethodsMixin],
-
+const Text = React.createClass({
propTypes: {
/**
* Used to truncate the text with an elipsis after computing the text
@@ -105,121 +102,126 @@ var Text = React.createClass({
*/
allowFontScaling: React.PropTypes.bool,
},
-
- viewConfig: viewConfig,
-
- getInitialState: function(): Object {
- return merge(this.touchableGetInitialState(), {
- isHighlighted: false,
- });
- },
- getDefaultProps: function(): Object {
+ getDefaultProps(): Object {
return {
+ accessible: true,
allowFontScaling: true,
};
},
-
- onStartShouldSetResponder: function(): bool {
- var shouldSetFromProps = this.props.onStartShouldSetResponder &&
- this.props.onStartShouldSetResponder();
- return shouldSetFromProps || !!this.props.onPress;
- },
-
- /*
- * Returns true to allow responder termination
- */
- handleResponderTerminationRequest: function(): bool {
- // Allow touchable or props.onResponderTerminationRequest to deny
- // the request
- var allowTermination = this.touchableHandleResponderTerminationRequest();
- if (allowTermination && this.props.onResponderTerminationRequest) {
- allowTermination = this.props.onResponderTerminationRequest();
- }
- return allowTermination;
- },
-
- handleResponderGrant: function(e: SyntheticEvent, dispatchID: string) {
- this.touchableHandleResponderGrant(e, dispatchID);
- this.props.onResponderGrant &&
- this.props.onResponderGrant.apply(this, arguments);
- },
-
- handleResponderMove: function(e: SyntheticEvent) {
- this.touchableHandleResponderMove(e);
- this.props.onResponderMove &&
- this.props.onResponderMove.apply(this, arguments);
- },
-
- handleResponderRelease: function(e: SyntheticEvent) {
- this.touchableHandleResponderRelease(e);
- this.props.onResponderRelease &&
- this.props.onResponderRelease.apply(this, arguments);
- },
-
- handleResponderTerminate: function(e: SyntheticEvent) {
- this.touchableHandleResponderTerminate(e);
- this.props.onResponderTerminate &&
- this.props.onResponderTerminate.apply(this, arguments);
- },
-
- touchableHandleActivePressIn: function() {
- if (this.props.suppressHighlighting || !this.props.onPress) {
- return;
- }
- this.setState({
- isHighlighted: true,
- });
- },
-
- touchableHandleActivePressOut: function() {
- if (this.props.suppressHighlighting || !this.props.onPress) {
- return;
- }
- this.setState({
+ getInitialState: function(): Object {
+ return merge(Touchable.Mixin.touchableGetInitialState(), {
isHighlighted: false,
});
},
-
- touchableHandlePress: function() {
- this.props.onPress && this.props.onPress();
- },
-
- touchableGetPressRectOffset: function(): RectOffset {
- return PRESS_RECT_OFFSET;
- },
-
- getChildContext: function(): Object {
+ mixins: [NativeMethodsMixin],
+ viewConfig: viewConfig,
+ getChildContext(): Object {
return {isInAParentText: true};
},
-
childContextTypes: {
isInAParentText: React.PropTypes.bool
},
+ contextTypes: {
+ isInAParentText: React.PropTypes.bool
+ },
+ /**
+ * Only assigned if touch is needed.
+ */
+ _handlers: (null: ?Object),
+ /**
+ * These are assigned lazily the first time the responder is set to make plain
+ * text nodes as cheap as possible.
+ */
+ touchableHandleActivePressIn: (null: ?Function),
+ touchableHandleActivePressOut: (null: ?Function),
+ touchableHandlePress: (null: ?Function),
+ touchableGetPressRectOffset: (null: ?Function),
+ render(): ReactElement {
+ let newProps = this.props;
+ if (this.props.onStartShouldSetResponder || this.props.onPress) {
+ if (!this._handlers) {
+ this._handlers = {
+ onStartShouldSetResponder: (): bool => {
+ const shouldSetFromProps = this.props.onStartShouldSetResponder &&
+ this.props.onStartShouldSetResponder();
+ const setResponder = shouldSetFromProps || !!this.props.onPress;
+ if (setResponder && !this.touchableHandleActivePressIn) {
+ // Attach and bind all the other handlers only the first time a touch
+ // actually happens.
+ for (let key in Touchable.Mixin) {
+ if (typeof Touchable.Mixin[key] === 'function') {
+ (this: any)[key] = Touchable.Mixin[key].bind(this);
+ }
+ }
+ this.touchableHandleActivePressIn = () => {
+ if (this.props.suppressHighlighting || !this.props.onPress) {
+ return;
+ }
+ this.setState({
+ isHighlighted: true,
+ });
+ };
- render: function() {
- var props = {};
- for (var key in this.props) {
- props[key] = this.props[key];
- }
- // Text is accessible by default
- if (props.accessible !== false) {
- props.accessible = true;
- }
- props.isHighlighted = this.state.isHighlighted;
- props.onStartShouldSetResponder = this.onStartShouldSetResponder;
- props.onResponderTerminationRequest =
- this.handleResponderTerminationRequest;
- props.onResponderGrant = this.handleResponderGrant;
- props.onResponderMove = this.handleResponderMove;
- props.onResponderRelease = this.handleResponderRelease;
- props.onResponderTerminate = this.handleResponderTerminate;
+ this.touchableHandleActivePressOut = () => {
+ if (this.props.suppressHighlighting || !this.props.onPress) {
+ return;
+ }
+ this.setState({
+ isHighlighted: false,
+ });
+ };
- // TODO: Switch to use contextTypes and this.context after React upgrade
- var context = ReactInstanceMap.get(this)._context;
- if (context.isInAParentText) {
- return ;
+ this.touchableHandlePress = () => {
+ this.props.onPress && this.props.onPress();
+ };
+
+ this.touchableGetPressRectOffset = function(): RectOffset {
+ return PRESS_RECT_OFFSET;
+ };
+ }
+ return setResponder;
+ },
+ onResponderGrant: (e: SyntheticEvent, dispatchID: string) => {
+ this.touchableHandleResponderGrant(e, dispatchID);
+ this.props.onResponderGrant &&
+ this.props.onResponderGrant.apply(this, arguments);
+ },
+ onResponderMove: (e: SyntheticEvent) => {
+ this.touchableHandleResponderMove(e);
+ this.props.onResponderMove &&
+ this.props.onResponderMove.apply(this, arguments);
+ },
+ onResponderRelease: (e: SyntheticEvent) => {
+ this.touchableHandleResponderRelease(e);
+ this.props.onResponderRelease &&
+ this.props.onResponderRelease.apply(this, arguments);
+ },
+ onResponderTerminate: (e: SyntheticEvent) => {
+ this.touchableHandleResponderTerminate(e);
+ this.props.onResponderTerminate &&
+ this.props.onResponderTerminate.apply(this, arguments);
+ },
+ onResponderTerminationRequest: (): bool => {
+ // Allow touchable or props.onResponderTerminationRequest to deny
+ // the request
+ var allowTermination = this.touchableHandleResponderTerminationRequest();
+ if (allowTermination && this.props.onResponderTerminationRequest) {
+ allowTermination = this.props.onResponderTerminationRequest();
+ }
+ return allowTermination;
+ },
+ };
+ }
+ newProps = {
+ ...this.props,
+ ...this._handlers,
+ isHighlighted: this.state.isHighlighted,
+ };
+ }
+ if (this.context.isInAParentText) {
+ return ;
} else {
- return ;
+ return ;
}
},
});