From 2b736e7c8ee45fafa1b2ec046028998c739d7a4e Mon Sep 17 00:00:00 2001 From: Fabian Jakobs Date: Thu, 22 Apr 2010 13:25:44 +0200 Subject: [PATCH] use APF style class declaration --- src/BackgroundTokenizer.js | 99 +-- src/Document.js | 641 ++++++++-------- src/Editor.js | 1020 +++++++++++++------------- src/KeyBinding.js | 43 +- src/ScrollBar.js | 36 +- src/Selection.js | 697 +++++++++--------- src/Tokenizer.js | 110 +-- src/VirtualRenderer.js | 386 +++++----- src/layer/Cursor.js | 130 ++-- src/layer/Gutter.js | 22 +- src/layer/Marker.js | 242 +++--- src/layer/Text.js | 147 ++-- src/mode/Css.js | 30 +- src/mode/CssHighlightRules.js | 10 +- src/mode/Html.js | 48 +- src/mode/HtmlHighlightRules.js | 29 +- src/mode/JavaScript.js | 66 +- src/mode/JavaScriptHighlightRules.js | 10 +- src/mode/Text.js | 36 +- src/mode/XmlHighlightRules.js | 10 +- 20 files changed, 1945 insertions(+), 1867 deletions(-) diff --git a/src/BackgroundTokenizer.js b/src/BackgroundTokenizer.js index 06ed59ac..f5bbe4e7 100644 --- a/src/BackgroundTokenizer.js +++ b/src/BackgroundTokenizer.js @@ -41,62 +41,67 @@ ace.BackgroundTokenizer = function(tokenizer) { this.$initEvents(); }; -ace.mixin(ace.BackgroundTokenizer.prototype, ace.MEventEmitter); -ace.BackgroundTokenizer.prototype.setTokenizer = function(tokenizer) { - this.tokenizer = tokenizer; - this.lines = []; +(function(){ - this.start(0); -}; + ace.mixin(this, ace.MEventEmitter); -ace.BackgroundTokenizer.prototype.setLines = function(textLines) { - this.textLines = textLines; - this.lines = []; + this.setTokenizer = function(tokenizer) { + this.tokenizer = tokenizer; + this.lines = []; - this.stop(); -}; - -ace.BackgroundTokenizer.prototype.fireUpdateEvent = function(firstRow, lastRow) { - var data = { - first: firstRow, - last: lastRow + this.start(0); }; - this.$dispatchEvent("update", {data: data}); -}; -ace.BackgroundTokenizer.prototype.start = function(startRow) { - this.currentLine = Math.min(startRow || 0, this.currentLine, - this.textLines.length); + this.setLines = function(textLines) { + this.textLines = textLines; + this.lines = []; - this.lines.splice(this.currentLine, this.lines.length); + this.stop(); + }; - if (!this.running) { - clearTimeout(this.running); - // pretty long delay to prevent the tokenizer from interfering with the user - this.running = setTimeout(this._worker, 200); - } -}; + this.fireUpdateEvent = function(firstRow, lastRow) { + var data = { + first: firstRow, + last: lastRow + }; + this.$dispatchEvent("update", {data: data}); + }; -ace.BackgroundTokenizer.prototype.stop = function() { - this.running = false; -}; + this.start = function(startRow) { + this.currentLine = Math.min(startRow || 0, this.currentLine, + this.textLines.length); -ace.BackgroundTokenizer.prototype.getTokens = function(row) { - return this._tokenizeRow(row).tokens; -}; + this.lines.splice(this.currentLine, this.lines.length); -ace.BackgroundTokenizer.prototype.getState = function(row) { - return this._tokenizeRow(row).state; -}; - -ace.BackgroundTokenizer.prototype._tokenizeRow = function(row) { - if (!this.lines[row]) { - var state = "start"; - if (row > 0 && this.lines[row - 1]) { - state = this.lines[row - 1].state; + if (!this.running) { + clearTimeout(this.running); + // pretty long delay to prevent the tokenizer from interfering with the user + this.running = setTimeout(this._worker, 200); } - this.lines[row] = this.tokenizer.getLineTokens(this.textLines[row] || "", state); - } - return this.lines[row]; -}; \ No newline at end of file + }; + + this.stop = function() { + this.running = false; + }; + + this.getTokens = function(row) { + return this._tokenizeRow(row).tokens; + }; + + this.getState = function(row) { + return this._tokenizeRow(row).state; + }; + + this._tokenizeRow = function(row) { + if (!this.lines[row]) { + var state = "start"; + if (row > 0 && this.lines[row - 1]) { + state = this.lines[row - 1].state; + } + this.lines[row] = this.tokenizer.getLineTokens(this.textLines[row] || "", state); + } + return this.lines[row]; + }; + +}).call(ace.BackgroundTokenizer.prototype); \ No newline at end of file diff --git a/src/Document.js b/src/Document.js index 9806ad06..9f39baef 100644 --- a/src/Document.js +++ b/src/Document.js @@ -13,377 +13,380 @@ ace.Document = function(text, mode) { } }; -ace.mixin(ace.Document.prototype, ace.MEventEmitter); +(function() { -ace.Document.prototype._split = function(text) { - return text.split(/\r\n|\r|\n/); -}; + ace.mixin(ace.Document.prototype, ace.MEventEmitter); -ace.Document.prototype.toString = function() { - return this.lines.join("\n"); -}; - -ace.Document.prototype.getSelection = function() { - return this.selection; -}; - -ace.Document.prototype.fireChangeEvent = function(firstRow, lastRow) { - var data = { - firstRow: firstRow, - lastRow: lastRow + this._split = function(text) { + return text.split(/\r\n|\r|\n/); }; - this.$dispatchEvent("change", { data: data}); -}; -ace.Document.prototype.getTabString = function() { - if (this.getUseSoftTabs()) { - return new Array(this.getTabSize()+1).join(" "); - } - return "\t"; -}; + this.toString = function() { + return this.lines.join("\n"); + }; -ace.Document.prototype._useSoftTabs = true; -ace.Document.prototype.setUseSoftTabs = function(useSoftTabs) { - if (this._useSoftTabs === useSoftTabs) return; + this.getSelection = function() { + return this.selection; + }; - this._useSoftTabs = useSoftTabs; -}; + this.fireChangeEvent = function(firstRow, lastRow) { + var data = { + firstRow: firstRow, + lastRow: lastRow + }; + this.$dispatchEvent("change", { data: data}); + }; -ace.Document.prototype.getUseSoftTabs = function() { - return this._useSoftTabs; -}; - -ace.Document.prototype._tabSize = 4; -ace.Document.prototype.setTabSize = function(tabSize) { - if (this._tabSize === tabSize) return; - - this._tabSize = tabSize; - this.$dispatchEvent("changeTabSize"); -}; - -ace.Document.prototype.getTabSize = function() { - return this._tabSize; -}; - -ace.Document.prototype._mode = null; -ace.Document.prototype.setMode = function(mode) { - if (this._mode === mode) return; - - this._mode = mode; - this.$dispatchEvent("changeMode"); -}; - -ace.Document.prototype.getMode = function() { - if (!this._mode) { - this._mode = new ace.mode.Text(); - } - return this._mode; -}; - -ace.Document.prototype._scrollTop = 0; -ace.Document.prototype.setScrollTopRow = function(scrollTopRow) { - if (this._scrollTop === scrollTopRow) return; - - this._scrollTop = scrollTopRow; - this.$dispatchEvent("changeScrollTop"); -}; - -ace.Document.prototype.getScrollTopRow = function() { - return this._scrollTop; -}; - -ace.Document.prototype.getWidth = function() { - if (this.modified) { - this.modified = false; - - var lines = this.lines; - var longestLine = 0; - for ( var i = 0; i < lines.length; i++) { - longestLine = Math.max(longestLine, lines[i].length); + this.getTabString = function() { + if (this.getUseSoftTabs()) { + return new Array(this.getTabSize()+1).join(" "); } - this.width = longestLine; - } - return this.width; -}; + return "\t"; + }; -ace.Document.prototype.getLine = function(row) { - return this.lines[row] || ""; -}; + this._useSoftTabs = false; + this.setUseSoftTabs = function(useSoftTabs) { + if (this._useSoftTabs === useSoftTabs) return; -ace.Document.prototype.getLength = function() { - return this.lines.length; -}; + this._useSoftTabs = useSoftTabs; + }; -ace.Document.prototype.getTextRange = function(range) { - if (range.start.row == range.end.row) { - return this.lines[range.start.row].substring(range.start.column, - range.end.column); - } - else { - var lines = []; - lines.push(this.lines[range.start.row].substring(range.start.column)); - lines.push.apply(lines, this.getLines(range.start.row+1, range.end.row-1)); - lines.push(this.lines[range.end.row].substring(0, range.end.column)); - return lines.join("\n"); - } -}; + this.getUseSoftTabs = function() { + return this._useSoftTabs; + }; -ace.Document.prototype.getLines = function(firstRow, lastRow) { - return this.lines.slice(firstRow, lastRow+1); -}; + this._tabSize = 4; + this.setTabSize = function(tabSize) { + if (this._tabSize === tabSize) return; -ace.Document.prototype.findMatchingBracket = function(position) { - if (position.column == 0) return null; + this._tabSize = tabSize; + this.$dispatchEvent("changeTabSize"); + }; - var charBeforeCursor = this.getLine(position.row).charAt(position.column-1); - if (charBeforeCursor == "") return null; + this.getTabSize = function() { + return this._tabSize; + }; - var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/); - if (!match) { + this._mode = null; + this.setMode = function(mode) { + if (this._mode === mode) return; + + this._mode = mode; + this.$dispatchEvent("changeMode"); + }; + + this.getMode = function() { + if (!this._mode) { + this._mode = new ace.mode.Text(); + } + return this._mode; + }; + + this._scrollTop = 0; + this.setScrollTopRow = function(scrollTopRow) { + if (this._scrollTop === scrollTopRow) return; + + this._scrollTop = scrollTopRow; + this.$dispatchEvent("changeScrollTop"); + }; + + this.getScrollTopRow = function() { + return this._scrollTop; + }; + + this.getWidth = function() { + if (this.modified) { + this.modified = false; + + var lines = this.lines; + var longestLine = 0; + for ( var i = 0; i < lines.length; i++) { + longestLine = Math.max(longestLine, lines[i].length); + } + this.width = longestLine; + } + return this.width; + }; + + this.getLine = function(row) { + return this.lines[row] || ""; + }; + + this.getLength = function() { + return this.lines.length; + }; + + this.getTextRange = function(range) { + if (range.start.row == range.end.row) { + return this.lines[range.start.row].substring(range.start.column, + range.end.column); + } + else { + var lines = []; + lines.push(this.lines[range.start.row].substring(range.start.column)); + lines.push.apply(lines, this.getLines(range.start.row+1, range.end.row-1)); + lines.push(this.lines[range.end.row].substring(0, range.end.column)); + return lines.join("\n"); + } + }; + + this.getLines = function(firstRow, lastRow) { + return this.lines.slice(firstRow, lastRow+1); + }; + + this.findMatchingBracket = function(position) { + if (position.column == 0) return null; + + var charBeforeCursor = this.getLine(position.row).charAt(position.column-1); + if (charBeforeCursor == "") return null; + + var match = charBeforeCursor.match(/([\(\[\{])|([\)\]\}])/); + if (!match) { + return null; + } + + if (match[1]) { + return this._findClosingBracket(match[1], position); + } else { + return this._findOpeningBracket(match[2], position); + } + }; + + this._brackets = { + ")": "(", + "(": ")", + "]": "[", + "[": "]", + "{": "}", + "}": "{" + }; + + this._findOpeningBracket = function(bracket, position) { + var openBracket = this._brackets[bracket]; + + var column = position.column - 2; + var row = position.row; + var depth = 1; + + var line = this.getLine(row); + + while (true) { + while(column >= 0) { + var char = line.charAt(column); + if (char == openBracket) { + depth -= 1; + if (depth == 0) { + return {row: row, column: column}; + } + } + else if (char == bracket) { + depth +=1; + } + column -= 1; + } + row -=1; + if (row < 0) break; + + var line = this.getLine(row); + var column = line.length-1; + } return null; - } + }; - if (match[1]) { - return this._findClosingBracket(match[1], position); - } else { - return this._findOpeningBracket(match[2], position); - } -}; + this._findClosingBracket = function(bracket, position) { + var closingBracket = this._brackets[bracket]; -ace.Document.prototype._brackets = { - ")": "(", - "(": ")", - "]": "[", - "[": "]", - "{": "}", - "}": "{" -}; - -ace.Document.prototype._findOpeningBracket = function(bracket, position) { - var openBracket = this._brackets[bracket]; - - var column = position.column - 2; - var row = position.row; - var depth = 1; - - var line = this.getLine(row); - - while (true) { - while(column >= 0) { - var char = line.charAt(column); - if (char == openBracket) { - depth -= 1; - if (depth == 0) { - return {row: row, column: column}; - } - } - else if (char == bracket) { - depth +=1; - } - column -= 1; - } - row -=1; - if (row < 0) break; + var column = position.column; + var row = position.row; + var depth = 1; var line = this.getLine(row); - var column = line.length-1; - } - return null; -}; + var lineCount = this.getLength(); -ace.Document.prototype._findClosingBracket = function(bracket, position) { - var closingBracket = this._brackets[bracket]; - - var column = position.column; - var row = position.row; - var depth = 1; - - var line = this.getLine(row); - var lineCount = this.getLength(); - - while (true) { - while(column < line.length) { - var char = line.charAt(column); - if (char == closingBracket) { - depth -= 1; - if (depth == 0) { - return {row: row, column: column}; + while (true) { + while(column < line.length) { + var char = line.charAt(column); + if (char == closingBracket) { + depth -= 1; + if (depth == 0) { + return {row: row, column: column}; + } } + else if (char == bracket) { + depth +=1; + } + column += 1; } - else if (char == bracket) { - depth +=1; + row +=1; + if (row >= lineCount) break; + + var line = this.getLine(row); + var column = 0; + } + return null; + }; + + this.insert = function(position, text) { + var end = this._insert(position, text); + this.fireChangeEvent(position.row, position.row == end.row ? position.row + : undefined); + return end; + }; + + this._insertLines = function(row, lines) { + var args = [row, 0]; + args.push.apply(args, lines); + this.lines.splice.apply(this.lines, args); + }, + + this._insert = function(position, text) { + this.modified = true; + + var newLines = this._split(text); + + if (this._isNewLine(text)) { + var line = this.lines[position.row] || ""; + this.lines[position.row] = line.substring(0, position.column); + this.lines.splice(position.row + 1, 0, line.substring(position.column)); + + return { + row : position.row + 1, + column : 0 + }; + } + else if (newLines.length == 1) { + var line = this.lines[position.row] || ""; + this.lines[position.row] = line.substring(0, position.column) + text + + line.substring(position.column); + + return { + row : position.row, + column : position.column + text.length + }; + } + else { + var line = this.lines[position.row] || ""; + + this.lines[position.row] = line.substring(0, position.column) + + newLines[0]; + this.lines[position.row + 1] = newLines[newLines.length - 1] + + line.substring(position.column); + + if (newLines.length > 2) { + this._insertLines(position.row + 1, newLines.slice(1, -1)); } - column += 1; + + return { + row : position.row + newLines.length - 1, + column : newLines[newLines.length - 1].length + }; } - row +=1; - if (row >= lineCount) break; + }; - var line = this.getLine(row); - var column = 0; - } - return null; -}; + this._isNewLine = function(text) { + return (text == "\r\n" || text == "\r" || text == "\n"); + }; -ace.Document.prototype.insert = function(position, text) { - var end = this._insert(position, text); - this.fireChangeEvent(position.row, position.row == end.row ? position.row - : undefined); - return end; -}; + this.remove = function(range) { + this._remove(range); -ace.Document.prototype._insertLines = function(row, lines) { - var args = [row, 0]; - args.push.apply(args, lines); - this.lines.splice.apply(this.lines, args); -}, + this.fireChangeEvent(range.start.row, + range.end.row == range.start.row ? range.start.row + : undefined); + return range.start; + }; -ace.Document.prototype._insert = function(position, text) { - this.modified = true; + this._remove = function(range) { + this.modified = true; - var newLines = this._split(text); + var firstRow = range.start.row; + var lastRow = range.end.row; - if (this._isNewLine(text)) { - var line = this.lines[position.row] || ""; - this.lines[position.row] = line.substring(0, position.column); - this.lines.splice(position.row + 1, 0, line.substring(position.column)); + var row = this.lines[firstRow].substring(0, range.start.column) + + this.lines[lastRow].substring(range.end.column); - return { - row : position.row + 1, - column : 0 - }; - } - else if (newLines.length == 1) { - var line = this.lines[position.row] || ""; - this.lines[position.row] = line.substring(0, position.column) + text - + line.substring(position.column); + this.lines.splice(firstRow, lastRow - firstRow + 1, row); - return { - row : position.row, - column : position.column + text.length - }; - } - else { - var line = this.lines[position.row] || ""; + return range.start; + }; - this.lines[position.row] = line.substring(0, position.column) - + newLines[0]; - this.lines[position.row + 1] = newLines[newLines.length - 1] - + line.substring(position.column); - - if (newLines.length > 2) { - this._insertLines(position.row + 1, newLines.slice(1, -1)); + this.replace = function(range, text) { + this._remove(range); + if (text) { + var end = this._insert(range.start, text); + } + else { + end = range.start; } - return { - row : position.row + newLines.length - 1, - column : newLines[newLines.length - 1].length - }; - } -}; + var lastRemoved = range.end.column == 0 ? range.end.column - 1 + : range.end.column; + this.fireChangeEvent(range.start.row, lastRemoved == end.row ? lastRemoved + : undefined); -ace.Document.prototype._isNewLine = function(text) { - return (text == "\r\n" || text == "\r" || text == "\n"); -}; + return end; + }; -ace.Document.prototype.remove = function(range) { - this._remove(range); + this.indentRows = function(range, indentString) { + for (var i=range.start.row; i<= range.end.row; i++) { + this.lines[i] = indentString + this.getLine(i); + } + this.fireChangeEvent(range.start.row, range.end.row); + return indentString.length; + }; - this.fireChangeEvent(range.start.row, - range.end.row == range.start.row ? range.start.row - : undefined); - return range.start; -}; + this.outdentRows = function(range, indentString) { + outdentLength = indentString.length; -ace.Document.prototype._remove = function(range) { - this.modified = true; - - var firstRow = range.start.row; - var lastRow = range.end.row; - - var row = this.lines[firstRow].substring(0, range.start.column) - + this.lines[lastRow].substring(range.end.column); - - this.lines.splice(firstRow, lastRow - firstRow + 1, row); - - return range.start; -}; - -ace.Document.prototype.replace = function(range, text) { - this._remove(range); - if (text) { - var end = this._insert(range.start, text); - } - else { - end = range.start; - } - - var lastRemoved = range.end.column == 0 ? range.end.column - 1 - : range.end.column; - this.fireChangeEvent(range.start.row, lastRemoved == end.row ? lastRemoved - : undefined); - - return end; -}; - -ace.Document.prototype.indentRows = function(range, indentString) { - for (var i=range.start.row; i<= range.end.row; i++) { - this.lines[i] = indentString + this.getLine(i); - } - this.fireChangeEvent(range.start.row, range.end.row); - return indentString.length; -}; - -ace.Document.prototype.outdentRows = function(range, indentString) { - outdentLength = indentString.length; - - for (var i=range.start.row; i<= range.end.row; i++) { - if (this.getLine(i).substr(0, outdentLength) !== indentString) { - return 0; + for (var i=range.start.row; i<= range.end.row; i++) { + if (this.getLine(i).substr(0, outdentLength) !== indentString) { + return 0; + } } - } - for (var i=range.start.row; i<= range.end.row; i++) { - this.lines[i] = this.getLine(i).substring(outdentLength); - } + for (var i=range.start.row; i<= range.end.row; i++) { + this.lines[i] = this.getLine(i).substring(outdentLength); + } - this.fireChangeEvent(range.start.row, range.end.row); - return -outdentLength; -}; + this.fireChangeEvent(range.start.row, range.end.row); + return -outdentLength; + }; -ace.Document.prototype.moveLinesUp = function(firstRow, lastRow) { - if (firstRow <= 0) return 0; + this.moveLinesUp = function(firstRow, lastRow) { + if (firstRow <= 0) return 0; - var removed = this.lines.splice(firstRow, lastRow-firstRow+1); - this._insertLines(firstRow-1, removed); + var removed = this.lines.splice(firstRow, lastRow-firstRow+1); + this._insertLines(firstRow-1, removed); - this.fireChangeEvent(firstRow-1, lastRow); - return -1; -}; + this.fireChangeEvent(firstRow-1, lastRow); + return -1; + }; -ace.Document.prototype.moveLinesDown = function(firstRow, lastRow) { - if (lastRow >= this.lines.length-1) return 0; + this.moveLinesDown = function(firstRow, lastRow) { + if (lastRow >= this.lines.length-1) return 0; - var removed = this.lines.splice(firstRow, lastRow-firstRow+1); - this._insertLines(firstRow+1, removed); + var removed = this.lines.splice(firstRow, lastRow-firstRow+1); + this._insertLines(firstRow+1, removed); - this.fireChangeEvent(firstRow, lastRow+1); - return 1; -}; + this.fireChangeEvent(firstRow, lastRow+1); + return 1; + }; -ace.Document.prototype.duplicateLines = function(firstRow, lastRow) { - var firstRow = this._clipRowToDocument(firstRow); - var lastRow = this._clipRowToDocument(lastRow); + this.duplicateLines = function(firstRow, lastRow) { + var firstRow = this._clipRowToDocument(firstRow); + var lastRow = this._clipRowToDocument(lastRow); - var lines = this.getLines(firstRow, lastRow); - this._insertLines(firstRow, lines); + var lines = this.getLines(firstRow, lastRow); + this._insertLines(firstRow, lines); - var addedRows = lastRow - firstRow + 1; - this.fireChangeEvent(firstRow, lastRow+addedRows); + var addedRows = lastRow - firstRow + 1; + this.fireChangeEvent(firstRow, lastRow+addedRows); - return addedRows; -}; + return addedRows; + }; -ace.Document.prototype._clipRowToDocument = function(row) { - return Math.max(0, Math.min(row, this.lines.length-1)); -}; + this._clipRowToDocument = function(row) { + return Math.max(0, Math.min(row, this.lines.length-1)); + }; +}).call(ace.Document.prototype); diff --git a/src/Editor.js b/src/Editor.js index ddee8e20..20508660 100644 --- a/src/Editor.js +++ b/src/Editor.js @@ -26,577 +26,579 @@ ace.Editor = function(renderer, doc) { this.setDocument(doc || new ace.Document("")); }; +(function(){ -ace.Editor.prototype.setDocument = function(doc) { - if (this.doc == doc) return; + this.setDocument = function(doc) { + if (this.doc == doc) return; - if (this.doc) { - this.doc.removeEventListener("change", this._onDocumentChange); - this.doc.removeEventListener("changeMode", this._onDocumentModeChange); - this.doc.removeEventListener("changeTabSize", this._onDocumentChangeTabSize); + if (this.doc) { + this.doc.removeEventListener("change", this._onDocumentChange); + this.doc.removeEventListener("changeMode", this._onDocumentModeChange); + this.doc.removeEventListener("changeTabSize", this._onDocumentChangeTabSize); - var selection = this.doc.getSelection(); - this.selection.removeEventListener("changeCursor", this._onCursorChange); - this.selection.removeEventListener("changeSelection", this._onSelectionChange); + var selection = this.doc.getSelection(); + this.selection.removeEventListener("changeCursor", this._onCursorChange); + this.selection.removeEventListener("changeSelection", this._onSelectionChange); - this.doc.setScrollTopRow(this.renderer.getScrollTopRow()); - } + this.doc.setScrollTopRow(this.renderer.getScrollTopRow()); + } - this.doc = doc; + this.doc = doc; - this._onDocumentChange = ace.bind(this.onDocumentChange, this); - doc.addEventListener("change", this._onDocumentChange); - this.renderer.setDocument(doc); + this._onDocumentChange = ace.bind(this.onDocumentChange, this); + doc.addEventListener("change", this._onDocumentChange); + this.renderer.setDocument(doc); - this._onDocumentModeChange = ace.bind(this.onDocumentModeChange, this); - doc.addEventListener("changeMode", this._onDocumentModeChange); + this._onDocumentModeChange = ace.bind(this.onDocumentModeChange, this); + doc.addEventListener("changeMode", this._onDocumentModeChange); - this._onDocumentChangeTabSize = ace.bind(this.renderer.draw, this.renderer); - doc.addEventListener("changeTabSize", this._onDocumentChangeTabSize); + this._onDocumentChangeTabSize = ace.bind(this.renderer.draw, this.renderer); + doc.addEventListener("changeTabSize", this._onDocumentChangeTabSize); - this.selection = doc.getSelection(); + this.selection = doc.getSelection(); - this._onCursorChange = ace.bind(this.onCursorChange, this); - this.selection.addEventListener("changeCursor", this._onCursorChange); + this._onCursorChange = ace.bind(this.onCursorChange, this); + this.selection.addEventListener("changeCursor", this._onCursorChange); - this._onSelectionChange = ace.bind(this.onSelectionChange, this); - this.selection.addEventListener("changeSelection", this._onSelectionChange); + this._onSelectionChange = ace.bind(this.onSelectionChange, this); + this.selection.addEventListener("changeSelection", this._onSelectionChange); - this.onDocumentModeChange(); - this.bgTokenizer.setLines(this.doc.lines); + this.onDocumentModeChange(); + this.bgTokenizer.setLines(this.doc.lines); - this.renderer.draw(); - this.onCursorChange(); - this.onSelectionChange(); - this.renderer.scrollToRow(doc.getScrollTopRow()); -}; + this.renderer.draw(); + this.onCursorChange(); + this.onSelectionChange(); + this.renderer.scrollToRow(doc.getScrollTopRow()); + }; -ace.Editor.prototype.getDocument = function() { - return this.doc; -}; + this.getDocument = function() { + return this.doc; + }; -ace.Editor.prototype.getSelection = function() { - return this.selection; -}; + this.getSelection = function() { + return this.selection; + }; -ace.Editor.prototype.resize = function() { - this.renderer.onResize(); -}; + this.resize = function() { + this.renderer.onResize(); + }; -ace.Editor.prototype._highlightBrackets = function() { - if (this._bracketHighlight) { - this.renderer.removeMarker(this._bracketHighlight); - this._bracketHighlight = null; - } + this._highlightBrackets = function() { + if (this._bracketHighlight) { + this.renderer.removeMarker(this._bracketHighlight); + this._bracketHighlight = null; + } - if (this._highlightPending) { - return; - } + 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; + // perform highlight async to not block the browser during navigation + var self = this; + this._highlightPending = true; + setTimeout(function() { + self._highlightPending = false; - var pos = self.doc.findMatchingBracket(self.getCursorPosition()); - if (pos) { - range = { - start: pos, + var pos = self.doc.findMatchingBracket(self.getCursorPosition()); + if (pos) { + range = { + start: pos, + end: { + row: pos.row, + column: pos.column+1 + } + }; + self._bracketHighlight = self.renderer.addMarker(range, "bracket"); + } + }, 10); + }; + + this.focus = function() { + this.textInput.focus(); + }; + + this.blur = function() { + this.textInput.blur(); + }; + + this.onFocus = function() { + this.renderer.showCursor(); + this.renderer.visualizeFocus(); + }; + + this.onBlur = function() { + this.renderer.hideCursor(); + this.renderer.visualizeBlur(); + }; + + this.onDocumentChange = function(e) { + var data = e.data; + this.bgTokenizer.start(data.firstRow); + this.renderer.updateLines(data.firstRow, data.lastRow); + }; + + this.onTokenizerUpdate = function(e) { + var rows = e.data; + this.renderer.updateLines(rows.first, rows.last); + }; + + this.onCursorChange = function() { + this._highlightBrackets(); + this.renderer.updateCursor(this.getCursorPosition()); + + if (!this._blockScrolling) { + this.renderer.scrollCursorIntoView(); + } + this._updateHighlightActiveLine(); + }; + + this._updateHighlightActiveLine = function() { + if (this._highlightLineMarker) { + this.renderer.removeMarker(this._highlightLineMarker); + } + this._highlightLineMarker = null; + + if (this.getHighlightActiveLine() && !this.selection.isMultiLine()) { + var cursor = this.getCursorPosition(); + var range = { + start: { + row: cursor.row, + column: 0 + }, end: { - row: pos.row, - column: pos.column+1 + row: cursor.row+1, + column: 0 } }; - self._bracketHighlight = self.renderer.addMarker(range, "bracket"); + this._highlightLineMarker = this.renderer.addMarker(range, "active_line", "line"); } - }, 10); -}; + }; -ace.Editor.prototype.focus = function() { - this.textInput.focus(); -}; + this.onSelectionChange = function() { + if (this._selectionMarker) { + this.renderer.removeMarker(this._selectionMarker); + } + this._selectionMarker = null; -ace.Editor.prototype.blur = function() { - this.textInput.blur(); -}; + if (!this.selection.isEmpty()) { + var range = this.selection.getRange(); + var style = this.getSelectionStyle(); + this._selectionMarker = this.renderer.addMarker(range, "selection", style); + } -ace.Editor.prototype.onFocus = function() { - this.renderer.showCursor(); - this.renderer.visualizeFocus(); -}; + this.onCursorChange(); + }; -ace.Editor.prototype.onBlur = function() { - this.renderer.hideCursor(); - this.renderer.visualizeBlur(); -}; + this.onDocumentModeChange = function() { + var mode = this.doc.getMode(); -ace.Editor.prototype.onDocumentChange = function(e) { - var data = e.data; - this.bgTokenizer.start(data.firstRow); - this.renderer.updateLines(data.firstRow, data.lastRow); -}; + this.mode = mode; + var tokenizer = mode.getTokenizer(); -ace.Editor.prototype.onTokenizerUpdate = function(e) { - var rows = e.data; - this.renderer.updateLines(rows.first, rows.last); -}; + if (!this.bgTokenizer) { + var onUpdate = ace.bind(this.onTokenizerUpdate, this); + this.bgTokenizer = new ace.BackgroundTokenizer(tokenizer); + this.bgTokenizer.addEventListener("update", onUpdate); + } else { + this.bgTokenizer.setTokenizer(tokenizer); + } -ace.Editor.prototype.onCursorChange = function() { - this._highlightBrackets(); - this.renderer.updateCursor(this.getCursorPosition()); + this.renderer.setTokenizer(this.bgTokenizer); + this.renderer.draw(); + }; - if (!this._blockScrolling) { + + this.onMouseDown = function(e) { + var pageX = ace.getDocumentX(e); + var pageY = ace.getDocumentY(e); + + var pos = this.renderer.screenToTextCoordinates(pageX, pageY); + this.moveCursorToPosition(pos); + this.selection.setSelectionAnchor(pos.row, pos.column); this.renderer.scrollCursorIntoView(); - } - this._updateHighlightActiveLine(); -}; -ace.Editor.prototype._updateHighlightActiveLine = function() { - if (this._highlightLineMarker) { - this.renderer.removeMarker(this._highlightLineMarker); - } - this._highlightLineMarker = null; + var _self = this; + var mousePageX, mousePageY; - if (this.getHighlightActiveLine() && !this.selection.isMultiLine()) { + var onMouseSelection = function(e) { + mousePageX = ace.getDocumentX(e); + mousePageY = ace.getDocumentY(e); + }; + + var onMouseSelectionEnd = function() { + clearInterval(timerId); + }; + + var onSelectionInterval = function() { + if (mousePageX === undefined || mousePageY === undefined) + return; + + selectionLead = _self.renderer.screenToTextCoordinates(mousePageX, + mousePageY); + + _self.selection.selectToPosition(selectionLead); + _self.renderer.scrollCursorIntoView(); + }; + + ace.capture(this.container, onMouseSelection, onMouseSelectionEnd); + var timerId = setInterval(onSelectionInterval, 20); + + return ace.preventDefault(e); + }; + + this.onMouseDoubleClick = function(e) { + this.selection.selectWord(); + }; + + this.onMouseTripleClick = function(e) { + this.selection.selectLine(); + }; + + this.onMouseWheel = function(e) { + var delta = e.wheel; + this.renderer.scrollToY(this.renderer.getScrollTop() - (delta * 15)); + return ace.preventDefault(e); + }; + + this.getCopyText = function() { + if (!this.selection.isEmpty()) { + return this.doc.getTextRange(this.getSelectionRange()); + } + else { + return ""; + } + }; + + this.onCut = function() { + if (!this.selection.isEmpty()) { + this.moveCursorToPosition(this.doc.remove(this.getSelectionRange())); + this.clearSelection(); + } + }; + + this.onTextInput = function(text) { var cursor = this.getCursorPosition(); + + if (this.doc.getUseSoftTabs()) { + text = text.replace(/\t/g, this.doc.getTabString()); + } + + if (!this.selection.isEmpty()) { + var end = this.doc.replace(this.getSelectionRange(), text); + this.clearSelection(); + } + else { + var end = this.doc.insert(cursor, text); + } + + // multi line insert + var row = cursor.row; + if (row !== end.row) { + var line = this.doc.getLine(row); + var lineState = this.bgTokenizer.getState(row); + var indent = this.mode.getNextLineIndent(line, lineState, this.doc.getTabString()); + if (indent) { + var indentRange = { + start: { + row: row+1, + column: 0 + }, + end : end + }; + end.column += this.doc.indentRows(indentRange, indent); + } + } + + this.moveCursorToPosition(end); + this.renderer.scrollCursorIntoView(); + }; + + this._selectionStyle = "line"; + this.setSelectionStyle = function(style) { + if (this._selectionStyle == style) return; + + this._selectionStyle = style; + this.onSelectionChange(); + }; + + this.getSelectionStyle = function() { + return this._selectionStyle; + }; + + this._highlightActiveLine = true; + this.setHighlightActiveLine = function(shouldHighlight) { + if (this._highlightActiveLine == shouldHighlight) return; + + this._highlightActiveLine = shouldHighlight; + this._updateHighlightActiveLine(); + }; + + this.getHighlightActiveLine = function() { + return this._highlightActiveLine; + }; + + this.removeRight = function() { + if (this.selection.isEmpty()) { + this.selection.selectRight(); + } + this.moveCursorToPosition(this.doc.remove(this.getSelectionRange())); + this.clearSelection(); + }; + + this.removeLeft = function() { + if (this.selection.isEmpty()) { + this.selection.selectLeft(); + } + this.moveCursorToPosition(this.doc.remove(this.getSelectionRange())); + this.clearSelection(); + }; + + this.blockIndent = function(indentString) { + var indentString = indentString || this.doc.getTabString(); + var addedColumns = this.doc.indentRows(this.getSelectionRange(), indentString); + + this.selection.shiftSelection(addedColumns); + }; + + this.blockOutdent = function(indentString) { + var indentString = indentString || this.doc.getTabString(); + var addedColumns = this.doc.outdentRows(this.getSelectionRange(), indentString); + + this.selection.shiftSelection(addedColumns); + }; + + this.toggleCommentLines = function() { + var rows = this._getSelectedRows(); + var range = { start: { - row: cursor.row, + row: rows.first, column: 0 }, end: { - row: cursor.row+1, + row: rows.last, column: 0 } }; - this._highlightLineMarker = this.renderer.addMarker(range, "active_line", "line"); - } -}; + var state = this.bgTokenizer.getState(this.getCursorPosition().row); + var addedColumns = this.mode.toggleCommentLines(this.doc, range, state); -ace.Editor.prototype.onSelectionChange = function() { - if (this._selectionMarker) { - this.renderer.removeMarker(this._selectionMarker); - } - this._selectionMarker = null; - - if (!this.selection.isEmpty()) { - var range = this.selection.getRange(); - var style = this.getSelectionStyle(); - this._selectionMarker = this.renderer.addMarker(range, "selection", style); - } - - this.onCursorChange(); -}; - -ace.Editor.prototype.onDocumentModeChange = function() { - var mode = this.doc.getMode(); - - this.mode = mode; - var tokenizer = mode.getTokenizer(); - - if (!this.bgTokenizer) { - var onUpdate = ace.bind(this.onTokenizerUpdate, this); - this.bgTokenizer = new ace.BackgroundTokenizer(tokenizer); - this.bgTokenizer.addEventListener("update", onUpdate); - } else { - this.bgTokenizer.setTokenizer(tokenizer); - } - - this.renderer.setTokenizer(this.bgTokenizer); - this.renderer.draw(); -}; - - -ace.Editor.prototype.onMouseDown = function(e) { - var pageX = ace.getDocumentX(e); - var pageY = ace.getDocumentY(e); - - var pos = this.renderer.screenToTextCoordinates(pageX, pageY); - this.moveCursorToPosition(pos); - this.selection.setSelectionAnchor(pos.row, pos.column); - this.renderer.scrollCursorIntoView(); - - var _self = this; - var mousePageX, mousePageY; - - var onMouseSelection = function(e) { - mousePageX = ace.getDocumentX(e); - mousePageY = ace.getDocumentY(e); + this.selection.shiftSelection(addedColumns); }; - var onMouseSelectionEnd = function() { - clearInterval(timerId); - }; + this.removeLines = function() { + var rows = this._getSelectedRows(); + this.selection.setSelectionAnchor(rows.last+1, 0); + this.selection.selectTo(rows.first, 0); - var onSelectionInterval = function() { - if (mousePageX === undefined || mousePageY === undefined) - return; - - selectionLead = _self.renderer.screenToTextCoordinates(mousePageX, - mousePageY); - - _self.selection.selectToPosition(selectionLead); - _self.renderer.scrollCursorIntoView(); - }; - - ace.capture(this.container, onMouseSelection, onMouseSelectionEnd); - var timerId = setInterval(onSelectionInterval, 20); - - return ace.preventDefault(e); -}; - -ace.Editor.prototype.onMouseDoubleClick = function(e) { - this.selection.selectWord(); -}; - -ace.Editor.prototype.onMouseTripleClick = function(e) { - this.selection.selectLine(); -}; - -ace.Editor.prototype.onMouseWheel = function(e) { - var delta = e.wheel; - this.renderer.scrollToY(this.renderer.getScrollTop() - (delta * 15)); - return ace.preventDefault(e); -}; - -ace.Editor.prototype.getCopyText = function() { - if (!this.selection.isEmpty()) { - return this.doc.getTextRange(this.getSelectionRange()); - } - else { - return ""; - } -}; - -ace.Editor.prototype.onCut = function() { - if (!this.selection.isEmpty()) { - this.moveCursorToPosition(this.doc.remove(this.getSelectionRange())); + this.doc.remove(this.getSelectionRange()); this.clearSelection(); - } -}; + }; -ace.Editor.prototype.onTextInput = function(text) { - var cursor = this.getCursorPosition(); + this.moveLinesDown = function() { + this._moveLines(function(firstRow, lastRow) { + return this.doc.moveLinesDown(firstRow, lastRow); + }); + }; - if (this.doc.getUseSoftTabs()) { - text = text.replace(/\t/g, this.doc.getTabString()); - } + this.moveLinesUp = function() { + this._moveLines(function(firstRow, lastRow) { + return this.doc.moveLinesUp(firstRow, lastRow); + }); + }; - if (!this.selection.isEmpty()) { - var end = this.doc.replace(this.getSelectionRange(), text); + this.copyLinesUp = function() { + this._moveLines(function(firstRow, lastRow) { + this.doc.duplicateLines(firstRow, lastRow); + return 0; + }); + }; + + this.copyLinesDown = function() { + this._moveLines(function(firstRow, lastRow) { + return this.doc.duplicateLines(firstRow, lastRow); + }); + }; + + + this._moveLines = function(mover) { + var rows = this._getSelectedRows(); + + var linesMoved = mover.call(this, rows.first, rows.last); + + var selection = this.selection; + selection.setSelectionAnchor(rows.last+linesMoved+1, 0); + selection._moveSelection(function() { + selection.moveCursorTo(rows.first+linesMoved, 0); + }); + }; + + this._getSelectedRows = function() { + var range = this.getSelectionRange(); + var firstRow = range.start.row; + var lastRow = range.end.row; + if (range.end.column == 0 && (range.start.row !== range.end.row)) { + lastRow -= 1; + } + + return { + first: firstRow, + last: lastRow + }; + }; + + this.onCompositionStart = function() { + this.renderer.showComposition(this.getCursorPosition()); + this.onTextInput(" "); + }; + + this.onCompositionUpdate = function(text) { + this.renderer.setCompositionText(text); + }; + + this.onCompositionEnd = function() { + this.renderer.hideComposition(); + this.removeLeft(); + }; + + + this.getFirstVisibleRow = function() { + return this.renderer.getFirstVisibleRow(); + }; + + this.getLastVisibleRow = function() { + return this.renderer.getLastVisibleRow(); + }; + + this.isRowVisible = function(row) { + return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow()); + }; + + this.getVisibleRowCount = function() { + return this.getLastVisibleRow() - this.getFirstVisibleRow() + 1; + }; + + this.getPageDownRow = function() { + return this.renderer.getLastVisibleRow() - 1; + }; + + this.getPageUpRow = function() { + var firstRow = this.renderer.getFirstVisibleRow(); + var lastRow = this.renderer.getLastVisibleRow(); + + return firstRow - (lastRow - firstRow) + 1; + }; + + + this.scrollPageDown = function() { + this.scrollToRow(this.getPageDownRow()); + }; + + this.scrollPageUp = function() { + this.renderer.scrollToRow(this.getPageUpRow()); + }; + + this.scrollToRow = function(row) { + this.renderer.scrollToRow(row); + }; + + + this.getCursorPosition = function() { + return this.selection.getCursor(); + }; + + this.getSelectionRange = function() { + return this.selection.getRange(); + }; + + this.clearSelection = function() { + this.selection.clearSelection(); + }; + + this.moveCursorTo = function(row, column) { + this.selection.moveCursorTo(row, column); + }; + + this.moveCursorToPosition = function(pos) { + this.selection.moveCursorToPosition(pos); + }; + + + this.gotoLine = function(lineNumber) { + this._blockScrolling = true; + this.moveCursorTo(lineNumber-1, 0); + this._blockScrolling = false; + + if (!this.isRowVisible(this.getCursorPosition().row)) { + this.scrollToRow(lineNumber - 1 - Math.floor(this.getVisibleRowCount() / 2)); + } + }, + + this.navigateTo = function(row, column) { this.clearSelection(); - } - else { - var end = this.doc.insert(cursor, text); - } - - // multi line insert - var row = cursor.row; - if (row !== end.row) { - var line = this.doc.getLine(row); - var lineState = this.bgTokenizer.getState(row); - var indent = this.mode.getNextLineIndent(line, lineState, this.doc.getTabString()); - if (indent) { - var indentRange = { - start: { - row: row+1, - column: 0 - }, - end : end - }; - end.column += this.doc.indentRows(indentRange, indent); - } - } - - this.moveCursorToPosition(end); - this.renderer.scrollCursorIntoView(); -}; - -ace.Editor.prototype._selectionStyle = "line"; -ace.Editor.prototype.setSelectionStyle = function(style) { - if (this._selectionStyle == style) return; - - this._selectionStyle = style; - this.onSelectionChange(); -}; - -ace.Editor.prototype.getSelectionStyle = function() { - return this._selectionStyle; -}; - -ace.Editor.prototype._highlightActiveLine = true; -ace.Editor.prototype.setHighlightActiveLine = function(shouldHighlight) { - if (this._highlightActiveLine == shouldHighlight) return; - - this._highlightActiveLine = shouldHighlight; - this._updateHighlightActiveLine(); -}; - -ace.Editor.prototype.getHighlightActiveLine = function() { - return this._highlightActiveLine; -}; - -ace.Editor.prototype.removeRight = function() { - if (this.selection.isEmpty()) { - this.selection.selectRight(); - } - this.moveCursorToPosition(this.doc.remove(this.getSelectionRange())); - this.clearSelection(); -}; - -ace.Editor.prototype.removeLeft = function() { - if (this.selection.isEmpty()) { - this.selection.selectLeft(); - } - this.moveCursorToPosition(this.doc.remove(this.getSelectionRange())); - this.clearSelection(); -}; - -ace.Editor.prototype.blockIndent = function(indentString) { - var indentString = indentString || this.doc.getTabString(); - var addedColumns = this.doc.indentRows(this.getSelectionRange(), indentString); - - this.selection.shiftSelection(addedColumns); -}; - -ace.Editor.prototype.blockOutdent = function(indentString) { - var indentString = indentString || this.doc.getTabString(); - var addedColumns = this.doc.outdentRows(this.getSelectionRange(), indentString); - - this.selection.shiftSelection(addedColumns); -}; - -ace.Editor.prototype.toggleCommentLines = function() { - var rows = this._getSelectedRows(); - - var range = { - start: { - row: rows.first, - column: 0 - }, - end: { - row: rows.last, - column: 0 - } + this.moveCursorTo(row, column); }; - var state = this.bgTokenizer.getState(this.getCursorPosition().row); - var addedColumns = this.mode.toggleCommentLines(this.doc, range, state); - this.selection.shiftSelection(addedColumns); -}; - -ace.Editor.prototype.removeLines = function() { - var rows = this._getSelectedRows(); - this.selection.setSelectionAnchor(rows.last+1, 0); - this.selection.selectTo(rows.first, 0); - - this.doc.remove(this.getSelectionRange()); - this.clearSelection(); -}; - -ace.Editor.prototype.moveLinesDown = function() { - this._moveLines(function(firstRow, lastRow) { - return this.doc.moveLinesDown(firstRow, lastRow); - }); -}; - -ace.Editor.prototype.moveLinesUp = function() { - this._moveLines(function(firstRow, lastRow) { - return this.doc.moveLinesUp(firstRow, lastRow); - }); -}; - -ace.Editor.prototype.copyLinesUp = function() { - this._moveLines(function(firstRow, lastRow) { - this.doc.duplicateLines(firstRow, lastRow); - return 0; - }); -}; - -ace.Editor.prototype.copyLinesDown = function() { - this._moveLines(function(firstRow, lastRow) { - return this.doc.duplicateLines(firstRow, lastRow); - }); -}; - - -ace.Editor.prototype._moveLines = function(mover) { - var rows = this._getSelectedRows(); - - var linesMoved = mover.call(this, rows.first, rows.last); - - var selection = this.selection; - selection.setSelectionAnchor(rows.last+linesMoved+1, 0); - selection._moveSelection(function() { - selection.moveCursorTo(rows.first+linesMoved, 0); - }); -}; - -ace.Editor.prototype._getSelectedRows = function() { - var range = this.getSelectionRange(); - var firstRow = range.start.row; - var lastRow = range.end.row; - if (range.end.column == 0 && (range.start.row !== range.end.row)) { - lastRow -= 1; - } - - return { - first: firstRow, - last: lastRow + this.navigateUp = function() { + this.clearSelection(); + this.selection.moveCursorUp(); }; -}; -ace.Editor.prototype.onCompositionStart = function() { - this.renderer.showComposition(this.getCursorPosition()); - this.onTextInput(" "); -}; + this.navigateDown = function() { + this.clearSelection(); + this.selection.moveCursorDown(); + }; -ace.Editor.prototype.onCompositionUpdate = function(text) { - this.renderer.setCompositionText(text); -}; + this.navigateLeft = function() { + if (!this.selection.isEmpty()) { + var selectionStart = this.getSelectionRange().start; + this.moveCursorToPosition(selectionStart); + } + else { + this.selection.moveCursorLeft(); + } + this.clearSelection(); + }; -ace.Editor.prototype.onCompositionEnd = function() { - this.renderer.hideComposition(); - this.removeLeft(); -}; + this.navigateRight = function() { + if (!this.selection.isEmpty()) { + var selectionEnd = this.getSelectionRange().end; + this.moveCursorToPosition(selectionEnd); + } + else { + this.selection.moveCursorRight(); + } + this.clearSelection(); + }; + this.navigateLineStart = function() { + this.clearSelection(); + this.selection.moveCursorLineStart(); + }; -ace.Editor.prototype.getFirstVisibleRow = function() { - return this.renderer.getFirstVisibleRow(); -}; + this.navigateLineEnd = function() { + this.clearSelection(); + this.selection.moveCursorLineEnd(); + }; -ace.Editor.prototype.getLastVisibleRow = function() { - return this.renderer.getLastVisibleRow(); -}; + this.navigateFileEnd = function() { + this.clearSelection(); + this.selection.moveCursorFileEnd(); + }; -ace.Editor.prototype.isRowVisible = function(row) { - return (row >= this.getFirstVisibleRow() && row <= this.getLastVisibleRow()); -}; + this.navigateFileStart = function() { + this.clearSelection(); + this.selection.moveCursorFileStart(); + }; -ace.Editor.prototype.getVisibleRowCount = function() { - return this.getLastVisibleRow() - this.getFirstVisibleRow() + 1; -}; + this.navigateWordRight = function() { + this.clearSelection(); + this.selection.moveCursorWordRight(); + }; -ace.Editor.prototype.getPageDownRow = function() { - return this.renderer.getLastVisibleRow() - 1; -}; - -ace.Editor.prototype.getPageUpRow = function() { - var firstRow = this.renderer.getFirstVisibleRow(); - var lastRow = this.renderer.getLastVisibleRow(); - - return firstRow - (lastRow - firstRow) + 1; -}; - - -ace.Editor.prototype.scrollPageDown = function() { - this.scrollToRow(this.getPageDownRow()); -}; - -ace.Editor.prototype.scrollPageUp = function() { - this.renderer.scrollToRow(this.getPageUpRow()); -}; - -ace.Editor.prototype.scrollToRow = function(row) { - this.renderer.scrollToRow(row); -}; - - -ace.Editor.prototype.getCursorPosition = function() { - return this.selection.getCursor(); -}; - -ace.Editor.prototype.getSelectionRange = function() { - return this.selection.getRange(); -}; - -ace.Editor.prototype.clearSelection = function() { - this.selection.clearSelection(); -}; - -ace.Editor.prototype.moveCursorTo = function(row, column) { - this.selection.moveCursorTo(row, column); -}; - -ace.Editor.prototype.moveCursorToPosition = function(pos) { - this.selection.moveCursorToPosition(pos); -}; - - -ace.Editor.prototype.gotoLine = function(lineNumber) { - this._blockScrolling = true; - this.moveCursorTo(lineNumber-1, 0); - this._blockScrolling = false; - - if (!this.isRowVisible(this.getCursorPosition().row)) { - this.scrollToRow(lineNumber - 1 - Math.floor(this.getVisibleRowCount() / 2)); - } -}, - -ace.Editor.prototype.navigateTo = function(row, column) { - this.clearSelection(); - this.moveCursorTo(row, column); -}; - -ace.Editor.prototype.navigateUp = function() { - this.clearSelection(); - this.selection.moveCursorUp(); -}; - -ace.Editor.prototype.navigateDown = function() { - this.clearSelection(); - this.selection.moveCursorDown(); -}; - -ace.Editor.prototype.navigateLeft = function() { - if (!this.selection.isEmpty()) { - var selectionStart = this.getSelectionRange().start; - this.moveCursorToPosition(selectionStart); - } - else { - this.selection.moveCursorLeft(); - } - this.clearSelection(); -}; - -ace.Editor.prototype.navigateRight = function() { - if (!this.selection.isEmpty()) { - var selectionEnd = this.getSelectionRange().end; - this.moveCursorToPosition(selectionEnd); - } - else { - this.selection.moveCursorRight(); - } - this.clearSelection(); -}; - -ace.Editor.prototype.navigateLineStart = function() { - this.clearSelection(); - this.selection.moveCursorLineStart(); -}; - -ace.Editor.prototype.navigateLineEnd = function() { - this.clearSelection(); - this.selection.moveCursorLineEnd(); -}; - -ace.Editor.prototype.navigateFileEnd = function() { - this.clearSelection(); - this.selection.moveCursorFileEnd(); -}; - -ace.Editor.prototype.navigateFileStart = function() { - this.clearSelection(); - this.selection.moveCursorFileStart(); -}; - -ace.Editor.prototype.navigateWordRight = function() { - this.clearSelection(); - this.selection.moveCursorWordRight(); -}; - -ace.Editor.prototype.navigateWordLeft = function() { - this.clearSelection(); - this.selection.moveCursorWordLeft(); -}; \ No newline at end of file + this.navigateWordLeft = function() { + this.clearSelection(); + this.selection.moveCursorWordLeft(); + }; +}).call(ace.Editor.prototype); \ No newline at end of file diff --git a/src/KeyBinding.js b/src/KeyBinding.js index cbc1af6b..f105cb18 100644 --- a/src/KeyBinding.js +++ b/src/KeyBinding.js @@ -1,26 +1,9 @@ ace.provide("ace.KeyBinding"); -(function() { - -var keys = { - UP : 38, - RIGHT : 39, - DOWN : 40, - LEFT : 37, - PAGEUP : 33, - PAGEDOWN : 34, - POS1 : 36, - END : 35, - DELETE : 46, - BACKSPACE : 8, - TAB : 9, - A : 65, - D: 68, - L: 76, - "7": 55 -}; - ace.KeyBinding = function(element, editor) { + + var keys = this.keys; + ace.addListener(element, "keydown", function(e) { var key = e.keyCode; var selection = editor.getSelection(); @@ -198,4 +181,22 @@ ace.KeyBinding = function(element, editor) { }); }; -})(); \ No newline at end of file +(function() { + this.keys = { + UP : 38, + RIGHT : 39, + DOWN : 40, + LEFT : 37, + PAGEUP : 33, + PAGEDOWN : 34, + POS1 : 36, + END : 35, + DELETE : 46, + BACKSPACE : 8, + TAB : 9, + A : 65, + D: 68, + L: 76, + "7": 55 + }; +}).call(ace.KeyBinding.prototype); diff --git a/src/ScrollBar.js b/src/ScrollBar.js index b4a35bac..4bdcb366 100644 --- a/src/ScrollBar.js +++ b/src/ScrollBar.js @@ -17,24 +17,28 @@ ace.ScrollBar = function(parent) { ace.addListener(this.element, "scroll", ace.bind(this.onScroll, this)); }; -ace.mixin(ace.ScrollBar.prototype, ace.MEventEmitter); +(function() { -ace.ScrollBar.prototype.onScroll = function() { - this.$dispatchEvent("scroll", {data: this.element.scrollTop}); -}; + ace.mixin(ace.ScrollBar.prototype, ace.MEventEmitter); -ace.ScrollBar.prototype.getWidth = function() { - return this.width; -}; + this.onScroll = function() { + this.$dispatchEvent("scroll", {data: this.element.scrollTop}); + }; -ace.ScrollBar.prototype.setHeight = function(height) { - this.element.style.height = Math.max(0, height - this.width) + "px"; -}; + this.getWidth = function() { + return this.width; + }; -ace.ScrollBar.prototype.setInnerHeight = function(height) { - this.inner.style.height = height + "px"; -}; + this.setHeight = function(height) { + this.element.style.height = Math.max(0, height - this.width) + "px"; + }; -ace.ScrollBar.prototype.setScrollTop = function(scrollTop) { - this.element.scrollTop = scrollTop; -}; \ No newline at end of file + this.setInnerHeight = function(height) { + this.inner.style.height = height + "px"; + }; + + this.setScrollTop = function(scrollTop) { + this.element.scrollTop = scrollTop; + }; + +}).call(ace.ScrollBar.prototype); \ No newline at end of file diff --git a/src/Selection.js b/src/Selection.js index af2078f2..20598e64 100644 --- a/src/Selection.js +++ b/src/Selection.js @@ -11,371 +11,376 @@ ace.Selection = function(doc) { column: 0 }; }; -ace.mixin(ace.Selection.prototype, ace.MEventEmitter); -ace.Selection.prototype.updateCursor = function() { - this.$dispatchEvent("changeCursor", { data: this.getCursor() }); -}; +(function() { -ace.Selection.prototype.updateSelection = function() { - this.$dispatchEvent("changeSelection", {}); -}; + ace.mixin(ace.Selection.prototype, ace.MEventEmitter); -ace.Selection.prototype.isEmpty = function() { - return (this.selectionAnchor == null); -}; + this.updateCursor = function() { + this.$dispatchEvent("changeCursor", { data: this.getCursor() }); + }; -ace.Selection.prototype.isMultiLine = function() { - if (this.isEmpty()) { - return false; - } + this.updateSelection = function() { + this.$dispatchEvent("changeSelection", {}); + }; - var range = this.getRange(); - return (range.start.row !== range.end.row); -}; + this.isEmpty = function() { + return (this.selectionAnchor == null); + }; -ace.Selection.prototype.getCursor = function() { - return this.selectionLead; -}; + this.isMultiLine = function() { + if (this.isEmpty()) { + return false; + } -ace.Selection.prototype.setSelectionAnchor = function(row, column) { - this.clearSelection(); + var range = this.getRange(); + return (range.start.row !== range.end.row); + }; - this.selectionAnchor = this._clipPositionToDocument(row, column); -}; + this.getCursor = function() { + return this.selectionLead; + }; -ace.Selection.prototype.getSelectionAnchor = function() { - if (this.selectionAnchor) { - return this._clone(this.selectionAnchor); - } else { + this.setSelectionAnchor = function(row, column) { + this.clearSelection(); + + this.selectionAnchor = this._clipPositionToDocument(row, column); + }; + + this.getSelectionAnchor = function() { + if (this.selectionAnchor) { + return this._clone(this.selectionAnchor); + } else { + return this._clone(this.selectionLead); + } + }; + + this.getSelectionLead = function() { return this._clone(this.selectionLead); - } -}; - -ace.Selection.prototype.getSelectionLead = function() { - return this._clone(this.selectionLead); -}; - -ace.Selection.prototype.shiftSelection = function(columns) { - if (this.isEmpty()) { - this.moveCursorTo(this.selectionLead.row, this.selectionLead.column + columns); - return; }; - var anchor = this.getSelectionAnchor(); - var lead = this.getSelectionLead(); - - this.setSelectionAnchor(anchor.row, anchor.column + columns); - this._moveSelection(function() { - this.moveCursorTo(lead.row, lead.column + columns); - }); -}; - -ace.Selection.prototype.getRange = function() { - var anchor = this.selectionAnchor || this.selectionLead; - var lead = this.selectionLead; - - if (anchor.row > lead.row - || (anchor.row == lead.row && anchor.column > lead.column)) { - return { - start : lead, - end : anchor + this.shiftSelection = function(columns) { + if (this.isEmpty()) { + this.moveCursorTo(this.selectionLead.row, this.selectionLead.column + columns); + return; }; - } - else { - return { - start : anchor, - end : lead - }; - } -}; -ace.Selection.prototype.clearSelection = function() { - this.selectionAnchor = null; - this.updateSelection(); -}; + var anchor = this.getSelectionAnchor(); + var lead = this.getSelectionLead(); + this.setSelectionAnchor(anchor.row, anchor.column + columns); + this._moveSelection(function() { + this.moveCursorTo(lead.row, lead.column + columns); + }); + }; -ace.Selection.prototype.selectAll = function() { - var lastRow = this.doc.getLength() - 1; - this.setSelectionAnchor(lastRow, this.doc.getLine(lastRow).length); + this.getRange = function() { + var anchor = this.selectionAnchor || this.selectionLead; + var lead = this.selectionLead; - this._moveSelection(function() { - this.moveCursorTo(0, 0); - }); -}; - -ace.Selection.prototype._moveSelection = function(mover) { - if (!this.selectionAnchor) { - this.selectionAnchor = this._clone(this.selectionLead); - } - - mover.call(this); - this.updateSelection(); -}; - -ace.Selection.prototype.selectTo = function(row, column) { - this._moveSelection(function() { - this.moveCursorTo(row, column); - }); -}; - -ace.Selection.prototype.selectToPosition = function(pos) { - this._moveSelection(function() { - this.moveCursorToPosition(pos); - }); -}; - -ace.Selection.prototype.selectUp = function() { - this._moveSelection(this.moveCursorUp); -}; - -ace.Selection.prototype.selectDown = function() { - this._moveSelection(this.moveCursorDown); -}; - -ace.Selection.prototype.selectRight = function() { - this._moveSelection(this.moveCursorRight); -}; - -ace.Selection.prototype.selectLeft = function() { - this._moveSelection(this.moveCursorLeft); -}; - -ace.Selection.prototype.selectLineStart = function() { - this._moveSelection(this.moveCursorLineStart); -}; - -ace.Selection.prototype.selectLineEnd = function() { - this._moveSelection(this.moveCursorLineEnd); -}; - -ace.Selection.prototype.selectPageDown = function() { - var row = this.getPageDownRow() + Math.floor(this.getVisibleRowCount() / 2); - - this.scrollPageDown(); - - this._moveSelection(function() { - this.moveCursorTo(row, this.selectionLead.column); - }); -}; - -ace.Selection.prototype.selectPageUp = function() { - var visibleRows = this.getLastVisibleRow() - this.getFirstVisibleRow(); - var row = this.getPageUpRow() + Math.round(visibleRows / 2); - - this.scrollPageUp(); - - this._moveSelection(function() { - this.moveCursorTo(row, this.selectionLead.column); - }); -}; - -ace.Selection.prototype.selectFileEnd = function() { - this._moveSelection(this.moveCursorFileEnd); -}; - -ace.Selection.prototype.selectFileStart = function() { - this._moveSelection(this.moveCursorFileStart); -}; - -ace.Selection.prototype.tokenRe = /^[\w\d]+/g; -ace.Selection.prototype.nonTokenRe = /^[^\w\d]+/g; - -ace.Selection.prototype.selectWordRight = function() { - this._moveSelection(this.moveCursorWordRight); -}; - -ace.Selection.prototype.selectWordLeft = function() { - this._moveSelection(this.moveCursorWordLeft); -}; - -ace.Selection.prototype.selectWord = function() { - var cursor = this.selectionLead; - - var line = this.doc.getLine(cursor.row); - var column = cursor.column; - - var inToken = false; - if (column > 0) { - inToken = !!line.charAt(column - 1).match(this.tokenRe); - } - - if (!inToken) { - inToken = !!line.charAt(column).match(this.tokenRe); - } - - var re = inToken ? this.tokenRe : this.nonTokenRe; - - var start = column; - if (start > 0) { - do { - start--; + if (anchor.row > lead.row + || (anchor.row == lead.row && anchor.column > lead.column)) { + return { + start : lead, + end : anchor + }; } - while (start >= 0 && line.charAt(start).match(re)); - start++; - } - - var end = column; - while (end < line.length && line.charAt(end).match(re)) { - end++; - } - - this.setSelectionAnchor(cursor.row, start); - this._moveSelection(function() { - this.moveCursorTo(cursor.row, end); - }); -}; - -ace.Selection.prototype.selectLine = function() { - this.setSelectionAnchor(this.selectionLead.row, 0); - this._moveSelection(function() { - this.moveCursorTo(this.selectionLead.row + 1, 0); - }); -}; - -ace.Selection.prototype.moveCursorUp = function() { - this.moveCursorBy(-1, 0); -}; - -ace.Selection.prototype.moveCursorDown = function() { - this.moveCursorBy(1, 0); -}; - -ace.Selection.prototype.moveCursorLeft = function() { - if (this.selectionLead.column == 0) { - if (this.selectionLead.row > 0) { - this.moveCursorTo(this.selectionLead.row - 1, this.doc - .getLine(this.selectionLead.row - 1).length); + else { + return { + start : anchor, + end : lead + }; } - } - else { - this.moveCursorBy(0, -1); - } -}; + }; -ace.Selection.prototype.moveCursorRight = function() { - if (this.selectionLead.column == this.doc.getLine(this.selectionLead.row).length) { - if (this.selectionLead.row < this.doc.getLength() - 1) { + this.clearSelection = function() { + this.selectionAnchor = null; + this.updateSelection(); + }; + + + this.selectAll = function() { + var lastRow = this.doc.getLength() - 1; + this.setSelectionAnchor(lastRow, this.doc.getLine(lastRow).length); + + this._moveSelection(function() { + this.moveCursorTo(0, 0); + }); + }; + + this._moveSelection = function(mover) { + if (!this.selectionAnchor) { + this.selectionAnchor = this._clone(this.selectionLead); + } + + mover.call(this); + this.updateSelection(); + }; + + this.selectTo = function(row, column) { + this._moveSelection(function() { + this.moveCursorTo(row, column); + }); + }; + + this.selectToPosition = function(pos) { + this._moveSelection(function() { + this.moveCursorToPosition(pos); + }); + }; + + this.selectUp = function() { + this._moveSelection(this.moveCursorUp); + }; + + this.selectDown = function() { + this._moveSelection(this.moveCursorDown); + }; + + this.selectRight = function() { + this._moveSelection(this.moveCursorRight); + }; + + this.selectLeft = function() { + this._moveSelection(this.moveCursorLeft); + }; + + this.selectLineStart = function() { + this._moveSelection(this.moveCursorLineStart); + }; + + this.selectLineEnd = function() { + this._moveSelection(this.moveCursorLineEnd); + }; + + this.selectPageDown = function() { + var row = this.getPageDownRow() + Math.floor(this.getVisibleRowCount() / 2); + + this.scrollPageDown(); + + this._moveSelection(function() { + this.moveCursorTo(row, this.selectionLead.column); + }); + }; + + this.selectPageUp = function() { + var visibleRows = this.getLastVisibleRow() - this.getFirstVisibleRow(); + var row = this.getPageUpRow() + Math.round(visibleRows / 2); + + this.scrollPageUp(); + + this._moveSelection(function() { + this.moveCursorTo(row, this.selectionLead.column); + }); + }; + + this.selectFileEnd = function() { + this._moveSelection(this.moveCursorFileEnd); + }; + + this.selectFileStart = function() { + this._moveSelection(this.moveCursorFileStart); + }; + + this.tokenRe = /^[\w\d]+/g; + this.nonTokenRe = /^[^\w\d]+/g; + + this.selectWordRight = function() { + this._moveSelection(this.moveCursorWordRight); + }; + + this.selectWordLeft = function() { + this._moveSelection(this.moveCursorWordLeft); + }; + + this.selectWord = function() { + var cursor = this.selectionLead; + + var line = this.doc.getLine(cursor.row); + var column = cursor.column; + + var inToken = false; + if (column > 0) { + inToken = !!line.charAt(column - 1).match(this.tokenRe); + } + + if (!inToken) { + inToken = !!line.charAt(column).match(this.tokenRe); + } + + var re = inToken ? this.tokenRe : this.nonTokenRe; + + var start = column; + if (start > 0) { + do { + start--; + } + while (start >= 0 && line.charAt(start).match(re)); + start++; + } + + var end = column; + while (end < line.length && line.charAt(end).match(re)) { + end++; + } + + this.setSelectionAnchor(cursor.row, start); + this._moveSelection(function() { + this.moveCursorTo(cursor.row, end); + }); + }; + + this.selectLine = function() { + this.setSelectionAnchor(this.selectionLead.row, 0); + this._moveSelection(function() { this.moveCursorTo(this.selectionLead.row + 1, 0); - } - } - else { - this.moveCursorBy(0, 1); - } -}; - -ace.Selection.prototype.moveCursorLineStart = function() { - this.moveCursorTo(this.selectionLead.row, 0); -}; - -ace.Selection.prototype.moveCursorLineEnd = function() { - this.moveCursorTo(this.selectionLead.row, - this.doc.getLine(this.selectionLead.row).length); -}; - -ace.Selection.prototype.moveCursorFileEnd = function() { - var row = this.doc.getLength() - 1; - var column = this.doc.getLine(row).length; - this.moveCursorTo(row, column); -}; - -ace.Selection.prototype.moveCursorFileStart = function() { - this.moveCursorTo(0, 0); -}; - -ace.Selection.prototype.moveCursorWordRight = function() { - var row = this.selectionLead.row; - var column = this.selectionLead.column; - var line = this.doc.getLine(row); - var rightOfCursor = line.substring(column); - - var match; - this.nonTokenRe.lastIndex = 0; - this.tokenRe.lastIndex = 0; - - if (column == line.length) { - this.moveCursorRight(); - return; - } - else if (match = this.nonTokenRe.exec(rightOfCursor)) { - column += this.nonTokenRe.lastIndex; - this.nonTokenRe.lastIndex = 0; - } - else if (match = this.tokenRe.exec(rightOfCursor)) { - column += this.tokenRe.lastIndex; - this.tokenRe.lastIndex = 0; - } - - this.moveCursorTo(row, column); -}; - -ace.Selection.prototype.moveCursorWordLeft = function() { - var row = this.selectionLead.row; - var column = this.selectionLead.column; - var line = this.doc.getLine(row); - var leftOfCursor = ace.stringReverse(line.substring(0, column)); - - var match; - this.nonTokenRe.lastIndex = 0; - this.tokenRe.lastIndex = 0; - - if (column == 0) { - this.moveCursorLeft(); - return; - } - else if (match = this.nonTokenRe.exec(leftOfCursor)) { - column -= this.nonTokenRe.lastIndex; - this.nonTokenRe.lastIndex = 0; - } - else if (match = this.tokenRe.exec(leftOfCursor)) { - column -= this.tokenRe.lastIndex; - this.tokenRe.lastIndex = 0; - } - - this.moveCursorTo(row, column); -}; - -ace.Selection.prototype.moveCursorBy = function(rows, chars) { - this.moveCursorTo(this.selectionLead.row + rows, this.selectionLead.column + chars); -}; - - -ace.Selection.prototype.moveCursorToPosition = function(position) { - this.moveCursorTo(position.row, position.column); -}; - -ace.Selection.prototype.moveCursorTo = function(row, column) { - this.selectionLead = this._clipPositionToDocument(row, column); - this.updateCursor(); -}; - -ace.Selection.prototype.moveCursorUp = function() { - this.moveCursorBy(-1, 0); -}; - -ace.Selection.prototype._clipPositionToDocument = function(row, column) { - var pos = {}; - - if (row >= this.doc.getLength()) { - pos.row = this.doc.getLength() - 1; - pos.column = this.doc.getLine(pos.row).length; - } - else if (row < 0) { - pos.row = 0; - pos.column = 0; - } - else { - pos.row = row; - pos.column = Math.min(this.doc.getLine(pos.row).length, - Math.max(0, column)); - } - return pos; -}; - -ace.Selection.prototype._clone = function(pos) { - return { - row: pos.row, - column: pos.column + }); }; -}; \ No newline at end of file + + this.moveCursorUp = function() { + this.moveCursorBy(-1, 0); + }; + + this.moveCursorDown = function() { + this.moveCursorBy(1, 0); + }; + + this.moveCursorLeft = function() { + if (this.selectionLead.column == 0) { + if (this.selectionLead.row > 0) { + this.moveCursorTo(this.selectionLead.row - 1, this.doc + .getLine(this.selectionLead.row - 1).length); + } + } + else { + this.moveCursorBy(0, -1); + } + }; + + this.moveCursorRight = function() { + if (this.selectionLead.column == this.doc.getLine(this.selectionLead.row).length) { + if (this.selectionLead.row < this.doc.getLength() - 1) { + this.moveCursorTo(this.selectionLead.row + 1, 0); + } + } + else { + this.moveCursorBy(0, 1); + } + }; + + this.moveCursorLineStart = function() { + this.moveCursorTo(this.selectionLead.row, 0); + }; + + this.moveCursorLineEnd = function() { + this.moveCursorTo(this.selectionLead.row, + this.doc.getLine(this.selectionLead.row).length); + }; + + this.moveCursorFileEnd = function() { + var row = this.doc.getLength() - 1; + var column = this.doc.getLine(row).length; + this.moveCursorTo(row, column); + }; + + this.moveCursorFileStart = function() { + this.moveCursorTo(0, 0); + }; + + this.moveCursorWordRight = function() { + var row = this.selectionLead.row; + var column = this.selectionLead.column; + var line = this.doc.getLine(row); + var rightOfCursor = line.substring(column); + + var match; + this.nonTokenRe.lastIndex = 0; + this.tokenRe.lastIndex = 0; + + if (column == line.length) { + this.moveCursorRight(); + return; + } + else if (match = this.nonTokenRe.exec(rightOfCursor)) { + column += this.nonTokenRe.lastIndex; + this.nonTokenRe.lastIndex = 0; + } + else if (match = this.tokenRe.exec(rightOfCursor)) { + column += this.tokenRe.lastIndex; + this.tokenRe.lastIndex = 0; + } + + this.moveCursorTo(row, column); + }; + + this.moveCursorWordLeft = function() { + var row = this.selectionLead.row; + var column = this.selectionLead.column; + var line = this.doc.getLine(row); + var leftOfCursor = ace.stringReverse(line.substring(0, column)); + + var match; + this.nonTokenRe.lastIndex = 0; + this.tokenRe.lastIndex = 0; + + if (column == 0) { + this.moveCursorLeft(); + return; + } + else if (match = this.nonTokenRe.exec(leftOfCursor)) { + column -= this.nonTokenRe.lastIndex; + this.nonTokenRe.lastIndex = 0; + } + else if (match = this.tokenRe.exec(leftOfCursor)) { + column -= this.tokenRe.lastIndex; + this.tokenRe.lastIndex = 0; + } + + this.moveCursorTo(row, column); + }; + + this.moveCursorBy = function(rows, chars) { + this.moveCursorTo(this.selectionLead.row + rows, this.selectionLead.column + chars); + }; + + + this.moveCursorToPosition = function(position) { + this.moveCursorTo(position.row, position.column); + }; + + this.moveCursorTo = function(row, column) { + this.selectionLead = this._clipPositionToDocument(row, column); + this.updateCursor(); + }; + + this.moveCursorUp = function() { + this.moveCursorBy(-1, 0); + }; + + this._clipPositionToDocument = function(row, column) { + var pos = {}; + + if (row >= this.doc.getLength()) { + pos.row = this.doc.getLength() - 1; + pos.column = this.doc.getLine(pos.row).length; + } + else if (row < 0) { + pos.row = 0; + pos.column = 0; + } + else { + pos.row = row; + pos.column = Math.min(this.doc.getLine(pos.row).length, + Math.max(0, column)); + } + return pos; + }; + + this._clone = function(pos) { + return { + row: pos.row, + column: pos.column + }; + }; + +}).call(ace.Selection.prototype); \ No newline at end of file diff --git a/src/Tokenizer.js b/src/Tokenizer.js index 194ce446..02c93382 100644 --- a/src/Tokenizer.js +++ b/src/Tokenizer.js @@ -17,72 +17,76 @@ ace.Tokenizer = function(rules) { } }; -ace.Tokenizer.prototype.getLineTokens = function(line, startState) { - var currentState = startState; - var state = this.rules[currentState]; - var re = this.regExps[currentState]; - re.lastIndex = 0; +(function() { - var match, tokens = []; + this.getLineTokens = function(line, startState) { + var currentState = startState; + var state = this.rules[currentState]; + var re = this.regExps[currentState]; + re.lastIndex = 0; - var lastIndex = 0; + var match, tokens = []; - var token = { - type: null, - value: "" - }; + var lastIndex = 0; - while (match = re.exec(line)) { - var type = "text"; - var value = match[0]; + var token = { + type: null, + value: "" + }; - if (re.lastIndex == lastIndex) { throw new Error("tokenizer error"); } - lastIndex = re.lastIndex; + while (match = re.exec(line)) { + var type = "text"; + var value = match[0]; - window.LOG && jstestdriver.console.log(currentState, match); + if (re.lastIndex == lastIndex) { throw new Error("tokenizer error"); } + lastIndex = re.lastIndex; - for ( var i = 0; i < state.length; i++) { - if (match[i + 1]) { - if (typeof state[i].token == "function") { - type = state[i].token(match[0]); - } - else { - type = state[i].token; + window.LOG && jstestdriver.console.log(currentState, match); + + for ( var i = 0; i < state.length; i++) { + if (match[i + 1]) { + if (typeof state[i].token == "function") { + type = state[i].token(match[0]); + } + else { + type = state[i].token; + } + + if (state[i].next && state[i].next !== currentState) { + currentState = state[i].next; + var state = this.rules[currentState]; + var lastIndex = re.lastIndex; + + var re = this.regExps[currentState]; + re.lastIndex = lastIndex; + } + break; } + }; - if (state[i].next && state[i].next !== currentState) { - currentState = state[i].next; - var state = this.rules[currentState]; - var lastIndex = re.lastIndex; - - var re = this.regExps[currentState]; - re.lastIndex = lastIndex; + if (token.type !== type) { + if (token.type) { + tokens.push(token); } - break; + token = { + type: type, + value: value + }; + } else { + token.value += value; } }; - if (token.type !== type) { - if (token.type) { - tokens.push(token); - } - token = { - type: type, - value: value - }; - } else { - token.value += value; + if (token.type) { + tokens.push(token); } + + window.LOG && jstestdriver.console.log(tokens, currentState); + + return { + tokens : tokens, + state : currentState + }; }; - if (token.type) { - tokens.push(token); - } - - window.LOG && jstestdriver.console.log(tokens, currentState); - - return { - tokens : tokens, - state : currentState - }; -}; \ No newline at end of file +}).call(ace.Tokenizer.prototype); \ No newline at end of file diff --git a/src/VirtualRenderer.js b/src/VirtualRenderer.js index 8d720cc7..042c4371 100644 --- a/src/VirtualRenderer.js +++ b/src/VirtualRenderer.js @@ -38,213 +38,217 @@ ace.VirtualRenderer = function(container) { this.onResize(); }; -ace.VirtualRenderer.prototype.setDocument = function(doc) { - this.lines = doc.lines; - this.doc = doc; - this.markerLayer.setDocument(doc); - this.textLayer.setTabSize(doc.getTabSize()); -}; +(function() { -ace.VirtualRenderer.prototype.setTokenizer = function(tokenizer) { - this.textLayer.setTokenizer(tokenizer); -}; + this.setDocument = function(doc) { + this.lines = doc.lines; + this.doc = doc; + this.markerLayer.setDocument(doc); + this.textLayer.setTabSize(doc.getTabSize()); + }; -ace.VirtualRenderer.prototype.getContainerElement = function() { - return this.container; -}; + this.setTokenizer = function(tokenizer) { + this.textLayer.setTokenizer(tokenizer); + }; -ace.VirtualRenderer.prototype.getMouseEventTarget = function() { - return this.scroller; -}; + this.getContainerElement = function() { + return this.container; + }; -ace.VirtualRenderer.prototype.getFirstVisibleRow = function() { - return this.layerConfig.firstRow || 0; -}; + this.getMouseEventTarget = function() { + return this.scroller; + }; -ace.VirtualRenderer.prototype.getLastVisibleRow = function() { - return this.layerConfig.lastRow || 0; -}; + this.getFirstVisibleRow = function() { + return this.layerConfig.firstRow || 0; + }; -ace.VirtualRenderer.prototype.onResize = function() -{ - var height = ace.getInnerHeight(this.container); - this.gutter.style.height = height + "px"; - this.scroller.style.height = height + "px"; - this.scrollBar.setHeight(height); + this.getLastVisibleRow = function() { + return this.layerConfig.lastRow || 0; + }; - var width = ace.getInnerWidth(this.container); - var gutterWidth = this.gutter.offsetWidth; - this.scroller.style.left = gutterWidth + "px"; - this.scroller.style.width = Math.max(0, width - gutterWidth - this.scrollBar.getWidth()) + "px"; + this.onResize = function() + { + var height = ace.getInnerHeight(this.container); + this.gutter.style.height = height + "px"; + this.scroller.style.height = height + "px"; + this.scrollBar.setHeight(height); + + var width = ace.getInnerWidth(this.container); + var gutterWidth = this.gutter.offsetWidth; + this.scroller.style.left = gutterWidth + "px"; + this.scroller.style.width = Math.max(0, width - gutterWidth - this.scrollBar.getWidth()) + "px"; + + if (this.doc) { + this._updateScrollBar(); + this.scrollToY(this.getScrollTop()); + this.draw(); + } + }; + + this.onScroll = function(e) { + this.scrollToY(e.data); + }; + + this._updateScrollBar = function() { + this.scrollBar.setInnerHeight(this.doc.getLength() * this.lineHeight); + this.scrollBar.setScrollTop(this.scrollTop); + }; + + this.updateLines = function(firstRow, lastRow) { + var layerConfig = this.layerConfig; + + if (firstRow > layerConfig.lastRow + 1) { return; } + if (lastRow < layerConfig.firstRow) { return; } + + // if the last row is unknown -> redraw everything + if (lastRow === undefined) { + this.draw(); + return; + } + + // else update only the changed rows + this.textLayer.updateLines(layerConfig, firstRow, lastRow); + }; + + this.draw = function() { + var lines = this.lines; + + var offset = this.scrollTop % this.lineHeight; + var minHeight = this.scroller.clientHeight + offset; + + var longestLine = Math.max(this.scroller.clientWidth, Math.round(this.doc.getWidth() * this.characterWidth)); + + var lineCount = Math.ceil(minHeight / this.lineHeight); + var firstRow = Math.round((this.scrollTop - offset) / this.lineHeight); + var lastRow = Math.min(lines.length, firstRow + lineCount) - 1; + + var layerConfig = this.layerConfig = { + width : longestLine, + firstRow : firstRow, + lastRow : lastRow, + lineHeight : this.lineHeight, + characterWidth : this.characterWidth + }; + + for ( var i = 0; i < this.layers.length; i++) { + var layer = this.layers[i]; + + var style = layer.element.style; + style.marginTop = (-offset) + "px"; + style.height = minHeight + "px"; + style.width = longestLine + "px"; + + layer.update(layerConfig); + }; + + this.gutterLayer.element.style.marginTop = (-offset) + "px"; + this.gutterLayer.element.style.height = minHeight + "px"; + this.gutterLayer.update(layerConfig); - if (this.doc) { this._updateScrollBar(); - this.scrollToY(this.getScrollTop()); - this.draw(); - } -}; - -ace.VirtualRenderer.prototype.onScroll = function(e) { - this.scrollToY(e.data); -}; - -ace.VirtualRenderer.prototype._updateScrollBar = function() { - this.scrollBar.setInnerHeight(this.doc.getLength() * this.lineHeight); - this.scrollBar.setScrollTop(this.scrollTop); -}; - -ace.VirtualRenderer.prototype.updateLines = function(firstRow, lastRow) { - var layerConfig = this.layerConfig; - - if (firstRow > layerConfig.lastRow + 1) { return; } - if (lastRow < layerConfig.firstRow) { return; } - - // if the last row is unknown -> redraw everything - if (lastRow === undefined) { - this.draw(); - return; - } - - // else update only the changed rows - this.textLayer.updateLines(layerConfig, firstRow, lastRow); -}; - -ace.VirtualRenderer.prototype.draw = function() { - var lines = this.lines; - - var offset = this.scrollTop % this.lineHeight; - var minHeight = this.scroller.clientHeight + offset; - - var longestLine = Math.max(this.scroller.clientWidth, Math.round(this.doc.getWidth() * this.characterWidth)); - - var lineCount = Math.ceil(minHeight / this.lineHeight); - var firstRow = Math.round((this.scrollTop - offset) / this.lineHeight); - var lastRow = Math.min(lines.length, firstRow + lineCount) - 1; - - var layerConfig = this.layerConfig = { - width : longestLine, - firstRow : firstRow, - lastRow : lastRow, - lineHeight : this.lineHeight, - characterWidth : this.characterWidth }; - for ( var i = 0; i < this.layers.length; i++) { - var layer = this.layers[i]; - - var style = layer.element.style; - style.marginTop = (-offset) + "px"; - style.height = minHeight + "px"; - style.width = longestLine + "px"; - - layer.update(layerConfig); + this.addMarker = function(range, clazz, type) { + return this.markerLayer.addMarker(range, clazz, type); }; - this.gutterLayer.element.style.marginTop = (-offset) + "px"; - this.gutterLayer.element.style.height = minHeight + "px"; - this.gutterLayer.update(layerConfig); - - this._updateScrollBar(); -}; - -ace.VirtualRenderer.prototype.addMarker = function(range, clazz, type) { - return this.markerLayer.addMarker(range, clazz, type); -}; - -ace.VirtualRenderer.prototype.removeMarker = function(markerId) { - this.markerLayer.removeMarker(markerId); -}; - -ace.VirtualRenderer.prototype.updateCursor = function(position) { - this.cursorLayer.setCursor(position); - this.cursorLayer.update(this.layerConfig); -}; - -ace.VirtualRenderer.prototype.hideCursor = function() { - this.cursorLayer.hideCursor(); -}; - -ace.VirtualRenderer.prototype.showCursor = function() { - this.cursorLayer.showCursor(); -}; - -ace.VirtualRenderer.prototype.scrollCursorIntoView = function() { - var pos = this.cursorLayer.getPixelPosition(); - - var left = pos.left; - var top = pos.top; - - if (this.getScrollTop() > top) { - this.scrollToY(top); - } - - if (this.getScrollTop() + this.scroller.clientHeight < top - + this.lineHeight) { - this.scrollToY(top + this.lineHeight - this.scroller.clientHeight); - } - - if (this.scroller.scrollLeft > left) { - this.scroller.scrollLeft = left; - } - - if (this.scroller.scrollLeft + this.scroller.clientWidth < left - + this.characterWidth) { - this.scroller.scrollLeft = Math.round(left + this.characterWidth - - this.scroller.clientWidth); - } -}, - -ace.VirtualRenderer.prototype.getScrollTop = function() { - return this.scrollTop; -}; - -ace.VirtualRenderer.prototype.getScrollTopRow = function() { - return this.scrollTop / this.lineHeight; -}; - -ace.VirtualRenderer.prototype.scrollToRow = function(row) { - this.scrollToY(row * this.lineHeight); -}; - -ace.VirtualRenderer.prototype.scrollToY = function(scrollTop) { - var maxHeight = this.lines.length * this.lineHeight - - this.scroller.clientHeight; - var scrollTop = Math.max(0, Math.min(maxHeight, scrollTop)); - - if (this.scrollTop !== scrollTop) { - this.scrollTop = scrollTop; - this._updateScrollBar(); - this.draw(); - } -}; - -ace.VirtualRenderer.prototype.screenToTextCoordinates = function(pageX, pageY) { - var canvasPos = this.scroller.getBoundingClientRect(); - - var col = Math.floor((pageX + this.scroller.scrollLeft - canvasPos.left) - / this.characterWidth); - var row = Math.floor((pageY + this.scrollTop - canvasPos.top) - / this.lineHeight); - - return { - row : row, - column : col + this.removeMarker = function(markerId) { + this.markerLayer.removeMarker(markerId); }; -}; -ace.VirtualRenderer.prototype.visualizeFocus = function() { - ace.addCssClass(this.container, "focus"); -}; + this.updateCursor = function(position) { + this.cursorLayer.setCursor(position); + this.cursorLayer.update(this.layerConfig); + }; -ace.VirtualRenderer.prototype.visualizeBlur = function() { - ace.removeCssClass(this.container, "focus"); -}; + this.hideCursor = function() { + this.cursorLayer.hideCursor(); + }; -ace.VirtualRenderer.prototype.showComposition = function(position) { -}; + this.showCursor = function() { + this.cursorLayer.showCursor(); + }; -ace.VirtualRenderer.prototype.setCompositionText = function(text) { -}; + this.scrollCursorIntoView = function() { + var pos = this.cursorLayer.getPixelPosition(); -ace.VirtualRenderer.prototype.hideComposition = function() { -}; \ No newline at end of file + var left = pos.left; + var top = pos.top; + + if (this.getScrollTop() > top) { + this.scrollToY(top); + } + + if (this.getScrollTop() + this.scroller.clientHeight < top + + this.lineHeight) { + this.scrollToY(top + this.lineHeight - this.scroller.clientHeight); + } + + if (this.scroller.scrollLeft > left) { + this.scroller.scrollLeft = left; + } + + if (this.scroller.scrollLeft + this.scroller.clientWidth < left + + this.characterWidth) { + this.scroller.scrollLeft = Math.round(left + this.characterWidth + - this.scroller.clientWidth); + } + }, + + this.getScrollTop = function() { + return this.scrollTop; + }; + + this.getScrollTopRow = function() { + return this.scrollTop / this.lineHeight; + }; + + this.scrollToRow = function(row) { + this.scrollToY(row * this.lineHeight); + }; + + this.scrollToY = function(scrollTop) { + var maxHeight = this.lines.length * this.lineHeight + - this.scroller.clientHeight; + var scrollTop = Math.max(0, Math.min(maxHeight, scrollTop)); + + if (this.scrollTop !== scrollTop) { + this.scrollTop = scrollTop; + this._updateScrollBar(); + this.draw(); + } + }; + + this.screenToTextCoordinates = function(pageX, pageY) { + var canvasPos = this.scroller.getBoundingClientRect(); + + var col = Math.floor((pageX + this.scroller.scrollLeft - canvasPos.left) + / this.characterWidth); + var row = Math.floor((pageY + this.scrollTop - canvasPos.top) + / this.lineHeight); + + return { + row : row, + column : col + }; + }; + + this.visualizeFocus = function() { + ace.addCssClass(this.container, "focus"); + }; + + this.visualizeBlur = function() { + ace.removeCssClass(this.container, "focus"); + }; + + this.showComposition = function(position) { + }; + + this.setCompositionText = function(text) { + }; + + this.hideComposition = function() { + }; + +}).call(ace.VirtualRenderer.prototype); \ No newline at end of file diff --git a/src/layer/Cursor.js b/src/layer/Cursor.js index acb5e56c..e43edc38 100644 --- a/src/layer/Cursor.js +++ b/src/layer/Cursor.js @@ -11,71 +11,75 @@ ace.layer.Cursor = function(parentEl) { this.isVisible = false; }; -ace.layer.Cursor.prototype.setCursor = function(position) { - this.position = { - row : position.row, - column : position.column - }; -}; +(function() { -ace.layer.Cursor.prototype.hideCursor = function() { - this.isVisible = false; - if (this.cursor.parentNode) { - this.cursor.parentNode.removeChild(this.cursor); - } - clearInterval(this.blinkId); -}; - -ace.layer.Cursor.prototype.showCursor = function() { - this.isVisible = true; - this.element.appendChild(this.cursor); - - var cursor = this.cursor; - cursor.style.visibility = "visible"; - this.restartTimer(); -}; - -ace.layer.Cursor.prototype.restartTimer = function() { - clearInterval(this.blinkId); - if (!this.isVisible) { - return; - } - - var cursor = this.cursor; - this.blinkId = setInterval(function() { - cursor.style.visibility = "hidden"; - setTimeout(function() { - cursor.style.visibility = "visible"; - }, 400); - }, 1000); -}; - -ace.layer.Cursor.prototype.getPixelPosition = function() { - return this.pixelPos || { - left : 0, - top : 0 - }; -}; - -ace.layer.Cursor.prototype.update = function(config) { - if (!this.position) - return; - - var cursorLeft = Math.round(this.position.column * config.characterWidth); - var cursorTop = this.position.row * config.lineHeight; - - this.pixelPos = { - left : cursorLeft, - top : cursorTop + this.setCursor = function(position) { + this.position = { + row : position.row, + column : position.column + }; }; - this.cursor.style.left = cursorLeft + "px"; - this.cursor.style.top = (cursorTop - (config.firstRow * config.lineHeight)) - + "px"; - this.cursor.style.height = config.lineHeight + "px"; + this.hideCursor = function() { + this.isVisible = false; + if (this.cursor.parentNode) { + this.cursor.parentNode.removeChild(this.cursor); + } + clearInterval(this.blinkId); + }; - if (this.isVisible) { + this.showCursor = function() { + this.isVisible = true; this.element.appendChild(this.cursor); - } - this.restartTimer(); -}; \ No newline at end of file + + var cursor = this.cursor; + cursor.style.visibility = "visible"; + this.restartTimer(); + }; + + this.restartTimer = function() { + clearInterval(this.blinkId); + if (!this.isVisible) { + return; + } + + var cursor = this.cursor; + this.blinkId = setInterval(function() { + cursor.style.visibility = "hidden"; + setTimeout(function() { + cursor.style.visibility = "visible"; + }, 400); + }, 1000); + }; + + this.getPixelPosition = function() { + return this.pixelPos || { + left : 0, + top : 0 + }; + }; + + this.update = function(config) { + if (!this.position) + return; + + var cursorLeft = Math.round(this.position.column * config.characterWidth); + var cursorTop = this.position.row * config.lineHeight; + + this.pixelPos = { + left : cursorLeft, + top : cursorTop + }; + + this.cursor.style.left = cursorLeft + "px"; + this.cursor.style.top = (cursorTop - (config.firstRow * config.lineHeight)) + + "px"; + this.cursor.style.height = config.lineHeight + "px"; + + if (this.isVisible) { + this.element.appendChild(this.cursor); + } + this.restartTimer(); + }; + +}).call(ace.layer.Cursor.prototype); \ No newline at end of file diff --git a/src/layer/Gutter.js b/src/layer/Gutter.js index 00872802..0d6033bc 100644 --- a/src/layer/Gutter.js +++ b/src/layer/Gutter.js @@ -6,13 +6,17 @@ ace.layer.Gutter = function(parentEl) { parentEl.appendChild(this.element); }; -ace.layer.Gutter.prototype.update = function(config) { - var html = []; - for ( var i = config.firstRow; i <= config.lastRow; i++) { - html.push("
", (i+1), "
"); - html.push(""); - } +(function() { - this.element.innerHTML = html.join(""); -}; \ No newline at end of file + this.update = function(config) { + var html = []; + for ( var i = config.firstRow; i <= config.lastRow; i++) { + html.push("
", (i+1), "
"); + html.push(""); + } + + this.element.innerHTML = html.join(""); + }; + +}).call(ace.layer.Gutter.prototype); \ No newline at end of file diff --git a/src/layer/Marker.js b/src/layer/Marker.js index af604603..638e8a28 100644 --- a/src/layer/Marker.js +++ b/src/layer/Marker.js @@ -9,153 +9,157 @@ ace.layer.Marker = function(parentEl) { this._markerId = 1; }; -ace.layer.Marker.prototype.setDocument = function(doc) { - this.doc = doc; -}; +(function() { -ace.layer.Marker.prototype.addMarker = function(range, clazz, type) { - var id = this._markerId++; - this.markers[id] = { - range : range, - type : type || "line", - clazz : clazz + this.setDocument = function(doc) { + this.doc = doc; }; - this.update(); - return id; -}; - -ace.layer.Marker.prototype.removeMarker = function(markerId) { - var marker = this.markers[markerId]; - if (marker) { - delete (this.markers[markerId]); - this.update(); - } -}; - -ace.layer.Marker.prototype.update = function(config) { - var config = config || this.config; - if (!config) - return; - - this.config = config; - - var html = []; - for ( var key in this.markers) { - var marker = this.markers[key]; - var range = { - start: marker.range.start, - end: marker.range.end + this.addMarker = function(range, clazz, type) { + var id = this._markerId++; + this.markers[id] = { + range : range, + type : type || "line", + clazz : clazz }; - // clip - if (range.start.row > config.lastRow) continue; - if (range.end.row < config.firstRow) continue; + this.update(); + return id; + }; - if (range.end.row > config.lastRow) { - range.end = { - row: config.lastRow+1, - column: 0 - }; + this.removeMarker = function(markerId) { + var marker = this.markers[markerId]; + if (marker) { + delete (this.markers[markerId]); + this.update(); } + }; - if (range.start.row < config.firstRow) { - range.start = { - row: config.firstRow, - column: 0 + this.update = function(config) { + var config = config || this.config; + if (!config) + return; + + this.config = config; + + var html = []; + for ( var key in this.markers) { + var marker = this.markers[key]; + var range = { + start: marker.range.start, + end: marker.range.end }; - } - if (range.start.row !== range.end.row) { - if (marker.type == "text") { - this.drawTextMarker(html, range, marker.clazz, config); - } else { - this.drawMultiLineMarker(html, range, marker.clazz, config); + // clip + if (range.start.row > config.lastRow) continue; + if (range.end.row < config.firstRow) continue; + + if (range.end.row > config.lastRow) { + range.end = { + row: config.lastRow+1, + column: 0 + }; + } + + if (range.start.row < config.firstRow) { + range.start = { + row: config.firstRow, + column: 0 + }; + } + + if (range.start.row !== range.end.row) { + if (marker.type == "text") { + this.drawTextMarker(html, range, marker.clazz, config); + } else { + this.drawMultiLineMarker(html, range, marker.clazz, config); + } + } + else { + this.drawSingleLineMarker(html, range, marker.clazz, config); } } - else { - this.drawSingleLineMarker(html, range, marker.clazz, config); - } - } - this.element.innerHTML = html.join(""); -}; + this.element.innerHTML = html.join(""); + }; -ace.layer.Marker.prototype.drawTextMarker = function(stringBuilder, range, clazz, layerConfig) { + this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig) { - // selection start - var row = range.start.row; - var lineRange = { start: {}, end: {}}; + // selection start + var row = range.start.row; + var lineRange = { start: {}, end: {}}; - lineRange.start.row = row; - lineRange.start.column = range.start.column; - lineRange.end.row = row; - lineRange.end.column = this.doc.getLine(row).length; - this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig); - - // selection end - var row = range.end.row; - lineRange.start.row = row; - lineRange.start.column = 0; - lineRange.end.row = row; - lineRange.end.column = range.end.column; - this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig); - - for (var row = range.start.row + 1; row < range.end.row; row++) { lineRange.start.row = row; + lineRange.start.column = range.start.column; lineRange.end.row = row; lineRange.end.column = this.doc.getLine(row).length; this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig); - } -}; -ace.layer.Marker.prototype.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig) { + // selection end + var row = range.end.row; + lineRange.start.row = row; + lineRange.start.column = 0; + lineRange.end.row = row; + lineRange.end.column = range.end.column; + this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig); - var height = layerConfig.lineHeight; - var width = Math.round(layerConfig.width - (range.start.column * layerConfig.characterWidth)); - var top = (range.start.row - layerConfig.firstRow) * layerConfig.lineHeight; - var left = Math.round(range.start.column * layerConfig.characterWidth); + for (var row = range.start.row + 1; row < range.end.row; row++) { + lineRange.start.row = row; + lineRange.end.row = row; + lineRange.end.column = this.doc.getLine(row).length; + this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig); + } + }; - stringBuilder.push( - "
" - ); + this.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig) { - var top = (range.end.row - layerConfig.firstRow) * layerConfig.lineHeight; - var width = Math.round(range.end.column * layerConfig.characterWidth); + var height = layerConfig.lineHeight; + var width = Math.round(layerConfig.width - (range.start.column * layerConfig.characterWidth)); + var top = (range.start.row - layerConfig.firstRow) * layerConfig.lineHeight; + var left = Math.round(range.start.column * layerConfig.characterWidth); - stringBuilder.push( - "
" - ); - - for (var row = range.start.row + 1; row < range.end.row; row++) { - var top = (row - layerConfig.firstRow) * layerConfig.lineHeight; stringBuilder.push( "
" + "width:", width, "px;", + "top:", top, "px;", + "left:", left, "px;'>" ); - } -}; -ace.layer.Marker.prototype.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig) { + var top = (range.end.row - layerConfig.firstRow) * layerConfig.lineHeight; + var width = Math.round(range.end.column * layerConfig.characterWidth); - var height = layerConfig.lineHeight; - var width = Math.round((range.end.column - range.start.column) * layerConfig.characterWidth); - var top = (range.start.row - layerConfig.firstRow) * layerConfig.lineHeight; - var left = Math.round(range.start.column * layerConfig.characterWidth); + stringBuilder.push( + "
" + ); - stringBuilder.push( - "
" - ); -}; \ No newline at end of file + for (var row = range.start.row + 1; row < range.end.row; row++) { + var top = (row - layerConfig.firstRow) * layerConfig.lineHeight; + stringBuilder.push( + "
" + ); + } + }; + + this.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig) { + + var height = layerConfig.lineHeight; + var width = Math.round((range.end.column - range.start.column) * layerConfig.characterWidth); + var top = (range.start.row - layerConfig.firstRow) * layerConfig.lineHeight; + var left = Math.round(range.start.column * layerConfig.characterWidth); + + stringBuilder.push( + "
" + ); + }; + +}).call(ace.layer.Marker.prototype); \ No newline at end of file diff --git a/src/layer/Text.js b/src/layer/Text.js index bb322dcd..264baf4f 100644 --- a/src/layer/Text.js +++ b/src/layer/Text.js @@ -9,86 +9,93 @@ ace.layer.Text = function(parentEl) { this._tabString = " "; }; -ace.layer.Text.prototype.setTokenizer = function(tokenizer) { - this.tokenizer = tokenizer; -}; +(function() { -ace.layer.Text.prototype.getLineHeight = function() { - return this.lineHeight; -}; + this.setTokenizer = function(tokenizer) { + this.tokenizer = tokenizer; + }; -ace.layer.Text.prototype.getCharacterWidth = function() { - return this.characterWidth; -}; + this.getLineHeight = function() { + return this.lineHeight; + }; -ace.layer.Text.prototype._measureSizes = function() { - var measureNode = document.createElement("div"); - var style = measureNode.style; - style.width = style.height = "auto"; - style.left = style.top = "-1000px"; - style.visibility = "hidden"; - style.position = "absolute"; - style.overflow = "visible"; + this.getCharacterWidth = function() { + return this.characterWidth; + }; - measureNode.innerHTML = new Array(1000).join("Xy"); - this.element.appendChild(measureNode); + this._measureSizes = function() { + var measureNode = document.createElement("div"); + var style = measureNode.style; + style.width = style.height = "auto"; + style.left = style.top = "-1000px"; + style.visibility = "hidden"; + style.position = "absolute"; + style.overflow = "visible"; - // in FF 3.6 monospace fonts can have a fixed sub pixel width. - // that's why we have to measure many characters - // Note: characterWidth can be a float! - this.lineHeight = measureNode.offsetHeight; - this.characterWidth = measureNode.offsetWidth / 2000; + measureNode.innerHTML = new Array(1000).join("Xy"); + this.element.appendChild(measureNode); - this.element.removeChild(measureNode); -}; + // in FF 3.6 monospace fonts can have a fixed sub pixel width. + // that's why we have to measure many characters + // Note: characterWidth can be a float! + this.lineHeight = measureNode.offsetHeight; + this.characterWidth = measureNode.offsetWidth / 2000; -ace.layer.Text.prototype.setTabSize = function(tabSize) { - this._tabString = new Array(tabSize+1).join(" "); -}; + this.element.removeChild(measureNode); + }; -ace.layer.Text.prototype.updateLines = function(layerConfig, firstRow, lastRow) { - var first = Math.max(firstRow, layerConfig.firstRow); - var last = Math.min(lastRow, layerConfig.lastRow); + this.setTabSize = function(tabSize) { + this._tabString = new Array(tabSize+1).join(" "); + }; - var lineElements = this.element.childNodes; + this.updateLines = function(layerConfig, firstRow, lastRow) { + var first = Math.max(firstRow, layerConfig.firstRow); + var last = Math.min(lastRow, layerConfig.lastRow); - for ( var i = first; i <= last; i++) { + var lineElements = this.element.childNodes; + + for ( var i = first; i <= last; i++) { + var html = []; + this.renderLine(html, i); + + var lineElement = lineElements[i - layerConfig.firstRow]; + lineElement.innerHTML = html.join(""); + }; + }; + + this.update = function(config) { var html = []; - this.renderLine(html, i); - - var lineElement = lineElements[i - layerConfig.firstRow]; - lineElement.innerHTML = html.join(""); - }; -}; - -ace.layer.Text.prototype.update = function(config) { - var html = []; - for ( var i = config.firstRow; i <= config.lastRow; i++) { - html.push("
"); - this.renderLine(html, i), html.push("
"); - } - - this.element.innerHTML = html.join(""); -}; - -ace.layer.Text.prototype.renderLine = function(stringBuilder, row) { - var tokens = this.tokenizer.getTokens(row); - for ( var i = 0; i < tokens.length; i++) { - var token = tokens[i]; - - var output = token.value - .replace(/&/g, "&") - .replace(/", output, - ""); - } - else { - stringBuilder.push(output); + for ( var i = config.firstRow; i <= config.lastRow; i++) { + html.push("
"); + this.renderLine(html, i), html.push("
"); } + + this.element.innerHTML = html.join(""); }; -}; \ No newline at end of file + + this.renderLine = function(stringBuilder, row) { + var tokens = this.tokenizer.getTokens(row); + for ( var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + + var output = token.value + .replace(/&/g, "&") + .replace(/", output, + ""); + } + else { + stringBuilder.push(output); + } + }; + // TODO: show invisibles + //stringBuilder.push("¶"); + }; + +}).call(ace.layer.Text.prototype); \ No newline at end of file diff --git a/src/mode/Css.js b/src/mode/Css.js index b8c06461..d07720ee 100644 --- a/src/mode/Css.js +++ b/src/mode/Css.js @@ -5,19 +5,23 @@ ace.mode.Css = function() { }; ace.inherits(ace.mode.Css, ace.mode.Text); -ace.mode.Css.prototype.getNextLineIndent = function(line, state, tab) { - var indent = this.$getIndent(line); +(function() { + + this.getNextLineIndent = function(line, state, tab) { + var indent = this.$getIndent(line); + + // ignore braces in comments + var tokens = this.$tokenizer.getLineTokens(line, state).tokens; + if (tokens.length && tokens[tokens.length-1].type == "comment") { + return indent; + } + + var match = line.match(/^.*\{\s*$/); + if (match) { + indent += tab; + } - // ignore braces in comments - var tokens = this.$tokenizer.getLineTokens(line, state).tokens; - if (tokens.length && tokens[tokens.length-1].type == "comment") { return indent; - } + }; - var match = line.match(/^.*\{\s*$/); - if (match) { - indent += tab; - } - - return indent; -}; \ No newline at end of file +}).call(ace.mode.Css.prototype); \ No newline at end of file diff --git a/src/mode/CssHighlightRules.js b/src/mode/CssHighlightRules.js index 35376d1e..ad3def8d 100644 --- a/src/mode/CssHighlightRules.js +++ b/src/mode/CssHighlightRules.js @@ -175,6 +175,10 @@ ace.mode.CssHighlightRules = function() { }; }; -ace.mode.CssHighlightRules.prototype.getRules = function() { - return this._rules; -}; \ No newline at end of file +(function() { + + this.getRules = function() { + return this._rules; + }; + +}).call(ace.mode.CssHighlightRules.prototype); \ No newline at end of file diff --git a/src/mode/Html.js b/src/mode/Html.js index 631aa038..45392821 100644 --- a/src/mode/Html.js +++ b/src/mode/Html.js @@ -8,30 +8,34 @@ ace.mode.Html = function() { }; ace.inherits(ace.mode.Html, ace.mode.Text); -ace.mode.Html.prototype.toggleCommentLines = function(doc, range, state) { - var split = state.split("js-"); - if (!split[0] && split[1]) { - return this._js.toggleCommentLines(doc, range, state); - } +(function() { - var split = state.split("css-"); - if (!split[0] && split[1]) { - return this._css.toggleCommentLines(doc, range, state); - } + this.toggleCommentLines = function(doc, range, state) { + var split = state.split("js-"); + if (!split[0] && split[1]) { + return this._js.toggleCommentLines(doc, range, state); + } - return 0; -}; + var split = state.split("css-"); + if (!split[0] && split[1]) { + return this._css.toggleCommentLines(doc, range, state); + } -ace.mode.Html.prototype.getNextLineIndent = function(line, state, tab) { - var split = state.split("js-"); - if (!split[0] && split[1]) { - return this._js.getNextLineIndent(line, split[1], tab); - } + return 0; + }; - var split = state.split("css-"); - if (!split[0] && split[1]) { - return this._css.getNextLineIndent(line, split[1], tab); - } + this.getNextLineIndent = function(line, state, tab) { + var split = state.split("js-"); + if (!split[0] && split[1]) { + return this._js.getNextLineIndent(line, split[1], tab); + } - return ""; -}; \ No newline at end of file + var split = state.split("css-"); + if (!split[0] && split[1]) { + return this._css.getNextLineIndent(line, split[1], tab); + } + + return ""; + }; + +}).call(ace.mode.Html.prototype); \ No newline at end of file diff --git a/src/mode/HtmlHighlightRules.js b/src/mode/HtmlHighlightRules.js index 5a0902b3..74f9c529 100644 --- a/src/mode/HtmlHighlightRules.js +++ b/src/mode/HtmlHighlightRules.js @@ -130,20 +130,23 @@ ace.mode.HtmlHighlightRules = function() { }); }; +(function() { -ace.mode.HtmlHighlightRules.prototype._addRules = function(rules, prefix) { - for (var key in rules) { - var state = rules[key]; - for (var i=0; i