Skip to content

Commit c888188

Browse files
author
Brian Vaughn
committed
Replaced direct calls to window.postMessage() with Bridge.send()
1 parent 2e14b94 commit c888188

File tree

5 files changed

+77
-97
lines changed

5 files changed

+77
-97
lines changed

packages/react-devtools-inline/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ const iframe = document.getElementById(frameID);
5656
const contentWindow = iframe.contentWindow;
5757

5858
// This returns a React component that can be rendered into your app.
59-
// <DevTools {...props} />
59+
// e.g. render(<DevTools {...props} />);
6060
const DevTools = initialize(contentWindow);
6161
```
6262

packages/react-devtools-inline/src/backend.js

Lines changed: 37 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -5,67 +5,54 @@ import Bridge from 'react-devtools-shared/src/bridge';
55
import {initBackend} from 'react-devtools-shared/src/backend';
66
import {installHook} from 'react-devtools-shared/src/hook';
77
import setupNativeStyleEditor from 'react-devtools-shared/src/backend/NativeStyleEditor/setupNativeStyleEditor';
8-
import {
9-
MESSAGE_TYPE_GET_SAVED_PREFERENCES,
10-
MESSAGE_TYPE_SAVED_PREFERENCES,
11-
} from './constants';
128

139
import type {BackendBridge} from 'react-devtools-shared/src/bridge';
1410
import type {Wall} from 'react-devtools-shared/src/types';
1511

1612
function startActivation(contentWindow: window, bridge: BackendBridge) {
17-
const {parent} = contentWindow;
18-
19-
const onMessage = ({data}) => {
20-
switch (data.type) {
21-
case MESSAGE_TYPE_SAVED_PREFERENCES:
22-
// This is the only message we're listening for,
23-
// so it's safe to cleanup after we've received it.
24-
contentWindow.removeEventListener('message', onMessage);
25-
26-
const {
27-
appendComponentStack,
28-
breakOnConsoleErrors,
29-
componentFilters,
30-
showInlineWarningsAndErrors,
31-
hideConsoleLogsInStrictMode,
32-
} = data;
33-
34-
contentWindow.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = appendComponentStack;
35-
contentWindow.__REACT_DEVTOOLS_BREAK_ON_CONSOLE_ERRORS__ = breakOnConsoleErrors;
36-
contentWindow.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = componentFilters;
37-
contentWindow.__REACT_DEVTOOLS_SHOW_INLINE_WARNINGS_AND_ERRORS__ = showInlineWarningsAndErrors;
38-
contentWindow.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__ = hideConsoleLogsInStrictMode;
39-
40-
// TRICKY
41-
// The backend entry point may be required in the context of an iframe or the parent window.
42-
// If it's required within the parent window, store the saved values on it as well,
43-
// since the injected renderer interface will read from window.
44-
// Technically we don't need to store them on the contentWindow in this case,
45-
// but it doesn't really hurt anything to store them there too.
46-
if (contentWindow !== window) {
47-
window.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = appendComponentStack;
48-
window.__REACT_DEVTOOLS_BREAK_ON_CONSOLE_ERRORS__ = breakOnConsoleErrors;
49-
window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = componentFilters;
50-
window.__REACT_DEVTOOLS_SHOW_INLINE_WARNINGS_AND_ERRORS__ = showInlineWarningsAndErrors;
51-
window.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__ = hideConsoleLogsInStrictMode;
52-
}
53-
54-
finishActivation(contentWindow, bridge);
55-
break;
56-
default:
57-
break;
13+
const onSavedPreferences = data => {
14+
// This is the only message we're listening for,
15+
// so it's safe to cleanup after we've received it.
16+
bridge.removeListener('savedPreferences', onSavedPreferences);
17+
18+
const {
19+
appendComponentStack,
20+
breakOnConsoleErrors,
21+
componentFilters,
22+
showInlineWarningsAndErrors,
23+
hideConsoleLogsInStrictMode,
24+
} = data;
25+
26+
contentWindow.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = appendComponentStack;
27+
contentWindow.__REACT_DEVTOOLS_BREAK_ON_CONSOLE_ERRORS__ = breakOnConsoleErrors;
28+
contentWindow.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = componentFilters;
29+
contentWindow.__REACT_DEVTOOLS_SHOW_INLINE_WARNINGS_AND_ERRORS__ = showInlineWarningsAndErrors;
30+
contentWindow.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__ = hideConsoleLogsInStrictMode;
31+
32+
// TRICKY
33+
// The backend entry point may be required in the context of an iframe or the parent window.
34+
// If it's required within the parent window, store the saved values on it as well,
35+
// since the injected renderer interface will read from window.
36+
// Technically we don't need to store them on the contentWindow in this case,
37+
// but it doesn't really hurt anything to store them there too.
38+
if (contentWindow !== window) {
39+
window.__REACT_DEVTOOLS_APPEND_COMPONENT_STACK__ = appendComponentStack;
40+
window.__REACT_DEVTOOLS_BREAK_ON_CONSOLE_ERRORS__ = breakOnConsoleErrors;
41+
window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = componentFilters;
42+
window.__REACT_DEVTOOLS_SHOW_INLINE_WARNINGS_AND_ERRORS__ = showInlineWarningsAndErrors;
43+
window.__REACT_DEVTOOLS_HIDE_CONSOLE_LOGS_IN_STRICT_MODE__ = hideConsoleLogsInStrictMode;
5844
}
45+
46+
finishActivation(contentWindow, bridge);
5947
};
6048

61-
contentWindow.addEventListener('message', onMessage);
49+
bridge.addListener('savedPreferences', onSavedPreferences);
6250

6351
// The backend may be unable to read saved preferences directly,
6452
// because they are stored in localStorage within the context of the extension (on the frontend).
6553
// Instead it relies on the extension to pass preferences through.
6654
// Because we might be in a sandboxed iframe, we have to ask for them by way of postMessage().
67-
// TODO WHAT HUH
68-
parent.postMessage({type: MESSAGE_TYPE_GET_SAVED_PREFERENCES}, '*');
55+
bridge.send('getSavedPreferences');
6956
}
7057

7158
function finishActivation(contentWindow: window, bridge: BackendBridge) {
@@ -114,9 +101,9 @@ export function createBridge(
114101
const onMessage = ({data}) => {
115102
fn(data);
116103
};
117-
window.addEventListener('message', onMessage);
104+
contentWindow.addEventListener('message', onMessage);
118105
return () => {
119-
window.removeEventListener('message', onMessage);
106+
contentWindow.removeEventListener('message', onMessage);
120107
};
121108
},
122109
send(event: string, payload: any, transferable?: Array<any>) {

packages/react-devtools-inline/src/constants.js

Lines changed: 0 additions & 6 deletions
This file was deleted.

packages/react-devtools-inline/src/frontend.js

Lines changed: 26 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,6 @@ import {
1212
getShowInlineWarningsAndErrors,
1313
getHideConsoleLogsInStrictMode,
1414
} from 'react-devtools-shared/src/utils';
15-
import {
16-
MESSAGE_TYPE_GET_SAVED_PREFERENCES,
17-
MESSAGE_TYPE_SAVED_PREFERENCES,
18-
} from './constants';
1915

2016
import type {Wall} from 'react-devtools-shared/src/types';
2117
import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
@@ -68,49 +64,40 @@ export function initialize(
6864
store?: Store,
6965
|} = {},
7066
): React.AbstractComponent<Props, mixed> {
71-
const onGetSavedPreferencesMessage = ({data, source}) => {
72-
if (source === 'react-devtools-content-script') {
73-
// Ignore messages from the DevTools browser extension.
74-
}
75-
76-
switch (data.type) {
77-
case MESSAGE_TYPE_GET_SAVED_PREFERENCES:
78-
// This is the only message we're listening for,
79-
// so it's safe to cleanup after we've received it.
80-
window.removeEventListener('message', onGetSavedPreferencesMessage);
81-
82-
// The renderer interface can't read saved preferences directly,
83-
// because they are stored in localStorage within the context of the extension.
84-
// Instead it relies on the extension to pass them through.
85-
contentWindow.postMessage(
86-
{
87-
type: MESSAGE_TYPE_SAVED_PREFERENCES,
88-
appendComponentStack: getAppendComponentStack(),
89-
breakOnConsoleErrors: getBreakOnConsoleErrors(),
90-
componentFilters: getSavedComponentFilters(),
91-
showInlineWarningsAndErrors: getShowInlineWarningsAndErrors(),
92-
hideConsoleLogsInStrictMode: getHideConsoleLogsInStrictMode(),
93-
},
94-
'*',
95-
);
96-
break;
97-
default:
98-
break;
99-
}
100-
};
101-
102-
window.addEventListener('message', onGetSavedPreferencesMessage);
103-
10467
if (bridge == null) {
10568
bridge = createBridge(contentWindow);
10669
}
10770

71+
// Type refinement.
72+
const frontendBridge = ((bridge: any): FrontendBridge);
73+
10874
if (store == null) {
109-
store = createStore(bridge);
75+
store = createStore(frontendBridge);
11076
}
11177

78+
const onGetSavedPreferences = () => {
79+
// This is the only message we're listening for,
80+
// so it's safe to cleanup after we've received it.
81+
frontendBridge.removeListener('getSavedPreferences', onGetSavedPreferences);
82+
83+
const data = {
84+
appendComponentStack: getAppendComponentStack(),
85+
breakOnConsoleErrors: getBreakOnConsoleErrors(),
86+
componentFilters: getSavedComponentFilters(),
87+
showInlineWarningsAndErrors: getShowInlineWarningsAndErrors(),
88+
hideConsoleLogsInStrictMode: getHideConsoleLogsInStrictMode(),
89+
};
90+
91+
// The renderer interface can't read saved preferences directly,
92+
// because they are stored in localStorage within the context of the extension.
93+
// Instead it relies on the extension to pass them through.
94+
frontendBridge.send('savedPreferences', data);
95+
};
96+
97+
frontendBridge.addListener('getSavedPreferences', onGetSavedPreferences);
98+
11299
const ForwardRef = forwardRef<Props, mixed>((props, ref) => (
113-
<DevTools ref={ref} bridge={bridge} store={store} {...props} />
100+
<DevTools ref={ref} bridge={frontendBridge} store={store} {...props} />
114101
));
115102
ForwardRef.displayName = 'DevTools';
116103

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,10 +176,19 @@ type UpdateConsolePatchSettingsParams = {|
176176
browserTheme: BrowserTheme,
177177
|};
178178

179+
type SavedPreferencesParams = {|
180+
appendComponentStack: boolean,
181+
breakOnConsoleErrors: boolean,
182+
componentFilters: Array<ComponentFilter>,
183+
showInlineWarningsAndErrors: boolean,
184+
hideConsoleLogsInStrictMode: boolean,
185+
|};
186+
179187
export type BackendEvents = {|
180188
bridgeProtocol: [BridgeProtocol],
181189
extensionBackendInitialized: [],
182190
fastRefreshScheduled: [],
191+
getSavedPreferences: [],
183192
inspectedElement: [InspectedElementPayload],
184193
isBackendStorageAPISupported: [boolean],
185194
isSynchronousXHRSupported: [boolean],
@@ -223,6 +232,7 @@ type FrontendEvents = {|
223232
profilingData: [ProfilingDataBackend],
224233
reloadAndProfile: [boolean],
225234
renamePath: [RenamePath],
235+
savedPreferences: [SavedPreferencesParams],
226236
selectFiber: [number],
227237
setTraceUpdatesEnabled: [boolean],
228238
shutdown: [],
@@ -277,7 +287,9 @@ class Bridge<
277287

278288
this._wallUnlisten =
279289
wall.listen((message: Message) => {
280-
(this: any).emit(message.event, message.payload);
290+
if (message && message.event) {
291+
(this: any).emit(message.event, message.payload);
292+
}
281293
}) || null;
282294

283295
// Temporarily support older standalone front-ends sending commands to newer embedded backends.

0 commit comments

Comments
 (0)