-
-
Notifications
You must be signed in to change notification settings - Fork 552
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
305 additions
and
32 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,305 @@ | ||
/** | ||
* The following code is modified based on | ||
* https://github.com/mahdyar/ansi-html-community/blob/b86cc3f1fa1d118477877352f0eafe1a70fd20ab/index.js | ||
* | ||
* Supported: | ||
* - added support for 24-bit RGB colors. | ||
* | ||
* Apache 2.0 Licensed | ||
* Author @Tjatse | ||
* https://github.com/mahdyar/ansi-html-community/blob/master/LICENSE | ||
*/ | ||
"use strict"; | ||
|
||
interface AnsiHtmlTags { | ||
open: typeof _openTags; | ||
close: typeof _closeTags; | ||
} | ||
|
||
type Option<T> = T | null | undefined; | ||
|
||
type Match = { | ||
advance: (n: number) => void; | ||
} & Array<string>; | ||
|
||
// Reference to https://github.com/sindresorhus/ansi-regex | ||
var _regANSI = | ||
/(?:(?:\u001b\[)|\u009b)(?:(?:[0-9]{1,3})?(?:(?:;[0-9]{0,3})*)?[A-M|f-m])|\u001b[A-M]/; | ||
|
||
var _defColors: Record<string, string | Array<string>> = { | ||
reset: ["fff", "000"], // [FOREGROUND_COLOR, BACKGROUND_COLOR] | ||
black: "000", | ||
red: "ff0000", | ||
green: "209805", | ||
yellow: "e8bf03", | ||
blue: "0000ff", | ||
magenta: "ff00ff", | ||
cyan: "00ffee", | ||
lightgrey: "f0f0f0", | ||
darkgrey: "888" | ||
}; | ||
var _styles: Record<string, string> = { | ||
30: "black", | ||
31: "red", | ||
32: "green", | ||
33: "yellow", | ||
34: "blue", | ||
35: "magenta", | ||
36: "cyan", | ||
37: "lightgrey" | ||
}; | ||
|
||
var _colorMode: Record<string, string> = { | ||
2: "rgb" | ||
}; | ||
|
||
var _openTags: Record<string, string | ((m: Match) => Option<string>)> = { | ||
1: "font-weight:bold", // bold | ||
2: "opacity:0.5", // dim | ||
3: "<i>", // italic | ||
4: "<u>", // underscore | ||
8: "display:none", // hidden | ||
9: "<del>", // delete | ||
38: (match: Match) => { | ||
// color | ||
var mode = _colorMode[match[0]]; | ||
if (mode === "rgb") { | ||
var r, g, b; | ||
r = match[1]; | ||
g = match[2]; | ||
b = match[3]; | ||
match.advance(4); | ||
return "color: rgb(" + r + "," + g + "," + b + ")"; | ||
} | ||
}, | ||
48: (match: Match) => { | ||
// background color | ||
var mode = _colorMode[match[0]]; | ||
if (mode === "rgb") { | ||
var r, g, b; | ||
r = match[1]; | ||
g = match[2]; | ||
b = match[3]; | ||
match.advance(4); | ||
return "background-color: rgb(" + r + "," + g + "," + b + ")"; | ||
} | ||
} | ||
}; | ||
|
||
var _openTagToCloseTag: Record<string, string> = { | ||
3: "23", | ||
4: "24", | ||
9: "29" | ||
}; | ||
|
||
var _closeTags: Record< | ||
string, | ||
string | ((ansiCodes: Option<Array<string>>) => string) | ||
> = { | ||
0: ansiCodes => { | ||
if (!ansiCodes) return "</span>"; | ||
if (!ansiCodes.length) return ""; | ||
var code: Option<string>, | ||
ret = ""; | ||
while ((code = ansiCodes.pop())) { | ||
var closeTag = _openTagToCloseTag[code]; | ||
if (closeTag) { | ||
ret += _closeTags[closeTag]; | ||
continue; | ||
} | ||
ret += "</span>"; | ||
} | ||
return ret; | ||
}, | ||
23: "</i>", // reset italic | ||
24: "</u>", // reset underscore | ||
29: "</del>" // reset delete | ||
}; | ||
|
||
[21, 22, 27, 28, 39, 49].forEach(n => { | ||
_closeTags[n] = "</span>"; | ||
}); | ||
|
||
/** | ||
* Normalize ';<seq>' | '<seq>' -> '<seq>' | ||
*/ | ||
function normalizeSeq(seq: Option<string>): Option<string> { | ||
if (seq === null || seq === undefined) return null; | ||
if (seq.startsWith(";")) { | ||
return seq.slice(1); | ||
} | ||
return seq; | ||
} | ||
|
||
/** | ||
* Converts text with ANSI color codes to HTML markup. | ||
*/ | ||
export default function ansiHTML(text: string) { | ||
// Returns the text if the string has no ANSI escape code. | ||
if (!_regANSI.test(text)) { | ||
return text; | ||
} | ||
|
||
// Cache opened sequence. | ||
var ansiCodes: string[] = []; | ||
// Replace with markup. | ||
//@ts-ignore TS1487 error | ||
var ret = text.replace(/\033\[(?:[0-9]{1,3})?(?:(?:;[0-9]{0,3})*)?m/g, m => { | ||
var match = m.match(/(;?\d+)/g)?.map(normalizeSeq) as unknown as Match; | ||
Object.defineProperty(match, "advance", { | ||
value: function (count: number) { | ||
this.splice(0, count); | ||
} | ||
}); | ||
var seq, | ||
rep = ""; | ||
while ((seq = match[0])) { | ||
match.advance(1); | ||
rep += applySeq(seq); | ||
} | ||
return rep; | ||
|
||
function applySeq(seq: string) { | ||
var other = _openTags[seq]; | ||
if ( | ||
other && | ||
(other = typeof other === "function" ? (other(match) as string) : other) | ||
) { | ||
// If reset signal is encountered, we have to reset everything. | ||
var ret = ""; | ||
if (seq === "0") { | ||
ret += ( | ||
_closeTags[seq] as (ansiCodes: Option<Array<string>>) => string | ||
)(ansiCodes); | ||
} | ||
// If current sequence has been opened, close it. | ||
if (!!~ansiCodes.indexOf(seq)) { | ||
// eslint-disable-line no-extra-boolean-cast | ||
ansiCodes.pop(); | ||
return "</span>"; | ||
} | ||
// Open tag. | ||
ansiCodes.push(seq); | ||
return ( | ||
ret + (other[0] === "<" ? other : '<span style="' + other + ';">') | ||
); | ||
} | ||
|
||
var ct = _closeTags[seq]; | ||
if (typeof ct === "function") { | ||
return ct(ansiCodes); | ||
} else if (ct) { | ||
// Pop sequence | ||
ansiCodes.pop(); | ||
return ct; | ||
} | ||
return ""; | ||
} | ||
}); | ||
|
||
// Make sure tags are closed. | ||
var l = ansiCodes.length; | ||
l > 0 && (ret += Array(l + 1).join("</span>")); | ||
|
||
return ret; | ||
} | ||
|
||
/** | ||
* Customize colors. | ||
* @param {Object} colors reference to _defColors | ||
*/ | ||
ansiHTML.setColors = (colors: typeof _defColors) => { | ||
if (typeof colors !== "object") { | ||
throw new Error("`colors` parameter must be an Object."); | ||
} | ||
|
||
var _finalColors: typeof _defColors = {}; | ||
for (var key in _defColors) { | ||
var hex = colors.hasOwnProperty(key) ? colors[key] : null; | ||
if (!hex) { | ||
_finalColors[key] = _defColors[key]; | ||
continue; | ||
} | ||
if ("reset" === key) { | ||
if (typeof hex === "string") { | ||
hex = [hex]; | ||
} | ||
if ( | ||
!Array.isArray(hex) || | ||
hex.length === 0 || | ||
hex.some(h => typeof h !== "string") | ||
) { | ||
throw new Error( | ||
"The value of `" + | ||
key + | ||
"` property must be an Array and each item could only be a hex string, e.g.: FF0000" | ||
); | ||
} | ||
var defHexColor = _defColors[key]; | ||
if (!hex[0]) { | ||
hex[0] = defHexColor[0]; | ||
} | ||
if (hex.length === 1 || !hex[1]) { | ||
hex = [hex[0]]; | ||
hex.push(defHexColor[1]); | ||
} | ||
|
||
hex = hex.slice(0, 2); | ||
} else if (typeof hex !== "string") { | ||
throw new Error( | ||
"The value of `" + key + "` property must be a hex string, e.g.: FF0000" | ||
); | ||
} | ||
_finalColors[key] = hex; | ||
} | ||
_setTags(_finalColors); | ||
}; | ||
|
||
/** | ||
* Reset colors. | ||
*/ | ||
ansiHTML.reset = () => { | ||
_setTags(_defColors); | ||
}; | ||
|
||
/** | ||
* Expose tags, including open and close. | ||
* @type {Object} | ||
*/ | ||
ansiHTML.tags = {} as AnsiHtmlTags; | ||
|
||
if (Object.defineProperty) { | ||
Object.defineProperty(ansiHTML.tags, "open", { | ||
get: () => _openTags | ||
}); | ||
Object.defineProperty(ansiHTML.tags, "close", { | ||
get: () => _closeTags | ||
}); | ||
} else { | ||
ansiHTML.tags.open = _openTags; | ||
ansiHTML.tags.close = _closeTags; | ||
} | ||
|
||
function _setTags(colors: typeof _defColors) { | ||
// reset all | ||
_openTags["0"] = | ||
"font-weight:normal;opacity:1;color:#" + | ||
colors.reset[0] + | ||
";background:#" + | ||
colors.reset[1]; | ||
// inverse | ||
_openTags["7"] = | ||
"color:#" + colors.reset[1] + ";background:#" + colors.reset[0]; | ||
// dark grey | ||
_openTags["90"] = "color:#" + colors.darkgrey; | ||
|
||
for (var code in _styles) { | ||
var color = _styles[code]; | ||
var oriColor = colors[color] || "000"; | ||
_openTags[code] = "color:#" + oriColor; | ||
const codeInt = Number.parseInt(code); | ||
_openTags[(codeInt + 10).toString()] = "background:#" + oriColor; | ||
} | ||
} | ||
|
||
ansiHTML.reset(); |
32 changes: 0 additions & 32 deletions
32
packages/rspack/src/builtin-plugin/css-extract/hmr/normalize-url.ts
This file was deleted.
Oops, something went wrong.