make tokenizer async

This commit is contained in:
Fabian Jakobs 2010-09-30 17:47:42 +02:00
commit f6002deac2
3 changed files with 87 additions and 66 deletions

View file

@ -15,6 +15,7 @@ var BackgroundTokenizer = function(tokenizer) {
this.tokenizer = tokenizer; this.tokenizer = tokenizer;
var self = this; var self = this;
this.$worker = function() { this.$worker = function() {
if (!self.running) { return; } if (!self.running) { return; }
@ -84,12 +85,12 @@ var BackgroundTokenizer = function(tokenizer) {
this.running = false; this.running = false;
}; };
this.getTokens = function(firstRow, lastRow) { this.getTokens = function(firstRow, lastRow, callback) {
return this.$tokenizeRows(firstRow, lastRow); callback(this.$tokenizeRows(firstRow, lastRow));
}; };
this.getState = function(row) { this.getState = function(row, callback) {
return this.$tokenizeRows(row, row)[0].state; callback(this.$tokenizeRows(row, row)[0].state);
}; };
this.$tokenizeRows = function(firstRow, lastRow) { this.$tokenizeRows = function(firstRow, lastRow) {

View file

@ -378,30 +378,32 @@ var Editor = function(renderer, doc) {
this.clearSelection(); this.clearSelection();
var lineState = this.bgTokenizer.getState(cursor.row-1); var _self = this;
var shouldOutdent = this.mode.checkOutdent(lineState, this.doc.getLine(cursor.row), text); this.bgTokenizer.getState(cursor.row-1, function(lineState) {
var shouldOutdent = _self.mode.checkOutdent(lineState, _self.doc.getLine(cursor.row), text);
var end = this.doc.insert(cursor, text); var end = _self.doc.insert(cursor, text);
var row = cursor.row; var row = cursor.row;
var line = this.doc.getLine(row); var line = _self.doc.getLine(row);
var lineState = this.bgTokenizer.getState(row); _self.bgTokenizer.getState(row, function(lineState ) {
// multi line insert
if (row !== end.row) {
var indent = _self.mode.getNextLineIndent(lineState, line, _self.doc.getTabString());
if (indent) {
var indentRange = new Range(row+1, 0, end.row, end.column);
end.column += _self.doc.indentRows(indentRange, indent);
}
} else {
if (shouldOutdent) {
end.column += _self.mode.autoOutdent(lineState, _self.doc, row);
}
}
// multi line insert _self.moveCursorToPosition(end);
if (row !== end.row) { _self.renderer.scrollCursorIntoView();
var indent = this.mode.getNextLineIndent(lineState, line, this.doc.getTabString()); });
if (indent) { });
var indentRange = new Range(row+1, 0, end.row, end.column);
end.column += this.doc.indentRows(indentRange, indent);
}
} else {
if (shouldOutdent) {
end.column += this.mode.autoOutdent(lineState, this.doc, row);
}
}
this.moveCursorToPosition(end);
this.renderer.scrollCursorIntoView();
}; };
this.$overwrite = false; this.$overwrite = false;
@ -541,10 +543,11 @@ var Editor = function(renderer, doc) {
var rows = this.$getSelectedRows(); var rows = this.$getSelectedRows();
var range = new Range(rows.first, 0, rows.last, 0); var range = new Range(rows.first, 0, rows.last, 0);
var state = this.bgTokenizer.getState(this.getCursorPosition().row); var _self = this;
var addedColumns = this.mode.toggleCommentLines(state, this.doc, range); this.bgTokenizer.getState(this.getCursorPosition().row, function(state) {
var addedColumns = _self.mode.toggleCommentLines(state, _self.doc, range);
this.selection.shiftSelection(addedColumns); _self.selection.shiftSelection(addedColumns);
});
}; };
this.removeLines = function() { this.removeLines = function() {

View file

@ -116,15 +116,16 @@ var Text = function(parentEl) {
var last = Math.min(lastRow, layerConfig.lastRow); var last = Math.min(lastRow, layerConfig.lastRow);
var lineElements = this.element.childNodes; var lineElements = this.element.childNodes;
var tokens = this.tokenizer.getTokens(first, last); var _self = this;
this.tokenizer.getTokens(first, last, function(tokens) {
for ( var i = first; i <= last; i++) {
var html = [];
_self.$renderLine(html, i, tokens[i-first].tokens);
for ( var i = first; i <= last; i++) { var lineElement = lineElements[i - layerConfig.firstRow];
var html = []; lineElement.innerHTML = html.join("");
this.$renderLine(html, i, tokens[i-first].tokens); }
});
var lineElement = lineElements[i - layerConfig.firstRow];
lineElement.innerHTML = html.join("");
}
}; };
this.scrollLines = function(config) { this.scrollLines = function(config) {
@ -148,50 +149,66 @@ var Text = function(parentEl) {
for (var row=config.lastRow+1; row<=oldConfig.lastRow; row++) for (var row=config.lastRow+1; row<=oldConfig.lastRow; row++)
el.removeChild(el.lastChild); el.removeChild(el.lastChild);
if (config.firstRow < oldConfig.firstRow) { appendTop(appendBottom);
var fragment = this.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1);
if (el.firstChild) var _self = this;
el.insertBefore(fragment, el.firstChild); function appendTop(callback) {
if (config.firstRow < oldConfig.firstRow) {
_self.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1, function(fragment) {
if (el.firstChild)
el.insertBefore(fragment, el.firstChild);
else
el.appendChild(fragment);
callback();
});
}
else else
el.appendChild(fragment); callback();
} }
if (config.lastRow > oldConfig.lastRow) { function appendBottom() {
var fragment = this.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow); if (config.lastRow > oldConfig.lastRow) {
el.appendChild(fragment); _self.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow, function(fragment) {
el.appendChild(fragment);
});
}
} }
}; };
this.$renderLinesFragment = function(config, firstRow, lastRow) { this.$renderLinesFragment = function(config, firstRow, lastRow, callback) {
var fragment = document.createDocumentFragment(); var fragment = document.createDocumentFragment();
var tokens = this.tokenizer.getTokens(firstRow, lastRow); var _self = this;
for (var row=firstRow; row<=lastRow; row++) { this.tokenizer.getTokens(firstRow, lastRow, function(tokens) {
var lineEl = document.createElement("div"); for (var row=firstRow; row<=lastRow; row++) {
lineEl.className = "ace_line"; var lineEl = document.createElement("div");
var style = lineEl.style; lineEl.className = "ace_line";
style.height = this.$characterSize.height + "px"; var style = lineEl.style;
style.width = config.width + "px"; style.height = _self.$characterSize.height + "px";
style.width = config.width + "px";
var html = []; var html = [];
this.$renderLine(html, row, tokens[row-firstRow].tokens); _self.$renderLine(html, row, tokens[row-firstRow].tokens);
lineEl.innerHTML = html.join(""); lineEl.innerHTML = html.join("");
fragment.appendChild(lineEl); fragment.appendChild(lineEl);
} }
return fragment; callback(fragment);
});
}; };
this.update = function(config) { this.update = function(config) {
this.$computeTabString(); this.$computeTabString();
var html = []; var html = [];
var tokens = this.tokenizer.getTokens(config.firstRow, config.lastRow); var _self = this;
for ( var i = config.firstRow; i <= config.lastRow; i++) { this.tokenizer.getTokens(config.firstRow, config.lastRow, function(tokens) {
html.push("<div class='ace_line' style='height:" + this.$characterSize.height + "px;", "width:", for ( var i = config.firstRow; i <= config.lastRow; i++) {
config.width, "px'>"); html.push("<div class='ace_line' style='height:" + _self.$characterSize.height + "px;", "width:",
this.$renderLine(html, i, tokens[i-config.firstRow].tokens), html.push("</div>"); config.width, "px'>");
} _self.$renderLine(html, i, tokens[i-config.firstRow].tokens), html.push("</div>");
}
this.element.innerHTML = html.join(""); _self.element.innerHTML = html.join("");
});
}; };
this.$textToken = { this.$textToken = {