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: '<' }, 68 { what: '>', with: '>' }, 69 { what: '(\r\n)|\n|\r', with: '<br>' }, 70 { what: '\t', with: ' ' }, 71 { what: ' ', with: ' ' }, 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