diff --git a/src/ace/BackgroundTokenizer.js b/src/ace/BackgroundTokenizer.js index 461f0354..0905f3bd 100644 --- a/src/ace/BackgroundTokenizer.js +++ b/src/ace/BackgroundTokenizer.js @@ -15,6 +15,7 @@ var BackgroundTokenizer = function(tokenizer) { this.tokenizer = tokenizer; var self = this; + this.$worker = function() { if (!self.running) { return; } @@ -84,12 +85,12 @@ var BackgroundTokenizer = function(tokenizer) { this.running = false; }; - this.getTokens = function(firstRow, lastRow) { - return this.$tokenizeRows(firstRow, lastRow); + this.getTokens = function(firstRow, lastRow, callback) { + callback(this.$tokenizeRows(firstRow, lastRow)); }; - this.getState = function(row) { - return this.$tokenizeRows(row, row)[0].state; + this.getState = function(row, callback) { + callback(this.$tokenizeRows(row, row)[0].state); }; this.$tokenizeRows = function(firstRow, lastRow) { diff --git a/src/ace/Editor.js b/src/ace/Editor.js index 668d4857..47bf334e 100644 --- a/src/ace/Editor.js +++ b/src/ace/Editor.js @@ -378,30 +378,32 @@ var Editor = function(renderer, doc) { this.clearSelection(); - var lineState = this.bgTokenizer.getState(cursor.row-1); - var shouldOutdent = this.mode.checkOutdent(lineState, this.doc.getLine(cursor.row), text); + var _self = this; + 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 line = this.doc.getLine(row); - var lineState = this.bgTokenizer.getState(row); + var row = cursor.row; + var line = _self.doc.getLine(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 - if (row !== end.row) { - 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(); + _self.moveCursorToPosition(end); + _self.renderer.scrollCursorIntoView(); + }); + }); }; this.$overwrite = false; @@ -541,10 +543,11 @@ var Editor = function(renderer, doc) { var rows = this.$getSelectedRows(); var range = new Range(rows.first, 0, rows.last, 0); - var state = this.bgTokenizer.getState(this.getCursorPosition().row); - var addedColumns = this.mode.toggleCommentLines(state, this.doc, range); - - this.selection.shiftSelection(addedColumns); + var _self = this; + this.bgTokenizer.getState(this.getCursorPosition().row, function(state) { + var addedColumns = _self.mode.toggleCommentLines(state, _self.doc, range); + _self.selection.shiftSelection(addedColumns); + }); }; this.removeLines = function() { diff --git a/src/ace/layer/Text.js b/src/ace/layer/Text.js index 6e2cb760..37f9aa7e 100644 --- a/src/ace/layer/Text.js +++ b/src/ace/layer/Text.js @@ -116,15 +116,16 @@ var Text = function(parentEl) { var last = Math.min(lastRow, layerConfig.lastRow); 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 html = []; - this.$renderLine(html, i, tokens[i-first].tokens); - - var lineElement = lineElements[i - layerConfig.firstRow]; - lineElement.innerHTML = html.join(""); - } + var lineElement = lineElements[i - layerConfig.firstRow]; + lineElement.innerHTML = html.join(""); + } + }); }; this.scrollLines = function(config) { @@ -148,50 +149,66 @@ var Text = function(parentEl) { for (var row=config.lastRow+1; row<=oldConfig.lastRow; row++) el.removeChild(el.lastChild); - if (config.firstRow < oldConfig.firstRow) { - var fragment = this.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1); - if (el.firstChild) - el.insertBefore(fragment, el.firstChild); + appendTop(appendBottom); + + var _self = this; + 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 - el.appendChild(fragment); + callback(); } - if (config.lastRow > oldConfig.lastRow) { - var fragment = this.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow); - el.appendChild(fragment); + function appendBottom() { + if (config.lastRow > oldConfig.lastRow) { + _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 tokens = this.tokenizer.getTokens(firstRow, lastRow); - for (var row=firstRow; row<=lastRow; row++) { - var lineEl = document.createElement("div"); - lineEl.className = "ace_line"; - var style = lineEl.style; - style.height = this.$characterSize.height + "px"; - style.width = config.width + "px"; + var _self = this; + this.tokenizer.getTokens(firstRow, lastRow, function(tokens) { + for (var row=firstRow; row<=lastRow; row++) { + var lineEl = document.createElement("div"); + lineEl.className = "ace_line"; + var style = lineEl.style; + style.height = _self.$characterSize.height + "px"; + style.width = config.width + "px"; - var html = []; - this.$renderLine(html, row, tokens[row-firstRow].tokens); - lineEl.innerHTML = html.join(""); - fragment.appendChild(lineEl); - } - return fragment; + var html = []; + _self.$renderLine(html, row, tokens[row-firstRow].tokens); + lineEl.innerHTML = html.join(""); + fragment.appendChild(lineEl); + } + callback(fragment); + }); }; this.update = function(config) { this.$computeTabString(); var html = []; - var tokens = this.tokenizer.getTokens(config.firstRow, config.lastRow); - for ( var i = config.firstRow; i <= config.lastRow; i++) { - html.push("