fix(webapp): avoid mutating render inputs
This commit is contained in:
@@ -221,35 +221,35 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
|
||||
const [modalCopied, setModalCopied] = useState(false);
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [isWrapped, setIsWrapped] = useState(wrap);
|
||||
const normalizedCode = code?.trim() ?? "";
|
||||
|
||||
const onCopied = useCallback(
|
||||
(event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
navigator.clipboard.writeText(code);
|
||||
navigator.clipboard.writeText(normalizedCode);
|
||||
setCopied(true);
|
||||
setTimeout(() => {
|
||||
setCopied(false);
|
||||
}, 1500);
|
||||
},
|
||||
[code]
|
||||
[normalizedCode]
|
||||
);
|
||||
|
||||
const onModalCopied = useCallback(
|
||||
(event: React.MouseEvent<HTMLButtonElement>) => {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
navigator.clipboard.writeText(code);
|
||||
navigator.clipboard.writeText(normalizedCode);
|
||||
setModalCopied(true);
|
||||
setTimeout(() => {
|
||||
setModalCopied(false);
|
||||
}, 1500);
|
||||
},
|
||||
[code]
|
||||
[normalizedCode]
|
||||
);
|
||||
|
||||
code = code?.trim() ?? "";
|
||||
const lineCount = code.split("\n").length;
|
||||
const lineCount = normalizedCode.split("\n").length;
|
||||
const maxLineWidth = lineCount.toString().length;
|
||||
let maxHeight: string | undefined = undefined;
|
||||
if (maxLines && lineCount > maxLines) {
|
||||
@@ -345,7 +345,7 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
|
||||
{shouldHighlight ? (
|
||||
<HighlightCode
|
||||
theme={theme}
|
||||
code={code}
|
||||
code={normalizedCode}
|
||||
language={language}
|
||||
showLineNumbers={showLineNumbers}
|
||||
highlightLines={highlightLines}
|
||||
@@ -373,7 +373,7 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
|
||||
)}
|
||||
dir="ltr"
|
||||
>
|
||||
{highlightSearchText(code, searchTerm)}
|
||||
{highlightSearchText(normalizedCode, searchTerm)}
|
||||
</pre>
|
||||
</div>
|
||||
)}
|
||||
@@ -400,7 +400,7 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
|
||||
{shouldHighlight ? (
|
||||
<HighlightCode
|
||||
theme={theme}
|
||||
code={code}
|
||||
code={normalizedCode}
|
||||
language={language}
|
||||
showLineNumbers={showLineNumbers}
|
||||
highlightLines={highlightLines}
|
||||
@@ -415,7 +415,7 @@ export const CodeBlock = forwardRef<HTMLDivElement, CodeBlockProps>(
|
||||
className="overflow-auto px-3 py-3 scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control"
|
||||
>
|
||||
<pre className="relative mr-2 p-2 font-mono text-base leading-relaxed" dir="ltr">
|
||||
{highlightSearchText(code, searchTerm)}
|
||||
{highlightSearchText(normalizedCode, searchTerm)}
|
||||
</pre>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -187,7 +187,7 @@ export function ReportFindingLine({
|
||||
* entities mono, verdict phrases bright and medium, everything else dimmed.
|
||||
* Colour stays reserved for severity, so emphasis here is weight only.
|
||||
*/
|
||||
const QUANTITY_RE = /~?\d[\d,.]*\s?(?:%|×|\/min|ms\b|s\b|min\b|h\b)?/g;
|
||||
const QUANTITY_RE = /~?\d[\d,.]*\s?(?:%|×|\/min|ms\b|s\b|min\b|h\b)?/;
|
||||
|
||||
const VERDICT_PHRASES = [
|
||||
"not your code",
|
||||
@@ -249,7 +249,6 @@ export function ReportProse({ text, entities }: { text: string; entities?: strin
|
||||
segments = splitBy(
|
||||
segments,
|
||||
(t) => {
|
||||
QUANTITY_RE.lastIndex = 0;
|
||||
const m = QUANTITY_RE.exec(t);
|
||||
return m && m[0].trim().length > 0 ? { start: m.index, end: m.index + m[0].length } : null;
|
||||
},
|
||||
|
||||
@@ -413,19 +413,20 @@ function SelectGroupedRenderer<TItem>({
|
||||
) => React.ReactNode;
|
||||
enableItemShortcuts: boolean;
|
||||
}) {
|
||||
let count = 0;
|
||||
return (
|
||||
<>
|
||||
{items.map((section, index) => {
|
||||
const previousItem = items.at(index - 1);
|
||||
count += previousItem ? previousItem.items.length : 0;
|
||||
const startIndex = items
|
||||
.slice(0, index)
|
||||
.reduce((count, previousSection) => count + previousSection.items.length, 0);
|
||||
|
||||
return (
|
||||
<Fragment key={index}>
|
||||
{children(section.items as ItemFromSection<TItem>[], {
|
||||
shortcutsEnabled: enableItemShortcuts,
|
||||
section: {
|
||||
title: section.title,
|
||||
startIndex: count - 1,
|
||||
startIndex,
|
||||
count: section.items.length,
|
||||
},
|
||||
})}
|
||||
|
||||
Reference in New Issue
Block a user