Merge branch 'inspect-log' of https://github.com/gaearon/react-devtools-experimental into gaearon-inspect-log

This commit is contained in:
Brian Vaughn
2019-04-08 10:41:58 -07:00
6 changed files with 99 additions and 11 deletions
+10
View File
@@ -75,6 +75,7 @@ export default class Agent extends EventEmitter {
bridge.addListener('getProfilingSummary', this.getProfilingSummary);
bridge.addListener('highlightElementInDOM', this.highlightElementInDOM);
bridge.addListener('inspectElement', this.inspectElement);
bridge.addListener('logElementToConsole', this.logElementToConsole);
bridge.addListener('overrideContext', this.overrideContext);
bridge.addListener('overrideHookState', this.overrideHookState);
bridge.addListener('overrideProps', this.overrideProps);
@@ -268,6 +269,15 @@ export default class Agent extends EventEmitter {
}
};
logElementToConsole = ({ id, rendererID }: InspectSelectParams) => {
const renderer = this._rendererInterfaces[rendererID];
if (renderer == null) {
console.warn(`Invalid renderer id "${rendererID}" for element "${id}"`);
} else {
renderer.logElementToConsole(id);
}
};
reloadAndProfile = () => {
localStorage.setItem(LOCAL_STORAGE_RELOAD_AND_PROFILE_KEY, 'true');
+58 -7
View File
@@ -1410,7 +1410,7 @@ export function attach(
}
}
function inspectElement(id: number): InspectedElement | null {
function inspectElementRaw(id: number): InspectedElement | null {
let fiber = idToFiberMap.get(id);
if (fiber == null) {
@@ -1491,7 +1491,7 @@ export function attach(
if (context !== null) {
// To simplify hydration and display logic for context, wrap in a value object.
// Otherwise simple values (e.g. strings, booleans) become harder to handle.
context = cleanForBridge({ value: context });
context = { value: context };
}
let owners = null;
@@ -1530,16 +1530,16 @@ export function attach(
// Can view component source location.
canViewSource,
displayName: getDataForFiber(fiber).displayName,
// Inspectable properties.
// TODO Review sanitization approach for the below inspectable values.
context,
hooks: usesHooks
? cleanForBridge(
inspectHooksOfFiber(fiber, (renderer.currentDispatcherRef: any))
)
? inspectHooksOfFiber(fiber, (renderer.currentDispatcherRef: any))
: null,
props: cleanForBridge(memoizedProps),
state: usesHooks ? null : cleanForBridge(memoizedState),
props: memoizedProps,
state: usesHooks ? null : memoizedState,
// List of owners
owners,
@@ -1549,6 +1549,56 @@ export function attach(
};
}
function inspectElement(id: number): InspectedElement | null {
let result = inspectElementRaw(id);
if (result === null) {
return null;
}
// TODO Review sanitization approach for the below inspectable values.
result.context = cleanForBridge(result.context);
result.hooks = cleanForBridge(result.hooks);
result.props = cleanForBridge(result.props);
result.state = cleanForBridge(result.state);
return result;
}
function logElementToConsole(id) {
const result = inspectElementRaw(id);
if (result === null) {
console.warn(`Could not find Fiber with id "${id}"`);
return;
}
const supportsGroup = typeof console.groupCollapsed === 'function';
const label =
'[Click to expand] <' + (result.displayName || 'Component') + ' />';
if (supportsGroup) {
console.groupCollapsed(label);
}
if (result.props !== null) {
console.log('Props:', result.props);
}
if (result.state !== null) {
console.log('State:', result.state);
}
if (result.hooks !== null) {
console.log('Hooks:', result.hooks);
}
const nativeNode = findNativeByFiberID(id);
if (nativeNode !== null) {
console.log('Node:', nativeNode);
}
if (window.chrome || /firefox/i.test(navigator.userAgent)) {
console.log(
'Right-click any value to save it as a global variable for further inspection.'
);
}
if (supportsGroup) {
console.groupEnd();
}
}
function setInHook(
id: number,
index: number,
@@ -1859,6 +1909,7 @@ export function attach(
handleCommitFiberRoot,
handleCommitFiberUnmount,
inspectElement,
logElementToConsole,
prepareViewElementSource,
overrideSuspense,
renderer,
+1
View File
@@ -106,6 +106,7 @@ export type RendererInterface = {
handleCommitFiberRoot: (fiber: Object) => void,
handleCommitFiberUnmount: (fiber: Object) => void,
inspectElement: (id: number) => InspectedElement | null,
logElementToConsole: (id: number) => void,
overrideSuspense: (id: number, forceFallback: boolean) => void,
prepareViewElementSource: (id: number) => void,
renderer: ReactRenderer | null,
+4
View File
@@ -12,6 +12,7 @@ export type IconType =
| 'export'
| 'filter'
| 'import'
| 'log-data'
| 'more'
| 'next'
| 'previous'
@@ -54,6 +55,9 @@ export default function ButtonIcon({ type }: Props) {
case 'import':
pathData = PATH_IMPORT;
break;
case 'log-data':
pathData = PATH_EXPORT; // TODO: real icon
break;
case 'more':
pathData = PATH_MORE;
break;
@@ -39,14 +39,14 @@ export default function SelectedElement(_: Props) {
const inspectedElement = useInspectedElement(selectedElementID);
const highlightElement = useCallback(() => {
if (element !== null && selectedElementID !== null) {
const rendererID =
store.getRendererIDForElement(selectedElementID) || null;
const id = selectedElementID;
if (element !== null && id !== null) {
const rendererID = store.getRendererIDForElement(id);
if (rendererID !== null) {
bridge.send('highlightElementInDOM', {
displayName: element.displayName,
hideAfterTimeout: true,
id: selectedElementID,
id,
rendererID,
scrollIntoView: true,
});
@@ -54,6 +54,19 @@ export default function SelectedElement(_: Props) {
}
}, [bridge, element, selectedElementID, store]);
const logElement = useCallback(() => {
const id = selectedElementID;
if (id !== null) {
const rendererID = store.getRendererIDForElement(id);
if (rendererID !== null) {
bridge.send('logElementToConsole', {
id,
rendererID,
});
}
}
}, [bridge, selectedElementID, store]);
const viewSource = useCallback(() => {
if (viewElementSource != null && selectedElementID !== null) {
viewElementSource(selectedElementID);
@@ -89,6 +102,13 @@ export default function SelectedElement(_: Props) {
>
<ButtonIcon type="view-dom" />
</Button>
<Button
className={styles.IconButton}
onClick={logElement}
title="Log this component data to the console"
>
<ButtonIcon type="log-data" />
</Button>
<Button
className={styles.IconButton}
disabled={!canViewSource}
+2
View File
@@ -58,6 +58,8 @@ export type InspectedElement = {|
// Location of component in source coude.
source: Object | null,
displayName: string | null,
|};
// TODO: Add profiling type