Skip to content

Commit 0fd15c3

Browse files
committed
util: add %c to ANSI transform for console.log()
1 parent 6a2d6df commit 0fd15c3

File tree

6 files changed

+568
-9
lines changed

6 files changed

+568
-9
lines changed

doc/api/console.md

+5-4
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,11 @@ changes:
118118
streams. **Default:** `true`.
119119
* `colorMode` {boolean|string} Set color support for this `Console` instance.
120120
Setting to `true` enables coloring while inspecting values. Setting to
121-
`false` disables coloring while inspecting values. Setting to
122-
`'auto'` makes color support depend on the value of the `isTTY` property
123-
and the value returned by `getColorDepth()` on the respective stream. This
124-
option can not be used, if `inspectOptions.colors` is set as well.
121+
`false` disables coloring while inspecting values as well as disabling `%c`
122+
CSS color effects. Setting to `'auto'` makes color support depend on the
123+
value of the `isTTY` property and the value returned by `getColorDepth()` on
124+
the respective stream. This option can not be used, if
125+
`inspectOptions.colors` is set as well.
125126
**Default:** `'auto'`.
126127
* `inspectOptions` {Object} Specifies options that are passed along to
127128
[`util.inspect()`][].

doc/api/util.md

+7-1
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,13 @@ corresponding argument. Supported specifiers are:
302302
* `%O`: `Object`. A string representation of an object with generic JavaScript
303303
object formatting. Similar to `util.inspect()` without options. This will show
304304
the full object not including non-enumerable properties and proxies.
305-
* `%c`: `CSS`. This specifier is ignored and will skip any CSS passed in.
305+
* `%c`: `CSS`. Will parse basic CSS from the substitution subject like
306+
`color: red` into ANSI color codes. These codes will then be placed where the
307+
`%c` specifier is. Supported CSS properties are `color`, `background-color`,
308+
`font-weight`, `font-style`, `text-decoration`, `text-decoration-color`, and
309+
`text-decoration-line`. Unsupported CSS properties are ignored. An empty
310+
`%c` CSS string substitution will become an ANSI style reset. If color is
311+
disabled, `%c` is ignored.
306312
* `%%`: single percent sign (`'%'`). This does not consume an argument.
307313
* Returns: {string} The formatted string
308314

lib/internal/util/inspect.js

+23-4
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ const {
2626
FunctionPrototypeCall,
2727
FunctionPrototypeToString,
2828
JSONStringify,
29-
MapPrototypeEntries,
3029
MapPrototypeGetSize,
30+
MapPrototypeEntries,
3131
MathFloor,
3232
MathMax,
3333
MathMin,
@@ -158,6 +158,8 @@ const {
158158
kValidateObjectAllowArray,
159159
} = require('internal/validators');
160160

161+
const { parseCss, cssToAnsi } = require('internal/util/inspect_colors');
162+
161163
let hexSlice;
162164
let internalUrl;
163165

@@ -2194,6 +2196,8 @@ function formatWithOptionsInternal(inspectOptions, args) {
21942196
}
21952197
let tempStr;
21962198
let lastPos = 0;
2199+
let usedStyle = false;
2200+
let prevCss = null;
21972201

21982202
for (let i = 0; i < first.length - 1; i++) {
21992203
if (StringPrototypeCharCodeAt(first, i) === 37) { // '%'
@@ -2267,10 +2271,22 @@ function formatWithOptionsInternal(inspectOptions, args) {
22672271
}
22682272
break;
22692273
}
2270-
case 99: // 'c'
2271-
a += 1;
2272-
tempStr = '';
2274+
case 99: { // 'c'
2275+
// Inspired by Deno's handling of '%c'.
2276+
// https://github.com/denoland/deno/blob/ece2a3de5b19588160634452638aa656218853c5/ext/console/01_console.js#L3115
2277+
const value = args[++a];
2278+
if (inspectOptions?.colors) {
2279+
const css = parseCss(value);
2280+
tempStr = cssToAnsi(css, prevCss);
2281+
if (tempStr !== '') {
2282+
usedStyle = true;
2283+
prevCss = css;
2284+
}
2285+
} else {
2286+
tempStr = '';
2287+
}
22732288
break;
2289+
}
22742290
case 37: // '%'
22752291
str += StringPrototypeSlice(first, lastPos, i);
22762292
lastPos = i + 1;
@@ -2296,6 +2312,9 @@ function formatWithOptionsInternal(inspectOptions, args) {
22962312
str += StringPrototypeSlice(first, lastPos);
22972313
}
22982314
}
2315+
if (usedStyle) {
2316+
str += '\x1b[0m';
2317+
}
22992318
}
23002319

23012320
while (a < args.length) {

0 commit comments

Comments
 (0)