@@ -22,6 +22,7 @@ import {
2222 setBrowserSelectionFromReact ,
2323 setReactSelectionFromBrowser ,
2424} from './elementSelection' ;
25+ import { startReactPolling } from './reactPolling' ;
2526import cloneStyleTags from './cloneStyleTags' ;
2627import injectBackendManager from './injectBackendManager' ;
2728import syncSavedPreferences from './syncSavedPreferences' ;
@@ -30,60 +31,6 @@ import getProfilingFlags from './getProfilingFlags';
3031import debounce from './debounce' ;
3132import './requestAnimationFramePolyfill' ;
3233
33- // Try polling for at least 5 seconds, in case if it takes too long to load react
34- const REACT_POLLING_TICK_COOLDOWN = 250 ;
35- const REACT_POLLING_ATTEMPTS_THRESHOLD = 20 ;
36-
37- let reactPollingTimeoutId = null ;
38- export function clearReactPollingTimeout ( ) {
39- clearTimeout ( reactPollingTimeoutId ) ;
40- reactPollingTimeoutId = null ;
41- }
42-
43- export function executeIfReactHasLoaded ( callback , attempt = 1 ) {
44- clearReactPollingTimeout ( ) ;
45-
46- if ( attempt > REACT_POLLING_ATTEMPTS_THRESHOLD ) {
47- return ;
48- }
49-
50- chrome . devtools . inspectedWindow . eval (
51- 'window.__REACT_DEVTOOLS_GLOBAL_HOOK__ && window.__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers.size > 0' ,
52- ( pageHasReact , exceptionInfo ) => {
53- if ( exceptionInfo ) {
54- const { code, description, isError, isException, value} = exceptionInfo ;
55-
56- if ( isException ) {
57- console . error (
58- `Received error while checking if react has loaded: ${ value } ` ,
59- ) ;
60- return ;
61- }
62-
63- if ( isError ) {
64- console . error (
65- `Received error with code ${ code } while checking if react has loaded: ${ description } ` ,
66- ) ;
67- return ;
68- }
69- }
70-
71- if ( pageHasReact ) {
72- callback ( ) ;
73- } else {
74- reactPollingTimeoutId = setTimeout (
75- executeIfReactHasLoaded ,
76- REACT_POLLING_TICK_COOLDOWN ,
77- callback ,
78- attempt + 1 ,
79- ) ;
80- }
81- } ,
82- ) ;
83- }
84-
85- let lastSubscribedBridgeListener = null ;
86-
8734function createBridge ( ) {
8835 bridge = new Bridge ( {
8936 listen ( fn ) {
@@ -370,6 +317,7 @@ function ensureInitialHTMLIsCleared(container) {
370317function createComponentsPanel ( ) {
371318 if ( componentsPortalContainer ) {
372319 // Panel is created and user opened it at least once
320+ ensureInitialHTMLIsCleared ( componentsPortalContainer ) ;
373321 render ( 'components' ) ;
374322
375323 return ;
@@ -389,7 +337,7 @@ function createComponentsPanel() {
389337
390338 createdPanel . onShown . addListener ( portal => {
391339 componentsPortalContainer = portal . container ;
392- if ( componentsPortalContainer != null ) {
340+ if ( componentsPortalContainer != null && render ) {
393341 ensureInitialHTMLIsCleared ( componentsPortalContainer ) ;
394342
395343 render ( 'components' ) ;
@@ -408,6 +356,7 @@ function createComponentsPanel() {
408356function createProfilerPanel ( ) {
409357 if ( profilerPortalContainer ) {
410358 // Panel is created and user opened it at least once
359+ ensureInitialHTMLIsCleared ( profilerPortalContainer ) ;
411360 render ( 'profiler' ) ;
412361
413362 return ;
@@ -427,7 +376,7 @@ function createProfilerPanel() {
427376
428377 createdPanel . onShown . addListener ( portal => {
429378 profilerPortalContainer = portal . container ;
430- if ( profilerPortalContainer != null ) {
379+ if ( profilerPortalContainer != null && render ) {
431380 ensureInitialHTMLIsCleared ( profilerPortalContainer ) ;
432381
433382 render ( 'profiler' ) ;
@@ -442,7 +391,7 @@ function createProfilerPanel() {
442391
443392function performInTabNavigationCleanup ( ) {
444393 // Potentially, if react hasn't loaded yet and user performs in-tab navigation
445- clearReactPollingTimeout ( ) ;
394+ clearReactPollingInstance ( ) ;
446395
447396 if ( store !== null ) {
448397 // Store profiling data, so it can be used later
@@ -479,7 +428,7 @@ function performInTabNavigationCleanup() {
479428
480429function performFullCleanup ( ) {
481430 // Potentially, if react hasn't loaded yet and user closed the browser DevTools
482- clearReactPollingTimeout ( ) ;
431+ clearReactPollingInstance ( ) ;
483432
484433 if ( ( componentsPortalContainer || profilerPortalContainer ) && root ) {
485434 // This should also emit bridge.shutdown, but only if this root was mounted
@@ -531,6 +480,8 @@ function connectExtensionPort() {
531480}
532481
533482function mountReactDevTools ( ) {
483+ reactPollingInstance = null ;
484+
534485 registerEventsLogger ( ) ;
535486
536487 createBridgeAndStore ( ) ;
@@ -541,18 +492,36 @@ function mountReactDevTools() {
541492 createProfilerPanel ( ) ;
542493}
543494
544- // TODO: display some disclaimer if user performs in-tab navigation to non-react application
545- // when React DevTools panels are already opened, currently we will display just blank white block
546- function mountReactDevToolsWhenReactHasLoaded ( ) {
547- function onReactReady ( ) {
548- clearReactPollingTimeout ( ) ;
549- mountReactDevTools ( ) ;
495+ let reactPollingInstance = null ;
496+ function clearReactPollingInstance ( ) {
497+ reactPollingInstance ?. abort ( ) ;
498+ reactPollingInstance = null ;
499+ }
500+
501+ function showNoReactDisclaimer ( ) {
502+ if ( componentsPortalContainer ) {
503+ componentsPortalContainer . innerHTML =
504+ '<h1 class="no-react-disclaimer">Looks like this page doesn\'t have React, or it hasn\'t been loaded yet.</h1>' ;
505+ delete componentsPortalContainer . _hasInitialHTMLBeenCleared ;
506+ }
507+
508+ if ( profilerPortalContainer ) {
509+ profilerPortalContainer . innerHTML =
510+ '<h1 class="no-react-disclaimer">Looks like this page doesn\'t have React, or it hasn\'t been loaded yet.</h1>' ;
511+ delete profilerPortalContainer . _hasInitialHTMLBeenCleared ;
550512 }
513+ }
551514
552- executeIfReactHasLoaded ( onReactReady , 1 ) ;
515+ function mountReactDevToolsWhenReactHasLoaded ( ) {
516+ reactPollingInstance = startReactPolling (
517+ mountReactDevTools ,
518+ 5 , // ~5 seconds
519+ showNoReactDisclaimer ,
520+ ) ;
553521}
554522
555523let bridge = null ;
524+ let lastSubscribedBridgeListener = null ;
556525let store = null ;
557526
558527let profilingData = null ;
0 commit comments