[DevTools] Add ignore-listed stack frame disclosure (#36828)
[DevTools] Add ignore-listed stack frame disclosure (#36828)
The diff introduces a new StackTraceGroup component that wraps stack trace displays and adds a toggle button for showing/hiding ignore-listed frames.
New imports
import { use, useContext, useState, useTransition } from 'react';
import FetchFileWithCachingContext from './FetchFileWithCachingContext';
import StackTraceView, { IgnoreListToggleButton } from './StackTraceView';
import Skeleton from './Skeleton';
import { symbolicateSourceWithCache } from 'react-devtools-shared/src/symbolicateSource';
import type { ReactStackTrace } from 'shared/ReactTypes';
import type { SourceMappedLocation } from 'react-devtools-shared/src/symbolicateSource';
New StackTraceGroup component
type StackTraceGroupProps = {
children: (showIgnoreList: boolean) => React.Node,
ioStack: null | ReactStackTrace,
asyncInfoStack: null | ReactStackTrace,
};
function StackTraceGroup({
children,
ioStack,
asyncInfoStack,
}: StackTraceGroupProps): React.Node {
const [showIgnoreList, setShowIgnoreList] = useState(false);
const fetchFileWithCaching = useContext(FetchFileWithCachingContext);
const ioStackHasIgnoredFrames =
ioStack !== null &&
ioStack.some(callSite => {
const [ , virtualURL, virtualLine, virtualColumn ] = callSite;
// symbolicated output is cached
const symbolicatedCallSite: null | SourceMappedLocation =
fetchFileWithCaching !== null
? use(
symbolicateSourceWithCache(
fetchFileWithCaching,
virtualURL,
virtualLine,
virtualColumn,
),
)
: null;
return symbolicatedCallSite !== null && symbolicatedCallSite.ignored;
});
const asyncInfoStackHasIgnoredFrames =
asyncInfoStack !== null &&
asyncInfoStack.some(callSite => {
const [ , virtualURL, virtualLine, virtualColumn ] = callSite;
// symbolicated output is cached
const symbolicatedCallSite: null | SourceMappedLocation =
fetchFileWithCaching !== null
? use(
symbolicateSourceWithCache(
fetchFileWithCaching,
virtualURL,
virtualLine,
virtualColumn,
),
)
: null;
return symbolicatedCallSite !== null && symbolicatedCallSite.ignored;
});
const hasIgnoredFrames =
ioStackHasIgnoredFrames || asyncInfoStackHasIgnoredFrames;
return (
<>
{children(showIgnoreList)}
{hasIgnoredFrames && (
<IgnoreListToggleButton
onClick={() => setShowIgnoreList(prev => !prev)}
showIgnoreList={showIgnoreList}
/>
)}
</>
);
}
Updated SuspendedByRow component
The SuspendedByRow component now wraps its stack trace content in a StackTraceGroup:
function SuspendedByRow({
bridge,
element,
// ...
}) {
// ...
{isOpen && (
<StackTraceGroup
ioStack={ioStack}
asyncInfoStack={asyncInfoStack}
>
{(showIgnoreList: boolean) => (
<>
{showIOStack && (
// IO stack trace view
)}
{ioOwner !== null &&
ioOwner.id !== inspectedElement.id &&
(showIOStack ||
!showAwaitStack ||
asyncOwner === null ||
ioOwner.id !== asyncOwner.id) ? (
// IO owner view
) : null}
{showAwaitStack ? (
<>
awaited at:
{asyncInfo.stack !== null &&
asyncInfo.stack.length > 0 && (
// Async stack trace view
)}
{asyncOwner !== null &&
asyncOwner.id !== inspectedElement.id ? (
// Async owner view
) : null}
</>
) : null}
</>
)}
</StackTraceGroup>
)}
}
0 commit comments
Comments
No comments yet. Start the discussion.