fix bug when same folded row is shown twice while scrolling

and optimize usage of getRowFoldEnd
This commit is contained in:
nightwing 2011-05-10 20:54:44 +05:00
commit 3cd9162103
3 changed files with 97 additions and 19 deletions

View file

@ -191,7 +191,11 @@ function Folding() {
this.getFoldLine = function(docRow, startFoldLine) {
var foldData = this.$foldData;
var i = Math.max(foldData.indexOf(startFoldLine), 0);
var i = 0;
if(startFoldLine)
i = foldData.indexOf(startFoldLine);
if(i == -1)
i = 0;
for (i; i < foldData.length; i++) {
var foldLine = foldData[i];
if (foldLine.start.row <= docRow && foldLine.end.row >= docRow) {
@ -203,6 +207,47 @@ function Folding() {
return null;
}
// returns the fold which starts after or contains docRow
this.getNextFold = function(docRow, startFoldLine) {
var foldData = this.$foldData, ans;
var i = 0;
if(startFoldLine)
i = foldData.indexOf(startFoldLine);
if(i == -1)
i = 0;
for (i; i < foldData.length; i++) {
var foldLine = foldData[i];
if (foldLine.end.row >= docRow) {
return foldLine;
}
}
return null;
}
this.getFoldedRowCount = function(first, last) {
var foldData = this.$foldData, rowCount = last-first+1;
for (var i = 0; i < foldData.length; i++) {
var foldLine = foldData[i],
end = foldLine.end.row,
start = foldLine.start.row;
if(end >= last) {
if(start < last) {
if(start >= first)
rowCount -= last-start;
else
rowCount = 0;//in one fold
}
break;
} else if(end >= first){
if (start >= first) //fold inside range
rowCount -= end-start;
else
rowCount -= end-first+1;
}
}
return rowCount;
}
this.$addFoldLine = function(foldLine) {
this.$foldData.push(foldLine);
this.$foldData.sort(function(a, b) {
@ -428,6 +473,7 @@ function Folding() {
};
this.getRowFoldEnd = function(docRow, startFoldRow) {
//console.trace()
var foldLine = this.getFoldLine(docRow, startFoldRow);
return (foldLine
? foldLine.end.row
@ -484,4 +530,4 @@ function Folding() {
exports.Folding = Folding;
});
});

View file

@ -99,12 +99,22 @@ var Gutter = function(parentEl) {
this.update = function(config) {
this.$config = config;
var emptyAnno = {className: "", text: []};
var html = [];
for ( var i = config.firstRow; i <= config.lastRow; i++) {
var annotation = this.$annotations[i] || {
className: "",
text: []
};
var i = config.firstRow, lastRow = config.lastRow
fold = this.session.getNextFold(i),
foldStart = fold ?fold.start.row :Infinity;
while (true) {
if(i > foldStart) {
i = fold.end.row+1;
fold = this.session.getNextFold(i);
foldStart = fold ?fold.start.row :Infinity;
}
if(i > lastRow)
break;
var annotation = this.$annotations[i] || emptyAnno;
html.push("<div class='ace_gutter-cell",
this.$decorations[i] || "",
this.$breakpoints[i] ? " ace_breakpoint " : " ",
@ -112,10 +122,9 @@ var Gutter = function(parentEl) {
"' title='", annotation.text.join("\n"),
"' style='height:", this.session.getRowHeight(config, i), "px;'>", (i+1), "</div>");
i = this.session.getRowFoldEnd(i);
i++;
}
this.element = dom.setInnerHtml(this.element, html.join(""));
this.element = dom.setInnerHtml(this.element, html.join(""));
this.element.style.height = config.minHeight + "px";
};

View file

@ -230,13 +230,12 @@ var Text = function(parentEl) {
return this.update(config);
var el = this.element;
if (oldConfig.firstRow < config.firstRow)
for (var row=oldConfig.firstRow; row<config.firstRow; row = this.session.getRowFoldEnd(row) + 1)
for (var row=this.session.getFoldedRowCount(oldConfig.firstRow, config.firstRow - 1); row>0; row--)
el.removeChild(el.firstChild);
if (oldConfig.lastRow > config.lastRow)
for (var row=config.lastRow+1; row<=oldConfig.lastRow; row = this.session.getRowFoldEnd(row) + 1)
for (var row=this.session.getFoldedRowCount(config.lastRow + 1, oldConfig.lastRow); row>0; row--)
el.removeChild(el.lastChild);
if (config.firstRow < oldConfig.firstRow) {
@ -254,8 +253,20 @@ var Text = function(parentEl) {
};
this.$renderLinesFragment = function(config, firstRow, lastRow) {
var fragment = document.createDocumentFragment();
for (var row=firstRow; row<=lastRow; row++) {
var fragment = document.createDocumentFragment(),
row = firstRow,
fold = this.session.getNextFold(row),
foldStart = fold ?fold.start.row :Infinity;
while (true) {
if(row > foldStart) {
row = fold.end.row+1;
fold = this.session.getNextFold(row);
foldStart = fold ?fold.start.row :Infinity;
}
if(row > lastRow)
break;
var lineEl = dom.createElement("div");
lineEl.className = "ace_line";
@ -276,7 +287,7 @@ var Text = function(parentEl) {
lineEl.innerHTML = html.join("");
fragment.appendChild(lineEl);
row = this.session.getRowFoldEnd(row);
row++;
}
return fragment;
};
@ -287,9 +298,20 @@ var Text = function(parentEl) {
var html = [];
var firstRow = config.firstRow, lastRow = config.lastRow;
var tokens = this.session.getTokens(firstRow, lastRow)
for (var row=firstRow; row<=lastRow; row++) {
var row = firstRow,
fold = this.session.getNextFold(row),
foldStart = fold ?fold.start.row :Infinity;
while (true) {
if(row > foldStart) {
row = fold.end.row+1;
fold = this.session.getNextFold(row);
foldStart = fold ?fold.start.row :Infinity;
}
if(row > lastRow)
break;
html.push("<div class='ace_line' style='height:",
this.session.getRowHeight(config, row) + "px;", "width", config.width + "px'>"
)
@ -301,7 +323,8 @@ var Text = function(parentEl) {
if (tokens.length == 1)
this.$renderLine(html, row, tokens[0].tokens);
html.push("</div>")
row = this.session.getRowFoldEnd(row);
row++;
}
this.element = dom.setInnerHtml(this.element, html.join(""));
};