@@ -22,8 +22,8 @@ import {
2222 EventTarget as EventTargetWorkTag ,
2323} from 'shared/ReactWorkTags' ;
2424import type {
25- ReactEventResponder ,
2625 ReactEventResponderEventType ,
26+ ReactEventComponentInstance ,
2727} from 'shared/ReactTypes' ;
2828import type { DOMTopLevelEventType } from 'events/TopLevelEventTypes' ;
2929import { batchedUpdates , interactiveUpdates } from 'events/ReactGenericBatching' ;
@@ -55,7 +55,7 @@ type PartialEventObject = {
5555} ;
5656
5757let currentOwner = null ;
58- let currentFiber : Fiber ;
58+ let currentInstance : ReactEventComponentInstance ;
5959let currentEventQueue : EventQueue ;
6060
6161const eventResponderContext : ResponderContext = {
@@ -140,12 +140,10 @@ const eventResponderContext: ResponderContext = {
140140 return false ;
141141 } ,
142142 isTargetWithinEventComponent ( target : Element | Document ) : boolean {
143- const eventFiber = currentFiber ;
144-
145143 if ( target != null ) {
146144 let fiber = getClosestInstanceFromNode ( target ) ;
147145 while ( fiber !== null ) {
148- if ( fiber === eventFiber || fiber === eventFiber . alternate ) {
146+ if ( fiber . stateNode === currentInstance ) {
149147 return true ;
150148 }
151149 fiber = fiber . return ;
@@ -174,78 +172,78 @@ const eventResponderContext: ResponderContext = {
174172 rootEventTypes : Array < ReactEventResponderEventType > ,
175173 ) : void {
176174 listenToResponderEventTypesImpl ( rootEventTypes , doc ) ;
177- const eventComponent = currentFiber ;
178175 for ( let i = 0 ; i < rootEventTypes . length ; i ++ ) {
179176 const rootEventType = rootEventTypes [ i ] ;
180177 const topLevelEventType =
181178 typeof rootEventType === 'string' ? rootEventType : rootEventType . name ;
182- let rootEventComponents = rootEventTypesToEventComponents . get (
179+ let rootEventComponentInstances = rootEventTypesToEventComponentInstances . get (
183180 topLevelEventType ,
184181 ) ;
185- if ( rootEventComponents === undefined ) {
186- rootEventComponents = new Set ( ) ;
187- rootEventTypesToEventComponents . set (
182+ if ( rootEventComponentInstances === undefined ) {
183+ rootEventComponentInstances = new Set ( ) ;
184+ rootEventTypesToEventComponentInstances . set (
188185 topLevelEventType ,
189- rootEventComponents ,
186+ rootEventComponentInstances ,
190187 ) ;
191188 }
192- rootEventComponents . add ( eventComponent ) ;
189+ rootEventComponentInstances . add ( currentInstance ) ;
193190 }
194191 } ,
195192 removeRootEventTypes (
196193 rootEventTypes : Array < ReactEventResponderEventType > ,
197194 ) : void {
198- const eventComponent = currentFiber ;
199195 for ( let i = 0 ; i < rootEventTypes . length ; i ++ ) {
200196 const rootEventType = rootEventTypes [ i ] ;
201197 const topLevelEventType =
202198 typeof rootEventType === 'string' ? rootEventType : rootEventType . name ;
203- let rootEventComponents = rootEventTypesToEventComponents . get (
199+ let rootEventComponents = rootEventTypesToEventComponentInstances . get (
204200 topLevelEventType ,
205201 ) ;
206202 if ( rootEventComponents !== undefined ) {
207- rootEventComponents . delete ( eventComponent ) ;
203+ rootEventComponents . delete ( currentInstance ) ;
208204 }
209205 }
210206 } ,
211207 hasOwnership ( ) : boolean {
212- return currentOwner === currentFiber ;
208+ return currentOwner === currentInstance ;
213209 } ,
214210 requestOwnership ( ) : boolean {
215211 if ( currentOwner !== null ) {
216212 return false ;
217213 }
218- currentOwner = currentFiber ;
214+ currentOwner = currentInstance ;
215+ triggerOwnershipListeners ( ) ;
219216 return true ;
220217 } ,
221218 releaseOwnership ( ) : boolean {
222- if ( currentOwner !== currentFiber ) {
219+ if ( currentOwner !== currentInstance ) {
223220 return false ;
224221 }
225222 currentOwner = null ;
223+ triggerOwnershipListeners ( ) ;
226224 return false ;
227225 } ,
228226 setTimeout ( func : ( ) = > void , delay ) : TimeoutID {
229- const contextFiber = currentFiber ;
227+ const contextInstance = currentInstance ;
230228 return setTimeout ( ( ) => {
231229 const previousEventQueue = currentEventQueue ;
232- const previousFiber = currentFiber ;
230+ const previousInstance = currentInstance ;
233231 currentEventQueue = createEventQueue ( ) ;
234- currentFiber = contextFiber ;
232+ currentInstance = contextInstance ;
235233 try {
236234 func ( ) ;
237235 batchedUpdates ( processEventQueue , currentEventQueue ) ;
238236 } finally {
239- currentFiber = previousFiber ;
237+ currentInstance = previousInstance ;
240238 currentEventQueue = previousEventQueue ;
241239 }
242240 } , delay ) ;
243241 } ,
244242} ;
245243
246- const rootEventTypesToEventComponents : Map <
244+ const rootEventTypesToEventComponentInstances : Map <
247245 DOMTopLevelEventType | string ,
248- Set < Fiber > ,
246+ Set < ReactEventComponentInstance > ,
249247> = new Map ( ) ;
250248const PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set ;
251249const eventsWithStopPropagation :
@@ -255,6 +253,7 @@ const targetEventTypeCached: Map<
255253 Array < ReactEventResponderEventType > ,
256254 Set< DOMTopLevelEventType > ,
257255> = new Map ( ) ;
256+ const ownershipChangeListeners : Set < ReactEventComponentInstance > = new Set();
258257
259258function createResponderEvent(
260259 topLevelType: string,
@@ -343,25 +342,24 @@ function getTargetEventTypes(
343342
344343function handleTopLevelType(
345344 topLevelType: DOMTopLevelEventType,
346- fiber : Fiber ,
347345 responderEvent: ResponderEvent,
346+ eventComponentInstance: ReactEventComponentInstance,
348347 isRootLevelEvent: boolean,
349348): void {
350- const responder : ReactEventResponder = fiber . type . responder ;
349+ let { props , responder , state } = eventComponentInstance ;
351350 if (!isRootLevelEvent) {
352351 // Validate the target event type exists on the responder
353352 const targetEventTypes = getTargetEventTypes ( responder . targetEventTypes ) ;
354353 if ( ! targetEventTypes . has ( topLevelType ) ) {
355354 return;
356355 }
357356 }
358- let { props, state} = fiber . stateNode ;
359- const previousFiber = currentFiber ;
360- currentFiber = fiber ;
357+ const previousInstance = currentInstance;
358+ currentInstance = eventComponentInstance;
361359 try {
362360 responder . onEvent ( responderEvent , eventResponderContext , props , state ) ;
363361 } finally {
364- currentFiber = previousFiber ;
362+ currentInstance = previousInstance ;
365363 }
366364}
367365
@@ -384,23 +382,29 @@ export function runResponderEventsInBatch(
384382 // Traverse up the fiber tree till we find event component fibers.
385383 while ( node !== null ) {
386384 if ( node . tag === EventComponent ) {
387- handleTopLevelType ( topLevelType , node , responderEvent , false ) ;
385+ const eventComponentInstance = node . stateNode ;
386+ handleTopLevelType (
387+ topLevelType ,
388+ responderEvent ,
389+ eventComponentInstance ,
390+ false ,
391+ ) ;
388392 }
389393 node = node . return ;
390394 }
391395 // Handle root level events
392- const rootEventComponents = rootEventTypesToEventComponents . get (
396+ const rootEventInstances = rootEventTypesToEventComponentInstances . get (
393397 topLevelType ,
394398 ) ;
395- if ( rootEventComponents !== undefined ) {
396- const rootEventComponentFibers = Array . from ( rootEventComponents ) ;
399+ if ( rootEventInstances !== undefined ) {
400+ const rootEventComponentInstances = Array . from ( rootEventInstances ) ;
397401
398- for ( let i = 0 ; i < rootEventComponentFibers . length ; i ++ ) {
399- const rootEventComponentFiber = rootEventComponentFibers [ i ] ;
402+ for ( let i = 0 ; i < rootEventComponentInstances . length ; i ++ ) {
403+ const rootEventComponentInstance = rootEventComponentInstances [ i ] ;
400404 handleTopLevelType (
401405 topLevelType ,
402- rootEventComponentFiber ,
403406 responderEvent ,
407+ rootEventComponentInstance ,
404408 true ,
405409 ) ;
406410 }
@@ -409,26 +413,53 @@ export function runResponderEventsInBatch(
409413 }
410414}
411415
416+ function triggerOwnershipListeners(): void {
417+ const listeningInstances = Array . from ( ownershipChangeListeners ) ;
418+ const previousInstance = currentInstance ;
419+ for ( let i = 0 ; i < listeningInstances . length ; i ++ ) {
420+ const instance = listeningInstances [ i ] ;
421+ const { props, responder, state} = instance ;
422+ currentInstance = instance ;
423+ try {
424+ responder. onOwnershipChange ( eventResponderContext , props , state ) ;
425+ } finally {
426+ currentInstance = previousInstance ;
427+ }
428+ }
429+ }
430+
431+ export function mountEventResponder(
432+ eventComponentInstance: ReactEventComponentInstance,
433+ ) {
434+ const responder = eventComponentInstance . responder ;
435+ if ( responder . onOwnershipChange !== undefined ) {
436+ ownershipChangeListeners . add ( eventComponentInstance ) ;
437+ }
438+ }
439+
412440export function unmountEventResponder (
413- responder : ReactEventResponder ,
414- fiber : Fiber ,
441+ eventComponentInstance : ReactEventComponentInstance ,
415442) : void {
443+ const responder = eventComponentInstance . responder ;
416444 const onUnmount = responder . onUnmount ;
417445 if ( onUnmount !== undefined ) {
418- let { props , state } = fiber . stateNode ;
446+ let { props, state} = eventComponentInstance ;
419447 const previousEventQueue = currentEventQueue ;
420- const previousFiber = currentFiber ;
448+ const previousInstance = currentInstance ;
421449 currentEventQueue = createEventQueue ( ) ;
422- currentFiber = fiber ;
450+ currentInstance = eventComponentInstance ;
423451 try {
424452 onUnmount ( eventResponderContext , props , state ) ;
425453 } finally {
426454 currentEventQueue = previousEventQueue ;
427- currentFiber = previousFiber ;
455+ currentInstance = previousInstance ;
428456 }
429457 }
430- if ( currentOwner === fiber ) {
431- // TODO fire owner changed callback
458+ if ( currentOwner === eventComponentInstance ) {
432459 currentOwner = null ;
460+ triggerOwnershipListeners ( ) ;
461+ }
462+ if ( responder . onOwnershipChange !== undefined ) {
463+ ownershipChangeListeners . delete ( eventComponentInstance ) ;
433464 }
434465}
0 commit comments