Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added trace updates feature (DOM only) #16989

Merged
merged 12 commits into from
Oct 3, 2019
2 changes: 1 addition & 1 deletion packages/react-devtools-core/src/backend.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export function connectToDevTools(options: ?ConnectOptions) {
}

if (bridge !== null) {
bridge.emit('shutdown');
bridge.shutdown();
}

scheduleRetry();
Expand Down
4 changes: 4 additions & 0 deletions packages/react-devtools-extensions/src/backend.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ function setup(hook) {

initBackend(hook, agent, window);

// Let the frontend know that the backend has attached listeners and is ready for messages.
// This covers the case of of syncing saved values after reloading/navigating while DevTools remain open.
bridge.send('extensionBackendInitialized');

// Setup React Native style editor if a renderer like react-native-web has injected it.
if (hook.resolveRNStyle) {
setupNativeStyleEditor(
Expand Down
12 changes: 12 additions & 0 deletions packages/react-devtools-extensions/src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
getBrowserName,
getBrowserTheme,
} from './utils';
import {LOCAL_STORAGE_TRACE_UPDATES_ENABLED_KEY} from 'react-devtools-shared/src/constants';
import {
getSavedComponentFilters,
getAppendComponentStack,
Expand Down Expand Up @@ -125,10 +126,21 @@ function createPanelIfReactLoaded() {
profilingData = store.profilerStore.profilingData;
}

bridge.addListener('extensionBackendInitialized', () => {
// Initialize the renderer's trace-updates setting.
// This handles the case of navigating to a new page after the DevTools have already been shown.
bridge.send(
'setTraceUpdatesEnabled',
localStorageGetItem(LOCAL_STORAGE_TRACE_UPDATES_ENABLED_KEY) ===
'true',
);
});

store = new Store(bridge, {
isProfiling,
supportsReloadAndProfile: isChrome,
supportsProfiling,
supportsTraceUpdates: true,
});
store.profilerStore.profilingData = profilingData;

Expand Down
2 changes: 1 addition & 1 deletion packages/react-devtools-inline/src/frontend.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function initialize(
},
});

const store: Store = new Store(bridge);
const store: Store = new Store(bridge, {supportsTraceUpdates: true});

const ForwardRef = forwardRef<Props, mixed>((props, ref) => (
<DevTools ref={ref} bridge={bridge} store={store} {...props} />
Expand Down
27 changes: 27 additions & 0 deletions packages/react-devtools-shared/src/backend/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ import {
sessionStorageSetItem,
} from 'react-devtools-shared/src/storage';
import setupHighlighter from './views/Highlighter';
import {
initialize as setupTraceUpdates,
toggleEnabled as setTraceUpdatesEnabled,
} from './views/TraceUpdates';
import {patch as patchConsole, unpatch as unpatchConsole} from './console';

import type {BackendBridge} from 'react-devtools-shared/src/bridge';
Expand Down Expand Up @@ -87,13 +91,15 @@ export default class Agent extends EventEmitter<{|
hideNativeHighlight: [],
showNativeHighlight: [NativeType],
shutdown: [],
traceUpdates: [Set<NativeType>],
|}> {
_bridge: BackendBridge;
_isProfiling: boolean = false;
_recordChangeDescriptions: boolean = false;
_rendererInterfaces: {[key: RendererID]: RendererInterface} = {};
_persistedSelection: PersistedSelection | null = null;
_persistedSelectionMatch: PathMatch | null = null;
_traceUpdatesEnabled: boolean = false;

constructor(bridge: BackendBridge) {
super();
Expand Down Expand Up @@ -131,6 +137,7 @@ export default class Agent extends EventEmitter<{|
bridge.addListener('overrideState', this.overrideState);
bridge.addListener('overrideSuspense', this.overrideSuspense);
bridge.addListener('reloadAndProfile', this.reloadAndProfile);
bridge.addListener('setTraceUpdatesEnabled', this.setTraceUpdatesEnabled);
bridge.addListener('startProfiling', this.startProfiling);
bridge.addListener('stopProfiling', this.stopProfiling);
bridge.addListener(
Expand Down Expand Up @@ -159,6 +166,7 @@ export default class Agent extends EventEmitter<{|
bridge.send('isBackendStorageAPISupported', isBackendStorageAPISupported);

setupHighlighter(bridge, this);
setupTraceUpdates(this);
}

get rendererInterfaces(): {[key: RendererID]: RendererInterface} {
Expand Down Expand Up @@ -340,6 +348,8 @@ export default class Agent extends EventEmitter<{|
rendererInterface.startProfiling(this._recordChangeDescriptions);
}

rendererInterface.setTraceUpdatesEnabled(this._traceUpdatesEnabled);

// When the renderer is attached, we need to tell it whether
// we remember the previous selection that we'd like to restore.
// It'll start tracking mounts for matches to the last selection path.
Expand All @@ -349,6 +359,19 @@ export default class Agent extends EventEmitter<{|
}
}

setTraceUpdatesEnabled = (traceUpdatesEnabled: boolean) => {
this._traceUpdatesEnabled = traceUpdatesEnabled;

setTraceUpdatesEnabled(traceUpdatesEnabled);

for (let rendererID in this._rendererInterfaces) {
const renderer = ((this._rendererInterfaces[
(rendererID: any)
]: any): RendererInterface);
renderer.setTraceUpdatesEnabled(traceUpdatesEnabled);
}
};

syncSelectionFromNativeElementsPanel = () => {
const target = window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0;
if (target == null) {
Expand Down Expand Up @@ -416,6 +439,10 @@ export default class Agent extends EventEmitter<{|
}
};

onTraceUpdates = (nodes: Set<NativeType>) => {
this.emit('traceUpdates', nodes);
};

onHookOperations = (operations: Array<number>) => {
if (__DEBUG__) {
debug('onHookOperations', operations);
Expand Down
1 change: 1 addition & 0 deletions packages/react-devtools-shared/src/backend/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export function initBackend(
}),

hook.sub('operations', agent.onHookOperations),
hook.sub('traceUpdates', agent.onTraceUpdates),

// TODO Add additional subscriptions required for profiling mode
];
Expand Down
5 changes: 5 additions & 0 deletions packages/react-devtools-shared/src/backend/legacy/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,10 @@ export function attach(
// Not implemented.
}

function setTraceUpdatesEnabled(enabled: boolean) {
// Not implemented.
}

function setTrackedPath(path: Array<PathFrame> | null) {
// Not implemented.
}
Expand Down Expand Up @@ -945,6 +949,7 @@ export function attach(
setInHook,
setInProps,
setInState,
setTraceUpdatesEnabled,
setTrackedPath,
startProfiling,
stopProfiling,
Expand Down
Loading