@@ -323,8 +323,6 @@ function createBridgeAndStore() {
323323 } ) ,
324324 ) ;
325325 } ;
326-
327- render ( ) ;
328326}
329327
330328const viewUrlSourceFunction = ( url , line , col ) => {
@@ -364,14 +362,14 @@ function createComponentsPanel() {
364362 }
365363 } ) ;
366364
367- // TODO: we should listen to extension .onHidden to unmount some listeners
365+ // TODO: we should listen to createdPanel .onHidden to unmount some listeners
368366 // and potentially stop highlighting
369367 } ,
370368 ) ;
371369}
372370
373371function createProfilerPanel ( ) {
374- if ( componentsPortalContainer ) {
372+ if ( profilerPortalContainer ) {
375373 render ( 'profiler' ) ;
376374
377375 return ;
@@ -398,6 +396,9 @@ function createProfilerPanel() {
398396}
399397
400398function performInTabNavigationCleanup ( ) {
399+ // Potentially, if react hasn't loaded yet and user performs in-tab navigation
400+ clearReactPollingInterval ( ) ;
401+
401402 if ( store !== null ) {
402403 // Store profiling data, so it can be used later
403404 profilingData = store . profilerStore . profilingData ;
@@ -435,6 +436,9 @@ function performInTabNavigationCleanup() {
435436}
436437
437438function performFullCleanup ( ) {
439+ // Potentially, if react hasn't loaded yet and user closed the browser DevTools
440+ clearReactPollingInterval ( ) ;
441+
438442 if ( ( componentsPortalContainer || profilerPortalContainer ) && root ) {
439443 // This should also emit bridge.shutdown, but only if this root was mounted
440444 flushSync ( ( ) => root . unmount ( ) ) ;
@@ -455,14 +459,24 @@ function performFullCleanup() {
455459 port = null ;
456460}
457461
458- function mountReactDevTools ( ) {
459- registerEventsLogger ( ) ;
460-
462+ function connectExtensionPort ( ) {
461463 const tabId = chrome . devtools . inspectedWindow . tabId ;
462464 port = chrome . runtime . connect ( {
463465 name : String ( tabId ) ,
464466 } ) ;
465467
468+ // This port may be disconnected by Chrome at some point, this callback
469+ // will be executed only if this port was disconnected from the other end
470+ // so, when we call `port.disconnect()` from this script,
471+ // this should not trigger this callback and port reconnection
472+ port . onDisconnect . addListener ( connectExtensionPort ) ;
473+ }
474+
475+ function mountReactDevTools ( ) {
476+ registerEventsLogger ( ) ;
477+
478+ connectExtensionPort ( ) ;
479+
466480 createBridgeAndStore ( ) ;
467481
468482 setReactSelectionFromBrowser ( bridge ) ;
@@ -477,18 +491,20 @@ function mountReactDevToolsWhenReactHasLoaded() {
477491 const checkIfReactHasLoaded = ( ) => executeIfReactHasLoaded ( onReactReady ) ;
478492
479493 // Check to see if React has loaded in case React is added after page load
480- const reactPollingIntervalId = setInterval ( ( ) => {
494+ reactPollingIntervalId = setInterval ( ( ) => {
481495 checkIfReactHasLoaded ( ) ;
482496 } , 500 ) ;
483497
484498 function onReactReady ( ) {
485- clearInterval ( reactPollingIntervalId ) ;
499+ clearReactPollingInterval ( ) ;
486500 mountReactDevTools ( ) ;
487501 }
488502
489503 checkIfReactHasLoaded ( ) ;
490504}
491505
506+ let reactPollingIntervalId = null ;
507+
492508let bridge = null ;
493509let store = null ;
494510
@@ -509,6 +525,8 @@ chrome.devtools.network.onNavigated.addListener(syncSavedPreferences);
509525
510526// Cleanup previous page state and remount everything
511527chrome . devtools . network . onNavigated . addListener ( ( ) => {
528+ clearReactPollingInterval ( ) ;
529+
512530 performInTabNavigationCleanup ( ) ;
513531 mountReactDevToolsWhenReactHasLoaded ( ) ;
514532} ) ;
@@ -521,5 +539,10 @@ if (IS_FIREFOX) {
521539 window . addEventListener ( 'beforeunload' , performFullCleanup ) ;
522540}
523541
542+ function clearReactPollingInterval ( ) {
543+ clearInterval ( reactPollingIntervalId ) ;
544+ reactPollingIntervalId = null ;
545+ }
546+
524547syncSavedPreferences ( ) ;
525548mountReactDevToolsWhenReactHasLoaded ( ) ;
0 commit comments