2019-08-06 01:09:26 +08:00
|
|
|
/** @flow */
|
|
|
|
|
|
2020-02-22 11:45:20 +08:00
|
|
|
import * as React from 'react';
|
|
|
|
|
import {forwardRef} from 'react';
|
2019-08-14 06:59:43 +08:00
|
|
|
import Bridge from 'react-devtools-shared/src/bridge';
|
|
|
|
|
import Store from 'react-devtools-shared/src/devtools/store';
|
|
|
|
|
import DevTools from 'react-devtools-shared/src/devtools/views/DevTools';
|
2019-08-14 08:58:03 +08:00
|
|
|
import {
|
|
|
|
|
getAppendComponentStack,
|
2020-05-30 05:34:43 +08:00
|
|
|
getBreakOnConsoleErrors,
|
|
|
|
|
getSavedComponentFilters,
|
2020-12-23 00:09:29 +08:00
|
|
|
getShowInlineWarningsAndErrors,
|
2021-08-26 06:35:38 +08:00
|
|
|
getHideConsoleLogsInStrictMode,
|
2019-08-14 08:58:03 +08:00
|
|
|
} from 'react-devtools-shared/src/utils';
|
2019-08-06 01:09:26 +08:00
|
|
|
import {
|
|
|
|
|
MESSAGE_TYPE_GET_SAVED_PREFERENCES,
|
|
|
|
|
MESSAGE_TYPE_SAVED_PREFERENCES,
|
|
|
|
|
} from './constants';
|
|
|
|
|
|
2021-04-13 05:07:14 +08:00
|
|
|
import type {Wall} from 'react-devtools-shared/src/types';
|
2019-08-14 08:58:03 +08:00
|
|
|
import type {FrontendBridge} from 'react-devtools-shared/src/bridge';
|
|
|
|
|
import type {Props} from 'react-devtools-shared/src/devtools/views/DevTools';
|
2019-08-06 01:09:26 +08:00
|
|
|
|
2021-08-21 00:55:50 +08:00
|
|
|
type Config = {|
|
|
|
|
|
supportsNativeInspection?: boolean,
|
|
|
|
|
|};
|
|
|
|
|
|
|
|
|
|
export function createStore(bridge: FrontendBridge, config?: Config): Store {
|
2021-04-28 05:26:07 +08:00
|
|
|
return new Store(bridge, {
|
|
|
|
|
checkBridgeProtocolCompatibility: true,
|
|
|
|
|
supportsTraceUpdates: true,
|
2021-11-04 23:40:45 +08:00
|
|
|
supportsTimeline: true,
|
2021-08-21 00:55:50 +08:00
|
|
|
supportsNativeInspection: config?.supportsNativeInspection !== false,
|
2021-04-28 05:26:07 +08:00
|
|
|
});
|
2021-04-13 05:07:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function createBridge(
|
|
|
|
|
contentWindow: window,
|
|
|
|
|
wall?: Wall,
|
|
|
|
|
): FrontendBridge {
|
|
|
|
|
if (wall == null) {
|
|
|
|
|
wall = {
|
|
|
|
|
listen(fn) {
|
|
|
|
|
const onMessage = ({data}) => {
|
|
|
|
|
fn(data);
|
|
|
|
|
};
|
|
|
|
|
window.addEventListener('message', onMessage);
|
|
|
|
|
return () => {
|
|
|
|
|
window.removeEventListener('message', onMessage);
|
|
|
|
|
};
|
|
|
|
|
},
|
|
|
|
|
send(event: string, payload: any, transferable?: Array<any>) {
|
|
|
|
|
contentWindow.postMessage({event, payload}, '*', transferable);
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (new Bridge(wall): FrontendBridge);
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-06 01:09:26 +08:00
|
|
|
export function initialize(
|
2019-08-14 08:58:03 +08:00
|
|
|
contentWindow: window,
|
2021-04-13 05:07:14 +08:00
|
|
|
{
|
|
|
|
|
bridge,
|
|
|
|
|
store,
|
|
|
|
|
}: {|
|
|
|
|
|
bridge?: FrontendBridge,
|
|
|
|
|
store?: Store,
|
|
|
|
|
|} = {},
|
2019-08-14 06:59:43 +08:00
|
|
|
): React.AbstractComponent<Props, mixed> {
|
2019-08-14 12:59:07 +08:00
|
|
|
const onGetSavedPreferencesMessage = ({data, source}) => {
|
2019-08-06 05:00:18 +08:00
|
|
|
if (source === 'react-devtools-content-script') {
|
|
|
|
|
// Ignore messages from the DevTools browser extension.
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-06 01:09:26 +08:00
|
|
|
switch (data.type) {
|
|
|
|
|
case MESSAGE_TYPE_GET_SAVED_PREFERENCES:
|
|
|
|
|
// This is the only message we're listening for,
|
|
|
|
|
// so it's safe to cleanup after we've received it.
|
2019-08-14 12:59:07 +08:00
|
|
|
window.removeEventListener('message', onGetSavedPreferencesMessage);
|
2019-08-06 01:09:26 +08:00
|
|
|
|
|
|
|
|
// The renderer interface can't read saved preferences directly,
|
|
|
|
|
// because they are stored in localStorage within the context of the extension.
|
|
|
|
|
// Instead it relies on the extension to pass them through.
|
|
|
|
|
contentWindow.postMessage(
|
|
|
|
|
{
|
|
|
|
|
type: MESSAGE_TYPE_SAVED_PREFERENCES,
|
|
|
|
|
appendComponentStack: getAppendComponentStack(),
|
2020-05-30 05:34:43 +08:00
|
|
|
breakOnConsoleErrors: getBreakOnConsoleErrors(),
|
2019-08-06 01:09:26 +08:00
|
|
|
componentFilters: getSavedComponentFilters(),
|
2020-12-23 00:09:29 +08:00
|
|
|
showInlineWarningsAndErrors: getShowInlineWarningsAndErrors(),
|
2021-08-26 06:35:38 +08:00
|
|
|
hideConsoleLogsInStrictMode: getHideConsoleLogsInStrictMode(),
|
2019-08-06 01:09:26 +08:00
|
|
|
},
|
2019-08-14 08:58:03 +08:00
|
|
|
'*',
|
2019-08-06 01:09:26 +08:00
|
|
|
);
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2019-08-14 12:59:07 +08:00
|
|
|
window.addEventListener('message', onGetSavedPreferencesMessage);
|
2019-08-06 01:09:26 +08:00
|
|
|
|
2021-04-13 05:07:14 +08:00
|
|
|
if (bridge == null) {
|
2021-04-15 01:27:21 +08:00
|
|
|
bridge = createBridge(contentWindow);
|
2021-04-13 05:07:14 +08:00
|
|
|
}
|
2019-08-06 01:09:26 +08:00
|
|
|
|
2021-04-13 05:07:14 +08:00
|
|
|
if (store == null) {
|
|
|
|
|
store = createStore(bridge);
|
|
|
|
|
}
|
2019-08-06 01:09:26 +08:00
|
|
|
|
|
|
|
|
const ForwardRef = forwardRef<Props, mixed>((props, ref) => (
|
|
|
|
|
<DevTools ref={ref} bridge={bridge} store={store} {...props} />
|
|
|
|
|
));
|
|
|
|
|
ForwardRef.displayName = 'DevTools';
|
|
|
|
|
|
|
|
|
|
return ForwardRef;
|
|
|
|
|
}
|