Skip to content

Commit 0784ec0

Browse files
authored
chore: apply formatting to console messages (#11735)
* chore: apply formatting to console messages * sanitize * fix
1 parent 152961a commit 0784ec0

File tree

3 files changed

+124
-14
lines changed

3 files changed

+124
-14
lines changed

sites/svelte-5-preview/src/lib/Output/console/ConsoleLine.svelte

Lines changed: 119 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,101 @@
44
55
/** @type {import('./console').Log} */
66
export let log;
7-
export let depth = 1;
7+
export let depth = 0;
88
99
function toggle_group_collapse() {
1010
log.collapsed = !log.collapsed;
1111
}
12+
13+
let style;
14+
15+
/** @param {string} text */
16+
function sanitize_css(text) {
17+
style ??= document.createElement('span').style;
18+
style.cssText = text;
19+
20+
for (const key in style) {
21+
const value = style[key];
22+
if (typeof value === 'string' && value.includes('url(')) {
23+
style[key] = value.replace(/url\([^)]+\)/g, '');
24+
}
25+
}
26+
27+
style.position = 'static';
28+
return style.cssText;
29+
}
30+
31+
/** @param {any[]} [args] */
32+
function format_args(args = []) {
33+
if (args.length === 0) return args;
34+
35+
if (typeof args[0] !== 'string') {
36+
return args.map((value) => ({ type: 'value', value }));
37+
}
38+
39+
args = args.slice();
40+
41+
const parts = args.shift().split(/(%[sdifoOc])/g);
42+
43+
const formatted = [];
44+
45+
if (parts[0] !== '') {
46+
formatted.push({ type: 'value', value: parts[0] });
47+
}
48+
49+
for (let i = 1; i < parts.length; i += 2) {
50+
const type = parts[i];
51+
const next = parts[i + 1];
52+
const value = args.shift();
53+
54+
switch (type) {
55+
case '%s':
56+
formatted.push({ type: 'value', value: String(value), formatted: true });
57+
break;
58+
59+
case '%d':
60+
case '%i':
61+
formatted.push({
62+
type: 'value',
63+
value: typeof value === 'symbol' ? NaN : parseInt(value, 10),
64+
formatted: true
65+
});
66+
break;
67+
68+
case '%f':
69+
formatted.push({
70+
type: 'value',
71+
value: typeof value === 'symbol' ? NaN : parseFloat(value),
72+
formatted: true
73+
});
74+
break;
75+
76+
case '%o':
77+
case '%O':
78+
formatted.push({ type: 'value', value, formatted: true });
79+
break;
80+
81+
case '%c':
82+
formatted.push({
83+
type: 'style',
84+
style: sanitize_css(String(value)),
85+
value: next,
86+
formatted: true
87+
});
88+
break;
89+
}
90+
91+
if (type !== '%c' && next !== '') {
92+
formatted.push({ type: 'value', value: next, formatted: true });
93+
}
94+
}
95+
96+
for (const value of args) {
97+
formatted.push({ type: 'value', value });
98+
}
99+
100+
return formatted;
101+
}
12102
</script>
13103
14104
{#if log.command === 'table'}
@@ -39,9 +129,18 @@
39129
{:else if log.command === 'table'}
40130
<JSONNode value={log.data} />
41131
{:else}
42-
{#each log.args ?? [] as arg}
43-
<JSONNode value={arg} defaultExpandedLevel={log.expanded ? 1 : 0} />
44-
{/each}
132+
<span class="values">
133+
{#each format_args(log.args) as part}
134+
<!-- we need to do some funky stuff to make whitespace behave as it does in devtools -->
135+
{#if !part.formatted}
136+
{' '}
137+
{/if}{#if part.type === 'value'}
138+
<JSONNode value={part.value} defaultExpandedLevel={log.expanded ? 1 : 0} />
139+
{:else}
140+
<span class="styled" style={part.style}>{part.value}</span>
141+
{/if}
142+
{/each}
143+
</span>
45144
{/if}
46145
</div>
47146
@@ -54,7 +153,7 @@
54153
</div>
55154
{/if}
56155
57-
{#each new Array(depth - 1) as _, idx}
156+
{#each new Array(depth) as _, idx}
58157
<div class="outline" style="left: {idx * 15 + 15}px"></div>
59158
{/each}
60159
</div>
@@ -103,24 +202,29 @@
103202
}
104203
105204
.log {
106-
padding: 5px 10px 5px var(--indent);
205+
padding: 0.5rem 1rem 0.5rem calc(1rem + var(--indent));
107206
display: flex;
207+
gap: 1rem;
108208
width: 100%;
109-
font-size: 12px;
209+
font-size: 1.2rem;
110210
font-family: var(--sk-font-mono);
111211
align-items: center;
112212
}
113213
114214
.log.expandable {
115215
cursor: pointer;
116-
padding-left: calc(var(--indent) + 1em);
216+
}
217+
218+
.values {
219+
display: block;
220+
flex: 1;
117221
}
118222
119223
.stack {
120224
display: grid;
121225
grid-template-columns: minmax(0, auto) minmax(auto, 1fr);
122226
grid-gap: 0 2rem;
123-
font-size: 12px;
227+
font-size: 1.2rem;
124228
font-family: var(--sk-font-mono);
125229
margin: 0 1rem 0.4rem calc(1em + var(--indent));
126230
overflow: hidden;
@@ -172,14 +276,17 @@
172276
}
173277
174278
.arrow {
175-
position: absolute;
176279
font-size: 0.9rem;
177280
transition: 150ms;
178281
transform-origin: 50% 50%;
179-
transform: translateX(-1.2rem) translateY(-1px);
282+
transform: translateY(-1px);
180283
}
181284
182285
.arrow.expand {
183-
transform: translateX(-1.2rem) translateY(0px) rotateZ(90deg);
286+
transform: translateY(0px) rotateZ(90deg);
287+
}
288+
289+
.styled {
290+
white-space: pre-wrap;
184291
}
185292
</style>

sites/svelte-5-preview/src/lib/Output/console/console.d.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ export type Log = {
66
expanded?: boolean;
77
count?: number;
88
logs?: Log[];
9-
stack?: string;
9+
stack?: Array<{
10+
label?: string;
11+
location?: string;
12+
}>;
1013
data?: any;
1114
columns?: string[];
1215
};

sites/svelte-5-preview/src/lib/Output/srcdoc/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@
251251
},
252252
trace: (...args) => {
253253
log('info', {
254-
args: args.length === 0 ? 'console.trace' : args,
254+
args: args.length === 0 ? ['console.trace'] : args,
255255
stack: stack('trace'),
256256
collapsed: false
257257
});

0 commit comments

Comments
 (0)