1'use strict';
2
3var gSetAttributes = [];
4
5
6function setAttribute(which, value)
7{
8	gSetAttributes = gSetAttributes.filter((value) => !value.startsWith(which));
9	gSetAttributes.push(which + value);
10}
11
12
13function replaceAttributes(match, inner)
14{
15	const kAttributes = [
16			'reset',
17			'bright',
18			'dim',
19			'italic',
20			'underscore',
21			'blink',
22			'blinkRapid',
23			'reverse',
24			'hidden',
25			'crossed'
26		];
27
28	const kColors = [
29			'black',
30			'red',
31			'green',
32			'yellow',
33			'blue',
34			'magenta',
35			'cyan',
36			'white',
37			'extended',
38			'default'
39		];
40
41	var result = '';
42	if (gSetAttributes.length > 0)
43		result += '</span>';
44
45	inner.split(';').forEach((attributeString) => {
46			var attribute = Number.parseInt(attributeString || '0');
47			if (attribute == 0)
48				gSetAttributes = [];
49			else if (attribute <= kAttributes.length)
50				setAttribute(kAttributes[attribute], '');
51			else if (attribute >= 30 && attribute <= 39)
52				setAttribute('fg-', kColors[attribute - 30]);
53			else if (attribute >= 40 && attribute <= 49)
54				setAttribute('bg-', kColors[attribute - 30]);
55		});
56
57	if (gSetAttributes.length == 0)
58		return result;
59
60	return result + '<span class="' + gSetAttributes.join(' ') + '">';
61}
62
63
64function parseLogfile(content)
65{
66	const replacements = [
67			{ what: '<', with: '&lt;' },
68			{ what: '>', with: '&gt;' },
69			{ what: '(\r\n)|\n|\r', with: '<br>' },
70			{ what: '\t', with: '        ' },
71			{ what: '  ', with: ' &nbsp;' },
72			{ what: '\x1b((\\[K)|(\\(.))', with: '' },
73			{ what: '\x1b\\[(([0-9]*;?)*)m', with: replaceAttributes }
74		];
75
76	document.body.textContent = 'parsing escape sequences';
77	document.body.innerHTML = replacements.reduce((value, replace) => {
78			return value.replace(new RegExp(replace.what, 'g'), replace.with);
79		}, content);
80	document.documentElement.scrollTop = document.documentElement.scrollHeight;
81}
82
83
84function init()
85{
86	var logfile = window.location.search.substring(1);
87	if (logfile.length == 0) {
88		document.body.textContent
89			= 'no log file specified, specify as search parameter';
90		return;
91	}
92
93	document.body.textContent = 'fetching "' + logfile + '"';
94	fetch(logfile).then((response) => {
95			if (!response.ok)
96				throw response.status + ' ' + response.statusText;
97			return response.text()
98		}).then(parseLogfile, (error) => {
99			document.body.textContent
100				= 'failed to load logfile "' + logfile + '": ' + error;
101		});
102}
103
104window.onload = init;
105