diff --git a/demo/demo.js b/demo/demo.js
index 67ee5c86..896518bf 100644
--- a/demo/demo.js
+++ b/demo/demo.js
@@ -149,7 +149,7 @@ exports.launch = function(env) {
// BEGING TESTING
var Range = require("ace/range").Range;
- docs.js.addFold(new Range(1,0, 2, 999), "foo...");
+ docs.js.addFold(new Range(1, 10, 2, 999), "foo...");
window.s = docs.js;
window.e = env.editor;
setTimeout(function() {
diff --git a/lib/ace/edit_session.js b/lib/ace/edit_session.js
index 55d48473..7a2d0dbc 100644
--- a/lib/ace/edit_session.js
+++ b/lib/ace/edit_session.js
@@ -1417,7 +1417,7 @@ var EditSession = function(text, mode) {
* folded parts such that some parts of the line is still visible.
**/
this.isRowFolded = function(docRow) {
- return this.$foldData[docRow];
+ return !!this.$foldData[docRow];
};
this.getRowLastFold = function(docRow) {
diff --git a/lib/ace/layer/text.js b/lib/ace/layer/text.js
index 50bf0f5c..68c350cc 100644
--- a/lib/ace/layer/text.js
+++ b/lib/ace/layer/text.js
@@ -270,6 +270,8 @@ var Text = function(parentEl) {
// don't use setInnerHtml since we are working with an empty DIV
lineEl.innerHTML = html.join("");
fragment.appendChild(lineEl);
+
+ row = this.session.getRowFoldEnd(row);
}
return fragment;
};
@@ -293,58 +295,61 @@ var Text = function(parentEl) {
"lparen": true
};
- this.$renderLine = function(stringBuilder, row, tokens) {
- // Nothing to do if the entire line is folded.
- // TODO: Remove this, once the folding feature is done. Only for
- // developing stuff at the moment.
- if (!this.session.isRowVisible(row)) {
- throw "Calling renderLine on folded line doesn't make sense?";
+ this.$renderToken = function(stringBuilder, screenColumn, token, value) {
+ var self = this;
+ var replaceReg = /\t|&|<|( +)|([\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000])|[\u1100-\u115F]|[\u11A3-\u11A7]|[\u11FA-\u11FF]|[\u2329-\u232A]|[\u2E80-\u2E99]|[\u2E9B-\u2EF3]|[\u2F00-\u2FD5]|[\u2FF0-\u2FFB]|[\u3000-\u303E]|[\u3041-\u3096]|[\u3099-\u30FF]|[\u3105-\u312D]|[\u3131-\u318E]|[\u3190-\u31BA]|[\u31C0-\u31E3]|[\u31F0-\u321E]|[\u3220-\u3247]|[\u3250-\u32FE]|[\u3300-\u4DBF]|[\u4E00-\uA48C]|[\uA490-\uA4C6]|[\uA960-\uA97C]|[\uAC00-\uD7A3]|[\uD7B0-\uD7C6]|[\uD7CB-\uD7FB]|[\uF900-\uFAFF]|[\uFE10-\uFE19]|[\uFE30-\uFE52]|[\uFE54-\uFE66]|[\uFE68-\uFE6B]|[\uFF01-\uFF60]|[\uFFE0-\uFFE6]/g;
+ var replaceFunc = function(c, a, b, tabIdx, idx4) {
+ if (c.charCodeAt(0) == 32) {
+ return new Array(c.length+1).join(" ");
+ } else if (c == "\t") {
+ var tabSize = self.session.
+ getScreenTabSize(screenColumn + tabIdx);
+ screenColumn += tabSize - 1;
+ return self.$tabStrings[tabSize];
+ } else if (c == "&") {
+ return "&";
+ } else if (c == "<") {
+ return "<";
+ } else if (c.match(/[\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]/)) {
+ if (self.showInvisibles) {
+ var space = new Array(c.length+1).join(self.SPACE_CHAR);
+ return "" + space + "";
+ } else {
+ return " ";
+ }
+ } else {
+ screenColumn += 1;
+ return "" + c + "";
+ }
}
- var _self = this,
+ var output = value.replace(replaceReg, replaceFunc);
+
+ if (!this.$textToken[token.type]) {
+ var classes = "ace_" + token.type.replace(/\./g, " ace_");
+ stringBuilder.push("", output, "");
+ }
+ else {
+ stringBuilder.push(output);
+ }
+ return value.length;
+ }
+
+ this.$renderLineCore = function(stringBuilder, lastRow, tokens, splits) {
+ var chars = 0,
+ split = 0,
+ splitChars,
characterWidth = this.config.characterWidth,
- screenColumn = 0;
+ screenColumn = 0,
+ self = this;
function addToken(token, value) {
- var output = value
- .replace(/\t|&|<|( +)|([\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000])|[\u1100-\u115F]|[\u11A3-\u11A7]|[\u11FA-\u11FF]|[\u2329-\u232A]|[\u2E80-\u2E99]|[\u2E9B-\u2EF3]|[\u2F00-\u2FD5]|[\u2FF0-\u2FFB]|[\u3000-\u303E]|[\u3041-\u3096]|[\u3099-\u30FF]|[\u3105-\u312D]|[\u3131-\u318E]|[\u3190-\u31BA]|[\u31C0-\u31E3]|[\u31F0-\u321E]|[\u3220-\u3247]|[\u3250-\u32FE]|[\u3300-\u4DBF]|[\u4E00-\uA48C]|[\uA490-\uA4C6]|[\uA960-\uA97C]|[\uAC00-\uD7A3]|[\uD7B0-\uD7C6]|[\uD7CB-\uD7FB]|[\uF900-\uFAFF]|[\uFE10-\uFE19]|[\uFE30-\uFE52]|[\uFE54-\uFE66]|[\uFE68-\uFE6B]|[\uFF01-\uFF60]|[\uFFE0-\uFFE6]/g, function(c, a, b, tabIdx, idx4) {
- if (c.charCodeAt(0) == 32) {
- return new Array(c.length+1).join(" ");
- } else if (c == "\t") {
- var tabSize = _self.session.
- getScreenTabSize(screenColumn + tabIdx);
- screenColumn += tabSize - 1;
- return _self.$tabStrings[tabSize];
- } else if (c == "&") {
- return "&";
- } else if (c == "<") {
- return "<";
- } else if (c.match(/[\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]/)) {
- if (this.showInvisibles) {
- var space = new Array(c.length+1).join(self.SPACE_CHAR);
- return "" + space + "";
- } else {
- return " "
- }
- } else {
- screenColumn += 1;
- return "" + c + ""
- }
- });
- screenColumn += value.length;
-
- if (!_self.$textToken[token.type]) {
- var classes = "ace_" + token.type.replace(/\./g, " ace_");
- stringBuilder.push("", output, "");
- }
- else {
- stringBuilder.push(output);
- }
+ screenColumn += self.$renderToken(
+ stringBuilder, screenColumn, token, value);
}
- var splits = this.session.getRowSplitData(row);
- var chars = 0, split = 0, splitChars;
-
if (!splits || splits.length == 0) {
splitChars = Number.MAX_VALUE;
} else {
@@ -383,15 +388,42 @@ var Text = function(parentEl) {
};
if (this.showInvisibles) {
- if (row !== this.session.getLength() - 1) {
+ if (lastRow !== this.session.getLength() - 1) {
stringBuilder.push("" + this.EOL_CHAR + "");
} else {
stringBuilder.push("" + this.EOF_CHAR + "");
}
}
stringBuilder.push("");
+ }
+
+ this.$renderLine = function(stringBuilder, row, tokens) {
+ // Nothing to do if the entire line is folded.
+ // TODO: Remove this, once the folding feature is done. Only for
+ // developing stuff at the moment.
+ if (!this.session.isRowVisible(row)) {
+ throw "Calling renderLine on folded line doesn't make sense?";
+ }
+
+ // Check if the line to render is folded or not. If not, things are
+ // simple, otherwise, we need to fake some things...
+ if (!this.session.isRowFolded(row)) {
+ var splits = this.session.getRowSplitData(row);
+ this.$renderLineCore(stringBuilder, row, tokens, splits)
+ } else {
+ this.$renderFoldLine(stringBuilder, row, tokens, splits);
+ }
};
+ this.$renderFoldLine = function(stringBuilder, row, tokens) {
+ // TODO: Build a fake tokens array!
+ // TODO: Build a fake splits array!
+ var splits
+ var tokens;
+ var lastRow;
+ this.$renderLineCore(stringBuilder, lastRow, tokens, splits);
+ }
+
}).call(Text.prototype);
exports.Text = Text;