Refactor: replace range map with a proper object

This commit is contained in:
Fabian Jakobs 2010-05-04 11:34:38 +02:00
commit cc0c16ca6f
10 changed files with 187 additions and 139 deletions

View file

@ -59,6 +59,7 @@
<script src="../src/ace/mode/MatchingBraceOutdent.js" type="text/javascript" charset="utf-8"></script>
<script src="../src/ace/MEventEmitter.js" type="text/javascript" charset="utf-8"></script>
<script src="../src/ace/Search.js" type="text/javascript" charset="utf-8"></script>
<script src="../src/ace/Range.js" type="text/javascript" charset="utf-8"></script>
<script src="../src/ace/Selection.js" type="text/javascript" charset="utf-8"></script>
<script src="../src/ace/UndoManager.js" type="text/javascript" charset="utf-8"></script>
<script src="../src/ace/Document.js" type="text/javascript" charset="utf-8"></script>

View file

@ -312,16 +312,7 @@ ace.Document = function(text, mode) {
var nl = this.$getNewLineCharacter();
this.$deltas.push({
type: "insert",
range: {
start: {
row: row,
column: 0
},
end: {
row: row + lines.length,
column: 0
}
},
range: new ace.Range(row, 0, row + lines.length, 0),
text: lines.join(nl) + nl
});
this.$informUndoManager.schedule();
@ -378,10 +369,7 @@ ace.Document = function(text, mode) {
var nl = this.$getNewLineCharacter();
this.$deltas.push({
type: "insert",
range: {
start: ace.copyObject(position),
end: ace.copyObject(end)
},
range: ace.Range.fromPoints(position, end),
text: text
});
this.$informUndoManager.schedule();
@ -398,7 +386,7 @@ ace.Document = function(text, mode) {
this.$remove(range, fromUndo);
this.fireChangeEvent(range.start.row,
range.end.row == range.start.row ? range.start.row
!range.isMultiLine() ? range.start.row
: undefined);
return range.start;
@ -409,10 +397,7 @@ ace.Document = function(text, mode) {
var nl = this.$getNewLineCharacter();
this.$deltas.push({
type: "remove",
range: {
start: ace.copyObject(range.start),
end: ace.copyObject(range.end)
},
range: range.clone(),
text: this.getTextRange(range)
});
this.$informUndoManager.schedule();
@ -423,8 +408,8 @@ ace.Document = function(text, mode) {
var firstRow = range.start.row;
var lastRow = range.end.row;
var row = this.lines[firstRow].substring(0, range.start.column)
+ this.lines[lastRow].substring(range.end.column);
var row = this.getLine(firstRow).substring(0, range.start.column)
+ this.getLine(lastRow).substring(range.end.column);
this.lines.splice(firstRow, lastRow - firstRow + 1, row);
@ -438,6 +423,7 @@ ace.Document = function(text, mode) {
var delta = deltas[i];
if (delta.type == "insert") {
this.remove(delta.range, true);
this.selection.clearSelection();
this.selection.moveCursorToPosition(delta.range.start);
} else {
this.insert(delta.range.start, delta.text, true);
@ -494,14 +480,7 @@ ace.Document = function(text, mode) {
}
}
var deleteRange = {
start: {
column: 0
},
end: {
column: outdentLength
}
};
var deleteRange = new ace.Range(0, 0, 0, outdentLength);
for (var i=range.start.row; i<= range.end.row; i++)
{

View file

@ -107,13 +107,7 @@ ace.Editor = function(renderer, doc) {
var pos = self.doc.findMatchingBracket(self.getCursorPosition());
if (pos) {
range = {
start: pos,
end: {
row: pos.row,
column: pos.column+1
}
};
range = new ace.Range(pos.row, pos.column, pos.row, pos.column=1);
self.$bracketHighlight = self.renderer.addMarker(range, "bracket");
}
}, 10);
@ -166,16 +160,7 @@ ace.Editor = function(renderer, doc) {
if (this.getHighlightActiveLine() && !this.selection.isMultiLine()) {
var cursor = this.getCursorPosition();
var range = {
start: {
row: cursor.row,
column: 0
},
end: {
row: cursor.row+1,
column: 0
}
};
var range = new ace.Range(cursor.row, 0, cursor.row+1, 0);
this.$highlightLineMarker = this.renderer.addMarker(range, "active_line", "line");
}
};
@ -296,13 +281,8 @@ ace.Editor = function(renderer, doc) {
var cursor = this.doc.remove(this.getSelectionRange());
this.clearSelection();
} else if (this.$overwrite){
var range = {
start: cursor,
end: {
row: cursor.row,
column: cursor.column + text.length
}
};
var range = new ace.Range.fromPoints(cursor, cursor);
range.end.column += text.length;
this.doc.remove(range);
}
@ -321,13 +301,7 @@ ace.Editor = function(renderer, doc) {
if (row !== end.row) {
var indent = this.mode.getNextLineIndent(lineState, line, this.doc.getTabString());
if (indent) {
var indentRange = {
start: {
row: row+1,
column: 0
},
end : end
};
var indentRange = new ace.Range(row+1, 0, end.row, end.column);
end.column += this.doc.indentRows(indentRange, indent);
}
} else {
@ -454,16 +428,7 @@ ace.Editor = function(renderer, doc) {
var rows = this.$getSelectedRows();
var range = {
start: {
row: rows.first,
column: 0
},
end: {
row: rows.last,
column: 0
}
};
var range = new ace.Range(rows.first, 0, rows.last, 0);
var state = this.bgTokenizer.getState(this.getCursorPosition().row);
var addedColumns = this.mode.toggleCommentLines(state, this.doc, range);

65
src/ace/Range.js Normal file
View file

@ -0,0 +1,65 @@
ace.provide("ace.Range");
ace.Range = function(startRow, startColumn, endRow, endColumn) {
this.start = {
row: startRow,
column: startColumn
};
this.end = {
row: endRow,
column: endColumn
};
};
(function() {
this.clipRows = function(firstRow, lastRow) {
if (this.end.row > lastRow) {
this.end = {
row: lastRow+1,
column: 0
};
}
if (this.start.row > lastRow) {
this.start = {
row: lastRow+1,
column: 0
};
}
if (this.start.row < firstRow) {
this.start = {
row: firstRow,
column: 0
};
}
if (this.end.row < firstRow) {
this.end = {
row: firstRow,
column: 0
};
}
return this;
};
this.isEmpty = function() {
return (this.start.row == this.end.row && this.start.column == this.end.column);
};
this.isMultiLine = function() {
return (this.start.row !== this.end.row);
};
this.clone = function() {
return ace.Range.fromPoints(this.start, this.end);
};
}).call(ace.Range.prototype);
ace.Range.fromPoints = function(start, end) {
return new ace.Range(start.row, start.column, end.row, end.column);
};

View file

@ -142,17 +142,7 @@ ace.Search.SELECTION = 2;
this.$rangeFromMatch = function(row, column, length) {
var range = {
start: {
row: row,
column: column
},
end: {
row: row,
column: column + length
}
};
return range;
return new ace.Range(row, column, row, column+length);
};
this.$assembleRegExp = function() {

View file

@ -27,8 +27,7 @@ ace.Selection = function(doc) {
return false;
}
var range = this.getRange();
return (range.start.row !== range.end.row);
return this.getRange().isMultiLine();
};
this.getCursor = function() {
@ -73,16 +72,10 @@ ace.Selection = function(doc) {
if (anchor.row > lead.row
|| (anchor.row == lead.row && anchor.column > lead.column)) {
return {
start : lead,
end : anchor
};
return ace.Range.fromPoints(lead, anchor);
}
else {
return {
start : anchor,
end : lead
};
return ace.Range.fromPoints(anchor, lead);
}
};

View file

@ -45,30 +45,11 @@ ace.layer.Marker = function(parentEl) {
var html = [];
for ( var key in this.markers) {
var marker = this.markers[key];
var range = {
start: marker.range.start,
end: marker.range.end
};
// clip
if (range.start.row > config.lastRow) continue;
if (range.end.row < config.firstRow) continue;
var range = marker.range.clone().clipRows(config.firstRow, config.lastRow);
if (range.isEmpty()) continue;
if (range.end.row > config.lastRow) {
range.end = {
row: config.lastRow+1,
column: 0
};
}
if (range.start.row < config.firstRow) {
range.start = {
row: config.firstRow,
column: 0
};
}
if (range.start.row !== range.end.row) {
if (range.isMultiLine()) {
if (marker.type == "text") {
this.drawTextMarker(html, range, marker.clazz, config);
} else {
@ -86,20 +67,12 @@ ace.layer.Marker = function(parentEl) {
// selection start
var row = range.start.row;
var lineRange = { start: {}, end: {}};
lineRange.start.row = row;
lineRange.start.column = range.start.column;
lineRange.end.row = row;
lineRange.end.column = this.doc.getLine(row).length;
var lineRange = new ace.Range(row, range.start.column, row, this.doc.getLine(row).length);
this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig);
// selection end
var row = range.end.row;
lineRange.start.row = row;
lineRange.start.column = 0;
lineRange.end.row = row;
lineRange.end.column = range.end.column;
var lineRange = new ace.Range(row, 0, row, range.end.column);
this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig);
for (var row = range.start.row + 1; row < range.end.row; row++) {

View file

@ -23,18 +23,7 @@ ace.mode.MatchingBraceOutdent = function() {};
if (!openBracePos || openBracePos.row == row) return 0;
var indent = this.$getIndent(doc.getLine(openBracePos.row));
var range = {
start: {
row: row,
column: 0
},
end: {
row: row,
column: column-1
}
};
doc.replace(range, indent);
doc.replace(new ace.Range(row, 0, row, column-1), indent);
return indent.length - (column-1);
};

View file

@ -135,15 +135,37 @@ var TextDocumentTest = new TestCase("TextDocumentTest", {
var editor = new ace.Editor(new MockRenderer(), doc);
editor.removeLines();
var removedText = doc.toString();
var step1 = doc.toString();
assertEquals("222\n333", step1);
// call normally async code now
doc.$informUndoManager.call();
editor.removeLines();
var step2 = doc.toString();
assertEquals("333", step2);
// call normally async code now
doc.$informUndoManager.call();
editor.removeLines();
var step3 = doc.toString();
assertEquals("", step3);
// call normally async code now
doc.$informUndoManager.call();
undoManager.undo();
assertEquals(step2, doc.toString());
undoManager.undo();
assertEquals(step1, doc.toString());
undoManager.undo();
assertEquals(initialText, doc.toString());
undoManager.redo();
assertEquals(removedText, doc.toString());
undoManager.undo();
assertEquals(initialText, doc.toString());
// undoManager.redo();
// assertEquals(removedText, doc.toString());
}
});

71
src/test/RangeTest.js Normal file
View file

@ -0,0 +1,71 @@
RangeTest = new TestCase("RangeTest", {
"test: create range": function() {
var range = new ace.Range(1,2,3,4);
assertEquals(1, range.start.row);
assertEquals(2, range.start.column);
assertEquals(3, range.end.row);
assertEquals(4, range.end.column);
},
"test: create from points": function() {
var range = ace.Range.fromPoints({row: 1, column: 2}, {row:3, column:4});
assertEquals(1, range.start.row);
assertEquals(2, range.start.column);
assertEquals(3, range.end.row);
assertEquals(4, range.end.column);
},
"test: clip to rows": function() {
var range = new ace.Range(0, 20, 100, 30);
range.clipRows(10, 30);
assertPosition(10, 0, range.start);
assertPosition(31, 0, range.end);
var range = new ace.Range(0, 20, 30, 10);
range.clipRows(10, 30);
assertPosition(10, 0, range.start);
assertPosition(30, 10, range.end);
var range = new ace.Range(0, 20, 3, 10);
range.clipRows(10, 30);
assertTrue(range.isEmpty());
assertPosition(10, 0, range.start);
assertPosition(10, 0, range.end);
},
"test: isEmpty": function() {
var range = new ace.Range(1, 2, 1, 2);
assertTrue(range.isEmpty());
var range = new ace.Range(1, 2, 1, 6);
assertFalse(range.isEmpty());
},
"test: is multi line": function() {
var range = new ace.Range(1, 2, 1, 6);
assertFalse(range.isMultiLine());
var range = new ace.Range(1, 2, 2, 6);
assertTrue(range.isMultiLine());
},
"test: clone": function() {
var range = new ace.Range(1, 2, 3, 4);
var clone = range.clone();
assertPosition(1, 2, clone.start);
assertPosition(3, 4, clone.end);
clone.start.column = 20;
assertPosition(1, 2, range.start);
clone.end.column = 20;
assertPosition(3, 4, range.end);
}
});