Skip to content

Commit 9d35890

Browse files
committed
convert "\r" string into a multiple-line string: "Reading...1%\nReading...5%\nReading...100%"
1 parent 2c72257 commit 9d35890

File tree

2 files changed

+28
-24
lines changed

2 files changed

+28
-24
lines changed
+10-7
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import {expect, test} from 'vitest';
22

3-
import {processConsoleLine} from './RepoActionView.vue';
3+
import {ansiLogToHTML} from './RepoActionView.vue';
44

55
test('processConsoleLine', () => {
6-
expect(processConsoleLine('abc')).toEqual('abc');
7-
expect(processConsoleLine('abc\n')).toEqual('abc');
8-
expect(processConsoleLine('abc\r\n')).toEqual('abc');
9-
expect(processConsoleLine('\r')).toEqual('');
10-
expect(processConsoleLine('\rx\rabc')).toEqual('abc');
11-
expect(processConsoleLine('\rabc\rx\r')).toEqual('xbc');
6+
expect(ansiLogToHTML('abc')).toEqual('abc');
7+
expect(ansiLogToHTML('abc\n')).toEqual('abc');
8+
expect(ansiLogToHTML('abc\r\n')).toEqual('abc');
9+
expect(ansiLogToHTML('\r')).toEqual('');
10+
expect(ansiLogToHTML('\rx\rabc')).toEqual('x\nabc');
11+
expect(ansiLogToHTML('\rabc\rx\r')).toEqual('abc\nx');
12+
13+
expect(ansiLogToHTML('\x1b[30mblack\x1b[37mwhite')).toEqual('<span style="color:#000">black<span style="color:#AAA">white</span></span>');
14+
expect(ansiLogToHTML('<script>')).toEqual('&lt;script&gt;');
1215
});

web_src/js/components/RepoActionView.vue

+18-17
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ import AnsiToHTML from 'ansi-to-html';
7777
7878
const {csrfToken} = window.config;
7979
80+
const ansiLogRender = new AnsiToHTML({escapeXML: true});
81+
8082
const sfc = {
8183
name: 'RepoActionView',
8284
components: {
@@ -91,8 +93,6 @@ const sfc = {
9193
9294
data() {
9395
return {
94-
ansiToHTML: new AnsiToHTML({escapeXML: true}),
95-
9696
// internal state
9797
loading: false,
9898
intervalID: null,
@@ -214,7 +214,7 @@ const sfc = {
214214
215215
const logMessage = document.createElement('div');
216216
logMessage.className = 'log-msg';
217-
logMessage.innerHTML = this.ansiToHTML.toHtml(processConsoleLine(line.message));
217+
logMessage.innerHTML = ansiLogToHTML(line.message);
218218
div.appendChild(logMessage);
219219
220220
return div;
@@ -307,27 +307,28 @@ export function initRepositoryActionView() {
307307
view.mount(el);
308308
}
309309
310-
export function processConsoleLine(line) {
310+
export function ansiLogToHTML(line) {
311311
if (line.endsWith('\r\n')) {
312312
line = line.substring(0, line.length - 2);
313313
} else if (line.endsWith('\n')) {
314314
line = line.substring(0, line.length - 1);
315315
}
316-
if (!line.includes('\r')) return line;
317-
318-
// handle "\rReading...1%\rReading...5%\rReading...100%", only show the final message
319-
// TODO: control chars like "\033[" ?
320-
const parts = line.split('\r');
321-
let result = '';
322-
for (const part of parts) {
323-
if (part.length >= result.length) {
324-
result = part;
325-
} else {
326-
result = part + result.substring(part.length);
327-
}
316+
if (!line.includes('\r')) {
317+
return ansiLogRender.toHtml(line);
328318
}
329-
return result;
319+
320+
// handle "\rReading...1%\rReading...5%\rReading...100%",
321+
// convert it into a multiple-line string: "Reading...1%\nReading...5%\nReading...100%"
322+
// then we do not need to process control chars like "\033[".
323+
const lines = [];
324+
for (const part of line.split('\r')) {
325+
if (part === '') continue;
326+
lines.push(part);
327+
}
328+
// the log message element is with "white-space: break-spaces;", so use "\n" to break lines
329+
return ansiLogRender.toHtml(lines.join('\n'));
330330
}
331+
331332
</script>
332333
333334
<style scoped>

0 commit comments

Comments
 (0)