Skip to content

Commit 43452c0

Browse files
committed
refactor[react-devtools]: propagate settings from global hook object to frontend
1 parent 4ba5e78 commit 43452c0

File tree

8 files changed

+136
-30
lines changed

8 files changed

+136
-30
lines changed

packages/react-devtools-core/src/cachedSettings.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ function parseConsolePatchSettings(
6666

6767
export function cacheConsolePatchSettings(
6868
devToolsSettingsManager: DevToolsSettingsManager,
69-
value: ConsolePatchSettings,
69+
value: $ReadOnly<ConsolePatchSettings>,
7070
): void {
7171
if (devToolsSettingsManager.setConsolePatchSettings == null) {
7272
return;

packages/react-devtools-shared/src/backend/agent.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ export default class Agent extends EventEmitter<{
150150
disableTraceUpdates: [],
151151
getIfHasUnsupportedRendererVersion: [],
152152
updateHookSettings: [DevToolsHookSettings],
153+
fetchHookSettings: [],
153154
}> {
154155
_bridge: BackendBridge;
155156
_isProfiling: boolean = false;
@@ -213,10 +214,13 @@ export default class Agent extends EventEmitter<{
213214
this.syncSelectionFromBuiltinElementsPanel,
214215
);
215216
bridge.addListener('shutdown', this.shutdown);
217+
216218
bridge.addListener(
217219
'updateConsolePatchSettings',
218220
this.updateConsolePatchSettings,
219221
);
222+
bridge.addListener('fetchHookSettings', this.fetchHookSettings);
223+
220224
bridge.addListener('updateComponentFilters', this.updateComponentFilters);
221225
bridge.addListener('getEnvironmentNames', this.getEnvironmentNames);
222226
bridge.addListener(
@@ -814,6 +818,15 @@ export default class Agent extends EventEmitter<{
814818
});
815819
};
816820

821+
fetchHookSettings: () => void = () => {
822+
this.emit('fetchHookSettings');
823+
};
824+
825+
onHookSettings: (settings: $ReadOnly<DevToolsHookSettings>) => void =
826+
settings => {
827+
this._bridge.send('hookSettings', settings);
828+
};
829+
817830
updateComponentFilters: (componentFilters: Array<ComponentFilter>) => void =
818831
componentFilters => {
819832
for (const rendererIDString in this._rendererInterfaces) {

packages/react-devtools-shared/src/backend/index.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export function initBackend(
5454
hook.sub('fastRefreshScheduled', agent.onFastRefreshScheduled),
5555
hook.sub('operations', agent.onHookOperations),
5656
hook.sub('traceUpdates', agent.onTraceUpdates),
57+
hook.sub('settingsInjected', agent.onHookSettings),
5758

5859
// TODO Add additional subscriptions required for profiling mode
5960
];
@@ -87,6 +88,12 @@ export function initBackend(
8788
hook.settings = settings;
8889
});
8990

91+
agent.addListener('fetchHookSettings', () => {
92+
if (hook.settings != null) {
93+
agent.onHookSettings(hook.settings);
94+
}
95+
});
96+
9097
return () => {
9198
subs.forEach(fn => fn());
9299
};

packages/react-devtools-shared/src/bridge.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,8 @@ export type BackendEvents = {
207207
{isSupported: boolean, validAttributes: ?$ReadOnlyArray<string>},
208208
],
209209
NativeStyleEditor_styleAndLayout: [StyleAndLayoutPayload],
210+
211+
hookSettings: [$ReadOnly<DevToolsHookSettings>],
210212
};
211213

212214
type FrontendEvents = {
@@ -241,7 +243,7 @@ type FrontendEvents = {
241243
storeAsGlobal: [StoreAsGlobalParams],
242244
updateComponentFilters: [Array<ComponentFilter>],
243245
getEnvironmentNames: [],
244-
updateConsolePatchSettings: [DevToolsHookSettings],
246+
updateConsolePatchSettings: [$ReadOnly<DevToolsHookSettings>],
245247
viewAttributeSource: [ViewAttributeSourceParams],
246248
viewElementSource: [ElementAndRendererID],
247249

@@ -267,6 +269,8 @@ type FrontendEvents = {
267269

268270
resumeElementPolling: [],
269271
pauseElementPolling: [],
272+
273+
fetchHookSettings: [],
270274
};
271275

272276
class Bridge<

packages/react-devtools-shared/src/devtools/store.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import type {
4949
BridgeProtocol,
5050
} from 'react-devtools-shared/src/bridge';
5151
import UnsupportedBridgeOperationError from 'react-devtools-shared/src/UnsupportedBridgeOperationError';
52+
import type {DevToolsHookSettings} from '../backend/types';
5253

5354
const debug = (methodName: string, ...args: Array<string>) => {
5455
if (__DEBUG__) {
@@ -94,6 +95,7 @@ export default class Store extends EventEmitter<{
9495
collapseNodesByDefault: [],
9596
componentFilters: [],
9697
error: [Error],
98+
hookSettings: [$ReadOnly<DevToolsHookSettings>],
9799
mutated: [[Array<number>, Map<number, number>]],
98100
recordChangeDescriptions: [],
99101
roots: [],
@@ -192,6 +194,7 @@ export default class Store extends EventEmitter<{
192194
_weightAcrossRoots: number = 0;
193195

194196
_shouldCheckBridgeProtocolCompatibility: boolean = false;
197+
_hookSettings: $ReadOnly<DevToolsHookSettings> | null = null;
195198

196199
constructor(bridge: FrontendBridge, config?: Config) {
197200
super();
@@ -270,6 +273,7 @@ export default class Store extends EventEmitter<{
270273

271274
bridge.addListener('backendVersion', this.onBridgeBackendVersion);
272275
bridge.addListener('saveToClipboard', this.onSaveToClipboard);
276+
bridge.addListener('hookSettings', this.onHookSettings);
273277
bridge.addListener('backendInitialized', this.onBackendInitialized);
274278
}
275279

@@ -1501,6 +1505,28 @@ export default class Store extends EventEmitter<{
15011505

15021506
this._bridge.send('getBackendVersion');
15031507
this._bridge.send('getIfHasUnsupportedRendererVersion');
1508+
this.fetchHookSettings();
1509+
};
1510+
1511+
fetchHookSettings: () => void = () => {
1512+
this._bridge.send('fetchHookSettings');
1513+
};
1514+
1515+
updateConsolePatchSettings: (
1516+
settings: $ReadOnly<DevToolsHookSettings>,
1517+
) => void = settings => {
1518+
this._hookSettings = settings;
1519+
this._bridge.send('updateConsolePatchSettings', settings);
1520+
};
1521+
1522+
onHookSettings: (settings: $ReadOnly<DevToolsHookSettings>) => void =
1523+
settings => {
1524+
this._hookSettings = settings;
1525+
this.emit('hookSettings', settings);
1526+
};
1527+
1528+
getHookSettings: () => $ReadOnly<DevToolsHookSettings> | null = () => {
1529+
return this._hookSettings;
15041530
};
15051531

15061532
// The Store should never throw an Error without also emitting an event.

packages/react-devtools-shared/src/devtools/views/Settings/SettingsContext.js

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,14 @@ import {
2020
import {
2121
LOCAL_STORAGE_BROWSER_THEME,
2222
LOCAL_STORAGE_PARSE_HOOK_NAMES_KEY,
23-
LOCAL_STORAGE_SHOULD_BREAK_ON_CONSOLE_ERRORS,
24-
LOCAL_STORAGE_SHOULD_APPEND_COMPONENT_STACK_KEY,
2523
LOCAL_STORAGE_TRACE_UPDATES_ENABLED_KEY,
26-
LOCAL_STORAGE_SHOW_INLINE_WARNINGS_AND_ERRORS_KEY,
27-
LOCAL_STORAGE_HIDE_CONSOLE_LOGS_IN_STRICT_MODE,
2824
} from 'react-devtools-shared/src/constants';
2925
import {
3026
COMFORTABLE_LINE_HEIGHT,
3127
COMPACT_LINE_HEIGHT,
3228
} from 'react-devtools-shared/src/devtools/constants';
33-
import {useLocalStorage} from '../hooks';
34-
import {BridgeContext} from '../context';
29+
import {useDevToolsHookSettings, useLocalStorage} from '../hooks';
30+
import {BridgeContext, StoreContext} from '../context';
3531
import {logEvent} from 'react-devtools-shared/src/Logger';
3632

3733
import type {BrowserTheme} from 'react-devtools-shared/src/frontend/types';
@@ -108,6 +104,7 @@ function SettingsContextController({
108104
profilerPortalContainer,
109105
}: Props): React.Node {
110106
const bridge = useContext(BridgeContext);
107+
const store = useContext(StoreContext);
111108

112109
const [displayDensity, setDisplayDensity] =
113110
useLocalStorageWithLog<DisplayDensity>(
@@ -118,36 +115,27 @@ function SettingsContextController({
118115
LOCAL_STORAGE_BROWSER_THEME,
119116
'auto',
120117
);
121-
const [appendComponentStack, setAppendComponentStack] =
122-
useLocalStorageWithLog<boolean>(
123-
LOCAL_STORAGE_SHOULD_APPEND_COMPONENT_STACK_KEY,
124-
true,
125-
);
126-
const [breakOnConsoleErrors, setBreakOnConsoleErrors] =
127-
useLocalStorageWithLog<boolean>(
128-
LOCAL_STORAGE_SHOULD_BREAK_ON_CONSOLE_ERRORS,
129-
false,
130-
);
131118
const [parseHookNames, setParseHookNames] = useLocalStorageWithLog<boolean>(
132119
LOCAL_STORAGE_PARSE_HOOK_NAMES_KEY,
133120
false,
134121
);
135-
const [hideConsoleLogsInStrictMode, setHideConsoleLogsInStrictMode] =
136-
useLocalStorageWithLog<boolean>(
137-
LOCAL_STORAGE_HIDE_CONSOLE_LOGS_IN_STRICT_MODE,
138-
false,
139-
);
140-
const [showInlineWarningsAndErrors, setShowInlineWarningsAndErrors] =
141-
useLocalStorageWithLog<boolean>(
142-
LOCAL_STORAGE_SHOW_INLINE_WARNINGS_AND_ERRORS_KEY,
143-
true,
144-
);
145122
const [traceUpdatesEnabled, setTraceUpdatesEnabled] =
146123
useLocalStorageWithLog<boolean>(
147124
LOCAL_STORAGE_TRACE_UPDATES_ENABLED_KEY,
148125
false,
149126
);
150127

128+
const {
129+
appendComponentStack,
130+
setAppendComponentStack,
131+
breakOnConsoleErrors,
132+
setBreakOnConsoleErrors,
133+
hideConsoleLogsInStrictMode,
134+
setHideConsoleLogsInStrictMode,
135+
showInlineWarningsAndErrors,
136+
setShowInlineWarningsAndErrors,
137+
} = useDevToolsHookSettings(store);
138+
151139
const documentElements = useMemo<DocumentElements>(() => {
152140
const array: Array<HTMLElement> = [
153141
((document.documentElement: any): HTMLElement),
@@ -197,14 +185,14 @@ function SettingsContextController({
197185
}, [browserTheme, theme, documentElements]);
198186

199187
useEffect(() => {
200-
bridge.send('updateConsolePatchSettings', {
188+
store.updateConsolePatchSettings({
201189
appendComponentStack,
202190
breakOnConsoleErrors,
203191
showInlineWarningsAndErrors,
204192
hideConsoleLogsInStrictMode,
205193
});
206194
}, [
207-
bridge,
195+
store,
208196
appendComponentStack,
209197
breakOnConsoleErrors,
210198
showInlineWarningsAndErrors,

packages/react-devtools-shared/src/devtools/views/hooks.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
* @flow
88
*/
99

10+
import type {DevToolsHookSettings} from 'react-devtools-shared/src/backend/types';
11+
1012
import {
1113
useCallback,
1214
useEffect,
@@ -19,6 +21,7 @@ import {
1921
localStorageGetItem,
2022
localStorageSetItem,
2123
} from 'react-devtools-shared/src/storage';
24+
import Store from 'react-devtools-shared/src/devtools/store';
2225
import {StoreContext, BridgeContext} from './context';
2326
import {sanitizeForParse, smartParse, smartStringify} from '../utils';
2427

@@ -206,6 +209,69 @@ export function useLocalStorage<T>(
206209
return [storedValue, setValue];
207210
}
208211

212+
type DevToolsHookSettingsGettersAndSetters = {
213+
appendComponentStack: boolean,
214+
setAppendComponentStack: boolean => void,
215+
breakOnConsoleErrors: boolean,
216+
setBreakOnConsoleErrors: boolean => void,
217+
hideConsoleLogsInStrictMode: boolean,
218+
setHideConsoleLogsInStrictMode: boolean => void,
219+
showInlineWarningsAndErrors: boolean,
220+
setShowInlineWarningsAndErrors: boolean => void,
221+
};
222+
223+
export function useDevToolsHookSettings(
224+
store: Store,
225+
): DevToolsHookSettingsGettersAndSetters {
226+
const settings = store.getHookSettings();
227+
228+
const [appendComponentStack, setAppendComponentStack] = useState(
229+
settings?.appendComponentStack || false,
230+
);
231+
const [breakOnConsoleErrors, setBreakOnConsoleErrors] = useState(
232+
settings?.breakOnConsoleErrors || false,
233+
);
234+
const [hideConsoleLogsInStrictMode, setHideConsoleLogsInStrictMode] =
235+
useState(settings?.hideConsoleLogsInStrictMode || false);
236+
const [showInlineWarningsAndErrors, setShowInlineWarningsAndErrors] =
237+
useState(settings?.showInlineWarningsAndErrors || false);
238+
239+
const onHookSettings = useCallback(
240+
(hookSettings: $ReadOnly<DevToolsHookSettings>) => {
241+
setAppendComponentStack(hookSettings.appendComponentStack);
242+
setBreakOnConsoleErrors(hookSettings.breakOnConsoleErrors);
243+
setHideConsoleLogsInStrictMode(hookSettings.hideConsoleLogsInStrictMode);
244+
setShowInlineWarningsAndErrors(hookSettings.showInlineWarningsAndErrors);
245+
},
246+
[],
247+
);
248+
249+
useEffect(() => {
250+
store.addListener('hookSettings', onHookSettings);
251+
252+
return () => {
253+
store.removeListener('hookSettings', onHookSettings);
254+
};
255+
}, [store, onHookSettings]);
256+
257+
useEffect(() => {
258+
if (!settings) {
259+
store.fetchHookSettings();
260+
}
261+
}, []);
262+
263+
return {
264+
appendComponentStack,
265+
setAppendComponentStack,
266+
breakOnConsoleErrors,
267+
setBreakOnConsoleErrors,
268+
hideConsoleLogsInStrictMode,
269+
setHideConsoleLogsInStrictMode,
270+
showInlineWarningsAndErrors,
271+
setShowInlineWarningsAndErrors,
272+
};
273+
}
274+
209275
export function useModalDismissSignal(
210276
modalRef: {current: HTMLDivElement | null, ...},
211277
dismissCallback: () => void,

packages/react-devtools-shared/src/hook.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,8 @@ export function installHook(
645645
Promise.resolve(maybeSettingsOrSettingsPromise)
646646
.then(settings => {
647647
hook.settings = settings;
648+
hook.emit('settingsInjected', settings);
649+
648650
patchConsoleForErrorsAndWarnings();
649651
})
650652
.catch(() => {

0 commit comments

Comments
 (0)