@samitouri / QOS-React-2 / commits / 08c1f79e1e

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`)

Mark Huang committed Feb 3, 2020 at 04:04 UTC 08c1f79e1e13719ae2b79240bbd8f97178ddd791
6 files changed +27 -14
packages/react-devtools-core/src/backend.js
+5 -1
@@ -32,7 +32,7 @@ type ConnectOptions = {
32
33 installHook(window);
34
35 -const hook: DevToolsHook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
35 +const hook: ?DevToolsHook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
36
37 let savedComponentFilters: Array<ComponentFilter> = getDefaultComponentFilters();
38
@@ -48,6 +48,10 @@ function debug(methodName: string, ...args) {
48 }
49
50 export function connectToDevTools(options: ?ConnectOptions) {
51 + if (hook == null) {
52 + // DevTools didn't get injected into this page (maybe b'c of the contentType).
53 + return;
54 + }
55 const {
56 host = 'localhost',
57 nativeStyleEditorValidAttributes,
packages/react-devtools-extensions/src/backend.js
+4
@@ -22,6 +22,10 @@ function welcome(event) {
22 window.addEventListener('message', welcome);
23
24 function setup(hook) {
25 + if (hook == null) {
26 + // DevTools didn't get injected into this page (maybe b'c of the contentType).
27 + return;
28 + }
29 const Agent = require('react-devtools-shared/src/backend/agent').default;
30 const Bridge = require('react-devtools-shared/src/bridge').default;
31 const {initBackend} = require('react-devtools-shared/src/backend');
packages/react-devtools-extensions/src/injectGlobalHook.js
+1 -1
@@ -88,7 +88,7 @@ if (sessionStorageGetItem(SESSION_STORAGE_RELOAD_AND_PROFILE_KEY) === 'true') {
88
89 // Inject a __REACT_DEVTOOLS_GLOBAL_HOOK__ global for React to interact with.
90 // Only do this for HTML documents though, to avoid e.g. breaking syntax highlighting for XML docs.
91 -if (document.contentType === 'text/html') {
91 +if ('text/html' === document.contentType) {
92 injectCode(
93 ';(' +
94 installHook.toString() +
packages/react-devtools-extensions/src/main.js
+1 -1
@@ -271,7 +271,7 @@ function createPanelIfReactLoaded() {
271 // When the user chooses a different node in the browser Elements tab,
272 // copy it over to the hook object so that we can sync the selection.
273 chrome.devtools.inspectedWindow.eval(
274 - '(window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0 !== $0) ?' +
274 + '(window.__REACT_DEVTOOLS_GLOBAL_HOOK__ && window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0 !== $0) ?' +
275 '(window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0 = $0, true) :' +
276 'false',
277 (didSelectionChange, evalError) => {
packages/react-devtools-inline/src/backend.js
+12 -11
@@ -73,17 +73,18 @@ function finishActivation(contentWindow: window) {
73 const agent = new Agent(bridge);
74
75 const hook = contentWindow.__REACT_DEVTOOLS_GLOBAL_HOOK__;
76 -
77 - initBackend(hook, agent, contentWindow);
78 -
79 - // Setup React Native style editor if a renderer like react-native-web has injected it.
80 - if (hook.resolveRNStyle) {
81 - setupNativeStyleEditor(
82 - bridge,
83 - agent,
84 - hook.resolveRNStyle,
85 - hook.nativeStyleEditorValidAttributes,
86 - );
76 + if (hook) {
77 + initBackend(hook, agent, contentWindow);
78 +
79 + // Setup React Native style editor if a renderer like react-native-web has injected it.
80 + if (hook.resolveRNStyle) {
81 + setupNativeStyleEditor(
82 + bridge,
83 + agent,
84 + hook.resolveRNStyle,
85 + hook.nativeStyleEditorValidAttributes,
86 + );
87 + }
88 }
89 }
90
packages/react-devtools-shared/src/backend/index.js
+4
@@ -19,6 +19,10 @@ export function initBackend(
19 agent: Agent,
20 global: Object,
21 ): () => void {
22 + if (hook == null) {
23 + // DevTools didn't get injected into this page (maybe b'c of the contentType).
24 + return () => {};
25 + }
26 const subs = [
27 hook.sub(
28 'renderer-attached',