UNPKG

8.53 kBJavaScriptView Raw
1export class ColoredConsole {
2 constructor(targetElement) {
3 this.targetElement = targetElement;
4 this.state = {
5 bold: false,
6 italic: false,
7 underline: false,
8 strikethrough: false,
9 foregroundColor: null,
10 backgroundColor: null,
11 carriageReturn: false,
12 secret: false,
13 };
14 }
15 logs() {
16 return this.targetElement.innerText;
17 }
18 addLine(line) {
19 const re = /(?:\033|\\033)(?:\[(.*?)[@-~]|\].*?(?:\007|\033\\))/g;
20 let i = 0;
21 if (this.state.carriageReturn) {
22 if (line !== "\n") {
23 // don't remove if \r\n
24 this.targetElement.removeChild(this.targetElement.lastChild);
25 }
26 this.state.carriageReturn = false;
27 }
28 if (line.includes("\r")) {
29 this.state.carriageReturn = true;
30 }
31 const lineSpan = document.createElement("span");
32 lineSpan.classList.add("line");
33 this.targetElement.appendChild(lineSpan);
34 const addSpan = (content) => {
35 if (content === "")
36 return;
37 const span = document.createElement("span");
38 if (this.state.bold)
39 span.classList.add("log-bold");
40 if (this.state.italic)
41 span.classList.add("log-italic");
42 if (this.state.underline)
43 span.classList.add("log-underline");
44 if (this.state.strikethrough)
45 span.classList.add("log-strikethrough");
46 if (this.state.secret)
47 span.classList.add("log-secret");
48 if (this.state.foregroundColor !== null)
49 span.classList.add(`log-fg-${this.state.foregroundColor}`);
50 if (this.state.backgroundColor !== null)
51 span.classList.add(`log-bg-${this.state.backgroundColor}`);
52 span.appendChild(document.createTextNode(content));
53 lineSpan.appendChild(span);
54 if (this.state.secret) {
55 const redacted = document.createElement("span");
56 redacted.classList.add("log-secret-redacted");
57 redacted.appendChild(document.createTextNode("[redacted]"));
58 lineSpan.appendChild(redacted);
59 }
60 };
61 while (true) {
62 const match = re.exec(line);
63 if (match === null)
64 break;
65 const j = match.index;
66 addSpan(line.substring(i, j));
67 i = j + match[0].length;
68 if (match[1] === undefined)
69 continue;
70 for (const colorCode of match[1].split(";")) {
71 switch (parseInt(colorCode)) {
72 case 0:
73 // reset
74 this.state.bold = false;
75 this.state.italic = false;
76 this.state.underline = false;
77 this.state.strikethrough = false;
78 this.state.foregroundColor = null;
79 this.state.backgroundColor = null;
80 this.state.secret = false;
81 break;
82 case 1:
83 this.state.bold = true;
84 break;
85 case 3:
86 this.state.italic = true;
87 break;
88 case 4:
89 this.state.underline = true;
90 break;
91 case 5:
92 this.state.secret = true;
93 break;
94 case 6:
95 this.state.secret = false;
96 break;
97 case 9:
98 this.state.strikethrough = true;
99 break;
100 case 22:
101 this.state.bold = false;
102 break;
103 case 23:
104 this.state.italic = false;
105 break;
106 case 24:
107 this.state.underline = false;
108 break;
109 case 29:
110 this.state.strikethrough = false;
111 break;
112 case 30:
113 this.state.foregroundColor = "black";
114 break;
115 case 31:
116 this.state.foregroundColor = "red";
117 break;
118 case 32:
119 this.state.foregroundColor = "green";
120 break;
121 case 33:
122 this.state.foregroundColor = "yellow";
123 break;
124 case 34:
125 this.state.foregroundColor = "blue";
126 break;
127 case 35:
128 this.state.foregroundColor = "magenta";
129 break;
130 case 36:
131 this.state.foregroundColor = "cyan";
132 break;
133 case 37:
134 this.state.foregroundColor = "white";
135 break;
136 case 39:
137 this.state.foregroundColor = null;
138 break;
139 case 41:
140 this.state.backgroundColor = "red";
141 break;
142 case 42:
143 this.state.backgroundColor = "green";
144 break;
145 case 43:
146 this.state.backgroundColor = "yellow";
147 break;
148 case 44:
149 this.state.backgroundColor = "blue";
150 break;
151 case 45:
152 this.state.backgroundColor = "magenta";
153 break;
154 case 46:
155 this.state.backgroundColor = "cyan";
156 break;
157 case 47:
158 this.state.backgroundColor = "white";
159 break;
160 case 40:
161 case 49:
162 this.state.backgroundColor = null;
163 break;
164 }
165 }
166 }
167 addSpan(line.substring(i));
168 if (this.targetElement.scrollTop + 56 >=
169 this.targetElement.scrollHeight - this.targetElement.offsetHeight) {
170 // at bottom
171 this.targetElement.scrollTop = this.targetElement.scrollHeight;
172 }
173 }
174}
175export const coloredConsoleStyles = `
176 .log {
177 flex: 1;
178 background-color: #1c1c1c;
179 font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, Courier,
180 monospace;
181 font-size: 12px;
182 padding: 16px;
183 overflow: auto;
184 line-height: 1.45;
185 border-radius: 3px;
186 white-space: pre-wrap;
187 overflow-wrap: break-word;
188 color: #ddd;
189 }
190
191 .log-bold {
192 font-weight: bold;
193 }
194 .log-italic {
195 font-style: italic;
196 }
197 .log-underline {
198 text-decoration: underline;
199 }
200 .log-strikethrough {
201 text-decoration: line-through;
202 }
203 .log-underline.log-strikethrough {
204 text-decoration: underline line-through;
205 }
206 .log-secret {
207 -webkit-user-select: none;
208 -moz-user-select: none;
209 -ms-user-select: none;
210 user-select: none;
211 }
212 .log-secret-redacted {
213 opacity: 0;
214 width: 1px;
215 font-size: 1px;
216 }
217 .log-fg-black {
218 color: rgb(128, 128, 128);
219 }
220 .log-fg-red {
221 color: rgb(255, 0, 0);
222 }
223 .log-fg-green {
224 color: rgb(0, 255, 0);
225 }
226 .log-fg-yellow {
227 color: rgb(255, 255, 0);
228 }
229 .log-fg-blue {
230 color: rgb(0, 0, 255);
231 }
232 .log-fg-magenta {
233 color: rgb(255, 0, 255);
234 }
235 .log-fg-cyan {
236 color: rgb(0, 255, 255);
237 }
238 .log-fg-white {
239 color: rgb(187, 187, 187);
240 }
241 .log-bg-black {
242 background-color: rgb(0, 0, 0);
243 }
244 .log-bg-red {
245 background-color: rgb(255, 0, 0);
246 }
247 .log-bg-green {
248 background-color: rgb(0, 255, 0);
249 }
250 .log-bg-yellow {
251 background-color: rgb(255, 255, 0);
252 }
253 .log-bg-blue {
254 background-color: rgb(0, 0, 255);
255 }
256 .log-bg-magenta {
257 background-color: rgb(255, 0, 255);
258 }
259 .log-bg-cyan {
260 background-color: rgb(0, 255, 255);
261 }
262 .log-bg-white {
263 background-color: rgb(255, 255, 255);
264 }
265`;