color names. tabs in textareas/boxes. cleanup old code. focus behavior.
This commit is contained in:
parent
150a7c2439
commit
3eb382e8f1
|
@ -190,6 +190,7 @@ var colorNames = exports.colorNames = {
|
|||
|
||||
exports.convert = function(color) {
|
||||
var val = colorNames[color];
|
||||
if (typeof val === 'string') val = val.replace(/[\- ]/g, '');
|
||||
if (val == null) val = color;
|
||||
if (val == null) val = -1;
|
||||
if (typeof val === 'string') {
|
||||
|
|
197
lib/widget.js
197
lib/widget.js
|
@ -25,7 +25,7 @@ function Node(options) {
|
|||
this.screen = this.screen
|
||||
|| Screen.global
|
||||
|| (function(){throw new Error('No active screen.')})();
|
||||
this.parent = options.parent || null; // this.screen;
|
||||
this.parent = options.parent || null;
|
||||
this.children = [];
|
||||
this.$ = this._ = this.data = {};
|
||||
this.uid = Node.uid++;
|
||||
|
@ -53,7 +53,7 @@ Node.prototype.__proto__ = EventEmitter.prototype;
|
|||
Node.prototype.type = 'node';
|
||||
|
||||
Node.prototype.prepend = function(element) {
|
||||
var old = element.parent;
|
||||
// var old = element.parent;
|
||||
|
||||
element.detach();
|
||||
element.parent = this;
|
||||
|
@ -69,20 +69,20 @@ Node.prototype.prepend = function(element) {
|
|||
element.emit('reparent', this);
|
||||
this.emit('adopt', element);
|
||||
|
||||
//if (!old) {
|
||||
// if (!old) {
|
||||
(function emit(el) {
|
||||
el._detached = false;
|
||||
el.emit('attach');
|
||||
if (el.children) el.children.forEach(emit);
|
||||
})(element);
|
||||
|
||||
//element.emitDescendants('attach', function(el) {
|
||||
// el._detached = false;
|
||||
//});
|
||||
// element.emitDescendants('attach', function(el) {
|
||||
// el._detached = false;
|
||||
// });
|
||||
};
|
||||
|
||||
Node.prototype.append = function(element) {
|
||||
var old = element.parent;
|
||||
// var old = element.parent;
|
||||
|
||||
element.detach();
|
||||
element.parent = this;
|
||||
|
@ -98,20 +98,20 @@ Node.prototype.append = function(element) {
|
|||
element.emit('reparent', this);
|
||||
this.emit('adopt', element);
|
||||
|
||||
//if (!old) {
|
||||
// if (!old) {
|
||||
(function emit(el) {
|
||||
el._detached = false;
|
||||
el.emit('attach');
|
||||
if (el.children) el.children.forEach(emit);
|
||||
})(element);
|
||||
|
||||
//element.emitDescendants('attach', function(el) {
|
||||
// el._detached = false;
|
||||
//});
|
||||
// element.emitDescendants('attach', function(el) {
|
||||
// el._detached = false;
|
||||
// });
|
||||
};
|
||||
|
||||
Node.prototype.remove = function(element) {
|
||||
element.parent = null; // this.screen;
|
||||
element.parent = null;
|
||||
|
||||
var i = this.children.indexOf(element);
|
||||
if (~i) {
|
||||
|
@ -138,9 +138,9 @@ Node.prototype.remove = function(element) {
|
|||
if (el.children) el.children.forEach(emit);
|
||||
})(element);
|
||||
|
||||
//element.emitDescendants('detach', function(el) {
|
||||
// el._detached = true;
|
||||
//});
|
||||
// element.emitDescendants('detach', function(el) {
|
||||
// el._detached = true;
|
||||
// });
|
||||
|
||||
// this.clearPos();
|
||||
};
|
||||
|
@ -237,7 +237,7 @@ function Screen(options) {
|
|||
bottom: this.bottom = this.rbottom = 0
|
||||
};
|
||||
|
||||
// this.focused = null;
|
||||
// this.focused;
|
||||
this.hover = null;
|
||||
this.history = [];
|
||||
this.clickable = [];
|
||||
|
@ -252,7 +252,6 @@ function Screen(options) {
|
|||
this.program.on('resize', function() {
|
||||
self.alloc();
|
||||
self.render();
|
||||
// self.emit('resize');
|
||||
(function emit(el) {
|
||||
el.emit('resize');
|
||||
if (el.children) {
|
||||
|
@ -429,6 +428,7 @@ Screen.prototype._listenKeys = function(el) {
|
|||
focused.emit('keypress', ch, key);
|
||||
focused.emit('key ' + key.name, ch, key);
|
||||
// self.emit('element keypress', focused, ch, key);
|
||||
// self.emit('element key ' + key.name, focused, ch, key);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -548,7 +548,7 @@ Screen.prototype.deleteBottom = function(top, bottom) {
|
|||
};
|
||||
|
||||
Screen.prototype.deleteTop = function(top, bottom) {
|
||||
// return this.insertBottom(top, bottom);
|
||||
// Same as: return this.insertBottom(top, bottom);
|
||||
return this.deleteLine(1, top, top, bottom);
|
||||
};
|
||||
|
||||
|
@ -1020,10 +1020,6 @@ function Element(options) {
|
|||
}
|
||||
});
|
||||
|
||||
// this.onScreenEvent('resize', function() {
|
||||
// self.parseContent();
|
||||
// });
|
||||
|
||||
this.on('resize', function() {
|
||||
self.parseContent();
|
||||
});
|
||||
|
@ -1051,9 +1047,7 @@ function Element(options) {
|
|||
this.on('mouseover', function() {
|
||||
Object.keys(effects).forEach(function(key) {
|
||||
var val = effects[key];
|
||||
//if (self._htemp[key] == null) {
|
||||
self._htemp[key] = self[key];
|
||||
//}
|
||||
self[key] = val;
|
||||
});
|
||||
self.screen.render();
|
||||
|
@ -1074,23 +1068,6 @@ Element.prototype.__proto__ = Node.prototype;
|
|||
|
||||
Element.prototype.type = 'element';
|
||||
|
||||
/*
|
||||
Element._emit = Element.prototype.emit;
|
||||
Element.prototype.emit = function(type) {
|
||||
var args = Array.prototype.slice.call(arguments)
|
||||
, ret = Element._emit.apply(this, args);
|
||||
|
||||
if (this.screen) {
|
||||
args.shift();
|
||||
args.unshift(this);
|
||||
args.unshift('element ' + type);
|
||||
this.screen.emit.apply(this.screen, args);
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
*/
|
||||
|
||||
Element.prototype.onScreenEvent = function(type, listener) {
|
||||
var self = this;
|
||||
if (this.parent) {
|
||||
|
@ -1109,17 +1086,16 @@ Element.prototype.hide = function() {
|
|||
this.hidden = true;
|
||||
this.clearPos();
|
||||
this.emit('hide');
|
||||
//if (this.screen.focused === this) {
|
||||
// this.screen.focusPop();
|
||||
// var el = this.screen.focusPop();
|
||||
// if (el) el.focus();
|
||||
//}
|
||||
|
||||
if (this.screen.focused === this && this.history[this.history.length-2]) {
|
||||
this.history[this.history.length-2].focus();
|
||||
}
|
||||
};
|
||||
|
||||
Element.prototype.show = function() {
|
||||
if (!this.hidden) return;
|
||||
this.hidden = false;
|
||||
//this.render();
|
||||
// this.render();
|
||||
this.emit('show');
|
||||
};
|
||||
|
||||
|
@ -1128,7 +1104,7 @@ Element.prototype.toggle = function() {
|
|||
};
|
||||
|
||||
Element.prototype.focus = function() {
|
||||
//if (this.screen.grabKeys || this.screen.lockKeys) return;
|
||||
// if (this.screen.grabKeys || this.screen.lockKeys) return;
|
||||
var old = this.screen.focused;
|
||||
this.screen.focused = this;
|
||||
old.emit('blur', this);
|
||||
|
@ -1154,6 +1130,7 @@ Element.prototype.parseContent = function() {
|
|||
// Could move these 2 lines back to setContent (?)
|
||||
content = content.replace(/\x1b(?!\[[\d;]*m)/g, '');
|
||||
content = this._parseTags(content || '');
|
||||
content = content.replace(/\t/g, ' ');
|
||||
this._clines = wrapContent(content, width, this.parseTags, this.align);
|
||||
this._clines.width = width;
|
||||
this._clines.content = this.content;
|
||||
|
@ -1584,10 +1561,8 @@ Box.prototype.render = function(stop) {
|
|||
|| this.options.right == null)) {
|
||||
if (this.options.left == null && this.options.right != null) {
|
||||
xi_ = xl - w - (this.border ? 2 : 0) - this.padding;
|
||||
//xi_--; // make it one cell wider for newlines
|
||||
} else {
|
||||
xl = xi_ + w + (this.border ? 2 : 0) + this.padding;
|
||||
//xl++; // make it one cell wider for newlines
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1741,25 +1716,9 @@ outer:
|
|||
}
|
||||
|
||||
if (this.border) {
|
||||
// var alt;
|
||||
// if (this.screen.tput
|
||||
// && this.screen.tput.strings.enter_alt_charset_mode
|
||||
// && this.border.type === 'ascii') {
|
||||
// //this.screen.program.put.smacs();
|
||||
// battr |= 32 << 18;
|
||||
// alt = true;
|
||||
// }
|
||||
|
||||
yi = yi_;
|
||||
for (xi = xi_; xi < xl; xi++) {
|
||||
if (!lines[yi]) break;
|
||||
|
||||
// if (alt) {
|
||||
// if (xi === xi_) ch = 'l';
|
||||
// else if (xi === xl - 1) ch = 'k';
|
||||
// else ch = 'q';
|
||||
// } else
|
||||
|
||||
if (this.border.type === 'ascii') {
|
||||
if (xi === xi_) ch = '┌';
|
||||
else if (xi === xl - 1) ch = '┐';
|
||||
|
@ -1778,11 +1737,6 @@ outer:
|
|||
yi = yi_ + 1;
|
||||
for (; yi < yl; yi++) {
|
||||
if (!lines[yi]) break;
|
||||
|
||||
// if (alt) {
|
||||
// ch = 'x';
|
||||
// } else
|
||||
|
||||
if (this.border.type === 'ascii') {
|
||||
ch = '│';
|
||||
} else if (this.border.type === 'bg') {
|
||||
|
@ -1806,13 +1760,6 @@ outer:
|
|||
yi = yl - 1;
|
||||
for (xi = xi_; xi < xl; xi++) {
|
||||
if (!lines[yi]) break;
|
||||
|
||||
// if (alt) {
|
||||
// if (xi === xi_) ch = 'm';
|
||||
// else if (xi === xl - 1) ch = 'j';
|
||||
// else ch = 'q';
|
||||
// } else
|
||||
|
||||
if (this.border.type === 'ascii') {
|
||||
if (xi === xi_) ch = '└';
|
||||
else if (xi === xl - 1) ch = '┘';
|
||||
|
@ -1828,11 +1775,6 @@ outer:
|
|||
lines[yi].dirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
// if (alt) {
|
||||
// //this.screen.program.put.rmacs();
|
||||
// battr &= ~(32 << 18);
|
||||
// }
|
||||
}
|
||||
|
||||
this.children.forEach(function(el) {
|
||||
|
@ -1970,8 +1912,9 @@ ScrollableBox.prototype.type = 'scrollable-box';
|
|||
|
||||
ScrollableBox.prototype.scroll = function(offset) {
|
||||
var visible = this.height - (this.border ? 2 : 0);
|
||||
|
||||
// Maybe do for lists:
|
||||
//if (this.items) visible = Math.min(this.items.length, visible);
|
||||
// if (this.items) visible = Math.min(this.items.length, visible);
|
||||
if (this.alwaysScroll) {
|
||||
// Semi-workaround
|
||||
this.childOffset = offset > 0
|
||||
|
@ -1980,6 +1923,7 @@ ScrollableBox.prototype.scroll = function(offset) {
|
|||
} else {
|
||||
this.childOffset += offset;
|
||||
}
|
||||
|
||||
if (this.childOffset > visible - 1) {
|
||||
var d = this.childOffset - (visible - 1);
|
||||
this.childOffset -= d;
|
||||
|
@ -1989,8 +1933,13 @@ ScrollableBox.prototype.scroll = function(offset) {
|
|||
this.childOffset += -d;
|
||||
this.childBase += d;
|
||||
}
|
||||
if (this.childBase < 0) this.childBase = 0;
|
||||
else if (this.childBase > this.baseLimit) this.childBase = this.baseLimit;
|
||||
|
||||
if (this.childBase < 0) {
|
||||
this.childBase = 0;
|
||||
} else if (this.childBase > this.baseLimit) {
|
||||
this.childBase = this.baseLimit;
|
||||
}
|
||||
|
||||
this.emit('scroll');
|
||||
};
|
||||
|
||||
|
@ -2128,7 +2077,7 @@ function List(options) {
|
|||
}
|
||||
}
|
||||
|
||||
//this.onScreenEvent('resize', resize);
|
||||
// this.onScreenEvent('resize', resize);
|
||||
|
||||
this.on('resize', resize);
|
||||
}
|
||||
|
@ -2364,6 +2313,7 @@ ScrollableText.prototype._recalculateIndex = function() {
|
|||
for (var i = 0, t = 0; i < this.childBase; i++) {
|
||||
t += this._clines[i].length + 1;
|
||||
}
|
||||
|
||||
this.contentIndex = t;
|
||||
};
|
||||
|
||||
|
@ -2405,7 +2355,6 @@ function Textbox(options) {
|
|||
this.on('move', updateCursor);
|
||||
|
||||
function updateCursor() {
|
||||
//if (!self.visible) return;
|
||||
if (self.screen.focused !== self) return;
|
||||
self.screen.program.cup(
|
||||
self.top + 1 + (self.border ? 1 : 0),
|
||||
|
@ -2421,13 +2370,18 @@ Textbox.prototype.type = 'textbox';
|
|||
Textbox.prototype.input =
|
||||
Textbox.prototype.readInput =
|
||||
Textbox.prototype.setInput = function(callback) {
|
||||
var self = this;
|
||||
var self = this
|
||||
, focused = this.screen.focused === this;
|
||||
|
||||
this.focus();
|
||||
if (!focused) {
|
||||
this.screen.saveFocus();
|
||||
this.focus();
|
||||
}
|
||||
|
||||
this.screen.grabKeys = true;
|
||||
|
||||
// this.screen.program.saveCursor();
|
||||
// Could possibly save and restore cursor.
|
||||
|
||||
this.screen.program.cup(
|
||||
this.top + 1 + (this.border ? 1 : 0),
|
||||
this.left + 1 + (this.border ? 1 : 0)
|
||||
|
@ -2436,13 +2390,12 @@ Textbox.prototype.setInput = function(callback) {
|
|||
this.screen.program.sgr('normal');
|
||||
|
||||
this._callback = function(err, value) {
|
||||
// self.screen.program.restoreCursor();
|
||||
self.screen.program.hideCursor();
|
||||
self.screen.grabKeys = false;
|
||||
|
||||
//self.screen.focusPop();
|
||||
//var el = self.screen.focusPop();
|
||||
//if (el) el.focus();
|
||||
if (!focused) {
|
||||
self.screen.restoreFocus();
|
||||
}
|
||||
|
||||
return err
|
||||
? callback(err)
|
||||
|
@ -2473,6 +2426,8 @@ Textbox.prototype._listener = function(ch, key) {
|
|||
}
|
||||
} else {
|
||||
if (ch) {
|
||||
// Tabs only work with textareas.
|
||||
if (ch === '\t') ch = ' ';
|
||||
this.value += ch;
|
||||
if (this.secret) return;
|
||||
if (this.value.length < this.width - (this.border ? 2 : 0)) {
|
||||
|
@ -2524,23 +2479,11 @@ Textbox.prototype.editor =
|
|||
Textbox.prototype.readEditor =
|
||||
Textbox.prototype.setEditor = function(callback) {
|
||||
var self = this;
|
||||
|
||||
this.focus();
|
||||
|
||||
return this.screen.readEditor({ value: this.value }, function(err, value) {
|
||||
if (err) return callback(err);
|
||||
value = value.replace(/[\r\n]/g, '');
|
||||
self.value = value;
|
||||
|
||||
////if (self.censor) {
|
||||
//// self.setContent(Array(self.value.length + 1).join('*'));
|
||||
////} else
|
||||
//if (!self.secret) {
|
||||
// self.setContent(value);
|
||||
//}
|
||||
//return callback(null, value);
|
||||
|
||||
return self.setInput(callback);
|
||||
return self.readInput(callback);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -2594,9 +2537,13 @@ Textarea.prototype.updateCursor = function() {
|
|||
Textarea.prototype.input =
|
||||
Textarea.prototype.readInput =
|
||||
Textarea.prototype.setInput = function(callback) {
|
||||
var self = this;
|
||||
var self = this
|
||||
, focused = this.screen.focused === this;
|
||||
|
||||
this.focus();
|
||||
if (!focused) {
|
||||
this.screen.saveFocus();
|
||||
this.focus();
|
||||
}
|
||||
|
||||
this.screen.grabKeys = true;
|
||||
|
||||
|
@ -2607,6 +2554,11 @@ Textarea.prototype.setInput = function(callback) {
|
|||
this._callback = function(err, value) {
|
||||
self.screen.program.hideCursor();
|
||||
self.screen.grabKeys = false;
|
||||
|
||||
if (!focused) {
|
||||
self.screen.restoreFocus();
|
||||
}
|
||||
|
||||
return err
|
||||
? callback(err)
|
||||
: callback(null, value);
|
||||
|
@ -2678,9 +2630,6 @@ Textarea.prototype.editor =
|
|||
Textarea.prototype.readEditor =
|
||||
Textarea.prototype.setEditor = function(callback) {
|
||||
var self = this;
|
||||
|
||||
this.focus();
|
||||
|
||||
return this.screen.readEditor({ value: this.value }, function(err, value) {
|
||||
if (err) return callback(err);
|
||||
self.value = value;
|
||||
|
@ -2688,7 +2637,7 @@ Textarea.prototype.setEditor = function(callback) {
|
|||
self._typeScroll();
|
||||
self.updateCursor();
|
||||
self.screen.render();
|
||||
return self.setInput(callback);
|
||||
return self.readInput(callback);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -2825,10 +2774,11 @@ ProgressBar.prototype.reset = function() {
|
|||
|
||||
// Convert an SGR string to our own attribute format.
|
||||
function attrCode(code, cur) {
|
||||
var flags = (cur >> 18) & 0x1ff;
|
||||
var fg = (cur >> 9) & 0x1ff;
|
||||
var bg = cur & 0x1ff;
|
||||
var c, i;
|
||||
var flags = (cur >> 18) & 0x1ff
|
||||
, fg = (cur >> 9) & 0x1ff
|
||||
, bg = cur & 0x1ff
|
||||
, c
|
||||
, i;
|
||||
|
||||
code = /^\x1b\[([\d;]*)m$/.exec(code);
|
||||
if (!code) return cur;
|
||||
|
@ -2967,9 +2917,6 @@ function wrapContent(content, width, tags, state) {
|
|||
while (line.length > width) {
|
||||
for (i = 0, total = 0; i < line.length; i++) {
|
||||
while (line[i] === '\x1b') {
|
||||
//var c = /^\x1b\[[\d;]*m/.exec(line.substring(i));
|
||||
//if (!c) { i++; break; }
|
||||
//i += c[0].length;
|
||||
while (line[i] && line[i++] !== 'm');
|
||||
}
|
||||
if (!line[i]) break;
|
||||
|
@ -2986,7 +2933,8 @@ function wrapContent(content, width, tags, state) {
|
|||
}
|
||||
}
|
||||
|
||||
i++; // FIX
|
||||
// XXX This shouldn't be required, but is.
|
||||
i++;
|
||||
|
||||
part = line.substring(0, i - 1);
|
||||
esc = /\x1b[\[\d;]*$/.exec(part);
|
||||
|
@ -2994,11 +2942,9 @@ function wrapContent(content, width, tags, state) {
|
|||
if (esc) {
|
||||
part = part.slice(0, -esc[0].length);
|
||||
line = line.substring(i - 1 - esc[0].length);
|
||||
//out.push(part);
|
||||
out.push(sp(part, width, align));
|
||||
} else {
|
||||
line = line.substring(i - 1);
|
||||
//out.push(part);
|
||||
out.push(sp(part, width, align));
|
||||
}
|
||||
}
|
||||
|
@ -3008,7 +2954,7 @@ function wrapContent(content, width, tags, state) {
|
|||
out[out.length-1] += line;
|
||||
return;
|
||||
}
|
||||
//out.push(line);
|
||||
|
||||
out.push(sp(line, width, align));
|
||||
});
|
||||
|
||||
|
@ -3039,6 +2985,7 @@ var colors = {
|
|||
|
||||
function convert(color) {
|
||||
var val = colors[color];
|
||||
if (typeof val === 'string') val = val.replace(/[\- ]/g, '');
|
||||
if (val == null) val = color;
|
||||
if (val == null) val = -1;
|
||||
//if (typeof val === 'string') val = Screen._findColor(val);
|
||||
|
|
Loading…
Reference in New Issue