addFold must not throw if new fold is inside the existing one

This commit is contained in:
nightwing 2011-11-28 00:20:33 +04:00
commit 77dfd0b29c
7 changed files with 106 additions and 37 deletions

View file

@ -74,6 +74,42 @@ var Fold = exports.Fold = function(range, placeholder) {
return fold;
};
this.addSubFold = function(fold) {
if (this.range.isEequal(fold))
return this;
if (!this.range.containsRange(fold))
throw "A fold can't intersect already existing fold" + fold.range + this.range;
var row = fold.range.start.row, column = fold.range.start.column;
for (var i = 0, cmp = -1; i < this.subFolds.length; i++) {
cmp = this.subFolds[i].range.compare(row, column);
if (cmp != 1)
break;
}
var afterStart = this.subFolds[i];
if (cmp == 0)
return afterStart.addSubFold(fold)
// cmp == -1
var row = fold.range.end.row, column = fold.range.end.column;
for (var j = i, cmp = -1; j < this.subFolds.length; j++) {
cmp = this.subFolds[j].range.compare(row, column);
if (cmp != 1)
break;
}
var afterEnd = this.subFolds[j];
if (cmp == 0)
throw "A fold can't intersect already existing fold" + fold.range + this.range;
var consumedFolds = this.subFolds.splice(i, j - i, fold)
fold.setFoldLine(this.foldLine);
return fold;
}
}).call(Fold.prototype);
});

View file

@ -41,7 +41,7 @@ define(function(require, exports, module) {
var Range = require("../range").Range;
/**
* If the an array is passed in, the folds are expected to be sorted already.
* If an array is passed in, the folds are expected to be sorted already.
*/
function FoldLine(foldData, folds) {
this.foldData = foldData;

View file

@ -247,6 +247,8 @@ function Folding() {
else
fold = new Fold(range, placeholder);
this.$clipRangeToDocument(fold.range);
var startRow = fold.start.row;
var startColumn = fold.start.column;
var endRow = fold.end.row;
@ -259,29 +261,18 @@ function Folding() {
if (startRow == endRow && endColumn - startColumn < 2)
throw "The range has to be at least 2 characters width";
var existingFold = this.getFoldAt(startRow, startColumn, 1);
var startFold = this.getFoldAt(startRow, startColumn, 1);
var endFold = this.getFoldAt(endRow, endColumn, -1);
if (startFold && endFold == startFold)
return startFold.addSubFold(fold);
if (
existingFold
&& existingFold.range.isEnd(endRow, endColumn)
&& existingFold.range.isStart(startRow, startColumn)
(startFold && !startFold.range.isStart(startRow, startColumn))
|| (endFold && !endFold.range.isEnd(endRow, endColumn))
) {
return fold;
throw "A fold can't intersect already existing fold" + fold.range + startFold.range;
}
existingFold = this.getFoldAt(startRow, startColumn, 1);
if (existingFold && !existingFold.range.isStart(startRow, startColumn))
throw "A fold can't start inside of an already existing fold";
existingFold = this.getFoldAt(endRow, endColumn, -1);
if (existingFold && !existingFold.range.isEnd(endRow, endColumn))
throw "A fold can't end inside of an already existing fold";
if (endRow >= this.doc.getLength())
throw "End of fold is outside of the document.";
if (endColumn > this.getLine(endRow).length || startColumn > this.getLine(startRow).length)
throw "End of fold is outside of the document.";
// Check if there are folds in the range we create the new fold for.
var folds = this.getFoldsInRange(fold.range);
if (folds.length > 0) {