mirror of
https://github.com/denoland/deno.git
synced 2025-01-18 03:44:05 -05:00
perf(cli/console): Don't add redundant ANSI codes (#7823)
This commit is contained in:
parent
f632b3b6e7
commit
72425810b8
2 changed files with 104 additions and 66 deletions
|
@ -1097,8 +1097,8 @@
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseCss(cssString) {
|
function getDefaultCss() {
|
||||||
const css = {
|
return {
|
||||||
backgroundColor: null,
|
backgroundColor: null,
|
||||||
color: null,
|
color: null,
|
||||||
fontWeight: null,
|
fontWeight: null,
|
||||||
|
@ -1106,6 +1106,10 @@
|
||||||
textDecorationColor: null,
|
textDecorationColor: null,
|
||||||
textDecorationLine: [],
|
textDecorationLine: [],
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseCss(cssString) {
|
||||||
|
const css = getDefaultCss();
|
||||||
|
|
||||||
const rawEntries = [];
|
const rawEntries = [];
|
||||||
let inValue = false;
|
let inValue = false;
|
||||||
|
@ -1160,12 +1164,12 @@
|
||||||
css.color = color;
|
css.color = color;
|
||||||
}
|
}
|
||||||
} else if (key == "font-weight") {
|
} else if (key == "font-weight") {
|
||||||
if (["normal", "bold"].includes(value)) {
|
if (value == "bold") {
|
||||||
css.fontWeight = value;
|
css.fontWeight = value;
|
||||||
}
|
}
|
||||||
} else if (key == "font-style") {
|
} else if (key == "font-style") {
|
||||||
if (["normal", "italic", "oblique", "oblique 14deg"].includes(value)) {
|
if (["italic", "oblique", "oblique 14deg"].includes(value)) {
|
||||||
css.fontStyle = value;
|
css.fontStyle = "italic";
|
||||||
}
|
}
|
||||||
} else if (key == "text-decoration-line") {
|
} else if (key == "text-decoration-line") {
|
||||||
css.textDecorationLine = [];
|
css.textDecorationLine = [];
|
||||||
|
@ -1196,51 +1200,82 @@
|
||||||
return css;
|
return css;
|
||||||
}
|
}
|
||||||
|
|
||||||
function cssToAnsi(css) {
|
function colorEquals(color1, color2) {
|
||||||
|
return color1?.[0] == color2?.[0] && color1?.[1] == color2?.[1] &&
|
||||||
|
color1?.[2] == color2?.[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
function cssToAnsi(css, prevCss = null) {
|
||||||
|
prevCss = prevCss ?? getDefaultCss();
|
||||||
let ansi = "";
|
let ansi = "";
|
||||||
|
if (!colorEquals(css.backgroundColor, prevCss.backgroundColor)) {
|
||||||
if (css.backgroundColor != null) {
|
if (css.backgroundColor != null) {
|
||||||
const [r, g, b] = css.backgroundColor;
|
const [r, g, b] = css.backgroundColor;
|
||||||
ansi += `\x1b[48;2;${r};${g};${b}m`;
|
ansi += `\x1b[48;2;${r};${g};${b}m`;
|
||||||
} else {
|
} else {
|
||||||
ansi += "\x1b[49m";
|
ansi += "\x1b[49m";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!colorEquals(css.color, prevCss.color)) {
|
||||||
if (css.color != null) {
|
if (css.color != null) {
|
||||||
const [r, g, b] = css.color;
|
const [r, g, b] = css.color;
|
||||||
ansi += `\x1b[38;2;${r};${g};${b}m`;
|
ansi += `\x1b[38;2;${r};${g};${b}m`;
|
||||||
} else {
|
} else {
|
||||||
ansi += "\x1b[39m";
|
ansi += "\x1b[39m";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (css.fontWeight != prevCss.fontWeight) {
|
||||||
if (css.fontWeight == "bold") {
|
if (css.fontWeight == "bold") {
|
||||||
ansi += `\x1b[1m`;
|
ansi += `\x1b[1m`;
|
||||||
} else {
|
} else {
|
||||||
ansi += "\x1b[22m";
|
ansi += "\x1b[22m";
|
||||||
}
|
}
|
||||||
if (["italic", "oblique"].includes(css.fontStyle)) {
|
}
|
||||||
|
if (css.fontStyle != prevCss.fontStyle) {
|
||||||
|
if (css.fontStyle == "italic") {
|
||||||
ansi += `\x1b[3m`;
|
ansi += `\x1b[3m`;
|
||||||
} else {
|
} else {
|
||||||
ansi += "\x1b[23m";
|
ansi += "\x1b[23m";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (!colorEquals(css.textDecorationColor, prevCss.textDecorationColor)) {
|
||||||
if (css.textDecorationColor != null) {
|
if (css.textDecorationColor != null) {
|
||||||
const [r, g, b] = css.textDecorationColor;
|
const [r, g, b] = css.textDecorationColor;
|
||||||
ansi += `\x1b[58;2;${r};${g};${b}m`;
|
ansi += `\x1b[58;2;${r};${g};${b}m`;
|
||||||
} else {
|
} else {
|
||||||
ansi += "\x1b[59m";
|
ansi += "\x1b[59m";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
css.textDecorationLine.includes("line-through") !=
|
||||||
|
prevCss.textDecorationLine.includes("line-through")
|
||||||
|
) {
|
||||||
if (css.textDecorationLine.includes("line-through")) {
|
if (css.textDecorationLine.includes("line-through")) {
|
||||||
ansi += "\x1b[9m";
|
ansi += "\x1b[9m";
|
||||||
} else {
|
} else {
|
||||||
ansi += "\x1b[29m";
|
ansi += "\x1b[29m";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
css.textDecorationLine.includes("overline") !=
|
||||||
|
prevCss.textDecorationLine.includes("overline")
|
||||||
|
) {
|
||||||
if (css.textDecorationLine.includes("overline")) {
|
if (css.textDecorationLine.includes("overline")) {
|
||||||
ansi += "\x1b[53m";
|
ansi += "\x1b[53m";
|
||||||
} else {
|
} else {
|
||||||
ansi += "\x1b[55m";
|
ansi += "\x1b[55m";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (
|
||||||
|
css.textDecorationLine.includes("underline") !=
|
||||||
|
prevCss.textDecorationLine.includes("underline")
|
||||||
|
) {
|
||||||
if (css.textDecorationLine.includes("underline")) {
|
if (css.textDecorationLine.includes("underline")) {
|
||||||
ansi += "\x1b[4m";
|
ansi += "\x1b[4m";
|
||||||
} else {
|
} else {
|
||||||
ansi += "\x1b[24m";
|
ansi += "\x1b[24m";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return ansi;
|
return ansi;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1257,6 +1292,7 @@
|
||||||
// have to append to `string` when a substitution occurs / at the end.
|
// have to append to `string` when a substitution occurs / at the end.
|
||||||
let appendedChars = 0;
|
let appendedChars = 0;
|
||||||
let usedStyle = false;
|
let usedStyle = false;
|
||||||
|
let prevCss = null;
|
||||||
for (let i = 0; i < first.length - 1; i++) {
|
for (let i = 0; i < first.length - 1; i++) {
|
||||||
if (first[i] == "%") {
|
if (first[i] == "%") {
|
||||||
const char = first[++i];
|
const char = first[++i];
|
||||||
|
@ -1293,9 +1329,15 @@
|
||||||
);
|
);
|
||||||
} else if (char == "c") {
|
} else if (char == "c") {
|
||||||
const value = args[a++];
|
const value = args[a++];
|
||||||
formattedArg = noColor ? "" : cssToAnsi(parseCss(value));
|
if (!noColor) {
|
||||||
|
const css = parseCss(value);
|
||||||
|
formattedArg = cssToAnsi(css, prevCss);
|
||||||
if (formattedArg != "") {
|
if (formattedArg != "") {
|
||||||
usedStyle = true;
|
usedStyle = true;
|
||||||
|
prevCss = css;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
formattedArg = "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,8 +57,8 @@ function parseCssColor(colorString: string): Css {
|
||||||
}
|
}
|
||||||
|
|
||||||
/** ANSI-fy the CSS, replace "\x1b" with "_". */
|
/** ANSI-fy the CSS, replace "\x1b" with "_". */
|
||||||
function cssToAnsiEsc(css: Css): string {
|
function cssToAnsiEsc(css: Css, prevCss: Css | null = null): string {
|
||||||
return cssToAnsi_(css).replaceAll("\x1b", "_");
|
return cssToAnsi_(css, prevCss).replaceAll("\x1b", "_");
|
||||||
}
|
}
|
||||||
|
|
||||||
// test cases from web-platform-tests
|
// test cases from web-platform-tests
|
||||||
|
@ -944,7 +944,7 @@ unitTest(function consoleParseCss(): void {
|
||||||
);
|
);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
parseCss("font-style: oblique"),
|
parseCss("font-style: oblique"),
|
||||||
{ ...DEFAULT_CSS, fontStyle: "oblique" },
|
{ ...DEFAULT_CSS, fontStyle: "italic" },
|
||||||
);
|
);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
parseCss("text-decoration-color: green"),
|
parseCss("text-decoration-color: green"),
|
||||||
|
@ -983,46 +983,42 @@ unitTest(function consoleParseCss(): void {
|
||||||
});
|
});
|
||||||
|
|
||||||
unitTest(function consoleCssToAnsi(): void {
|
unitTest(function consoleCssToAnsi(): void {
|
||||||
// TODO(nayeemrmn): Optimize these by accounting for the previous CSS.
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
cssToAnsiEsc({ ...DEFAULT_CSS, backgroundColor: [200, 201, 202] }),
|
cssToAnsiEsc({ ...DEFAULT_CSS, backgroundColor: [200, 201, 202] }),
|
||||||
"_[48;2;200;201;202m_[39m_[22m_[23m_[59m_[29m_[55m_[24m",
|
"_[48;2;200;201;202m",
|
||||||
);
|
);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
cssToAnsiEsc({ ...DEFAULT_CSS, color: [203, 204, 205] }),
|
cssToAnsiEsc({ ...DEFAULT_CSS, color: [203, 204, 205] }),
|
||||||
"_[49m_[38;2;203;204;205m_[22m_[23m_[59m_[29m_[55m_[24m",
|
"_[38;2;203;204;205m",
|
||||||
);
|
|
||||||
assertEquals(
|
|
||||||
cssToAnsiEsc({ ...DEFAULT_CSS, fontWeight: "bold" }),
|
|
||||||
"_[49m_[39m_[1m_[23m_[59m_[29m_[55m_[24m",
|
|
||||||
);
|
|
||||||
assertEquals(
|
|
||||||
cssToAnsiEsc({ ...DEFAULT_CSS, fontStyle: "italic" }),
|
|
||||||
"_[49m_[39m_[22m_[3m_[59m_[29m_[55m_[24m",
|
|
||||||
);
|
|
||||||
assertEquals(
|
|
||||||
cssToAnsiEsc({ ...DEFAULT_CSS, fontStyle: "oblique" }),
|
|
||||||
"_[49m_[39m_[22m_[3m_[59m_[29m_[55m_[24m",
|
|
||||||
);
|
);
|
||||||
|
assertEquals(cssToAnsiEsc({ ...DEFAULT_CSS, fontWeight: "bold" }), "_[1m");
|
||||||
|
assertEquals(cssToAnsiEsc({ ...DEFAULT_CSS, fontStyle: "italic" }), "_[3m");
|
||||||
assertEquals(
|
assertEquals(
|
||||||
cssToAnsiEsc({ ...DEFAULT_CSS, textDecorationColor: [206, 207, 208] }),
|
cssToAnsiEsc({ ...DEFAULT_CSS, textDecorationColor: [206, 207, 208] }),
|
||||||
"_[49m_[39m_[22m_[23m_[58;2;206;207;208m_[29m_[55m_[24m",
|
"_[58;2;206;207;208m",
|
||||||
);
|
);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
cssToAnsiEsc({ ...DEFAULT_CSS, textDecorationLine: ["underline"] }),
|
cssToAnsiEsc({ ...DEFAULT_CSS, textDecorationLine: ["underline"] }),
|
||||||
"_[49m_[39m_[22m_[23m_[59m_[29m_[55m_[4m",
|
"_[4m",
|
||||||
);
|
);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
cssToAnsiEsc(
|
cssToAnsiEsc(
|
||||||
{ ...DEFAULT_CSS, textDecorationLine: ["overline", "line-through"] },
|
{ ...DEFAULT_CSS, textDecorationLine: ["overline", "line-through"] },
|
||||||
),
|
),
|
||||||
"_[49m_[39m_[22m_[23m_[59m_[9m_[53m_[24m",
|
"_[9m_[53m",
|
||||||
);
|
);
|
||||||
assertEquals(
|
assertEquals(
|
||||||
cssToAnsiEsc(
|
cssToAnsiEsc(
|
||||||
{ ...DEFAULT_CSS, color: [203, 204, 205], fontWeight: "bold" },
|
{ ...DEFAULT_CSS, color: [203, 204, 205], fontWeight: "bold" },
|
||||||
),
|
),
|
||||||
"_[49m_[38;2;203;204;205m_[1m_[23m_[59m_[29m_[55m_[24m",
|
"_[38;2;203;204;205m_[1m",
|
||||||
|
);
|
||||||
|
assertEquals(
|
||||||
|
cssToAnsiEsc(
|
||||||
|
{ ...DEFAULT_CSS, color: [0, 0, 0], fontWeight: "bold" },
|
||||||
|
{ ...DEFAULT_CSS, color: [203, 204, 205], fontStyle: "italic" },
|
||||||
|
),
|
||||||
|
"_[38;2;0;0;0m_[1m_[23m",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue