diff --git a/packages/react-devtools-shared/src/backend/agent.js b/packages/react-devtools-shared/src/backend/agent.js index 92db4c062d5a2..cb45f5368776c 100644 --- a/packages/react-devtools-shared/src/backend/agent.js +++ b/packages/react-devtools-shared/src/backend/agent.js @@ -37,11 +37,9 @@ import type { RendererID, RendererInterface, ConsolePatchSettings, + DevToolsHookSettings, } from './types'; -import type { - ComponentFilter, - BrowserTheme, -} from 'react-devtools-shared/src/frontend/types'; +import type {ComponentFilter} from 'react-devtools-shared/src/frontend/types'; import {isSynchronousXHRSupported, isReactNativeEnvironment} from './utils'; const debug = (methodName: string, ...args: Array) => { @@ -152,6 +150,7 @@ export default class Agent extends EventEmitter<{ traceUpdates: [Set], drawTraceUpdates: [Array], disableTraceUpdates: [], + updateHookSettings: [DevToolsHookSettings], }> { _bridge: BackendBridge; _isProfiling: boolean = false; @@ -805,30 +804,22 @@ export default class Agent extends EventEmitter<{ } }; - updateConsolePatchSettings: ({ - appendComponentStack: boolean, - breakOnConsoleErrors: boolean, - browserTheme: BrowserTheme, - hideConsoleLogsInStrictMode: boolean, - showInlineWarningsAndErrors: boolean, - }) => void = ({ - appendComponentStack, - breakOnConsoleErrors, - showInlineWarningsAndErrors, - hideConsoleLogsInStrictMode, - browserTheme, - }: ConsolePatchSettings) => { + updateConsolePatchSettings: ( + settings: $ReadOnly, + ) => void = settings => { + // Propagate the settings, so Backend can subscribe to it and modify hook + this.emit('updateHookSettings', { + appendComponentStack: settings.appendComponentStack, + breakOnConsoleErrors: settings.breakOnConsoleErrors, + showInlineWarningsAndErrors: settings.showInlineWarningsAndErrors, + hideConsoleLogsInStrictMode: settings.hideConsoleLogsInStrictMode, + }); + // If the frontend preferences have changed, // or in the case of React Native- if the backend is just finding out the preferences- // then reinstall the console overrides. // It's safe to call `patchConsole` multiple times. - patchConsole({ - appendComponentStack, - breakOnConsoleErrors, - showInlineWarningsAndErrors, - hideConsoleLogsInStrictMode, - browserTheme, - }); + patchConsole(settings); }; updateComponentFilters: (componentFilters: Array) => void = diff --git a/packages/react-devtools-shared/src/backend/console.js b/packages/react-devtools-shared/src/backend/console.js index d4e9651fa7503..47e4a0008c537 100644 --- a/packages/react-devtools-shared/src/backend/console.js +++ b/packages/react-devtools-shared/src/backend/console.js @@ -135,7 +135,7 @@ export function patch({ showInlineWarningsAndErrors, hideConsoleLogsInStrictMode, browserTheme, -}: ConsolePatchSettings): void { +}: $ReadOnly): void { // Settings may change after we've patched the console. // Using a shared ref allows the patch function to read the latest values. consoleSettingsRef.appendComponentStack = appendComponentStack; diff --git a/packages/react-devtools-shared/src/backend/index.js b/packages/react-devtools-shared/src/backend/index.js index 943c0360ffc99..d08e18e930b4e 100644 --- a/packages/react-devtools-shared/src/backend/index.js +++ b/packages/react-devtools-shared/src/backend/index.js @@ -140,6 +140,10 @@ export function initBackend( agent.removeListener('shutdown', onAgentShutdown); }); + agent.addListener('updateHookSettings', settings => { + hook.settings = settings; + }); + return () => { subs.forEach(fn => fn()); }; diff --git a/packages/react-devtools-shared/src/backend/types.js b/packages/react-devtools-shared/src/backend/types.js index dc3222072a482..b468f8d35996c 100644 --- a/packages/react-devtools-shared/src/backend/types.js +++ b/packages/react-devtools-shared/src/backend/types.js @@ -526,6 +526,9 @@ export type DevToolsHook = { // Testing dangerous_setTargetConsoleForTesting?: (fakeConsole: Object) => void, + settings: DevToolsHookSettings, + settingsHaveBeenInjected: boolean, + injectSettings: (settings: DevToolsHookSettings) => void, ... }; @@ -536,3 +539,10 @@ export type ConsolePatchSettings = { hideConsoleLogsInStrictMode: boolean, browserTheme: BrowserTheme, }; + +export type DevToolsHookSettings = { + appendComponentStack: boolean, + breakOnConsoleErrors: boolean, + showInlineWarningsAndErrors: boolean, + hideConsoleLogsInStrictMode: boolean, +}; diff --git a/packages/react-devtools-shared/src/hook.js b/packages/react-devtools-shared/src/hook.js index aeef1abc0e737..a333b6a00139a 100644 --- a/packages/react-devtools-shared/src/hook.js +++ b/packages/react-devtools-shared/src/hook.js @@ -15,6 +15,7 @@ import type { RendererID, RendererInterface, DevToolsBackend, + DevToolsHookSettings, } from './backend/types'; import { @@ -24,7 +25,17 @@ import { declare var window: any; -export function installHook(target: any): DevToolsHook | null { +const defaultHookSettings: DevToolsHookSettings = { + appendComponentStack: true, + breakOnConsoleErrors: false, + showInlineWarningsAndErrors: true, + hideConsoleLogsInStrictMode: false, +}; + +export function installHook( + target: any, + settingsToInject?: DevToolsHookSettings, +): DevToolsHook | null { if (target.hasOwnProperty('__REACT_DEVTOOLS_GLOBAL_HOOK__')) { return null; } @@ -526,6 +537,16 @@ export function installHook(target: any): DevToolsHook | null { const renderers = new Map(); const backends = new Map(); + const settings = settingsToInject || defaultHookSettings; + const settingsHaveBeenInjected = settingsToInject != null; + + // Should be used once when the persisted settings were loaded from some asynchronous storage + // This will be used as a signal that Hook initialization has finished, and it can now use patched console implementation + function injectSettings(newSettings: DevToolsHookSettings): void { + hook.settings = newSettings; + hook.settingsHaveBeenInjected = true; + } + const hook: DevToolsHook = { rendererInterfaces, listeners, @@ -562,6 +583,10 @@ export function installHook(target: any): DevToolsHook | null { getInternalModuleRanges, registerInternalModuleStart, registerInternalModuleStop, + + settings, + settingsHaveBeenInjected, + injectSettings, }; if (__TEST__) {