mirror of
https://github.com/microsoft/playwright.git
synced 2024-10-26 21:33:38 +03:00
feat(trace-viewer) add copy to clipboard on the Source > Stacktrace tab (#31394)
This commit is contained in:
parent
9dc7e40084
commit
262586a46a
@ -18,7 +18,8 @@ import * as React from 'react';
|
|||||||
|
|
||||||
export const CopyToClipboard: React.FunctionComponent<{
|
export const CopyToClipboard: React.FunctionComponent<{
|
||||||
value: string,
|
value: string,
|
||||||
}> = ({ value }) => {
|
description?: string,
|
||||||
|
}> = ({ value, description }) => {
|
||||||
const [iconClassName, setIconClassName] = React.useState('codicon-clippy');
|
const [iconClassName, setIconClassName] = React.useState('codicon-clippy');
|
||||||
|
|
||||||
const handleCopy = React.useCallback(() => {
|
const handleCopy = React.useCallback(() => {
|
||||||
@ -32,5 +33,5 @@ export const CopyToClipboard: React.FunctionComponent<{
|
|||||||
});
|
});
|
||||||
|
|
||||||
}, [value]);
|
}, [value]);
|
||||||
return <span className={`copy-icon codicon ${iconClassName}`} onClick={handleCopy}/>;
|
return <span title={description ? description : 'Copy'} className={`copy-icon codicon ${iconClassName}`} onClick={handleCopy}/>;
|
||||||
};
|
};
|
@ -31,3 +31,13 @@
|
|||||||
box-shadow: var(--vscode-scrollbar-shadow) 0 6px 6px -6px;
|
box-shadow: var(--vscode-scrollbar-shadow) 0 6px 6px -6px;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.source-tab-file-name .copy-icon.codicon {
|
||||||
|
display: block;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.source-copy-to-clipboard {
|
||||||
|
display: block;
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
@ -23,6 +23,7 @@ import { CodeMirrorWrapper } from '@web/components/codeMirrorWrapper';
|
|||||||
import type { SourceHighlight } from '@web/components/codeMirrorWrapper';
|
import type { SourceHighlight } from '@web/components/codeMirrorWrapper';
|
||||||
import type { SourceLocation, SourceModel } from './modelUtil';
|
import type { SourceLocation, SourceModel } from './modelUtil';
|
||||||
import type { StackFrame } from '@protocol/channels';
|
import type { StackFrame } from '@protocol/channels';
|
||||||
|
import { CopyToClipboard } from './copyToClipboard';
|
||||||
|
|
||||||
export const SourceTab: React.FunctionComponent<{
|
export const SourceTab: React.FunctionComponent<{
|
||||||
stack: StackFrame[] | undefined,
|
stack: StackFrame[] | undefined,
|
||||||
@ -82,7 +83,14 @@ export const SourceTab: React.FunctionComponent<{
|
|||||||
|
|
||||||
return <SplitView sidebarSize={200} orientation={stackFrameLocation === 'bottom' ? 'vertical' : 'horizontal'} sidebarHidden={!showStackFrames}>
|
return <SplitView sidebarSize={200} orientation={stackFrameLocation === 'bottom' ? 'vertical' : 'horizontal'} sidebarHidden={!showStackFrames}>
|
||||||
<div className='vbox' data-testid='source-code'>
|
<div className='vbox' data-testid='source-code'>
|
||||||
{fileName && <div className='source-tab-file-name'>{fileName}</div>}
|
{fileName && (
|
||||||
|
<div className='source-tab-file-name'>
|
||||||
|
{fileName}
|
||||||
|
<span className='source-copy-to-clipboard'>
|
||||||
|
<CopyToClipboard description='Copy filename' value={getFileName(fileName, targetLine)}/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
<CodeMirrorWrapper text={source.content || ''} language='javascript' highlight={highlight} revealLine={targetLine} readOnly={true} lineNumbers={true} />
|
<CodeMirrorWrapper text={source.content || ''} language='javascript' highlight={highlight} revealLine={targetLine} readOnly={true} lineNumbers={true} />
|
||||||
</div>
|
</div>
|
||||||
<StackTraceView stack={stack} selectedFrame={selectedFrame} setSelectedFrame={setSelectedFrame} />
|
<StackTraceView stack={stack} selectedFrame={selectedFrame} setSelectedFrame={setSelectedFrame} />
|
||||||
@ -100,3 +108,11 @@ export async function calculateSha1(text: string): Promise<string> {
|
|||||||
}
|
}
|
||||||
return hexCodes.join('');
|
return hexCodes.join('');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getFileName(fullPath?: string, lineNum?: number): string {
|
||||||
|
if (!fullPath)
|
||||||
|
return '';
|
||||||
|
const pathSep = fullPath?.includes('/') ? '/' : '\\';
|
||||||
|
const fileName = fullPath?.split(pathSep).pop() ?? '';
|
||||||
|
return lineNum ? `${fileName}:${lineNum}` : fileName;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user