|
11 | 11 | */ |
12 | 12 | 'use strict'; |
13 | 13 |
|
14 | | -var NativeMethodsMixin = require('NativeMethodsMixin'); |
15 | | -var Platform = require('Platform'); |
16 | | -var React = require('React'); |
17 | | -var ReactInstanceMap = require('ReactInstanceMap'); |
18 | | -var ReactNativeViewAttributes = require('ReactNativeViewAttributes'); |
19 | | -var StyleSheetPropType = require('StyleSheetPropType'); |
20 | | -var TextStylePropTypes = require('TextStylePropTypes'); |
21 | | -var Touchable = require('Touchable'); |
22 | | - |
23 | | -var createReactNativeComponentClass = |
| 14 | +const NativeMethodsMixin = require('NativeMethodsMixin'); |
| 15 | +const Platform = require('Platform'); |
| 16 | +const React = require('React'); |
| 17 | +const ReactInstanceMap = require('ReactInstanceMap'); |
| 18 | +const ReactNativeViewAttributes = require('ReactNativeViewAttributes'); |
| 19 | +const StyleSheetPropType = require('StyleSheetPropType'); |
| 20 | +const TextStylePropTypes = require('TextStylePropTypes'); |
| 21 | +const Touchable = require('Touchable'); |
| 22 | + |
| 23 | +const createReactNativeComponentClass = |
24 | 24 | require('createReactNativeComponentClass'); |
25 | | -var merge = require('merge'); |
| 25 | +const merge = require('merge'); |
26 | 26 |
|
27 | | -var stylePropType = StyleSheetPropType(TextStylePropTypes); |
| 27 | +const stylePropType = StyleSheetPropType(TextStylePropTypes); |
28 | 28 |
|
29 | | -var viewConfig = { |
| 29 | +const viewConfig = { |
30 | 30 | validAttributes: merge(ReactNativeViewAttributes.UIView, { |
31 | 31 | isHighlighted: true, |
32 | 32 | numberOfLines: true, |
@@ -68,10 +68,7 @@ var viewConfig = { |
68 | 68 | * ``` |
69 | 69 | */ |
70 | 70 |
|
71 | | -var Text = React.createClass({ |
72 | | - |
73 | | - mixins: [Touchable.Mixin, NativeMethodsMixin], |
74 | | - |
| 71 | +const Text = React.createClass({ |
75 | 72 | propTypes: { |
76 | 73 | /** |
77 | 74 | * Used to truncate the text with an elipsis after computing the text |
@@ -105,121 +102,126 @@ var Text = React.createClass({ |
105 | 102 | */ |
106 | 103 | allowFontScaling: React.PropTypes.bool, |
107 | 104 | }, |
108 | | - |
109 | | - viewConfig: viewConfig, |
110 | | - |
111 | | - getInitialState: function(): Object { |
112 | | - return merge(this.touchableGetInitialState(), { |
113 | | - isHighlighted: false, |
114 | | - }); |
115 | | - }, |
116 | | - getDefaultProps: function(): Object { |
| 105 | + getDefaultProps(): Object { |
117 | 106 | return { |
| 107 | + accessible: true, |
118 | 108 | allowFontScaling: true, |
119 | 109 | }; |
120 | 110 | }, |
121 | | - |
122 | | - onStartShouldSetResponder: function(): bool { |
123 | | - var shouldSetFromProps = this.props.onStartShouldSetResponder && |
124 | | - this.props.onStartShouldSetResponder(); |
125 | | - return shouldSetFromProps || !!this.props.onPress; |
126 | | - }, |
127 | | - |
128 | | - /* |
129 | | - * Returns true to allow responder termination |
130 | | - */ |
131 | | - handleResponderTerminationRequest: function(): bool { |
132 | | - // Allow touchable or props.onResponderTerminationRequest to deny |
133 | | - // the request |
134 | | - var allowTermination = this.touchableHandleResponderTerminationRequest(); |
135 | | - if (allowTermination && this.props.onResponderTerminationRequest) { |
136 | | - allowTermination = this.props.onResponderTerminationRequest(); |
137 | | - } |
138 | | - return allowTermination; |
139 | | - }, |
140 | | - |
141 | | - handleResponderGrant: function(e: SyntheticEvent, dispatchID: string) { |
142 | | - this.touchableHandleResponderGrant(e, dispatchID); |
143 | | - this.props.onResponderGrant && |
144 | | - this.props.onResponderGrant.apply(this, arguments); |
145 | | - }, |
146 | | - |
147 | | - handleResponderMove: function(e: SyntheticEvent) { |
148 | | - this.touchableHandleResponderMove(e); |
149 | | - this.props.onResponderMove && |
150 | | - this.props.onResponderMove.apply(this, arguments); |
151 | | - }, |
152 | | - |
153 | | - handleResponderRelease: function(e: SyntheticEvent) { |
154 | | - this.touchableHandleResponderRelease(e); |
155 | | - this.props.onResponderRelease && |
156 | | - this.props.onResponderRelease.apply(this, arguments); |
157 | | - }, |
158 | | - |
159 | | - handleResponderTerminate: function(e: SyntheticEvent) { |
160 | | - this.touchableHandleResponderTerminate(e); |
161 | | - this.props.onResponderTerminate && |
162 | | - this.props.onResponderTerminate.apply(this, arguments); |
163 | | - }, |
164 | | - |
165 | | - touchableHandleActivePressIn: function() { |
166 | | - if (this.props.suppressHighlighting || !this.props.onPress) { |
167 | | - return; |
168 | | - } |
169 | | - this.setState({ |
170 | | - isHighlighted: true, |
171 | | - }); |
172 | | - }, |
173 | | - |
174 | | - touchableHandleActivePressOut: function() { |
175 | | - if (this.props.suppressHighlighting || !this.props.onPress) { |
176 | | - return; |
177 | | - } |
178 | | - this.setState({ |
| 111 | + getInitialState: function(): Object { |
| 112 | + return merge(Touchable.Mixin.touchableGetInitialState(), { |
179 | 113 | isHighlighted: false, |
180 | 114 | }); |
181 | 115 | }, |
182 | | - |
183 | | - touchableHandlePress: function() { |
184 | | - this.props.onPress && this.props.onPress(); |
185 | | - }, |
186 | | - |
187 | | - touchableGetPressRectOffset: function(): RectOffset { |
188 | | - return PRESS_RECT_OFFSET; |
189 | | - }, |
190 | | - |
191 | | - getChildContext: function(): Object { |
| 116 | + mixins: [NativeMethodsMixin], |
| 117 | + viewConfig: viewConfig, |
| 118 | + getChildContext(): Object { |
192 | 119 | return {isInAParentText: true}; |
193 | 120 | }, |
194 | | - |
195 | 121 | childContextTypes: { |
196 | 122 | isInAParentText: React.PropTypes.bool |
197 | 123 | }, |
198 | | - |
199 | | - render: function() { |
200 | | - var props = {}; |
201 | | - for (var key in this.props) { |
202 | | - props[key] = this.props[key]; |
203 | | - } |
204 | | - // Text is accessible by default |
205 | | - if (props.accessible !== false) { |
206 | | - props.accessible = true; |
| 124 | + contextTypes: { |
| 125 | + isInAParentText: React.PropTypes.bool |
| 126 | + }, |
| 127 | + /** |
| 128 | + * Only assigned if touch is needed. |
| 129 | + */ |
| 130 | + _handlers: (null: ?Object), |
| 131 | + /** |
| 132 | + * These are assigned lazily the first time the responder is set to make plain |
| 133 | + * text nodes as cheap as possible. |
| 134 | + */ |
| 135 | + touchableHandleActivePressIn: (null: ?Function), |
| 136 | + touchableHandleActivePressOut: (null: ?Function), |
| 137 | + touchableHandlePress: (null: ?Function), |
| 138 | + touchableGetPressRectOffset: (null: ?Function), |
| 139 | + render(): ReactElement { |
| 140 | + let newProps = this.props; |
| 141 | + if (this.props.onStartShouldSetResponder || this.props.onPress) { |
| 142 | + if (!this._handlers) { |
| 143 | + this._handlers = { |
| 144 | + onStartShouldSetResponder: (): bool => { |
| 145 | + const shouldSetFromProps = this.props.onStartShouldSetResponder && |
| 146 | + this.props.onStartShouldSetResponder(); |
| 147 | + const setResponder = shouldSetFromProps || !!this.props.onPress; |
| 148 | + if (setResponder && !this.touchableHandleActivePressIn) { |
| 149 | + // Attach and bind all the other handlers only the first time a touch |
| 150 | + // actually happens. |
| 151 | + for (let key in Touchable.Mixin) { |
| 152 | + if (typeof Touchable.Mixin[key] === 'function') { |
| 153 | + (this: any)[key] = Touchable.Mixin[key].bind(this); |
| 154 | + } |
| 155 | + } |
| 156 | + this.touchableHandleActivePressIn = () => { |
| 157 | + if (this.props.suppressHighlighting || !this.props.onPress) { |
| 158 | + return; |
| 159 | + } |
| 160 | + this.setState({ |
| 161 | + isHighlighted: true, |
| 162 | + }); |
| 163 | + }; |
| 164 | + |
| 165 | + this.touchableHandleActivePressOut = () => { |
| 166 | + if (this.props.suppressHighlighting || !this.props.onPress) { |
| 167 | + return; |
| 168 | + } |
| 169 | + this.setState({ |
| 170 | + isHighlighted: false, |
| 171 | + }); |
| 172 | + }; |
| 173 | + |
| 174 | + this.touchableHandlePress = () => { |
| 175 | + this.props.onPress && this.props.onPress(); |
| 176 | + }; |
| 177 | + |
| 178 | + this.touchableGetPressRectOffset = function(): RectOffset { |
| 179 | + return PRESS_RECT_OFFSET; |
| 180 | + }; |
| 181 | + } |
| 182 | + return setResponder; |
| 183 | + }, |
| 184 | + onResponderGrant: (e: SyntheticEvent, dispatchID: string) => { |
| 185 | + this.touchableHandleResponderGrant(e, dispatchID); |
| 186 | + this.props.onResponderGrant && |
| 187 | + this.props.onResponderGrant.apply(this, arguments); |
| 188 | + }, |
| 189 | + onResponderMove: (e: SyntheticEvent) => { |
| 190 | + this.touchableHandleResponderMove(e); |
| 191 | + this.props.onResponderMove && |
| 192 | + this.props.onResponderMove.apply(this, arguments); |
| 193 | + }, |
| 194 | + onResponderRelease: (e: SyntheticEvent) => { |
| 195 | + this.touchableHandleResponderRelease(e); |
| 196 | + this.props.onResponderRelease && |
| 197 | + this.props.onResponderRelease.apply(this, arguments); |
| 198 | + }, |
| 199 | + onResponderTerminate: (e: SyntheticEvent) => { |
| 200 | + this.touchableHandleResponderTerminate(e); |
| 201 | + this.props.onResponderTerminate && |
| 202 | + this.props.onResponderTerminate.apply(this, arguments); |
| 203 | + }, |
| 204 | + onResponderTerminationRequest: (): bool => { |
| 205 | + // Allow touchable or props.onResponderTerminationRequest to deny |
| 206 | + // the request |
| 207 | + var allowTermination = this.touchableHandleResponderTerminationRequest(); |
| 208 | + if (allowTermination && this.props.onResponderTerminationRequest) { |
| 209 | + allowTermination = this.props.onResponderTerminationRequest(); |
| 210 | + } |
| 211 | + return allowTermination; |
| 212 | + }, |
| 213 | + }; |
| 214 | + } |
| 215 | + newProps = { |
| 216 | + ...this.props, |
| 217 | + ...this._handlers, |
| 218 | + isHighlighted: this.state.isHighlighted, |
| 219 | + }; |
207 | 220 | } |
208 | | - props.isHighlighted = this.state.isHighlighted; |
209 | | - props.onStartShouldSetResponder = this.onStartShouldSetResponder; |
210 | | - props.onResponderTerminationRequest = |
211 | | - this.handleResponderTerminationRequest; |
212 | | - props.onResponderGrant = this.handleResponderGrant; |
213 | | - props.onResponderMove = this.handleResponderMove; |
214 | | - props.onResponderRelease = this.handleResponderRelease; |
215 | | - props.onResponderTerminate = this.handleResponderTerminate; |
216 | | - |
217 | | - // TODO: Switch to use contextTypes and this.context after React upgrade |
218 | | - var context = ReactInstanceMap.get(this)._context; |
219 | | - if (context.isInAParentText) { |
220 | | - return <RCTVirtualText {...props} />; |
| 221 | + if (this.context.isInAParentText) { |
| 222 | + return <RCTVirtualText {...newProps} />; |
221 | 223 | } else { |
222 | | - return <RCTText {...props} />; |
| 224 | + return <RCTText {...newProps} />; |
223 | 225 | } |
224 | 226 | }, |
225 | 227 | }); |
|
0 commit comments