* Moved menus -> menus.json::menus
* Move prompts -> prompts.json::prompts * Default to 80x25 if NAWS/ENV/CPR term size negotiations fail. Seeing this with Netrunner. May need more work.
This commit is contained in:
parent
9ac2e9af6e
commit
0d9add70bd
|
@ -454,6 +454,7 @@ function display(options, cb) {
|
|||
var nextPauseTermHeight = options.client.term.termHeight;
|
||||
var continous = false;
|
||||
|
||||
/*
|
||||
parser.on('row update', function rowUpdate(row) {
|
||||
if(row >= nextPauseTermHeight) {
|
||||
if(!continous && 'termHeight' === options.pause) {
|
||||
|
@ -469,6 +470,7 @@ function display(options, cb) {
|
|||
nextPauseTermHeight += options.client.term.termHeight;
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
parser.on('mci', function mciEncountered(mciInfo) {
|
||||
|
||||
|
|
|
@ -14,33 +14,56 @@ var util = require('util');
|
|||
|
||||
exports.connectEntry = connectEntry;
|
||||
|
||||
function ansiQueryTermSizeIfNeeded(client) {
|
||||
function ansiQueryTermSizeIfNeeded(client, cb) {
|
||||
if(client.term.termHeight > 0 || client.term.termWidth > 0) {
|
||||
cb(true);
|
||||
return;
|
||||
}
|
||||
|
||||
var onCPR = function(pos) {
|
||||
var cprListener = function(pos) {
|
||||
//
|
||||
// If we've already found out, disregard
|
||||
//
|
||||
if(client.term.termHeight > 0 || client.term.termWidth > 0) {
|
||||
cb(true);
|
||||
return;
|
||||
}
|
||||
|
||||
assert(2 === pos.length);
|
||||
client.term.termHeight = pos[0];
|
||||
client.term.termWidth = pos[1];
|
||||
var h = pos[0];
|
||||
var w = pos[1];
|
||||
|
||||
//
|
||||
// Netrunner for example gives us 1x1 here. Not really useful. Ignore
|
||||
// values that seem obviously bad.
|
||||
//
|
||||
if(h < 10 || w < 10) {
|
||||
Log.warn(
|
||||
{ height : h, width : w },
|
||||
'Ignoring ANSI CPR screen size query response due to very small values');
|
||||
cb(false);
|
||||
return;
|
||||
}
|
||||
|
||||
client.term.termHeight = h;
|
||||
client.term.termWidth = w;
|
||||
|
||||
Log.debug(
|
||||
{ termWidth : client.term.termWidth, termHeight : client.term.termHeight, updateSource : 'ANSI CPR' },
|
||||
'Window size updated');
|
||||
{
|
||||
termWidth : client.term.termWidth,
|
||||
termHeight : client.term.termHeight,
|
||||
source : 'ANSI CPR'
|
||||
},
|
||||
'Window size updated'
|
||||
);
|
||||
};
|
||||
|
||||
client.once('cursor position report', onCPR);
|
||||
client.once('cursor position report', cprListener);
|
||||
|
||||
// give up after 2s
|
||||
setTimeout(function onTimeout() {
|
||||
client.removeListener('cursor position report', onCPR);
|
||||
client.removeListener('cursor position report', cprListener);
|
||||
cb(true);
|
||||
}, 2000);
|
||||
|
||||
client.term.write(ansi.queryScreenSize());
|
||||
|
@ -53,10 +76,10 @@ function prepareTerminal(term) {
|
|||
}
|
||||
|
||||
function displayBanner(term) {
|
||||
// :TODO: add URL to banner
|
||||
// :TODO: add URL(s) to banner
|
||||
term.write(ansi.fromPipeCode(util.format('' +
|
||||
'|33Conected to |32EN|33|01i|32|22GMA|32|01½|00 |33BBS version|31|01 %s\n' +
|
||||
'|00|33Copyright (c) 2014 Bryan Ashby\n' +
|
||||
'|33Conected to |32EN|33|01i|00|32|22GMA|32|01½|00 |33BBS version|31|01 %s\n' +
|
||||
'|00|33Copyright (c) 2014-2015 Bryan Ashby\n' +
|
||||
'|00', packageJson.version)));
|
||||
}
|
||||
|
||||
|
@ -67,7 +90,19 @@ function connectEntry(client) {
|
|||
// If we don't yet know the client term width/height,
|
||||
// try with a nonstandard ANSI DSR type request.
|
||||
//
|
||||
ansiQueryTermSizeIfNeeded(client);
|
||||
ansiQueryTermSizeIfNeeded(client, function ansiCprResult(result) {
|
||||
|
||||
if(!result) {
|
||||
//
|
||||
// We still don't have something good for term height/width.
|
||||
// Default to DOS size 80x25.
|
||||
//
|
||||
// :TODO: Netrunner is currenting hitting this and it feels wrong. Why is NAWS/ENV/CPR all failing???
|
||||
Log.warn('Failed to negotiate term size; Defaulting to 80x25!');
|
||||
|
||||
term.termHeight = 25;
|
||||
term.termWidth = 80;
|
||||
}
|
||||
|
||||
prepareTerminal(term);
|
||||
|
||||
|
@ -79,5 +114,6 @@ function connectEntry(client) {
|
|||
setTimeout(function onTimeout() {
|
||||
client.gotoMenuModule( { name : Config.firstMenu });
|
||||
}, 500);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ function MaskEditTextView(options) {
|
|||
this.maskPattern = options.maskPattern || '';
|
||||
|
||||
this.clientBackspace = function() {
|
||||
var fillCharSGR = this.getStyleSGR(2) || this.getSGR();
|
||||
var fillCharSGR = this.getStyleSGR(3) || this.getSGR();
|
||||
this.client.term.write('\b' + fillCharSGR + this.fillChar + '\b' + this.getFocusSGR());
|
||||
};
|
||||
|
||||
|
@ -55,10 +55,11 @@ function MaskEditTextView(options) {
|
|||
self.client.term.write((self.hasFocus ? self.getFocusSGR() : self.getSGR()) + textToDraw[t]);
|
||||
t++;
|
||||
} else {
|
||||
self.client.term.write((self.getStyleSGR(2) || '') + self.fillChar);
|
||||
self.client.term.write((self.getStyleSGR(3) || '') + self.fillChar);
|
||||
}
|
||||
} else {
|
||||
self.client.term.write((self.getStyleSGR(1) || '') + self.maskPattern[i]);
|
||||
var styleSgr = this.hasFocus ? (self.getStyleSGR(2) || '') : (self.getStyleSGR(1) || '');
|
||||
self.client.term.write(styleSgr + self.maskPattern[i]);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
@ -79,6 +80,10 @@ function MaskEditTextView(options) {
|
|||
}
|
||||
};
|
||||
|
||||
this.getCursorEditYPosition = function() {
|
||||
return this.position.y + this.patternArrayPos;
|
||||
};
|
||||
|
||||
this.buildPattern();
|
||||
|
||||
}
|
||||
|
@ -92,6 +97,21 @@ MaskEditTextView.maskPatternCharacterRegEx = {
|
|||
'&' : /[\w\d\s]/, // Any "printable" 32-126, 128-255
|
||||
};
|
||||
|
||||
MaskEditTextView.prototype.setFocus = function(focused) {
|
||||
// :TODO: can't call super unless we want wasted redraw stuff. This seems sloppy & should probably be looked into
|
||||
//MaskEditTextView.super_.prototype.setFocus.call(this, focused);
|
||||
assert(this.acceptsFocus, 'View does not accept focus');
|
||||
|
||||
this.hasFocus = focused;
|
||||
this.restoreCursor();
|
||||
|
||||
this.redraw();
|
||||
|
||||
// position & SGR for cursor
|
||||
this.client.term.write(ansi.goto(this.position.x, this.getCursorEditYPosition()));
|
||||
this.client.term.write(this.getFocusSGR());
|
||||
};
|
||||
|
||||
MaskEditTextView.prototype.setMaskPattern = function(pattern) {
|
||||
this.dimens.width = pattern.length;
|
||||
|
||||
|
@ -123,9 +143,9 @@ MaskEditTextView.prototype.onKeyPress = function(key, isSpecial) {
|
|||
}
|
||||
|
||||
this.redraw();
|
||||
this.client.term.write(ansi.goto(this.position.x, this.getCursorEditYPosition()));
|
||||
}
|
||||
|
||||
|
||||
MaskEditTextView.super_.prototype.onKeyPress.call(this, key, isSpecial);
|
||||
};
|
||||
|
||||
|
@ -140,21 +160,14 @@ MaskEditTextView.prototype.onSpecialKeyPress = function(keyName) {
|
|||
this.text = this.text.substr(0, this.text.length - 1);
|
||||
this.clientBackspace();
|
||||
} else {
|
||||
var offset = -1;
|
||||
while(this.patternArrayPos > 0) {
|
||||
if(_.isRegExp(this.patternArray[this.patternArrayPos])) {
|
||||
this.text = this.text.substr(0, this.text.length - 1);
|
||||
this.client.term.write(ansi.goto(this.position.x, this.position.y + (this.text.length - offset)));
|
||||
// :TODO: use better ANSI Position code to just go back
|
||||
// this.client.term.write(ansi.goto(this.position.x, yPosition));
|
||||
|
||||
this.client.term.write(ansi.goto(this.position.x, this.getCursorEditYPosition() + 1));
|
||||
this.clientBackspace();
|
||||
break;
|
||||
}
|
||||
console.log('skip past ' + this.patternArray[this.patternArrayPos])
|
||||
//this.client.term.write(ansi.back() + ansi.back());
|
||||
this.patternArrayPos--;
|
||||
offset++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,8 +48,8 @@ function getMenuConfig(name, cb) {
|
|||
});
|
||||
},
|
||||
function locateMenuConfig(menuJson, callback) {
|
||||
if(_.isObject(menuJson[name])) {
|
||||
menuConfig = menuJson[name];
|
||||
if(_.has(menuJson, [ 'menus', name ])) {
|
||||
menuConfig = menuJson.menus[name];
|
||||
callback(null);
|
||||
} else {
|
||||
callback(new Error('No menu entry for \'' + name + '\''));
|
||||
|
@ -66,7 +66,7 @@ function getMenuConfig(name, cb) {
|
|||
},
|
||||
function locatePromptConfig(promptJson, callback) {
|
||||
if(promptJson) {
|
||||
if(_.isObject(promptJson[menuConfig.prompt])) {
|
||||
if(_.has(promptJson, [ 'prompts', menuConfig.prompt ])) {
|
||||
menuConfig.promptConfig = promptJson[menuConfig.prompt];
|
||||
} else {
|
||||
callback(new Error('No prompt entry for \'' + menuConfig.prompt + '\''));
|
||||
|
|
|
@ -538,7 +538,7 @@ TelnetClient.prototype.setTermType = function(ttype) {
|
|||
this.term.env['TERM'] = ttype;
|
||||
this.term.termType = ttype;
|
||||
|
||||
Log.debug({ termType : ttype }, 'Set terminal type');
|
||||
Log.debug( { termType : ttype }, 'Set terminal type');
|
||||
}
|
||||
|
||||
TelnetClient.prototype.handleSbCommand = function(evt) {
|
||||
|
@ -571,10 +571,10 @@ TelnetClient.prototype.handleSbCommand = function(evt) {
|
|||
self.setTermType(evt.envVars[name]);
|
||||
} else if('COLUMNS' === name && 0 === self.term.termWidth) {
|
||||
self.term.termWidth = parseInt(evt.envVars[name]);
|
||||
Log.debug({ termWidth : self.term.termWidth, updateSource : 'NEW-ENVIRON'}, 'Window width updated');
|
||||
Log.debug({ termWidth : self.term.termWidth, source : 'NEW-ENVIRON'}, 'Window width updated');
|
||||
} else if('ROWS' === name && 0 === self.term.termHeight) {
|
||||
self.term.termHeight = parseInt(evt.envVars[name]);
|
||||
Log.debug({ termHeight : self.term.termHeight, updateSource : 'NEW-ENVIRON'}, 'Window height updated');
|
||||
Log.debug({ termHeight : self.term.termHeight, source : 'NEW-ENVIRON'}, 'Window height updated');
|
||||
} else {
|
||||
if(name in self.term.env) {
|
||||
assert(evt.type === SB_COMMANDS.INFO);
|
||||
|
@ -604,7 +604,7 @@ TelnetClient.prototype.handleSbCommand = function(evt) {
|
|||
self.term.env['ROWS'] = evt.height;
|
||||
}
|
||||
|
||||
Log.debug({ termWidth : evt.width , termHeight : evt.height, updateSource : 'NAWS' }, 'Window size updated');
|
||||
Log.debug({ termWidth : evt.width , termHeight : evt.height, source : 'NAWS' }, 'Window size updated');
|
||||
} else {
|
||||
console.log('unhandled SB: ' + JSON.stringify(evt));
|
||||
}
|
||||
|
|
|
@ -194,16 +194,18 @@ function ViewController(options) {
|
|||
|
||||
setViewProp('maxLength');
|
||||
|
||||
|
||||
['styleSGR1', 'styleSGR2'].forEach(function styleSgr(style) {
|
||||
setViewProp(style, function(v) {
|
||||
//
|
||||
// styleSGRx: 1..25
|
||||
//
|
||||
for(var i = 1; i <= 25; i++) {
|
||||
setViewProp('styleSGR' + i, function(v) {
|
||||
if(_.isObject(v)) {
|
||||
view[style] = ansi.getSGRFromGraphicRendition(v, true);
|
||||
view['styleSGR' + i] = ansi.getSGRFromGraphicRendition(v, true);
|
||||
} else if(_.isString(v)) {
|
||||
view[style] = ansi.fromPipeCode(v);
|
||||
view['styleSGR' + i] = ansi.fromPipeCode(v);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
setViewProp('fillChar', function(v) {
|
||||
if(_.isNumber(v)) {
|
||||
|
|
|
@ -33,8 +33,9 @@
|
|||
}
|
||||
}
|
||||
*/
|
||||
"connected" : {
|
||||
"menus" : {
|
||||
"art" : "CONNECT",
|
||||
"connected" : {
|
||||
"next" : "matrix",
|
||||
"options" : {
|
||||
"cls" : true,
|
||||
|
@ -335,7 +336,8 @@
|
|||
"mci" : {
|
||||
"ME1" : {
|
||||
"maskPattern" : "##/##/##",
|
||||
"styleSGR1" : "|00|30|01"
|
||||
"styleSGR1" : "|00|30|01",
|
||||
"styleSGR2" : "|00|45|01"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -423,4 +425,5 @@
|
|||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
{
|
||||
"userCredentials" : {
|
||||
"prompts" : {
|
||||
"art" : "usercred",
|
||||
"userCredentials" : {
|
||||
"mci" : {
|
||||
"ET1" : {
|
||||
"argName" : "username",
|
||||
|
@ -33,7 +34,7 @@
|
|||
... better, a special prompt
|
||||
|
||||
GetKeyView
|
||||
* showKey : false
|
||||
* echoKey : false
|
||||
|
||||
*/
|
||||
},
|
||||
|
@ -67,5 +68,5 @@
|
|||
}
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue