UNPKG

26.9 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
8
9var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
10
11var _react = require('react');
12
13var _react2 = _interopRequireDefault(_react);
14
15var _reactDom = require('react-dom');
16
17var _reactDom2 = _interopRequireDefault(_reactDom);
18
19var _PressEvent = require('./PressEvent');
20
21var _PressEvent2 = _interopRequireDefault(_PressEvent);
22
23function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
24
25function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
26
27function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
28
29function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // inspired by react-native
30
31
32function keyMirror(obj) {
33 Object.keys(obj).forEach(function (k) {
34 return obj[k] = k;
35 });
36 return obj;
37}
38function copy(from, list) {
39 var to = {};
40 list.forEach(function (k) {
41 to[k] = from[k];
42 });
43 return to;
44}
45function extractSingleTouch(_nativeEvent) {
46 var nativeEvent = _nativeEvent;
47 if (nativeEvent.nativeEvent) {
48 nativeEvent = nativeEvent.nativeEvent;
49 }
50 var touches = nativeEvent.touches;
51 var changedTouches = nativeEvent.changedTouches;
52 var hasTouches = touches && touches.length > 0;
53 var hasChangedTouches = changedTouches && changedTouches.length > 0;
54 return !hasTouches && hasChangedTouches ? changedTouches[0] : hasTouches ? touches[0] : nativeEvent;
55}
56/**
57 * Touchable states.
58 */
59var States = keyMirror({
60 NOT_RESPONDER: null,
61 RESPONDER_INACTIVE_PRESS_IN: null,
62 RESPONDER_INACTIVE_PRESS_OUT: null,
63 RESPONDER_ACTIVE_PRESS_IN: null,
64 RESPONDER_ACTIVE_PRESS_OUT: null,
65 RESPONDER_ACTIVE_LONG_PRESS_IN: null,
66 RESPONDER_ACTIVE_LONG_PRESS_OUT: null,
67 ERROR: null
68});
69/**
70 * Quick lookup map for states that are considered to be "active"
71 */
72var IsActive = {
73 RESPONDER_ACTIVE_PRESS_OUT: true,
74 RESPONDER_ACTIVE_PRESS_IN: true
75};
76/**
77 * Quick lookup for states that are considered to be "pressing" and are
78 * therefore eligible to result in a "selection" if the press stops.
79 */
80var IsPressingIn = {
81 RESPONDER_INACTIVE_PRESS_IN: true,
82 RESPONDER_ACTIVE_PRESS_IN: true,
83 RESPONDER_ACTIVE_LONG_PRESS_IN: true
84};
85var IsLongPressingIn = {
86 RESPONDER_ACTIVE_LONG_PRESS_IN: true
87};
88/**
89 * Inputs to the state machine.
90 */
91var Signals = keyMirror({
92 DELAY: null,
93 RESPONDER_GRANT: null,
94 RESPONDER_RELEASE: null,
95 RESPONDER_TERMINATED: null,
96 ENTER_PRESS_RECT: null,
97 LEAVE_PRESS_RECT: null,
98 LONG_PRESS_DETECTED: null
99});
100/**
101 * Mapping from States x Signals => States
102 */
103var Transitions = {
104 NOT_RESPONDER: {
105 DELAY: States.ERROR,
106 RESPONDER_GRANT: States.RESPONDER_INACTIVE_PRESS_IN,
107 RESPONDER_RELEASE: States.ERROR,
108 RESPONDER_TERMINATED: States.ERROR,
109 ENTER_PRESS_RECT: States.ERROR,
110 LEAVE_PRESS_RECT: States.ERROR,
111 LONG_PRESS_DETECTED: States.ERROR
112 },
113 RESPONDER_INACTIVE_PRESS_IN: {
114 DELAY: States.RESPONDER_ACTIVE_PRESS_IN,
115 RESPONDER_GRANT: States.ERROR,
116 RESPONDER_RELEASE: States.NOT_RESPONDER,
117 RESPONDER_TERMINATED: States.NOT_RESPONDER,
118 ENTER_PRESS_RECT: States.RESPONDER_INACTIVE_PRESS_IN,
119 LEAVE_PRESS_RECT: States.RESPONDER_INACTIVE_PRESS_OUT,
120 LONG_PRESS_DETECTED: States.ERROR
121 },
122 RESPONDER_INACTIVE_PRESS_OUT: {
123 DELAY: States.RESPONDER_ACTIVE_PRESS_OUT,
124 RESPONDER_GRANT: States.ERROR,
125 RESPONDER_RELEASE: States.NOT_RESPONDER,
126 RESPONDER_TERMINATED: States.NOT_RESPONDER,
127 ENTER_PRESS_RECT: States.RESPONDER_INACTIVE_PRESS_IN,
128 LEAVE_PRESS_RECT: States.RESPONDER_INACTIVE_PRESS_OUT,
129 LONG_PRESS_DETECTED: States.ERROR
130 },
131 RESPONDER_ACTIVE_PRESS_IN: {
132 DELAY: States.ERROR,
133 RESPONDER_GRANT: States.ERROR,
134 RESPONDER_RELEASE: States.NOT_RESPONDER,
135 RESPONDER_TERMINATED: States.NOT_RESPONDER,
136 ENTER_PRESS_RECT: States.RESPONDER_ACTIVE_PRESS_IN,
137 LEAVE_PRESS_RECT: States.RESPONDER_ACTIVE_PRESS_OUT,
138 LONG_PRESS_DETECTED: States.RESPONDER_ACTIVE_LONG_PRESS_IN
139 },
140 RESPONDER_ACTIVE_PRESS_OUT: {
141 DELAY: States.ERROR,
142 RESPONDER_GRANT: States.ERROR,
143 RESPONDER_RELEASE: States.NOT_RESPONDER,
144 RESPONDER_TERMINATED: States.NOT_RESPONDER,
145 ENTER_PRESS_RECT: States.RESPONDER_ACTIVE_PRESS_IN,
146 LEAVE_PRESS_RECT: States.RESPONDER_ACTIVE_PRESS_OUT,
147 LONG_PRESS_DETECTED: States.ERROR
148 },
149 RESPONDER_ACTIVE_LONG_PRESS_IN: {
150 DELAY: States.ERROR,
151 RESPONDER_GRANT: States.ERROR,
152 RESPONDER_RELEASE: States.NOT_RESPONDER,
153 RESPONDER_TERMINATED: States.NOT_RESPONDER,
154 ENTER_PRESS_RECT: States.RESPONDER_ACTIVE_LONG_PRESS_IN,
155 LEAVE_PRESS_RECT: States.RESPONDER_ACTIVE_LONG_PRESS_OUT,
156 LONG_PRESS_DETECTED: States.RESPONDER_ACTIVE_LONG_PRESS_IN
157 },
158 RESPONDER_ACTIVE_LONG_PRESS_OUT: {
159 DELAY: States.ERROR,
160 RESPONDER_GRANT: States.ERROR,
161 RESPONDER_RELEASE: States.NOT_RESPONDER,
162 RESPONDER_TERMINATED: States.NOT_RESPONDER,
163 ENTER_PRESS_RECT: States.RESPONDER_ACTIVE_LONG_PRESS_IN,
164 LEAVE_PRESS_RECT: States.RESPONDER_ACTIVE_LONG_PRESS_OUT,
165 LONG_PRESS_DETECTED: States.ERROR
166 },
167 error: {
168 DELAY: States.NOT_RESPONDER,
169 RESPONDER_GRANT: States.RESPONDER_INACTIVE_PRESS_IN,
170 RESPONDER_RELEASE: States.NOT_RESPONDER,
171 RESPONDER_TERMINATED: States.NOT_RESPONDER,
172 ENTER_PRESS_RECT: States.NOT_RESPONDER,
173 LEAVE_PRESS_RECT: States.NOT_RESPONDER,
174 LONG_PRESS_DETECTED: States.NOT_RESPONDER
175 }
176};
177// ==== Typical Constants for integrating into UI components ====
178// const HIT_EXPAND_PX = 20;
179// const HIT_VERT_OFFSET_PX = 10;
180var HIGHLIGHT_DELAY_MS = 130;
181var PRESS_EXPAND_PX = 20;
182var LONG_PRESS_THRESHOLD = 500;
183var LONG_PRESS_DELAY_MS = LONG_PRESS_THRESHOLD - HIGHLIGHT_DELAY_MS;
184var LONG_PRESS_ALLOWED_MOVEMENT = 10;
185var lastClickTime = 0;
186var pressDelay = 200;
187function isAllowPress() {
188 // avoid click penetration
189 return Date.now() - lastClickTime >= pressDelay;
190}
191
192var Touchable = function (_React$Component) {
193 _inherits(Touchable, _React$Component);
194
195 function Touchable() {
196 _classCallCheck(this, Touchable);
197
198 var _this = _possibleConstructorReturn(this, (Touchable.__proto__ || Object.getPrototypeOf(Touchable)).apply(this, arguments));
199
200 _this.state = {
201 active: false
202 };
203 _this.touchable = { touchState: undefined };
204 _this.onTouchStart = function (e) {
205 _this.callChildEvent('onTouchStart', e);
206 _this.lockMouse = true;
207 if (_this.releaseLockTimer) {
208 clearTimeout(_this.releaseLockTimer);
209 }
210 _this.touchableHandleResponderGrant(e.nativeEvent);
211 };
212 _this.onTouchMove = function (e) {
213 _this.callChildEvent('onTouchMove', e);
214 _this.touchableHandleResponderMove(e.nativeEvent);
215 };
216 _this.onTouchEnd = function (e) {
217 _this.callChildEvent('onTouchEnd', e);
218 _this.releaseLockTimer = setTimeout(function () {
219 _this.lockMouse = false;
220 }, 300);
221 _this.touchableHandleResponderRelease(new _PressEvent2['default'](e.nativeEvent));
222 };
223 _this.onTouchCancel = function (e) {
224 _this.callChildEvent('onTouchCancel', e);
225 _this.releaseLockTimer = setTimeout(function () {
226 _this.lockMouse = false;
227 }, 300);
228 _this.touchableHandleResponderTerminate(e.nativeEvent);
229 };
230 _this.onMouseDown = function (e) {
231 _this.callChildEvent('onMouseDown', e);
232 if (_this.lockMouse) {
233 return;
234 }
235 _this.touchableHandleResponderGrant(e.nativeEvent);
236 document.addEventListener('mousemove', _this.touchableHandleResponderMove, false);
237 document.addEventListener('mouseup', _this.onMouseUp, false);
238 };
239 _this.onMouseUp = function (e) {
240 document.removeEventListener('mousemove', _this.touchableHandleResponderMove, false);
241 document.removeEventListener('mouseup', _this.onMouseUp, false);
242 _this.touchableHandleResponderRelease(new _PressEvent2['default'](e));
243 };
244 _this.touchableHandleResponderMove = function (e) {
245 if (!_this.touchable.startMouse) {
246 return;
247 }
248 // Measurement may not have returned yet.
249 if (!_this.touchable.dimensionsOnActivate || _this.touchable.touchState === States.NOT_RESPONDER) {
250 return;
251 }
252 // Not enough time elapsed yet, wait for highlight -
253 // this is just a perf optimization.
254 if (_this.touchable.touchState === States.RESPONDER_INACTIVE_PRESS_IN) {
255 return;
256 }
257 var touch = extractSingleTouch(e);
258 var pageX = touch && touch.pageX;
259 var pageY = touch && touch.pageY;
260 if (_this.pressInLocation) {
261 var movedDistance = _this._getDistanceBetweenPoints(pageX, pageY, _this.pressInLocation.pageX, _this.pressInLocation.pageY);
262 if (movedDistance > LONG_PRESS_ALLOWED_MOVEMENT) {
263 _this._cancelLongPressDelayTimeout();
264 }
265 }
266 if (_this.checkTouchWithinActive(e)) {
267 _this._receiveSignal(Signals.ENTER_PRESS_RECT, e);
268 var curState = _this.touchable.touchState;
269 if (curState === States.RESPONDER_INACTIVE_PRESS_IN) {
270 _this._cancelLongPressDelayTimeout();
271 }
272 } else {
273 _this._cancelLongPressDelayTimeout();
274 _this._receiveSignal(Signals.LEAVE_PRESS_RECT, e);
275 }
276 };
277 return _this;
278 }
279
280 _createClass(Touchable, [{
281 key: 'componentDidMount',
282 value: function componentDidMount() {
283 this.root = _reactDom2['default'].findDOMNode(this);
284 }
285 }, {
286 key: 'componentDidUpdate',
287 value: function componentDidUpdate() {
288 this.root = _reactDom2['default'].findDOMNode(this);
289 // disabled auto clear active state
290 if (this.props.disabled && this.state.active) {
291 this.setState({
292 active: false
293 });
294 }
295 }
296 }, {
297 key: 'componentWillUnmount',
298 value: function componentWillUnmount() {
299 if (this.releaseLockTimer) {
300 clearTimeout(this.releaseLockTimer);
301 }
302 if (this.touchableDelayTimeout) {
303 clearTimeout(this.touchableDelayTimeout);
304 }
305 if (this.longPressDelayTimeout) {
306 clearTimeout(this.longPressDelayTimeout);
307 }
308 if (this.pressOutDelayTimeout) {
309 clearTimeout(this.pressOutDelayTimeout);
310 }
311 }
312 }, {
313 key: 'callChildEvent',
314 value: function callChildEvent(event, e) {
315 var childHandle = _react2['default'].Children.only(this.props.children).props[event];
316 if (childHandle) {
317 childHandle(e);
318 }
319 }
320 }, {
321 key: '_remeasureMetricsOnInit',
322 value: function _remeasureMetricsOnInit(e) {
323 var root = this.root;
324
325 var touch = extractSingleTouch(e);
326 var boundingRect = root.getBoundingClientRect();
327 this.touchable = {
328 touchState: this.touchable.touchState,
329 startMouse: {
330 pageX: touch.pageX,
331 pageY: touch.pageY
332 },
333 positionOnGrant: {
334 left: boundingRect.left + window.pageXOffset,
335 top: boundingRect.top + window.pageYOffset,
336 width: boundingRect.width,
337 height: boundingRect.height,
338 clientLeft: boundingRect.left,
339 clientTop: boundingRect.top
340 }
341 };
342 }
343 }, {
344 key: 'processActiveStopPropagation',
345 value: function processActiveStopPropagation(e) {
346 var nativeEvent = e.nativeEvent || e;
347 this.shouldActive = !nativeEvent.__activeStopPropagation;
348 if (this.props.activeStopPropagation) {
349 nativeEvent.__activeStopPropagation = 1;
350 }
351 }
352 }, {
353 key: 'touchableHandleResponderGrant',
354 value: function touchableHandleResponderGrant(e) {
355 var _this2 = this;
356
357 this.touchable.touchState = States.NOT_RESPONDER;
358 if (this.pressOutDelayTimeout) {
359 clearTimeout(this.pressOutDelayTimeout);
360 this.pressOutDelayTimeout = null;
361 }
362 if (this.props.fixClickPenetration && !isAllowPress()) {
363 return;
364 }
365 this._remeasureMetricsOnInit(e);
366 this._receiveSignal(Signals.RESPONDER_GRANT, e);
367 var _props = this.props,
368 delayMS = _props.delayPressIn,
369 longDelayMS = _props.delayLongPress;
370
371 this.processActiveStopPropagation(e);
372 if (delayMS) {
373 this.touchableDelayTimeout = setTimeout(function () {
374 _this2._handleDelay(e);
375 }, delayMS);
376 } else {
377 this._handleDelay(e);
378 }
379 var longPressEvent = new _PressEvent2['default'](e);
380 this.longPressDelayTimeout = setTimeout(function () {
381 _this2._handleLongDelay(longPressEvent);
382 }, longDelayMS + delayMS);
383 }
384 }, {
385 key: 'checkScroll',
386 value: function checkScroll(e) {
387 var positionOnGrant = this.touchable.positionOnGrant;
388 // container or window scroll
389 var boundingRect = this.root.getBoundingClientRect();
390 if (boundingRect.left !== positionOnGrant.clientLeft || boundingRect.top !== positionOnGrant.clientTop) {
391 this._receiveSignal(Signals.RESPONDER_TERMINATED, e);
392 return true;
393 }
394 return false;
395 }
396 }, {
397 key: 'touchableHandleResponderRelease',
398 value: function touchableHandleResponderRelease(e) {
399 if (!this.touchable.startMouse) {
400 return;
401 }
402 var touch = extractSingleTouch(e);
403 if (Math.abs(touch.pageX - this.touchable.startMouse.pageX) > 30 || Math.abs(touch.pageY - this.touchable.startMouse.pageY) > 30) {
404 this._receiveSignal(Signals.RESPONDER_TERMINATED, e);
405 return;
406 }
407 if (this.checkScroll(e)) {
408 return;
409 }
410 this._receiveSignal(Signals.RESPONDER_RELEASE, e);
411 }
412 }, {
413 key: 'touchableHandleResponderTerminate',
414 value: function touchableHandleResponderTerminate(e) {
415 if (!this.touchable.startMouse) {
416 return;
417 }
418 this._receiveSignal(Signals.RESPONDER_TERMINATED, e);
419 }
420 }, {
421 key: 'checkTouchWithinActive',
422 value: function checkTouchWithinActive(e) {
423 var positionOnGrant = this.touchable.positionOnGrant;
424 var _props2 = this.props,
425 _props2$pressRetentio = _props2.pressRetentionOffset,
426 pressRetentionOffset = _props2$pressRetentio === undefined ? {} : _props2$pressRetentio,
427 hitSlop = _props2.hitSlop;
428
429 var pressExpandLeft = pressRetentionOffset.left;
430 var pressExpandTop = pressRetentionOffset.top;
431 var pressExpandRight = pressRetentionOffset.right;
432 var pressExpandBottom = pressRetentionOffset.bottom;
433 if (hitSlop) {
434 pressExpandLeft += hitSlop.left;
435 pressExpandTop += hitSlop.top;
436 pressExpandRight += hitSlop.right;
437 pressExpandBottom += hitSlop.bottom;
438 }
439 var touch = extractSingleTouch(e);
440 var pageX = touch && touch.pageX;
441 var pageY = touch && touch.pageY;
442 return pageX > positionOnGrant.left - pressExpandLeft && pageY > positionOnGrant.top - pressExpandTop && pageX < positionOnGrant.left + positionOnGrant.width + pressExpandRight && pageY < positionOnGrant.top + positionOnGrant.height + pressExpandBottom;
443 }
444 }, {
445 key: 'callProp',
446 value: function callProp(name, e) {
447 if (this.props[name] && !this.props.disabled) {
448 this.props[name](e);
449 }
450 }
451 }, {
452 key: 'touchableHandleActivePressIn',
453 value: function touchableHandleActivePressIn(e) {
454 if (this.shouldActive) {
455 this.setActive(true);
456 }
457 this.callProp('onPressIn', e);
458 }
459 }, {
460 key: 'touchableHandleActivePressOut',
461 value: function touchableHandleActivePressOut(e) {
462 this.setActive(false);
463 this.callProp('onPressOut', e);
464 }
465 }, {
466 key: 'touchableHandlePress',
467 value: function touchableHandlePress(e) {
468 if ((0, _PressEvent.shouldFirePress)(e)) {
469 this.callProp('onPress', e);
470 }
471 lastClickTime = Date.now();
472 }
473 }, {
474 key: 'touchableHandleLongPress',
475 value: function touchableHandleLongPress(e) {
476 if ((0, _PressEvent.shouldFirePress)(e)) {
477 this.callProp('onLongPress', e);
478 }
479 }
480 }, {
481 key: 'setActive',
482 value: function setActive(active) {
483 if (this.state.active !== active && (this.props.activeClassName || this.props.activeStyle)) {
484 this.setState({
485 active: active
486 });
487 }
488 }
489 }, {
490 key: '_remeasureMetricsOnActivation',
491 value: function _remeasureMetricsOnActivation() {
492 this.touchable.dimensionsOnActivate = this.touchable.positionOnGrant;
493 }
494 }, {
495 key: '_handleDelay',
496 value: function _handleDelay(e) {
497 this.touchableDelayTimeout = null;
498 this._receiveSignal(Signals.DELAY, e);
499 }
500 }, {
501 key: '_handleLongDelay',
502 value: function _handleLongDelay(e) {
503 this.longPressDelayTimeout = null;
504 var curState = this.touchable.touchState;
505 if (curState !== States.RESPONDER_ACTIVE_PRESS_IN && curState !== States.RESPONDER_ACTIVE_LONG_PRESS_IN) {
506 console.error('Attempted to transition from state `' + curState + '` to `' + States.RESPONDER_ACTIVE_LONG_PRESS_IN + '`, which is not supported. This is ' + 'most likely due to `Touchable.longPressDelayTimeout` not being cancelled.');
507 } else {
508 this._receiveSignal(Signals.LONG_PRESS_DETECTED, e);
509 }
510 }
511 }, {
512 key: '_receiveSignal',
513 value: function _receiveSignal(signal, e) {
514 var curState = this.touchable.touchState;
515 var nextState = Transitions[curState] && Transitions[curState][signal];
516 if (!nextState) {
517 return;
518 }
519 if (nextState === States.ERROR) {
520 return;
521 }
522 if (curState !== nextState) {
523 this._performSideEffectsForTransition(curState, nextState, signal, e);
524 this.touchable.touchState = nextState;
525 }
526 }
527 }, {
528 key: '_cancelLongPressDelayTimeout',
529 value: function _cancelLongPressDelayTimeout() {
530 if (this.longPressDelayTimeout) {
531 clearTimeout(this.longPressDelayTimeout);
532 this.longPressDelayTimeout = null;
533 }
534 }
535 }, {
536 key: '_isHighlight',
537 value: function _isHighlight(state) {
538 return state === States.RESPONDER_ACTIVE_PRESS_IN || state === States.RESPONDER_ACTIVE_LONG_PRESS_IN;
539 }
540 }, {
541 key: '_savePressInLocation',
542 value: function _savePressInLocation(e) {
543 var touch = extractSingleTouch(e);
544 var pageX = touch && touch.pageX;
545 var pageY = touch && touch.pageY;
546 this.pressInLocation = { pageX: pageX, pageY: pageY };
547 }
548 }, {
549 key: '_getDistanceBetweenPoints',
550 value: function _getDistanceBetweenPoints(aX, aY, bX, bY) {
551 var deltaX = aX - bX;
552 var deltaY = aY - bY;
553 return Math.sqrt(deltaX * deltaX + deltaY * deltaY);
554 }
555 }, {
556 key: '_performSideEffectsForTransition',
557 value: function _performSideEffectsForTransition(curState, nextState, signal, e) {
558 var curIsHighlight = this._isHighlight(curState);
559 var newIsHighlight = this._isHighlight(nextState);
560 var isFinalSignal = signal === Signals.RESPONDER_TERMINATED || signal === Signals.RESPONDER_RELEASE;
561 if (isFinalSignal) {
562 this._cancelLongPressDelayTimeout();
563 }
564 if (!IsActive[curState] && IsActive[nextState]) {
565 this._remeasureMetricsOnActivation();
566 }
567 if (IsPressingIn[curState] && signal === Signals.LONG_PRESS_DETECTED) {
568 this.touchableHandleLongPress(e);
569 }
570 if (newIsHighlight && !curIsHighlight) {
571 this._startHighlight(e);
572 } else if (!newIsHighlight && curIsHighlight) {
573 this._endHighlight(e);
574 }
575 if (IsPressingIn[curState] && signal === Signals.RESPONDER_RELEASE) {
576 var hasLongPressHandler = !!this.props.onLongPress;
577 var pressIsLongButStillCallOnPress = IsLongPressingIn[curState] && ( // We *are* long pressing..
578 !hasLongPressHandler || // But either has no long handler
579 !this.props.longPressCancelsPress // or we're told to ignore it.
580 );
581 var shouldInvokePress = !IsLongPressingIn[curState] || pressIsLongButStillCallOnPress;
582 if (shouldInvokePress) {
583 if (!newIsHighlight && !curIsHighlight) {
584 // we never highlighted because of delay, but we should highlight now
585 this._startHighlight(e);
586 this._endHighlight(e);
587 }
588 this.touchableHandlePress(e);
589 }
590 }
591 if (this.touchableDelayTimeout) {
592 clearTimeout(this.touchableDelayTimeout);
593 this.touchableDelayTimeout = null;
594 }
595 }
596 }, {
597 key: '_startHighlight',
598 value: function _startHighlight(e) {
599 this._savePressInLocation(e);
600 this.touchableHandleActivePressIn(e);
601 }
602 }, {
603 key: '_endHighlight',
604 value: function _endHighlight(e) {
605 var _this3 = this;
606
607 if (this.props.delayPressOut) {
608 this.pressOutDelayTimeout = setTimeout(function () {
609 _this3.touchableHandleActivePressOut(e);
610 }, this.props.delayPressOut);
611 } else {
612 this.touchableHandleActivePressOut(e);
613 }
614 }
615 }, {
616 key: 'render',
617 value: function render() {
618 var _props3 = this.props,
619 children = _props3.children,
620 disabled = _props3.disabled,
621 activeStyle = _props3.activeStyle,
622 activeClassName = _props3.activeClassName;
623
624 var events = disabled ? undefined : copy(this, ['onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel', 'onMouseDown']);
625 var child = _react2['default'].Children.only(children);
626 if (!disabled && this.state.active) {
627 var _child$props = child.props,
628 style = _child$props.style,
629 className = _child$props.className;
630
631 if (activeStyle) {
632 style = _extends({}, style, activeStyle);
633 }
634 if (activeClassName) {
635 if (className) {
636 className += ' ' + activeClassName;
637 } else {
638 className = activeClassName;
639 }
640 }
641 return _react2['default'].cloneElement(child, _extends({ className: className,
642 style: style }, events));
643 }
644 return _react2['default'].cloneElement(child, events);
645 }
646 }]);
647
648 return Touchable;
649}(_react2['default'].Component);
650
651exports['default'] = Touchable;
652
653Touchable.defaultProps = {
654 fixClickPenetration: false,
655 disabled: false,
656 delayPressIn: HIGHLIGHT_DELAY_MS,
657 delayLongPress: LONG_PRESS_DELAY_MS,
658 delayPressOut: 100,
659 pressRetentionOffset: {
660 left: PRESS_EXPAND_PX,
661 right: PRESS_EXPAND_PX,
662 top: PRESS_EXPAND_PX,
663 bottom: PRESS_EXPAND_PX
664 },
665 hitSlop: undefined,
666 longPressCancelsPress: true
667};
668module.exports = exports['default'];
\No newline at end of file