From e0db46ae145f9f838467e2534b8d58928688fd82 Mon Sep 17 00:00:00 2001 From: Pavel Feldman Date: Tue, 5 Sep 2023 17:29:07 -0700 Subject: [PATCH] chore: highlight ansi in browser messages as well (#26881) --- packages/trace-viewer/src/ui/consoleTab.tsx | 64 +++++++++++++-------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/packages/trace-viewer/src/ui/consoleTab.tsx b/packages/trace-viewer/src/ui/consoleTab.tsx index 4541903542..3dcfd4dbad 100644 --- a/packages/trace-viewer/src/ui/consoleTab.tsx +++ b/packages/trace-viewer/src/ui/consoleTab.tsx @@ -22,15 +22,16 @@ import { ListView } from '@web/components/listView'; import type { Boundaries } from '../geometry'; import { msToString } from '@web/uiUtils'; import { ansi2html } from '@web/ansi2html'; -import type * as trace from '@trace/trace'; import { PlaceholderPanel } from './placeholderPanel'; export type ConsoleEntry = { - browserMessage?: trace.ConsoleMessageTraceEvent['initializer'], + browserMessage?: { + body: JSX.Element[]; + location: string; + }, browserError?: channels.SerializedError; nodeMessage?: { - text?: string; - base64?: string; + html: string; }, isError: boolean; isWarning: boolean; @@ -54,12 +55,23 @@ export function useConsoleTabModel(model: modelUtil.MultiTraceModel | undefined, continue; if (event.method === 'console') { const { guid } = event.params.message; - entries.push({ - browserMessage: modelUtil.context(event).initializers[guid], - isError: modelUtil.context(event).initializers[guid]?.type === 'error', - isWarning: modelUtil.context(event).initializers[guid]?.type === 'warning', - timestamp: event.time, - }); + const browserMessage = modelUtil.context(event).initializers[guid]; + if (browserMessage) { + const body = browserMessage.args && browserMessage.args.length ? format(browserMessage.args) : formatAnsi(browserMessage.text); + const url = browserMessage.location.url; + const filename = url ? url.substring(url.lastIndexOf('/') + 1) : ''; + const location = `${filename}:${browserMessage.location.lineNumber}`; + + entries.push({ + browserMessage: { + body, + location, + }, + isError: modelUtil.context(event).initializers[guid]?.type === 'error', + isWarning: modelUtil.context(event).initializers[guid]?.type === 'warning', + timestamp: event.time, + }); + } } if (event.method === 'pageError') { entries.push({ @@ -71,11 +83,14 @@ export function useConsoleTabModel(model: modelUtil.MultiTraceModel | undefined, } } for (const event of model.stdio) { + let html = ''; + if (event.text) + html = ansi2html(event.text.trim()) || ''; + if (event.base64) + html = ansi2html(atob(event.base64).trim()) || ''; + entries.push({ - nodeMessage: { - text: event.text, - base64: event.base64, - }, + nodeMessage: { html }, isError: event.type === 'stderr', isWarning: false, timestamp: event.timestamp, @@ -119,11 +134,8 @@ export const ConsoleTab: React.FunctionComponent<{ const { browserMessage, browserError, nodeMessage } = entry; if (browserMessage) { - const text = browserMessage.args && browserMessage.args.length ? format(browserMessage.args) : browserMessage.text; - const url = browserMessage.location.url; - const filename = url ? url.substring(url.lastIndexOf('/') + 1) : ''; - locationText = `${filename}:${browserMessage.location.lineNumber}`; - messageBody = text; + locationText = browserMessage.location; + messageBody = browserMessage.body; } if (browserError) { @@ -136,11 +148,8 @@ export const ConsoleTab: React.FunctionComponent<{ } } - if (nodeMessage?.text) - messageInnerHTML = ansi2html(nodeMessage.text.trim()) || ''; - - if (nodeMessage?.base64) - messageInnerHTML = ansi2html(atob(nodeMessage.base64).trim()) || ''; + if (nodeMessage) + messageInnerHTML = nodeMessage.html; return
{timestampElement} @@ -157,7 +166,8 @@ export const ConsoleTab: React.FunctionComponent<{ function format(args: { preview: string, value: any }[]): JSX.Element[] { if (args.length === 1) - return [{args[0].preview}]; + return formatAnsi(args[0].preview); + const hasMessageFormat = typeof args[0].value === 'string' && args[0].value.includes('%'); const messageFormat = hasMessageFormat ? args[0].value as string : ''; const tail = hasMessageFormat ? args.slice(1) : args; @@ -203,6 +213,10 @@ function format(args: { preview: string, value: any }[]): JSX.Element[] { return formatted; } +function formatAnsi(text: string): JSX.Element[] { + return []; +} + function parseCSSStyle(cssFormat: string): Record { try { const styleObject: Record = {};