@@ -43,7 +43,7 @@ import type {
43
43
ComponentFilter ,
44
44
BrowserTheme ,
45
45
} from 'react-devtools-shared/src/frontend/types' ;
46
- import { isSynchronousXHRSupported } from './utils' ;
46
+ import { isSynchronousXHRSupported , isReactNativeEnvironment } from './utils' ;
47
47
48
48
const debug = ( methodName : string , ...args : Array < string > ) => {
49
49
if ( __DEBUG__ ) {
@@ -343,31 +343,79 @@ export default class Agent extends EventEmitter<{
343
343
return renderer . getInstanceAndStyle ( id ) ;
344
344
}
345
345
346
- getBestMatchingRendererInterface ( node : Object ) : RendererInterface | null {
347
- let bestMatch = null ;
346
+ getIDForHostInstance ( target : HostInstance ) : number | null {
347
+ let bestMatch : null | HostInstance = null ;
348
+ let bestRenderer : null | RendererInterface = null ;
349
+ // Find the nearest ancestor which is mounted by a React.
348
350
for ( const rendererID in this . _rendererInterfaces ) {
349
351
const renderer = ( ( this . _rendererInterfaces [
350
352
( rendererID : any )
351
353
] : any ) : RendererInterface ) ;
352
- const fiber = renderer . getFiberForNative ( node ) ;
353
- if ( fiber !== null ) {
354
- // check if fiber.stateNode is matching the original hostInstance
355
- if ( fiber . stateNode === node ) {
356
- return renderer ;
357
- } else if ( bestMatch === null ) {
358
- bestMatch = renderer ;
354
+ const nearestNode : null = renderer . getNearestMountedHostInstance ( target ) ;
355
+ if ( nearestNode !== null ) {
356
+ if ( nearestNode === target ) {
357
+ // Exact match we can exit early.
358
+ bestMatch = nearestNode ;
359
+ bestRenderer = renderer ;
360
+ break ;
361
+ }
362
+ if (
363
+ bestMatch === null ||
364
+ ( ! isReactNativeEnvironment ( ) && bestMatch . contains ( nearestNode ) )
365
+ ) {
366
+ // If this is the first match or the previous match contains the new match,
367
+ // so the new match is a deeper and therefore better match.
368
+ bestMatch = nearestNode ;
369
+ bestRenderer = renderer ;
359
370
}
360
371
}
361
372
}
362
- // if an exact match is not found, return the first valid renderer as fallback
363
- return bestMatch ;
373
+ if ( bestRenderer != null && bestMatch != null ) {
374
+ try {
375
+ return bestRenderer . getElementIDForHostInstance ( bestMatch , true ) ;
376
+ } catch ( error ) {
377
+ // Some old React versions might throw if they can't find a match.
378
+ // If so we should ignore it...
379
+ }
380
+ }
381
+ return null ;
364
382
}
365
383
366
- getIDForNode ( node : Object ) : number | null {
367
- const rendererInterface = this . getBestMatchingRendererInterface ( node ) ;
368
- if ( rendererInterface != null ) {
384
+ getComponentNameForHostInstance ( target : HostInstance ) : string | null {
385
+ // We duplicate this code from getIDForHostInstance to avoid an object allocation.
386
+ let bestMatch : null | HostInstance = null ;
387
+ let bestRenderer : null | RendererInterface = null ;
388
+ // Find the nearest ancestor which is mounted by a React.
389
+ for ( const rendererID in this . _rendererInterfaces ) {
390
+ const renderer = ( ( this . _rendererInterfaces [
391
+ ( rendererID : any )
392
+ ] : any ) : RendererInterface ) ;
393
+ const nearestNode = renderer . getNearestMountedHostInstance ( target ) ;
394
+ if ( nearestNode !== null ) {
395
+ if ( nearestNode === target ) {
396
+ // Exact match we can exit early.
397
+ bestMatch = nearestNode ;
398
+ bestRenderer = renderer ;
399
+ break ;
400
+ }
401
+ if (
402
+ bestMatch === null ||
403
+ ( ! isReactNativeEnvironment ( ) && bestMatch . contains ( nearestNode ) )
404
+ ) {
405
+ // If this is the first match or the previous match contains the new match,
406
+ // so the new match is a deeper and therefore better match.
407
+ bestMatch = nearestNode ;
408
+ bestRenderer = renderer ;
409
+ }
410
+ }
411
+ }
412
+
413
+ if ( bestRenderer != null && bestMatch != null ) {
369
414
try {
370
- return rendererInterface . getElementIDForHostInstance ( node , true ) ;
415
+ const id = bestRenderer . getElementIDForHostInstance ( bestMatch , true ) ;
416
+ if ( id ) {
417
+ return bestRenderer . getDisplayNameForElementID ( id ) ;
418
+ }
371
419
} catch ( error ) {
372
420
// Some old React versions might throw if they can't find a match.
373
421
// If so we should ignore it...
@@ -616,8 +664,8 @@ export default class Agent extends EventEmitter<{
616
664
}
617
665
} ;
618
666
619
- selectNode ( target : Object ) : void {
620
- const id = this . getIDForNode ( target ) ;
667
+ selectNode ( target : HostInstance ) : void {
668
+ const id = this . getIDForHostInstance ( target ) ;
621
669
if ( id !== null ) {
622
670
this . _bridge . send ( 'selectElement' , id ) ;
623
671
}
0 commit comments