@samitouri / QOS-React / commits / a241780dc2

Filter changes are applied to the renderer without reloading

Brian Vaughn committed Apr 29, 2019 at 13:08 UTC a241780dc249bc959c6b7e663dbe2e6deec1ab42
4 files changed +45 -6
src/backend/agent.js
+11 -1
@@ -16,7 +16,7 @@ import type {
16 RendererID,
17 RendererInterface,
18 } from './types';
19 -import type { Bridge } from '../types';
19 +import type { Bridge, FilterPreferences } from '../types';
20
21 const debug = (methodName, ...args) => {
22 if (__DEBUG__) {
@@ -118,6 +118,7 @@ export default class Agent extends EventEmitter {
118 this.syncSelectionFromNativeElementsPanel
119 );
120 bridge.addListener('shutdown', this.shutdown);
121 + bridge.addListener('updateFilterPreferences', this.updateFilterPreferences);
122 bridge.addListener('viewElementSource', this.viewElementSource);
123
124 if (this._isProfiling) {
@@ -489,6 +490,15 @@ export default class Agent extends EventEmitter {
490 this._bridge.send('profilingStatus', this._isProfiling);
491 };
492
493 + updateFilterPreferences = (filterPreferences: FilterPreferences) => {
494 + for (let rendererID in this._rendererInterfaces) {
495 + const renderer = ((this._rendererInterfaces[
496 + (rendererID: any)
497 + ]: any): RendererInterface);
498 + renderer.updateFilterPreferences(filterPreferences);
499 + }
500 + };
501 +
502 viewElementSource = ({ id, rendererID }: InspectSelectParams) => {
503 const renderer = this._rendererInterfaces[rendererID];
504 if (renderer == null) {
src/backend/renderer.js
+29 -3
@@ -48,6 +48,7 @@ import type {
48 RendererInterface,
49 } from './types';
50 import type { InspectedElement } from 'src/devtools/views/Components/types';
51 +import type { FilterPreferences } from 'src/types';
52
53 function getInternalReactConstants(version) {
54 const ReactSymbols = {
@@ -264,12 +265,36 @@ export function attach(
265 }
266 };
267
267 - const {
268 + let {
269 hideElementsWithTypes,
269 - // TOOD (filter) hideElementsWithDisplayNames,
270 - // TOOD (filter) hideElementsWithPaths,
270 + hideElementsWithDisplayNames,
271 + hideElementsWithPaths,
272 } = getSavedFilterPreferences();
273
274 + // TODO (filter) We could make this more efficient.
275 + function updateFilterPreferences(filterPreferences: FilterPreferences) {
276 + // Recursively unmount and then re-mount all roots.
277 + hook.getFiberRoots(rendererID).forEach(root => {
278 + currentRootID = getFiberID(getPrimaryFiber(root.current));
279 + unmountFiberChildrenRecursively(root.current);
280 + recordUnmount(root.current, false);
281 + currentRootID = -1;
282 + });
283 +
284 + hideElementsWithTypes = filterPreferences.hideElementsWithTypes;
285 + hideElementsWithDisplayNames =
286 + filterPreferences.hideElementsWithDisplayNames;
287 + hideElementsWithPaths = filterPreferences.hideElementsWithPaths;
288 +
289 + // Recursively re-mount all roots with new filter criteria applied.
290 + hook.getFiberRoots(rendererID).forEach(root => {
291 + currentRootID = getFiberID(getPrimaryFiber(root.current));
292 + mountFiberRecursively(root.current, null);
293 + flushPendingEvents(root);
294 + currentRootID = -1;
295 + });
296 + }
297 +
298 // NOTICE Keep in sync with getDataForFiber()
299 function shouldFilterFiber(fiber: Fiber): boolean {
300 const { tag } = fiber;
@@ -2288,5 +2313,6 @@ export function attach(
2313 setTrackedPath,
2314 startProfiling,
2315 stopProfiling,
2316 + updateFilterPreferences,
2317 };
2318 }
src/backend/types.js
+2 -1
@@ -1,6 +1,6 @@
1 // @flow
2
3 -import type { ElementType } from 'src/types';
3 +import type { ElementType, FilterPreferences } from 'src/types';
4 import type { InspectedElement } from 'src/devtools/views/Components/types';
5
6 type BundleType =
@@ -139,6 +139,7 @@ export type RendererInterface = {
139 setTrackedPath: (path: Array<PathFrame> | null) => void,
140 startProfiling: () => void,
141 stopProfiling: () => void,
142 + updateFilterPreferences: (filterPreferences: FilterPreferences) => void,
143 };
144
145 export type Handler = (data: any) => void;
src/devtools/store.js
+3 -1
@@ -247,8 +247,10 @@ export default class Store extends EventEmitter {
247
248 saveFilterPreferences(value);
249
250 - // TODO (filter) Dump all nodes, update renderer preferences, and re-initialize tree.
250 + // TODO (filter) Dump all nodes, update renderer preferences, and re-initialize tree.
251 // TODO (filter) Invariant check that we aren't profiling.
252 + // TODO (filter) Flushing every time a filter setting is changed is too expensive. We probably need an explitit configm
253 + this._bridge.send('updateFilterPreferences', value);
254
255 this.emit('filterPreferences');
256 }