Use a cache to speed up doc->screen and screen->doc mapping on very long document.
This commit is contained in:
parent
007125025f
commit
a3496dfad1
4 changed files with 45 additions and 8 deletions
|
|
@ -85,7 +85,7 @@ exports.launch = function(env) {
|
|||
|
||||
// Make the lorem ipsum text a little bit longer.
|
||||
var loreIpsum = document.getElementById("plaintext").innerHTML;
|
||||
for (var i = 0; i < 5; i++) {
|
||||
for (var i = 0; i < 11; i++) {
|
||||
loreIpsum += loreIpsum;
|
||||
}
|
||||
docs.plain = new EditSession(loreIpsum);
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ var EditSession = function(text, mode) {
|
|||
doc.on("change", this.onChange.bind(this));
|
||||
doc.on("changeStart", this.onChangeStart.bind(this));
|
||||
doc.on("changeEnd", this.onChangeEnd.bind(this));
|
||||
this.on("changeFold", this.onChangeFold.bind(this));
|
||||
};
|
||||
|
||||
this.getDocument = function() {
|
||||
|
|
@ -99,13 +100,11 @@ var EditSession = function(text, mode) {
|
|||
};
|
||||
|
||||
this.onChangeStart = function() {
|
||||
console.log(">>> onChangeStart", this.$docChangeCounter);
|
||||
this.$docChangeCounter ++;
|
||||
};
|
||||
|
||||
this.onChangeEnd = function() {
|
||||
this.$docChangeCounter --;
|
||||
console.log("<<< onChangeEnd", this.$docChangeCounter);
|
||||
if (this.$docChangeCounter == 0
|
||||
&& !this.$fromUndo && this.$undoManager)
|
||||
{
|
||||
|
|
@ -127,24 +126,36 @@ var EditSession = function(text, mode) {
|
|||
}
|
||||
};
|
||||
|
||||
this.onChangeFold = function(e) {
|
||||
var fold = e.data;
|
||||
if (this.$cacheRowData
|
||||
&& fold.start.row < this.$cacheRowData.docRow)
|
||||
{
|
||||
this.$cacheRowData = null;
|
||||
}
|
||||
};
|
||||
|
||||
this.onChange = function(e) {
|
||||
var delta = e.data;
|
||||
this.$modified = true;
|
||||
|
||||
if (this.$cacheRowData
|
||||
&& delta.range.start.row < this.$cacheRowData.docRow)
|
||||
{
|
||||
this.$cacheRowData = null;
|
||||
}
|
||||
|
||||
var removedFolds = this.$updateInternalDataOnChange(e);
|
||||
if (!this.$fromUndo && this.$undoManager && !delta.ignore) {
|
||||
console.log("onChange", JSON.stringify(delta));
|
||||
this.$deltasDoc.push(delta);
|
||||
if (removedFolds && removedFolds.length != 0) {
|
||||
this.$deltasFold.push({
|
||||
action: "removeFolds",
|
||||
folds: removedFolds
|
||||
});
|
||||
console.log("onChangeFold", removedFolds[0].toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
this.bgTokenizer.start(delta.range.start.row);
|
||||
this._dispatchEvent("change", e);
|
||||
};
|
||||
|
|
@ -154,6 +165,7 @@ var EditSession = function(text, mode) {
|
|||
this.$deltas = [];
|
||||
this.$deltasDoc = [];
|
||||
this.$deltasFold = [];
|
||||
this.$cacheRowData = null;
|
||||
this.getUndoManager().reset();
|
||||
};
|
||||
|
||||
|
|
@ -1361,6 +1373,17 @@ var EditSession = function(text, mode) {
|
|||
return this.screenToDocumentPosition(screenRow, screenColumn).column;
|
||||
};
|
||||
|
||||
this.setCacheRow = function(docRow) {
|
||||
// Don't update the cache if the docRow stayed the same.
|
||||
if (this.$cacheRowData && this.$cacheRowData.docRow == docRow) {
|
||||
return;
|
||||
}
|
||||
this.$cacheRowData = {
|
||||
docRow: docRow,
|
||||
screenRow: this.documentToScreenRow(docRow, 0)
|
||||
}
|
||||
}
|
||||
|
||||
this.screenToDocumentPosition = function(screenRow, screenColumn) {
|
||||
var line;
|
||||
var docRow = 0;
|
||||
|
|
@ -1373,6 +1396,12 @@ var EditSession = function(text, mode) {
|
|||
var splits = null;
|
||||
var split = 0;
|
||||
|
||||
var cacheRowData = this.$cacheRowData;
|
||||
if (cacheRowData && cacheRowData.screenRow < screenRow) {
|
||||
row = cacheRowData.screenRow ;
|
||||
docRow = cacheRowData.docRow;
|
||||
}
|
||||
|
||||
while (row <= screenRow) {
|
||||
rowLength = this.getRowLength(docRow);
|
||||
if (row + rowLength - 1 >= screenRow) {
|
||||
|
|
@ -1457,6 +1486,12 @@ var EditSession = function(text, mode) {
|
|||
}
|
||||
|
||||
var rowEnd, row = 0;
|
||||
var cacheRowData = this.$cacheRowData;
|
||||
if (cacheRowData && cacheRowData.docRow < docRow) {
|
||||
row = cacheRowData.docRow ;
|
||||
screenRow = cacheRowData.screenRow// + this.getRowLength(row);;
|
||||
}
|
||||
|
||||
while (row < docRow) {
|
||||
rowEnd = this.getRowFoldEnd(row);
|
||||
if (rowEnd >= docRow) {
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ function Folding() {
|
|||
|
||||
// Notify that fold data has changed.
|
||||
this.$modified = true;
|
||||
this._dispatchEvent("changeFold");
|
||||
this._dispatchEvent("changeFold", { data: fold });
|
||||
|
||||
return fold;
|
||||
};
|
||||
|
|
@ -387,7 +387,7 @@ function Folding() {
|
|||
|
||||
// Notify that fold data has changed.
|
||||
this.$modified = true;
|
||||
this._dispatchEvent("changeFold");
|
||||
this._dispatchEvent("changeFold", { data: fold });
|
||||
}
|
||||
|
||||
this.removeFolds = function(folds) {
|
||||
|
|
|
|||
|
|
@ -479,6 +479,8 @@ var VirtualRenderer = function(container, theme) {
|
|||
var lineHeight = { lineHeight: this.lineHeight };
|
||||
firstRow = session.screenToDocumentRow(firstRow, 0);
|
||||
|
||||
session.setCacheRow(firstRow);
|
||||
|
||||
// Check if firstRow is inside of a foldLine. If true, then use the first
|
||||
// row of the foldLine.
|
||||
var foldLine = session.getFoldLine(firstRow);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue