diff --git a/lib/ace/editor.js b/lib/ace/editor.js index 689c9910..78e5f3aa 100644 --- a/lib/ace/editor.js +++ b/lib/ace/editor.js @@ -122,95 +122,15 @@ var Editor = function(windowView, buffer) { return this.keyBinding.getKeyboardHandler(); }; + // TODO refactor + // remove this.setSession = function(session) { if (this.session == session) return; this.windowModel.setBuffer(session); - - if (this.session) { - var oldSession = this.session; - this.session.removeEventListener("change", this.$onDocumentChange); - this.session.removeEventListener("changeMode", this.$onChangeMode); - this.session.removeEventListener("tokenizerUpdate", this.$onTokenizerUpdate); - this.session.removeEventListener("changeTabSize", this.$onChangeTabSize); - this.session.removeEventListener("changeWrapLimit", this.$onChangeWrapLimit); - this.session.removeEventListener("changeWrapMode", this.$onChangeWrapMode); - this.session.removeEventListener("onChangeFold", this.$onChangeFold); - this.session.removeEventListener("changeFrontMarker", this.$onChangeFrontMarker); - this.session.removeEventListener("changeBackMarker", this.$onChangeBackMarker); - this.session.removeEventListener("changeBreakpoint", this.$onChangeBreakpoint); - this.session.removeEventListener("changeAnnotation", this.$onChangeAnnotation); - this.session.removeEventListener("changeOverwrite", this.$onCursorChange); - - var selection = this.session.getSelection(); - selection.removeEventListener("changeCursor", this.$onCursorChange); - selection.removeEventListener("changeSelection", this.$onSelectionChange); - - this.session.setScrollTopRow(this.windowModel.getScrollTopRow()); - } - this.session = session; - - this.$onDocumentChange = this.onDocumentChange.bind(this); - session.addEventListener("change", this.$onDocumentChange); - this.renderer.setSession(session); - - this.$onChangeMode = this.onChangeMode.bind(this); - session.addEventListener("changeMode", this.$onChangeMode); - - this.$onTokenizerUpdate = this.onTokenizerUpdate.bind(this); - session.addEventListener("tokenizerUpdate", this.$onTokenizerUpdate); - - this.$onChangeTabSize = this.renderer.updateText.bind(this.renderer); - session.addEventListener("changeTabSize", this.$onChangeTabSize); - - this.$onChangeWrapLimit = this.onChangeWrapLimit.bind(this); - session.addEventListener("changeWrapLimit", this.$onChangeWrapLimit); - - this.$onChangeWrapMode = this.onChangeWrapMode.bind(this); - session.addEventListener("changeWrapMode", this.$onChangeWrapMode); - - this.$onChangeFold = this.onChangeFold.bind(this); - session.addEventListener("changeFold", this.$onChangeFold); - - this.$onChangeFrontMarker = this.onChangeFrontMarker.bind(this); - this.session.addEventListener("changeFrontMarker", this.$onChangeFrontMarker); - - this.$onChangeBackMarker = this.onChangeBackMarker.bind(this); - this.session.addEventListener("changeBackMarker", this.$onChangeBackMarker); - - this.$onChangeBreakpoint = this.onChangeBreakpoint.bind(this); - this.session.addEventListener("changeBreakpoint", this.$onChangeBreakpoint); - - this.$onChangeAnnotation = this.onChangeAnnotation.bind(this); - this.session.addEventListener("changeAnnotation", this.$onChangeAnnotation); - - this.$onCursorChange = this.onCursorChange.bind(this); - this.session.addEventListener("changeOverwrite", this.$onCursorChange); - this.selection = session.getSelection(); - this.selection.addEventListener("changeCursor", this.$onCursorChange); - - this.$onSelectionChange = this.onSelectionChange.bind(this); - this.selection.addEventListener("changeSelection", this.$onSelectionChange); - - this.onChangeMode(); - - this.onCursorChange(); - this.onSelectionChange(); - this.onChangeFrontMarker(); - this.onChangeBackMarker(); - this.onChangeBreakpoint(); - this.onChangeAnnotation(); - this.session.getUseWrapMode() && this.renderer.adjustWrapLimit(); - this.windowModel.scrollToRow(session.getScrollTopRow()); - this.renderer.updateFull(); - - this._dispatchEvent("changeSession", { - session: session, - oldSession: oldSession - }); }; this.getSession = function() { @@ -245,30 +165,6 @@ var Editor = function(windowView, buffer) { this.container.style.fontSize = size; }; - this.$highlightBrackets = function() { - if (this.session.$bracketHighlight) { - this.session.removeMarker(this.session.$bracketHighlight); - this.session.$bracketHighlight = null; - } - - if (this.$highlightPending) { - return; - } - - // perform highlight async to not block the browser during navigation - var self = this; - this.$highlightPending = true; - setTimeout(function() { - self.$highlightPending = false; - - var pos = self.session.findMatchingBracket(self.getCursorPosition()); - if (pos) { - var range = new Range(pos.row, pos.column, pos.row, pos.column+1); - self.session.$bracketHighlight = self.session.addMarker(range, "ace_bracket", "text"); - } - }, 10); - }; - this.focus = function() { // Safari needs the timeout // iOS and Firefox need it called immediately @@ -300,7 +196,7 @@ var Editor = function(windowView, buffer) { this._dispatchEvent("blur"); }; - this.onDocumentChange = function(e) { +/* this.onDocumentChange = function(e) { var delta = e.data; var range = delta.range; @@ -409,7 +305,7 @@ var Editor = function(windowView, buffer) { this.$updateHighlightActiveLine(); // TODO: This might be too much updating. Okay for now. this.renderer.updateFull(); - }; + };*/ this.getCopyText = function() { var text = ""; @@ -580,45 +476,28 @@ var Editor = function(windowView, buffer) { return this.$mouseHandler.getScrollSpeed() }; - this.$selectionStyle = "line"; this.setSelectionStyle = function(style) { - if (this.$selectionStyle == style) return; - - this.$selectionStyle = style; - this.onSelectionChange(); - this._dispatchEvent("changeSelectionStyle", {data: style}); + this.windowModel.setSelectionStyle(style); }; this.getSelectionStyle = function() { - return this.$selectionStyle; + return this.windowModel.getSelectionStyle(); }; - this.$highlightActiveLine = true; this.setHighlightActiveLine = function(shouldHighlight) { - if (this.$highlightActiveLine == shouldHighlight) return; - - this.$highlightActiveLine = shouldHighlight; - this.$updateHighlightActiveLine(); + this.windowModel.setHighlightActiveLine(shouldHighlight); }; this.getHighlightActiveLine = function() { - return this.$highlightActiveLine; + return this.windowModel.getHighlightActiveLine(); }; - this.$highlightSelectedWord = true; this.setHighlightSelectedWord = function(shouldHighlight) { - if (this.$highlightSelectedWord == shouldHighlight) - return; - - this.$highlightSelectedWord = shouldHighlight; - if (shouldHighlight) - this.session.getMode().highlightSelection(this); - else - this.session.getMode().clearSelectionHighlight(this); + this.windowModel.setHighlightSelectedWord(shouldHighlight); }; this.getHighlightSelectedWord = function() { - return this.$highlightSelectedWord; + return this.windowModel.getHighlightSelectedWord(); }; this.setShowInvisibles = function(showInvisibles) { diff --git a/lib/ace/editor_navigation_test.js b/lib/ace/editor_navigation_test.js index d88c92aa..86c95166 100644 --- a/lib/ace/editor_navigation_test.js +++ b/lib/ace/editor_navigation_test.js @@ -48,6 +48,9 @@ var MockRenderer = require("ace/view/window_view_mock").MockRenderer; var assert = require("ace/test/assertions"); module.exports = { + + name: "editor navigation", + createBuffer : function(rows, cols) { var line = new Array(cols + 1).join("a"); var text = new Array(rows).join(line + "\n") + line; diff --git a/lib/ace/mode/text.js b/lib/ace/mode/text.js index 8113ac27..2c7d5c40 100644 --- a/lib/ace/mode/text.js +++ b/lib/ace/mode/text.js @@ -97,21 +97,21 @@ var Mode = function() { return null; }; - this.highlightSelection = function(editor) { - var session = editor.session; - if (!session.$selectionOccurrences) - session.$selectionOccurrences = []; + this.highlightSelection = function(windowModel) { + var buffer = windowModel.buffer; + if (!buffer.selectionOccurrences) + buffer.selectionOccurrences = []; - if (session.$selectionOccurrences.length) + if (buffer.selectionOccurrences.length) this.clearSelectionHighlight(editor); - var selection = editor.getSelectionRange(); + var selection = windowModel.selection.getRange(); if (selection.isEmpty() || selection.isMultiLine()) return; var startOuter = selection.start.column - 1; var endOuter = selection.end.column + 1; - var line = session.getLine(selection.start.row); + var line = buffer.getLine(selection.start.row); var lineCols = line.length; var needle = line.substring(Math.max(startOuter, 0), Math.min(endOuter, lineCols)); @@ -125,7 +125,7 @@ var Mode = function() { if (!/^[\w\d]+$/.test(needle)) return; - var cursor = editor.getCursorPosition(); + var cursor = windowModel.selection.getCursor(); var newOptions = { wrap: true, @@ -134,29 +134,35 @@ var Mode = function() { needle: needle }; - var currentOptions = editor.$search.getOptions(); - editor.$search.set(newOptions); + // TODO refactor + /* + var search = windowModel.search; + var currentOptions = search.getOptions(); + search.set(newOptions); - var ranges = editor.$search.findAll(session); + var ranges = search.findAll(buffer); ranges.forEach(function(range) { if (!range.contains(cursor.row, cursor.column)) { - var marker = session.addMarker(range, "ace_selected_word", "text"); - session.$selectionOccurrences.push(marker); + var marker = buffer.addMarker(range, "ace_selected_word", "text"); + buffer.selectionOccurrences.push(marker); } }); - editor.$search.set(currentOptions); + search.set(currentOptions); + */ }; - this.clearSelectionHighlight = function(editor) { - if (!editor.session.$selectionOccurrences) + this.clearSelectionHighlight = function(windowModel) { + var buffer = windowModel.buffer; + + if (!buffer.selectionOccurrences) return; - editor.session.$selectionOccurrences.forEach(function(marker) { - editor.session.removeMarker(marker); + buffer.selectionOccurrences.forEach(function(marker) { + buffer.removeMarker(marker); }); - editor.session.$selectionOccurrences = []; + buffer.selectionOccurrences = []; }; this.createModeDelegates = function (mapping) { diff --git a/lib/ace/model/window.js b/lib/ace/model/window.js index 1169d8f5..45e72351 100644 --- a/lib/ace/model/window.js +++ b/lib/ace/model/window.js @@ -44,8 +44,6 @@ var EventEmitter = require("ace/lib/event_emitter").EventEmitter; /** * A window represents the viewport of a buffer - * - * */ var Window = exports.Window = function(theme) { this.theme = null; @@ -86,6 +84,10 @@ var Window = exports.Window = function(theme) { this.showGutter = true; this.padding = 4; this.horizScrollAlwaysVisible = false; + + this.selectionStyle = "line"; + this.highlightActiveLine = true; + this.highlightSelectedWord = true; }; (function() { @@ -227,11 +229,16 @@ var Window = exports.Window = function(theme) { // SETTINGS this.setBuffer = function(buffer) { + if (!buffer) + throw new Error("Buffer cannot be null"); + if (this.buffer === buffer) return; var oldValue = this.buffer; this.buffer = buffer; + this.selection = buffer.getSelection(); + this._emit("changeBuffer", {oldValue: oldValue, value: buffer}); }; @@ -339,7 +346,43 @@ var Window = exports.Window = function(theme) { this.charSize = size; this._emit("changeCharacterSize") - } + }; + + this.setSelectionStyle = function(style) { + if (this.selectionStyle === style) + return; + + this.selectionStyle = style; + this._dispatchEvent("changeSelectionStyle"); + }; + + this.getSelectionStyle = function() { + return this.selectionStyle; + }; + + this.setHighlightActiveLine = function(shouldHighlight) { + if (this.highlightActiveLine == shouldHighlight) + return; + + this.highlightActiveLine = shouldHighlight; + this._dispatchEvent("changeHighlightActiveLine"); + }; + + this.getHighlightActiveLine = function() { + return this.highlightActiveLine; + }; + + this.setHighlightSelectedWord = function(shouldHighlight) { + if (this.highlightSelectedWord == shouldHighlight) + return; + + this.highlightSelectedWord = shouldHighlight; + this._dispatchEvent("changeHighlightSelectedWord"); + }; + + this.getHighlightSelectedWord = function() { + return this.highlightSelectedWord; + }; }).call(Window.prototype); diff --git a/lib/ace/view/layer/marker.js b/lib/ace/view/layer/marker.js index 05ac0292..1d4a1bdf 100644 --- a/lib/ace/view/layer/marker.js +++ b/lib/ace/view/layer/marker.js @@ -130,7 +130,7 @@ var Marker = function(model, parentEl) { */ this._drawMultiLineMarker = function(stringBuilder, range, clazz, type) { // from selection start to the end of the line - var layerConfig = this.model.config; + var layerConfig = this.model.layerConfig; var charSize = this.model.charSize; var padding = type === "background" ? 0 : this.model.padding; var height = charSize.height; diff --git a/lib/ace/view/layer/text.js b/lib/ace/view/layer/text.js index 53405b47..edb9f24a 100644 --- a/lib/ace/view/layer/text.js +++ b/lib/ace/view/layer/text.js @@ -363,7 +363,7 @@ var Text = function(model, parentEl) { } if (this.model.showInvisibles) { - if (lastRow !== this.session.getLength() - 1) { + if (lastRow !== this.session.getLength() - 1) stringBuilder.push("" + this.EOL_CHAR + ""); else stringBuilder.push("" + this.EOF_CHAR + ""); diff --git a/lib/ace/view/window_view.js b/lib/ace/view/window_view.js index be0c3c97..86b39060 100644 --- a/lib/ace/view/window_view.js +++ b/lib/ace/view/window_view.js @@ -128,10 +128,10 @@ var WindowView = function(windowModel, container) { oop.implement(this, EventEmitter); + // TODO refctor + // remove this.setSession = function(session) { - this.session = session; this.$textLayer.setSession(session); - this.$loop.schedule(this.CHANGE_FULL); }; /** @@ -180,7 +180,7 @@ var WindowView = function(windowModel, container) { * Triggers resize of the editor */ this.onResize = function(force) { - if (!this.scroller || !this.container || !this.session) + if (!this.scroller || !this.container || !this.model.buffer) return; var changes = this.CHANGE_SIZE; @@ -194,7 +194,7 @@ var WindowView = function(windowModel, container) { size.scrollerHeight = this.scroller.clientHeight; this.scrollBar.setHeight(size.scrollerHeight); - if (this.session) { + if (this.model.buffer) { this.model.scrollToY(this.model.scrollTop); changes = changes | this.CHANGE_FULL; } @@ -209,7 +209,7 @@ var WindowView = function(windowModel, container) { size.scrollerWidth = Math.max(0, width - gutterWidth - this.scrollBar.getWidth()) this.scroller.style.width = size.scrollerWidth + "px"; - if (this.session.getUseWrapMode() && this.adjustWrapLimit() || force) + if (this.model.buffer.getUseWrapMode() && this.adjustWrapLimit() || force) changes = changes | this.CHANGE_FULL; } @@ -219,7 +219,7 @@ var WindowView = function(windowModel, container) { this.adjustWrapLimit = function(){ var availableWidth = this.model.size.scrollerWidth - this.model.padding * 2; var limit = Math.floor(availableWidth / this.model.charSize.width) - 1; - return this.session.adjustWrapLimit(limit); + return this.model.buffer.adjustWrapLimit(limit); }; this.$onGutterClick = function(e) { @@ -312,7 +312,7 @@ var WindowView = function(windowModel, container) { }; this.$renderChanges = function(changes) { - if (!changes || !this.session) + if (!changes || !this.model.buffer) return; // text, scrolling and resize changes can cause the view port size to change @@ -383,7 +383,7 @@ var WindowView = function(windowModel, container) { }; this.$computeLayerConfig = function() { - var session = this.session; + var buffer = this.model.buffer; var charSize = this.model.charSize; var offset = this.model.scrollTop % charSize.height; @@ -398,7 +398,7 @@ var WindowView = function(windowModel, container) { if (horizScrollChanged) this.scroller.style.overflowX = horizScroll ? "scroll" : "hidden"; - var maxHeight = this.session.getScreenLength() * charSize.height; + var maxHeight = buffer.getScreenLength() * charSize.height; this.model.scrollToY(Math.max(0, Math.min(this.model.scrollTop, maxHeight - this.model.size.scrollerHeight))); var lineCount = Math.ceil(minHeight / charSize.height) - 1; @@ -407,19 +407,19 @@ var WindowView = function(windowModel, container) { // Map lines on the screen to lines in the document. var firstRowScreen, firstRowHeight; - firstRow = session.screenToDocumentRow(firstRow, 0); + firstRow = buffer.screenToDocumentRow(firstRow, 0); // Check if firstRow is inside of a foldLine. If true, then use the first // row of the foldLine. - var foldLine = session.getFoldLine(firstRow); + var foldLine = buffer.getFoldLine(firstRow); if (foldLine) { firstRow = foldLine.start.row; } - firstRowScreen = session.documentToScreenRow(firstRow, 0); + firstRowScreen = buffer.documentToScreenRow(firstRow, 0); firstRowHeight = this.model.getRowHeight(firstRow); - lastRow = Math.min(session.screenToDocumentRow(lastRow, 0), session.getLength() - 1); + lastRow = Math.min(buffer.screenToDocumentRow(lastRow, 0), buffer.getLength() - 1); minHeight = this.model.size.scrollerHeight + this.model.getRowHeight(lastRow) + firstRowHeight; @@ -475,11 +475,11 @@ var WindowView = function(windowModel, container) { } // else update only the changed rows - this.$textLayer.updateLines(layerConfig, firstRow, lastRow); + this.$textLayer.updateLines(firstRow, lastRow); }; this.$getLongestLine = function() { - var charCount = this.session.getScreenWidth() + 1; + var charCount = this.model.buffer.getScreenWidth() + 1; if (this.model.showInvisibles) charCount += 1; @@ -487,12 +487,12 @@ var WindowView = function(windowModel, container) { }; this.updateFrontMarkers = function() { - this.$markerFront.setMarkers(this.session.getMarkers(true)); + this.$markerFront.setMarkers(this.model.buffer.getMarkers(true)); this.$loop.schedule(this.CHANGE_MARKER_FRONT); }; this.updateBackMarkers = function() { - this.$markerBack.setMarkers(this.session.getMarkers()); + this.$markerBack.setMarkers(this.model.buffer.getMarkers()); this.$loop.schedule(this.CHANGE_MARKER_BACK); }; @@ -544,13 +544,13 @@ var WindowView = function(windowModel, container) { var row = Math.floor((pageY + this.model.scrollTop - canvasPos.top - dom.getPageScrollTop()) / this.model.charSize.height); - return this.session.screenToDocumentPosition(row, Math.max(col, 0)); + return this.model.buffer.screenToDocumentPosition(row, Math.max(col, 0)); }; this.textToScreenCoordinates = function(row, column) { var charSize = this.model.charSize; var canvasPos = this.scroller.getBoundingClientRect(); - var pos = this.session.documentToScreenPosition(row, column); + var pos = this.model.buffer.documentToScreenPosition(row, column); var x = this.model.padding + Math.round(pos.column * charSize.width); var y = pos.row * charSize.height; diff --git a/lib/ace/view/window_view_mock.js b/lib/ace/view/window_view_mock.js index dc41554f..fb0f3220 100644 --- a/lib/ace/view/window_view_mock.js +++ b/lib/ace/view/window_view_mock.js @@ -91,7 +91,9 @@ WindowViewMock.prototype.getSession = function(session) { "updateText", "showCursor", "visualizeFocus", - "setAnnotations" + "setAnnotations", + "updateScrollLeft", + "updateScrollTop" ].forEach(function(name) { WindowViewMock.prototype[name] = function() {}; }) diff --git a/lib/ace/window_controller.js b/lib/ace/window_controller.js index b9473ac9..f30e7267 100644 --- a/lib/ace/window_controller.js +++ b/lib/ace/window_controller.js @@ -37,6 +37,8 @@ define(function(require, exports, module) { +var Range = require("ace/range").Range; + var WindowController = exports.WindowController = function(model, view) { this.model = model; this.view = view; @@ -51,11 +53,225 @@ var WindowController = exports.WindowController = function(model, view) { model.on("changeScrollLeft", view.updateScrollLeft.bind(view)); model.on("changeScrollTop", view.updateScrollTop.bind(view)); + model.on("changeSelectionStyle", this.onSelectionChange.bind(this)); + model.on("changeHighlightActiveLine", this._updateHighlightActiveLine.bind(this)); + model.on("changeHighlightSelectedWord", this.onChangeHighlightSelectedWord.bind(this)); + model.on("changeBuffer", this.onChangeBuffer.bind(this)); }; (function() { + this.onChangeHighlightSelectedWord = function() { + var buffer = this.model.buffer; + if (this.model.shouldHighlight) + buffer.getMode().highlightSelection(this.model); + else + buffer.getMode().clearSelectionHighlight(this.model); + }; + + this.onChangeBuffer = function(e) { + var buffer = e.value; + var oldBuffer = e.oldValue; + + // cleanup + if (oldBuffer) { + oldBuffer.removeListener("change", this._onDocumentChange); + oldBuffer.removeListener("tokenizerUpdate", this._onTokenizerUpdate); + oldBuffer.removeListener("changeTabSize", this._onChangeTabSize); + oldBuffer.removeListener("changeMode", this._onChangeMode); + oldBuffer.removeListener("changeWrapLimit", this._onChangeWrapLimit); + oldBuffer.removeListener("changeWrapMode", this._onChangeWrapMode); + oldBuffer.removeListener("onChangeFold", this._onChangeFold); + oldBuffer.removeListener("changeFrontMarker", this._onChangeFrontMarker); + oldBuffer.removeListener("changeBackMarker", this._onChangeBackMarker); + oldBuffer.removeListener("changeBreakpoint", this._onChangeBreakpoint); + oldBuffer.removeListener("changeAnnotation", this._onChangeAnnotation); + oldBuffer.removeListener("changeOverwrite", this._onCursorChange); + + var selection = oldBuffer.getSelection(); + selection.removeEventListener("changeCursor", this._onCursorChange); + selection.removeEventListener("changeSelection", this._onSelectionChange); + } + + // TODO refactor + this.view.setSession(buffer); + + this._onDocumentChange = this.onDocumentChange.bind(this); + buffer.on("change", this._onDocumentChange); + + this._onTokenizerUpdate = this.onTokenizerUpdate.bind(this); + buffer.on("tokenizerUpdate", this._onTokenizerUpdate); + + this._onChangeTabSize = this.view.updateText.bind(this.view); + buffer.on("changeTabSize", this._onChangeTabSize); + + this._onChangeMode = this.view.updateText.bind(this.view); + buffer.on("changeMode", this._onChangeMode); + + this._onChangeWrapLimit = this.view.updateFull.bind(this.view); + buffer.on("changeWrapLimit", this._onChangeWrapLimit); + + this._onChangeWrapMode = this.onChangeWrapMode.bind(this); + buffer.on("changeWrapMode", this._onChangeWrapMode); + + this._onChangeFold = this.onChangeFold.bind(this); + buffer.on("changeFold", this._onChangeFold); + + this._onChangeFrontMarker = this.view.updateFrontMarkers.bind(this.view); + buffer.on("changeFrontMarker", this._onChangeFrontMarker); + + this._onChangeBackMarker = this.view.updateBackMarkers.bind(this.view); + buffer.on("changeBackMarker", this._onChangeBackMarker); + + this._onChangeBreakpoint = this.onChangeBreakpoint.bind(this); + buffer.on("changeBreakpoint", this._onChangeBreakpoint); + + this._onChangeAnnotation = this.onChangeAnnotation.bind(this); + buffer.on("changeAnnotation", this._onChangeAnnotation); + + this._onCursorChange = this.onCursorChange.bind(this); + buffer.on("changeOverwrite", this._onCursorChange); + + this.selection = buffer.getSelection(); + this.selection.on("changeCursor", this._onCursorChange); + + this._onSelectionChange = this.onSelectionChange.bind(this); + this.selection.on("changeSelection", this._onSelectionChange); + + this._onChangeFrontMarker(); + this._onChangeBackMarker(); + this.onChangeBreakpoint(); + this.onChangeAnnotation(); + if (buffer.getUseWrapMode()) + this.view.adjustWrapLimit(); + + this.onCursorChange(); + this.onSelectionChange(); + + this.view.updateFull(); + }; + + this.onDocumentChange = function(e) { + var delta = e.data; + var range = delta.range; + + if (range.start.row == range.end.row && delta.action != "insertLines" && delta.action != "removeLines") + var lastRow = range.end.row; + else + lastRow = Infinity; + + this.view.updateLines(range.start.row, lastRow); + + // update cursor because tab characters can influence the cursor position + this.view.updateCursor(); + }; + + this.onTokenizerUpdate = function(e) { + var rows = e.data; + this.view.updateLines(rows.first, rows.last); + }; + + this.onChangeWrapMode = function() { + this.view.onResize(true); + }; + + this.onChangeFold = function() { + // Update the active line marker as due to folding changes the current + // line range on the screen might have changed. + this._updateHighlightActiveLine(); + this.view.updateFull(); + }; + + this.onChangeBreakpoint = function() { + this.view.setBreakpoints(this.model.buffer.getBreakpoints()); + }; + + this.onChangeAnnotation = function() { + this.view.setAnnotations(this.model.buffer.getAnnotations()); + }; + + this.onCursorChange = function(e) { + this.view.updateCursor(); + + if (!this._blockScrolling) + this.model.scrollCursorIntoView(); + + // move text input over the cursor + // this is required for iOS and IME + // TODO refactor + //this.view.moveTextAreaToCursor(this.textInput.getElement()); + + this._highlightBrackets(); + this._updateHighlightActiveLine(); + }; + + this.onSelectionChange = function(e) { + var buffer = this.model.buffer; + + if (buffer._selectionMarker) { + buffer.removeMarker(buffer._selectionMarker); + } + buffer._selectionMarker = null; + + if (!this.selection.isEmpty()) { + var range = this.selection.getRange(); + var style = this.model.getSelectionStyle(); + buffer._selectionMarker = buffer.addMarker(range, "ace_selection", style); + } else { + this._updateHighlightActiveLine(); + } + + if (this.model.highlightSelectedWord) + this.model.buffer.getMode().highlightSelection(this.model); + }; + + this._updateHighlightActiveLine = function() { + var buffer = this.model.buffer; + + if (buffer._highlightLineMarker) + buffer.removeMarker(buffer._highlightLineMarker); + + buffer._highlightLineMarker = null; + + if (this.model.highlightActiveLine && (this.model.selectionStyle != "line" || !this.selection.isMultiLine())) { + var cursor = this.selection.getCursor(); + var foldLine = buffer.getFoldLine(cursor.row); + var range; + if (foldLine) { + range = new Range(foldLine.start.row, 0, foldLine.end.row + 1, 0); + } else { + range = new Range(cursor.row, 0, cursor.row+1, 0); + } + buffer._highlightLineMarker = buffer.addMarker(range, "ace_active_line", "background"); + } + }; + + this._highlightBrackets = function() { + var buffer = this.model.buffer; + + if (buffer._bracketHighlight) { + buffer.removeMarker(buffer._bracketHighlight); + buffer._bracketHighlight = null; + } + + if (this._highlightPending) + return; + + // perform highlight async to not block the browser during navigation + var self = this; + this._highlightPending = true; + setTimeout(function() { + self._highlightPending = false; + + var pos = buffer.findMatchingBracket(self.selection.getCursor()); + if (pos) { + var range = new Range(pos.row, pos.column, pos.row, pos.column+1); + buffer._bracketHighlight = buffer.addMarker(range, "ace_bracket", "text"); + } + }, 10); + }; + }).call(WindowController.prototype); }); \ No newline at end of file