diff --git a/packages/react-devtools-core/README.md b/packages/react-devtools-core/README.md
index 21f4f697cf3..a42e569697f 100644
--- a/packages/react-devtools-core/README.md
+++ b/packages/react-devtools-core/README.md
@@ -25,15 +25,30 @@ if (process.env.NODE_ENV !== 'production') {
> **NOTE** that this API (`connectToDevTools`) must be (1) run in the same context as React and (2) must be called before React packages are imported (e.g. `react`, `react-dom`, `react-native`).
### `initialize` arguments
-| Argument | Description |
-|------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| `settings` | Optional. If not specified, or received as null, then default settings are used. Can be plain object or a Promise that resolves with the [plain settings object](#Settings). If Promise rejects, the console will not be patched and some console features from React DevTools will not work. |
+| Argument | Description |
+|---------------------------|-------------|
+| `settings` | Optional. If not specified, or received as null, then default settings are used. Can be plain object or a Promise that resolves with the [plain settings object](#Settings). If Promise rejects, the console will not be patched and some console features from React DevTools will not work. |
+| `shouldStartProfilingNow` | Optional. Whether to start profiling immediately after installing the hook. Defaults to `false`. |
+| `profilingSettings` | Optional. Profiling settings used when `shouldStartProfilingNow` is `true`. Defaults to `{ recordChangeDescriptions: false, recordTimeline: false }`. |
+| `componentFilters` | Optional. Array or Promise that resolves to an array of component filters to apply before DevTools connects. Defaults to the built-in host component filter. See [Component filters](#component-filters) for the full spec. |
#### `Settings`
| Spec | Default value |
|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
{
appendComponentStack: boolean,
breakOnConsoleErrors: boolean,
showInlineWarningsAndErrors: boolean,
hideConsoleLogsInStrictMode: boolean,
disableSecondConsoleLogDimmingInStrictMode: boolean
} | {
appendComponentStack: true,
breakOnConsoleErrors: false,
showInlineWarningsAndErrors: true,
hideConsoleLogsInStrictMode: false,
disableSecondConsoleLogDimmingInStrictMode: false
} |
+#### Component filters
+Each filter object must include `type` and `isEnabled`. Some filters also require `value` or `isValid`.
+
+| Type | Required fields | Description |
+|------|-----------------|-------------|
+| `ComponentFilterElementType` (`1`) | `type`, `isEnabled`, `value: ElementType` | Hides elements of the given element type. DevTools defaults to hiding host components. |
+| `ComponentFilterDisplayName` (`2`) | `type`, `isEnabled`, `isValid`, `value: string` | Hides components whose display name matches the provided RegExp string. |
+| `ComponentFilterLocation` (`3`) | `type`, `isEnabled`, `isValid`, `value: string` | Hides components whose source location matches the provided RegExp string. |
+| `ComponentFilterHOC` (`4`) | `type`, `isEnabled`, `isValid` | Hides higher-order components. |
+| `ComponentFilterEnvironmentName` (`5`) | `type`, `isEnabled`, `isValid`, `value: string` | Hides components whose environment name matches the provided string. |
+| `ComponentFilterActivitySlice` (`6`) | `type`, `isEnabled`, `isValid`, `activityID`, `rendererID` | Filters activity slices; usually managed by DevTools rather than user code. |
+
### `connectToDevTools` options
| Prop | Default | Description |
|------------------------|---------------|---------------------------------------------------------------------------------------------------------------------------|
diff --git a/packages/react-devtools-core/src/backend.js b/packages/react-devtools-core/src/backend.js
index 4cca0887c57..262b3bc0412 100644
--- a/packages/react-devtools-core/src/backend.js
+++ b/packages/react-devtools-core/src/backend.js
@@ -66,9 +66,17 @@ export function initialize(
| Promise,
shouldStartProfilingNow: boolean = false,
profilingSettings?: ProfilingSettings,
+ maybeComponentFiltersOrComponentFiltersPromise?:
+ | Array
+ | Promise>,
) {
+ const componentFiltersOrComponentFiltersPromise =
+ maybeComponentFiltersOrComponentFiltersPromise
+ ? maybeComponentFiltersOrComponentFiltersPromise
+ : savedComponentFilters;
installHook(
window,
+ componentFiltersOrComponentFiltersPromise,
maybeSettingsOrSettingsPromise,
shouldStartProfilingNow,
profilingSettings,
@@ -174,19 +182,6 @@ export function connectToDevTools(options: ?ConnectOptions) {
},
);
- // The renderer interface doesn't read saved component filters directly,
- // because they are generally stored in localStorage within the context of the extension.
- // Because of this it relies on the extension to pass filters.
- // In the case of the standalone DevTools being used with a website,
- // saved filters are injected along with the backend script tag so we shouldn't override them here.
- // This injection strategy doesn't work for React Native though.
- // Ideally the backend would save the filters itself, but RN doesn't provide a sync storage solution.
- // So for now we just fall back to using the default filters...
- if (window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ == null) {
- // $FlowFixMe[incompatible-use] found when upgrading Flow
- bridge.send('overrideComponentFilters', savedComponentFilters);
- }
-
// TODO (npm-packages) Warn if "isBackendStorageAPISupported"
// $FlowFixMe[incompatible-call] found when upgrading Flow
const agent = new Agent(bridge, isProfiling, onReloadAndProfile);
@@ -381,10 +376,6 @@ export function connectWithCustomMessagingProtocol({
},
);
- if (window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ == null) {
- bridge.send('overrideComponentFilters', savedComponentFilters);
- }
-
const agent = new Agent(bridge, isProfiling, onReloadAndProfile);
if (typeof onReloadAndProfileFlagsReset === 'function') {
onReloadAndProfileFlagsReset();
diff --git a/packages/react-devtools-core/src/standalone.js b/packages/react-devtools-core/src/standalone.js
index f8286783a9b..df89a728c30 100644
--- a/packages/react-devtools-core/src/standalone.js
+++ b/packages/react-devtools-core/src/standalone.js
@@ -356,17 +356,12 @@ function startServer(
// because they are generally stored in localStorage within the context of the extension.
// Because of this it relies on the extension to pass filters, so include them wth the response here.
// This will ensure that saved filters are shared across different web pages.
- const savedPreferencesString = `
- window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = ${JSON.stringify(
- getSavedComponentFilters(),
- )};`;
+ const componentFiltersString = JSON.stringify(getSavedComponentFilters());
response.end(
- savedPreferencesString +
+ backendFile.toString() +
'\n;' +
- backendFile.toString() +
- '\n;' +
- 'ReactDevToolsBackend.initialize();' +
+ `ReactDevToolsBackend.initialize(undefined, undefined, undefined, ${componentFiltersString});` +
'\n' +
`ReactDevToolsBackend.connectToDevTools({port: ${port}, host: '${host}', useHttps: ${
useHttps ? 'true' : 'false'
diff --git a/packages/react-devtools-extensions/src/contentScripts/hookSettingsInjector.js b/packages/react-devtools-extensions/src/contentScripts/hookSettingsInjector.js
index 196369e71d9..00c9b905a66 100644
--- a/packages/react-devtools-extensions/src/contentScripts/hookSettingsInjector.js
+++ b/packages/react-devtools-extensions/src/contentScripts/hookSettingsInjector.js
@@ -5,9 +5,15 @@
// This is the only purpose of this script - to send persisted settings to installHook.js content script
import type {UnknownMessageEvent} from './messages';
-import type {DevToolsHookSettings} from 'react-devtools-shared/src/backend/types';
+import type {
+ DevToolsHookSettings,
+ DevToolsSettings,
+} from 'react-devtools-shared/src/backend/types';
+import type {ComponentFilter} from 'react-devtools-shared/src/frontend/types';
import {postMessage} from './messages';
+import {getDefaultComponentFilters} from 'react-devtools-shared/src/utils';
+
async function messageListener(event: UnknownMessageEvent) {
if (event.source !== window) {
return;
@@ -15,7 +21,7 @@ async function messageListener(event: UnknownMessageEvent) {
if (event.data.source === 'react-devtools-hook-installer') {
if (event.data.payload.handshake) {
- const settings: Partial =
+ const settings: Partial =
await chrome.storage.local.get();
// If storage was empty (first installation), define default settings
const hookSettings: DevToolsHookSettings = {
@@ -41,10 +47,15 @@ async function messageListener(event: UnknownMessageEvent) {
? settings.disableSecondConsoleLogDimmingInStrictMode
: false,
};
+ const componentFilters: Array = Array.isArray(
+ settings.componentFilters,
+ )
+ ? settings.componentFilters
+ : getDefaultComponentFilters();
postMessage({
- source: 'react-devtools-hook-settings-injector',
- payload: {settings: hookSettings},
+ source: 'react-devtools-settings-injector',
+ payload: {hookSettings, componentFilters},
});
window.removeEventListener('message', messageListener);
@@ -54,6 +65,6 @@ async function messageListener(event: UnknownMessageEvent) {
window.addEventListener('message', messageListener);
postMessage({
- source: 'react-devtools-hook-settings-injector',
+ source: 'react-devtools-settings-injector',
payload: {handshake: true},
});
diff --git a/packages/react-devtools-extensions/src/contentScripts/installHook.js b/packages/react-devtools-extensions/src/contentScripts/installHook.js
index 8f30d6f0892..490232baf86 100644
--- a/packages/react-devtools-extensions/src/contentScripts/installHook.js
+++ b/packages/react-devtools-extensions/src/contentScripts/installHook.js
@@ -2,6 +2,7 @@
import type {UnknownMessageEvent} from './messages';
import type {DevToolsHookSettings} from 'react-devtools-shared/src/backend/types';
+import type {ComponentFilter} from 'react-devtools-shared/src/frontend/types';
import {installHook} from 'react-devtools-shared/src/hook';
import {
@@ -11,13 +12,14 @@ import {
import {postMessage} from './messages';
let resolveHookSettingsInjection: (settings: DevToolsHookSettings) => void;
+let resolveComponentFiltersInjection: (filters: Array) => void;
function messageListener(event: UnknownMessageEvent) {
if (event.source !== window) {
return;
}
- if (event.data.source === 'react-devtools-hook-settings-injector') {
+ if (event.data.source === 'react-devtools-settings-injector') {
const payload = event.data.payload;
// In case handshake message was sent prior to hookSettingsInjector execution
// We can't guarantee order
@@ -26,9 +28,10 @@ function messageListener(event: UnknownMessageEvent) {
source: 'react-devtools-hook-installer',
payload: {handshake: true},
});
- } else if (payload.settings) {
+ } else if (payload.hookSettings) {
window.removeEventListener('message', messageListener);
- resolveHookSettingsInjection(payload.settings);
+ resolveHookSettingsInjection(payload.hookSettings);
+ resolveComponentFiltersInjection(payload.componentFilters);
}
}
}
@@ -38,6 +41,11 @@ if (!window.hasOwnProperty('__REACT_DEVTOOLS_GLOBAL_HOOK__')) {
const hookSettingsPromise = new Promise(resolve => {
resolveHookSettingsInjection = resolve;
});
+ const componentFiltersPromise = new Promise>(
+ resolve => {
+ resolveComponentFiltersInjection = resolve;
+ },
+ );
window.addEventListener('message', messageListener);
postMessage({
@@ -50,6 +58,7 @@ if (!window.hasOwnProperty('__REACT_DEVTOOLS_GLOBAL_HOOK__')) {
// Can't delay hook installation, inject settings lazily
installHook(
window,
+ componentFiltersPromise,
hookSettingsPromise,
shouldStartProfiling,
profilingSettings,
diff --git a/packages/react-devtools-extensions/src/contentScripts/messages.js b/packages/react-devtools-extensions/src/contentScripts/messages.js
index e65d46b4b26..b93a3f0df86 100644
--- a/packages/react-devtools-extensions/src/contentScripts/messages.js
+++ b/packages/react-devtools-extensions/src/contentScripts/messages.js
@@ -1,6 +1,7 @@
/** @flow */
import type {DevToolsHookSettings} from 'react-devtools-shared/src/backend/types';
+import type {ComponentFilter} from 'react-devtools-shared/src/frontend/types';
export function postMessage(event: UnknownMessageEventData): void {
window.postMessage(event);
@@ -10,7 +11,7 @@ export interface UnknownMessageEvent
extends MessageEvent {}
export type UnknownMessageEventData =
- | HookSettingsInjectorEventData
+ | SettingsInjectorEventData
| HookInstallerEventData;
export type HookInstallerEventData = {
@@ -24,19 +25,20 @@ export type HookInstallerEventPayloadHandshake = {
handshake: true,
};
-export type HookSettingsInjectorEventData = {
- source: 'react-devtools-hook-settings-injector',
- payload: HookSettingsInjectorEventPayload,
+export type SettingsInjectorEventData = {
+ source: 'react-devtools-settings-injector',
+ payload: SettingsInjectorEventPayload,
};
-export type HookSettingsInjectorEventPayload =
- | HookSettingsInjectorEventPayloadHandshake
- | HookSettingsInjectorEventPayloadSettings;
+export type SettingsInjectorEventPayload =
+ | SettingsInjectorEventPayloadHandshake
+ | SettingsInjectorEventPayloadSettings;
-export type HookSettingsInjectorEventPayloadHandshake = {
+export type SettingsInjectorEventPayloadHandshake = {
handshake: true,
};
-export type HookSettingsInjectorEventPayloadSettings = {
- settings: DevToolsHookSettings,
+export type SettingsInjectorEventPayloadSettings = {
+ hookSettings: DevToolsHookSettings,
+ componentFilters: Array,
};
diff --git a/packages/react-devtools-extensions/src/main/index.js b/packages/react-devtools-extensions/src/main/index.js
index c2616cf04a1..75a81c92ddc 100644
--- a/packages/react-devtools-extensions/src/main/index.js
+++ b/packages/react-devtools-extensions/src/main/index.js
@@ -171,8 +171,8 @@ function createBridgeAndStore() {
createSuspensePanel();
});
- store.addListener('settingsUpdated', settings => {
- chrome.storage.local.set(settings);
+ store.addListener('settingsUpdated', (hookSettings, componentFilters) => {
+ chrome.storage.local.set({...hookSettings, componentFilters});
});
if (!isProfiling) {
diff --git a/packages/react-devtools-inline/src/backend.js b/packages/react-devtools-inline/src/backend.js
index 2dd03417121..9810d5b39cc 100644
--- a/packages/react-devtools-inline/src/backend.js
+++ b/packages/react-devtools-inline/src/backend.js
@@ -10,7 +10,10 @@ import type {
BackendBridge,
SavedPreferencesParams,
} from 'react-devtools-shared/src/bridge';
-import type {Wall} from 'react-devtools-shared/src/frontend/types';
+import type {
+ ComponentFilter,
+ Wall,
+} from 'react-devtools-shared/src/frontend/types';
import {
getIfReloadedAndProfiling,
getIsReloadAndProfileSupported,
@@ -18,6 +21,11 @@ import {
onReloadAndProfileFlagsReset,
} from 'react-devtools-shared/src/utils';
+let resolveComponentFiltersInjection: (filters: Array) => void;
+const componentFiltersPromise = new Promise>(resolve => {
+ resolveComponentFiltersInjection = resolve;
+});
+
function startActivation(contentWindow: any, bridge: BackendBridge) {
const onSavedPreferences = (data: SavedPreferencesParams) => {
// This is the only message we're listening for,
@@ -26,21 +34,13 @@ function startActivation(contentWindow: any, bridge: BackendBridge) {
const {componentFilters} = data;
- contentWindow.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = componentFilters;
-
- // TRICKY
- // The backend entry point may be required in the context of an iframe or the parent window.
- // If it's required within the parent window, store the saved values on it as well,
- // since the injected renderer interface will read from window.
- // Technically we don't need to store them on the contentWindow in this case,
- // but it doesn't really hurt anything to store them there too.
- if (contentWindow !== window) {
- window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = componentFilters;
- }
-
- finishActivation(contentWindow, bridge);
+ resolveComponentFiltersInjection(componentFilters);
};
+ componentFiltersPromise.then(
+ finishActivation.bind(null, contentWindow, bridge),
+ );
+
bridge.addListener('savedPreferences', onSavedPreferences);
// The backend may be unable to read saved preferences directly,
@@ -113,5 +113,5 @@ export function createBridge(contentWindow: any, wall?: Wall): BackendBridge {
}
export function initialize(contentWindow: any): void {
- installHook(contentWindow);
+ installHook(contentWindow, componentFiltersPromise);
}
diff --git a/packages/react-devtools-shared/src/__tests__/setupTests.js b/packages/react-devtools-shared/src/__tests__/setupTests.js
index 5774a573b31..37b07ea7c35 100644
--- a/packages/react-devtools-shared/src/__tests__/setupTests.js
+++ b/packages/react-devtools-shared/src/__tests__/setupTests.js
@@ -238,9 +238,8 @@ beforeEach(() => {
// Initialize filters to a known good state.
setSavedComponentFilters(getDefaultComponentFilters());
- global.__REACT_DEVTOOLS_COMPONENT_FILTERS__ = getDefaultComponentFilters();
- installHook(global, {
+ installHook(global, getDefaultComponentFilters(), {
appendComponentStack: true,
breakOnConsoleErrors: false,
showInlineWarningsAndErrors: true,
diff --git a/packages/react-devtools-shared/src/attachRenderer.js b/packages/react-devtools-shared/src/attachRenderer.js
index fedf76293cb..fa230fe7eff 100644
--- a/packages/react-devtools-shared/src/attachRenderer.js
+++ b/packages/react-devtools-shared/src/attachRenderer.js
@@ -14,6 +14,7 @@ import type {
RendererID,
ProfilingSettings,
} from 'react-devtools-shared/src/backend/types';
+import type {ComponentFilter} from 'react-devtools-shared/src/frontend/types';
import {attach as attachFlight} from 'react-devtools-shared/src/backend/flight/renderer';
import {attach as attachFiber} from 'react-devtools-shared/src/backend/fiber/renderer';
@@ -32,6 +33,9 @@ export default function attachRenderer(
global: Object,
shouldStartProfilingNow: boolean,
profilingSettings: ProfilingSettings,
+ componentFiltersOrComponentFiltersPromise:
+ | Array
+ | Promise>,
): RendererInterface | void {
// only attach if the renderer is compatible with the current version of the backend
if (!isMatchingRender(renderer.reconcilerVersion || renderer.version)) {
@@ -58,6 +62,7 @@ export default function attachRenderer(
global,
shouldStartProfilingNow,
profilingSettings,
+ componentFiltersOrComponentFiltersPromise,
);
} else if (renderer.ComponentTree) {
// react-dom v15
diff --git a/packages/react-devtools-shared/src/backend/fiber/renderer.js b/packages/react-devtools-shared/src/backend/fiber/renderer.js
index 892a3c6fc77..289bad6f329 100644
--- a/packages/react-devtools-shared/src/backend/fiber/renderer.js
+++ b/packages/react-devtools-shared/src/backend/fiber/renderer.js
@@ -48,13 +48,11 @@ import {
deletePathInObject,
getDisplayName,
getWrappedDisplayName,
- getDefaultComponentFilters,
getInObject,
getUID,
renamePathInObject,
setInObject,
utfEncodeString,
- persistableComponentFilters,
} from 'react-devtools-shared/src/utils';
import {
formatConsoleArgumentsToSingleString,
@@ -1010,6 +1008,9 @@ export function attach(
global: Object,
shouldStartProfilingNow: boolean,
profilingSettings: ProfilingSettings,
+ componentFiltersOrComponentFiltersPromise:
+ | Array
+ | Promise>,
): RendererInterface {
// Newer versions of the reconciler package also specific reconciler version.
// If that version number is present, use it.
@@ -1516,21 +1517,12 @@ export function attach(
});
}
- // The renderer interface can't read saved component filters directly,
- // because they are stored in localStorage within the context of the extension.
- // Instead it relies on the extension to pass filters through.
- if (window.__REACT_DEVTOOLS_COMPONENT_FILTERS__ != null) {
- const restoredComponentFilters: Array =
- persistableComponentFilters(window.__REACT_DEVTOOLS_COMPONENT_FILTERS__);
- applyComponentFilters(restoredComponentFilters, null);
+ if (Array.isArray(componentFiltersOrComponentFiltersPromise)) {
+ applyComponentFilters(componentFiltersOrComponentFiltersPromise, null);
} else {
- // Unfortunately this feature is not expected to work for React Native for now.
- // It would be annoying for us to spam YellowBox warnings with unactionable stuff,
- // so for now just skip this message...
- //console.warn('⚛ DevTools: Could not locate saved component filters');
-
- // Fallback to assuming the default filters in this case.
- applyComponentFilters(getDefaultComponentFilters(), null);
+ componentFiltersOrComponentFiltersPromise.then(componentFilters => {
+ applyComponentFilters(componentFilters, null);
+ });
}
// If necessary, we can revisit optimizing this operation.
diff --git a/packages/react-devtools-shared/src/backend/types.js b/packages/react-devtools-shared/src/backend/types.js
index 00c66355b2d..a97439b7cf9 100644
--- a/packages/react-devtools-shared/src/backend/types.js
+++ b/packages/react-devtools-shared/src/backend/types.js
@@ -599,3 +599,7 @@ export type DevToolsHookSettings = {
hideConsoleLogsInStrictMode: boolean,
disableSecondConsoleLogDimmingInStrictMode: boolean,
};
+
+export type DevToolsSettings = DevToolsHookSettings & {
+ componentFilters: Array,
+};
diff --git a/packages/react-devtools-shared/src/bridge.js b/packages/react-devtools-shared/src/bridge.js
index af3a87b5968..bc752ec4b8c 100644
--- a/packages/react-devtools-shared/src/bridge.js
+++ b/packages/react-devtools-shared/src/bridge.js
@@ -208,7 +208,6 @@ export type BackendEvents = {
isReloadAndProfileSupportedByBackend: [boolean],
operations: [Array],
ownersList: [OwnersList],
- overrideComponentFilters: [Array],
environmentNames: [Array],
profilingData: [ProfilingDataBackend],
profilingStatus: [boolean],
diff --git a/packages/react-devtools-shared/src/devtools/store.js b/packages/react-devtools-shared/src/devtools/store.js
index c48d5b42fb6..3e2dde5fea1 100644
--- a/packages/react-devtools-shared/src/devtools/store.js
+++ b/packages/react-devtools-shared/src/devtools/store.js
@@ -148,7 +148,7 @@ export default class Store extends EventEmitter<{
error: [Error],
hookSettings: [$ReadOnly],
hostInstanceSelected: [Element['id'] | null],
- settingsUpdated: [$ReadOnly],
+ settingsUpdated: [$ReadOnly, Array],
mutated: [
[
Array,
@@ -321,10 +321,6 @@ export default class Store extends EventEmitter<{
this._bridge = bridge;
bridge.addListener('operations', this.onBridgeOperations);
- bridge.addListener(
- 'overrideComponentFilters',
- this.onBridgeOverrideComponentFilters,
- );
bridge.addListener('shutdown', this.onBridgeShutdown);
bridge.addListener(
'isReloadAndProfileSupportedByBackend',
@@ -437,8 +433,23 @@ export default class Store extends EventEmitter<{
this._componentFilters = value;
- // Update persisted filter preferences stored in localStorage.
+ // Update persisted filter preferences
setSavedComponentFilters(value);
+ if (this._hookSettings === null) {
+ // We changed filters before we got the hook settings.
+ // Wait for hook settings before persisting component filters to not overwrite
+ // persisted hook settings with defaults.
+ // This exists purely as a type safety check; in practice the hook settings
+ // should have arrived before any filter changes could be made.
+ const onHookSettings = (settings: $ReadOnly) => {
+ this._bridge.removeListener('hookSettings', onHookSettings);
+ this.emit('settingsUpdated', settings, value);
+ };
+ this._bridge.addListener('hookSettings', onHookSettings);
+ this._bridge.send('getHookSettings');
+ } else {
+ this.emit('settingsUpdated', this._hookSettings, value);
+ }
// Notify the renderer that filter preferences have changed.
// This is an expensive operation; it unmounts and remounts the entire tree,
@@ -2264,19 +2275,6 @@ export default class Store extends EventEmitter<{
return didMutate;
}
- // Certain backends save filters on a per-domain basis.
- // In order to prevent filter preferences and applied filters from being out of sync,
- // this message enables the backend to override the frontend's current ("saved") filters.
- // This action should also override the saved filters too,
- // else reloading the frontend without reloading the backend would leave things out of sync.
- onBridgeOverrideComponentFilters: (
- componentFilters: Array,
- ) => void = componentFilters => {
- this._componentFilters = componentFilters;
-
- setSavedComponentFilters(componentFilters);
- };
-
onBridgeShutdown: () => void = () => {
if (__DEBUG__) {
debug('onBridgeShutdown', 'unsubscribing from Bridge');
@@ -2284,10 +2282,6 @@ export default class Store extends EventEmitter<{
const bridge = this._bridge;
bridge.removeListener('operations', this.onBridgeOperations);
- bridge.removeListener(
- 'overrideComponentFilters',
- this.onBridgeOverrideComponentFilters,
- );
bridge.removeListener('shutdown', this.onBridgeShutdown);
bridge.removeListener(
'isReloadAndProfileSupportedByBackend',
@@ -2419,7 +2413,7 @@ export default class Store extends EventEmitter<{
this._hookSettings = settings;
this._bridge.send('updateHookSettings', settings);
- this.emit('settingsUpdated', settings);
+ this.emit('settingsUpdated', settings, this._componentFilters);
};
onHookSettings: (settings: $ReadOnly) => void =
diff --git a/packages/react-devtools-shared/src/hook.js b/packages/react-devtools-shared/src/hook.js
index 97f8230b6a2..5764a8bee4b 100644
--- a/packages/react-devtools-shared/src/hook.js
+++ b/packages/react-devtools-shared/src/hook.js
@@ -18,6 +18,7 @@ import type {
DevToolsHookSettings,
ProfilingSettings,
} from './backend/types';
+import type {ComponentFilter} from './frontend/types';
import {
FIREFOX_CONSOLE_DIMMING_COLOR,
@@ -57,6 +58,9 @@ const defaultProfilingSettings: ProfilingSettings = {
export function installHook(
target: any,
+ componentFiltersOrComponentFiltersPromise:
+ | Array
+ | Promise>,
maybeSettingsOrSettingsPromise?:
| DevToolsHookSettings
| Promise,
@@ -224,6 +228,7 @@ export function installHook(
target,
isProfiling,
profilingSettings,
+ componentFiltersOrComponentFiltersPromise,
);
if (rendererInterface != null) {
hook.rendererInterfaces.set(id, rendererInterface);