@@ -19,8 +19,9 @@ import {registrationNameDependencies} from 'legacy-events/EventPluginRegistry';
1919import { batchedEventUpdates } from 'legacy-events/ReactGenericBatching' ;
2020import { executeDispatchesInOrder } from 'legacy-events/EventPluginUtils' ;
2121import { plugins } from 'legacy-events/EventPluginRegistry' ;
22+ import getListener from 'legacy-events/getListener' ;
2223
23- import { HostRoot , HostPortal } from 'shared/ReactWorkTags' ;
24+ import { HostRoot , HostPortal , HostComponent } from 'shared/ReactWorkTags' ;
2425
2526import { addTrappedEventListener } from './ReactDOMEventListener' ;
2627import getEventTarget from './getEventTarget' ;
@@ -305,3 +306,46 @@ export function attachElementListener(listener: ReactDOMListener): void {
305306export function detachElementListener ( listener : ReactDOMListener ) : void {
306307 // TODO
307308}
309+
310+ export function accumulateTwoPhaseListeners ( event : ReactSyntheticEvent ) : void {
311+ const phasedRegistrationNames = event . dispatchConfig . phasedRegistrationNames ;
312+ if ( phasedRegistrationNames == null ) {
313+ return ;
314+ }
315+ const { bubbled , captured } = phasedRegistrationNames ;
316+ const dispatchListeners = [ ] ;
317+ const dispatchInstances = [ ] ;
318+ let node = event . _targetInst ;
319+ let hasListeners = false ;
320+
321+ // Accumulate all instances and listeners via the target -> root path.
322+ while ( node !== null ) {
323+ // We only care for listeners that are on HostComponents (i.e. <div>)
324+ if ( node . tag === HostComponent ) {
325+ // Standard React on* listeners, i.e. onClick prop
326+ const captureListener = getListener ( node , captured ) ;
327+ if ( captureListener != null ) {
328+ hasListeners = true ;
329+ // Capture listeners/instances should go at the start, so we
330+ // unshift them to the start of the array.
331+ dispatchListeners . unshift ( captureListener ) ;
332+ dispatchInstances . unshift ( node ) ;
333+ }
334+ const bubbleListener = getListener ( node , bubbled ) ;
335+ if ( bubbleListener != null ) {
336+ hasListeners = true ;
337+ // Bubble listeners/instances should go at the end, so we
338+ // push them to the end of the array.
339+ dispatchListeners . push ( bubbleListener ) ;
340+ dispatchInstances . push ( node ) ;
341+ }
342+ }
343+ node = node . return ;
344+ }
345+ // To prevent allocation to the event unless we actually
346+ // have listeners we use the flag we would have set above.
347+ if ( hasListeners ) {
348+ event . _dispatchListeners = dispatchListeners ;
349+ event . _dispatchInstances = dispatchInstances ;
350+ }
351+ }
0 commit comments