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.
|
// Make the lorem ipsum text a little bit longer.
|
||||||
var loreIpsum = document.getElementById("plaintext").innerHTML;
|
var loreIpsum = document.getElementById("plaintext").innerHTML;
|
||||||
for (var i = 0; i < 5; i++) {
|
for (var i = 0; i < 11; i++) {
|
||||||
loreIpsum += loreIpsum;
|
loreIpsum += loreIpsum;
|
||||||
}
|
}
|
||||||
docs.plain = new EditSession(loreIpsum);
|
docs.plain = new EditSession(loreIpsum);
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,7 @@ var EditSession = function(text, mode) {
|
||||||
doc.on("change", this.onChange.bind(this));
|
doc.on("change", this.onChange.bind(this));
|
||||||
doc.on("changeStart", this.onChangeStart.bind(this));
|
doc.on("changeStart", this.onChangeStart.bind(this));
|
||||||
doc.on("changeEnd", this.onChangeEnd.bind(this));
|
doc.on("changeEnd", this.onChangeEnd.bind(this));
|
||||||
|
this.on("changeFold", this.onChangeFold.bind(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getDocument = function() {
|
this.getDocument = function() {
|
||||||
|
|
@ -99,13 +100,11 @@ var EditSession = function(text, mode) {
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onChangeStart = function() {
|
this.onChangeStart = function() {
|
||||||
console.log(">>> onChangeStart", this.$docChangeCounter);
|
|
||||||
this.$docChangeCounter ++;
|
this.$docChangeCounter ++;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.onChangeEnd = function() {
|
this.onChangeEnd = function() {
|
||||||
this.$docChangeCounter --;
|
this.$docChangeCounter --;
|
||||||
console.log("<<< onChangeEnd", this.$docChangeCounter);
|
|
||||||
if (this.$docChangeCounter == 0
|
if (this.$docChangeCounter == 0
|
||||||
&& !this.$fromUndo && this.$undoManager)
|
&& !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) {
|
this.onChange = function(e) {
|
||||||
var delta = e.data;
|
var delta = e.data;
|
||||||
this.$modified = true;
|
this.$modified = true;
|
||||||
|
|
||||||
|
if (this.$cacheRowData
|
||||||
|
&& delta.range.start.row < this.$cacheRowData.docRow)
|
||||||
|
{
|
||||||
|
this.$cacheRowData = null;
|
||||||
|
}
|
||||||
|
|
||||||
var removedFolds = this.$updateInternalDataOnChange(e);
|
var removedFolds = this.$updateInternalDataOnChange(e);
|
||||||
if (!this.$fromUndo && this.$undoManager && !delta.ignore) {
|
if (!this.$fromUndo && this.$undoManager && !delta.ignore) {
|
||||||
console.log("onChange", JSON.stringify(delta));
|
|
||||||
this.$deltasDoc.push(delta);
|
this.$deltasDoc.push(delta);
|
||||||
if (removedFolds && removedFolds.length != 0) {
|
if (removedFolds && removedFolds.length != 0) {
|
||||||
this.$deltasFold.push({
|
this.$deltasFold.push({
|
||||||
action: "removeFolds",
|
action: "removeFolds",
|
||||||
folds: removedFolds
|
folds: removedFolds
|
||||||
});
|
});
|
||||||
console.log("onChangeFold", removedFolds[0].toString());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.bgTokenizer.start(delta.range.start.row);
|
this.bgTokenizer.start(delta.range.start.row);
|
||||||
this._dispatchEvent("change", e);
|
this._dispatchEvent("change", e);
|
||||||
};
|
};
|
||||||
|
|
@ -154,6 +165,7 @@ var EditSession = function(text, mode) {
|
||||||
this.$deltas = [];
|
this.$deltas = [];
|
||||||
this.$deltasDoc = [];
|
this.$deltasDoc = [];
|
||||||
this.$deltasFold = [];
|
this.$deltasFold = [];
|
||||||
|
this.$cacheRowData = null;
|
||||||
this.getUndoManager().reset();
|
this.getUndoManager().reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -1361,6 +1373,17 @@ var EditSession = function(text, mode) {
|
||||||
return this.screenToDocumentPosition(screenRow, screenColumn).column;
|
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) {
|
this.screenToDocumentPosition = function(screenRow, screenColumn) {
|
||||||
var line;
|
var line;
|
||||||
var docRow = 0;
|
var docRow = 0;
|
||||||
|
|
@ -1373,6 +1396,12 @@ var EditSession = function(text, mode) {
|
||||||
var splits = null;
|
var splits = null;
|
||||||
var split = 0;
|
var split = 0;
|
||||||
|
|
||||||
|
var cacheRowData = this.$cacheRowData;
|
||||||
|
if (cacheRowData && cacheRowData.screenRow < screenRow) {
|
||||||
|
row = cacheRowData.screenRow ;
|
||||||
|
docRow = cacheRowData.docRow;
|
||||||
|
}
|
||||||
|
|
||||||
while (row <= screenRow) {
|
while (row <= screenRow) {
|
||||||
rowLength = this.getRowLength(docRow);
|
rowLength = this.getRowLength(docRow);
|
||||||
if (row + rowLength - 1 >= screenRow) {
|
if (row + rowLength - 1 >= screenRow) {
|
||||||
|
|
@ -1457,6 +1486,12 @@ var EditSession = function(text, mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var rowEnd, row = 0;
|
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) {
|
while (row < docRow) {
|
||||||
rowEnd = this.getRowFoldEnd(row);
|
rowEnd = this.getRowFoldEnd(row);
|
||||||
if (rowEnd >= docRow) {
|
if (rowEnd >= docRow) {
|
||||||
|
|
|
||||||
|
|
@ -329,7 +329,7 @@ function Folding() {
|
||||||
|
|
||||||
// Notify that fold data has changed.
|
// Notify that fold data has changed.
|
||||||
this.$modified = true;
|
this.$modified = true;
|
||||||
this._dispatchEvent("changeFold");
|
this._dispatchEvent("changeFold", { data: fold });
|
||||||
|
|
||||||
return fold;
|
return fold;
|
||||||
};
|
};
|
||||||
|
|
@ -387,7 +387,7 @@ function Folding() {
|
||||||
|
|
||||||
// Notify that fold data has changed.
|
// Notify that fold data has changed.
|
||||||
this.$modified = true;
|
this.$modified = true;
|
||||||
this._dispatchEvent("changeFold");
|
this._dispatchEvent("changeFold", { data: fold });
|
||||||
}
|
}
|
||||||
|
|
||||||
this.removeFolds = function(folds) {
|
this.removeFolds = function(folds) {
|
||||||
|
|
|
||||||
|
|
@ -479,6 +479,8 @@ var VirtualRenderer = function(container, theme) {
|
||||||
var lineHeight = { lineHeight: this.lineHeight };
|
var lineHeight = { lineHeight: this.lineHeight };
|
||||||
firstRow = session.screenToDocumentRow(firstRow, 0);
|
firstRow = session.screenToDocumentRow(firstRow, 0);
|
||||||
|
|
||||||
|
session.setCacheRow(firstRow);
|
||||||
|
|
||||||
// Check if firstRow is inside of a foldLine. If true, then use the first
|
// Check if firstRow is inside of a foldLine. If true, then use the first
|
||||||
// row of the foldLine.
|
// row of the foldLine.
|
||||||
var foldLine = session.getFoldLine(firstRow);
|
var foldLine = session.getFoldLine(firstRow);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue