rename "src" to "lib"

This commit is contained in:
Fabian Jakobs 2010-10-27 13:11:21 +02:00
commit 58494e088c
76 changed files with 3 additions and 3 deletions

View file

@ -0,0 +1,132 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/BackgroundTokenizer", ["ace/lib/oop", "ace/MEventEmitter"], function(oop, MEventEmitter) {
var BackgroundTokenizer = function(tokenizer, editor) {
this.running = false;
this.textLines = [];
this.lines = [];
this.currentLine = 0;
this.tokenizer = tokenizer;
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;
var lastVisibleRow = editor.getLastVisibleRow();
while (self.currentLine < textLines.length) {
self.lines[self.currentLine] = self.$tokenizeRows(self.currentLine, self.currentLine)[0];
self.currentLine++;
// only check every 5 lines
processedLines += 1;
if ((processedLines % 5 == 0) && (new Date() - workerStart) > 20) {
self.fireUpdateEvent(startLine, self.currentLine-1);
var timeout = self.currentLine < lastVisibleRow ? 20 : 100;
self.running = setTimeout(self.$worker, timeout);
return;
}
}
self.running = false;
self.fireUpdateEvent(startLine, textLines.length - 1);
};
};
(function(){
oop.implement(this, MEventEmitter);
this.setTokenizer = function(tokenizer) {
this.tokenizer = tokenizer;
this.lines = [];
this.start(0);
};
this.setLines = function(textLines) {
this.textLines = textLines;
this.lines = [];
this.stop();
};
this.fireUpdateEvent = function(firstRow, lastRow) {
var data = {
first: firstRow,
last: lastRow
};
this.$dispatchEvent("update", {data: data});
};
this.start = function(startRow) {
this.currentLine = Math.min(startRow || 0, this.currentLine,
this.textLines.length);
// remove all cached items below this line
this.lines.splice(this.currentLine, this.lines.length);
this.stop();
// pretty long delay to prevent the tokenizer from interfering with the user
this.running = setTimeout(this.$worker, 700);
};
this.stop = function() {
if (this.running)
clearTimeout(this.running);
this.running = false;
};
this.getTokens = function(firstRow, lastRow, callback) {
callback(this.$tokenizeRows(firstRow, lastRow));
};
this.getState = function(row, callback) {
callback(this.$tokenizeRows(row, row)[0].state);
};
this.$tokenizeRows = function(firstRow, lastRow) {
var rows = [];
// determine start state
var state = "start";
var doCache = false;
if (firstRow > 0 && this.lines[firstRow - 1]) {
state = this.lines[firstRow - 1].state;
doCache = true;
}
for (var row=firstRow; row<=lastRow; row++) {
if (!this.lines[row]) {
var tokens = this.tokenizer.getLineTokens(this.textLines[row] || "", state);
var state = tokens.state;
rows.push(tokens);
if (doCache) {
this.lines[row] = tokens;
}
}
else
rows.push(this.lines[row]);
}
return rows;
};
}).call(BackgroundTokenizer.prototype);
return BackgroundTokenizer;
});

687
lib/ace/Document.js Normal file
View file

@ -0,0 +1,687 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/Document",
[
"ace/lib/oop",
"ace/lib/lang",
"ace/MEventEmitter",
"ace/Selection",
"ace/mode/Text",
"ace/Range"
], function(oop, lang, MEventEmitter, Selection, TextMode, Range) {
var Document = function(text, mode) {
this.modified = true;
this.lines = [];
this.selection = new Selection(this);
this.$breakpoints = [];
this.listeners = [];
if (mode) {
this.setMode(mode);
}
if (lang.isArray(text)) {
this.$insertLines(0, text);
} else {
this.$insert({row: 0, column: 0}, text);
}
};
(function() {
oop.implement(this, MEventEmitter);
this.$undoManager = null;
this.$split = function(text) {
return text.split(/\r\n|\r|\n/);
};
this.setValue = function(text) {
var args = [0, this.lines.length];
args.push.apply(args, this.$split(text));
this.lines.splice.apply(this.lines, args);
this.modified = true;
this.fireChangeEvent(0);
};
this.toString = function() {
return this.lines.join(this.$getNewLineCharacter());
};
this.getSelection = function() {
return this.selection;
};
this.fireChangeEvent = function(firstRow, lastRow) {
var data = {
firstRow: firstRow,
lastRow: lastRow
};
this.$dispatchEvent("change", { data: data});
};
this.setUndoManager = function(undoManager) {
this.$undoManager = undoManager;
this.$deltas = [];
if (this.$informUndoManager) {
this.$informUndoManager.cancel();
}
if (undoManager) {
//undoManager.setDocument(this);
var self = this;
this.$informUndoManager = lang.deferredCall(function() {
if (self.$deltas.length > 0)
undoManager.execute({
action : "aceupdate",
args : [self.$deltas, self]
});
self.$deltas = [];
});
}
};
this.$defaultUndoManager = {
undo: function() {},
redo: function() {}
};
this.getUndoManager = function() {
return this.$undoManager || this.$defaultUndoManager;
},
this.getTabString = function() {
if (this.getUseSoftTabs()) {
return lang.stringRepeat(" ", this.getTabSize());
} else {
return "\t";
}
};
this.$useSoftTabs = true;
this.setUseSoftTabs = function(useSoftTabs) {
if (this.$useSoftTabs === useSoftTabs) return;
this.$useSoftTabs = useSoftTabs;
};
this.getUseSoftTabs = function() {
return this.$useSoftTabs;
};
this.$tabSize = 4;
this.setTabSize = function(tabSize) {
if (isNaN(tabSize) || this.$tabSize === tabSize) return;
this.modified = true;
this.$tabSize = tabSize;
this.$dispatchEvent("changeTabSize");
};
this.getTabSize = function() {
return this.$tabSize;
};
this.getBreakpoints = function() {
return this.$breakpoints;
};
this.setBreakpoints = function(rows) {
this.$breakpoints = [];
for (var i=0; i<rows.length; i++) {
this.$breakpoints[rows[i]] = true;
}
this.$dispatchEvent("changeBreakpoint", {});
};
this.clearBreakpoints = function() {
this.$breakpoints = [];
this.$dispatchEvent("changeBreakpoint", {});
};
this.setBreakpoint = function(row) {
this.$breakpoints[row] = true;
this.$dispatchEvent("changeBreakpoint", {});
};
this.clearBreakpoint = function(row) {
delete this.$breakpoints[row];
this.$dispatchEvent("changeBreakpoint", {});
};
this.$detectNewLine = function(text) {
var match = text.match(/^.*?(\r?\n)/m);
if (match) {
this.$autoNewLine = match[1];
} else {
this.$autoNewLine = "\n";
}
};
this.$getNewLineCharacter = function() {
switch (this.$newLineMode) {
case "windows":
return "\r\n";
case "unix":
return "\n";
case "auto":
return this.$autoNewLine;
}
},
this.$autoNewLine = "\n";
this.$newLineMode = "auto";
this.setNewLineMode = function(newLineMode) {
if (this.$newLineMode === newLineMode) return;
this.$newLineMode = newLineMode;
};
this.getNewLineMode = function() {
return this.$newLineMode;
};
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 TextMode();
}
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() {
this.$computeWidth();
return this.width;
};
this.getScreenWidth = function() {
this.$computeWidth();
return this.screenWith;
};
this.$computeWidth = function() {
if (this.modified) {
this.modified = false;
var lines = this.lines;
var longestLine = 0;
var longestScreenLine = 0;
var tabSize = this.getTabSize();
for ( var i = 0; i < lines.length; i++) {
var len = lines[i].length;
longestLine = Math.max(longestLine, len);
lines[i].replace("\t", function(m) {
len += tabSize-1;
return m;
});
longestScreenLine = Math.max(longestScreenLine, len);
}
this.width = longestLine;
this.screenWith = longestScreenLine;
}
};
/**
* Get a verbatim copy of the given line as it is in the document
*/
this.getLine = function(row) {
return this.lines[row] || "";
};
/**
* Get a line as it is displayed on screen. Tabs are replaced by spaces.
*/
this.getDisplayLine = function(row) {
var tab = new Array(this.getTabSize()+1).join(" ");
return this.lines[row].replace(/\t/g, tab);
};
this.getLines = function(firstRow, lastRow) {
return this.lines.slice(firstRow, lastRow+1);
};
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(this.$getNewLineCharacter());
}
};
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;
};
this.$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};
}
}
else if (char == bracket) {
depth +=1;
}
column += 1;
}
row +=1;
if (row >= lineCount) break;
var line = this.getLine(row);
var column = 0;
}
return null;
};
this.insert = function(position, text, fromUndo) {
var end = this.$insert(position, text, fromUndo);
this.fireChangeEvent(position.row, position.row == end.row ? position.row
: undefined);
return end;
};
this.$insertLines = function(row, lines, fromUndo) {
if (lines.length == 0)
return;
var args = [row, 0];
args.push.apply(args, lines);
this.lines.splice.apply(this.lines, args);
if (!fromUndo && this.$undoManager) {
var nl = this.$getNewLineCharacter();
this.$deltas.push({
action: "insertText",
range: new Range(row, 0, row + lines.length, 0),
text: lines.join(nl) + nl
});
this.$informUndoManager.schedule();
}
},
this.$insert = function(position, text, fromUndo) {
if (text.length == 0)
return position;
this.modified = true;
if (this.lines.length <= 1) {
this.$detectNewLine(text);
}
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));
var end = {
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);
var end = {
row : position.row,
column : position.column + text.length
};
}
else {
var line = this.lines[position.row] || "";
var firstLine = line.substring(0, position.column) + newLines[0];
var lastLine = newLines[newLines.length - 1] + line.substring(position.column);
this.lines[position.row] = firstLine;
this.$insertLines(position.row + 1, [lastLine], true);
if (newLines.length > 2) {
this.$insertLines(position.row + 1, newLines.slice(1, -1), true);
}
var end = {
row : position.row + newLines.length - 1,
column : newLines[newLines.length - 1].length
};
}
if (!fromUndo && this.$undoManager) {
this.$deltas.push({
action: "insertText",
range: Range.fromPoints(position, end),
text: text
});
this.$informUndoManager.schedule();
}
return end;
};
this.$isNewLine = function(text) {
return (text == "\r\n" || text == "\r" || text == "\n");
};
this.remove = function(range, fromUndo) {
if (range.isEmpty())
return range.start;
this.$remove(range, fromUndo);
this.fireChangeEvent(range.start.row,
!range.isMultiLine() ? range.start.row
: undefined);
return range.start;
};
this.$remove = function(range, fromUndo) {
if (range.isEmpty())
return;
if (!fromUndo && this.$undoManager) {
var nl = this.$getNewLineCharacter();
this.$deltas.push({
action: "removeText",
range: range.clone(),
text: this.getTextRange(range)
});
this.$informUndoManager.schedule();
}
this.modified = true;
var firstRow = range.start.row;
var lastRow = range.end.row;
var row = this.getLine(firstRow).substring(0, range.start.column)
+ this.getLine(lastRow).substring(range.end.column);
this.lines.splice(firstRow, lastRow - firstRow + 1, row);
return range.start;
};
this.undoChanges = function(deltas) {
this.selection.clearSelection();
for (var i=deltas.length-1; i>=0; i--) {
var delta = deltas[i];
if (delta.action == "insertText") {
this.remove(delta.range, true);
this.selection.moveCursorToPosition(delta.range.start);
} else {
this.insert(delta.range.start, delta.text, true);
this.selection.setSelectionRange(delta.range);
}
}
},
this.redoChanges = function(deltas) {
this.selection.clearSelection();
for (var i=0; i<deltas.length; i++) {
var delta = deltas[i];
if (delta.action == "insertText") {
this.insert(delta.range.start, delta.text, true);
this.selection.setSelectionRange(delta.range);
} else {
this.remove(delta.range, true);
this.selection.moveCursorToPosition(delta.range.start);
}
}
},
this.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;
};
this.indentRows = function(range, indentString) {
indentString.replace("\t", this.getTabString());
for (var row=range.start.row; row<=range.end.row; row++) {
this.$insert({row: row, column:0}, indentString);
}
this.fireChangeEvent(range.start.row, range.end.row);
return indentString.length;
};
this.outdentRows = function (range) {
var deleteRange = new Range(0, 0, 0, 0),
size = this.getTabSize();
for (var i = range.start.row; i <= range.end.row; ++i) {
var line = this.getLine(i);
deleteRange.start.row = i;
deleteRange.end.row = i;
for (var j = 0; j < size; ++j)
if (line.charAt(j) != ' ')
break;
if (j < size && line.charAt(j) == '\t') {
deleteRange.start.column = j;
deleteRange.end.column = j + 1;
} else {
deleteRange.start.column = 0;
deleteRange.end.column = j;
}
if (i == range.start.row)
range.start.column -= deleteRange.end.column - deleteRange.start.column;
if (i == range.end.row)
range.end.column -= deleteRange.end.column - deleteRange.start.column;
this.$remove(deleteRange);
}
this.fireChangeEvent(range.start.row, range.end.row);
return range;
}
this.moveLinesUp = function(firstRow, lastRow) {
if (firstRow <= 0) return 0;
var removed = this.lines.splice(firstRow, lastRow-firstRow+1);
this.$insertLines(firstRow-1, removed);
this.fireChangeEvent(firstRow-1, lastRow);
return -1;
};
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);
this.fireChangeEvent(firstRow, lastRow+1);
return 1;
};
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 addedRows = lastRow - firstRow + 1;
this.fireChangeEvent(firstRow);
return addedRows;
};
this.$clipRowToDocument = function(row) {
return Math.max(0, Math.min(row, this.lines.length-1));
};
this.documentToScreenColumn = function(row, docColumn) {
var tabSize = this.getTabSize();
var screenColumn = 0;
var remaining = docColumn;
var line = this.getLine(row).split("\t");
for (var i=0; i<line.length; i++) {
var len = line[i].length;
if (remaining > len) {
remaining -= (len + 1);
screenColumn += len + tabSize;
}
else {
screenColumn += remaining;
break;
}
}
return screenColumn;
};
this.screenToDocumentColumn = function(row, screenColumn) {
var tabSize = this.getTabSize();
var docColumn = 0;
var remaining = screenColumn;
var line = this.getLine(row).split("\t");
for (var i=0; i<line.length; i++) {
var len = line[i].length;
if (remaining >= len + tabSize) {
remaining -= (len + tabSize);
docColumn += (len + 1);
}
else if (remaining > len){
docColumn += len;
break;
}
else {
docColumn += remaining;
break;
}
}
return docColumn;
};
}).call(Document.prototype);
return Document;
});

985
lib/ace/Editor.js Normal file
View file

@ -0,0 +1,985 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/Editor",
[
"ace/lib/oop",
"ace/lib/event",
"ace/lib/lang",
"ace/TextInput",
"ace/KeyBinding",
"ace/Document",
"ace/Search",
"ace/BackgroundTokenizer",
"ace/Range",
"ace/MEventEmitter"
], function(oop, event, lang, TextInput, KeyBinding, Document, Search, BackgroundTokenizer, Range, MEventEmitter) {
var Editor = function(renderer, doc) {
var container = renderer.getContainerElement();
this.container = container;
this.renderer = renderer;
this.textInput = new TextInput(container, this);
this.keyBinding = new KeyBinding(container, this);
var self = this;
event.addListener(container, "mousedown", function(e) {
setTimeout(function() {self.focus();});
return event.preventDefault(e);
});
event.addListener(container, "selectstart", function(e) {
return event.preventDefault(e);
});
var mouseTarget = renderer.getMouseEventTarget();
event.addListener(mouseTarget, "mousedown", lang.bind(this.onMouseDown, this));
event.addMultiMouseDownListener(mouseTarget, 2, 500, lang.bind(this.onMouseDoubleClick, this));
event.addMultiMouseDownListener(mouseTarget, 3, 600, lang.bind(this.onMouseTripleClick, this));
event.addMouseWheelListener(mouseTarget, lang.bind(this.onMouseWheel, this));
this.$selectionMarker = null;
this.$highlightLineMarker = null;
this.$blockScrolling = false;
this.$search = new Search().set({
wrap: true
});
this.setDocument(doc || new Document(""));
this.focus();
};
(function(){
oop.implement(this, MEventEmitter);
this.$forwardEvents = {
gutterclick: 1,
gutterdblclick: 1
};
this.$originalAddEventListener = this.addEventListener;
this.$originalRemoveEventListener = this.removeEventListener;
this.addEventListener = function(eventName, callback) {
if (this.$forwardEvents[eventName]) {
return this.renderer.addEventListener(eventName, callback);
} else {
return this.$originalAddEventListener(eventName, callback);
}
};
this.removeEventListener = function(eventName, callback) {
if (this.$forwardEvents[eventName]) {
return this.renderer.removeEventListener(eventName, callback);
} else {
return this.$originalRemoveEventListener(eventName, callback);
}
};
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);
this.doc.removeEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint);
var selection = this.doc.getSelection();
selection.removeEventListener("changeCursor", this.$onCursorChange);
selection.removeEventListener("changeSelection", this.$onSelectionChange);
this.doc.setScrollTopRow(this.renderer.getScrollTopRow());
}
this.doc = doc;
this.$onDocumentChange = lang.bind(this.onDocumentChange, this);
doc.addEventListener("change", this.$onDocumentChange);
this.renderer.setDocument(doc);
this.$onDocumentModeChange = lang.bind(this.onDocumentModeChange, this);
doc.addEventListener("changeMode", this.$onDocumentModeChange);
this.$onDocumentChangeTabSize = lang.bind(this.renderer.updateText, this.renderer);
doc.addEventListener("changeTabSize", this.$onDocumentChangeTabSize);
this.$onDocumentChangeBreakpoint = lang.bind(this.onDocumentChangeBreakpoint, this);
this.doc.addEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint);
this.selection = doc.getSelection();
this.$desiredColumn = 0;
this.$onCursorChange = lang.bind(this.onCursorChange, this);
this.selection.addEventListener("changeCursor", this.$onCursorChange);
this.$onSelectionChange = lang.bind(this.onSelectionChange, this);
this.selection.addEventListener("changeSelection", this.$onSelectionChange);
this.onDocumentModeChange();
this.bgTokenizer.setLines(this.doc.lines);
this.bgTokenizer.start(0);
this.onCursorChange();
this.onSelectionChange();
this.onDocumentChangeBreakpoint();
this.renderer.scrollToRow(doc.getScrollTopRow());
this.renderer.updateFull();
};
this.getDocument = function() {
return this.doc;
};
this.getSelection = function() {
return this.selection;
};
this.resize = function() {
this.renderer.onResize();
};
this.setTheme = function(theme) {
this.renderer.setTheme(theme);
};
this.$highlightBrackets = function() {
if (this.$bracketHighlight) {
this.renderer.removeMarker(this.$bracketHighlight);
this.$bracketHighlight = null;
}
if (this.$highlightPending) {
return;
}
// perform highlight async to not block the browser during navigation
var self = this;
this.$highlightPending = true;
setTimeout(function() {
self.$highlightPending = false;
var pos = self.doc.findMatchingBracket(self.getCursorPosition());
if (pos) {
var range = new Range(pos.row, pos.column, pos.row, pos.column+1);
self.$bracketHighlight = self.renderer.addMarker(range, "ace_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);
// update cursor because tab characters can influence the cursor position
this.renderer.updateCursor(this.getCursorPosition(), this.$overwrite);
};
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(), this.$overwrite);
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.getSelectionStyle() != "line" || !this.selection.isMultiLine())) {
var cursor = this.getCursorPosition();
var range = new Range(cursor.row, 0, cursor.row+1, 0);
this.$highlightLineMarker = this.renderer.addMarker(range, "ace_active_line", "line");
}
};
this.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, "ace_selection", style);
}
this.onCursorChange();
};
this.onDocumentChangeBreakpoint = function() {
this.renderer.setBreakpoints(this.doc.getBreakpoints());
};
this.onDocumentModeChange = function() {
var mode = this.doc.getMode();
if (this.mode == mode)
return;
this.mode = mode;
var tokenizer = mode.getTokenizer();
if (!this.bgTokenizer) {
var onUpdate = lang.bind(this.onTokenizerUpdate, this);
this.bgTokenizer = new BackgroundTokenizer(tokenizer, this);
this.bgTokenizer.addEventListener("update", onUpdate);
} else {
this.bgTokenizer.setTokenizer(tokenizer);
}
this.renderer.setTokenizer(this.bgTokenizer);
};
this.onMouseDown = function(e) {
var pageX = event.getDocumentX(e);
var pageY = event.getDocumentY(e);
if (event.getButton(e) != 0)
return;
var pos = this.renderer.screenToTextCoordinates(pageX, pageY);
pos.row = Math.max(0, Math.min(pos.row, this.doc.getLength()-1));
if (e.shiftKey)
this.selection.selectToPosition(pos)
else {
this.moveCursorToPosition(pos);
if (!this.$clickSelection)
this.selection.clearSelection(pos.row, pos.column);
}
this.renderer.scrollCursorIntoView();
var self = this;
var mousePageX, mousePageY;
var onMouseSelection = function(e) {
mousePageX = event.getDocumentX(e);
mousePageY = event.getDocumentY(e);
};
var onMouseSelectionEnd = function() {
clearInterval(timerId);
self.$clickSelection = null;
};
var onSelectionInterval = function() {
if (mousePageX === undefined || mousePageY === undefined)
return;
var cursor = self.renderer.screenToTextCoordinates(mousePageX, mousePageY);
cursor.row = Math.max(0, Math.min(cursor.row, self.doc.getLength()-1));
if (self.$clickSelection) {
if (self.$clickSelection.contains(cursor.row, cursor.column)) {
self.selection.setSelectionRange(self.$clickSelection);
} else {
if (self.$clickSelection.compare(cursor.row, cursor.column) == -1) {
var anchor = self.$clickSelection.end;
} else {
var anchor = self.$clickSelection.start;
}
self.selection.setSelectionAnchor(anchor.row, anchor.column);
self.selection.selectToPosition(cursor);
}
}
else {
self.selection.selectToPosition(cursor);
}
self.renderer.scrollCursorIntoView();
};
event.capture(this.container, onMouseSelection, onMouseSelectionEnd);
var timerId = setInterval(onSelectionInterval, 20);
return event.preventDefault(e);
};
this.onMouseDoubleClick = function(e) {
this.selection.selectWord();
this.$clickSelection = this.getSelectionRange();
this.$updateDesiredColumn();
};
this.onMouseTripleClick = function(e) {
this.selection.selectLine();
this.$clickSelection = this.getSelectionRange();
this.$updateDesiredColumn();
};
this.onMouseWheel = function(e) {
var speed = this.$scrollSpeed * 2;
this.renderer.scrollBy(e.wheelX * speed, e.wheelY * speed);
return event.preventDefault(e);
};
this.getCopyText = function() {
if (!this.selection.isEmpty()) {
return this.doc.getTextRange(this.getSelectionRange());
}
else {
return "";
}
};
this.onCut = function() {
if (this.$readOnly)
return;
if (!this.selection.isEmpty()) {
this.moveCursorToPosition(this.doc.remove(this.getSelectionRange()));
this.clearSelection();
}
};
this.onTextInput = function(text) {
if (this.$readOnly)
return;
var cursor = this.getCursorPosition();
text = text.replace("\t", this.doc.getTabString());
// remove selected text
if (!this.selection.isEmpty()) {
var cursor = this.doc.remove(this.getSelectionRange());
this.clearSelection();
} else if (this.$overwrite){
var range = new Range.fromPoints(cursor, cursor);
range.end.column += text.length;
this.doc.remove(range);
}
this.clearSelection();
var _self = this;
var row = cursor.row;
this.bgTokenizer.getState(cursor.row-1, function (lineState) {
var shouldOutdent = _self.mode.checkOutdent(lineState, _self.doc.getLine(row), text);
var line = _self.doc.getLine(row);
var end = _self.doc.insert(cursor, text);
/* TODO: This shortcut is somehow broken
if (!shouldOutdent && line != _self.doc.getLine(row) && text != "\n") {
_self.moveCursorToPosition(end);
_self.renderer.scrollCursorIntoView();
return;
}
*/
var line = _self.doc.getLine(row);
_self.bgTokenizer.getState(row, function(lineState) {
// multi line insert
if (row !== end.row) {
var indent = _self.mode.getNextLineIndent(lineState, line, _self.doc.getTabString());
if (indent) {
var indentRange = new Range(row+1, 0, end.row, end.column);
end.column += _self.doc.indentRows(indentRange, indent);
}
} else {
if (shouldOutdent) {
end.column += _self.mode.autoOutdent(lineState, _self.doc, row);
}
}
_self.moveCursorToPosition(end);
_self.renderer.scrollCursorIntoView();
});
});
};
this.$overwrite = false;
this.setOverwrite = function(overwrite) {
if (this.$overwrite == overwrite) return;
this.$overwrite = overwrite;
this.$blockScrolling = true;
this.onCursorChange();
this.$blockScrolling = false;
this.$dispatchEvent("changeOverwrite", {data: overwrite});
};
this.getOverwrite = function() {
return this.$overwrite;
};
this.toggleOverwrite = function() {
this.setOverwrite(!this.$overwrite);
};
this.$scrollSpeed = 1;
this.setScrollSpeed = function(speed) {
this.$scrollSpeed = speed;
}
this.getScrollSpeed = function() {
return this.$scrollSpeed;
}
this.$selectionStyle = "line";
this.setSelectionStyle = function(style) {
if (this.$selectionStyle == style) return;
this.$selectionStyle = style;
this.onSelectionChange();
this.$dispatchEvent("changeSelectionStyle", {data: style});
};
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.setShowInvisibles = function(showInvisibles) {
if (this.getShowInvisibles() == showInvisibles)
return;
this.renderer.setShowInvisibles(showInvisibles);
};
this.getShowInvisibles = function() {
return this.renderer.getShowInvisibles();
};
this.setShowPrintMargin = function(showPrintMargin) {
this.renderer.setShowPrintMargin(showPrintMargin);
};
this.getShowPrintMargin = function() {
return this.renderer.getShowPrintMargin();
};
this.setPrintMarginColumn = function(showPrintMargin) {
this.renderer.setPrintMarginColumn(showPrintMargin);
};
this.getPrintMarginColumn = function() {
return this.renderer.getPrintMarginColumn();
};
this.$readOnly = false;
this.setReadOnly = function(readOnly) {
this.$readOnly = readOnly;
};
this.getReadOnly = function() {
return this.$readOnly;
};
this.removeRight = function() {
if (this.$readOnly)
return;
if (this.selection.isEmpty()) {
this.selection.selectRight();
}
this.moveCursorToPosition(this.doc.remove(this.getSelectionRange()));
this.clearSelection();
};
this.removeLeft = function() {
if (this.$readOnly)
return;
if (this.selection.isEmpty()) {
this.selection.selectLeft();
}
this.moveCursorToPosition(this.doc.remove(this.getSelectionRange()));
this.clearSelection();
};
this.indent = function() {
if (this.$readOnly)
return;
var range = this.getSelectionRange();
if (range.start.row < range.end.row ||
range.start.column < range.end.column) {
var count = this.doc.indentRows(this.getSelectionRange(), "\t");
this.selection.shiftSelection(count);
} else {
var indentString;
if (this.doc.getUseSoftTabs()) {
var size = this.doc.getTabSize(),
count = (size - this.getCursorPosition().column % size);
indentString = lang.stringRepeat(" ", count);
} else
indentString = "\t";
return this.onTextInput(indentString);
}
};
this.blockOutdent = function(indentString) {
if (this.$readOnly)
return;
var selection = this.doc.getSelection(),
range = this.doc.outdentRows(selection.getRange());
selection.setSelectionRange(range, selection.isBackwards());
this.$updateDesiredColumn();
};
this.toggleCommentLines = function() {
if (this.$readOnly)
return;
var rows = this.$getSelectedRows();
var range = new Range(rows.first, 0, rows.last, 0);
var _self = this;
this.bgTokenizer.getState(this.getCursorPosition().row, function(state) {
var addedColumns = _self.mode.toggleCommentLines(state, _self.doc, range);
_self.selection.shiftSelection(addedColumns);
});
};
this.removeLines = function() {
if (this.$readOnly)
return;
var rows = this.$getSelectedRows();
this.selection.setSelectionAnchor(rows.last+1, 0);
this.selection.selectTo(rows.first, 0);
this.doc.remove(this.getSelectionRange());
this.clearSelection();
};
this.moveLinesDown = function() {
if (this.$readOnly)
return;
this.$moveLines(function(firstRow, lastRow) {
return this.doc.moveLinesDown(firstRow, lastRow);
});
};
this.moveLinesUp = function() {
if (this.$readOnly)
return;
this.$moveLines(function(firstRow, lastRow) {
return this.doc.moveLinesUp(firstRow, lastRow);
});
};
this.copyLinesUp = function() {
if (this.$readOnly)
return;
this.$moveLines(function(firstRow, lastRow) {
this.doc.duplicateLines(firstRow, lastRow);
return 0;
});
};
this.copyLinesDown = function() {
if (this.$readOnly)
return;
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(text) {
this.renderer.showComposition(this.getCursorPosition());
//this.onTextInput(text);
};
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.selectPageDown = function() {
var row = this.getPageDownRow() + Math.floor(this.getVisibleRowCount() / 2);
this.scrollPageDown();
var selection = this.getSelection();
selection.$moveSelection(function() {
selection.moveCursorTo(row, selection.getSelectionLead().column);
});
};
this.selectPageUp = function() {
var visibleRows = this.getLastVisibleRow() - this.getFirstVisibleRow();
var row = this.getPageUpRow() + Math.round(visibleRows / 2);
this.scrollPageUp();
var selection = this.getSelection();
selection.$moveSelection(function() {
selection.moveCursorTo(row, selection.getSelectionLead().column);
});
};
this.gotoPageDown = function() {
console.log("Goto page down");
var row = this.getPageDownRow(),
column = Math.min(this.getCursorPosition().column,
this.doc.getLine(row).length);
this.scrollToRow(row);
this.getSelection().moveCursorTo(row, column);
};
this.gotoPageUp = function() {
console.log("Goto page up");
var row = this.getPageUpRow(),
column = Math.min(this.getCursorPosition().column,
this.doc.getLine(row).length);
this.scrollToRow(row);
this.getSelection().moveCursorTo(row, column);
};
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.$updateDesiredColumn();
};
this.moveCursorTo = function(row, column) {
this.selection.moveCursorTo(row, column);
this.$updateDesiredColumn();
};
this.moveCursorToPosition = function(pos) {
this.selection.moveCursorToPosition(pos);
this.$updateDesiredColumn();
};
this.gotoLine = function(lineNumber, row) {
this.selection.clearSelection();
this.$blockScrolling = true;
this.moveCursorTo(lineNumber-1, row || 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();
this.moveCursorTo(row, column);
this.$updateDesiredColumn(column);
};
this.navigateUp = function() {
this.selection.clearSelection();
this.selection.moveCursorBy(-1, 0);
if (this.$desiredColumn) {
var cursor = this.getCursorPosition();
var column = this.doc.screenToDocumentColumn(cursor.row, this.$desiredColumn);
this.selection.moveCursorTo(cursor.row, column);
}
};
this.navigateDown = function() {
this.selection.clearSelection();
this.selection.moveCursorBy(1, 0);
if (this.$desiredColumn) {
var cursor = this.getCursorPosition();
var column = this.doc.screenToDocumentColumn(cursor.row, this.$desiredColumn);
this.selection.moveCursorTo(cursor.row, column);
}
};
this.$updateDesiredColumn = function() {
var cursor = this.getCursorPosition();
this.$desiredColumn = this.doc.documentToScreenColumn(cursor.row, cursor.column);
};
this.navigateLeft = function() {
if (!this.selection.isEmpty()) {
var selectionStart = this.getSelectionRange().start;
this.moveCursorToPosition(selectionStart);
}
else {
this.selection.moveCursorLeft();
}
this.clearSelection();
};
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.selection.moveCursorLineStart();
this.clearSelection();
};
this.navigateLineEnd = function() {
this.selection.moveCursorLineEnd();
this.clearSelection();
};
this.navigateFileEnd = function() {
this.selection.moveCursorFileEnd();
this.clearSelection();
};
this.navigateFileStart = function() {
this.selection.moveCursorFileStart();
this.clearSelection();
};
this.navigateWordRight = function() {
this.selection.moveCursorWordRight();
this.clearSelection();
};
this.navigateWordLeft = function() {
this.selection.moveCursorWordLeft();
this.clearSelection();
};
this.replace = function(replacement, options) {
if (options)
this.$search.set(options);
var range = this.$tryReplace(this.getSelectionRange(), replacement);
if (range !== null)
this.selection.setSelectionRange(range);
this.$updateDesiredColumn();
},
this.replaceAll = function(replacement, options) {
if (options) {
console.log("Find " + options.needle);
this.$search.set(options);
}
console.log("Replace " + replacement);
this.clearSelection();
this.selection.moveCursorTo(0, 0);
var ranges = this.$search.findAll(this.doc);
if (!ranges.length)
return;
for (var i = ranges.length - 1; i >= 0; --i)
this.$tryReplace(ranges[i], replacement);
this.selection.setSelectionRange(ranges[0]);
this.$updateDesiredColumn();
},
this.$tryReplace = function(range, replacement) {
var input = this.doc.getTextRange(range);
var replacement = this.$search.replace(input, replacement);
if (replacement !== null) {
range.end = this.doc.replace(range, replacement);
return range;
} else {
return null;
}
};
this.getLastSearchOptions = function() {
return this.$search.getOptions();
};
this.find = function(needle, options) {
this.clearSelection();
options = options || {};
options.needle = needle;
this.$search.set(options);
this.$find();
},
this.findNext = function(options) {
options = options || {};
if (typeof options.backwards == "undefined")
options.backwards = false;
this.$search.set(options);
this.$find();
};
this.findPrevious = function(options) {
options = options || {};
if (typeof options.backwards == "undefined")
options.backwards = true;
this.$search.set(options);
this.$find();
};
this.$find = function(backwards) {
if (!this.selection.isEmpty()) {
this.$search.set({needle: this.doc.getTextRange(this.getSelectionRange())});
}
if (typeof backwards != "undefined")
this.$search.set({backwards: backwards});
var range = this.$search.find(this.doc);
if (range) {
this.gotoLine(range.end.row+1, range.end.column);
this.$updateDesiredColumn();
this.selection.setSelectionRange(range);
}
};
this.undo = function() {
this.doc.getUndoManager().undo();
};
this.redo = function() {
this.doc.getUndoManager().redo();
};
}).call(Editor.prototype);
return Editor;
});

123
lib/ace/KeyBinding.js Normal file
View file

@ -0,0 +1,123 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/KeyBinding",
["ace/lib/core",
"ace/lib/event",
"ace/conf/keybindings/default_mac",
"ace/conf/keybindings/default_win",
"ace/PluginManager",
"ace/commands/DefaultCommands"],
function(core, event, default_mac, default_win, PluginManager) {
var KeyBinding = function(element, editor, config) {
this.setConfig(config);
var _self = this;
event.addKeyListener(element, function(e) {
var hashId = 0 | (e.ctrlKey ? 1 : 0) | (e.altKey ? 2 : 0)
| (e.shiftKey ? 4 : 0) | (e.metaKey ? 8 : 0);
var key = _self.keyNames[e.keyCode];
var commandName = (_self.config.reverse[hashId] || {})[(key
|| String.fromCharCode(e.keyCode)).toLowerCase()];
var command = PluginManager.commands[commandName];
if (command) {
command(editor, editor.getSelection());
return event.stopEvent(e);
}
});
};
(function() {
this.keyMods = {"ctrl": 1, "alt": 2, "option" : 2, "shift": 4, "meta": 8, "command": 8};
this.keyNames = {
"8" : "Backspace",
"9" : "Tab",
"13" : "Enter",
"27" : "Esc",
"32" : "Space",
"33" : "PageUp",
"34" : "PageDown",
"35" : "End",
"36" : "Home",
"37" : "Left",
"38" : "Up",
"39" : "Right",
"40" : "Down",
"45" : "Insert",
"46" : "Delete",
"107": "+",
"112": "F1",
"113": "F2",
"114": "F3",
"115": "F4",
"116": "F5",
"117": "F6",
"118": "F7",
"119": "F8",
"120": "F9",
"121": "F10",
"122": "F11",
"123": "F12"
};
function splitSafe(s, separator, limit, bLowerCase) {
return (bLowerCase && s.toLowerCase() || s)
.replace(/(?:^\s+|\n|\s+$)/g, "")
.split(new RegExp("[\\s ]*" + separator + "[\\s ]*", "g"), limit || 999);
}
function parseKeys(keys, val, ret) {
var key,
hashId = 0,
parts = splitSafe(keys, "\\-", null, true),
i = 0,
l = parts.length;
for (; i < l; ++i) {
if (this.keyMods[parts[i]])
hashId = hashId | this.keyMods[parts[i]];
else
key = parts[i] || "-"; //when empty, the splitSafe removed a '-'
}
(ret[hashId] || (ret[hashId] = {}))[key] = val;
return ret;
}
function objectReverse(obj, keySplit) {
var i, j, l, key,
ret = {};
for (i in obj) {
key = obj[i];
if (keySplit && typeof key == "string") {
key = key.split(keySplit);
for (j = 0, l = key.length; j < l; ++j)
parseKeys.call(this, key[j], i, ret);
}
else {
parseKeys.call(this, key, i, ret);
}
}
return ret;
}
this.setConfig = function(config) {
this.config = config || (core.isMac
? default_mac
: default_win);
if (typeof this.config.reverse == "undefined")
this.config.reverse = objectReverse.call(this, this.config, "|");
};
}).call(KeyBinding.prototype);
return KeyBinding;
});

56
lib/ace/MEventEmitter.js Normal file
View file

@ -0,0 +1,56 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
if (!require.def) require.def = require("requireJS-node")(module);
require.def("ace/MEventEmitter", ["ace/lib/lang"], function(lang) {
var MEventEmitter = {}
MEventEmitter.$dispatchEvent = function(eventName, e) {
this.$eventRegistry = this.$eventRegistry || {};
var listeners = this.$eventRegistry[eventName];
if (!listeners || !listeners.length) return;
var e = e || {};
e.type = eventName;
for (var i=0; i<listeners.length; i++) {
listeners[i](e);
}
};
MEventEmitter.on =
MEventEmitter.addEventListener = function(eventName, callback) {
this.$eventRegistry = this.$eventRegistry || {};
var listeners = this.$eventRegistry[eventName];
if (!listeners) {
var listeners = this.$eventRegistry[eventName] = [];
}
if (lang.arrayIndexOf(listeners, callback) == -1) {
listeners.push(callback);
}
};
MEventEmitter.removeEventListener = function(eventName, callback) {
this.$eventRegistry = this.$eventRegistry || {};
var listeners = this.$eventRegistry[eventName];
if (!listeners) {
return;
}
var index = lang.arrayIndexOf(listeners, callback);
if (index !== -1) {
listeners.splice(index, 1);
}
};
return MEventEmitter;
});

19
lib/ace/PluginManager.js Normal file
View file

@ -0,0 +1,19 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/PluginManager", [], function() {
var PluginManager = {
commands : {},
registerCommand : function(name, command) {
this.commands[name] = command;
}
};
return PluginManager;
});

126
lib/ace/Range.js Normal file
View file

@ -0,0 +1,126 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/Range", function() {
var Range = function(startRow, startColumn, endRow, endColumn) {
this.start = {
row: startRow,
column: startColumn
};
this.end = {
row: endRow,
column: endColumn
};
};
(function() {
this.toString = function() {
return ("Range: [" + this.start.row + "/" + this.start.column +
"] -> [" + this.end.row + "/" + this.end.column + "]");
};
this.contains = function(row, column) {
return this.compare(row, column) == 0;
};
this.compare = function(row, column) {
if (!this.isMultiLine()) {
if (row === this.start.row) {
return column < this.start.column ? -1 : (column > this.end.column ? 1 : 0);
};
}
if (row < this.start.row)
return -1;
if (row > this.end.row)
return 1;
if (this.start.row === row)
return column >= this.start.column ? 0 : -1;
if (this.end.row === row)
return column <= this.end.column ? 0 : 1;
return 0;
};
this.clipRows = function(firstRow, lastRow) {
if (this.end.row > lastRow) {
var end = {
row: lastRow+1,
column: 0
};
}
if (this.start.row > lastRow) {
var start = {
row: lastRow+1,
column: 0
};
}
if (this.start.row < firstRow) {
var start = {
row: firstRow,
column: 0
};
}
if (this.end.row < firstRow) {
var end = {
row: firstRow,
column: 0
};
}
return Range.fromPoints(start || this.start, end || this.end);
};
this.extend = function(row, column) {
var cmp = this.compare(row, column);
if (cmp == 0)
return this;
else if (cmp == -1)
var start = {row: row, column: column};
else
var end = {row: row, column: column};
return Range.fromPoints(start || this.start, end || this.end);
};
this.isEmpty = function() {
return (this.start.row == this.end.row && this.start.column == this.end.column);
};
this.isMultiLine = function() {
return (this.start.row !== this.end.row);
};
this.clone = function() {
return Range.fromPoints(this.start, this.end);
};
this.toScreenRange = function(doc) {
return new Range(
this.start.row, doc.documentToScreenColumn(this.start.row, this.start.column),
this.end.row, doc.documentToScreenColumn(this.end.row, this.end.column)
);
};
}).call(Range.prototype);
Range.fromPoints = function(start, end) {
return new Range(start.row, start.column, end.row, end.column);
};
return Range;
})

60
lib/ace/RenderLoop.js Normal file
View file

@ -0,0 +1,60 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/RenderLoop", function() {
var RenderLoop = function(onRender) {
this.onRender = onRender;
this.pending = false;
this.changes = 0;
};
(function() {
this.schedule = function(change) {
this.changes = this.changes | change;
if (!this.pending) {
this.pending = true;
var _self = this;
this.setTimeoutZero(function() {
_self.pending = false;
_self.onRender(_self.changes);
_self.changes = 0;
})
}
};
if (window.postMessage) {
this.messageName = "zero-timeout-message";
this.setTimeoutZero = function(callback) {
if (!this.attached) {
var _self = this;
window.addEventListener("message", function(e) {
if (e.source == window && _self.callback && e.data == _self.messageName) {
e.stopPropagation();
_self.callback();
}
}, false);
this.attached = true;
}
this.callback = callback;
window.postMessage(this.messageName, "*");
}
} else {
this.setTimeoutZero = function(callback) {
setTimeout(callback, 0);
}
}
}).call(RenderLoop.prototype);
return RenderLoop;
});

57
lib/ace/ScrollBar.js Normal file
View file

@ -0,0 +1,57 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/ScrollBar", [
"ace/lib/oop",
"ace/lib/lang",
"ace/lib/dom",
"ace/lib/event",
"ace/MEventEmitter"
], function(oop, lang, dom, event, MEventEmitter) {
var ScrollBar = function(parent) {
this.element = document.createElement("div");
this.element.className = "ace_sb";
this.inner = document.createElement("div");
this.element.appendChild(this.inner);
parent.appendChild(this.element);
this.width = dom.scrollbarWidth();
this.element.style.width = this.width;
event.addListener(this.element, "scroll", lang.bind(this.onScroll, this));
};
(function() {
oop.implement(this, MEventEmitter);
this.onScroll = function() {
this.$dispatchEvent("scroll", {data: this.element.scrollTop});
};
this.getWidth = function() {
return this.width;
};
this.setHeight = function(height) {
this.element.style.height = Math.max(0, height - this.width) + "px";
};
this.setInnerHeight = function(height) {
this.inner.style.height = height + "px";
};
this.setScrollTop = function(scrollTop) {
this.element.scrollTop = scrollTop;
};
}).call(ScrollBar.prototype);
return ScrollBar;
});

291
lib/ace/Search.js Normal file
View file

@ -0,0 +1,291 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/Search",
["ace/lib/lang",
"ace/lib/oop",
"ace/Range"],
function(lang, oop, Range) {
var Search = function() {
this.$options = {
needle: "",
backwards: false,
wrap: false,
caseSensitive: false,
wholeWord: false,
scope: Search.ALL,
regExp: false
};
};
Search.ALL = 1;
Search.SELECTION = 2;
(function() {
this.set = function(options) {
oop.mixin(this.$options, options);
return this;
};
this.getOptions = function() {
return lang.copyObject(this.$options);
};
this.find = function(doc) {
if (!this.$options.needle)
return null;
if (this.$options.backwards) {
var iterator = this.$backwardMatchIterator(doc);
} else {
iterator = this.$forwardMatchIterator(doc);
}
var firstRange = null;
iterator.forEach(function(range) {
firstRange = range;
return true;
});
return firstRange;
};
this.findAll = function(doc) {
if (!this.$options.needle)
return [];
if (this.$options.backwards) {
var iterator = this.$backwardMatchIterator(doc);
} else {
iterator = this.$forwardMatchIterator(doc);
}
var ranges = [];
iterator.forEach(function(range) {
ranges.push(range);
});
return ranges;
};
this.replace = function(input, replacement) {
var re = this.$assembleRegExp();
var match = re.exec(input);
if (match && match[0].length == input.length) {
if (this.$options.regExp) {
return input.replace(re, replacement);
} else {
return replacement;
}
} else {
return null;
}
};
this.$forwardMatchIterator = function(doc) {
var re = this.$assembleRegExp();
var self = this;
return {
forEach: function(callback) {
self.$forwardLineIterator(doc).forEach(function(line, startIndex, row) {
if (startIndex) {
line = line.substring(startIndex);
}
var matches = [];
line.replace(re, function(str) {
var offset = arguments[arguments.length-2];
matches.push({
str: str,
offset: startIndex + offset
});
return str;
});
for (var i=0; i<matches.length; i++) {
var match = matches[i];
var range = self.$rangeFromMatch(row, match.offset, match.str.length);
if (callback(range))
return true;
}
});
}
};
};
this.$backwardMatchIterator = function(doc) {
var re = this.$assembleRegExp();
var self = this;
return {
forEach: function(callback) {
self.$backwardLineIterator(doc).forEach(function(line, startIndex, row) {
if (startIndex) {
line = line.substring(startIndex);
}
var matches = [];
line.replace(re, function(str, offset) {
matches.push({
str: str,
offset: startIndex + offset
});
return str;
});
for (var i=matches.length-1; i>= 0; i--) {
var match = matches[i];
var range = self.$rangeFromMatch(row, match.offset, match.str.length);
if (callback(range))
return true;
}
});
}
};
};
this.$rangeFromMatch = function(row, column, length) {
return new Range(row, column, row, column+length);
};
this.$assembleRegExp = function() {
if (this.$options.regExp) {
var needle = this.$options.needle;
} else {
needle = lang.escapeRegExp(this.$options.needle);
}
if (this.$options.wholeWord) {
needle = "\\b" + needle + "\\b";
}
var modifier = "g";
if (!this.$options.caseSensitive) {
modifier += "i";
}
var re = new RegExp(needle, modifier);
return re;
};
this.$forwardLineIterator = function(doc) {
var searchSelection = this.$options.scope == Search.SELECTION;
var range = doc.getSelection().getRange();
var start = doc.getSelection().getCursor();
var firstRow = searchSelection ? range.start.row : 0;
var firstColumn = searchSelection ? range.start.column : 0;
var lastRow = searchSelection ? range.end.row : doc.getLength() - 1;
var wrap = this.$options.wrap;
function getLine(row) {
var line = doc.getLine(row);
if (searchSelection && row == range.end.row) {
line = line.substring(0, range.end.column);
}
return line;
}
return {
forEach: function(callback) {
var row = start.row;
var line = getLine(row);
var startIndex = start.column;
var stop = false;
while (!callback(line, startIndex, row)) {
if (stop) {
return;
}
row++;
startIndex = 0;
if (row > lastRow) {
if (wrap) {
row = firstRow;
startIndex = firstColumn;
} else {
return;
}
}
if (row == start.row)
stop = true;
line = getLine(row);
}
}
};
};
this.$backwardLineIterator = function(doc) {
var searchSelection = this.$options.scope == Search.SELECTION;
var range = doc.getSelection().getRange();
var start = searchSelection ? range.end : range.start;
var firstRow = searchSelection ? range.start.row : 0;
var firstColumn = searchSelection ? range.start.column : 0;
var lastRow = searchSelection ? range.end.row : doc.getLength() - 1;
var wrap = this.$options.wrap;
return {
forEach : function(callback) {
var row = start.row;
var line = doc.getLine(row).substring(0, start.column);
var startIndex = 0;
var stop = false;
while (!callback(line, startIndex, row)) {
if (stop)
return;
row--;
startIndex = 0;
if (row < firstRow) {
if (wrap) {
row = lastRow;
} else {
return;
}
}
if (row == start.row)
stop = true;
line = doc.getLine(row);
if (searchSelection) {
if (row == firstRow)
startIndex = firstColumn;
else if (row == lastRow)
line = line.substring(0, range.end.column);
}
}
}
};
};
}).call(Search.prototype);
return Search;
});

417
lib/ace/Selection.js Normal file
View file

@ -0,0 +1,417 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/Selection", [
"ace/lib/oop",
"ace/lib/lang",
"ace/MEventEmitter",
"ace/Range"
], function(oop, lang, MEventEmitter, Range) {
var Selection = function(doc) {
this.doc = doc;
this.clearSelection();
this.selectionLead = {
row: 0,
column: 0
};
};
(function() {
oop.implement(this, MEventEmitter);
this.isEmpty = function() {
return (!this.selectionAnchor ||
(this.selectionAnchor.row == this.selectionLead.row &&
this.selectionAnchor.column == this.selectionLead.column));
};
this.isMultiLine = function() {
if (this.isEmpty()) {
return false;
}
return this.getRange().isMultiLine();
};
this.getCursor = function() {
return this.selectionLead;
};
this.setSelectionAnchor = function(row, column) {
var anchor = this.$clipPositionToDocument(row, column);
if (!this.selectionAnchor) {
this.selectionAnchor = anchor;
this.$dispatchEvent("changeSelection", {});
}
else if (this.selectionAnchor.row !== anchor.row || this.selectionAnchor.column !== anchor.column) {
this.selectionAnchor = anchor;
this.$dispatchEvent("changeSelection", {});
}
};
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);
};
this.shiftSelection = function(columns) {
if (this.isEmpty()) {
this.moveCursorTo(this.selectionLead.row, this.selectionLead.column + columns);
return;
};
var anchor = this.getSelectionAnchor();
var lead = this.getSelectionLead();
var isBackwards = this.isBackwards();
if (!isBackwards || anchor.column !== 0)
this.setSelectionAnchor(anchor.row, anchor.column + columns);
if (isBackwards || lead.column !== 0) {
this.$moveSelection(function() {
this.moveCursorTo(lead.row, lead.column + columns);
});
}
};
this.isBackwards = function() {
var anchor = this.selectionAnchor || this.selectionLead;
var lead = this.selectionLead;
return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column));
};
this.getRange = function() {
var anchor = this.selectionAnchor || this.selectionLead;
var lead = this.selectionLead;
if (this.isBackwards()) {
return Range.fromPoints(lead, anchor);
}
else {
return Range.fromPoints(anchor, lead);
}
};
this.clearSelection = function() {
if (this.selectionAnchor) {
this.selectionAnchor = null;
this.$dispatchEvent("changeSelection", {});
}
};
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.setSelectionRange = function(range, reverse) {
if (reverse) {
this.setSelectionAnchor(range.end.row, range.end.column);
this.selectTo(range.start.row, range.start.column);
} else {
this.setSelectionAnchor(range.start.row, range.start.column);
this.selectTo(range.end.row, range.end.column);
}
};
this.$moveSelection = function(mover) {
var changed = false;
if (!this.selectionAnchor) {
changed = true;
this.selectionAnchor = this.$clone(this.selectionLead);
}
var cursor = this.$clone(this.selectionLead);
mover.call(this);
if (cursor.row !== this.selectionLead.row || cursor.column !== this.selectionLead.column) {
changed = true;
}
if (changed)
this.$dispatchEvent("changeSelection", {});
};
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.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);
});
};
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() {
var row = this.selectionLead.row;
var column = this.selectionLead.column;
var beforeCursor = this.doc.getLine(row).slice(0, column);
var leadingSpace = beforeCursor.match(/^\s+/);
if (!leadingSpace || leadingSpace[0].length >= column)
this.moveCursorTo(this.selectionLead.row, 0);
else
this.moveCursorTo(this.selectionLead.row, leadingSpace[0].length);
};
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 = lang.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) {
var cursor = this.$clipPositionToDocument(row, column);
// only dispatch change if the cursor actually changed
if (cursor.row !== this.selectionLead.row || cursor.column !== this.selectionLead.column) {
this.selectionLead = cursor;
this.$dispatchEvent("changeCursor", { data: this.getCursor() });
}
};
this.moveCursorUp = function() {
this.moveCursorBy(-1, 0);
};
this.$clipPositionToDocument = function(row, column) {
var pos = {};
if (row >= this.doc.getLength()) {
pos.row = Math.max(0, 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(Selection.prototype);
return Selection;
});

118
lib/ace/TextInput.js Normal file
View file

@ -0,0 +1,118 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/TextInput", ["ace/lib/event"], function(event) {
var 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 PLACEHOLDER = String.fromCharCode(0);
sendText();
var inCompostion = false;
var copied = false;
function sendText() {
if (!copied) {
var value = text.value;
if (value) {
if (value.charCodeAt(value.length-1) == PLACEHOLDER.charCodeAt(0)) {
value = value.slice(0, -1);
if (value)
host.onTextInput(value);
} else
host.onTextInput(value);
}
}
copied = false;
// Safari doesn't fire copy events if no text is selected
text.value = PLACEHOLDER;
text.select();
}
var onTextInput = function(e) {
setTimeout(function() {
if (!inCompostion)
sendText();
}, 0);
};
var onCompositionStart = function(e) {
inCompostion = true;
sendText();
text.value = "";
host.onCompositionStart();
setTimeout(onCompositionUpdate, 0);
};
var onCompositionUpdate = function() {
host.onCompositionUpdate(text.value);
};
var onCompositionEnd = function() {
inCompostion = false;
host.onCompositionEnd();
onTextInput();
};
var onCopy = function() {
copied = true;
text.value = host.getCopyText();
text.select();
copied = true;
setTimeout(sendText, 0);
};
var onCut = function() {
copied = true;
text.value = host.getCopyText();
host.onCut();
text.select();
setTimeout(sendText, 0);
};
event.addListener(text, "keypress", onTextInput);
event.addListener(text, "textInput", onTextInput);
event.addListener(text, "paste", onTextInput);
event.addListener(text, "propertychange", onTextInput);
event.addListener(text, "copy", onCopy);
event.addListener(text, "cut", onCut);
event.addListener(text, "compositionstart", onCompositionStart);
event.addListener(text, "compositionupdate", onCompositionUpdate);
event.addListener(text, "compositionend", onCompositionEnd);
event.addListener(text, "blur", function() {
host.onBlur();
});
event.addListener(text, "focus", function() {
host.onFocus();
text.select();
});
this.focus = function() {
host.onFocus();
text.select();
text.focus();
};
this.blur = function() {
text.blur();
};
};
return TextInput;
});

102
lib/ace/Tokenizer.js Normal file
View file

@ -0,0 +1,102 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/Tokenizer", [], function() {
var 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");
}
};
(function() {
this.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;
var token = {
type: null,
value: ""
};
while (match = re.exec(line)) {
var type = "text";
var value = match[0];
if (re.lastIndex == lastIndex) { throw new Error("tokenizer error"); }
lastIndex = re.lastIndex;
window.LOG && 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 (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 && console.log(tokens, currentState);
return {
tokens : tokens,
state : currentState
};
};
}).call(Tokenizer.prototype);
return Tokenizer;
});

47
lib/ace/UndoManager.js Normal file
View file

@ -0,0 +1,47 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/UndoManager", function() {
var UndoManager = function() {
this.$undoStack = [];
this.$redoStack = [];
};
(function() {
/*this.$doc = null;
this.setDocument = function(doc) {
this.$doc = doc;
};*/
this.execute = function(options) {
var deltas = options.args[0];
this.$doc = options.args[1];
this.$undoStack.push(deltas);
};
this.undo = function() {
var deltas = this.$undoStack.pop();
if (deltas) {
this.$doc.undoChanges(deltas);
this.$redoStack.push(deltas);
}
};
this.redo = function() {
var deltas = this.$redoStack.pop();
if (deltas) {
this.$doc.redoChanges(deltas);
this.$undoStack.push(deltas);
}
};
}).call(UndoManager.prototype);
return UndoManager;
});

569
lib/ace/VirtualRenderer.js Normal file
View file

@ -0,0 +1,569 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/VirtualRenderer",
[
"ace/lib/oop",
"ace/lib/lang",
"ace/lib/dom",
"ace/lib/event",
"ace/layer/Gutter",
"ace/layer/Marker",
"ace/layer/Text",
"ace/layer/Cursor",
"ace/ScrollBar",
"ace/RenderLoop",
"ace/MEventEmitter",
"text!ace/css/editor.css"
], function(
oop, lang, dom, event, GutterLayer, MarkerLayer, TextLayer,
CursorLayer, ScrollBar, RenderLoop, MEventEmitter, editorCss) {
// import CSS once
dom.importCssString(editorCss);
var VirtualRenderer = function(container, theme) {
this.container = container;
dom.addCssClass(this.container, "ace_editor");
this.setTheme(theme);
this.scroller = document.createElement("div");
this.scroller.className = "ace_scroller";
this.container.appendChild(this.scroller);
this.$gutter = document.createElement("div");
this.$gutter.className = "ace_gutter";
this.container.appendChild(this.$gutter);
this.content = document.createElement("div");
this.content.style.position = "absolute";
this.scroller.appendChild(this.content);
this.$gutterLayer = new GutterLayer(this.$gutter);
this.$markerLayer = new MarkerLayer(this.content);
var textLayer = this.$textLayer = new TextLayer(this.content);
this.canvas = textLayer.element;
this.characterWidth = textLayer.getCharacterWidth();
this.lineHeight = textLayer.getLineHeight();
this.$cursorLayer = new CursorLayer(this.content);
this.layers = [ this.$markerLayer, textLayer, this.$cursorLayer ];
this.scrollBar = new ScrollBar(container);
this.scrollBar.addEventListener("scroll", lang.bind(this.onScroll, this));
this.scrollTop = 0;
this.cursorPos = {
row : 0,
column : 0
};
var self = this;
this.$textLayer.addEventListener("changeCharaterSize", function() {
self.characterWidth = textLayer.getCharacterWidth();
self.lineHeight = textLayer.getLineHeight();
self.$loop.schedule(self.CHANGE_FULL);
});
event.addListener(this.$gutter, "click", lang.bind(this.$onGutterClick, this));
event.addListener(this.$gutter, "dblclick", lang.bind(this.$onGutterClick, this));
this.$size = {
width: 0,
height: 0,
scrollerHeight: 0,
scrollerWidth: 0
};
this.$updatePrintMargin();
this.$loop = new RenderLoop(lang.bind(this.$renderChanges, this));
this.$loop.schedule(this.CHANGE_FULL);
};
(function() {
this.CHANGE_CURSOR = 1;
this.CHANGE_MARKER = 2;
this.CHANGE_GUTTER = 4;
this.CHANGE_SCROLL = 8;
this.CHANGE_LINES = 16;
this.CHANGE_TEXT = 32;
this.CHANGE_SIZE = 64;
this.CHANGE_FULL = 128;
oop.implement(this, MEventEmitter);
this.setDocument = function(doc) {
this.lines = doc.lines;
this.doc = doc;
this.$cursorLayer.setDocument(doc);
this.$markerLayer.setDocument(doc);
this.$textLayer.setDocument(doc);
this.$loop.schedule(this.CHANGE_FULL);
};
/**
* Triggers partial update of the text layer
*/
this.updateLines = function(firstRow, lastRow) {
if (!this.$changedLines) {
this.$changedLines = {
firstRow: firstRow,
lastRow: lastRow
};
}
else {
if (this.$changedLines.firstRow > firstRow)
this.$changedLines.firstRow = firstRow;
if (this.$changedLines.lastRow < lastRow)
this.$changedLines.lastRow = lastRow;
}
if (this.$changedLines.lastRow === undefined)
this.$changedLines.lastRow = Infinity;
this.$loop.schedule(this.CHANGE_LINES);
};
/**
* Triggers full update of the text layer
*/
this.updateText = function() {
this.$loop.schedule(this.CHANGE_TEXT);
};
/**
* Triggers a full update of all layers
*/
this.updateFull = function() {
this.$loop.schedule(this.CHANGE_FULL);
};
/**
* Triggers resize of the editor
*/
this.onResize = function() {
this.$loop.schedule(this.CHANGE_SIZE);
var height = dom.getInnerHeight(this.container);
if (this.$size.height != height) {
this.$size.height = height;
this.scroller.style.height = height + "px";
this.scrollBar.setHeight(height);
if (this.doc) {
this.scrollToY(this.getScrollTop());
this.$loop.schedule(this.CHANGE_FULL);
}
}
var width = dom.getInnerWidth(this.container);
if (this.$size.width != width) {
this.$size.width = width;
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.$size.scrollerWidth = this.scroller.clientWidth;
this.$size.scrollerHeight = this.scroller.clientHeight;
};
this.setTokenizer = function(tokenizer) {
this.$textLayer.setTokenizer(tokenizer);
this.$loop.schedule(this.CHANGE_TEXT);
};
this.$onGutterClick = function(e) {
var pageX = event.getDocumentX(e);
var pageY = event.getDocumentY(e);
this.$dispatchEvent("gutter" + e.type, {
row: this.screenToTextCoordinates(pageX, pageY).row,
htmlEvent: e
});
};
this.$showInvisibles = true;
this.setShowInvisibles = function(showInvisibles) {
this.$showInvisibles = showInvisibles;
this.$textLayer.setShowInvisibles(showInvisibles);
this.$loop.schedule(this.CHANGE_TEXT);
};
this.getShowInvisibles = function() {
return this.$showInvisibles;
};
this.$showPrintMargin = true;
this.setShowPrintMargin = function(showPrintMargin) {
this.$showPrintMargin = showPrintMargin;
this.$updatePrintMargin();
};
this.getShowPrintMargin = function() {
return this.$showPrintMargin;
};
this.$printMarginColumn = 80;
this.setPrintMarginColumn = function(showPrintMargin) {
this.$printMarginColumn = showPrintMargin;
this.$updatePrintMargin();
};
this.getPrintMarginColumn = function() {
return this.$printMarginColumn;
};
this.$updatePrintMargin = function() {
if (!this.$showPrintMargin && !this.$printMarginEl)
return;
if (!this.$printMarginEl) {
this.$printMarginEl = document.createElement("div");
this.$printMarginEl.className = "ace_printMargin";
this.content.insertBefore(this.$printMarginEl, this.$textLayer.element);
}
var style = this.$printMarginEl.style;
style.left = (this.characterWidth * this.$printMarginColumn) + "px";
style.visibility = this.$showPrintMargin ? "visible" : "hidden";
};
this.getContainerElement = function() {
return this.container;
};
this.getMouseEventTarget = function() {
return this.content;
};
this.getFirstVisibleRow = function() {
return (this.layerConfig || {}).firstRow || 0;
};
this.getLastVisibleRow = function() {
return (this.layerConfig || {}).lastRow || 0;
};
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.$renderChanges = function(changes) {
if (!changes)
return;
// text, scrolling and resize changes can cause the view port size to change
if (!this.layerConfig ||
changes & this.CHANGE_FULL ||
changes & this.CHANGE_SIZE ||
changes & this.CHANGE_TEXT ||
changes & this.CHANGE_LINES ||
changes & this.CHANGE_SCROLL
)
this.$computeLayerConfig();
// full
if (changes & this.CHANGE_FULL) {
this.$textLayer.update(this.layerConfig);
this.$gutterLayer.update(this.layerConfig);
this.$markerLayer.update(this.layerConfig);
this.$cursorLayer.update(this.layerConfig);
this.$updateScrollBar();
return;
}
// scrolling
if (changes & this.CHANGE_SCROLL) {
if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES) {
this.$textLayer.scrollLines(this.layerConfig);
this.$gutterLayer.update(this.layerConfig);
this.$markerLayer.update(this.layerConfig);
this.$cursorLayer.update(this.layerConfig);
}
else {
this.$textLayer.update(this.layerConfig);
this.$gutterLayer.update(this.layerConfig);
this.$markerLayer.update(this.layerConfig);
this.$cursorLayer.update(this.layerConfig);
}
this.$updateScrollBar();
return;
}
if (changes & this.CHANGE_TEXT) {
this.$textLayer.update(this.layerConfig);
this.$gutterLayer.update(this.layerConfig);
}
else if (changes & this.CHANGE_LINES) {
this.$updateLines();
this.$updateScrollBar();
}
else if (changes & this.CHANGE_SCROLL) {
this.$textLayer.scrollLines(this.layerConfig);
this.$gutterLayer.update(this.layerConfig);
} if (changes & this.CHANGE_GUTTER) {
this.$gutterLayer.update(this.layerConfig);
}
if (changes & this.CHANGE_CURSOR)
this.$cursorLayer.update(this.layerConfig);
if (changes & this.CHANGE_MARKER) {
this.$markerLayer.update(this.layerConfig);
}
if (changes & this.CHANGE_SIZE)
this.$updateScrollBar();
};
this.$computeLayerConfig = function() {
var offset = this.scrollTop % this.lineHeight;
var minHeight = this.$size.scrollerHeight + this.lineHeight;
var longestLine = this.$getLongestLine();
var widthChanged = !this.layerConfig ? true : (this.layerConfig.width != longestLine);
var lineCount = Math.ceil(minHeight / this.lineHeight);
var firstRow = Math.round((this.scrollTop - offset) / this.lineHeight);
var lastRow = Math.min(this.lines.length, firstRow + lineCount) - 1;
var layerConfig = this.layerConfig = {
width : longestLine,
firstRow : firstRow,
lastRow : lastRow,
lineHeight : this.lineHeight,
characterWidth : this.characterWidth,
minHeight : minHeight
};
for ( var i = 0; i < this.layers.length; i++) {
var layer = this.layers[i];
if (widthChanged) {
var style = layer.element.style;
style.width = longestLine + "px";
}
};
this.$gutterLayer.element.style.marginTop = (-offset) + "px";
this.content.style.marginTop = (-offset) + "px";
this.content.style.height = minHeight + "px";
};
this.$updateLines = function() {
var firstRow = this.$changedLines.firstRow;
var lastRow = this.$changedLines.lastRow;
this.$changedLines = {
firstRow: 0,
lastRow: Infinity
};
var layerConfig = this.layerConfig;
// if the update changes the width of the document do a full redraw
if (layerConfig.width != this.$getLongestLine())
return this.$textLayer.update(layerConfig);
if (firstRow > layerConfig.lastRow + 1) { return; }
if (lastRow < layerConfig.firstRow) { return; }
// if the last row is unknown -> redraw everything
if (lastRow === Infinity) {
this.$gutterLayer.update(layerConfig);
this.$textLayer.update(layerConfig);
return;
}
// else update only the changed rows
this.$textLayer.updateLines(layerConfig, firstRow, lastRow);
};
this.$getLongestLine = function() {
var charCount = this.doc.getScreenWidth();
if (this.$showInvisibles)
charCount += 1;
return Math.max(this.$size.scrollerWidth, Math.round(charCount * this.characterWidth));
};
this.addMarker = function(range, clazz, type) {
return this.$markerLayer.addMarker(range, clazz, type);
this.$loop.schedule(this.CHANGE_MARKER);
};
this.removeMarker = function(markerId) {
this.$markerLayer.removeMarker(markerId);
this.$loop.schedule(this.CHANGE_MARKER);
};
this.setBreakpoints = function(rows) {
this.$gutterLayer.setBreakpoints(rows);
this.$loop.schedule(this.CHANGE_GUTTER);
};
this.updateCursor = function(position, overwrite) {
this.$cursorLayer.setCursor(position, overwrite);
this.$loop.schedule(this.CHANGE_CURSOR);
};
this.hideCursor = function() {
this.$cursorLayer.hideCursor();
};
this.showCursor = function() {
this.$cursorLayer.showCursor();
};
this.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.$size.scrollerHeight < top
+ this.lineHeight) {
this.scrollToY(top + this.lineHeight - this.$size.scrollerHeight);
}
if (this.scroller.scrollLeft > left) {
this.scroller.scrollLeft = left;
}
if (this.scroller.scrollLeft + this.$size.scrollerWidth < left
+ this.characterWidth) {
this.scroller.scrollLeft = Math.round(left + this.characterWidth
- this.$size.scrollerWidth);
}
},
this.getScrollTop = function() {
return this.scrollTop;
};
this.getScrollLeft = function() {
return this.scroller.scrollLeft;
};
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.$size.scrollerHeight;
var scrollTop = Math.max(0, Math.min(maxHeight, scrollTop));
if (this.scrollTop !== scrollTop) {
this.scrollTop = scrollTop;
this.$loop.schedule(this.CHANGE_SCROLL);
}
};
this.scrollBy = function(deltaX, deltaY) {
deltaY && this.scrollToY(this.scrollTop + deltaY);
deltaX && (this.scroller.scrollLeft += deltaX);
};
this.screenToTextCoordinates = function(pageX, pageY) {
var canvasPos = this.scroller.getBoundingClientRect();
var col = Math.round((pageX + this.scroller.scrollLeft - canvasPos.left)
/ this.characterWidth);
var row = Math.floor((pageY + this.scrollTop - canvasPos.top)
/ this.lineHeight);
return {
row : row,
column : this.doc.screenToDocumentColumn(Math.max(0, Math.min(row, this.doc.getLength()-1)), col)
};
};
this.textToScreenCoordinates = function(row, column) {
var canvasPos = this.scroller.getBoundingClientRect();
var x = Math.round(this.doc.documentToScreenColumn(row, column) * this.characterWidth);
var y = row * this.lineHeight;
return {
pageX: canvasPos.left + x - this.getScrollLeft(),
pageY: canvasPos.top + y - this.getScrollTop()
}
};
this.visualizeFocus = function() {
dom.addCssClass(this.container, "ace_focus");
};
this.visualizeBlur = function() {
dom.removeCssClass(this.container, "ace_focus");
};
this.showComposition = function(position) {
};
this.setCompositionText = function(text) {
};
this.hideComposition = function() {
};
this.setTheme = function(theme) {
var _self = this;
if (!theme || typeof theme == "string") {
theme = theme || "ace/theme/TextMate";
require([theme], function(theme) {
afterLoad(theme);
});
} else {
afterLoad(theme);
}
var _self = this;
function afterLoad(theme) {
if (_self.$theme)
dom.removeCssClass(_self.container, _self.$theme);
_self.$theme = theme ? theme.cssClass : null;
if (_self.$theme)
dom.addCssClass(_self.container, _self.$theme);
// force re-measure of the gutter width
if (_self.$size) {
_self.$size.width = 0;
_self.onResize();
}
}
};
}).call(VirtualRenderer.prototype);
return VirtualRenderer;
});

View file

@ -0,0 +1,163 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/commands/DefaultCommands",
["ace/PluginManager"], function(PluginManager) {
PluginManager.registerCommand("selectall", function(editor, selection) {
selection.selectAll();
});
PluginManager.registerCommand("removeline", function(editor, selection) {
editor.removeLines();
});
PluginManager.registerCommand("gotoline", function(editor, selection) {
var line = parseInt(prompt("Enter line number:"));
if (!isNaN(line)) {
editor.gotoLine(line);
}
});
PluginManager.registerCommand("togglecomment", function(editor, selection) {
editor.toggleCommentLines();
});
PluginManager.registerCommand("findnext", function(editor, selection) {
editor.findNext();
});
PluginManager.registerCommand("findprevious", function(editor, selection) {
editor.findPrevious();
});
PluginManager.registerCommand("find", function(editor, selection) {
var needle = prompt("Find:");
editor.find(needle);
});
PluginManager.registerCommand("undo", function(editor, selection) {
editor.undo();
});
PluginManager.registerCommand("redo", function(editor, selection) {
editor.redo();
});
PluginManager.registerCommand("redo", function(editor, selection) {
editor.redo();
});
PluginManager.registerCommand("overwrite", function(editor, selection) {
editor.toggleOverwrite();
});
PluginManager.registerCommand("copylinesup", function(editor, selection) {
editor.copyLinesUp();
});
PluginManager.registerCommand("movelinesup", function(editor, selection) {
editor.moveLinesUp();
});
PluginManager.registerCommand("selecttostart", function(editor, selection) {
selection.selectFileStart();
});
PluginManager.registerCommand("gotostart", function(editor, selection) {
editor.navigateFileStart();
});
PluginManager.registerCommand("selectup", function(editor, selection) {
selection.selectUp();
});
PluginManager.registerCommand("golineup", function(editor, selection) {
editor.navigateUp();
});
PluginManager.registerCommand("copylinesdown", function(editor, selection) {
editor.copyLinesDown();
});
PluginManager.registerCommand("movelinesdown", function(editor, selection) {
editor.moveLinesDown();
});
PluginManager.registerCommand("selecttoend", function(editor, selection) {
selection.selectFileEnd();
});
PluginManager.registerCommand("gotoend", function(editor, selection) {
editor.navigateFileEnd();
});
PluginManager.registerCommand("selectdown", function(editor, selection) {
selection.selectDown();
});
PluginManager.registerCommand("godown", function(editor, selection) {
editor.navigateDown();
});
PluginManager.registerCommand("selectwordleft", function(editor, selection) {
selection.selectWordLeft();
});
PluginManager.registerCommand("gotowordleft", function(editor, selection) {
editor.navigateWordLeft();
});
PluginManager.registerCommand("selecttolinestart", function(editor, selection) {
selection.selectLineStart();
});
PluginManager.registerCommand("gotolinestart", function(editor, selection) {
editor.navigateLineStart();
});
PluginManager.registerCommand("selectleft", function(editor, selection) {
selection.selectLeft();
});
PluginManager.registerCommand("gotoleft", function(editor, selection) {
editor.navigateLeft();
});
PluginManager.registerCommand("selectwordright", function(editor, selection) {
selection.selectWordRight();
});
PluginManager.registerCommand("gotowordright", function(editor, selection) {
editor.navigateWordRight();
});
PluginManager.registerCommand("selecttolineend", function(editor, selection) {
selection.selectLineEnd();
});
PluginManager.registerCommand("gotolineend", function(editor, selection) {
editor.navigateLineEnd();
});
PluginManager.registerCommand("selectright", function(editor, selection) {
selection.selectRight();
});
PluginManager.registerCommand("gotoright", function(editor, selection) {
editor.navigateRight();
});
PluginManager.registerCommand("selectpagedown", function(editor, selection) {
editor.selectPageDown();
});
PluginManager.registerCommand("pagedown", function(editor, selection) {
editor.scrollPageDown();
});
PluginManager.registerCommand("gotopagedown", function(editor, selection) {
editor.gotoPageDown();
});
PluginManager.registerCommand("selectpageup", function(editor, selection) {
editor.selectPageUp();
});
PluginManager.registerCommand("pageup", function(editor, selection) {
editor.scrollPageUp();
});
PluginManager.registerCommand("gotopageup", function(editor, selection) {
editor.gotoPageUp();
});
PluginManager.registerCommand("selectlinestart", function(editor, selection) {
selection.selectLineStart();
});
PluginManager.registerCommand("gotolinestart", function(editor, selection) {
editor.navigateLineStart();
});
PluginManager.registerCommand("selectlineend", function(editor, selection) {
selection.selectLineEnd();
});
PluginManager.registerCommand("gotolineend", function(editor, selection) {
editor.navigateLineEnd();
});
PluginManager.registerCommand("del", function(editor, selection) {
editor.removeRight();
});
PluginManager.registerCommand("backspace", function(editor, selection) {
editor.removeLeft();
});
PluginManager.registerCommand("outdent", function(editor, selection) {
editor.blockOutdent();
});
PluginManager.registerCommand("indent", function(editor, selection) {
editor.indent();
});
});

View file

@ -0,0 +1,58 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/conf/keybindings/default_mac", function() {
return {
"selectall": "Command-A",
"removeline": "Command-D",
"gotoline": "Command-L",
"togglecomment": "Command-7",
"findnext": "Command-K",
"findprevious": "Command-Shift-K",
"find": "Command-F",
"replace": "Command-R",
"undo": "Command-Z",
"redo": "Command-Shift-Z|Command-Y",
"overwrite": "Insert",
"copylinesup": "Command-Option-Up",
"movelinesup": "Option-Up",
"selecttostart": "Command-Shift-Up",
"gotostart": "Command-Home|Command-Up",
"selectup": "Shift-Up",
"golineup": "Up",
"copylinesdown": "Command-Option-Down",
"movelinsedown": "Option-Down",
"selecttoend": "Command-Shift-Down",
"gotoend": "Command-End|Command-Down",
"selectdown": "Shift-Down",
"godown": "Down",
"selectwordleft": "Option-Shift-Left",
"gotowordleft": "Option-Left",
"selecttolinestart": "Command-Shift-Left",
"gotolinestart": "Command-Left|Home",
"selectleft": "Shift-Left",
"gotoleft": "Left",
"selectwordright": "Option-Shift-Right",
"gotowordright": "Option-Right",
"selecttolineend": "Command-Shift-Right",
"gotolineend": "Command-Right|End",
"selectright": "Shift-Right",
"gotoright": "Right",
"selectpagedown": "Shift-PageDown",
"pagedown": "PageDown",
"selectpageup": "Shift-PageUp",
"pageup": "PageUp",
"selectlinestart": "Shift-Home",
"selectlineend": "Shift-End",
"del": "Delete",
"backspace": "Backspace",
"outdent": "Shift-Tab",
"indent": "Tab"
};
});

View file

@ -0,0 +1,58 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/conf/keybindings/default_win", function() {
return {
"selectall": "Ctrl-A",
"removeline": "Ctrl-D",
"gotoline": "Ctrl-L",
"togglecomment": "Ctrl-7",
"findnext": "Ctrl-K",
"findprevious": "Ctrl-Shift-K",
"find": "Ctrl-F",
"replace": "Ctrl-R",
"undo": "Ctrl-Z",
"redo": "Ctrl-Shift-Z|Ctrl-Y",
"overwrite": "Insert",
"copylinesup": "Ctrl-Alt-Up",
"movelinesup": "Alt-Up",
"selecttostart": "Ctrl-Shift-Up",
"gotostart": "Ctrl-Home|Ctrl-Up",
"selectup": "Shift-Up",
"golineup": "Up",
"copylinesdown": "Ctrl-Alt-Down",
"movelinsedown": "Alt-Down",
"selecttoend": "Ctrl-Shift-Down",
"gotoend": "Ctrl-End|Ctrl-Down",
"selectdown": "Shift-Down",
"godown": "Down",
"selectwordleft": "Alt-Shift-Left",
"gotowordleft": "Alt-Left",
"selecttolinestart": "Ctrl-Shift-Left",
"gotolinestart": "Ctrl-Left|Home",
"selectleft": "Shift-Left",
"gotoleft": "Left",
"selectwordright": "Alt-Shift-Right",
"gotowordright": "Alt-Right",
"selecttolineend": "Ctrl-Shift-Right",
"gotolineend": "Ctrl-Right|End",
"selectright": "Shift-Right",
"gotoright": "Right",
"selectpagedown": "Shift-PageDown",
"pagedown": "PageDown",
"selectpageup": "Shift-PageUp",
"pageup": "PageUp",
"selectlinestart": "Shift-Home",
"selectlineend": "Shift-End",
"del": "Delete",
"backspace": "Backspace",
"outdent": "Shift-Tab",
"indent": "Tab"
};
});

87
lib/ace/css/editor.css Normal file
View file

@ -0,0 +1,87 @@
.ace_editor {
position: absolute;
overflow: hidden;
font-family: "Menlo", "Monaco", "Courier New", monospace;
font-size: 12px;
}
.ace_scroller {
position: absolute;
overflow-x: scroll;
overflow-y: hidden;
}
.ace_gutter {
position: absolute;
overflow-x: hidden;
overflow-y: hidden;
height: 100%;
}
.ace_editor .ace_sb {
position: absolute;
overflow-x: hidden;
overflow-y: scroll;
right: 0;
}
.ace_editor .ace_sb div {
position: absolute;
width: 1px;
left: 0px;
}
.ace_editor .ace_printMargin {
position: absolute;
height: 100%;
}
.ace_layer {
z-index: 0;
position: absolute;
overflow: hidden;
white-space: nowrap;
height: 100%;
}
.ace_text-layer {
font-family: Monaco, "Courier New", monospace;
color: black;
}
.ace_cursor-layer {
cursor: text;
}
.ace_cursor {
z-index: 3;
position: absolute;
}
.ace_line {
white-space: nowrap;
}
.ace_marker-layer {
}
.ace_marker-layer .ace_step {
position: absolute;
z-index: 2;
}
.ace_marker-layer .ace_selection {
position: absolute;
z-index: 3;
}
.ace_marker-layer .ace_bracket {
position: absolute;
z-index: 4;
}
.ace_marker-layer .ace_active_line {
position: absolute;
z-index: 1;
}

117
lib/ace/layer/Cursor.js Normal file
View file

@ -0,0 +1,117 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/layer/Cursor", ["ace/lib/dom"], function(dom) {
var Cursor = function(parentEl) {
this.element = document.createElement("div");
this.element.className = "ace_layer ace_cursor-layer";
parentEl.appendChild(this.element);
this.cursor = document.createElement("div");
this.cursor.className = "ace_cursor";
this.isVisible = false;
};
(function() {
this.setDocument = function(doc) {
this.doc = doc;
};
this.setCursor = function(position, overwrite) {
this.position = {
row : position.row,
column : this.doc.documentToScreenColumn(position.row, position.column)
};
if (overwrite) {
dom.addCssClass(this.cursor, "ace_overwrite");
} else {
dom.removeCssClass(this.cursor, "ace_overwrite");
}
};
this.hideCursor = function() {
this.isVisible = false;
if (this.cursor.parentNode) {
this.cursor.parentNode.removeChild(this.cursor);
}
clearInterval(this.blinkId);
};
this.showCursor = function() {
this.isVisible = true;
this.element.appendChild(this.cursor);
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() {
if (!this.config || !this.position) {
return {
left : 0,
top : 0
};
}
var cursorLeft = Math.round(this.position.column * this.config.characterWidth);
var cursorTop = this.position.row * this.config.lineHeight;
return {
left : cursorLeft,
top : cursorTop
};
};
this.update = function(config) {
if (!this.position)
return;
this.config = config;
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.width = config.characterWidth + "px";
this.cursor.style.height = config.lineHeight + "px";
if (this.isVisible) {
this.element.appendChild(this.cursor);
}
this.restartTimer();
};
}).call(Cursor.prototype);
return Cursor;
});

45
lib/ace/layer/Gutter.js Normal file
View file

@ -0,0 +1,45 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/layer/Gutter", [], function() {
var Gutter = function(parentEl) {
this.element = document.createElement("div");
this.element.className = "ace_layer ace_gutter-layer";
parentEl.appendChild(this.element);
this.$breakpoints = [];
};
(function() {
this.setBreakpoints = function(rows) {
this.$breakpoints = rows.concat();
if (this.$config)
this.update(this.$config);
};
this.update = function(config) {
this.$config = config;
var html = [];
for ( var i = config.firstRow; i <= config.lastRow; i++) {
html.push("<div class='ace_gutter-cell",
this.$breakpoints[i] ? " ace_breakpoint" : "",
"' style='height:", config.lineHeight, "px;'>", (i+1), "</div>");
html.push("</div>");
}
this.element.innerHTML = html.join("");
this.element.style.height = config.minHeight + "px";
};
}).call(Gutter.prototype);
return Gutter;
});

153
lib/ace/layer/Marker.js Normal file
View file

@ -0,0 +1,153 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/layer/Marker", ["ace/Range"], function(Range) {
var Marker = function(parentEl) {
this.element = document.createElement("div");
this.element.className = "ace_layer ace_marker-layer";
parentEl.appendChild(this.element);
this.markers = {};
this.$markerId = 1;
};
(function() {
this.setDocument = function(doc) {
this.doc = doc;
};
this.addMarker = function(range, clazz, type) {
var id = this.$markerId++;
this.markers[id] = {
range : range,
type : type || "line",
clazz : clazz
};
return id;
};
this.removeMarker = function(markerId) {
var marker = this.markers[markerId];
if (marker) {
delete (this.markers[markerId]);
}
};
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 = marker.range.clipRows(config.firstRow, config.lastRow);
if (range.isEmpty()) continue;
if (range.isMultiLine()) {
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);
}
}
this.element.innerHTML = html.join("");
};
this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig) {
// selection start
var row = range.start.row;
var lineRange = new Range(row, range.start.column, row, this.doc.getLine(row).length);
this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig);
// selection end
var row = range.end.row;
var lineRange = new Range(row, 0, row, 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.end.row = row;
lineRange.end.column = this.doc.getLine(row).length;
this.drawSingleLineMarker(stringBuilder, lineRange, clazz, layerConfig);
}
};
this.drawMultiLineMarker = function(stringBuilder, range, clazz, layerConfig) {
var range = range.toScreenRange(this.doc);
// from selection start to the end of the line
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(
"<div class='", clazz, "' style='",
"height:", height, "px;",
"width:", width, "px;",
"top:", top, "px;",
"left:", left, "px;'></div>"
);
// from start of the last line to the selection end
var top = (range.end.row - layerConfig.firstRow) * layerConfig.lineHeight;
var width = Math.round(range.end.column * layerConfig.characterWidth);
stringBuilder.push(
"<div class='", clazz, "' style='",
"height:", height, "px;",
"top:", top, "px;",
"width:", width, "px;'></div>"
);
// all the complete lines
var height = (range.end.row - range.start.row - 1) * layerConfig.lineHeight;
if (height < 0)
return;
var top = (range.start.row + 1 - layerConfig.firstRow) * layerConfig.lineHeight;
stringBuilder.push(
"<div class='", clazz, "' style='",
"height:", height, "px;",
"width:", layerConfig.width, "px;",
"top:", top, "px;'></div>"
);
};
this.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig) {
var range = range.toScreenRange(this.doc);
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(
"<div class='", clazz, "' style='",
"height:", height, "px;",
"width:", width, "px;",
"top:", top, "px;",
"left:", left,"px;'></div>"
);
};
}).call(Marker.prototype);
return Marker;
});

267
lib/ace/layer/Text.js Normal file
View file

@ -0,0 +1,267 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/layer/Text", ["ace/lib/oop", "ace/lib/dom", "ace/MEventEmitter"], function(oop, dom, MEventEmitter) {
var Text = function(parentEl) {
this.element = document.createElement("div");
this.element.className = "ace_layer ace_text-layer";
parentEl.appendChild(this.element);
this.$characterSize = this.$measureSizes();
this.$pollSizeChanges();
};
(function() {
oop.implement(this, MEventEmitter);
this.EOF_CHAR = "&para;";
this.EOL_CHAR = "&not;";
this.TAB_CHAR = "&rarr;";
this.SPACE_CHAR = "&middot;";
this.setTokenizer = function(tokenizer) {
this.tokenizer = tokenizer;
};
this.getLineHeight = function() {
return this.$characterSize.height || 1;
};
this.getCharacterWidth = function() {
return this.$characterSize.width || 1;
};
this.$pollSizeChanges = function() {
var self = this;
setInterval(function() {
var size = self.$measureSizes();
if (self.$characterSize.width !== size.width || self.$characterSize.height !== size.height) {
self.$characterSize = size;
self.$dispatchEvent("changeCharaterSize", {data: size});
}
}, 500);
};
this.$fontStyles = {
fontFamily : 1,
fontSize : 1,
fontWeight : 1,
fontStyle : 1,
lineHeight : 1
},
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";
for (var prop in this.$fontStyles) {
var value = dom.computedStyle(this.element, prop);
style[prop] = value;
}
// 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!
measureNode.innerHTML = new Array(1000).join("Xy");
document.body.insertBefore(measureNode, document.body.firstChild);
var size = {
height: measureNode.offsetHeight,
width: measureNode.offsetWidth / 2000
};
document.body.removeChild(measureNode);
return size;
};
this.setDocument = function(doc) {
this.doc = doc;
};
this.$showInvisibles = false;
this.setShowInvisibles = function(showInvisibles) {
this.$showInvisibles = showInvisibles;
};
this.$computeTabString = function() {
var tabSize = this.doc.getTabSize();
if (this.$showInvisibles) {
var halfTab = (tabSize) / 2;
this.$tabString = "<span class='ace_invisible'>"
+ new Array(Math.floor(halfTab)).join("&nbsp;")
+ this.TAB_CHAR
+ new Array(Math.ceil(halfTab)+1).join("&nbsp;")
+ "</span>";
} else {
this.$tabString = new Array(tabSize+1).join("&nbsp;");
}
};
this.updateLines = function(layerConfig, firstRow, lastRow) {
this.$computeTabString();
var first = Math.max(firstRow, layerConfig.firstRow);
var last = Math.min(lastRow, layerConfig.lastRow);
var lineElements = this.element.childNodes;
var _self = this;
this.tokenizer.getTokens(first, last, function(tokens) {
for ( var i = first; i <= last; i++) {
var lineElement = lineElements[i - layerConfig.firstRow];
if (!lineElement)
continue;
var html = [];
_self.$renderLine(html, i, tokens[i-first].tokens);
lineElement.innerHTML = html.join("");
}
});
};
this.scrollLines = function(config) {
var _self = this;
this.$computeTabString();
var oldConfig = this.config;
this.config = config;
if (!oldConfig || oldConfig.lastRow < config.firstRow)
return this.update(config);
if (config.lastRow < oldConfig.firstRow)
return this.update(config);
var el = this.element;
if (oldConfig.firstRow < config.firstRow)
for (var row=oldConfig.firstRow; row<config.firstRow; row++)
el.removeChild(el.firstChild);
if (oldConfig.lastRow > config.lastRow)
for (var row=config.lastRow+1; row<=oldConfig.lastRow; row++)
el.removeChild(el.lastChild);
appendTop(appendBottom);
function appendTop(callback) {
if (config.firstRow < oldConfig.firstRow) {
_self.$renderLinesFragment(config, config.firstRow, oldConfig.firstRow - 1, function(fragment) {
if (el.firstChild)
el.insertBefore(fragment, el.firstChild);
else
el.appendChild(fragment);
callback();
});
}
else
callback();
}
function appendBottom() {
if (config.lastRow > oldConfig.lastRow) {
_self.$renderLinesFragment(config, oldConfig.lastRow + 1, config.lastRow, function(fragment) {
el.appendChild(fragment);
});
}
}
};
this.$renderLinesFragment = function(config, firstRow, lastRow, callback) {
var fragment = document.createDocumentFragment();
var _self = this;
this.tokenizer.getTokens(firstRow, lastRow, function(tokens) {
for (var row=firstRow; row<=lastRow; row++) {
var lineEl = document.createElement("div");
lineEl.className = "ace_line";
var style = lineEl.style;
style.height = _self.$characterSize.height + "px";
style.width = config.width + "px";
var html = [];
_self.$renderLine(html, row, tokens[row-firstRow].tokens);
lineEl.innerHTML = html.join("");
fragment.appendChild(lineEl);
}
callback(fragment);
});
};
this.update = function(config) {
this.$computeTabString();
var html = [];
var _self = this;
this.tokenizer.getTokens(config.firstRow, config.lastRow, function(tokens) {
for ( var i = config.firstRow; i <= config.lastRow; i++) {
html.push("<div class='ace_line' style='height:" + _self.$characterSize.height + "px;", "width:",
config.width, "px'>");
_self.$renderLine(html, i, tokens[i-config.firstRow].tokens), html.push("</div>");
}
_self.element.innerHTML = html.join("");
});
};
this.$textToken = {
"text": true,
"rparen": true,
"lparen": true
};
this.$renderLine = function(stringBuilder, row, tokens) {
// if (this.$showInvisibles) {
// var self = this;
// var spaceRe = /[\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]+/g;
// var spaceReplace = function(space) {
// var space = new Array(space.length+1).join(self.SPACE_CHAR);
// return "<span class='ace_invisible'>" + space + "</span>";
// };
// }
// else {
var spaceRe = /[\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]/g;
var spaceReplace = "&nbsp;";
// }
for ( var i = 0; i < tokens.length; i++) {
var token = tokens[i];
var output = token.value
.replace(/&/g, "&amp;")
.replace(/</g, "&lt;")
.replace(spaceRe, spaceReplace)
.replace(/\t/g, this.$tabString);
if (!this.$textToken[token.type]) {
var classes = "ace_" + token.type.replace(/\./g, " ace_");
stringBuilder.push("<span class='", classes, "'>", output, "</span>");
}
else {
stringBuilder.push(output);
}
};
if (this.$showInvisibles) {
if (row !== this.doc.getLength() - 1) {
stringBuilder.push("<span class='ace_invisible'>" + this.EOL_CHAR + "</span>");
} else {
stringBuilder.push("<span class='ace_invisible'>" + this.EOF_CHAR + "</span>");
}
}
};
}).call(Text.prototype);
return Text;
});

36
lib/ace/lib/core.js Normal file
View file

@ -0,0 +1,36 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
if (!require.def) require.def = require("requireJS-node")(module);
require.def("ace/lib/core", function() {
var core = {};
var os = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase();
core.isWin = (os == "win");
core.isMac = (os == "mac");
core.isLinux = (os == "linux");
core.isIE = ! + "\v1";
core.isGecko = window.controllers && window.navigator.product === "Gecko";
core.provide = function(namespace) {
var parts = namespace.split(".");
var obj = window;
for (var i=0; i<parts.length; i++) {
var part = parts[i];
if (!obj[part]) {
obj[part] = {};
}
obj = obj[part];
}
};
return core;
});

112
lib/ace/lib/dom.js Normal file
View file

@ -0,0 +1,112 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
if (!require.def) require.def = require("requireJS-node")(module);
require.def("ace/lib/dom", ["ace/lib/lang"], function(lang) {
var dom = {};
dom.setText = function(elem, text) {
if (elem.innerText !== undefined) {
elem.innerText = text;
}
if (elem.textContent !== undefined) {
elem.textContent = text;
}
};
dom.hasCssClass = function(el, name) {
var classes = el.className.split(/\s+/g);
return lang.arrayIndexOf(classes, name) !== -1;
};
dom.addCssClass = function(el, name) {
if (!dom.hasCssClass(el, name)) {
el.className += " " + name;
}
};
dom.removeCssClass = function(el, name) {
var classes = el.className.split(/\s+/g);
while (true) {
var index = lang.arrayIndexOf(classes, name);
if (index == -1) {
break;
}
classes.splice(index, 1);
}
el.className = classes.join(" ");
};
dom.importCssString = function(cssText, doc){
doc = doc || document;
if (doc.createStyleSheet) {
var sheet = doc.createStyleSheet();
sheet.cssText = cssText;
}
else {
var style = doc.createElement("style");
style.appendChild(doc.createTextNode(cssText));
doc.getElementsByTagName("head")[0].appendChild(style);
}
};
dom.getInnerWidth = function(element) {
return (parseInt(dom.computedStyle(element, "paddingLeft"))
+ parseInt(dom.computedStyle(element, "paddingRight")) + element.clientWidth);
};
dom.getInnerHeight = function(element) {
return (parseInt(dom.computedStyle(element, "paddingTop"))
+ parseInt(dom.computedStyle(element, "paddingBottom")) + element.clientHeight);
};
dom.computedStyle = function(element, style) {
if (window.getComputedStyle) {
return (window.getComputedStyle(element, "") || {})[style] || "";
}
else {
return element.currentStyle[style];
}
};
dom.scrollbarWidth = function() {
var inner = document.createElement('p');
inner.style.width = "100%";
inner.style.height = "200px";
var outer = document.createElement("div");
var style = outer.style;
style.position = "absolute";
style.left = "-10000px";
style.overflow = "hidden";
style.width = "200px";
style.height = "150px";
outer.appendChild(inner);
document.body.appendChild(outer);
var noScrollbar = inner.offsetWidth;
style.overflow = "scroll";
var withScrollbar = inner.offsetWidth;
if (noScrollbar == withScrollbar) {
withScrollbar = outer.clientWidth;
}
document.body.removeChild(outer);
return noScrollbar-withScrollbar;
};
return dom;
});

212
lib/ace/lib/event.js Normal file
View file

@ -0,0 +1,212 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
if (!require.def) require.def = require("requireJS-node")(module);
require.def("ace/lib/event", ["ace/lib/core"], function(core) {
var event = {};
event.addListener = function(elem, type, callback) {
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);
}
};
event.removeListener = function(elem, type, callback) {
if (elem.removeEventListener) {
return elem.removeEventListener(type, callback, false);
}
if (elem.detachEvent) {
elem.detachEvent("on" + type, callback.$$wrapper || callback);
}
};
event.stopEvent = function(e) {
event.stopPropagation(e);
event.preventDefault(e);
return false;
};
event.stopPropagation = function(e) {
if (e.stopPropagation)
e.stopPropagation();
else
e.cancelBubble = true;
};
event.preventDefault = function(e) {
if (e.preventDefault)
e.preventDefault();
else
e.returnValue = false;
};
event.getDocumentX = function(e) {
if (e.clientX) {
var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
return e.clientX + scrollLeft;
} else {
return e.pageX;
}
};
event.getDocumentY = function(e) {
if (e.clientY) {
var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
return e.clientY + scrollTop;
} else {
return e.pageX;
}
};
/**
* @return {Number} 0 for left button, 1 for middle button, 2 for right button
*/
event.getButton = function(e) {
// DOM Event
if (e.preventDefault) {
return e.button;
}
// old IE
else {
return Math.max(e.button - 1, 2)
}
};
if (document.documentElement.setCapture) {
event.capture = function(el, eventHandler, releaseCaptureHandler) {
function onMouseMove(e) {
eventHandler(e);
return event.stopPropagation(e);
}
function onReleaseCapture(e) {
eventHandler && eventHandler(e);
releaseCaptureHandler && releaseCaptureHandler();
event.removeListener(el, "mousemove", eventHandler);
event.removeListener(el, "mouseup", onReleaseCapture);
event.removeListener(el, "losecapture", onReleaseCapture);
el.releaseCapture();
}
event.addListener(el, "mousemove", eventHandler);
event.addListener(el, "mouseup", onReleaseCapture);
event.addListener(el, "losecapture", onReleaseCapture);
el.setCapture();
};
}
else {
event.capture = function(el, eventHandler, releaseCaptureHandler) {
function onMouseMove(e) {
eventHandler(e);
e.stopPropagation();
}
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);
};
}
event.addMouseWheelListener = function(el, callback) {
var listener = function(e) {
if (e.wheelDelta !== undefined) {
if (e.wheelDeltaX !== undefined) {
e.wheelX = -e.wheelDeltaX / 8;
e.wheelY = -e.wheelDeltaY / 8;
} else {
e.wheelX = 0;
e.wheelY = -e.wheelDelta / 8;
}
}
else {
if (e.axis && e.axis == e.HORIZONTAL_AXIS) {
e.wheelX = (e.detail || 0) * 5;
e.wheelY = 0;
} else {
e.wheelX = 0;
e.wheelY = (e.detail || 0) * 5;
}
}
callback(e);
};
event.addListener(el, "DOMMouseScroll", listener);
event.addListener(el, "mousewheel", listener);
};
event.addMultiMouseDownListener = function(el, count, timeout, callback) {
var clicks = 0;
var startX, startY;
var listener = function(e) {
clicks += 1;
if (clicks == 1) {
startX = e.clientX;
startY = e.clientY;
setTimeout(function() {
clicks = 0;
}, timeout || 600);
}
if (Math.abs(e.clientX - startX) > 5 || Math.abs(e.clientY - startY) > 5)
clicks = 0;
if (clicks == count) {
clicks = 0;
callback(e);
}
return event.preventDefault(e);
};
event.addListener(el, "mousedown", listener);
core.isIE && event.addListener(el, "dblclick", listener);
};
event.addKeyListener = function(el, callback) {
var lastDown = null;
event.addListener(el, "keydown", function(e) {
lastDown = e.keyIdentifier || e.keyCode;
return callback(e);
});
// repeated keys are fired as keypress and not keydown events
if (core.isMac && core.isGecko) {
event.addListener(el, "keypress", function(e) {
var keyId = e.keyIdentifier || e.keyCode;
if (lastDown !== keyId) {
return callback(e);
} else {
lastDown = null;
}
});
}
};
return event;
});

98
lib/ace/lib/lang.js Normal file
View file

@ -0,0 +1,98 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
if (!require.def) require.def = require("requireJS-node")(module);
require.def("ace/lib/lang", function() {
var lang = {};
lang.stringReverse = function(string) {
return string.split("").reverse().join("");
};
lang.stringRepeat = function (string, count) {
return new Array(count + 1).join(string);
}
if (Array.prototype.indexOf) {
lang.arrayIndexOf = function(array, searchElement) {
return array.indexOf(searchElement);
};
}
else {
lang.arrayIndexOf = function(array, searchElement) {
for (var i=0; i<array.length; i++) {
if (array[i] == searchElement) {
return i;
}
}
return -1;
};
}
lang.isArray = function(value) {
return Object.prototype.toString.call(value) == "[object Array]";
};
lang.copyObject = function(obj) {
var copy = {};
for (var key in obj) {
copy[key] = obj[key];
}
return copy;
};
lang.arrayToMap = function(arr) {
var map = {};
for (var i=0; i<arr.length; i++) {
map[arr[i]] = 1;
}
return map;
};
lang.escapeRegExp = function(str) {
return str.replace(/([.*+?^${}()|[\]\/\\])/g, '\\$1');
};
lang.bind = function(fcn, context) {
return function() {
return fcn.apply(context, arguments);
};
};
lang.deferredCall = function(fcn) {
var timer = null;
var callback = function() {
timer = null;
fcn();
};
return {
schedule: function() {
if (!timer) {
timer = setTimeout(callback, 0);
}
},
call: function() {
lang.cancel();
fcn();
},
cancel: function() {
clearTimeout(timer);
timer = null;
}
};
};
return lang;
});

34
lib/ace/lib/oop.js Normal file
View file

@ -0,0 +1,34 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
if (!require.def) require.def = require("requireJS-node")(module);
require.def("ace/lib/oop", function() {
var oop = {};
oop.inherits = function(ctor, superCtor) {
var tempCtor = function() {};
tempCtor.prototype = superCtor.prototype;
ctor.super_ = superCtor.prototype;
ctor.prototype = new tempCtor();
ctor.prototype.constructor = ctor;
};
oop.mixin = function(obj, mixin) {
for (var key in mixin) {
obj[key] = mixin[key];
}
};
oop.implement = function(proto, mixin) {
oop.mixin(proto, mixin);
};
return oop;
});

53
lib/ace/mode/Css.js Normal file
View file

@ -0,0 +1,53 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/mode/Css",
[
"ace/lib/oop",
"ace/mode/Text",
"ace/Tokenizer",
"ace/mode/CssHighlightRules",
"ace/mode/MatchingBraceOutdent"
], function(oop, TextMode, Tokenizer, CssHighlightRules, MatchingBraceOutdent) {
var Css = function() {
this.$tokenizer = new Tokenizer(new CssHighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
};
oop.inherits(Css, TextMode);
(function() {
this.getNextLineIndent = function(state, line, 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;
}
return indent;
};
this.checkOutdent = function(state, line, input) {
return this.$outdent.checkOutdent(line, input);
};
this.autoOutdent = function(state, doc, row) {
return this.$outdent.autoOutdent(doc, row);
};
}).call(Css.prototype);
return Css;
});

View file

@ -0,0 +1,204 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/mode/CssHighlightRules",
[
"ace/lib/oop",
"ace/lib/lang",
"ace/mode/TextHighlightRules"
], function(oop, lang, TextHighlightRules) {
var CssHighlightRules = function() {
var properties = lang.arrayToMap(
("azimuth|background-attachment|background-color|background-image|" +
"background-position|background-repeat|background|border-bottom-color|" +
"border-bottom-style|border-bottom-width|border-bottom|border-collapse|" +
"border-color|border-left-color|border-left-style|border-left-width|" +
"border-left|border-right-color|border-right-style|border-right-width|" +
"border-right|border-spacing|border-style|border-top-color|" +
"border-top-style|border-top-width|border-top|border-width|border|" +
"bottom|caption-side|clear|clip|color|content|counter-increment|" +
"counter-reset|cue-after|cue-before|cue|cursor|direction|display|" +
"elevation|empty-cells|float|font-family|font-size-adjust|font-size|" +
"font-stretch|font-style|font-variant|font-weight|font|height|left|" +
"letter-spacing|line-height|list-style-image|list-style-position|" +
"list-style-type|list-style|margin-bottom|margin-left|margin-right|" +
"margin-top|marker-offset|margin|marks|max-height|max-width|min-height|" +
"min-width|-moz-border-radius|opacity|orphans|outline-color|" +
"outline-style|outline-width|outline|overflow|overflow-x|overflow-y|padding-bottom|" +
"padding-left|padding-right|padding-top|padding|page-break-after|" +
"page-break-before|page-break-inside|page|pause-after|pause-before|" +
"pause|pitch-range|pitch|play-during|position|quotes|richness|right|" +
"size|speak-header|speak-numeral|speak-punctuation|speech-rate|speak|" +
"stress|table-layout|text-align|text-decoration|text-indent|" +
"text-shadow|text-transform|top|unicode-bidi|vertical-align|" +
"visibility|voice-family|volume|white-space|widows|width|word-spacing|" +
"z-index").split("|")
);
var functions = lang.arrayToMap(
("rgb|rgba|url|attr|counter|counters").split("|")
);
var constants = lang.arrayToMap(
("absolute|all-scroll|always|armenian|auto|baseline|below|bidi-override|" +
"block|bold|bolder|both|bottom|break-all|break-word|capitalize|center|" +
"char|circle|cjk-ideographic|col-resize|collapse|crosshair|dashed|" +
"decimal-leading-zero|decimal|default|disabled|disc|" +
"distribute-all-lines|distribute-letter|distribute-space|" +
"distribute|dotted|double|e-resize|ellipsis|fixed|georgian|groove|" +
"hand|hebrew|help|hidden|hiragana-iroha|hiragana|horizontal|" +
"ideograph-alpha|ideograph-numeric|ideograph-parenthesis|" +
"ideograph-space|inactive|inherit|inline-block|inline|inset|inside|" +
"inter-ideograph|inter-word|italic|justify|katakana-iroha|katakana|" +
"keep-all|left|lighter|line-edge|line-through|line|list-item|loose|" +
"lower-alpha|lower-greek|lower-latin|lower-roman|lowercase|lr-tb|ltr|" +
"medium|middle|move|n-resize|ne-resize|newspaper|no-drop|no-repeat|" +
"nw-resize|none|normal|not-allowed|nowrap|oblique|outset|outside|" +
"overline|pointer|progress|relative|repeat-x|repeat-y|repeat|right|" +
"ridge|row-resize|rtl|s-resize|scroll|se-resize|separate|small-caps|" +
"solid|square|static|strict|super|sw-resize|table-footer-group|" +
"table-header-group|tb-rl|text-bottom|text-top|text|thick|thin|top|" +
"transparent|underline|upper-alpha|upper-latin|upper-roman|uppercase|" +
"vertical-ideographic|vertical-text|visible|w-resize|wait|whitespace|" +
"zero").split("|")
);
var colors = lang.arrayToMap(
("aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|" +
"purple|red|silver|teal|white|yellow").split("|")
);
// regexp must not have capturing parentheses. Use (?:) instead.
// regexps are ordered -> the first match is used
var numRe = "\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))";
function ic(str) {
var re = [];
var chars = str.split("");
for (var i=0; i<chars.length; i++) {
re.push(
"[",
chars[i].toLowerCase(),
chars[i].toUpperCase(),
"]"
);
}
return re.join("");
}
this.$rules = {
"start" : [ {
token : "comment", // multi line comment
regex : "\\/\\*",
next : "comment"
}, {
token : "string", // single line
regex : '["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'
}, {
token : "string", // single line
regex : "['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"
}, {
token : "constant.numeric",
regex : numRe + ic("em")
}, {
token : "constant.numeric",
regex : numRe + ic("ex")
}, {
token : "constant.numeric",
regex : numRe + ic("px")
}, {
token : "constant.numeric",
regex : numRe + ic("cm")
}, {
token : "constant.numeric",
regex : numRe + ic("mm")
}, {
token : "constant.numeric",
regex : numRe + ic("in")
}, {
token : "constant.numeric",
regex : numRe + ic("pt")
}, {
token : "constant.numeric",
regex : numRe + ic("pc")
}, {
token : "constant.numeric",
regex : numRe + ic("deg")
}, {
token : "constant.numeric",
regex : numRe + ic("rad")
}, {
token : "constant.numeric",
regex : numRe + ic("grad")
}, {
token : "constant.numeric",
regex : numRe + ic("ms")
}, {
token : "constant.numeric",
regex : numRe + ic("s")
}, {
token : "constant.numeric",
regex : numRe + ic("hz")
}, {
token : "constant.numeric",
regex : numRe + ic("khz")
}, {
token : "constant.numeric",
regex : numRe + "%"
}, {
token : "constant.numeric",
regex : numRe
}, {
token : "constant.numeric", // hex6 color
regex : "#[a-fA-F0-9]{6}"
}, {
token : "constant.numeric", // hex3 color
regex : "#[a-fA-F0-9]{3}"
}, {
token : "lparen",
regex : "\{"
}, {
token : "rparen",
regex : "\}"
}, {
token : function(value) {
if (properties[value.toLowerCase()]) {
return "support.type";
}
else if (functions[value.toLowerCase()]) {
return "support.function";
}
else if (constants[value.toLowerCase()]) {
return "support.constant";
}
else if (colors[value.toLowerCase()]) {
return "support.constant.color";
}
else {
return "text";
}
},
regex : "\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"
}],
"comment" : [{
token : "comment", // closing comment
regex : ".*?\\*\\/",
next : "start"
}, {
token : "comment", // comment spanning whole line
regex : ".+"
}]
};
};
oop.inherits(CssHighlightRules, TextHighlightRules);
return CssHighlightRules;
});

View file

@ -0,0 +1,52 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/mode/DocCommentHighlightRules",
[
"ace/lib/oop",
"ace/mode/TextHighlightRules"
], function(oop, TextHighlightRules) {
var DocCommentHighlightRules = function() {
this.$rules = {
"start" : [ {
token : "comment.doc", // closing comment
regex : "\\*\\/",
next : "start"
}, {
token : "comment.doc.tag",
regex : "@[\\w\\d_]+"
}, {
token : "comment.doc",
regex : "\s+"
}, {
token : "comment.doc",
regex : "[^@\\*]+"
}, {
token : "comment.doc",
regex : "."
}]
};
};
oop.inherits(DocCommentHighlightRules, TextHighlightRules);
(function() {
this.getStartRule = function(start) {
return {
token : "comment.doc", // doc comment
regex : "\\/\\*\\*",
next: start
};
};
}).call(DocCommentHighlightRules.prototype);
return DocCommentHighlightRules;
});

72
lib/ace/mode/Html.js Normal file
View file

@ -0,0 +1,72 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/mode/Html",
[
"ace/lib/oop",
"ace/mode/Text",
"ace/mode/JavaScript",
"ace/mode/Css",
"ace/Tokenizer",
"ace/mode/HtmlHighlightRules"
], function(oop, TextMode, JavaScriptMode, CssMode, Tokenizer, HtmlHighlightRules) {
var Html = function() {
this.$tokenizer = new Tokenizer(new HtmlHighlightRules().getRules());
this.$js = new JavaScriptMode();
this.$css = new CssMode();
};
oop.inherits(Html, TextMode);
(function() {
this.toggleCommentLines = function(state, doc, range) {
return this.$delegate("toggleCommentLines", arguments, function() {
return 0;
});
};
this.getNextLineIndent = function(state, line, tab) {
var self = this;
return this.$delegate("getNextLineIndent", arguments, function() {
return self.$getIndent(line);
});
};
this.checkOutdent = function(state, line, input) {
return this.$delegate("checkOutdent", arguments, function() {
return false;
});
};
this.autoOutdent = function(state, doc, row) {
return this.$delegate("autoOutdent", arguments);
};
this.$delegate = function(method, args, defaultHandler) {
var state = args[0];
var split = state.split("js-");
if (!split[0] && split[1]) {
args[0] = split[1];
return this.$js[method].apply(this.$js, args);
}
var split = state.split("css-");
if (!split[0] && split[1]) {
args[0] = split[1];
return this.$css[method].apply(this.$css, args);
}
return defaultHandler ? defaultHandler() : undefined;
};
}).call(Html.prototype);
return Html;
});

View file

@ -0,0 +1,153 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/mode/HtmlHighlightRules",
[
"ace/lib/oop",
"ace/mode/CssHighlightRules",
"ace/mode/JavaScriptHighlightRules",
"ace/mode/TextHighlightRules"
], function(oop, CssHighlightRules, JavaScriptHighlightRules, TextHighlightRules) {
var HtmlHighlightRules = function() {
// regexp must not have capturing parentheses
// regexps are ordered -> the first match is used
this.$rules = {
start : [ {
token : "text",
regex : "<\\!\\[CDATA\\[",
next : "cdata"
}, {
token : "xml_pe",
regex : "<\\?.*?\\?>"
}, {
token : "comment",
regex : "<\\!--",
next : "comment"
}, {
token : "text",
regex : "<(?=\s*script)",
next : "script"
}, {
token : "text",
regex : "<(?=\s*style)",
next : "css"
}, {
token : "text", // opening tag
regex : "<\\/?",
next : "tag"
}, {
token : "text",
regex : "\\s+"
}, {
token : "text",
regex : "[^<]+"
} ],
script : [ {
token : "text",
regex : ">",
next : "js-start"
}, {
token : "keyword",
regex : "[-_a-zA-Z0-9:]+"
}, {
token : "text",
regex : "\\s+"
}, {
token : "string",
regex : '".*?"'
}, {
token : "string",
regex : "'.*?'"
} ],
css : [ {
token : "text",
regex : ">",
next : "css-start"
}, {
token : "keyword",
regex : "[-_a-zA-Z0-9:]+"
}, {
token : "text",
regex : "\\s+"
}, {
token : "string",
regex : '".*?"'
}, {
token : "string",
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 : ".+"
} ]
};
var jsRules = new JavaScriptHighlightRules().getRules();
this.addRules(jsRules, "js-");
this.$rules["js-start"].unshift({
token: "comment",
regex: "\\/\\/.*(?=<\\/script>)",
next: "tag"
}, {
token: "text",
regex: "<\\/(?=script)",
next: "tag"
});
var cssRules = new CssHighlightRules().getRules();
this.addRules(cssRules, "css-");
this.$rules["css-start"].unshift({
token: "text",
regex: "<\\/(?=style)",
next: "tag"
});
};
oop.inherits(HtmlHighlightRules, TextHighlightRules);
return HtmlHighlightRules;
});

View file

@ -0,0 +1,98 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/mode/JavaScript",
[
"ace/lib/oop",
"ace/mode/Text",
"ace/Tokenizer",
"ace/mode/JavaScriptHighlightRules",
"ace/mode/MatchingBraceOutdent",
"ace/Range"
], function(oop, TextMode, Tokenizer, JavaScriptHighlightRules, MatchingBraceOutdent, Range) {
var JavaScript = function() {
this.$tokenizer = new Tokenizer(new JavaScriptHighlightRules().getRules());
this.$outdent = new MatchingBraceOutdent();
};
oop.inherits(JavaScript, TextMode);
(function() {
this.toggleCommentLines = function(state, doc, range) {
var outdent = true;
var outentedRows = [];
var re = /^(\s*)\/\//;
for (var i=range.start.row; i<= range.end.row; i++) {
if (!re.test(doc.getLine(i))) {
outdent = false;
break;
}
}
if (outdent) {
var deleteRange = new Range(0, 0, 0, 0);
for (var i=range.start.row; i<= range.end.row; i++)
{
var line = doc.getLine(i).replace(re, "$1");
deleteRange.start.row = i;
deleteRange.end.row = i;
deleteRange.end.column = line.length + 2;
doc.replace(deleteRange, line);
}
return -2;
}
else {
return doc.indentRows(range, "//");
}
};
this.getNextLineIndent = function(state, line, tab) {
var indent = this.$getIndent(line);
var tokenizedLine = this.$tokenizer.getLineTokens(line, state);
var tokens = tokenizedLine.tokens;
var endState = tokenizedLine.state;
if (tokens.length && tokens[tokens.length-1].type == "comment") {
return indent;
}
if (state == "start") {
var match = line.match(/^.*[\{\(\[]\s*$/);
if (match) {
indent += tab;
}
} else if (state == "doc-start") {
if (endState == "start") {
return "";
}
var match = line.match(/^\s*(\/?)\*/);
if (match) {
if (match[1]) {
indent += " ";
}
indent += "* ";
}
}
return indent;
};
this.checkOutdent = function(state, line, input) {
return this.$outdent.checkOutdent(line, input);
};
this.autoOutdent = function(state, doc, row) {
return this.$outdent.autoOutdent(doc, row);
};
}).call(JavaScript.prototype);
return JavaScript;
});

View file

@ -0,0 +1,135 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/mode/JavaScriptHighlightRules",
[
"ace/lib/oop",
"ace/lib/lang",
"ace/mode/DocCommentHighlightRules",
"ace/mode/TextHighlightRules"
], function(oop, lang, DocCommentHighlightRules, TextHighlightRules) {
JavaScriptHighlightRules = function() {
var docComment = new DocCommentHighlightRules();
var keywords = lang.arrayToMap(
("break|case|catch|continue|default|delete|do|else|finally|for|function|" +
"if|in|instanceof|new|return|switch|throw|try|typeof|var|while|with").split("|")
);
var buildinConstants = lang.arrayToMap(
("true|false|null|undefined|Infinity|NaN|undefined").split("|")
);
var futureReserved = lang.arrayToMap(
("class|enum|extends|super|const|export|import|implements|let|private|" +
"public|yield|interface|package|protected|static").split("|")
);
// regexp must not have capturing parentheses. Use (?:) instead.
// regexps are ordered -> the first match is used
this.$rules = {
"start" : [ {
token : "comment",
regex : "\\/\\/.*$"
},
docComment.getStartRule("doc-start"),
{
token : "comment", // multi line comment
regex : "\\/\\*",
next : "comment"
}, {
token : "string.regexp",
regex : "[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/][gimy]*\\s*(?=[).;]|$)"
}, {
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 : "constant.numeric", // hex
regex : "0[xX][0-9a-fA-F]+\\b"
}, {
token : "constant.numeric", // float
regex : "[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"
}, {
token : function(value) {
if (value == "this")
return "variable.language";
else if (keywords[value])
return "keyword";
else if (buildinConstants[value])
return "constant.language";
else if (futureReserved[value])
return "invalid.illegal";
else if (value == "debugger")
return "invalid.deprecated";
else
return "identifier";
},
// TODO: Unicode escape sequences
// TODO: Unicode identifiers
regex : "[a-zA-Z_$][a-zA-Z0-9_$]*\\b"
}, {
token : "keyword.operator",
regex : "!|\\$|%|&|\\*|\\-\\-|\\-|\\+\\+|\\+|~|===|==|=|!=|!==|<=|>=|<<=|>>=|>>>=|<>|<|>|!|&&|\\|\\||\\?\\:|\\*=|%=|\\+=|\\-=|&=|\\^=|\\b(in|instanceof|new|delete|typeof|void)"
}, {
token : "lparen",
regex : "[\\[\\(\\{]"
}, {
token : "rparen",
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 : '.+'
} ]
};
this.addRules(docComment.getRules(), "doc-");
this.$rules["doc-start"][0].next = "start";
};
oop.inherits(JavaScriptHighlightRules, TextHighlightRules);
return JavaScriptHighlightRules;
});

View file

@ -0,0 +1,52 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/mode/MatchingBraceOutdent",
["ace/Range"],
function(Range) {
var MatchingBraceOutdent = function() {};
(function() {
this.checkOutdent = function(line, input) {
if (! /^\s+$/.test(line))
return false;
return /^\s*\}/.test(input);
};
this.autoOutdent = function(doc, row) {
var line = doc.getLine(row);
var match = line.match(/^(\s*\})/);
if (!match) return 0;
var column = match[1].length;
var openBracePos = doc.findMatchingBracket({row: row, column: column});
if (!openBracePos || openBracePos.row == row) return 0;
var indent = this.$getIndent(doc.getLine(openBracePos.row));
doc.replace(new Range(row, 0, row, column-1), indent);
return indent.length - (column-1);
};
this.$getIndent = function(line) {
var match = line.match(/^(\s+)/);
if (match) {
return match[1];
}
return "";
};
}).call(MatchingBraceOutdent.prototype);
return MatchingBraceOutdent;
});

51
lib/ace/mode/Text.js Normal file
View file

@ -0,0 +1,51 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/mode/Text",
[
"ace/Tokenizer",
"ace/mode/TextHighlightRules",
], function(Tokenizer, TextHighlightRules) {
var Text = function() {
this.$tokenizer = new Tokenizer(new TextHighlightRules().getRules());
};
(function() {
this.getTokenizer = function() {
return this.$tokenizer;
};
this.toggleCommentLines = function(state, doc, range) {
return 0;
};
this.getNextLineIndent = function(state, line, tab) {
return "";
};
this.checkOutdent = function(state, line, input) {
return false;
};
this.autoOutdent = function(state, doc, row) {
};
this.$getIndent = function(line) {
var match = line.match(/^(\s+)/);
if (match) {
return match[1];
}
return "";
};
}).call(Text.prototype);
return Text;
});

View file

@ -0,0 +1,47 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/mode/TextHighlightRules", [], function() {
var TextHighlightRules = function() {
// regexp must not have capturing parentheses
// regexps are ordered -> the first match is used
this.$rules = {
"start" : [ {
token : "text",
regex : ".+"
} ]
};
};
(function() {
this.addRules = function(rules, prefix) {
for (var key in rules) {
var state = rules[key];
for (var i=0; i<state.length; i++) {
var rule = state[i];
if (rule.next) {
rule.next = prefix + rule.next;
} else {
rule.next = prefix + key;
}
}
this.$rules[prefix + key] = state;
}
};
this.getRules = function() {
return this.$rules;
};
}).call(TextHighlightRules.prototype);
return TextHighlightRules;
});

31
lib/ace/mode/Xml.js Normal file
View file

@ -0,0 +1,31 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/mode/Xml",
[
"ace/lib/oop",
"ace/mode/Text",
"ace/Tokenizer",
"ace/mode/XmlHighlightRules"
], function(oop, TextMode, Tokenizer, XmlHighlightRules) {
var Xml = function() {
this.$tokenizer = new Tokenizer(new XmlHighlightRules().getRules());
};
oop.inherits(Xml, TextMode);
(function() {
this.getNextLineIndent = function(state, line, tab) {
return this.$getIndent(line);
};
}).call(Xml.prototype);
return Xml;
});

View file

@ -0,0 +1,89 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def("ace/mode/XmlHighlightRules",
[
"ace/lib/oop",
"ace/mode/TextHighlightRules"
], function(oop, TextHighlightRules) {
var XmlHighlightRules = function() {
// regexp must not have capturing parentheses
// regexps are ordered -> the first match is used
this.$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 : ".+"
} ]
};
};
/fd/g
oop.inherits(XmlHighlightRules, TextHighlightRules);
return XmlHighlightRules;
});

View file

@ -0,0 +1,130 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/Document",
"ace/Editor",
"ace/mode/Text",
"ace/mode/JavaScript",
"ace/test/MockRenderer"
], function(
Document,
Editor,
TextMode,
JavaScriptMode,
MockRenderer
) {
var ChangeDocumentTest = new TestCase("ChangeDocumentTest", {
setUp : function() {
this.doc1 = new Document(["abc", "def"].join("\n"));
this.doc2 = new Document(["ghi", "jkl"].join("\n"));
this.editor = new Editor(new MockRenderer());
},
"test: change document" : function() {
this.editor.setDocument(this.doc1);
assertEquals(this.doc1, this.editor.getDocument());
this.editor.setDocument(this.doc2);
assertEquals(this.doc2, this.editor.getDocument());
},
"test: only changes to the new document should have effect" : function() {
var called = false;
this.editor.onDocumentChange = function() {
called = true;
};
this.editor.setDocument(this.doc1);
this.editor.setDocument(this.doc2);
this.doc1.duplicateLines(0, 0);
assertFalse(called);
this.doc2.duplicateLines(0, 0);
assertTrue(called);
},
"test: should use cursor of new document" : function() {
this.doc1.getSelection().moveCursorTo(0, 1);
this.doc2.getSelection().moveCursorTo(1, 0);
this.editor.setDocument(this.doc1);
assertPosition(0, 1, this.editor.getCursorPosition());
this.editor.setDocument(this.doc2);
assertPosition(1, 0, this.editor.getCursorPosition());
},
"test: only changing the cursor of the new doc should not have an effect" : function() {
this.editor.onCursorChange = function() {
called = true;
};
this.editor.setDocument(this.doc1);
this.editor.setDocument(this.doc2);
assertPosition(0, 0, this.editor.getCursorPosition());
var called = false;
this.doc1.getSelection().moveCursorTo(0, 1);
assertPosition(0, 0, this.editor.getCursorPosition());
assertFalse(called);
this.doc2.getSelection().moveCursorTo(1, 1);
assertPosition(1, 1, this.editor.getCursorPosition());
assertTrue(called);
},
"test: should use selection of new document" : function() {
this.doc1.getSelection().selectTo(0, 1);
this.doc2.getSelection().selectTo(1, 0);
this.editor.setDocument(this.doc1);
assertPosition(0, 1, this.editor.getSelection().getSelectionLead());
this.editor.setDocument(this.doc2);
assertPosition(1, 0, this.editor.getSelection().getSelectionLead());
},
"test: only changing the selection of the new doc should not have an effect" : function() {
this.editor.onSelectionChange = function() {
called = true;
};
this.editor.setDocument(this.doc1);
this.editor.setDocument(this.doc2);
assertPosition(0, 0, this.editor.getSelection().getSelectionLead());
var called = false;
this.doc1.getSelection().selectTo(0, 1);
assertPosition(0, 0, this.editor.getSelection().getSelectionLead());
assertFalse(called);
this.doc2.getSelection().selectTo(1, 1);
assertPosition(1, 1, this.editor.getSelection().getSelectionLead());
assertTrue(called);
},
"test: should use mode of new document" : function() {
this.editor.onDocumentModeChange = function() {
called = true;
};
this.editor.setDocument(this.doc1);
this.editor.setDocument(this.doc2);
var called = false;
this.doc1.setMode(new Text());
assertFalse(called);
this.doc2.setMode(new JavaScriptMode());
assertTrue(called);
}
});
});

View file

@ -0,0 +1,234 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/Document",
"ace/UndoManager",
"ace/Editor",
"ace/test/MockRenderer"
], function(
Document,
UndoManager,
Editor,
MockRenderer
) {
var TextDocumentTest = new TestCase("TextDocumentTest", {
"test: find matching opening bracket" : function() {
var doc = new Document(["(()(", "())))"]);
assertPosition(0, 1, doc.findMatchingBracket({row: 0, column: 3}));
assertPosition(1, 0, doc.findMatchingBracket({row: 1, column: 2}));
assertPosition(0, 3, doc.findMatchingBracket({row: 1, column: 3}));
assertPosition(0, 0, doc.findMatchingBracket({row: 1, column: 4}));
assertEquals(null, doc.findMatchingBracket({row: 1, column: 5}));
},
"test: find matching closing bracket" : function() {
var doc = new Document(["(()(", "())))"]);
assertPosition(1, 1, doc.findMatchingBracket({row: 1, column: 1}));
assertPosition(1, 1, doc.findMatchingBracket({row: 1, column: 1}));
assertPosition(1, 2, doc.findMatchingBracket({row: 0, column: 4}));
assertPosition(0, 2, doc.findMatchingBracket({row: 0, column: 2}));
assertPosition(1, 3, doc.findMatchingBracket({row: 0, column: 1}));
assertEquals(null, doc.findMatchingBracket({row: 0, column: 0}));
},
"test: match different bracket types" : function() {
var doc = new Document(["({[", ")]}"]);
assertPosition(1, 0, doc.findMatchingBracket({row: 0, column: 1}));
assertPosition(1, 2, doc.findMatchingBracket({row: 0, column: 2}));
assertPosition(1, 1, doc.findMatchingBracket({row: 0, column: 3}));
assertPosition(0, 0, doc.findMatchingBracket({row: 1, column: 1}));
assertPosition(0, 2, doc.findMatchingBracket({row: 1, column: 2}));
assertPosition(0, 1, doc.findMatchingBracket({row: 1, column: 3}));
},
"test: move lines down" : function() {
var doc = new Document(["1", "2", "3", "4"]);
doc.moveLinesDown(0, 1);
assertEquals(["3", "1", "2", "4"].join("\n"), doc.toString());
doc.moveLinesDown(1, 2);
assertEquals(["3", "4", "1", "2"].join("\n"), doc.toString());
doc.moveLinesDown(2, 3);
assertEquals(["3", "4", "1", "2"].join("\n"), doc.toString());
doc.moveLinesDown(2, 2);
assertEquals(["3", "4", "2", "1"].join("\n"), doc.toString());
},
"test: move lines up" : function() {
var doc = new Document(["1", "2", "3", "4"]);
doc.moveLinesUp(2, 3);
assertEquals(["1", "3", "4", "2"].join("\n"), doc.toString());
doc.moveLinesUp(1, 2);
assertEquals(["3", "4", "1", "2"].join("\n"), doc.toString());
doc.moveLinesUp(0, 1);
assertEquals(["3", "4", "1", "2"].join("\n"), doc.toString());
doc.moveLinesUp(2, 2);
assertEquals(["3", "1", "4", "2"].join("\n"), doc.toString());
},
"test: duplicate lines" : function() {
var doc = new Document(["1", "2", "3", "4"]);
doc.duplicateLines(1, 2);
assertEquals(["1", "2", "3", "2", "3", "4"].join("\n"), doc.toString());
},
"test: duplicate last line" : function() {
var doc = new Document(["1", "2", "3"]);
doc.duplicateLines(2, 2);
assertEquals(["1", "2", "3", "3"].join("\n"), doc.toString());
},
"test: duplicate first line" : function() {
var doc = new Document(["1", "2", "3"]);
doc.duplicateLines(0, 0);
assertEquals(["1", "1", "2", "3"].join("\n"), doc.toString());
},
"test: should handle unix style new lines" : function() {
var doc = new Document(["1", "2", "3"]);
assertEquals(["1", "2", "3"].join("\n"), doc.toString());
},
"test: should handle windows style new lines" : function() {
var doc = new Document(["1", "2", "3"].join("\r\n"));
doc.setNewLineMode("unix");
assertEquals(["1", "2", "3"].join("\n"), doc.toString());
},
"test: set new line mode to 'windows' should use '\r\n' as new lines": function() {
var doc = new Document(["1", "2", "3"].join("\n"));
doc.setNewLineMode("windows");
assertEquals(["1", "2", "3"].join("\r\n"), doc.toString());
},
"test: set new line mode to 'unix' should use '\n' as new lines": function() {
var doc = new Document(["1", "2", "3"].join("\r\n"));
doc.setNewLineMode("unix");
assertEquals(["1", "2", "3"].join("\n"), doc.toString());
},
"test: set new line mode to 'auto' should use detect the incoming nl type": function() {
var doc = new Document(["1", "2", "3"].join("\n"));
doc.setNewLineMode("auto");
assertEquals(["1", "2", "3"].join("\n"), doc.toString());
var doc = new Document(["1", "2", "3"].join("\r\n"));
doc.setNewLineMode("auto");
assertEquals(["1", "2", "3"].join("\r\n"), doc.toString());
doc.replace(new Range(0, 0, 2, 1), ["4", "5", "6"].join("\n"));
assertEquals(["4", "5", "6"].join("\n"), doc.toString());
},
"test: undo/redo for delete line" : function() {
var doc = new Document(["111", "222", "333"]);
var undoManager = new UndoManager();
doc.setUndoManager(undoManager);
var initialText = doc.toString();
var editor = new Editor(new MockRenderer(), doc);
editor.removeLines();
var step1 = doc.toString();
assertEquals("222\n333", step1);
doc.$informUndoManager.call();
editor.removeLines();
var step2 = doc.toString();
assertEquals("333", step2);
doc.$informUndoManager.call();
editor.removeLines();
var step3 = doc.toString();
assertEquals("", step3);
doc.$informUndoManager.call();
undoManager.undo();
doc.$informUndoManager.call();
assertEquals(step2, doc.toString());
undoManager.undo();
doc.$informUndoManager.call();
assertEquals(step1, doc.toString());
undoManager.undo();
doc.$informUndoManager.call();
assertEquals(initialText, doc.toString());
undoManager.undo();
doc.$informUndoManager.call();
assertEquals(initialText, doc.toString());
},
"test: convert document to screen coordinates" : function() {
var doc = new Document("01234\t567890\t1234");
doc.setTabSize(4);
assertEquals(0, doc.documentToScreenColumn(0, 0));
assertEquals(4, doc.documentToScreenColumn(0, 4));
assertEquals(5, doc.documentToScreenColumn(0, 5));
assertEquals(9, doc.documentToScreenColumn(0, 6));
assertEquals(15, doc.documentToScreenColumn(0, 12));
assertEquals(19, doc.documentToScreenColumn(0, 13));
doc.setTabSize(2);
assertEquals(0, doc.documentToScreenColumn(0, 0));
assertEquals(4, doc.documentToScreenColumn(0, 4));
assertEquals(5, doc.documentToScreenColumn(0, 5));
assertEquals(7, doc.documentToScreenColumn(0, 6));
assertEquals(13, doc.documentToScreenColumn(0, 12));
assertEquals(15, doc.documentToScreenColumn(0, 13));
},
"test: convert document to scrren coordinates with leading tabs": function() {
var doc = new Document("\t\t123");
doc.setTabSize(4);
assertEquals(0, doc.documentToScreenColumn(0, 0));
assertEquals(4, doc.documentToScreenColumn(0, 1));
assertEquals(8, doc.documentToScreenColumn(0, 2));
assertEquals(9, doc.documentToScreenColumn(0, 3));
},
"test: convert screen to document coordinates" : function() {
var doc = new Document("01234\t567890\t1234");
doc.setTabSize(4);
assertEquals(0, doc.screenToDocumentColumn(0, 0));
assertEquals(4, doc.screenToDocumentColumn(0, 4));
assertEquals(5, doc.screenToDocumentColumn(0, 5));
assertEquals(5, doc.screenToDocumentColumn(0, 6));
assertEquals(5, doc.screenToDocumentColumn(0, 7));
assertEquals(5, doc.screenToDocumentColumn(0, 8));
assertEquals(6, doc.screenToDocumentColumn(0, 9));
assertEquals(12, doc.screenToDocumentColumn(0, 15));
assertEquals(13, doc.screenToDocumentColumn(0, 19));
}
});
});

View file

@ -0,0 +1,36 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/lib/oop",
"ace/MEventEmitter"
], function(
oop,
MEventEmitter
) {
var EventEmitter = function() {};
oop.implement(EventEmitter.prototype, MEventEmitter);
var EventEmitterTest = new TestCase("EventEmitterTest", {
"test: dispatch event with no data" : function() {
var emitter = new EventEmitter();
var called = false;
emitter.addEventListener("juhu", function(e) {
called = true;
assertEquals("juhu", e.type);
});
emitter.$dispatchEvent("juhu");
assertTrue(called);
}
});
});

View file

@ -0,0 +1,88 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([], function() {
MockRenderer = function(visibleRowCount) {
this.container = document.createElement("div");
this.cursor = {
row : 0,
column : 0
};
this.visibleRowCount = visibleRowCount || 20;
this.layerConfig = {
firstVisibleRow : 0,
lastVisibleRow : this.visibleRowCount
};
};
MockRenderer.prototype.getFirstVisibleRow = function() {
return this.layerConfig.firstVisibleRow;
};
MockRenderer.prototype.getLastVisibleRow = function() {
return this.layerConfig.lastVisibleRow;
};
MockRenderer.prototype.getContainerElement = function() {
return this.container;
};
MockRenderer.prototype.getMouseEventTarget = function() {
return this.container;
};
MockRenderer.prototype.setDocument = function(doc) {
this.lines = doc.lines;
};
MockRenderer.prototype.setTokenizer = function() {
};
MockRenderer.prototype.updateCursor = function(position) {
this.cursor.row = position.row;
this.cursor.column = position.column;
};
MockRenderer.prototype.scrollCursorIntoView = function() {
if (this.cursor.row < this.layerConfig.firstVisibleRow) {
this.scrollToRow(this.cursor.row);
}
else if (this.cursor.row > this.layerConfig.lastVisibleRow) {
this.scrollToRow(this.cursor.row);
}
};
MockRenderer.prototype.scrollToRow = function(row) {
var row = Math.min(this.lines.length - this.visibleRowCount, Math.max(0,
row));
this.layerConfig.firstVisibleRow = row;
this.layerConfig.lastVisibleRow = row + this.visibleRowCount;
};
MockRenderer.prototype.getScrollTopRow = function() {
return this.layerConfig.firstVisibleRow;
};
MockRenderer.prototype.draw = function() {
};
MockRenderer.prototype.updateLines = function(startRow, endRow) {
};
MockRenderer.prototype.addMarker = function() {
};
MockRenderer.prototype.setBreakpoints = function() {
};
return MockRenderer;
});

View file

@ -0,0 +1,126 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/Document",
"ace/Editor",
"ace/test/MockRenderer"
], function(
Document,
Editor,
MockRenderer
) {
var NavigationTest = TestCase("NavigationTest",
{
createTextDocument : function(rows, cols) {
var line = new Array(cols + 1).join("a");
var text = new Array(rows).join(line + "\n") + line;
return new Document(text);
},
"test: navigate to end of file should scroll the last line into view" : function() {
var doc = this.createTextDocument(200, 10);
var editor = new Editor(new MockRenderer(), doc);
editor.navigateFileEnd();
var cursor = editor.getCursorPosition();
assertTrue(editor.getFirstVisibleRow() <= cursor.row);
assertTrue(editor.getLastVisibleRow() >= cursor.row);
},
"test: navigate to start of file should scroll the first row into view" : function() {
var doc = this.createTextDocument(200, 10);
var editor = new Editor(new MockRenderer(), doc);
editor.moveCursorTo(editor.getLastVisibleRow() + 20);
editor.navigateFileStart();
assertEquals(0, editor.getFirstVisibleRow());
},
"test: goto hidden line should scroll the line into the middle of the viewport" : function() {
var editor = new Editor(new MockRenderer(), this.createTextDocument(200, 5));
editor.navigateTo(0, 0);
editor.gotoLine(101);
assertPosition(100, 0, editor.getCursorPosition());
assertEquals(90, editor.getFirstVisibleRow());
editor.navigateTo(100, 0);
editor.gotoLine(11);
assertPosition(10, 0, editor.getCursorPosition());
assertEquals(0, editor.getFirstVisibleRow());
editor.navigateTo(100, 0);
editor.gotoLine(6);
assertPosition(5, 0, editor.getCursorPosition());
assertEquals(0, editor.getFirstVisibleRow());
editor.navigateTo(100, 0);
editor.gotoLine(1);
assertPosition(0, 0, editor.getCursorPosition());
assertEquals(0, editor.getFirstVisibleRow());
editor.navigateTo(0, 0);
editor.gotoLine(191);
assertPosition(190, 0, editor.getCursorPosition());
assertEquals(180, editor.getFirstVisibleRow());
editor.navigateTo(0, 0);
editor.gotoLine(196);
assertPosition(195, 0, editor.getCursorPosition());
assertEquals(180, editor.getFirstVisibleRow());
},
"test: goto visible line should only move the cursor and not scroll": function() {
var editor = new Editor(new MockRenderer(), this.createTextDocument(200, 5));
editor.navigateTo(0, 0);
editor.gotoLine(12);
assertPosition(11, 0, editor.getCursorPosition());
assertEquals(0, editor.getFirstVisibleRow());
editor.navigateTo(30, 0);
editor.gotoLine(33);
assertPosition(32, 0, editor.getCursorPosition());
assertEquals(30, editor.getFirstVisibleRow());
},
"test: navigate from the end of a long line down to a short line and back should maintain the curser column": function() {
var editor = new Editor(new MockRenderer(), new Document(["123456", "1"]));
editor.navigateTo(0, 6);
assertPosition(0, 6, editor.getCursorPosition());
editor.navigateDown();
assertPosition(1, 1, editor.getCursorPosition());
editor.navigateUp();
assertPosition(0, 6, editor.getCursorPosition());
},
"test: reset desired column on navigate left or right": function() {
var editor = new Editor(new MockRenderer(), new Document(["123456", "12"]));
editor.navigateTo(0, 6);
assertPosition(0, 6, editor.getCursorPosition());
editor.navigateDown();
assertPosition(1, 2, editor.getCursorPosition());
editor.navigateLeft();
assertPosition(1, 1, editor.getCursorPosition());
editor.navigateUp();
assertPosition(0, 1, editor.getCursorPosition());
}
});
});

123
lib/ace/test/RangeTest.js Normal file
View file

@ -0,0 +1,123 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/Range"
], function(
Range
) {
RangeTest = new TestCase("RangeTest", {
"test: create range": function() {
var range = new Range(1,2,3,4);
assertEquals(1, range.start.row);
assertEquals(2, range.start.column);
assertEquals(3, range.end.row);
assertEquals(4, range.end.column);
},
"test: create from points": function() {
var range = Range.fromPoints({row: 1, column: 2}, {row:3, column:4});
assertEquals(1, range.start.row);
assertEquals(2, range.start.column);
assertEquals(3, range.end.row);
assertEquals(4, range.end.column);
},
"test: clip to rows": function() {
assertRange(10, 0, 31, 0, new Range(0, 20, 100, 30).clipRows(10, 30));
assertRange(10, 0, 30, 10, new Range(0, 20, 30, 10).clipRows(10, 30));
var range = new Range(0, 20, 3, 10);
var range = range.clipRows(10, 30);
assertTrue(range.isEmpty());
assertRange(10, 0, 10, 0, range);
},
"test: isEmpty": function() {
var range = new Range(1, 2, 1, 2);
assertTrue(range.isEmpty());
var range = new Range(1, 2, 1, 6);
assertFalse(range.isEmpty());
},
"test: is multi line": function() {
var range = new Range(1, 2, 1, 6);
assertFalse(range.isMultiLine());
var range = new Range(1, 2, 2, 6);
assertTrue(range.isMultiLine());
},
"test: clone": function() {
var range = new Range(1, 2, 3, 4);
var clone = range.clone();
assertPosition(1, 2, clone.start);
assertPosition(3, 4, clone.end);
clone.start.column = 20;
assertPosition(1, 2, range.start);
clone.end.column = 20;
assertPosition(3, 4, range.end);
},
"test: contains for multi line ranges": function() {
var range = new Range(1, 10, 5, 20);
assertTrue(range.contains(1, 10));
assertTrue(range.contains(2, 0));
assertTrue(range.contains(3, 100));
assertTrue(range.contains(5, 19));
assertTrue(range.contains(5, 20));
assertFalse(range.contains(1, 9));
assertFalse(range.contains(0, 0));
assertFalse(range.contains(5, 21));
},
"test: contains for single line ranges": function() {
var range = new Range(1, 10, 1, 20);
assertTrue(range.contains(1, 10));
assertTrue(range.contains(1, 15));
assertTrue(range.contains(1, 20));
assertFalse(range.contains(0, 9));
assertFalse(range.contains(2, 9));
assertFalse(range.contains(1, 9));
assertFalse(range.contains(1, 21));
},
"test: extend range": function() {
var range = new Range(2, 10, 2, 30);
var range = range.extend(2, 5);
assertRange(2, 5, 2, 30, range);
var range = range.extend(2, 35);
assertRange(2, 5, 2, 35, range);
var range = range.extend(2, 15);
assertRange(2, 5, 2, 35, range);
var range = range.extend(1, 4);
assertRange(1, 4, 2, 35, range);
var range = range.extend(6, 10);
assertRange(1, 4, 6, 10, range);
}
});
});

322
lib/ace/test/SearchTest.js Normal file
View file

@ -0,0 +1,322 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/Document",
"ace/Search"
], function(
Document,
Search
) {
var SearchTest = new TestCase("SearchTest", {
"test: configure the search object" : function() {
var search = new Search();
search.set({
needle: "juhu",
scope: Search.ALL
});
},
"test: find simple text in document" : function() {
var doc = new Document(["juhu kinners 123", "456"]);
var search = new Search().set({
needle: "kinners"
});
var range = search.find(doc);
assertPosition(0, 5, range.start);
assertPosition(0, 12, range.end);
},
"test: find simple text in next line" : function() {
var doc = new Document(["abc", "juhu kinners 123", "456"]);
var search = new Search().set({
needle: "kinners"
});
var range = search.find(doc);
assertPosition(1, 5, range.start);
assertPosition(1, 12, range.end);
},
"test: find text starting at cursor position" : function() {
var doc = new Document(["juhu kinners", "juhu kinners 123"]);
doc.getSelection().moveCursorTo(0, 6);
var search = new Search().set({
needle: "kinners"
});
var range = search.find(doc);
assertPosition(1, 5, range.start);
assertPosition(1, 12, range.end);
},
"test: wrap search is off by default" : function() {
var doc = new Document(["abc", "juhu kinners 123", "456"]);
doc.getSelection().moveCursorTo(2, 1);
var search = new Search().set({
needle: "kinners"
});
assertEquals(null, search.find(doc));
},
"test: wrap search should wrap at file end" : function() {
var doc = new Document(["abc", "juhu kinners 123", "456"]);
doc.getSelection().moveCursorTo(2, 1);
var search = new Search().set({
needle: "kinners",
wrap: true
});
var range = search.find(doc);
assertPosition(1, 5, range.start);
assertPosition(1, 12, range.end);
},
"test: wrap search with no match should return 'null'": function() {
var doc = new Document(["abc", "juhu kinners 123", "456"]);
doc.getSelection().moveCursorTo(2, 1);
var search = new Search().set({
needle: "xyz",
wrap: true
});
assertEquals(null, search.find(doc));
},
"test: case sensitive is by default off": function() {
var doc = new Document(["abc", "juhu kinners 123", "456"]);
var search = new Search().set({
needle: "JUHU"
});
assertEquals(null, search.find(doc));
},
"test: case sensitive search": function() {
var doc = new Document(["abc", "juhu kinners 123", "456"]);
var search = new Search().set({
needle: "KINNERS",
caseSensitive: true
});
var range = search.find(doc);
assertPosition(1, 5, range.start);
assertPosition(1, 12, range.end);
},
"test: whole word search should not match inside of words": function() {
var doc = new Document(["juhukinners", "juhu kinners 123", "456"]);
var search = new Search().set({
needle: "kinners",
wholeWord: true
});
var range = search.find(doc);
assertPosition(1, 5, range.start);
assertPosition(1, 12, range.end);
},
"test: find backwards": function() {
var doc = new Document(["juhu juhu juhu juhu"]);
doc.getSelection().moveCursorTo(0, 10);
var search = new Search().set({
needle: "juhu",
backwards: true
});
var range = search.find(doc);
assertPosition(0, 5, range.start);
assertPosition(0, 9, range.end);
},
"test: find in selection": function() {
var doc = new Document(["juhu", "juhu", "juhu", "juhu"]);
doc.getSelection().setSelectionAnchor(1, 0);
doc.getSelection().selectTo(3, 5);
var search = new Search().set({
needle: "juhu",
wrap: true,
scope: Search.SELECTION
});
var range = search.find(doc);
assertPosition(1, 0, range.start);
assertPosition(1, 4, range.end);
doc.getSelection().setSelectionAnchor(0, 2);
doc.getSelection().selectTo(3, 2);
var range = search.find(doc);
assertPosition(1, 0, range.start);
assertPosition(1, 4, range.end);
},
"test: find backwards in selection": function() {
var doc = new Document(["juhu", "juhu", "juhu", "juhu"]);
var search = new Search().set({
needle: "juhu",
wrap: true,
backwards: true,
scope: Search.SELECTION
});
doc.getSelection().setSelectionAnchor(0, 2);
doc.getSelection().selectTo(3, 2);
var range = search.find(doc);
assertPosition(2, 0, range.start);
assertPosition(2, 4, range.end);
doc.getSelection().setSelectionAnchor(0, 2);
doc.getSelection().selectTo(1, 2);
assertEquals(null, search.find(doc));
},
"test: edge case - match directly before the cursor" : function() {
var doc = new Document(["123", "123", "juhu"]);
var search = new Search().set({
needle: "juhu",
wrap: true
});
doc.getSelection().moveCursorTo(2, 5);
var range = search.find(doc);
assertPosition(2, 0, range.start);
assertPosition(2, 4, range.end);
},
"test: edge case - match backwards directly after the cursor" : function() {
var doc = new Document(["123", "123", "juhu"]);
var search = new Search().set({
needle: "juhu",
wrap: true,
backwards: true
});
doc.getSelection().moveCursorTo(2, 0);
var range = search.find(doc);
assertPosition(2, 0, range.start);
assertPosition(2, 4, range.end);
},
"test: find using a regular expression" : function() {
var doc = new Document(["abc123 123 cd", "abc"]);
var search = new Search().set({
needle: "\\d+",
regExp: true
});
var range = search.find(doc);
assertPosition(0, 3, range.start);
assertPosition(0, 6, range.end);
},
"test: find using a regular expression and whole word" : function() {
var doc = new Document(["abc123 123 cd", "abc"]);
var search = new Search().set({
needle: "\\d+\\b",
regExp: true,
wholeWord: true
});
var range = search.find(doc);
assertPosition(0, 7, range.start);
assertPosition(0, 10, range.end);
},
"test: use regular expressions with capture groups": function() {
var doc = new Document([" ab: 12px", " <h1 abc"]);
var search = new Search().set({
needle: "(\\d+)",
regExp: true
});
var range = search.find(doc);
assertPosition(0, 6, range.start);
assertPosition(0, 8, range.end);
},
"test: find all matches in selection" : function() {
var doc = new Document(["juhu", "juhu", "juhu", "juhu"]);
var search = new Search().set({
needle: "uh",
wrap: true,
scope: Search.SELECTION
});
doc.getSelection().setSelectionAnchor(0, 2);
doc.getSelection().selectTo(3, 2);
var ranges = search.findAll(doc);
assertEquals(2, ranges.length);
assertPosition(1, 1, ranges[0].start);
assertPosition(1, 3, ranges[0].end);
assertPosition(2, 1, ranges[1].start);
assertPosition(2, 3, ranges[1].end);
},
"test: replace() should return the replacement if the input matches the needle" : function() {
var search = new Search().set({
needle: "juhu"
});
assertEquals("kinners", search.replace("juhu", "kinners"));
assertEquals(null, search.replace("", "kinners"));
assertEquals(null, search.replace(" juhu", "kinners"));
// regexp replacement
},
"test: replace with a RegExp search" : function() {
var search = new Search().set({
needle: "\\d+",
regExp: true
});
assertEquals("kinners", search.replace("123", "kinners"));
assertEquals("kinners", search.replace("01234", "kinners"));
assertEquals(null, search.replace("", "kinners"));
assertEquals(null, search.replace("a12", "kinners"));
assertEquals(null, search.replace("12a", "kinners"));
},
"test: replace with RegExp match and capture groups" : function() {
var search = new Search().set({
needle: "ab(\\d\\d)",
regExp: true
});
assertEquals("cd12", search.replace("ab12", "cd$1"));
assertEquals("-ab12-", search.replace("ab12", "-$&-"));
assertEquals("$", search.replace("ab12", "$$"));
}
});
});

View file

@ -0,0 +1,266 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/Document"
], function(
Document
) {
var SelectionTest = TestCase("SelectionTest",
{
createTextDocument : function(rows, cols) {
var line = new Array(cols + 1).join("a");
var text = new Array(rows).join(line + "\n") + line;
return new Document(text);
},
"test: move cursor to end of file should place the cursor on last row and column" : function() {
var doc = this.createTextDocument(200, 10);
var selection = doc.getSelection();
selection.moveCursorFileEnd();
assertPosition(199, 10, selection.getCursor());
},
"test: moveCursor to start of file should place the cursor on the first row and column" : function() {
var doc = this.createTextDocument(200, 10);
var selection = doc.getSelection();
selection.moveCursorFileStart();
assertPosition(0, 0, selection.getCursor());
},
"test: move selection lead to end of file" : function() {
var doc = this.createTextDocument(200, 10);
var selection = doc.getSelection();
selection.moveCursorTo(100, 5);
selection.selectFileEnd();
var range = selection.getRange();
assertPosition(100, 5, range.start);
assertPosition(199, 10, range.end);
},
"test: move selection lead to start of file" : function() {
var doc = this.createTextDocument(200, 10);
var selection = doc.getSelection();
selection.moveCursorTo(100, 5);
selection.selectFileStart();
var range = selection.getRange();
assertPosition(0, 0, range.start);
assertPosition(100, 5, range.end);
},
"test: move cursor word right" : function() {
var doc = new Document( ["ab",
" Juhu Kinners (abc, 12)", " cde"].join("\n"));
var selection = doc.getSelection();
selection.moveCursorDown();
assertPosition(1, 0, selection.getCursor());
selection.moveCursorWordRight();
assertPosition(1, 1, selection.getCursor());
selection.moveCursorWordRight();
assertPosition(1, 5, selection.getCursor());
selection.moveCursorWordRight();
assertPosition(1, 6, selection.getCursor());
selection.moveCursorWordRight();
assertPosition(1, 13, selection.getCursor());
selection.moveCursorWordRight();
assertPosition(1, 15, selection.getCursor());
selection.moveCursorWordRight();
assertPosition(1, 18, selection.getCursor());
selection.moveCursorWordRight();
assertPosition(1, 20, selection.getCursor());
selection.moveCursorWordRight();
assertPosition(1, 22, selection.getCursor());
selection.moveCursorWordRight();
assertPosition(1, 23, selection.getCursor());
// wrap line
selection.moveCursorWordRight();
assertPosition(2, 0, selection.getCursor());
},
"test: select word right if cursor in word" : function() {
var doc = new Document("Juhu Kinners");
var selection = doc.getSelection();
selection.moveCursorTo(0, 2);
selection.moveCursorWordRight();
assertPosition(0, 4, selection.getCursor());
},
"test: moveCursor word left" : function() {
var doc = new Document( ["ab",
" Juhu Kinners (abc, 12)", " cde"].join("\n"));
var selection = doc.getSelection();
selection.moveCursorDown();
selection.moveCursorLineEnd();
assertPosition(1, 23, selection.getCursor());
selection.moveCursorWordLeft();
assertPosition(1, 22, selection.getCursor());
selection.moveCursorWordLeft();
assertPosition(1, 20, selection.getCursor());
selection.moveCursorWordLeft();
assertPosition(1, 18, selection.getCursor());
selection.moveCursorWordLeft();
assertPosition(1, 15, selection.getCursor());
selection.moveCursorWordLeft();
assertPosition(1, 13, selection.getCursor());
selection.moveCursorWordLeft();
assertPosition(1, 6, selection.getCursor());
selection.moveCursorWordLeft();
assertPosition(1, 5, selection.getCursor());
selection.moveCursorWordLeft();
assertPosition(1, 1, selection.getCursor());
selection.moveCursorWordLeft();
assertPosition(1, 0, selection.getCursor());
// wrap line
selection.moveCursorWordLeft();
assertPosition(0, 2, selection.getCursor());
},
"test: select word left if cursor in word" : function() {
var doc = new Document("Juhu Kinners");
var selection = doc.getSelection();
selection.moveCursorTo(0, 8);
selection.moveCursorWordLeft();
assertPosition(0, 5, selection.getCursor());
},
"test: select word right and select" : function() {
var doc = new Document("Juhu Kinners");
var selection = doc.getSelection();
selection.moveCursorTo(0, 0);
selection.selectWordRight();
var range = selection.getRange();
assertPosition(0, 0, range.start);
assertPosition(0, 4, range.end);
},
"test: select word left and select" : function() {
var doc = new Document("Juhu Kinners");
var selection = doc.getSelection();
selection.moveCursorTo(0, 3);
selection.selectWordLeft();
var range = selection.getRange();
assertPosition(0, 0, range.start);
assertPosition(0, 3, range.end);
},
"test: select word with cursor in word should select the word" : function() {
var doc = new Document("Juhu Kinners 123");
var selection = doc.getSelection();
selection.moveCursorTo(0, 8);
selection.selectWord();
var range = selection.getRange();
assertPosition(0, 5, range.start);
assertPosition(0, 12, range.end);
},
"test: select word with cursor betwen white space and word should select the word" : function() {
var doc = new Document("Juhu Kinners");
var selection = doc.getSelection();
selection.moveCursorTo(0, 4);
selection.selectWord();
var range = selection.getRange();
assertPosition(0, 0, range.start);
assertPosition(0, 4, range.end);
selection.moveCursorTo(0, 5);
selection.selectWord();
var range = selection.getRange();
assertPosition(0, 5, range.start);
assertPosition(0, 12, range.end);
},
"test: select word with cursor in white space should select white space" : function() {
var doc = new Document("Juhu Kinners");
var selection = doc.getSelection();
selection.moveCursorTo(0, 5);
selection.selectWord();
var range = selection.getRange();
assertPosition(0, 4, range.start);
assertPosition(0, 6, range.end);
},
"test: moving cursor should fire a 'changeCursor' event" : function() {
var doc = new Document("Juhu Kinners");
var selection = doc.getSelection();
selection.moveCursorTo(0, 5);
var called = false;
selection.addEventListener("changeCursor", function() {
called = true;
});
selection.moveCursorTo(0, 6);
assertTrue(called);
},
"test: calling setCursor with the same position should not fire an event": function() {
var doc = new Document("Juhu Kinners");
var selection = doc.getSelection();
selection.moveCursorTo(0, 5);
var called = false;
selection.addEventListener("changeCursor", function() {
called = true;
});
selection.moveCursorTo(0, 5);
assertFalse(called);
}
});
});

View file

@ -0,0 +1,315 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/Document",
"ace/Editor",
"ace/mode/JavaScript",
"ace/test/MockRenderer"
], function(
Document,
Editor,
JavaScriptMode,
MockRenderer
) {
var TextEditTest = TestCase("TextEditTest",
{
"test: delete line from the middle" : function() {
var doc = new Document(["a", "b", "c", "d"].join("\n"));
var editor = new Editor(new MockRenderer(), doc);
editor.moveCursorTo(1, 1);
editor.removeLines();
assertEquals("a\nc\nd", doc.toString());
assertPosition(1, 0, editor.getCursorPosition());
editor.removeLines();
assertEquals("a\nd", doc.toString());
assertPosition(1, 0, editor.getCursorPosition());
editor.removeLines();
assertEquals("a\n", doc.toString());
assertPosition(1, 0, editor.getCursorPosition());
editor.removeLines();
assertEquals("a\n", doc.toString());
assertPosition(1, 0, editor.getCursorPosition());
},
"test: delete multiple selected lines" : function() {
var doc = new Document(["a", "b", "c", "d"].join("\n"));
var editor = new Editor(new MockRenderer(), doc);
editor.moveCursorTo(1, 1);
editor.getSelection().selectDown();
editor.removeLines();
assertEquals("a\nd", doc.toString());
assertPosition(1, 0, editor.getCursorPosition());
},
"test: delete first line" : function() {
var doc = new Document(["a", "b", "c"].join("\n"));
var editor = new Editor(new MockRenderer(), doc);
editor.removeLines();
assertEquals("b\nc", doc.toString());
assertPosition(0, 0, editor.getCursorPosition());
},
"test: delete last" : function() {
var doc = new Document(["a", "b", "c"].join("\n"));
var editor = new Editor(new MockRenderer(), doc);
editor.moveCursorTo(2, 1);
editor.removeLines();
assertEquals("a\nb\n", doc.toString());
assertPosition(2, 0, editor.getCursorPosition());
},
"test: indent block" : function() {
var doc = new Document(["a12345", "b12345", "c12345"].join("\n"));
var editor = new Editor(new MockRenderer(), doc);
editor.moveCursorTo(1, 3);
editor.getSelection().selectDown();
editor.blockIndent(" ");
assertEquals(["a12345", " b12345", " c12345"].join("\n"),
doc.toString());
assertPosition(2, 7, editor.getCursorPosition());
var range = editor.getSelectionRange();
assertPosition(1, 7, range.start);
assertPosition(2, 7, range.end);
},
"test: outdent block" : function() {
var doc = new Document([" a12345", " b12345", " c12345"].join("\n"));
var editor = new Editor(new MockRenderer(), doc);
editor.moveCursorTo(0, 3);
editor.getSelection().selectDown();
editor.getSelection().selectDown();
editor.blockOutdent(" ");
assertEquals([" a12345", "b12345", " c12345"].join("\n"),
doc.toString());
assertPosition(2, 1, editor.getCursorPosition());
var range = editor.getSelectionRange();
assertPosition(0, 1, range.start);
assertPosition(2, 1, range.end);
editor.blockOutdent(" ");
assertEquals([" a12345", "b12345", " c12345"].join("\n"),
doc.toString());
var range = editor.getSelectionRange();
assertPosition(0, 1, range.start);
assertPosition(2, 1, range.end);
},
"test: outent without a selection should update cursor" : function() {
var doc = new Document(" 12");
var editor = new Editor(new MockRenderer(), doc);
editor.moveCursorTo(0, 3);
editor.blockOutdent(" ");
assertEquals(" 12", doc.toString());
assertPosition(0, 1, editor.getCursorPosition());
},
"test: comment lines should perserve selection" : function() {
var doc = new Document([" abc", "cde"].join("\n"), new JavaScriptMode());
var editor = new Editor(new MockRenderer(), doc);
editor.moveCursorTo(0, 2);
editor.getSelection().selectDown();
editor.toggleCommentLines();
assertEquals(["// abc", "//cde"].join("\n"), doc.toString());
var selection = editor.getSelectionRange();
assertPosition(0, 4, selection.start);
assertPosition(1, 4, selection.end);
},
"test: uncomment lines should perserve selection" : function() {
var doc = new Document(["// abc", "//cde"].join("\n"), new JavaScriptMode());
var editor = new Editor(new MockRenderer(), doc);
editor.moveCursorTo(0, 1);
editor.getSelection().selectDown();
editor.getSelection().selectRight();
editor.getSelection().selectRight();
editor.toggleCommentLines();
assertEquals([" abc", "cde"].join("\n"), doc.toString());
assertRange(0, 0, 1, 1, editor.getSelectionRange());
},
"test: comment lines - if the selection end is at the line start it should stay there": function() {
//select down
var doc = new Document(["abc", "cde"].join("\n"), new JavaScriptMode());
var editor = new Editor(new MockRenderer(), doc);
editor.moveCursorTo(0, 0);
editor.getSelection().selectDown();
editor.toggleCommentLines();
assertRange(0, 2, 1, 0, editor.getSelectionRange());
// select up
var doc = new Document(["abc", "cde"].join("\n"), new JavaScriptMode());
var editor = new Editor(new MockRenderer(), doc);
editor.moveCursorTo(1, 0);
editor.getSelection().selectUp();
editor.toggleCommentLines();
assertRange(0, 2, 1, 0, editor.getSelectionRange());
},
"test: move lines down should select moved lines" : function() {
var doc = new Document(["11", "22", "33", "44"].join("\n"));
var editor = new Editor(new MockRenderer(), doc);
editor.moveCursorTo(0, 1);
editor.getSelection().selectDown();
editor.moveLinesDown();
assertEquals(["33", "11", "22", "44"].join("\n"), doc.toString());
assertPosition(1, 0, editor.getCursorPosition());
assertPosition(3, 0, editor.getSelection().getSelectionAnchor());
assertPosition(1, 0, editor.getSelection().getSelectionLead());
editor.moveLinesDown();
assertEquals(["33", "44", "11", "22"].join("\n"), doc.toString());
assertPosition(2, 0, editor.getCursorPosition());
assertPosition(3, 2, editor.getSelection().getSelectionAnchor());
assertPosition(2, 0, editor.getSelection().getSelectionLead());
// moving again should have no effect
editor.moveLinesDown();
assertEquals(["33", "44", "11", "22"].join("\n"), doc.toString());
assertPosition(2, 0, editor.getCursorPosition());
assertPosition(3, 2, editor.getSelection().getSelectionAnchor());
assertPosition(2, 0, editor.getSelection().getSelectionLead());
},
"test: move lines up should select moved lines" : function() {
var doc = new Document(["11", "22", "33", "44"].join("\n"));
var editor = new Editor(new MockRenderer(), doc);
editor.moveCursorTo(2, 1);
editor.getSelection().selectDown();
editor.moveLinesUp();
assertEquals(["11", "33", "44", "22"].join("\n"), doc.toString());
assertPosition(1, 0, editor.getCursorPosition());
assertPosition(3, 0, editor.getSelection().getSelectionAnchor());
assertPosition(1, 0, editor.getSelection().getSelectionLead());
editor.moveLinesUp();
assertEquals(["33", "44", "11", "22"].join("\n"), doc.toString());
assertPosition(0, 0, editor.getCursorPosition());
assertPosition(2, 0, editor.getSelection().getSelectionAnchor());
assertPosition(0, 0, editor.getSelection().getSelectionLead());
},
"test: move line without active selection should move cursor to start of the moved line" : function()
{
var doc = new Document(["11", "22", "33", "44"].join("\n"));
var editor = new Editor(new MockRenderer(), doc);
editor.moveCursorTo(1, 1);
editor.clearSelection();
editor.moveLinesDown();
assertEquals(["11", "33", "22", "44"].join("\n"), doc.toString());
assertPosition(2, 0, editor.getCursorPosition());
editor.clearSelection();
editor.moveLinesUp();
assertEquals(["11", "22", "33", "44"].join("\n"), doc.toString());
assertPosition(1, 0, editor.getCursorPosition());
},
"test: copy lines down should select lines and place cursor at the selection start" : function() {
var doc = new Document(["11", "22", "33", "44"].join("\n"));
var editor = new Editor(new MockRenderer(), doc);
editor.moveCursorTo(1, 1);
editor.getSelection().selectDown();
editor.copyLinesDown();
assertEquals(["11", "22", "33", "22", "33", "44"].join("\n"), doc.toString());
assertPosition(3, 0, editor.getCursorPosition());
assertPosition(5, 0, editor.getSelection().getSelectionAnchor());
assertPosition(3, 0, editor.getSelection().getSelectionLead());
},
"test: copy lines up should select lines and place cursor at the selection start" : function() {
var doc = new Document(["11", "22", "33", "44"].join("\n"));
var editor = new Editor(new MockRenderer(), doc);
editor.moveCursorTo(1, 1);
editor.getSelection().selectDown();
editor.copyLinesUp();
assertEquals(["11", "22", "33", "22", "33", "44"].join("\n"), doc.toString());
assertPosition(1, 0, editor.getCursorPosition());
assertPosition(3, 0, editor.getSelection().getSelectionAnchor());
assertPosition(1, 0, editor.getSelection().getSelectionLead());
},
"test: input a tab with soft tab should convert it to spaces" : function() {
var doc = new Document("");
var editor = new Editor(new MockRenderer(), doc);
doc.setTabSize(2);
doc.setUseSoftTabs(true);
editor.onTextInput("\t");
assertEquals(" ", doc.toString());
doc.setTabSize(5);
editor.onTextInput("\t");
assertEquals(" ", doc.toString());
},
"test: input tab without soft tabs should keep the tab character" : function() {
var doc = new Document("");
var editor = new Editor(new MockRenderer(), doc);
doc.setUseSoftTabs(false);
editor.onTextInput("\t");
assertEquals("\t", doc.toString());
}
});
});

View file

@ -0,0 +1,48 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/Document",
"ace/VirtualRenderer"
], function(
Document,
VirtualRenderer
) {
var VirtualRendererTest = new TestCase("VirtualRendererTest", {
"test: screen2text the column should be rounded to the next character edge" : function() {
var el = document.createElement("div");
el.style.left = "0px";
el.style.top = "0px";
el.style.width = "100px";
el.style.height = "100px";
document.body.style.margin = "0px";
document.body.style.padding = "0px";
document.body.appendChild(el);
var renderer = new VirtualRenderer(el);
renderer.setDocument(new Document("1234"));
renderer.characterWidth = 10;
renderer.lineHeight = 15;
assertPosition(0, 0, renderer.screenToTextCoordinates(0, 0));
assertPosition(0, 0, renderer.screenToTextCoordinates(4, 0));
assertPosition(0, 1, renderer.screenToTextCoordinates(5, 0));
assertPosition(0, 1, renderer.screenToTextCoordinates(9, 0));
assertPosition(0, 1, renderer.screenToTextCoordinates(10, 0));
assertPosition(0, 1, renderer.screenToTextCoordinates(14, 0));
assertPosition(0, 2, renderer.screenToTextCoordinates(15, 0));
document.body.removeChild(el);
}
// change tab size after setDocument (for text layer)
});
});

11
lib/ace/test/all.js Normal file
View file

@ -0,0 +1,11 @@
require({
paths: {
"ace": "../src/ace"
}},
["ace/test/assertions", "ace/test/ChangeDocumentTest"],
function(a) {
console.log(a)
alert("a " + a)
}
);

View file

@ -0,0 +1,25 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([], function() {
window.assertPosition = function(row, column, cursor) {
assertEquals(row, cursor.row);
assertEquals(column, cursor.column);
};
window.assertRange = function(startRow, startColumn, endRow, endColumn, range) {
assertPosition(startRow, startColumn, range.start);
assertPosition(endRow, endColumn, range.end);
};
window.assertJsonEquals = function(expectedJson, foundJson) {
assertEquals(JSON.stringify(expectedJson), JSON.stringify(foundJson));
};
});

View file

@ -0,0 +1,50 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/Document",
"ace/Range",
"ace/mode/Css"
], function(
Document,
Range,
CssMode
) {
var CssTest = new TestCase("mode.CssTest", {
setUp : function() {
this.mode = new CssMode();
},
"test: toggle comment lines should not do anything" : function() {
var doc = new Document([" abc", "cde", "fg"].join("\n"));
var range = new Range(0, 3, 1, 1);
var comment = this.mode.toggleCommentLines("start", doc, range);
assertEquals([" abc", "cde", "fg"].join("\n"), doc.toString());
},
"test: lines should keep indentation" : function() {
assertEquals(" ", this.mode.getNextLineIndent("start", " abc", " "));
assertEquals("\t", this.mode.getNextLineIndent("start", "\tabc", " "));
},
"test: new line after { should increase indent" : function() {
assertEquals(" ", this.mode.getNextLineIndent("start", " abc{", " "));
assertEquals("\t ", this.mode.getNextLineIndent("start", "\tabc { ", " "));
},
"test: no indent increase after { in a comment" : function() {
assertEquals(" ", this.mode.getNextLineIndent("start", " /*{", " "));
assertEquals(" ", this.mode.getNextLineIndent("start", " /*{ ", " "));
}
});
});

View file

@ -0,0 +1,53 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/mode/Css"
], function(
CssMode
) {
var CssTest = new TestCase("mode.CssTest", {
setUp : function() {
this.tokenizer = new CssMode().getTokenizer();
},
"test: tokenize pixel number" : function() {
var line = "-12px";
var tokens = this.tokenizer.getLineTokens(line, "start").tokens;
assertEquals(1, tokens.length);
assertEquals("number", tokens[0].type);
},
"test: tokenize hex3 color" : function() {
var tokens = this.tokenizer.getLineTokens("#abc", "start").tokens;
assertEquals(1, tokens.length);
assertEquals("number", tokens[0].type);
},
"test: tokenize hex6 color" : function() {
var tokens = this.tokenizer.getLineTokens("#abc012", "start").tokens;
assertEquals(1, tokens.length);
assertEquals("number", tokens[0].type);
},
"test: tokenize parens" : function() {
var tokens = this.tokenizer.getLineTokens("{()}", "start").tokens;
assertEquals(3, tokens.length);
assertEquals("lparen", tokens[0].type);
assertEquals("text", tokens[1].type);
assertEquals("rparen", tokens[2].type);
}
});
});

View file

@ -0,0 +1,40 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/Document",
"ace/Range",
"ace/mode/Html"
], function(
Document,
Range,
HtmlMode
) {
var HtmlTest = new TestCase("mode.HtmlTest", {
setUp : function() {
this.mode = new HtmlMode();
},
"test: toggle comment lines should not do anything" : function() {
var doc = new Document([" abc", "cde", "fg"]);
var range = new Range(0, 3, 1, 1);
var comment = this.mode.toggleCommentLines("start", doc, range);
assertEquals([" abc", "cde", "fg"].join("\n"), doc.toString());
},
"test: next line indent should be the same as the current line indent" : function() {
assertEquals(" ", this.mode.getNextLineIndent("start", " abc"));
assertEquals("", this.mode.getNextLineIndent("start", "abc"));
assertEquals("\t", this.mode.getNextLineIndent("start", "\tabc"));
}
});
});

View file

@ -0,0 +1,41 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/mode/Html"
], function(
HtmlMode
) {
var HtmlTest = new TestCase("mode.HtmlTest", {
setUp : function() {
this.tokenizer = new HtmlMode().getTokenizer();
},
"test: tokenize embedded script" : function() {
var line = "<script a='a'>var</script>'123'";
var tokens = this.tokenizer.getLineTokens(line, "start").tokens;
//assertEquals(10, tokens.length);
assertEquals("text", tokens[0].type);
assertEquals("keyword", tokens[1].type);
assertEquals("text", tokens[2].type);
assertEquals("keyword", tokens[3].type);
assertEquals("text", tokens[4].type);
assertEquals("string", tokens[5].type);
assertEquals("text", tokens[6].type);
assertEquals("keyword", tokens[7].type);
assertEquals("text", tokens[8].type);
assertEquals("keyword", tokens[9].type);
assertEquals("text", tokens[10].type);
}
});
});

View file

@ -0,0 +1,121 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/Document",
"ace/Range",
"ace/Tokenizer",
"ace/mode/JavaScript"
], function(
Document,
Range,
Tokenizer,
JavaScriptMode
) {
var JavaScriptTest = new TestCase("mode.JavaScriptTest", {
setUp : function() {
this.mode = new JavaScriptMode();
},
"test: getTokenizer() (smoke test)" : function() {
var tokenizer = this.mode.getTokenizer();
assertTrue(tokenizer instanceof Tokenizer);
var tokens = tokenizer.getLineTokens("'juhu'", "start").tokens;
assertEquals("string", tokens[0].type);
},
"test: toggle comment lines should prepend '//' to each line" : function() {
var doc = new Document([" abc", "cde", "fg"]);
var range = new Range(0, 3, 1, 1);
var comment = this.mode.toggleCommentLines("start", doc, range);
assertEquals(["// abc", "//cde", "fg"].join("\n"), doc.toString());
},
"test: toggle comment on commented lines should remove leading '//' chars" : function() {
var doc = new Document(["// abc", "//cde", "fg"]);
var range = new Range(0, 3, 1, 1);
var comment = this.mode.toggleCommentLines("start", doc, range);
assertEquals([" abc", "cde", "fg"].join("\n"), doc.toString());
},
"test: toggle comment on multiple lines with one commented line prepend '//' to each line" : function() {
var doc = new Document(["// abc", "//cde", "fg"]);
var range = new Range(0, 3, 2, 1);
var comment = this.mode.toggleCommentLines("start", doc, range);
assertEquals(["//// abc", "////cde", "//fg"].join("\n"), doc.toString());
},
"test: toggle comment on a comment line with leading white space": function() {
var doc = new Document(["//cde", " //fg"]);
var range = new Range(0, 3, 1, 1);
var comment = this.mode.toggleCommentLines("start", doc, range);
assertEquals(["cde", " fg"].join("\n"), doc.toString());
},
"test: auto indent after opening brace" : function() {
assertEquals(" ", this.mode.getNextLineIndent("start", "if () {", " "));
},
"test: no auto indent after opening brace in multi line comment" : function() {
assertEquals("", this.mode.getNextLineIndent("start", "/*if () {", " "));
assertEquals(" ", this.mode.getNextLineIndent("comment", " abcd", " "));
},
"test: no auto indent after opening brace in single line comment" : function() {
assertEquals("", this.mode.getNextLineIndent("start", "//if () {", " "));
assertEquals(" ", this.mode.getNextLineIndent("start", " //if () {", " "));
},
"test: no auto indent should add to existing indent" : function() {
assertEquals(" ", this.mode.getNextLineIndent("start", " if () {", " "));
assertEquals(" ", this.mode.getNextLineIndent("start", " cde", " "));
},
"test: special indent in doc comments" : function() {
assertEquals(" * ", this.mode.getNextLineIndent("doc-start", "/**", " "));
assertEquals(" * ", this.mode.getNextLineIndent("doc-start", " /**", " "));
assertEquals(" * ", this.mode.getNextLineIndent("doc-start", " *", " "));
assertEquals(" * ", this.mode.getNextLineIndent("doc-start", " *", " "));
assertEquals(" ", this.mode.getNextLineIndent("doc-start", " abc", " "));
},
"test: no indent after doc comments" : function() {
assertEquals("", this.mode.getNextLineIndent("doc-start", " */", " "));
},
"test: trigger outdent if line is space and new text starts with closing brace" : function() {
assertTrue(this.mode.checkOutdent("start", " ", " }"));
assertFalse(this.mode.checkOutdent("start", " a ", " }"));
assertFalse(this.mode.checkOutdent("start", "", "}"));
assertFalse(this.mode.checkOutdent("start", " ", "a }"));
assertFalse(this.mode.checkOutdent("start", " }", "}"));
},
"test: auto outdent should indent the line with the same indent as the line with the matching opening brace" : function() {
var doc = new Document([" function foo() {", " bla", " }"]);
this.mode.autoOutdent("start", doc, 2);
assertEquals(" }", doc.getLine(2));
},
"test: no auto outdent if no matching brace is found" : function() {
var doc = new Document([" function foo()", " bla", " }"]);
this.mode.autoOutdent("start", doc, 2);
assertEquals(" }", doc.getLine(2));
}
});
});

View file

@ -0,0 +1,68 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/mode/JavaScript"
], function(
JavaScriptMode
) {
var JavaScriptTokenizerTest = new TestCase("mode.JavaScriptTokenizerTest", {
setUp : function() {
this.tokenizer = new JavaScriptMode().getTokenizer();
},
"test: tokenize1" : function() {
var line = "foo = function";
var tokens = this.tokenizer.getLineTokens(line, "start").tokens;
assertEquals(3, tokens.length);
assertEquals("identifier", tokens[0].type);
assertEquals("text", tokens[1].type);
assertEquals("keyword", tokens[2].type);
},
"test: tokenize doc comment" : function() {
var line = "abc /** de */ fg";
var tokens = this.tokenizer.getLineTokens(line, "start").tokens;
assertEquals(5, tokens.length);
assertEquals("identifier", tokens[0].type);
assertEquals("text", tokens[1].type);
assertEquals("doc-comment", tokens[2].type);
assertEquals("text", tokens[3].type);
assertEquals("identifier", tokens[4].type);
},
"test: tokenize doc comment with tag" : function() {
var line = "/** @param {} */";
var tokens = this.tokenizer.getLineTokens(line, "start").tokens;
assertEquals(3, tokens.length);
assertEquals("doc-comment", tokens[0].type);
assertEquals("doc-comment-tag", tokens[1].type);
assertEquals("doc-comment", tokens[2].type);
},
"test: tokenize parens" : function() {
var line = "[{( )}]";
var tokens = this.tokenizer.getLineTokens(line, "start").tokens;
assertEquals(3, tokens.length);
assertEquals("lparen", tokens[0].type);
assertEquals("text", tokens[1].type);
assertEquals("rparen", tokens[2].type);
}
});
});

View file

@ -0,0 +1,39 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/Document",
"ace/Range",
"ace/mode/Text"
], function(
Document,
Range,
TextMode
) {
var TextTest = new TestCase("mode.TextTest", {
setUp : function() {
this.mode = new TextMode();
},
"test: toggle comment lines should not do anything" : function() {
var doc = new Document([" abc", "cde", "fg"]);
var range = new Range(0, 3, 1, 1);
var comment = this.mode.toggleCommentLines("start", doc, range);
assertEquals([" abc", "cde", "fg"].join("\n"), doc.toString());
},
"text: lines should not be indented" : function() {
assertEquals("", this.mode.getNextLineIndent("start", " abc", " "));
}
});
});

View file

@ -0,0 +1,51 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/Document",
"ace/Range",
"ace/Tokenizer",
"ace/mode/Xml"
], function(
Document,
Range,
Tokenizer,
XmlMode
) {
var XmlTest = new TestCase("mode.XmlTest", {
setUp : function() {
this.mode = new XmlMode();
},
"test: getTokenizer() (smoke test)" : function() {
var tokenizer = this.mode.getTokenizer();
assertTrue(tokenizer instanceof Tokenizer);
var tokens = tokenizer.getLineTokens("<juhu>", "start").tokens;
assertEquals("keyword", tokens[1].type);
},
"test: toggle comment lines should not do anything" : function() {
var doc = new Document([" abc", "cde", "fg"]);
var range = new Range(0, 3, 1, 1);
var comment = this.mode.toggleCommentLines("start", doc, range);
assertEquals([" abc", "cde", "fg"].join("\n"), doc.toString());
},
"test: next line indent should be the same as the current line indent" : function() {
assertEquals(" ", this.mode.getNextLineIndent("start", " abc"));
assertEquals("", this.mode.getNextLineIndent("start", "abc"));
assertEquals("\t", this.mode.getNextLineIndent("start", "\tabc"));
}
});
});

View file

@ -0,0 +1,35 @@
/**
* Ajax.org Code Editor (ACE)
*
* @copyright 2010, Ajax.org Services B.V.
* @license LGPLv3 <http://www.gnu.org/licenses/lgpl-3.0.txt>
* @author Fabian Jakobs <fabian AT ajax DOT org>
*/
require.def([
"ace/mode/Xml"
], function(
XmlMode
) {
var XmlTest = new TestCase("mode.XmlTest", {
setUp : function() {
this.tokenizer = new XmlMode().getTokenizer();
},
"test: tokenize1" : function() {
var line = "<Juhu>//Juhu Kinners</Kinners>";
var tokens = this.tokenizer.getLineTokens(line, "start").tokens;
assertEquals(5, tokens.length);
assertEquals("text", tokens[0].type);
assertEquals("keyword", tokens[1].type);
assertEquals("text", tokens[2].type);
assertEquals("keyword", tokens[3].type);
assertEquals("text", tokens[4].type);
}
});
});

159
lib/ace/theme/Clouds.js Normal file
View file

@ -0,0 +1,159 @@
require.def("ace/theme/Clouds",
["ace/lib/dom"], function(dom) {
var cssText = ".ace-clouds .ace_editor {\
border: 2px solid rgb(159, 159, 159);\
}\
\
.ace-clouds .ace_editor.ace_focus {\
border: 2px solid #327fbd;\
}\
\
.ace-clouds .ace_gutter {\
width: 50px;\
background: #e8e8e8;\
color: #333;\
overflow : hidden;\
}\
\
.ace-clouds .ace_gutter-layer {\
width: 100%;\
text-align: right;\
}\
\
.ace-clouds .ace_gutter-layer .ace_gutter-cell {\
padding-right: 6px;\
}\
\
.ace-clouds .ace_editor .ace_printMargin {\
width: 1px;\
background: #e8e8e8;\
}\
\
.ace-clouds .ace_scroller {\
background-color: #FFFFFF;\
}\
\
.ace-clouds .ace_text-layer {\
cursor: text;\
color: #000000;\
}\
\
.ace-clouds .ace_cursor {\
border-left: 2px solid #000000;\
}\
\
.ace-clouds .ace_cursor.ace_overwrite {\
border-left: 0px;\
border-bottom: 1px solid #000000;\
}\
\
.ace-clouds .ace_marker-layer .ace_selection {\
background: #BDD5FC;\
}\
\
.ace-clouds .ace_marker-layer .ace_step {\
background: rgb(198, 219, 174);\
}\
\
.ace-clouds .ace_marker-layer .ace_bracket {\
margin: -1px 0 0 -1px;\
border: 1px solid #BFBFBF;\
}\
\
.ace-clouds .ace_marker-layer .ace_active_line {\
background: #FFFBD1;\
}\
\
\
.ace-clouds .ace_invisible {\
color: #BFBFBF;\
}\
\
.ace-clouds .ace_keyword {\
color:#AF956F;\
}\
\
.ace-clouds .ace_keyword.ace_operator {\
color:#484848;\
}\
\
.ace-clouds .ace_constant {\
\
}\
\
.ace-clouds .ace_constant.ace_language {\
color:#39946A;\
}\
\
.ace-clouds .ace_constant.ace_library {\
\
}\
\
.ace-clouds .ace_constant.ace_numeric {\
color:#46A609;\
}\
\
.ace-clouds .ace_invalid {\
background-color:#FF002A;\
}\
\
.ace-clouds .ace_invalid.ace_illegal {\
\
}\
\
.ace-clouds .ace_invalid.ace_deprecated {\
\
}\
\
.ace-clouds .ace_support {\
\
}\
\
.ace-clouds .ace_support.ace_function {\
color:#C52727;\
}\
\
.ace-clouds .ace_function.ace_buildin {\
\
}\
\
.ace-clouds .ace_string {\
color:#5D90CD;\
}\
\
.ace-clouds .ace_string.ace_regexp {\
\
}\
\
.ace-clouds .ace_comment {\
color:#BCC8BA;\
}\
\
.ace-clouds .ace_comment.ace_doc {\
\
}\
\
.ace-clouds .ace_comment.ace_doc.ace_tag {\
\
}\
\
.ace-clouds .ace_variable {\
\
}\
\
.ace-clouds .ace_variable.ace_language {\
\
}\
\
.ace-clouds .ace_xml_pe {\
\
}";
// import CSS once
dom.importCssString(cssText);
return {
cssClass: "ace-clouds"
};
})

View file

@ -0,0 +1,160 @@
require.def("ace/theme/CloudsMidnight",
["ace/lib/dom"], function(dom) {
var cssText = ".ace-clouds-midnight .ace_editor {\
border: 2px solid rgb(159, 159, 159);\
}\
\
.ace-clouds-midnight .ace_editor.ace_focus {\
border: 2px solid #327fbd;\
}\
\
.ace-clouds-midnight .ace_gutter {\
width: 50px;\
background: #e8e8e8;\
color: #333;\
overflow : hidden;\
}\
\
.ace-clouds-midnight .ace_gutter-layer {\
width: 100%;\
text-align: right;\
}\
\
.ace-clouds-midnight .ace_gutter-layer .ace_gutter-cell {\
padding-right: 6px;\
}\
\
.ace-clouds-midnight .ace_editor .ace_printMargin {\
width: 1px;\
background: #e8e8e8;\
}\
\
.ace-clouds-midnight .ace_scroller {\
background-color: #191919;\
}\
\
.ace-clouds-midnight .ace_text-layer {\
cursor: text;\
color: #929292;\
}\
\
.ace-clouds-midnight .ace_cursor {\
border-left: 2px solid #7DA5DC;\
}\
\
.ace-clouds-midnight .ace_cursor.ace_overwrite {\
border-left: 0px;\
border-bottom: 1px solid #7DA5DC;\
}\
\
.ace-clouds-midnight .ace_marker-layer .ace_selection {\
background: #000000;\
}\
\
.ace-clouds-midnight .ace_marker-layer .ace_step {\
background: rgb(198, 219, 174);\
}\
\
.ace-clouds-midnight .ace_marker-layer .ace_bracket {\
margin: -1px 0 0 -1px;\
border: 1px solid #BFBFBF;\
}\
\
.ace-clouds-midnight .ace_marker-layer .ace_active_line {\
background: rgba(215, 215, 215, 0.031);\
}\
\
\
.ace-clouds-midnight .ace_invisible {\
color: #BFBFBF;\
}\
\
.ace-clouds-midnight .ace_keyword {\
color:#927C5D;\
}\
\
.ace-clouds-midnight .ace_keyword.ace_operator {\
color:#4B4B4B;\
}\
\
.ace-clouds-midnight .ace_constant {\
\
}\
\
.ace-clouds-midnight .ace_constant.ace_language {\
color:#39946A;\
}\
\
.ace-clouds-midnight .ace_constant.ace_library {\
\
}\
\
.ace-clouds-midnight .ace_constant.ace_numeric {\
color:#46A609;\
}\
\
.ace-clouds-midnight .ace_invalid {\
color:#FFFFFF;\
background-color:#E92E2E;\
}\
\
.ace-clouds-midnight .ace_invalid.ace_illegal {\
\
}\
\
.ace-clouds-midnight .ace_invalid.ace_deprecated {\
\
}\
\
.ace-clouds-midnight .ace_support {\
\
}\
\
.ace-clouds-midnight .ace_support.ace_function {\
color:#E92E2E;\
}\
\
.ace-clouds-midnight .ace_function.ace_buildin {\
\
}\
\
.ace-clouds-midnight .ace_string {\
color:#5D90CD;\
}\
\
.ace-clouds-midnight .ace_string.ace_regexp {\
\
}\
\
.ace-clouds-midnight .ace_comment {\
color:#3C403B;\
}\
\
.ace-clouds-midnight .ace_comment.ace_doc {\
\
}\
\
.ace-clouds-midnight .ace_comment.ace_doc.ace_tag {\
\
}\
\
.ace-clouds-midnight .ace_variable {\
\
}\
\
.ace-clouds-midnight .ace_variable.ace_language {\
\
}\
\
.ace-clouds-midnight .ace_xml_pe {\
\
}";
// import CSS once
dom.importCssString(cssText);
return {
cssClass: "ace-clouds-midnight"
};
})

161
lib/ace/theme/Cobalt.js Normal file
View file

@ -0,0 +1,161 @@
require.def("ace/theme/Cobalt",
["ace/lib/dom"], function(dom) {
var cssText = ".ace-cobalt .ace_editor {\
border: 2px solid rgb(159, 159, 159);\
}\
\
.ace-cobalt .ace_editor.ace_focus {\
border: 2px solid #327fbd;\
}\
\
.ace-cobalt .ace_gutter {\
width: 50px;\
background: #e8e8e8;\
color: #333;\
overflow : hidden;\
}\
\
.ace-cobalt .ace_gutter-layer {\
width: 100%;\
text-align: right;\
}\
\
.ace-cobalt .ace_gutter-layer .ace_gutter-cell {\
padding-right: 6px;\
}\
\
.ace-cobalt .ace_editor .ace_printMargin {\
width: 1px;\
background: #e8e8e8;\
}\
\
.ace-cobalt .ace_scroller {\
background-color: #002240;\
}\
\
.ace-cobalt .ace_text-layer {\
cursor: text;\
color: #FFFFFF;\
}\
\
.ace-cobalt .ace_cursor {\
border-left: 2px solid #FFFFFF;\
}\
\
.ace-cobalt .ace_cursor.ace_overwrite {\
border-left: 0px;\
border-bottom: 1px solid #FFFFFF;\
}\
\
.ace-cobalt .ace_marker-layer .ace_selection {\
background: rgba(179, 101, 57, 0.75);\
}\
\
.ace-cobalt .ace_marker-layer .ace_step {\
background: rgb(198, 219, 174);\
}\
\
.ace-cobalt .ace_marker-layer .ace_bracket {\
margin: -1px 0 0 -1px;\
border: 1px solid rgba(255, 255, 255, 0.15);\
}\
\
.ace-cobalt .ace_marker-layer .ace_active_line {\
background: rgba(0, 0, 0, 0.35);\
}\
\
\
.ace-cobalt .ace_invisible {\
color: rgba(255, 255, 255, 0.15);\
}\
\
.ace-cobalt .ace_keyword {\
color:#FF9D00;\
}\
\
.ace-cobalt .ace_keyword.ace_operator {\
\
}\
\
.ace-cobalt .ace_constant {\
color:#FF628C;\
}\
\
.ace-cobalt .ace_constant.ace_language {\
\
}\
\
.ace-cobalt .ace_constant.ace_library {\
\
}\
\
.ace-cobalt .ace_constant.ace_numeric {\
\
}\
\
.ace-cobalt .ace_invalid {\
color:#F8F8F8;\
background-color:#800F00;\
}\
\
.ace-cobalt .ace_invalid.ace_illegal {\
\
}\
\
.ace-cobalt .ace_invalid.ace_deprecated {\
\
}\
\
.ace-cobalt .ace_support {\
color:#80FFBB;\
}\
\
.ace-cobalt .ace_support.ace_function {\
color:#FFB054;\
}\
\
.ace-cobalt .ace_function.ace_buildin {\
\
}\
\
.ace-cobalt .ace_string {\
\
}\
\
.ace-cobalt .ace_string.ace_regexp {\
color:#80FFC2;\
}\
\
.ace-cobalt .ace_comment {\
font-style:italic;\
color:#0088FF;\
}\
\
.ace-cobalt .ace_comment.ace_doc {\
\
}\
\
.ace-cobalt .ace_comment.ace_doc.ace_tag {\
\
}\
\
.ace-cobalt .ace_variable {\
color:#CCCCCC;\
}\
\
.ace-cobalt .ace_variable.ace_language {\
color:#FF80E1;\
}\
\
.ace-cobalt .ace_xml_pe {\
\
}";
// import CSS once
dom.importCssString(cssText);
return {
cssClass: "ace-cobalt"
};
})

165
lib/ace/theme/Dawn.js Normal file
View file

@ -0,0 +1,165 @@
require.def("ace/theme/Dawn",
["ace/lib/dom"], function(dom) {
var cssText = ".ace-dawn .ace_editor {\
border: 2px solid rgb(159, 159, 159);\
}\
\
.ace-dawn .ace_editor.ace_focus {\
border: 2px solid #327fbd;\
}\
\
.ace-dawn .ace_gutter {\
width: 50px;\
background: #e8e8e8;\
color: #333;\
overflow : hidden;\
}\
\
.ace-dawn .ace_gutter-layer {\
width: 100%;\
text-align: right;\
}\
\
.ace-dawn .ace_gutter-layer .ace_gutter-cell {\
padding-right: 6px;\
}\
\
.ace-dawn .ace_editor .ace_printMargin {\
width: 1px;\
background: #e8e8e8;\
}\
\
.ace-dawn .ace_scroller {\
background-color: #F9F9F9;\
}\
\
.ace-dawn .ace_text-layer {\
cursor: text;\
color: #080808;\
}\
\
.ace-dawn .ace_cursor {\
border-left: 2px solid #000000;\
}\
\
.ace-dawn .ace_cursor.ace_overwrite {\
border-left: 0px;\
border-bottom: 1px solid #000000;\
}\
\
.ace-dawn .ace_marker-layer .ace_selection {\
background: rgba(39, 95, 255, 0.30);\
}\
\
.ace-dawn .ace_marker-layer .ace_step {\
background: rgb(198, 219, 174);\
}\
\
.ace-dawn .ace_marker-layer .ace_bracket {\
margin: -1px 0 0 -1px;\
border: 1px solid rgba(75, 75, 126, 0.50);\
}\
\
.ace-dawn .ace_marker-layer .ace_active_line {\
background: rgba(36, 99, 180, 0.12);\
}\
\
\
.ace-dawn .ace_invisible {\
color: rgba(75, 75, 126, 0.50);\
}\
\
.ace-dawn .ace_keyword {\
color:#794938;\
}\
\
.ace-dawn .ace_keyword.ace_operator {\
\
}\
\
.ace-dawn .ace_constant {\
color:#811F24;\
}\
\
.ace-dawn .ace_constant.ace_language {\
\
}\
\
.ace-dawn .ace_constant.ace_library {\
\
}\
\
.ace-dawn .ace_constant.ace_numeric {\
\
}\
\
.ace-dawn .ace_invalid {\
\
}\
\
.ace-dawn .ace_invalid.ace_illegal {\
text-decoration:underline;\
font-style:italic;\
color:#F8F8F8;\
background-color:#B52A1D;\
}\
\
.ace-dawn .ace_invalid.ace_deprecated {\
text-decoration:underline;\
font-style:italic;\
color:#B52A1D;\
}\
\
.ace-dawn .ace_support {\
color:#691C97;\
}\
\
.ace-dawn .ace_support.ace_function {\
color:#693A17;\
}\
\
.ace-dawn .ace_function.ace_buildin {\
\
}\
\
.ace-dawn .ace_string {\
color:#0B6125;\
}\
\
.ace-dawn .ace_string.ace_regexp {\
color:#CF5628;\
}\
\
.ace-dawn .ace_comment {\
font-style:italic;\
color:#5A525F;\
}\
\
.ace-dawn .ace_comment.ace_doc {\
\
}\
\
.ace-dawn .ace_comment.ace_doc.ace_tag {\
\
}\
\
.ace-dawn .ace_variable {\
color:#234A97;\
}\
\
.ace-dawn .ace_variable.ace_language {\
\
}\
\
.ace-dawn .ace_xml_pe {\
\
}";
// import CSS once
dom.importCssString(cssText);
return {
cssClass: "ace-dawn"
};
})

10
lib/ace/theme/Eclipse.js Normal file
View file

@ -0,0 +1,10 @@
require.def("ace/theme/Eclipse",
["ace/lib/dom", "text!ace/theme/eclipse.css"], function(dom, cssText) {
// import CSS once
dom.importCssString(cssText);
return {
cssClass: "ace-eclipse"
};
})

View file

@ -0,0 +1,161 @@
require.def("ace/theme/IdleFingers",
["ace/lib/dom"], function(dom) {
var cssText = ".ace-idle-fingers .ace_editor {\
border: 2px solid rgb(159, 159, 159);\
}\
\
.ace-idle-fingers .ace_editor.ace_focus {\
border: 2px solid #327fbd;\
}\
\
.ace-idle-fingers .ace_gutter {\
width: 50px;\
background: #e8e8e8;\
color: #333;\
overflow : hidden;\
}\
\
.ace-idle-fingers .ace_gutter-layer {\
width: 100%;\
text-align: right;\
}\
\
.ace-idle-fingers .ace_gutter-layer .ace_gutter-cell {\
padding-right: 6px;\
}\
\
.ace-idle-fingers .ace_editor .ace_printMargin {\
width: 1px;\
background: #e8e8e8;\
}\
\
.ace-idle-fingers .ace_scroller {\
background-color: #323232;\
}\
\
.ace-idle-fingers .ace_text-layer {\
cursor: text;\
color: #FFFFFF;\
}\
\
.ace-idle-fingers .ace_cursor {\
border-left: 2px solid #91FF00;\
}\
\
.ace-idle-fingers .ace_cursor.ace_overwrite {\
border-left: 0px;\
border-bottom: 1px solid #91FF00;\
}\
\
.ace-idle-fingers .ace_marker-layer .ace_selection {\
background: rgba(90, 100, 126, 0.88);\
}\
\
.ace-idle-fingers .ace_marker-layer .ace_step {\
background: rgb(198, 219, 174);\
}\
\
.ace-idle-fingers .ace_marker-layer .ace_bracket {\
margin: -1px 0 0 -1px;\
border: 1px solid #404040;\
}\
\
.ace-idle-fingers .ace_marker-layer .ace_active_line {\
background: #353637;\
}\
\
\
.ace-idle-fingers .ace_invisible {\
color: #404040;\
}\
\
.ace-idle-fingers .ace_keyword {\
color:#CC7833;\
}\
\
.ace-idle-fingers .ace_keyword.ace_operator {\
\
}\
\
.ace-idle-fingers .ace_constant {\
color:#6C99BB;\
}\
\
.ace-idle-fingers .ace_constant.ace_language {\
\
}\
\
.ace-idle-fingers .ace_constant.ace_library {\
\
}\
\
.ace-idle-fingers .ace_constant.ace_numeric {\
\
}\
\
.ace-idle-fingers .ace_invalid {\
color:#FFFFFF;\
background-color:#FF0000;\
}\
\
.ace-idle-fingers .ace_invalid.ace_illegal {\
\
}\
\
.ace-idle-fingers .ace_invalid.ace_deprecated {\
\
}\
\
.ace-idle-fingers .ace_support {\
\
}\
\
.ace-idle-fingers .ace_support.ace_function {\
color:#B83426;\
}\
\
.ace-idle-fingers .ace_function.ace_buildin {\
\
}\
\
.ace-idle-fingers .ace_string {\
color:#A5C261;\
}\
\
.ace-idle-fingers .ace_string.ace_regexp {\
color:#CCCC33;\
}\
\
.ace-idle-fingers .ace_comment {\
font-style:italic;\
color:#BC9458;\
}\
\
.ace-idle-fingers .ace_comment.ace_doc {\
\
}\
\
.ace-idle-fingers .ace_comment.ace_doc.ace_tag {\
\
}\
\
.ace-idle-fingers .ace_variable {\
\
}\
\
.ace-idle-fingers .ace_variable.ace_language {\
\
}\
\
.ace-idle-fingers .ace_xml_pe {\
\
}";
// import CSS once
dom.importCssString(cssText);
return {
cssClass: "ace-idle-fingers"
};
})

161
lib/ace/theme/KrTheme.js Normal file
View file

@ -0,0 +1,161 @@
require.def("ace/theme/KrTheme",
["ace/lib/dom"], function(dom) {
var cssText = ".ace-kr-theme .ace_editor {\
border: 2px solid rgb(159, 159, 159);\
}\
\
.ace-kr-theme .ace_editor.ace_focus {\
border: 2px solid #327fbd;\
}\
\
.ace-kr-theme .ace_gutter {\
width: 50px;\
background: #e8e8e8;\
color: #333;\
overflow : hidden;\
}\
\
.ace-kr-theme .ace_gutter-layer {\
width: 100%;\
text-align: right;\
}\
\
.ace-kr-theme .ace_gutter-layer .ace_gutter-cell {\
padding-right: 6px;\
}\
\
.ace-kr-theme .ace_editor .ace_printMargin {\
width: 1px;\
background: #e8e8e8;\
}\
\
.ace-kr-theme .ace_scroller {\
background-color: #0B0A09;\
}\
\
.ace-kr-theme .ace_text-layer {\
cursor: text;\
color: #FCFFE0;\
}\
\
.ace-kr-theme .ace_cursor {\
border-left: 2px solid #FF9900;\
}\
\
.ace-kr-theme .ace_cursor.ace_overwrite {\
border-left: 0px;\
border-bottom: 1px solid #FF9900;\
}\
\
.ace-kr-theme .ace_marker-layer .ace_selection {\
background: rgba(170, 0, 255, 0.45);\
}\
\
.ace-kr-theme .ace_marker-layer .ace_step {\
background: rgb(198, 219, 174);\
}\
\
.ace-kr-theme .ace_marker-layer .ace_bracket {\
margin: -1px 0 0 -1px;\
border: 1px solid rgba(255, 177, 111, 0.32);\
}\
\
.ace-kr-theme .ace_marker-layer .ace_active_line {\
background: #38403D;\
}\
\
\
.ace-kr-theme .ace_invisible {\
color: rgba(255, 177, 111, 0.32);\
}\
\
.ace-kr-theme .ace_keyword {\
color:#949C8B;\
}\
\
.ace-kr-theme .ace_keyword.ace_operator {\
\
}\
\
.ace-kr-theme .ace_constant {\
color:rgba(210, 117, 24, 0.76);\
}\
\
.ace-kr-theme .ace_constant.ace_language {\
\
}\
\
.ace-kr-theme .ace_constant.ace_library {\
\
}\
\
.ace-kr-theme .ace_constant.ace_numeric {\
\
}\
\
.ace-kr-theme .ace_invalid {\
color:#F8F8F8;\
background-color:#A41300;\
}\
\
.ace-kr-theme .ace_invalid.ace_illegal {\
\
}\
\
.ace-kr-theme .ace_invalid.ace_deprecated {\
\
}\
\
.ace-kr-theme .ace_support {\
color:#9FC28A;\
}\
\
.ace-kr-theme .ace_support.ace_function {\
color:#85873A;\
}\
\
.ace-kr-theme .ace_function.ace_buildin {\
\
}\
\
.ace-kr-theme .ace_string {\
\
}\
\
.ace-kr-theme .ace_string.ace_regexp {\
color:rgba(125, 255, 192, 0.65);\
}\
\
.ace-kr-theme .ace_comment {\
font-style:italic;\
color:#706D5B;\
}\
\
.ace-kr-theme .ace_comment.ace_doc {\
\
}\
\
.ace-kr-theme .ace_comment.ace_doc.ace_tag {\
\
}\
\
.ace-kr-theme .ace_variable {\
color:#D1A796;\
}\
\
.ace-kr-theme .ace_variable.ace_language {\
color:#FF80E1;\
}\
\
.ace-kr-theme .ace_xml_pe {\
\
}";
// import CSS once
dom.importCssString(cssText);
return {
cssClass: "ace-kr-theme"
};
})

View file

@ -0,0 +1,161 @@
require.def("ace/theme/MonoIndustrial",
["ace/lib/dom"], function(dom) {
var cssText = ".ace-mono-industrial .ace_editor {\
border: 2px solid rgb(159, 159, 159);\
}\
\
.ace-mono-industrial .ace_editor.ace_focus {\
border: 2px solid #327fbd;\
}\
\
.ace-mono-industrial .ace_gutter {\
width: 50px;\
background: #e8e8e8;\
color: #333;\
overflow : hidden;\
}\
\
.ace-mono-industrial .ace_gutter-layer {\
width: 100%;\
text-align: right;\
}\
\
.ace-mono-industrial .ace_gutter-layer .ace_gutter-cell {\
padding-right: 6px;\
}\
\
.ace-mono-industrial .ace_editor .ace_printMargin {\
width: 1px;\
background: #e8e8e8;\
}\
\
.ace-mono-industrial .ace_scroller {\
background-color: #222C28;\
}\
\
.ace-mono-industrial .ace_text-layer {\
cursor: text;\
color: #FFFFFF;\
}\
\
.ace-mono-industrial .ace_cursor {\
border-left: 2px solid #FFFFFF;\
}\
\
.ace-mono-industrial .ace_cursor.ace_overwrite {\
border-left: 0px;\
border-bottom: 1px solid #FFFFFF;\
}\
\
.ace-mono-industrial .ace_marker-layer .ace_selection {\
background: rgba(145, 153, 148, 0.40);\
}\
\
.ace-mono-industrial .ace_marker-layer .ace_step {\
background: rgb(198, 219, 174);\
}\
\
.ace-mono-industrial .ace_marker-layer .ace_bracket {\
margin: -1px 0 0 -1px;\
border: 1px solid rgba(102, 108, 104, 0.50);\
}\
\
.ace-mono-industrial .ace_marker-layer .ace_active_line {\
background: rgba(12, 13, 12, 0.25);\
}\
\
\
.ace-mono-industrial .ace_invisible {\
color: rgba(102, 108, 104, 0.50);\
}\
\
.ace-mono-industrial .ace_keyword {\
color:#A39E64;\
}\
\
.ace-mono-industrial .ace_keyword.ace_operator {\
color:#A8B3AB;\
}\
\
.ace-mono-industrial .ace_constant {\
color:#E98800;\
}\
\
.ace-mono-industrial .ace_constant.ace_language {\
\
}\
\
.ace-mono-industrial .ace_constant.ace_library {\
\
}\
\
.ace-mono-industrial .ace_constant.ace_numeric {\
color:#E98800;\
}\
\
.ace-mono-industrial .ace_invalid {\
color:#FFFFFF;\
background-color:rgba(153, 0, 0, 0.68);\
}\
\
.ace-mono-industrial .ace_invalid.ace_illegal {\
\
}\
\
.ace-mono-industrial .ace_invalid.ace_deprecated {\
\
}\
\
.ace-mono-industrial .ace_support {\
\
}\
\
.ace-mono-industrial .ace_support.ace_function {\
color:#588E60;\
}\
\
.ace-mono-industrial .ace_function.ace_buildin {\
\
}\
\
.ace-mono-industrial .ace_string {\
\
}\
\
.ace-mono-industrial .ace_string.ace_regexp {\
\
}\
\
.ace-mono-industrial .ace_comment {\
color:#666C68;\
background-color:#151C19;\
}\
\
.ace-mono-industrial .ace_comment.ace_doc {\
\
}\
\
.ace-mono-industrial .ace_comment.ace_doc.ace_tag {\
\
}\
\
.ace-mono-industrial .ace_variable {\
\
}\
\
.ace-mono-industrial .ace_variable.ace_language {\
color:#648BD2;\
}\
\
.ace-mono-industrial .ace_xml_pe {\
\
}";
// import CSS once
dom.importCssString(cssText);
return {
cssClass: "ace-mono-industrial"
};
})

161
lib/ace/theme/Monokai.js Normal file
View file

@ -0,0 +1,161 @@
require.def("ace/theme/Monokai",
["ace/lib/dom"], function(dom) {
var cssText = ".ace-monokai .ace_editor {\
border: 2px solid rgb(159, 159, 159);\
}\
\
.ace-monokai .ace_editor.ace_focus {\
border: 2px solid #327fbd;\
}\
\
.ace-monokai .ace_gutter {\
width: 50px;\
background: #e8e8e8;\
color: #333;\
overflow : hidden;\
}\
\
.ace-monokai .ace_gutter-layer {\
width: 100%;\
text-align: right;\
}\
\
.ace-monokai .ace_gutter-layer .ace_gutter-cell {\
padding-right: 6px;\
}\
\
.ace-monokai .ace_editor .ace_printMargin {\
width: 1px;\
background: #e8e8e8;\
}\
\
.ace-monokai .ace_scroller {\
background-color: #272822;\
}\
\
.ace-monokai .ace_text-layer {\
cursor: text;\
color: #F8F8F2;\
}\
\
.ace-monokai .ace_cursor {\
border-left: 2px solid #F8F8F0;\
}\
\
.ace-monokai .ace_cursor.ace_overwrite {\
border-left: 0px;\
border-bottom: 1px solid #F8F8F0;\
}\
\
.ace-monokai .ace_marker-layer .ace_selection {\
background: #49483E;\
}\
\
.ace-monokai .ace_marker-layer .ace_step {\
background: rgb(198, 219, 174);\
}\
\
.ace-monokai .ace_marker-layer .ace_bracket {\
margin: -1px 0 0 -1px;\
border: 1px solid #49483E;\
}\
\
.ace-monokai .ace_marker-layer .ace_active_line {\
background: #49483E;\
}\
\
\
.ace-monokai .ace_invisible {\
color: #49483E;\
}\
\
.ace-monokai .ace_keyword {\
color:#F92672;\
}\
\
.ace-monokai .ace_keyword.ace_operator {\
\
}\
\
.ace-monokai .ace_constant {\
\
}\
\
.ace-monokai .ace_constant.ace_language {\
color:#AE81FF;\
}\
\
.ace-monokai .ace_constant.ace_library {\
\
}\
\
.ace-monokai .ace_constant.ace_numeric {\
color:#AE81FF;\
}\
\
.ace-monokai .ace_invalid {\
color:#F8F8F0;\
background-color:#F92672;\
}\
\
.ace-monokai .ace_invalid.ace_illegal {\
\
}\
\
.ace-monokai .ace_invalid.ace_deprecated {\
color:#F8F8F0;\
background-color:#AE81FF;\
}\
\
.ace-monokai .ace_support {\
\
}\
\
.ace-monokai .ace_support.ace_function {\
color:#66D9EF;\
}\
\
.ace-monokai .ace_function.ace_buildin {\
\
}\
\
.ace-monokai .ace_string {\
color:#E6DB74;\
}\
\
.ace-monokai .ace_string.ace_regexp {\
\
}\
\
.ace-monokai .ace_comment {\
color:#75715E;\
}\
\
.ace-monokai .ace_comment.ace_doc {\
\
}\
\
.ace-monokai .ace_comment.ace_doc.ace_tag {\
\
}\
\
.ace-monokai .ace_variable {\
\
}\
\
.ace-monokai .ace_variable.ace_language {\
\
}\
\
.ace-monokai .ace_xml_pe {\
\
}";
// import CSS once
dom.importCssString(cssText);
return {
cssClass: "ace-monokai"
};
})

10
lib/ace/theme/TextMate.js Normal file
View file

@ -0,0 +1,10 @@
require.def("ace/theme/TextMate",
["ace/lib/dom", "text!ace/theme/tm.css"], function(dom, cssText) {
// import CSS once
dom.importCssString(cssText);
return {
cssClass: "ace-tm"
};
})

163
lib/ace/theme/Twilight.js Normal file
View file

@ -0,0 +1,163 @@
require.def("ace/theme/Twilight",
["ace/lib/dom"], function(dom) {
var cssText = ".ace-twilight .ace_editor {\
border: 2px solid rgb(159, 159, 159);\
}\
\
.ace-twilight .ace_editor.ace_focus {\
border: 2px solid #327fbd;\
}\
\
.ace-twilight .ace_gutter {\
width: 50px;\
background: #e8e8e8;\
color: #333;\
overflow : hidden;\
}\
\
.ace-twilight .ace_gutter-layer {\
width: 100%;\
text-align: right;\
}\
\
.ace-twilight .ace_gutter-layer .ace_gutter-cell {\
padding-right: 6px;\
}\
\
.ace-twilight .ace_editor .ace_printMargin {\
width: 1px;\
background: #e8e8e8;\
}\
\
.ace-twilight .ace_scroller {\
background-color: #141414;\
}\
\
.ace-twilight .ace_text-layer {\
cursor: text;\
color: #F8F8F8;\
}\
\
.ace-twilight .ace_cursor {\
border-left: 2px solid #A7A7A7;\
}\
\
.ace-twilight .ace_cursor.ace_overwrite {\
border-left: 0px;\
border-bottom: 1px solid #A7A7A7;\
}\
\
.ace-twilight .ace_marker-layer .ace_selection {\
background: rgba(221, 240, 255, 0.20);\
}\
\
.ace-twilight .ace_marker-layer .ace_step {\
background: rgb(198, 219, 174);\
}\
\
.ace-twilight .ace_marker-layer .ace_bracket {\
margin: -1px 0 0 -1px;\
border: 1px solid rgba(255, 255, 255, 0.25);\
}\
\
.ace-twilight .ace_marker-layer .ace_active_line {\
background: rgba(255, 255, 255, 0.031);\
}\
\
\
.ace-twilight .ace_invisible {\
color: rgba(255, 255, 255, 0.25);\
}\
\
.ace-twilight .ace_keyword {\
color:#CDA869;\
}\
\
.ace-twilight .ace_keyword.ace_operator {\
\
}\
\
.ace-twilight .ace_constant {\
color:#CF6A4C;\
}\
\
.ace-twilight .ace_constant.ace_language {\
\
}\
\
.ace-twilight .ace_constant.ace_library {\
\
}\
\
.ace-twilight .ace_constant.ace_numeric {\
\
}\
\
.ace-twilight .ace_invalid {\
\
}\
\
.ace-twilight .ace_invalid.ace_illegal {\
color:#F8F8F8;\
background-color:rgba(86, 45, 86, 0.75);\
}\
\
.ace-twilight .ace_invalid.ace_deprecated {\
text-decoration:underline;\
font-style:italic;\
color:#D2A8A1;\
}\
\
.ace-twilight .ace_support {\
color:#9B859D;\
}\
\
.ace-twilight .ace_support.ace_function {\
color:#DAD085;\
}\
\
.ace-twilight .ace_function.ace_buildin {\
\
}\
\
.ace-twilight .ace_string {\
color:#8F9D6A;\
}\
\
.ace-twilight .ace_string.ace_regexp {\
color:#E9C062;\
}\
\
.ace-twilight .ace_comment {\
font-style:italic;\
color:#5F5A60;\
}\
\
.ace-twilight .ace_comment.ace_doc {\
\
}\
\
.ace-twilight .ace_comment.ace_doc.ace_tag {\
\
}\
\
.ace-twilight .ace_variable {\
color:#7587A6;\
}\
\
.ace-twilight .ace_variable.ace_language {\
\
}\
\
.ace-twilight .ace_xml_pe {\
color:#494949;\
}";
// import CSS once
dom.importCssString(cssText);
return {
cssClass: "ace-twilight"
};
})

83
lib/ace/theme/eclipse.css Normal file
View file

@ -0,0 +1,83 @@
.ace-eclipse .ace_editor {
border: 2px solid rgb(159, 159, 159);
}
.ace-eclipse .ace_editor.ace_focus {
border: 2px solid #327fbd;
}
.ace-eclipse .ace_gutter {
width: 40px;
background: rgb(227, 227, 227);
border-right: 1px solid rgb(159, 159, 159);
color: rgb(136, 136, 136);
}
.ace-eclipse .ace_gutter-layer {
right: 10px;
text-align: right;
}
.ace-eclipse .ace_text-layer {
cursor: text;
}
.ace-eclipse .ace_cursor {
border-left: 1px solid black;
}
.ace-eclipse .ace_line .ace_keyword, .ace-eclipse .ace_line .ace_variable {
color: rgb(127, 0, 85);
}
.ace-eclipse .ace_line .ace_constant.ace_buildin {
color: rgb(88, 72, 246);
}
.ace-eclipse .ace_line .ace_constant.ace_library {
color: rgb(6, 150, 14);
}
.ace-eclipse .ace_line .ace_function {
color: rgb(60, 76, 114);
}
.ace-eclipse .ace_line .ace_string {
color: rgb(42, 0, 255);
}
.ace-eclipse .ace_line .ace_comment {
color: rgb(63, 127, 95);
}
.ace-eclipse .ace_line .ace_comment.ace_doc {
color: rgb(63, 95, 191);
}
.ace-eclipse .ace_line .ace_comment.ace_doc.ace_tag {
color: rgb(127, 159, 191);
}
.ace-eclipse .ace_line .ace_constant.ace_numeric {
}
.ace-eclipse .ace_line .ace_tag {
color: rgb(63, 127, 127);
}
.ace-eclipse .ace_line .ace_xml_pe {
color: rgb(104, 104, 91);
}
.ace-eclipse .ace_marker-layer .ace_selection {
background: rgb(181, 213, 255);
}
.ace-eclipse .ace_marker-layer .ace_bracket {
margin: -1px 0 0 -1px;
border: 1px solid rgb(192, 192, 192);
}
.ace-eclipse .ace_marker-layer .ace_active_line {
background: rgb(232, 242, 254);
}

119
lib/ace/theme/tm.css Normal file
View file

@ -0,0 +1,119 @@
.ace-tm .ace_editor {
border: 2px solid rgb(159, 159, 159);
}
.ace-tm .ace_editor.ace_focus {
border: 2px solid #327fbd;
}
.ace-tm .ace_gutter {
width: 50px;
background: #e8e8e8;
color: #333;
overflow : hidden;
}
.ace-tm .ace_gutter-layer {
width: 100%;
text-align: right;
}
.ace-tm .ace_gutter-layer .ace_gutter-cell {
padding-right: 6px;
}
.ace-tm .ace_editor .ace_printMargin {
width: 1px;
background: #e8e8e8;
}
.ace-tm .ace_text-layer {
cursor: text;
}
.ace-tm .ace_cursor {
border-left: 2px solid black;
}
.ace-tm .ace_cursor.ace_overwrite {
border-left: 0px;
border-bottom: 1px solid black;
}
.ace-tm .ace_line .ace_invisible {
color: rgb(191, 191, 191);
}
.ace-tm .ace_line .ace_keyword {
color: blue;
}
.ace-tm .ace_line .ace_constant.ace_buildin {
color: rgb(88, 72, 246);
}
.ace-tm .ace_line .ace_constant.ace_library {
color: rgb(6, 150, 14);
}
.ace-tm .ace_line .ace_invalid {
background-color: rgb(153, 0, 0);
color: white;
}
.ace-tm .ace_line .ace_support.ace_function {
color: rgb(60, 76, 114);
}
.ace-tm .ace_line .ace_keyword.ace_operator {
color: rgb(104, 118, 135);
}
.ace-tm .ace_line .ace_string {
color: rgb(3, 106, 7);
}
.ace-tm .ace_line .ace_comment {
color: rgb(76, 136, 107);
}
.ace-tm .ace_line .ace_comment.ace_doc {
color: rgb(0, 102, 255);
}
.ace-tm .ace_line .ace_comment.ace_doc.ace_tag {
color: rgb(128, 159, 191);
}
.ace-tm .ace_line .ace_constant.ace_numeric {
color: rgb(0, 0, 205);
}
.ace-tm .ace_line .ace_variable {
color: rgb(49, 132, 149);
}
.ace-tm .ace_line .ace_xml_pe {
color: rgb(104, 104, 91);
}
.ace-tm .ace_marker-layer .ace_selection {
background: rgb(181, 213, 255);
}
.ace-tm .ace_marker-layer .ace_step {
background: rgb(198, 219, 174);
}
.ace-tm .ace_marker-layer .ace_bracket {
margin: -1px 0 0 -1px;
border: 1px solid rgb(192, 192, 192);
}
.ace-tm .ace_marker-layer .ace_active_line {
background: rgb(232, 242, 254);
}
.ace-tm .ace_string.ace_regex {
color: rgb(255, 0, 0)
}