* Fix MCI colors. Everything working well so far!
This commit is contained in:
parent
23a4344a4b
commit
04c85d2311
|
@ -21,7 +21,7 @@ function ANSIEscapeParser(options) {
|
||||||
this.column = 1;
|
this.column = 1;
|
||||||
this.row = 1;
|
this.row = 1;
|
||||||
this.scrollBack = 0;
|
this.scrollBack = 0;
|
||||||
this.graphicRendition = { styles : [] };
|
this.graphicRendition = {};
|
||||||
|
|
||||||
options = miscUtil.valueWithDefault(options, {
|
options = miscUtil.valueWithDefault(options, {
|
||||||
mciReplaceChar : '',
|
mciReplaceChar : '',
|
||||||
|
@ -118,7 +118,7 @@ function ANSIEscapeParser(options) {
|
||||||
|
|
||||||
function getProcessedMCI(mci) {
|
function getProcessedMCI(mci) {
|
||||||
if(self.mciReplaceChar.length > 0) {
|
if(self.mciReplaceChar.length > 0) {
|
||||||
return ansi.getSGRFromGraphicRendition(self.graphicRendition) + new Array(mci.length + 1).join(self.mciReplaceChar);
|
return ansi.getSGRFromGraphicRendition(self.graphicRendition, true) + new Array(mci.length + 1).join(self.mciReplaceChar);
|
||||||
} else {
|
} else {
|
||||||
return mci;
|
return mci;
|
||||||
}
|
}
|
||||||
|
@ -161,10 +161,14 @@ function ANSIEscapeParser(options) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
self.emit('mci', mciCode, id, args);
|
self.emit('mci', {
|
||||||
|
mci : mciCode,
|
||||||
|
id : id ? parseInt(id, 10) : null,
|
||||||
|
args : args,
|
||||||
|
SGR : ansi.getSGRFromGraphicRendition(self.graphicRendition, true)
|
||||||
|
});
|
||||||
|
|
||||||
if(self.mciReplaceChar.length > 0) {
|
if(self.mciReplaceChar.length > 0) {
|
||||||
//self.emit('chunk', ansi.sgr(self.eraseColor.style, self.eraseColor.fgColor, self.eraseColor.bgColor));
|
|
||||||
self.emit('chunk', ansi.getSGRFromGraphicRendition(self.graphicRenditionForErase));
|
self.emit('chunk', ansi.getSGRFromGraphicRendition(self.graphicRenditionForErase));
|
||||||
literal(new Array(match[0].length + 1).join(self.mciReplaceChar));
|
literal(new Array(match[0].length + 1).join(self.mciReplaceChar));
|
||||||
} else {
|
} else {
|
||||||
|
@ -270,10 +274,6 @@ function ANSIEscapeParser(options) {
|
||||||
|
|
||||||
// set graphic rendition
|
// set graphic rendition
|
||||||
case 'm' :
|
case 'm' :
|
||||||
|
|
||||||
self.graphicRendition = { styles : [ 0 ] }; // reset
|
|
||||||
//self.graphicRendition.styles = [ 0 ];
|
|
||||||
|
|
||||||
for(i = 0, len = args.length; i < len; ++i) {
|
for(i = 0, len = args.length; i < len; ++i) {
|
||||||
arg = args[i];
|
arg = args[i];
|
||||||
|
|
||||||
|
@ -281,18 +281,54 @@ function ANSIEscapeParser(options) {
|
||||||
self.graphicRendition.fg = arg;
|
self.graphicRendition.fg = arg;
|
||||||
} else if(ANSIEscapeParser.backgroundColors[arg]) {
|
} else if(ANSIEscapeParser.backgroundColors[arg]) {
|
||||||
self.graphicRendition.bg = arg;
|
self.graphicRendition.bg = arg;
|
||||||
} else if(39 === arg) {
|
|
||||||
delete self.graphicRendition.fg;
|
|
||||||
} else if(49 === arg) {
|
|
||||||
delete self.graphicRendition.bg;
|
|
||||||
} else if(ANSIEscapeParser.styles[arg]) {
|
} else if(ANSIEscapeParser.styles[arg]) {
|
||||||
self.graphicRendition.styles.push(arg);
|
switch(arg) {
|
||||||
} else if(22 === arg) {
|
case 0 :
|
||||||
// :TODO: remove bold.
|
// clear out everything
|
||||||
|
delete self.graphicRendition.intensity;
|
||||||
|
delete self.graphicRendition.underline;
|
||||||
|
delete self.graphicRendition.blink;
|
||||||
|
delete self.graphicRendition.negative;
|
||||||
|
delete self.graphicRendition.invisible;
|
||||||
|
|
||||||
|
self.graphicRendition.fg = 39;
|
||||||
|
self.graphicRendition.bg = 49;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1 :
|
||||||
|
case 2 :
|
||||||
|
case 22 :
|
||||||
|
self.graphicRendition.intensity = arg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 4 :
|
||||||
|
case 24 :
|
||||||
|
self.graphicRendition.underline = arg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 5 :
|
||||||
|
case 6 :
|
||||||
|
case 25 :
|
||||||
|
self.graphicRendition.blink = arg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 7 :
|
||||||
|
case 27 :
|
||||||
|
self.graphicRendition.negative = arg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 8 :
|
||||||
|
case 28 :
|
||||||
|
self.graphicRendition.invisible = arg;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default :
|
||||||
|
console.log('Unknown attribute: ' + arg); // :TODO: Log properly
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(self.graphicRendition)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// erase display/screen
|
// erase display/screen
|
||||||
|
@ -317,6 +353,8 @@ ANSIEscapeParser.foregroundColors = {
|
||||||
35 : 'magenta',
|
35 : 'magenta',
|
||||||
36 : 'cyan',
|
36 : 'cyan',
|
||||||
37 : 'white',
|
37 : 'white',
|
||||||
|
39 : 'default', // same as white for most implementations
|
||||||
|
|
||||||
90 : 'grey'
|
90 : 'grey'
|
||||||
};
|
};
|
||||||
Object.freeze(ANSIEscapeParser.foregroundColors);
|
Object.freeze(ANSIEscapeParser.foregroundColors);
|
||||||
|
@ -329,20 +367,39 @@ ANSIEscapeParser.backgroundColors = {
|
||||||
44 : 'blue',
|
44 : 'blue',
|
||||||
45 : 'magenta',
|
45 : 'magenta',
|
||||||
46 : 'cyan',
|
46 : 'cyan',
|
||||||
47 : 'white'
|
47 : 'white',
|
||||||
|
49 : 'default', // same as black for most implementations
|
||||||
};
|
};
|
||||||
Object.freeze(ANSIEscapeParser.backgroundColors);
|
Object.freeze(ANSIEscapeParser.backgroundColors);
|
||||||
|
|
||||||
// :TODO: ensure these all align with that of ansi_term.js
|
// :TODO: ensure these names all align with that of ansi_term.js
|
||||||
|
//
|
||||||
|
// See the following specs:
|
||||||
|
// * http://www.ansi-bbs.org/ansi-bbs-core-server.html
|
||||||
|
// * http://www.vt100.net/docs/vt510-rm/SGR
|
||||||
|
// * https://github.com/protomouse/synchronet/blob/master/src/conio/cterm.txt
|
||||||
|
//
|
||||||
|
// Note that these are intentionally not in order such that they
|
||||||
|
// can be grouped by concept here in code.
|
||||||
|
//
|
||||||
ANSIEscapeParser.styles = {
|
ANSIEscapeParser.styles = {
|
||||||
0 : 'default',
|
0 : 'default', // Everything disabled
|
||||||
1 : 'bright',
|
|
||||||
2 : 'dim',
|
1 : 'intensityBright', // aka bold
|
||||||
5 : 'slowBlink',
|
2 : 'intensityDim',
|
||||||
6 : 'fastBlink',
|
22 : 'intensityNormal',
|
||||||
7 : 'negative',
|
|
||||||
8 : 'concealed',
|
4 : 'underlineOn', // Not supported by most BBS-like terminals
|
||||||
22 : 'normal',
|
24 : 'underlineOff', // Not supported by most BBS-like terminals
|
||||||
27 : 'positive',
|
|
||||||
|
5 : 'blinkSlow', // blinkSlow & blinkFast are generally treated the same
|
||||||
|
6 : 'blinkFast', // blinkSlow & blinkFast are generally treated the same
|
||||||
|
25 : 'blinkOff',
|
||||||
|
|
||||||
|
7 : 'negativeImageOn', // Generally not supported or treated as "reverse FG & BG"
|
||||||
|
27 : 'negativeImageOff', // Generally not supported or treated as "reverse FG & BG"
|
||||||
|
|
||||||
|
8 : 'invisibleOn', // FG set to BG
|
||||||
|
28 : 'invisibleOff', // Not supported by most BBS-like terminals
|
||||||
};
|
};
|
||||||
Object.freeze(ANSIEscapeParser.styles);
|
Object.freeze(ANSIEscapeParser.styles);
|
|
@ -326,16 +326,35 @@ function sgr() {
|
||||||
|
|
||||||
//
|
//
|
||||||
// Converts a Graphic Rendition object used elsewhere
|
// Converts a Graphic Rendition object used elsewhere
|
||||||
// to a ANSI SGR sequence
|
// to a ANSI SGR sequence.
|
||||||
//
|
//
|
||||||
function getSGRFromGraphicRendition(graphicRendition) {
|
function getSGRFromGraphicRendition(graphicRendition, initialReset) {
|
||||||
var sgrSeq = graphicRendition.styles.slice(0); // start out with styles
|
var sgrSeq = [];
|
||||||
|
|
||||||
|
var styleCount = 0;
|
||||||
|
[ 'intensity', 'underline', 'blink', 'negative', 'invisible' ].forEach(function style(s) {
|
||||||
|
if(graphicRendition[s]) {
|
||||||
|
sgrSeq.push(graphicRendition[s]);
|
||||||
|
++styleCount;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!styleCount) {
|
||||||
|
sgrSeq.push(0);
|
||||||
|
}
|
||||||
|
|
||||||
if(graphicRendition.fg) {
|
if(graphicRendition.fg) {
|
||||||
sgrSeq.push(graphicRendition.fg);
|
sgrSeq.push(graphicRendition.fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(graphicRendition.bg) {
|
if(graphicRendition.bg) {
|
||||||
sgrSeq.push(graphicRendition.bg);
|
sgrSeq.push(graphicRendition.bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(initialReset) {
|
||||||
|
sgrSeq.unshift(0);
|
||||||
|
}
|
||||||
|
|
||||||
return sgr(sgrSeq);
|
return sgr(sgrSeq);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
50
core/art.js
50
core/art.js
|
@ -420,7 +420,7 @@ function display(options, cb) {
|
||||||
termWidth : options.client.term.termWidth,
|
termWidth : options.client.term.termWidth,
|
||||||
});
|
});
|
||||||
|
|
||||||
var mci = {};
|
var mciMap = {};
|
||||||
var mciPosQueue = [];
|
var mciPosQueue = [];
|
||||||
var parseComplete = false;
|
var parseComplete = false;
|
||||||
|
|
||||||
|
@ -429,7 +429,7 @@ function display(options, cb) {
|
||||||
var onCPR = function(pos) {
|
var onCPR = function(pos) {
|
||||||
if(mciPosQueue.length > 0) {
|
if(mciPosQueue.length > 0) {
|
||||||
var forMapItem = mciPosQueue.shift();
|
var forMapItem = mciPosQueue.shift();
|
||||||
mci[forMapItem].position = pos;
|
mciMap[forMapItem].position = pos;
|
||||||
|
|
||||||
if(parseComplete && 0 === mciPosQueue.length) {
|
if(parseComplete && 0 === mciPosQueue.length) {
|
||||||
completed();
|
completed();
|
||||||
|
@ -445,50 +445,36 @@ function display(options, cb) {
|
||||||
// options.client.term.write(ansi.blinkNormal());
|
// options.client.term.write(ansi.blinkNormal());
|
||||||
}
|
}
|
||||||
|
|
||||||
cb(null, mci);
|
cb(null, mciMap);
|
||||||
}
|
}
|
||||||
|
|
||||||
options.client.on('cursor position report', onCPR);
|
options.client.on('cursor position report', onCPR);
|
||||||
|
|
||||||
parser.on('mci', function onMCI(mciCode, id, args) {
|
parser.on('mci', function mciEncountered(mciInfo) {
|
||||||
|
|
||||||
// :TODO: ensure generatedId's do not conflict with any |id|
|
// :TODO: ensure generatedId's do not conflict with any |id|
|
||||||
id = id || generatedId++;
|
var id = _.isUndefined(mciInfo.id) ? generatedId++ : mciInfo.id;
|
||||||
var mapItem = mciCode + id;
|
var mapKey = mciInfo.mci + id;
|
||||||
// :TODO: Avoid mutiple [] lookups here
|
var mapEntry = mciMap[mapKey];
|
||||||
if(mci[mapItem]) {
|
if(mapEntry) {
|
||||||
mci[mapItem].focusGraphicRendition = parser.graphicRendition;
|
mapEntry.focusSGR = mciInfo.SGR;
|
||||||
|
mapEntry.focusArgs = mciInfo.args;
|
||||||
/*
|
|
||||||
mci[mapItem].focusColor = {
|
|
||||||
fg : parser.fgColor,
|
|
||||||
bg : parser.bgColor,
|
|
||||||
flags : parser.style,
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
mci[mapItem].focusArgs = args;
|
|
||||||
} else {
|
} else {
|
||||||
mci[mapItem] = {
|
mciMap[mapKey] = {
|
||||||
args : args,
|
args : mciInfo.args,
|
||||||
/*
|
SGR : mciInfo.SGR,
|
||||||
color : {
|
code : mciInfo.mci,
|
||||||
fg : parser.fgColor,
|
id : id,
|
||||||
bg : parser.bgColor,
|
|
||||||
flags : parser.style,
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
graphicRendition : parser.graphicRendition,
|
|
||||||
code : mciCode,
|
|
||||||
id : parseInt(id, 10),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
mciPosQueue.push(mapItem);
|
mciPosQueue.push(mapKey);
|
||||||
|
|
||||||
options.client.term.write(ansi.queryPos(), false); // :TODO: don't convert LF's
|
options.client.term.write(ansi.queryPos(), false); // :TODO: don't convert LF's
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
parser.on('chunk', function onChunk(chunk) {
|
parser.on('chunk', function onChunk(chunk) {
|
||||||
options.client.term.write(chunk, false);// :TODO: don't convert LF's
|
options.client.term.write(chunk, false);
|
||||||
});
|
});
|
||||||
|
|
||||||
parser.on('complete', function onComplete() {
|
parser.on('complete', function onComplete() {
|
||||||
|
|
|
@ -56,15 +56,11 @@ MCIViewFactory.prototype.createFromMCI = function(mci) {
|
||||||
|
|
||||||
var view;
|
var view;
|
||||||
var options = {
|
var options = {
|
||||||
client : this.client,
|
client : this.client,
|
||||||
id : mci.id,
|
id : mci.id,
|
||||||
color : mci.color,
|
ansiSGR : mci.SGR,
|
||||||
focusColor : mci.focusColor,
|
ansiFocusSGR : mci.focusSGR,
|
||||||
|
position : { x : mci.position[0], y : mci.position[1] },
|
||||||
graphicRendition : mci.graphicRendition,
|
|
||||||
focusGraphicRendition : mci.focusGraphicRendition,
|
|
||||||
|
|
||||||
position : { x : mci.position[0], y : mci.position[1] },
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function setOption(pos, name) {
|
function setOption(pos, name) {
|
||||||
|
@ -183,6 +179,7 @@ MCIViewFactory.prototype.createFromMCI = function(mci) {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'TM' :
|
case 'TM' :
|
||||||
|
// :TODO: convert to new Graphics Rendition system here:
|
||||||
if(mci.args.length > 0) {
|
if(mci.args.length > 0) {
|
||||||
var color = { fg : parseInt(mci.args[0], 10), flags : 0 };
|
var color = { fg : parseInt(mci.args[0], 10), flags : 0 };
|
||||||
if(mci.args.length > 1) {
|
if(mci.args.length > 1) {
|
||||||
|
|
|
@ -112,19 +112,19 @@ function stylizeString(s, style) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Based on http://www.webtoolkit.info/
|
// Based on http://www.webtoolkit.info/
|
||||||
function pad(s, len, padChar, dir, stringColor, padColor) {
|
function pad(s, len, padChar, dir, stringSGR, padSGR) {
|
||||||
len = miscUtil.valueWithDefault(len, 0);
|
len = miscUtil.valueWithDefault(len, 0);
|
||||||
padChar = miscUtil.valueWithDefault(padChar, ' ');
|
padChar = miscUtil.valueWithDefault(padChar, ' ');
|
||||||
dir = miscUtil.valueWithDefault(dir, 'right');
|
dir = miscUtil.valueWithDefault(dir, 'right');
|
||||||
stringColor = miscUtil.valueWithDefault(stringColor, '');
|
stringSGR = miscUtil.valueWithDefault(stringSGR, '');
|
||||||
padColor = miscUtil.valueWithDefault(padColor, '');
|
padSGR = miscUtil.valueWithDefault(padSGR, '');
|
||||||
|
|
||||||
var padlen = len - s.length;
|
var padlen = len - s.length;
|
||||||
|
|
||||||
switch(dir) {
|
switch(dir) {
|
||||||
case 'L' :
|
case 'L' :
|
||||||
case 'left' :
|
case 'left' :
|
||||||
s = padColor + new Array(padlen).join(padChar) + stringColor + s;
|
s = padSGR + new Array(padlen).join(padChar) + stringSGR + s;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'C' :
|
case 'C' :
|
||||||
|
@ -132,16 +132,16 @@ function pad(s, len, padChar, dir, stringColor, padColor) {
|
||||||
case 'both' :
|
case 'both' :
|
||||||
var right = Math.ceil(padlen / 2);
|
var right = Math.ceil(padlen / 2);
|
||||||
var left = padlen - right;
|
var left = padlen - right;
|
||||||
s = padColor + new Array(left + 1).join(padChar) + stringColor + s + padColor + new Array(right + 1).join(padChar);
|
s = padSGR + new Array(left + 1).join(padChar) + stringSGR + s + padSGR + new Array(right + 1).join(padChar);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'R' :
|
case 'R' :
|
||||||
case 'right' :
|
case 'right' :
|
||||||
s = stringColor + s + padColor + new Array(padlen).join(padChar);
|
s = stringSGR + s + padSGR + new Array(padlen).join(padChar);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default : break;
|
default : break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return stringColor + s;
|
return stringSGR + s;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,11 +81,6 @@ TextView.prototype.setFocus = function(focused) {
|
||||||
|
|
||||||
this.redraw();
|
this.redraw();
|
||||||
|
|
||||||
console.log('---')
|
|
||||||
console.log(this.graphicRendition)
|
|
||||||
console.log(this.focusGraphicRendition)
|
|
||||||
console.log('---')
|
|
||||||
|
|
||||||
// position & SGR for cursor
|
// position & SGR for cursor
|
||||||
this.client.term.write(ansi.goto(this.position.x, this.position.y + this.text.length));
|
this.client.term.write(ansi.goto(this.position.x, this.position.y + this.text.length));
|
||||||
this.client.term.write(this.getFocusSGR());
|
this.client.term.write(this.getFocusSGR());
|
||||||
|
|
16
core/view.js
16
core/view.js
|
@ -64,8 +64,8 @@ function View(options) {
|
||||||
this.dimens.width = options.dimens.width;
|
this.dimens.width = options.dimens.width;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.graphicRendition = options.graphicRendition || { fg : 7, bg : 0, styles : [ 0 ] };
|
this.ansiSGR = options.ansiSGR || ansi.getSGRFromGraphicRendition( { fg : 39, bg : 49 }, true);
|
||||||
this.focusGraphicRendition = options.focusGraphicRendition || this.graphicRendition;
|
this.ansiFocusSGR = options.ansiFocusSGR || this.ansiSGR;
|
||||||
|
|
||||||
if(options.styleColor1) {
|
if(options.styleColor1) {
|
||||||
this.styleColor1 = options.styleColor1;
|
this.styleColor1 = options.styleColor1;
|
||||||
|
@ -167,20 +167,12 @@ View.prototype.setColor = function(color, bgColor, flags) {
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
|
|
||||||
View.prototype.getGraphicRendition = function() {
|
|
||||||
return this.graphicRendition;
|
|
||||||
}
|
|
||||||
|
|
||||||
View.prototype.getFocusGraphicRendition = function() {
|
|
||||||
return this.focusGraphicRendition;
|
|
||||||
}
|
|
||||||
|
|
||||||
View.prototype.getSGR = function() {
|
View.prototype.getSGR = function() {
|
||||||
return ansi.getSGRFromGraphicRendition(this.getGraphicRendition());
|
return this.ansiSGR;
|
||||||
}
|
}
|
||||||
|
|
||||||
View.prototype.getFocusSGR = function() {
|
View.prototype.getFocusSGR = function() {
|
||||||
return ansi.getSGRFromGraphicRendition(this.getFocusGraphicRendition());
|
return this.ansiFocusSGR;
|
||||||
}
|
}
|
||||||
|
|
||||||
View.prototype.redraw = function() {
|
View.prototype.redraw = function() {
|
||||||
|
|
|
@ -184,6 +184,7 @@ function ViewController(options) {
|
||||||
setViewProp('maxLength');
|
setViewProp('maxLength');
|
||||||
setViewProp('width', function(v) { view.dimens.width = parseInt(v, 10); });
|
setViewProp('width', function(v) { view.dimens.width = parseInt(v, 10); });
|
||||||
|
|
||||||
|
// :TODO: This needs converted to new GraphicRendition object and possibly allow escaped ANSI SGR here if string
|
||||||
setViewProp('styleColor1', function(v) {
|
setViewProp('styleColor1', function(v) {
|
||||||
if(!_.has(v, 'fg')) {
|
if(!_.has(v, 'fg')) {
|
||||||
return;
|
return;
|
||||||
|
|
Loading…
Reference in New Issue