From 42351724d31c425fc3f948fbbf3d85cd3c86958f Mon Sep 17 00:00:00 2001 From: Christopher Jeffrey Date: Thu, 18 Jul 2013 02:37:18 -0500 Subject: [PATCH] move wrapContent. --- lib/widget.js | 275 ++++++++++++++++++++++++++------------------------ 1 file changed, 142 insertions(+), 133 deletions(-) diff --git a/lib/widget.js b/lib/widget.js index a8b4b5c..7084a2c 100644 --- a/lib/widget.js +++ b/lib/widget.js @@ -690,6 +690,12 @@ Screen.prototype.cleanSides = function(el) { return false; } + // The scrollbar can't update properly, and there's also a + // chance that the scrollbar may get moved around senselessly. + if (this.scrollbar) { + return false; + } + var yi = pos.yi + (el.border ? 1 : 0) + el.padding , yl = pos.yl - (el.border ? 1 : 0) - el.padding , first @@ -1622,6 +1628,142 @@ Element.prototype._parseTags = function(text) { }); }; + +function sp(line, width, align) { + if (!align) return line; + + var len = line.replace(/\x1b\[[\d;]*m/g, '').length + , s = width - len; + + if (len === 0) return line; + if (s < 0) return line; + + if (align === 'center') { + s = Array(((s / 2) | 0) + 1).join(' '); + return s + line + s; + } else if (align === 'right') { + s = Array(s + 1).join(' '); + return s + line; + } + + return line; +} + +// TODO: Add text padding. +// TODO: Fix a bug where, in a box with a width of 3, `jjj` is: +// |jjj| +// But `jjjj` is: +// |jj | +// |jj | +// A possibly related bug: +// For some reason (see jitsu-ui): +// {red-fg}my-app2{/red-fg} gets wrapped to: +// {red-fg}my-app\n2{/red-fg} when my-app2 +// does not. Since escape codes are not printable +// characters, this means wrapContent is doing +// something wrong and determining length including +// at least 1 char from the escape code. +function wrapContent(content, width, tags, state, margin) { + var lines = content.split('\n') + , out = []; + + if (!content) { + out.push(content || ''); + return out; + } + + // Useful for textareas. + if (margin && width > 1) width--; + + lines.forEach(function(line) { + var align = state + , cap; + + if (tags) { + //if (cap = /^(\x1b\[[\d;]*m)*^{(left|center|right)}/.exec(line)) { + // line = (cap[1] || '') + line.substring(cap[0].length); + // align = state = cap[2] !== 'left' + // ? cap[2] + // : null; + //} + + //if (cap = /{\/(left|center|right)}(\x1b\[[\d;]*m)*$/.exec(line)) { + // line = line.slice(0, -cap[0].length) + (cap[2] || ''); + // state = null; + //} + + if (cap = /^{(left|center|right)}/.exec(line)) { + line = line.substring(cap[0].length); + align = state = cap[1] !== 'left' + ? cap[1] + : null; + } + + if (cap = /{\/(left|center|right)}$/.exec(line)) { + line = line.slice(0, -cap[0].length); + state = null; + } + } + + var total + , i + , part + , esc; + + while (line.length > width) { + for (i = 0, total = 0; i < line.length; i++) { + while (line[i] === '\x1b') { + while (line[i] && line[i++] !== 'm'); + } + if (!line[i]) break; + if (++total === width) { + // Try to find a space to break on: + if (line[i] !== ' ') { + var j = i; + while (j > i - 10 && j > 0 && line[j] !== ' ') j--; + if (line[j] === ' ') i = j + 1; + else i++; + } else { + i++; + } + break; + } + } + + // XXX This shouldn't be required, but is. + i++; + + part = line.substring(0, i - 1); + esc = /\x1b[\[\d;]*$/.exec(part); + + if (esc) { + part = part.slice(0, -esc[0].length); + line = line.substring(i - 1 - esc[0].length); + out.push(sp(part, width, align)); + } else { + line = line.substring(i - 1); + out.push(sp(part, width, align)); + } + + // Make sure we didn't wrap the line to the very end, otherwise + // we get a pointless empty line after a newline. + if (line === '') return; + } + + // If only an escape code got cut off, at it to `part`. + if (/^(?:\x1b[\[\d;]*m)+$/.test(line)) { + out[out.length-1] += line; + return; + } + + out.push(sp(line, width, align)); + }); + + return out; +} + + + Element.prototype.__defineGetter__('visible', function() { var el = this; do { @@ -4701,139 +4843,6 @@ Passbox.prototype.type = 'passbox'; * Helpers */ -function sp(line, width, align) { - if (!align) return line; - - var len = line.replace(/\x1b\[[\d;]*m/g, '').length - , s = width - len; - - if (len === 0) return line; - if (s < 0) return line; - - if (align === 'center') { - s = Array(((s / 2) | 0) + 1).join(' '); - return s + line + s; - } else if (align === 'right') { - s = Array(s + 1).join(' '); - return s + line; - } - - return line; -} - -// TODO: Add text padding. -// TODO: Fix a bug where, in a box with a width of 3, `jjj` is: -// |jjj| -// But `jjjj` is: -// |jj | -// |jj | -// A possibly related bug: -// For some reason (see jitsu-ui): -// {red-fg}my-app2{/red-fg} gets wrapped to: -// {red-fg}my-app\n2{/red-fg} when my-app2 -// does not. Since escape codes are not printable -// characters, this means wrapContent is doing -// something wrong and determining length including -// at least 1 char from the escape code. -function wrapContent(content, width, tags, state, margin) { - var lines = content.split('\n') - , out = []; - - if (!content) { - out.push(content || ''); - return out; - } - - // Useful for textareas. - if (margin && width > 1) width--; - - lines.forEach(function(line) { - var align = state - , cap; - - if (tags) { - //if (cap = /^(\x1b\[[\d;]*m)*^{(left|center|right)}/.exec(line)) { - // line = (cap[1] || '') + line.substring(cap[0].length); - // align = state = cap[2] !== 'left' - // ? cap[2] - // : null; - //} - - //if (cap = /{\/(left|center|right)}(\x1b\[[\d;]*m)*$/.exec(line)) { - // line = line.slice(0, -cap[0].length) + (cap[2] || ''); - // state = null; - //} - - if (cap = /^{(left|center|right)}/.exec(line)) { - line = line.substring(cap[0].length); - align = state = cap[1] !== 'left' - ? cap[1] - : null; - } - - if (cap = /{\/(left|center|right)}$/.exec(line)) { - line = line.slice(0, -cap[0].length); - state = null; - } - } - - var total - , i - , part - , esc; - - while (line.length > width) { - for (i = 0, total = 0; i < line.length; i++) { - while (line[i] === '\x1b') { - while (line[i] && line[i++] !== 'm'); - } - if (!line[i]) break; - if (++total === width) { - // Try to find a space to break on: - if (line[i] !== ' ') { - var j = i; - while (j > i - 10 && j > 0 && line[j] !== ' ') j--; - if (line[j] === ' ') i = j + 1; - else i++; - } else { - i++; - } - break; - } - } - - // XXX This shouldn't be required, but is. - i++; - - part = line.substring(0, i - 1); - esc = /\x1b[\[\d;]*$/.exec(part); - - if (esc) { - part = part.slice(0, -esc[0].length); - line = line.substring(i - 1 - esc[0].length); - out.push(sp(part, width, align)); - } else { - line = line.substring(i - 1); - out.push(sp(part, width, align)); - } - - // Make sure we didn't wrap the line to the very end, otherwise - // we get a pointless empty line after a newline. - if (line === '') return; - } - - // If only an escape code got cut off, at it to `part`. - if (/^(?:\x1b[\[\d;]*m)+$/.test(line)) { - out[out.length-1] += line; - return; - } - - out.push(sp(line, width, align)); - }); - - return out; -} - function asort(obj) { return obj.sort(function(a, b) { a = a.name.toLowerCase();