diff --git a/load/defs.js b/load/defs.js index 14251c2..8d30aee 100644 --- a/load/defs.js +++ b/load/defs.js @@ -96,9 +96,9 @@ function TexFrame() { } if ((this.type == FRAME_TYPE_LOGIN) || (this.type == FRAME_TYPE_RESPONSE)) { - return header+this.parse(this.content); + return header+this.parse(base64_decode(this.content)); } else { - return header+this.content; + return header+base64_decode(this.content); } }; @@ -113,6 +113,284 @@ function TexFrame() { return null; } + // Load a frame from disk (.tex file) + this.load = function(filename) { + log(LOG_DEBUG,'Loading frame from: '+filename); + + f = new File(system.mods_dir+'ansitex/text/'+filename+'.tex'); + if (! f.exists || ! f.open('r')) { + return null; + } + + try { + var load = JSON.parse(f.read()); + + for (property in load) { + this[property] = load[property]; + } + + //this.content = base64_decode(this.content); + + } catch (error) { + log(LOG_ERROR,'Frame error: '+error); + return null; + } + + log(LOG_DEBUG,'Loaded frame: ['+this.frame+']['+this.index+'] ('+this.page+')'); + }; + + /** + * Parse the page text, and return the frame as 2 arrays: + * + First array is all the characters and the position on the frame + * + Second array is the array of the control codes that changes the color of the character + * + * The purpose of this function is to convert any special char sequences there are interpreted directly by Ansitex + * Currently they are: + * + ESC _ [;value] ESC \ + * + * Additionally, for response frames, if the cursor is moved to a field, its to determine what attributes (eg: color) + * should apply for that field. + * + * @param text + */ + this.parse = function(text) { + var c = 1; // column + var r = 2; // row (row 1 is the header) + var output = ''; + this.frame_fields = []; + + // Default Attributes + f = 39; + b = 49; + i = 0; + + for(p=0;p= 0 && csi[num] <= 8) { + i = csi[num]; + f = 39; + b = 49; + + // Forground Color + } else if (csi[num] >= 30 && csi[num] <= 39) { + f = csi[num]; + + // Background Color + } else if (csi[num] >= 40 && csi[num] <= 49) { + b = num; + } + } + break; + + // Advance characters + case 'C': + //log(LOG_DEBUG,'CSI C ['+r+'x'+c+'] CHARS: '+matches[1]); + c += parseInt(matches[1]); // Advance our position + break; + + default: + log(LOG_DEBUG,'? CSI: '.matches[2]); + } + + break; + + case ' ': + log(LOG_DEBUG,'LOOSE ESC? ['+r+'x'+c+'] '+advance); + + break; + + // SOS + case '_': + //log(LOG_DEBUG,'SOS ['+r+'x'+c+'] '+advance); + advance++; + + // Find our end ST param in the next 50 chars + matches = text.substr(p+advance,50).match(/(([A-Z]+;[0-9a-z]+)([;]?.+)?)\x1b\\/); + //log(LOG_DEBUG,'SOS ['+r+'x'+c+'] ADVANCE: '+advance+', MATCHES: '+matches+', LENGTH: '+matches[0].length+', STRING: '+text.substr(p+advance,50)); + + if (! matches) { + chars += nextbyte; + + break; + } + + advance += matches[0].length-1; + + // The last 2 chars of matches[0] are the ESC \ + sos = matches[0].substr(0,matches[0].length-2).split(';'); + //log(LOG_DEBUG,'SOS ['+r+'x'+c+'] ADVANCE: '+advance+', SOS: '+sos); + + var num = null; + var fieldlen = null; + for (num in sos) { + //log(LOG_DEBUG,'SOS ['+r+'x'+c+'] NUM: '+num+', SOS: '+sos[num]); + + switch (num) { + // First value is the field name + case '0': + field = sos[num]; + break; + + // Second value is the length/type of the field + case '1': + x = sos[num].match(/([0-9]+)([a-z])/); + if (! x) { + log(LOG_ERROR,'SOS FAILED PARSING FIELD LENGTH/TYPE. ['+r+'x'+c+'] '+sos[num]); + break; + } + + //log(LOG_DEBUG,'SOS ['+r+'x'+c+'] NUM CHARS: '+x[1]+', TYPE: '+x[2]); + fieldlen = x[1]; + fieldtype = x[2]; + break; + + // Third field is the char to to use + case '2': + fieldchar = sos[num]; + break; + + default: + log(LOG_ERROR,'IGNORING ADDITIONAL SOS FIELDS. ['+r+'x'+c+'] '+sos[num]); + } + } + + if (fieldlen) { + chars = fieldchar.repeat(fieldlen); + } + + byte = ''; + + this.frame_fields.push({ + ftype: fieldtype, + flength: fieldlen, + fchar: fieldchar, + fname: field, + r: r, + c: c, + attribute: {i:i,f:f,b:b}, + fvalue: '', + }); + + log(LOG_DEBUG,'SOS Field found at ['+r+'x'+(c-1)+'], Type: '+fieldtype+', Length: '+fieldlen+', Attrs: '+JSON.stringify({i:i,f:f,b:b})); + + break; + + default: + log(LOG_DEBUG,'DEFAULT ['+r+'x'+c+'] '+advance); + } + + break; + + default: + c++; + } + + output += byte; + + if (advance) { + //log(LOG_DEBUG,'ADVANCE P ['+r+'x'+c+'] '+advance+', NEXT CHAR: '+text.charAt(p+advance)+' ('+text.charCodeAt(p+advance)+')'); + output += chars; + p += advance; + } + + if (c>FRAME_WIDTH) { + c = 1; + r++; + } + + /* + // @todo - If we are longer than FRAME_LENGTH, move the output into the next frame. + if (r>FRAME_LENGTH) { + break; + } + */ + } + + return output; + }; + + this.save=function() { + file = system.mods_dir+'ansitex/text/'+this.page+'.tex'; + w = new File(file); + if (! w.open('w')) { + log(LOG_ERROR,'! ERROR: Unable to create TEX file for '+this.page); + exit(1); + } + + w.write(JSON.stringify(this)); + w.close(); + + log(LOG_DEBUG,'Saved file: '+this.page+'.tex'); + } + Object.defineProperty(this,'page', { get: function() { if (this.frame == null || this.index == null) return null; @@ -149,268 +427,4 @@ function TexFrame() { }); } -// Load a frame from disk (.tex file) -TexFrame.prototype.load = function(filename) { - log(LOG_DEBUG,'Loading frame from: '+filename); - - f = new File(system.mods_dir+'ansitex/text/'+filename+'.tex'); - if (! f.exists || ! f.open('r')) { - return null; - } - - try { - var load = JSON.parse(f.read()); - - for (property in load) { - this[property] = load[property]; - } - - this.content = base64_decode(this.content); - - } catch (error) { - log(LOG_ERROR,'Frame error: '+error); - return null; - } - - log(LOG_DEBUG,'Loaded frame: ['+this.frame+']['+this.index+'] ('+this.page+')'); -}; - -/** - * Parse the page text, and return the frame as 2 arrays: - * + First array is all the characters and the position on the frame - * + Second array is the array of the control codes that changes the color of the character - * - * The purpose of this function is to convert any special char sequences there are interpreted directly by Ansitex - * Currently they are: - * + ESC _ [;value] ESC \ - * - * Additionally, for response frames, if the cursor is moved to a field, its to determine what attributes (eg: color) - * should apply for that field. - * - * @param text - */ -TexFrame.prototype.parse = function(text) { - var c = 1; // column - var r = 2; // row (row 1 is the header) - var output = ''; - this.frame_fields = []; - - // Default Attributes - f = 39; - b = 49; - i = 0; - - for(p=0;p= 0 && csi[num] <= 8) { - i = csi[num]; - f = 39; - b = 49; - - // Forground Color - } else if (csi[num] >= 30 && csi[num] <= 39) { - f = csi[num]; - - // Background Color - } else if (csi[num] >= 40 && csi[num] <= 49) { - b = num; - } - } - break; - - // Advance characters - case 'C': - //log(LOG_DEBUG,'CSI C ['+r+'x'+c+'] CHARS: '+matches[1]); - c += parseInt(matches[1]); // Advance our position - break; - - default: - log(LOG_DEBUG,'? CSI: '.matches[2]); - } - - break; - - case ' ': - log(LOG_DEBUG,'LOOSE ESC? ['+r+'x'+c+'] '+advance); - - break; - - // SOS - case '_': - //log(LOG_DEBUG,'SOS ['+r+'x'+c+'] '+advance); - advance++; - - // Find our end ST param in the next 50 chars - matches = text.substr(p+advance,50).match(/(([A-Z]+;[0-9a-z]+)([;]?.+)?)\x1b\\/); - //log(LOG_DEBUG,'SOS ['+r+'x'+c+'] ADVANCE: '+advance+', MATCHES: '+matches+', LENGTH: '+matches[0].length+', STRING: '+text.substr(p+advance,50)); - - if (! matches) { - chars += nextbyte; - - break; - } - - advance += matches[0].length-1; - - // The last 2 chars of matches[0] are the ESC \ - sos = matches[0].substr(0,matches[0].length-2).split(';'); - //log(LOG_DEBUG,'SOS ['+r+'x'+c+'] ADVANCE: '+advance+', SOS: '+sos); - - var num = null; - var fieldlen = null; - for (num in sos) { - //log(LOG_DEBUG,'SOS ['+r+'x'+c+'] NUM: '+num+', SOS: '+sos[num]); - - switch (num) { - // First value is the field name - case '0': - field = sos[num]; - break; - - // Second value is the length/type of the field - case '1': - x = sos[num].match(/([0-9]+)([a-z])/); - if (! x) { - log(LOG_ERROR,'SOS FAILED PARSING FIELD LENGTH/TYPE. ['+r+'x'+c+'] '+sos[num]); - break; - } - - //log(LOG_DEBUG,'SOS ['+r+'x'+c+'] NUM CHARS: '+x[1]+', TYPE: '+x[2]); - fieldlen = x[1]; - fieldtype = x[2]; - break; - - // Third field is the char to to use - case '2': - fieldchar = sos[num]; - break; - - default: - log(LOG_ERROR,'IGNORING ADDITIONAL SOS FIELDS. ['+r+'x'+c+'] '+sos[num]); - } - } - - if (fieldlen) { - chars = fieldchar.repeat(fieldlen); - } - - byte = ''; - - this.frame_fields.push({ - ftype: fieldtype, - flength: fieldlen, - fchar: fieldchar, - fname: field, - r: r, - c: c, - attribute: {i:i,f:f,b:b}, - fvalue: '', - }); - - log(LOG_DEBUG,'SOS Field found at ['+r+'x'+(c-1)+'], Type: '+fieldtype+', Length: '+fieldlen+', Attrs: '+JSON.stringify({i:i,f:f,b:b})); - - break; - - default: - log(LOG_DEBUG,'DEFAULT ['+r+'x'+c+'] '+advance); - } - - break; - - default: - c++; - } - - output += byte; - - if (advance) { - //log(LOG_DEBUG,'ADVANCE P ['+r+'x'+c+'] '+advance+', NEXT CHAR: '+text.charAt(p+advance)+' ('+text.charCodeAt(p+advance)+')'); - output += chars; - p += advance; - } - - if (c>FRAME_WIDTH) { - c = 1; - r++; - } - - /* - // @todo - If we are longer than FRAME_LENGTH, move the output into the next frame. - if (r>FRAME_LENGTH) { - break; - } - */ - } - - return output; -}; - this; \ No newline at end of file diff --git a/load/edit.js b/load/edit.js index fb73aae..4e87008 100644 --- a/load/edit.js +++ b/load/edit.js @@ -65,7 +65,7 @@ function edit(fo) { editor.menu.addItem('Save & Exit', save_and_exit); x = new Graphic; - x.ANSI = fo.content; + x.ANSI = base64_decode(fo.content); log(LOG_DEBUG,JSON.stringify(x)); const bin = x.BIN; @@ -99,7 +99,8 @@ function edit(fo) { frame.close(); complete = true; console.clear(LIGHTGRAY); - fo.content = editor.exportAnsi().join(''); + fo.content = base64_encode(editor.exportAnsi().join('')); + fo.save(); console.putmsg(fo.render()); return ''; }