Refacored text rendering code a little bit. About to lift of code folding rendering.
This commit is contained in:
parent
c010348eae
commit
e0d01ffa95
3 changed files with 80 additions and 48 deletions
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 "<span class='ace_invisible'>" + space + "</span>";
|
||||
} else {
|
||||
return " ";
|
||||
}
|
||||
} 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(" ");
|
||||
} 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 "<span class='ace_invisible'>" + space + "</span>";
|
||||
} else {
|
||||
return " "
|
||||
}
|
||||
} 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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue