diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..354d9ca3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +.settings.xml +.settings.xml.old \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..0498a164 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,12 @@ +[submodule "tool/support/node-o3-xml"] + path = tool/support/node-o3-xml + url = git://github.com/ajaxorg/node-o3-xml.git +[submodule "tool/support/async"] + path = tool/support/async + url = git://github.com/fjakobs/async.js.git +[submodule "support/requirejs"] + path = support/requirejs + url = git://github.com/jrburke/requirejs.git +[submodule "support/node-o3-xml"] + path = support/node-o3-xml + url = git://github.com/ajaxorg/node-o3-xml.git diff --git a/.project b/.project new file mode 100644 index 00000000..dbb46bdc --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + editor + + + + + + org.eclipse.wst.jsdt.core.javascriptValidator + + + + + + org.eclipse.wst.jsdt.core.jsNature + + diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..02bbb60b --- /dev/null +++ b/LICENSE @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..82e66a2c --- /dev/null +++ b/Makefile @@ -0,0 +1,3 @@ +package: + rm -rf build + support/requirejs/build/build.sh build.js diff --git a/build.js b/build.js new file mode 100644 index 00000000..03e04890 --- /dev/null +++ b/build.js @@ -0,0 +1,79 @@ +{ + baseUrl: "./lib", + dir: "build", + + //- "closure": uses Google's Closure Compiler in simple optimization + //mode to minify the code. + //- "closure.keepLines": Same as closure option, but keeps line returns + //in the minified files. + //- "none": no minification will be done. + optimize: "closure.keepLines", + inlineText: true, + useStrict: false, + + pragmas: { + jquery: false, + requireExcludeModify: true, + requireExcludePlugin: false, + requireExcludePageLoad: false + }, + + skipPragmas: false, + execModules: false, + skipModuleInsertion: false, + + modules: [ + { + name: "ace/Editor", + include: [ + "ace/Document", + "ace/UndoManager", + "ace/VirtualRenderer", + + "ace/mode/JavaScript", + "ace/theme/TextMate" + ], + includeRequire: false + }, + + { + name: "ace/theme/Eclipse", + exclude: [ + "ace/lib/lang", + "ace/lib/dom", + "ace/lib/oop" + ] + }, + { + name: "ace/mode/Xml", + exclude: [ + "ace/lib/oop", + "ace/Tokenizer", + "ace/mode/Text" + ] + }, + { + name: "ace/mode/Css", + exclude: [ + "ace/lib/oop", + "ace/lib/lang", + "ace/Tokenizer", + "ace/Range", + "ace/mode/Text" + ] + }, + { + name: "ace/mode/Html", + exclude: [ + "ace/lib/oop", + "ace/lib/lang", + "ace/Tokenizer", + "ace/Range", + "ace/mode/Text", + "ace/mode/JavaScript", + "ace/mode/Css", + ] + } + ] +} + diff --git a/build/ace/BackgroundTokenizer.js b/build/ace/BackgroundTokenizer.js new file mode 100644 index 00000000..57711cbe --- /dev/null +++ b/build/ace/BackgroundTokenizer.js @@ -0,0 +1,81 @@ +/* + LGPLv3 +*/ +require.def("ace/BackgroundTokenizer", ["ace/lib/oop", "ace/MEventEmitter"], function(i, j) { + var h = function(a, c) { + this.running = false; + this.textLines = []; + this.lines = []; + this.currentLine = 0; + this.tokenizer = a; + var b = this; + this.$worker = function() { + if(b.running) { + for(var e = new Date, f = b.currentLine, d = b.textLines, g = 0, k = c.getLastVisibleRow();b.currentLine < d.length;) { + b.lines[b.currentLine] = b.$tokenizeRows(b.currentLine, b.currentLine)[0]; + b.currentLine++; + g += 1; + if(g % 5 == 0 && new Date - e > 20) { + b.fireUpdateEvent(f, b.currentLine - 1); + b.running = setTimeout(b.$worker, b.currentLine < k ? 20 : 100); + return + } + }b.running = false; + b.fireUpdateEvent(f, d.length - 1) + } + } + }; + (function() { + i.implement(this, j); + this.setTokenizer = function(a) { + this.tokenizer = a; + this.lines = []; + this.start(0) + }; + this.setLines = function(a) { + this.textLines = a; + this.lines = []; + this.stop() + }; + this.fireUpdateEvent = function(a, c) { + this.$dispatchEvent("update", {data:{first:a, last:c}}) + }; + this.start = function(a) { + this.currentLine = Math.min(a || 0, this.currentLine, this.textLines.length); + this.lines.splice(this.currentLine, this.lines.length); + this.stop(); + this.running = setTimeout(this.$worker, 700) + }; + this.stop = function() { + this.running && clearTimeout(this.running); + this.running = false + }; + this.getTokens = function(a, c, b) { + b(this.$tokenizeRows(a, c)) + }; + this.getState = function(a, c) { + c(this.$tokenizeRows(a, a)[0].state) + }; + this.$tokenizeRows = function(a, c) { + var b = [], e = "start", f = false; + if(a > 0 && this.lines[a - 1]) { + e = this.lines[a - 1].state; + f = true + }for(a = a;a <= c;a++) { + if(this.lines[a]) { + d = this.lines[a]; + e = d.state; + b.push(d) + }else { + var d = this.tokenizer.getLineTokens(this.textLines[a] || "", e); + e = d.state; + b.push(d); + if(f) { + this.lines[a] = d + } + } + }return b + } + }).call(h.prototype); + return h +}); \ No newline at end of file diff --git a/build/ace/Document.js b/build/ace/Document.js new file mode 100644 index 00000000..b4400664 --- /dev/null +++ b/build/ace/Document.js @@ -0,0 +1,461 @@ +/* + LGPLv3 +*/ +require.def("ace/Document", ["ace/lib/oop", "ace/lib/lang", "ace/MEventEmitter", "ace/Selection", "ace/mode/Text", "ace/Range"], function(l, i, m, n, o, g) { + var j = function(a, b) { + this.modified = true; + this.lines = []; + this.selection = new n(this); + this.$breakpoints = []; + this.listeners = []; + b && this.setMode(b); + i.isArray(a) ? this.$insertLines(0, a) : this.$insert({row:0, column:0}, a) + }; + (function() { + l.implement(this, m); + this.$undoManager = null; + this.$split = function(a) { + return a.split(/\r\n|\r|\n/) + }; + this.setValue = function(a) { + var b = [0, this.lines.length]; + b.push.apply(b, this.$split(a)); + this.lines.splice.apply(this.lines, b); + this.modified = true; + this.fireChangeEvent(0) + }; + this.toString = function() { + return this.lines.join(this.$getNewLineCharacter()) + }; + this.getSelection = function() { + return this.selection + }; + this.fireChangeEvent = function(a, b) { + this.$dispatchEvent("change", {data:{firstRow:a, lastRow:b}}) + }; + this.setUndoManager = function(a) { + this.$undoManager = a; + this.$deltas = []; + this.$informUndoManager && this.$informUndoManager.cancel(); + if(a) { + var b = this; + this.$informUndoManager = i.deferredCall(function() { + b.$deltas.length > 0 && a.execute({action:"aceupdate", args:[b.$deltas, b]}); + b.$deltas = [] + }) + } + }; + this.$defaultUndoManager = {undo:function() { + }, redo:function() { + }}; + this.getUndoManager = function() { + return this.$undoManager || this.$defaultUndoManager + }; + this.getTabString = function() { + return this.getUseSoftTabs() ? i.stringRepeat(" ", this.getTabSize()) : "\t" + }; + this.$useSoftTabs = true; + this.setUseSoftTabs = function(a) { + if(this.$useSoftTabs !== a) { + this.$useSoftTabs = a + } + }; + this.getUseSoftTabs = function() { + return this.$useSoftTabs + }; + this.$tabSize = 4; + this.setTabSize = function(a) { + if(!(isNaN(a) || this.$tabSize === a)) { + this.modified = true; + this.$tabSize = a; + this.$dispatchEvent("changeTabSize") + } + }; + this.getTabSize = function() { + return this.$tabSize + }; + this.getBreakpoints = function() { + return this.$breakpoints + }; + this.setBreakpoints = function(a) { + this.$breakpoints = []; + for(var b = 0;b < a.length;b++) { + this.$breakpoints[a[b]] = true + }this.$dispatchEvent("changeBreakpoint", {}) + }; + this.clearBreakpoints = function() { + this.$breakpoints = []; + this.$dispatchEvent("changeBreakpoint", {}) + }; + this.setBreakpoint = function(a) { + this.$breakpoints[a] = true; + this.$dispatchEvent("changeBreakpoint", {}) + }; + this.clearBreakpoint = function(a) { + delete this.$breakpoints[a]; + this.$dispatchEvent("changeBreakpoint", {}) + }; + this.$detectNewLine = function(a) { + this.$autoNewLine = (a = a.match(/^.*?(\r?\n)/m)) ? a[1] : "\n" + }; + this.tokenRe = /^[\w\d]+/g; + this.nonTokenRe = /^[^\w\d]+/g; + this.getWordRange = function(a, b) { + var c = this.getLine(a), d = false; + if(b > 0) { + d = !!c.charAt(b - 1).match(this.tokenRe) + }d || (d = !!c.charAt(b).match(this.tokenRe)); + d = d ? this.tokenRe : this.nonTokenRe; + var e = b; + if(e > 0) { + do { + e-- + }while(e >= 0 && c.charAt(e).match(d)); + e++ + }for(b = b;b < c.length && c.charAt(b).match(d);) { + b++ + }return new g(a, e, a, b) + }; + 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(a) { + if(this.$newLineMode !== a) { + this.$newLineMode = a + } + }; + this.getNewLineMode = function() { + return this.$newLineMode + }; + this.$mode = null; + this.setMode = function(a) { + if(this.$mode !== a) { + this.$mode = a; + this.$dispatchEvent("changeMode") + } + }; + this.getMode = function() { + if(!this.$mode) { + this.$mode = new o + }return this.$mode + }; + this.$scrollTop = 0; + this.setScrollTopRow = function(a) { + if(this.$scrollTop !== a) { + this.$scrollTop = a; + 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; + for(var a = this.lines, b = 0, c = 0, d = this.getTabSize(), e = 0;e < a.length;e++) { + var f = a[e].length; + b = Math.max(b, f); + a[e].replace("\t", function(h) { + f += d - 1; + return h + }); + c = Math.max(c, f) + }this.width = b; + this.screenWith = c + } + }; + this.getLine = function(a) { + return this.lines[a] || "" + }; + this.getDisplayLine = function(a) { + var b = (new Array(this.getTabSize() + 1)).join(" "); + return this.lines[a].replace(/\t/g, b) + }; + this.getLines = function(a, b) { + return this.lines.slice(a, b + 1) + }; + this.getLength = function() { + return this.lines.length + }; + this.getTextRange = function(a) { + if(a.start.row == a.end.row) { + return this.lines[a.start.row].substring(a.start.column, a.end.column) + }else { + var b = []; + b.push(this.lines[a.start.row].substring(a.start.column)); + b.push.apply(b, this.getLines(a.start.row + 1, a.end.row - 1)); + b.push(this.lines[a.end.row].substring(0, a.end.column)); + return b.join(this.$getNewLineCharacter()) + } + }; + this.findMatchingBracket = function(a) { + if(a.column == 0) { + return null + }var b = this.getLine(a.row).charAt(a.column - 1); + if(b == "") { + return null + }b = b.match(/([\(\[\{])|([\)\]\}])/); + if(!b) { + return null + }return b[1] ? this.$findClosingBracket(b[1], a) : this.$findOpeningBracket(b[2], a) + }; + this.$brackets = {")":"(", "(":")", "]":"[", "[":"]", "{":"}", "}":"{"}; + this.$findOpeningBracket = function(a, b) { + var c = this.$brackets[a], d = b.column - 2; + b = b.row; + for(var e = 1, f = this.getLine(b);;) { + for(;d >= 0;) { + var h = f.charAt(d); + if(h == c) { + e -= 1; + if(e == 0) { + return{row:b, column:d} + } + }else { + if(h == a) { + e += 1 + } + }d -= 1 + }b -= 1; + if(b < 0) { + break + }f = this.getLine(b); + d = f.length - 1 + }return null + }; + this.$findClosingBracket = function(a, b) { + var c = this.$brackets[a], d = b.column; + b = b.row; + for(var e = 1, f = this.getLine(b), h = this.getLength();;) { + for(;d < f.length;) { + var k = f.charAt(d); + if(k == c) { + e -= 1; + if(e == 0) { + return{row:b, column:d} + } + }else { + if(k == a) { + e += 1 + } + }d += 1 + }b += 1; + if(b >= h) { + break + }f = this.getLine(b); + d = 0 + }return null + }; + this.insert = function(a, b, c) { + b = this.$insert(a, b, c); + this.fireChangeEvent(a.row, a.row == b.row ? a.row : undefined); + return b + }; + this.$insertLines = function(a, b, c) { + if(b.length != 0) { + var d = [a, 0]; + d.push.apply(d, b); + this.lines.splice.apply(this.lines, d); + if(!c && this.$undoManager) { + c = this.$getNewLineCharacter(); + this.$deltas.push({action:"insertText", range:new g(a, 0, a + b.length, 0), text:b.join(c) + c}); + this.$informUndoManager.schedule() + } + } + }; + this.$insert = function(a, b, c) { + if(b.length == 0) { + return a + }this.modified = true; + this.lines.length <= 1 && this.$detectNewLine(b); + var d = this.$split(b); + if(this.$isNewLine(b)) { + var e = this.lines[a.row] || ""; + this.lines[a.row] = e.substring(0, a.column); + this.lines.splice(a.row + 1, 0, e.substring(a.column)); + d = {row:a.row + 1, column:0} + }else { + if(d.length == 1) { + e = this.lines[a.row] || ""; + this.lines[a.row] = e.substring(0, a.column) + b + e.substring(a.column); + d = {row:a.row, column:a.column + b.length} + }else { + e = this.lines[a.row] || ""; + var f = e.substring(0, a.column) + d[0]; + e = d[d.length - 1] + e.substring(a.column); + this.lines[a.row] = f; + this.$insertLines(a.row + 1, [e], true); + d.length > 2 && this.$insertLines(a.row + 1, d.slice(1, -1), true); + d = {row:a.row + d.length - 1, column:d[d.length - 1].length} + } + }if(!c && this.$undoManager) { + this.$deltas.push({action:"insertText", range:g.fromPoints(a, d), text:b}); + this.$informUndoManager.schedule() + }return d + }; + this.$isNewLine = function(a) { + return a == "\r\n" || a == "\r" || a == "\n" + }; + this.remove = function(a, b) { + if(a.isEmpty()) { + return a.start + }this.$remove(a, b); + this.fireChangeEvent(a.start.row, a.isMultiLine() ? undefined : a.start.row); + return a.start + }; + this.$remove = function(a, b) { + if(!a.isEmpty()) { + if(!b && this.$undoManager) { + this.$getNewLineCharacter(); + this.$deltas.push({action:"removeText", range:a.clone(), text:this.getTextRange(a)}); + this.$informUndoManager.schedule() + }this.modified = true; + b = a.start.row; + var c = a.end.row, d = this.getLine(b).substring(0, a.start.column) + this.getLine(c).substring(a.end.column); + this.lines.splice(b, c - b + 1, d); + return a.start + } + }; + this.undoChanges = function(a) { + this.selection.clearSelection(); + for(var b = a.length - 1;b >= 0;b--) { + var c = a[b]; + if(c.action == "insertText") { + this.remove(c.range, true); + this.selection.moveCursorToPosition(c.range.start) + }else { + this.insert(c.range.start, c.text, true); + this.selection.clearSelection() + } + } + }; + this.redoChanges = function(a) { + this.selection.clearSelection(); + for(var b = 0;b < a.length;b++) { + var c = a[b]; + if(c.action == "insertText") { + this.insert(c.range.start, c.text, true); + this.selection.setSelectionRange(c.range) + }else { + this.remove(c.range, true); + this.selection.moveCursorToPosition(c.range.start) + } + } + }; + this.replace = function(a, b) { + this.$remove(a); + b = b ? this.$insert(a.start, b) : a.start; + var c = a.end.column == 0 ? a.end.column - 1 : a.end.column; + this.fireChangeEvent(a.start.row, c == b.row ? c : undefined); + return b + }; + this.indentRows = function(a, b) { + b.replace("\t", this.getTabString()); + for(var c = a.start.row;c <= a.end.row;c++) { + this.$insert({row:c, column:0}, b) + }this.fireChangeEvent(a.start.row, a.end.row); + return b.length + }; + this.outdentRows = function(a) { + for(var b = new g(0, 0, 0, 0), c = this.getTabSize(), d = a.start.row;d <= a.end.row;++d) { + var e = this.getLine(d); + b.start.row = d; + b.end.row = d; + for(var f = 0;f < c;++f) { + if(e.charAt(f) != " ") { + break + } + }if(f < c && e.charAt(f) == "\t") { + b.start.column = f; + b.end.column = f + 1 + }else { + b.start.column = 0; + b.end.column = f + }if(d == a.start.row) { + a.start.column -= b.end.column - b.start.column + }if(d == a.end.row) { + a.end.column -= b.end.column - b.start.column + }this.$remove(b) + }this.fireChangeEvent(a.start.row, a.end.row); + return a + }; + this.moveLinesUp = function(a, b) { + if(a <= 0) { + return 0 + }var c = this.lines.slice(a, b + 1); + this.$remove(new g(a, 0, b + 1, 0)); + this.$insertLines(a - 1, c); + this.fireChangeEvent(a - 1, b); + return-1 + }; + this.moveLinesDown = function(a, b) { + if(b >= this.lines.length - 1) { + return 0 + }var c = this.lines.slice(a, b + 1); + this.$remove(new g(a, 0, b + 1, 0)); + this.$insertLines(a + 1, c); + this.fireChangeEvent(a, b + 1); + return 1 + }; + this.duplicateLines = function(a, b) { + a = this.$clipRowToDocument(a); + b = this.$clipRowToDocument(b); + var c = this.getLines(a, b); + this.$insertLines(a, c); + b = b - a + 1; + this.fireChangeEvent(a); + return b + }; + this.$clipRowToDocument = function(a) { + return Math.max(0, Math.min(a, this.lines.length - 1)) + }; + this.documentToScreenColumn = function(a, b) { + var c = this.getTabSize(), d = 0; + b = b; + a = this.getLine(a).split("\t"); + for(var e = 0;e < a.length;e++) { + var f = a[e].length; + if(b > f) { + b -= f + 1; + d += f + c + }else { + d += b; + break + } + }return d + }; + this.screenToDocumentColumn = function(a, b) { + var c = this.getTabSize(), d = 0; + b = b; + a = this.getLine(a).split("\t"); + for(var e = 0;e < a.length;e++) { + var f = a[e].length; + if(b >= f + c) { + b -= f + c; + d += f + 1 + }else { + d += b > f ? f : b; + break + } + }return d + } + }).call(j.prototype); + return j +}); \ No newline at end of file diff --git a/build/ace/Editor.js b/build/ace/Editor.js new file mode 100644 index 00000000..6eba462a --- /dev/null +++ b/build/ace/Editor.js @@ -0,0 +1,3436 @@ +/* + RequireJS text Copyright (c) 2010, The Dojo Foundation All Rights Reserved. + Available via the MIT or new BSD license. + see: http://github.com/jrburke/requirejs for details + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 + LGPLv3 +*/ +(function() { + var k = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP", "Msxml2.XMLHTTP.4.0"], f = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, a = /]*>\s*([\s\S]+)\s*<\/body>/im; + if(!require.textStrip) { + require.textStrip = function(h) { + if(h) { + h = h.replace(f, ""); + var i = h.match(a); + if(i) { + h = i[1] + } + }else { + h = "" + }return h + } + }if(!require.getXhr) { + require.getXhr = function() { + var h, i, e; + if(typeof XMLHttpRequest !== "undefined") { + return new XMLHttpRequest + }else { + for(i = 0;i < 3;i++) { + e = k[i]; + try { + h = new ActiveXObject(e) + }catch(j) { + }if(h) { + k = [e]; + break + } + } + }if(!h) { + throw new Error("require.getXhr(): XMLHttpRequest not available"); + }return h + } + }if(!require.fetchText) { + require.fetchText = function(h, i) { + var e = require.getXhr(); + e.open("GET", h, true); + e.onreadystatechange = function() { + e.readyState === 4 && i(e.responseText) + }; + e.send(null) + } + }require.plugin({prefix:"text", require:function() { + }, newContext:function(h) { + require.mixin(h, {text:{}, textWaiting:[]}) + }, load:function(h, i) { + var e = false, j = null, c, g = h.indexOf("."), l = h.substring(0, g), m = h.substring(g + 1, h.length), b = require.s.contexts[i], d = b.textWaiting; + g = m.indexOf("!"); + if(g !== -1) { + e = m.substring(g + 1, m.length); + m = m.substring(0, g); + g = e.indexOf("!"); + if(g !== -1 && e.substring(0, g) === "strip") { + j = e.substring(g + 1, e.length); + e = "strip" + }else { + if(e !== "strip") { + j = e; + e = null + } + } + }c = l + "!" + m; + g = e ? c + "!" + e : c; + if(j !== null && !b.text[c]) { + b.defined[h] = b.text[c] = j + }else { + if(!b.text[c] && !b.textWaiting[c] && !b.textWaiting[g]) { + d[g] || (d[g] = d[d.push({name:h, key:c, fullKey:g, strip:!!e}) - 1]); + i = require.nameToUrl(l, "." + m, i); + b.loaded[h] = false; + require.fetchText(i, function(n) { + b.text[c] = n; + b.loaded[h] = true + }) + } + } + }, checkDeps:function() { + }, isWaiting:function(h) { + return!!h.textWaiting.length + }, orderDeps:function(h) { + var i, e, j, c = h.textWaiting; + h.textWaiting = []; + for(i = 0;e = c[i];i++) { + j = h.text[e.key]; + h.defined[e.name] = e.strip ? require.textStrip(j) : j + } + }}) +})(); +if(!require.def) { + require.def = require("requireJS-node")(module, require) +}require.def("ace/lib/oop", function() { + var k = {}; + k.inherits = function(f, a) { + var h = function() { + }; + h.prototype = a.prototype; + f.super_ = a.prototype; + f.prototype = new h; + f.prototype.constructor = f + }; + k.mixin = function(f, a) { + for(var h in a) { + f[h] = a[h] + } + }; + k.implement = function(f, a) { + k.mixin(f, a) + }; + return k +}); +if(!require.def) { + require.def = require("requireJS-node")(module, require) +}require.def("ace/lib/core", function() { + var k = {}, f = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase(); + k.isWin = f == "win"; + k.isMac = f == "mac"; + k.isLinux = f == "linux"; + k.isIE = !+"\u000b1"; + k.isGecko = window.controllers && window.navigator.product === "Gecko"; + k.provide = function(a) { + a = a.split("."); + for(var h = window, i = 0;i < a.length;i++) { + var e = a[i]; + h[e] || (h[e] = {}); + h = h[e] + } + }; + return k +}); +if(!require.def) { + require.def = require("requireJS-node")(module, require) +}require.def("ace/lib/event", ["ace/lib/core"], function(k) { + var f = {}; + f.addListener = function(a, h, i) { + if(a.addEventListener) { + return a.addEventListener(h, i, false) + }if(a.attachEvent) { + var e = function() { + i(window.event) + }; + i.$$wrapper = e; + a.attachEvent("on" + h, e) + } + }; + f.removeListener = function(a, h, i) { + if(a.removeEventListener) { + return a.removeEventListener(h, i, false) + }if(a.detachEvent) { + a.detachEvent("on" + h, i.$$wrapper || i) + } + }; + f.stopEvent = function(a) { + f.stopPropagation(a); + f.preventDefault(a); + return false + }; + f.stopPropagation = function(a) { + if(a.stopPropagation) { + a.stopPropagation() + }else { + a.cancelBubble = true + } + }; + f.preventDefault = function(a) { + if(a.preventDefault) { + a.preventDefault() + }else { + a.returnValue = false + } + }; + f.getDocumentX = function(a) { + return a.clientX ? a.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) : a.pageX + }; + f.getDocumentY = function(a) { + return a.clientY ? a.clientY + (document.documentElement.scrollTop || document.body.scrollTop) : a.pageX + }; + f.getButton = function(a) { + return a.preventDefault ? a.button : Math.max(a.button - 1, 2) + }; + f.capture = document.documentElement.setCapture ? function(a, h, i) { + function e(j) { + h && h(j); + i && i(); + f.removeListener(a, "mousemove", h); + f.removeListener(a, "mouseup", e); + f.removeListener(a, "losecapture", e); + a.releaseCapture() + } + f.addListener(a, "mousemove", h); + f.addListener(a, "mouseup", e); + f.addListener(a, "losecapture", e); + a.setCapture() + } : function(a, h, i) { + function e(c) { + h(c); + c.stopPropagation() + } + function j(c) { + h && h(c); + i && i(); + document.removeEventListener("mousemove", e, true); + document.removeEventListener("mouseup", j, true); + c.stopPropagation() + } + document.addEventListener("mousemove", e, true); + document.addEventListener("mouseup", j, true) + }; + f.addMouseWheelListener = function(a, h) { + var i = 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 + } + }h(e) + }; + f.addListener(a, "DOMMouseScroll", i); + f.addListener(a, "mousewheel", i) + }; + f.addMultiMouseDownListener = function(a, h, i, e, j) { + var c = 0, g, l, m = function(b) { + c += 1; + if(c == 1) { + g = b.clientX; + l = b.clientY; + setTimeout(function() { + c = 0 + }, e || 600) + }if(f.getButton(b) != h || Math.abs(b.clientX - g) > 5 || Math.abs(b.clientY - l) > 5) { + c = 0 + }if(c == i) { + c = 0; + j(b) + }return f.preventDefault(b) + }; + f.addListener(a, "mousedown", m); + k.isIE && f.addListener(a, "dblclick", m) + }; + f.addKeyListener = function(a, h) { + var i = null; + f.addListener(a, "keydown", function(e) { + i = e.keyIdentifier || e.keyCode; + return h(e) + }); + k.isMac && k.isGecko && f.addListener(a, "keypress", function(e) { + if(i !== (e.keyIdentifier || e.keyCode)) { + return h(e) + }else { + i = null + } + }) + }; + return f +}); +if(!require.def) { + require.def = require("requireJS-node")(module, require) +}require.def("ace/lib/lang", function() { + var k = {}; + k.stringReverse = function(f) { + return f.split("").reverse().join("") + }; + k.stringRepeat = function(f, a) { + return(new Array(a + 1)).join(f) + }; + k.arrayIndexOf = Array.prototype.indexOf ? function(f, a) { + return f.indexOf(a) + } : function(f, a) { + for(var h = 0;h < f.length;h++) { + if(f[h] == a) { + return h + } + }return-1 + }; + k.isArray = function(f) { + return Object.prototype.toString.call(f) == "[object Array]" + }; + k.copyObject = function(f) { + var a = {}; + for(var h in f) { + a[h] = f[h] + }return a + }; + k.arrayToMap = function(f) { + for(var a = {}, h = 0;h < f.length;h++) { + a[f[h]] = 1 + }return a + }; + k.escapeRegExp = function(f) { + return f.replace(/([.*+?^${}()|[\]\/\\])/g, "\\$1") + }; + k.bind = function(f, a) { + return function() { + return f.apply(a, arguments) + } + }; + k.deferredCall = function(f) { + var a = null, h = function() { + a = null; + f() + }; + return{schedule:function() { + a || (a = setTimeout(h, 0)) + }, call:function() { + k.cancel(); + f() + }, cancel:function() { + clearTimeout(a); + a = null + }} + }; + return k +}); +require.def("ace/TextInput", ["ace/lib/event"], function(k) { + return function(f, a) { + function h() { + if(!g) { + var b = i.value; + if(b) { + if(b.charCodeAt(b.length - 1) == j.charCodeAt(0)) { + (b = b.slice(0, -1)) && a.onTextInput(b) + }else { + a.onTextInput(b) + } + } + }g = false; + i.value = j; + i.select() + } + var i = document.createElement("textarea"), e = i.style; + e.position = "absolute"; + e.left = "-10000px"; + e.top = "-10000px"; + f.appendChild(i); + var j = String.fromCharCode(0); + h(); + var c = false, g = false, l = function() { + setTimeout(function() { + c || h() + }, 0) + }, m = function() { + a.onCompositionUpdate(i.value) + }; + k.addListener(i, "keypress", l); + k.addListener(i, "textInput", l); + k.addListener(i, "paste", l); + k.addListener(i, "propertychange", l); + k.addListener(i, "copy", function() { + g = true; + i.value = a.getCopyText(); + i.select(); + g = true; + setTimeout(h, 0) + }); + k.addListener(i, "cut", function() { + g = true; + i.value = a.getCopyText(); + a.onCut(); + i.select(); + setTimeout(h, 0) + }); + k.addListener(i, "compositionstart", function() { + c = true; + h(); + i.value = ""; + a.onCompositionStart(); + setTimeout(m, 0) + }); + k.addListener(i, "compositionupdate", m); + k.addListener(i, "compositionend", function() { + c = false; + a.onCompositionEnd(); + l() + }); + k.addListener(i, "blur", function() { + a.onBlur() + }); + k.addListener(i, "focus", function() { + a.onFocus(); + i.select() + }); + this.focus = function() { + a.onFocus(); + i.select(); + i.focus() + }; + this.blur = function() { + i.blur() + } + } +}); +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", movelinesdown:"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"} +}); +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", movelinesdown:"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"} +}); +require.def("ace/PluginManager", [], function() { + return{commands:{}, registerCommand:function(k, f) { + this.commands[k] = f + }} +}); +require.def("ace/commands/DefaultCommands", ["ace/PluginManager"], function(k) { + k.registerCommand("selectall", function(f, a) { + a.selectAll() + }); + k.registerCommand("removeline", function(f) { + f.removeLines() + }); + k.registerCommand("gotoline", function(f) { + var a = parseInt(prompt("Enter line number:")); + isNaN(a) || f.gotoLine(a) + }); + k.registerCommand("togglecomment", function(f) { + f.toggleCommentLines() + }); + k.registerCommand("findnext", function(f) { + f.findNext() + }); + k.registerCommand("findprevious", function(f) { + f.findPrevious() + }); + k.registerCommand("find", function(f) { + var a = prompt("Find:"); + f.find(a) + }); + k.registerCommand("undo", function(f) { + f.undo() + }); + k.registerCommand("redo", function(f) { + f.redo() + }); + k.registerCommand("redo", function(f) { + f.redo() + }); + k.registerCommand("overwrite", function(f) { + f.toggleOverwrite() + }); + k.registerCommand("copylinesup", function(f) { + f.copyLinesUp() + }); + k.registerCommand("movelinesup", function(f) { + f.moveLinesUp() + }); + k.registerCommand("selecttostart", function(f, a) { + a.selectFileStart() + }); + k.registerCommand("gotostart", function(f) { + f.navigateFileStart() + }); + k.registerCommand("selectup", function(f, a) { + a.selectUp() + }); + k.registerCommand("golineup", function(f) { + f.navigateUp() + }); + k.registerCommand("copylinesdown", function(f) { + f.copyLinesDown() + }); + k.registerCommand("movelinesdown", function(f) { + f.moveLinesDown() + }); + k.registerCommand("selecttoend", function(f, a) { + a.selectFileEnd() + }); + k.registerCommand("gotoend", function(f) { + f.navigateFileEnd() + }); + k.registerCommand("selectdown", function(f, a) { + a.selectDown() + }); + k.registerCommand("godown", function(f) { + f.navigateDown() + }); + k.registerCommand("selectwordleft", function(f, a) { + a.selectWordLeft() + }); + k.registerCommand("gotowordleft", function(f) { + f.navigateWordLeft() + }); + k.registerCommand("selecttolinestart", function(f, a) { + a.selectLineStart() + }); + k.registerCommand("gotolinestart", function(f) { + f.navigateLineStart() + }); + k.registerCommand("selectleft", function(f, a) { + a.selectLeft() + }); + k.registerCommand("gotoleft", function(f) { + f.navigateLeft() + }); + k.registerCommand("selectwordright", function(f, a) { + a.selectWordRight() + }); + k.registerCommand("gotowordright", function(f) { + f.navigateWordRight() + }); + k.registerCommand("selecttolineend", function(f, a) { + a.selectLineEnd() + }); + k.registerCommand("gotolineend", function(f) { + f.navigateLineEnd() + }); + k.registerCommand("selectright", function(f, a) { + a.selectRight() + }); + k.registerCommand("gotoright", function(f) { + f.navigateRight() + }); + k.registerCommand("selectpagedown", function(f) { + f.selectPageDown() + }); + k.registerCommand("pagedown", function(f) { + f.scrollPageDown() + }); + k.registerCommand("gotopagedown", function(f) { + f.gotoPageDown() + }); + k.registerCommand("selectpageup", function(f) { + f.selectPageUp() + }); + k.registerCommand("pageup", function(f) { + f.scrollPageUp() + }); + k.registerCommand("gotopageup", function(f) { + f.gotoPageUp() + }); + k.registerCommand("selectlinestart", function(f, a) { + a.selectLineStart() + }); + k.registerCommand("gotolinestart", function(f) { + f.navigateLineStart() + }); + k.registerCommand("selectlineend", function(f, a) { + a.selectLineEnd() + }); + k.registerCommand("gotolineend", function(f) { + f.navigateLineEnd() + }); + k.registerCommand("del", function(f) { + f.removeRight() + }); + k.registerCommand("backspace", function(f) { + f.removeLeft() + }); + k.registerCommand("outdent", function(f) { + f.blockOutdent() + }); + k.registerCommand("indent", function(f) { + f.indent() + }) +}); +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(k, f, a, h, i) { + var e = function(j, c, g) { + this.setConfig(g); + var l = this; + f.addKeyListener(j, function(m) { + var b = (l.config.reverse[0 | (m.ctrlKey ? 1 : 0) | (m.altKey ? 2 : 0) | (m.shiftKey ? 4 : 0) | (m.metaKey ? 8 : 0)] || {})[(l.keyNames[m.keyCode] || String.fromCharCode(m.keyCode)).toLowerCase()]; + if(b = i.commands[b]) { + b(c, c.getSelection()); + return f.stopEvent(m) + } + }) + }; + (function() { + function j(l, m, b, d) { + return(d && l.toLowerCase() || l).replace(/(?:^\s+|\n|\s+$)/g, "").split(new RegExp("[\\s ]*" + m + "[\\s ]*", "g"), b || 999) + } + function c(l, m, b) { + var d, n = 0; + l = j(l, "\\-", null, true); + for(var o = 0, p = l.length;o < p;++o) { + if(this.keyMods[l[o]]) { + n |= this.keyMods[l[o]] + }else { + d = l[o] || "-" + } + }(b[n] || (b[n] = {}))[d] = m; + return b + } + function g(l, m) { + var b, d, n, o, p = {}; + for(b in l) { + o = l[b]; + if(m && typeof o == "string") { + o = o.split(m); + d = 0; + for(n = o.length;d < n;++d) { + c.call(this, o[d], b, p) + } + }else { + c.call(this, o, b, p) + } + }return p + } + 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"}; + this.setConfig = function(l) { + this.config = l || (k.isMac ? a : h); + if(typeof this.config.reverse == "undefined") { + this.config.reverse = g.call(this, this.config, "|") + } + } + }).call(e.prototype); + return e +}); +if(!require.def) { + require.def = require("requireJS-node")(module, require) +}require.def("ace/MEventEmitter", ["ace/lib/lang"], function(k) { + var f = {}; + f.$dispatchEvent = function(a, h) { + this.$eventRegistry = this.$eventRegistry || {}; + var i = this.$eventRegistry[a]; + if(i && i.length) { + h = h || {}; + h.type = a; + for(a = 0;a < i.length;a++) { + i[a](h) + } + } + }; + f.on = f.addEventListener = function(a, h) { + this.$eventRegistry = this.$eventRegistry || {}; + var i = this.$eventRegistry[a]; + i || (i = this.$eventRegistry[a] = []); + k.arrayIndexOf(i, h) == -1 && i.push(h) + }; + f.removeEventListener = function(a, h) { + this.$eventRegistry = this.$eventRegistry || {}; + if(a = this.$eventRegistry[a]) { + h = k.arrayIndexOf(a, h); + h !== -1 && a.splice(h, 1) + } + }; + return f +}); +require.def("ace/Range", function() { + var k = function(f, a, h, i) { + this.start = {row:f, column:a}; + this.end = {row:h, column:i} + }; + (function() { + this.toString = function() { + return"Range: [" + this.start.row + "/" + this.start.column + "] -> [" + this.end.row + "/" + this.end.column + "]" + }; + this.contains = function(f, a) { + return this.compare(f, a) == 0 + }; + this.compare = function(f, a) { + if(!this.isMultiLine()) { + if(f === this.start.row) { + return a < this.start.column ? -1 : a > this.end.column ? 1 : 0 + } + }if(f < this.start.row) { + return-1 + }if(f > this.end.row) { + return 1 + }if(this.start.row === f) { + return a >= this.start.column ? 0 : -1 + }if(this.end.row === f) { + return a <= this.end.column ? 0 : 1 + }return 0 + }; + this.clipRows = function(f, a) { + if(this.end.row > a) { + var h = {row:a + 1, column:0} + }if(this.start.row > a) { + var i = {row:a + 1, column:0} + }if(this.start.row < f) { + i = {row:f, column:0} + }if(this.end.row < f) { + h = {row:f, column:0} + }return k.fromPoints(i || this.start, h || this.end) + }; + this.extend = function(f, a) { + var h = this.compare(f, a); + if(h == 0) { + return this + }else { + if(h == -1) { + var i = {row:f, column:a} + }else { + var e = {row:f, column:a} + } + }return k.fromPoints(i || this.start, e || 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 k.fromPoints(this.start, this.end) + }; + this.toScreenRange = function(f) { + return new k(this.start.row, f.documentToScreenColumn(this.start.row, this.start.column), this.end.row, f.documentToScreenColumn(this.end.row, this.end.column)) + } + }).call(k.prototype); + k.fromPoints = function(f, a) { + return new k(f.row, f.column, a.row, a.column) + }; + return k +}); +require.def("ace/Selection", ["ace/lib/oop", "ace/lib/lang", "ace/MEventEmitter", "ace/Range"], function(k, f, a, h) { + var i = function(e) { + this.doc = e; + this.clearSelection(); + this.selectionLead = {row:0, column:0} + }; + (function() { + k.implement(this, a); + 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(e, j) { + e = this.$clipPositionToDocument(e, j); + if(this.selectionAnchor) { + if(this.selectionAnchor.row !== e.row || this.selectionAnchor.column !== e.column) { + this.selectionAnchor = e; + this.$dispatchEvent("changeSelection", {}) + } + }else { + this.selectionAnchor = e; + this.$dispatchEvent("changeSelection", {}) + } + }; + this.getSelectionAnchor = function() { + return this.selectionAnchor ? this.$clone(this.selectionAnchor) : this.$clone(this.selectionLead) + }; + this.getSelectionLead = function() { + return this.$clone(this.selectionLead) + }; + this.shiftSelection = function(e) { + if(this.isEmpty()) { + this.moveCursorTo(this.selectionLead.row, this.selectionLead.column + e) + }else { + var j = this.getSelectionAnchor(), c = this.getSelectionLead(), g = this.isBackwards(); + if(!g || j.column !== 0) { + this.setSelectionAnchor(j.row, j.column + e) + }if(g || c.column !== 0) { + this.$moveSelection(function() { + this.moveCursorTo(c.row, c.column + e) + }) + } + } + }; + this.isBackwards = function() { + var e = this.selectionAnchor || this.selectionLead, j = this.selectionLead; + return e.row > j.row || e.row == j.row && e.column > j.column + }; + this.getRange = function() { + var e = this.selectionAnchor || this.selectionLead, j = this.selectionLead; + return this.isBackwards() ? h.fromPoints(j, e) : h.fromPoints(e, j) + }; + this.clearSelection = function() { + if(this.selectionAnchor) { + this.selectionAnchor = null; + this.$dispatchEvent("changeSelection", {}) + } + }; + this.selectAll = function() { + var e = this.doc.getLength() - 1; + this.setSelectionAnchor(e, this.doc.getLine(e).length); + this.$moveSelection(function() { + this.moveCursorTo(0, 0) + }) + }; + this.setSelectionRange = function(e, j) { + if(j) { + this.setSelectionAnchor(e.end.row, e.end.column); + this.selectTo(e.start.row, e.start.column) + }else { + this.setSelectionAnchor(e.start.row, e.start.column); + this.selectTo(e.end.row, e.end.column) + } + }; + this.$moveSelection = function(e) { + var j = false; + if(!this.selectionAnchor) { + j = true; + this.selectionAnchor = this.$clone(this.selectionLead) + }var c = this.$clone(this.selectionLead); + e.call(this); + if(c.row !== this.selectionLead.row || c.column !== this.selectionLead.column) { + j = true + }j && this.$dispatchEvent("changeSelection", {}) + }; + this.selectTo = function(e, j) { + this.$moveSelection(function() { + this.moveCursorTo(e, j) + }) + }; + this.selectToPosition = function(e) { + this.$moveSelection(function() { + this.moveCursorToPosition(e) + }) + }; + 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.selectWordRight = function() { + this.$moveSelection(this.moveCursorWordRight) + }; + this.selectWordLeft = function() { + this.$moveSelection(this.moveCursorWordLeft) + }; + this.selectWord = function() { + var e = this.selectionLead; + this.setSelectionRange(this.doc.getWordRange(e.row, e.column)) + }; + 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) { + 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) { + this.selectionLead.row < this.doc.getLength() - 1 && this.moveCursorTo(this.selectionLead.row + 1, 0) + }else { + this.moveCursorBy(0, 1) + } + }; + this.moveCursorLineStart = function() { + var e = this.selectionLead.row, j = this.selectionLead.column, c = this.doc.getLine(e).slice(0, j).match(/^\s*/); + if(c[0].length == 0) { + this.moveCursorTo(e, this.doc.getLine(e).match(/^\s*/)[0].length) + }else { + c[0].length >= j ? this.moveCursorTo(e, 0) : this.moveCursorTo(e, c[0].length) + } + }; + this.moveCursorLineEnd = function() { + this.moveCursorTo(this.selectionLead.row, this.doc.getLine(this.selectionLead.row).length) + }; + this.moveCursorFileEnd = function() { + var e = this.doc.getLength() - 1, j = this.doc.getLine(e).length; + this.moveCursorTo(e, j) + }; + this.moveCursorFileStart = function() { + this.moveCursorTo(0, 0) + }; + this.moveCursorWordRight = function() { + var e = this.selectionLead.row, j = this.selectionLead.column, c = this.doc.getLine(e), g = c.substring(j); + this.doc.nonTokenRe.lastIndex = 0; + this.doc.tokenRe.lastIndex = 0; + if(j == c.length) { + this.moveCursorRight() + }else { + if(this.doc.nonTokenRe.exec(g)) { + j += this.doc.nonTokenRe.lastIndex; + this.doc.nonTokenRe.lastIndex = 0 + }else { + if(this.doc.tokenRe.exec(g)) { + j += this.doc.tokenRe.lastIndex; + this.doc.tokenRe.lastIndex = 0 + } + }this.moveCursorTo(e, j) + } + }; + this.moveCursorWordLeft = function() { + var e = this.selectionLead.row, j = this.selectionLead.column, c = this.doc.getLine(e); + c = f.stringReverse(c.substring(0, j)); + this.doc.nonTokenRe.lastIndex = 0; + this.doc.tokenRe.lastIndex = 0; + if(j == 0) { + this.moveCursorLeft() + }else { + if(this.doc.nonTokenRe.exec(c)) { + j -= this.doc.nonTokenRe.lastIndex; + this.doc.nonTokenRe.lastIndex = 0 + }else { + if(this.doc.tokenRe.exec(c)) { + j -= this.doc.tokenRe.lastIndex; + this.doc.tokenRe.lastIndex = 0 + } + }this.moveCursorTo(e, j) + } + }; + this.moveCursorBy = function(e, j) { + this.moveCursorTo(this.selectionLead.row + e, this.selectionLead.column + j) + }; + this.moveCursorToPosition = function(e) { + this.moveCursorTo(e.row, e.column) + }; + this.moveCursorTo = function(e, j) { + e = this.$clipPositionToDocument(e, j); + if(e.row !== this.selectionLead.row || e.column !== this.selectionLead.column) { + this.selectionLead = e; + this.$dispatchEvent("changeCursor", {data:this.getCursor()}) + } + }; + this.moveCursorUp = function() { + this.moveCursorBy(-1, 0) + }; + this.$clipPositionToDocument = function(e, j) { + var c = {}; + if(e >= this.doc.getLength()) { + c.row = Math.max(0, this.doc.getLength() - 1); + c.column = this.doc.getLine(c.row).length + }else { + if(e < 0) { + c.row = 0; + c.column = 0 + }else { + c.row = e; + c.column = Math.min(this.doc.getLine(c.row).length, Math.max(0, j)) + } + }return c + }; + this.$clone = function(e) { + return{row:e.row, column:e.column} + } + }).call(i.prototype); + return i +}); +require.def("ace/Tokenizer", [], function() { + var k = function(f) { + this.rules = f; + this.regExps = {}; + for(var a in this.rules) { + f = this.rules[a]; + for(var h = [], i = 0;i < f.length;i++) { + h.push(f[i].regex) + }this.regExps[a] = new RegExp("(?:(" + h.join(")|(") + ")|(.))", "g") + } + }; + (function() { + this.getLineTokens = function(f, a) { + a = a; + var h = this.rules[a], i = this.regExps[a]; + i.lastIndex = 0; + for(var e, j = [], c = 0, g = {type:null, value:""};e = i.exec(f);) { + var l = "text", m = e[0]; + if(i.lastIndex == c) { + throw new Error("tokenizer error"); + }c = i.lastIndex; + window.LOG && console.log(a, e); + for(var b = 0;b < h.length;b++) { + if(e[b + 1]) { + l = typeof h[b].token == "function" ? h[b].token(e[0]) : h[b].token; + if(h[b].next && h[b].next !== a) { + a = h[b].next; + h = this.rules[a]; + c = i.lastIndex; + i = this.regExps[a]; + i.lastIndex = c + }break + } + }if(g.type !== l) { + g.type && j.push(g); + g = {type:l, value:m} + }else { + g.value += m + } + }g.type && j.push(g); + window.LOG && console.log(j, a); + return{tokens:j, state:a} + } + }).call(k.prototype); + return k +}); +require.def("ace/mode/TextHighlightRules", [], function() { + var k = function() { + this.$rules = {start:[{token:"text", regex:".+"}]} + }; + (function() { + this.addRules = function(f, a) { + for(var h in f) { + for(var i = f[h], e = 0;e < i.length;e++) { + var j = i[e]; + j.next = j.next ? a + j.next : a + h + }this.$rules[a + h] = i + } + }; + this.getRules = function() { + return this.$rules + } + }).call(k.prototype); + return k +}); +require.def("ace/mode/Text", ["ace/Tokenizer", "ace/mode/TextHighlightRules"], function(k, f) { + var a = function() { + this.$tokenizer = new k((new f).getRules()) + }; + (function() { + this.getTokenizer = function() { + return this.$tokenizer + }; + this.toggleCommentLines = function() { + return 0 + }; + this.getNextLineIndent = function() { + return"" + }; + this.checkOutdent = function() { + return false + }; + this.autoOutdent = function() { + }; + this.$getIndent = function(h) { + if(h = h.match(/^(\s+)/)) { + return h[1] + }return"" + } + }).call(a.prototype); + return a +}); +require.def("ace/Document", ["ace/lib/oop", "ace/lib/lang", "ace/MEventEmitter", "ace/Selection", "ace/mode/Text", "ace/Range"], function(k, f, a, h, i, e) { + var j = function(c, g) { + this.modified = true; + this.lines = []; + this.selection = new h(this); + this.$breakpoints = []; + this.listeners = []; + g && this.setMode(g); + f.isArray(c) ? this.$insertLines(0, c) : this.$insert({row:0, column:0}, c) + }; + (function() { + k.implement(this, a); + this.$undoManager = null; + this.$split = function(c) { + return c.split(/\r\n|\r|\n/) + }; + this.setValue = function(c) { + var g = [0, this.lines.length]; + g.push.apply(g, this.$split(c)); + this.lines.splice.apply(this.lines, g); + this.modified = true; + this.fireChangeEvent(0) + }; + this.toString = function() { + return this.lines.join(this.$getNewLineCharacter()) + }; + this.getSelection = function() { + return this.selection + }; + this.fireChangeEvent = function(c, g) { + this.$dispatchEvent("change", {data:{firstRow:c, lastRow:g}}) + }; + this.setUndoManager = function(c) { + this.$undoManager = c; + this.$deltas = []; + this.$informUndoManager && this.$informUndoManager.cancel(); + if(c) { + var g = this; + this.$informUndoManager = f.deferredCall(function() { + g.$deltas.length > 0 && c.execute({action:"aceupdate", args:[g.$deltas, g]}); + g.$deltas = [] + }) + } + }; + this.$defaultUndoManager = {undo:function() { + }, redo:function() { + }}; + this.getUndoManager = function() { + return this.$undoManager || this.$defaultUndoManager + }; + this.getTabString = function() { + return this.getUseSoftTabs() ? f.stringRepeat(" ", this.getTabSize()) : "\t" + }; + this.$useSoftTabs = true; + this.setUseSoftTabs = function(c) { + if(this.$useSoftTabs !== c) { + this.$useSoftTabs = c + } + }; + this.getUseSoftTabs = function() { + return this.$useSoftTabs + }; + this.$tabSize = 4; + this.setTabSize = function(c) { + if(!(isNaN(c) || this.$tabSize === c)) { + this.modified = true; + this.$tabSize = c; + this.$dispatchEvent("changeTabSize") + } + }; + this.getTabSize = function() { + return this.$tabSize + }; + this.getBreakpoints = function() { + return this.$breakpoints + }; + this.setBreakpoints = function(c) { + this.$breakpoints = []; + for(var g = 0;g < c.length;g++) { + this.$breakpoints[c[g]] = true + }this.$dispatchEvent("changeBreakpoint", {}) + }; + this.clearBreakpoints = function() { + this.$breakpoints = []; + this.$dispatchEvent("changeBreakpoint", {}) + }; + this.setBreakpoint = function(c) { + this.$breakpoints[c] = true; + this.$dispatchEvent("changeBreakpoint", {}) + }; + this.clearBreakpoint = function(c) { + delete this.$breakpoints[c]; + this.$dispatchEvent("changeBreakpoint", {}) + }; + this.$detectNewLine = function(c) { + this.$autoNewLine = (c = c.match(/^.*?(\r?\n)/m)) ? c[1] : "\n" + }; + this.tokenRe = /^[\w\d]+/g; + this.nonTokenRe = /^[^\w\d]+/g; + this.getWordRange = function(c, g) { + var l = this.getLine(c), m = false; + if(g > 0) { + m = !!l.charAt(g - 1).match(this.tokenRe) + }m || (m = !!l.charAt(g).match(this.tokenRe)); + m = m ? this.tokenRe : this.nonTokenRe; + var b = g; + if(b > 0) { + do { + b-- + }while(b >= 0 && l.charAt(b).match(m)); + b++ + }for(g = g;g < l.length && l.charAt(g).match(m);) { + g++ + }return new e(c, b, c, g) + }; + 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(c) { + if(this.$newLineMode !== c) { + this.$newLineMode = c + } + }; + this.getNewLineMode = function() { + return this.$newLineMode + }; + this.$mode = null; + this.setMode = function(c) { + if(this.$mode !== c) { + this.$mode = c; + this.$dispatchEvent("changeMode") + } + }; + this.getMode = function() { + if(!this.$mode) { + this.$mode = new i + }return this.$mode + }; + this.$scrollTop = 0; + this.setScrollTopRow = function(c) { + if(this.$scrollTop !== c) { + this.$scrollTop = c; + 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; + for(var c = this.lines, g = 0, l = 0, m = this.getTabSize(), b = 0;b < c.length;b++) { + var d = c[b].length; + g = Math.max(g, d); + c[b].replace("\t", function(n) { + d += m - 1; + return n + }); + l = Math.max(l, d) + }this.width = g; + this.screenWith = l + } + }; + this.getLine = function(c) { + return this.lines[c] || "" + }; + this.getDisplayLine = function(c) { + var g = (new Array(this.getTabSize() + 1)).join(" "); + return this.lines[c].replace(/\t/g, g) + }; + this.getLines = function(c, g) { + return this.lines.slice(c, g + 1) + }; + this.getLength = function() { + return this.lines.length + }; + this.getTextRange = function(c) { + if(c.start.row == c.end.row) { + return this.lines[c.start.row].substring(c.start.column, c.end.column) + }else { + var g = []; + g.push(this.lines[c.start.row].substring(c.start.column)); + g.push.apply(g, this.getLines(c.start.row + 1, c.end.row - 1)); + g.push(this.lines[c.end.row].substring(0, c.end.column)); + return g.join(this.$getNewLineCharacter()) + } + }; + this.findMatchingBracket = function(c) { + if(c.column == 0) { + return null + }var g = this.getLine(c.row).charAt(c.column - 1); + if(g == "") { + return null + }g = g.match(/([\(\[\{])|([\)\]\}])/); + if(!g) { + return null + }return g[1] ? this.$findClosingBracket(g[1], c) : this.$findOpeningBracket(g[2], c) + }; + this.$brackets = {")":"(", "(":")", "]":"[", "[":"]", "{":"}", "}":"{"}; + this.$findOpeningBracket = function(c, g) { + var l = this.$brackets[c], m = g.column - 2; + g = g.row; + for(var b = 1, d = this.getLine(g);;) { + for(;m >= 0;) { + var n = d.charAt(m); + if(n == l) { + b -= 1; + if(b == 0) { + return{row:g, column:m} + } + }else { + if(n == c) { + b += 1 + } + }m -= 1 + }g -= 1; + if(g < 0) { + break + }d = this.getLine(g); + m = d.length - 1 + }return null + }; + this.$findClosingBracket = function(c, g) { + var l = this.$brackets[c], m = g.column; + g = g.row; + for(var b = 1, d = this.getLine(g), n = this.getLength();;) { + for(;m < d.length;) { + var o = d.charAt(m); + if(o == l) { + b -= 1; + if(b == 0) { + return{row:g, column:m} + } + }else { + if(o == c) { + b += 1 + } + }m += 1 + }g += 1; + if(g >= n) { + break + }d = this.getLine(g); + m = 0 + }return null + }; + this.insert = function(c, g, l) { + g = this.$insert(c, g, l); + this.fireChangeEvent(c.row, c.row == g.row ? c.row : undefined); + return g + }; + this.$insertLines = function(c, g, l) { + if(g.length != 0) { + var m = [c, 0]; + m.push.apply(m, g); + this.lines.splice.apply(this.lines, m); + if(!l && this.$undoManager) { + l = this.$getNewLineCharacter(); + this.$deltas.push({action:"insertText", range:new e(c, 0, c + g.length, 0), text:g.join(l) + l}); + this.$informUndoManager.schedule() + } + } + }; + this.$insert = function(c, g, l) { + if(g.length == 0) { + return c + }this.modified = true; + this.lines.length <= 1 && this.$detectNewLine(g); + var m = this.$split(g); + if(this.$isNewLine(g)) { + var b = this.lines[c.row] || ""; + this.lines[c.row] = b.substring(0, c.column); + this.lines.splice(c.row + 1, 0, b.substring(c.column)); + m = {row:c.row + 1, column:0} + }else { + if(m.length == 1) { + b = this.lines[c.row] || ""; + this.lines[c.row] = b.substring(0, c.column) + g + b.substring(c.column); + m = {row:c.row, column:c.column + g.length} + }else { + b = this.lines[c.row] || ""; + var d = b.substring(0, c.column) + m[0]; + b = m[m.length - 1] + b.substring(c.column); + this.lines[c.row] = d; + this.$insertLines(c.row + 1, [b], true); + m.length > 2 && this.$insertLines(c.row + 1, m.slice(1, -1), true); + m = {row:c.row + m.length - 1, column:m[m.length - 1].length} + } + }if(!l && this.$undoManager) { + this.$deltas.push({action:"insertText", range:e.fromPoints(c, m), text:g}); + this.$informUndoManager.schedule() + }return m + }; + this.$isNewLine = function(c) { + return c == "\r\n" || c == "\r" || c == "\n" + }; + this.remove = function(c, g) { + if(c.isEmpty()) { + return c.start + }this.$remove(c, g); + this.fireChangeEvent(c.start.row, c.isMultiLine() ? undefined : c.start.row); + return c.start + }; + this.$remove = function(c, g) { + if(!c.isEmpty()) { + if(!g && this.$undoManager) { + this.$getNewLineCharacter(); + this.$deltas.push({action:"removeText", range:c.clone(), text:this.getTextRange(c)}); + this.$informUndoManager.schedule() + }this.modified = true; + g = c.start.row; + var l = c.end.row, m = this.getLine(g).substring(0, c.start.column) + this.getLine(l).substring(c.end.column); + this.lines.splice(g, l - g + 1, m); + return c.start + } + }; + this.undoChanges = function(c) { + this.selection.clearSelection(); + for(var g = c.length - 1;g >= 0;g--) { + var l = c[g]; + if(l.action == "insertText") { + this.remove(l.range, true); + this.selection.moveCursorToPosition(l.range.start) + }else { + this.insert(l.range.start, l.text, true); + this.selection.clearSelection() + } + } + }; + this.redoChanges = function(c) { + this.selection.clearSelection(); + for(var g = 0;g < c.length;g++) { + var l = c[g]; + if(l.action == "insertText") { + this.insert(l.range.start, l.text, true); + this.selection.setSelectionRange(l.range) + }else { + this.remove(l.range, true); + this.selection.moveCursorToPosition(l.range.start) + } + } + }; + this.replace = function(c, g) { + this.$remove(c); + g = g ? this.$insert(c.start, g) : c.start; + var l = c.end.column == 0 ? c.end.column - 1 : c.end.column; + this.fireChangeEvent(c.start.row, l == g.row ? l : undefined); + return g + }; + this.indentRows = function(c, g) { + g.replace("\t", this.getTabString()); + for(var l = c.start.row;l <= c.end.row;l++) { + this.$insert({row:l, column:0}, g) + }this.fireChangeEvent(c.start.row, c.end.row); + return g.length + }; + this.outdentRows = function(c) { + for(var g = new e(0, 0, 0, 0), l = this.getTabSize(), m = c.start.row;m <= c.end.row;++m) { + var b = this.getLine(m); + g.start.row = m; + g.end.row = m; + for(var d = 0;d < l;++d) { + if(b.charAt(d) != " ") { + break + } + }if(d < l && b.charAt(d) == "\t") { + g.start.column = d; + g.end.column = d + 1 + }else { + g.start.column = 0; + g.end.column = d + }if(m == c.start.row) { + c.start.column -= g.end.column - g.start.column + }if(m == c.end.row) { + c.end.column -= g.end.column - g.start.column + }this.$remove(g) + }this.fireChangeEvent(c.start.row, c.end.row); + return c + }; + this.moveLinesUp = function(c, g) { + if(c <= 0) { + return 0 + }var l = this.lines.slice(c, g + 1); + this.$remove(new e(c, 0, g + 1, 0)); + this.$insertLines(c - 1, l); + this.fireChangeEvent(c - 1, g); + return-1 + }; + this.moveLinesDown = function(c, g) { + if(g >= this.lines.length - 1) { + return 0 + }var l = this.lines.slice(c, g + 1); + this.$remove(new e(c, 0, g + 1, 0)); + this.$insertLines(c + 1, l); + this.fireChangeEvent(c, g + 1); + return 1 + }; + this.duplicateLines = function(c, g) { + c = this.$clipRowToDocument(c); + g = this.$clipRowToDocument(g); + var l = this.getLines(c, g); + this.$insertLines(c, l); + g = g - c + 1; + this.fireChangeEvent(c); + return g + }; + this.$clipRowToDocument = function(c) { + return Math.max(0, Math.min(c, this.lines.length - 1)) + }; + this.documentToScreenColumn = function(c, g) { + var l = this.getTabSize(), m = 0; + g = g; + c = this.getLine(c).split("\t"); + for(var b = 0;b < c.length;b++) { + var d = c[b].length; + if(g > d) { + g -= d + 1; + m += d + l + }else { + m += g; + break + } + }return m + }; + this.screenToDocumentColumn = function(c, g) { + var l = this.getTabSize(), m = 0; + g = g; + c = this.getLine(c).split("\t"); + for(var b = 0;b < c.length;b++) { + var d = c[b].length; + if(g >= d + l) { + g -= d + l; + m += d + 1 + }else { + m += g > d ? d : g; + break + } + }return m + } + }).call(j.prototype); + return j +}); +require.def("ace/Search", ["ace/lib/lang", "ace/lib/oop", "ace/Range"], function(k, f, a) { + var h = function() { + this.$options = {needle:"", backwards:false, wrap:false, caseSensitive:false, wholeWord:false, scope:h.ALL, regExp:false} + }; + h.ALL = 1; + h.SELECTION = 2; + (function() { + this.set = function(i) { + f.mixin(this.$options, i); + return this + }; + this.getOptions = function() { + return k.copyObject(this.$options) + }; + this.find = function(i) { + if(!this.$options.needle) { + return null + }var e = null; + (this.$options.backwards ? this.$backwardMatchIterator(i) : this.$forwardMatchIterator(i)).forEach(function(j) { + e = j; + return true + }); + return e + }; + this.findAll = function(i) { + if(!this.$options.needle) { + return[] + }var e = []; + (this.$options.backwards ? this.$backwardMatchIterator(i) : this.$forwardMatchIterator(i)).forEach(function(j) { + e.push(j) + }); + return e + }; + this.replace = function(i, e) { + var j = this.$assembleRegExp(), c = j.exec(i); + return c && c[0].length == i.length ? this.$options.regExp ? i.replace(j, e) : e : null + }; + this.$forwardMatchIterator = function(i) { + var e = this.$assembleRegExp(), j = this; + return{forEach:function(c) { + j.$forwardLineIterator(i).forEach(function(g, l, m) { + if(l) { + g = g.substring(l) + }var b = []; + g.replace(e, function(n) { + b.push({str:n, offset:l + arguments[arguments.length - 2]}); + return n + }); + for(g = 0;g < b.length;g++) { + var d = b[g]; + d = j.$rangeFromMatch(m, d.offset, d.str.length); + if(c(d)) { + return true + } + } + }) + }} + }; + this.$backwardMatchIterator = function(i) { + var e = this.$assembleRegExp(), j = this; + return{forEach:function(c) { + j.$backwardLineIterator(i).forEach(function(g, l, m) { + if(l) { + g = g.substring(l) + }var b = []; + g.replace(e, function(n, o) { + b.push({str:n, offset:l + o}); + return n + }); + for(g = b.length - 1;g >= 0;g--) { + var d = b[g]; + d = j.$rangeFromMatch(m, d.offset, d.str.length); + if(c(d)) { + return true + } + } + }) + }} + }; + this.$rangeFromMatch = function(i, e, j) { + return new a(i, e, i, e + j) + }; + this.$assembleRegExp = function() { + var i = this.$options.regExp ? this.$options.needle : k.escapeRegExp(this.$options.needle); + if(this.$options.wholeWord) { + i = "\\b" + i + "\\b" + }var e = "g"; + this.$options.caseSensitive || (e += "i"); + return new RegExp(i, e) + }; + this.$forwardLineIterator = function(i) { + function e(n) { + var o = i.getLine(n); + if(j && n == c.end.row) { + o = o.substring(0, c.end.column) + }return o + } + var j = this.$options.scope == h.SELECTION, c = i.getSelection().getRange(), g = i.getSelection().getCursor(), l = j ? c.start.row : 0, m = j ? c.start.column : 0, b = j ? c.end.row : i.getLength() - 1, d = this.$options.wrap; + return{forEach:function(n) { + for(var o = g.row, p = e(o), r = g.column, q = false;!n(p, r, o);) { + if(q) { + return + }o++; + r = 0; + if(o > b) { + if(d) { + o = l; + r = m + }else { + return + } + }if(o == g.row) { + q = true + }p = e(o) + } + }} + }; + this.$backwardLineIterator = function(i) { + var e = this.$options.scope == h.SELECTION, j = i.getSelection().getRange(), c = e ? j.end : j.start, g = e ? j.start.row : 0, l = e ? j.start.column : 0, m = e ? j.end.row : i.getLength() - 1, b = this.$options.wrap; + return{forEach:function(d) { + for(var n = c.row, o = i.getLine(n).substring(0, c.column), p = 0, r = false;!d(o, p, n);) { + if(r) { + return + }n--; + p = 0; + if(n < g) { + if(b) { + n = m + }else { + return + } + }if(n == c.row) { + r = true + }o = i.getLine(n); + if(e) { + if(n == g) { + p = l + }else { + if(n == m) { + o = o.substring(0, j.end.column) + } + } + } + } + }} + } + }).call(h.prototype); + return h +}); +require.def("ace/BackgroundTokenizer", ["ace/lib/oop", "ace/MEventEmitter"], function(k, f) { + var a = function(h, i) { + this.running = false; + this.textLines = []; + this.lines = []; + this.currentLine = 0; + this.tokenizer = h; + var e = this; + this.$worker = function() { + if(e.running) { + for(var j = new Date, c = e.currentLine, g = e.textLines, l = 0, m = i.getLastVisibleRow();e.currentLine < g.length;) { + e.lines[e.currentLine] = e.$tokenizeRows(e.currentLine, e.currentLine)[0]; + e.currentLine++; + l += 1; + if(l % 5 == 0 && new Date - j > 20) { + e.fireUpdateEvent(c, e.currentLine - 1); + e.running = setTimeout(e.$worker, e.currentLine < m ? 20 : 100); + return + } + }e.running = false; + e.fireUpdateEvent(c, g.length - 1) + } + } + }; + (function() { + k.implement(this, f); + this.setTokenizer = function(h) { + this.tokenizer = h; + this.lines = []; + this.start(0) + }; + this.setLines = function(h) { + this.textLines = h; + this.lines = []; + this.stop() + }; + this.fireUpdateEvent = function(h, i) { + this.$dispatchEvent("update", {data:{first:h, last:i}}) + }; + this.start = function(h) { + this.currentLine = Math.min(h || 0, this.currentLine, this.textLines.length); + this.lines.splice(this.currentLine, this.lines.length); + this.stop(); + this.running = setTimeout(this.$worker, 700) + }; + this.stop = function() { + this.running && clearTimeout(this.running); + this.running = false + }; + this.getTokens = function(h, i, e) { + e(this.$tokenizeRows(h, i)) + }; + this.getState = function(h, i) { + i(this.$tokenizeRows(h, h)[0].state) + }; + this.$tokenizeRows = function(h, i) { + var e = [], j = "start", c = false; + if(h > 0 && this.lines[h - 1]) { + j = this.lines[h - 1].state; + c = true + }for(h = h;h <= i;h++) { + if(this.lines[h]) { + g = this.lines[h]; + j = g.state; + e.push(g) + }else { + var g = this.tokenizer.getLineTokens(this.textLines[h] || "", j); + j = g.state; + e.push(g); + if(c) { + this.lines[h] = g + } + } + }return e + } + }).call(a.prototype); + return a +}); +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(k, f, a, h, i, e, j, c, g, l) { + var m = function(b, d) { + var n = b.getContainerElement(); + this.container = n; + this.renderer = b; + this.textInput = new h(n, this); + this.keyBinding = new i(n, this); + var o = this; + f.addListener(n, "mousedown", function(p) { + setTimeout(function() { + o.focus() + }); + return f.preventDefault(p) + }); + f.addListener(n, "selectstart", function(p) { + return f.preventDefault(p) + }); + b = b.getMouseEventTarget(); + f.addListener(b, "mousedown", a.bind(this.onMouseDown, this)); + f.addMultiMouseDownListener(b, 0, 2, 500, a.bind(this.onMouseDoubleClick, this)); + f.addMultiMouseDownListener(b, 0, 3, 600, a.bind(this.onMouseTripleClick, this)); + f.addMouseWheelListener(b, a.bind(this.onMouseWheel, this)); + this.$highlightLineMarker = this.$selectionMarker = null; + this.$blockScrolling = false; + this.$search = (new j).set({wrap:true}); + this.setDocument(d || new e("")); + this.focus() + }; + (function() { + k.implement(this, l); + this.$forwardEvents = {gutterclick:1, gutterdblclick:1}; + this.$originalAddEventListener = this.addEventListener; + this.$originalRemoveEventListener = this.removeEventListener; + this.addEventListener = function(b, d) { + return this.$forwardEvents[b] ? this.renderer.addEventListener(b, d) : this.$originalAddEventListener(b, d) + }; + this.removeEventListener = function(b, d) { + return this.$forwardEvents[b] ? this.renderer.removeEventListener(b, d) : this.$originalRemoveEventListener(b, d) + }; + this.setDocument = function(b) { + if(this.doc != b) { + 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 d = this.doc.getSelection(); + d.removeEventListener("changeCursor", this.$onCursorChange); + d.removeEventListener("changeSelection", this.$onSelectionChange); + this.doc.setScrollTopRow(this.renderer.getScrollTopRow()) + }this.doc = b; + this.$onDocumentChange = a.bind(this.onDocumentChange, this); + b.addEventListener("change", this.$onDocumentChange); + this.renderer.setDocument(b); + this.$onDocumentModeChange = a.bind(this.onDocumentModeChange, this); + b.addEventListener("changeMode", this.$onDocumentModeChange); + this.$onDocumentChangeTabSize = a.bind(this.renderer.updateText, this.renderer); + b.addEventListener("changeTabSize", this.$onDocumentChangeTabSize); + this.$onDocumentChangeBreakpoint = a.bind(this.onDocumentChangeBreakpoint, this); + this.doc.addEventListener("changeBreakpoint", this.$onDocumentChangeBreakpoint); + this.selection = b.getSelection(); + this.$desiredColumn = 0; + this.$onCursorChange = a.bind(this.onCursorChange, this); + this.selection.addEventListener("changeCursor", this.$onCursorChange); + this.$onSelectionChange = a.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(b.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(b) { + this.renderer.setTheme(b) + }; + this.$highlightBrackets = function() { + if(this.$bracketHighlight) { + this.renderer.removeMarker(this.$bracketHighlight); + this.$bracketHighlight = null + }if(!this.$highlightPending) { + var b = this; + this.$highlightPending = true; + setTimeout(function() { + b.$highlightPending = false; + var d = b.doc.findMatchingBracket(b.getCursorPosition()); + if(d) { + d = new g(d.row, d.column, d.row, d.column + 1); + b.$bracketHighlight = b.renderer.addMarker(d, "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(b) { + b = b.data; + this.bgTokenizer.start(b.firstRow); + this.renderer.updateLines(b.firstRow, b.lastRow); + this.renderer.updateCursor(this.getCursorPosition(), this.$overwrite) + }; + this.onTokenizerUpdate = function(b) { + b = b.data; + this.renderer.updateLines(b.first, b.last) + }; + this.onCursorChange = function() { + this.$highlightBrackets(); + this.renderer.updateCursor(this.getCursorPosition(), this.$overwrite); + this.$blockScrolling || this.renderer.scrollCursorIntoView(); + this.$updateHighlightActiveLine() + }; + this.$updateHighlightActiveLine = function() { + this.$highlightLineMarker && this.renderer.removeMarker(this.$highlightLineMarker); + this.$highlightLineMarker = null; + if(this.getHighlightActiveLine() && (this.getSelectionStyle() != "line" || !this.selection.isMultiLine())) { + var b = this.getCursorPosition(); + this.$highlightLineMarker = this.renderer.addMarker(new g(b.row, 0, b.row + 1, 0), "ace_active_line", "line") + } + }; + this.onSelectionChange = function() { + this.$selectionMarker && this.renderer.removeMarker(this.$selectionMarker); + this.$selectionMarker = null; + if(!this.selection.isEmpty()) { + var b = this.selection.getRange(), d = this.getSelectionStyle(); + this.$selectionMarker = this.renderer.addMarker(b, "ace_selection", d) + }this.onCursorChange() + }; + this.onDocumentChangeBreakpoint = function() { + this.renderer.setBreakpoints(this.doc.getBreakpoints()) + }; + this.onDocumentModeChange = function() { + var b = this.doc.getMode(); + if(this.mode != b) { + this.mode = b; + b = b.getTokenizer(); + if(this.bgTokenizer) { + this.bgTokenizer.setTokenizer(b) + }else { + var d = a.bind(this.onTokenizerUpdate, this); + this.bgTokenizer = new c(b, this); + this.bgTokenizer.addEventListener("update", d) + }this.renderer.setTokenizer(this.bgTokenizer) + } + }; + this.onMouseDown = function(b) { + var d = f.getDocumentX(b), n = f.getDocumentY(b); + d = this.renderer.screenToTextCoordinates(d, n); + d.row = Math.max(0, Math.min(d.row, this.doc.getLength() - 1)); + if(f.getButton(b) != 0) { + this.selection.isEmpty() && this.moveCursorToPosition(d) + }else { + if(b.shiftKey) { + this.selection.selectToPosition(d) + }else { + this.moveCursorToPosition(d); + this.$clickSelection || this.selection.clearSelection(d.row, d.column) + }this.renderer.scrollCursorIntoView(); + var o = this, p, r; + f.capture(this.container, function(s) { + p = f.getDocumentX(s); + r = f.getDocumentY(s) + }, function() { + clearInterval(q); + o.$clickSelection = null + }); + var q = setInterval(function() { + if(!(p === undefined || r === undefined)) { + var s = o.renderer.screenToTextCoordinates(p, r); + s.row = Math.max(0, Math.min(s.row, o.doc.getLength() - 1)); + if(o.$clickSelection) { + if(o.$clickSelection.contains(s.row, s.column)) { + o.selection.setSelectionRange(o.$clickSelection) + }else { + var t = o.$clickSelection.compare(s.row, s.column) == -1 ? o.$clickSelection.end : o.$clickSelection.start; + o.selection.setSelectionAnchor(t.row, t.column); + o.selection.selectToPosition(s) + } + }else { + o.selection.selectToPosition(s) + }o.renderer.scrollCursorIntoView() + } + }, 20); + return f.preventDefault(b) + } + }; + this.onMouseDoubleClick = function() { + this.selection.selectWord(); + this.$clickSelection = this.getSelectionRange(); + this.$updateDesiredColumn() + }; + this.onMouseTripleClick = function() { + this.selection.selectLine(); + this.$clickSelection = this.getSelectionRange(); + this.$updateDesiredColumn() + }; + this.onMouseWheel = function(b) { + var d = this.$scrollSpeed * 2; + this.renderer.scrollBy(b.wheelX * d, b.wheelY * d); + return f.preventDefault(b) + }; + this.getCopyText = function() { + return this.selection.isEmpty() ? "" : this.doc.getTextRange(this.getSelectionRange()) + }; + this.onCut = function() { + if(!this.$readOnly) { + if(!this.selection.isEmpty()) { + this.moveCursorToPosition(this.doc.remove(this.getSelectionRange())); + this.clearSelection() + } + } + }; + this.onTextInput = function(b) { + if(!this.$readOnly) { + var d = this.getCursorPosition(); + b = b.replace("\t", this.doc.getTabString()); + if(this.selection.isEmpty()) { + if(this.$overwrite) { + var n = new g.fromPoints(d, d); + n.end.column += b.length; + this.doc.remove(n) + } + }else { + d = this.doc.remove(this.getSelectionRange()); + this.clearSelection() + }this.clearSelection(); + var o = this; + this.bgTokenizer.getState(d.row, function(p) { + var r = o.mode.checkOutdent(p, o.doc.getLine(d.row), b), q = o.doc.getLine(d.row), s = o.mode.getNextLineIndent(p, q, o.doc.getTabString()), t = o.doc.insert(d, b); + o.bgTokenizer.getState(d.row, function(x) { + if(d.row !== t.row) { + x = o.doc.getTabSize(); + for(var y = Number.MAX_VALUE, v = d.row + 1;v <= t.row;++v) { + var w = 0; + q = o.doc.getLine(v); + for(var u = 0;u < q.length;++u) { + if(q.charAt(u) == "\t") { + w += x + }else { + if(q.charAt(u) == " ") { + w += 1 + }else { + break + } + } + }if(/[^\s]$/.test(q)) { + y = Math.min(w, y) + } + }for(v = d.row + 1;v <= t.row;++v) { + w = y; + q = o.doc.getLine(v); + for(u = 0;u < q.length && w > 0;++u) { + if(q.charAt(u) == "\t") { + w -= x + }else { + if(q.charAt(u) == " ") { + w -= 1 + } + } + }o.doc.replace(new g(v, 0, v, q.length), q.substr(u)) + }t.column += o.doc.indentRows(new g(d.row + 1, 0, t.row, t.column), s) + }else { + if(r) { + t.column += o.mode.autoOutdent(x, o.doc, d.row) + } + }o.moveCursorToPosition(t); + o.renderer.scrollCursorIntoView() + }) + }) + } + }; + this.$overwrite = false; + this.setOverwrite = function(b) { + if(this.$overwrite != b) { + this.$overwrite = b; + this.$blockScrolling = true; + this.onCursorChange(); + this.$blockScrolling = false; + this.$dispatchEvent("changeOverwrite", {data:b}) + } + }; + this.getOverwrite = function() { + return this.$overwrite + }; + this.toggleOverwrite = function() { + this.setOverwrite(!this.$overwrite) + }; + this.$scrollSpeed = 1; + this.setScrollSpeed = function(b) { + this.$scrollSpeed = b + }; + this.getScrollSpeed = function() { + return this.$scrollSpeed + }; + this.$selectionStyle = "line"; + this.setSelectionStyle = function(b) { + if(this.$selectionStyle != b) { + this.$selectionStyle = b; + this.onSelectionChange(); + this.$dispatchEvent("changeSelectionStyle", {data:b}) + } + }; + this.getSelectionStyle = function() { + return this.$selectionStyle + }; + this.$highlightActiveLine = true; + this.setHighlightActiveLine = function(b) { + if(this.$highlightActiveLine != b) { + this.$highlightActiveLine = b; + this.$updateHighlightActiveLine() + } + }; + this.getHighlightActiveLine = function() { + return this.$highlightActiveLine + }; + this.setShowInvisibles = function(b) { + this.getShowInvisibles() != b && this.renderer.setShowInvisibles(b) + }; + this.getShowInvisibles = function() { + return this.renderer.getShowInvisibles() + }; + this.setShowPrintMargin = function(b) { + this.renderer.setShowPrintMargin(b) + }; + this.getShowPrintMargin = function() { + return this.renderer.getShowPrintMargin() + }; + this.setPrintMarginColumn = function(b) { + this.renderer.setPrintMarginColumn(b) + }; + this.getPrintMarginColumn = function() { + return this.renderer.getPrintMarginColumn() + }; + this.$readOnly = false; + this.setReadOnly = function(b) { + this.$readOnly = b + }; + this.getReadOnly = function() { + return this.$readOnly + }; + this.removeRight = function() { + if(!this.$readOnly) { + this.selection.isEmpty() && this.selection.selectRight(); + this.moveCursorToPosition(this.doc.remove(this.getSelectionRange())); + this.clearSelection() + } + }; + this.removeLeft = function() { + if(!this.$readOnly) { + this.selection.isEmpty() && this.selection.selectLeft(); + this.moveCursorToPosition(this.doc.remove(this.getSelectionRange())); + this.clearSelection() + } + }; + this.indent = function() { + if(!this.$readOnly) { + var b = this.getSelectionRange(); + if(b.start.row < b.end.row || b.start.column < b.end.column) { + b = this.doc.indentRows(this.getSelectionRange(), "\t"); + this.selection.shiftSelection(b) + }else { + if(this.doc.getUseSoftTabs()) { + b = this.doc.getTabSize(); + b = b - this.getCursorPosition().column % b; + b = a.stringRepeat(" ", b) + }else { + b = "\t" + }return this.onTextInput(b) + } + } + }; + this.blockOutdent = function() { + if(!this.$readOnly) { + var b = this.doc.getSelection(), d = this.doc.outdentRows(b.getRange()); + b.setSelectionRange(d, b.isBackwards()); + this.$updateDesiredColumn() + } + }; + this.toggleCommentLines = function() { + if(!this.$readOnly) { + var b = this.$getSelectedRows(), d = new g(b.first, 0, b.last, 0), n = this; + this.bgTokenizer.getState(this.getCursorPosition().row, function(o) { + o = n.mode.toggleCommentLines(o, n.doc, d); + n.selection.shiftSelection(o) + }) + } + }; + this.removeLines = function() { + if(!this.$readOnly) { + var b = this.$getSelectedRows(); + this.selection.setSelectionAnchor(b.last + 1, 0); + this.selection.selectTo(b.first, 0); + this.doc.remove(this.getSelectionRange()); + this.clearSelection() + } + }; + this.moveLinesDown = function() { + this.$readOnly || this.$moveLines(function(b, d) { + return this.doc.moveLinesDown(b, d) + }) + }; + this.moveLinesUp = function() { + this.$readOnly || this.$moveLines(function(b, d) { + return this.doc.moveLinesUp(b, d) + }) + }; + this.copyLinesUp = function() { + this.$readOnly || this.$moveLines(function(b, d) { + this.doc.duplicateLines(b, d); + return 0 + }) + }; + this.copyLinesDown = function() { + this.$readOnly || this.$moveLines(function(b, d) { + return this.doc.duplicateLines(b, d) + }) + }; + this.$moveLines = function(b) { + var d = this.$getSelectedRows(), n = b.call(this, d.first, d.last), o = this.selection; + o.setSelectionAnchor(d.last + n + 1, 0); + o.$moveSelection(function() { + o.moveCursorTo(d.first + n, 0) + }) + }; + this.$getSelectedRows = function() { + var b = this.getSelectionRange(), d = b.start.row, n = b.end.row; + if(b.end.column == 0 && b.start.row !== b.end.row) { + n -= 1 + }return{first:d, last:n} + }; + this.onCompositionStart = function() { + this.renderer.showComposition(this.getCursorPosition()) + }; + this.onCompositionUpdate = function(b) { + this.renderer.setCompositionText(b) + }; + this.onCompositionEnd = function() { + this.renderer.hideComposition() + }; + this.getFirstVisibleRow = function() { + return this.renderer.getFirstVisibleRow() + }; + this.getLastVisibleRow = function() { + return this.renderer.getLastVisibleRow() + }; + this.isRowVisible = function(b) { + return b >= this.getFirstVisibleRow() && b <= this.getLastVisibleRow() + }; + this.getVisibleRowCount = function() { + return this.getLastVisibleRow() - this.getFirstVisibleRow() + 1 + }; + this.getPageDownRow = function() { + return this.renderer.getLastVisibleRow() - 1 + }; + this.getPageUpRow = function() { + var b = this.renderer.getFirstVisibleRow(), d = this.renderer.getLastVisibleRow(); + return b - (d - b) + 1 + }; + this.selectPageDown = function() { + var b = this.getPageDownRow() + Math.floor(this.getVisibleRowCount() / 2); + this.scrollPageDown(); + var d = this.getSelection(); + d.$moveSelection(function() { + d.moveCursorTo(b, d.getSelectionLead().column) + }) + }; + this.selectPageUp = function() { + var b = this.getLastVisibleRow() - this.getFirstVisibleRow(), d = this.getPageUpRow() + Math.round(b / 2); + this.scrollPageUp(); + var n = this.getSelection(); + n.$moveSelection(function() { + n.moveCursorTo(d, n.getSelectionLead().column) + }) + }; + this.gotoPageDown = function() { + var b = this.getPageDownRow(), d = Math.min(this.getCursorPosition().column, this.doc.getLine(b).length); + this.scrollToRow(b); + this.getSelection().moveCursorTo(b, d) + }; + this.gotoPageUp = function() { + var b = this.getPageUpRow(), d = Math.min(this.getCursorPosition().column, this.doc.getLine(b).length); + this.scrollToRow(b); + this.getSelection().moveCursorTo(b, d) + }; + this.scrollPageDown = function() { + this.scrollToRow(this.getPageDownRow()) + }; + this.scrollPageUp = function() { + this.renderer.scrollToRow(this.getPageUpRow()) + }; + this.scrollToRow = function(b) { + this.renderer.scrollToRow(b) + }; + 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(b, d) { + this.selection.moveCursorTo(b, d); + this.$updateDesiredColumn() + }; + this.moveCursorToPosition = function(b) { + this.selection.moveCursorToPosition(b); + this.$updateDesiredColumn() + }; + this.gotoLine = function(b, d) { + this.selection.clearSelection(); + this.$blockScrolling = true; + this.moveCursorTo(b - 1, d || 0); + this.$blockScrolling = false; + this.isRowVisible(this.getCursorPosition().row) || this.scrollToRow(b - 1 - Math.floor(this.getVisibleRowCount() / 2)) + }; + this.navigateTo = function(b, d) { + this.clearSelection(); + this.moveCursorTo(b, d); + this.$updateDesiredColumn(d) + }; + this.navigateUp = function() { + this.selection.clearSelection(); + this.selection.moveCursorBy(-1, 0); + if(this.$desiredColumn) { + var b = this.getCursorPosition(), d = this.doc.screenToDocumentColumn(b.row, this.$desiredColumn); + this.selection.moveCursorTo(b.row, d) + } + }; + this.navigateDown = function() { + this.selection.clearSelection(); + this.selection.moveCursorBy(1, 0); + if(this.$desiredColumn) { + var b = this.getCursorPosition(), d = this.doc.screenToDocumentColumn(b.row, this.$desiredColumn); + this.selection.moveCursorTo(b.row, d) + } + }; + this.$updateDesiredColumn = function() { + var b = this.getCursorPosition(); + this.$desiredColumn = this.doc.documentToScreenColumn(b.row, b.column) + }; + this.navigateLeft = function() { + this.selection.isEmpty() ? this.selection.moveCursorLeft() : this.moveCursorToPosition(this.getSelectionRange().start); + this.clearSelection() + }; + this.navigateRight = function() { + this.selection.isEmpty() ? this.selection.moveCursorRight() : this.moveCursorToPosition(this.getSelectionRange().end); + 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(b, d) { + d && this.$search.set(d); + d = this.$search.find(this.doc); + this.$tryReplace(d, b); + d !== null && this.selection.setSelectionRange(d); + this.$updateDesiredColumn() + }; + this.replaceAll = function(b, d) { + d && this.$search.set(d); + this.clearSelection(); + this.selection.moveCursorTo(0, 0); + d = this.$search.findAll(this.doc); + if(d.length) { + for(var n = d.length - 1;n >= 0;--n) { + this.$tryReplace(d[n], b) + }d[0] !== null && this.selection.setSelectionRange(d[0]); + this.$updateDesiredColumn() + } + }; + this.$tryReplace = function(b, d) { + d = this.$search.replace(this.doc.getTextRange(b), d); + if(d !== null) { + b.end = this.doc.replace(b, d); + return b + }else { + return null + } + }; + this.getLastSearchOptions = function() { + return this.$search.getOptions() + }; + this.find = function(b, d) { + this.clearSelection(); + d = d || {}; + d.needle = b; + this.$search.set(d); + this.$find() + }; + this.findNext = function(b) { + b = b || {}; + if(typeof b.backwards == "undefined") { + b.backwards = false + }this.$search.set(b); + this.$find() + }; + this.findPrevious = function(b) { + b = b || {}; + if(typeof b.backwards == "undefined") { + b.backwards = true + }this.$search.set(b); + this.$find() + }; + this.$find = function(b) { + this.selection.isEmpty() || this.$search.set({needle:this.doc.getTextRange(this.getSelectionRange())}); + typeof b != "undefined" && this.$search.set({backwards:b}); + if(b = this.$search.find(this.doc)) { + this.gotoLine(b.end.row + 1, b.end.column); + this.$updateDesiredColumn(); + this.selection.setSelectionRange(b) + } + }; + this.undo = function() { + this.doc.getUndoManager().undo() + }; + this.redo = function() { + this.doc.getUndoManager().redo() + } + }).call(m.prototype); + return m +}); +require.def("ace/UndoManager", function() { + var k = function() { + this.$undoStack = []; + this.$redoStack = [] + }; + (function() { + this.execute = function(f) { + var a = f.args[0]; + this.$doc = f.args[1]; + this.$undoStack.push(a) + }; + this.undo = function() { + var f = this.$undoStack.pop(); + if(f) { + this.$doc.undoChanges(f); + this.$redoStack.push(f) + } + }; + this.redo = function() { + var f = this.$redoStack.pop(); + if(f) { + this.$doc.redoChanges(f); + this.$undoStack.push(f) + } + } + }).call(k.prototype); + return k +}); +if(!require.def) { + require.def = require("requireJS-node")(module, require) +}require.def("ace/lib/dom", ["ace/lib/lang"], function(k) { + var f = {}; + f.setText = function(a, h) { + if(a.innerText !== undefined) { + a.innerText = h + }if(a.textContent !== undefined) { + a.textContent = h + } + }; + f.hasCssClass = function(a, h) { + a = a.className.split(/\s+/g); + return k.arrayIndexOf(a, h) !== -1 + }; + f.addCssClass = function(a, h) { + f.hasCssClass(a, h) || (a.className += " " + h) + }; + f.removeCssClass = function(a, h) { + for(var i = a.className.split(/\s+/g);;) { + var e = k.arrayIndexOf(i, h); + if(e == -1) { + break + }i.splice(e, 1) + }a.className = i.join(" ") + }; + f.importCssString = function(a, h) { + h = h || document; + if(h.createStyleSheet) { + h.createStyleSheet().cssText = a + }else { + var i = h.createElement("style"); + i.appendChild(h.createTextNode(a)); + h.getElementsByTagName("head")[0].appendChild(i) + } + }; + f.getInnerWidth = function(a) { + return parseInt(f.computedStyle(a, "paddingLeft")) + parseInt(f.computedStyle(a, "paddingRight")) + a.clientWidth + }; + f.getInnerHeight = function(a) { + return parseInt(f.computedStyle(a, "paddingTop")) + parseInt(f.computedStyle(a, "paddingBottom")) + a.clientHeight + }; + f.computedStyle = function(a, h) { + return window.getComputedStyle ? (window.getComputedStyle(a, "") || {})[h] || "" : a.currentStyle[h] + }; + f.scrollbarWidth = function() { + var a = document.createElement("p"); + a.style.width = "100%"; + a.style.height = "200px"; + var h = document.createElement("div"), i = h.style; + i.position = "absolute"; + i.left = "-10000px"; + i.overflow = "hidden"; + i.width = "200px"; + i.height = "150px"; + h.appendChild(a); + document.body.appendChild(h); + var e = a.offsetWidth; + i.overflow = "scroll"; + a = a.offsetWidth; + if(e == a) { + a = h.clientWidth + }document.body.removeChild(h); + return e - a + }; + return f +}); +require.def("ace/layer/Gutter", [], function() { + var k = function(f) { + this.element = document.createElement("div"); + this.element.className = "ace_layer ace_gutter-layer"; + f.appendChild(this.element); + this.$breakpoints = []; + this.$decorations = [] + }; + (function() { + this.addGutterDecoration = function(f, a) { + this.$decorations[f] || (this.$decorations[f] = ""); + this.$decorations[f] += " ace_" + a + }; + this.removeGutterDecoration = function(f, a) { + this.$decorations[f] = this.$decorations[f].replace(" ace_" + a, "") + }; + this.setBreakpoints = function(f) { + this.$breakpoints = f.concat() + }; + this.update = function(f) { + this.$config = f; + for(var a = [], h = f.firstRow;h <= f.lastRow;h++) { + a.push("
", h + 1, "
"); + a.push("") + }this.element.innerHTML = a.join(""); + this.element.style.height = f.minHeight + "px" + } + }).call(k.prototype); + return k +}); +require.def("ace/layer/Marker", ["ace/Range"], function(k) { + var f = function(a) { + this.element = document.createElement("div"); + this.element.className = "ace_layer ace_marker-layer"; + a.appendChild(this.element); + this.markers = {}; + this.$markerId = 1 + }; + (function() { + this.setDocument = function(a) { + this.doc = a + }; + this.addMarker = function(a, h, i) { + var e = this.$markerId++; + this.markers[e] = {range:a, type:i || "line", clazz:h}; + return e + }; + this.removeMarker = function(a) { + this.markers[a] && delete this.markers[a] + }; + this.update = function(a) { + if(a = a || this.config) { + this.config = a; + var h = []; + for(var i in this.markers) { + var e = this.markers[i], j = e.range.clipRows(a.firstRow, a.lastRow); + if(!j.isEmpty()) { + if(j.isMultiLine()) { + e.type == "text" ? this.drawTextMarker(h, j, e.clazz, a) : this.drawMultiLineMarker(h, j, e.clazz, a) + }else { + this.drawSingleLineMarker(h, j, e.clazz, a) + } + } + }this.element.innerHTML = h.join("") + } + }; + this.drawTextMarker = function(a, h, i, e) { + var j = h.start.row, c = new k(j, h.start.column, j, this.doc.getLine(j).length); + this.drawSingleLineMarker(a, c, i, e); + j = h.end.row; + c = new k(j, 0, j, h.end.column); + this.drawSingleLineMarker(a, c, i, e); + for(j = h.start.row + 1;j < h.end.row;j++) { + c.start.row = j; + c.end.row = j; + c.end.column = this.doc.getLine(j).length; + this.drawSingleLineMarker(a, c, i, e) + } + }; + this.drawMultiLineMarker = function(a, h, i, e) { + h = h.toScreenRange(this.doc); + var j = e.lineHeight, c = Math.round(e.width - h.start.column * e.characterWidth), g = (h.start.row - e.firstRow) * e.lineHeight, l = Math.round(h.start.column * e.characterWidth); + a.push("
"); + g = (h.end.row - e.firstRow) * e.lineHeight; + c = Math.round(h.end.column * e.characterWidth); + a.push("
"); + j = (h.end.row - h.start.row - 1) * e.lineHeight; + if(!(j < 0)) { + g = (h.start.row + 1 - e.firstRow) * e.lineHeight; + a.push("
") + } + }; + this.drawSingleLineMarker = function(a, h, i, e) { + h = h.toScreenRange(this.doc); + var j = e.lineHeight, c = Math.round((h.end.column - h.start.column) * e.characterWidth), g = (h.start.row - e.firstRow) * e.lineHeight; + h = Math.round(h.start.column * e.characterWidth); + a.push("
") + } + }).call(f.prototype); + return f +}); +require.def("ace/layer/Text", ["ace/lib/oop", "ace/lib/dom", "ace/MEventEmitter"], function(k, f, a) { + var h = function(i) { + this.element = document.createElement("div"); + this.element.className = "ace_layer ace_text-layer"; + i.appendChild(this.element); + this.$characterSize = this.$measureSizes(); + this.$pollSizeChanges() + }; + (function() { + k.implement(this, a); + this.EOF_CHAR = "¶"; + this.EOL_CHAR = "¬"; + this.TAB_CHAR = "→"; + this.SPACE_CHAR = "·"; + this.setTokenizer = function(i) { + this.tokenizer = i + }; + this.getLineHeight = function() { + return this.$characterSize.height || 1 + }; + this.getCharacterWidth = function() { + return this.$characterSize.width || 1 + }; + this.$pollSizeChanges = function() { + var i = this; + setInterval(function() { + var e = i.$measureSizes(); + if(i.$characterSize.width !== e.width || i.$characterSize.height !== e.height) { + i.$characterSize = e; + i.$dispatchEvent("changeCharaterSize", {data:e}) + } + }, 500) + }; + this.$fontStyles = {fontFamily:1, fontSize:1, fontWeight:1, fontStyle:1, lineHeight:1}; + this.$measureSizes = function() { + var i = document.createElement("div"), e = i.style; + e.width = e.height = "auto"; + e.left = e.top = "-1000px"; + e.visibility = "hidden"; + e.position = "absolute"; + e.overflow = "visible"; + for(var j in this.$fontStyles) { + var c = f.computedStyle(this.element, j); + e[j] = c + }i.innerHTML = (new Array(1E3)).join("Xy"); + document.body.insertBefore(i, document.body.firstChild); + e = {height:i.offsetHeight, width:i.offsetWidth / 2E3}; + document.body.removeChild(i); + return e + }; + this.setDocument = function(i) { + this.doc = i + }; + this.$showInvisibles = false; + this.setShowInvisibles = function(i) { + this.$showInvisibles = i + }; + this.$computeTabString = function() { + var i = this.doc.getTabSize(); + if(this.$showInvisibles) { + i = i / 2; + this.$tabString = "" + (new Array(Math.floor(i))).join(" ") + this.TAB_CHAR + (new Array(Math.ceil(i) + 1)).join(" ") + "" + }else { + this.$tabString = (new Array(i + 1)).join(" ") + } + }; + this.updateLines = function(i, e, j) { + this.$computeTabString(); + var c = Math.max(e, i.firstRow), g = Math.min(j, i.lastRow), l = this.element.childNodes, m = this; + this.tokenizer.getTokens(c, g, function(b) { + for(var d = c;d <= g;d++) { + var n = l[d - i.firstRow]; + if(n) { + var o = []; + m.$renderLine(o, d, b[d - c].tokens); + n.innerHTML = o.join("") + } + } + }) + }; + this.scrollLines = function(i) { + function e(b) { + i.firstRow < g.firstRow ? c.$renderLinesFragment(i, i.firstRow, g.firstRow - 1, function(d) { + l.firstChild ? l.insertBefore(d, l.firstChild) : l.appendChild(d); + b() + }) : b() + } + function j() { + i.lastRow > g.lastRow && c.$renderLinesFragment(i, g.lastRow + 1, i.lastRow, function(b) { + l.appendChild(b) + }) + } + var c = this; + this.$computeTabString(); + var g = this.config; + this.config = i; + if(!g || g.lastRow < i.firstRow) { + return this.update(i) + }if(i.lastRow < g.firstRow) { + return this.update(i) + }var l = this.element; + if(g.firstRow < i.firstRow) { + for(var m = g.firstRow;m < i.firstRow;m++) { + l.removeChild(l.firstChild) + } + }if(g.lastRow > i.lastRow) { + for(m = i.lastRow + 1;m <= g.lastRow;m++) { + l.removeChild(l.lastChild) + } + }e(j) + }; + this.$renderLinesFragment = function(i, e, j, c) { + var g = document.createDocumentFragment(), l = this; + this.tokenizer.getTokens(e, j, function(m) { + for(var b = e;b <= j;b++) { + var d = document.createElement("div"); + d.className = "ace_line"; + var n = d.style; + n.height = l.$characterSize.height + "px"; + n.width = i.width + "px"; + n = []; + l.$renderLine(n, b, m[b - e].tokens); + d.innerHTML = n.join(""); + g.appendChild(d) + }c(g) + }) + }; + this.update = function(i) { + this.$computeTabString(); + var e = [], j = this; + this.tokenizer.getTokens(i.firstRow, i.lastRow, function(c) { + for(var g = i.firstRow;g <= i.lastRow;g++) { + e.push("
"); + j.$renderLine(e, g, c[g - i.firstRow].tokens); + e.push("
") + }j.element.innerHTML = e.join("") + }) + }; + this.$textToken = {text:true, rparen:true, lparen:true}; + this.$renderLine = function(i, e, j) { + for(var c = /[\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]/g, g = 0;g < j.length;g++) { + var l = j[g], m = l.value.replace(/&/g, "&").replace(/", m, "") + } + }if(this.$showInvisibles) { + e !== this.doc.getLength() - 1 ? i.push("" + this.EOL_CHAR + "") : i.push("" + this.EOF_CHAR + "") + } + } + }).call(h.prototype); + return h +}); +require.def("ace/layer/Cursor", ["ace/lib/dom"], function(k) { + var f = function(a) { + this.element = document.createElement("div"); + this.element.className = "ace_layer ace_cursor-layer"; + a.appendChild(this.element); + this.cursor = document.createElement("div"); + this.cursor.className = "ace_cursor"; + this.isVisible = false + }; + (function() { + this.setDocument = function(a) { + this.doc = a + }; + this.setCursor = function(a, h) { + this.position = {row:a.row, column:this.doc.documentToScreenColumn(a.row, a.column)}; + h ? k.addCssClass(this.cursor, "ace_overwrite") : k.removeCssClass(this.cursor, "ace_overwrite") + }; + this.hideCursor = function() { + this.isVisible = false; + this.cursor.parentNode && this.cursor.parentNode.removeChild(this.cursor); + clearInterval(this.blinkId) + }; + this.showCursor = function() { + this.isVisible = true; + this.element.appendChild(this.cursor); + this.cursor.style.visibility = "visible"; + this.restartTimer() + }; + this.restartTimer = function() { + clearInterval(this.blinkId); + if(this.isVisible) { + var a = this.cursor; + this.blinkId = setInterval(function() { + a.style.visibility = "hidden"; + setTimeout(function() { + a.style.visibility = "visible" + }, 400) + }, 1E3) + } + }; + this.getPixelPosition = function() { + if(!this.config || !this.position) { + return{left:0, top:0} + }var a = this.position.row * this.config.lineHeight; + return{left:Math.round(this.position.column * this.config.characterWidth), top:a} + }; + this.update = function(a) { + if(this.position) { + this.config = a; + var h = Math.round(this.position.column * a.characterWidth), i = this.position.row * a.lineHeight; + this.pixelPos = {left:h, top:i}; + this.cursor.style.left = h + "px"; + this.cursor.style.top = i - a.firstRow * a.lineHeight + "px"; + this.cursor.style.width = a.characterWidth + "px"; + this.cursor.style.height = a.lineHeight + "px"; + this.isVisible && this.element.appendChild(this.cursor); + this.restartTimer() + } + } + }).call(f.prototype); + return f +}); +require.def("ace/ScrollBar", ["ace/lib/oop", "ace/lib/lang", "ace/lib/dom", "ace/lib/event", "ace/MEventEmitter"], function(k, f, a, h, i) { + var e = function(j) { + this.element = document.createElement("div"); + this.element.className = "ace_sb"; + this.inner = document.createElement("div"); + this.element.appendChild(this.inner); + j.appendChild(this.element); + this.width = a.scrollbarWidth(); + this.element.style.width = this.width; + h.addListener(this.element, "scroll", f.bind(this.onScroll, this)) + }; + (function() { + k.implement(this, i); + this.onScroll = function() { + this.$dispatchEvent("scroll", {data:this.element.scrollTop}) + }; + this.getWidth = function() { + return this.width + }; + this.setHeight = function(j) { + this.element.style.height = Math.max(0, j - this.width) + "px" + }; + this.setInnerHeight = function(j) { + this.inner.style.height = j + "px" + }; + this.setScrollTop = function(j) { + this.element.scrollTop = j + } + }).call(e.prototype); + return e +}); +require.def("ace/RenderLoop", function() { + var k = function(f) { + this.onRender = f; + this.pending = false; + this.changes = 0 + }; + (function() { + this.schedule = function(f) { + this.changes |= f; + if(!this.pending) { + this.pending = true; + var a = this; + this.setTimeoutZero(function() { + a.pending = false; + a.onRender(a.changes); + a.changes = 0 + }) + } + }; + if(window.postMessage) { + this.messageName = "zero-timeout-message"; + this.setTimeoutZero = function(f) { + if(!this.attached) { + var a = this; + window.addEventListener("message", function(h) { + if(h.source == window && a.callback && h.data == a.messageName) { + h.stopPropagation(); + a.callback() + } + }, false); + this.attached = true + }this.callback = f; + window.postMessage(this.messageName, "*") + } + }else { + this.setTimeoutZero = function(f) { + setTimeout(f, 0) + } + } + }).call(k.prototype); + return k +}); +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!.ace_editor {\n position: absolute;\n overflow: hidden;\n\n font-family: "Menlo", "Monaco", "Courier New", monospace;\n font-size: 12px; \n}\n\n.ace_scroller {\n position: absolute;\n overflow-x: scroll;\n overflow-y: hidden; \n}\n\n.ace_gutter {\n position: absolute;\n overflow-x: hidden;\n overflow-y: hidden;\n height: 100%;\n}\n\n.ace_editor .ace_sb {\n position: absolute;\n overflow-x: hidden;\n overflow-y: scroll;\n right: 0;\n}\n\n.ace_editor .ace_sb div {\n position: absolute;\n width: 1px;\n left: 0px;\n}\n\n.ace_editor .ace_printMargin {\n position: absolute;\n height: 100%;\n}\n\n.ace_layer {\n z-index: 0;\n position: absolute;\n overflow: hidden; \n white-space: nowrap;\n height: 100%;\n}\n\n.ace_text-layer {\n font-family: Monaco, "Courier New", monospace;\n color: black;\n}\n\n.ace_cursor-layer {\n cursor: text;\n}\n\n.ace_cursor {\n z-index: 3;\n position: absolute;\n}\n\n.ace_line {\n white-space: nowrap;\n}\n\n.ace_marker-layer {\n}\n\n.ace_marker-layer .ace_step {\n position: absolute;\n z-index: 2;\n}\n\n.ace_marker-layer .ace_selection {\n position: absolute;\n z-index: 3;\n}\n\n.ace_marker-layer .ace_bracket {\n position: absolute;\n z-index: 4;\n}\n\n.ace_marker-layer .ace_active_line {\n position: absolute;\n z-index: 1;\n}'], +function(k, f, a, h, i, e, j, c, g, l, m, b) { + a.importCssString(b); + b = function(d, n) { + this.container = d; + a.addCssClass(this.container, "ace_editor"); + this.setTheme(n); + 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 i(this.$gutter); + this.$markerLayer = new e(this.content); + var o = this.$textLayer = new j(this.content); + this.canvas = o.element; + this.characterWidth = o.getCharacterWidth(); + this.lineHeight = o.getLineHeight(); + this.$cursorLayer = new c(this.content); + this.layers = [this.$markerLayer, o, this.$cursorLayer]; + this.scrollBar = new g(d); + this.scrollBar.addEventListener("scroll", f.bind(this.onScroll, this)); + this.scrollTop = 0; + this.cursorPos = {row:0, column:0}; + var p = this; + this.$textLayer.addEventListener("changeCharaterSize", function() { + p.characterWidth = o.getCharacterWidth(); + p.lineHeight = o.getLineHeight(); + p.$loop.schedule(p.CHANGE_FULL) + }); + h.addListener(this.$gutter, "click", f.bind(this.$onGutterClick, this)); + h.addListener(this.$gutter, "dblclick", f.bind(this.$onGutterClick, this)); + this.$size = {width:0, height:0, scrollerHeight:0, scrollerWidth:0}; + this.$loop = new l(f.bind(this.$renderChanges, this)); + this.$loop.schedule(this.CHANGE_FULL); + this.$updatePrintMargin(); + this.setPadding(4) + }; + (function() { + this.showGutter = true; + 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; + k.implement(this, m); + this.setDocument = function(d) { + this.lines = d.lines; + this.doc = d; + this.$cursorLayer.setDocument(d); + this.$markerLayer.setDocument(d); + this.$textLayer.setDocument(d); + this.$loop.schedule(this.CHANGE_FULL) + }; + this.updateLines = function(d, n) { + if(n === undefined) { + n = Infinity + }if(this.$changedLines) { + if(this.$changedLines.firstRow > d) { + this.$changedLines.firstRow = d + }if(this.$changedLines.lastRow < n) { + this.$changedLines.lastRow = n + } + }else { + this.$changedLines = {firstRow:d, lastRow:n} + }this.$loop.schedule(this.CHANGE_LINES) + }; + this.updateText = function() { + this.$loop.schedule(this.CHANGE_TEXT) + }; + this.updateFull = function() { + this.$loop.schedule(this.CHANGE_FULL) + }; + this.onResize = function() { + this.$loop.schedule(this.CHANGE_SIZE); + var d = a.getInnerHeight(this.container); + if(this.$size.height != d) { + this.$size.height = d; + this.scroller.style.height = d + "px"; + this.scrollBar.setHeight(d); + if(this.doc) { + this.scrollToY(this.getScrollTop()); + this.$loop.schedule(this.CHANGE_FULL) + } + }d = a.getInnerWidth(this.container); + if(this.$size.width != d) { + this.$size.width = d; + var n = this.showGutter ? this.$gutter.offsetWidth : 0; + this.scroller.style.left = n + "px"; + this.scroller.style.width = Math.max(0, d - n - this.scrollBar.getWidth()) + "px" + }this.$size.scrollerWidth = this.scroller.clientWidth; + this.$size.scrollerHeight = this.scroller.clientHeight + }; + this.setTokenizer = function(d) { + this.$tokenizer = d; + this.$textLayer.setTokenizer(d); + this.$loop.schedule(this.CHANGE_TEXT) + }; + this.$onGutterClick = function(d) { + var n = h.getDocumentX(d), o = h.getDocumentY(d); + this.$dispatchEvent("gutter" + d.type, {row:this.screenToTextCoordinates(n, o).row, htmlEvent:d}) + }; + this.$showInvisibles = true; + this.setShowInvisibles = function(d) { + this.$showInvisibles = d; + this.$textLayer.setShowInvisibles(d); + this.$loop.schedule(this.CHANGE_TEXT) + }; + this.getShowInvisibles = function() { + return this.$showInvisibles + }; + this.$showPrintMargin = true; + this.setShowPrintMargin = function(d) { + this.$showPrintMargin = d; + this.$updatePrintMargin() + }; + this.getShowPrintMargin = function() { + return this.$showPrintMargin + }; + this.$printMarginColumn = 80; + this.setPrintMarginColumn = function(d) { + this.$printMarginColumn = d; + this.$updatePrintMargin() + }; + this.getPrintMarginColumn = function() { + return this.$printMarginColumn + }; + this.setShowGutter = function(d) { + this.$gutter.style.display = d ? "block" : "none"; + this.showGutter = d; + this.onResize() + }; + this.$updatePrintMargin = function() { + if(this.$showPrintMargin || this.$printMarginEl) { + if(!this.$printMarginEl) { + this.$printMarginEl = document.createElement("div"); + this.$printMarginEl.className = "ace_printMargin"; + this.content.insertBefore(this.$printMarginEl, this.$textLayer.element) + }var d = this.$printMarginEl.style; + d.left = this.characterWidth * this.$printMarginColumn + "px"; + d.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.getFirstFullyVisibleRow = function() { + if(!this.layerConfig) { + return 0 + }return this.layerConfig.firstRow + (this.layerConfig.offset == 0 ? 0 : 1) + }; + this.getLastFullyVisibleRow = function() { + if(!this.layerConfig) { + return 0 + }return this.layerConfig.firstRow - 1 + Math.floor((this.layerConfig.height + this.layerConfig.offset) / this.layerConfig.lineHeight) + }; + this.getLastVisibleRow = function() { + return(this.layerConfig || {}).lastRow || 0 + }; + this.$padding = null; + this.setPadding = function(d) { + this.$padding = d; + this.content.style.padding = "0 " + d + "px"; + this.$loop.schedule(this.CHANGE_FULL) + }; + this.onScroll = function(d) { + this.scrollToY(d.data) + }; + this.$updateScrollBar = function() { + this.scrollBar.setInnerHeight(this.doc.getLength() * this.lineHeight); + this.scrollBar.setScrollTop(this.scrollTop) + }; + this.$renderChanges = function(d) { + if(!(!d || !this.doc || !this.$tokenizer)) { + if(!this.layerConfig || d & this.CHANGE_FULL || d & this.CHANGE_SIZE || d & this.CHANGE_TEXT || d & this.CHANGE_LINES || d & this.CHANGE_SCROLL) { + this.$computeLayerConfig() + }if(d & this.CHANGE_FULL) { + this.$textLayer.update(this.layerConfig); + this.showGutter && this.$gutterLayer.update(this.layerConfig); + this.$markerLayer.update(this.layerConfig); + this.$cursorLayer.update(this.layerConfig); + this.$updateScrollBar() + }else { + if(d & this.CHANGE_SCROLL) { + d & this.CHANGE_TEXT || d & this.CHANGE_LINES ? this.$textLayer.scrollLines(this.layerConfig) : this.$textLayer.update(this.layerConfig); + this.showGutter && this.$gutterLayer.update(this.layerConfig); + this.$markerLayer.update(this.layerConfig); + this.$cursorLayer.update(this.layerConfig); + this.$updateScrollBar() + }else { + if(d & this.CHANGE_TEXT) { + this.$textLayer.update(this.layerConfig); + this.showGutter && this.$gutterLayer.update(this.layerConfig) + }else { + if(d & this.CHANGE_LINES) { + this.$updateLines(); + this.$updateScrollBar() + }else { + if(d & this.CHANGE_SCROLL) { + this.$textLayer.scrollLines(this.layerConfig); + this.showGutter && this.$gutterLayer.update(this.layerConfig) + } + } + }d & this.CHANGE_GUTTER && this.showGutter && this.$gutterLayer.update(this.layerConfig); + d & this.CHANGE_CURSOR && this.$cursorLayer.update(this.layerConfig); + d & this.CHANGE_MARKER && this.$markerLayer.update(this.layerConfig); + d & this.CHANGE_SIZE && this.$updateScrollBar() + } + } + } + }; + this.$computeLayerConfig = function() { + var d = this.scrollTop % this.lineHeight, n = this.$size.scrollerHeight + this.lineHeight, o = this.$getLongestLine(), p = !this.layerConfig ? true : this.layerConfig.width != o, r = Math.ceil(n / this.lineHeight), q = Math.max(0, Math.round((this.scrollTop - d) / this.lineHeight)); + r = Math.min(this.lines.length, q + r) - 1; + this.layerConfig = {width:o, padding:this.$padding, firstRow:q, lastRow:r, lineHeight:this.lineHeight, characterWidth:this.characterWidth, minHeight:n, offset:d, height:this.$size.scrollerHeight}; + for(q = 0;q < this.layers.length;q++) { + r = this.layers[q]; + if(p) { + r.element.style.width = o + "px" + } + }this.$gutterLayer.element.style.marginTop = -d + "px"; + this.content.style.marginTop = -d + "px"; + this.content.style.width = o + "px"; + this.content.style.height = n + "px" + }; + this.$updateLines = function() { + var d = this.$changedLines.firstRow, n = this.$changedLines.lastRow; + this.$changedLines = null; + var o = this.layerConfig; + if(o.width != this.$getLongestLine()) { + return this.$textLayer.update(o) + }if(!(d > o.lastRow + 1)) { + if(!(n < o.firstRow)) { + if(n === Infinity) { + this.showGutter && this.$gutterLayer.update(o); + this.$textLayer.update(o) + }else { + this.$textLayer.updateLines(o, d, n) + } + } + } + }; + this.$getLongestLine = function() { + var d = this.doc.getScreenWidth(); + if(this.$showInvisibles) { + d += 1 + }return Math.max(this.$size.scrollerWidth - this.$padding * 2, Math.round(d * this.characterWidth)) + }; + this.addMarker = function(d, n, o) { + d = this.$markerLayer.addMarker(d, n, o); + this.$loop.schedule(this.CHANGE_MARKER); + return d + }; + this.removeMarker = function(d) { + this.$markerLayer.removeMarker(d); + this.$loop.schedule(this.CHANGE_MARKER) + }; + this.addGutterDecoration = function(d, n) { + this.$gutterLayer.addGutterDecoration(d, n); + this.$loop.schedule(this.CHANGE_GUTTER) + }; + this.removeGutterDecoration = function(d, n) { + this.$gutterLayer.removeGutterDecoration(d, n); + this.$loop.schedule(this.CHANGE_GUTTER) + }; + this.setBreakpoints = function(d) { + this.$gutterLayer.setBreakpoints(d); + this.$loop.schedule(this.CHANGE_GUTTER) + }; + this.updateCursor = function(d, n) { + this.$cursorLayer.setCursor(d, n); + this.$loop.schedule(this.CHANGE_CURSOR) + }; + this.hideCursor = function() { + this.$cursorLayer.hideCursor() + }; + this.showCursor = function() { + this.$cursorLayer.showCursor() + }; + this.scrollCursorIntoView = function() { + var d = this.$cursorLayer.getPixelPosition(), n = d.left + this.$padding; + d = d.top; + this.getScrollTop() > d && this.scrollToY(d); + this.getScrollTop() + this.$size.scrollerHeight < d + this.lineHeight && this.scrollToY(d + this.lineHeight - this.$size.scrollerHeight); + this.scroller.scrollLeft > n && this.scrollToX(n); + this.scroller.scrollLeft + this.$size.scrollerWidth < n + this.characterWidth && this.scrollToX(Math.round(n + 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(d) { + this.scrollToY(d * this.lineHeight) + }; + this.scrollToY = function(d) { + d = Math.max(0, Math.min(this.lines.length * this.lineHeight - this.$size.scrollerHeight, d)); + if(this.scrollTop !== d) { + this.scrollTop = d; + this.$loop.schedule(this.CHANGE_SCROLL) + } + }; + this.scrollToX = function(d) { + if(d <= this.$padding) { + d = 0 + }this.scroller.scrollLeft = d + }; + this.scrollBy = function(d, n) { + n && this.scrollToY(this.scrollTop + n); + d && this.scrollToX(this.scroller.scrollLeft + d) + }; + this.screenToTextCoordinates = function(d, n) { + var o = this.scroller.getBoundingClientRect(); + d = Math.round((d + this.scroller.scrollLeft - o.left - this.$padding) / this.characterWidth); + n = Math.floor((n + this.scrollTop - o.top) / this.lineHeight); + return{row:n, column:this.doc.screenToDocumentColumn(Math.max(0, Math.min(n, this.doc.getLength() - 1)), d)} + }; + this.textToScreenCoordinates = function(d, n) { + var o = this.scroller.getBoundingClientRect(); + n = this.padding + Math.round(this.doc.documentToScreenColumn(d, n) * this.characterWidth); + d = d * this.lineHeight; + return{pageX:o.left + n - this.getScrollLeft(), pageY:o.top + d - this.getScrollTop()} + }; + this.visualizeFocus = function() { + a.addCssClass(this.container, "ace_focus") + }; + this.visualizeBlur = function() { + a.removeCssClass(this.container, "ace_focus") + }; + this.showComposition = function() { + }; + this.setCompositionText = function() { + }; + this.hideComposition = function() { + }; + this.setTheme = function(d) { + function n(p) { + o.$theme && a.removeCssClass(o.container, o.$theme); + o.$theme = p ? p.cssClass : null; + o.$theme && a.addCssClass(o.container, o.$theme); + if(o.$size) { + o.$size.width = 0; + o.onResize() + } + } + var o = this; + if(!d || typeof d == "string") { + d = d || "ace/theme/TextMate"; + require([d], function(p) { + n(p) + }) + }else { + n(d) + }o = this + } + }).call(b.prototype); + return b +}); +require.def("ace/mode/DocCommentHighlightRules", ["ace/lib/oop", "ace/mode/TextHighlightRules"], function(k, f) { + var a = function() { + this.$rules = {start:[{token:"comment.doc", regex:"\\*\\/", next:"start"}, {token:"comment.doc.tag", regex:"@[\\w\\d_]+"}, {token:"comment.doc", regex:"s+"}, {token:"comment.doc", regex:"[^@\\*]+"}, {token:"comment.doc", regex:"."}]} + }; + k.inherits(a, f); + (function() { + this.getStartRule = function(h) { + return{token:"comment.doc", regex:"\\/\\*(?=\\*)", next:h} + } + }).call(a.prototype); + return a +}); +require.def("ace/mode/JavaScriptHighlightRules", ["ace/lib/oop", "ace/lib/lang", "ace/mode/DocCommentHighlightRules", "ace/mode/TextHighlightRules"], function(k, f, a, h) { + JavaScriptHighlightRules = function() { + var i = new a, e = f.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("|")), j = f.arrayToMap("true|false|null|undefined|Infinity|NaN|undefined".split("|")), c = f.arrayToMap("abstract|boolean|byte|char|class|const|enum|export|extends|final|float|goto|implements|int|interface|long|native|package|private|protected|short|static|super|synchronized|throws|transient|volatiledouble|import|public".split("|")); + this.$rules = {start:[{token:"comment", regex:"\\/\\/.*$"}, i.getStartRule("doc-start"), {token:"comment", regex:"\\/\\*", next:"comment"}, {token:"string.regexp", regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/][gimy]*\\s*(?=[).,;]|$)"}, {token:"string", regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'}, {token:"string", regex:'["].*\\\\$', next:"qqstring"}, {token:"string", regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"}, {token:"string", regex:"['].*\\\\$", next:"qstring"}, {token:"constant.numeric", + regex:"0[xX][0-9a-fA-F]+\\b"}, {token:"constant.numeric", regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"}, {token:function(g) { + return g == "this" ? "variable.language" : e[g] ? "keyword" : j[g] ? "constant.language" : c[g] ? "invalid.illegal" : g == "debugger" ? "invalid.deprecated" : "identifier" + }, 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", regex:".*?\\*\\/", next:"start"}, {token:"comment", regex:".+"}], qqstring:[{token:"string", regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"', + next:"start"}, {token:"string", regex:".+"}], qstring:[{token:"string", regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'", next:"start"}, {token:"string", regex:".+"}]}; + this.addRules(i.getRules(), "doc-"); + this.$rules["doc-start"][0].next = "start" + }; + k.inherits(JavaScriptHighlightRules, h); + return JavaScriptHighlightRules +}); +require.def("ace/mode/MatchingBraceOutdent", ["ace/Range"], function(k) { + var f = function() { + }; + (function() { + this.checkOutdent = function(a, h) { + if(!/^\s+$/.test(a)) { + return false + }return/^\s*\}/.test(h) + }; + this.autoOutdent = function(a, h) { + var i = a.getLine(h).match(/^(\s*\})/); + if(!i) { + return 0 + }i = i[1].length; + var e = a.findMatchingBracket({row:h, column:i}); + if(!e || e.row == h) { + return 0 + }e = this.$getIndent(a.getLine(e.row)); + a.replace(new k(h, 0, h, i - 1), e); + return e.length - (i - 1) + }; + this.$getIndent = function(a) { + if(a = a.match(/^(\s+)/)) { + return a[1] + }return"" + } + }).call(f.prototype); + return f +}); +require.def("ace/mode/JavaScript", ["ace/lib/oop", "ace/mode/Text", "ace/Tokenizer", "ace/mode/JavaScriptHighlightRules", "ace/mode/MatchingBraceOutdent", "ace/Range"], function(k, f, a, h, i, e) { + var j = function() { + this.$tokenizer = new a((new h).getRules()); + this.$outdent = new i + }; + k.inherits(j, f); + (function() { + this.toggleCommentLines = function(c, g, l) { + var m = true; + c = /^(\s*)\/\//; + for(var b = l.start.row;b <= l.end.row;b++) { + if(!c.test(g.getLine(b))) { + m = false; + break + } + }if(m) { + m = new e(0, 0, 0, 0); + for(b = l.start.row;b <= l.end.row;b++) { + var d = g.getLine(b).replace(c, "$1"); + m.start.row = b; + m.end.row = b; + m.end.column = d.length + 2; + g.replace(m, d) + }return-2 + }else { + return g.indentRows(l, "//") + } + }; + this.getNextLineIndent = function(c, g, l) { + var m = this.$getIndent(g), b = this.$tokenizer.getLineTokens(g, c), d = b.tokens; + b = b.state; + if(d.length && d[d.length - 1].type == "comment") { + return m + }if(c == "start") { + if(c = g.match(/^.*[\{\(\[]\s*$/)) { + m += l + } + }else { + if(c == "doc-start") { + if(b == "start") { + return"" + }if(c = g.match(/^\s*(\/?)\*/)) { + if(c[1]) { + m += " " + }m += "* " + } + } + }return m + }; + this.checkOutdent = function(c, g, l) { + return this.$outdent.checkOutdent(g, l) + }; + this.autoOutdent = function(c, g, l) { + return this.$outdent.autoOutdent(g, l) + } + }).call(j.prototype); + return j +}); +require.def("ace/theme/TextMate", ["ace/lib/dom", "text!ace/theme/tm.css!.ace-tm .ace_editor {\n border: 2px solid rgb(159, 159, 159);\n}\n\n.ace-tm .ace_editor.ace_focus {\n border: 2px solid #327fbd;\n}\n\n.ace-tm .ace_gutter {\n width: 50px;\n background: #e8e8e8;\n color: #333;\n overflow : hidden;\n}\n\n.ace-tm .ace_gutter-layer {\n width: 100%;\n text-align: right;\n}\n\n.ace-tm .ace_gutter-layer .ace_gutter-cell {\n padding-right: 6px;\n}\n\n.ace-tm .ace_editor .ace_printMargin {\n width: 1px;\n background: #e8e8e8;\n}\n\n.ace-tm .ace_text-layer {\n cursor: text;\n}\n\n.ace-tm .ace_cursor {\n border-left: 2px solid black;\n}\n\n.ace-tm .ace_cursor.ace_overwrite {\n border-left: 0px;\n border-bottom: 1px solid black;\n}\n \n.ace-tm .ace_line .ace_invisible {\n color: rgb(191, 191, 191);\n}\n\n.ace-tm .ace_line .ace_keyword {\n color: blue;\n}\n\n.ace-tm .ace_line .ace_constant.ace_buildin {\n color: rgb(88, 72, 246);\n}\n\n.ace-tm .ace_line .ace_constant.ace_library {\n color: rgb(6, 150, 14);\n}\n\n.ace-tm .ace_line .ace_invalid {\n background-color: rgb(153, 0, 0);\n color: white;\n}\n\n.ace-tm .ace_line .ace_support.ace_function {\n color: rgb(60, 76, 114);\n}\n\n.ace-tm .ace_line .ace_keyword.ace_operator {\n color: rgb(104, 118, 135);\n}\n\n.ace-tm .ace_line .ace_string {\n color: rgb(3, 106, 7);\n}\n\n.ace-tm .ace_line .ace_comment {\n color: rgb(76, 136, 107);\n}\n\n.ace-tm .ace_line .ace_comment.ace_doc {\n color: rgb(0, 102, 255);\n}\n\n.ace-tm .ace_line .ace_comment.ace_doc.ace_tag {\n color: rgb(128, 159, 191);\n}\n\n.ace-tm .ace_line .ace_constant.ace_numeric {\n color: rgb(0, 0, 205);\n}\n\n.ace-tm .ace_line .ace_variable {\n color: rgb(49, 132, 149);\n}\n\n.ace-tm .ace_line .ace_xml_pe {\n color: rgb(104, 104, 91);\n}\n\n.ace-tm .ace_marker-layer .ace_selection {\n background: rgb(181, 213, 255);\n}\n\n.ace-tm .ace_marker-layer .ace_step {\n background: rgb(252, 255, 0);\n}\n\n.ace-tm .ace_marker-layer .ace_stack {\n background: rgb(164, 229, 101);\n}\n\n.ace-tm .ace_marker-layer .ace_bracket {\n margin: -1px 0 0 -1px;\n border: 1px solid rgb(192, 192, 192);\n}\n\n.ace-tm .ace_marker-layer .ace_active_line {\n background: rgb(232, 242, 254);\n}\n\n.ace-tm .ace_string.ace_regex {\n color: rgb(255, 0, 0) \n}"], +function(k, f) { + k.importCssString(f); + return{cssClass:"ace-tm"} +}); \ No newline at end of file diff --git a/build/ace/KeyBinding.js b/build/ace/KeyBinding.js new file mode 100644 index 00000000..630b8b96 --- /dev/null +++ b/build/ace/KeyBinding.js @@ -0,0 +1,57 @@ +/* + LGPLv3 +*/ +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(m, k, n, o, p) { + var l = function(i, g, j) { + this.setConfig(j); + var a = this; + k.addKeyListener(i, function(b) { + var c = (a.config.reverse[0 | (b.ctrlKey ? 1 : 0) | (b.altKey ? 2 : 0) | (b.shiftKey ? 4 : 0) | (b.metaKey ? 8 : 0)] || {})[(a.keyNames[b.keyCode] || String.fromCharCode(b.keyCode)).toLowerCase()]; + if(c = p.commands[c]) { + c(g, g.getSelection()); + return k.stopEvent(b) + } + }) + }; + (function() { + function i(a, b, c, e) { + return(e && a.toLowerCase() || a).replace(/(?:^\s+|\n|\s+$)/g, "").split(new RegExp("[\\s ]*" + b + "[\\s ]*", "g"), c || 999) + } + function g(a, b, c) { + var e, f = 0; + a = i(a, "\\-", null, true); + for(var d = 0, h = a.length;d < h;++d) { + if(this.keyMods[a[d]]) { + f |= this.keyMods[a[d]] + }else { + e = a[d] || "-" + } + }(c[f] || (c[f] = {}))[e] = b; + return c + } + function j(a, b) { + var c, e, f, d, h = {}; + for(c in a) { + d = a[c]; + if(b && typeof d == "string") { + d = d.split(b); + e = 0; + for(f = d.length;e < f;++e) { + g.call(this, d[e], c, h) + } + }else { + g.call(this, d, c, h) + } + }return h + } + 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"}; + this.setConfig = function(a) { + this.config = a || (m.isMac ? n : o); + if(typeof this.config.reverse == "undefined") { + this.config.reverse = j.call(this, this.config, "|") + } + } + }).call(l.prototype); + return l +}); \ No newline at end of file diff --git a/build/ace/MEventEmitter.js b/build/ace/MEventEmitter.js new file mode 100644 index 00000000..488095fa --- /dev/null +++ b/build/ace/MEventEmitter.js @@ -0,0 +1,33 @@ +/* + LGPLv3 +*/ +if(!require.def) { + require.def = require("requireJS-node")(module, require) +}require.def("ace/MEventEmitter", ["ace/lib/lang"], function(e) { + var d = {}; + d.$dispatchEvent = function(a, b) { + this.$eventRegistry = this.$eventRegistry || {}; + var c = this.$eventRegistry[a]; + if(c && c.length) { + b = b || {}; + b.type = a; + for(a = 0;a < c.length;a++) { + c[a](b) + } + } + }; + d.on = d.addEventListener = function(a, b) { + this.$eventRegistry = this.$eventRegistry || {}; + var c = this.$eventRegistry[a]; + c || (c = this.$eventRegistry[a] = []); + e.arrayIndexOf(c, b) == -1 && c.push(b) + }; + d.removeEventListener = function(a, b) { + this.$eventRegistry = this.$eventRegistry || {}; + if(a = this.$eventRegistry[a]) { + b = e.arrayIndexOf(a, b); + b !== -1 && a.splice(b, 1) + } + }; + return d +}); \ No newline at end of file diff --git a/build/ace/PluginManager.js b/build/ace/PluginManager.js new file mode 100644 index 00000000..0378800b --- /dev/null +++ b/build/ace/PluginManager.js @@ -0,0 +1,8 @@ +/* + LGPLv3 +*/ +require.def("ace/PluginManager", [], function() { + return{commands:{}, registerCommand:function(a, b) { + this.commands[a] = b + }} +}); \ No newline at end of file diff --git a/build/ace/Range.js b/build/ace/Range.js new file mode 100644 index 00000000..e3268974 --- /dev/null +++ b/build/ace/Range.js @@ -0,0 +1,71 @@ +/* + LGPLv3 +*/ +require.def("ace/Range", function() { + var c = function(a, b, d, e) { + this.start = {row:a, column:b}; + this.end = {row:d, column:e} + }; + (function() { + this.toString = function() { + return"Range: [" + this.start.row + "/" + this.start.column + "] -> [" + this.end.row + "/" + this.end.column + "]" + }; + this.contains = function(a, b) { + return this.compare(a, b) == 0 + }; + this.compare = function(a, b) { + if(!this.isMultiLine()) { + if(a === this.start.row) { + return b < this.start.column ? -1 : b > this.end.column ? 1 : 0 + } + }if(a < this.start.row) { + return-1 + }if(a > this.end.row) { + return 1 + }if(this.start.row === a) { + return b >= this.start.column ? 0 : -1 + }if(this.end.row === a) { + return b <= this.end.column ? 0 : 1 + }return 0 + }; + this.clipRows = function(a, b) { + if(this.end.row > b) { + var d = {row:b + 1, column:0} + }if(this.start.row > b) { + var e = {row:b + 1, column:0} + }if(this.start.row < a) { + e = {row:a, column:0} + }if(this.end.row < a) { + d = {row:a, column:0} + }return c.fromPoints(e || this.start, d || this.end) + }; + this.extend = function(a, b) { + var d = this.compare(a, b); + if(d == 0) { + return this + }else { + if(d == -1) { + var e = {row:a, column:b} + }else { + var f = {row:a, column:b} + } + }return c.fromPoints(e || this.start, f || 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 c.fromPoints(this.start, this.end) + }; + this.toScreenRange = function(a) { + return new c(this.start.row, a.documentToScreenColumn(this.start.row, this.start.column), this.end.row, a.documentToScreenColumn(this.end.row, this.end.column)) + } + }).call(c.prototype); + c.fromPoints = function(a, b) { + return new c(a.row, a.column, b.row, b.column) + }; + return c +}); \ No newline at end of file diff --git a/build/ace/RenderLoop.js b/build/ace/RenderLoop.js new file mode 100644 index 00000000..0d7ed9b1 --- /dev/null +++ b/build/ace/RenderLoop.js @@ -0,0 +1,45 @@ +/* + LGPLv3 +*/ +require.def("ace/RenderLoop", function() { + var d = function(b) { + this.onRender = b; + this.pending = false; + this.changes = 0 + }; + (function() { + this.schedule = function(b) { + this.changes |= b; + if(!this.pending) { + this.pending = true; + var a = this; + this.setTimeoutZero(function() { + a.pending = false; + a.onRender(a.changes); + a.changes = 0 + }) + } + }; + if(window.postMessage) { + this.messageName = "zero-timeout-message"; + this.setTimeoutZero = function(b) { + if(!this.attached) { + var a = this; + window.addEventListener("message", function(c) { + if(c.source == window && a.callback && c.data == a.messageName) { + c.stopPropagation(); + a.callback() + } + }, false); + this.attached = true + }this.callback = b; + window.postMessage(this.messageName, "*") + } + }else { + this.setTimeoutZero = function(b) { + setTimeout(b, 0) + } + } + }).call(d.prototype); + return d +}); \ No newline at end of file diff --git a/build/ace/ScrollBar.js b/build/ace/ScrollBar.js new file mode 100644 index 00000000..8d5cee59 --- /dev/null +++ b/build/ace/ScrollBar.js @@ -0,0 +1,34 @@ +/* + LGPLv3 +*/ +require.def("ace/ScrollBar", ["ace/lib/oop", "ace/lib/lang", "ace/lib/dom", "ace/lib/event", "ace/MEventEmitter"], function(c, d, e, f, g) { + var b = function(a) { + this.element = document.createElement("div"); + this.element.className = "ace_sb"; + this.inner = document.createElement("div"); + this.element.appendChild(this.inner); + a.appendChild(this.element); + this.width = e.scrollbarWidth(); + this.element.style.width = this.width; + f.addListener(this.element, "scroll", d.bind(this.onScroll, this)) + }; + (function() { + c.implement(this, g); + this.onScroll = function() { + this.$dispatchEvent("scroll", {data:this.element.scrollTop}) + }; + this.getWidth = function() { + return this.width + }; + this.setHeight = function(a) { + this.element.style.height = Math.max(0, a - this.width) + "px" + }; + this.setInnerHeight = function(a) { + this.inner.style.height = a + "px" + }; + this.setScrollTop = function(a) { + this.element.scrollTop = a + } + }).call(b.prototype); + return b +}); \ No newline at end of file diff --git a/build/ace/Search.js b/build/ace/Search.js new file mode 100644 index 00000000..a8c334c3 --- /dev/null +++ b/build/ace/Search.js @@ -0,0 +1,152 @@ +/* + LGPLv3 +*/ +require.def("ace/Search", ["ace/lib/lang", "ace/lib/oop", "ace/Range"], function(o, q, r) { + var l = function() { + this.$options = {needle:"", backwards:false, wrap:false, caseSensitive:false, wholeWord:false, scope:l.ALL, regExp:false} + }; + l.ALL = 1; + l.SELECTION = 2; + (function() { + this.set = function(a) { + q.mixin(this.$options, a); + return this + }; + this.getOptions = function() { + return o.copyObject(this.$options) + }; + this.find = function(a) { + if(!this.$options.needle) { + return null + }var b = null; + (this.$options.backwards ? this.$backwardMatchIterator(a) : this.$forwardMatchIterator(a)).forEach(function(c) { + b = c; + return true + }); + return b + }; + this.findAll = function(a) { + if(!this.$options.needle) { + return[] + }var b = []; + (this.$options.backwards ? this.$backwardMatchIterator(a) : this.$forwardMatchIterator(a)).forEach(function(c) { + b.push(c) + }); + return b + }; + this.replace = function(a, b) { + var c = this.$assembleRegExp(), g = c.exec(a); + return g && g[0].length == a.length ? this.$options.regExp ? a.replace(c, b) : b : null + }; + this.$forwardMatchIterator = function(a) { + var b = this.$assembleRegExp(), c = this; + return{forEach:function(g) { + c.$forwardLineIterator(a).forEach(function(d, i, k) { + if(i) { + d = d.substring(i) + }var j = []; + d.replace(b, function(e) { + j.push({str:e, offset:i + arguments[arguments.length - 2]}); + return e + }); + for(d = 0;d < j.length;d++) { + var h = j[d]; + h = c.$rangeFromMatch(k, h.offset, h.str.length); + if(g(h)) { + return true + } + } + }) + }} + }; + this.$backwardMatchIterator = function(a) { + var b = this.$assembleRegExp(), c = this; + return{forEach:function(g) { + c.$backwardLineIterator(a).forEach(function(d, i, k) { + if(i) { + d = d.substring(i) + }var j = []; + d.replace(b, function(e, f) { + j.push({str:e, offset:i + f}); + return e + }); + for(d = j.length - 1;d >= 0;d--) { + var h = j[d]; + h = c.$rangeFromMatch(k, h.offset, h.str.length); + if(g(h)) { + return true + } + } + }) + }} + }; + this.$rangeFromMatch = function(a, b, c) { + return new r(a, b, a, b + c) + }; + this.$assembleRegExp = function() { + var a = this.$options.regExp ? this.$options.needle : o.escapeRegExp(this.$options.needle); + if(this.$options.wholeWord) { + a = "\\b" + a + "\\b" + }var b = "g"; + this.$options.caseSensitive || (b += "i"); + return new RegExp(a, b) + }; + this.$forwardLineIterator = function(a) { + function b(e) { + var f = a.getLine(e); + if(c && e == g.end.row) { + f = f.substring(0, g.end.column) + }return f + } + var c = this.$options.scope == l.SELECTION, g = a.getSelection().getRange(), d = a.getSelection().getCursor(), i = c ? g.start.row : 0, k = c ? g.start.column : 0, j = c ? g.end.row : a.getLength() - 1, h = this.$options.wrap; + return{forEach:function(e) { + for(var f = d.row, m = b(f), n = d.column, p = false;!e(m, n, f);) { + if(p) { + return + }f++; + n = 0; + if(f > j) { + if(h) { + f = i; + n = k + }else { + return + } + }if(f == d.row) { + p = true + }m = b(f) + } + }} + }; + this.$backwardLineIterator = function(a) { + var b = this.$options.scope == l.SELECTION, c = a.getSelection().getRange(), g = b ? c.end : c.start, d = b ? c.start.row : 0, i = b ? c.start.column : 0, k = b ? c.end.row : a.getLength() - 1, j = this.$options.wrap; + return{forEach:function(h) { + for(var e = g.row, f = a.getLine(e).substring(0, g.column), m = 0, n = false;!h(f, m, e);) { + if(n) { + return + }e--; + m = 0; + if(e < d) { + if(j) { + e = k + }else { + return + } + }if(e == g.row) { + n = true + }f = a.getLine(e); + if(b) { + if(e == d) { + m = i + }else { + if(e == k) { + f = f.substring(0, c.end.column) + } + } + } + } + }} + } + }).call(l.prototype); + return l +}); \ No newline at end of file diff --git a/build/ace/Selection.js b/build/ace/Selection.js new file mode 100644 index 00000000..b401b0e4 --- /dev/null +++ b/build/ace/Selection.js @@ -0,0 +1,257 @@ +/* + LGPLv3 +*/ +require.def("ace/Selection", ["ace/lib/oop", "ace/lib/lang", "ace/MEventEmitter", "ace/Range"], function(g, h, i, e) { + var f = function(a) { + this.doc = a; + this.clearSelection(); + this.selectionLead = {row:0, column:0} + }; + (function() { + g.implement(this, i); + 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(a, b) { + a = this.$clipPositionToDocument(a, b); + if(this.selectionAnchor) { + if(this.selectionAnchor.row !== a.row || this.selectionAnchor.column !== a.column) { + this.selectionAnchor = a; + this.$dispatchEvent("changeSelection", {}) + } + }else { + this.selectionAnchor = a; + this.$dispatchEvent("changeSelection", {}) + } + }; + this.getSelectionAnchor = function() { + return this.selectionAnchor ? this.$clone(this.selectionAnchor) : this.$clone(this.selectionLead) + }; + this.getSelectionLead = function() { + return this.$clone(this.selectionLead) + }; + this.shiftSelection = function(a) { + if(this.isEmpty()) { + this.moveCursorTo(this.selectionLead.row, this.selectionLead.column + a) + }else { + var b = this.getSelectionAnchor(), c = this.getSelectionLead(), d = this.isBackwards(); + if(!d || b.column !== 0) { + this.setSelectionAnchor(b.row, b.column + a) + }if(d || c.column !== 0) { + this.$moveSelection(function() { + this.moveCursorTo(c.row, c.column + a) + }) + } + } + }; + this.isBackwards = function() { + var a = this.selectionAnchor || this.selectionLead, b = this.selectionLead; + return a.row > b.row || a.row == b.row && a.column > b.column + }; + this.getRange = function() { + var a = this.selectionAnchor || this.selectionLead, b = this.selectionLead; + return this.isBackwards() ? e.fromPoints(b, a) : e.fromPoints(a, b) + }; + this.clearSelection = function() { + if(this.selectionAnchor) { + this.selectionAnchor = null; + this.$dispatchEvent("changeSelection", {}) + } + }; + this.selectAll = function() { + var a = this.doc.getLength() - 1; + this.setSelectionAnchor(a, this.doc.getLine(a).length); + this.$moveSelection(function() { + this.moveCursorTo(0, 0) + }) + }; + this.setSelectionRange = function(a, b) { + if(b) { + this.setSelectionAnchor(a.end.row, a.end.column); + this.selectTo(a.start.row, a.start.column) + }else { + this.setSelectionAnchor(a.start.row, a.start.column); + this.selectTo(a.end.row, a.end.column) + } + }; + this.$moveSelection = function(a) { + var b = false; + if(!this.selectionAnchor) { + b = true; + this.selectionAnchor = this.$clone(this.selectionLead) + }var c = this.$clone(this.selectionLead); + a.call(this); + if(c.row !== this.selectionLead.row || c.column !== this.selectionLead.column) { + b = true + }b && this.$dispatchEvent("changeSelection", {}) + }; + this.selectTo = function(a, b) { + this.$moveSelection(function() { + this.moveCursorTo(a, b) + }) + }; + this.selectToPosition = function(a) { + this.$moveSelection(function() { + this.moveCursorToPosition(a) + }) + }; + 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.selectWordRight = function() { + this.$moveSelection(this.moveCursorWordRight) + }; + this.selectWordLeft = function() { + this.$moveSelection(this.moveCursorWordLeft) + }; + this.selectWord = function() { + var a = this.selectionLead; + this.setSelectionRange(this.doc.getWordRange(a.row, a.column)) + }; + 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) { + 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) { + this.selectionLead.row < this.doc.getLength() - 1 && this.moveCursorTo(this.selectionLead.row + 1, 0) + }else { + this.moveCursorBy(0, 1) + } + }; + this.moveCursorLineStart = function() { + var a = this.selectionLead.row, b = this.selectionLead.column, c = this.doc.getLine(a).slice(0, b).match(/^\s*/); + if(c[0].length == 0) { + this.moveCursorTo(a, this.doc.getLine(a).match(/^\s*/)[0].length) + }else { + c[0].length >= b ? this.moveCursorTo(a, 0) : this.moveCursorTo(a, c[0].length) + } + }; + this.moveCursorLineEnd = function() { + this.moveCursorTo(this.selectionLead.row, this.doc.getLine(this.selectionLead.row).length) + }; + this.moveCursorFileEnd = function() { + var a = this.doc.getLength() - 1, b = this.doc.getLine(a).length; + this.moveCursorTo(a, b) + }; + this.moveCursorFileStart = function() { + this.moveCursorTo(0, 0) + }; + this.moveCursorWordRight = function() { + var a = this.selectionLead.row, b = this.selectionLead.column, c = this.doc.getLine(a), d = c.substring(b); + this.doc.nonTokenRe.lastIndex = 0; + this.doc.tokenRe.lastIndex = 0; + if(b == c.length) { + this.moveCursorRight() + }else { + if(this.doc.nonTokenRe.exec(d)) { + b += this.doc.nonTokenRe.lastIndex; + this.doc.nonTokenRe.lastIndex = 0 + }else { + if(this.doc.tokenRe.exec(d)) { + b += this.doc.tokenRe.lastIndex; + this.doc.tokenRe.lastIndex = 0 + } + }this.moveCursorTo(a, b) + } + }; + this.moveCursorWordLeft = function() { + var a = this.selectionLead.row, b = this.selectionLead.column, c = this.doc.getLine(a); + c = h.stringReverse(c.substring(0, b)); + this.doc.nonTokenRe.lastIndex = 0; + this.doc.tokenRe.lastIndex = 0; + if(b == 0) { + this.moveCursorLeft() + }else { + if(this.doc.nonTokenRe.exec(c)) { + b -= this.doc.nonTokenRe.lastIndex; + this.doc.nonTokenRe.lastIndex = 0 + }else { + if(this.doc.tokenRe.exec(c)) { + b -= this.doc.tokenRe.lastIndex; + this.doc.tokenRe.lastIndex = 0 + } + }this.moveCursorTo(a, b) + } + }; + this.moveCursorBy = function(a, b) { + this.moveCursorTo(this.selectionLead.row + a, this.selectionLead.column + b) + }; + this.moveCursorToPosition = function(a) { + this.moveCursorTo(a.row, a.column) + }; + this.moveCursorTo = function(a, b) { + a = this.$clipPositionToDocument(a, b); + if(a.row !== this.selectionLead.row || a.column !== this.selectionLead.column) { + this.selectionLead = a; + this.$dispatchEvent("changeCursor", {data:this.getCursor()}) + } + }; + this.moveCursorUp = function() { + this.moveCursorBy(-1, 0) + }; + this.$clipPositionToDocument = function(a, b) { + var c = {}; + if(a >= this.doc.getLength()) { + c.row = Math.max(0, this.doc.getLength() - 1); + c.column = this.doc.getLine(c.row).length + }else { + if(a < 0) { + c.row = 0; + c.column = 0 + }else { + c.row = a; + c.column = Math.min(this.doc.getLine(c.row).length, Math.max(0, b)) + } + }return c + }; + this.$clone = function(a) { + return{row:a.row, column:a.column} + } + }).call(f.prototype); + return f +}); \ No newline at end of file diff --git a/build/ace/TextInput.js b/build/ace/TextInput.js new file mode 100644 index 00000000..e34a8351 --- /dev/null +++ b/build/ace/TextInput.js @@ -0,0 +1,81 @@ +/* + LGPLv3 +*/ +require.def("ace/TextInput", ["ace/lib/event"], function(b) { + return function(l, c) { + function e() { + if(!f) { + var d = a.value; + if(d) { + if(d.charCodeAt(d.length - 1) == j.charCodeAt(0)) { + (d = d.slice(0, -1)) && c.onTextInput(d) + }else { + c.onTextInput(d) + } + } + }f = false; + a.value = j; + a.select() + } + var a = document.createElement("textarea"), h = a.style; + h.position = "absolute"; + h.left = "-10000px"; + h.top = "-10000px"; + l.appendChild(a); + var j = String.fromCharCode(0); + e(); + var i = false, f = false, g = function() { + setTimeout(function() { + i || e() + }, 0) + }, k = function() { + c.onCompositionUpdate(a.value) + }; + b.addListener(a, "keypress", g); + b.addListener(a, "textInput", g); + b.addListener(a, "paste", g); + b.addListener(a, "propertychange", g); + b.addListener(a, "copy", function() { + f = true; + a.value = c.getCopyText(); + a.select(); + f = true; + setTimeout(e, 0) + }); + b.addListener(a, "cut", function() { + f = true; + a.value = c.getCopyText(); + c.onCut(); + a.select(); + setTimeout(e, 0) + }); + b.addListener(a, "compositionstart", function() { + i = true; + e(); + a.value = ""; + c.onCompositionStart(); + setTimeout(k, 0) + }); + b.addListener(a, "compositionupdate", k); + b.addListener(a, "compositionend", function() { + i = false; + c.onCompositionEnd(); + g() + }); + b.addListener(a, "blur", function() { + c.onBlur() + }); + b.addListener(a, "focus", function() { + c.onFocus(); + a.select() + }); + this.focus = function() { + c.onFocus(); + a.select(); + a.focus() + }; + this.blur = function() { + a.blur() + } + } +}); \ No newline at end of file diff --git a/build/ace/Tokenizer.js b/build/ace/Tokenizer.js new file mode 100644 index 00000000..c651721a --- /dev/null +++ b/build/ace/Tokenizer.js @@ -0,0 +1,49 @@ +/* + LGPLv3 +*/ +require.def("ace/Tokenizer", [], function() { + var k = function(f) { + this.rules = f; + this.regExps = {}; + for(var a in this.rules) { + f = this.rules[a]; + for(var b = [], c = 0;c < f.length;c++) { + b.push(f[c].regex) + }this.regExps[a] = new RegExp("(?:(" + b.join(")|(") + ")|(.))", "g") + } + }; + (function() { + this.getLineTokens = function(f, a) { + a = a; + var b = this.rules[a], c = this.regExps[a]; + c.lastIndex = 0; + for(var g, h = [], i = 0, e = {type:null, value:""};g = c.exec(f);) { + var j = "text", l = g[0]; + if(c.lastIndex == i) { + throw new Error("tokenizer error"); + }i = c.lastIndex; + window.LOG && console.log(a, g); + for(var d = 0;d < b.length;d++) { + if(g[d + 1]) { + j = typeof b[d].token == "function" ? b[d].token(g[0]) : b[d].token; + if(b[d].next && b[d].next !== a) { + a = b[d].next; + b = this.rules[a]; + i = c.lastIndex; + c = this.regExps[a]; + c.lastIndex = i + }break + } + }if(e.type !== j) { + e.type && h.push(e); + e = {type:j, value:l} + }else { + e.value += l + } + }e.type && h.push(e); + window.LOG && console.log(h, a); + return{tokens:h, state:a} + } + }).call(k.prototype); + return k +}); \ No newline at end of file diff --git a/build/ace/UndoManager.js b/build/ace/UndoManager.js new file mode 100644 index 00000000..e7b54308 --- /dev/null +++ b/build/ace/UndoManager.js @@ -0,0 +1,31 @@ +/* + LGPLv3 +*/ +require.def("ace/UndoManager", function() { + var b = function() { + this.$undoStack = []; + this.$redoStack = [] + }; + (function() { + this.execute = function(a) { + var c = a.args[0]; + this.$doc = a.args[1]; + this.$undoStack.push(c) + }; + this.undo = function() { + var a = this.$undoStack.pop(); + if(a) { + this.$doc.undoChanges(a); + this.$redoStack.push(a) + } + }; + this.redo = function() { + var a = this.$redoStack.pop(); + if(a) { + this.$doc.redoChanges(a); + this.$undoStack.push(a) + } + } + }).call(b.prototype); + return b +}); \ No newline at end of file diff --git a/build/ace/VirtualRenderer.js b/build/ace/VirtualRenderer.js new file mode 100644 index 00000000..07b07452 --- /dev/null +++ b/build/ace/VirtualRenderer.js @@ -0,0 +1,378 @@ +/* + LGPLv3 +*/ +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!.ace_editor {\n position: absolute;\n overflow: hidden;\n\n font-family: "Menlo", "Monaco", "Courier New", monospace;\n font-size: 12px; \n}\n\n.ace_scroller {\n position: absolute;\n overflow-x: scroll;\n overflow-y: hidden; \n}\n\n.ace_gutter {\n position: absolute;\n overflow-x: hidden;\n overflow-y: hidden;\n height: 100%;\n}\n\n.ace_editor .ace_sb {\n position: absolute;\n overflow-x: hidden;\n overflow-y: scroll;\n right: 0;\n}\n\n.ace_editor .ace_sb div {\n position: absolute;\n width: 1px;\n left: 0px;\n}\n\n.ace_editor .ace_printMargin {\n position: absolute;\n height: 100%;\n}\n\n.ace_layer {\n z-index: 0;\n position: absolute;\n overflow: hidden; \n white-space: nowrap;\n height: 100%;\n}\n\n.ace_text-layer {\n font-family: Monaco, "Courier New", monospace;\n color: black;\n}\n\n.ace_cursor-layer {\n cursor: text;\n}\n\n.ace_cursor {\n z-index: 3;\n position: absolute;\n}\n\n.ace_line {\n white-space: nowrap;\n}\n\n.ace_marker-layer {\n}\n\n.ace_marker-layer .ace_step {\n position: absolute;\n z-index: 2;\n}\n\n.ace_marker-layer .ace_selection {\n position: absolute;\n z-index: 3;\n}\n\n.ace_marker-layer .ace_bracket {\n position: absolute;\n z-index: 4;\n}\n\n.ace_marker-layer .ace_active_line {\n position: absolute;\n z-index: 1;\n}'], +function(k, h, e, i, l, m, n, o, p, q, r, j) { + e.importCssString(j); + j = function(a, b) { + this.container = a; + e.addCssClass(this.container, "ace_editor"); + this.setTheme(b); + 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 l(this.$gutter); + this.$markerLayer = new m(this.content); + var c = this.$textLayer = new n(this.content); + this.canvas = c.element; + this.characterWidth = c.getCharacterWidth(); + this.lineHeight = c.getLineHeight(); + this.$cursorLayer = new o(this.content); + this.layers = [this.$markerLayer, c, this.$cursorLayer]; + this.scrollBar = new p(a); + this.scrollBar.addEventListener("scroll", h.bind(this.onScroll, this)); + this.scrollTop = 0; + this.cursorPos = {row:0, column:0}; + var d = this; + this.$textLayer.addEventListener("changeCharaterSize", function() { + d.characterWidth = c.getCharacterWidth(); + d.lineHeight = c.getLineHeight(); + d.$loop.schedule(d.CHANGE_FULL) + }); + i.addListener(this.$gutter, "click", h.bind(this.$onGutterClick, this)); + i.addListener(this.$gutter, "dblclick", h.bind(this.$onGutterClick, this)); + this.$size = {width:0, height:0, scrollerHeight:0, scrollerWidth:0}; + this.$loop = new q(h.bind(this.$renderChanges, this)); + this.$loop.schedule(this.CHANGE_FULL); + this.$updatePrintMargin(); + this.setPadding(4) + }; + (function() { + this.showGutter = true; + 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; + k.implement(this, r); + this.setDocument = function(a) { + this.lines = a.lines; + this.doc = a; + this.$cursorLayer.setDocument(a); + this.$markerLayer.setDocument(a); + this.$textLayer.setDocument(a); + this.$loop.schedule(this.CHANGE_FULL) + }; + this.updateLines = function(a, b) { + if(b === undefined) { + b = Infinity + }if(this.$changedLines) { + if(this.$changedLines.firstRow > a) { + this.$changedLines.firstRow = a + }if(this.$changedLines.lastRow < b) { + this.$changedLines.lastRow = b + } + }else { + this.$changedLines = {firstRow:a, lastRow:b} + }this.$loop.schedule(this.CHANGE_LINES) + }; + this.updateText = function() { + this.$loop.schedule(this.CHANGE_TEXT) + }; + this.updateFull = function() { + this.$loop.schedule(this.CHANGE_FULL) + }; + this.onResize = function() { + this.$loop.schedule(this.CHANGE_SIZE); + var a = e.getInnerHeight(this.container); + if(this.$size.height != a) { + this.$size.height = a; + this.scroller.style.height = a + "px"; + this.scrollBar.setHeight(a); + if(this.doc) { + this.scrollToY(this.getScrollTop()); + this.$loop.schedule(this.CHANGE_FULL) + } + }a = e.getInnerWidth(this.container); + if(this.$size.width != a) { + this.$size.width = a; + var b = this.showGutter ? this.$gutter.offsetWidth : 0; + this.scroller.style.left = b + "px"; + this.scroller.style.width = Math.max(0, a - b - this.scrollBar.getWidth()) + "px" + }this.$size.scrollerWidth = this.scroller.clientWidth; + this.$size.scrollerHeight = this.scroller.clientHeight + }; + this.setTokenizer = function(a) { + this.$tokenizer = a; + this.$textLayer.setTokenizer(a); + this.$loop.schedule(this.CHANGE_TEXT) + }; + this.$onGutterClick = function(a) { + var b = i.getDocumentX(a), c = i.getDocumentY(a); + this.$dispatchEvent("gutter" + a.type, {row:this.screenToTextCoordinates(b, c).row, htmlEvent:a}) + }; + this.$showInvisibles = true; + this.setShowInvisibles = function(a) { + this.$showInvisibles = a; + this.$textLayer.setShowInvisibles(a); + this.$loop.schedule(this.CHANGE_TEXT) + }; + this.getShowInvisibles = function() { + return this.$showInvisibles + }; + this.$showPrintMargin = true; + this.setShowPrintMargin = function(a) { + this.$showPrintMargin = a; + this.$updatePrintMargin() + }; + this.getShowPrintMargin = function() { + return this.$showPrintMargin + }; + this.$printMarginColumn = 80; + this.setPrintMarginColumn = function(a) { + this.$printMarginColumn = a; + this.$updatePrintMargin() + }; + this.getPrintMarginColumn = function() { + return this.$printMarginColumn + }; + this.setShowGutter = function(a) { + this.$gutter.style.display = a ? "block" : "none"; + this.showGutter = a; + this.onResize() + }; + this.$updatePrintMargin = function() { + if(this.$showPrintMargin || this.$printMarginEl) { + if(!this.$printMarginEl) { + this.$printMarginEl = document.createElement("div"); + this.$printMarginEl.className = "ace_printMargin"; + this.content.insertBefore(this.$printMarginEl, this.$textLayer.element) + }var a = this.$printMarginEl.style; + a.left = this.characterWidth * this.$printMarginColumn + "px"; + a.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.getFirstFullyVisibleRow = function() { + if(!this.layerConfig) { + return 0 + }return this.layerConfig.firstRow + (this.layerConfig.offset == 0 ? 0 : 1) + }; + this.getLastFullyVisibleRow = function() { + if(!this.layerConfig) { + return 0 + }return this.layerConfig.firstRow - 1 + Math.floor((this.layerConfig.height + this.layerConfig.offset) / this.layerConfig.lineHeight) + }; + this.getLastVisibleRow = function() { + return(this.layerConfig || {}).lastRow || 0 + }; + this.$padding = null; + this.setPadding = function(a) { + this.$padding = a; + this.content.style.padding = "0 " + a + "px"; + this.$loop.schedule(this.CHANGE_FULL) + }; + this.onScroll = function(a) { + this.scrollToY(a.data) + }; + this.$updateScrollBar = function() { + this.scrollBar.setInnerHeight(this.doc.getLength() * this.lineHeight); + this.scrollBar.setScrollTop(this.scrollTop) + }; + this.$renderChanges = function(a) { + if(!(!a || !this.doc || !this.$tokenizer)) { + if(!this.layerConfig || a & this.CHANGE_FULL || a & this.CHANGE_SIZE || a & this.CHANGE_TEXT || a & this.CHANGE_LINES || a & this.CHANGE_SCROLL) { + this.$computeLayerConfig() + }if(a & this.CHANGE_FULL) { + this.$textLayer.update(this.layerConfig); + this.showGutter && this.$gutterLayer.update(this.layerConfig); + this.$markerLayer.update(this.layerConfig); + this.$cursorLayer.update(this.layerConfig); + this.$updateScrollBar() + }else { + if(a & this.CHANGE_SCROLL) { + a & this.CHANGE_TEXT || a & this.CHANGE_LINES ? this.$textLayer.scrollLines(this.layerConfig) : this.$textLayer.update(this.layerConfig); + this.showGutter && this.$gutterLayer.update(this.layerConfig); + this.$markerLayer.update(this.layerConfig); + this.$cursorLayer.update(this.layerConfig); + this.$updateScrollBar() + }else { + if(a & this.CHANGE_TEXT) { + this.$textLayer.update(this.layerConfig); + this.showGutter && this.$gutterLayer.update(this.layerConfig) + }else { + if(a & this.CHANGE_LINES) { + this.$updateLines(); + this.$updateScrollBar() + }else { + if(a & this.CHANGE_SCROLL) { + this.$textLayer.scrollLines(this.layerConfig); + this.showGutter && this.$gutterLayer.update(this.layerConfig) + } + } + }a & this.CHANGE_GUTTER && this.showGutter && this.$gutterLayer.update(this.layerConfig); + a & this.CHANGE_CURSOR && this.$cursorLayer.update(this.layerConfig); + a & this.CHANGE_MARKER && this.$markerLayer.update(this.layerConfig); + a & this.CHANGE_SIZE && this.$updateScrollBar() + } + } + } + }; + this.$computeLayerConfig = function() { + var a = this.scrollTop % this.lineHeight, b = this.$size.scrollerHeight + this.lineHeight, c = this.$getLongestLine(), d = !this.layerConfig ? true : this.layerConfig.width != c, g = Math.ceil(b / this.lineHeight), f = Math.max(0, Math.round((this.scrollTop - a) / this.lineHeight)); + g = Math.min(this.lines.length, f + g) - 1; + this.layerConfig = {width:c, padding:this.$padding, firstRow:f, lastRow:g, lineHeight:this.lineHeight, characterWidth:this.characterWidth, minHeight:b, offset:a, height:this.$size.scrollerHeight}; + for(f = 0;f < this.layers.length;f++) { + g = this.layers[f]; + if(d) { + g.element.style.width = c + "px" + } + }this.$gutterLayer.element.style.marginTop = -a + "px"; + this.content.style.marginTop = -a + "px"; + this.content.style.width = c + "px"; + this.content.style.height = b + "px" + }; + this.$updateLines = function() { + var a = this.$changedLines.firstRow, b = this.$changedLines.lastRow; + this.$changedLines = null; + var c = this.layerConfig; + if(c.width != this.$getLongestLine()) { + return this.$textLayer.update(c) + }if(!(a > c.lastRow + 1)) { + if(!(b < c.firstRow)) { + if(b === Infinity) { + this.showGutter && this.$gutterLayer.update(c); + this.$textLayer.update(c) + }else { + this.$textLayer.updateLines(c, a, b) + } + } + } + }; + this.$getLongestLine = function() { + var a = this.doc.getScreenWidth(); + if(this.$showInvisibles) { + a += 1 + }return Math.max(this.$size.scrollerWidth - this.$padding * 2, Math.round(a * this.characterWidth)) + }; + this.addMarker = function(a, b, c) { + a = this.$markerLayer.addMarker(a, b, c); + this.$loop.schedule(this.CHANGE_MARKER); + return a + }; + this.removeMarker = function(a) { + this.$markerLayer.removeMarker(a); + this.$loop.schedule(this.CHANGE_MARKER) + }; + this.addGutterDecoration = function(a, b) { + this.$gutterLayer.addGutterDecoration(a, b); + this.$loop.schedule(this.CHANGE_GUTTER) + }; + this.removeGutterDecoration = function(a, b) { + this.$gutterLayer.removeGutterDecoration(a, b); + this.$loop.schedule(this.CHANGE_GUTTER) + }; + this.setBreakpoints = function(a) { + this.$gutterLayer.setBreakpoints(a); + this.$loop.schedule(this.CHANGE_GUTTER) + }; + this.updateCursor = function(a, b) { + this.$cursorLayer.setCursor(a, b); + this.$loop.schedule(this.CHANGE_CURSOR) + }; + this.hideCursor = function() { + this.$cursorLayer.hideCursor() + }; + this.showCursor = function() { + this.$cursorLayer.showCursor() + }; + this.scrollCursorIntoView = function() { + var a = this.$cursorLayer.getPixelPosition(), b = a.left + this.$padding; + a = a.top; + this.getScrollTop() > a && this.scrollToY(a); + this.getScrollTop() + this.$size.scrollerHeight < a + this.lineHeight && this.scrollToY(a + this.lineHeight - this.$size.scrollerHeight); + this.scroller.scrollLeft > b && this.scrollToX(b); + this.scroller.scrollLeft + this.$size.scrollerWidth < b + this.characterWidth && this.scrollToX(Math.round(b + 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(a) { + this.scrollToY(a * this.lineHeight) + }; + this.scrollToY = function(a) { + a = Math.max(0, Math.min(this.lines.length * this.lineHeight - this.$size.scrollerHeight, a)); + if(this.scrollTop !== a) { + this.scrollTop = a; + this.$loop.schedule(this.CHANGE_SCROLL) + } + }; + this.scrollToX = function(a) { + if(a <= this.$padding) { + a = 0 + }this.scroller.scrollLeft = a + }; + this.scrollBy = function(a, b) { + b && this.scrollToY(this.scrollTop + b); + a && this.scrollToX(this.scroller.scrollLeft + a) + }; + this.screenToTextCoordinates = function(a, b) { + var c = this.scroller.getBoundingClientRect(); + a = Math.round((a + this.scroller.scrollLeft - c.left - this.$padding) / this.characterWidth); + b = Math.floor((b + this.scrollTop - c.top) / this.lineHeight); + return{row:b, column:this.doc.screenToDocumentColumn(Math.max(0, Math.min(b, this.doc.getLength() - 1)), a)} + }; + this.textToScreenCoordinates = function(a, b) { + var c = this.scroller.getBoundingClientRect(); + b = this.padding + Math.round(this.doc.documentToScreenColumn(a, b) * this.characterWidth); + a = a * this.lineHeight; + return{pageX:c.left + b - this.getScrollLeft(), pageY:c.top + a - this.getScrollTop()} + }; + this.visualizeFocus = function() { + e.addCssClass(this.container, "ace_focus") + }; + this.visualizeBlur = function() { + e.removeCssClass(this.container, "ace_focus") + }; + this.showComposition = function() { + }; + this.setCompositionText = function() { + }; + this.hideComposition = function() { + }; + this.setTheme = function(a) { + function b(d) { + c.$theme && e.removeCssClass(c.container, c.$theme); + c.$theme = d ? d.cssClass : null; + c.$theme && e.addCssClass(c.container, c.$theme); + if(c.$size) { + c.$size.width = 0; + c.onResize() + } + } + var c = this; + if(!a || typeof a == "string") { + a = a || "ace/theme/TextMate"; + require([a], function(d) { + b(d) + }) + }else { + b(a) + }c = this + } + }).call(j.prototype); + return j +}); \ No newline at end of file diff --git a/build/ace/commands/DefaultCommands.js b/build/ace/commands/DefaultCommands.js new file mode 100644 index 00000000..263d0aa4 --- /dev/null +++ b/build/ace/commands/DefaultCommands.js @@ -0,0 +1,154 @@ +/* + LGPLv3 +*/ +require.def("ace/commands/DefaultCommands", ["ace/PluginManager"], function(b) { + b.registerCommand("selectall", function(a, c) { + c.selectAll() + }); + b.registerCommand("removeline", function(a) { + a.removeLines() + }); + b.registerCommand("gotoline", function(a) { + var c = parseInt(prompt("Enter line number:")); + isNaN(c) || a.gotoLine(c) + }); + b.registerCommand("togglecomment", function(a) { + a.toggleCommentLines() + }); + b.registerCommand("findnext", function(a) { + a.findNext() + }); + b.registerCommand("findprevious", function(a) { + a.findPrevious() + }); + b.registerCommand("find", function(a) { + var c = prompt("Find:"); + a.find(c) + }); + b.registerCommand("undo", function(a) { + a.undo() + }); + b.registerCommand("redo", function(a) { + a.redo() + }); + b.registerCommand("redo", function(a) { + a.redo() + }); + b.registerCommand("overwrite", function(a) { + a.toggleOverwrite() + }); + b.registerCommand("copylinesup", function(a) { + a.copyLinesUp() + }); + b.registerCommand("movelinesup", function(a) { + a.moveLinesUp() + }); + b.registerCommand("selecttostart", function(a, c) { + c.selectFileStart() + }); + b.registerCommand("gotostart", function(a) { + a.navigateFileStart() + }); + b.registerCommand("selectup", function(a, c) { + c.selectUp() + }); + b.registerCommand("golineup", function(a) { + a.navigateUp() + }); + b.registerCommand("copylinesdown", function(a) { + a.copyLinesDown() + }); + b.registerCommand("movelinesdown", function(a) { + a.moveLinesDown() + }); + b.registerCommand("selecttoend", function(a, c) { + c.selectFileEnd() + }); + b.registerCommand("gotoend", function(a) { + a.navigateFileEnd() + }); + b.registerCommand("selectdown", function(a, c) { + c.selectDown() + }); + b.registerCommand("godown", function(a) { + a.navigateDown() + }); + b.registerCommand("selectwordleft", function(a, c) { + c.selectWordLeft() + }); + b.registerCommand("gotowordleft", function(a) { + a.navigateWordLeft() + }); + b.registerCommand("selecttolinestart", function(a, c) { + c.selectLineStart() + }); + b.registerCommand("gotolinestart", function(a) { + a.navigateLineStart() + }); + b.registerCommand("selectleft", function(a, c) { + c.selectLeft() + }); + b.registerCommand("gotoleft", function(a) { + a.navigateLeft() + }); + b.registerCommand("selectwordright", function(a, c) { + c.selectWordRight() + }); + b.registerCommand("gotowordright", function(a) { + a.navigateWordRight() + }); + b.registerCommand("selecttolineend", function(a, c) { + c.selectLineEnd() + }); + b.registerCommand("gotolineend", function(a) { + a.navigateLineEnd() + }); + b.registerCommand("selectright", function(a, c) { + c.selectRight() + }); + b.registerCommand("gotoright", function(a) { + a.navigateRight() + }); + b.registerCommand("selectpagedown", function(a) { + a.selectPageDown() + }); + b.registerCommand("pagedown", function(a) { + a.scrollPageDown() + }); + b.registerCommand("gotopagedown", function(a) { + a.gotoPageDown() + }); + b.registerCommand("selectpageup", function(a) { + a.selectPageUp() + }); + b.registerCommand("pageup", function(a) { + a.scrollPageUp() + }); + b.registerCommand("gotopageup", function(a) { + a.gotoPageUp() + }); + b.registerCommand("selectlinestart", function(a, c) { + c.selectLineStart() + }); + b.registerCommand("gotolinestart", function(a) { + a.navigateLineStart() + }); + b.registerCommand("selectlineend", function(a, c) { + c.selectLineEnd() + }); + b.registerCommand("gotolineend", function(a) { + a.navigateLineEnd() + }); + b.registerCommand("del", function(a) { + a.removeRight() + }); + b.registerCommand("backspace", function(a) { + a.removeLeft() + }); + b.registerCommand("outdent", function(a) { + a.blockOutdent() + }); + b.registerCommand("indent", function(a) { + a.indent() + }) +}); \ No newline at end of file diff --git a/build/ace/conf/keybindings/default_mac.js b/build/ace/conf/keybindings/default_mac.js new file mode 100644 index 00000000..bedb40f1 --- /dev/null +++ b/build/ace/conf/keybindings/default_mac.js @@ -0,0 +1,8 @@ +/* + LGPLv3 +*/ +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", movelinesdown:"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"} +}); \ No newline at end of file diff --git a/build/ace/conf/keybindings/default_win.js b/build/ace/conf/keybindings/default_win.js new file mode 100644 index 00000000..bcec8dd3 --- /dev/null +++ b/build/ace/conf/keybindings/default_win.js @@ -0,0 +1,8 @@ +/* + LGPLv3 +*/ +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", movelinesdown:"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"} +}); \ No newline at end of file diff --git a/build/ace/css/editor.css b/build/ace/css/editor.css new file mode 100644 index 00000000..b8125397 --- /dev/null +++ b/build/ace/css/editor.css @@ -0,0 +1,71 @@ +.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; +} diff --git a/build/ace/layer/Cursor.js b/build/ace/layer/Cursor.js new file mode 100644 index 00000000..433092f9 --- /dev/null +++ b/build/ace/layer/Cursor.js @@ -0,0 +1,65 @@ +/* + LGPLv3 +*/ +require.def("ace/layer/Cursor", ["ace/lib/dom"], function(c) { + var d = function(a) { + this.element = document.createElement("div"); + this.element.className = "ace_layer ace_cursor-layer"; + a.appendChild(this.element); + this.cursor = document.createElement("div"); + this.cursor.className = "ace_cursor"; + this.isVisible = false + }; + (function() { + this.setDocument = function(a) { + this.doc = a + }; + this.setCursor = function(a, b) { + this.position = {row:a.row, column:this.doc.documentToScreenColumn(a.row, a.column)}; + b ? c.addCssClass(this.cursor, "ace_overwrite") : c.removeCssClass(this.cursor, "ace_overwrite") + }; + this.hideCursor = function() { + this.isVisible = false; + this.cursor.parentNode && this.cursor.parentNode.removeChild(this.cursor); + clearInterval(this.blinkId) + }; + this.showCursor = function() { + this.isVisible = true; + this.element.appendChild(this.cursor); + this.cursor.style.visibility = "visible"; + this.restartTimer() + }; + this.restartTimer = function() { + clearInterval(this.blinkId); + if(this.isVisible) { + var a = this.cursor; + this.blinkId = setInterval(function() { + a.style.visibility = "hidden"; + setTimeout(function() { + a.style.visibility = "visible" + }, 400) + }, 1E3) + } + }; + this.getPixelPosition = function() { + if(!this.config || !this.position) { + return{left:0, top:0} + }var a = this.position.row * this.config.lineHeight; + return{left:Math.round(this.position.column * this.config.characterWidth), top:a} + }; + this.update = function(a) { + if(this.position) { + this.config = a; + var b = Math.round(this.position.column * a.characterWidth), e = this.position.row * a.lineHeight; + this.pixelPos = {left:b, top:e}; + this.cursor.style.left = b + "px"; + this.cursor.style.top = e - a.firstRow * a.lineHeight + "px"; + this.cursor.style.width = a.characterWidth + "px"; + this.cursor.style.height = a.lineHeight + "px"; + this.isVisible && this.element.appendChild(this.cursor); + this.restartTimer() + } + } + }).call(d.prototype); + return d +}); \ No newline at end of file diff --git a/build/ace/layer/Gutter.js b/build/ace/layer/Gutter.js new file mode 100644 index 00000000..8848d2f9 --- /dev/null +++ b/build/ace/layer/Gutter.js @@ -0,0 +1,33 @@ +/* + LGPLv3 +*/ +require.def("ace/layer/Gutter", [], function() { + var d = function(a) { + this.element = document.createElement("div"); + this.element.className = "ace_layer ace_gutter-layer"; + a.appendChild(this.element); + this.$breakpoints = []; + this.$decorations = [] + }; + (function() { + this.addGutterDecoration = function(a, b) { + this.$decorations[a] || (this.$decorations[a] = ""); + this.$decorations[a] += " ace_" + b + }; + this.removeGutterDecoration = function(a, b) { + this.$decorations[a] = this.$decorations[a].replace(" ace_" + b, "") + }; + this.setBreakpoints = function(a) { + this.$breakpoints = a.concat() + }; + this.update = function(a) { + this.$config = a; + for(var b = [], c = a.firstRow;c <= a.lastRow;c++) { + b.push("
", c + 1, "
"); + b.push("") + }this.element.innerHTML = b.join(""); + this.element.style.height = a.minHeight + "px" + } + }).call(d.prototype); + return d +}); \ No newline at end of file diff --git a/build/ace/layer/Marker.js b/build/ace/layer/Marker.js new file mode 100644 index 00000000..35038256 --- /dev/null +++ b/build/ace/layer/Marker.js @@ -0,0 +1,74 @@ +/* + LGPLv3 +*/ +require.def("ace/layer/Marker", ["ace/Range"], function(h) { + var i = function(c) { + this.element = document.createElement("div"); + this.element.className = "ace_layer ace_marker-layer"; + c.appendChild(this.element); + this.markers = {}; + this.$markerId = 1 + }; + (function() { + this.setDocument = function(c) { + this.doc = c + }; + this.addMarker = function(c, a, e) { + var b = this.$markerId++; + this.markers[b] = {range:c, type:e || "line", clazz:a}; + return b + }; + this.removeMarker = function(c) { + this.markers[c] && delete this.markers[c] + }; + this.update = function(c) { + if(c = c || this.config) { + this.config = c; + var a = []; + for(var e in this.markers) { + var b = this.markers[e], d = b.range.clipRows(c.firstRow, c.lastRow); + if(!d.isEmpty()) { + if(d.isMultiLine()) { + b.type == "text" ? this.drawTextMarker(a, d, b.clazz, c) : this.drawMultiLineMarker(a, d, b.clazz, c) + }else { + this.drawSingleLineMarker(a, d, b.clazz, c) + } + } + }this.element.innerHTML = a.join("") + } + }; + this.drawTextMarker = function(c, a, e, b) { + var d = a.start.row, f = new h(d, a.start.column, d, this.doc.getLine(d).length); + this.drawSingleLineMarker(c, f, e, b); + d = a.end.row; + f = new h(d, 0, d, a.end.column); + this.drawSingleLineMarker(c, f, e, b); + for(d = a.start.row + 1;d < a.end.row;d++) { + f.start.row = d; + f.end.row = d; + f.end.column = this.doc.getLine(d).length; + this.drawSingleLineMarker(c, f, e, b) + } + }; + this.drawMultiLineMarker = function(c, a, e, b) { + a = a.toScreenRange(this.doc); + var d = b.lineHeight, f = Math.round(b.width - a.start.column * b.characterWidth), g = (a.start.row - b.firstRow) * b.lineHeight, j = Math.round(a.start.column * b.characterWidth); + c.push("
"); + g = (a.end.row - b.firstRow) * b.lineHeight; + f = Math.round(a.end.column * b.characterWidth); + c.push("
"); + d = (a.end.row - a.start.row - 1) * b.lineHeight; + if(!(d < 0)) { + g = (a.start.row + 1 - b.firstRow) * b.lineHeight; + c.push("
") + } + }; + this.drawSingleLineMarker = function(c, a, e, b) { + a = a.toScreenRange(this.doc); + var d = b.lineHeight, f = Math.round((a.end.column - a.start.column) * b.characterWidth), g = (a.start.row - b.firstRow) * b.lineHeight; + a = Math.round(a.start.column * b.characterWidth); + c.push("
") + } + }).call(i.prototype); + return i +}); \ No newline at end of file diff --git a/build/ace/layer/Text.js b/build/ace/layer/Text.js new file mode 100644 index 00000000..a38df019 --- /dev/null +++ b/build/ace/layer/Text.js @@ -0,0 +1,158 @@ +/* + LGPLv3 +*/ +require.def("ace/layer/Text", ["ace/lib/oop", "ace/lib/dom", "ace/MEventEmitter"], function(m, n, o) { + var k = function(a) { + this.element = document.createElement("div"); + this.element.className = "ace_layer ace_text-layer"; + a.appendChild(this.element); + this.$characterSize = this.$measureSizes(); + this.$pollSizeChanges() + }; + (function() { + m.implement(this, o); + this.EOF_CHAR = "¶"; + this.EOL_CHAR = "¬"; + this.TAB_CHAR = "→"; + this.SPACE_CHAR = "·"; + this.setTokenizer = function(a) { + this.tokenizer = a + }; + this.getLineHeight = function() { + return this.$characterSize.height || 1 + }; + this.getCharacterWidth = function() { + return this.$characterSize.width || 1 + }; + this.$pollSizeChanges = function() { + var a = this; + setInterval(function() { + var b = a.$measureSizes(); + if(a.$characterSize.width !== b.width || a.$characterSize.height !== b.height) { + a.$characterSize = b; + a.$dispatchEvent("changeCharaterSize", {data:b}) + } + }, 500) + }; + this.$fontStyles = {fontFamily:1, fontSize:1, fontWeight:1, fontStyle:1, lineHeight:1}; + this.$measureSizes = function() { + var a = document.createElement("div"), b = a.style; + b.width = b.height = "auto"; + b.left = b.top = "-1000px"; + b.visibility = "hidden"; + b.position = "absolute"; + b.overflow = "visible"; + for(var e in this.$fontStyles) { + var f = n.computedStyle(this.element, e); + b[e] = f + }a.innerHTML = (new Array(1E3)).join("Xy"); + document.body.insertBefore(a, document.body.firstChild); + b = {height:a.offsetHeight, width:a.offsetWidth / 2E3}; + document.body.removeChild(a); + return b + }; + this.setDocument = function(a) { + this.doc = a + }; + this.$showInvisibles = false; + this.setShowInvisibles = function(a) { + this.$showInvisibles = a + }; + this.$computeTabString = function() { + var a = this.doc.getTabSize(); + if(this.$showInvisibles) { + a = a / 2; + this.$tabString = "" + (new Array(Math.floor(a))).join(" ") + this.TAB_CHAR + (new Array(Math.ceil(a) + 1)).join(" ") + "" + }else { + this.$tabString = (new Array(a + 1)).join(" ") + } + }; + this.updateLines = function(a, b, e) { + this.$computeTabString(); + var f = Math.max(b, a.firstRow), c = Math.min(e, a.lastRow), d = this.element.childNodes, h = this; + this.tokenizer.getTokens(f, c, function(i) { + for(var g = f;g <= c;g++) { + var j = d[g - a.firstRow]; + if(j) { + var l = []; + h.$renderLine(l, g, i[g - f].tokens); + j.innerHTML = l.join("") + } + } + }) + }; + this.scrollLines = function(a) { + function b(i) { + a.firstRow < c.firstRow ? f.$renderLinesFragment(a, a.firstRow, c.firstRow - 1, function(g) { + d.firstChild ? d.insertBefore(g, d.firstChild) : d.appendChild(g); + i() + }) : i() + } + function e() { + a.lastRow > c.lastRow && f.$renderLinesFragment(a, c.lastRow + 1, a.lastRow, function(i) { + d.appendChild(i) + }) + } + var f = this; + this.$computeTabString(); + var c = this.config; + this.config = a; + if(!c || c.lastRow < a.firstRow) { + return this.update(a) + }if(a.lastRow < c.firstRow) { + return this.update(a) + }var d = this.element; + if(c.firstRow < a.firstRow) { + for(var h = c.firstRow;h < a.firstRow;h++) { + d.removeChild(d.firstChild) + } + }if(c.lastRow > a.lastRow) { + for(h = a.lastRow + 1;h <= c.lastRow;h++) { + d.removeChild(d.lastChild) + } + }b(e) + }; + this.$renderLinesFragment = function(a, b, e, f) { + var c = document.createDocumentFragment(), d = this; + this.tokenizer.getTokens(b, e, function(h) { + for(var i = b;i <= e;i++) { + var g = document.createElement("div"); + g.className = "ace_line"; + var j = g.style; + j.height = d.$characterSize.height + "px"; + j.width = a.width + "px"; + j = []; + d.$renderLine(j, i, h[i - b].tokens); + g.innerHTML = j.join(""); + c.appendChild(g) + }f(c) + }) + }; + this.update = function(a) { + this.$computeTabString(); + var b = [], e = this; + this.tokenizer.getTokens(a.firstRow, a.lastRow, function(f) { + for(var c = a.firstRow;c <= a.lastRow;c++) { + b.push("
"); + e.$renderLine(b, c, f[c - a.firstRow].tokens); + b.push("
") + }e.element.innerHTML = b.join("") + }) + }; + this.$textToken = {text:true, rparen:true, lparen:true}; + this.$renderLine = function(a, b, e) { + for(var f = /[\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]/g, c = 0;c < e.length;c++) { + var d = e[c], h = d.value.replace(/&/g, "&").replace(/", h, "") + } + }if(this.$showInvisibles) { + b !== this.doc.getLength() - 1 ? a.push("" + this.EOL_CHAR + "") : a.push("" + this.EOF_CHAR + "") + } + } + }).call(k.prototype); + return k +}); \ No newline at end of file diff --git a/build/ace/lib/core.js b/build/ace/lib/core.js new file mode 100644 index 00000000..de0d02e6 --- /dev/null +++ b/build/ace/lib/core.js @@ -0,0 +1,22 @@ +/* + LGPLv3 +*/ +if(!require.def) { + require.def = require("requireJS-node")(module, require) +}require.def("ace/lib/core", function() { + var a = {}, d = (navigator.platform.match(/mac|win|linux/i) || ["other"])[0].toLowerCase(); + a.isWin = d == "win"; + a.isMac = d == "mac"; + a.isLinux = d == "linux"; + a.isIE = !+"\u000b1"; + a.isGecko = window.controllers && window.navigator.product === "Gecko"; + a.provide = function(b) { + b = b.split("."); + for(var c = window, e = 0;e < b.length;e++) { + var f = b[e]; + c[f] || (c[f] = {}); + c = c[f] + } + }; + return a +}); \ No newline at end of file diff --git a/build/ace/lib/dom.js b/build/ace/lib/dom.js new file mode 100644 index 00000000..b8a6919f --- /dev/null +++ b/build/ace/lib/dom.js @@ -0,0 +1,70 @@ +/* + LGPLv3 +*/ +if(!require.def) { + require.def = require("requireJS-node")(module, require) +}require.def("ace/lib/dom", ["ace/lib/lang"], function(f) { + var c = {}; + c.setText = function(a, b) { + if(a.innerText !== undefined) { + a.innerText = b + }if(a.textContent !== undefined) { + a.textContent = b + } + }; + c.hasCssClass = function(a, b) { + a = a.className.split(/\s+/g); + return f.arrayIndexOf(a, b) !== -1 + }; + c.addCssClass = function(a, b) { + c.hasCssClass(a, b) || (a.className += " " + b) + }; + c.removeCssClass = function(a, b) { + for(var d = a.className.split(/\s+/g);;) { + var e = f.arrayIndexOf(d, b); + if(e == -1) { + break + }d.splice(e, 1) + }a.className = d.join(" ") + }; + c.importCssString = function(a, b) { + b = b || document; + if(b.createStyleSheet) { + b.createStyleSheet().cssText = a + }else { + var d = b.createElement("style"); + d.appendChild(b.createTextNode(a)); + b.getElementsByTagName("head")[0].appendChild(d) + } + }; + c.getInnerWidth = function(a) { + return parseInt(c.computedStyle(a, "paddingLeft")) + parseInt(c.computedStyle(a, "paddingRight")) + a.clientWidth + }; + c.getInnerHeight = function(a) { + return parseInt(c.computedStyle(a, "paddingTop")) + parseInt(c.computedStyle(a, "paddingBottom")) + a.clientHeight + }; + c.computedStyle = function(a, b) { + return window.getComputedStyle ? (window.getComputedStyle(a, "") || {})[b] || "" : a.currentStyle[b] + }; + c.scrollbarWidth = function() { + var a = document.createElement("p"); + a.style.width = "100%"; + a.style.height = "200px"; + var b = document.createElement("div"), d = b.style; + d.position = "absolute"; + d.left = "-10000px"; + d.overflow = "hidden"; + d.width = "200px"; + d.height = "150px"; + b.appendChild(a); + document.body.appendChild(b); + var e = a.offsetWidth; + d.overflow = "scroll"; + a = a.offsetWidth; + if(e == a) { + a = b.clientWidth + }document.body.removeChild(b); + return e - a + }; + return c +}); \ No newline at end of file diff --git a/build/ace/lib/event.js b/build/ace/lib/event.js new file mode 100644 index 00000000..d53e9a5d --- /dev/null +++ b/build/ace/lib/event.js @@ -0,0 +1,139 @@ +/* + LGPLv3 +*/ +if(!require.def) { + require.def = require("requireJS-node")(module, require) +}require.def("ace/lib/event", ["ace/lib/core"], function(i) { + var c = {}; + c.addListener = function(a, e, d) { + if(a.addEventListener) { + return a.addEventListener(e, d, false) + }if(a.attachEvent) { + var b = function() { + d(window.event) + }; + d.$$wrapper = b; + a.attachEvent("on" + e, b) + } + }; + c.removeListener = function(a, e, d) { + if(a.removeEventListener) { + return a.removeEventListener(e, d, false) + }if(a.detachEvent) { + a.detachEvent("on" + e, d.$$wrapper || d) + } + }; + c.stopEvent = function(a) { + c.stopPropagation(a); + c.preventDefault(a); + return false + }; + c.stopPropagation = function(a) { + if(a.stopPropagation) { + a.stopPropagation() + }else { + a.cancelBubble = true + } + }; + c.preventDefault = function(a) { + if(a.preventDefault) { + a.preventDefault() + }else { + a.returnValue = false + } + }; + c.getDocumentX = function(a) { + return a.clientX ? a.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) : a.pageX + }; + c.getDocumentY = function(a) { + return a.clientY ? a.clientY + (document.documentElement.scrollTop || document.body.scrollTop) : a.pageX + }; + c.getButton = function(a) { + return a.preventDefault ? a.button : Math.max(a.button - 1, 2) + }; + c.capture = document.documentElement.setCapture ? function(a, e, d) { + function b(h) { + e && e(h); + d && d(); + c.removeListener(a, "mousemove", e); + c.removeListener(a, "mouseup", b); + c.removeListener(a, "losecapture", b); + a.releaseCapture() + } + c.addListener(a, "mousemove", e); + c.addListener(a, "mouseup", b); + c.addListener(a, "losecapture", b); + a.setCapture() + } : function(a, e, d) { + function b(f) { + e(f); + f.stopPropagation() + } + function h(f) { + e && e(f); + d && d(); + document.removeEventListener("mousemove", b, true); + document.removeEventListener("mouseup", h, true); + f.stopPropagation() + } + document.addEventListener("mousemove", b, true); + document.addEventListener("mouseup", h, true) + }; + c.addMouseWheelListener = function(a, e) { + var d = function(b) { + if(b.wheelDelta !== undefined) { + if(b.wheelDeltaX !== undefined) { + b.wheelX = -b.wheelDeltaX / 8; + b.wheelY = -b.wheelDeltaY / 8 + }else { + b.wheelX = 0; + b.wheelY = -b.wheelDelta / 8 + } + }else { + if(b.axis && b.axis == b.HORIZONTAL_AXIS) { + b.wheelX = (b.detail || 0) * 5; + b.wheelY = 0 + }else { + b.wheelX = 0; + b.wheelY = (b.detail || 0) * 5 + } + }e(b) + }; + c.addListener(a, "DOMMouseScroll", d); + c.addListener(a, "mousewheel", d) + }; + c.addMultiMouseDownListener = function(a, e, d, b, h) { + var f = 0, j, k, l = function(g) { + f += 1; + if(f == 1) { + j = g.clientX; + k = g.clientY; + setTimeout(function() { + f = 0 + }, b || 600) + }if(c.getButton(g) != e || Math.abs(g.clientX - j) > 5 || Math.abs(g.clientY - k) > 5) { + f = 0 + }if(f == d) { + f = 0; + h(g) + }return c.preventDefault(g) + }; + c.addListener(a, "mousedown", l); + i.isIE && c.addListener(a, "dblclick", l) + }; + c.addKeyListener = function(a, e) { + var d = null; + c.addListener(a, "keydown", function(b) { + d = b.keyIdentifier || b.keyCode; + return e(b) + }); + i.isMac && i.isGecko && c.addListener(a, "keypress", function(b) { + if(d !== (b.keyIdentifier || b.keyCode)) { + return e(b) + }else { + d = null + } + }) + }; + return c +}); \ No newline at end of file diff --git a/build/ace/lib/lang.js b/build/ace/lib/lang.js new file mode 100644 index 00000000..186c175d --- /dev/null +++ b/build/ace/lib/lang.js @@ -0,0 +1,61 @@ +/* + LGPLv3 +*/ +if(!require.def) { + require.def = require("requireJS-node")(module, require) +}require.def("ace/lib/lang", function() { + var d = {}; + d.stringReverse = function(a) { + return a.split("").reverse().join("") + }; + d.stringRepeat = function(a, b) { + return(new Array(b + 1)).join(a) + }; + d.arrayIndexOf = Array.prototype.indexOf ? function(a, b) { + return a.indexOf(b) + } : function(a, b) { + for(var c = 0;c < a.length;c++) { + if(a[c] == b) { + return c + } + }return-1 + }; + d.isArray = function(a) { + return Object.prototype.toString.call(a) == "[object Array]" + }; + d.copyObject = function(a) { + var b = {}; + for(var c in a) { + b[c] = a[c] + }return b + }; + d.arrayToMap = function(a) { + for(var b = {}, c = 0;c < a.length;c++) { + b[a[c]] = 1 + }return b + }; + d.escapeRegExp = function(a) { + return a.replace(/([.*+?^${}()|[\]\/\\])/g, "\\$1") + }; + d.bind = function(a, b) { + return function() { + return a.apply(b, arguments) + } + }; + d.deferredCall = function(a) { + var b = null, c = function() { + b = null; + a() + }; + return{schedule:function() { + b || (b = setTimeout(c, 0)) + }, call:function() { + d.cancel(); + a() + }, cancel:function() { + clearTimeout(b); + b = null + }} + }; + return d +}); \ No newline at end of file diff --git a/build/ace/lib/oop.js b/build/ace/lib/oop.js new file mode 100644 index 00000000..6bb3fd09 --- /dev/null +++ b/build/ace/lib/oop.js @@ -0,0 +1,25 @@ +/* + LGPLv3 +*/ +if(!require.def) { + require.def = require("requireJS-node")(module, require) +}require.def("ace/lib/oop", function() { + var c = {}; + c.inherits = function(a, b) { + var d = function() { + }; + d.prototype = b.prototype; + a.super_ = b.prototype; + a.prototype = new d; + a.prototype.constructor = a + }; + c.mixin = function(a, b) { + for(var d in b) { + a[d] = b[d] + } + }; + c.implement = function(a, b) { + c.mixin(a, b) + }; + return c +}); \ No newline at end of file diff --git a/build/ace/mode/Css.js b/build/ace/mode/Css.js new file mode 100644 index 00000000..dadcb7eb --- /dev/null +++ b/build/ace/mode/Css.js @@ -0,0 +1,81 @@ +/* + LGPLv3 + LGPLv3 + LGPLv3 +*/ +require.def("ace/mode/CssHighlightRules", ["ace/lib/oop", "ace/lib/lang", "ace/mode/TextHighlightRules"], function(j, f, b) { + var e = function() { + function a(c) { + var l = []; + c = c.split(""); + for(var k = 0;k < c.length;k++) { + l.push("[", c[k].toLowerCase(), c[k].toUpperCase(), "]") + }return l.join("") + } + var d = f.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("|")), + g = f.arrayToMap("rgb|rgba|url|attr|counter|counters".split("|")), h = f.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("|")), + i = f.arrayToMap("aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow".split("|")); + this.$rules = {start:[{token:"comment", regex:"\\/\\*", next:"comment"}, {token:"string", regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'}, {token:"string", regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("em")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("ex")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("px")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + + a("cm")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("mm")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("in")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("pt")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("pc")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("deg")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + + a("rad")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("grad")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("ms")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("s")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("hz")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("khz")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))%"}, + {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))"}, {token:"constant.numeric", regex:"#[a-fA-F0-9]{6}"}, {token:"constant.numeric", regex:"#[a-fA-F0-9]{3}"}, {token:"lparen", regex:"{"}, {token:"rparen", regex:"}"}, {token:function(c) { + return d[c.toLowerCase()] ? "support.type" : g[c.toLowerCase()] ? "support.function" : h[c.toLowerCase()] ? "support.constant" : i[c.toLowerCase()] ? "support.constant.color" : "text" + }, regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"}], comment:[{token:"comment", regex:".*?\\*\\/", next:"start"}, {token:"comment", regex:".+"}]} + }; + j.inherits(e, b); + return e +}); +require.def("ace/mode/MatchingBraceOutdent", ["ace/Range"], function(j) { + var f = function() { + }; + (function() { + this.checkOutdent = function(b, e) { + if(!/^\s+$/.test(b)) { + return false + }return/^\s*\}/.test(e) + }; + this.autoOutdent = function(b, e) { + var a = b.getLine(e).match(/^(\s*\})/); + if(!a) { + return 0 + }a = a[1].length; + var d = b.findMatchingBracket({row:e, column:a}); + if(!d || d.row == e) { + return 0 + }d = this.$getIndent(b.getLine(d.row)); + b.replace(new j(e, 0, e, a - 1), d); + return d.length - (a - 1) + }; + this.$getIndent = function(b) { + if(b = b.match(/^(\s+)/)) { + return b[1] + }return"" + } + }).call(f.prototype); + return f +}); +require.def("ace/mode/Css", ["ace/lib/oop", "ace/mode/Text", "ace/Tokenizer", "ace/mode/CssHighlightRules", "ace/mode/MatchingBraceOutdent"], function(j, f, b, e, a) { + var d = function() { + this.$tokenizer = new b((new e).getRules()); + this.$outdent = new a + }; + j.inherits(d, f); + (function() { + this.getNextLineIndent = function(g, h, i) { + var c = this.$getIndent(h); + g = this.$tokenizer.getLineTokens(h, g).tokens; + if(g.length && g[g.length - 1].type == "comment") { + return c + }if(h.match(/^.*\{\s*$/)) { + c += i + }return c + }; + this.checkOutdent = function(g, h, i) { + return this.$outdent.checkOutdent(h, i) + }; + this.autoOutdent = function(g, h, i) { + return this.$outdent.autoOutdent(h, i) + } + }).call(d.prototype); + return d +}); \ No newline at end of file diff --git a/build/ace/mode/CssHighlightRules.js b/build/ace/mode/CssHighlightRules.js new file mode 100644 index 00000000..1773ce2a --- /dev/null +++ b/build/ace/mode/CssHighlightRules.js @@ -0,0 +1,25 @@ +/* + LGPLv3 +*/ +require.def("ace/mode/CssHighlightRules", ["ace/lib/oop", "ace/lib/lang", "ace/mode/TextHighlightRules"], function(g, c, h) { + var f = function() { + function a(b) { + var e = []; + b = b.split(""); + for(var d = 0;d < b.length;d++) { + e.push("[", b[d].toLowerCase(), b[d].toUpperCase(), "]") + }return e.join("") + } + var i = c.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("|")), + j = c.arrayToMap("rgb|rgba|url|attr|counter|counters".split("|")), k = c.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("|")), + l = c.arrayToMap("aqua|black|blue|fuchsia|gray|green|lime|maroon|navy|olive|orange|purple|red|silver|teal|white|yellow".split("|")); + this.$rules = {start:[{token:"comment", regex:"\\/\\*", next:"comment"}, {token:"string", regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'}, {token:"string", regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("em")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("ex")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("px")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + + a("cm")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("mm")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("in")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("pt")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("pc")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("deg")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + + a("rad")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("grad")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("ms")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("s")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("hz")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))" + a("khz")}, {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))%"}, + {token:"constant.numeric", regex:"\\-?(?:(?:[0-9]+)|(?:[0-9]*\\.[0-9]+))"}, {token:"constant.numeric", regex:"#[a-fA-F0-9]{6}"}, {token:"constant.numeric", regex:"#[a-fA-F0-9]{3}"}, {token:"lparen", regex:"{"}, {token:"rparen", regex:"}"}, {token:function(b) { + return i[b.toLowerCase()] ? "support.type" : j[b.toLowerCase()] ? "support.function" : k[b.toLowerCase()] ? "support.constant" : l[b.toLowerCase()] ? "support.constant.color" : "text" + }, regex:"\\-?[a-zA-Z_][a-zA-Z0-9_\\-]*"}], comment:[{token:"comment", regex:".*?\\*\\/", next:"start"}, {token:"comment", regex:".+"}]} + }; + g.inherits(f, h); + return f +}); \ No newline at end of file diff --git a/build/ace/mode/DocCommentHighlightRules.js b/build/ace/mode/DocCommentHighlightRules.js new file mode 100644 index 00000000..f85873bb --- /dev/null +++ b/build/ace/mode/DocCommentHighlightRules.js @@ -0,0 +1,15 @@ +/* + LGPLv3 +*/ +require.def("ace/mode/DocCommentHighlightRules", ["ace/lib/oop", "ace/mode/TextHighlightRules"], function(b, c) { + var a = function() { + this.$rules = {start:[{token:"comment.doc", regex:"\\*\\/", next:"start"}, {token:"comment.doc.tag", regex:"@[\\w\\d_]+"}, {token:"comment.doc", regex:"s+"}, {token:"comment.doc", regex:"[^@\\*]+"}, {token:"comment.doc", regex:"."}]} + }; + b.inherits(a, c); + (function() { + this.getStartRule = function(d) { + return{token:"comment.doc", regex:"\\/\\*(?=\\*)", next:d} + } + }).call(a.prototype); + return a +}); \ No newline at end of file diff --git a/build/ace/mode/Html.js b/build/ace/mode/Html.js new file mode 100644 index 00000000..5c75edf2 --- /dev/null +++ b/build/ace/mode/Html.js @@ -0,0 +1,58 @@ +/* + LGPLv3 + LGPLv3 +*/ +require.def("ace/mode/HtmlHighlightRules", ["ace/lib/oop", "ace/mode/CssHighlightRules", "ace/mode/JavaScriptHighlightRules", "ace/mode/TextHighlightRules"], function(e, f, g, h) { + var c = function() { + 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", 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:".+"}]}; + this.addRules((new g).getRules(), "js-"); + this.$rules["js-start"].unshift({token:"comment", regex:"\\/\\/.*(?=<\\/script>)", next:"tag"}, {token:"text", regex:"<\\/(?=script)", next:"tag"}); + this.addRules((new f).getRules(), "css-"); + this.$rules["css-start"].unshift({token:"text", regex:"<\\/(?=style)", next:"tag"}) + }; + e.inherits(c, h); + return c +}); +require.def("ace/mode/Html", ["ace/lib/oop", "ace/mode/Text", "ace/mode/JavaScript", "ace/mode/Css", "ace/Tokenizer", "ace/mode/HtmlHighlightRules"], function(e, f, g, h, c, l) { + var i = function() { + this.$tokenizer = new c((new l).getRules()); + this.$js = new g; + this.$css = new h + }; + e.inherits(i, f); + (function() { + this.toggleCommentLines = function() { + return this.$delegate("toggleCommentLines", arguments, function() { + return 0 + }) + }; + this.getNextLineIndent = function(j, a) { + var d = this; + return this.$delegate("getNextLineIndent", arguments, function() { + return d.$getIndent(a) + }) + }; + this.checkOutdent = function() { + return this.$delegate("checkOutdent", arguments, function() { + return false + }) + }; + this.autoOutdent = function() { + return this.$delegate("autoOutdent", arguments) + }; + this.$delegate = function(j, a, d) { + var k = a[0], b = k.split("js-"); + if(!b[0] && b[1]) { + a[0] = b[1]; + return this.$js[j].apply(this.$js, a) + }b = k.split("css-"); + if(!b[0] && b[1]) { + a[0] = b[1]; + return this.$css[j].apply(this.$css, a) + }return d ? d() : undefined + } + }).call(i.prototype); + return i +}); \ No newline at end of file diff --git a/build/ace/mode/HtmlHighlightRules.js b/build/ace/mode/HtmlHighlightRules.js new file mode 100644 index 00000000..b3257846 --- /dev/null +++ b/build/ace/mode/HtmlHighlightRules.js @@ -0,0 +1,16 @@ +/* + LGPLv3 +*/ +require.def("ace/mode/HtmlHighlightRules", ["ace/lib/oop", "ace/mode/CssHighlightRules", "ace/mode/JavaScriptHighlightRules", "ace/mode/TextHighlightRules"], function(b, c, d, e) { + var a = function() { + 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", 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:".+"}]}; + this.addRules((new d).getRules(), "js-"); + this.$rules["js-start"].unshift({token:"comment", regex:"\\/\\/.*(?=<\\/script>)", next:"tag"}, {token:"text", regex:"<\\/(?=script)", next:"tag"}); + this.addRules((new c).getRules(), "css-"); + this.$rules["css-start"].unshift({token:"text", regex:"<\\/(?=style)", next:"tag"}) + }; + b.inherits(a, e); + return a +}); \ No newline at end of file diff --git a/build/ace/mode/JavaScript.js b/build/ace/mode/JavaScript.js new file mode 100644 index 00000000..a4bceb82 --- /dev/null +++ b/build/ace/mode/JavaScript.js @@ -0,0 +1,61 @@ +/* + LGPLv3 +*/ +require.def("ace/mode/JavaScript", ["ace/lib/oop", "ace/mode/Text", "ace/Tokenizer", "ace/mode/JavaScriptHighlightRules", "ace/mode/MatchingBraceOutdent", "ace/Range"], function(h, i, j, k, l, m) { + var g = function() { + this.$tokenizer = new j((new k).getRules()); + this.$outdent = new l + }; + h.inherits(g, i); + (function() { + this.toggleCommentLines = function(d, b, e) { + var c = true; + d = /^(\s*)\/\//; + for(var a = e.start.row;a <= e.end.row;a++) { + if(!d.test(b.getLine(a))) { + c = false; + break + } + }if(c) { + c = new m(0, 0, 0, 0); + for(a = e.start.row;a <= e.end.row;a++) { + var f = b.getLine(a).replace(d, "$1"); + c.start.row = a; + c.end.row = a; + c.end.column = f.length + 2; + b.replace(c, f) + }return-2 + }else { + return b.indentRows(e, "//") + } + }; + this.getNextLineIndent = function(d, b, e) { + var c = this.$getIndent(b), a = this.$tokenizer.getLineTokens(b, d), f = a.tokens; + a = a.state; + if(f.length && f[f.length - 1].type == "comment") { + return c + }if(d == "start") { + if(d = b.match(/^.*[\{\(\[]\s*$/)) { + c += e + } + }else { + if(d == "doc-start") { + if(a == "start") { + return"" + }if(d = b.match(/^\s*(\/?)\*/)) { + if(d[1]) { + c += " " + }c += "* " + } + } + }return c + }; + this.checkOutdent = function(d, b, e) { + return this.$outdent.checkOutdent(b, e) + }; + this.autoOutdent = function(d, b, e) { + return this.$outdent.autoOutdent(b, e) + } + }).call(g.prototype); + return g +}); \ No newline at end of file diff --git a/build/ace/mode/JavaScriptHighlightRules.js b/build/ace/mode/JavaScriptHighlightRules.js new file mode 100644 index 00000000..18ae6f17 --- /dev/null +++ b/build/ace/mode/JavaScriptHighlightRules.js @@ -0,0 +1,17 @@ +/* + LGPLv3 +*/ +require.def("ace/mode/JavaScriptHighlightRules", ["ace/lib/oop", "ace/lib/lang", "ace/mode/DocCommentHighlightRules", "ace/mode/TextHighlightRules"], function(d, b, e, f) { + JavaScriptHighlightRules = function() { + var c = new e, g = b.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("|")), h = b.arrayToMap("true|false|null|undefined|Infinity|NaN|undefined".split("|")), i = b.arrayToMap("abstract|boolean|byte|char|class|const|enum|export|extends|final|float|goto|implements|int|interface|long|native|package|private|protected|short|static|super|synchronized|throws|transient|volatiledouble|import|public".split("|")); + this.$rules = {start:[{token:"comment", regex:"\\/\\/.*$"}, c.getStartRule("doc-start"), {token:"comment", regex:"\\/\\*", next:"comment"}, {token:"string.regexp", regex:"[/](?:(?:\\[(?:\\\\]|[^\\]])+\\])|(?:\\\\/|[^\\]/]))*[/][gimy]*\\s*(?=[).,;]|$)"}, {token:"string", regex:'["](?:(?:\\\\.)|(?:[^"\\\\]))*?["]'}, {token:"string", regex:'["].*\\\\$', next:"qqstring"}, {token:"string", regex:"['](?:(?:\\\\.)|(?:[^'\\\\]))*?[']"}, {token:"string", regex:"['].*\\\\$", next:"qstring"}, {token:"constant.numeric", + regex:"0[xX][0-9a-fA-F]+\\b"}, {token:"constant.numeric", regex:"[+-]?\\d+(?:(?:\\.\\d*)?(?:[eE][+-]?\\d+)?)?\\b"}, {token:function(a) { + return a == "this" ? "variable.language" : g[a] ? "keyword" : h[a] ? "constant.language" : i[a] ? "invalid.illegal" : a == "debugger" ? "invalid.deprecated" : "identifier" + }, 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", regex:".*?\\*\\/", next:"start"}, {token:"comment", regex:".+"}], qqstring:[{token:"string", regex:'(?:(?:\\\\.)|(?:[^"\\\\]))*?"', + next:"start"}, {token:"string", regex:".+"}], qstring:[{token:"string", regex:"(?:(?:\\\\.)|(?:[^'\\\\]))*?'", next:"start"}, {token:"string", regex:".+"}]}; + this.addRules(c.getRules(), "doc-"); + this.$rules["doc-start"][0].next = "start" + }; + d.inherits(JavaScriptHighlightRules, f); + return JavaScriptHighlightRules +}); \ No newline at end of file diff --git a/build/ace/mode/MatchingBraceOutdent.js b/build/ace/mode/MatchingBraceOutdent.js new file mode 100644 index 00000000..d2cc35e5 --- /dev/null +++ b/build/ace/mode/MatchingBraceOutdent.js @@ -0,0 +1,32 @@ +/* + LGPLv3 +*/ +require.def("ace/mode/MatchingBraceOutdent", ["ace/Range"], function(f) { + var e = function() { + }; + (function() { + this.checkOutdent = function(a, b) { + if(!/^\s+$/.test(a)) { + return false + }return/^\s*\}/.test(b) + }; + this.autoOutdent = function(a, b) { + var c = a.getLine(b).match(/^(\s*\})/); + if(!c) { + return 0 + }c = c[1].length; + var d = a.findMatchingBracket({row:b, column:c}); + if(!d || d.row == b) { + return 0 + }d = this.$getIndent(a.getLine(d.row)); + a.replace(new f(b, 0, b, c - 1), d); + return d.length - (c - 1) + }; + this.$getIndent = function(a) { + if(a = a.match(/^(\s+)/)) { + return a[1] + }return"" + } + }).call(e.prototype); + return e +}); \ No newline at end of file diff --git a/build/ace/mode/Text.js b/build/ace/mode/Text.js new file mode 100644 index 00000000..0a665da4 --- /dev/null +++ b/build/ace/mode/Text.js @@ -0,0 +1,30 @@ +/* + LGPLv3 +*/ +require.def("ace/mode/Text", ["ace/Tokenizer", "ace/mode/TextHighlightRules"], function(c, d) { + var b = function() { + this.$tokenizer = new c((new d).getRules()) + }; + (function() { + this.getTokenizer = function() { + return this.$tokenizer + }; + this.toggleCommentLines = function() { + return 0 + }; + this.getNextLineIndent = function() { + return"" + }; + this.checkOutdent = function() { + return false + }; + this.autoOutdent = function() { + }; + this.$getIndent = function(a) { + if(a = a.match(/^(\s+)/)) { + return a[1] + }return"" + } + }).call(b.prototype); + return b +}); \ No newline at end of file diff --git a/build/ace/mode/TextHighlightRules.js b/build/ace/mode/TextHighlightRules.js new file mode 100644 index 00000000..31d047c9 --- /dev/null +++ b/build/ace/mode/TextHighlightRules.js @@ -0,0 +1,22 @@ +/* + LGPLv3 +*/ +require.def("ace/mode/TextHighlightRules", [], function() { + var f = function() { + this.$rules = {start:[{token:"text", regex:".+"}]} + }; + (function() { + this.addRules = function(g, a) { + for(var b in g) { + for(var c = g[b], d = 0;d < c.length;d++) { + var e = c[d]; + e.next = e.next ? a + e.next : a + b + }this.$rules[a + b] = c + } + }; + this.getRules = function() { + return this.$rules + } + }).call(f.prototype); + return f +}); \ No newline at end of file diff --git a/build/ace/mode/Xml.js b/build/ace/mode/Xml.js new file mode 100644 index 00000000..d56249da --- /dev/null +++ b/build/ace/mode/Xml.js @@ -0,0 +1,24 @@ +/* + LGPLv3 + LGPLv3 +*/ +require.def("ace/mode/XmlHighlightRules", ["ace/lib/oop", "ace/mode/TextHighlightRules"], function(b, c) { + var a = function() { + this.$rules = {start:[{token:"text", regex:"<\\!\\[CDATA\\[", next:"cdata"}, {token:"xml_pe", regex:"<\\?.*?\\?>"}, {token:"comment", regex:"<\\!--", next:"comment"}, {token:"text", 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:".+"}]} + }; + b.inherits(a, c); + return a +}); +require.def("ace/mode/Xml", ["ace/lib/oop", "ace/mode/Text", "ace/Tokenizer", "ace/mode/XmlHighlightRules"], function(b, c, a, e) { + var d = function() { + this.$tokenizer = new a((new e).getRules()) + }; + b.inherits(d, c); + (function() { + this.getNextLineIndent = function(g, f) { + return this.$getIndent(f) + } + }).call(d.prototype); + return d +}); \ No newline at end of file diff --git a/build/ace/mode/XmlHighlightRules.js b/build/ace/mode/XmlHighlightRules.js new file mode 100644 index 00000000..8969598a --- /dev/null +++ b/build/ace/mode/XmlHighlightRules.js @@ -0,0 +1,11 @@ +/* + LGPLv3 +*/ +require.def("ace/mode/XmlHighlightRules", ["ace/lib/oop", "ace/mode/TextHighlightRules"], function(b, c) { + var a = function() { + this.$rules = {start:[{token:"text", regex:"<\\!\\[CDATA\\[", next:"cdata"}, {token:"xml_pe", regex:"<\\?.*?\\?>"}, {token:"comment", regex:"<\\!--", next:"comment"}, {token:"text", 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:".+"}]} + }; + b.inherits(a, c); + return a +}); \ No newline at end of file diff --git a/build/ace/test/ChangeDocumentTest.js b/build/ace/test/ChangeDocumentTest.js new file mode 100644 index 00000000..afd3d113 --- /dev/null +++ b/build/ace/test/ChangeDocumentTest.js @@ -0,0 +1,79 @@ +/* + LGPLv3 +*/ +require.def(["ace/Document", "ace/Editor", "ace/mode/Text", "ace/mode/JavaScript", "ace/test/MockRenderer"], function(b, c, f, d, e) { + new TestCase("ChangeDocumentTest", {setUp:function() { + this.doc1 = new b("abc\ndef"); + this.doc2 = new b("ghi\njkl"); + this.editor = new c(new e) + }, "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 a = false; + this.editor.onDocumentChange = function() { + a = true + }; + this.editor.setDocument(this.doc1); + this.editor.setDocument(this.doc2); + this.doc1.duplicateLines(0, 0); + assertFalse(a); + this.doc2.duplicateLines(0, 0); + assertTrue(a) + }, "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() { + a = true + }; + this.editor.setDocument(this.doc1); + this.editor.setDocument(this.doc2); + assertPosition(0, 0, this.editor.getCursorPosition()); + var a = false; + this.doc1.getSelection().moveCursorTo(0, 1); + assertPosition(0, 0, this.editor.getCursorPosition()); + assertFalse(a); + this.doc2.getSelection().moveCursorTo(1, 1); + assertPosition(1, 1, this.editor.getCursorPosition()); + assertTrue(a) + }, "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() { + a = true + }; + this.editor.setDocument(this.doc1); + this.editor.setDocument(this.doc2); + assertPosition(0, 0, this.editor.getSelection().getSelectionLead()); + var a = false; + this.doc1.getSelection().selectTo(0, 1); + assertPosition(0, 0, this.editor.getSelection().getSelectionLead()); + assertFalse(a); + this.doc2.getSelection().selectTo(1, 1); + assertPosition(1, 1, this.editor.getSelection().getSelectionLead()); + assertTrue(a) + }, "test: should use mode of new document":function() { + this.editor.onDocumentModeChange = function() { + a = true + }; + this.editor.setDocument(this.doc1); + this.editor.setDocument(this.doc2); + var a = false; + this.doc1.setMode(new Text); + assertFalse(a); + this.doc2.setMode(new d); + assertTrue(a) + }}) +}); \ No newline at end of file diff --git a/build/ace/test/DocumentTest.js b/build/ace/test/DocumentTest.js new file mode 100644 index 00000000..c9e44b04 --- /dev/null +++ b/build/ace/test/DocumentTest.js @@ -0,0 +1,148 @@ +/* + LGPLv3 +*/ +require.def(["ace/Document", "ace/UndoManager", "ace/Editor", "ace/test/MockRenderer"], function(b, h, i, j) { + new TestCase("TextDocumentTest", {"test: find matching opening bracket":function() { + var a = new b(["(()(", "())))"]); + assertPosition(0, 1, a.findMatchingBracket({row:0, column:3})); + assertPosition(1, 0, a.findMatchingBracket({row:1, column:2})); + assertPosition(0, 3, a.findMatchingBracket({row:1, column:3})); + assertPosition(0, 0, a.findMatchingBracket({row:1, column:4})); + assertEquals(null, a.findMatchingBracket({row:1, column:5})) + }, "test: find matching closing bracket":function() { + var a = new b(["(()(", "())))"]); + assertPosition(1, 1, a.findMatchingBracket({row:1, column:1})); + assertPosition(1, 1, a.findMatchingBracket({row:1, column:1})); + assertPosition(1, 2, a.findMatchingBracket({row:0, column:4})); + assertPosition(0, 2, a.findMatchingBracket({row:0, column:2})); + assertPosition(1, 3, a.findMatchingBracket({row:0, column:1})); + assertEquals(null, a.findMatchingBracket({row:0, column:0})) + }, "test: match different bracket types":function() { + var a = new b(["({[", ")]}"]); + assertPosition(1, 0, a.findMatchingBracket({row:0, column:1})); + assertPosition(1, 2, a.findMatchingBracket({row:0, column:2})); + assertPosition(1, 1, a.findMatchingBracket({row:0, column:3})); + assertPosition(0, 0, a.findMatchingBracket({row:1, column:1})); + assertPosition(0, 2, a.findMatchingBracket({row:1, column:2})); + assertPosition(0, 1, a.findMatchingBracket({row:1, column:3})) + }, "test: move lines down":function() { + var a = new b(["1", "2", "3", "4"]); + a.moveLinesDown(0, 1); + assertEquals("3\n1\n2\n4", a.toString()); + a.moveLinesDown(1, 2); + assertEquals("3\n4\n1\n2", a.toString()); + a.moveLinesDown(2, 3); + assertEquals("3\n4\n1\n2", a.toString()); + a.moveLinesDown(2, 2); + assertEquals("3\n4\n2\n1", a.toString()) + }, "test: move lines up":function() { + var a = new b(["1", "2", "3", "4"]); + a.moveLinesUp(2, 3); + assertEquals("1\n3\n4\n2", a.toString()); + a.moveLinesUp(1, 2); + assertEquals("3\n4\n1\n2", a.toString()); + a.moveLinesUp(0, 1); + assertEquals("3\n4\n1\n2", a.toString()); + a.moveLinesUp(2, 2); + assertEquals("3\n1\n4\n2", a.toString()) + }, "test: duplicate lines":function() { + var a = new b(["1", "2", "3", "4"]); + a.duplicateLines(1, 2); + assertEquals("1\n2\n3\n2\n3\n4", a.toString()) + }, "test: duplicate last line":function() { + var a = new b(["1", "2", "3"]); + a.duplicateLines(2, 2); + assertEquals("1\n2\n3\n3", a.toString()) + }, "test: duplicate first line":function() { + var a = new b(["1", "2", "3"]); + a.duplicateLines(0, 0); + assertEquals("1\n1\n2\n3", a.toString()) + }, "test: should handle unix style new lines":function() { + var a = new b(["1", "2", "3"]); + assertEquals("1\n2\n3", a.toString()) + }, "test: should handle windows style new lines":function() { + var a = new b("1\r\n2\r\n3"); + a.setNewLineMode("unix"); + assertEquals("1\n2\n3", a.toString()) + }, "test: set new line mode to 'windows' should use '\r\n' as new lines":function() { + var a = new b("1\n2\n3"); + a.setNewLineMode("windows"); + assertEquals("1\r\n2\r\n3", a.toString()) + }, "test: set new line mode to 'unix' should use '\n' as new lines":function() { + var a = new b("1\r\n2\r\n3"); + a.setNewLineMode("unix"); + assertEquals("1\n2\n3", a.toString()) + }, "test: set new line mode to 'auto' should use detect the incoming nl type":function() { + var a = new b("1\n2\n3"); + a.setNewLineMode("auto"); + assertEquals("1\n2\n3", a.toString()); + a = new b("1\r\n2\r\n3"); + a.setNewLineMode("auto"); + assertEquals("1\r\n2\r\n3", a.toString()); + a.replace(new Range(0, 0, 2, 1), "4\n5\n6"); + assertEquals("4\n5\n6", a.toString()) + }, "test: undo/redo for delete line":function() { + var a = new b(["111", "222", "333"]), c = new h; + a.setUndoManager(c); + var e = a.toString(), d = new i(new j, a); + d.removeLines(); + var f = a.toString(); + assertEquals("222\n333", f); + a.$informUndoManager.call(); + d.removeLines(); + var g = a.toString(); + assertEquals("333", g); + a.$informUndoManager.call(); + d.removeLines(); + d = a.toString(); + assertEquals("", d); + a.$informUndoManager.call(); + c.undo(); + a.$informUndoManager.call(); + assertEquals(g, a.toString()); + c.undo(); + a.$informUndoManager.call(); + assertEquals(f, a.toString()); + c.undo(); + a.$informUndoManager.call(); + assertEquals(e, a.toString()); + c.undo(); + a.$informUndoManager.call(); + assertEquals(e, a.toString()) + }, "test: convert document to screen coordinates":function() { + var a = new b("01234\t567890\t1234"); + a.setTabSize(4); + assertEquals(0, a.documentToScreenColumn(0, 0)); + assertEquals(4, a.documentToScreenColumn(0, 4)); + assertEquals(5, a.documentToScreenColumn(0, 5)); + assertEquals(9, a.documentToScreenColumn(0, 6)); + assertEquals(15, a.documentToScreenColumn(0, 12)); + assertEquals(19, a.documentToScreenColumn(0, 13)); + a.setTabSize(2); + assertEquals(0, a.documentToScreenColumn(0, 0)); + assertEquals(4, a.documentToScreenColumn(0, 4)); + assertEquals(5, a.documentToScreenColumn(0, 5)); + assertEquals(7, a.documentToScreenColumn(0, 6)); + assertEquals(13, a.documentToScreenColumn(0, 12)); + assertEquals(15, a.documentToScreenColumn(0, 13)) + }, "test: convert document to scrren coordinates with leading tabs":function() { + var a = new b("\t\t123"); + a.setTabSize(4); + assertEquals(0, a.documentToScreenColumn(0, 0)); + assertEquals(4, a.documentToScreenColumn(0, 1)); + assertEquals(8, a.documentToScreenColumn(0, 2)); + assertEquals(9, a.documentToScreenColumn(0, 3)) + }, "test: convert screen to document coordinates":function() { + var a = new b("01234\t567890\t1234"); + a.setTabSize(4); + assertEquals(0, a.screenToDocumentColumn(0, 0)); + assertEquals(4, a.screenToDocumentColumn(0, 4)); + assertEquals(5, a.screenToDocumentColumn(0, 5)); + assertEquals(5, a.screenToDocumentColumn(0, 6)); + assertEquals(5, a.screenToDocumentColumn(0, 7)); + assertEquals(5, a.screenToDocumentColumn(0, 8)); + assertEquals(6, a.screenToDocumentColumn(0, 9)); + assertEquals(12, a.screenToDocumentColumn(0, 15)); + assertEquals(13, a.screenToDocumentColumn(0, 19)) + }}) +}); \ No newline at end of file diff --git a/build/ace/test/EventEmitterTest.js b/build/ace/test/EventEmitterTest.js new file mode 100644 index 00000000..5b91cdfa --- /dev/null +++ b/build/ace/test/EventEmitterTest.js @@ -0,0 +1,17 @@ +/* + LGPLv3 +*/ +require.def(["ace/lib/oop", "ace/MEventEmitter"], function(d, e) { + var a = function() { + }; + d.implement(a.prototype, e); + new TestCase("EventEmitterTest", {"test: dispatch event with no data":function() { + var b = new a, c = false; + b.addEventListener("juhu", function(f) { + c = true; + assertEquals("juhu", f.type) + }); + b.$dispatchEvent("juhu"); + assertTrue(c) + }}) +}); \ No newline at end of file diff --git a/build/ace/test/MockRenderer.js b/build/ace/test/MockRenderer.js new file mode 100644 index 00000000..80df09eb --- /dev/null +++ b/build/ace/test/MockRenderer.js @@ -0,0 +1,56 @@ +/* + LGPLv3 +*/ +require.def([], function() { + MockRenderer = function(a) { + this.container = document.createElement("div"); + this.cursor = {row:0, column:0}; + this.visibleRowCount = a || 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(a) { + this.lines = a.lines + }; + MockRenderer.prototype.setTokenizer = function() { + }; + MockRenderer.prototype.updateCursor = function(a) { + this.cursor.row = a.row; + this.cursor.column = a.column + }; + MockRenderer.prototype.scrollCursorIntoView = function() { + if(this.cursor.row < this.layerConfig.firstVisibleRow) { + this.scrollToRow(this.cursor.row) + }else { + this.cursor.row > this.layerConfig.lastVisibleRow && this.scrollToRow(this.cursor.row) + } + }; + MockRenderer.prototype.scrollToRow = function(a) { + a = Math.min(this.lines.length - this.visibleRowCount, Math.max(0, a)); + this.layerConfig.firstVisibleRow = a; + this.layerConfig.lastVisibleRow = a + this.visibleRowCount + }; + MockRenderer.prototype.getScrollTopRow = function() { + return this.layerConfig.firstVisibleRow + }; + MockRenderer.prototype.draw = function() { + }; + MockRenderer.prototype.updateLines = function() { + }; + MockRenderer.prototype.addMarker = function() { + }; + MockRenderer.prototype.setBreakpoints = function() { + }; + return MockRenderer +}); \ No newline at end of file diff --git a/build/ace/test/NavigationTest.js b/build/ace/test/NavigationTest.js new file mode 100644 index 00000000..7a33ea4d --- /dev/null +++ b/build/ace/test/NavigationTest.js @@ -0,0 +1,77 @@ +/* + LGPLv3 +*/ +require.def(["ace/Document", "ace/Editor", "ace/test/MockRenderer"], function(e, c, d) { + TestCase("NavigationTest", {createTextDocument:function(a, b) { + b = (new Array(b + 1)).join("a"); + a = (new Array(a)).join(b + "\n") + b; + return new e(a) + }, "test: navigate to end of file should scroll the last line into view":function() { + var a = this.createTextDocument(200, 10); + a = new c(new d, a); + a.navigateFileEnd(); + var b = a.getCursorPosition(); + assertTrue(a.getFirstVisibleRow() <= b.row); + assertTrue(a.getLastVisibleRow() >= b.row) + }, "test: navigate to start of file should scroll the first row into view":function() { + var a = this.createTextDocument(200, 10); + a = new c(new d, a); + a.moveCursorTo(a.getLastVisibleRow() + 20); + a.navigateFileStart(); + assertEquals(0, a.getFirstVisibleRow()) + }, "test: goto hidden line should scroll the line into the middle of the viewport":function() { + var a = new c(new d, this.createTextDocument(200, 5)); + a.navigateTo(0, 0); + a.gotoLine(101); + assertPosition(100, 0, a.getCursorPosition()); + assertEquals(90, a.getFirstVisibleRow()); + a.navigateTo(100, 0); + a.gotoLine(11); + assertPosition(10, 0, a.getCursorPosition()); + assertEquals(0, a.getFirstVisibleRow()); + a.navigateTo(100, 0); + a.gotoLine(6); + assertPosition(5, 0, a.getCursorPosition()); + assertEquals(0, a.getFirstVisibleRow()); + a.navigateTo(100, 0); + a.gotoLine(1); + assertPosition(0, 0, a.getCursorPosition()); + assertEquals(0, a.getFirstVisibleRow()); + a.navigateTo(0, 0); + a.gotoLine(191); + assertPosition(190, 0, a.getCursorPosition()); + assertEquals(180, a.getFirstVisibleRow()); + a.navigateTo(0, 0); + a.gotoLine(196); + assertPosition(195, 0, a.getCursorPosition()); + assertEquals(180, a.getFirstVisibleRow()) + }, "test: goto visible line should only move the cursor and not scroll":function() { + var a = new c(new d, this.createTextDocument(200, 5)); + a.navigateTo(0, 0); + a.gotoLine(12); + assertPosition(11, 0, a.getCursorPosition()); + assertEquals(0, a.getFirstVisibleRow()); + a.navigateTo(30, 0); + a.gotoLine(33); + assertPosition(32, 0, a.getCursorPosition()); + assertEquals(30, a.getFirstVisibleRow()) + }, "test: navigate from the end of a long line down to a short line and back should maintain the curser column":function() { + var a = new c(new d, new e(["123456", "1"])); + a.navigateTo(0, 6); + assertPosition(0, 6, a.getCursorPosition()); + a.navigateDown(); + assertPosition(1, 1, a.getCursorPosition()); + a.navigateUp(); + assertPosition(0, 6, a.getCursorPosition()) + }, "test: reset desired column on navigate left or right":function() { + var a = new c(new d, new e(["123456", "12"])); + a.navigateTo(0, 6); + assertPosition(0, 6, a.getCursorPosition()); + a.navigateDown(); + assertPosition(1, 2, a.getCursorPosition()); + a.navigateLeft(); + assertPosition(1, 1, a.getCursorPosition()); + a.navigateUp(); + assertPosition(0, 1, a.getCursorPosition()) + }}) +}); \ No newline at end of file diff --git a/build/ace/test/RangeTest.js b/build/ace/test/RangeTest.js new file mode 100644 index 00000000..56243724 --- /dev/null +++ b/build/ace/test/RangeTest.js @@ -0,0 +1,74 @@ +/* + LGPLv3 +*/ +require.def(["ace/Range"], function(b) { + RangeTest = new TestCase("RangeTest", {"test: create range":function() { + var a = new b(1, 2, 3, 4); + assertEquals(1, a.start.row); + assertEquals(2, a.start.column); + assertEquals(3, a.end.row); + assertEquals(4, a.end.column) + }, "test: create from points":function() { + var a = b.fromPoints({row:1, column:2}, {row:3, column:4}); + assertEquals(1, a.start.row); + assertEquals(2, a.start.column); + assertEquals(3, a.end.row); + assertEquals(4, a.end.column) + }, "test: clip to rows":function() { + assertRange(10, 0, 31, 0, (new b(0, 20, 100, 30)).clipRows(10, 30)); + assertRange(10, 0, 30, 10, (new b(0, 20, 30, 10)).clipRows(10, 30)); + var a = new b(0, 20, 3, 10); + a = a.clipRows(10, 30); + assertTrue(a.isEmpty()); + assertRange(10, 0, 10, 0, a) + }, "test: isEmpty":function() { + var a = new b(1, 2, 1, 2); + assertTrue(a.isEmpty()); + a = new b(1, 2, 1, 6); + assertFalse(a.isEmpty()) + }, "test: is multi line":function() { + var a = new b(1, 2, 1, 6); + assertFalse(a.isMultiLine()); + a = new b(1, 2, 2, 6); + assertTrue(a.isMultiLine()) + }, "test: clone":function() { + var a = new b(1, 2, 3, 4), c = a.clone(); + assertPosition(1, 2, c.start); + assertPosition(3, 4, c.end); + c.start.column = 20; + assertPosition(1, 2, a.start); + c.end.column = 20; + assertPosition(3, 4, a.end) + }, "test: contains for multi line ranges":function() { + var a = new b(1, 10, 5, 20); + assertTrue(a.contains(1, 10)); + assertTrue(a.contains(2, 0)); + assertTrue(a.contains(3, 100)); + assertTrue(a.contains(5, 19)); + assertTrue(a.contains(5, 20)); + assertFalse(a.contains(1, 9)); + assertFalse(a.contains(0, 0)); + assertFalse(a.contains(5, 21)) + }, "test: contains for single line ranges":function() { + var a = new b(1, 10, 1, 20); + assertTrue(a.contains(1, 10)); + assertTrue(a.contains(1, 15)); + assertTrue(a.contains(1, 20)); + assertFalse(a.contains(0, 9)); + assertFalse(a.contains(2, 9)); + assertFalse(a.contains(1, 9)); + assertFalse(a.contains(1, 21)) + }, "test: extend range":function() { + var a = new b(2, 10, 2, 30); + a = a.extend(2, 5); + assertRange(2, 5, 2, 30, a); + a = a.extend(2, 35); + assertRange(2, 5, 2, 35, a); + a = a.extend(2, 15); + assertRange(2, 5, 2, 35, a); + a = a.extend(1, 4); + assertRange(1, 4, 2, 35, a); + a = a.extend(6, 10); + assertRange(1, 4, 6, 10, a) + }}) +}); \ No newline at end of file diff --git a/build/ace/test/SearchTest.js b/build/ace/test/SearchTest.js new file mode 100644 index 00000000..83494e64 --- /dev/null +++ b/build/ace/test/SearchTest.js @@ -0,0 +1,135 @@ +/* + LGPLv3 +*/ +require.def(["ace/Document", "ace/Search"], function(c, b) { + new TestCase("SearchTest", {"test: configure the search object":function() { + (new b).set({needle:"juhu", scope:b.ALL}) + }, "test: find simple text in document":function() { + var a = new c(["juhu kinners 123", "456"]); + a = (new b).set({needle:"kinners"}).find(a); + assertPosition(0, 5, a.start); + assertPosition(0, 12, a.end) + }, "test: find simple text in next line":function() { + var a = new c(["abc", "juhu kinners 123", "456"]); + a = (new b).set({needle:"kinners"}).find(a); + assertPosition(1, 5, a.start); + assertPosition(1, 12, a.end) + }, "test: find text starting at cursor position":function() { + var a = new c(["juhu kinners", "juhu kinners 123"]); + a.getSelection().moveCursorTo(0, 6); + a = (new b).set({needle:"kinners"}).find(a); + assertPosition(1, 5, a.start); + assertPosition(1, 12, a.end) + }, "test: wrap search is off by default":function() { + var a = new c(["abc", "juhu kinners 123", "456"]); + a.getSelection().moveCursorTo(2, 1); + var d = (new b).set({needle:"kinners"}); + assertEquals(null, d.find(a)) + }, "test: wrap search should wrap at file end":function() { + var a = new c(["abc", "juhu kinners 123", "456"]); + a.getSelection().moveCursorTo(2, 1); + a = (new b).set({needle:"kinners", wrap:true}).find(a); + assertPosition(1, 5, a.start); + assertPosition(1, 12, a.end) + }, "test: wrap search with no match should return 'null'":function() { + var a = new c(["abc", "juhu kinners 123", "456"]); + a.getSelection().moveCursorTo(2, 1); + var d = (new b).set({needle:"xyz", wrap:true}); + assertEquals(null, d.find(a)) + }, "test: case sensitive is by default off":function() { + var a = new c(["abc", "juhu kinners 123", "456"]), d = (new b).set({needle:"JUHU"}); + assertEquals(null, d.find(a)) + }, "test: case sensitive search":function() { + var a = new c(["abc", "juhu kinners 123", "456"]); + a = (new b).set({needle:"KINNERS", caseSensitive:true}).find(a); + assertPosition(1, 5, a.start); + assertPosition(1, 12, a.end) + }, "test: whole word search should not match inside of words":function() { + var a = new c(["juhukinners", "juhu kinners 123", "456"]); + a = (new b).set({needle:"kinners", wholeWord:true}).find(a); + assertPosition(1, 5, a.start); + assertPosition(1, 12, a.end) + }, "test: find backwards":function() { + var a = new c(["juhu juhu juhu juhu"]); + a.getSelection().moveCursorTo(0, 10); + a = (new b).set({needle:"juhu", backwards:true}).find(a); + assertPosition(0, 5, a.start); + assertPosition(0, 9, a.end) + }, "test: find in selection":function() { + var a = new c(["juhu", "juhu", "juhu", "juhu"]); + a.getSelection().setSelectionAnchor(1, 0); + a.getSelection().selectTo(3, 5); + var d = (new b).set({needle:"juhu", wrap:true, scope:b.SELECTION}), e = d.find(a); + assertPosition(1, 0, e.start); + assertPosition(1, 4, e.end); + a.getSelection().setSelectionAnchor(0, 2); + a.getSelection().selectTo(3, 2); + e = d.find(a); + assertPosition(1, 0, e.start); + assertPosition(1, 4, e.end) + }, "test: find backwards in selection":function() { + var a = new c(["juhu", "juhu", "juhu", "juhu"]), d = (new b).set({needle:"juhu", wrap:true, backwards:true, scope:b.SELECTION}); + a.getSelection().setSelectionAnchor(0, 2); + a.getSelection().selectTo(3, 2); + var e = d.find(a); + assertPosition(2, 0, e.start); + assertPosition(2, 4, e.end); + a.getSelection().setSelectionAnchor(0, 2); + a.getSelection().selectTo(1, 2); + assertEquals(null, d.find(a)) + }, "test: edge case - match directly before the cursor":function() { + var a = new c(["123", "123", "juhu"]), d = (new b).set({needle:"juhu", wrap:true}); + a.getSelection().moveCursorTo(2, 5); + a = d.find(a); + assertPosition(2, 0, a.start); + assertPosition(2, 4, a.end) + }, "test: edge case - match backwards directly after the cursor":function() { + var a = new c(["123", "123", "juhu"]), d = (new b).set({needle:"juhu", wrap:true, backwards:true}); + a.getSelection().moveCursorTo(2, 0); + a = d.find(a); + assertPosition(2, 0, a.start); + assertPosition(2, 4, a.end) + }, "test: find using a regular expression":function() { + var a = new c(["abc123 123 cd", "abc"]); + a = (new b).set({needle:"\\d+", regExp:true}).find(a); + assertPosition(0, 3, a.start); + assertPosition(0, 6, a.end) + }, "test: find using a regular expression and whole word":function() { + var a = new c(["abc123 123 cd", "abc"]); + a = (new b).set({needle:"\\d+\\b", regExp:true, wholeWord:true}).find(a); + assertPosition(0, 7, a.start); + assertPosition(0, 10, a.end) + }, "test: use regular expressions with capture groups":function() { + var a = new c([" ab: 12px", "

+*/ +require.def(["ace/Document"], function(c) { + TestCase("SelectionTest", {createTextDocument:function(a, b) { + b = (new Array(b + 1)).join("a"); + a = (new Array(a)).join(b + "\n") + b; + return new c(a) + }, "test: move cursor to end of file should place the cursor on last row and column":function() { + var a = this.createTextDocument(200, 10).getSelection(); + a.moveCursorFileEnd(); + assertPosition(199, 10, a.getCursor()) + }, "test: moveCursor to start of file should place the cursor on the first row and column":function() { + var a = this.createTextDocument(200, 10).getSelection(); + a.moveCursorFileStart(); + assertPosition(0, 0, a.getCursor()) + }, "test: move selection lead to end of file":function() { + var a = this.createTextDocument(200, 10).getSelection(); + a.moveCursorTo(100, 5); + a.selectFileEnd(); + a = a.getRange(); + assertPosition(100, 5, a.start); + assertPosition(199, 10, a.end) + }, "test: move selection lead to start of file":function() { + var a = this.createTextDocument(200, 10).getSelection(); + a.moveCursorTo(100, 5); + a.selectFileStart(); + a = a.getRange(); + assertPosition(0, 0, a.start); + assertPosition(100, 5, a.end) + }, "test: move cursor word right":function() { + var a = (new c("ab\n Juhu Kinners (abc, 12)\n cde")).getSelection(); + a.moveCursorDown(); + assertPosition(1, 0, a.getCursor()); + a.moveCursorWordRight(); + assertPosition(1, 1, a.getCursor()); + a.moveCursorWordRight(); + assertPosition(1, 5, a.getCursor()); + a.moveCursorWordRight(); + assertPosition(1, 6, a.getCursor()); + a.moveCursorWordRight(); + assertPosition(1, 13, a.getCursor()); + a.moveCursorWordRight(); + assertPosition(1, 15, a.getCursor()); + a.moveCursorWordRight(); + assertPosition(1, 18, a.getCursor()); + a.moveCursorWordRight(); + assertPosition(1, 20, a.getCursor()); + a.moveCursorWordRight(); + assertPosition(1, 22, a.getCursor()); + a.moveCursorWordRight(); + assertPosition(1, 23, a.getCursor()); + a.moveCursorWordRight(); + assertPosition(2, 0, a.getCursor()) + }, "test: select word right if cursor in word":function() { + var a = (new c("Juhu Kinners")).getSelection(); + a.moveCursorTo(0, 2); + a.moveCursorWordRight(); + assertPosition(0, 4, a.getCursor()) + }, "test: moveCursor word left":function() { + var a = (new c("ab\n Juhu Kinners (abc, 12)\n cde")).getSelection(); + a.moveCursorDown(); + a.moveCursorLineEnd(); + assertPosition(1, 23, a.getCursor()); + a.moveCursorWordLeft(); + assertPosition(1, 22, a.getCursor()); + a.moveCursorWordLeft(); + assertPosition(1, 20, a.getCursor()); + a.moveCursorWordLeft(); + assertPosition(1, 18, a.getCursor()); + a.moveCursorWordLeft(); + assertPosition(1, 15, a.getCursor()); + a.moveCursorWordLeft(); + assertPosition(1, 13, a.getCursor()); + a.moveCursorWordLeft(); + assertPosition(1, 6, a.getCursor()); + a.moveCursorWordLeft(); + assertPosition(1, 5, a.getCursor()); + a.moveCursorWordLeft(); + assertPosition(1, 1, a.getCursor()); + a.moveCursorWordLeft(); + assertPosition(1, 0, a.getCursor()); + a.moveCursorWordLeft(); + assertPosition(0, 2, a.getCursor()) + }, "test: select word left if cursor in word":function() { + var a = (new c("Juhu Kinners")).getSelection(); + a.moveCursorTo(0, 8); + a.moveCursorWordLeft(); + assertPosition(0, 5, a.getCursor()) + }, "test: select word right and select":function() { + var a = (new c("Juhu Kinners")).getSelection(); + a.moveCursorTo(0, 0); + a.selectWordRight(); + a = a.getRange(); + assertPosition(0, 0, a.start); + assertPosition(0, 4, a.end) + }, "test: select word left and select":function() { + var a = (new c("Juhu Kinners")).getSelection(); + a.moveCursorTo(0, 3); + a.selectWordLeft(); + a = a.getRange(); + assertPosition(0, 0, a.start); + assertPosition(0, 3, a.end) + }, "test: select word with cursor in word should select the word":function() { + var a = (new c("Juhu Kinners 123")).getSelection(); + a.moveCursorTo(0, 8); + a.selectWord(); + a = a.getRange(); + assertPosition(0, 5, a.start); + assertPosition(0, 12, a.end) + }, "test: select word with cursor betwen white space and word should select the word":function() { + var a = (new c("Juhu Kinners")).getSelection(); + a.moveCursorTo(0, 4); + a.selectWord(); + var b = a.getRange(); + assertPosition(0, 0, b.start); + assertPosition(0, 4, b.end); + a.moveCursorTo(0, 5); + a.selectWord(); + b = a.getRange(); + assertPosition(0, 5, b.start); + assertPosition(0, 12, b.end) + }, "test: select word with cursor in white space should select white space":function() { + var a = (new c("Juhu Kinners")).getSelection(); + a.moveCursorTo(0, 5); + a.selectWord(); + a = a.getRange(); + assertPosition(0, 4, a.start); + assertPosition(0, 6, a.end) + }, "test: moving cursor should fire a 'changeCursor' event":function() { + var a = (new c("Juhu Kinners")).getSelection(); + a.moveCursorTo(0, 5); + var b = false; + a.addEventListener("changeCursor", function() { + b = true + }); + a.moveCursorTo(0, 6); + assertTrue(b) + }, "test: calling setCursor with the same position should not fire an event":function() { + var a = (new c("Juhu Kinners")).getSelection(); + a.moveCursorTo(0, 5); + var b = false; + a.addEventListener("changeCursor", function() { + b = true + }); + a.moveCursorTo(0, 5); + assertFalse(b) + }}) +}); \ No newline at end of file diff --git a/build/ace/test/TextEditTest.js b/build/ace/test/TextEditTest.js new file mode 100644 index 00000000..f69ce6f4 --- /dev/null +++ b/build/ace/test/TextEditTest.js @@ -0,0 +1,178 @@ +/* + LGPLv3 +*/ +require.def(["ace/Document", "ace/Editor", "ace/mode/JavaScript", "ace/test/MockRenderer"], function(c, d, g, e) { + TestCase("TextEditTest", {"test: delete line from the middle":function() { + var b = new c("a\nb\nc\nd"), a = new d(new e, b); + a.moveCursorTo(1, 1); + a.removeLines(); + assertEquals("a\nc\nd", b.toString()); + assertPosition(1, 0, a.getCursorPosition()); + a.removeLines(); + assertEquals("a\nd", b.toString()); + assertPosition(1, 0, a.getCursorPosition()); + a.removeLines(); + assertEquals("a\n", b.toString()); + assertPosition(1, 0, a.getCursorPosition()); + a.removeLines(); + assertEquals("a\n", b.toString()); + assertPosition(1, 0, a.getCursorPosition()) + }, "test: delete multiple selected lines":function() { + var b = new c("a\nb\nc\nd"), a = new d(new e, b); + a.moveCursorTo(1, 1); + a.getSelection().selectDown(); + a.removeLines(); + assertEquals("a\nd", b.toString()); + assertPosition(1, 0, a.getCursorPosition()) + }, "test: delete first line":function() { + var b = new c("a\nb\nc"), a = new d(new e, b); + a.removeLines(); + assertEquals("b\nc", b.toString()); + assertPosition(0, 0, a.getCursorPosition()) + }, "test: delete last":function() { + var b = new c("a\nb\nc"), a = new d(new e, b); + a.moveCursorTo(2, 1); + a.removeLines(); + assertEquals("a\nb\n", b.toString()); + assertPosition(2, 0, a.getCursorPosition()) + }, "test: indent block":function() { + var b = new c("a12345\nb12345\nc12345"), a = new d(new e, b); + a.moveCursorTo(1, 3); + a.getSelection().selectDown(); + a.blockIndent(" "); + assertEquals("a12345\n b12345\n c12345", b.toString()); + assertPosition(2, 7, a.getCursorPosition()); + b = a.getSelectionRange(); + assertPosition(1, 7, b.start); + assertPosition(2, 7, b.end) + }, "test: outdent block":function() { + var b = new c(" a12345\n b12345\n c12345"), a = new d(new e, b); + a.moveCursorTo(0, 3); + a.getSelection().selectDown(); + a.getSelection().selectDown(); + a.blockOutdent(" "); + assertEquals(" a12345\nb12345\n c12345", b.toString()); + assertPosition(2, 1, a.getCursorPosition()); + var f = a.getSelectionRange(); + assertPosition(0, 1, f.start); + assertPosition(2, 1, f.end); + a.blockOutdent(" "); + assertEquals(" a12345\nb12345\n c12345", b.toString()); + f = a.getSelectionRange(); + assertPosition(0, 1, f.start); + assertPosition(2, 1, f.end) + }, "test: outent without a selection should update cursor":function() { + var b = new c(" 12"), a = new d(new e, b); + a.moveCursorTo(0, 3); + a.blockOutdent(" "); + assertEquals(" 12", b.toString()); + assertPosition(0, 1, a.getCursorPosition()) + }, "test: comment lines should perserve selection":function() { + var b = new c(" abc\ncde", new g), a = new d(new e, b); + a.moveCursorTo(0, 2); + a.getSelection().selectDown(); + a.toggleCommentLines(); + assertEquals("// abc\n//cde", b.toString()); + b = a.getSelectionRange(); + assertPosition(0, 4, b.start); + assertPosition(1, 4, b.end) + }, "test: uncomment lines should perserve selection":function() { + var b = new c("// abc\n//cde", new g), a = new d(new e, b); + a.moveCursorTo(0, 1); + a.getSelection().selectDown(); + a.getSelection().selectRight(); + a.getSelection().selectRight(); + a.toggleCommentLines(); + assertEquals(" abc\ncde", b.toString()); + assertRange(0, 0, 1, 1, a.getSelectionRange()) + }, "test: comment lines - if the selection end is at the line start it should stay there":function() { + var b = new c("abc\ncde", new g); + b = new d(new e, b); + b.moveCursorTo(0, 0); + b.getSelection().selectDown(); + b.toggleCommentLines(); + assertRange(0, 2, 1, 0, b.getSelectionRange()); + b = new c("abc\ncde", new g); + b = new d(new e, b); + b.moveCursorTo(1, 0); + b.getSelection().selectUp(); + b.toggleCommentLines(); + assertRange(0, 2, 1, 0, b.getSelectionRange()) + }, "test: move lines down should select moved lines":function() { + var b = new c("11\n22\n33\n44"), a = new d(new e, b); + a.moveCursorTo(0, 1); + a.getSelection().selectDown(); + a.moveLinesDown(); + assertEquals("33\n11\n22\n44", b.toString()); + assertPosition(1, 0, a.getCursorPosition()); + assertPosition(3, 0, a.getSelection().getSelectionAnchor()); + assertPosition(1, 0, a.getSelection().getSelectionLead()); + a.moveLinesDown(); + assertEquals("33\n44\n11\n22", b.toString()); + assertPosition(2, 0, a.getCursorPosition()); + assertPosition(3, 2, a.getSelection().getSelectionAnchor()); + assertPosition(2, 0, a.getSelection().getSelectionLead()); + a.moveLinesDown(); + assertEquals("33\n44\n11\n22", b.toString()); + assertPosition(2, 0, a.getCursorPosition()); + assertPosition(3, 2, a.getSelection().getSelectionAnchor()); + assertPosition(2, 0, a.getSelection().getSelectionLead()) + }, "test: move lines up should select moved lines":function() { + var b = new c("11\n22\n33\n44"), a = new d(new e, b); + a.moveCursorTo(2, 1); + a.getSelection().selectDown(); + a.moveLinesUp(); + assertEquals("11\n33\n44\n22", b.toString()); + assertPosition(1, 0, a.getCursorPosition()); + assertPosition(3, 0, a.getSelection().getSelectionAnchor()); + assertPosition(1, 0, a.getSelection().getSelectionLead()); + a.moveLinesUp(); + assertEquals("33\n44\n11\n22", b.toString()); + assertPosition(0, 0, a.getCursorPosition()); + assertPosition(2, 0, a.getSelection().getSelectionAnchor()); + assertPosition(0, 0, a.getSelection().getSelectionLead()) + }, "test: move line without active selection should move cursor to start of the moved line":function() { + var b = new c("11\n22\n33\n44"), a = new d(new e, b); + a.moveCursorTo(1, 1); + a.clearSelection(); + a.moveLinesDown(); + assertEquals("11\n33\n22\n44", b.toString()); + assertPosition(2, 0, a.getCursorPosition()); + a.clearSelection(); + a.moveLinesUp(); + assertEquals("11\n22\n33\n44", b.toString()); + assertPosition(1, 0, a.getCursorPosition()) + }, "test: copy lines down should select lines and place cursor at the selection start":function() { + var b = new c("11\n22\n33\n44"), a = new d(new e, b); + a.moveCursorTo(1, 1); + a.getSelection().selectDown(); + a.copyLinesDown(); + assertEquals("11\n22\n33\n22\n33\n44", b.toString()); + assertPosition(3, 0, a.getCursorPosition()); + assertPosition(5, 0, a.getSelection().getSelectionAnchor()); + assertPosition(3, 0, a.getSelection().getSelectionLead()) + }, "test: copy lines up should select lines and place cursor at the selection start":function() { + var b = new c("11\n22\n33\n44"), a = new d(new e, b); + a.moveCursorTo(1, 1); + a.getSelection().selectDown(); + a.copyLinesUp(); + assertEquals("11\n22\n33\n22\n33\n44", b.toString()); + assertPosition(1, 0, a.getCursorPosition()); + assertPosition(3, 0, a.getSelection().getSelectionAnchor()); + assertPosition(1, 0, a.getSelection().getSelectionLead()) + }, "test: input a tab with soft tab should convert it to spaces":function() { + var b = new c(""), a = new d(new e, b); + b.setTabSize(2); + b.setUseSoftTabs(true); + a.onTextInput("\t"); + assertEquals(" ", b.toString()); + b.setTabSize(5); + a.onTextInput("\t"); + assertEquals(" ", b.toString()) + }, "test: input tab without soft tabs should keep the tab character":function() { + var b = new c(""), a = new d(new e, b); + b.setUseSoftTabs(false); + a.onTextInput("\t"); + assertEquals("\t", b.toString()) + }}) +}); \ No newline at end of file diff --git a/build/ace/test/VirtualRendererTest.js b/build/ace/test/VirtualRendererTest.js new file mode 100644 index 00000000..8c3a51c3 --- /dev/null +++ b/build/ace/test/VirtualRendererTest.js @@ -0,0 +1,27 @@ +/* + LGPLv3 +*/ +require.def(["ace/Document", "ace/VirtualRenderer"], function(c, d) { + new TestCase("VirtualRendererTest", {"test: screen2text the column should be rounded to the next character edge":function() { + var b = document.createElement("div"); + b.style.left = "0px"; + b.style.top = "0px"; + b.style.width = "100px"; + b.style.height = "100px"; + document.body.style.margin = "0px"; + document.body.style.padding = "0px"; + document.body.appendChild(b); + var a = new d(b); + a.setDocument(new c("1234")); + a.characterWidth = 10; + a.lineHeight = 15; + assertPosition(0, 0, a.screenToTextCoordinates(0, 0)); + assertPosition(0, 0, a.screenToTextCoordinates(4, 0)); + assertPosition(0, 1, a.screenToTextCoordinates(5, 0)); + assertPosition(0, 1, a.screenToTextCoordinates(9, 0)); + assertPosition(0, 1, a.screenToTextCoordinates(10, 0)); + assertPosition(0, 1, a.screenToTextCoordinates(14, 0)); + assertPosition(0, 2, a.screenToTextCoordinates(15, 0)); + document.body.removeChild(b) + }}) +}); \ No newline at end of file diff --git a/build/ace/test/all.js b/build/ace/test/all.js new file mode 100644 index 00000000..ece34003 --- /dev/null +++ b/build/ace/test/all.js @@ -0,0 +1,4 @@ +require({paths:{ace:"../src/ace"}}, ["ace/test/assertions", "ace/test/ChangeDocumentTest"], function(a) { + console.log(a); + alert("a " + a) +}); \ No newline at end of file diff --git a/build/ace/test/assertions.js b/build/ace/test/assertions.js new file mode 100644 index 00000000..c7c5eefa --- /dev/null +++ b/build/ace/test/assertions.js @@ -0,0 +1,16 @@ +/* + LGPLv3 +*/ +require.def([], function() { + window.assertPosition = function(a, b, c) { + assertEquals(a, c.row); + assertEquals(b, c.column) + }; + window.assertRange = function(a, b, c, e, d) { + assertPosition(a, b, d.start); + assertPosition(c, e, d.end) + }; + window.assertJsonEquals = function(a, b) { + assertEquals(JSON.stringify(a), JSON.stringify(b)) + } +}); \ No newline at end of file diff --git a/build/ace/test/mode/CssTest.js b/build/ace/test/mode/CssTest.js new file mode 100644 index 00000000..d2a1eef8 --- /dev/null +++ b/build/ace/test/mode/CssTest.js @@ -0,0 +1,21 @@ +/* + LGPLv3 +*/ +require.def(["ace/Document", "ace/Range", "ace/mode/Css"], function(b, c, d) { + new TestCase("mode.CssTest", {setUp:function() { + this.mode = new d + }, "test: toggle comment lines should not do anything":function() { + var a = new b(" abc\ncde\nfg"), e = new c(0, 3, 1, 1); + this.mode.toggleCommentLines("start", a, e); + assertEquals(" abc\ncde\nfg", a.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", " /*{ ", " ")) + }}) +}); \ No newline at end of file diff --git a/build/ace/test/mode/CssTokenizerTest.js b/build/ace/test/mode/CssTokenizerTest.js new file mode 100644 index 00000000..759dfb95 --- /dev/null +++ b/build/ace/test/mode/CssTokenizerTest.js @@ -0,0 +1,26 @@ +/* + LGPLv3 +*/ +require.def(["ace/mode/Css"], function(b) { + new TestCase("mode.CssTest", {setUp:function() { + this.tokenizer = (new b).getTokenizer() + }, "test: tokenize pixel number":function() { + var a = this.tokenizer.getLineTokens("-12px", "start").tokens; + assertEquals(1, a.length); + assertEquals("number", a[0].type) + }, "test: tokenize hex3 color":function() { + var a = this.tokenizer.getLineTokens("#abc", "start").tokens; + assertEquals(1, a.length); + assertEquals("number", a[0].type) + }, "test: tokenize hex6 color":function() { + var a = this.tokenizer.getLineTokens("#abc012", "start").tokens; + assertEquals(1, a.length); + assertEquals("number", a[0].type) + }, "test: tokenize parens":function() { + var a = this.tokenizer.getLineTokens("{()}", "start").tokens; + assertEquals(3, a.length); + assertEquals("lparen", a[0].type); + assertEquals("text", a[1].type); + assertEquals("rparen", a[2].type) + }}) +}); \ No newline at end of file diff --git a/build/ace/test/mode/HtmlTest.js b/build/ace/test/mode/HtmlTest.js new file mode 100644 index 00000000..2af56ba6 --- /dev/null +++ b/build/ace/test/mode/HtmlTest.js @@ -0,0 +1,16 @@ +/* + LGPLv3 +*/ +require.def(["ace/Document", "ace/Range", "ace/mode/Html"], function(b, c, d) { + new TestCase("mode.HtmlTest", {setUp:function() { + this.mode = new d + }, "test: toggle comment lines should not do anything":function() { + var a = new b([" abc", "cde", "fg"]), e = new c(0, 3, 1, 1); + this.mode.toggleCommentLines("start", a, e); + assertEquals(" abc\ncde\nfg", a.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")) + }}) +}); \ No newline at end of file diff --git a/build/ace/test/mode/HtmlTokenizerTest.js b/build/ace/test/mode/HtmlTokenizerTest.js new file mode 100644 index 00000000..3ed6b4b2 --- /dev/null +++ b/build/ace/test/mode/HtmlTokenizerTest.js @@ -0,0 +1,21 @@ +/* + LGPLv3 +*/ +require.def(["ace/mode/Html"], function(b) { + new TestCase("mode.HtmlTest", {setUp:function() { + this.tokenizer = (new b).getTokenizer() + }, "test: tokenize embedded script":function() { + var a = this.tokenizer.getLineTokens(" + + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ +
+
+ + + + + + + + + + + \ No newline at end of file diff --git a/demo/editor.html b/demo/editor.html new file mode 100644 index 00000000..6cc21662 --- /dev/null +++ b/demo/editor.html @@ -0,0 +1,298 @@ + + + + + + Editor + + + + + + +
+ + + + + + + + + + +
+ + + + + + + + + + + + + + + + +
+ +
+
+ + + + + + + + + + + \ No newline at end of file diff --git a/demo/logo.png b/demo/logo.png new file mode 100644 index 00000000..58df6062 Binary files /dev/null and b/demo/logo.png differ diff --git a/demo/require.js b/demo/require.js new file mode 100644 index 00000000..739a12a3 --- /dev/null +++ b/demo/require.js @@ -0,0 +1,2397 @@ +/** vim: et:ts=4:sw=4:sts=4 + * @license RequireJS Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved. + * Available via the MIT, GPL or new BSD license. + * see: http://github.com/jrburke/requirejs for details + */ +//laxbreak is true to allow build pragmas to change some statements. +/*jslint plusplus: false, nomen: false, laxbreak: true, regexp: false */ +/*global window: false, document: false, navigator: false, +setTimeout: false, traceDeps: true, clearInterval: false, self: false, +setInterval: false, importScripts: false */ + + +var require; +(function () { + //Change this version number for each release. + var version = "0.14.2", + empty = {}, s, + i, defContextName = "_", contextLoads = [], + scripts, script, rePkg, src, m, dataMain, cfg = {}, setReadyState, + readyRegExp = /^(complete|loaded)$/, + commentRegExp = /(\/\*([\s\S]*?)\*\/|\/\/(.*)$)/mg, + cjsRequireRegExp = /require\(["']([\w-_\.\/]+)["']\)/g, + main, + isBrowser = !!(typeof window !== "undefined" && navigator && document), + isWebWorker = !isBrowser && typeof importScripts !== "undefined", + ostring = Object.prototype.toString, + ap = Array.prototype, + aps = ap.slice, scrollIntervalId, req, baseElement, + defQueue = [], useInteractive = false, currentlyAddingScript; + + function isFunction(it) { + return ostring.call(it) === "[object Function]"; + } + + //Check for an existing version of require. If so, then exit out. Only allow + //one version of require to be active in a page. However, allow for a require + //config object, just exit quickly if require is an actual function. + if (typeof require !== "undefined") { + if (isFunction(require)) { + return; + } else { + //assume it is a config object. + cfg = require; + } + } + + /** + * Calls a method on a plugin. The obj object should have two property, + * name: the name of the method to call on the plugin + * args: the arguments to pass to the plugin method. + */ + function callPlugin(prefix, context, obj) { + //Call the plugin, or load it. + var plugin = s.plugins.defined[prefix], waiting; + if (plugin) { + plugin[obj.name].apply(null, obj.args); + } else { + //Put the call in the waiting call BEFORE requiring the module, + //since the require could be synchronous in some environments, + //like builds + waiting = s.plugins.waiting[prefix] || (s.plugins.waiting[prefix] = []); + waiting.push(obj); + + //Load the module + req(["require/" + prefix], context.contextName); + } + } + + /** + * Convenience method to call main for a require.def call that was put on + * hold in the defQueue. + */ + function callDefMain(args, context) { + main.apply(req, args); + //Mark the module loaded. Must do it here in addition + //to doing it in require.def in case a script does + //not call require.def + context.loaded[args[0]] = true; + } + + /** + * Used to set up package paths from a packagePaths or packages config object. + * @param {Object} packages the object to store the new package config + * @param {Array} currentPackages an array of packages to configure + * @param {String} [dir] a prefix dir to use. + */ + function configurePackageDir(packages, currentPackages, dir) { + var i, location, pkgObj; + for (i = 0; (pkgObj = currentPackages[i]); i++) { + pkgObj = typeof pkgObj === "string" ? { name: pkgObj } : pkgObj; + location = pkgObj.location; + + //Add dir to the path, but avoid paths that start with a slash + //or have a colon (indicates a protocol) + if (dir && (!location || (location.indexOf("/") !== 0 && location.indexOf(":") === -1))) { + pkgObj.location = dir + "/" + (pkgObj.location || pkgObj.name); + } + + //Normalize package paths. + pkgObj.location = pkgObj.location || pkgObj.name; + pkgObj.lib = pkgObj.lib || "lib"; + pkgObj.main = pkgObj.main || "main"; + + packages[pkgObj.name] = pkgObj; + } + } + + /** + * Resumes tracing of dependencies and then checks if everything is loaded. + */ + function resume(context) { + var args, i, paused = s.paused; + if (context.scriptCount <= 0) { + //Synchronous envs will push the number below zero with the + //decrement above, be sure to set it back to zero for good measure. + //require() calls that also do not end up loading scripts could + //push the number negative too. + context.scriptCount = 0; + + //Make sure any remaining defQueue items get properly processed. + while (defQueue.length) { + args = defQueue.shift(); + if (args[0] === null) { + req.onError(new Error('Mismatched anonymous require.def modules')); + } else { + callDefMain(args, context); + } + } + + //Skip the resume if current context is in priority wait. + if (s.contexts[s.ctxName].config.priorityWait) { + return; + } + + if (paused.length) { + for (i = 0; (args = paused[i]); i++) { + req.checkDeps.apply(req, args); + } + } + + req.checkLoaded(s.ctxName); + } + } + + /** + * Main entry point. + * + * If the only argument to require is a string, then the module that + * is represented by that string is fetched for the appropriate context. + * + * If the first argument is an array, then it will be treated as an array + * of dependency string names to fetch. An optional function callback can + * be specified to execute when all of those dependencies are available. + */ + require = function (deps, callback, contextName, relModuleName) { + var context, config; + if (typeof deps === "string" && !isFunction(callback)) { + //Just return the module wanted. In this scenario, the + //second arg (if passed) is just the contextName. + return require.get(deps, callback, contextName, relModuleName); + } + // Dependencies first + if (!require.isArray(deps)) { + // deps is a config object + config = deps; + if (require.isArray(callback)) { + // Adjust args if there are dependencies + deps = callback; + callback = contextName; + contextName = arguments[3]; + } else { + deps = []; + } + } + main(null, deps, callback, config, contextName); + + //If the require call does not trigger anything new to load, + //then resume the dependency processing. Context will be undefined + //on first run of require. + context = s.contexts[(contextName || (config && config.context) || s.ctxName)]; + if (context && context.scriptCount === 0) { + resume(context); + } + //Returning undefined for Spidermonky strict checking in Komodo + return undefined; + }; + + //Alias for caja compliance internally - + //specifically: "Dynamically computed names should use require.async()" + //even though this spec isn't really decided on. + //Since it is here, use this alias to make typing shorter. + req = require; + + /** + * Any errors that require explicitly generates will be passed to this + * function. Intercept/override it if you want custom error handling. + * If you do override it, this method should *always* throw an error + * to stop the execution flow correctly. Otherwise, other weird errors + * will occur. + * @param {Error} err the error object. + */ + req.onError = function (err) { + throw err; + }; + + /** + * The function that handles definitions of modules. Differs from + * require() in that a string for the module should be the first argument, + * and the function to execute after dependencies are loaded should + * return a value to define the module corresponding to the first argument's + * name. + */ + req.def = function (name, deps, callback, contextName) { + var i, scripts, script, node = currentlyAddingScript; + + //Allow for anonymous functions + if (typeof name !== 'string') { + //Adjust args appropriately + contextName = callback; + callback = deps; + deps = name; + name = null; + } + + //This module may not have dependencies + if (!req.isArray(deps)) { + contextName = callback; + callback = deps; + deps = []; + } + + //If no name, and callback is a function, then figure out if it a + //CommonJS thing with dependencies. + if (!name && !deps.length && req.isFunction(callback)) { + //Remove comments from the callback string, + //look for require calls, and pull them into the dependencies. + callback + .toString() + .replace(commentRegExp, "") + .replace(cjsRequireRegExp, function (match, dep) { + deps.push(dep); + }); + + //May be a CommonJS thing even without require calls, but still + //could use exports, and such, so always add those as dependencies. + //This is a bit wasteful for RequireJS modules that do not need + //an exports or module object, but erring on side of safety. + //REQUIRES the function to expect the CommonJS variables in the + //order listed below. + deps = ["require", "exports", "module"].concat(deps); + } + + //If in IE 6-8 and hit an anonymous require.def call, do the interactive/ + //currentlyAddingScript scripts stuff. + if (!name && useInteractive) { + scripts = document.getElementsByTagName('script'); + for (i = scripts.length - 1; i > -1 && (script = scripts[i]); i--) { + if (script.readyState === 'interactive') { + node = script; + break; + } + } + if (!node) { + req.onError(new Error("ERROR: No matching script interactive for " + callback)); + } + + name = node.getAttribute("data-requiremodule"); + } + + //Always save off evaluating the def call until the script onload handler. + //This allows multiple modules to be in a file without prematurely + //tracing dependencies, and allows for anonymous module support, + //where the module name is not known until the script onload event + //occurs. + defQueue.push([name, deps, callback, null, contextName]); + }; + + main = function (name, deps, callback, config, contextName) { + //Grab the context, or create a new one for the given context name. + var context, newContext, loaded, pluginPrefix, + canSetContext, prop, newLength, outDeps, mods, paths, index, i, + deferMods, deferModArgs, lastModArg, waitingName, packages, + packagePaths; + + contextName = contextName ? contextName : (config && config.context ? config.context : s.ctxName); + context = s.contexts[contextName]; + + if (name) { + // Pull off any plugin prefix. + index = name.indexOf("!"); + if (index !== -1) { + pluginPrefix = name.substring(0, index); + name = name.substring(index + 1, name.length); + } else { + //Could be that the plugin name should be auto-applied. + //Used by i18n plugin to enable anonymous i18n modules, but + //still associating the auto-generated name with the i18n plugin. + pluginPrefix = context.defPlugin[name]; + } + + + //If module already defined for context, or already waiting to be + //evaluated, leave. + waitingName = context.waiting[name]; + if (context && (context.defined[name] || (waitingName && waitingName !== ap[name]))) { + return; + } + } + + if (contextName !== s.ctxName) { + //If nothing is waiting on being loaded in the current context, + //then switch s.ctxName to current contextName. + loaded = (s.contexts[s.ctxName] && s.contexts[s.ctxName].loaded); + canSetContext = true; + if (loaded) { + for (prop in loaded) { + if (!(prop in empty)) { + if (!loaded[prop]) { + canSetContext = false; + break; + } + } + } + } + if (canSetContext) { + s.ctxName = contextName; + } + } + + if (!context) { + newContext = { + contextName: contextName, + config: { + waitSeconds: 7, + baseUrl: s.baseUrl || "./", + paths: {}, + packages: {} + }, + waiting: [], + specified: { + "require": true, + "exports": true, + "module": true + }, + loaded: {}, + scriptCount: 0, + urlFetched: {}, + defPlugin: {}, + defined: {}, + modifiers: {} + }; + + if (s.plugins.newContext) { + s.plugins.newContext(newContext); + } + + context = s.contexts[contextName] = newContext; + } + + //If have a config object, update the context's config object with + //the config values. + if (config) { + //Make sure the baseUrl ends in a slash. + if (config.baseUrl) { + if (config.baseUrl.charAt(config.baseUrl.length - 1) !== "/") { + config.baseUrl += "/"; + } + } + + //Save off the paths and packages since they require special processing, + //they are additive. + paths = context.config.paths; + packages = context.config.packages; + + //Mix in the config values, favoring the new values over + //existing ones in context.config. + req.mixin(context.config, config, true); + + //Adjust paths if necessary. + if (config.paths) { + for (prop in config.paths) { + if (!(prop in empty)) { + paths[prop] = config.paths[prop]; + } + } + context.config.paths = paths; + } + + packagePaths = config.packagePaths; + if (packagePaths || config.packages) { + //Convert packagePaths into a packages config. + if (packagePaths) { + for (prop in packagePaths) { + if (!(prop in empty)) { + configurePackageDir(packages, packagePaths[prop], prop); + } + } + } + + //Adjust packages if necessary. + if (config.packages) { + configurePackageDir(packages, config.packages); + } + + //Done with modifications, assing packages back to context config + context.config.packages = packages; + } + + //If priority loading is in effect, trigger the loads now + if (config.priority) { + //Create a separate config property that can be + //easily tested for config priority completion. + //Do this instead of wiping out the config.priority + //in case it needs to be inspected for debug purposes later. + req(config.priority); + context.config.priorityWait = config.priority; + } + + //If a deps array or a config callback is specified, then call + //require with those args. This is useful when require is defined as a + //config object before require.js is loaded. + if (config.deps || config.callback) { + req(config.deps || [], config.callback); + } + + //Set up ready callback, if asked. Useful when require is defined as a + //config object before require.js is loaded. + if (config.ready) { + req.ready(config.ready); + } + + //If it is just a config block, nothing else, + //then return. + if (!deps) { + return; + } + } + + //Normalize dependency strings: need to determine if they have + //prefixes and to also normalize any relative paths. Replace the deps + //array of strings with an array of objects. + if (deps) { + outDeps = deps; + deps = []; + for (i = 0; i < outDeps.length; i++) { + deps[i] = req.splitPrefix(outDeps[i], name, context); + } + } + + //Store the module for later evaluation + newLength = context.waiting.push({ + name: name, + deps: deps, + callback: callback + }); + + if (name) { + //Store index of insertion for quick lookup + context.waiting[name] = newLength - 1; + + //Mark the module as specified so no need to fetch it again. + //Important to set specified here for the + //pause/resume case where there are multiple modules in a file. + context.specified[name] = true; + + //Load any modifiers for the module. + mods = context.modifiers[name]; + if (mods) { + req(mods, contextName); + deferMods = mods.__deferMods; + if (deferMods) { + for (i = 0; i < deferMods.length; i++) { + deferModArgs = deferMods[i]; + + //Add the context name to the def call. + lastModArg = deferModArgs[deferModArgs.length - 1]; + if (lastModArg === undefined) { + deferModArgs[deferModArgs.length - 1] = contextName; + } else if (typeof lastModArg === "string") { + deferMods.push(contextName); + } + + require.def.apply(require, deferModArgs); + } + } + } + } + + //If the callback is not an actual function, it means it already + //has the definition of the module as a literal value. + if (name && callback && !req.isFunction(callback)) { + context.defined[name] = callback; + } + + //If a pluginPrefix is available, call the plugin, or load it. + if (pluginPrefix) { + callPlugin(pluginPrefix, context, { + name: "require", + args: [name, deps, callback, context] + }); + } + + //Hold on to the module until a script load or other adapter has finished + //evaluating the whole file. This helps when a file has more than one + //module in it -- dependencies are not traced and fetched until the whole + //file is processed. + s.paused.push([pluginPrefix, name, deps, context]); + + //Set loaded here for modules that are also loaded + //as part of a layer, where onScriptLoad is not fired + //for those cases. Do this after the inline define and + //dependency tracing is done. + if (name) { + context.loaded[name] = true; + } + }; + + /** + * Simple function to mix in properties from source into target, + * but only if target does not already have a property of the same name. + */ + req.mixin = function (target, source, force) { + for (var prop in source) { + if (!(prop in empty) && (!(prop in target) || force)) { + target[prop] = source[prop]; + } + } + return req; + }; + + req.version = version; + + //Set up page state. + s = req.s = { + ctxName: defContextName, + contexts: {}, + paused: [], + plugins: { + defined: {}, + callbacks: {}, + waiting: {} + }, + //Stores a list of URLs that should not get async script tag treatment. + skipAsync: {}, + isBrowser: isBrowser, + isPageLoaded: !isBrowser, + readyCalls: [], + doc: isBrowser ? document : null + }; + + req.isBrowser = s.isBrowser; + if (isBrowser) { + s.head = document.getElementsByTagName("head")[0]; + //If BASE tag is in play, using appendChild is a problem for IE6. + //When that browser dies, this can be removed. Details in this jQuery bug: + //http://dev.jquery.com/ticket/2709 + baseElement = document.getElementsByTagName("base")[0]; + if (baseElement) { + s.head = baseElement.parentNode; + } + } + + /** + * Sets up a plugin callback name. Want to make it easy to test if a plugin + * needs to be called for a certain lifecycle event by testing for + * if (s.plugins.onLifeCyleEvent) so only define the lifecycle event + * if there is a real plugin that registers for it. + */ + function makePluginCallback(name, returnOnTrue) { + var cbs = s.plugins.callbacks[name] = []; + s.plugins[name] = function () { + for (var i = 0, cb; (cb = cbs[i]); i++) { + if (cb.apply(null, arguments) === true && returnOnTrue) { + return true; + } + } + return false; + }; + } + + /** + * Registers a new plugin for require. + */ + req.plugin = function (obj) { + var i, prop, call, prefix = obj.prefix, cbs = s.plugins.callbacks, + waiting = s.plugins.waiting[prefix], generics, + defined = s.plugins.defined, contexts = s.contexts, context; + + //Do not allow redefinition of a plugin, there may be internal + //state in the plugin that could be lost. + if (defined[prefix]) { + return req; + } + + //Save the plugin. + defined[prefix] = obj; + + //Set up plugin callbacks for methods that need to be generic to + //require, for lifecycle cases where it does not care about a particular + //plugin, but just that some plugin work needs to be done. + generics = ["newContext", "isWaiting", "orderDeps"]; + for (i = 0; (prop = generics[i]); i++) { + if (!s.plugins[prop]) { + makePluginCallback(prop, prop === "isWaiting"); + } + cbs[prop].push(obj[prop]); + } + + //Call newContext for any contexts that were already created. + if (obj.newContext) { + for (prop in contexts) { + if (!(prop in empty)) { + context = contexts[prop]; + obj.newContext(context); + } + } + } + + //If there are waiting requests for a plugin, execute them now. + if (waiting) { + for (i = 0; (call = waiting[i]); i++) { + if (obj[call.name]) { + obj[call.name].apply(null, call.args); + } + } + delete s.plugins.waiting[prefix]; + } + + return req; + }; + + /** + * Internal method used by environment adapters to complete a load event. + * A load event could be a script load or just a load pass from a synchronous + * load call. + * @param {String} moduleName the name of the module to potentially complete. + * @param {Object} context the context object + */ + req.completeLoad = function (moduleName, context) { + //If there is a waiting require.def call + var args; + while (defQueue.length) { + args = defQueue.shift(); + if (args[0] === null) { + args[0] = moduleName; + break; + } else if (args[0] === moduleName) { + //Found matching require.def call for this script! + break; + } else { + //Some other named require.def call, most likely the result + //of a build layer that included many require.def calls. + callDefMain(args, context); + } + } + if (args) { + callDefMain(args, context); + } + + //Mark the script as loaded. Note that this can be different from a + //moduleName that maps to a require.def call. This line is important + //for traditional browser scripts. + context.loaded[moduleName] = true; + + context.scriptCount -= 1; + resume(context); + }; + + /** + * Legacy function, remove at some point + */ + req.pause = req.resume = function () {}; + + /** + * Trace down the dependencies to see if they are loaded. If not, trigger + * the load. + * @param {String} pluginPrefix the plugin prefix, if any associated with the name. + * + * @param {String} name: the name of the module that has the dependencies. + * + * @param {Array} deps array of dependencies. + * + * @param {Object} context: the loading context. + * + * @private + */ + req.checkDeps = function (pluginPrefix, name, deps, context) { + //Figure out if all the modules are loaded. If the module is not + //being loaded or already loaded, add it to the "to load" list, + //and request it to be loaded. + var i, dep; + + if (pluginPrefix) { + callPlugin(pluginPrefix, context, { + name: "checkDeps", + args: [name, deps, context] + }); + } else { + for (i = 0; (dep = deps[i]); i++) { + if (!context.specified[dep.fullName]) { + context.specified[dep.fullName] = true; + + //Reset the start time to use for timeouts + context.startTime = (new Date()).getTime(); + + //If a plugin, call its load method. + if (dep.prefix) { + callPlugin(dep.prefix, context, { + name: "load", + args: [dep.name, context.contextName] + }); + } else { + req.load(dep.name, context.contextName); + } + } + } + } + }; + + /** + * Register a module that modifies another module. The modifier will + * only be called once the target module has been loaded. + * + * First syntax: + * + * require.modify({ + * "some/target1": "my/modifier1", + * "some/target2": "my/modifier2", + * }); + * + * With this syntax, the my/modifier1 will only be loaded when + * "some/target1" is loaded. + * + * Second syntax, defining a modifier. + * + * require.modify("some/target1", "my/modifier", + * ["some/target1", "some/other"], + * function (target, other) { + * //Modify properties of target here. + * Only properties of target can be modified, but + * target cannot be replaced. + * } + * ); + */ + req.modify = function (target, name, deps, callback, contextName) { + var prop, modifier, list, + cName = (typeof target === "string" ? contextName : name) || s.ctxName, + context = s.contexts[cName], + mods = context.modifiers; + + if (typeof target === "string") { + //A modifier module. + //First store that it is a modifier. + list = mods[target] || (mods[target] = []); + if (!list[name]) { + list.push(name); + list[name] = true; + } + + //Trigger the normal module definition logic if the target + //is already in the system. + if (context.specified[target]) { + req.def(name, deps, callback, contextName); + } else { + //Hold on to the execution/dependency checks for the modifier + //until the target is fetched. + (list.__deferMods || (list.__deferMods = [])).push([name, deps, callback, contextName]); + } + } else { + //A list of modifiers. Save them for future reference. + for (prop in target) { + if (!(prop in empty)) { + //Store the modifier for future use. + modifier = target[prop]; + list = mods[prop] || (context.modifiers[prop] = []); + if (!list[modifier]) { + list.push(modifier); + list[modifier] = true; + + if (context.specified[prop]) { + //Load the modifier right away. + req([modifier], cName); + } + } + } + } + } + }; + + req.isArray = function (it) { + return ostring.call(it) === "[object Array]"; + }; + + req.isFunction = isFunction; + + /** + * Gets one module's exported value. This method is used by require(). + * It is broken out as a separate function to allow a host environment + * shim to overwrite this function with something appropriate for that + * environment. + * + * @param {String} moduleName the name of the module. + * @param {String} [contextName] the name of the context to use. Uses + * default context if no contextName is provided. You should never + * pass the contextName explicitly -- it is handled by the require() code. + * @param {String} [relModuleName] a module name to use for relative + * module name lookups. You should never pass this argument explicitly -- + * it is handled by the require() code. + * + * @returns {Object} the exported module value. + */ + req.get = function (moduleName, contextName, relModuleName) { + if (moduleName === "require" || moduleName === "exports" || moduleName === "module") { + req.onError(new Error("Explicit require of " + moduleName + " is not allowed.")); + } + contextName = contextName || s.ctxName; + + var ret, context = s.contexts[contextName]; + + //Normalize module name, if it contains . or .. + moduleName = req.normalizeName(moduleName, relModuleName, context); + + ret = context.defined[moduleName]; + if (ret === undefined) { + req.onError(new Error("require: module name '" + + moduleName + + "' has not been loaded yet for context: " + + contextName)); + } + return ret; + }; + + /** + * Makes the request to load a module. May be an async load depending on + * the environment and the circumstance of the load call. Override this + * method in a host environment shim to do something specific for that + * environment. + * + * @param {String} moduleName the name of the module. + * @param {String} contextName the name of the context to use. + */ + req.load = function (moduleName, contextName) { + var context = s.contexts[contextName], + urlFetched = context.urlFetched, + loaded = context.loaded, url; + s.isDone = false; + + //Only set loaded to false for tracking if it has not already been set. + if (!loaded[moduleName]) { + loaded[moduleName] = false; + } + + if (contextName !== s.ctxName) { + //Not in the right context now, hold on to it until + //the current context finishes all its loading. + contextLoads.push(arguments); + } else { + //First derive the path name for the module. + url = req.nameToUrl(moduleName, null, contextName); + if (!urlFetched[url]) { + context.scriptCount += 1; + req.attach(url, contextName, moduleName); + urlFetched[url] = true; + } + } + }; + + req.jsExtRegExp = /\.js$/; + + + /** + * Given a relative module name, like ./something, normalize it to + * a real name that can be mapped to a path. + * @param {String} name the relative name + * @param {String} baseName a real name that the name arg is relative + * to. + * @param {Object} context + * @returns {String} normalized name + */ + req.normalizeName = function (name, baseName, context) { + //Adjust any relative paths. + var part; + if (name.charAt(0) === ".") { + if (!baseName) { + req.onError(new Error("Cannot normalize module name: " + + name + + ", no relative module name available.")); + } + + if (context.config.packages[baseName]) { + //If the baseName is a package name, then just treat it as one + //name to concat the name with. + baseName = [baseName]; + } else { + //Convert baseName to array, and lop off the last part, + //so that . matches that "directory" and not name of the baseName's + //module. For instance, baseName of "one/two/three", maps to + //"one/two/three.js", but we want the directory, "one/two" for + //this normalization. + baseName = baseName.split("/"); + baseName = baseName.slice(0, baseName.length - 1); + } + + name = baseName.concat(name.split("/")); + for (i = 0; (part = name[i]); i++) { + if (part === ".") { + name.splice(i, 1); + i -= 1; + } else if (part === "..") { + name.splice(i - 1, 2); + i -= 2; + } + } + name = name.join("/"); + } + return name; + }; + + /** + * Splits a name into a possible plugin prefix and + * the module name. If baseName is provided it will + * also normalize the name via require.normalizeName() + * + * @param {String} name the module name + * @param {String} [baseName] base name that name is + * relative to. + * @param {Object} context + * + * @returns {Object} with properties, 'prefix' (which + * may be null), 'name' and 'fullName', which is a combination + * of the prefix (if it exists) and the name. + */ + req.splitPrefix = function (name, baseName, context) { + var index = name.indexOf("!"), prefix = null; + if (index !== -1) { + prefix = name.substring(0, index); + name = name.substring(index + 1, name.length); + } + + //Account for relative paths if there is a base name. + name = req.normalizeName(name, baseName, context); + + return { + prefix: prefix, + name: name, + fullName: prefix ? prefix + "!" + name : name + }; + }; + + /** + * Converts a module name to a file path. + */ + req.nameToUrl = function (moduleName, ext, contextName, relModuleName) { + var paths, packages, pkg, pkgPath, syms, i, parentModule, url, + context = s.contexts[contextName], + config = context.config; + + //Normalize module name if have a base relative module name to work from. + moduleName = req.normalizeName(moduleName, relModuleName, context); + + //If a colon is in the URL, it indicates a protocol is used and it is just + //an URL to a file, or if it starts with a slash or ends with .js, it is just a plain file. + //The slash is important for protocol-less URLs as well as full paths. + if (moduleName.indexOf(":") !== -1 || moduleName.charAt(0) === '/' || req.jsExtRegExp.test(moduleName)) { + //Just a plain path, not module name lookup, so just return it. + //Add extension if it is included. This is a bit wonky, only non-.js things pass + //an extension, this method probably needs to be reworked. + return moduleName + (ext ? ext : ""); + } else if (moduleName.charAt(0) === ".") { + return req.onError(new Error("require.nameToUrl does not handle relative module names (ones that start with '.' or '..')")); + } else { + //A module that needs to be converted to a path. + paths = config.paths; + packages = config.packages; + + syms = moduleName.split("/"); + //For each module name segment, see if there is a path + //registered for it. Start with most specific name + //and work up from it. + for (i = syms.length; i > 0; i--) { + parentModule = syms.slice(0, i).join("/"); + if (paths[parentModule]) { + syms.splice(0, i, paths[parentModule]); + break; + } else if ((pkg = packages[parentModule])) { + //pkg can have just a string value to the path + //or can be an object with props: + //main, lib, name, location. + pkgPath = pkg.location + '/' + pkg.lib; + //If module name is just the package name, then looking + //for the main module. + if (moduleName === pkg.name) { + pkgPath += '/' + pkg.main; + } + syms.splice(0, i, pkgPath); + break; + } + } + + //Join the path parts together, then figure out if baseUrl is needed. + url = syms.join("/") + (ext || ".js"); + return ((url.charAt(0) === '/' || url.match(/^\w+:/)) ? "" : config.baseUrl) + url; + } + }; + + /** + * Checks if all modules for a context are loaded, and if so, evaluates the + * new ones in right dependency order. + * + * @private + */ + req.checkLoaded = function (contextName) { + var context = s.contexts[contextName || s.ctxName], + waitInterval = context.config.waitSeconds * 1000, + //It is possible to disable the wait interval by using waitSeconds of 0. + expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), + loaded, defined = context.defined, + modifiers = context.modifiers, waiting, noLoads = "", + hasLoadedProp = false, stillLoading = false, prop, priorityDone, + priorityName, + + pIsWaiting = s.plugins.isWaiting, pOrderDeps = s.plugins.orderDeps, + + i, module, allDone, loads, loadArgs, err; + + //If already doing a checkLoaded call, + //then do not bother checking loaded state. + if (context.isCheckLoaded) { + return; + } + + //Determine if priority loading is done. If so clear the priority. If + //not, then do not check + if (context.config.priorityWait) { + priorityDone = true; + for (i = 0; (priorityName = context.config.priorityWait[i]); i++) { + if (!context.loaded[priorityName]) { + priorityDone = false; + break; + } + } + if (priorityDone) { + //Clean up priority and call resume, since it could have + //some waiting dependencies to trace. + delete context.config.priorityWait; + resume(context); + } else { + return; + } + } + + //Signal that checkLoaded is being require, so other calls that could be triggered + //by calling a waiting callback that then calls require and then this function + //should not proceed. At the end of this function, if there are still things + //waiting, then checkLoaded will be called again. + context.isCheckLoaded = true; + + //Grab waiting and loaded lists here, since it could have changed since + //this function was first called. + waiting = context.waiting; + loaded = context.loaded; + + //See if anything is still in flight. + for (prop in loaded) { + if (!(prop in empty)) { + hasLoadedProp = true; + if (!loaded[prop]) { + if (expired) { + noLoads += prop + " "; + } else { + stillLoading = true; + break; + } + } + } + } + + //Check for exit conditions. + if (!hasLoadedProp && !waiting.length + && (!pIsWaiting || !pIsWaiting(context)) + ) { + //If the loaded object had no items, then the rest of + //the work below does not need to be done. + context.isCheckLoaded = false; + return; + } + if (expired && noLoads) { + //If wait time expired, throw error of unloaded modules. + err = new Error("require.js load timeout for modules: " + noLoads); + err.requireType = "timeout"; + err.requireModules = noLoads; + req.onError(err); + } + if (stillLoading) { + //Something is still waiting to load. Wait for it. + context.isCheckLoaded = false; + if (isBrowser || isWebWorker) { + setTimeout(function () { + req.checkLoaded(contextName); + }, 50); + } + return; + } + + //Order the dependencies. Also clean up state because the evaluation + //of modules might create new loading tasks, so need to reset. + //Be sure to call plugins too. + context.waiting = []; + context.loaded = {}; + + //Call plugins to order their dependencies, do their + //module definitions. + if (pOrderDeps) { + pOrderDeps(context); + } + + //Before defining the modules, give priority treatment to any modifiers + //for modules that are already defined. + for (prop in modifiers) { + if (!(prop in empty)) { + if (defined[prop]) { + req.execModifiers(prop, {}, waiting, context); + } + } + } + + //Define the modules, doing a depth first search. + for (i = 0; (module = waiting[i]); i++) { + req.exec(module, {}, waiting, context); + } + + //Indicate checkLoaded is now done. + context.isCheckLoaded = false; + + if (context.waiting.length + || (pIsWaiting && pIsWaiting(context)) + ) { + //More things in this context are waiting to load. They were probably + //added while doing the work above in checkLoaded, calling module + //callbacks that triggered other require calls. + req.checkLoaded(contextName); + } else if (contextLoads.length) { + //Check for other contexts that need to load things. + //First, make sure current context has no more things to + //load. After defining the modules above, new require calls + //could have been made. + loaded = context.loaded; + allDone = true; + for (prop in loaded) { + if (!(prop in empty)) { + if (!loaded[prop]) { + allDone = false; + break; + } + } + } + + if (allDone) { + s.ctxName = contextLoads[0][1]; + loads = contextLoads; + //Reset contextLoads in case some of the waiting loads + //are for yet another context. + contextLoads = []; + for (i = 0; (loadArgs = loads[i]); i++) { + req.load.apply(req, loadArgs); + } + } + } else { + //Make sure we reset to default context. + s.ctxName = defContextName; + s.isDone = true; + if (req.callReady) { + req.callReady(); + } + } + }; + + /** + * Helper function that creates a setExports function for a "module" + * CommonJS dependency. Do this here to avoid creating a closure that + * is part of a loop in require.exec. + */ + function makeSetExports(moduleObj) { + return function (exports) { + moduleObj.exports = exports; + }; + } + + function makeContextModuleFunc(name, contextName, moduleName) { + return function () { + //A version of a require function that forces a contextName value + //and also passes a moduleName value for items that may need to + //look up paths relative to the moduleName + var args = [].concat(aps.call(arguments, 0)); + args.push(contextName, moduleName); + return (name ? require[name] : require).apply(null, args); + }; + } + + /** + * Helper function that creates a require function object to give to + * modules that ask for it as a dependency. It needs to be specific + * per module because of the implication of path mappings that may + * need to be relative to the module name. + */ + function makeRequire(context, moduleName) { + var contextName = context.contextName, + modRequire = makeContextModuleFunc(null, contextName, moduleName); + + req.mixin(modRequire, { + modify: makeContextModuleFunc("modify", contextName, moduleName), + def: makeContextModuleFunc("def", contextName, moduleName), + get: makeContextModuleFunc("get", contextName, moduleName), + nameToUrl: makeContextModuleFunc("nameToUrl", contextName, moduleName), + ready: req.ready, + context: context, + config: context.config, + isBrowser: s.isBrowser + }); + return modRequire; + } + + /** + * Executes the modules in the correct order. + * + * @private + */ + req.exec = function (module, traced, waiting, context) { + //Some modules are just plain script files, abddo not have a formal + //module definition, + if (!module) { + //Returning undefined for Spidermonky strict checking in Komodo + return undefined; + } + + var name = module.name, cb = module.callback, deps = module.deps, j, dep, + defined = context.defined, ret, args = [], depModule, cjsModule, + usingExports = false, depName; + + //If already traced or defined, do not bother a second time. + if (name) { + if (traced[name] || name in defined) { + return defined[name]; + } + + //Mark this module as being traced, so that it is not retraced (as in a circular + //dependency) + traced[name] = true; + } + + if (deps) { + for (j = 0; (dep = deps[j]); j++) { + depName = dep.name; + if (depName === "require") { + depModule = makeRequire(context, name); + } else if (depName === "exports") { + //CommonJS module spec 1.1 + depModule = defined[name] = {}; + usingExports = true; + } else if (depName === "module") { + //CommonJS module spec 1.1 + cjsModule = depModule = { + id: name, + uri: name ? req.nameToUrl(name, null, context.contextName) : undefined + }; + cjsModule.setExports = makeSetExports(cjsModule); + } else { + //Get dependent module. It could not exist, for a circular + //dependency or if the loaded dependency does not actually call + //require. Favor not throwing an error here if undefined because + //we want to allow code that does not use require as a module + //definition framework to still work -- allow a web site to + //gradually update to contained modules. That is more + //important than forcing a throw for the circular dependency case. + depModule = depName in defined ? defined[depName] : (traced[depName] ? undefined : req.exec(waiting[waiting[depName]], traced, waiting, context)); + } + + args.push(depModule); + } + } + + //Call the callback to define the module, if necessary. + cb = module.callback; + if (cb && req.isFunction(cb)) { + ret = req.execCb(name, cb, args); + if (name) { + //If using exports and the function did not return a value, + //and the "module" object for this definition function did not + //define an exported value, then use the exports object. + if (usingExports && ret === undefined && (!cjsModule || !("exports" in cjsModule))) { + ret = defined[name]; + } else { + if (cjsModule && "exports" in cjsModule) { + ret = defined[name] = cjsModule.exports; + } else { + if (name in defined && !usingExports) { + req.onError(new Error(name + " has already been defined")); + } + defined[name] = ret; + } + } + } + } + + //Execute modifiers, if they exist. + req.execModifiers(name, traced, waiting, context); + + return ret; + }; + + /** + * Executes a module callack function. Broken out as a separate function + * solely to allow the build system to sequence the files in the built + * layer in the right sequence. + * @param {String} name the module name. + * @param {Function} cb the module callback/definition function. + * @param {Array} args The arguments (dependent modules) to pass to callback. + * + * @private + */ + req.execCb = function (name, cb, args) { + return cb.apply(null, args); + }; + + /** + * Executes modifiers for the given module name. + * @param {String} target + * @param {Object} traced + * @param {Object} context + * + * @private + */ + req.execModifiers = function (target, traced, waiting, context) { + var modifiers = context.modifiers, mods = modifiers[target], mod, i; + if (mods) { + for (i = 0; i < mods.length; i++) { + mod = mods[i]; + //Not all modifiers define a module, they might collect other modules. + //If it is just a collection it will not be in waiting. + if (mod in waiting) { + req.exec(waiting[waiting[mod]], traced, waiting, context); + } + } + delete modifiers[target]; + } + }; + + /** + * callback for script loads, used to check status of loading. + * + * @param {Event} evt the event from the browser for the script + * that was loaded. + * + * @private + */ + req.onScriptLoad = function (evt) { + //Using currentTarget instead of target for Firefox 2.0's sake. Not + //all old browsers will be supported, but this one was easy enough + //to support and still makes sense. + var node = evt.currentTarget || evt.srcElement, contextName, moduleName, + context; + if (evt.type === "load" || readyRegExp.test(node.readyState)) { + //Pull out the name of the module and the context. + contextName = node.getAttribute("data-requirecontext"); + moduleName = node.getAttribute("data-requiremodule"); + context = s.contexts[contextName]; + + req.completeLoad(moduleName, context); + + //Clean up script binding. + if (node.removeEventListener) { + node.removeEventListener("load", req.onScriptLoad, false); + } else { + //Probably IE. If not it will throw an error, which will be + //useful to know. + node.detachEvent("onreadystatechange", req.onScriptLoad); + } + } + }; + + /** + * Attaches the script represented by the URL to the current + * environment. Right now only supports browser loading, + * but can be redefined in other environments to do the right thing. + * @param {String} url the url of the script to attach. + * @param {String} contextName the name of the context that wants the script. + * @param {moduleName} the name of the module that is associated with the script. + * @param {Function} [callback] optional callback, defaults to require.onScriptLoad + * @param {String} [type] optional type, defaults to text/javascript + */ + req.attach = function (url, contextName, moduleName, callback, type) { + var node, loaded, context; + if (isBrowser) { + //In the browser so use a script tag + callback = callback || req.onScriptLoad; + node = document.createElement("script"); + node.type = type || "text/javascript"; + node.charset = "utf-8"; + //Use async so Gecko does not block on executing the script if something + //like a long-polling comet tag is being run first. Gecko likes + //to evaluate scripts in DOM order, even for dynamic scripts. + //It will fetch them async, but only evaluate the contents in DOM + //order, so a long-polling script tag can delay execution of scripts + //after it. But telling Gecko we expect async gets us the behavior + //we want -- execute it whenever it is finished downloading. Only + //Helps Firefox 3.6+ + //Allow some URLs to not be fetched async. Mostly helps the order! + //plugin + if (!s.skipAsync[url]) { + node.async = true; + } + node.setAttribute("data-requirecontext", contextName); + node.setAttribute("data-requiremodule", moduleName); + + //Set up load listener. + if (node.addEventListener) { + node.addEventListener("load", callback, false); + } else { + //Probably IE. If not it will throw an error, which will be + //useful to know. IE (at least 6-8) do not fire + //script onload right after executing the script, so + //we cannot tie the anonymous require.def call to a name. + //However, IE reports the script as being in "interactive" + //readyState at the time of the require.def call. + useInteractive = true; + node.attachEvent("onreadystatechange", callback); + } + node.src = url; + + //For some cache cases in IE 6-8, the script executes before the end + //of the appendChild execution, so to tie an anonymous require.def + //call to the module name (which is stored on the node), hold on + //to a reference to this node, but clear after the DOM insertion. + currentlyAddingScript = node; + if (baseElement) { + s.head.insertBefore(node, baseElement); + } else { + s.head.appendChild(node); + } + currentlyAddingScript = null; + return node; + } else if (isWebWorker) { + //In a web worker, use importScripts. This is not a very + //efficient use of importScripts, importScripts will block until + //its script is downloaded and evaluated. However, if web workers + //are in play, the expectation that a build has been done so that + //only one script needs to be loaded anyway. This may need to be + //reevaluated if other use cases become common. + context = s.contexts[contextName]; + loaded = context.loaded; + loaded[moduleName] = false; + importScripts(url); + + //Account for anonymous modules + req.completeLoad(moduleName, context); + } + return null; + }; + + //Determine what baseUrl should be if not already defined via a require config object + s.baseUrl = cfg.baseUrl; + if (isBrowser && (!s.baseUrl || !s.head)) { + //Figure out baseUrl. Get it from the script tag with require.js in it. + scripts = document.getElementsByTagName("script"); + if (cfg.baseUrlMatch) { + rePkg = cfg.baseUrlMatch; + } else { + + + + rePkg = /(allplugins-|transportD-)?require\.js(\W|$)/i; + + } + + for (i = scripts.length - 1; i > -1 && (script = scripts[i]); i--) { + //Set the "head" where we can append children by + //using the script's parent. + if (!s.head) { + s.head = script.parentNode; + } + + //Look for a data-main attribute to set main script for the page + //to load. + if (!cfg.deps) { + dataMain = script.getAttribute('data-main'); + if (dataMain) { + cfg.deps = [dataMain]; + } + } + + //Using .src instead of getAttribute to get an absolute URL. + //While using a relative URL will be fine for script tags, other + //URLs used for text! resources that use XHR calls might benefit + //from an absolute URL. + src = script.src; + if (src && !s.baseUrl) { + m = src.match(rePkg); + if (m) { + s.baseUrl = src.substring(0, m.index); + break; + } + } + } + } + + //****** START page load functionality **************** + /** + * Sets the page as loaded and triggers check for all modules loaded. + */ + req.pageLoaded = function () { + if (!s.isPageLoaded) { + s.isPageLoaded = true; + if (scrollIntervalId) { + clearInterval(scrollIntervalId); + } + + //Part of a fix for FF < 3.6 where readyState was not set to + //complete so libraries like jQuery that check for readyState + //after page load where not getting initialized correctly. + //Original approach suggested by Andrea Giammarchi: + //http://webreflection.blogspot.com/2009/11/195-chars-to-help-lazy-loading.html + //see other setReadyState reference for the rest of the fix. + if (setReadyState) { + document.readyState = "complete"; + } + + req.callReady(); + } + }; + + /** + * Internal function that calls back any ready functions. If you are + * integrating RequireJS with another library without require.ready support, + * you can define this method to call your page ready code instead. + */ + req.callReady = function () { + var callbacks = s.readyCalls, i, callback; + + if (s.isPageLoaded && s.isDone && callbacks.length) { + s.readyCalls = []; + for (i = 0; (callback = callbacks[i]); i++) { + callback(); + } + } + }; + + /** + * Registers functions to call when the page is loaded + */ + req.ready = function (callback) { + if (s.isPageLoaded && s.isDone) { + callback(); + } else { + s.readyCalls.push(callback); + } + return req; + }; + + if (isBrowser) { + if (document.addEventListener) { + //Standards. Hooray! Assumption here that if standards based, + //it knows about DOMContentLoaded. + document.addEventListener("DOMContentLoaded", req.pageLoaded, false); + window.addEventListener("load", req.pageLoaded, false); + //Part of FF < 3.6 readystate fix (see setReadyState refs for more info) + if (!document.readyState) { + setReadyState = true; + document.readyState = "loading"; + } + } else if (window.attachEvent) { + window.attachEvent("onload", req.pageLoaded); + + //DOMContentLoaded approximation, as found by Diego Perini: + //http://javascript.nwbox.com/IEContentLoaded/ + if (self === self.top) { + scrollIntervalId = setInterval(function () { + try { + //From this ticket: + //http://bugs.dojotoolkit.org/ticket/11106, + //In IE HTML Application (HTA), such as in a selenium test, + //javascript in the iframe can't see anything outside + //of it, so self===self.top is true, but the iframe is + //not the top window and doScroll will be available + //before document.body is set. Test document.body + //before trying the doScroll trick. + if (document.body) { + document.documentElement.doScroll("left"); + req.pageLoaded(); + } + } catch (e) {} + }, 30); + } + } + + //Check if document already complete, and if so, just trigger page load + //listeners. NOTE: does not work with Firefox before 3.6. To support + //those browsers, manually call require.pageLoaded(). + if (document.readyState === "complete") { + req.pageLoaded(); + } + } + //****** END page load functionality **************** + + //Set up default context. If require was a configuration object, use that as base config. + req(cfg); + + //If modules are built into require.js, then need to make sure dependencies are + //traced. Use a setTimeout in the browser world, to allow all the modules to register + //themselves. In a non-browser env, assume that modules are not built into require.js, + //which seems odd to do on the server. + if (typeof setTimeout !== "undefined") { + setTimeout(function () { + resume(s.contexts[(cfg.context || defContextName)]); + }, 0); + } +}()); + +/** + * @license RequireJS i18n Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved. + * Available via the MIT, GPL or new BSD license. + * see: http://github.com/jrburke/requirejs for details + */ +/*jslint regexp: false, nomen: false, plusplus: false */ +/*global require: false, navigator: false */ + + +/** + * This plugin handles i18n! prefixed modules. It does the following: + * + * 1) A regular module can have a dependency on an i18n bundle, but the regular + * module does not want to specify what locale to load. So it just specifies + * the top-level bundle, like "i18n!nls/colors". + * + * This plugin will load the i18n bundle at nls/colors, see that it is a root/master + * bundle since it does not have a locale in its name. It will then try to find + * the best match locale available in that master bundle, then request all the + * locale pieces for that best match locale. For instance, if the locale is "en-us", + * then the plugin will ask for the "en-us", "en" and "root" bundles to be loaded + * (but only if they are specified on the master bundle). + * + * Once all the bundles for the locale pieces load, then it mixes in all those + * locale pieces into each other, then finally sets the context.defined value + * for the nls/colors bundle to be that mixed in locale. + * + * 2) A regular module specifies a specific locale to load. For instance, + * i18n!nls/fr-fr/colors. In this case, the plugin needs to load the master bundle + * first, at nls/colors, then figure out what the best match locale is for fr-fr, + * since maybe only fr or just root is defined for that locale. Once that best + * fit is found, all of its locale pieces need to have their bundles loaded. + * + * Once all the bundles for the locale pieces load, then it mixes in all those + * locale pieces into each other, then finally sets the context.defined value + * for the nls/fr-fr/colors bundle to be that mixed in locale. + */ +(function () { + //regexp for reconstructing the master bundle name from parts of the regexp match + //nlsRegExp.exec("foo/bar/baz/nls/en-ca/foo") gives: + //["foo/bar/baz/nls/en-ca/foo", "foo/bar/baz/nls/", "/", "/", "en-ca", "foo"] + //nlsRegExp.exec("foo/bar/baz/nls/foo") gives: + //["foo/bar/baz/nls/foo", "foo/bar/baz/nls/", "/", "/", "foo", ""] + //so, if match[5] is blank, it means this is the top bundle definition. + var nlsRegExp = /(^.*(^|\/)nls(\/|$))([^\/]*)\/?([^\/]*)/, + empty = {}; + + function getWaiting(name, context) { + var nlswAry = context.nlsWaiting; + return nlswAry[name] || + //Push a new waiting object on the nlsWaiting array, but also put + //a shortcut lookup by name to the object on the array. + (nlswAry[name] = nlswAry[(nlswAry.push({ _name: name}) - 1)]); + } + + /** + * Makes sure all the locale pieces are loaded, and finds the best match + * for the requested locale. + */ + function resolveLocale(masterName, bundle, locale, context) { + //Break apart the locale to get the parts. + var i, parts, toLoad, nlsw, loc, val, bestLoc = "root"; + + parts = locale.split("-"); + + //Now see what bundles exist for each country/locale. + //Want to walk up the chain, so if locale is en-us-foo, + //look for en-us-foo, en-us, en, then root. + toLoad = []; + + nlsw = getWaiting(masterName, context); + + for (i = parts.length; i > -1; i--) { + loc = i ? parts.slice(0, i).join("-") : "root"; + val = bundle[loc]; + if (val) { + //Store which bundle to use for the default bundle definition. + if (locale === context.config.locale && !nlsw._match) { + nlsw._match = loc; + } + + //Store the best match for the target locale + if (bestLoc === "root") { + bestLoc = loc; + } + + //Track that the locale needs to be resolved with its parts. + //Mark what locale should be used when resolving. + nlsw[loc] = loc; + + //If locale value is true, it means it is a resource that + //needs to be loaded. Track it to load if it has not already + //been asked for. + if (val === true) { + //split off the bundl name from master name and insert the + //locale before the bundle name. So, if masterName is + //some/path/nls/colors, then the locale fr-fr's bundle name should + //be some/path/nls/fr-fr/colors + val = masterName.split("/"); + val.splice(-1, 0, loc); + val = val.join("/"); + + if (!context.specified[val] && !(val in context.loaded) && !context.defined[val]) { + context.defPlugin[val] = 'i18n'; + toLoad.push(val); + } + } + } + } + + //If locale was not an exact match, store the closest match for it. + if (bestLoc !== locale) { + if (context.defined[bestLoc]) { + //Already got it. Easy peasy lemon squeezy. + context.defined[locale] = context.defined[bestLoc]; + } else { + //Need to wait for things to load then define it. + nlsw[locale] = bestLoc; + } + } + + //Load any bundles that are still needed. + if (toLoad.length) { + require(toLoad, context.contextName); + } + } + + require.plugin({ + prefix: "i18n", + + /** + * This callback is prefix-specific, only gets called for this prefix + */ + require: function (name, deps, callback, context) { + var i, match, nlsw, bundle, master, toLoad, obj = context.defined[name]; + + //All i18n modules must match the nls module name structure. + match = nlsRegExp.exec(name); + //If match[5] is blank, it means this is the top bundle definition, + //so it does not have to be handled. Only deal with ones that have a locale + //(a match[4] value but no match[5]) + if (match[5]) { + master = match[1] + match[5]; + + //Track what locale bundle need to be generated once all the modules load. + nlsw = getWaiting(master, context); + nlsw[match[4]] = match[4]; + + bundle = context.nls[master]; + if (!bundle) { + //No master bundle yet, ask for it. + context.defPlugin[master] = 'i18n'; + require([master], context.contextName); + bundle = context.nls[master] = {}; + } + //For nls modules, the callback is just a regular object, + //so save it off in the bundle now. + bundle[match[4]] = callback; + } else { + //Integrate bundle into the nls area. + bundle = context.nls[name]; + if (bundle) { + //A specific locale already started the bundle object. + //Do a mixin (which will not overwrite the locale property + //on the bundle that has the previously loaded locale's info) + require.mixin(bundle, obj); + } else { + bundle = context.nls[name] = obj; + } + context.nlsRootLoaded[name] = true; + + //Make sure there are no locales waiting to be resolved. + toLoad = context.nlsToLoad[name]; + if (toLoad) { + delete context.nlsToLoad[name]; + for (i = 0; i < toLoad.length; i++) { + resolveLocale(name, bundle, toLoad[i], context); + } + } + + resolveLocale(name, bundle, context.config.locale, context); + } + }, + + /** + * Called when a new context is defined. Use this to store + * context-specific info on it. + */ + newContext: function (context) { + require.mixin(context, { + nlsWaiting: [], + nls: {}, + nlsRootLoaded: {}, + nlsToLoad: {} + }); + if (!context.config.locale) { + context.config.locale = typeof navigator === "undefined" ? "root" : + (navigator.language || navigator.userLanguage || "root").toLowerCase(); + } + }, + + /** + * Called when a dependency needs to be loaded. + */ + load: function (name, contextName) { + //Make sure the root bundle is loaded, to check if we can support + //loading the requested locale, or if a different one needs + //to be chosen. + var masterName, context = require.s.contexts[contextName], bundle, + match = nlsRegExp.exec(name), locale = match[4]; + + //If match[5] is blank, it means this is the top bundle definition, + //so it does not have to be handled. Only deal with ones that have a locale + //(a match[4] value but no match[5]) + if (match[5]) { + //locale-specific bundle + masterName = match[1] + match[5]; + bundle = context.nls[masterName]; + if (context.nlsRootLoaded[masterName] && bundle) { + resolveLocale(masterName, bundle, locale, context); + } else { + //Store this locale to figure out after masterName is loaded and load masterName. + (context.nlsToLoad[masterName] || (context.nlsToLoad[masterName] = [])).push(locale); + context.defPlugin[masterName] = 'i18n'; + require([masterName], contextName); + } + } else { + //Top-level bundle. Just call regular load, if not already loaded + if (!context.nlsRootLoaded[name]) { + context.defPlugin[name] = 'i18n'; + require.load(name, contextName); + } + } + }, + + /** + * Called when the dependencies of a module are checked. + */ + checkDeps: function (name, deps, context) { + //i18n bundles are always defined as objects for their "dependencies", + //and that object is already processed in the require method, no need to + //do work in here. + }, + + /** + * Called to determine if a module is waiting to load. + */ + isWaiting: function (context) { + return !!context.nlsWaiting.length; + }, + + /** + * Called when all modules have been loaded. + */ + orderDeps: function (context) { + //Clear up state since further processing could + //add more things to fetch. + var i, j, master, msWaiting, bundle, parts, moduleSuffix, mixed, + modulePrefix, loc, defLoc, locPart, nlsWaiting = context.nlsWaiting, + bestFit; + context.nlsWaiting = []; + context.nlsToLoad = {}; + + //First, properly mix in any nls bundles waiting to happen. + for (i = 0; (msWaiting = nlsWaiting[i]); i++) { + //Each property is a master bundle name. + master = msWaiting._name; + bundle = context.nls[master]; + defLoc = null; + + //Create the module name parts from the master name. So, if master + //is foo/nls/bar, then the parts should be prefix: "foo/nls", + // suffix: "bar", and the final locale's module name will be foo/nls/locale/bar + parts = master.split("/"); + modulePrefix = parts.slice(0, parts.length - 1).join("/"); + moduleSuffix = parts[parts.length - 1]; + //Cycle through the locale props on the waiting object and combine + //the locales together. + for (loc in msWaiting) { + if (loc !== "_name" && !(loc in empty)) { + if (loc === "_match") { + //Found default locale to use for the top-level bundle name. + defLoc = msWaiting[loc]; + + } else if (msWaiting[loc] !== loc) { + //A "best fit" locale, store it off to the end and handle + //it at the end by just assigning the best fit value, since + //after this for loop, the best fit locale will be defined. + (bestFit || (bestFit = {}))[loc] = msWaiting[loc]; + } else { + //Mix in the properties of this locale together. + //Split the locale into pieces. + mixed = {}; + parts = loc.split("-"); + for (j = parts.length; j > 0; j--) { + locPart = parts.slice(0, j).join("-"); + if (locPart !== "root" && bundle[locPart]) { + require.mixin(mixed, bundle[locPart]); + } + } + if (bundle.root) { + require.mixin(mixed, bundle.root); + } + + context.defined[modulePrefix + "/" + loc + "/" + moduleSuffix] = mixed; + } + } + } + + //Finally define the default locale. Wait to the end of the property + //loop above so that the default locale bundle has been properly mixed + //together. + context.defined[master] = context.defined[modulePrefix + "/" + defLoc + "/" + moduleSuffix]; + + //Handle any best fit locale definitions. + if (bestFit) { + for (loc in bestFit) { + if (!(loc in empty)) { + context.defined[modulePrefix + "/" + loc + "/" + moduleSuffix] = context.defined[modulePrefix + "/" + bestFit[loc] + "/" + moduleSuffix]; + } + } + } + } + } + }); +}()); +/** + * @license RequireJS text Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved. + * Available via the MIT, GPL or new BSD license. + * see: http://github.com/jrburke/requirejs for details + */ +/*jslint regexp: false, nomen: false, plusplus: false */ +/*global require: false, XMLHttpRequest: false, ActiveXObject: false */ + + +(function () { + var progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'], + xmlRegExp = /^\s*<\?xml(\s)+version=[\'\"](\d)*.(\d)*[\'\"](\s)*\?>/im, + bodyRegExp = /]*>\s*([\s\S]+)\s*<\/body>/im; + + if (!require.textStrip) { + require.textStrip = function (text) { + //Strips declarations so that external SVG and XML + //documents can be added to a document without worry. Also, if the string + //is an HTML document, only the part inside the body tag is returned. + if (text) { + text = text.replace(xmlRegExp, ""); + var matches = text.match(bodyRegExp); + if (matches) { + text = matches[1]; + } + } else { + text = ""; + } + return text; + }; + } + + //Upgrade require to add some methods for XHR handling. But it could be that + //this require is used in a non-browser env, so detect for existing method + //before attaching one. + if (!require.getXhr) { + require.getXhr = function () { + //Would love to dump the ActiveX crap in here. Need IE 6 to die first. + var xhr, i, progId; + if (typeof XMLHttpRequest !== "undefined") { + return new XMLHttpRequest(); + } else { + for (i = 0; i < 3; i++) { + progId = progIds[i]; + try { + xhr = new ActiveXObject(progId); + } catch (e) {} + + if (xhr) { + progIds = [progId]; // so faster next time + break; + } + } + } + + if (!xhr) { + throw new Error("require.getXhr(): XMLHttpRequest not available"); + } + + return xhr; + }; + } + + if (!require.fetchText) { + require.fetchText = function (url, callback) { + var xhr = require.getXhr(); + xhr.open('GET', url, true); + xhr.onreadystatechange = function (evt) { + //Do not explicitly handle errors, those should be + //visible via console output in the browser. + if (xhr.readyState === 4) { + callback(xhr.responseText); + } + }; + xhr.send(null); + }; + } + + require.plugin({ + prefix: "text", + + /** + * This callback is prefix-specific, only gets called for this prefix + */ + require: function (name, deps, callback, context) { + //No-op, require never gets these text items, they are always + //a dependency, see load for the action. + }, + + /** + * Called when a new context is defined. Use this to store + * context-specific info on it. + */ + newContext: function (context) { + require.mixin(context, { + text: {}, + textWaiting: [] + }); + }, + + /** + * Called when a dependency needs to be loaded. + */ + load: function (name, contextName) { + //Name has format: some.module!filext!strip!text + //The strip and text parts are optional. + //if strip is present, then that means only get the string contents + //inside a body tag in an HTML string. For XML/SVG content it means + //removing the declarations so the content can be inserted + //into the current doc without problems. + //If text is present, it is the actual text of the file. + var strip = false, text = null, key, url, index = name.indexOf("."), + modName = name.substring(0, index), fullKey, + ext = name.substring(index + 1, name.length), + context = require.s.contexts[contextName], + tWaitAry = context.textWaiting; + + index = ext.indexOf("!"); + if (index !== -1) { + //Pull off the strip arg. + strip = ext.substring(index + 1, ext.length); + ext = ext.substring(0, index); + index = strip.indexOf("!"); + if (index !== -1 && strip.substring(0, index) === "strip") { + //Pull off the text. + text = strip.substring(index + 1, strip.length); + strip = "strip"; + } else if (strip !== "strip") { + //strip is actually the inlined text. + text = strip; + strip = null; + } + } + key = modName + "!" + ext; + fullKey = strip ? key + "!" + strip : key; + + //Store off text if it is available for the given key and be done. + if (text !== null && !context.text[key]) { + context.defined[name] = context.text[key] = text; + return; + } + + //If text is not available, load it. + if (!context.text[key] && !context.textWaiting[key] && !context.textWaiting[fullKey]) { + //Keep track that the fullKey needs to be resolved, during the + //orderDeps stage. + if (!tWaitAry[fullKey]) { + tWaitAry[fullKey] = tWaitAry[(tWaitAry.push({ + name: name, + key: key, + fullKey: fullKey, + strip: !!strip + }) - 1)]; + } + + //Load the text. + url = require.nameToUrl(modName, "." + ext, contextName); + context.loaded[name] = false; + require.fetchText(url, function (text) { + context.text[key] = text; + context.loaded[name] = true; + require.checkLoaded(contextName); + }); + } + }, + + /** + * Called when the dependencies of a module are checked. + */ + checkDeps: function (name, deps, context) { + //No-op, checkDeps never gets these text items, they are always + //a dependency, see load for the action. + }, + + /** + * Called to determine if a module is waiting to load. + */ + isWaiting: function (context) { + return !!context.textWaiting.length; + }, + + /** + * Called when all modules have been loaded. + */ + orderDeps: function (context) { + //Clear up state since further processing could + //add more things to fetch. + var i, dep, text, tWaitAry = context.textWaiting; + context.textWaiting = []; + for (i = 0; (dep = tWaitAry[i]); i++) { + text = context.text[dep.key]; + context.defined[dep.name] = dep.strip ? require.textStrip(text) : text; + } + } + }); +}()); +/** + * @license RequireJS jsonp Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved. + * Available via the MIT, GPL or new BSD license. + * see: http://github.com/jrburke/requirejs for details + */ +/*jslint nomen: false, plusplus: false */ +/*global require: false, setTimeout: false */ + + +(function () { + var countId = 0; + + //A place to hold callback functions + require._jsonp = {}; + + require.plugin({ + prefix: "jsonp", + + /** + * This callback is prefix-specific, only gets called for this prefix + */ + require: function (name, deps, callback, context) { + //No-op, require never gets these jsonp items, they are always + //a dependency, see load for the action. + }, + + /** + * Called when a new context is defined. Use this to store + * context-specific info on it. + */ + newContext: function (context) { + require.mixin(context, { + jsonpWaiting: [] + }); + }, + + /** + * Called when a dependency needs to be loaded. + */ + load: function (name, contextName) { + //Name has format: some/url?param1=value1&callback=? + //where the last question mark indicates where the jsonp callback + //function name needs to go. + var index = name.indexOf("?"), + url = name.substring(0, index), + params = name.substring(index + 1, name.length), + context = require.s.contexts[contextName], + data = { + name: name + }, + funcName = "f" + (countId++), + head = require.s.head, + node = head.ownerDocument.createElement("script"); + + //Create JSONP callback function + require._jsonp[funcName] = function (value) { + data.value = value; + context.loaded[name] = true; + require.checkLoaded(contextName); + //Use a setTimeout for cleanup because some older IE versions vomit + //if removing a script node while it is being evaluated. + setTimeout(function () { + head.removeChild(node); + delete require._jsonp[funcName]; + }, 15); + }; + + //Hold on to the data for later dependency resolution in orderDeps. + context.jsonpWaiting.push(data); + + //Build up the full JSONP URL + url = require.nameToUrl(url, "?", contextName); + //nameToUrl call may or may not have placed an ending ? on the URL, + //be sure there is one and add the rest of the params. + url += (url.indexOf("?") === -1 ? "?" : "") + params.replace("?", "require._jsonp." + funcName); + + context.loaded[name] = false; + node.type = "text/javascript"; + node.charset = "utf-8"; + node.src = url; + + //Use async so Gecko does not block on executing the script if something + //like a long-polling comet tag is being run first. Gecko likes + //to evaluate scripts in DOM order, even for dynamic scripts. + //It will fetch them async, but only evaluate the contents in DOM + //order, so a long-polling script tag can delay execution of scripts + //after it. But telling Gecko we expect async gets us the behavior + //we want -- execute it whenever it is finished downloading. Only + //Helps Firefox 3.6+ + node.async = true; + + head.appendChild(node); + }, + + /** + * Called when the dependencies of a module are checked. + */ + checkDeps: function (name, deps, context) { + //No-op, checkDeps never gets these jsonp items, they are always + //a dependency, see load for the action. + }, + + /** + * Called to determine if a module is waiting to load. + */ + isWaiting: function (context) { + return !!context.jsonpWaiting.length; + }, + + /** + * Called when all modules have been loaded. + */ + orderDeps: function (context) { + //Clear up state since further processing could + //add more things to fetch. + var i, dep, waitAry = context.jsonpWaiting; + context.jsonpWaiting = []; + for (i = 0; (dep = waitAry[i]); i++) { + context.defined[dep.name] = dep.value; + } + } + }); +}()); +/** + * @license RequireJS order Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved. + * Available via the MIT, GPL or new BSD license. + * see: http://github.com/jrburke/requirejs for details + */ +/*jslint nomen: false, plusplus: false */ +/*global require: false, window: false, document: false, setTimeout: false */ + + +(function () { + //Sadly necessary browser inference due to differences in the way + //that browsers load and execute dynamically inserted javascript + //and whether the script/cache method works. + //Currently, Gecko and Opera do not load/fire onload for scripts with + //type="script/cache" but they execute injected scripts in order + //unless the 'async' flag is present. + var supportsInOrderExecution = ((window.opera && Object.prototype.toString.call(window.opera) === "[object Opera]") || + //If Firefox 2 does not have to be supported, then + //a better check may be: + //('mozIsLocallyAvailable' in window.navigator) + ("MozAppearance" in document.documentElement.style)), + readyRegExp = /^(complete|loaded)$/; + + //Callback used by the type="script/cache" callback that indicates a script + //has finished downloading. + function scriptCacheCallback(evt) { + var node = evt.currentTarget || evt.srcElement, i, + context, contextName, moduleName, waiting, cached; + + if (evt.type === "load" || readyRegExp.test(node.readyState)) { + //Pull out the name of the module and the context. + contextName = node.getAttribute("data-requirecontext"); + moduleName = node.getAttribute("data-requiremodule"); + context = require.s.contexts[contextName]; + waiting = context.orderWaiting; + cached = context.orderCached; + + //Mark this cache request as loaded + cached[moduleName] = true; + + //Find out how many ordered modules have loaded + for (i = 0; cached[waiting[i]]; i++) {} + if (i > 0) { + require(waiting.splice(0, i), contextName); + } + + //If no other order cache items are in the queue, do some cleanup. + if (!waiting.length) { + context.orderCached = {}; + } + + //Remove this script tag from the DOM + //Use a setTimeout for cleanup because some older IE versions vomit + //if removing a script node while it is being evaluated. + setTimeout(function () { + node.parentNode.removeChild(node); + }, 15); + } + } + + require.plugin({ + prefix: "order", + + /** + * This callback is prefix-specific, only gets called for this prefix + */ + require: function (name, deps, callback, context) { + //No-op, require never gets these order items, they are always + //a dependency, see load for the action. + }, + + /** + * Called when a new context is defined. Use this to store + * context-specific info on it. + */ + newContext: function (context) { + require.mixin(context, { + orderWaiting: [], + orderCached: {} + }); + }, + + /** + * Called when a dependency needs to be loaded. + */ + load: function (name, contextName) { + var context = require.s.contexts[contextName], + url = require.nameToUrl(name, null, contextName); + + //Make sure the async attribute is not set for any pathway involving + //this script. + require.s.skipAsync[url] = true; + if (supportsInOrderExecution) { + //Just a normal script tag append, but without async attribute + //on the script. + require([name], contextName); + } else { + //Credit to LABjs author Kyle Simpson for finding that scripts + //with type="script/cache" allow scripts to be downloaded into + //browser cache but not executed. Use that + //so that subsequent addition of a real type="text/javascript" + //tag will cause the scripts to be executed immediately in the + //correct order. + context.orderWaiting.push(name); + context.loaded[name] = false; + require.attach(url, contextName, name, scriptCacheCallback, "script/cache"); + } + }, + + /** + * Called when the dependencies of a module are checked. + */ + checkDeps: function (name, deps, context) { + //No-op, checkDeps never gets these order items, they are always + //a dependency, see load for the action. + }, + + /** + * Called to determine if a module is waiting to load. + */ + isWaiting: function (context) { + return !!context.orderWaiting.length; + }, + + /** + * Called when all modules have been loaded. Not needed for this plugin. + * State is reset as part of scriptCacheCallback. + */ + orderDeps: function (context) { + } + }); +}()); + +//Target build file for a require.js that has all of require's functionality, +//and includes specific plugins: i18n and text. \ No newline at end of file diff --git a/doc/Editor.mm b/doc/Editor.mm new file mode 100644 index 00000000..57208079 --- /dev/null +++ b/doc/Editor.mm @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/ace/BackgroundTokenizer.js b/lib/ace/BackgroundTokenizer.js new file mode 100644 index 00000000..c9075639 --- /dev/null +++ b/lib/ace/BackgroundTokenizer.js @@ -0,0 +1,135 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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 { + var tokens = this.lines[row]; + state = tokens.state; + rows.push(tokens); + } + } + return rows; + }; + +}).call(BackgroundTokenizer.prototype); + +return BackgroundTokenizer; +}); diff --git a/lib/ace/Document.js b/lib/ace/Document.js new file mode 100644 index 00000000..ab28e841 --- /dev/null +++ b/lib/ace/Document.js @@ -0,0 +1,721 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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 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++; + } + + return new Range(row, start, row, end); + }; + + 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 chr = line.charAt(column); + if (chr == openBracket) { + depth -= 1; + if (depth == 0) { + return {row: row, column: column}; + } + } + else if (chr == 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 chr = line.charAt(column); + if (chr == closingBracket) { + depth -= 1; + if (depth == 0) { + return {row: row, column: column}; + } + } + else if (chr == 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() ? undefined : range.start.row); + + 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.clearSelection(); + } + } + }, + + this.redoChanges = function(deltas) { + this.selection.clearSelection(); + for (var i=0; i= this.lines.length-1) return 0; + + var removed = this.lines.slice(firstRow, lastRow + 1); + this.$remove(new Range(firstRow, 0, lastRow + 1, 0)); + 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 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= 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; +}); diff --git a/lib/ace/Editor.js b/lib/ace/Editor.js new file mode 100644 index 00000000..18d66f06 --- /dev/null +++ b/lib/ace/Editor.js @@ -0,0 +1,1011 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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, 0, 2, 500, lang.bind(this.onMouseDoubleClick, this)); + event.addMultiMouseDownListener(mouseTarget, 0, 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); + + var pos = this.renderer.screenToTextCoordinates(pageX, pageY); + pos.row = Math.max(0, Math.min(pos.row, this.doc.getLength()-1)); + + if (event.getButton(e) != 0) { + if (this.selection.isEmpty()) { + this.moveCursorToPosition(pos); + } + return; + } + + 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; + this.bgTokenizer.getState(cursor.row, function (lineState) { + var shouldOutdent = _self.mode.checkOutdent(lineState, _self.doc.getLine(cursor.row), text); + var line = _self.doc.getLine(cursor.row), + lineIndent = _self.mode.getNextLineIndent(lineState, line, _self.doc.getTabString()); + 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; + } + */ + + _self.bgTokenizer.getState(cursor.row, function(lineState) { + // multi line insert + if (cursor.row !== end.row) { + var size = _self.doc.getTabSize(), + minIndent = Number.MAX_VALUE; + + for (var row = cursor.row + 1; row <= end.row; ++row) { + var indent = 0; + + line = _self.doc.getLine(row); + for (var i = 0; i < line.length; ++i) + if (line.charAt(i) == '\t') + indent += size; + else if (line.charAt(i) == ' ') + indent += 1; + else + break; + if (/[^\s]$/.test(line)) + minIndent = Math.min(indent, minIndent); + } + for (var row = cursor.row + 1; row <= end.row; ++row) { + var outdent = minIndent; + + line = _self.doc.getLine(row); + for (var i = 0; i < line.length && outdent > 0; ++i) + if (line.charAt(i) == '\t') + outdent -= size; + else if (line.charAt(i) == ' ') + outdent -= 1; + _self.doc.replace(new Range(row, 0, row, line.length), line.substr(i)); + } + end.column += _self.doc.indentRows( + new Range(cursor.row + 1, 0, end.row, end.column), + lineIndent); + } else { + if (shouldOutdent) { + end.column += _self.mode.autoOutdent(lineState, _self.doc, cursor.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() { + 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() { + 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.$search.find(this.doc); + this.$tryReplace(range, replacement); + if (range !== null) + this.selection.setSelectionRange(range); + this.$updateDesiredColumn(); + }, + + this.replaceAll = function(replacement, options) { + if (options) { + this.$search.set(options); + } + 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); + if (ranges[0] !== null) + 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; +}); diff --git a/lib/ace/KeyBinding.js b/lib/ace/KeyBinding.js new file mode 100644 index 00000000..e46c420c --- /dev/null +++ b/lib/ace/KeyBinding.js @@ -0,0 +1,123 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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; +}); diff --git a/lib/ace/MEventEmitter.js b/lib/ace/MEventEmitter.js new file mode 100644 index 00000000..117cd266 --- /dev/null +++ b/lib/ace/MEventEmitter.js @@ -0,0 +1,56 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +if (!require.def) require.def = require("requireJS-node")(module, require); + +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 + * @author Fabian Jakobs + */ +require.def("ace/PluginManager", [], function() { + +var PluginManager = { + commands : {}, + + registerCommand : function(name, command) { + this.commands[name] = command; + } +}; + +return PluginManager; +}); \ No newline at end of file diff --git a/lib/ace/Range.js b/lib/ace/Range.js new file mode 100644 index 00000000..57783a85 --- /dev/null +++ b/lib/ace/Range.js @@ -0,0 +1,126 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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; +}) diff --git a/lib/ace/RenderLoop.js b/lib/ace/RenderLoop.js new file mode 100644 index 00000000..c1fcd490 --- /dev/null +++ b/lib/ace/RenderLoop.js @@ -0,0 +1,62 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +require.def("ace/RenderLoop", function() { + +var RenderLoop = function(onRender) { + this.onRender = onRender; + this.pending = false; + this.changes = 0; +}; + +(function() { + + this.schedule = function(change) { +// this.onRender(change); +// return; + 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; +}); \ No newline at end of file diff --git a/lib/ace/ScrollBar.js b/lib/ace/ScrollBar.js new file mode 100644 index 00000000..a0dece62 --- /dev/null +++ b/lib/ace/ScrollBar.js @@ -0,0 +1,57 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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; +}); diff --git a/lib/ace/Search.js b/lib/ace/Search.js new file mode 100644 index 00000000..2399f172 --- /dev/null +++ b/lib/ace/Search.js @@ -0,0 +1,291 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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= 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; +}); diff --git a/lib/ace/Selection.js b/lib/ace/Selection.js new file mode 100644 index 00000000..7915481c --- /dev/null +++ b/lib/ace/Selection.js @@ -0,0 +1,391 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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.selectWordRight = function() { + this.$moveSelection(this.moveCursorWordRight); + }; + + this.selectWordLeft = function() { + this.$moveSelection(this.moveCursorWordLeft); + }; + + this.selectWord = function() { + var cursor = this.selectionLead; + var column = cursor.column; + var range = this.doc.getWordRange(cursor.row, column); + this.setSelectionRange(range); + + /*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[0].length == 0) + this.moveCursorTo(row, this.doc.getLine(row).match(/^\s*/)[0].length); + else if (leadingSpace[0].length >= column) + this.moveCursorTo(row, 0); + else + this.moveCursorTo(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.doc.nonTokenRe.lastIndex = 0; + this.doc.tokenRe.lastIndex = 0; + + if (column == line.length) { + this.moveCursorRight(); + return; + } + else if (match = this.doc.nonTokenRe.exec(rightOfCursor)) { + column += this.doc.nonTokenRe.lastIndex; + this.doc.nonTokenRe.lastIndex = 0; + } + else if (match = this.doc.tokenRe.exec(rightOfCursor)) { + column += this.doc.tokenRe.lastIndex; + this.doc.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.doc.nonTokenRe.lastIndex = 0; + this.doc.tokenRe.lastIndex = 0; + + if (column == 0) { + this.moveCursorLeft(); + return; + } + else if (match = this.doc.nonTokenRe.exec(leftOfCursor)) { + column -= this.doc.nonTokenRe.lastIndex; + this.doc.nonTokenRe.lastIndex = 0; + } + else if (match = this.doc.tokenRe.exec(leftOfCursor)) { + column -= this.doc.tokenRe.lastIndex; + this.doc.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; +}); diff --git a/lib/ace/TextInput.js b/lib/ace/TextInput.js new file mode 100644 index 00000000..b29bac8c --- /dev/null +++ b/lib/ace/TextInput.js @@ -0,0 +1,118 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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; +}); \ No newline at end of file diff --git a/lib/ace/Tokenizer.js b/lib/ace/Tokenizer.js new file mode 100644 index 00000000..4be24df4 --- /dev/null +++ b/lib/ace/Tokenizer.js @@ -0,0 +1,102 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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; +}); \ No newline at end of file diff --git a/lib/ace/UndoManager.js b/lib/ace/UndoManager.js new file mode 100644 index 00000000..6d7d2260 --- /dev/null +++ b/lib/ace/UndoManager.js @@ -0,0 +1,47 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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; +}); \ No newline at end of file diff --git a/lib/ace/VirtualRenderer.js b/lib/ace/VirtualRenderer.js new file mode 100644 index 00000000..d56d62f9 --- /dev/null +++ b/lib/ace/VirtualRenderer.js @@ -0,0 +1,621 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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.$loop = new RenderLoop(lang.bind(this.$renderChanges, this)); + this.$loop.schedule(this.CHANGE_FULL); + + this.$updatePrintMargin(); + this.setPadding(4); +}; + +(function() { + + this.showGutter = true; + + 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 (lastRow === undefined) + lastRow = Infinity; + + 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; + } + + 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.showGutter ? this.$gutter.offsetWidth : 0; + 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.$tokenizer = 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.setShowGutter = function(show){ + this.$gutter.style.display = show ? "block" : "none"; + this.showGutter = show; + this.onResize(); + } + + 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.getFirstFullyVisibleRow = function(){ + if (!this.layerConfig) + return 0; + + return this.layerConfig.firstRow + (this.layerConfig.offset == 0 ? 0 : 1); + } + + this.getLastFullyVisibleRow = function() { + if (!this.layerConfig) + return 0; + + var flint = Math.floor((this.layerConfig.height + this.layerConfig.offset) / this.layerConfig.lineHeight); + return this.layerConfig.firstRow - 1 + flint; + } + + this.getLastVisibleRow = function() { + return (this.layerConfig || {}).lastRow || 0; + }; + + this.$padding = null; + this.setPadding = function(padding) { + this.$padding = padding; + this.content.style.padding = "0 " + padding + "px"; + this.$loop.schedule(this.CHANGE_FULL); + }; + + 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 || !this.doc || !this.$tokenizer) + 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.showGutter && 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.showGutter && this.$gutterLayer.update(this.layerConfig); + this.$markerLayer.update(this.layerConfig); + this.$cursorLayer.update(this.layerConfig); + } + else { + this.$textLayer.update(this.layerConfig); + this.showGutter && 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.showGutter && 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.showGutter && this.$gutterLayer.update(this.layerConfig); + } if (changes & this.CHANGE_GUTTER) { + this.showGutter && 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.max(0, Math.round((this.scrollTop - offset) / this.lineHeight)); + var lastRow = Math.min(this.lines.length, firstRow + lineCount) - 1; + + var layerConfig = this.layerConfig = { + width : longestLine, + padding : this.$padding, + firstRow : firstRow, + lastRow : lastRow, + lineHeight : this.lineHeight, + characterWidth : this.characterWidth, + minHeight : minHeight, + offset : offset, + height : this.$size.scrollerHeight + }; + + 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.width = longestLine + "px"; + this.content.style.height = minHeight + "px"; + }; + + this.$updateLines = function() { + var firstRow = this.$changedLines.firstRow; + var lastRow = this.$changedLines.lastRow; + this.$changedLines = null; + + 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.showGutter && 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 - this.$padding * 2, Math.round(charCount * this.characterWidth)); + }; + + this.addMarker = function(range, clazz, type) { + var id = this.$markerLayer.addMarker(range, clazz, type); + this.$loop.schedule(this.CHANGE_MARKER); + return id; + }; + + this.removeMarker = function(markerId) { + this.$markerLayer.removeMarker(markerId); + this.$loop.schedule(this.CHANGE_MARKER); + }; + + this.addGutterDecoration = function(row, className){ + this.$gutterLayer.addGutterDecoration(row, className); + this.$loop.schedule(this.CHANGE_GUTTER); + } + + this.removeGutterDecoration = function(row, className){ + this.$gutterLayer.removeGutterDecoration(row, className); + this.$loop.schedule(this.CHANGE_GUTTER); + } + + 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 + this.$padding; + 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.scrollToX(left); + } + + if (this.scroller.scrollLeft + this.$size.scrollerWidth < left + + this.characterWidth) { + this.scrollToX(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.scrollToX = function(scrollLeft) { + if (scrollLeft <= this.$padding) + scrollLeft = 0; + + this.scroller.scrollLeft = scrollLeft; + }; + + this.scrollBy = function(deltaX, deltaY) { + deltaY && this.scrollToY(this.scrollTop + deltaY); + deltaX && this.scrollToX(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.$padding) + / 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 = this.padding + 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; +}); \ No newline at end of file diff --git a/lib/ace/commands/DefaultCommands.js b/lib/ace/commands/DefaultCommands.js new file mode 100644 index 00000000..f0877051 --- /dev/null +++ b/lib/ace/commands/DefaultCommands.js @@ -0,0 +1,163 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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(); +}); + +}); \ No newline at end of file diff --git a/lib/ace/conf/keybindings/default_mac.js b/lib/ace/conf/keybindings/default_mac.js new file mode 100644 index 00000000..0a652dda --- /dev/null +++ b/lib/ace/conf/keybindings/default_mac.js @@ -0,0 +1,58 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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", + "movelinesdown": "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" +}; + +}); \ No newline at end of file diff --git a/lib/ace/conf/keybindings/default_win.js b/lib/ace/conf/keybindings/default_win.js new file mode 100644 index 00000000..fd5d393c --- /dev/null +++ b/lib/ace/conf/keybindings/default_win.js @@ -0,0 +1,58 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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", + "movelinesdown": "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" +}; + +}); diff --git a/lib/ace/css/editor.css b/lib/ace/css/editor.css new file mode 100644 index 00000000..cd52dfe1 --- /dev/null +++ b/lib/ace/css/editor.css @@ -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; +} \ No newline at end of file diff --git a/lib/ace/layer/Cursor.js b/lib/ace/layer/Cursor.js new file mode 100644 index 00000000..4141269d --- /dev/null +++ b/lib/ace/layer/Cursor.js @@ -0,0 +1,117 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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; +}); diff --git a/lib/ace/layer/Gutter.js b/lib/ace/layer/Gutter.js new file mode 100644 index 00000000..d3e8c3ea --- /dev/null +++ b/lib/ace/layer/Gutter.js @@ -0,0 +1,55 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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 = []; + this.$decorations = []; +}; + +(function() { + + this.addGutterDecoration = function(row, className){ + if (!this.$decorations[row]) + this.$decorations[row] = ""; + this.$decorations[row] += " ace_" + className; + } + + this.removeGutterDecoration = function(row, className){ + this.$decorations[row] = + this.$decorations[row].replace(" ace_" + className, ""); + } + + this.setBreakpoints = function(rows) { + this.$breakpoints = rows.concat(); + }; + + this.update = function(config) { + this.$config = config; + + var html = []; + for ( var i = config.firstRow; i <= config.lastRow; i++) { + html.push("
", (i+1), "
"); + html.push(""); + } + + this.element.innerHTML = html.join(""); + this.element.style.height = config.minHeight + "px"; + }; + +}).call(Gutter.prototype); + +return Gutter; +}); diff --git a/lib/ace/layer/Marker.js b/lib/ace/layer/Marker.js new file mode 100644 index 00000000..506cec07 --- /dev/null +++ b/lib/ace/layer/Marker.js @@ -0,0 +1,153 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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( + "
" + ); + + // 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( + "
" + ); + + // 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( + "
" + ); + }; + + 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( + "
" + ); + }; + +}).call(Marker.prototype); + +return Marker; +}); diff --git a/lib/ace/layer/Text.js b/lib/ace/layer/Text.js new file mode 100644 index 00000000..8a43e005 --- /dev/null +++ b/lib/ace/layer/Text.js @@ -0,0 +1,267 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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 = "¶"; + this.EOL_CHAR = "¬"; + this.TAB_CHAR = "→"; + this.SPACE_CHAR = "·"; + + 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 = "" + + new Array(Math.floor(halfTab)).join(" ") + + this.TAB_CHAR + + new Array(Math.ceil(halfTab)+1).join(" ") + + ""; + } else { + this.$tabString = new Array(tabSize+1).join(" "); + } + }; + + 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.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("
"); + _self.$renderLine(html, i, tokens[i-config.firstRow].tokens), html.push("
"); + } + + _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 "" + space + ""; +// }; +// } +// else { + var spaceRe = /[\v\f \u00a0\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u3000]/g; + var spaceReplace = " "; +// } + + for ( var i = 0; i < tokens.length; i++) { + var token = tokens[i]; + + var output = token.value + .replace(/&/g, "&") + .replace(/", output, ""); + } + else { + stringBuilder.push(output); + } + }; + + if (this.$showInvisibles) { + if (row !== this.doc.getLength() - 1) { + stringBuilder.push("" + this.EOL_CHAR + ""); + } else { + stringBuilder.push("" + this.EOF_CHAR + ""); + } + } + }; + +}).call(Text.prototype); + +return Text; +}); diff --git a/lib/ace/lib/core.js b/lib/ace/lib/core.js new file mode 100644 index 00000000..6e0541e0 --- /dev/null +++ b/lib/ace/lib/core.js @@ -0,0 +1,36 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +if (!require.def) require.def = require("requireJS-node")(module, require); + +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 + * @author Fabian Jakobs + */ + +if (!require.def) require.def = require("requireJS-node")(module, require); + +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; +}); \ No newline at end of file diff --git a/lib/ace/lib/event.js b/lib/ace/lib/event.js new file mode 100644 index 00000000..803ee803 --- /dev/null +++ b/lib/ace/lib/event.js @@ -0,0 +1,213 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +if (!require.def) require.def = require("requireJS-node")(module, require); + +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, button, 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 (event.getButton(e) != button + || 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; +}); \ No newline at end of file diff --git a/lib/ace/lib/lang.js b/lib/ace/lib/lang.js new file mode 100644 index 00000000..49942ece --- /dev/null +++ b/lib/ace/lib/lang.js @@ -0,0 +1,98 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +if (!require.def) require.def = require("requireJS-node")(module, require); + +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 + * @author Fabian Jakobs + */ + +if (!require.def) require.def = require("requireJS-node")(module, require); + +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; +}); \ No newline at end of file diff --git a/lib/ace/mode/Css.js b/lib/ace/mode/Css.js new file mode 100644 index 00000000..652c8229 --- /dev/null +++ b/lib/ace/mode/Css.js @@ -0,0 +1,53 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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; +}); \ No newline at end of file diff --git a/lib/ace/mode/CssHighlightRules.js b/lib/ace/mode/CssHighlightRules.js new file mode 100644 index 00000000..9d25aab0 --- /dev/null +++ b/lib/ace/mode/CssHighlightRules.js @@ -0,0 +1,204 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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 + * @author Fabian Jakobs + */ +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; +}); \ No newline at end of file diff --git a/lib/ace/mode/Html.js b/lib/ace/mode/Html.js new file mode 100644 index 00000000..87c8e33c --- /dev/null +++ b/lib/ace/mode/Html.js @@ -0,0 +1,72 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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; +}); diff --git a/lib/ace/mode/HtmlHighlightRules.js b/lib/ace/mode/HtmlHighlightRules.js new file mode 100644 index 00000000..21e7b07c --- /dev/null +++ b/lib/ace/mode/HtmlHighlightRules.js @@ -0,0 +1,153 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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; +}); diff --git a/lib/ace/mode/JavaScript.js b/lib/ace/mode/JavaScript.js new file mode 100644 index 00000000..c5833baa --- /dev/null +++ b/lib/ace/mode/JavaScript.js @@ -0,0 +1,98 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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; +}); diff --git a/lib/ace/mode/JavaScriptHighlightRules.js b/lib/ace/mode/JavaScriptHighlightRules.js new file mode 100644 index 00000000..5552f7f9 --- /dev/null +++ b/lib/ace/mode/JavaScriptHighlightRules.js @@ -0,0 +1,144 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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("|") + ); + + // ES3 future reserved + var futureReserved = lang.arrayToMap( + ("abstract|boolean|byte|char|class|const|enum|export|extends|final|" + + "float|goto|implements|int|interface|long|native|package|private|" + + "protected|short|static|super|synchronized|throws|transient|volatile" + + "double|import|public").split("|") + ); + +// ES5 future reserved +// 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; +}); \ No newline at end of file diff --git a/lib/ace/mode/MatchingBraceOutdent.js b/lib/ace/mode/MatchingBraceOutdent.js new file mode 100644 index 00000000..455ff1df --- /dev/null +++ b/lib/ace/mode/MatchingBraceOutdent.js @@ -0,0 +1,52 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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; +}); diff --git a/lib/ace/mode/Text.js b/lib/ace/mode/Text.js new file mode 100644 index 00000000..ba97cc9f --- /dev/null +++ b/lib/ace/mode/Text.js @@ -0,0 +1,51 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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; +}); \ No newline at end of file diff --git a/lib/ace/mode/TextHighlightRules.js b/lib/ace/mode/TextHighlightRules.js new file mode 100644 index 00000000..3918c55e --- /dev/null +++ b/lib/ace/mode/TextHighlightRules.js @@ -0,0 +1,47 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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 + * @author Fabian Jakobs + */ +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; +}); \ No newline at end of file diff --git a/lib/ace/mode/XmlHighlightRules.js b/lib/ace/mode/XmlHighlightRules.js new file mode 100644 index 00000000..21a85c36 --- /dev/null +++ b/lib/ace/mode/XmlHighlightRules.js @@ -0,0 +1,89 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ +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; +}); \ No newline at end of file diff --git a/lib/ace/test/ChangeDocumentTest.js b/lib/ace/test/ChangeDocumentTest.js new file mode 100644 index 00000000..796b9e42 --- /dev/null +++ b/lib/ace/test/ChangeDocumentTest.js @@ -0,0 +1,130 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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); + } +}); + +}); \ No newline at end of file diff --git a/lib/ace/test/DocumentTest.js b/lib/ace/test/DocumentTest.js new file mode 100644 index 00000000..1caadebf --- /dev/null +++ b/lib/ace/test/DocumentTest.js @@ -0,0 +1,234 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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)); + } +}); + +}); \ No newline at end of file diff --git a/lib/ace/test/EventEmitterTest.js b/lib/ace/test/EventEmitterTest.js new file mode 100644 index 00000000..22c6e9fe --- /dev/null +++ b/lib/ace/test/EventEmitterTest.js @@ -0,0 +1,36 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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); + } +}); + +}); \ No newline at end of file diff --git a/lib/ace/test/MockRenderer.js b/lib/ace/test/MockRenderer.js new file mode 100644 index 00000000..2d14096f --- /dev/null +++ b/lib/ace/test/MockRenderer.js @@ -0,0 +1,88 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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; +}); diff --git a/lib/ace/test/NavigationTest.js b/lib/ace/test/NavigationTest.js new file mode 100644 index 00000000..45e73cc2 --- /dev/null +++ b/lib/ace/test/NavigationTest.js @@ -0,0 +1,126 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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()); + } +}); + +}); \ No newline at end of file diff --git a/lib/ace/test/RangeTest.js b/lib/ace/test/RangeTest.js new file mode 100644 index 00000000..346ed5fe --- /dev/null +++ b/lib/ace/test/RangeTest.js @@ -0,0 +1,123 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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); + } +}); + +}); \ No newline at end of file diff --git a/lib/ace/test/SearchTest.js b/lib/ace/test/SearchTest.js new file mode 100644 index 00000000..81397065 --- /dev/null +++ b/lib/ace/test/SearchTest.js @@ -0,0 +1,322 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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", "

+ * @author Fabian Jakobs + */ + +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); + } +}); + +}); \ No newline at end of file diff --git a/lib/ace/test/TextEditTest.js b/lib/ace/test/TextEditTest.js new file mode 100644 index 00000000..654529db --- /dev/null +++ b/lib/ace/test/TextEditTest.js @@ -0,0 +1,315 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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()); + } +}); + +}); \ No newline at end of file diff --git a/lib/ace/test/VirtualRendererTest.js b/lib/ace/test/VirtualRendererTest.js new file mode 100644 index 00000000..f164fd4b --- /dev/null +++ b/lib/ace/test/VirtualRendererTest.js @@ -0,0 +1,48 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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) +}); + +}); \ No newline at end of file diff --git a/lib/ace/test/all.js b/lib/ace/test/all.js new file mode 100644 index 00000000..be6a4ffa --- /dev/null +++ b/lib/ace/test/all.js @@ -0,0 +1,11 @@ +require({ + paths: { + "ace": "../src/ace" + }}, + ["ace/test/assertions", "ace/test/ChangeDocumentTest"], + function(a) { + console.log(a) + alert("a " + a) + } +); + diff --git a/lib/ace/test/assertions.js b/lib/ace/test/assertions.js new file mode 100644 index 00000000..8dc4893b --- /dev/null +++ b/lib/ace/test/assertions.js @@ -0,0 +1,25 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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)); +}; + +}); \ No newline at end of file diff --git a/lib/ace/test/mode/CssTest.js b/lib/ace/test/mode/CssTest.js new file mode 100644 index 00000000..0660ad56 --- /dev/null +++ b/lib/ace/test/mode/CssTest.js @@ -0,0 +1,50 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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", " /*{ ", " ")); + } +}); + +}); diff --git a/lib/ace/test/mode/CssTokenizerTest.js b/lib/ace/test/mode/CssTokenizerTest.js new file mode 100644 index 00000000..d6200751 --- /dev/null +++ b/lib/ace/test/mode/CssTokenizerTest.js @@ -0,0 +1,53 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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); + } +}); + +}); \ No newline at end of file diff --git a/lib/ace/test/mode/HtmlTest.js b/lib/ace/test/mode/HtmlTest.js new file mode 100644 index 00000000..d809315f --- /dev/null +++ b/lib/ace/test/mode/HtmlTest.js @@ -0,0 +1,40 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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")); + } +}); + +}); \ No newline at end of file diff --git a/lib/ace/test/mode/HtmlTokenizerTest.js b/lib/ace/test/mode/HtmlTokenizerTest.js new file mode 100644 index 00000000..b538e4c4 --- /dev/null +++ b/lib/ace/test/mode/HtmlTokenizerTest.js @@ -0,0 +1,41 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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 = "'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); + } +}); + +}); \ No newline at end of file diff --git a/lib/ace/test/mode/JavaScriptTest.js b/lib/ace/test/mode/JavaScriptTest.js new file mode 100644 index 00000000..8f61d55a --- /dev/null +++ b/lib/ace/test/mode/JavaScriptTest.js @@ -0,0 +1,121 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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)); + } + +}); + +}); \ No newline at end of file diff --git a/lib/ace/test/mode/JavaScriptTokenizerTest.js b/lib/ace/test/mode/JavaScriptTokenizerTest.js new file mode 100644 index 00000000..65f40f21 --- /dev/null +++ b/lib/ace/test/mode/JavaScriptTokenizerTest.js @@ -0,0 +1,68 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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); + } +}); + +}); \ No newline at end of file diff --git a/lib/ace/test/mode/TextTest.js b/lib/ace/test/mode/TextTest.js new file mode 100644 index 00000000..252b867e --- /dev/null +++ b/lib/ace/test/mode/TextTest.js @@ -0,0 +1,39 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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", " ")); + } +}); + +}); \ No newline at end of file diff --git a/lib/ace/test/mode/XmlTest.js b/lib/ace/test/mode/XmlTest.js new file mode 100644 index 00000000..8c8e7f92 --- /dev/null +++ b/lib/ace/test/mode/XmlTest.js @@ -0,0 +1,51 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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("", "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")); + } +}); + +}); \ No newline at end of file diff --git a/lib/ace/test/mode/XmlTokenizerTest.js b/lib/ace/test/mode/XmlTokenizerTest.js new file mode 100644 index 00000000..3963fa70 --- /dev/null +++ b/lib/ace/test/mode/XmlTokenizerTest.js @@ -0,0 +1,35 @@ +/** + * Ajax.org Code Editor (ACE) + * + * @copyright 2010, Ajax.org Services B.V. + * @license LGPLv3 + * @author Fabian Jakobs + */ + +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 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); + } +}); + +}); \ No newline at end of file diff --git a/lib/ace/theme/Clouds.js b/lib/ace/theme/Clouds.js new file mode 100644 index 00000000..ca6ae73b --- /dev/null +++ b/lib/ace/theme/Clouds.js @@ -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" + }; +}) \ No newline at end of file diff --git a/lib/ace/theme/CloudsMidnight.js b/lib/ace/theme/CloudsMidnight.js new file mode 100644 index 00000000..f3c092c5 --- /dev/null +++ b/lib/ace/theme/CloudsMidnight.js @@ -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" + }; +}) \ No newline at end of file diff --git a/lib/ace/theme/Cobalt.js b/lib/ace/theme/Cobalt.js new file mode 100644 index 00000000..ae177aad --- /dev/null +++ b/lib/ace/theme/Cobalt.js @@ -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" + }; +}) \ No newline at end of file diff --git a/lib/ace/theme/Dawn.js b/lib/ace/theme/Dawn.js new file mode 100644 index 00000000..e4c59257 --- /dev/null +++ b/lib/ace/theme/Dawn.js @@ -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" + }; +}) \ No newline at end of file diff --git a/lib/ace/theme/Eclipse.js b/lib/ace/theme/Eclipse.js new file mode 100644 index 00000000..224d9165 --- /dev/null +++ b/lib/ace/theme/Eclipse.js @@ -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" + }; +}) \ No newline at end of file diff --git a/lib/ace/theme/IdleFingers.js b/lib/ace/theme/IdleFingers.js new file mode 100644 index 00000000..48ca72f7 --- /dev/null +++ b/lib/ace/theme/IdleFingers.js @@ -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" + }; +}) \ No newline at end of file diff --git a/lib/ace/theme/KrTheme.js b/lib/ace/theme/KrTheme.js new file mode 100644 index 00000000..e201c5bb --- /dev/null +++ b/lib/ace/theme/KrTheme.js @@ -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" + }; +}) \ No newline at end of file diff --git a/lib/ace/theme/MonoIndustrial.js b/lib/ace/theme/MonoIndustrial.js new file mode 100644 index 00000000..0a721576 --- /dev/null +++ b/lib/ace/theme/MonoIndustrial.js @@ -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" + }; +}) \ No newline at end of file diff --git a/lib/ace/theme/Monokai.js b/lib/ace/theme/Monokai.js new file mode 100644 index 00000000..a992134c --- /dev/null +++ b/lib/ace/theme/Monokai.js @@ -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" + }; +}) \ No newline at end of file diff --git a/lib/ace/theme/TextMate.js b/lib/ace/theme/TextMate.js new file mode 100644 index 00000000..c4f74dd5 --- /dev/null +++ b/lib/ace/theme/TextMate.js @@ -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" + }; +}) \ No newline at end of file diff --git a/lib/ace/theme/Twilight.js b/lib/ace/theme/Twilight.js new file mode 100644 index 00000000..61b9c6ac --- /dev/null +++ b/lib/ace/theme/Twilight.js @@ -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" + }; +}) \ No newline at end of file diff --git a/lib/ace/theme/eclipse.css b/lib/ace/theme/eclipse.css new file mode 100644 index 00000000..ff24f87f --- /dev/null +++ b/lib/ace/theme/eclipse.css @@ -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); +} \ No newline at end of file diff --git a/lib/ace/theme/tm.css b/lib/ace/theme/tm.css new file mode 100644 index 00000000..4e999fa1 --- /dev/null +++ b/lib/ace/theme/tm.css @@ -0,0 +1,123 @@ +.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(252, 255, 0); +} + +.ace-tm .ace_marker-layer .ace_stack { + background: rgb(164, 229, 101); +} + +.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) +} \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 00000000..f27b9a63 --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "ace", + "description": "Ajax.org Code Editor is a full featured source code highlighting editor that powers the Cloud9 IDE", + "version": "0.1", + "homepage" : "http://github.com/ajaxorg/ace", + "engines": {"node": ">= 0.1.102"}, + "author": "Fabian Jakobs ", + "main": "src/ace/ace", + "repository" : { + "type" : "git", + "url" : "http://github.com/ajaxorg/ace.git" + }, + "licenses": [{ + "type": "LGPLv3", + "url": "http://www.gnu.org/licenses/lgpl-3.0.txt"} + ] +} \ No newline at end of file diff --git a/support/node-o3-xml b/support/node-o3-xml new file mode 160000 index 00000000..563a2b10 --- /dev/null +++ b/support/node-o3-xml @@ -0,0 +1 @@ +Subproject commit 563a2b1091bd1b9a7d26a9f597aacb4341edb619 diff --git a/support/requirejs b/support/requirejs new file mode 160000 index 00000000..819c4e7b --- /dev/null +++ b/support/requirejs @@ -0,0 +1 @@ +Subproject commit 819c4e7b9b1e6e5f99696b5c9f2805891a9e7cfd diff --git a/tool/Theme.tmpl.css b/tool/Theme.tmpl.css new file mode 100644 index 00000000..9d2c5107 --- /dev/null +++ b/tool/Theme.tmpl.css @@ -0,0 +1,148 @@ +.%cssClass% .ace_editor { + border: 2px solid rgb(159, 159, 159); +} + +.%cssClass% .ace_editor.ace_focus { + border: 2px solid #327fbd; +} + +.%cssClass% .ace_gutter { + width: 50px; + background: #e8e8e8; + color: #333; + overflow : hidden; +} + +.%cssClass% .ace_gutter-layer { + width: 100%; + text-align: right; +} + +.%cssClass% .ace_gutter-layer .ace_gutter-cell { + padding-right: 6px; +} + +.%cssClass% .ace_editor .ace_printMargin { + width: 1px; + background: %printMargin%; +} + +.%cssClass% .ace_scroller { + background-color: %background%; +} + +.%cssClass% .ace_text-layer { + cursor: text; + color: %foreground%; +} + +.%cssClass% .ace_cursor { + border-left: 2px solid %cursor%; +} + +.%cssClass% .ace_cursor.ace_overwrite { + border-left: 0px; + border-bottom: 1px solid %overwrite%; +} + +.%cssClass% .ace_marker-layer .ace_selection { + background: %selection%; +} + +.%cssClass% .ace_marker-layer .ace_step { + background: %step%; +} + +.%cssClass% .ace_marker-layer .ace_bracket { + margin: -1px 0 0 -1px; + border: 1px solid %bracket%; +} + +.%cssClass% .ace_marker-layer .ace_active_line { + background: %active_line%; +} + + +.%cssClass% .ace_invisible { + %invisible% +} + +.%cssClass% .ace_keyword { + %keyword% +} + +.%cssClass% .ace_keyword.ace_operator { + %keyword.operator% +} + +.%cssClass% .ace_constant { + %constant% +} + +.%cssClass% .ace_constant.ace_language { + %constant.language% +} + +.%cssClass% .ace_constant.ace_library { + %constant.library% +} + +.%cssClass% .ace_constant.ace_numeric { + %constant.numeric% +} + +.%cssClass% .ace_invalid { + %invalid% +} + +.%cssClass% .ace_invalid.ace_illegal { + %invalid.illegal% +} + +.%cssClass% .ace_invalid.ace_deprecated { + %invalid.deprecated% +} + +.%cssClass% .ace_support { + %support% +} + +.%cssClass% .ace_support.ace_function { + %support.function% +} + +.%cssClass% .ace_function.ace_buildin { + %function.buildin% +} + +.%cssClass% .ace_string { + %string% +} + +.%cssClass% .ace_string.ace_regexp { + %string.regexp% +} + +.%cssClass% .ace_comment { + %comment% +} + +.%cssClass% .ace_comment.ace_doc { + %comment.doc% +} + +.%cssClass% .ace_comment.ace_doc.ace_tag { + %comment.doc.tag% +} + +.%cssClass% .ace_variable { + %variable% +} + +.%cssClass% .ace_variable.ace_language { + %variable.language% +} + +.%cssClass% .ace_xml_pe { + %xml_pe% +} \ No newline at end of file diff --git a/tool/theme.tmpl.js b/tool/theme.tmpl.js new file mode 100644 index 00000000..90cdf6eb --- /dev/null +++ b/tool/theme.tmpl.js @@ -0,0 +1,12 @@ +require.def("ace/theme/%name%", + ["ace/lib/dom"], function(dom) { + + var cssText = %css%; + + // import CSS once + dom.importCssString(cssText); + + return { + cssClass: "%cssClass%" + }; +}) \ No newline at end of file diff --git a/tool/tmtheme.js b/tool/tmtheme.js new file mode 100644 index 00000000..d7a6b05f --- /dev/null +++ b/tool/tmtheme.js @@ -0,0 +1,196 @@ +var xml = require("../support/node-o3-xml/lib/o3-xml"); +var fs = require("fs"); + +function plistToJson(el) { + if (el.tagName != "plist") + throw new Error("not a plist!"); + + return $plistParse(el.selectSingleNode("dict")); +}; + +function $plistParse(el) { + if (el.tagName == "dict") { + var dict = {}; + var key; + var childNodes = el.childNodes; + for (var i=0, l=childNodes.length; i + + + + name + Active4D + settings + + + settings + + background + #FFFFFF + caret + #000000 + foreground + #3B3B3B + invisibles + #BFBFBF + lineHighlight + #00000012 + selection + #BAD6FD + + + + name + Embedded source + scope + text.html source.active4d + settings + + background + #E2E9FF5E + + + + name + Plain XML text + scope + text.xml + settings + + foreground + #000000 + + + + name + Line comment + scope + comment.line + settings + + fontStyle + + foreground + #AF82D4 + + + + name + Block comment + scope + comment.block + settings + + foreground + #AF82D4 + + + + name + String + scope + string + settings + + fontStyle + + foreground + #666666 + + + + name + Interpolated entity + scope + string.interpolated variable + settings + + fontStyle + bold + foreground + #66CCFF + + + + name + Number + scope + constant.numeric + settings + + foreground + #A8017E + + + + name + User-defined constant + scope + constant.character, constant.other + settings + + + + name + Date/time literal + scope + constant.other.date, constant.other.time + settings + + fontStyle + bold + foreground + #66CCFF + + + + name + Built-in constant + scope + constant.language + settings + + foreground + #A535AE + + + + name + Local variable + scope + variable.other.local + settings + + fontStyle + bold + foreground + #6392FF + + + + name + Variable + scope + variable + settings + + fontStyle + bold + foreground + #0053FF + + + + name + Table/field + scope + variable.other.table-field + settings + + foreground + #6988AE + + + + name + Keyword + scope + keyword + settings + + fontStyle + bold + foreground + #006699 + + + + name + Operator + scope + keyword.operator + settings + + + + name + Storage + scope + storage + settings + + foreground + #FF5600 + + + + name + Type name + scope + entity.name.type + settings + + foreground + #21439C + + + + name + Inherited class + scope + entity.other.inherited-class + settings + + + + name + Function name + scope + entity.name.function + settings + + foreground + #21439C + + + + name + Function argument + scope + variable.parameter + settings + + + + name + Tag container + scope + meta.tag + settings + + foreground + #7A7A7A + + + + name + Tag name + scope + entity.name.tag + settings + + foreground + #016CFF + + + + name + Tag attribute + scope + entity.other.attribute-name + settings + + foreground + #963DFF + + + + name + Command/method + scope + support.function + settings + + fontStyle + bold + foreground + #45AE34 + + + + name + Named constant + scope + support.constant + settings + + foreground + #B7734C + + + + name + Library class/type + scope + support.type, support.class + settings + + foreground + #A535AE + + + + name + Library variable + scope + support.variable + settings + + foreground + #A535AE + + + + name + Invalid + scope + invalid + settings + + background + #990000 + foreground + #FFFFFF + + + + name + diff header + scope + meta.diff + settings + + background + #656565 + foreground + #FFFFFF + + + + name + diff line range + scope + meta.diff.range + settings + + background + #1B63FF + foreground + #FFFFFF + + + + name + diff deleted line + scope + markup.deleted.diff + settings + + background + #FF7880 + foreground + #000000 + + + + name + diff inserted line + scope + markup.inserted.diff + settings + + background + #98FF9A + foreground + #000000 + + + + name + diff unchanged line + scope + source.diff + settings + + foreground + #5E5E5E + + + + uuid + 7D2863D0-473C-47A0-B03B-92880559EBA9 + + diff --git a/tool/tmthemes/All Hallows Eve.tmTheme b/tool/tmthemes/All Hallows Eve.tmTheme new file mode 100644 index 00000000..47a67978 --- /dev/null +++ b/tool/tmthemes/All Hallows Eve.tmTheme @@ -0,0 +1,277 @@ + + + + + author + David Heinemeier Hansson + name + All Hallow's Eve + settings + + + settings + + background + #000000 + caret + #FFFFFF + foreground + #FFFFFF + invisibles + #404040 + lineHighlight + #333300 + selection + #73597EE0 + + + + name + Text base + scope + text + settings + + background + #434242 + foreground + #FFFFFF + + + + name + Source base + scope + source + settings + + background + #000000 + foreground + #FFFFFF + + + + name + Comment + scope + comment + settings + + foreground + #9933CC + + + + name + Constant + scope + constant + settings + + foreground + #3387CC + + + + name + Keyword + scope + keyword + settings + + fontStyle + + foreground + #CC7833 + + + + name + Pre-processor Line + scope + meta.preprocessor.c + settings + + fontStyle + + foreground + #D0D0FF + + + + name + Pre-processor Directive + scope + keyword.control.import + settings + + fontStyle + + + + + name + Function name + scope + entity.name.function + settings + + fontStyle + + + + + name + Function argument + scope + variable.parameter + settings + + fontStyle + italic + + + + name + Block comment + scope + source comment.block + settings + + background + #9B9B9B + foreground + #FFFFFF + + + + name + String + scope + string + settings + + foreground + #66CC33 + + + + name + String escapes + scope + string constant.character.escape + settings + + foreground + #AAAAAA + + + + name + String (executed) + scope + string.interpolated + settings + + background + #CCCC33 + foreground + #000000 + + + + name + Regular expression + scope + string.regexp + settings + + foreground + #CCCC33 + + + + name + String (literal) + scope + string.literal + settings + + foreground + #CCCC33 + + + + name + String escapes (executed) + scope + string.interpolated constant.character.escape + settings + + foreground + #555555 + + + + name + Type name + scope + entity.name.type + settings + + fontStyle + underline + + + + name + Class inheritance + scope + entity.other.inherited-class + settings + + fontStyle + italic underline + + + + name + Tag name + scope + entity.name.tag + settings + + fontStyle + underline + + + + name + Tag attribute + scope + entity.other.attribute-name + settings + + fontStyle + + + + + name + Support function + scope + support.function + settings + + fontStyle + + foreground + #C83730 + + + + uuid + 37F22BDC-B2F4-11D9-850C-000A95A89C98 + + diff --git a/tool/tmthemes/Amy.tmTheme b/tool/tmthemes/Amy.tmTheme new file mode 100644 index 00000000..b3258c46 --- /dev/null +++ b/tool/tmthemes/Amy.tmTheme @@ -0,0 +1,557 @@ + + + + + name + Amy + author + William D. Neumann + settings + + + settings + + background + #200020 + caret + #7070FF + foreground + #D0D0FF + invisibles + #BFBFBF + lineHighlight + #80000040 + selection + #80000080 + + + + name + Comment + scope + comment.block + settings + + background + #200020 + fontStyle + italic + foreground + #404080 + + + + name + String + scope + string + settings + + foreground + #999999 + + + + name + Built-in constant + scope + constant.language + settings + + foreground + #707090 + + + + name + Integer + scope + constant.numeric + settings + + foreground + #7090B0 + + + + name + Int32 constant + scope + constant.numeric.integer.int32 + settings + + fontStyle + bold + + + + name + Int64 constant + scope + constant.numeric.integer.int64 + settings + + fontStyle + italic + + + + name + Nativeint constant + scope + constant.numeric.integer.nativeint + settings + + fontStyle + bold italic + + + + name + Floating-point constant + scope + constant.numeric.floating-point.ocaml + settings + + fontStyle + underline + + + + name + Character constant + scope + constant.character + settings + + fontStyle + + foreground + #666666 + + + + name + Boolean constant + scope + constant.language.boolean + settings + + foreground + #8080A0 + + + + name + Built-in constant + scope + constant.language + settings + + + + name + User-defined constant + scope + constant.other + settings + + + + name + Variable + scope + variable.language, variable.other + settings + + fontStyle + + foreground + #008080 + + + + name + Keyword + scope + keyword + settings + + foreground + #A080FF + + + + name + Keyword operator + scope + keyword.operator + settings + + foreground + #A0A0FF + + + + name + Keyword decorator + scope + keyword.other.decorator + settings + + foreground + #D0D0FF + + + + name + Floating-point infix operator + scope + keyword.operator.infix.floating-point.ocaml + settings + + fontStyle + underline + + + + name + Floating-point prefix operator + scope + keyword.operator.prefix.floating-point.ocaml + settings + + fontStyle + underline + + + + name + Compiler directives + scope + keyword.other.directive + settings + + fontStyle + + foreground + #C080C0 + + + + name + Line-number directives + scope + keyword.other.directive.line-number + settings + + fontStyle + underline + foreground + #C080C0 + + + + name + Control keyword + scope + keyword.control + settings + + foreground + #80A0FF + + + + name + Storage + scope + storage + settings + + foreground + #B0FFF0 + + + + name + Variants + scope + entity.name.type.variant + settings + + foreground + #60B0FF + + + + name + Polymorphic variants + scope + storage.type.variant.polymorphic, entity.name.type.variant.polymorphic + settings + + fontStyle + italic + foreground + #60B0FF + + + + name + Module definitions + scope + entity.name.type.module + settings + + foreground + #B000B0 + + + + name + Module type definitions + scope + entity.name.type.module-type.ocaml + settings + + fontStyle + underline + foreground + #B000B0 + + + + name + Support modules + scope + support.other + settings + + foreground + #A00050 + + + + name + Class name + scope + entity.name.type.class + settings + + foreground + #70E080 + + + + name + Class type + scope + entity.name.type.class-type + settings + + fontStyle + + foreground + #70E0A0 + + + + name + Inherited class + scope + entity.other.inherited-class + settings + + + + name + Function name + scope + entity.name.function + settings + + foreground + #50A0A0 + + + + name + Function argument + scope + variable.parameter + settings + + foreground + #80B0B0 + + + + name + Token definition (ocamlyacc) + scope + entity.name.type.token + settings + + fontStyle + + foreground + #3080A0 + + + + name + Token reference (ocamlyacc) + scope + entity.name.type.token.reference + settings + + fontStyle + + foreground + #3CB0D0 + + + + name + Non-terminal definition (ocamlyacc) + scope + entity.name.function.non-terminal + settings + + foreground + #90E0E0 + + + + name + Non-terminal reference (ocamlyacc) + scope + entity.name.function.non-terminal.reference + settings + + foreground + #C0F0F0 + + + + name + Tag name + scope + entity.name.tag + settings + + foreground + #009090 + + + + name + Tag attribute + scope + entity.other.attribute-name + settings + + + + name + Library function + settings + + background + #200020 + + + + name + Library constant + scope + support.constant + settings + + background + #200020 + + + + name + Library class/type + scope + support.type, support.class + settings + + + + name + Library variable + scope + support.other.variable + settings + + + + name + Invalid - illegal + scope + invalid.illegal + settings + + background + #FFFF00 + fontStyle + bold + foreground + #400080 + + + + name + Invalid - depricated + scope + invalid.deprecated + settings + + background + #CC66FF + foreground + #200020 + + + + name + Camlp4 code + scope + source.camlp4.embedded + settings + + background + #40008054 + + + + name + Camlp4 temp (parser) + scope + source.camlp4.embedded.parser.ocaml + settings + + fontStyle + + + + + name + Punctuation + scope + punctuation + settings + + foreground + #805080 + + + + uuid + 3C01FADD-7592-49DD-B7A5-1B82CA4E57B5 + + diff --git a/tool/tmthemes/Blackboard.tmTheme b/tool/tmthemes/Blackboard.tmTheme new file mode 100644 index 00000000..18bb72e3 --- /dev/null +++ b/tool/tmthemes/Blackboard.tmTheme @@ -0,0 +1,350 @@ + + + + + name + Blackboard + author + Domenico Carbotta + settings + + + settings + + background + #0C1021 + caret + #FFFFFFA6 + foreground + #F8F8F8 + invisibles + #FFFFFF40 + lineHighlight + #FFFFFF0F + selection + #253B76 + + + + name + Comment + scope + comment + settings + + fontStyle + + foreground + #AEAEAE + + + + name + Constant + scope + constant + settings + + fontStyle + + foreground + #D8FA3C + + + + name + Entity + scope + entity + settings + + fontStyle + + foreground + #FF6400 + + + + name + Keyword + scope + keyword + settings + + fontStyle + + foreground + #FBDE2D + + + + name + Storage + scope + storage + settings + + fontStyle + + foreground + #FBDE2D + + + + name + String + scope + string, meta.verbatim + settings + + fontStyle + + foreground + #61CE3C + + + + name + Support + scope + support + settings + + fontStyle + + foreground + #8DA6CE + + + + name + Variable + scope + variable + settings + + fontStyle + + + + + name + Invalid – Deprecated + scope + invalid.deprecated + settings + + fontStyle + italic + foreground + #AB2A1D + + + + name + Invalid – Illegal + scope + invalid.illegal + settings + + background + #9D1E15 + foreground + #F8F8F8 + + + + name + Superclass + scope + entity.other.inherited-class + settings + + fontStyle + italic + foreground + #FF6400 + + + + name + String interpolation + scope + string constant.other.placeholder + settings + + fontStyle + + foreground + #FF6400 + + + + name + meta.function-call.py + scope + meta.function-call.py + settings + + fontStyle + + foreground + #BECDE6 + + + + name + meta.tag + scope + meta.tag, meta.tag entity + settings + + foreground + #7F90AA + + + + name + entity.name.section + scope + entity.name.section + settings + + fontStyle + + foreground + #FFFFFF + + + + name + OCaml variant + scope + keyword.type.variant + settings + + foreground + #D5E0F3 + + + + name + OCaml operator + scope + source.ocaml keyword.operator.symbol + settings + + foreground + #F8F8F8 + + + + name + OCaml infix operator + scope + source.ocaml keyword.operator.symbol.infix + settings + + fontStyle + + foreground + #8DA6CE + + + + name + OCaml prefix operator + scope + source.ocaml keyword.operator.symbol.prefix + settings + + fontStyle + + foreground + #8DA6CE + + + + name + OCaml f-p infix operator + scope + source.ocaml keyword.operator.symbol.infix.floating-point + settings + + fontStyle + underline + + + + name + OCaml f-p prefix operator + scope + source.ocaml keyword.operator.symbol.prefix.floating-point + settings + + fontStyle + underline + + + + name + OCaml f-p constant + scope + source.ocaml constant.numeric.floating-point + settings + + fontStyle + underline + + + + name + LaTeX environment + scope + text.tex.latex meta.function.environment + settings + + background + #FFFFFF08 + + + + name + LaTeX environment (nested) + scope + text.tex.latex meta.function.environment meta.function.environment + settings + + background + #7A96FA08 + + + + name + Latex support + scope + text.tex.latex support.function + settings + + fontStyle + + foreground + #FBDE2D + + + + name + PList unquoted string + scope + source.plist string.unquoted, source.plist keyword.operator + settings + + foreground + #FFFFFF + + + + uuid + A2C6BAA7-90D0-4147-BBF5-96B0CD92D109 + + diff --git a/tool/tmthemes/Brilliance Black.tmTheme b/tool/tmthemes/Brilliance Black.tmTheme new file mode 100644 index 00000000..560c825b --- /dev/null +++ b/tool/tmthemes/Brilliance Black.tmTheme @@ -0,0 +1,2619 @@ + + + + + author + Thomas Aylott + comment + Thomas Aylott ㊷ subtleGradient.com + name + Brilliance Black + settings + + + settings + + background + #0D0D0DFA + caret + #3333FF + foreground + #EEEEEE + invisibles + #CCCCCC1A + lineHighlight + #00008033 + selection + #0010B499 + + + + name + Thomas Aylott ㊷ + scope + meta.thomas_aylott + settings + + background + #FFFFFF + fontStyle + bold + foreground + #000000 + + + + name + subtleGradient.com + scope + meta.subtlegradient + settings + + background + #FFFFFF + fontStyle + underline + foreground + #555555 + + + + name + ~ String + scope + string -meta.tag -meta.doctype -string.regexp -string.literal -string.interpolated -string.quoted.literal -string.unquoted, variable.parameter.misc.css, text string source string, string.unquoted string, string.regexp string, string.interpolated string, meta.tag source string + settings + + background + #803D0033 + foreground + #FFFC80 + + + + name + ~ String Punctuation + scope + punctuation.definition.string -meta.tag + settings + + foreground + #803D00 + + + + name + ~ String Punctuation II + scope + string.regexp punctuation.definition.string, string.quoted.literal punctuation.definition.string, string.quoted.double.ruby.mod punctuation.definition.string + settings + + foreground + #FFF80033 + + + + name + ~ String Literal + scope + string.quoted.literal, string.quoted.double.ruby.mod + settings + + background + #43800033 + foreground + #FFF800 + + + + name + ~ String Unquoted + scope + string.unquoted -string.unquoted.embedded, string.quoted.double.multiline, meta.scope.heredoc + settings + + foreground + #FFBC80 + + + + name + ~ String Interpolated + scope + string.interpolated + settings + + background + #1A1A1A + foreground + #FFFC80 + + + + name + ~ String RegEx + scope + string.regexp + settings + + background + #43800033 + foreground + #FFF800 + + + + name + ~ String RegEx Group 1 + scope + string.regexp.group + settings + + background + #43800033 + + + + name + ~ String RegEx Group 2 + scope + string.regexp.group string.regexp.group + settings + + background + #43800033 + foreground + #FFFFFF66 + + + + name + ~ String RegEx Group 3 + scope + string.regexp.group string.regexp.group string.regexp.group + settings + + background + #43800033 + foreground + #FFFFFF66 + + + + name + ~ String RegEx Group 4 + scope + string.regexp.group string.regexp.group string.regexp.group string.regexp.group + settings + + background + #43800033 + foreground + #FFFFFF66 + + + + name + ~ String RegEx Character-Class + scope + string.regexp.character-class + settings + + background + #43800033 + foreground + #86FF00 + + + + name + ~ String RegEx Arbitrary-Repitition + scope + string.regexp.arbitrary-repitition + settings + + background + #43800033 + foreground + #00FFF8 + + + + name + ~ String RegEx Definition Keyword + scope + string.regexp punctuation.definition.string keyword.other + settings + + fontStyle + + foreground + #803D00 + + + + name + ~ Meta Group Assertion Regexp + scope + meta.group.assertion.regexp + settings + + background + #0086FF33 + + + + name + ~ Meta Assertion + scope + meta.assertion, meta.group.assertion keyword.control.group.regexp, meta.group.assertion punctuation.definition.group + settings + + foreground + #0086FF + + + + name + ~ Number + scope + constant.numeric + settings + + foreground + #C6FF00 + + + + name + ~ Character constant + scope + constant.character + settings + + foreground + #86FF00 + + + + name + ~ Built-in constant + scope + constant.language, keyword.other.unit, constant.other.java, constant.other.unit + settings + + foreground + #07FF00 + + + + name + ~ Built-in constant+ + scope + constant.language.pseudo-variable + settings + + background + #04800033 + foreground + #07FF00 + + + + name + ~ User-defined constant + scope + constant.other, constant.block + settings + + foreground + #00FF79 + + + + name + ~ Library constant + scope + support.constant, constant.name + settings + + foreground + #00FFF8 + + + + name + ————————————————— + settings + + + + name + √ pre-defined variable + scope + variable.other.readwrite.global.pre-defined, variable.language + settings + + background + #00807C33 + foreground + #00FF79 + + + + name + √ Constant Variable + scope + variable.other.constant + settings + + foreground + #00FFF8 + + + + name + √ Library variable + scope + support.variable + settings + + background + #00807C33 + foreground + #00FFF8 + + + + name + √ global Variable + scope + variable.other.readwrite.global + settings + + background + #00438033 + foreground + #00807C + + + + name + √ Variable + scope + variable.other, variable.js, punctuation.separator.variable + settings + + foreground + #31A6FF + + + + name + √ class Variable + scope + variable.other.readwrite.class + settings + + background + #0008FF33 + foreground + #0086FF + + + + name + √ instance Variable + scope + variable.other.readwrite.instance + settings + + foreground + #406180 + + + + name + √ Normal Variables + scope + variable.other.php, variable.other.normal + settings + + foreground + #406180 + + + + name + √ Variable Punctuation + scope + punctuation.definition, punctuation.separator.variable + settings + + foreground + #00000080 + + + + name + ————————————————— + settings + + + + name + ¢ Storage + scope + storage -storage.modifier + settings + + foreground + #7E0080 + + + + name + ¢ Entity Name Preprocessor + scope + other.preprocessor, entity.name.preprocessor + settings + + background + #803D0033 + + + + name + ~ variable.language.this.js.prototype + scope + variable.language.this.js + settings + + foreground + #666666 + + + + name + ¢ Storage Modifier + scope + storage.modifier + settings + + foreground + #803D00 + + + + name + ¢ Class name + scope + entity.name.class, entity.name.type.class, entity.name.type.module + settings + + foreground + #FF0000 + + + + name + ¢ Class + scope + meta.class -meta.class.instance, declaration.class, meta.definition.class, declaration.module + settings + + background + #FF000033 + foreground + #870000 + + + + name + ¢ Library class/type + scope + support.type, support.class + settings + + background + #87000033 + foreground + #FF0000 + + + + name + ¢ Instance + scope + entity.name.instance, entity.name.type.instance + settings + + foreground + #FF3D44 + + + + name + ¢ Instance.constructor + scope + meta.class.instance.constructor + settings + + background + #831E5133 + + + + name + ¢ Inherited class + scope + entity.other.inherited-class, entity.name.module + settings + + background + #80000433 + foreground + #FF0086 + + + + name + ¢ Class Method + scope + meta.definition.method + settings + + foreground + #FF0086 + + + + name + ¢ Function Declaration + scope + meta.function, meta.property.function, declaration.function + settings + + + + name + ¢ Function Declaration Name + scope + entity.name.function, entity.name.preprocessor + settings + + foreground + #FF0086 + + + + name + ¢ Function Declaration Parameters + scope + variable.parameter.function + settings + + foreground + #9799FF + + + + name + ¢ Function Declaration Parameters + scope + variable.parameter -variable.parameter.misc.css, meta.definition.method meta.definition.param-list, meta.function.method.with-arguments variable.parameter.function + settings + + foreground + #9799FF + + + + name + ¢ Function Declaration Parameters Punctuation + scope + punctuation.definition.parameters, variable.parameter.function punctuation.separator.object + settings + + foreground + #800004 + + + + name + ™ Function Call + scope + keyword.other.special-method, meta.function-call entity.name.function -(meta.function-call meta.function), support.function - variable + settings + + foreground + #782EC1 + + + + name + ™ Library Function Call + scope + meta.function-call support.function - variable + settings + + fontStyle + + foreground + #9D3EFF + + + + name + ™ Library Function Name + scope + support.function + settings + + background + #603F8033 + foreground + #603F80 + + + + name + ™ Function Call Arguments Punctuation + scope + punctuation.section.function, meta.brace.curly.function, meta.function-call punctuation.section.scope.ruby, meta.function-call punctuation.separator.object + settings + + fontStyle + + foreground + #BC80FF + + + + name + ™ Function Punctuation + scope + meta.group.braces.round punctuation.section.scope, +meta.group.braces.round meta.delimiter.object.comma, +meta.group.braces.curly.function meta.delimiter.object.comma, +meta.brace.round + settings + + fontStyle + bold + foreground + #BC80FF + + + + name + ™ Function Call Without Arguments + scope + meta.function-call.method.without-arguments, meta.function-call.method.without-arguments entity.name.function + settings + + foreground + #A88FC0 + + + + name + ————————————————— + settings + + + + name + ™ Keyword Control + scope + keyword.control + settings + + foreground + #F800FF + + + + name + ™ Keyword + scope + keyword + settings + + + + name + ™ Keyword other + scope + keyword.other + settings + + foreground + #7900FF + + + + name + ™ Regex Keyword + scope + source.regexp keyword.operator + settings + + + + name + ™ Keyword Operator + scope + keyword.operator, declaration.function.operator, meta.preprocessor.c.include, punctuation.separator.operator + settings + + foreground + #0000CE + + + + name + ™ Keyword Operator Assignment + scope + keyword.operator.assignment + settings + + background + #00009A33 + foreground + #0000CE + + + + name + ™ Keyword Operator Arithmetic + scope + keyword.operator.arithmetic + settings + + foreground + #2136CE + + + + name + ™ Keyword Operator Logical + scope + keyword.operator.logical + settings + + background + #00009A33 + foreground + #3759FF + + + + name + ™ Keyword Operator Comparison + scope + keyword.operator.comparison + settings + + foreground + #7C88FF + + + + name + meta.class.instance.constructor keyword.operator.new + scope + meta.class.instance.constructor keyword.operator.new + settings + + foreground + #800043 + + + + name + ————————————————— + settings + + + + name + ✘ HTML + settings + + + + name + ✘ Tag Doctype + scope + meta.doctype, meta.tag.sgml-declaration.doctype, meta.tag.sgml.doctype + settings + + background + #333333 + foreground + #CCCCCC + + + + name + ✘ Tag + scope + meta.tag + settings + + foreground + #333333 + + + + name + ✘ Tag Structure + scope + meta.tag.structure, meta.tag.segment + settings + + background + #333333BF + foreground + #666666 + + + + name + ✘ Tag Block + scope + meta.tag.block, meta.tag.xml, meta.tag.key + settings + + background + #4C4C4C33 + foreground + #4C4C4C + + + + name + ✘ Tag Inline + scope + meta.tag.inline + settings + + background + #803D0033 + foreground + #FF7900 + + + + name + meta.tag.inline source + scope + meta.tag.inline source + settings + + background + #803D0033 + + + + name + ✘ Tag Other + scope + meta.tag.other, entity.name.tag.style, entity.name.tag.script, meta.tag.block.script, source.js.embedded punctuation.definition.tag.html, source.css.embedded punctuation.definition.tag.html + settings + + background + #80000433 + foreground + #FF0007 + + + + name + ✘ Tag Form + scope + meta.tag.form, meta.tag.block.form + settings + + background + #00438033 + foreground + #0086FF + + + + name + ✘ Tag Meta + scope + meta.tag.meta + settings + + background + #3C008033 + foreground + #F800FF + + + + name + ✘ Tag Block Head + scope + meta.section.html.head + settings + + background + #121212 + + + + name + ✘ Tag Block Form + scope + meta.section.html.form + settings + + background + #0043801A + + + + name + ✘ XML Tag + scope + meta.tag.xml + settings + + foreground + #666666 + + + + name + ✘ Tag name + scope + entity.name.tag + settings + + foreground + #FFFFFF4D + + + + name + ✘ Tag attribute + scope + entity.other.attribute-name, meta.tag punctuation.definition.string + settings + + foreground + #FFFFFF33 + + + + name + ✘ Tag value + scope + meta.tag string -source -punctuation, text source text meta.tag string -punctuation + settings + + foreground + #FFFFFF66 + + + + name + ————————————————— + settings + + + + name + text meta.paragraph + scope + text meta.paragraph + settings + + foreground + #999999 + + + + name + M markup + scope + markup markup -(markup meta.paragraph.list) + settings + + background + #33333333 + foreground + #FFF800 + + + + name + M HR + scope + markup.hr + settings + + background + #FFFFFF + foreground + #000000 + + + + name + M heading + scope + markup.heading + settings + + fontStyle + + foreground + #FFFFFF + + + + name + M bold + scope + markup.bold + settings + + fontStyle + bold + foreground + #95D4FF80 + + + + name + M italic + scope + markup.italic + settings + + fontStyle + italic + + + + name + M strike + settings + + + + name + M add + settings + + + + name + M del + settings + + + + name + M underline + scope + markup.underline + settings + + fontStyle + underline + + + + name + M reference + scope + meta.reference, markup.underline.link + settings + + fontStyle + + foreground + #0086FF + + + + name + M reference name + scope + entity.name.reference + settings + + background + #00438033 + foreground + #00FFF8 + + + + name + M underline link + scope + meta.reference.list markup.underline.link, text.html.textile markup.underline.link + settings + + fontStyle + underline + foreground + #00FFF8 + + + + name + M raw block + scope + markup.raw.block + settings + + background + #80808040 + + + + name + M quote block + scope + markup.quote + settings + + background + #FFFFFF1A + + + + name + M list + scope + markup.list meta.paragraph + settings + + fontStyle + + foreground + #FFFFFF + + + + name + ————————————————— + settings + + + + name + Markdown + scope + text.html.markdown + settings + + background + #FFFFFF + foreground + #000000 + + + + name + text.html.markdown meta.paragraph + scope + text.html.markdown meta.paragraph + settings + + foreground + #000000 + + + + name + text.html.markdown markup.list meta.paragraph + scope + text.html.markdown markup.list meta.paragraph + settings + + foreground + #555555 + + + + name + text.html.markdown markup.heading + scope + text.html.markdown markup.heading + settings + + fontStyle + bold + foreground + #000000 + + + + name + text.html.markdown string + scope + text.html.markdown string + settings + + foreground + #8A5420 + + + + name + ————————————————— + settings + + + + name + § CSS + scope + source.css + settings + + + + name + § Selector + scope + meta.selector + settings + + foreground + #666666 + + + + name + Property Value Parens + scope + source.css meta.scope.property-list meta.property-value punctuation.definition.arguments, +source.css meta.scope.property-list meta.property-value punctuation.separator.arguments + settings + + fontStyle + + foreground + #006680 + + + + name + § Pseudo-Element + scope + entity.other.attribute-name.pseudo-element + settings + + foreground + #4F00FF + + + + name + § Pseudo-Class + scope + entity.other.attribute-name.pseudo-class, entity.other.attribute-name.tag.pseudo-class + settings + + foreground + #7900FF + + + + name + § Class + scope + meta.selector entity.other.attribute-name.class + settings + + foreground + #F800FF + + + + name + § ID + scope + meta.selector entity.other.attribute-name.id + settings + + foreground + #FF0086 + + + + name + § Tag + scope + meta.selector entity.name.tag + settings + + fontStyle + + foreground + #FF0007 + + + + name + § Tag Wildcard + scope + entity.name.tag.wildcard, entity.other.attribute-name.universal + settings + + fontStyle + bold + foreground + #FF7900 + + + + name + § Attribute + scope + source.css entity.other.attribute-name.attribute + settings + + foreground + #C25A00 + + + + name + § Attribute-Match + scope + source.css meta.attribute-selector keyword.operator.comparison + settings + + foreground + #673000 + + + + name + § meta.scope.property-list + scope + meta.scope.property-list + settings + + fontStyle + bold + foreground + #333333 + + + + name + § meta.property-name + scope + meta.property-name + settings + + fontStyle + + foreground + #999999 + + + + name + § support.type.property-name + scope + support.type.property-name + settings + + background + #0D0D0D + fontStyle + + foreground + #FFFFFF + + + + name + § meta.property-value + scope + meta.property-value + settings + + background + #19191980 + fontStyle + + foreground + #999999 + + + + name + ————————————————— + settings + + + + name + LaTeX + scope + text.latex + settings + + + + name + L Markup Raw + scope + text.latex markup.raw + settings + + background + #000000 + + + + name + L support.function + scope + text.latex support.function -support.function.textit -support.function.emph + settings + + foreground + #BC80FF + + + + name + L support.function.section + scope + text.latex support.function.section + settings + + foreground + #FFFFFFBF + + + + name + L entity.name.section + scope + text.latex entity.name.section -meta.group -keyword.operator.braces + settings + + background + #FFFFFF + fontStyle + + foreground + #000000 + + + + name + L constant.language.general + scope + text.latex constant.language.general + settings + + + + name + L keyword.operator.delimiter + scope + text.latex keyword.operator.delimiter + settings + + background + #00000080 + + + + name + L keyword.operator.brackets + scope + text.latex keyword.operator.brackets + settings + + foreground + #999999 + + + + name + L keyword.operator.braces + scope + text.latex keyword.operator.braces + settings + + fontStyle + + foreground + #666666 + + + + name + L meta.footnote + scope + meta.footnote + settings + + background + #00008033 + foreground + #0008FF4D + + + + name + L meta.label.reference + scope + text.latex meta.label.reference + settings + + background + #FFFFFF0D + fontStyle + + + + + name + L keyword.control.ref + scope + text.latex keyword.control.ref + settings + + background + #260001 + foreground + #FF0007 + + + + name + L variable.parameter.label.reference + scope + text.latex variable.parameter.label.reference + settings + + background + #400002 + foreground + #FFBC80 + + + + name + L keyword.control.cite + scope + text.latex keyword.control.cite + settings + + background + #260014 + foreground + #FF0086 + + + + name + L variable.parameter.cite + scope + variable.parameter.cite + settings + + background + #400022 + foreground + #FFBFE1 + + + + name + L variable.parameter.label + scope + text.latex variable.parameter.label + settings + + foreground + #FFFFFF80 + + + + name + L markup + scope + meta.function markup + settings + + foreground + #CDCDCD + + + + name + L meta.group.braces + scope + text.latex meta.group.braces + settings + + foreground + #33333333 + + + + name + L meta.environment.list + scope + text.latex meta.environment.list + settings + + background + #00000080 + fontStyle + + foreground + #33333333 + + + + name + L meta.environment.list 2 + scope + text.latex meta.environment.list meta.environment.list + settings + + background + #00000080 + foreground + #33333333 + + + + name + L meta.environment.list 3 + scope + text.latex meta.environment.list meta.environment.list meta.environment.list + settings + + background + #000000 + foreground + #33333333 + + + + name + L meta.environment.list 4 + scope + text.latex meta.environment.list meta.environment.list meta.environment.list meta.environment.list + settings + + foreground + #33333333 + + + + name + L meta.environment.list 5 + scope + text.latex meta.environment.list meta.environment.list meta.environment.list meta.environment.list meta.environment.list + settings + + foreground + #33333333 + + + + name + L meta.environment.list 6 + scope + text.latex meta.environment.list meta.environment.list meta.environment.list meta.environment.list meta.environment.list meta.environment.list + settings + + foreground + #33333333 + + + + name + L meta.end-document + scope + text.latex meta.end-document, text.latex meta.begin-document, meta.end-document.latex support.function, meta.end-document.latex variable.parameter, meta.begin-document.latex support.function, meta.begin-document.latex variable.parameter + settings + + background + #CCCCCC + foreground + #000000 + + + + name + ————————————————— + settings + + + + name + meta.brace.erb.return-value + scope + meta.brace.erb.return-value + settings + + background + #00805533 + foreground + #00FFAA + + + + name + source.ruby.rails.embedded.return-value.one-line + scope + source.ruby.rails.embedded.return-value.one-line + settings + + background + #8080801A + + + + name + meta.brace.erb + scope + punctuation.section.embedded -(source string source punctuation.section.embedded), meta.brace.erb.html + settings + + background + #00FFF81A + foreground + #00FFF8 + + + + name + source.ruby.rails.embedded.one-line + scope + source.ruby.rails.embedded.one-line + settings + + background + #00FFF81A + + + + name + String Embedded Source + scope + source string source punctuation.section.embedded + settings + + foreground + #406180 + + + + name + source.js.embedded + scope + source.js.embedded + settings + + background + #0D0D0D + + + + name + ◊ Source + scope + source + settings + + fontStyle + + + + + name + ◊ meta.brace.erb + scope + meta.brace.erb + settings + + background + #000000 + + + + name + ◊ Source String Source + scope + source string source + settings + + background + #33333380 + foreground + #FFFFFF + + + + name + ◊ Source String Interpolated Source + scope + source string.interpolated source + settings + + background + #00000099 + foreground + #999999 + + + + name + ◊ Source Embeded Source + scope + source source, source.java.embedded + settings + + background + #3333331A + + + + name + ◊ Text + scope + text -text.xml.strict + settings + + foreground + #FFFFFF + + + + name + ◊ Text Source + scope + text source, meta.scope.django.template + settings + + background + #000000 + foreground + #CCCCCC + + + + name + ◊ Text Source Text String + settings + + + + name + ◊ Text String Source + scope + text string source + settings + + foreground + #999999 + + + + name + ◊ Text Source String Source + settings + + + + name + ◊ Text String Source String Source + scope + text string source string source + settings + + + + name + ————————————————— + settings + + + + name + Invalid + scope + invalid -invalid.SOMETHING + settings + + background + #FF0007 + fontStyle + bold + foreground + #330004 + + + + name + Invalid Value + scope + invalid.SOMETHING + settings + + fontStyle + underline + foreground + #FF3600 + + + + name + Syntax + scope + meta.syntax + settings + + foreground + #333333 + + + + name + comment + scope + comment -comment.line + settings + + background + #33333333 + foreground + #4C4C4C + + + + name + comment.line + scope + comment.line + settings + + fontStyle + italic + foreground + #4C4C4C + + + + name + Comment Punctuation + scope + comment punctuation + settings + + + + name + ✘ HTML Comment + scope + text comment.block -source + settings + + fontStyle + italic + + + + name + ————————————————— + settings + + + + name + D Diff Add + scope + markup.inserted + settings + + background + #00401E + foreground + #40FF9A + + + + name + D Diff Delete + scope + markup.deleted + settings + + background + #400022 + foreground + #FF40A3 + + + + name + D Diff Changed + scope + markup.changed + settings + + background + #803D00 + foreground + #FFFF55 + + + + name + text.subversion-commit meta.scope.changed-files + scope + text.subversion-commit meta.scope.changed-files, text.subversion-commit meta.scope.changed-files.svn meta.diff.separator + settings + + background + #000000 + foreground + #FFFFFF + + + + name + text.subversion-commit + scope + text.subversion-commit + settings + + background + #FFFFFF + foreground + #000000 + + + + name + ————————————————— + settings + + + + name + meta.delimiter + scope + punctuation.terminator, meta.delimiter, punctuation.separator.method + settings + + background + #FFFFFF03 + fontStyle + bold + foreground + #7F7F7F + + + + name + meta.delimiter.statement.js + scope + punctuation.terminator.statement, meta.delimiter.statement.js + settings + + background + #00000080 + + + + name + meta.delimiter.object.js + scope + meta.delimiter.object.js + settings + + background + #00000040 + + + + name + Bold String Quotes + scope + string.quoted.single.brace, string.quoted.double.brace + settings + + fontStyle + bold + foreground + #803D00 + + + + name + ————————————————— + settings + + + + name + ß Blog Post / Email Message + scope + text.blog, text.mail + settings + + background + #DCDCDC + foreground + #333333 + + + + name + ß Post Content + scope + text.blog text, text.mail text + settings + + background + #000000 + foreground + #CCCCCC + + + + name + ß Post Header Keys + scope + meta.header.blog keyword.other, meta.header.mail keyword.other + settings + + background + #00FFF81A + fontStyle + + foreground + #06403E + + + + name + ß Post Header Values + scope + meta.header.blog string.unquoted.blog, meta.header.mail string.unquoted + settings + + background + #FFFF551A + foreground + #803D00 + + + + name + ————————————————— + settings + + + + name + OCAML + settings + + + + name + entity.name.type.module + scope + source.ocaml entity.name.type.module + settings + + foreground + #FF0000 + + + + name + support.other.module + scope + source.ocaml support.other.module + settings + + background + #83000033 + foreground + #FF0000 + + + + name + entity.name.type.variant + scope + entity.name.type.variant + settings + + foreground + #00FFF8 + + + + name + entity.name.tag, meta.record.definition + scope + source.ocaml entity.name.tag, source.ocaml meta.record.definition + settings + + foreground + #00FF79 + + + + name + ———————— PUNCTUATION ———————— + settings + + + + name + punctuation.separator.parameters + scope + punctuation.separator.parameters + settings + + fontStyle + bold + foreground + #FFFFFF + + + + name + meta.brace.pipe + scope + meta.brace.pipe + settings + + background + #33333333 + fontStyle + + foreground + #4C4C4C + + + + name + Misc Punctuation + scope + meta.brace.erb, source.ruby.embedded.source.brace, punctuation.section.dictionary, punctuation.terminator.dictionary, punctuation.separator.object, punctuation.separator.statement, punctuation.separator.key-value.css + settings + + fontStyle + bold + foreground + #666666 + + + + name + Curly Punctuation + scope + punctuation.section.scope.curly, punctuation.section.scope + settings + + fontStyle + bold + foreground + #999999 + + + + name + Object Punctuation + scope + punctuation.separator.objects, +meta.group.braces.curly meta.delimiter.object.comma, +punctuation.separator.key-value -meta.tag, +source.ocaml punctuation.separator.match-definition + + settings + + fontStyle + bold + foreground + #0C823B + + + + name + Function Punctuation + scope + punctuation.separator.parameters.function.js,punctuation.definition.function, punctuation.separator.function-return, punctuation.separator.function-definition, punctuation.definition.arguments, punctuation.separator.arguments + settings + + foreground + #800043 + + + + name + Array Punctuation + scope + meta.group.braces.square punctuation.section.scope, meta.group.braces.square meta.delimiter.object.comma, meta.brace.square, punctuation.separator.array, punctuation.section.array, punctuation.definition.array, punctuation.definition.constant.range + settings + + background + #803D001A + fontStyle + bold + foreground + #7F5E40 + + + + name + Array, Range + scope + meta.structure.array -punctuation.definition.array, meta.definition.range -punctuation.definition.constant.range + settings + + background + #803D001A + + + + name + meta.brace.curly meta.group + scope + meta.brace.curly meta.group.css + settings + + background + #00000080 + fontStyle + + + + + name + º meta.source.embedded + scope + meta.source.embedded, entity.other.django.tagbraces + settings + + background + #00000080 + foreground + #666666 + + + + name + º meta.group.braces.round JS + scope + source.js meta.group.braces.round, meta.scope.heredoc + settings + + + + name + º Even + scope + source.ruby meta.even-tab, source.ruby meta.even-tab.group2, source.ruby meta.even-tab.group4, source.ruby meta.even-tab.group6, source.ruby meta.even-tab.group8, source.ruby meta.even-tab.group10, source.ruby meta.even-tab.group12 + + settings + + background + #00000080 + + + + name + º meta.block.slate + scope + meta.block.slate + settings + + foreground + #666666 + + + + name + º meta.block.content.slate + scope + meta.block.content.slate + settings + + foreground + #CCCCCC + + + + name + Function Group1 + scope + meta.function meta.group.braces.curly.function -(meta.group meta.group), meta.function meta.odd-tab.group1 + settings + + + + name + Group1 + scope + meta.odd-tab.group1, meta.group.braces, meta.block.slate, text.xml.strict meta.tag, meta.paren-group, meta.section + settings + + background + #0A0A0A + + + + name + Group2 + scope + meta.even-tab.group2, meta.group.braces meta.group.braces, meta.block.slate meta.block.slate, text.xml.strict meta.tag meta.tag, meta.group.braces meta.group.braces, meta.paren-group meta.paren-group, meta.section meta.section + settings + + background + #0E0E0E + + + + name + Group3 + scope + meta.odd-tab.group3, meta.group.braces meta.group.braces meta.group.braces , meta.block.slate meta.block.slate meta.block.slate , text.xml.strict meta.tag meta.tag meta.tag, meta.group.braces meta.group.braces meta.group.braces, meta.paren-group meta.paren-group meta.paren-group, meta.section meta.section meta.section + settings + + background + #111111 + + + + name + Group4 + scope + meta.even-tab.group4, meta.group.braces meta.group.braces meta.group.braces meta.group.braces , meta.block.slate meta.block.slate meta.block.slate meta.block.slate , text.xml.strict meta.tag meta.tag meta.tag meta.tag, meta.group.braces meta.group.braces meta.group.braces meta.group.braces, meta.paren-group meta.paren-group meta.paren-group meta.paren-group, meta.section meta.section meta.section meta.section + settings + + background + #151515 + + + + name + Group5 + scope + meta.odd-tab.group5, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces , meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate , text.xml.strict meta.tag meta.tag meta.tag meta.tag meta.tag, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces, meta.paren-group meta.paren-group meta.paren-group meta.paren-group meta.paren-group, meta.section meta.section meta.section meta.section meta.section + settings + + background + #191919 + + + + name + Group6 + scope + meta.even-tab.group6, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces , meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate , text.xml.strict meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces, meta.paren-group meta.paren-group meta.paren-group meta.paren-group meta.paren-group meta.paren-group, meta.section meta.section meta.section meta.section meta.section meta.section + settings + + background + #1C1C1C + + + + name + Group7 + scope + meta.odd-tab.group7, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces , meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate , text.xml.strict meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces, meta.paren-group meta.paren-group meta.paren-group meta.paren-group meta.paren-group meta.paren-group meta.paren-group, meta.section meta.section meta.section meta.section meta.section meta.section meta.section + settings + + background + #1F1F1F + + + + name + Group8 + scope + meta.even-tab.group8, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces , meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate , text.xml.strict meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces, meta.paren-group meta.paren-group meta.paren-group meta.paren-group meta.paren-group meta.paren-group meta.paren-group meta.paren-group, meta.section meta.section meta.section meta.section meta.section meta.section meta.section meta.section + settings + + background + #212121 + + + + name + Group9 + scope + meta.odd-tab.group9, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces , meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate , text.xml.strict meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces, meta.paren-group meta.paren-group meta.paren-group meta.paren-group meta.paren-group meta.paren-group meta.paren-group meta.paren-group meta.paren-group, meta.section meta.section meta.section meta.section meta.section meta.section meta.section meta.section meta.section + settings + + background + #242424 + + + + name + Group10 + scope + meta.even-tab.group10 + settings + + background + #1F1F1F + + + + name + Group11 + scope + meta.odd-tab.group11 + settings + + background + #151515 + + + + name + ———————— END ———————— + settings + + + + name + IE6 + scope + meta.property.vendor.microsoft.trident.4, +meta.property.vendor.microsoft.trident.4 support.type.property-name, +meta.property.vendor.microsoft.trident.4 punctuation.terminator.rule + settings + + fontStyle + + foreground + #1B95E2 + + + + name + IE7 + scope + meta.property.vendor.microsoft.trident.5, +meta.property.vendor.microsoft.trident.5 support.type.property-name, +meta.property.vendor.microsoft.trident.5 punctuation.separator.key-value, +meta.property.vendor.microsoft.trident.5 punctuation.terminator.rule + settings + + fontStyle + + foreground + #F5C034 + + + + uuid + 24847CB3-23BC-4BF9-861B-E39661A6DA71 + + diff --git a/tool/tmthemes/Brilliance Dull.tmTheme b/tool/tmthemes/Brilliance Dull.tmTheme new file mode 100644 index 00000000..39f90ae2 --- /dev/null +++ b/tool/tmthemes/Brilliance Dull.tmTheme @@ -0,0 +1,2243 @@ + + + + + author + Thomas Aylott + comment + by Thomas Aylott subtleGradient.com + name + Brilliance Dull + settings + + + settings + + background + #050505FA + caret + #7979B7 + foreground + #CDCDCD + invisibles + #CDCDCD1A + lineHighlight + #0000801A + selection + #2E2EE64D + + + + name + Thomas Aylott ㊷ + scope + meta.thomas_aylott + settings + + background + #FFFFFF + fontStyle + bold + foreground + #000000 + + + + name + subtleGradient.com + scope + meta.subtlegradient + settings + + background + #FFFFFF + fontStyle + underline + foreground + #555555 + + + + name + —————————————————— + scope + meta.subtlegradient + settings + + background + #FFFFFF + foreground + #E6E6E6 + + + + name + ~ String + scope + string -meta.tag -meta.doctype -string.regexp -string.literal -string.interpolated -string.quoted.literal -string.unquoted, variable.parameter.misc.css, text string source string, string.unquoted string, string.regexp string + settings + + background + #803D0033 + foreground + #D2D1AB + + + + name + ~ String Punctuation + scope + punctuation.definition.string -meta.tag + settings + + foreground + #533F2C + + + + name + ~ String Punctuation II + scope + string.regexp punctuation.definition.string, string.quoted.literal punctuation.definition.string, string.quoted.double.ruby.mod punctuation.definition.string + settings + + foreground + #FFF80033 + + + + name + ~ String Literal + scope + string.quoted.literal, string.quoted.double.ruby.mod + settings + + background + #43800033 + foreground + #A6A458 + + + + name + ~ String Unquoted + scope + string.unquoted -string.unquoted.embedded, string.quoted.double.multiline, meta.scope.heredoc + settings + + foreground + #D2BEAB + + + + name + ~ String Interpolated + scope + string.interpolated + settings + + background + #1A1A1A + foreground + #D2D1AB + + + + name + ~ String RegEx + scope + string.regexp + settings + + background + #43800033 + foreground + #A6A458 + + + + name + ~ String RegEx Group 1 + scope + string.regexp.group + settings + + background + #43800033 + + + + name + ~ String RegEx Group 2 + scope + string.regexp.group string.regexp.group + settings + + background + #43800033 + foreground + #FFFFFF66 + + + + name + ~ String RegEx Group 3 + scope + string.regexp.group string.regexp.group string.regexp.group + settings + + background + #43800033 + foreground + #FFFFFF66 + + + + name + ~ String RegEx Group 4 + scope + string.regexp.group string.regexp.group string.regexp.group string.regexp.group + settings + + background + #43800033 + foreground + #FFFFFF66 + + + + name + ~ String RegEx Character-Class + scope + string.regexp.character-class + settings + + background + #43800033 + foreground + #80A659 + + + + name + ~ String RegEx Arbitrary-Repitition + scope + string.regexp.arbitrary-repitition + settings + + background + #43800033 + foreground + #56A5A4 + + + + name + source.regexp keyword + scope + source.regexp keyword.operator + settings + + foreground + #A75980 + + + + name + ~ String RegEx Comment + scope + string.regexp comment + settings + + fontStyle + italic + foreground + #FFFFFF + + + + name + ~ Meta Group Assertion Regexp + scope + meta.group.assertion.regexp + settings + + background + #0086FF33 + + + + name + ~ Meta Assertion + scope + meta.assertion, meta.group.assertion keyword.control.group.regexp + settings + + foreground + #5780A6 + + + + name + ~ Number + scope + constant.numeric + settings + + foreground + #95A658 + + + + name + ~ Character constant + scope + constant.character + settings + + foreground + #80A659 + + + + name + ~ Built-in constant + scope + constant.language, keyword.other.unit, constant.other.java, constant.other.unit + settings + + foreground + #59A559 + + + + name + ~ Built-in constant+ + scope + constant.language.pseudo-variable + settings + + background + #04800033 + foreground + #59A559 + + + + name + ~ User-defined constant + scope + constant.other, constant.block + settings + + foreground + #57A57D + + + + name + ~ Library constant + scope + support.constant, constant.name + settings + + foreground + #56A5A4 + + + + name + ————————————————— + settings + + + + name + √ pre-defined variable + scope + variable.language, variable.other.readwrite.global.pre-defined + settings + + foreground + #5E6B6B + + + + name + √ Constant Variable + scope + variable.other.constant + settings + + foreground + #56A5A4 + + + + name + √ Library variable + scope + support.variable + settings + + background + #00807C33 + foreground + #56A5A4 + + + + name + √ global Variable + scope + variable.other.readwrite.global + settings + + background + #00438033 + foreground + #2B5252 + + + + name + √ Variable + scope + variable.other, variable.js + settings + + foreground + #5780A6 + + + + name + √ class Variable + scope + variable.other.readwrite.class + settings + + background + #0007FF33 + foreground + #5780A6 + + + + name + √ instance Variable + scope + variable.other.readwrite.instance + settings + + foreground + #555F69 + + + + name + √ Normal Variables + scope + variable.other.php, variable.other.normal + settings + + foreground + #555F69 + + + + name + √ Variable Punctuation + scope + punctuation.definition -punctuation.definition.comment, punctuation.separator.variable + settings + + foreground + #00000080 + + + + name + ————————————————— + settings + + + + name + ¢ Storage + scope + storage -storage.modifier + settings + + foreground + #A77D58 + + + + name + ¢ Entity Name Preprocessor + scope + other.preprocessor, entity.name.preprocessor + settings + + background + #803D0033 + + + + name + ~ variable.language.this.js.prototype + scope + variable.language.this.js + settings + + foreground + #666666 + + + + name + ¢ Storage Modifier + scope + storage.modifier + settings + + foreground + #533F2C + + + + name + ¢ Class name + scope + entity.name.class, entity.name.type.class, entity.name.type.module + settings + + foreground + #A7595A + + + + name + ¢ Class + scope + meta.class -meta.class.instance, declaration.class, meta.definition.class, declaration.module + settings + + background + #29161780 + foreground + #532D2D + + + + name + ¢ Library class/type + scope + support.type, support.class + settings + + background + #80000433 + foreground + #A7595A + + + + name + ¢ Instance + scope + entity.name.instance + settings + + foreground + #A7595A + + + + name + ¢ Instance.constructor + scope + meta.class.instance.constructor + settings + + background + #80004333 + + + + name + ¢ Inherited class + scope + entity.other.inherited-class, entity.name.module + settings + + background + #80000433 + foreground + #A75980 + + + + name + ¢ Class Method + scope + object.property.function, meta.definition.method + settings + + foreground + #A75980 + + + + name + ¢ Function + scope + meta.function -(meta.tell-block), meta.property.function, declaration.function + settings + + background + #80004333 + foreground + #532D40 + + + + name + ¢ Function name + scope + entity.name.function, entity.name.preprocessor + settings + + foreground + #A75980 + + + + name + ————————————————— + settings + + + + name + ™ Keyword + scope + keyword + settings + + foreground + #A459A5 + + + + name + ™ Keyword.control + scope + keyword.control + settings + + background + #3C008033 + foreground + #A459A5 + + + + name + ™ Special Function + scope + keyword.other.special-method, meta.function-call entity.name.function -(meta.function-call meta.function), support.function - variable + settings + + foreground + #8D809D + + + + name + ™ Library function + scope + support.function - variable + settings + + foreground + #634683 + + + + name + ™ Keyword.operator + scope + keyword.operator, declaration.function.operator, meta.preprocessor.c.include + settings + + fontStyle + bold + foreground + #7979B7 + + + + name + ™ keyword.operator.comparison + scope + keyword.operator.comparison + settings + + fontStyle + + foreground + #9899C8 + + + + name + ™ Function argument + scope + variable.parameter -variable.parameter.misc.css, meta.definition.method meta.definition.param-list, meta.function.method.with-arguments variable.parameter.function + settings + + background + #3C008033 + foreground + #ABACD2 + + + + name + ————————————————— + settings + + + + name + ✘ HTML + settings + + + + name + ✘ Tag Doctype + scope + meta.doctype, meta.tag.sgml-declaration.doctype, meta.tag.sgml.doctype + settings + + background + #333333 + foreground + #CDCDCD + + + + name + ✘ Tag + scope + meta.tag + settings + + foreground + #333333 + + + + name + ✘ Tag Structure + scope + meta.tag.structure, meta.tag.segment + settings + + background + #333333BF + foreground + #666666 + + + + name + ✘ Tag Block + scope + meta.tag.block, meta.tag.xml, meta.tag.key + settings + + background + #4C4C4C33 + foreground + #4C4C4C + + + + name + ✘ Tag Inline + scope + meta.tag.inline + settings + + background + #803D0033 + foreground + #A77D58 + + + + name + meta.tag.inline source + scope + meta.tag.inline source + settings + + background + #803D0033 + + + + name + ✘ Tag Other + scope + meta.tag.other, entity.name.tag.style, source entity.other.attribute-name -text.html.basic.embedded , entity.name.tag.script, meta.tag.block.script + settings + + background + #80000433 + foreground + #A7595A + + + + name + ✘ Tag Form + scope + meta.tag.form, meta.tag.block.form + settings + + background + #00438033 + foreground + #5780A6 + + + + name + ✘ Tag Meta + scope + meta.tag.meta + settings + + background + #3C008033 + foreground + #A459A5 + + + + name + ✘ Tag Block Head + scope + meta.section.html.head + settings + + background + #121212 + + + + name + ✘ Tag Block Form + scope + meta.section.html.form + settings + + background + #0043801A + + + + name + ✘ XML Tag + scope + meta.tag.xml + settings + + foreground + #666666 + + + + name + ✘ Tag name + scope + entity.name.tag + settings + + foreground + #FFFFFF4D + + + + name + ✘ Tag attribute + scope + entity.other.attribute-name, meta.tag punctuation.definition.string + settings + + foreground + #FFFFFF33 + + + + name + ✘ Tag value + scope + meta.tag string -source -punctuation, text source text meta.tag string -punctuation + settings + + foreground + #FFFFFF66 + + + + name + ————————————————— + settings + + + + name + M markdown + settings + + + + name + M markup + scope + markup markup -(markup meta.paragraph.list) + settings + + background + #33333333 + foreground + #A6A458 + + + + name + M HR + scope + markup.hr + settings + + background + #FFFFFF + foreground + #000000 + + + + name + M heading + scope + markup.heading + settings + + background + #33333380 + foreground + #666666 + + + + name + M bold + scope + markup.bold + settings + + fontStyle + bold + + + + name + M italic + scope + markup.italic + settings + + fontStyle + italic + + + + name + M strike + settings + + + + name + M add + settings + + + + name + M del + settings + + + + name + M underline + scope + markup.underline + settings + + fontStyle + underline + + + + name + M reference + scope + meta.reference, markup.underline.link + settings + + fontStyle + + foreground + #5780A6 + + + + name + M reference name + scope + entity.name.reference + settings + + background + #00438033 + foreground + #56A5A4 + + + + name + M underline link + scope + meta.reference.list markup.underline.link, text.html.textile markup.underline.link + settings + + fontStyle + underline + foreground + #56A5A4 + + + + name + M raw block + scope + markup.raw.block + settings + + background + #000000 + foreground + #999999 + + + + name + M quote block + scope + markup.quote + settings + + background + #FFFFFF1A + + + + name + ————————————————— + settings + + + + name + § CSS + scope + source.css + settings + + + + name + § Selector + scope + meta.selector + settings + + background + #00000080 + foreground + #666666 + + + + name + § Attribute-Match + scope + meta.attribute-match.css + settings + + background + #00048033 + foreground + #575AA6 + + + + name + § Pseudo-Class + scope + entity.other.attribute-name.pseudo-class, entity.other.attribute-name.tag.pseudo-class + settings + + foreground + #7C58A5 + + + + name + § Class + scope + meta.selector entity.other.attribute-name.class + settings + + foreground + #A459A5 + + + + name + § ID + scope + meta.selector entity.other.attribute-name.id + settings + + foreground + #A75980 + + + + name + § Tag + scope + meta.selector entity.name.tag + settings + + fontStyle + + foreground + #A7595A + + + + name + § Tag Wildcard + scope + entity.name.tag.wildcard, entity.other.attribute-name.universal + settings + + fontStyle + bold + foreground + #A77D58 + + + + name + § meta.scope.property-list + scope + meta.scope.property-list + settings + + fontStyle + bold + foreground + #333333 + + + + name + § meta.property-name + scope + meta.property-name + settings + + fontStyle + + foreground + #999999 + + + + name + § support.type.property-name + scope + support.type.property-name + settings + + background + #000000 + fontStyle + + foreground + #FFFFFF + + + + name + § meta.property-value + scope + meta.property-value + settings + + background + #0D0D0D + fontStyle + + foreground + #999999 + + + + name + ————————————————— + settings + + + + name + LaTeX + scope + text.latex + settings + + + + name + L Markup Raw + scope + text.latex markup.raw + settings + + background + #000000 + + + + name + L support.function + scope + text.latex support.function -support.function.textit -support.function.emph + settings + + foreground + #BDABD1 + + + + name + L support.function.section + scope + text.latex support.function.section + settings + + foreground + #FFFFFFBF + + + + name + L entity.name.section + scope + text.latex entity.name.section -meta.group -keyword.operator.braces + settings + + background + #FFFFFF + fontStyle + + foreground + #000000 + + + + name + L constant.language.general + scope + text.latex constant.language.general + settings + + + + name + L keyword.operator.delimiter + scope + text.latex keyword.operator.delimiter + settings + + background + #00000080 + + + + name + L keyword.operator.brackets + scope + text.latex keyword.operator.brackets + settings + + foreground + #999999 + + + + name + L keyword.operator.braces + scope + text.latex keyword.operator.braces + settings + + fontStyle + + foreground + #666666 + + + + name + L meta.footnote + scope + meta.footnote + settings + + background + #00048033 + foreground + #0008FF4D + + + + name + L meta.label.reference + scope + text.latex meta.label.reference + settings + + background + #FFFFFF0D + fontStyle + + + + + name + L keyword.control.ref + scope + text.latex keyword.control.ref + settings + + background + #180D0C + foreground + #A7595A + + + + name + L variable.parameter.label.reference + scope + text.latex variable.parameter.label.reference + settings + + background + #291616 + foreground + #D2BEAB + + + + name + L keyword.control.cite + scope + text.latex keyword.control.cite + settings + + background + #180D12 + foreground + #A75980 + + + + name + L variable.parameter.cite + scope + variable.parameter.cite + settings + + background + #29161F + foreground + #E8D5DE + + + + name + L variable.parameter.label + scope + text.latex variable.parameter.label + settings + + foreground + #FFFFFF80 + + + + name + L meta.group.braces + scope + text.latex meta.group.braces + settings + + foreground + #33333333 + + + + name + L meta.environment.list + scope + text.latex meta.environment.list + settings + + background + #00000080 + fontStyle + + foreground + #33333333 + + + + name + L meta.environment.list 2 + scope + text.latex meta.environment.list meta.environment.list + settings + + background + #00000080 + foreground + #33333333 + + + + name + L meta.environment.list 3 + scope + text.latex meta.environment.list meta.environment.list meta.environment.list + settings + + background + #000000 + foreground + #33333333 + + + + name + L meta.environment.list 4 + scope + text.latex meta.environment.list meta.environment.list meta.environment.list meta.environment.list + settings + + foreground + #33333333 + + + + name + L meta.environment.list 5 + scope + text.latex meta.environment.list meta.environment.list meta.environment.list meta.environment.list meta.environment.list + settings + + foreground + #33333333 + + + + name + L meta.environment.list 6 + scope + text.latex meta.environment.list meta.environment.list meta.environment.list meta.environment.list meta.environment.list meta.environment.list + settings + + foreground + #33333333 + + + + name + L meta.end-document + scope + text.latex meta.end-document, text.latex meta.begin-document, meta.end-document.latex support.function, meta.end-document.latex variable.parameter, meta.begin-document.latex support.function, meta.begin-document.latex variable.parameter + settings + + background + #CDCDCD + foreground + #000000 + + + + name + ————————————————— + settings + + + + name + meta.brace.erb.return-value + scope + meta.brace.erb.return-value + settings + + background + #45815D33 + foreground + #596B61 + + + + name + source.ruby.rails.embedded.return-value.one-line + scope + source.ruby.rails.embedded.return-value.one-line + settings + + background + #66666633 + + + + name + meta.brace.erb + scope + punctuation.section.embedded -(source string source punctuation.section.embedded), meta.brace.erb.html + settings + + background + #00FFF81A + foreground + #56A5A4 + + + + name + source.ruby.rails.embedded.one-line + scope + source.ruby.rails.embedded.one-line + settings + + background + #00FFF81A + + + + name + String Embedded Source + scope + source string source punctuation.section.embedded + settings + + foreground + #555F69 + + + + name + ◊ Source + scope + source + settings + + background + #000000 + fontStyle + + + + + name + ◊ meta.brace.erb + scope + meta.brace.erb + settings + + background + #000000 + + + + name + ◊ Source String Source + scope + source string source + settings + + background + #33333380 + foreground + #FFFFFF + + + + name + ◊ Source String Interpolated Source + scope + source string.interpolated source + settings + + background + #00000099 + foreground + #999999 + + + + name + ◊ Source Embeded Source + scope + source.java.embedded + settings + + background + #3333331A + + + + name + ◊ Text + scope + text -text.xml.strict + settings + + foreground + #FFFFFF + + + + name + ◊ Text Source + scope + text source, meta.scope.django.template + settings + + background + #000000 + foreground + #CCCCCC + + + + name + ◊ Text Source Text String + settings + + + + name + ◊ Text String Source + scope + text string source + settings + + foreground + #999999 + + + + name + ◊ Text Source String Source + settings + + + + name + ◊ Text String Source String Source + scope + text string source string source + settings + + + + name + ————————————————— + settings + + + + name + Syntax + scope + meta.syntax + settings + + foreground + #333333 + + + + name + Invalid + scope + invalid + settings + + background + #A7595A + fontStyle + bold + foreground + #211211 + + + + name + Comment + scope + 0comment + settings + + background + #0000FF1A + fontStyle + italic + foreground + #8F8FC3 + + + + name + Comment Punctuation + scope + comment punctuation + settings + + fontStyle + bold + foreground + #0000FF1A + + + + name + comment + scope + comment + settings + + foreground + #333333 + + + + name + Comment Punctuation + scope + comment punctuation + settings + + background + #8080800D + fontStyle + bold italic + foreground + #262626 + + + + name + ✘ HTML Comment + scope + text comment.block -source + settings + + fontStyle + italic + + + + name + ————————————————— + settings + + + + name + D Diff Add + scope + markup.inserted + settings + + background + #15281F + foreground + #81BB9E + + + + name + D Diff Delete + scope + markup.deleted + settings + + background + #400021 + foreground + #BC839F + + + + name + D Diff Changed + scope + markup.changed + settings + + background + #533F2C + foreground + #C3C38F + + + + name + text.subversion-commit meta.scope.changed-files + scope + text.subversion-commit meta.scope.changed-files, text.subversion-commit meta.scope.changed-files.svn meta.diff.separator + settings + + background + #000000 + foreground + #FFFFFF + + + + name + text.subversion-commit + scope + text.subversion-commit + settings + + background + #FFFFFF + foreground + #000000 + + + + name + ————————————————— + settings + + + + name + meta.delimiter + scope + punctuation.terminator, meta.delimiter, punctuation.separator.method + settings + + background + #FFFFFF03 + fontStyle + bold + foreground + #FFFFFF + + + + name + meta.delimiter.statement.js + scope + punctuation.terminator.statement, meta.delimiter.statement.js + settings + + background + #000000BF + + + + name + meta.delimiter.object.js + scope + meta.delimiter.object.js + settings + + background + #00000040 + + + + name + Bold String Quotes + scope + string.quoted.single.brace, string.quoted.double.brace + settings + + fontStyle + bold + foreground + #533F2C + + + + name + ————————————————— + settings + + + + name + meta.headers.blog + scope + text.blog -(text.blog text) + settings + + background + #FFFFFF + + + + name + meta.headers.blog + scope + meta.headers.blog + settings + + background + #FFFFFF + foreground + #666666 + + + + name + meta.headers.blog keyword.other.blog + scope + meta.headers.blog keyword.other.blog + settings + + background + #00FFF81A + fontStyle + + foreground + #192B2A + + + + name + meta.headers.blog string.unquoted.blog + scope + meta.headers.blog string.unquoted.blog + settings + + background + #FFFF551A + foreground + #533F2C + + + + name + ————————————————— + settings + + + + name + meta.brace.pipe + scope + meta.brace.pipe + settings + + background + #33333333 + fontStyle + + foreground + #4C4C4C + + + + name + Misc Punctuation + scope + meta.brace.erb, source.ruby.embedded.source.brace, punctuation.section.dictionary, punctuation.terminator.dictionary, punctuation.separator.object + settings + + fontStyle + bold + foreground + #4C4C4C + + + + name + Curly Punctuation + scope + meta.group.braces.curly punctuation.section.scope, meta.brace.curly + settings + + fontStyle + bold + foreground + #FFFFFF + + + + name + Object Punctuation + scope + punctuation.separator.objects, meta.group.braces.curly meta.delimiter.object.comma, punctuation.separator.key-value -meta.tag + settings + + fontStyle + bold + foreground + #345743 + + + + name + Array Punctuation + scope + meta.group.braces.square punctuation.section.scope, meta.group.braces.square meta.delimiter.object.comma, meta.brace.square, punctuation.separator.array, punctuation.section.array + settings + + background + #803D001A + fontStyle + bold + foreground + #695F55 + + + + name + meta.brace.curly meta.group + scope + meta.brace.curly meta.group + settings + + background + #00000080 + fontStyle + + foreground + #CDCDCD + + + + name + Function Punctuation + scope + meta.group.braces.round punctuation.section.scope, meta.group.braces.round meta.delimiter.object.comma, meta.brace.round + settings + + fontStyle + bold + foreground + #532D40 + + + + name + meta.brace.curly.function + scope + punctuation.section.function, meta.brace.curly.function, meta.function-call punctuation.section.scope.ruby + settings + + background + #3C008033 + fontStyle + + foreground + #ABACD2 + + + + name + º meta.source.embedded + scope + meta.source.embedded, entity.other.django.tagbraces + settings + + background + #00000080 + foreground + #666666 + + + + name + º meta.group.braces.round JS + scope + source.js meta.group.braces.round, meta.scope.heredoc + settings + + + + name + º meta.group.braces 1 + scope + meta.odd-tab.group1, meta.group.braces, meta.block.slate, text.xml.strict meta.tag, meta.tell-block meta.tell-block + settings + + background + #0A0A0A + + + + name + º meta.group.braces 2 + scope + meta.even-tab.group2, meta.group.braces meta.group.braces, meta.block.slate meta.block.slate, text.xml.strict meta.tag meta.tag, meta.group.braces meta.group.braces, meta.tell-block meta.tell-block + settings + + background + #0E0E0E + + + + name + º meta.group.braces 3 + scope + meta.odd-tab.group3, meta.group.braces meta.group.braces meta.group.braces , meta.block.slate meta.block.slate meta.block.slate , text.xml.strict meta.tag meta.tag meta.tag, meta.group.braces meta.group.braces meta.group.braces, meta.tell-block meta.tell-block meta.tell-block + settings + + background + #111111 + + + + name + º meta.group.braces 4 + scope + meta.even-tab.group4, meta.group.braces meta.group.braces meta.group.braces meta.group.braces , meta.block.slate meta.block.slate meta.block.slate meta.block.slate , text.xml.strict meta.tag meta.tag meta.tag meta.tag, meta.group.braces meta.group.braces meta.group.braces meta.group.braces, meta.tell-block meta.tell-block meta.tell-block meta.tell-block + settings + + background + #151515 + + + + name + º meta.group.braces 5 + scope + meta.odd-tab.group5, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces , meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate , text.xml.strict meta.tag meta.tag meta.tag meta.tag meta.tag, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces, meta.tell-block meta.tell-block meta.tell-block meta.tell-block meta.tell-block + settings + + background + #191919 + + + + name + º meta.group.braces 6 + scope + meta.even-tab.group6, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces , meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate , text.xml.strict meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces, meta.tell-block meta.tell-block meta.tell-block meta.tell-block meta.tell-block meta.tell-block + settings + + background + #1C1C1C + + + + name + º meta.group.braces 7 + scope + meta.odd-tab.group7, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces , meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate , text.xml.strict meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces, meta.tell-block meta.tell-block meta.tell-block meta.tell-block meta.tell-block meta.tell-block meta.tell-block + settings + + background + #1F1F1F + + + + name + º meta.group.braces 8 + scope + meta.even-tab.group8, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces , meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate , text.xml.strict meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces, meta.tell-block meta.tell-block meta.tell-block meta.tell-block meta.tell-block meta.tell-block meta.tell-block meta.tell-block + settings + + background + #212121 + + + + name + º meta.group.braces 9 + scope + meta.odd-tab.group11, meta.odd-tab.group10, meta.odd-tab.group9, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces , meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate meta.block.slate , text.xml.strict meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag meta.tag, meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces meta.group.braces, meta.tell-block meta.tell-block meta.tell-block meta.tell-block meta.tell-block meta.tell-block meta.tell-block meta.tell-block meta.tell-block + settings + + background + #242424 + + + + name + º meta.block.slate + scope + meta.block.slate + settings + + foreground + #666666 + + + + name + º meta.block.content.slate + scope + meta.block.content.slate + settings + + foreground + #CDCDCD + + + + name + ————————————————— + settings + + + + uuid + 4535004C-927A-401A-A6D5-1C9AC89E24C6 + + diff --git a/tool/tmthemes/Clouds Midnight.tmTheme b/tool/tmthemes/Clouds Midnight.tmTheme new file mode 100644 index 00000000..1859deba --- /dev/null +++ b/tool/tmthemes/Clouds Midnight.tmTheme @@ -0,0 +1,361 @@ + + + + + name + Clouds Midnight + settings + + + settings + + background + #191919 + caret + #7DA5DC + foreground + #929292 + invisibles + #BFBFBF + lineHighlight + #D7D7D708 + selection + #000000 + + + + name + Comment + scope + comment + settings + + fontStyle + + foreground + #3C403B + + + + name + String + scope + string + settings + + fontStyle + + foreground + #5D90CD + + + + name + Number + scope + constant.numeric + settings + + foreground + #46A609 + + + + name + Built-in constant + scope + constant.language + settings + + fontStyle + + foreground + #39946A + + + + name + User-defined constant + scope + constant.character, constant.other + settings + + + + name + Variable + scope + variable.language, variable.other + settings + + fontStyle + + + + + name + Keyword + scope + keyword, support.constant.property-value, constant.other.color + settings + + fontStyle + + foreground + #927C5D + + + + name + Keyword -> Unit + scope + keyword.other.unit + settings + + foreground + #366F1A + + + + name + HTML Attribute + scope + entity.other.attribute-name.html + settings + + foreground + #A46763 + + + + name + Keyword -> Operator + scope + keyword.operator + settings + + foreground + #4B4B4B + + + + name + Storage + scope + storage + settings + + fontStyle + + foreground + #E92E2E + + + + name + Class name + scope + entity.name.class + settings + + fontStyle + + + + + name + Inherited class + scope + entity.other.inherited-class + settings + + fontStyle + + foreground + #858585 + + + + name + Function name + scope + entity.name.function + settings + + fontStyle + + + + + name + Function argument + scope + variable.parameter + settings + + + + name + Tag name + scope + entity.name.tag + settings + + fontStyle + + foreground + #606060 + + + + name + HTML Entity + scope + constant.character.entity + settings + + foreground + #A165AC + + + + name + JS Support Class + scope + support.class.js + settings + + foreground + #A165AC + + + + name + Tag attribute + scope + entity.other.attribute-name + settings + + fontStyle + + foreground + #606060 + + + + name + CSS Selector + scope + meta.selector.css, entity.name.tag.css, entity.other.attribute-name.id.css, entity.other.attribute-name.class.css + settings + + fontStyle + + foreground + #E92E2E + + + + name + CSS Property + scope + meta.property-name.css + settings + + foreground + #616161 + + + + name + Library function + scope + support.function + settings + + foreground + #E92E2E + + + + name + Library constant + scope + support.constant + settings + + + + name + Library class/type + scope + support.type, support.class + settings + + + + name + Library variable + scope + support.other.variable + settings + + fontStyle + + + + + name + Invalid + scope + invalid + settings + + background + #E92E2E + foreground + #FFFFFF + + + + name + Punctuation/Widgets + scope + punctuation.section.embedded + settings + + fontStyle + + foreground + #E92E2E + + + + name + Punctuation (Tags) + scope + punctuation.definition.tag + settings + + fontStyle + + foreground + #606060 + + + + name + Keyword -> CSS + scope + constant.other.color.rgb-value.css, support.constant.property-value.css + settings + + foreground + #A165AC + + + + uuid + E5304455-0AC7-4082-8E62-5FD1B3313EEC + + diff --git a/tool/tmthemes/Clouds.tmTheme b/tool/tmthemes/Clouds.tmTheme new file mode 100644 index 00000000..821476be --- /dev/null +++ b/tool/tmthemes/Clouds.tmTheme @@ -0,0 +1,348 @@ + + + + + name + Clouds + settings + + + settings + + background + #FFFFFF + caret + #000000 + foreground + #000000 + invisibles + #BFBFBF + lineHighlight + #FFFBD1 + selection + #BDD5FC + + + + name + Comment + scope + comment + settings + + fontStyle + + foreground + #BCC8BA + + + + name + String + scope + string + settings + + fontStyle + + foreground + #5D90CD + + + + name + Number + scope + constant.numeric + settings + + foreground + #46A609 + + + + name + Built-in constant + scope + constant.language + settings + + fontStyle + + foreground + #39946A + + + + name + User-defined constant + scope + constant.character, constant.other + settings + + + + name + Variable + scope + variable.language, variable.other + settings + + fontStyle + + + + + name + Keyword + scope + keyword, support.constant.property-value, constant.other.color + settings + + fontStyle + + foreground + #AF956F + + + + name + Keyword -> Unit + scope + keyword.other.unit + settings + + foreground + #96DC5F + + + + name + Keyword -> Operator + scope + keyword.operator + settings + + foreground + #484848 + + + + name + Storage + scope + storage + settings + + fontStyle + + foreground + #C52727 + + + + name + Class name + scope + entity.name.class + settings + + fontStyle + + + + + name + Inherited class + scope + entity.other.inherited-class + settings + + fontStyle + + foreground + #858585 + + + + name + Function name + scope + entity.name.function + settings + + fontStyle + + + + + name + Function argument + scope + variable.parameter + settings + + + + name + Tag name + scope + entity.name.tag + settings + + fontStyle + + foreground + #606060 + + + + name + HTML Entity + scope + constant.character.entity + settings + + foreground + #BF78CC + + + + name + JS Support Class + scope + support.class.js + settings + + foreground + #BF78CC + + + + name + Tag attribute + scope + entity.other.attribute-name + settings + + fontStyle + + foreground + #606060 + + + + name + CSS Selector + scope + meta.selector.css, entity.name.tag.css, entity.other.attribute-name.id.css, entity.other.attribute-name.class.css + settings + + fontStyle + + foreground + #C52727 + + + + name + CSS Property + scope + meta.property-name.css + settings + + foreground + #484848 + + + + name + Library function + scope + support.function + settings + + foreground + #C52727 + + + + name + Library constant + scope + support.constant + settings + + + + name + Library class/type + scope + support.type, support.class + settings + + + + name + Library variable + scope + support.other.variable + settings + + fontStyle + + + + + name + Invalid + scope + invalid + settings + + background + #FF002A + + + + name + Punctuation/Widgets + scope + punctuation.section.embedded + settings + + fontStyle + + foreground + #C52727 + + + + name + Punctuation (Tags) + scope + punctuation.definition.tag + settings + + fontStyle + + foreground + #606060 + + + + name + Keyword -> CSS + scope + constant.other.color.rgb-value.css, support.constant.property-value.css + settings + + foreground + #BF78CC + + + + uuid + 47536290-6FC1-4B09-A08F-B219909E1A69 + + diff --git a/tool/tmthemes/Cobalt.tmTheme b/tool/tmthemes/Cobalt.tmTheme new file mode 100644 index 00000000..3c685f25 --- /dev/null +++ b/tool/tmthemes/Cobalt.tmTheme @@ -0,0 +1,559 @@ + + + + + author + Jacob Rus + comment + Created by Jacob Rus. Based on ‘Slate’ by Wilson Miner + name + Cobalt + settings + + + settings + + background + #002240 + caret + #FFFFFF + foreground + #FFFFFF + invisibles + #FFFFFF26 + lineHighlight + #00000059 + selection + #B36539BF + + + + name + Punctuation + scope + punctuation - (punctuation.definition.string | punctuation.definition.comment) + settings + + fontStyle + + foreground + #E1EFFF + + + + name + Constant + scope + constant + settings + + fontStyle + + foreground + #FF628C + + + + name + Entity + scope + entity + settings + + fontStyle + + foreground + #FFDD00 + + + + name + Keyword + scope + keyword + settings + + fontStyle + + foreground + #FF9D00 + + + + name + Storage + scope + storage + settings + + fontStyle + + foreground + #FFEE80 + + + + name + String + scope + string -string.unquoted.old-plist -string.unquoted.heredoc, string.unquoted.heredoc string + settings + + fontStyle + + foreground + #3AD900 + + + + name + Comment + scope + comment + settings + + fontStyle + italic + foreground + #0088FF + + + + name + Support + scope + support + settings + + fontStyle + + foreground + #80FFBB + + + + name + Variable + scope + variable + settings + + fontStyle + + foreground + #CCCCCC + + + + name + Lang Variable + scope + variable.language + settings + + fontStyle + + foreground + #FF80E1 + + + + name + Function Call + scope + meta.function-call + settings + + foreground + #FFEE80 + + + + name + Invalid + scope + invalid + settings + + background + #800F00 + foreground + #F8F8F8 + + + + name + Embedded Source + scope + text source, string.unquoted.heredoc, source source + settings + + background + #223545 + fontStyle + + foreground + #FFFFFF + + + + name + Entity inherited-class + scope + entity.other.inherited-class + settings + + fontStyle + italic + foreground + #80FCFF + + + + name + String embedded-source + scope + string.quoted source + settings + + fontStyle + + foreground + #9EFF80 + + + + name + String constant + scope + string constant + settings + + foreground + #80FF82 + + + + name + String.regexp + scope + string.regexp + settings + + foreground + #80FFC2 + + + + name + String variable + scope + string variable + settings + + foreground + #EDEF7D + + + + name + Support.function + scope + support.function + settings + + fontStyle + + foreground + #FFB054 + + + + name + Support.constant + scope + support.constant + settings + + fontStyle + + foreground + #EB939A + + + + name + Exception + scope + support.type.exception + settings + + foreground + #FF1E00 + + + + name + C/C++ Preprocessor Line + scope + meta.preprocessor.c + settings + + foreground + #8996A8 + + + + name + C/C++ Preprocessor Directive + scope + meta.preprocessor.c keyword + settings + + foreground + #AFC4DB + + + + name + Doctype/XML Processing + scope + meta.sgml.html meta.doctype, meta.sgml.html meta.doctype entity, meta.sgml.html meta.doctype string, meta.xml-processing, meta.xml-processing entity, meta.xml-processing string + settings + + foreground + #73817D + + + + name + Meta.tag.A + scope + meta.tag, meta.tag entity + settings + + foreground + #9EFFFF + + + + name + css tag-name + scope + meta.selector.css entity.name.tag + settings + + foreground + #9EFFFF + + + + name + css#id + scope + meta.selector.css entity.other.attribute-name.id + settings + + foreground + #FFB454 + + + + name + css.class + scope + meta.selector.css entity.other.attribute-name.class + settings + + foreground + #5FE461 + + + + name + css property-name: + scope + support.type.property-name.css + settings + + foreground + #9DF39F + + + + name + css property-value; + scope + meta.property-group support.constant.property-value.css, meta.property-value support.constant.property-value.css + settings + + foreground + #F6F080 + + + + name + css @at-rule + scope + meta.preprocessor.at-rule keyword.control.at-rule + settings + + foreground + #F6AA11 + + + + name + css additional-constants + scope + meta.property-value support.constant.named-color.css, meta.property-value constant + settings + + foreground + #EDF080 + + + + name + css constructor.argument + scope + meta.constructor.argument.css + settings + + foreground + #EB939A + + + + name + diff.header + scope + meta.diff, meta.diff.header + settings + + background + #000E1A + fontStyle + + foreground + #F8F8F8 + + + + name + diff.deleted + scope + markup.deleted + settings + + background + #4C0900 + foreground + #F8F8F8 + + + + name + diff.changed + scope + markup.changed + settings + + background + #806F00 + foreground + #F8F8F8 + + + + name + diff.inserted + scope + markup.inserted + settings + + background + #154F00 + foreground + #F8F8F8 + + + + name + Raw Markup + scope + markup.raw + settings + + background + #8FDDF630 + + + + name + Block Quote + scope + markup.quote + settings + + background + #004480 + + + + name + List + scope + markup.list + settings + + background + #130D26 + + + + name + Bold Markup + scope + markup.bold + settings + + fontStyle + bold + foreground + #C1AFFF + + + + name + Italic Markup + scope + markup.italic + settings + + fontStyle + italic + foreground + #B8FFD9 + + + + name + Heading Markup + scope + markup.heading + settings + + background + #001221 + fontStyle + bold + foreground + #C8E4FD + + + + uuid + 06CD1FB2-A00A-4F8C-97B2-60E131980454 + + diff --git a/tool/tmthemes/Dawn.tmTheme b/tool/tmthemes/Dawn.tmTheme new file mode 100644 index 00000000..12cff9b6 --- /dev/null +++ b/tool/tmthemes/Dawn.tmTheme @@ -0,0 +1,437 @@ + + + + + author + David Powers + comment + Dawn + name + Dawn + settings + + + settings + + background + #F9F9F9 + caret + #000000 + foreground + #080808 + invisibles + #4B4B7E80 + lineHighlight + #2463B41F + selection + #275FFF4D + + + + name + Comment + scope + comment + settings + + fontStyle + italic + foreground + #5A525F + + + + name + Constant + scope + constant + settings + + fontStyle + bold + foreground + #811F24 + + + + name + Entity + scope + entity + settings + + fontStyle + + foreground + #BF4F24 + + + + name + Keyword + scope + keyword + settings + + fontStyle + + foreground + #794938 + + + + name + Storage + scope + storage + settings + + fontStyle + italic + foreground + #A71D5D + + + + name + String + scope + string | punctuation.definition.string + settings + + fontStyle + + foreground + #0B6125 + + + + name + Support + scope + support + settings + + fontStyle + + foreground + #691C97 + + + + name + Variable + scope + variable + settings + + fontStyle + + foreground + #234A97 + + + + name + Punctuation.separator + scope + punctuation.separator + settings + + foreground + #794938 + + + + name + Invalid – Deprecated + scope + invalid.deprecated + settings + + fontStyle + bold italic underline + foreground + #B52A1D + + + + name + Invalid – Illegal + scope + invalid.illegal + settings + + background + #B52A1D + fontStyle + italic underline + foreground + #F8F8F8 + + + + name + String embedded-source + scope + string source + settings + + background + #6F8BBA26 + fontStyle + + foreground + #080808 + + + + name + String constant + scope + string constant + settings + + fontStyle + bold + foreground + #696969 + + + + name + String variable + scope + string variable + settings + + fontStyle + + foreground + #234A97 + + + + name + String.regexp + scope + string.regexp + settings + + fontStyle + + foreground + #CF5628 + + + + name + String.regexp.«special» + scope + string.regexp.character-class, string.regexp constant.character.escaped, string.regexp source.ruby.embedded, string.regexp string.regexp.arbitrary-repitition + settings + + fontStyle + bold italic + foreground + #CF5628 + + + + name + String.regexp constant.character.escape + scope + string.regexp constant.character.escape + settings + + fontStyle + bold + foreground + #811F24 + + + + name + Embedded Source + scope + text source + settings + + background + #6F8BBA26 + + + + name + Support.function + scope + support.function + settings + + fontStyle + + foreground + #693A17 + + + + name + Support.constant + scope + support.constant + settings + + fontStyle + + foreground + #B4371F + + + + name + Support.variable + scope + support.variable + settings + + foreground + #234A97 + + + + name + Markup.list + scope + markup.list + settings + + foreground + #693A17 + + + + name + Markup.heading + scope + markup.heading | markup.heading entity.name + settings + + fontStyle + bold + foreground + #19356D + + + + name + Markup.quote + scope + markup.quote + settings + + background + #BBBBBB30 + fontStyle + italic + foreground + #0B6125 + + + + name + Markup.italic + scope + markup.italic + settings + + fontStyle + italic + foreground + #080808 + + + + name + Markup.bold + scope + markup.bold + settings + + fontStyle + bold + foreground + #080808 + + + + name + Markup.underline + scope + markup.underline + settings + + fontStyle + underline + foreground + #080808 + + + + name + Markup.link + scope + markup.link + settings + + fontStyle + italic underline + foreground + #234A97 + + + + name + Markup.raw + scope + markup.raw + settings + + background + #BBBBBB30 + fontStyle + + foreground + #234A97 + + + + name + Markup.deleted + scope + markup.deleted + settings + + foreground + #59140E + + + + name + Meta.separator + scope + meta.separator + settings + + background + #DCDCDC + fontStyle + bold + foreground + #19356D + + + + uuid + E7E82498-F9EA-49A6-A0D8-12327EA46B01 + + diff --git a/tool/tmthemes/Eiffel.tmTheme b/tool/tmthemes/Eiffel.tmTheme new file mode 100644 index 00000000..1e8160c6 --- /dev/null +++ b/tool/tmthemes/Eiffel.tmTheme @@ -0,0 +1,439 @@ + + + + + name + Eiffel + author + Ian Joyner + settings + + + settings + + background + #FFFFFF + caret + #000000 + foreground + #000000 + invisibles + #BFBFBF + lineHighlight + #00000012 + selection + #C3DCFF + + + + name + Comment + scope + comment + settings + + fontStyle + + foreground + #00B418 + + + + name + Variable + scope + variable + settings + + fontStyle + italic + foreground + #0206FF + + + + name + Keyword + scope + keyword + settings + + fontStyle + bold + foreground + #0100B6 + + + + name + Number + scope + constant.numeric + settings + + fontStyle + italic + foreground + #CD0000 + + + + name + User-defined constant + scope + constant + settings + + fontStyle + italic + foreground + #C5060B + + + + name + Built-in constant + scope + constant.language + settings + + fontStyle + italic + foreground + #585CF6 + + + + name + String + scope + string + settings + + fontStyle + + foreground + #D80800 + + + + name + String interpolation + scope + constant.character.escape, string source + settings + + fontStyle + + foreground + #26B31A + + + + name + Preprocessor line + scope + meta.preprocessor + settings + + fontStyle + + foreground + #1A921C + + + + name + Preprocessor directive + scope + keyword.control.import + settings + + fontStyle + bold + foreground + #0C450D + + + + name + Function name + scope + entity.name.function, keyword.other.name-of-parameter.objc + settings + + fontStyle + bold + foreground + #0000A2 + + + + name + Type name + scope + entity.name.type + settings + + fontStyle + italic + + + + name + Inherited class name + scope + entity.other.inherited-class + settings + + fontStyle + italic + + + + name + Function parameter + scope + variable.parameter + settings + + fontStyle + italic + + + + name + Function argument and result types + scope + storage.type.method + settings + + fontStyle + + foreground + #70727E + + + + name + Section + scope + meta.section entity.name.section, declaration.section entity.name.section + settings + + fontStyle + italic + + + + name + Library function + scope + support.function + settings + + fontStyle + bold + foreground + #3C4C72 + + + + name + Library object + scope + support.class, support.type + settings + + fontStyle + bold + foreground + #6D79DE + + + + name + Library constant + scope + support.constant + settings + + fontStyle + bold + foreground + #06960E + + + + name + Library variable + scope + support.variable + settings + + fontStyle + bold + foreground + #21439C + + + + name + JS: Operator + scope + keyword.operator.js + settings + + foreground + #687687 + + + + name + Invalid + scope + invalid + settings + + background + #990000 + foreground + #FFFFFF + + + + name + Invalid trailing whitespace + scope + invalid.deprecated.trailing-whitespace + settings + + background + #FFD0D0 + + + + name + Embedded source + scope + text source, string.unquoted + settings + + background + #427FF530 + + + + name + Markup XML declaration + scope + meta.xml-processing, declaration.xml-processing + settings + + fontStyle + + foreground + #68685B + + + + name + Markup DOCTYPE + scope + meta.doctype, declaration.doctype + settings + + fontStyle + + foreground + #888888 + + + + name + Markup DTD + scope + meta.doctype.DTD, declaration.doctype.DTD + settings + + fontStyle + italic + + + + name + Markup tag + scope + meta.tag, declaration.tag + settings + + fontStyle + + foreground + #1C02FF + + + + name + Markup name of tag + scope + entity.name.tag + settings + + fontStyle + bold + + + + name + Markup tag attribute + scope + entity.other.attribute-name + settings + + fontStyle + italic + + + + name + Markup: Heading + scope + markup.heading + settings + + fontStyle + bold + foreground + #0C07FF + + + + name + Markup: Quote + scope + markup.quote + settings + + fontStyle + italic + foreground + #000000 + + + + name + Markup: List + scope + markup.list + settings + + foreground + #B90690 + + + + uuid + ADD7FDE7-C6BE-454B-A71A-7951ED54FB04 + + diff --git a/tool/tmthemes/Espresso Libre.tmTheme b/tool/tmthemes/Espresso Libre.tmTheme new file mode 100644 index 00000000..2ccae644 --- /dev/null +++ b/tool/tmthemes/Espresso Libre.tmTheme @@ -0,0 +1,402 @@ + + + + + author + Chris Thomas + name + Espresso Libre + settings + + + settings + + background + #2A211C + caret + #889AFF + foreground + #BDAE9D + invisibles + #BFBFBF + lineHighlight + #3A312C + selection + #C3DCFF + + + + name + Comment + scope + comment + settings + + fontStyle + italic + foreground + #0066FF + + + + name + Keyword + scope + keyword, storage + settings + + fontStyle + bold + foreground + #43A8ED + + + + name + Number + scope + constant.numeric + settings + + fontStyle + + foreground + #44AA43 + + + + name + User-defined constant + scope + constant + settings + + fontStyle + bold + foreground + #C5656B + + + + name + Built-in constant + scope + constant.language + settings + + fontStyle + bold + foreground + #585CF6 + + + + name + Variable + scope + variable.language, variable.other + settings + + fontStyle + + foreground + #318495 + + + + name + String + scope + string + settings + + fontStyle + + foreground + #049B0A + + + + name + String interpolation + scope + constant.character.escape, string source + settings + + fontStyle + + foreground + #2FE420 + + + + name + Preprocessor line + scope + meta.preprocessor + settings + + fontStyle + + foreground + #1A921C + + + + name + Preprocessor directive + scope + keyword.control.import + settings + + fontStyle + bold + foreground + #9AFF87 + + + + name + Function name + scope + entity.name.function, keyword.other.name-of-parameter.objc + settings + + fontStyle + bold + foreground + #FF9358 + + + + name + Type name + scope + entity.name.type + settings + + fontStyle + underline + + + + name + Inherited class name + scope + entity.other.inherited-class + settings + + fontStyle + italic + + + + name + Function parameter + scope + variable.parameter + settings + + fontStyle + italic + + + + name + Function argument and result types + scope + storage.type.method + settings + + fontStyle + + foreground + #8B8E9C + + + + name + Section + scope + meta.section entity.name.section, declaration.section entity.name.section + settings + + fontStyle + italic + + + + name + Library function + scope + support.function + settings + + fontStyle + bold + foreground + #7290D9 + + + + name + Library object + scope + support.class, support.type + settings + + fontStyle + bold + foreground + #6D79DE + + + + name + Library constant + scope + support.constant + settings + + fontStyle + bold + foreground + #00AF0E + + + + name + Library variable + scope + support.variable + settings + + fontStyle + bold + foreground + #2F5FE0 + + + + name + JS: Operator + scope + keyword.operator.js + settings + + foreground + #687687 + + + + name + Invalid + scope + invalid + settings + + background + #990000 + foreground + #FFFFFF + + + + name + Invalid trailing whitespace + scope + invalid.deprecated.trailing-whitespace + settings + + background + #FFD0D0 + + + + name + Embedded source + scope + text source, string.unquoted + settings + + background + #F5AA7730 + + + + name + Markup XML declaration + scope + meta.tag.preprocessor.xml + settings + + fontStyle + + foreground + #8F7E65 + + + + name + Markup DOCTYPE + scope + meta.tag.sgml.doctype + settings + + fontStyle + + foreground + #888888 + + + + name + Markup DTD + scope + string.quoted.docinfo.doctype.DTD + settings + + fontStyle + italic + + + + name + Markup tag + scope + meta.tag, declaration.tag + settings + + fontStyle + + foreground + #43A8ED + + + + name + Markup name of tag + scope + entity.name.tag + settings + + fontStyle + bold + + + + name + Markup tag attribute + scope + entity.other.attribute-name + settings + + fontStyle + italic + + + + uuid + 6B90703E-4E4B-43C8-9D32-921BEDF6D725 + + diff --git a/tool/tmthemes/IDLE.tmTheme b/tool/tmthemes/IDLE.tmTheme new file mode 100644 index 00000000..704296f5 --- /dev/null +++ b/tool/tmthemes/IDLE.tmTheme @@ -0,0 +1,235 @@ + + + + + author + Domenico Carbotta + name + IDLE + settings + + + settings + + background + #FFFFFF + caret + #000000 + foreground + #000000 + invisibles + #BFBFBF + lineHighlight + #00000012 + selection + #BAD6FD + + + + name + Comment + scope + comment + settings + + foreground + #919191 + + + + name + String + scope + string + settings + + foreground + #00A33F + + + + name + Number + scope + constant.numeric + settings + + + + name + Built-in constant + scope + constant.language + settings + + foreground + #A535AE + + + + name + User-defined constant + scope + constant.character, constant.other + settings + + + + name + Variable + scope + variable.language, variable.other + settings + + + + name + Keyword + scope + keyword + settings + + foreground + #FF5600 + + + + name + Storage + scope + storage + settings + + foreground + #FF5600 + + + + name + Type name + scope + entity.name.type + settings + + foreground + #21439C + + + + name + Inherited class + scope + entity.other.inherited-class + settings + + + + name + Function name + scope + entity.name.function + settings + + foreground + #21439C + + + + name + Function argument + scope + variable.parameter + settings + + + + name + Tag name + scope + entity.name.tag + settings + + + + name + Tag attribute + scope + entity.other.attribute-name + settings + + + + name + Library function + scope + support.function + settings + + foreground + #A535AE + + + + name + Library constant + scope + support.constant + settings + + foreground + #A535AE + + + + name + Library class/type + scope + support.type, support.class + settings + + foreground + #A535AE + + + + name + Library variable + scope + support.variable + settings + + foreground + #A535AE + + + + name + Invalid + scope + invalid + settings + + background + #990000 + foreground + #FFFFFF + + + + name + String interpolation + scope + constant.other.placeholder.py + settings + + fontStyle + + foreground + #990000 + + + + uuid + DDC0CBE1-442B-4CB5-80E4-26E4CFB3A277 + + diff --git a/tool/tmthemes/LAZY.tmTheme b/tool/tmthemes/LAZY.tmTheme new file mode 100644 index 00000000..09ff5111 --- /dev/null +++ b/tool/tmthemes/LAZY.tmTheme @@ -0,0 +1,291 @@ + + + + + author + Domenico Carbotta + name + LAZY + settings + + + settings + + background + #FFFFFF + caret + #7C7C7C + foreground + #000000 + invisibles + #B6B6B6 + lineHighlight + #EFFCA68F + selection + #E3FC8D + + + + name + Comment + scope + comment + settings + + fontStyle + + foreground + #8C868F + + + + name + Constant + scope + constant + settings + + fontStyle + + foreground + #3B5BB5 + + + + name + Entity + scope + entity + settings + + fontStyle + + foreground + #3B5BB5 + + + + name + Latex Entity + scope + text.tex.latex entity + settings + + fontStyle + + foreground + #D62A28 + + + + name + Keyword + scope + keyword, storage + settings + + fontStyle + + foreground + #FF7800 + + + + name + String + scope + string, meta.verbatim + settings + + fontStyle + + foreground + #409B1C + + + + name + Support + scope + support + settings + + fontStyle + + foreground + #3B5BB5 + + + + name + Variable + scope + variable + settings + + fontStyle + + + + + name + Invalid – Deprecated + scope + invalid.deprecated + settings + + fontStyle + italic + foreground + #990000 + + + + name + Invalid – Illegal + scope + invalid.illegal + settings + + background + #9D1E15 + foreground + #F8F8F8 + + + + name + Superclass + scope + entity.other.inherited-class + settings + + fontStyle + italic + foreground + #3B5BB5 + + + + name + String interpolation + scope + string constant.other.placeholder + settings + + fontStyle + + foreground + #671EBB + + + + name + meta.function-call.py + scope + meta.function-call.py + settings + + fontStyle + + foreground + #3E4558 + + + + name + meta.tag + scope + meta.tag, meta.tag entity + settings + + foreground + #3A4A64 + + + + name + OCaml variant + scope + keyword.type.variant + settings + + fontStyle + + foreground + #7F90AA + + + + name + OCaml operator + scope + source.ocaml keyword.operator + settings + + foreground + #000000 + + + + name + OCaml infix operator + scope + source.ocaml keyword.operator.symbol.infix + settings + + fontStyle + + foreground + #3B5BB5 + + + + name + OCaml prefix operator + scope + source.ocaml keyword.operator.symbol.prefix + settings + + foreground + #3B5BB5 + + + + name + OCaml infix f-p operator + scope + source.ocaml keyword.operator.symbol.infix.floating-point + settings + + fontStyle + underline + + + + name + OCaml prefix f-p operator + scope + source.ocaml keyword.operator.symbol.prefix.floating-point + settings + + fontStyle + underline + + + + name + OCaml f-p constant + scope + source.ocaml constant.numeric.floating-point + settings + + fontStyle + underline + + + + uuid + A1E55FCB-3CD2-4811-9E73-D9B87419443A + + diff --git a/tool/tmthemes/LICENSE b/tool/tmthemes/LICENSE new file mode 100644 index 00000000..08f1380f --- /dev/null +++ b/tool/tmthemes/LICENSE @@ -0,0 +1,8 @@ +If not otherwise specified (see below), files in this directory fall under the following license: + + Permission to copy, use, modify, sell and distribute this + software is granted. This software is provided "as is" without + express or implied warranty, and with no claim as to its + suitability for any purpose. + +An exception is made for files in readable text which contain their own license information, or files where an accompanying file exists (in the same directory) with a “-license” suffix added to the base-name name of the original file, and an extension of txt, html, or similar. For example “tidy” is accompanied by “tidy-license.txt”. \ No newline at end of file diff --git a/tool/tmthemes/Mac Classic.tmTheme b/tool/tmthemes/Mac Classic.tmTheme new file mode 100644 index 00000000..4b789dfe --- /dev/null +++ b/tool/tmthemes/Mac Classic.tmTheme @@ -0,0 +1,450 @@ + + + + + author + Chris Thomas + name + Mac Classic + settings + + + settings + + background + #FFFFFF + caret + #000000 + foreground + #000000 + invisibles + #BFBFBF + lineHighlight + #00000012 + selection + #4D97FF54 + + + + name + Comment + scope + comment + settings + + fontStyle + italic + foreground + #0066FF + + + + name + Keyword + scope + keyword, storage + settings + + fontStyle + bold + foreground + #0000FF + + + + name + Number + scope + constant.numeric + settings + + fontStyle + + foreground + #0000CD + + + + name + User-defined constant + scope + constant + settings + + fontStyle + bold + foreground + #C5060B + + + + name + Built-in constant + scope + constant.language + settings + + fontStyle + bold + foreground + #585CF6 + + + + name + Variable + scope + variable.language, variable.other + settings + + fontStyle + + foreground + #318495 + + + + name + String + scope + string + settings + + fontStyle + + foreground + #036A07 + + + + name + String interpolation + scope + constant.character.escape, string source + settings + + fontStyle + + foreground + #26B31A + + + + name + Preprocessor line + scope + meta.preprocessor + settings + + fontStyle + + foreground + #1A921C + + + + name + Preprocessor directive + scope + keyword.control.import + settings + + fontStyle + bold + foreground + #0C450D + + + + name + Function name + scope + entity.name.function, support.function.any-method + settings + + fontStyle + bold + foreground + #0000A2 + + + + name + Type name + scope + entity.name.type + settings + + fontStyle + underline + + + + name + Inherited class name + scope + entity.other.inherited-class + settings + + fontStyle + italic + + + + name + Function parameter + scope + variable.parameter + settings + + fontStyle + italic + + + + name + Function argument and result types + scope + storage.type.method + settings + + fontStyle + + foreground + #70727E + + + + name + Section + scope + meta.section entity.name.section, declaration.section entity.name.section + settings + + fontStyle + italic + + + + name + Library function + scope + support.function + settings + + fontStyle + bold + foreground + #3C4C72 + + + + name + Library object + scope + support.class, support.type + settings + + fontStyle + bold + foreground + #6D79DE + + + + name + Library constant + scope + support.constant + settings + + fontStyle + bold + foreground + #06960E + + + + name + Library variable + scope + support.variable + settings + + fontStyle + bold + foreground + #21439C + + + + name + JS: Operator + scope + keyword.operator.js + settings + + foreground + #687687 + + + + name + Invalid + scope + invalid + settings + + background + #990000 + foreground + #FFFFFF + + + + name + Invalid trailing whitespace + scope + invalid.deprecated.trailing-whitespace + settings + + background + #FFD0D0 + + + + name + Embedded source + scope + text source, string.unquoted + settings + + background + #0000000D + + + + name + Embedded embedded source + scope + text source string.unquoted, text source text source + settings + + background + #0000000F + + + + name + Markup XML declaration + scope + meta.tag.preprocessor.xml + settings + + fontStyle + + foreground + #68685B + + + + name + Markup DOCTYPE + scope + meta.tag.sgml.doctype, meta.tag.sgml.doctype entity, meta.tag.sgml.doctype string, meta.tag.preprocessor.xml, meta.tag.preprocessor.xml entity, meta.tag.preprocessor.xml string + settings + + fontStyle + + foreground + #888888 + + + + name + Markup DTD + scope + string.quoted.docinfo.doctype.DTD + settings + + fontStyle + italic + + + + name + Markup tag + scope + meta.tag, declaration.tag + settings + + fontStyle + + foreground + #1C02FF + + + + name + Markup name of tag + scope + entity.name.tag + settings + + fontStyle + bold + + + + name + Markup tag attribute + scope + entity.other.attribute-name + settings + + fontStyle + italic + + + + name + Markup: Heading + scope + markup.heading + settings + + fontStyle + bold + foreground + #0C07FF + + + + name + Markup: Quote + scope + markup.quote + settings + + fontStyle + italic + foreground + #000000 + + + + name + Markup: List + scope + markup.list + settings + + foreground + #B90690 + + + + uuid + 71D40D9D-AE48-11D9-920A-000D93589AF6 + + diff --git a/tool/tmthemes/MagicWB (Amiga).tmTheme b/tool/tmthemes/MagicWB (Amiga).tmTheme new file mode 100644 index 00000000..7897886b --- /dev/null +++ b/tool/tmthemes/MagicWB (Amiga).tmTheme @@ -0,0 +1,376 @@ + + + + + author + Allan Odgaard + comment + Inspired by the original 8 MagicWB colors from Martin Huttenloher + name + MagicWB (Amiga) + settings + + + settings + + background + #969696 + caret + #FFFFFF + foreground + #000000 + invisibles + #FF38FF + lineHighlight + #00000012 + selection + #B1B1B1 + + + + name + Comment + scope + comment + settings + + fontStyle + italic + foreground + #8D2E75 + + + + name + String + scope + string + settings + + background + #FF000033 + fontStyle + + foreground + #FFFFFF + + + + name + Number + scope + constant.numeric + settings + + foreground + #FFFFFF + + + + name + Constant: Built-in + scope + constant.language + settings + + fontStyle + bold + foreground + #FFA995 + + + + name + Constant: User-defined + scope + constant.character, constant.other + settings + + background + #0000FF33 + fontStyle + + foreground + #FFA995 + + + + name + Variable + scope + variable.language, variable.other + settings + + foreground + #FFA995 + + + + name + Keyword + scope + keyword + settings + + fontStyle + bold + + + + name + Storage + scope + storage + settings + + fontStyle + bold + foreground + #3A68A3 + + + + name + Type Name + scope + entity.name.type + settings + + fontStyle + underline + + + + name + Inherited Class + scope + entity.other.inherited-class + settings + + fontStyle + italic + + + + name + Function Name + scope + entity.name.function + settings + + fontStyle + + foreground + #FFA995 + + + + name + Function Argument + scope + variable.parameter + settings + + fontStyle + italic + + + + name + Entity Name + scope + entity.name + settings + + fontStyle + bold + foreground + #0000FF + + + + name + Tag Attribute + scope + entity.other.attribute-name + settings + + fontStyle + italic + foreground + #3A68A3 + + + + name + Library Function + scope + support.function + settings + + foreground + #E5B3FF + + + + name + Objective-C Method Call + scope + support.function.any-method + settings + + fontStyle + + foreground + #000000 + + + + name + Objective-C Method Call - : + scope + support.function.any-method - punctuation + settings + + fontStyle + italic + + + + name + Library Constant + scope + support.constant + settings + + foreground + #FFFFFF + + + + name + Library Class/Type + scope + support.type, support.class + settings + + foreground + #FFA995 + + + + name + Library Variable + scope + support.variable + settings + + foreground + #3A68A3 + + + + name + Invalid + scope + invalid + settings + + background + #797979 + foreground + #FFFFFF + + + + name + Include <system> + scope + string.quoted.other.lt-gt.include + settings + + background + #969696 + fontStyle + italic + foreground + #FFA995 + + + + name + Include "user" + scope + string.quoted.double.include + settings + + background + #969696 + foreground + #FFA995 + + + + name + Markup: List Item + scope + markup.list + settings + + foreground + #4D4E60 + + + + name + Markup: Raw + scope + markup.raw + settings + + background + #0000FF + foreground + #FFFFFF + + + + name + Markup: Quote (Email) + scope + markup.quote + settings + + foreground + #00F0C9 + + + + name + Markup: Quote Double (Email) + scope + markup.quote markup.quote + settings + + fontStyle + + foreground + #4C457E + + + + name + Embedded Source + scope + text.html source + settings + + background + #8A9ECB + + + + uuid + B0A18BAA-6220-481C-9914-F6D3E51B5410 + + diff --git a/tool/tmthemes/Monokai.tmTheme b/tool/tmthemes/Monokai.tmTheme new file mode 100644 index 00000000..fb01ff36 --- /dev/null +++ b/tool/tmthemes/Monokai.tmTheme @@ -0,0 +1,289 @@ + + + + + name + Monokai + settings + + + settings + + background + #272822 + caret + #F8F8F0 + foreground + #F8F8F2 + invisibles + #49483E + lineHighlight + #49483E + selection + #49483E + + + + name + Comment + scope + comment + settings + + foreground + #75715E + + + + name + String + scope + string + settings + + foreground + #E6DB74 + + + + name + Number + scope + constant.numeric + settings + + foreground + #AE81FF + + + + name + Built-in constant + scope + constant.language + settings + + foreground + #AE81FF + + + + name + User-defined constant + scope + constant.character, constant.other + settings + + foreground + #AE81FF + + + + name + Variable + scope + variable + settings + + fontStyle + + + + + name + Keyword + scope + keyword + settings + + foreground + #F92672 + + + + name + Storage + scope + storage + settings + + fontStyle + + foreground + #F92672 + + + + name + Storage type + scope + storage.type + settings + + fontStyle + italic + foreground + #66D9EF + + + + name + Class name + scope + entity.name.class + settings + + fontStyle + underline + foreground + #A6E22E + + + + name + Inherited class + scope + entity.other.inherited-class + settings + + fontStyle + italic underline + foreground + #A6E22E + + + + name + Function name + scope + entity.name.function + settings + + fontStyle + + foreground + #A6E22E + + + + name + Function argument + scope + variable.parameter + settings + + fontStyle + italic + foreground + #FD971F + + + + name + Tag name + scope + entity.name.tag + settings + + fontStyle + + foreground + #F92672 + + + + name + Tag attribute + scope + entity.other.attribute-name + settings + + fontStyle + + foreground + #A6E22E + + + + name + Library function + scope + support.function + settings + + fontStyle + + foreground + #66D9EF + + + + name + Library constant + scope + support.constant + settings + + fontStyle + + foreground + #66D9EF + + + + name + Library class/type + scope + support.type, support.class + settings + + fontStyle + italic + foreground + #66D9EF + + + + name + Library variable + scope + support.other.variable + settings + + fontStyle + + + + + name + Invalid + scope + invalid + settings + + background + #F92672 + fontStyle + + foreground + #F8F8F0 + + + + name + Invalid deprecated + scope + invalid.deprecated + settings + + background + #AE81FF + foreground + #F8F8F0 + + + + uuid + D8D5E82E-3D5B-46B5-B38E-8C841C21347D + + diff --git a/tool/tmthemes/Pastels on Dark.tmTheme b/tool/tmthemes/Pastels on Dark.tmTheme new file mode 100644 index 00000000..e3928606 --- /dev/null +++ b/tool/tmthemes/Pastels on Dark.tmTheme @@ -0,0 +1,701 @@ + + + + + author + Mats Persson + name + Pastels on Dark + settings + + + settings + + background + #211E1E + caret + #FFFFFF + foreground + #DADADA + invisibles + #4F4D4D + lineHighlight + #353030 + selection + #73597E80 + + + + name + Comments + scope + comment + settings + + fontStyle + + foreground + #555555 + + + + name + Comments Block + scope + comment.block + settings + + fontStyle + + foreground + #555555 + + + + name + Strings + scope + string + settings + + foreground + #AD9361 + + + + name + Numbers + scope + constant.numeric + settings + + fontStyle + + foreground + #CCCCCC + + + + name + Keywords + scope + keyword + settings + + fontStyle + + foreground + #A1A1FF + + + + name + Preprocessor Line + scope + meta.preprocessor + settings + + fontStyle + + foreground + #2F006E + + + + name + Preprocessor Directive + scope + keyword.control.import + settings + + fontStyle + bold + + + + name + Functions + scope + support.function + settings + + fontStyle + + foreground + #A1A1FF + + + + name + Function result + scope + declaration.function function-result + settings + + foreground + #0000FF + + + + name + Function name + scope + declaration.function function-name + settings + + fontStyle + bold + + + + name + Function argument name + scope + declaration.function argument-name + settings + + fontStyle + bold + + + + name + Function argument type + scope + declaration.function function-arg-type + settings + + foreground + #0000FF + + + + name + Function argument variable + scope + declaration.function function-argument + settings + + fontStyle + italic + + + + name + Class name + scope + declaration.class class-name + settings + + fontStyle + underline + + + + name + Class inheritance + scope + declaration.class class-inheritance + settings + + fontStyle + italic underline + + + + name + Invalid + scope + invalid + settings + + background + #FF0000 + fontStyle + bold + foreground + #FFF9F9 + + + + name + Invalid Trailing Whitespace + scope + invalid.deprecated.trailing-whitespace + settings + + background + #FFD0D0 + + + + name + Section + scope + declaration.section section-name + settings + + fontStyle + italic + + + + name + Interpolation + scope + string.interpolation + settings + + foreground + #C10006 + + + + name + Regular Expressions + scope + string.regexp + settings + + fontStyle + + foreground + #666666 + + + + name + Variables + scope + variable + settings + + foreground + #C1C144 + + + + name + Constants + scope + constant + settings + + foreground + #6782D3 + + + + name + Character Constants + scope + constant.character + settings + + fontStyle + + foreground + #AFA472 + + + + name + Language Constants + scope + constant.language + settings + + fontStyle + bold + foreground + #DE8E30 + + + + name + Embedded Code + scope + embedded + settings + + fontStyle + underline + + + + name + Tag name + scope + keyword.markup.element-name + settings + + fontStyle + + foreground + #858EF4 + + + + name + Attribute name + scope + keyword.markup.attribute-name + settings + + fontStyle + + foreground + #9B456F + + + + name + Attribute with Value + scope + meta.attribute-with-value + settings + + fontStyle + + foreground + #9B456F + + + + name + Exceptions + scope + keyword.exception + settings + + fontStyle + bold + foreground + #C82255 + + + + name + Operators + scope + keyword.operator + settings + + fontStyle + + foreground + #47B8D6 + + + + name + Control Structures + scope + keyword.control + settings + + fontStyle + bold + foreground + #6969FA + + + + name + HTML: DocInfo XML + scope + meta.tag.preprocessor.xml + settings + + foreground + #68685B + + + + name + HTML: DocType + scope + meta.tag.sgml.doctype + settings + + foreground + #888888 + + + + name + HTML: DocInfo DTD + scope + string.quoted.docinfo.doctype.DTD + settings + + fontStyle + italic + + + + name + HTML: ServerSide Includes + scope + comment.other.server-side-include.xhtml, comment.other.server-side-include.html + settings + + foreground + #909090 + + + + name + HTML: Tag + scope + text.html declaration.tag, text.html meta.tag, text.html entity.name.tag.xhtml + settings + + foreground + #858EF4 + + + + name + HTML: attribute="" + scope + keyword.markup.attribute-name + settings + + foreground + #9B456F + + + + name + PHP: PHPdocs + scope + keyword.other.phpdoc.php + settings + + foreground + #777777 + + + + name + PHP: Include() & Require() + scope + keyword.other.include.php + settings + + foreground + #C82255 + + + + name + PHP: Constants Core Predefined + scope + support.constant.core.php + settings + + fontStyle + bold + foreground + #DE8E20 + + + + name + PHP: Constants Standard Predefined + scope + support.constant.std.php + settings + + fontStyle + bold + foreground + #DE8E10 + + + + name + PHP: Variables Globals + scope + variable.other.global.php + settings + + foreground + #B72E1D + + + + name + PHP: Variables Safer Globals + scope + variable.other.global.safer.php + settings + + foreground + #00FF00 + + + + name + PHP: Strings Single-Quoted + scope + string.quoted.single.php + settings + + foreground + #BFA36D + + + + name + PHP: Keywords Storage + scope + keyword.storage.php + settings + + foreground + #6969FA + + + + name + PHP: Strings Double-Quoted + scope + string.quoted.double.php + settings + + foreground + #AD9361 + + + + name + CSS: Selectors #ID + scope + entity.other.attribute-name.id.css + settings + + foreground + #EC9E00 + + + + name + CSS: Selectors <Elements> + scope + entity.name.tag.css + settings + + fontStyle + bold + foreground + #B8CD06 + + + + name + CSS: Selectors .ClassName + scope + entity.other.attribute-name.class.css + settings + + foreground + #EDCA06 + + + + name + CSS: Selectors :PseudoClass + scope + entity.other.attribute-name.pseudo-class.css + settings + + foreground + #2E759C + + + + name + CSS: Invalid Comma + scope + invalid.bad-comma.css + settings + + background + #FF0000 + foreground + #FFFFFF + + + + name + CSS: Property Value + scope + support.constant.property-value.css + settings + + foreground + #9B2E4D + + + + name + CSS: Property Keyword + scope + support.type.property-name.css + settings + + foreground + #E1C96B + + + + name + CSS: Property Colours + scope + constant.other.rgb-value.css + settings + + foreground + #666633 + + + + name + CSS: Font Names + scope + support.constant.font-name.css + settings + + foreground + #666633 + + + + name + TMLangDef: Keys + scope + support.constant.tm-language-def, support.constant.name.tm-language-def + settings + + foreground + #7171F3 + + + + name + CSS: Units + scope + keyword.other.unit.css + settings + + foreground + #6969FA + + + + uuid + 343011CC-B7DF-11D9-B5C6-000D93C8BE28 + + diff --git a/tool/tmthemes/Slush and Poppies.tmTheme b/tool/tmthemes/Slush and Poppies.tmTheme new file mode 100644 index 00000000..02ecbcbe --- /dev/null +++ b/tool/tmthemes/Slush and Poppies.tmTheme @@ -0,0 +1,336 @@ + + + + + author + William D. Neumann + name + Slush & Poppies + settings + + + settings + + background + #F1F1F1 + caret + #000000 + foreground + #000000 + invisibles + #BFBFBF + lineHighlight + #00000026 + selection + #B0B0FF + + + + name + Comment + scope + comment + settings + + fontStyle + + foreground + #406040 + + + + name + String + scope + string + settings + + foreground + #C03030 + + + + name + Number + scope + constant.numeric + settings + + foreground + #0080A0 + + + + name + OCaml floating-point constants + scope + source.ocaml constant.numeric.floating-point + settings + + fontStyle + underline + + + + name + Character constants + scope + constant.character + settings + + foreground + #800000 + + + + name + Built-in constant + scope + constant.language + settings + + + + name + User-defined constant + scope + constant.character, constant.other + settings + + + + name + Variable + scope + variable.parameter, variable.other + settings + + + + name + Keyword + scope + keyword + settings + + fontStyle + + foreground + #2060A0 + + + + name + Operators + scope + keyword.operator + settings + + fontStyle + + foreground + #2060A0 + + + + name + OCaml prefix f-p operators + scope + source.ocaml keyword.operator.symbol.prefix.floating-point + settings + + fontStyle + underline + + + + name + OCaml infix f-p operators + scope + source.ocaml keyword.operator.symbol.infix.floating-point + settings + + fontStyle + underline + + + + name + Module Keyword + scope + entity.name.module, support.other.module + settings + + fontStyle + + foreground + #0080FF + + + + name + Storage types + scope + storage.type + settings + + foreground + #A08000 + + + + name + Storage + scope + storage + settings + + foreground + #008080 + + + + name + Variant types + scope + entity.name.class.variant + settings + + foreground + #C08060 + + + + name + Directives + scope + keyword.other.directive + settings + + fontStyle + bold + + + + name + Line-number directives + scope + source.ocaml keyword.other.directive.line-number + settings + + fontStyle + + + + + name + Inherited class + scope + entity.other.inherited-class + settings + + + + name + Function name + scope + entity.name.function + settings + + fontStyle + + foreground + #800000 + + + + name + Type name + scope + storage.type.user-defined + settings + + foreground + #800080 + + + + name + Class type name + scope + entity.name.type.class.type + settings + + foreground + #8000C0 + + + + name + Function argument + scope + variable.parameter + settings + + + + name + Tag name + scope + entity.name.tag + settings + + + + name + Tag attribute + scope + entity.other.attribute-name + settings + + + + name + Library function + scope + support.function + settings + + + + name + Library constant + scope + support.constant + settings + + + + name + Library class/type + scope + support.type, support.class + settings + + + + name + Library variable + scope + support.variable + settings + + + + name + Invalid + scope + invalid + settings + + + + uuid + D68685B8-1CFE-4C10-99C4-E21CBC892376 + + diff --git a/tool/tmthemes/SpaceCadet.tmTheme b/tool/tmthemes/SpaceCadet.tmTheme new file mode 100644 index 00000000..156f43de --- /dev/null +++ b/tool/tmthemes/SpaceCadet.tmTheme @@ -0,0 +1,212 @@ + + + + + author + Alex Ross + comment + Created by Alex Ross + name + SpaceCadet + settings + + + settings + + background + #0D0D0D + caret + #7F005D + foreground + #DDE6CF + invisibles + #BFBFBF + lineHighlight + #00000012 + selection + #40002F + + + + name + Comment + scope + comment + settings + + foreground + #473C45 + + + + name + String + scope + string + settings + + foreground + #805978 + + + + name + Constant + scope + constant + settings + + foreground + #A8885A + + + + name + Variable + scope + variable.parameter, variable.other + settings + + foreground + #596380 + + + + name + Keyword + scope + keyword - keyword.operator, keyword.operator.logical + settings + + foreground + #728059 + + + + name + Storage + scope + storage + settings + + foreground + #9EBF60 + + + + name + Entity + scope + entity + settings + + foreground + #6078BF + + + + name + Inherited class + scope + entity.other.inherited-class + settings + + fontStyle + italic + + + + name + Support + scope + support + settings + + foreground + #8A4B66 + + + + name + Exception + scope + support.type.exception + settings + + foreground + #893062 + + + + name + Tag name + scope + entity.name.tag + settings + + + + name + Tag attribute + scope + entity.other.attribute-name + settings + + + + name + Library constant + scope + support.constant + settings + + + + name + Library class/type + scope + support.type, support.class + settings + + + + name + Library variable + scope + support.other.variable + settings + + + + name + Invalid + scope + invalid + settings + + background + #5F0047 + + + + name + - Meta + settings + + + + name + function.section + scope + meta.function.section + settings + + background + #371D28 + + + + uuid + 2C24E84F-F9FE-4C2E-92D2-F52198BA7E41 + + diff --git a/tool/tmthemes/Sunburst.tmTheme b/tool/tmthemes/Sunburst.tmTheme new file mode 100644 index 00000000..694c2c8c --- /dev/null +++ b/tool/tmthemes/Sunburst.tmTheme @@ -0,0 +1,665 @@ + + + + + author + Stanley Rost + comment + (π) Soryu, 2005 + name + Sunburst + settings + + + settings + + background + #000000 + caret + #A7A7A7 + foreground + #F8F8F8 + invisibles + #CAE2FB3D + lineHighlight + #FFFFFF1A + selection + #DDF0FF33 + + + + name + Comment + scope + comment + settings + + fontStyle + italic + foreground + #AEAEAE + + + + name + Constant + scope + constant + settings + + foreground + #3387CC + + + + name + Entity + scope + entity + settings + + fontStyle + + foreground + #89BDFF + + + + name + Keyword + scope + keyword + settings + + fontStyle + + foreground + #E28964 + + + + name + Storage + scope + storage + settings + + fontStyle + + foreground + #99CF50 + + + + name + String + scope + string + settings + + fontStyle + + foreground + #65B042 + + + + name + Support + scope + support + settings + + fontStyle + + foreground + #9B859D + + + + name + Variable + scope + variable + settings + + foreground + #3E87E3 + + + + name + Invalid – Deprecated + scope + invalid.deprecated + settings + + fontStyle + italic underline + foreground + #FD5FF1 + + + + name + Invalid – Illegal + scope + invalid.illegal + settings + + background + #562D56BF + foreground + #FD5FF1 + + + + name + ----------------------------------- + settings + + + + name + ♦ Embedded Source (Bright) + scope + text source + settings + + background + #B1B3BA08 + + + + name + ♦ Entity inherited-class + scope + entity.other.inherited-class + settings + + fontStyle + italic + foreground + #9B5C2E + + + + name + ♦ String embedded-source + scope + string.quoted source + settings + + fontStyle + + foreground + #DAEFA3 + + + + name + ♦ String constant + scope + string constant + settings + + foreground + #DDF2A4 + + + + name + ♦ String.regexp + scope + string.regexp + settings + + foreground + #E9C062 + + + + name + ♦ String.regexp.«special» + scope + string.regexp constant.character.escape, string.regexp source.ruby.embedded, string.regexp string.regexp.arbitrary-repitition + settings + + foreground + #CF7D34 + + + + name + ♦ String variable + scope + string variable + settings + + foreground + #8A9A95 + + + + name + ♦ Support.function + scope + support.function + settings + + fontStyle + + foreground + #DAD085 + + + + name + ♦ Support.constant + scope + support.constant + settings + + fontStyle + + foreground + #CF6A4C + + + + name + c C/C++ Preprocessor Line + scope + meta.preprocessor.c + settings + + foreground + #8996A8 + + + + name + c C/C++ Preprocessor Directive + scope + meta.preprocessor.c keyword + settings + + foreground + #AFC4DB + + + + name + j Entity Name Type + scope + entity.name.type + settings + + fontStyle + underline + + + + name + j Cast + scope + meta.cast + settings + + fontStyle + italic + foreground + #676767 + + + + name + ✘ Doctype/XML Processing + scope + meta.sgml.html meta.doctype, meta.sgml.html meta.doctype entity, meta.sgml.html meta.doctype string, meta.xml-processing, meta.xml-processing entity, meta.xml-processing string + settings + + foreground + #494949 + + + + name + ✘ Meta.tag.«all» + scope + meta.tag, meta.tag entity + settings + + foreground + #89BDFF + + + + name + ✘ Meta.tag.inline + scope + source entity.name.tag, source entity.other.attribute-name, meta.tag.inline, meta.tag.inline entity + settings + + foreground + #E0C589 + + + + name + ✘ Namespaces + scope + entity.name.tag.namespace, entity.other.attribute-name.namespace + settings + + foreground + #E18964 + + + + name + § css tag-name + scope + meta.selector.css entity.name.tag + settings + + foreground + #CDA869 + + + + name + § css:pseudo-class + scope + meta.selector.css entity.other.attribute-name.tag.pseudo-class + settings + + foreground + #8F9D6A + + + + name + § css#id + scope + meta.selector.css entity.other.attribute-name.id + settings + + foreground + #8B98AB + + + + name + § css.class + scope + meta.selector.css entity.other.attribute-name.class + settings + + foreground + #9B703F + + + + name + § css property-name: + scope + support.type.property-name.css + settings + + foreground + #C5AF75 + + + + name + § css property-value; + scope + meta.property-group support.constant.property-value.css, meta.property-value support.constant.property-value.css + settings + + foreground + #F9EE98 + + + + name + § css @at-rule + scope + meta.preprocessor.at-rule keyword.control.at-rule + settings + + foreground + #8693A5 + + + + name + § css additional-constants + scope + meta.property-value support.constant.named-color.css, meta.property-value constant + settings + + foreground + #DD7B3B + + + + name + § css constructor.argument + scope + meta.constructor.argument.css + settings + + foreground + #8F9D6A + + + + name + ⎇ diff.header + scope + meta.diff, meta.diff.header + settings + + background + #0E2231 + fontStyle + italic + foreground + #F8F8F8 + + + + name + ⎇ diff.deleted + scope + markup.deleted + settings + + background + #420E09 + foreground + #F8F8F8 + + + + name + ⎇ diff.changed + scope + markup.changed + settings + + background + #4A410D + foreground + #F8F8F8 + + + + name + ⎇ diff.inserted + scope + markup.inserted + settings + + background + #253B22 + foreground + #F8F8F8 + + + + name + -------------------------------- + settings + + + + name + Markup: Italic + scope + markup.italic + settings + + fontStyle + italic + foreground + #E9C062 + + + + name + Markup: Bold + scope + markup.bold + settings + + fontStyle + bold + foreground + #E9C062 + + + + name + Markup: Underline + scope + markup.underline + settings + + fontStyle + underline + foreground + #E18964 + + + + name + Markup: Quote + scope + markup.quote + settings + + background + #FEE09C12 + fontStyle + italic + foreground + #E1D4B9 + + + + name + Markup: Heading + scope + markup.heading, markup.heading entity + settings + + background + #632D04 + fontStyle + + foreground + #FEDCC5 + + + + name + Markup: List + scope + markup.list + settings + + foreground + #E1D4B9 + + + + name + Markup: Raw + scope + markup.raw + settings + + background + #B1B3BA08 + fontStyle + + foreground + #578BB3 + + + + name + Markup: Comment + scope + markup comment + settings + + fontStyle + italic + foreground + #F67B37 + + + + name + Markup: Separator + scope + meta.separator + settings + + background + #242424 + foreground + #60A633 + + + + name + Log Entry + scope + meta.line.entry.logfile, meta.line.exit.logfile + settings + + background + #EEEEEE29 + + + + name + Log Entry Error + scope + meta.line.error.logfile + settings + + background + #751012 + + + + uuid + C8C58F9A-35FE-44A4-9BC2-2F3C343DC81D + + diff --git a/tool/tmthemes/Twilight.tmTheme b/tool/tmthemes/Twilight.tmTheme new file mode 100644 index 00000000..a83f7ecb --- /dev/null +++ b/tool/tmthemes/Twilight.tmTheme @@ -0,0 +1,514 @@ + + + + + author + Michael Sheets + name + Twilight + settings + + + settings + + background + #141414 + caret + #A7A7A7 + foreground + #F8F8F8 + invisibles + #FFFFFF40 + lineHighlight + #FFFFFF08 + selection + #DDF0FF33 + + + + name + Comment + scope + comment + settings + + fontStyle + italic + foreground + #5F5A60 + + + + name + Constant + scope + constant + settings + + foreground + #CF6A4C + + + + name + Entity + scope + entity + settings + + fontStyle + + foreground + #9B703F + + + + name + Keyword + scope + keyword + settings + + fontStyle + + foreground + #CDA869 + + + + name + Storage + scope + storage + settings + + fontStyle + + foreground + #F9EE98 + + + + name + String + scope + string + settings + + fontStyle + + foreground + #8F9D6A + + + + name + Support + scope + support + settings + + fontStyle + + foreground + #9B859D + + + + name + Variable + scope + variable + settings + + foreground + #7587A6 + + + + name + Invalid – Deprecated + scope + invalid.deprecated + settings + + fontStyle + italic underline + foreground + #D2A8A1 + + + + name + Invalid – Illegal + scope + invalid.illegal + settings + + background + #562D56BF + foreground + #F8F8F8 + + + + name + ----------------------------------- + settings + + + + name + ♦ Embedded Source + scope + text source + settings + + background + #B0B3BA14 + + + + name + ♦ Embedded Source (Bright) + scope + text.html.ruby source + settings + + background + #B1B3BA21 + + + + name + ♦ Entity inherited-class + scope + entity.other.inherited-class + settings + + fontStyle + italic + foreground + #9B5C2E + + + + name + ♦ String embedded-source + scope + string source + settings + + fontStyle + + foreground + #DAEFA3 + + + + name + ♦ String constant + scope + string constant + settings + + foreground + #DDF2A4 + + + + name + ♦ String.regexp + scope + string.regexp + settings + + fontStyle + + foreground + #E9C062 + + + + name + ♦ String.regexp.«special» + scope + string.regexp constant.character.escape, string.regexp source.ruby.embedded, string.regexp string.regexp.arbitrary-repitition + settings + + foreground + #CF7D34 + + + + name + ♦ String variable + scope + string variable + settings + + foreground + #8A9A95 + + + + name + ♦ Support.function + scope + support.function + settings + + fontStyle + + foreground + #DAD085 + + + + name + ♦ Support.constant + scope + support.constant + settings + + fontStyle + + foreground + #CF6A4C + + + + name + c C/C++ Preprocessor Line + scope + meta.preprocessor.c + settings + + foreground + #8996A8 + + + + name + c C/C++ Preprocessor Directive + scope + meta.preprocessor.c keyword + settings + + foreground + #AFC4DB + + + + name + ✘ Doctype/XML Processing + scope + meta.tag.sgml.doctype, meta.tag.sgml.doctype entity, meta.tag.sgml.doctype string, meta.tag.preprocessor.xml, meta.tag.preprocessor.xml entity, meta.tag.preprocessor.xml string + settings + + foreground + #494949 + + + + name + ✘ Meta.tag.«all» + scope + declaration.tag, declaration.tag entity, meta.tag, meta.tag entity + settings + + foreground + #AC885B + + + + name + ✘ Meta.tag.inline + scope + declaration.tag.inline, declaration.tag.inline entity, source entity.name.tag, source entity.other.attribute-name, meta.tag.inline, meta.tag.inline entity + settings + + foreground + #E0C589 + + + + name + § css tag-name + scope + meta.selector.css entity.name.tag + settings + + foreground + #CDA869 + + + + name + § css:pseudo-class + scope + meta.selector.css entity.other.attribute-name.tag.pseudo-class + settings + + foreground + #8F9D6A + + + + name + § css#id + scope + meta.selector.css entity.other.attribute-name.id + settings + + foreground + #8B98AB + + + + name + § css.class + scope + meta.selector.css entity.other.attribute-name.class + settings + + foreground + #9B703F + + + + name + § css property-name: + scope + support.type.property-name.css + settings + + foreground + #C5AF75 + + + + name + § css property-value; + scope + meta.property-group support.constant.property-value.css, meta.property-value support.constant.property-value.css + settings + + foreground + #F9EE98 + + + + name + § css @at-rule + scope + meta.preprocessor.at-rule keyword.control.at-rule + settings + + foreground + #8693A5 + + + + name + § css additional-constants + scope + meta.property-value support.constant.named-color.css, meta.property-value constant + settings + + foreground + #CA7840 + + + + name + § css constructor.argument + scope + meta.constructor.argument.css + settings + + foreground + #8F9D6A + + + + name + ⎇ diff.header + scope + meta.diff, meta.diff.header, meta.separator + settings + + background + #0E2231 + fontStyle + italic + foreground + #F8F8F8 + + + + name + ⎇ diff.deleted + scope + markup.deleted + settings + + background + #420E09 + foreground + #F8F8F8 + + + + name + ⎇ diff.changed + scope + markup.changed + settings + + background + #4A410D + foreground + #F8F8F8 + + + + name + ⎇ diff.inserted + scope + markup.inserted + settings + + background + #253B22 + foreground + #F8F8F8 + + + + name + Markup: List + scope + markup.list + settings + + foreground + #F9EE98 + + + + name + Markup: Heading + scope + markup.heading + settings + + foreground + #CF6A4C + + + + uuid + 766026CB-703D-4610-B070-8DE07D967C5F + + diff --git a/tool/tmthemes/Zenburnesque.tmTheme b/tool/tmthemes/Zenburnesque.tmTheme new file mode 100644 index 00000000..8631f986 --- /dev/null +++ b/tool/tmthemes/Zenburnesque.tmTheme @@ -0,0 +1,343 @@ + + + + + author + William D. Neumann + name + Zenburnesque + settings + + + settings + + background + #404040 + caret + #FFFF66 + foreground + #DEDEDE + invisibles + #A8A8A8 + lineHighlight + #A0804026 + selection + #A0A0C0 + + + + name + Comment + scope + comment + settings + + fontStyle + italic + foreground + #709070 + + + + name + Directive + scope + keyword.other.directive + settings + + fontStyle + bold + + + + name + Line-number directives + scope + keyword.other.directive.line-number + settings + + fontStyle + underline + + + + name + Characters + scope + constant.character + settings + + foreground + #FF8080 + + + + name + String + scope + string + settings + + foreground + #FF2020 + + + + name + Number + scope + constant.numeric + settings + + foreground + #22C0FF + + + + name + Floating-point numbers + scope + constant.numeric.floating-point + settings + + fontStyle + underline + + + + name + Built-in constant + scope + constant.language + settings + + + + name + User-defined constant + scope + constant.character, constant.other + settings + + + + name + Variable + scope + variable.parameter, variable.other + settings + + + + name + Language Keyword + scope + keyword + settings + + foreground + #FFFFA0 + + + + name + Module Keyword + scope + entity.name.module, support.other.module + settings + + fontStyle + bold + foreground + #FF8000 + + + + name + Operators + scope + keyword.operator + settings + + foreground + #FFFFA0 + + + + name + Floating-point infix operators + scope + source.ocaml keyword.operator.symbol.infix.floating-point + settings + + fontStyle + underline + + + + name + Floating-point prefix operators + scope + source.ocaml keyword.operator.symbol.prefix.floating-point + settings + + fontStyle + underline + + + + name + Storage Types + scope + storage.type + settings + + foreground + #6080FF + + + + name + Variant Types + scope + entity.name.class.variant + settings + + foreground + #4080A0 + + + + name + Storage + scope + storage + settings + + + + name + Type name + scope + entity.name.type + settings + + foreground + #F09040 + + + + name + Inherited class + scope + entity.other.inherited-class + settings + + + + name + Function name + scope + entity.name.function + settings + + fontStyle + bold + foreground + #FFCC66 + + + + name + Type name + scope + storage.type.user-defined + settings + + foreground + #FFE000 + + + + name + Class type name + scope + entity.name.type.class.type + settings + + foreground + #F4A020 + + + + name + Function argument + scope + variable.parameter + settings + + fontStyle + + + + + name + Tag name + scope + entity.name.tag + settings + + + + name + Tag attribute + scope + entity.other.attribute-name + settings + + + + name + Library function + scope + support.function + settings + + + + name + Library constant + scope + support.constant + settings + + + + name + Library class/type + scope + support.type, support.class + settings + + + + name + Library variable + scope + support.variable + settings + + + + name + Invalid + scope + invalid + settings + + + + uuid + 8D4988B9-ADD8-436F-B388-BC1360F8504B + + diff --git a/tool/tmthemes/iPlastic.tmTheme b/tool/tmthemes/iPlastic.tmTheme new file mode 100644 index 00000000..7253df6a --- /dev/null +++ b/tool/tmthemes/iPlastic.tmTheme @@ -0,0 +1,286 @@ + + + + + author + Jeroen van der Ham + name + iPlastic + settings + + + settings + + background + #EEEEEEEB + caret + #000000 + foreground + #000000 + invisibles + #B3B3B3F4 + lineHighlight + #0000001A + selection + #BAD6FD + + + + name + String + scope + string + settings + + foreground + #009933 + + + + name + Number + scope + constant.numeric + settings + + foreground + #0066FF + + + + name + Regular expression + scope + string.regexp + settings + + foreground + #FF0080 + + + + name + Keyword + scope + keyword + settings + + foreground + #0000FF + + + + name + Identifier + scope + constant.language + settings + + foreground + #9700CC + + + + name + Exception + scope + support.class.exception + settings + + foreground + #990000 + + + + name + Function name + scope + entity.name.function + settings + + foreground + #FF8000 + + + + name + Type name + scope + entity.name.type + settings + + fontStyle + bold underline + + + + name + Arguments + scope + variable.parameter + settings + + fontStyle + italic + + + + name + Comment + scope + comment + settings + + fontStyle + italic + foreground + #0066FF + + + + name + Invalid + scope + invalid + settings + + background + #E71A114D + foreground + #FF0000 + + + + name + Trailing whitespace + scope + invalid.deprecated.trailing-whitespace + settings + + background + #E71A1100 + + + + name + Embedded source + scope + text source + settings + + background + #FAFAFAFC + foreground + #000000 + + + + name + Tag + scope + meta.tag, declaration.tag + settings + + foreground + #0033CC + + + + name + Constant + scope + constant, support.constant + settings + + foreground + #6782D3 + + + + name + Support + scope + support + settings + + fontStyle + bold + foreground + #3333FF + + + + name + Storage + scope + storage + settings + + fontStyle + bold + + + + name + Section name + scope + entity.name.section + settings + + fontStyle + bold underline + + + + name + Frame title + scope + entity.name.function.frame + settings + + fontStyle + bold + foreground + #000000 + + + + name + XML Declaration + scope + meta.tag.preprocessor.xml + settings + + foreground + #333333 + + + + name + Tag Attribute + scope + entity.other.attribute-name + settings + + fontStyle + italic + foreground + #3366CC + + + + name + Tag Name + scope + entity.name.tag + settings + + fontStyle + bold + + + + uuid + 4FCFA210-B247-11D9-9D00-000D93347A42 + + diff --git a/tool/tmthemes/idleFingers.tmTheme b/tool/tmthemes/idleFingers.tmTheme new file mode 100644 index 00000000..51666df3 --- /dev/null +++ b/tool/tmthemes/idleFingers.tmTheme @@ -0,0 +1,380 @@ + + + + + name + idleFingers + settings + + + settings + + background + #323232 + caret + #91FF00 + foreground + #FFFFFF + invisibles + #404040 + lineHighlight + #353637 + selection + #5A647EE0 + + + + name + text + scope + text + settings + + foreground + #FFFFFF + + + + name + Source base + scope + source + settings + + background + #282828 + foreground + #CDCDCD + + + + name + Comment + scope + comment + settings + + fontStyle + italic + foreground + #BC9458 + + + + name + Html Tags + scope + meta.tag, declaration.tag, meta.doctype + settings + + foreground + #FFE5BB + + + + name + Function Name + scope + entity.name + settings + + foreground + #FFC66D + + + + name + Ruby Function Name + scope + source.ruby entity.name + settings + + foreground + #FFF980 + + + + name + Other Variable + scope + variable.other + settings + + foreground + #B7DFF8 + + + + name + Ruby Class Name + scope + support.class.ruby + settings + + foreground + #CCCC33 + + + + name + Constant + scope + constant, support.constant + settings + + foreground + #6C99BB + + + + name + Keyword + scope + keyword + settings + + fontStyle + + foreground + #CC7833 + + + + name + Pre-processor Line + scope + other.preprocessor.c + settings + + fontStyle + + foreground + #D0D0FF + + + + name + Pre-processor Directive + scope + entity.name.preprocessor + settings + + fontStyle + + + + + name + Function name + scope + entity.name.function + settings + + fontStyle + + + + + name + Function argument + scope + variable.parameter + settings + + fontStyle + italic + + + + name + Block comment + scope + source comment.block + settings + + background + #575757 + foreground + #FFFFFF + + + + name + String + scope + string + settings + + foreground + #A5C261 + + + + name + String escapes + scope + string constant.character.escape + settings + + foreground + #AAAAAA + + + + name + String (executed) + scope + string.interpolated + settings + + background + #CCCC33 + foreground + #000000 + + + + name + Regular expression + scope + string.regexp + settings + + foreground + #CCCC33 + + + + name + String (literal) + scope + string.literal + settings + + foreground + #CCCC33 + + + + name + String escapes (executed) + scope + string.interpolated constant.character.escape + settings + + foreground + #787878 + + + + name + Class name + scope + entity.name.class + settings + + fontStyle + underline + + + + name + Class inheritance + scope + entity.other.inherited-class + settings + + fontStyle + italic underline + + + + name + Tag name + scope + entity.name.tag + settings + + fontStyle + + + + + name + Tag attribute + scope + entity.other.attribute-name + settings + + fontStyle + + + + + name + Support function + scope + support.function + settings + + fontStyle + + foreground + #B83426 + + + + name + Textile List + scope + markup.list.unnumbered.textile + settings + + foreground + #6EA533 + + + + name + Textile Numbered list + scope + markup.list.numbered.textile + settings + + foreground + #6EA533 + + + + name + Textile Bold + scope + markup.bold.textile + settings + + fontStyle + bold + foreground + #C2C2C2 + + + + name + Invalid + scope + invalid + settings + + background + #FF0000 + fontStyle + + foreground + #FFFFFF + + + + uuid + 95BEF169-A2E5-4041-A84A-AAFC1DD61558 + + diff --git a/tool/tmthemes/krTheme.tmTheme b/tool/tmthemes/krTheme.tmTheme new file mode 100644 index 00000000..65c5c9b6 --- /dev/null +++ b/tool/tmthemes/krTheme.tmTheme @@ -0,0 +1,551 @@ + + + + + comment + Created by Kenneth Reitz, inspired by minimal design + name + krTheme + settings + + + settings + + background + #0B0A09 + caret + #FF9900 + foreground + #FCFFE0 + invisibles + #FFB16F52 + lineHighlight + #38403D + selection + #AA00FF73 + + + + name + Constant + scope + constant + settings + + fontStyle + + foreground + #D27518C2 + + + + name + Entity + scope + entity + settings + + fontStyle + + foreground + #A89100B5 + + + + name + Entity Other + scope + entity.other + settings + + foreground + #BA6912 + + + + name + Keyword + scope + keyword + settings + + fontStyle + + foreground + #949C8B + + + + name + Storage + scope + storage + settings + + fontStyle + + foreground + #FFEE80 + + + + name + String + scope + string -string.unquoted.old-plist -string.unquoted.heredoc, string.unquoted.heredoc string + settings + + foreground + #C7A4A1B5 + + + + name + Comment + scope + comment + settings + + fontStyle + italic + foreground + #706D5B + + + + name + Support + scope + support + settings + + fontStyle + + foreground + #9FC28A + + + + name + Variable + scope + variable + settings + + fontStyle + + foreground + #D1A796 + + + + name + Lang Variable + scope + variable.language + settings + + fontStyle + + foreground + #FF80E1 + + + + name + Function Call + scope + meta.function-call + settings + + foreground + #FFEE80 + + + + name + Invalid + scope + invalid + settings + + background + #A41300 + foreground + #F8F8F8 + + + + name + Embedded Source + scope + text source, string.unquoted.heredoc, source source + settings + + background + #24231D4D + fontStyle + + foreground + #D9D59F + + + + name + Entity inherited-class + scope + entity.other.inherited-class + settings + + fontStyle + + foreground + #7EFCFF + + + + name + String embedded-source + scope + string.quoted source + settings + + fontStyle + + foreground + #439740BA + + + + name + String constant + scope + string constant + settings + + foreground + #60DB5DBA + + + + name + String.regexp + scope + string.regexp + settings + + foreground + #7DFFC0A6 + + + + name + String variable + scope + string variable + settings + + fontStyle + + foreground + #B8B960 + + + + name + Support.function + scope + support.function + settings + + fontStyle + + foreground + #85873A + + + + name + Support.constant + scope + support.constant + settings + + fontStyle + + foreground + #C27E66 + + + + name + Exception + scope + support.class.exception + settings + + foreground + #FF1E00 + + + + name + C/C++ Preprocessor Line + scope + meta.preprocessor.c + settings + + foreground + #8996A8 + + + + name + C/C++ Preprocessor Directive + scope + meta.preprocessor.c keyword + settings + + foreground + #AFC4DB + + + + name + Doctype/XML Processing + scope + meta.sgml.html meta.doctype, meta.sgml.html meta.doctype entity, meta.sgml.html meta.doctype string, meta.xml-processing, meta.xml-processing entity, meta.xml-processing string + settings + + foreground + #73817D + + + + name + Meta.tag.A + scope + meta.tag, meta.tag entity + settings + + foreground + #BABD9C + + + + name + css tag-name + scope + meta.selector.css entity.name.tag + settings + + foreground + #99A190 + + + + name + css#id + scope + meta.selector.css entity.other.attribute-name.id + settings + + foreground + #CC8844 + + + + name + css.class + scope + meta.selector.css entity.other.attribute-name.class + settings + + foreground + #CFB958 + + + + name + css property-name: + scope + support.type.property-name.css + settings + + foreground + #E0DDAD + + + + name + css property-value; + scope + meta.property-group support.constant.property-value.css, meta.property-value support.constant.property-value.css + settings + + foreground + #AEB14B + + + + name + css @at-rule + scope + meta.preprocessor.at-rule keyword.control.at-rule + settings + + foreground + #FFB010 + + + + name + css additional-constants + scope + meta.property-value support.constant.named-color.css, meta.property-value constant + settings + + foreground + #999179 + + + + name + css constructor.argument + scope + meta.constructor.argument.css + settings + + foreground + #EB939A + + + + name + diff.header + scope + meta.diff, meta.diff.header + settings + + background + #000E1A + fontStyle + + foreground + #F8F8F8 + + + + name + diff.deleted + scope + markup.deleted + settings + + background + #800F00 + foreground + #F8F8F8 + + + + name + diff.changed + scope + markup.changed + settings + + background + #806F00 + foreground + #F8F8F8 + + + + name + diff.inserted + scope + markup.inserted + settings + + background + #228000 + foreground + #F8F8F8 + + + + name + Raw Markup + scope + markup.raw + settings + + background + #8FDDF630 + + + + name + Block Quote + scope + markup.quote + settings + + background + #005BAA + + + + name + List + scope + markup.list + settings + + background + #0F0040 + + + + name + Bold Markup + scope + markup.bold + settings + + fontStyle + bold + foreground + #9D80FF + + + + name + Italic Markup + scope + markup.italic + settings + + fontStyle + italic + foreground + #80FFBB + + + + name + Heading Markup + scope + markup.heading + settings + + fontStyle + bold + + + + uuid + 87F051F7-B6FB-408C-96F9-467B66C14E9F + + diff --git a/tool/tmthemes/monoindustrial.tmTheme b/tool/tmthemes/monoindustrial.tmTheme new file mode 100644 index 00000000..81f8eb70 --- /dev/null +++ b/tool/tmthemes/monoindustrial.tmTheme @@ -0,0 +1,451 @@ + + + + + name + monoindustrial + settings + + + settings + + background + #222C28 + caret + #FFFFFF + foreground + #FFFFFF + invisibles + #666C6880 + lineHighlight + #0C0D0C40 + selection + #91999466 + + + + name + Comment + scope + comment + settings + + background + #151C19 + fontStyle + + foreground + #666C68 + + + + name + Type + scope + storage, support.type + settings + + foreground + #C23B00 + + + + name + Embedded code + scope + string.unquoted.embedded, text source, string.unquoted + settings + + background + #151C19 + foreground + #FFFFFF + + + + name + String interpolation + scope + constant.character.escaped, string source - string.unquoted.embedded, string string source + settings + + background + #1A0700 + foreground + #E9470000 + + + + name + String + scope + string - string source, string source string, meta.scope.heredoc + settings + + background + #1A0700 + fontStyle + + foreground + #C23800 + + + + name + Number + scope + constant.numeric + settings + + foreground + #E98800 + + + + name + Variable + scope + variable.language, variable.other + settings + + fontStyle + + foreground + #648BD2 + + + + name + Constant + scope + constant + settings + + foreground + #E98800 + + + + name + Preprocessor line + scope + other.preprocessor + settings + + background + #161D1A + fontStyle + + foreground + #A8B3AB + + + + name + Preprocessor directive + scope + entity.name.preprocessor + settings + + background + #161D1A + fontStyle + + foreground + #A8B3AB + + + + name + Function name + scope + entity.name.function, keyword.operator, keyword.other.name-of-parameter + settings + + fontStyle + + foreground + #A8B3AB + + + + name + Class name + scope + entity.name.class + settings + + fontStyle + + foreground + #9A2F00 + + + + name + Function parameter + scope + variable.parameter + settings + + fontStyle + + foreground + #648BD2 + + + + name + Function argument and result types + scope + storage.type.method + settings + + fontStyle + + foreground + #666C68 + + + + name + Keyword + scope + keyword, storage.type.function.php + settings + + fontStyle + + foreground + #A39E64 + + + + name + Invalid + scope + invalid + settings + + background + #990000AD + foreground + #FFFFFF + + + + name + Invalid trailing whitespace + scope + invalid.trailing-whitespace + settings + + background + #FFD0D0 + foreground + #000000 + + + + name + Library function + scope + support.function + settings + + fontStyle + + foreground + #588E60 + + + + name + Library object + scope + support.class, support.type, entity.name + settings + + fontStyle + + foreground + #5778B6 + + + + name + Library constant + scope + support.constant + settings + + foreground + #C87500 + + + + name + Library variable + scope + support.other.variable + settings + + fontStyle + + foreground + #5879B7 + + + + name + Markup XML declaration + scope + declaration.xml-processing + settings + + fontStyle + + foreground + #68685B + + + + name + Markup DOCTYPE + scope + declaration.doctype + settings + + fontStyle + + foreground + #888888 + + + + name + Markup DTD + scope + declaration.doctype.DTD + settings + + fontStyle + + foreground + #888888 + + + + name + Markup tag + scope + declaration.tag + settings + + fontStyle + + foreground + #A65EFF + + + + name + Markup name of tag + scope + entity.name.tag + settings + + foreground + #A65EFF + + + + name + Markup tag attribute + scope + entity.other.attribute-name + settings + + fontStyle + + foreground + #909993 + + + + name + Punctuation + scope + punctuation + settings + + foreground + #90999380 + + + + name + Inherited class name + scope + entity.other.inherited-class + settings + + fontStyle + + foreground + #7642B7 + + + + name + Changed files (Subversion) + scope + meta.scope.changed-files.svn, markup.inserted.svn, markup.changed.svn, markup.deleted.svn + settings + + background + #00000059 + fontStyle + + foreground + #FFFFFF + + + + name + Blocks, Expressions 1 + scope + meta.section + settings + + background + #78807B0A + + + + name + Blocks, Expressions 2 + scope + meta.section meta.section + settings + + background + #78807B0A + + + + name + Blocks, Expressions 3 + scope + meta.section meta.section meta.section + settings + + background + #78807B0A + + + + uuid + EEA328BA-54E5-49DC-81F3-1F25BF8AF163 + +