Sync DevTools Elements and Components tabs

This commit is contained in:
Dan Abramov
2019-04-08 20:41:01 +01:00
parent ab89d6500f
commit 4a301bd0e0
2 changed files with 57 additions and 2 deletions
+34 -2
View File
@@ -162,10 +162,43 @@ function createPanelIfReactLoaded() {
container._hasInitialHTMLBeenCleared = true;
}
function maybeSetReactSelectionFromBrowser() {
// When the user chooses a different node in the browser Elements tab,
// copy it over to the hook object so that we can sync the selection.
chrome.devtools.inspectedWindow.eval(
// Don't reset selection if it didn't change in Elements tab.
'(window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0 !== $0)' +
' ? (window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0 = $0, true)' +
' : false',
(didChangeSelection, error) => {
if (error) {
console.error(error);
} else if (didChangeSelection) {
bridge.send('syncSelectionFromBrowserTools');
}
}
);
}
function maybeSetBrowserSelectionFromReact() {
chrome.devtools.inspectedWindow.eval(
'(window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0 != null)' +
' ? (inspect(window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0), true)' +
' : false',
(didChangeSelection, error) => {
if (error) {
console.error(error);
}
}
);
}
let currentPanel = null;
chrome.devtools.panels.create('⚛ Components', '', 'panel.html', panel => {
panel.onShown.addListener(panel => {
maybeSetReactSelectionFromBrowser();
if (currentPanel === panel) {
return;
}
@@ -178,10 +211,9 @@ function createPanelIfReactLoaded() {
render('components');
panel.injectStyles(cloneStyleTags);
}
// TODO: When the user switches to the panel, check for an Elements tab selection.
});
panel.onHidden.addListener(() => {
maybeSetBrowserSelectionFromReact();
// TODO: Stop highlighting and stuff.
});
});
+23
View File
@@ -87,6 +87,10 @@ export default class Agent extends EventEmitter {
bridge.addListener('startProfiling', this.startProfiling);
bridge.addListener('stopInspectingDOM', this.stopInspectingDOM);
bridge.addListener('stopProfiling', this.stopProfiling);
bridge.addListener(
'syncSelectionFromBrowserTools',
this.syncSelectionFromBrowserTools
);
bridge.addListener('shutdown', this.shutdown);
bridge.addListener('viewElementSource', this.viewElementSource);
@@ -292,6 +296,14 @@ export default class Agent extends EventEmitter {
if (renderer == null) {
console.warn(`Invalid renderer id "${rendererID}" for element "${id}"`);
} else {
// Update the active DOM node on the global hook object.
// The content script will read this to update window.$0
// when we switch tabs.
let node: HTMLElement | null = null;
node = ((renderer.findNativeByFiberID(id): any): HTMLElement);
if (node !== null) {
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0 = node;
}
this._bridge.send('selectElement', renderer.selectElement(id));
}
};
@@ -362,6 +374,17 @@ export default class Agent extends EventEmitter {
}
}
syncSelectionFromBrowserTools = () => {
const target = window.__REACT_DEVTOOLS_GLOBAL_HOOK__.$0;
if (target == null) {
return;
}
const id = this.getIDForNode(target);
if (id !== null) {
this._bridge.send('selectFiber', id);
}
};
shutdown = () => {
this.emit('shutdown');
};