diff --git a/lib/widget.js b/lib/widget.js index bb43ee1..85471a3 100644 --- a/lib/widget.js +++ b/lib/widget.js @@ -135,8 +135,8 @@ Node.prototype.remove = function(element) { //}); }; -Node.prototype.detach = function(element) { - this.parent.remove(element); +Node.prototype.detach = function() { + this.parent.remove(this); }; Node.prototype.emitDescendants = function() { @@ -1353,7 +1353,7 @@ Box.prototype.render = function(stop) { attr = dattr; // Check previous line for escape codes. - if (this.childBase > 0 && this._clines) { + if (this.contentIndex != null && this.childBase > 0 && this._clines) { var cci = ci - (this._clines[this.childBase - 1].length + 1); for (; cci < ci; cci++) { if (content[cci] === '\x1b') { @@ -1505,6 +1505,24 @@ outer: return ret; }; +// Create a much more efficient rendering by using insert-line, +// delete-line, and change screen region codes when possible. +Box.prototype.insertTop = function(line) { + if (!this._lastPos) return; + if (this._lastPos.xi === 0 && this._lastPos.xl === this.screen.width) { + this.screen.insertTop(this._lastPos.yi, this._lastPos.yl - 1); + } + this.setContent(line + '\n' + this.content); +}; + +Box.prototype.insertBottom = function(line) { + if (!this._lastPos) return; + if (this._lastPos.xi === 0 && this._lastPos.xl === this.screen.width) { + this.screen.insertBottom(this._lastPos.yi, this._lastPos.yl - 1); + } + this.setContent(this.content + '\n' + line); +}; + /** * Text */ @@ -1969,6 +1987,7 @@ function Textbox(options) { Input.call(this, options); this.screen._listenKeys(this); this.value = options.value || ''; + this.secret = options.secret; } Textbox.prototype.__proto__ = Input.prototype; @@ -2027,6 +2046,7 @@ Textbox.prototype._listener = function(ch, key) { } else if (key.name === 'backspace') { if (this.value.length) { this.value = this.value.slice(0, -1); + if (this.secret) return; if (this.value.length < this.width - (this.border ? 2 : 0) - 1) { this.screen.program.cub(); } @@ -2034,6 +2054,7 @@ Textbox.prototype._listener = function(ch, key) { } else { if (ch) { this.value += ch; + if (this.secret) return; if (this.value.length < this.width - (this.border ? 2 : 0)) { this.screen.program.cuf(); } @@ -2049,11 +2070,24 @@ Textbox.prototype._listener = function(ch, key) { this.screen.render(); }; +Textbox.prototype.submit = function() { + return this._listener(null, { name: 'enter' }); +}; + +Textbox.prototype.cancel = function() { + return this._listener('\x1b', { name: 'escape' }); +}; + Textbox.prototype._render = Input.prototype.render; Textbox.prototype.render = function(stop) { // setContent is necessary to clear the area in case // .shrink is being used and the new content is smaller. // Could technically optimize this. + if (this.secret) { + this.setContent(''); + //this.setContent(Array(this.value.length + 1).join('*')); + return this._render(stop); + } this.setContent(this.value.slice(-(this.width - (this.border ? 2 : 0) - 1))); return this._render(stop); }; @@ -2074,7 +2108,9 @@ Textbox.prototype.setEditor = function(callback) { if (err) return callback(err); value = value.replace(/[\r\n]/g, ''); self.value = value; - self.setContent(value); + if (!self.secret) { + self.setContent(value); + } //return callback(null, value); return self.setInput(callback); });