Refacored text rendering code a little bit. About to lift of code folding rendering.

This commit is contained in:
Julian Viereck 2011-04-23 02:39:41 +02:00
commit e0d01ffa95
3 changed files with 80 additions and 48 deletions

View file

@ -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() {

View file

@ -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) {

View file

@ -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("&#160;");
} else if (c == "\t") {
var tabSize = self.session.
getScreenTabSize(screenColumn + tabIdx);
screenColumn += tabSize - 1;
return self.$tabStrings[tabSize];
} else if (c == "&") {
return "&amp";
} else if (c == "<") {
return "&lt;";
} 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 "<span class='ace_invisible'>" + space + "</span>";
} else {
return "&#160;";
}
} else {
screenColumn += 1;
return "<span class='ace_cjk' style='width:" + (
self.config.characterWidth * 2) +
"px'>" + c + "</span>";
}
}
var _self = this,
var output = value.replace(replaceReg, replaceFunc);
if (!this.$textToken[token.type]) {
var classes = "ace_" + token.type.replace(/\./g, " ace_");
stringBuilder.push("<span class='", classes, "'>", output, "</span>");
}
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("&#160;");
} else if (c == "\t") {
var tabSize = _self.session.
getScreenTabSize(screenColumn + tabIdx);
screenColumn += tabSize - 1;
return _self.$tabStrings[tabSize];
} else if (c == "&") {
return "&amp";
} else if (c == "<") {
return "&lt;";
} 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 "<span class='ace_invisible'>" + space + "</span>";
} else {
return "&#160;"
}
} else {
screenColumn += 1;
return "<span class='ace_cjk' style='width:" + (characterWidth * 2) + "px'>" + c + "</span>"
}
});
screenColumn += value.length;
if (!_self.$textToken[token.type]) {
var classes = "ace_" + token.type.replace(/\./g, " ace_");
stringBuilder.push("<span class='", classes, "'>", output, "</span>");
}
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("<span class='ace_invisible'>" + this.EOL_CHAR + "</span>");
} else {
stringBuilder.push("<span class='ace_invisible'>" + this.EOF_CHAR + "</span>");
}
}
stringBuilder.push("</div>");
}
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;