From aa951c640f03fc6fc45dc1d5910520aebbe241dc Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Sun, 14 Jul 2013 22:11:48 -0500 Subject: [PATCH] use better cleanside detection algorithm. add insert method. --- lib/widget.js | 69 ++++++++++++++++++++++++++++++++++++++++++---- test/widget-csr.js | 68 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 5 deletions(-) create mode 100644 test/widget-csr.js diff --git a/lib/widget.js b/lib/widget.js index 70a04c9..2a077db 100644 --- a/lib/widget.js +++ b/lib/widget.js @@ -113,6 +113,59 @@ Node.prototype.append = function(element) { // }); }; +Node.prototype.insert = function(element, i) { + // var old = element.parent; + + element.detach(); + element.parent = this; + + if (this.type === 'screen' && !this.focused) { + this.focused = element; + } + + if (!~this.children.indexOf(element)) { + if (i === 0) { + this.children.unshift(element); + } else if (i === this.children.length) { + this.children.push(element); + } else { + this.children.splice(i, 0, element); + } + } + + element.emit('reparent', this); + this.emit('adopt', element); + + // 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; + // }); +}; + +Node.prototype.insertBefore = function(element, other) { + var i = this.children.indexOf(other); + if (~i) this.insert(element, i); +}; + +Node.prototype.insertAfter = function(element, other) { + var i = this.children.indexOf(other); + if (~i) this.insert(element, i + 1); +}; + +Node.prototype.prepend = function(element) { + this.insert(element, 0); +}; + +Node.prototype.append = function(element) { + this.insert(element, this.children.length); +}; + Node.prototype.remove = function(element) { element.parent = null; @@ -680,13 +733,14 @@ Screen.prototype.cleanSides = function(el) { var yi = pos.yi + (el.border ? 1 : 0) + el.padding , yl = pos.yl - (el.border ? 1 : 0) - el.padding - , first = this.olines[yi][pos.xi - 1] + , first , ch , x , y; - for (y = yi; y < yl; y++) { - for (x = pos.xi - 1; x >= 0; x--) { + for (x = pos.xi - 1; x >= 0; x--) { + first = this.olines[yi][x]; + for (y = yi; y < yl; y++) { ch = this.olines[y][x]; if (ch[0] !== first[0] || ch[1] !== first[1]) { return pos._cleanSides = false; @@ -694,8 +748,9 @@ Screen.prototype.cleanSides = function(el) { } } - for (y = yi; y < yl; y++) { - for (x = pos.xl; x < this.width; x++) { + for (x = pos.xl; x < this.width; x++) { + first = this.olines[yi][x]; + for (y = yi; y < yl; y++) { ch = this.olines[y][x]; if (ch[0] !== first[0] || ch[1] !== first[1]) { return pos._cleanSides = false; @@ -1266,6 +1321,10 @@ function Element(options) { var pname = props[0], over = props[1], out = props[2], temp = props[3]; self.screen.setEffects(self, self, over, out, self.options[pname], temp); }); + + if (options.focused) { + this.focus(); + } } Element.prototype.__proto__ = Node.prototype; diff --git a/test/widget-csr.js b/test/widget-csr.js new file mode 100644 index 0000000..e68ad16 --- /dev/null +++ b/test/widget-csr.js @@ -0,0 +1,68 @@ +var blessed = require('blessed') + , screen = blessed.screen({ dump: __dirname + '/p.log' }); + +var lorem = require('fs').readFileSync(__dirname + '/git.diff', 'utf8'); + +function expectClean(value) { + var cleanSides = screen.cleanSides; + screen.cleanSides = function() { + var ret = cleanSides.apply(this, arguments); + if (ret !== value) { + throw new Error('Failed. Expected ' + + value + ' from cleanSides. Got ' + + ret + '.'); + } + return ret; + }; +} + +blessed.box({ + parent: screen, + left: 0, + top: 'center', + width: '50%', + height: 2, + bg: 'green', + content: 'This will disallow CSR.' +}); +expectClean(false); + +/* +blessed.box({ + parent: screen, + left: 'center', + top: 'center', + width: '80%', + height: '80%', + bg: 'green', + border: { + type: 'ascii' + }, + content: 'CSR should still work.' +}); +expectClean(true); +*/ + +var text = blessed.scrollabletext({ + parent: screen, + content: lorem, + border: { + type: 'ascii' + }, + left: 'center', + top: 'center', + width: '100%', + width: '50%', + height: '50%', + mouse: true, + keys: true, + vi: true +}); + +text.focus(); + +screen.key('q', function() { + return process.exit(0); +}); + +screen.render();