From 08c1f79e1e13719ae2b79240bbd8f97178ddd791 Mon Sep 17 00:00:00 2001 From: Mark Huang <8191686+wfnuser@users.noreply.github.com> Date: Mon, 3 Feb 2020 04:04:48 +0800 Subject: [PATCH] Fix Cannot read property 'sub' of undefined when navigating to plain-text pages (#17848) Update various parts of DevTools to account for the fact that the global "hook" might be undefined if DevTools didn't inject it (due to the page's `contentType`) it (due to the page's `contentType`) --- packages/react-devtools-core/src/backend.js | 6 ++++- .../react-devtools-extensions/src/backend.js | 4 ++++ .../src/injectGlobalHook.js | 2 +- .../react-devtools-extensions/src/main.js | 2 +- packages/react-devtools-inline/src/backend.js | 23 ++++++++++--------- .../src/backend/index.js | 4 ++++ 6 files changed, 27 insertions(+), 14 deletions(-) diff --git a/packages/react-devtools-core/src/backend.js b/packages/react-devtools-core/src/backend.js index 6b95b4c79114a..ec9253b5f94ae 100644 --- a/packages/react-devtools-core/src/backend.js +++ b/packages/react-devtools-core/src/backend.js @@ -32,7 +32,7 @@ type ConnectOptions = { installHook(window); -const hook: DevToolsHook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__; +const hook: ?DevToolsHook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__; let savedComponentFilters: Array = getDefaultComponentFilters(); @@ -48,6 +48,10 @@ function debug(methodName: string, ...args) { } export function connectToDevTools(options: ?ConnectOptions) { + if (hook == null) { + // DevTools didn't get injected into this page (maybe b'c of the contentType). + return; + } const { host = 'localhost', nativeStyleEditorValidAttributes, diff --git a/packages/react-devtools-extensions/src/backend.js b/packages/react-devtools-extensions/src/backend.js index 6a8fe9c3e5cae..357c286c2e287 100644 --- a/packages/react-devtools-extensions/src/backend.js +++ b/packages/react-devtools-extensions/src/backend.js @@ -22,6 +22,10 @@ function welcome(event) { window.addEventListener('message', welcome); function setup(hook) { + if (hook == null) { + // DevTools didn't get injected into this page (maybe b'c of the contentType). + return; + } const Agent = require('react-devtools-shared/src/backend/agent').default; const Bridge = require('react-devtools-shared/src/bridge').default; const {initBackend} = require('react-devtools-shared/src/backend'); diff --git a/packages/react-devtools-extensions/src/injectGlobalHook.js b/packages/react-devtools-extensions/src/injectGlobalHook.js index 8785d97fc5ec8..980fe21f96d51 100644 --- a/packages/react-devtools-extensions/src/injectGlobalHook.js +++ b/packages/react-devtools-extensions/src/injectGlobalHook.js @@ -88,7 +88,7 @@ if (sessionStorageGetItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY) === 'true') { // Inject a __REACT_DEVTOOLS_GLOBAL_HOOK__ global for React to interact with. // Only do this for HTML documents though, to avoid e.g. breaking syntax highlighting for XML docs. -if (document.contentType === 'text/html') { +if ('text/html' === document.contentType) { injectCode( ';(' + installHook.toString() + diff --git a/packages/react-devtools-extensions/src/main.js b/packages/react-devtools-extensions/src/main.js index 0651734b5571a..74144f3392b7c 100644 --- a/packages/react-devtools-extensions/src/main.js +++ b/packages/react-devtools-extensions/src/main.js @@ -271,7 +271,7 @@ function createPanelIfReactLoaded() { // When the user chooses a different node in the browser Elements tab, // copy it over to the hook object so that we can sync the selection. chrome.devtools.inspectedWindow.eval( - '(window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0 !== $0) ?' + + '(window.__REACT_DEVTOOLS_GLOBAL_HOOK__ && window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0 !== $0) ?' + '(window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0 = $0, true) :' + 'false', (didSelectionChange, evalError) => { diff --git a/packages/react-devtools-inline/src/backend.js b/packages/react-devtools-inline/src/backend.js index 0528e2018d1c1..a6e901029a182 100644 --- a/packages/react-devtools-inline/src/backend.js +++ b/packages/react-devtools-inline/src/backend.js @@ -73,17 +73,18 @@ function finishActivation(contentWindow: window) { const agent = new Agent(bridge); const hook = contentWindow.__REACT_DEVTOOLS_GLOBAL_HOOK__; - - initBackend(hook, agent, contentWindow); - - // Setup React Native style editor if a renderer like react-native-web has injected it. - if (hook.resolveRNStyle) { - setupNativeStyleEditor( - bridge, - agent, - hook.resolveRNStyle, - hook.nativeStyleEditorValidAttributes, - ); + if (hook) { + initBackend(hook, agent, contentWindow); + + // Setup React Native style editor if a renderer like react-native-web has injected it. + if (hook.resolveRNStyle) { + setupNativeStyleEditor( + bridge, + agent, + hook.resolveRNStyle, + hook.nativeStyleEditorValidAttributes, + ); + } } } diff --git a/packages/react-devtools-shared/src/backend/index.js b/packages/react-devtools-shared/src/backend/index.js index 6a70c250bb3cd..ac8eaeb10f15c 100644 --- a/packages/react-devtools-shared/src/backend/index.js +++ b/packages/react-devtools-shared/src/backend/index.js @@ -19,6 +19,10 @@ export function initBackend( agent: Agent, global: Object, ): () => void { + if (hook == null) { + // DevTools didn't get injected into this page (maybe b'c of the contentType). + return () => {}; + } const subs = [ hook.sub( 'renderer-attached',