From 8fe20516d44c1d112e6290bb5ef1adfb9a6650a9 Mon Sep 17 00:00:00 2001 From: Fabian Jakobs Date: Mon, 12 Apr 2010 12:49:00 +0200 Subject: [PATCH] adapt better to ajax.org coding styles --- src/BackgroundTokenizer.js | 143 +++-- src/CursorLayer.js | 111 ++-- src/Editor.js | 1013 ++++++++++++++++++------------------ src/GutterLayer.js | 35 +- src/JavaScript.js | 219 ++++---- src/MarkerLayer.js | 186 +++---- src/TextDocument.js | 367 +++++++------ src/TextInput.js | 147 +++--- src/TextLayer.js | 151 +++--- src/Tokenizer.js | 141 +++-- src/VirtualRenderer.js | 289 +++++----- src/XML.js | 159 +++--- src/lib.js | 240 ++++----- 13 files changed, 1556 insertions(+), 1645 deletions(-) diff --git a/src/BackgroundTokenizer.js b/src/BackgroundTokenizer.js index 1d7820ad..d69b420f 100644 --- a/src/BackgroundTokenizer.js +++ b/src/BackgroundTokenizer.js @@ -1,87 +1,84 @@ -if (!window.ace) ace = {}; +if (!window.ace) + ace = {}; -ace.BackgroundTokenizer = function(tokenizer, onUpdate, onComplete) -{ - this.running = false; - this.textLines = []; - this.lines = []; - this.currentLine = 0; - this.tokenizer = tokenizer; - - this.onUpdate = onUpdate || function(firstLine, lastLine) {}; - this.onComplete = onComplete || function() {}; - - var self = this; - this._worker = function() - { - if (!self.running) { - return; +ace.BackgroundTokenizer = function(tokenizer, onUpdate, onComplete) { + this.running = false; + this.textLines = []; + this.lines = []; + this.currentLine = 0; + this.tokenizer = tokenizer; + + this.onUpdate = onUpdate || function(firstLine, lastLine) { + }; + this.onComplete = onComplete || function() { + }; + + var self = this; + this._worker = function() { + if (!self.running) { return; } + + var workerStart = new Date(); + var startLine = self.currentLine; + var textLines = self.textLines; + + var processedLines = 0; + + while (self.currentLine < textLines.length) { + var line = textLines[self.currentLine]; + + var state = self.currentLine == 0 ? "start" + : self.lines[self.currentLine - 1].state; + self.lines[self.currentLine] = self.tokenizer.getLineTokens(line, + state); + + // only check every 30 lines + processedLines += 1; + if ((processedLines % 30 == 0) && (new Date() - workerStart) > 20) { + self.onUpdate(startLine, self.currentLine); + return setTimeout(self._worker, 10); + } + + self.currentLine++; + } + + self.running = false; + + self.onUpdate(startLine, textLines.length - 1); + self.onComplete(); } - - var workerStart = new Date(); - var startLine = self.currentLine; - var textLines = self.textLines; - - var processedLines = 0; - - while (self.currentLine < textLines.length) - { - var line = textLines[self.currentLine]; - - var state = self.currentLine == 0 ? "start" : self.lines[self.currentLine-1].state; - self.lines[self.currentLine] = self.tokenizer.getLineTokens(line, state); - - // only check every 30 lines - processedLines += 1; - if ((processedLines % 30 == 0) && (new Date()-workerStart) > 20) - { - self.onUpdate(startLine, self.currentLine); - return setTimeout(self._worker, 10); - } - - self.currentLine++; - } - - self.running = false; - - self.onUpdate(startLine, textLines.length-1); - self.onComplete(); - } }; -ace.BackgroundTokenizer.prototype.setLines = function(textLines) -{ - this.textLines = textLines; - this.lines = []; - - this.stop(); +ace.BackgroundTokenizer.prototype.setLines = function(textLines) { + this.textLines = textLines; + this.lines = []; + + this.stop(); }; -ace.BackgroundTokenizer.prototype.start = function(startRow) -{ - this.currentLine = Math.min(startRow || 0, this.currentLine, this.textLines.length); - this.lines.splice(startRow, this.lines.length); +ace.BackgroundTokenizer.prototype.start = function(startRow) { + this.currentLine = Math.min(startRow || 0, this.currentLine, + this.textLines.length); + this.lines.splice(startRow, this.lines.length); - if (!this.running) - { - this.running = true; - setTimeout(this._worker, 50); - } + if (!this.running) { + this.running = true; + setTimeout(this._worker, 50); + } }; ace.BackgroundTokenizer.prototype.stop = function() { - this.running = false; + this.running = false; }; -ace.BackgroundTokenizer.prototype.getTokens = function(row) -{ - if (this.lines[row]) { - return this.lines[row].tokens; - } else { - var state = "start"; - if (row > 0 && this.lines[row-1]) { - state = this.lines[row-1].state; +ace.BackgroundTokenizer.prototype.getTokens = function(row) { + if (this.lines[row]) { + return this.lines[row].tokens; + } + else { + var state = "start"; + if (row > 0 && this.lines[row - 1]) { + state = this.lines[row - 1].state; + } + return this.tokenizer.getLineTokens(this.textLines[row] || "", state).tokens; } - return this.tokenizer.getLineTokens(this.textLines[row] || "", state).tokens; - } }; \ No newline at end of file diff --git a/src/CursorLayer.js b/src/CursorLayer.js index 2336546e..74861421 100644 --- a/src/CursorLayer.js +++ b/src/CursorLayer.js @@ -1,71 +1,72 @@ -if (!window.ace) ace = {}; +if (!window.ace) + ace = {}; -ace.CursorLayer = function(parentEl) -{ - this.element = document.createElement("div"); - this.element.className = "layer cursor-layer"; - parentEl.appendChild(this.element); - - this.cursor = document.createElement("div"); - this.cursor.className = "cursor"; - - this.isVisible = false; +ace.CursorLayer = function(parentEl) { + this.element = document.createElement("div"); + this.element.className = "layer cursor-layer"; + parentEl.appendChild(this.element); + + this.cursor = document.createElement("div"); + this.cursor.className = "cursor"; + + this.isVisible = false; } -ace.CursorLayer.prototype.setCursor = function(position) -{ - this.position = { - row: position.row, - column: position.column - }; +ace.CursorLayer.prototype.setCursor = function(position) { + this.position = { + row : position.row, + column : position.column + }; }; -ace.CursorLayer.prototype.hideCursor = function() -{ - this.isVisible = false; - if (this.cursor.parentNode) { - this.cursor.parentNode.removeChild(this.cursor); - } - clearInterval(this.blinkId); +ace.CursorLayer.prototype.hideCursor = function() { + this.isVisible = false; + if (this.cursor.parentNode) { + this.cursor.parentNode.removeChild(this.cursor); + } + clearInterval(this.blinkId); }; -ace.CursorLayer.prototype.showCursor = function() -{ - this.isVisible = true; - this.element.appendChild(this.cursor); +ace.CursorLayer.prototype.showCursor = function() { + this.isVisible = true; + this.element.appendChild(this.cursor); - var cursor = this.cursor; - cursor.style.visibility = "visible"; - - this.blinkId = setInterval(function() { - cursor.style.visibility = "hidden"; - setTimeout(function() { - cursor.style.visibility = "visible"; - }, 400); - }, 1000); + var cursor = this.cursor; + cursor.style.visibility = "visible"; + + this.blinkId = setInterval(function() { + cursor.style.visibility = "hidden"; + setTimeout(function() { + cursor.style.visibility = "visible"; + }, 400); + }, 1000); }; ace.CursorLayer.prototype.getPixelPosition = function() { - return this.pixelPos || {left: 0, top:0}; + return this.pixelPos || { + left : 0, + top : 0 + }; } -ace.CursorLayer.prototype.update = function(config) -{ - if (!this.position) return; +ace.CursorLayer.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.cursor.style.left = cursorLeft + "px"; - this.cursor.style.top = (cursorTop - (config.firstRow * config.lineHeight)) + "px"; - this.cursor.style.height = config.lineHeight + "px"; + var cursorLeft = Math.round(this.position.column * config.characterWidth); + var cursorTop = this.position.row * config.lineHeight; - if (this.isVisible) { - this.element.appendChild(this.cursor); - } + 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); + } }; \ No newline at end of file diff --git a/src/Editor.js b/src/Editor.js index b37c0476..62cb00e7 100644 --- a/src/Editor.js +++ b/src/Editor.js @@ -1,514 +1,512 @@ -if (!window.ace) ace = {}; +if (!window.ace) + ace = {}; (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 + UP : 38, + RIGHT : 39, + DOWN : 40, + LEFT : 37, + PAGEUP : 33, + PAGEDOWN : 34, + POS1 : 36, + END : 35, + DELETE : 46, + BACKSPACE : 8, + TAB : 9, + A : 65 } -var KeyBinding = function(element, host) -{ - ace.addListener(element, "keydown", function(e) - { - var key = e.keyCode; - - switch (key) - { - case keys.A: - if (e.metaKey) - { - host.selectAll(); - return ace.stopEvent(e); - } - break; - - case keys.UP: - if (e.metaKey) { - host.navigateFileStart(); - } if (e.shiftKey) { - host.selectUp(); - } else { - host.navigateUp(); - } - return ace.stopEvent(e); - - case keys.DOWN: - if (e.metaKey) { - host.navigateFileEnd(); - } if (e.shiftKey) { - host.selectDown(); - } else{ - host.navigateDown(); - } - return ace.stopEvent(e); - - case keys.LEFT: - if (e.metaKey && e.shiftKey) { - host.selectLineStart(); - } else if (e.metaKey) { - host.navigateLineStart(); - } else if (e.shiftKey) { - host.selectLeft(); - } else { - host.navigateLeft(); - } - return ace.stopEvent(e); - - case keys.RIGHT: - if (e.metaKey && e.shiftKey) { - host.selectLineEnd(); - } else if (e.metaKey) { - host.navigateLineEnd(); - } else if (e.shiftKey) { - host.selectRight(); - } else { - host.navigateRight(); - } - return ace.stopEvent(e); - - case keys.PAGEDOWN: - if (e.shiftKey) { - host.selectPageDown(); - } else { - host.scrollPageDown(); - } - return ace.stopEvent(e); - - case keys.PAGEUP: - if (e.shiftKey) { - host.selectPageUp(); - } else { - host.scrollPageUp(); - } - return ace.stopEvent(e); - - case keys.POS1: - if (e.shiftKey) { - host.selectLineStart(); - } else { - host.navigateLineStart(); - } - return ace.stopEvent(e); +var KeyBinding = function(element, host) { + ace.addListener(element, "keydown", function(e) { + var key = e.keyCode; - case keys.END: - if (e.shiftKey) { - host.selectLineEnd(); - } else { - host.navigateLineEnd(); + switch (key) { + case keys.A: + if (e.metaKey) { + host.selectAll(); + return ace.stopEvent(e); + } + break; + + case keys.UP: + if (e.metaKey) { + host.navigateFileStart(); + } + if (e.shiftKey) { + host.selectUp(); + } + else { + host.navigateUp(); + } + return ace.stopEvent(e); + + case keys.DOWN: + if (e.metaKey) { + host.navigateFileEnd(); + } + if (e.shiftKey) { + host.selectDown(); + } + else { + host.navigateDown(); + } + return ace.stopEvent(e); + + case keys.LEFT: + if (e.metaKey && e.shiftKey) { + host.selectLineStart(); + } + else if (e.metaKey) { + host.navigateLineStart(); + } + else if (e.shiftKey) { + host.selectLeft(); + } + else { + host.navigateLeft(); + } + return ace.stopEvent(e); + + case keys.RIGHT: + if (e.metaKey && e.shiftKey) { + host.selectLineEnd(); + } + else if (e.metaKey) { + host.navigateLineEnd(); + } + else if (e.shiftKey) { + host.selectRight(); + } + else { + host.navigateRight(); + } + return ace.stopEvent(e); + + case keys.PAGEDOWN: + if (e.shiftKey) { + host.selectPageDown(); + } + else { + host.scrollPageDown(); + } + return ace.stopEvent(e); + + case keys.PAGEUP: + if (e.shiftKey) { + host.selectPageUp(); + } + else { + host.scrollPageUp(); + } + return ace.stopEvent(e); + + case keys.POS1: + if (e.shiftKey) { + host.selectLineStart(); + } + else { + host.navigateLineStart(); + } + return ace.stopEvent(e); + + case keys.END: + if (e.shiftKey) { + host.selectLineEnd(); + } + else { + host.navigateLineEnd(); + } + return ace.stopEvent(e); + + case keys.DELETE: + host.removeRight(); + return ace.stopEvent(e); + + case keys.BACKSPACE: + host.removeLeft(); + return ace.stopEvent(e); + + case keys.TAB: + host.onTextInput(" "); + return ace.stopEvent(e); } - return ace.stopEvent(e); - - case keys.DELETE: - host.removeRight(); - return ace.stopEvent(e); - - case keys.BACKSPACE: - host.removeLeft(); - return ace.stopEvent(e); - - case keys.TAB: - host.onTextInput(" "); - return ace.stopEvent(e); - } - }); + }); }; -ace.Editor = function(doc, renderer) -{ - var container = renderer.getContainerElement(); - this.renderer = renderer; - - this.textInput = new ace.TextInput(container, this); - new KeyBinding(container, this); - - ace.addListener(container, "mousedown", ace.bind(this.onMouseDown, this)); - ace.addListener(container, "dblclick", ace.bind(this.onMouseDoubleClick, this)); - ace.addMouseWheelListener(container, ace.bind(this.onMouseWheel, this)); - ace.addTripleClickListener(container, ace.bind(this.selectCurrentLine, this)); - - this.doc = doc; - doc.addChangeListener(ace.bind(this.onDocumentChange, this)); - renderer.setDocument(doc); - - this.tokenizer = new ace.BackgroundTokenizer( - new ace.Tokenizer(ace.XML.RULES), - ace.bind(this.onTokenizerUpdate, this) - ); - - this.tokenizer.setLines(doc.lines); - renderer.setTokenizer(this.tokenizer); - - this.cursor = { - row: 0, - column: 0 - }; +ace.Editor = function(doc, renderer) { + var container = renderer.getContainerElement(); + this.renderer = renderer; - this.selectionAnchor = null; - this.selectionLead = null; - this.selection = null; + this.textInput = new ace.TextInput(container, this); + new KeyBinding(container, this); - this.renderer.draw(); + ace.addListener(container, "mousedown", ace + .bind(this.onMouseDown, this)); + ace.addListener(container, "dblclick", ace + .bind(this.onMouseDoubleClick, this)); + ace.addMouseWheelListener(container, ace.bind(this.onMouseWheel, this)); + ace.addTripleClickListener(container, ace.bind(this.selectCurrentLine, + this)); + + this.doc = doc; + doc.addChangeListener(ace.bind(this.onDocumentChange, this)); + renderer.setDocument(doc); + + this.tokenizer = new ace.BackgroundTokenizer(new ace.Tokenizer( + ace.XML.RULES), ace.bind(this.onTokenizerUpdate, this)); + + this.tokenizer.setLines(doc.lines); + renderer.setTokenizer(this.tokenizer); + + this.cursor = { + row : 0, + column : 0 + }; + + this.selectionAnchor = null; + this.selectionLead = null; + this.selection = null; + + this.renderer.draw(); }; - + ace.Editor.prototype.resize = function() { - this.renderer.draw(); + this.renderer.draw(); }; ace.Editor.prototype.updateCursor = function() { - this.renderer.updateCursor(this.cursor); + this.renderer.updateCursor(this.cursor); }; ace.Editor.prototype.onFocus = function() { - this.renderer.showCursor(); - this.renderer.visualizeFocus(); + this.renderer.showCursor(); + this.renderer.visualizeFocus(); }; ace.Editor.prototype.onBlur = function() { - this.renderer.hideCursor(); - this.renderer.visualizeBlur(); + this.renderer.hideCursor(); + this.renderer.visualizeBlur(); }; -ace.Editor.prototype.onDocumentChange = function(startRow, endRow) -{ - this.tokenizer.start(startRow); - this.renderer.updateLines(startRow, endRow); +ace.Editor.prototype.onDocumentChange = function(startRow, endRow) { + this.tokenizer.start(startRow); + this.renderer.updateLines(startRow, endRow); }; ace.Editor.prototype.onTokenizerUpdate = function(startRow, endRow) { - this.renderer.updateLines(startRow, endRow); + this.renderer.updateLines(startRow, endRow); }; -ace.Editor.prototype.onMouseDown = function(e) -{ - this.textInput.focus(); +ace.Editor.prototype.onMouseDown = function(e) { + this.textInput.focus(); - var pos = this.renderer.screenToTextCoordinates(e.pageX, e.pageY); - this.moveCursorTo(pos.row, pos.column); - this.setSelectionAnchor(pos.row, pos.column); - this.renderer.scrollCursorIntoView(); + var pos = this.renderer.screenToTextCoordinates(e.pageX, e.pageY); + this.moveCursorTo(pos.row, pos.column); + this.setSelectionAnchor(pos.row, pos.column); + this.renderer.scrollCursorIntoView(); - var _self = this; - var mousePageX, mousePageY; + var _self = this; + var mousePageX, mousePageY; - var onMouseSelection = function(e) { - mousePageX = e.pageX; - mousePageY = e.pageY; - }; + var onMouseSelection = function(e) { + mousePageX = e.pageX; + mousePageY = e.pageY; + }; - var onMouseSelectionEnd = function() { - clearInterval(timerId); - }; + var onMouseSelectionEnd = function() { + clearInterval(timerId); + }; - var onSelectionInterval = function() - { - if (mousePageX === undefined || mousePageY === undefined) return; - - selectionLead = _self.renderer.screenToTextCoordinates(mousePageX, mousePageY); - - _self._moveSelection(function() { - _self.moveCursorTo(selectionLead.row, selectionLead.column); + var onSelectionInterval = function() { + if (mousePageX === undefined || mousePageY === undefined) + return; + + selectionLead = _self.renderer.screenToTextCoordinates(mousePageX, + mousePageY); + + _self._moveSelection(function() { + _self.moveCursorTo(selectionLead.row, selectionLead.column); + }); + _self.renderer.scrollCursorIntoView(); + }; + + ace.capture(this.container, onMouseSelection, onMouseSelectionEnd); + var timerId = setInterval(onSelectionInterval, 20); + + return ace.preventDefault(e); +}; + +ace.Editor.prototype.onMouseDoubleClick = function(e) { + var line = this.doc.getLine(this.cursor.row); + var column = this.cursor.column; + + var tokenRe = /[a-zA-Z0-9_]+/g; + var nonTokenRe = /[^a-zA-Z0-9_]+/g; + + var inToken = false; + if (column > 0) { + inToken = !!line.charAt(column - 1).match(tokenRe); + } + + if (!inToken) { + inToken = !!line.charAt(column).match(tokenRe); + } + + var re = inToken ? tokenRe : 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(this.cursor.row, start); + this._moveSelection(function() { + this.moveCursorTo(this.cursor.row, end); }); - _self.renderer.scrollCursorIntoView(); - }; - - ace.capture(this.container, onMouseSelection, onMouseSelectionEnd); - var timerId = setInterval(onSelectionInterval, 20 ); - - return ace.preventDefault(e); }; -ace.Editor.prototype.onMouseDoubleClick = function(e) -{ - var line = this.doc.getLine(this.cursor.row); - var column = this.cursor.column; - - var tokenRe = /[a-zA-Z0-9_]+/g; - var nonTokenRe = /[^a-zA-Z0-9_]+/g; - - var inToken = false; - if (column > 0) { - inToken = !!line.charAt(column-1).match(tokenRe); - } - - if (!inToken) { - inToken = !!line.charAt(column).match(tokenRe); - } - - var re = inToken ? tokenRe : 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(this.cursor.row, start); - this._moveSelection(function() { - this.moveCursorTo(this.cursor.row, end); - }); +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.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.hasSelection()) { + return this.doc.getTextRange(this.getSelectionRange()); + } + else { + return ""; + } }; -ace.Editor.prototype.getCopyText = function() -{ - if (this.hasSelection()) { - return this.doc.getTextRange(this.getSelectionRange()); - } else { - return ""; - } +ace.Editor.prototype.onCut = function() { + if (this.hasSelection()) { + this.cursor = this.doc.remove(this.getSelectionRange()); + this.clearSelection(); + this.renderer.updateCursor(this.cursor); + } }; -ace.Editor.prototype.onCut = function() -{ - if (this.hasSelection()) - { - this.cursor = this.doc.remove(this.getSelectionRange()); - this.clearSelection(); +ace.Editor.prototype.onTextInput = function(text) { + if (this.hasSelection()) { + this.cursor = this.doc.replace(this.getSelectionRange(), text); + this.clearSelection(); + } + else { + this.cursor = this.doc.insert(this.cursor, text); + } this.renderer.updateCursor(this.cursor); - } + this.renderer.scrollCursorIntoView(); }; -ace.Editor.prototype.onTextInput = function(text) -{ - if (this.hasSelection()) - { - this.cursor = this.doc.replace(this.getSelectionRange(), text); - this.clearSelection(); - } else { - this.cursor = this.doc.insert(this.cursor, text); - } - this.renderer.updateCursor(this.cursor); - this.renderer.scrollCursorIntoView(); +ace.Editor.prototype.removeRight = function() { + if (this.hasSelection()) { + this.cursor = this.doc.remove(this.getSelectionRange()); + this.renderer.updateCursor(this.cursor); + this.clearSelection(); + } + else { + var rangeEnd = { + row : this.cursor.row, + column : this.cursor.column + 1 + } + if (rangeEnd.column > this.doc.getLine(this.cursor.row).length) { + rangeEnd.row += 1; + rangeEnd.column = 0; + } + this.doc.remove( { + start : this.cursor, + end : renageEnd + }); + } + + this.renderer.scrollCursorIntoView(); }; -ace.Editor.prototype.removeRight = function() -{ - if (this.hasSelection()) - { - this.cursor = this.doc.remove(this.getSelectionRange()); - this.renderer.updateCursor(this.cursor); - this.clearSelection(); - } - else - { - var rangeEnd = { - row: this.cursor.row, - column: this.cursor.column + 1 - } - if (rangeEnd.column > this.doc.getLine(this.cursor.row).length) { - rangeEnd.row += 1; - rangeEnd.column = 0; - } - this.doc.remove({start: this.cursor, end: renageEnd}); - } + ace.Editor.prototype.removeLeft = function() { + if (this.hasSelection()) { + this.cursor = this.doc.remove(this.getSelectionRange()); + this.clearSelection(); + } + else { + if (this.cursor.row == 0 && this.cursor.column == 0) { return; } - this.renderer.scrollCursorIntoView(); -}; + var rangeStart = { + row : this.cursor.row, + column : this.cursor.column + -1 + } + if (rangeStart.column < 0) { + rangeStart.row -= 1; + rangeStart.column = this.doc + .getLine(this.cursor.row - 1).length; + } + this.cursor = this.doc.remove( { + start : rangeStart, + end : this.cursor + }); + } -ace.Editor.prototype.removeLeft = function() -{ - if (this.hasSelection()) - { - this.cursor = this.doc.remove(this.getSelectionRange()); - this.clearSelection(); - } - else - { - if (this.cursor.row == 0 && this.cursor.column == 0) { - return; - } + this.renderer.updateCursor(this.cursor); + this.renderer.scrollCursorIntoView(); + }, - var rangeStart = { - row: this.cursor.row, - column: this.cursor.column + -1 - } - if (rangeStart.column < 0) - { - rangeStart.row -= 1; - rangeStart.column = this.doc.getLine(this.cursor.row-1).length; - } - this.cursor = this.doc.remove({start: rangeStart, end: this.cursor}); - } - - this.renderer.updateCursor(this.cursor); - this.renderer.scrollCursorIntoView(); -}, - -ace.Editor.prototype.onCompositionStart = function() -{ - this.renderer.showComposition(this.cursor); - this.onTextInput(" "); -}; + ace.Editor.prototype.onCompositionStart = function() { + this.renderer.showComposition(this.cursor); + this.onTextInput(" "); + }; ace.Editor.prototype.onCompositionUpdate = function(text) { - this.renderer.setCompositionText(text); + this.renderer.setCompositionText(text); }; ace.Editor.prototype.onCompositionEnd = function() { - this.renderer.hideComposition(); - this.removeLeft(); + this.renderer.hideComposition(); + this.removeLeft(); }; ace.Editor.prototype.getFirstVisibleRow = function() { - return this.renderer.getFirstVisibleRow(); + return this.renderer.getFirstVisibleRow(); }; ace.Editor.prototype.getLastVisibleRow = function() { - return this.renderer.getLastVisibleRow(); + return this.renderer.getLastVisibleRow(); }; ace.Editor.prototype.getPageDownRow = function() { - return this.renderer.getLastVisibleRow() - 1; + return this.renderer.getLastVisibleRow() - 1; }; -ace.Editor.prototype.getPageUpRow = function() -{ - var firstRow = this.renderer.getFirstVisibleRow(); - var lastRow = this.renderer.getLastVisibleRow(); +ace.Editor.prototype.getPageUpRow = function() { + var firstRow = this.renderer.getFirstVisibleRow(); + var lastRow = this.renderer.getLastVisibleRow(); - return firstRow - (lastRow-firstRow) + 1; + return firstRow - (lastRow - firstRow) + 1; }; ace.Editor.prototype.scrollPageDown = function() { - this.scrollToRow(this.getPageDownRow()); + this.scrollToRow(this.getPageDownRow()); }; ace.Editor.prototype.scrollPageUp = function() { - this.renderer.scrollToRow(this.getPageUpRow()); + this.renderer.scrollToRow(this.getPageUpRow()); }; ace.Editor.prototype.scrollToRow = function(row) { this.renderer.scrollToRow(row); }; -ace.Editor.prototype.navigateUp = function() -{ - this.clearSelection(); - this.moveCursorUp(); - this.renderer.scrollCursorIntoView(); +ace.Editor.prototype.navigateUp = function() { + this.clearSelection(); + this.moveCursorUp(); + this.renderer.scrollCursorIntoView(); }; ace.Editor.prototype.navigateDown = function() { - this.clearSelection(); - this.moveCursorDown(); - this.renderer.scrollCursorIntoView(); + this.clearSelection(); + this.moveCursorDown(); + this.renderer.scrollCursorIntoView(); }; -ace.Editor.prototype.navigateLeft = function() -{ - if (this.hasSelection()) { - var selectionStart = this.getSelectionRange().start; - this.moveCursorTo(selectionStart.row, selectionStart.column); - } else { - this.moveCursorLeft(); - } - this.clearSelection(); +ace.Editor.prototype.navigateLeft = function() { + if (this.hasSelection()) { + var selectionStart = this.getSelectionRange().start; + this.moveCursorTo(selectionStart.row, selectionStart.column); + } + else { + this.moveCursorLeft(); + } + this.clearSelection(); - this.renderer.scrollCursorIntoView(); + this.renderer.scrollCursorIntoView(); }; -ace.Editor.prototype.navigateRight = function() -{ - if (this.hasSelection()) { - var selectionEnd = this.getSelectionRange().end; - this.moveCursorTo(selectionEnd.row, selectionEnd.column); - } else { - this.moveCursorRight(); - } - this.clearSelection(); +ace.Editor.prototype.navigateRight = function() { + if (this.hasSelection()) { + var selectionEnd = this.getSelectionRange().end; + this.moveCursorTo(selectionEnd.row, selectionEnd.column); + } + else { + this.moveCursorRight(); + } + this.clearSelection(); - this.renderer.scrollCursorIntoView(); -}, + this.renderer.scrollCursorIntoView(); +}, -ace.Editor.prototype.navigateLineStart = function() -{ - this.clearSelection(); - this.moveCursorLineStart(); - this.renderer.scrollCursorIntoView(); +ace.Editor.prototype.navigateLineStart = function() { + this.clearSelection(); + this.moveCursorLineStart(); + this.renderer.scrollCursorIntoView(); }; -ace.Editor.prototype.navigateLineEnd = function() -{ - this.clearSelection(); - this.moveCursorLineEnd(); - this.renderer.scrollCursorIntoView(); +ace.Editor.prototype.navigateLineEnd = function() { + this.clearSelection(); + this.moveCursorLineEnd(); + this.renderer.scrollCursorIntoView(); }; -ace.Editor.prototype.navigateFileEnd = function() -{ +ace.Editor.prototype.navigateFileEnd = function() { this.clearSelection(); this.moveCursorFileEnd(); this.renderer.scrollCursorIntoView(); }, -ace.Editor.prototype.navigateFileStart = function() -{ +ace.Editor.prototype.navigateFileStart = function() { this.clearSelection(); this.moveCursorFileStart(); this.renderer.scrollCursorIntoView(); }, ace.Editor.prototype.moveCursorUp = function() { - this.moveCursorBy(-1, 0); + this.moveCursorBy(-1, 0); }; ace.Editor.prototype.moveCursorDown = function() { - this.moveCursorBy(1, 0); + this.moveCursorBy(1, 0); }; -ace.Editor.prototype.moveCursorLeft = function() -{ - if (this.cursor.column == 0) { - if (this.cursor.row > 0) { - this.moveCursorTo(this.cursor.row-1, this.doc.getLine(this.cursor.row-1).length); +ace.Editor.prototype.moveCursorLeft = function() { + if (this.cursor.column == 0) { + if (this.cursor.row > 0) { + this.moveCursorTo(this.cursor.row - 1, this.doc + .getLine(this.cursor.row - 1).length); + } + } + else { + this.moveCursorBy(0, -1); } - } else { - this.moveCursorBy(0, -1); - } }; -ace.Editor.prototype.moveCursorRight = function() -{ - if (this.cursor.column == this.doc.getLine(this.cursor.row).length) { - if (this.cursor.row < this.doc.getLength()-1) { - this.moveCursorTo(this.cursor.row+1, 0); +ace.Editor.prototype.moveCursorRight = function() { + if (this.cursor.column == this.doc.getLine(this.cursor.row).length) { + if (this.cursor.row < this.doc.getLength() - 1) { + this.moveCursorTo(this.cursor.row + 1, 0); + } + } + else { + this.moveCursorBy(0, 1); } - } else { - this.moveCursorBy(0, 1); - } }; ace.Editor.prototype.moveCursorLineStart = function() { - this.moveCursorTo(this.cursor.row, 0); + this.moveCursorTo(this.cursor.row, 0); }; ace.Editor.prototype.moveCursorLineEnd = function() { - this.moveCursorTo(this.cursor.row, this.doc.getLine(this.cursor.row).length); + this.moveCursorTo(this.cursor.row, + this.doc.getLine(this.cursor.row).length); }; ace.Editor.prototype.moveCursorFileEnd = function() { @@ -522,168 +520,167 @@ ace.Editor.prototype.moveCursorFileStart = function() { }; ace.Editor.prototype.moveCursorBy = function(rows, chars) { - this.moveCursorTo(this.cursor.row+rows, this.cursor.column+chars); + this.moveCursorTo(this.cursor.row + rows, this.cursor.column + chars); }; -ace.Editor.prototype.moveCursorTo = function(row, column) -{ - if (row >= this.doc.getLength()) { - this.cursor.row = this.doc.getLength()-1; - this.cursor.column = this.doc.getLine(this.cursor.row).length; - } else if (row < 0) { - this.cursor.row = 0; - this.cursor.column = 0; - } else { - this.cursor.row = row; - this.cursor.column = Math.min(this.doc.getLine(this.cursor.row).length, Math.max(0, column)); - } - this.updateCursor(); +ace.Editor.prototype.moveCursorTo = function(row, column) { + if (row >= this.doc.getLength()) { + this.cursor.row = this.doc.getLength() - 1; + this.cursor.column = this.doc.getLine(this.cursor.row).length; + } + else if (row < 0) { + this.cursor.row = 0; + this.cursor.column = 0; + } + else { + this.cursor.row = row; + this.cursor.column = Math + .min(this.doc.getLine(this.cursor.row).length, Math + .max(0, column)); + } + this.updateCursor(); }; -ace.Editor.prototype.getCursorPosition = function() -{ +ace.Editor.prototype.getCursorPosition = function() { return { - row: this.cursor.row, - column: this.cursor.column + row : this.cursor.row, + column : this.cursor.column } }; ace.Editor.prototype.hasSelection = function() { - return !!this.selectionLead; + return !!this.selectionLead; }; -ace.Editor.prototype.setSelectionAnchor = function(row, column) -{ - this.clearSelection(); +ace.Editor.prototype.setSelectionAnchor = function(row, column) { + this.clearSelection(); - this.selectionAnchor = { - row: Math.min(this.doc.getLength()-1, Math.max(0, row)), - column: Math.min(this.doc.getLine(this.cursor.row).length, Math.max(0, column)) - }; - - this.selectionLead = null; -}; - -ace.Editor.prototype.getSelectionRange = function() -{ - var anchor = this.selectionAnchor; - var lead = this.selectionLead; - - if (!anchor) { - return null; - } else { - if (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column)) { - return { - start: lead, - end: anchor - } - } else { - return { - start: anchor, - end: lead - } - } - } -}; - -ace.Editor.prototype.clearSelection = function() -{ - this.selectionLead = null; - this.selectionAnchor = null; - - if (this.selection) { - this.renderer.removeMarker(this.selection); - this.selection = null; - } -}; - -ace.Editor.prototype.selectAll = function() -{ - var lastRow = this.doc.getLength()-1; - this.setSelectionAnchor(lastRow, this.doc.getLine(lastRow).length); - - this._moveSelection(function() { - this.moveCursorTo(0, 0); - }); -}; - -ace.Editor.prototype._moveSelection = function(mover) -{ - if (!this.selectionAnchor) { this.selectionAnchor = { - row: this.cursor.row, - column: this.cursor.column + row : Math.min(this.doc.getLength() - 1, Math.max(0, row)), + column : Math.min(this.doc.getLine(this.cursor.row).length, Math + .max(0, column)) + }; + + this.selectionLead = null; +}; + +ace.Editor.prototype.getSelectionRange = function() { + var anchor = this.selectionAnchor; + var lead = this.selectionLead; + + if (!anchor) { + return null; } - } + else { + if (anchor.row > lead.row + || (anchor.row == lead.row && anchor.column > lead.column)) { + return { + start : lead, + end : anchor + } + } + else { + return { + start : anchor, + end : lead + } + } + } +}; - mover.call(this); +ace.Editor.prototype.clearSelection = function() { + this.selectionLead = null; + this.selectionAnchor = null; - this.selectionLead = { - row: this.cursor.row, - column: this.cursor.column - } + if (this.selection) { + this.renderer.removeMarker(this.selection); + this.selection = null; + } +}; - if (this.selection) { - this.renderer.removeMarker(this.selection); - } - this.selection = this.renderer.addMarker(this.getSelectionRange(), "selection"); - this.renderer.scrollCursorIntoView(); +ace.Editor.prototype.selectAll = function() { + var lastRow = this.doc.getLength() - 1; + this.setSelectionAnchor(lastRow, this.doc.getLine(lastRow).length); + + this._moveSelection(function() { + this.moveCursorTo(0, 0); + }); +}; + +ace.Editor.prototype._moveSelection = function(mover) { + if (!this.selectionAnchor) { + this.selectionAnchor = { + row : this.cursor.row, + column : this.cursor.column + } + } + + mover.call(this); + + this.selectionLead = { + row : this.cursor.row, + column : this.cursor.column + } + + if (this.selection) { + this.renderer.removeMarker(this.selection); + } + this.selection = this.renderer.addMarker(this.getSelectionRange(), + "selection"); + this.renderer.scrollCursorIntoView(); }; ace.Editor.prototype.selectUp = function() { - this._moveSelection(this.moveCursorUp); + this._moveSelection(this.moveCursorUp); }; ace.Editor.prototype.selectDown = function() { - this._moveSelection(this.moveCursorDown); + this._moveSelection(this.moveCursorDown); }; ace.Editor.prototype.selectRight = function() { - this._moveSelection(this.moveCursorRight); + this._moveSelection(this.moveCursorRight); }; ace.Editor.prototype.selectLeft = function() { - this._moveSelection(this.moveCursorLeft); + this._moveSelection(this.moveCursorLeft); }; ace.Editor.prototype.selectLineStart = function() { - this._moveSelection(this.moveCursorLineStart); + this._moveSelection(this.moveCursorLineStart); }; ace.Editor.prototype.selectLineEnd = function() { - this._moveSelection(this.moveCursorLineEnd); + this._moveSelection(this.moveCursorLineEnd); }; -ace.Editor.prototype.selectPageDown = function() -{ - var visibleRows = this.getLastVisibleRow() - this.getFirstVisibleRow(); - var row = this.getPageDownRow() + Math.round(visibleRows / 2); +ace.Editor.prototype.selectPageDown = function() { + var visibleRows = this.getLastVisibleRow() - this.getFirstVisibleRow(); + var row = this.getPageDownRow() + Math.round(visibleRows / 2); - this.scrollPageDown(); + this.scrollPageDown(); - this._moveSelection(function() { - this.moveCursorTo(row, this.cursor.column); - }); + this._moveSelection(function() { + this.moveCursorTo(row, this.cursor.column); + }); }; -ace.Editor.prototype.selectPageUp = function() -{ - var visibleRows = this.getLastVisibleRow() - this.getFirstVisibleRow(); - var row = this.getPageUpRow() + Math.round(visibleRows / 2); +ace.Editor.prototype.selectPageUp = function() { + var visibleRows = this.getLastVisibleRow() - this.getFirstVisibleRow(); + var row = this.getPageUpRow() + Math.round(visibleRows / 2); - this.scrollPageUp(); + this.scrollPageUp(); - this._moveSelection(function() { - this.moveCursorTo(row, this.cursor.column); - }); + this._moveSelection(function() { + this.moveCursorTo(row, this.cursor.column); + }); }; -ace.Editor.prototype.selectCurrentLine = function() -{ - this.setSelectionAnchor(this.cursor.row, 0); - this._moveSelection(function() { - this.moveCursorTo(this.cursor.row+1, 0); - }); +ace.Editor.prototype.selectCurrentLine = function() { + this.setSelectionAnchor(this.cursor.row, 0); + this._moveSelection(function() { + this.moveCursorTo(this.cursor.row + 1, 0); + }); } })(); \ No newline at end of file diff --git a/src/GutterLayer.js b/src/GutterLayer.js index 69b1dfb9..1f9fc7c4 100644 --- a/src/GutterLayer.js +++ b/src/GutterLayer.js @@ -1,24 +1,19 @@ -if (!window.ace) ace = {}; +if (!window.ace) + ace = {}; -ace.GutterLayer = function(parentEl) -{ - this.element = document.createElement("div"); - this.element.className = "layer gutter-layer"; - parentEl.appendChild(this.element); +ace.GutterLayer = function(parentEl) { + this.element = document.createElement("div"); + this.element.className = "layer gutter-layer"; + parentEl.appendChild(this.element); } -ace.GutterLayer.prototype.update = function(config) -{ - var html = []; - for (var i=config.firstRow; i<=config.lastRow; i++) - { - html.push( - "
", - i, - "
" - ); - html.push(""); - } - - this.element.innerHTML = html.join(""); +ace.GutterLayer.prototype.update = function(config) { + var html = []; + for ( var i = config.firstRow; i <= config.lastRow; i++) { + html.push("
", i, "
"); + html.push(""); + } + + this.element.innerHTML = html.join(""); }; \ No newline at end of file diff --git a/src/JavaScript.js b/src/JavaScript.js index 780e3f7a..ed387e38 100644 --- a/src/JavaScript.js +++ b/src/JavaScript.js @@ -1,139 +1,114 @@ -if (!window.ace) ace = {}; +if (!window.ace) + ace = {}; (function() { ace.JavaScript = {}; var keywords = { - "break" : 1, - "case" : 1, - "catch" : 1, - "continue" : 1, - "default" : 1, - "delete" : 1, - "do" : 1, - "else" : 1, - "finally" : 1, - "for" : 1, - "function" : 1, - "if" : 1, - "in" : 1, - "instanceof" : 1, - "new" : 1, - "return" : 1, - "switch" : 1, - "throw" : 1, - "try" : 1, - "typeof" : 1, - "var" : 1, - "while" : 1, - "with" : 1 + "break" : 1, + "case" : 1, + "catch" : 1, + "continue" : 1, + "default" : 1, + "delete" : 1, + "do" : 1, + "else" : 1, + "finally" : 1, + "for" : 1, + "function" : 1, + "if" : 1, + "in" : 1, + "instanceof" : 1, + "new" : 1, + "return" : 1, + "switch" : 1, + "throw" : 1, + "try" : 1, + "typeof" : 1, + "var" : 1, + "while" : 1, + "with" : 1 }; // regexp must not have capturing parentheses // regexps are ordered -> the first match is used ace.JavaScript.RULES = { - start : - [ - { - token: "comment", - regex: "\\/\\/.*$" - }, - { - token: "comment", // multi line comment in one line - regex: "\\/\\*.*?\\*\\/" - }, - { - token: "comment", // multi line comment start - regex: "\\/\\*.*$", - next: "comment" - }, - { - token: "string", // single line - regex: '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' - }, - { - token: "string", // multi line string start - regex: '["].*\\\\$', - next: "qqstring" - }, - { - token: "string", // single line - regex: "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" - }, - { - token: "string", // multi line string start - regex: "['].*\\\\$", - next: "qstring" - }, - { - token: "number", // hex - regex: "0[xX][0-9a-fA-F]+\\b" - }, - { - token: "number", // float - regex: "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" - }, - { - token: function(value) - { - if (keywords[value]) { - return "keyword"; - } else { - return "identifier" - } - }, - regex: "[a-zA-Z_][a-zA-Z0-9_]*\\b" - }, - { - token: function(value) { - //return parens[value]; + start : [ { + token : "comment", + regex : "\\/\\/.*$" + }, { + token : "comment", // multi line comment in one line + regex : "\\/\\*.*?\\*\\/" + }, { + token : "comment", // multi line comment start + regex : "\\/\\*.*$", + next : "comment" + }, { + token : "string", // single line + regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]' + }, { + token : "string", // multi line string start + regex : '["].*\\\\$', + next : "qqstring" + }, { + token : "string", // single line + regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']" + }, { + token : "string", // multi line string start + regex : "['].*\\\\$", + next : "qstring" + }, { + token : "number", // hex + regex : "0[xX][0-9a-fA-F]+\\b" + }, { + token : "number", // float + regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b" + }, { + token : function(value) { + if (keywords[value]) { + return "keyword"; + } + else { + return "identifier" + } + }, + regex : "[a-zA-Z_][a-zA-Z0-9_]*\\b" + }, { + token : function(value) { + // return parens[value]; return "text"; - }, - regex: "[\\[\\]\\(\\)\\{\\}]" }, - { - token: "text", - regex: "\\s+" - } - ], - "comment": - [ - { - token: "comment", // closing comment - regex: ".*?\\*\\/", - next: "start" - }, - { - token: "comment", // comment spanning whole line - regex: ".+" - } - ], - "qqstring": - [ - { - token: "string", - regex: '(?:(?:\\\\.)|(?:[^"\\\\]))*?"', - next: "start" - }, - { - token: "string", - regex: '.+' - } - ], - "qstring": - [ - { - token: "string", - regex: "(?:(?:\\\\.)|(?:[^'\\\\]))*?'", - next: "start" - }, - { - token: "string", - regex: '.+' - } - ] + regex : "[\\[\\]\\(\\)\\{\\}]" + }, { + token : "text", + regex : "\\s+" + } ], + "comment" : [ { + token : "comment", // closing comment + regex : ".*?\\*\\/", + next : "start" + }, { + token : "comment", // comment spanning whole line + regex : ".+" + } ], + "qqstring" : [ { + token : "string", + regex : '(?:(?:\\\\.)|(?:[^"\\\\]))*?"', + next : "start" + }, { + token : "string", + regex : '.+' + } ], + "qstring" : [ { + token : "string", + regex : "(?:(?:\\\\.)|(?:[^'\\\\]))*?'", + next : "start" + }, { + token : "string", + regex : '.+' + } ] }; })(); \ No newline at end of file diff --git a/src/MarkerLayer.js b/src/MarkerLayer.js index 5f8e2a02..f1d806b9 100644 --- a/src/MarkerLayer.js +++ b/src/MarkerLayer.js @@ -1,99 +1,107 @@ -if (!window.ace) ace = {}; +if (!window.ace) + ace = {}; -ace.MarkerLayer = function(parentEl) -{ - this.element = document.createElement("div"); - this.element.className = "layer marker-layer"; - parentEl.appendChild(this.element); - - this.markers = {}; - this._markerId = 1; +ace.MarkerLayer = function(parentEl) { + this.element = document.createElement("div"); + this.element.className = "layer marker-layer"; + parentEl.appendChild(this.element); + + this.markers = {}; + this._markerId = 1; } -ace.MarkerLayer.prototype.addMarker = function(range, clazz) -{ - var id = this._markerId++; - this.markers[id] = { - range: range, - type: "line", - clazz: clazz - }; - - this.update(); - return id; -}; +ace.MarkerLayer.prototype.addMarker = function(range, clazz) { + var id = this._markerId++; + this.markers[id] = { + range : range, + type : "line", + clazz : clazz + }; -ace.MarkerLayer.prototype.removeMarker = function(markerId) -{ - var marker = this.markers[markerId]; - if (marker) { - delete(this.markers[markerId]); this.update(); - } + return id; }; -ace.MarkerLayer.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 = marker.range; - - if (range.start.row !== range.end.row) - { - if (range.start.row >= config.firstRow && range.start.row <= config.lastRow) - { - html.push( - "
" - ); - } - - if (range.end.row >= config.firstRow && range.end.row <= config.lastRow) - { - html.push( - "
" - ); - }; - - for (var row=range.start.row+1; row < range.end.row; row++) - { - if (row >= config.firstRow && row <= config.lastRow) - { - html.push( - "
" - ); +ace.MarkerLayer.prototype.removeMarker = function(markerId) { + var marker = this.markers[markerId]; + if (marker) { + delete (this.markers[markerId]); + this.update(); + } +}; + +ace.MarkerLayer.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 = marker.range; + + if (range.start.row !== range.end.row) { + if (range.start.row >= config.firstRow + && range.start.row <= config.lastRow) { + html + .push( + "
"); + } + + if (range.end.row >= config.firstRow + && range.end.row <= config.lastRow) { + html + .push("
"); + } + ; + + for ( var row = range.start.row + 1; row < range.end.row; row++) { + if (row >= config.firstRow && row <= config.lastRow) { + html.push("
"); + } + } + ; + } + else { + if (range.start.row >= config.firstRow + && range.start.row <= config.lastRow) { + html.push("
"); + } } - }; } - else - { - if (range.start.row >= config.firstRow && range.start.row <= config.lastRow) - { - html.push( - "
" - ); - } - } - } - this.element.innerHTML = html.join(""); + this.element.innerHTML = html.join(""); }; \ No newline at end of file diff --git a/src/TextDocument.js b/src/TextDocument.js index 57e590f1..8136f366 100644 --- a/src/TextDocument.js +++ b/src/TextDocument.js @@ -1,221 +1,212 @@ -if (!window.ace) ace = {}; +if (!window.ace) + ace = {}; -ace.TextDocument = function(text) -{ - this.lines = this._split(text); - this.modified = true; - - this.listeners = []; +ace.TextDocument = function(text) { + this.lines = this._split(text); + this.modified = true; + + this.listeners = []; } ace.TextDocument.prototype._split = function(text) { - return text.split(/[\n\r]/) + return text.split(/[\n\r]/) }; ace.TextDocument.prototype.addChangeListener = function(listener) { - this.listeners.push(listener); + this.listeners.push(listener); }; -ace.TextDocument.prototype.fireChangeEvent = function(firstRow, lastRow) -{ - for (var i=0; i < this.listeners.length; i++) { - this.listeners[i](firstRow, lastRow); - }; +ace.TextDocument.prototype.fireChangeEvent = function(firstRow, lastRow) { + for ( var i = 0; i < this.listeners.length; i++) { + this.listeners[i](firstRow, lastRow); + } + ; }; -ace.TextDocument.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.width = longestLine; - } - return this.width; +ace.TextDocument.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.width = longestLine; + } + return this.width; }; ace.TextDocument.prototype.getLine = function(row) { - return this.lines[row] || ""; + return this.lines[row] || ""; }; ace.TextDocument.prototype.keywords = { - "break" : 1, - "case" : 1, - "catch" : 1, - "continue" : 1, - "default" : 1, - "delete" : 1, - "do" : 1, - "else" : 1, - "finally" : 1, - "for" : 1, - "function" : 1, - "if" : 1, - "in" : 1, - "instanceof" : 1, - "new" : 1, - "return" : 1, - "switch" : 1, - "throw" : 1, - "try" : 1, - "typeof" : 1, - "var" : 1, - "while" : 1, - "with" : 1 + "break" : 1, + "case" : 1, + "catch" : 1, + "continue" : 1, + "default" : 1, + "delete" : 1, + "do" : 1, + "else" : 1, + "finally" : 1, + "for" : 1, + "function" : 1, + "if" : 1, + "in" : 1, + "instanceof" : 1, + "new" : 1, + "return" : 1, + "switch" : 1, + "throw" : 1, + "try" : 1, + "typeof" : 1, + "var" : 1, + "while" : 1, + "with" : 1 }; -ace.TextDocument.prototype.getLineTokens = function(row) -{ - var tokens = []; - - var re = /(?:(\s+)|("[^"]*")|('[^']*')|([\[\]\(\)\{\}])|([a-zA-Z_][a-zA-Z0-9_]*)|(\/\/.*)|(.))/g - re.lastIndex = 0; +ace.TextDocument.prototype.getLineTokens = function(row) { + var tokens = []; - var match; - var line = this.getLine(row); - while (match = re.exec(line)) - { - var token = { - type: "text", - value: match[0] + var re = /(?:(\s+)|("[^"]*")|('[^']*')|([\[\]\(\)\{\}])|([a-zA-Z_][a-zA-Z0-9_]*)|(\/\/.*)|(.))/g + re.lastIndex = 0; + + var match; + var line = this.getLine(row); + while (match = re.exec(line)) { + var token = { + type : "text", + value : match[0] + } + + if (match[2] || match[3]) { + token.type = "string"; + } + else if (match[5] && this.keywords[match[5]]) { + token.type = "keyword"; + } + else if (match[6]) { + token.type = "comment"; + } + + tokens.push(token); } - - if (match[2] || match[3]) { - token.type = "string"; - } else if (match[5] && this.keywords[match[5]]) { - token.type = "keyword"; - } else if (match[6]) { - token.type = "comment"; - } - - tokens.push(token); - }; - - return tokens; + ; + + return tokens; }; ace.TextDocument.prototype.getLength = function() { - return this.lines.length; + return this.lines.length; }; -ace.TextDocument.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.lines.slice(range.start.row+1, range.end.row)); - lines.push(this.lines[range.end.row].substring(0, range.end.column)); - - return lines.join("\n"); - } -}; - -ace.TextDocument.prototype.insert = function(position, text) -{ - var end = this._insert(position, text); - this.fireChangeEvent( - position.row, - position.row == end.row ? position.row : undefined - ); - return end; -}; - -ace.TextDocument.prototype._insert = function(position, text) -{ - this.modified = true; - - var newLines = this._split(text); - - if (text == "\n") - { - 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 +ace.TextDocument.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 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) - { - var args = [position.row + 1, 0] - args.push.apply(args, newLines.slice(1, -1)); - this.lines.splice.apply(this.lines, args); + else { + var lines = []; + lines.push(this.lines[range.start.row].substring(range.start.column)); + lines.push.apply(lines, this.lines.slice(range.start.row + 1, + range.end.row)); + lines.push(this.lines[range.end.row].substring(0, range.end.column)); + + return lines.join("\n"); } - - return { - row: position.row + newLines.length - 1, - column: newLines[newLines.length-1].length - }; - } -}; - -ace.TextDocument.prototype.remove = function(range) -{ - var end = this._remove(range); - - this.fireChangeEvent( - range.start.row, - range.end.row == range.start.row ? range.start.row : undefined - ); - return end; }; -ace.TextDocument.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.TextDocument.prototype.insert = function(position, text) { + var end = this._insert(position, text); + this.fireChangeEvent(position.row, position.row == end.row ? position.row + : undefined); + return end; }; -ace.TextDocument.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.TextDocument.prototype._insert = function(position, text) { + this.modified = true; + + var newLines = this._split(text); + + if (text == "\n") { + 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) { + var args = [ position.row + 1, 0 ] + args.push.apply(args, newLines.slice(1, -1)); + this.lines.splice.apply(this.lines, args); + } + + return { + row : position.row + newLines.length - 1, + column : newLines[newLines.length - 1].length + }; + } +}; + +ace.TextDocument.prototype.remove = function(range) { + var end = this._remove(range); + + this.fireChangeEvent(range.start.row, + range.end.row == range.start.row ? range.start.row + : undefined); + return end; +}; + +ace.TextDocument.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.TextDocument.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; } \ No newline at end of file diff --git a/src/TextInput.js b/src/TextInput.js index becf9634..616f73b1 100644 --- a/src/TextInput.js +++ b/src/TextInput.js @@ -1,84 +1,85 @@ -if (!window.ace) ace = {}; +if (!window.ace) + ace = {}; ace.TextInput = function(parentNode, host) { - - var text = document.createElement("textarea"); - var style = text.style; - style.position = "absolute"; - style.left = "-10000px"; - style.top = "-10000px"; - parentNode.appendChild(text); - - var inCompostion = false; - - var onTextInput = function(e) { - setTimeout(function() { - if (!inCompostion) { - if (text.value) host.onTextInput(text.value); + + var text = document.createElement("textarea"); + var style = text.style; + style.position = "absolute"; + style.left = "-10000px"; + style.top = "-10000px"; + parentNode.appendChild(text); + + var inCompostion = false; + + var onTextInput = function(e) { + setTimeout(function() { + if (!inCompostion) { + if (text.value) + host.onTextInput(text.value); + text.value = ""; + } + }, 0) + } + + var onCompositionStart = function(e) { + inCompostion = true; + + if (text.value) + host.onTextInput(text.value); text.value = ""; - } - }, 0) - } - var onCompositionStart = function(e) - { - inCompostion = true; + host.onCompositionStart(); + setTimeout(onCompositionUpdate, 0); + } - if (text.value) host.onTextInput(text.value); - text.value = ""; - - host.onCompositionStart(); - setTimeout(onCompositionUpdate, 0); - } + var onCompositionUpdate = function() { + host.onCompositionUpdate(text.value); + } - var onCompositionUpdate = function() { - host.onCompositionUpdate(text.value); - } + var onCompositionEnd = function() { + inCompostion = false; + host.onCompositionEnd(); + onTextInput(); + } - var onCompositionEnd = function() - { - inCompostion = false; - host.onCompositionEnd(); - onTextInput(); - } - - var onCopy = function() { - text.value = host.getCopyText(); - text.select(); - } - - var onCut = function() { - text.value = host.getCopyText(); - host.onCut(); - text.select(); - } + var onCopy = function() { + text.value = host.getCopyText(); + text.select(); + } - ace.addListener(text, "keypress", onTextInput, false); - ace.addListener(text, "textInput", onTextInput, false); - ace.addListener(text, "paste", onTextInput, false); - ace.addListener(text, "propertychange", onTextInput, false); + var onCut = function() { + text.value = host.getCopyText(); + host.onCut(); + text.select(); + } - ace.addListener(text, "copy", onCopy, false); - ace.addListener(text, "cut", onCut, false); + ace.addListener(text, "keypress", onTextInput, false); + ace.addListener(text, "textInput", onTextInput, false); + ace.addListener(text, "paste", onTextInput, false); + ace.addListener(text, "propertychange", onTextInput, false); - ace.addListener(text, "compositionstart", onCompositionStart, false); - ace.addListener(text, "compositionupdate", onCompositionUpdate, false); - ace.addListener(text, "compositionend", onCompositionEnd, false); - - ace.addListener(text, "blur", function() { - host.onBlur(); - }, false); - - ace.addListener(text, "focus", function() { - host.onFocus(); - }, false); - - - this.focus = function() { - text.focus(); - } - - this.blur = function() { - this.blur(); - } + ace.addListener(text, "copy", onCopy, false); + ace.addListener(text, "cut", onCut, false); + + ace.addListener(text, "compositionstart", onCompositionStart, false); + ace.addListener(text, "compositionupdate", onCompositionUpdate, false); + ace.addListener(text, "compositionend", onCompositionEnd, false); + + ace.addListener(text, "blur", function() { + host.onBlur(); + }, false); + + ace.addListener(text, "focus", function() { + host.onFocus(); + }, false); + + + this.focus = function() { + text.focus(); + } + + this.blur = function() { + this.blur(); + } }; \ No newline at end of file diff --git a/src/TextLayer.js b/src/TextLayer.js index cf81715b..acdcc5c2 100644 --- a/src/TextLayer.js +++ b/src/TextLayer.js @@ -1,99 +1,90 @@ -if (!window.ace) ace = {}; +if (!window.ace) + ace = {}; -ace.TextLayer = function(parentEl) -{ - this.element = document.createElement("div"); - this.element.className = "layer text-layer"; - parentEl.appendChild(this.element); - - this._measureSizes(); +ace.TextLayer = function(parentEl) { + this.element = document.createElement("div"); + this.element.className = "layer text-layer"; + parentEl.appendChild(this.element); + + this._measureSizes(); } ace.TextLayer.prototype.setTokenizer = function(tokenizer) { - this.tokenizer = tokenizer; + this.tokenizer = tokenizer; }; ace.TextLayer.prototype.getLineHeight = function() { - return this.lineHeight; + return this.lineHeight; }; ace.TextLayer.prototype.getCharacterWidth = function() { - return this.characterWidth; + return this.characterWidth; }; -ace.TextLayer.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"; - - measureNode.innerHTML = new Array(1000).join("Xy"); - this.element.appendChild(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; - - this.element.removeChild(measureNode); +ace.TextLayer.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"; + + measureNode.innerHTML = new Array(1000).join("Xy"); + this.element.appendChild(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; + + this.element.removeChild(measureNode); }; -ace.TextLayer.prototype.updateLines = function(layerConfig, firstRow, lastRow) -{ - var first = Math.max(firstRow, layerConfig.firstRow); - var last = Math.min(lastRow, layerConfig.lastRow); - - 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(""); - }; -}; +ace.TextLayer.prototype.updateLines = function(layerConfig, firstRow, lastRow) { + var first = Math.max(firstRow, layerConfig.firstRow); + var last = Math.min(lastRow, layerConfig.lastRow); -ace.TextLayer.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(""); -}; + var lineElements = this.element.childNodes; -ace.TextLayer.prototype.renderLine = function(stringBuilder, row) -{ - var tokens = this.tokenizer.getTokens(row); - for (var i=0; i < tokens.length; i++) - { - var token = tokens[i]; + for ( var i = first; i <= last; i++) { + var html = []; + this.renderLine(html, i); - var output = token.value. - replace(/&/g, "&"). - replace(/", output, ""); - } else { - stringBuilder.push(output); + var lineElement = lineElements[i - layerConfig.firstRow]; + lineElement.innerHTML = html.join(""); } - }; + ; +}; + +ace.TextLayer.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.TextLayer.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); + } + } + ; }; \ No newline at end of file diff --git a/src/Tokenizer.js b/src/Tokenizer.js index 0e727ccc..af75ca3c 100644 --- a/src/Tokenizer.js +++ b/src/Tokenizer.js @@ -1,78 +1,75 @@ -if (!window.ace) ace = {}; +if (!window.ace) + ace = {}; -ace.Tokenizer = function(rules) -{ - this.rules = rules; - - this.regExps = {}; - for (var key in this.rules) - { - var state = this.rules[key]; - var ruleRegExps = []; - - for (var i=0; i < state.length; i++) { - ruleRegExps.push(state[i].regex); - }; - - this.regExps[key] = new RegExp("(?:(" + ruleRegExps.join(")|(") + ")|(.))", "g"); - } +ace.Tokenizer = function(rules) { + this.rules = rules; + + this.regExps = {}; + for ( var key in this.rules) { + var state = this.rules[key]; + var ruleRegExps = []; + + for ( var i = 0; i < state.length; i++) { + ruleRegExps.push(state[i].regex); + } + ; + + this.regExps[key] = new RegExp("(?:(" + ruleRegExps.join(")|(") + + ")|(.))", "g"); + } }; -ace.Tokenizer.prototype.getLineTokens = function(line, startState) -{ - var currentState = startState; - var state = this.rules[currentState]; - var re = this.regExps[currentState]; - re.lastIndex = 0; - - var match, tokens = []; - - var lastIndex = 0; - - while (match = re.exec(line)) - { - var token = { - type: "text", - value: match[0] - } - - if (re.lastIndex == lastIndex) { - throw new Error("tokenizer error") - } - lastIndex = re.lastIndex; - - //console.log(match); - - for (var i=0; i < state.length; i++) - { - if (match[i+1]) - { - if (typeof state[i].token == "function") { - token.type = state[i].token(match[0]); - } else { - token.type = state[i].token; +ace.Tokenizer.prototype.getLineTokens = function(line, startState) { + var currentState = startState; + var state = this.rules[currentState]; + var re = this.regExps[currentState]; + re.lastIndex = 0; + + var match, tokens = []; + + var lastIndex = 0; + + while (match = re.exec(line)) { + var token = { + type : "text", + value : match[0] } - - 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 (re.lastIndex == lastIndex) { throw new Error("tokenizer error") } + lastIndex = re.lastIndex; + + // console.log(match); + + for ( var i = 0; i < state.length; i++) { + if (match[i + 1]) { + if (typeof state[i].token == "function") { + token.type = state[i].token(match[0]); + } + else { + token.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; + } } - break; - } - }; - - tokens.push(token); - }; - - //console.log(tokens, currentState) - - return { - tokens: tokens, - state: currentState - } + ; + + tokens.push(token); + } + ; + + // console.log(tokens, currentState) + + return { + tokens : tokens, + state : currentState + } }; \ No newline at end of file diff --git a/src/VirtualRenderer.js b/src/VirtualRenderer.js index b65d4db0..9930202d 100644 --- a/src/VirtualRenderer.js +++ b/src/VirtualRenderer.js @@ -1,206 +1,201 @@ -if (!window.ace) ace = {}; +if (!window.ace) + ace = {}; -ace.VirtualRenderer = function(container) -{ - this.container = container; - this.container.className += "editor"; - - this.scroller = document.createElement("div"); - this.scroller.className = "scroller"; - this.container.appendChild(this.scroller); - - this.gutter = document.createElement("div"); - this.gutter.className = "gutter"; - this.container.appendChild(this.gutter); +ace.VirtualRenderer = function(container) { + this.container = container; + this.container.className += "editor"; - this.gutterLayer = new ace.GutterLayer(this.gutter); - this.markerLayer = new ace.MarkerLayer(this.scroller); + this.scroller = document.createElement("div"); + this.scroller.className = "scroller"; + this.container.appendChild(this.scroller); - var textLayer = this.textLayer = new ace.TextLayer(this.scroller); - this.canvas = textLayer.element; - - this.characterWidth = textLayer.getCharacterWidth(); - this.lineHeight = textLayer.getLineHeight(); - - this.cursorLayer = new ace.CursorLayer(this.scroller); - - this.layers = [this.markerLayer, textLayer, this.cursorLayer]; - - this.scrollTop = 0; - - this.cursorPos = { - row: 0, - column: 0 - }; + this.gutter = document.createElement("div"); + this.gutter.className = "gutter"; + this.container.appendChild(this.gutter); + + this.gutterLayer = new ace.GutterLayer(this.gutter); + this.markerLayer = new ace.MarkerLayer(this.scroller); + + var textLayer = this.textLayer = new ace.TextLayer(this.scroller); + this.canvas = textLayer.element; + + this.characterWidth = textLayer.getCharacterWidth(); + this.lineHeight = textLayer.getLineHeight(); + + this.cursorLayer = new ace.CursorLayer(this.scroller); + + this.layers = [ this.markerLayer, textLayer, this.cursorLayer ]; + + this.scrollTop = 0; + + this.cursorPos = { + row : 0, + column : 0 + }; } -ace.VirtualRenderer.prototype.setDocument = function(doc) -{ - this.lines = doc.lines; - this.doc = doc; +ace.VirtualRenderer.prototype.setDocument = function(doc) { + this.lines = doc.lines; + this.doc = doc; }; ace.VirtualRenderer.prototype.setTokenizer = function(tokenizer) { - this.textLayer.setTokenizer(tokenizer); + this.textLayer.setTokenizer(tokenizer); }; ace.VirtualRenderer.prototype.getContainerElement = function() { - return this.container; + return this.container; }; ace.VirtualRenderer.prototype.getFirstVisibleRow = function() { - return this.layerConfig.firstRow || 0; + return this.layerConfig.firstRow || 0; }; ace.VirtualRenderer.prototype.getLastVisibleRow = function() { - return this.layerConfig.lastRow || 0; + return this.layerConfig.lastRow || 0; }; -ace.VirtualRenderer.prototype.updateLines = function(firstRow, lastRow) -{ - var layerConfig = this.layerConfig; - - // if the first row is below the viewport -> ignore it - if (firstRow > layerConfig.lastRow+1) { - return; - } - - // if the last row is unknow -> redraw everything - if (lastRow === undefined) - { - this.draw() - return; - } - - // else update only the changed rows - this.textLayer.updateLines(layerConfig, firstRow, lastRow); +ace.VirtualRenderer.prototype.updateLines = function(firstRow, lastRow) { + var layerConfig = this.layerConfig; + + // if the first row is below the viewport -> ignore it + if (firstRow > layerConfig.lastRow + 1) { return; } + + // if the last row is unknow -> 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; +ace.VirtualRenderer.prototype.draw = function() { + var lines = this.lines; - 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 offset = this.scrollTop % this.lineHeight; + var minHeight = this.scroller.clientHeight + offset; - var style = layer.element.style; - style.marginTop = (-offset) + "px"; - style.height = minHeight + "px"; - style.width = longestLine + "px"; + var longestLine = Math.max(this.scroller.clientWidth, Math.round(this.doc + .getWidth() + * this.characterWidth)); - layer.update(layerConfig); - }; - - this.gutterLayer.element.style.marginTop = (-offset) + "px"; - this.gutterLayer.element.style.height = minHeight + "px"; - this.gutterLayer.update(layerConfig); + 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); } ace.VirtualRenderer.prototype.addMarker = function(range, clazz) { - return this.markerLayer.addMarker(range, clazz); + return this.markerLayer.addMarker(range, clazz); }; ace.VirtualRenderer.prototype.removeMarker = function(markerId) { - this.markerLayer.removeMarker(markerId); + this.markerLayer.removeMarker(markerId); }; -ace.VirtualRenderer.prototype.updateCursor = function(position) -{ - this.cursorLayer.setCursor(position); - this.cursorLayer.update(this.layerConfig); +ace.VirtualRenderer.prototype.updateCursor = function(position) { + this.cursorLayer.setCursor(position); + this.cursorLayer.update(this.layerConfig); }; ace.VirtualRenderer.prototype.hideCursor = function() { - this.cursorLayer.hideCursor(); + this.cursorLayer.hideCursor(); }; ace.VirtualRenderer.prototype.showCursor = function() { - this.cursorLayer.showCursor(); + 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.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; + return this.scrollTop; }; ace.VirtualRenderer.prototype.scrollToRow = function(row) { - this.scrollToY(row*this.lineHeight); + 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.draw(); - } +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.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 - } +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 + } }; ace.VirtualRenderer.prototype.visualizeFocus = function() { - this.container.className = "editor focus"; + this.container.className = "editor focus"; }; ace.VirtualRenderer.prototype.visualizeBlur = function() { - this.container.className = "editor"; + this.container.className = "editor"; }; ace.VirtualRenderer.prototype.showComposition = function(position) { diff --git a/src/XML.js b/src/XML.js index 69f1d709..96389128 100644 --- a/src/XML.js +++ b/src/XML.js @@ -1,98 +1,75 @@ -if (!window.ace) ace = {}; +if (!window.ace) + ace = {}; (function() { -ace.XML = {}; + ace.XML = {}; -// regexp must not have capturing parentheses -// regexps are ordered -> the first match is used + // regexp must not have capturing parentheses + // regexps are ordered -> the first match is used -ace.XML.RULES = { - start : - [ - { - token: "text", - regex: "<\\!\\[CDATA\\[", - next: "cdata" - }, - { - token: "xml_pe", - regex: "<\\?.*?\\?>" - }, - { - token: "comment", - regex: "<\\!--", - next: "comment" - }, - { - token: "text", // opening tag - regex: "<", - next: "tag" - }, - { - token: "text", - regex: "\\s+" - }, - { - token: "text", - regex: ".+" - } - ], - - tag: - [ - { - token: "text", - regex: ">", - next: "start" - }, - { - token: "keyword", - regex: "[-_a-zA-Z0-9:]+" - }, - { - token: "text", - regex: "\\s+" - }, - { - token: "string", - regex: '".*?"' - }, - { - token: "string", - regex: "'.*?'" - } - ], - - cdata: - [ - { - token: "text", - regex: "\\]\\]>", - next: "start" - }, - { - token: "text", - regex: "\\s+" - }, - { - token: "text", - regex: ".+" - } - ], - - comment: - [ - { - token: "comment", - regex: ".*?-->", - next: "start" - }, - { - token: "comment", - regex: ".+" - } - ] -}; + ace.XML.RULES = { + start : [ { + token : "text", + regex : "<\\!\\[CDATA\\[", + next : "cdata" + }, { + token : "xml_pe", + regex : "<\\?.*?\\?>" + }, { + token : "comment", + regex : "<\\!--", + next : "comment" + }, { + token : "text", // opening tag + regex : "<", + next : "tag" + }, { + token : "text", + regex : "\\s+" + }, { + token : "text", + regex : ".+" + } ], + + tag : [ { + token : "text", + regex : ">", + next : "start" + }, { + token : "keyword", + regex : "[-_a-zA-Z0-9:]+" + }, { + token : "text", + regex : "\\s+" + }, { + token : "string", + regex : '".*?"' + }, { + token : "string", + regex : "'.*?'" + } ], + + cdata : [ { + token : "text", + regex : "\\]\\]>", + next : "start" + }, { + token : "text", + regex : "\\s+" + }, { + token : "text", + regex : ".+" + } ], + + comment : [ { + token : "comment", + regex : ".*?-->", + next : "start" + }, { + token : "comment", + regex : ".+" + } ] + }; })(); \ No newline at end of file diff --git a/src/lib.js b/src/lib.js index 92c1f8c5..04036745 100644 --- a/src/lib.js +++ b/src/lib.js @@ -1,173 +1,159 @@ -if (!window.ace) ace = {}; +if (!window.ace) + ace = {}; (function() { ace.addListener = function(elem, type, callback) { - if (elem.addEventListener) { - return elem.addEventListener(type, callback, false); - } - if (elem.attachEvent) { - var wrapper = function() { - callback(window.event); + if (elem.addEventListener) { return elem.addEventListener(type, + callback, + false); } + if (elem.attachEvent) { + var wrapper = function() { + callback(window.event); + } + callback.$$wrapper = wrapper; + elem.attachEvent("on" + type, wrapper); } - callback.$$wrapper = wrapper; - elem.attachEvent("on" + type, wrapper); - } } ace.removeListener = function(elem, type, callback) { - if (elem.removeEventListener) { - return elem.removeEventListener(type, callback, false); - } - if (elem.detachEvent) { - elem.detachEvent("on" + type, callback.$$wrapper || callback); - } + if (elem.removeEventListener) { return elem + .removeEventListener(type, callback, false); } + if (elem.detachEvent) { + elem.detachEvent("on" + type, callback.$$wrapper || callback); + } } ace.setText = function(elem, text) { - if (elem.innerText !== undefined) { - elem.innerText = text; - } - if (elem.textContent !== undefined) { - elem.textContent = text; - } -} - + if (elem.innerText !== undefined) { + elem.innerText = text; + } + if (elem.textContent !== undefined) { + elem.textContent = text; + } +} + ace.stopEvent = function(e) { - ace.stopPropagation(e); - ace.preventDefault(e); - return false; + ace.stopPropagation(e); + ace.preventDefault(e); + return false; } ace.stopPropagation = function(e) { - if (e.stopPropagation) - e.stopPropagation(); - else - e.cancelBubble = true; + if (e.stopPropagation) + e.stopPropagation(); + else + e.cancelBubble = true; } -ace.preventDefault = function(e) -{ - if (e.preventDefault) - e.preventDefault(); - else - e.returnValue = false; +ace.preventDefault = function(e) { + if (e.preventDefault) + e.preventDefault(); + else + e.returnValue = false; } ace.inherits = function(ctor, superCtor) { - var tempCtor = function(){}; - tempCtor.prototype = superCtor.prototype; - ctor.super_ = superCtor.prototype; - ctor.prototype = new tempCtor(); - ctor.prototype.constructor = ctor; + var tempCtor = function() { + }; + tempCtor.prototype = superCtor.prototype; + ctor.super_ = superCtor.prototype; + ctor.prototype = new tempCtor(); + ctor.prototype.constructor = ctor; }; -ace.getInnerWidth = function(element) -{ - return ( - parseInt(ace.computedStyle(element, "paddingLeft")) + - parseInt(ace.computedStyle(element, "paddingRight")) + - element.clientWidth - ); +ace.getInnerWidth = function(element) { + return (parseInt(ace.computedStyle(element, "paddingLeft")) + + parseInt(ace.computedStyle(element, "paddingRight")) + element.clientWidth); }; -ace.getInnerHeight = function(element) -{ - return ( - parseInt(ace.computedStyle(element, "paddingTop")) + - parseInt(ace.computedStyle(element, "paddingBottom")) + - element.clientHeight - ); +ace.getInnerHeight = function(element) { + return (parseInt(ace.computedStyle(element, "paddingTop")) + + parseInt(ace.computedStyle(element, "paddingBottom")) + element.clientHeight); }; -ace.computedStyle = function(element, style) -{ - if (window.getComputedStyle) { - return (window.getComputedStyle(element, null))[style]; - } else { - return element.currentStyle[style]; - } +ace.computedStyle = function(element, style) { + if (window.getComputedStyle) { + return (window.getComputedStyle(element, null))[style]; + } + else { + return element.currentStyle[style]; + } } ace.scrollbarHeight = function() { - var el = document.createElement("div"); - var style = el.style; - - style.position = "absolute"; - style.left = "-10000px"; - style.overflow = "scroll"; - style.height = "100px"; - - document.body.appendChild(el); - var height = el.offsetHeight - el.clientHeight; - document.body.removeChild(el); - - return height; + var el = document.createElement("div"); + var style = el.style; + + style.position = "absolute"; + style.left = "-10000px"; + style.overflow = "scroll"; + style.height = "100px"; + + document.body.appendChild(el); + var height = el.offsetHeight - el.clientHeight; + document.body.removeChild(el); + + return height; } ace.bind = function(fcn, context) { - return function() { - return fcn.apply(context, arguments); - } + return function() { + return fcn.apply(context, arguments); + } } -ace.capture = function(el, eventHandler, releaseCaptureHandler) -{ - function onMouseMove(e) - { - eventHandler(e); - e.stopPropagation(); - } - - function onMouseUp(e) - { - eventHandler && eventHandler(e); - releaseCaptureHandler && releaseCaptureHandler(); +ace.capture = function(el, eventHandler, releaseCaptureHandler) { + function onMouseMove(e) { + eventHandler(e); + e.stopPropagation(); + } - document.removeEventListener("mousemove", onMouseMove, true); - document.removeEventListener("mouseup", onMouseUp, true); - - e.stopPropagation(); - } - - document.addEventListener("mousemove", onMouseMove, true); - document.addEventListener("mouseup", onMouseUp, true); + function onMouseUp(e) { + eventHandler && eventHandler(e); + releaseCaptureHandler && releaseCaptureHandler(); + + document.removeEventListener("mousemove", onMouseMove, true); + document.removeEventListener("mouseup", onMouseUp, true); + + e.stopPropagation(); + } + + document.addEventListener("mousemove", onMouseMove, true); + document.addEventListener("mouseup", onMouseUp, true); } -ace.addMouseWheelListener = function(el, callback) -{ - var listener = function(e) { - e.wheel = (e.wheelDelta) ? e.wheelDelta / 120 : -(e.detail || 0) / 3; - callback(e); - } - ace.addListener(el, "DOMMouseScroll", listener); - ace.addListener(el, "mousewheel", listener); +ace.addMouseWheelListener = function(el, callback) { + var listener = function(e) { + e.wheel = (e.wheelDelta) ? e.wheelDelta / 120 + : -(e.detail || 0) / 3; + callback(e); + } + ace.addListener(el, "DOMMouseScroll", listener); + ace.addListener(el, "mousewheel", listener); }; -ace.autoremoveListener = function(el, type, callback, timeout) -{ - var listener = function(e) - { - clearTimeout(timeoutId); - remove(); - callback(e); - } +ace.autoremoveListener = function(el, type, callback, timeout) { + var listener = function(e) { + clearTimeout(timeoutId); + remove(); + callback(e); + } - var remove = function() { - ace.removeListener(el, type, listener); - }; + var remove = function() { + ace.removeListener(el, type, listener); + }; - ace.addListener(el, type, listener); - var timeoutId = setTimeout(remove, timeout); + ace.addListener(el, type, listener); + var timeoutId = setTimeout(remove, timeout); } -ace.addTripleClickListener = function(el, callback) -{ - ace.addListener(el, "mousedown", function() { - ace.autoremoveListener(el, "mousedown", function() { - ace.autoremoveListener(el, "mousedown", callback, 300); - }, 300); - }); +ace.addTripleClickListener = function(el, callback) { + ace.addListener(el, "mousedown", function() { + ace.autoremoveListener(el, "mousedown", function() { + ace.autoremoveListener(el, "mousedown", callback, 300); + }, 300); + }); } })(); \ No newline at end of file