1010import type {
1111 ReactResponderEvent ,
1212 ReactResponderContext ,
13- ReactResponderDispatchEventOptions ,
1413} from 'shared/ReactTypes' ;
1514
1615import React from 'react' ;
17-
1816import { isEventPositionWithinTouchHitTarget } from './utils' ;
1917
2018type PressProps = {
@@ -86,6 +84,13 @@ type PressEvent = {|
8684 target : Element | Document ,
8785 type : PressEventType ,
8886 pointerType : PointerType ,
87+ timeStamp : null | number ,
88+ clientX : null | number ,
89+ clientY : null | number ,
90+ pageX : null | number ,
91+ pageY : null | number ,
92+ screenX : null | number ,
93+ screenY : null | number ,
8994| } ;
9095
9196const DEFAULT_PRESS_END_DELAY_MS = 0 ;
@@ -133,58 +138,112 @@ function createPressEvent(
133138 type : PressEventType ,
134139 target : Element | Document ,
135140 pointerType : PointerType ,
141+ event : ?ReactResponderEvent ,
142+ delay : number ,
136143) : PressEvent {
144+ let clientX = null ;
145+ let clientY = null ;
146+ let pageX = null ;
147+ let pageY = null ;
148+ let screenX = null ;
149+ let screenY = null ;
150+ let timeStamp = null ;
151+
152+ if ( event ) {
153+ const nativeEvent = ( event . nativeEvent : any ) ;
154+ timeStamp = nativeEvent . timeStamp + delay ;
155+ // Only check for one property, checking for all of them is costly. We can assume
156+ // if clientX exists, so do the rest.
157+ let eventObject ;
158+ if ( nativeEvent . clientX !== undefined ) {
159+ eventObject = ( nativeEvent : any ) ;
160+ } else if ( isTouchEvent ( nativeEvent ) ) {
161+ eventObject = getTouchFromPressEvent ( nativeEvent ) ;
162+ }
163+ if ( eventObject ) {
164+ ( { clientX, clientY, pageX, pageY, screenX, screenY} = eventObject ) ;
165+ }
166+ }
137167 return {
138168 target,
139169 type,
140170 pointerType,
171+ timeStamp,
172+ clientX,
173+ clientY,
174+ pageX,
175+ pageY,
176+ screenX,
177+ screenY,
141178 } ;
142179}
143180
144181function dispatchEvent (
182+ event : ?ReactResponderEvent ,
145183 context : ReactResponderContext ,
146184 state : PressState ,
147185 name : PressEventType ,
148186 listener : ( e : Object ) = > void ,
149- options ?: ReactResponderDispatchEventOptions ,
187+ discrete : boolean ,
188+ delay : number ,
150189) : void {
151190 const target = ( ( state . pressTarget : any ) : Element | Document ) ;
152191 const pointerType = state . pointerType ;
153- const syntheticEvent = createPressEvent ( name , target , pointerType ) ;
154- context . dispatchEvent (
155- syntheticEvent ,
156- listener ,
157- options || {
158- discrete : true ,
159- } ,
192+ const syntheticEvent = createPressEvent (
193+ name ,
194+ target ,
195+ pointerType ,
196+ event ,
197+ delay ,
160198 ) ;
199+ context . dispatchEvent ( syntheticEvent , listener , {
200+ discrete,
201+ } ) ;
161202}
162203
163204function dispatchPressChangeEvent (
205+ event : ?ReactResponderEvent ,
164206 context : ReactResponderContext ,
165207 props : PressProps ,
166208 state : PressState ,
209+ delay : number ,
167210) : void {
168211 const bool = state . isActivePressed ;
169212 const listener = ( ) => {
170213 props . onPressChange ( bool ) ;
171214 } ;
172- dispatchEvent ( context , state , 'presschange' , listener ) ;
215+ dispatchEvent ( event , context , state , 'presschange' , listener , true , delay ) ;
173216}
174217
175218function dispatchLongPressChangeEvent (
219+ event : ?ReactResponderEvent ,
176220 context : ReactResponderContext ,
177221 props : PressProps ,
178222 state : PressState ,
223+ delay : number ,
179224) : void {
180225 const bool = state . isLongPressed ;
181226 const listener = ( ) => {
182227 props . onLongPressChange ( bool ) ;
183228 } ;
184- dispatchEvent ( context , state , 'longpresschange' , listener ) ;
229+ dispatchEvent (
230+ event ,
231+ context ,
232+ state ,
233+ 'longpresschange' ,
234+ listener ,
235+ true ,
236+ delay ,
237+ ) ;
185238}
186239
187- function activate ( event , context , props , state ) {
240+ function activate (
241+ event : ReactResponderEvent ,
242+ context ,
243+ props ,
244+ state ,
245+ delay : number ,
246+ ) {
188247 const nativeEvent : any = event . nativeEvent ;
189248 const { x, y} = getEventPageCoords ( nativeEvent ) ;
190249 const wasActivePressed = state . isActivePressed ;
@@ -197,26 +256,48 @@ function activate(event, context, props, state) {
197256 }
198257
199258 if ( props . onPressStart ) {
200- dispatchEvent ( context , state , 'pressstart' , props . onPressStart ) ;
259+ dispatchEvent (
260+ event ,
261+ context ,
262+ state ,
263+ 'pressstart' ,
264+ props . onPressStart ,
265+ true ,
266+ delay ,
267+ ) ;
201268 }
202269 if ( ! wasActivePressed && props . onPressChange ) {
203- dispatchPressChangeEvent ( context , props , state ) ;
270+ dispatchPressChangeEvent ( event , context , props , state , delay ) ;
204271 }
205272}
206273
207- function deactivate ( context , props , state ) {
274+ function deactivate (
275+ event : ?ReactResponderEvent ,
276+ context ,
277+ props ,
278+ state ,
279+ delay : number ,
280+ ) {
208281 const wasLongPressed = state . isLongPressed ;
209282 state . isActivePressed = false ;
210283 state . isLongPressed = false ;
211284
212285 if ( props . onPressEnd ) {
213- dispatchEvent ( context , state , 'pressend' , props . onPressEnd ) ;
286+ dispatchEvent (
287+ event ,
288+ context ,
289+ state ,
290+ 'pressend' ,
291+ props . onPressEnd ,
292+ true ,
293+ delay ,
294+ ) ;
214295 }
215296 if ( props . onPressChange ) {
216- dispatchPressChangeEvent ( context , props , state ) ;
297+ dispatchPressChangeEvent ( event , context , props , state , delay ) ;
217298 }
218299 if ( wasLongPressed && props . onLongPressChange ) {
219- dispatchLongPressChangeEvent ( context , props , state ) ;
300+ dispatchLongPressChangeEvent ( event , context , props , state , delay ) ;
220301 }
221302}
222303
@@ -233,9 +314,9 @@ function dispatchPressStartEvents(
233314 state . pressEndTimeout = null ;
234315 }
235316
236- const dispatch = ( ) => {
317+ const dispatch = ( delay : number ) => {
237318 state . isActivePressStart = true ;
238- activate ( event , context , props , state ) ;
319+ activate ( event , context , props , state , delay ) ;
239320
240321 if (
241322 ( props . onLongPress || props . onLongPressChange ) &&
@@ -250,10 +331,24 @@ function dispatchPressStartEvents(
250331 state . isLongPressed = true ;
251332 state . longPressTimeout = null ;
252333 if ( props . onLongPress ) {
253- dispatchEvent ( context , state , 'longpress' , props . onLongPress ) ;
334+ dispatchEvent (
335+ event ,
336+ context ,
337+ state ,
338+ 'longpress' ,
339+ props . onLongPress ,
340+ true ,
341+ delayLongPress + delay ,
342+ ) ;
254343 }
255344 if ( props . onLongPressChange ) {
256- dispatchLongPressChangeEvent ( context , props , state ) ;
345+ dispatchLongPressChangeEvent (
346+ event ,
347+ context ,
348+ props ,
349+ state ,
350+ delayLongPress + delay ,
351+ ) ;
257352 }
258353 } , delayLongPress ) ;
259354 }
@@ -268,10 +363,10 @@ function dispatchPressStartEvents(
268363 if ( delayPressStart > 0 ) {
269364 state . pressStartTimeout = context . setTimeout ( ( ) => {
270365 state . pressStartTimeout = null ;
271- dispatch ( ) ;
366+ dispatch ( delayPressStart ) ;
272367 } , delayPressStart ) ;
273368 } else {
274- dispatch ( ) ;
369+ dispatch ( 0 ) ;
275370 }
276371 }
277372}
@@ -299,7 +394,7 @@ function dispatchPressEndEvents(
299394 // don't activate if a press has moved beyond the responder region
300395 if ( state . isPressWithinResponderRegion && event != null ) {
301396 // if we haven't yet activated (due to delays), activate now
302- activate ( event , context , props , state ) ;
397+ activate ( event , context , props , state , 0 ) ;
303398 activationWasForced = true ;
304399 }
305400 }
@@ -316,10 +411,10 @@ function dispatchPressEndEvents(
316411 if ( delayPressEnd > 0 ) {
317412 state . pressEndTimeout = context . setTimeout ( ( ) => {
318413 state . pressEndTimeout = null ;
319- deactivate ( context , props , state ) ;
414+ deactivate ( event , context , props , state , delayPressEnd ) ;
320415 } , delayPressEnd ) ;
321416 } else {
322- deactivate ( context , props , state ) ;
417+ deactivate ( event , context , props , state , 0 ) ;
323418 }
324419 }
325420}
@@ -368,8 +463,8 @@ function calculateResponderRegion(
368463) {
369464 const pressRetentionOffset = context . objectAssign (
370465 { } ,
371- ... DEFAULT_PRESS_RETENTION_OFFSET ,
372- ... props . pressRetentionOffset ,
466+ DEFAULT_PRESS_RETENTION_OFFSET ,
467+ props . pressRetentionOffset ,
373468 ) ;
374469
375470 const clientRect = target . getBoundingClientRect ( ) ;
@@ -656,9 +751,15 @@ const PressResponder = {
656751 if ( state . isPressWithinResponderRegion ) {
657752 if ( state . isPressed ) {
658753 if ( props . onPressMove ) {
659- dispatchEvent ( context , state , 'pressmove' , props . onPressMove , {
660- discrete : false ,
661- } ) ;
754+ dispatchEvent (
755+ event ,
756+ context ,
757+ state ,
758+ 'pressmove' ,
759+ props . onPressMove ,
760+ false ,
761+ 0 ,
762+ ) ;
662763 }
663764 if (
664765 state . activationPosition != null &&
@@ -735,7 +836,15 @@ const PressResponder = {
735836 props . onLongPressShouldCancelPress ( )
736837 )
737838 ) {
738- dispatchEvent ( context , state , 'press' , props . onPress ) ;
839+ dispatchEvent (
840+ event ,
841+ context ,
842+ state ,
843+ 'press' ,
844+ props . onPress ,
845+ true ,
846+ 0 ,
847+ ) ;
739848 }
740849 }
741850 }
0 commit comments