chore: apply formatting to console messages (#11735)

* chore: apply formatting to console messages

* sanitize

* fix
pull/11748/head
Rich Harris 2 months ago committed by GitHub
parent 152961a649
commit 0784ec0661
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -4,11 +4,101 @@
/** @type {import('./console').Log} */ /** @type {import('./console').Log} */
export let log; export let log;
export let depth = 1; export let depth = 0;
function toggle_group_collapse() { function toggle_group_collapse() {
log.collapsed = !log.collapsed; log.collapsed = !log.collapsed;
} }
let style;
/** @param {string} text */
function sanitize_css(text) {
style ??= document.createElement('span').style;
style.cssText = text;
for (const key in style) {
const value = style[key];
if (typeof value === 'string' && value.includes('url(')) {
style[key] = value.replace(/url\([^)]+\)/g, '');
}
}
style.position = 'static';
return style.cssText;
}
/** @param {any[]} [args] */
function format_args(args = []) {
if (args.length === 0) return args;
if (typeof args[0] !== 'string') {
return args.map((value) => ({ type: 'value', value }));
}
args = args.slice();
const parts = args.shift().split(/(%[sdifoOc])/g);
const formatted = [];
if (parts[0] !== '') {
formatted.push({ type: 'value', value: parts[0] });
}
for (let i = 1; i < parts.length; i += 2) {
const type = parts[i];
const next = parts[i + 1];
const value = args.shift();
switch (type) {
case '%s':
formatted.push({ type: 'value', value: String(value), formatted: true });
break;
case '%d':
case '%i':
formatted.push({
type: 'value',
value: typeof value === 'symbol' ? NaN : parseInt(value, 10),
formatted: true
});
break;
case '%f':
formatted.push({
type: 'value',
value: typeof value === 'symbol' ? NaN : parseFloat(value),
formatted: true
});
break;
case '%o':
case '%O':
formatted.push({ type: 'value', value, formatted: true });
break;
case '%c':
formatted.push({
type: 'style',
style: sanitize_css(String(value)),
value: next,
formatted: true
});
break;
}
if (type !== '%c' && next !== '') {
formatted.push({ type: 'value', value: next, formatted: true });
}
}
for (const value of args) {
formatted.push({ type: 'value', value });
}
return formatted;
}
</script> </script>
{#if log.command === 'table'} {#if log.command === 'table'}
@ -39,9 +129,18 @@
{:else if log.command === 'table'} {:else if log.command === 'table'}
<JSONNode value={log.data} /> <JSONNode value={log.data} />
{:else} {:else}
{#each log.args ?? [] as arg} <span class="values">
<JSONNode value={arg} defaultExpandedLevel={log.expanded ? 1 : 0} /> {#each format_args(log.args) as part}
{/each} <!-- we need to do some funky stuff to make whitespace behave as it does in devtools -->
{#if !part.formatted}
{' '}
{/if}{#if part.type === 'value'}
<JSONNode value={part.value} defaultExpandedLevel={log.expanded ? 1 : 0} />
{:else}
<span class="styled" style={part.style}>{part.value}</span>
{/if}
{/each}
</span>
{/if} {/if}
</div> </div>
@ -54,7 +153,7 @@
</div> </div>
{/if} {/if}
{#each new Array(depth - 1) as _, idx} {#each new Array(depth) as _, idx}
<div class="outline" style="left: {idx * 15 + 15}px"></div> <div class="outline" style="left: {idx * 15 + 15}px"></div>
{/each} {/each}
</div> </div>
@ -103,24 +202,29 @@
} }
.log { .log {
padding: 5px 10px 5px var(--indent); padding: 0.5rem 1rem 0.5rem calc(1rem + var(--indent));
display: flex; display: flex;
gap: 1rem;
width: 100%; width: 100%;
font-size: 12px; font-size: 1.2rem;
font-family: var(--sk-font-mono); font-family: var(--sk-font-mono);
align-items: center; align-items: center;
} }
.log.expandable { .log.expandable {
cursor: pointer; cursor: pointer;
padding-left: calc(var(--indent) + 1em); }
.values {
display: block;
flex: 1;
} }
.stack { .stack {
display: grid; display: grid;
grid-template-columns: minmax(0, auto) minmax(auto, 1fr); grid-template-columns: minmax(0, auto) minmax(auto, 1fr);
grid-gap: 0 2rem; grid-gap: 0 2rem;
font-size: 12px; font-size: 1.2rem;
font-family: var(--sk-font-mono); font-family: var(--sk-font-mono);
margin: 0 1rem 0.4rem calc(1em + var(--indent)); margin: 0 1rem 0.4rem calc(1em + var(--indent));
overflow: hidden; overflow: hidden;
@ -172,14 +276,17 @@
} }
.arrow { .arrow {
position: absolute;
font-size: 0.9rem; font-size: 0.9rem;
transition: 150ms; transition: 150ms;
transform-origin: 50% 50%; transform-origin: 50% 50%;
transform: translateX(-1.2rem) translateY(-1px); transform: translateY(-1px);
} }
.arrow.expand { .arrow.expand {
transform: translateX(-1.2rem) translateY(0px) rotateZ(90deg); transform: translateY(0px) rotateZ(90deg);
}
.styled {
white-space: pre-wrap;
} }
</style> </style>

@ -6,7 +6,10 @@ export type Log = {
expanded?: boolean; expanded?: boolean;
count?: number; count?: number;
logs?: Log[]; logs?: Log[];
stack?: string; stack?: Array<{
label?: string;
location?: string;
}>;
data?: any; data?: any;
columns?: string[]; columns?: string[];
}; };

@ -251,7 +251,7 @@
}, },
trace: (...args) => { trace: (...args) => {
log('info', { log('info', {
args: args.length === 0 ? 'console.trace' : args, args: args.length === 0 ? ['console.trace'] : args,
stack: stack('trace'), stack: stack('trace'),
collapsed: false collapsed: false
}); });

Loading…
Cancel
Save