diff --git a/load/page.js b/load/page.js index 6868837..71a1abe 100644 --- a/load/page.js +++ b/load/page.js @@ -10,9 +10,9 @@ - Line 2..23 - Content (Scrollable) - Line 24 - Status/Command Input (Fixed) - = When scrolling is disabled, and the canvas is greater than the window, then "nextpage" returns the next frame - = Pageable windows cannot have children, only "CONTENT" is paged - = Pageable windows are pagable when scrolling is false and window canvas.height > window.height and canvas.width = window.width + = @todo When scrolling is disabled, and the canvas is greater than the window, then "nextpage" returns the next frame + = Pageable windows cannot have children [b-z frames], only "CONTENT" is paged + = @todo Pageable windows are pagable when scrolling is false and window canvas.height > window.height and canvas.width = window.width + Window - size W x H, where W/H can be larger than the Screen - Window holds all the content to be shown @@ -75,7 +75,10 @@ --:____.____|____.____|____.____|____.____|____.____|____.____|____.____|____.____| */ -load('ansitex/load/windows.js'); +load('ansitex/load/windows.js'); // Our supporting window class +require('sbbsdefs.js','SS_USERON'); // Need for our ANSI colors eg: BG_* +require('ansitex/load/msgbases.js','MAX_PAGE_NUM'); // To read/write to message bases +require('ansitex/load/session-ansitex.js','SESSION_ANSITEX'); // @todo Only load this if it is an ANSI page we are loading /** * This object represents a full page that interacts with the user @@ -102,13 +105,12 @@ load('ansitex/load/windows.js'); * Pages have the following public functions * - build - Compile the frame for rendering * - display - Display the compiled frame - * - load - Load a frame from a file source + * - import - Load a frame from a file source + * - save - Save the frame to the msgbase + * - load - Load the frame from the msgbase */ function Page(service,debug) { - this.__properties__ = { - type: undefined, // Viewdata or ANSItex frame - name: new PageObject, - + this.__window__ = { layout: undefined, // Window - Full page content header: undefined, // Window - Page Title @@ -116,7 +118,12 @@ function Page(service,debug) { pagenum: undefined, // Our page number (*) cost: undefined, // Page cost (*) - content: undefined, // Window - Page Content + body: undefined, // Window - Page body + }; + + this.__properties__ = { + type: undefined, // Viewdata or ANSItex frame + name: new PageObject, input_fields: [], // Array of our input fields dynamic_fields: [], // Array of our dynamic fields @@ -130,7 +137,7 @@ function Page(service,debug) { }; this.__compiled__ = { - build: undefined, + build: undefined, // Our page compiled content }; /* @@ -151,25 +158,25 @@ function Page(service,debug) { switch (service) { case 'tex': - this.__properties__.layout = new Window(1,1,ANSI_FRAME_WIDTH,ANSI_FRAME_HEIGHT+1,'LAYOUT',this,debug); - this.__properties__.content = new Window(1,2,ANSI_FRAME_WIDTH,ANSI_FRAME_HEIGHT,'CONTENT',this.__properties__.layout,debug); + this.__window__.layout = new Window(1,1,ANSI_FRAME_WIDTH,ANSI_FRAME_HEIGHT+1,'LAYOUT',this,debug); + this.__window__.body = new Window(1,2,ANSI_FRAME_WIDTH,ANSI_FRAME_HEIGHT,'CONTENT',this.__window__.layout,debug); - this.__properties__.header = new Window(1,1,ANSI_FRAME_WIDTH,1,'HEADER',this.__properties__.layout,debug); - this.__properties__.provider = new Window(1,1,ANSI_FRAME_PROVIDER_LENGTH,1,'PROVIDER',this.__properties__.header,debug); - this.__properties__.pagenum = new Window(57,1,ANSI_FRAME_PAGE_LENGTH,1,'#',this.__properties__.header,debug); - this.__properties__.cost = new Window(71,1,ANSI_FRAME_COST_LENGTH,1,'$',this.__properties__.header,debug); + this.__window__.header = new Window(1,1,ANSI_FRAME_WIDTH,1,'HEADER',this.__window__.layout,debug); + this.__window__.provider = new Window(1,1,ANSI_FRAME_PROVIDER_LENGTH,1,'PROVIDER',this.__window__.header,debug); + this.__window__.pagenum = new Window(57,1,ANSI_FRAME_PAGE_LENGTH,1,'#',this.__window__.header,debug); + this.__window__.cost = new Window(71,1,ANSI_FRAME_COST_LENGTH,1,'$',this.__window__.header,debug); break; case 'vtx': // @todo VTX hasnt been worked on at all - need at last a viewdata2attrs function - this.__properties__.layout = new Window(1,1,VIEWDATA_FRAME_WIDTH,VIEWDATA_FRAME_HEIGHT+1,'LAYOUT',this,debug); - this.__properties__.content = new Window(1,2,VIEWDATA_FRAME_WIDTH,VIEWDATA_FRAME_HEIGHT,'CONTENT',this.__properties__.layout,debug) + this.__window__.layout = new Window(1,1,VIEWDATA_FRAME_WIDTH,VIEWDATA_FRAME_HEIGHT+1,'LAYOUT',this,debug); + this.__window__.body = new Window(1,2,VIEWDATA_FRAME_WIDTH,VIEWDATA_FRAME_HEIGHT,'CONTENT',this.__window__.layout,debug) - this.__properties__.header = new Window(1,1,VIEWDATA_FRAME_WIDTH,1,'HEADER',this.__properties__.layout,debug); - this.__properties__.provider = new Window(1,1,VIEWDATA_FRAME_PROVIDER_LENGTH,1,'PROVIDER',this.__properties__.header,debug); - this.__properties__.pagenum = new Window(24,1,VIEWDATA_FRAME_PAGE_LENGTH,1,'#',this.__properties__.header,debug); - this.__properties__.cost = new Window(35,1,VIEWDATA_FRAME_COST_LENGTH,1,'$',this.__properties__.header,debug); + this.__window__.header = new Window(1,1,VIEWDATA_FRAME_WIDTH,1,'HEADER',this.__window__.layout,debug); + this.__window__.provider = new Window(1,1,VIEWDATA_FRAME_PROVIDER_LENGTH,1,'PROVIDER',this.__window__.header,debug); + this.__window__.pagenum = new Window(24,1,VIEWDATA_FRAME_PAGE_LENGTH,1,'#',this.__window__.header,debug); + this.__window__.cost = new Window(35,1,VIEWDATA_FRAME_COST_LENGTH,1,'$',this.__window__.header,debug); break; @@ -180,8 +187,6 @@ function Page(service,debug) { this.service = service; } - init.apply(this,arguments); - // @todo change this to Object.defineProperty() - see session.js /** * Determine if this frame is accessible to the current user @@ -197,7 +202,7 @@ function Page(service,debug) { (this.__properties__.isAccessible && this.pageowner === SYSTEM_OWNER && ! this.__properties__.isPublic) || (this.__properties__.isAccessible && this.__properties__.isPublic) || (this.__properties__.isAccessible && ! this.__properties__.isPublic && this.isMember) || - (pageEditor(this.frame)) + (pageEditor(this.name.frame)) ); } else { @@ -209,12 +214,12 @@ function Page(service,debug) { if (typeof int !== 'number') throw new Error('Cost must be a number'); - switch (this.service) { + switch (this.__properties__.service) { case 'tex': if ((''+int).length > ANSI_FRAME_COST_LENGTH-1) throw new Error('Cost too large'); - this.__properties__.cost.__properties__.content = anstoattrs(ESC+'[1;32m'+padright(int,ANSI_FRAME_COST_LENGTH-1,' ')+'c').content; + this.__window__.cost.__properties__.content = anstoattrs(ESC+'[1;32m'+padright(int,ANSI_FRAME_COST_LENGTH-1,' ')+'c').content; break; @@ -222,30 +227,36 @@ function Page(service,debug) { if ((''+int).length > VIEWDATA_FRAME_COST_LENGTH-2) throw new Error('Cost too large'); - this.__properties__.cost.__properties__.content = bintoattrs(VIEWDATA_BIN_GREEN+padright(int,VIEWDATA_FRAME_COST_LENGTH-2,' ')+'c').content; + this.__window__.cost.__properties__.content = bintoattrs(VIEWDATA_BIN_GREEN+padright(int,VIEWDATA_FRAME_COST_LENGTH-2,' ')+'c').content; break; default: - throw new Error(this.service+' type not implemented'); + throw new Error(this.__properties__.service+' type not implemented'); } }); Page.prototype.__defineGetter__('dimensions',function() { - return this.width+' X '+this.height; + return this.__properties__.width+' X '+this.__properties__.height; }); Page.prototype.__defineGetter__('dynamic_fields',function() { return this.__properties__.dynamic_fields; }); + Page.prototype.__defineSetter__('dynamic_fields',function(array) { + this.__properties__.dynamic_fields = array; + }); Page.prototype.__defineGetter__('height',function() { - return Number(this.__properties__.layout.height); + return Number(this.__window__.layout.height); }); Page.prototype.__defineGetter__('input_fields',function() { return this.__properties__.input_fields; }); + Page.prototype.__defineSetter__('input_fields',function(array) { + this.__properties__.input_fields = array; + }); Page.prototype.__defineSetter__('isAccessible',function(bool) { if ((typeof bool !== 'boolean') && (typeof bool !== 'number')) @@ -270,25 +281,25 @@ function Page(service,debug) { this.__properties__.name = object; - switch (this.service) { + switch (this.__properties__.service) { case 'tex': - if ((''+this.name.frame).length > ANSI_FRAME_PAGE_LENGTH-1) + if ((''+this.__properties__.name.frame).length > ANSI_FRAME_PAGE_LENGTH-1) throw new Error('Pagenum too large'); - this.__properties__.pagenum.__properties__.content = anstoattrs(ESC+'[1;37m'+this.name.name).content; + this.__window__.pagenum.__properties__.content = anstoattrs(ESC+'[1;37m'+this.__properties__.name.name).content; break; case 'vtx': - if ((''+this.name.frame).length > VIEWDATA_FRAME_PAGE_LENGTH-2) + if ((''+this.__properties__.name.frame).length > VIEWDATA_FRAME_PAGE_LENGTH-2) throw new Error('Pagenum too large'); - this.__properties__.pagenum.__properties__.content = bintoattrs(VIEWDATA_BIN_WHITE+this.name.name).content; + this.__window__.pagenum.__properties__.content = bintoattrs(VIEWDATA_BIN_WHITE+this.__properties__.name.name).content; break; default: - throw new Error(this.service+' type not implemented'); + throw new Error(this.__properties__.service+' type not implemented'); } }); @@ -300,15 +311,15 @@ function Page(service,debug) { * Determine who the owner of a page is */ Page.prototype.__defineGetter__('pageowner',function() { - log(LOG_DEBUG,'Getting page owner for:'+this.__properties__.name.__properties__.frame); + log(LOG_DEBUG,'Getting page owner for:'+this.__properties__.name.frame); - return pageOwner(this.__properties__.name.__properties__.frame).prefix; + return pageOwner(this.__properties__.name.frame).prefix; }); Page.prototype.__defineSetter__('provider',function(ansi) { var provider; - switch (this.service) { + switch (this.__properties__.service) { case 'tex': provider = anstoattrs(ansi+ESC+'[0m').content; @@ -326,10 +337,10 @@ function Page(service,debug) { break; default: - throw new Error(this.service+' not implemented'); + throw new Error(this.__properties__.service+' not implemented'); } - this.__properties__.provider.__properties__.content = provider; + this.__window__.provider.__properties__.content = provider; }); Page.prototype.__defineGetter__('service',function() { @@ -349,11 +360,11 @@ function Page(service,debug) { if (typeof bool !== 'boolean') throw new Error('showHeader expected a true/false'); - this.__properties__.header.__properties__.visible = bool; + this.__window__.header.visible = bool; }); Page.prototype.__defineGetter__('width',function() { - return Number(this.__properties__.layout.width); + return Number(this.__window__.layout.width); }); /** @@ -366,7 +377,7 @@ function Page(service,debug) { throw new Error('Refusing to build without force.'); this.build_system_fields(); - this.__compiled__.build = this.__properties__.layout.build(1,1,false); + this.__compiled__.build = this.__window__.layout.build(1,1,false); // Add our dynamic values var fields = this.dynamic_fields.filter(function(item) { return item.value !== undefined; }); @@ -484,25 +495,25 @@ function Page(service,debug) { // The current char value var char = (display[y] !== undefined && display[y][x] !== undefined) ? display[y][x] : undefined; if (debug) - log(LOG_DEBUG,' - CHAR : '+(char !== undefined ? char.__properties__.ch : 'undefined')+', ATTR:'+(char !== undefined ? char.__properties__.attr : 'undefined')+', LAST:'+last); + log(LOG_DEBUG,' - CHAR : '+(char !== undefined ? char.ch : 'undefined')+', ATTR:'+(char !== undefined ? char.attr : 'undefined')+', LAST:'+last); if (debug) { writeln(); writeln('-------- ['+x+'] ------'); - writeln('y:'+y+',x:'+x+', attr:'+(char !== undefined ? char.__properties__.attr : 'undefined')); + writeln('y:'+y+',x:'+x+', attr:'+(char !== undefined ? char.attr : 'undefined')); } if ((color === undefined) || color) { // Only write a new attribute if it has changed (and not Videotex) - if ((this.service === 'vtx') || (last === undefined) || (last !== char.__properties__.attr)) { + if ((this.service === 'vtx') || (last === undefined) || (last !== char.attr)) { // The current attribute for this character - attr = (char === undefined) ? undefined : char.attr(last,this.service,debug); + attr = (char === undefined) ? undefined : char.attribute(last,this.service,debug); switch (this.service) { case 'tex': // If the attribute is null, we'll write our default attribute if (attr === null) - line += this.__defaults__.attr + line += this.attr else line += (attr !== undefined) ? attr : ''; @@ -525,13 +536,13 @@ function Page(service,debug) { // For no-color output and ViewData, we'll render a character } else { - if ((this.service === 'vtx') && char.__properties__.attr) + if ((this.service === 'vtx') && char.attr) line += '^'; } if (char.ch !== undefined) { if (debug) - log(LOG_DEBUG,' = SEND CHAR :'+char.ch+', attr:'+char.__properties__.attr+', last:'+last); + log(LOG_DEBUG,' = SEND CHAR :'+char.ch+', attr:'+char.attr+', last:'+last); line += (char.ch !== null) ? char.ch : ''; @@ -541,7 +552,7 @@ function Page(service,debug) { line += ' '; } - last = (char.__properties__.attr === undefined) ? undefined : char.__properties__.attr; + last = (char.attr === undefined) ? undefined : char.attr; } result.push(line); @@ -611,36 +622,36 @@ function Page(service,debug) { } write('['); - if (display[y][x].__properties__.attr === undefined) { + if (display[y][x].attr === undefined) { // NOOP - } else if (display[y][x].__properties__.attr === null) { + } else if (display[y][x].attr === null) { // NOOP } else { try { - write((last === display[y][x].__properties__.attr) ? '' : display[y][x].__properties__.attr); + write((last === display[y][x].attr) ? '' : display[y][x].attr); } catch (e) { writeln(); writeln('error:'+e); writeln(' y:'+y); writeln(' x:'+x); - writeln(JSON.stringify(display[y][x].__properties__.attr)); + writeln(JSON.stringify(display[y][x].attr)); exit(1); } } write(':'); - if (display[y][x].__properties__.ch === undefined) { + if (display[y][x].ch === undefined) { // NOOP - No window filled a character at this location - write((display[y][x].__properties__.attr === undefined) ? '--' : ''); - } else if (display[y][x].__properties__.ch === null) { + write((display[y][x].attr === undefined) ? '--' : ''); + } else if (display[y][x].ch === null) { // NOOP } else { - write('_'+display[y][x].__properties__.ch); + write('_'+display[y][x].ch); } write(']'); - last = display[y][x].__properties__.attr; + last = display[y][x].attr; xx++; } @@ -661,9 +672,9 @@ function Page(service,debug) { var xx = 1; for (var x in display[y]) { - var attr = display[y][x].__properties__.attr; + var attr = display[y][x].attr; - writeln('X:'+(xx++)+'|'+attr+':'+display[y][x].__properties__.ch+'|'+display[y][x].attr(last,this.service,debug)); + writeln('X:'+(xx++)+'|'+attr+':'+display[y][x].ch+'|'+display[y][x].attribute(last,this.service,debug)); // Only write a new attribute if it has changed if ((this.last === undefined) || (this.last !== attr)) { @@ -750,7 +761,7 @@ function Page(service,debug) { if (!(page instanceof PageObject)) throw new Error('page must be a PageObject'); - return this.load(system.mods_dir+'ansitex/text/'+page.name+'.'+ext); + return this.import(system.mods_dir+'ansitex/text/'+page.name+'.'+ext); } /** @@ -772,18 +783,20 @@ function Page(service,debug) { /** * Load a frame from a file * - * @param filename - Name of file to load page from + * @param filename - Name of file to load page from (SBBS default dir is CTRL, so relative to it) * @param width - Width to build window (not required for ANS) * @param height - Height to build window (not required for ANS) * @returns {boolean} * @todo Dont allow load() to load a Viewdata frame for an ANSItex session and visa-versa. */ - this.load = function(filename,width,height) { - log(LOG_DEBUG,'Loading frame: ['+filename+']'); + this.import = function(filename,width,height) { + log(LOG_DEBUG,' - Importing frame: ['+filename+']'); var f = new File(filename); - if (! f.exists || ! f.open('rb',true)) + if (! f.exists || ! f.open('rb',true)) { + log(LOG_ERROR,' ? File doesnt exist: ['+filename+']'); return null; + } var contents = f.read(); f.close(); @@ -856,12 +869,12 @@ function Page(service,debug) { switch (ext) { // ANSI files case 'ans': - var page = anstoattrs(contents,this.width,this.__properties__.content.y,this.__properties__.content.x); + var page = anstoattrs(contents,this.width,this.__window__.body.y,this.__window__.body.x); - this.__properties__.content.__properties__.content = page.content; - this.__properties__.dynamic_fields = page.dynamic_fields; + this.__window__.body.__properties__.content = page.content; + this.dynamic_fields = page.dynamic_fields; // Our fields are sorted in x descending order - this.__properties__.input_fields = page.input_fields.sort(function(a,b) { return a.x < b.x ? 1 : -1; }); + this.input_fields = page.input_fields.sort(function(a,b) { return a.x < b.x ? 1 : -1; }); break; @@ -879,16 +892,16 @@ function Page(service,debug) { log(LOG_INFO,'- Parsing content'); //log(LOG_ERROR,'Frame content: '+JSON.stringify(base64_decode(load[SAVED_FRAME_ATTRS[property]]))); if (ext === 'tex') - var page = anstoattrs(base64_decode(load[SAVED_FRAME_ATTRS[property]]).replace("\x0a\x0d\x0a\x0d","\x0a\x0d"),this.width,this.__properties__.content.y,this.__properties__.content.x); - else if (ext == 'vtx') - var page = bintoattrs(base64_decode(load[SAVED_FRAME_ATTRS[property]]),this.width,this.__properties__.content.y,this.__properties__.content.x); + var page = anstoattrs(base64_decode(load[SAVED_FRAME_ATTRS[property]]).replace("\x0a\x0d\x0a\x0d","\x0a\x0d"),this.width,this.__window__.body.y,this.__window__.body.x); + else if (ext === 'vtx') + var page = bintoattrs(base64_decode(load[SAVED_FRAME_ATTRS[property]]),this.width,this.__window__.body.y,this.__window__.body.x); //log(LOG_ERROR,'Frame content: '+JSON.stringify(page)); - this.__properties__.content.__properties__.content = page.content; - this.__properties__.dynamic_fields = page.dynamic_fields; + this.__window__.body.__properties__.content = page.content; + this.dynamic_fields = page.dynamic_fields; // Our fields are sorted in x descending order if (page.input_fields.length) - this.__properties__.input_fields = page.input_fields.sort(function(a,b) { return a.x < b.x ? 1 : -1; }); + this.input_fields = page.input_fields.sort(function(a,b) { return a.x < b.x ? 1 : -1; }); log(LOG_INFO,'- Parsing content complete'); break; @@ -898,16 +911,16 @@ function Page(service,debug) { break; case 'frame': - this.__properties__.name.frame = ''+load[SAVED_FRAME_ATTRS[property]]; + this.name.frame = ''+load[SAVED_FRAME_ATTRS[property]]; break; case 'input_fields': if (load[SAVED_FRAME_ATTRS[property]]) - this.__properties__.input_fields = load[SAVED_FRAME_ATTRS[property]]; + this.input_fields = load[SAVED_FRAME_ATTRS[property]]; break; case 'index': - this.__properties__.name.index = load[SAVED_FRAME_ATTRS[property]]; + this.name.index = load[SAVED_FRAME_ATTRS[property]]; break; case 'version': @@ -945,12 +958,12 @@ function Page(service,debug) { // ViewData files case 'bin': - var page = bintoattrs(contents,this.width,this.__properties__.content.y,this.__properties__.content.x,debug); + var page = bintoattrs(contents,this.width,this.__window__.body.y,this.__window__.body.x,debug); - this.__properties__.content.__properties__.content = page.content; - this.__properties__.dynamic_fields = page.dynamic_fields; + this.__window__.body.__properties__.content = page.content; + this.dynamic_fields = page.dynamic_fields; // Our fields are sorted in x descending order - this.__properties__.input_fields = page.input_fields.sort(function(a,b) { return a.x < b.x ? 1 : -1; }); + this.input_fields = page.input_fields.sort(function(a,b) { return a.x < b.x ? 1 : -1; }); break; @@ -982,13 +995,13 @@ function Page(service,debug) { switch (this.service) { case 'tex': - this.__properties__.pagenum.__properties__.content = anstoattrs(ESC+'[1;37m'+this.name.name).content; + this.__window__.pagenum.__properties__.content = anstoattrs(ESC+'[1;37m'+this.name.name).content; this.provider = base64_decode(po.logoans); break; case 'vtx': - this.__properties__.pagenum.__properties__.content = bintoattrs(VIEWDATA_BIN_WHITE+this.name.name).content; + this.__window__.pagenum.__properties__.content = bintoattrs(VIEWDATA_BIN_WHITE+this.name.name).content; this.provider = base64_decode(po.logovtx); break; @@ -1027,7 +1040,7 @@ function Page(service,debug) { // Line intro write('\x1b[0m'); - line = this.__properties__.layout.drawline(1,this.width,y,false); + line = this.__window__.layout.drawline(1,this.width,y,false); write(line.content); write('\x1b[0m'); @@ -1035,6 +1048,8 @@ function Page(service,debug) { writeln(); } } + + init.apply(this,arguments); } function PageObject(frame,index) { @@ -1046,11 +1061,13 @@ function PageObject(frame,index) { function init(frame,index) { if (typeof frame === 'object') { this.__properties__.frame = frame.frame; - this.__properties__.index = frame.index; + this.index = frame.index; } else { this.__properties__.frame = frame; - this.__properties__.index = index; + + if (index) + this.index = index; } } @@ -1081,16 +1098,16 @@ function PageObject(frame,index) { }); PageObject.prototype.__defineGetter__('name',function() { - return (this.__properties__.frame && this.__properties__.index) ? this.frame+this.index : null; + return (this.frame && this.index) ? this.frame+this.index : null; }); PageObject.prototype.__defineGetter__('next',function() { var next = undefined; - if (this.__properties__.index !== 'z') { - log(LOG_DEBUG,'page_next: Current page:'+this.__properties__.frame+', current index:'+this.__properties__.index); + if (this.index !== 'z') { + log(LOG_DEBUG,'page_next: Current page:'+this.frame+', current index:'+this.index); - next = new PageObject(this.__properties__.frame,String.fromCharCode(this.__properties__.index.charCodeAt(0)+1)); + next = new PageObject(this.frame,String.fromCharCode(this.index.charCodeAt(0)+1)); } return next; diff --git a/load/windows.js b/load/windows.js index 42d5f0c..7946cd6 100644 --- a/load/windows.js +++ b/load/windows.js @@ -110,36 +110,34 @@ function Window(x,y,width,height,name,parent,debug) { this.name = name; this.x = x; this.y = y; - this.__properties__.width = this.__properties__.canvaswidth = width; - this.__properties__.height = this.__properties__.canvasheight = height; + this.width = this.canvaswidth = width; + this.height = this.canvasheight = height; if (debug) { - this.__properties__.canvaswidth = width*2; - this.__properties__.canvasheight = height*2; + this.canvaswidth = width*2; + this.canvasheight = height*2; } // Fill with data - for(var y=1;y<=this.__properties__.canvasheight;y++) { - for(var x=1;x<=this.__properties__.canvaswidth;x++) { - if (this.__properties__.content[y] == undefined) - this.__properties__.content[y] = []; + for(var y=1;y<=this.canvasheight;y++) { + for(var x=1;x<=this.canvaswidth;x++) { + if (this.content[y] === undefined) + this.content[y] = []; - this.__properties__.content[y][x] = debug + this.content[y][x] = debug ? new Char((x > this.width) || (y > this.height) ? this.name[0].toUpperCase() : this.name[0].toLowerCase(),undefined) : new Char(undefined,undefined); } } } - init.apply(this,arguments); - // Windows boundary (right most width) of parent [1..] Window.prototype.__defineGetter__('bx',function() { - return this.x+this.width-1; + return this.__properties__.x+this.__properties__.width-1; }); // Windows boundary (bottom most height) of parent [1..] Window.prototype.__defineGetter__('by',function() { - return this.y+this.height-1; + return this.__properties__.y+this.__properties__.height-1; }); /* @@ -155,7 +153,7 @@ function Window(x,y,width,height,name,parent,debug) { // Management of children objects, in highest z order Window.prototype.__defineGetter__('child',function() { // Return the children sorted in z order lowest to highest - return this.__relations__.child.sort(function(a,b) { return (a.z < b.z) ? -1 : ((b.z < a.z) ? 1 : 0); }); + return this.__relations__.child.sort(function(a,b) { return (a.__properties__.z < b.__properties__.z) ? -1 : ((b.__properties__.z < a.__properties__.z) ? 1 : 0); }); }); Window.prototype.__defineSetter__('child',function(obj) { if(obj instanceof Window) { @@ -165,6 +163,39 @@ function Window(x,y,width,height,name,parent,debug) { throw new Error('child not an instance of Window()'); }); + // Window content + Window.prototype.__defineGetter__('content',function() { + return this.__properties__.content; + }); + Window.prototype.__defineSetter__('content',function(string) { + if (this.__properties__.content) + throw new Error('content already DEFINED'); + + return this.__properties__.content = string; + }); + + // Window canvas height + Window.prototype.__defineGetter__('canvasheight',function() { + return this.__properties__.canvasheight; + }); + Window.prototype.__defineSetter__('canvasheight',function(int) { + if (this.__properties__.canvasheight) + throw new Error('canvasheight already DEFINED'); + + return this.__properties__.canvasheight = int; + }); + + // Window canvas width + Window.prototype.__defineGetter__('canvaswidth',function() { + return this.__properties__.canvaswidth; + }); + Window.prototype.__defineSetter__('canvaswidth',function(int) { + if (this.__properties__.canvaswidth) + throw new Error('canvaswidth already DEFINED'); + + return this.__properties__.canvaswidth = int; + }); + // Window name Window.prototype.__defineGetter__('name',function() { return this.__properties__.name; @@ -176,6 +207,26 @@ function Window(x,y,width,height,name,parent,debug) { return this.__properties__.name = string; }); + Window.prototype.__defineGetter__('ox',function() { + return this.__properties__.ox; + }); + Window.prototype.__defineSetter__('ox',function(int) { + if (this.__properties__.ox) + throw new Error('ox already DEFINED'); + + this.__properties__.ox = int; + }); + + Window.prototype.__defineGetter__('oy',function() { + return this.__properties__.oy; + }); + Window.prototype.__defineSetter__('oy',function(int) { + if (this.__properties__.oy) + throw new Error('oy already DEFINED'); + + this.__properties__.oy = int; + }); + // Parent window object Window.prototype.__defineGetter__('parent',function() { return this.__relations__.parent; @@ -235,6 +286,12 @@ function Window(x,y,width,height,name,parent,debug) { Window.prototype.__defineGetter__('visible',function() { return this.__properties__.visible; }); + Window.prototype.__defineSetter__('visible',function(bool) { + if (typeof bool !== 'boolean') + throw new Error('visible expected a true/false'); + + this.__properties__.visible = bool; + }); // What position is this window (highest is visible) Window.prototype.__defineSetter__('z',function(int) { @@ -265,12 +322,12 @@ function Window(x,y,width,height,name,parent,debug) { writeln('yoff :'+yoffset); writeln('x :'+this.x); writeln('bx :'+this.bx) - writeln('ox :'+this.__properties__.ox); + writeln('ox :'+this.ox); writeln('y :'+this.y); writeln('by :'+this.by) - writeln('oy :'+this.__properties__.oy); - writeln('lines :'+this.__properties__.content.length); - writeln('content:'+JSON.stringify(Object.keys(this.__properties__.content).join(','))); + writeln('oy :'+this.oy); + writeln('lines :'+this.content.length); + writeln('content:'+JSON.stringify(Object.keys(this.content).join(','))); } if (debug) @@ -284,14 +341,14 @@ function Window(x,y,width,height,name,parent,debug) { for (x=1;x<=this.width;x++) { if (debug) - writeln('- Checking :'+this.name+', y:'+(y+this.__properties__.oy)+', x:'+(x+this.__properties__.ox)); + writeln('- Checking :'+this.name+', y:'+(y+this.oy)+', x:'+(x+this.ox)); var sx = this.x-1+x+xoffset-1; if (display[sy] === undefined) display[sy] = []; - if ((this.__properties__.content[y+this.__properties__.oy] !== undefined) && (this.__properties__.content[y+this.__properties__.oy][x+this.__properties__.ox] !== undefined)) { - display[sy][sx] = this.__properties__.content[y+this.__properties__.oy][x+this.__properties__.ox]; + if ((this.content[y+this.oy] !== undefined) && (this.content[y+this.oy][x+this.ox] !== undefined)) { + display[sy][sx] = this.content[y+this.oy][x+this.ox]; if (debug) writeln('- storing in y:'+(sy)+', x:'+(sx)+', ch:'+display[sy][sx].ch); @@ -375,34 +432,34 @@ function Window(x,y,width,height,name,parent,debug) { var content = ''; for (x=start;x<=end;x++) { - var rx = this.__properties__.ox+x; - var ry = this.__properties__.oy+y; + var rx = this.ox+x; + var ry = this.oy+y; // Check if we have an attribute to draw - if (! (ry in this.__properties__.content) || ! (rx in this.__properties__.content[ry])) { + if (! (ry in this.content) || ! (rx in this.content[ry])) { content += ' '; continue; } if (color === undefined || color === true) { // Only write a new attribute if it has changed - if ((this.last === undefined) || (this.last !== this.__properties__.content[ry][rx].attr)) { - this.last = this.__properties__.content[ry][rx].attr; + if ((this.last === undefined) || (this.last !== this.content[ry][rx].attr)) { + this.last = this.content[ry][rx].attr; content += (this.last === null ? BG_BLACK|LIGHTGRAY : this.last); } } try { - content += (this.__properties__.content[ry][rx].ch !== null ? this.__properties__.content[ry][rx].ch : ' '); + content += (this.content[ry][rx].ch !== null ? this.content[ry][rx].ch : ' '); } catch (e) { writeln(e); writeln('---'); writeln('x:'+(x-this.x)); writeln('y:'+(y-this.y)); - writeln('ox:'+this.__properties__.ox); - writeln('oy:'+this.__properties__.oy); + writeln('ox:'+this.ox); + writeln('oy:'+this.oy); writeln('rx:'+rx); writeln('ry:'+ry); exit(); @@ -726,6 +783,8 @@ function Window(x,y,width,height,name,parent,debug) { return child.visible; }); } + + init.apply(this,arguments); } /** @@ -753,13 +812,13 @@ function Char(ch,attr) { * @param debug - debug mode * @returns {string|undefined} */ - Char.prototype.attr = function(last,ext,debug) { + Char.prototype.attribute = function(last,ext,debug) { // If our attr is undefined, we'll return - if (this.__properties__.attr === undefined) + if (this.attr === undefined) return; // @todo This condition appears to fail? - if (this.__properties__.attr === null) + if (this.attr === null) throw new Error('Attributes shouldnt be null'); var ansi = []; @@ -769,40 +828,40 @@ function Char(ch,attr) { if (debug) { writeln(); - writeln('- last:'+last+', this:'+this.__properties__.attr); + writeln('- last:'+last+', this:'+this.attr); } switch (ext) { case 'tex': if (debug) { - writeln(' - this BG_BLACK:'+(this.__properties__.attr & BG_BLACK)); + writeln(' - this BG_BLACK:'+(this.attr & BG_BLACK)); writeln(' - last BG_BLACK:'+(last & BG_BLACK)); - writeln(' - this HIGH:'+(this.__properties__.attr & HIGH)); + writeln(' - this HIGH:'+(this.attr & HIGH)); writeln(' - last HIGH:'+(last & HIGH)); - writeln(' - this BLINK:'+(this.__properties__.attr & BLINK)); + writeln(' - this BLINK:'+(this.attr & BLINK)); writeln(' - last BLINK:'+(last & BLINK)); } if ( - (((this.__properties__.attr & BG_BLACK) !== (last & BG_BLACK)) - || ((this.__properties__.attr & HIGH) !== (last & HIGH)) - || ((this.__properties__.attr & BLINK) !== (last & BLINK)))) + (((this.attr & BG_BLACK) !== (last & BG_BLACK)) + || ((this.attr & HIGH) !== (last & HIGH)) + || ((this.attr & BLINK) !== (last & BLINK)))) { ansi.push('0'); last = BG_BLACK|LIGHTGRAY; } - if ((this.__properties__.attr & HIGH) && ((this.__properties__.attr & HIGH) !== (last & HIGH))) { + if ((this.attr & HIGH) && ((this.attr & HIGH) !== (last & HIGH))) { ansi.push('1'); } - if ((this.__properties__.attr & BLINK) && ((this.__properties__.attr & BLINK) !== (last & BLINK))) { + if ((this.attr & BLINK) && ((this.attr & BLINK) !== (last & BLINK))) { ansi.push('5'); } - c = (this.__properties__.attr & 0x07); + c = (this.attr & 0x07); l = (last & 0x07); // Foreground @@ -838,11 +897,11 @@ function Char(ch,attr) { ansi.push(r); // Background - if (this.__properties__.attr & 0x70) { - c = (this.__properties__.attr & 0x70); + if (this.attr & 0x70) { + c = (this.attr & 0x70); l = (last & 0x70); - switch (this.__properties__.attr & 0x70) { + switch (this.attr & 0x70) { case BG_BLACK: r = 40; break; @@ -879,8 +938,8 @@ function Char(ch,attr) { return ansi.length ? (debug ? '': '\x1b')+'['+ansi.join(';')+'m' : undefined; case 'vtx': - log(LOG_DEBUG,'+ last:'+last+', attr ('+this.__properties__.attr+')'); - switch (this.__properties__.attr) { + log(LOG_DEBUG,'+ last:'+last+', attr ('+this.attr+')'); + switch (this.attr) { // \x08 case BLINK: r = VIEWDATA_BLINK; @@ -932,8 +991,8 @@ function Char(ch,attr) { return '?'; default: - var mosiac = (this.__properties__.attr & MOSIAC); - c = (this.__properties__.attr & 0x07); + var mosiac = (this.attr & MOSIAC); + c = (this.attr & 0x07); // Color control \x00-\x07, \x10-\x17 switch (c) { @@ -972,10 +1031,14 @@ function Char(ch,attr) { return ESC+r; default: - throw new Error(this.__properties__.type+': has not been implemented'); + throw new Error(ext+': has not been implemented'); } }; + Char.prototype.__defineGetter__('attr',function() { + return this.__properties__.attr; + }); + Char.prototype.__defineGetter__('ch',function() { return this.__properties__.ch; }); diff --git a/main.js b/main.js index 822eee6..f746577 100644 --- a/main.js +++ b/main.js @@ -51,6 +51,11 @@ switch (client.socket.local_port) { require('ansitex/load/session-ansitex.js','SESSION_ANSITEX'); } +// @todo Suppress "Read your mail now" at login +// @todo Update message loading to process mystic color codes - this todo shouldnt be here, but placed here so I would see it and move it +// @todo Add "time ago" for messages, as an easier visual of how old it is. +bbs.node_settings &= ~(NM_LOGON_P); // Dont always ask for a password. + /** * This is our main event loop - where we interact with the user. * This loop takes care of first connect (unauthenticated users), or after authentication (main shell).