ghost-progress-webpack-plugin
Version:
A no side effects progress plugin for webpack.
203 lines • 6.17 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const cjk = require("cjk-regex");
const readline = require("readline");
const ansi = require('ansi-regex');
const cliCursor = require('cli-cursor');
class Helper {
constructor(stream) {
this.xLength = 0;
this.yLength = 0;
this.stream = stream;
}
clearLine(dir) {
readline.clearLine(this.stream, dir);
}
cursorTo(x, y) {
readline.cursorTo(this.stream, x, y);
}
moveCursor(dx, dy = 0) {
readline.moveCursor(this.stream, dx, dy);
}
showCursor() {
cliCursor.show(this.stream);
}
hideCursor() {
cliCursor.hide(this.stream);
}
clearAll() {
for (let i = 0; i < this.yLength; i++) {
this.stream.write('\n'); // 当光标位于最底部时, moveCursor(0, 1) 无效
this.clearLine(0);
}
this.moveCursor(0, -this.yLength);
}
write(message, yLimit) {
if (yLimit == undefined) {
let result = parseDisplayLength(message, this.xLength, this.stream.columns);
this.xLength = result.xLength;
this.yLength += result.yLength;
this.stream.write(message);
}
else {
let result = parseDisplayLengthAndLimit(message, yLimit, this.xLength, this.stream.columns);
this.xLength = result.xLength;
this.yLength += result.yLength;
this.stream.write(result.str);
}
}
begin() {
this.hideCursor();
hookStdoutWrite();
}
end() {
this.showCursor();
unhookStdoutWrite();
}
beginWrite() {
this.clearAll();
this.xLength = 0;
this.yLength = 1;
this.stream.write('\n');
}
endWrite() {
this.moveCursor(0, -this.yLength);
this.cursorTo(0);
}
}
exports.Helper = Helper;
// TODO https://github.com/chalk/ansi-regex/pull/24
const ansiRegexG = ansi();
const ansiRegex = new RegExp(ansiRegexG.source);
const cjkRegex = cjk().toRegExp();
function parseDisplayLength(str, xLength = 0, xMax = 128) {
let yLength = 0;
str = str.replace(ansiRegexG, '');
for (let i = 0; i < str.length; i++) {
let char = str.charAt(i);
let code = str.codePointAt(i);
if (code > 0xffff) {
char = String.fromCodePoint(code);
i += 1;
}
if (char === '\r') {
xLength = 0;
}
else if (char === '\n') {
xLength = 0;
yLength += 1;
}
else {
if (cjkRegex.test(char)) {
xLength += 2;
}
else {
xLength += 1;
}
if (xLength > xMax) {
xLength -= xMax;
yLength += 1;
}
}
}
return { xLength, yLength };
}
exports.parseDisplayLength = parseDisplayLength;
function parseDisplayLengthAndLimit(str, yLimit, xLength = 0, xMax = 128) {
let newStr = '';
let yLength = 0;
for (let i = 0; i < str.length; i++) {
let char = str.charAt(i);
let code = str.codePointAt(i);
if (code > 0xffff) {
char = String.fromCodePoint(code);
i += 1;
}
if (char === '\u001b' || char === '\u009b') {
let sub = str.substring(i);
let match = sub.match(ansiRegex);
if (match && match.index === 0) {
i += match[0].length - 1;
newStr += match[0];
}
else {
newStr += char;
}
}
else if (char === '\r') {
xLength = 0;
newStr += char;
}
else if (char === '\n') {
if (yLength + 1 < yLimit) {
xLength = 0;
yLength += 1;
newStr += char;
}
else {
continue; // 不使用 break 是为了防止 ANSI 转义序列被截断引发颜色污染
}
}
else {
if (cjkRegex.test(char)) {
xLength += 2;
}
else {
xLength += 1;
}
if (xLength > xMax) {
if (yLength + 1 < yLimit) {
if (xLength - xMax === 0)
xLength = 0;
else
xLength = 2;
yLength += 1;
}
else {
continue;
}
}
newStr += char;
}
}
return { str: newStr, xLength, yLength };
}
exports.parseDisplayLengthAndLimit = parseDisplayLengthAndLimit;
let stdoutWrite;
function hookStdoutWrite() {
if (stdoutWrite == undefined) {
stdoutWrite = process.stdout.write;
process.stdout.write = handleStdoutWrite;
}
}
exports.hookStdoutWrite = hookStdoutWrite;
function unhookStdoutWrite() {
if (stdoutWrite != undefined) {
process.stdout.write = stdoutWrite;
stdoutWrite = undefined;
}
}
exports.unhookStdoutWrite = unhookStdoutWrite;
// 帮助其他程序清理控制台,避免进度字符的残留
function handleStdoutWrite() {
let stream = process.stderr;
let str = arguments[0];
if (typeof str === 'string') {
if (str.includes('\n')) {
let result = parseDisplayLength(str, 0, stream.columns);
readline.clearLine(stream, 1);
for (let i = 0; i < result.yLength; i++) {
stream.write('\n');
readline.clearLine(stream, 0);
}
readline.moveCursor(stream, 0, -result.yLength);
}
else {
readline.clearLine(stream, 1);
}
}
stdoutWrite.apply(process.stdout, arguments);
if (typeof str === 'string')
readline.clearLine(stream, 1);
}
//# sourceMappingURL=helper.js.map