diff --git a/Makefile.dryice.js b/Makefile.dryice.js index 0ae45a18..9fe021ff 100755 --- a/Makefile.dryice.js +++ b/Makefile.dryice.js @@ -220,7 +220,7 @@ function buildAce(aceProject, options) { "css", "html", "javascript", "php", "coldfusion", "python", "lua", "xml", "ruby", "java", "c_cpp", "coffee", "perl", "csharp", "haxe", "liquid", "svg", "clojure", "scss", "json", "groovy", "ocaml", "scala", "textile", "scad", "markdown", "latex", "powershell", "sql", - "text", "pgsql", "sh", "xquery" + "text", "pgsql", "sh", "xquery", "less" ], themes: [ "chrome", "clouds", "clouds_midnight", "cobalt", "crimson_editor", "dawn", diff --git a/demo/kitchen-sink/demo.js b/demo/kitchen-sink/demo.js index 4d9c9b99..7a1bc33a 100644 --- a/demo/kitchen-sink/demo.js +++ b/demo/kitchen-sink/demo.js @@ -39,9 +39,10 @@ define(function(require, exports, module) { +"use strict"; require("ace/lib/fixoldbrowsers"); -require("ace/config").init(); +require("ace/config").init(); var env = {}; var event = require("ace/lib/event"); @@ -53,9 +54,12 @@ var vim = require("ace/keyboard/keybinding/vim").Vim; var emacs = require("ace/keyboard/keybinding/emacs").Emacs; var HashHandler = require("ace/keyboard/hash_handler").HashHandler; - var modesByName; +// workers do not work for file: +if (location.protocol == "file:") + EditSession.prototype.$useWorker = false; + var Doc = function(name, desc, file) { this.name = name; this.desc = desc; @@ -96,6 +100,7 @@ var modes = [ new Mode("javascript", "JavaScript", ["js"]), new Mode("json", "JSON", ["json"]), new Mode("latex", "LaTeX", ["tex"]), + new Mode("less", "LESS", ["less"]), new Mode("lua", "Lua", ["lua"]), new Mode("liquid", "Liquid", ["liquid"]), new Mode("markdown", "Markdown", ["md", "markdown"]), @@ -149,6 +154,10 @@ var docs = [ "scss", "SCSS", require("ace/requirejs/text!./docs/scss.scss") ), + new Doc( + "less", "LESS", + require("ace/requirejs/text!./docs/less.less") + ), new Doc( "html", "HTML", require("ace/requirejs/text!./docs/html.html") @@ -301,6 +310,7 @@ var showGutterEl = document.getElementById("show_gutter"); var showPrintMarginEl = document.getElementById("show_print_margin"); var highlightSelectedWordE = document.getElementById("highlight_selected_word"); var showHScrollEl = document.getElementById("show_hscroll"); +var animateScrollEl = document.getElementById("animate_scroll"); var softTabEl = document.getElementById("soft_tab"); var behavioursEl = document.getElementById("enable_behaviours"); @@ -318,14 +328,19 @@ modes.forEach(function(mode) { modeEl.appendChild(option); }); +bindDropdown("mode", function(value) { + env.editor.getSession().setMode(modesByName[value].mode || modesByName.text.mode); + env.editor.getSession().modeName = value; +}); + bindDropdown("doc", function(value) { var doc = docsByName[value].doc; - + if (!docsByName[value].initialized) { docsByName[value].initialized = true; doc.setMode(modesByName[docsByName[value].name].mode); } - + var session = env.split.setSession(doc); session.name = doc.name; @@ -338,39 +353,47 @@ function updateUIEditorOptions() { var editor = env.editor; var session = editor.session; - docEl.value = session.name; - modeEl.value = session.modeName || "text"; - session.setFoldStyle(foldingEl.value); - if (!session.getUseWrapMode()) { - wrapModeEl.value = "off"; - } else { - wrapModeEl.value = session.getWrapLimitRange().min || "free"; - } + saveOption(docEl, session.name); + saveOption(modeEl, session.modeName || "text"); + saveOption(wrapModeEl, session.getUseWrapMode() ? session.getWrapLimitRange().min || "free" : "off"); - selectStyleEl.checked = editor.getSelectionStyle() == "line"; - themeEl.value = editor.getTheme(); - highlightActiveEl.checked = editor.getHighlightActiveLine(); - showHiddenEl.checked = editor.getShowInvisibles(); - showGutterEl.checked = editor.renderer.getShowGutter(); - showPrintMarginEl.checked = editor.renderer.getShowPrintMargin(); - highlightSelectedWordE.checked = editor.getHighlightSelectedWord(); - showHScrollEl.checked = editor.renderer.getHScrollBarAlwaysVisible(); - softTabEl.checked = session.getUseSoftTabs(); - behavioursEl.checked = editor.getBehavioursEnabled(); + saveOption(selectStyleEl, editor.getSelectionStyle() == "line"); + saveOption(themeEl, editor.getTheme()); + saveOption(highlightActiveEl, editor.getHighlightActiveLine()); + saveOption(showHiddenEl, editor.getShowInvisibles()); + saveOption(showGutterEl, editor.renderer.getShowGutter()); + saveOption(showPrintMarginEl, editor.renderer.getShowPrintMargin()); + saveOption(highlightSelectedWordE, editor.getHighlightSelectedWord()); + saveOption(showHScrollEl, editor.renderer.getHScrollBarAlwaysVisible()); + saveOption(animateScrollEl, editor.getAnimatedScroll()); + saveOption(softTabEl, session.getUseSoftTabs()); + saveOption(behavioursEl, editor.getBehavioursEnabled()); } -bindDropdown("mode", function(value) { - env.editor.getSession().setMode(modesByName[value].mode || modesByName.text.mode); - env.editor.getSession().modeName = value; -}); +function saveOption(el, val) { + if (!el.onchange || el.onclick) + return; + + if ("checked" in el) { + if (val !== undefined) + el.checked = val; + + localStorage && localStorage.setItem(el.id, el.checked ? 1 : 0); + } + else { + if (val !== undefined) + el.value = val; + + localStorage && localStorage.setItem(el.id, el.value); + } +} bindDropdown("theme", function(value) { if (!value) return; - - env.editor.setTheme(value); + env.editor.setTheme(value); }); bindDropdown("keybinding", function(value) { @@ -440,6 +463,10 @@ bindCheckbox("show_hscroll", function(checked) { env.editor.renderer.setHScrollBarAlwaysVisible(checked); }); +bindCheckbox("animate_scroll", function(checked) { + env.editor.setAnimatedScroll(checked); +}); + bindCheckbox("soft_tab", function(checked) { env.editor.getSession().setUseSoftTabs(checked); }); @@ -448,6 +475,7 @@ bindCheckbox("enable_behaviours", function(checked) { env.editor.setBehavioursEnabled(checked); }); + var secondSession = null; bindDropdown("split", function(value) { var sp = env.split; @@ -475,8 +503,12 @@ bindDropdown("split", function(value) { function bindCheckbox(id, callback) { var el = document.getElementById(id); + if (localStorage && localStorage.getItem(id)) + el.checked = localStorage.getItem(id) == "1"; + var onCheck = function() { callback(!!el.checked); + saveOption(el); }; el.onclick = onCheck; onCheck(); @@ -484,9 +516,14 @@ function bindCheckbox(id, callback) { function bindDropdown(id, callback) { var el = document.getElementById(id); + if (localStorage && localStorage.getItem(id)) + el.value = localStorage.getItem(id); + var onChange = function() { callback(el.value); + saveOption(el); }; + el.onchange = onChange; onChange(); } @@ -497,7 +534,6 @@ function onResize() { container.style.width = width + "px"; container.style.height = document.documentElement.clientHeight + "px"; env.split.resize(); -// env.editor.resize(); } window.onresize = onResize; @@ -578,4 +614,7 @@ commands.addCommand({ } }); +// add multiple cursor support to editor +require("ace/multi_select").MultiSelect(env.editor); + }); diff --git a/demo/kitchen-sink/docs/javascript.js b/demo/kitchen-sink/docs/javascript.js index 178edf4a..5b367b5f 100644 --- a/demo/kitchen-sink/docs/javascript.js +++ b/demo/kitchen-sink/docs/javascript.js @@ -1,4 +1,4 @@ -function foo (items, nada) { +function foo(items, nada) { for (var i=0; iAce Kitchen Sink - @@ -132,6 +132,13 @@ + + + + + + + @@ -210,7 +217,7 @@ - + 1) +}; +var testRanges = function(str) { + assert.equal(editor.selection.getAllRanges() + "", str + ""); +} + +module.exports = { + + name: "ACE multi_select.js", + + "test: multiselect editing": function() { + var doc = new EditSession([ + "w1.w2", + " wtt.w", + " wtt.w" + ]); + editor = new Editor(new MockRenderer(), doc); + MultiSelect(editor); + + editor.navigateFileEnd(); + exec("selectMoreBefore", 3); + assert.ok(editor.inMultiSelectMode); + assert.equal(editor.selection.getAllRanges().length, 4); + + var newLine = editor.session.getDocument().getNewLineCharacter(); + var copyText = "wwww".split("").join(newLine); + assert.equal(editor.getCopyText(), copyText); + exec("insertstring", 1, "a"); + exec("backspace", 2); + assert.equal(editor.session.getValue(), "w1.w2\ntt\ntt"); + assert.equal(editor.selection.getAllRanges().length, 4); + + exec("selectall"); + assert.ok(!editor.inMultiSelectMode); + //assert.equal(editor.selection.getAllRanges().length, 1); + }, + + "test: multiselect navigation": function() { + var doc = new EditSession([ + "w1.w2", + " wtt.w", + " wtt.we" + ]); + editor = new Editor(new MockRenderer(), doc); + MultiSelect(editor); + + editor.selectMoreLines(1); + testRanges("Range: [0/0] -> [0/0],Range: [1/0] -> [1/0]"); + assert.ok(editor.inMultiSelectMode); + + exec("golinedown"); + exec("gotolineend"); + testRanges("Range: [1/9] -> [1/9],Range: [2/10] -> [2/10]"); + exec("selectwordleft"); + + testRanges("Range: [1/8] -> [1/9],Range: [2/8] -> [2/10]"); + exec("golinedown", 2); + assert.ok(!editor.inMultiSelectMode); + }, + + "test: multiselect session change": function() { + var doc = new EditSession([ + "w1.w2", + " wtt.w", + " wtt.w" + ]); + editor = new Editor(new MockRenderer(), doc); + MultiSelect(editor); + + editor.selectMoreLines(1) + testRanges("Range: [0/0] -> [0/0],Range: [1/0] -> [1/0]"); + assert.ok(editor.inMultiSelectMode); + + var doc2 = new EditSession(["w1"]); + editor.setSession(doc2); + assert.ok(!editor.inMultiSelectMode); + + editor.setSession(doc); + assert.ok(editor.inMultiSelectMode); + }, + + "test: multiselect addRange": function() { + var doc = new EditSession([ + "w1.w2", + " wtt.w", + " wtt.w" + ]); + editor = new Editor(new MockRenderer(), doc); + MultiSelect(editor); + var selection = editor.selection; + + var range1 = new Range(0, 2, 0, 4); + editor.selection.fromOrientedRange(range1); + + var range2 = new Range(0, 3, 0, 4); + selection.addRange(range2); + assert.ok(!editor.inMultiSelectMode); + assert.ok(range2.isEqual(editor.selection.getRange())); + + var range3 = new Range(0, 1, 0, 1); + selection.addRange(range3); + assert.ok(editor.inMultiSelectMode); + testRanges([range3, range2]); + + var range4 = new Range(0, 0, 4, 0); + selection.addRange(range4); + assert.ok(!editor.inMultiSelectMode); + } +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec() +} \ No newline at end of file diff --git a/lib/ace/narcissus/definitions.js b/lib/ace/narcissus/definitions.js index a2d07caa..48a7c1e5 100644 --- a/lib/ace/narcissus/definitions.js +++ b/lib/ace/narcissus/definitions.js @@ -111,7 +111,7 @@ var strictKeywords = { "implements": true, "interface": true, "let": true, - "module": true, + //"module": true, "package": true, "private": true, "protected": true, diff --git a/lib/ace/range.js b/lib/ace/range.js index a74810a5..9d823180 100644 --- a/lib/ace/range.js +++ b/lib/ace/range.js @@ -69,13 +69,13 @@ var Range = function(startRow, startColumn, endRow, endColumn) { (function() { /** - * Range.isEequal(range) -> Boolean + * Range.isEqual(range) -> Boolean * - range (Range): A range to check against * * Returns `true` if and only if the starting row and column, and ending tow and column, are equivalent to those given by `range`. * **/ - this.isEequal = function(range) { + this.isEqual = function(range) { return this.start.row == range.start.row && this.end.row == range.end.row && this.start.column == range.start.column && @@ -195,6 +195,18 @@ var Range = function(startRow, startColumn, endRow, endColumn) { return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0; } + /** + * Range.intersects(range) -> Boolean + * - range (Range): A range to compare with + * + * Returns `true` if passed in `range` intersects with the one calling this method. + * + **/ + this.intersects = function(range) { + var cmp = this.compareRange(range); + return (cmp == -1 || cmp == 0 || cmp == 1); + } + /** * Range.isEnd(row, column) -> Boolean * - row (Number): A row point to compare with @@ -202,7 +214,7 @@ var Range = function(startRow, startColumn, endRow, endColumn) { * * Returns `true` if the caller's ending row point is the same as `row`, and if the caller's ending column is the same as `column`. * - **/ + **/ this.isEnd = function(row, column) { return this.end.row == row && this.end.column == column; } @@ -356,7 +368,7 @@ var Range = function(startRow, startColumn, endRow, endColumn) { return 0; }; - /** + /** * Range.compareStart(row, column) -> Number * - row (Number): A row point to compare with * - column (Number): A column point to compare with @@ -386,7 +398,7 @@ var Range = function(startRow, startColumn, endRow, endColumn) { } } - /** + /** * Range.compareEnd(row, column) -> Number * - row (Number): A row point to compare with * - column (Number): A column point to compare with @@ -501,12 +513,6 @@ var Range = function(startRow, startColumn, endRow, endColumn) { return Range.fromPoints(start || this.start, end || this.end); }; - /** - * Range.isEmpty() -> Boolean - * - * Checks if the range is empty; that is, the starting and ending points for row and column are equivalent. Returns `true` if the range is indeed empty. - * - **/ this.isEmpty = function() { return (this.start.row == this.end.row && this.start.column == this.end.column); }; diff --git a/lib/ace/range_list.js b/lib/ace/range_list.js new file mode 100644 index 00000000..185ca5a6 --- /dev/null +++ b/lib/ace/range_list.js @@ -0,0 +1,231 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Harutyun Amirjanyan + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +define(function(require, exports, module) { +"use strict"; + + +var RangeList = function() { + this.ranges = []; +}; + +(function() { + this.comparePoints = function(p1, p2) { + return p1.row - p2.row || p1.column - p2.column; + }; + + this.pointIndex = function(pos, startIndex) { + var list = this.ranges; + + for (var i = startIndex || 0; i < list.length; i++) { + var range = list[i]; + var cmp = this.comparePoints(pos, range.end); + + if (cmp > 0) + continue; + if (cmp == 0) + return i; + cmp = this.comparePoints(pos, range.start); + if (cmp >= 0) + return i; + + return -i-1; + } + return -i - 1; + }; + + this.add = function(range) { + var startIndex = this.pointIndex(range.start); + if (startIndex < 0) + startIndex = -startIndex - 1; + + var endIndex = this.pointIndex(range.end, startIndex); + + if (endIndex < 0) + endIndex = -endIndex - 1; + else + endIndex++; + + return this.ranges.splice(startIndex, endIndex - startIndex, range); + }; + + this.addList = function(list) { + var removed = []; + for (var i = list.length; i--; ) { + removed.push.call(removed, this.add(list[i])); + } + return removed; + }; + + this.substractPoint = function(pos) { + var i = this.pointIndex(pos); + + if (i >= 0) + return this.ranges.splice(i, 1); + }; + + // merge overlapping ranges + this.merge = function() { + var removed = []; + var list = this.ranges; + var next = list[0], range; + for (var i = 1; i < list.length; i++) { + range = next; + next = list[i]; + var cmp = this.comparePoints(range.end, next.start); + if (cmp < 0) + continue; + + if (cmp == 0 && !(range.isEmpty() || next.isEmpty())) + continue; + + if (this.comparePoints(range.end, next.end) < 0) { + range.end.row = next.end.row; + range.end.column = next.end.column; + } + + list.splice(i, 1); + removed.push(next); + next = range; + i--; + } + + return removed; + }; + + this.contains = function(row, column) { + return this.pointIndex({row: row, column: column}) >= 0; + }; + + this.containsPoint = function(pos) { + return this.pointIndex(pos) >= 0; + }; + + this.rangeAtPoint = function(pos) { + var i = this.pointIndex(pos); + if (i >= 0) + return this.ranges[i]; + }; + + + this.clipRows = function(startRow, endRow) { + var list = this.ranges; + if (list[0].start.row > endRow || list[list.length - 1].start.row < startRow) + return []; + + var startIndex = this.pointIndex({row: startRow, column: 0}); + if (startIndex < 0) + startIndex = -startIndex - 1; + var endIndex = this.pointIndex({row: endRow, column: 0}, startIndex); + if (endIndex < 0) + endIndex = -endIndex - 1; + + var clipped = []; + for (var i = startIndex; i < endIndex; i++) { + clipped.push(list[i]); + } + return clipped; + }; + + this.removeAll = function() { + return this.ranges.splice(0, this.ranges.length); + }; + + this.attach = function(session) { + if (this.session) + this.detach(); + + this.session = session; + this.onChange = this.$onChange.bind(this); + + this.session.on('change', this.onChange); + }; + + this.detach = function() { + if (!this.session) + return; + this.session.removeListener('change', this.onChange); + this.session = null; + }; + + this.$onChange = function(e) { + var changeRange = e.data.range; + if (e.data.action[0] == "i"){ + var start = changeRange.start; + var end = changeRange.end; + } else { + var end = changeRange.start; + var start = changeRange.end; + } + var startRow = start.row; + var endRow = end.row; + var lineDif = endRow - startRow; + + var colDiff = -start.column + end.column; + + var ranges = this.ranges; + + for (var i=0, n = ranges.length; i < n; i++) { + var r = ranges[i]; + if (r.end.row < startRow) + continue; + if (r.start.row > startRow) + break; + + if (r.start.row == startRow && r.start.column >= start.column ) { + r.start.column += colDiff; + r.start.row += lineDif; + } + if (r.end.row == startRow && r.end.column >= start.column) { + r.end.column += colDiff; + r.end.row += lineDif; + } + } + + if (lineDif != 0 && i < n) { + for (; i < n; i++) { + var r = ranges[i]; + r.start.row += lineDif; + r.end.row += lineDif; + } + } + }; + +}).call(RangeList.prototype); + +exports.RangeList = RangeList; +}); diff --git a/lib/ace/range_list_test.js b/lib/ace/range_list_test.js new file mode 100644 index 00000000..6c397369 --- /dev/null +++ b/lib/ace/range_list_test.js @@ -0,0 +1,170 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is Ajax.org Code Editor (ACE). + * + * The Initial Developer of the Original Code is + * Ajax.org B.V. + * Portions created by the Initial Developer are Copyright (C) 2010 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Fabian Jakobs + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +if (typeof process !== "undefined") { + require("amd-loader"); +} + +define(function(require, exports, module) { +"use strict"; + +var Range = require("./range").Range; +var RangeList = require("./range_list").RangeList; +var EditSession = require("./edit_session").EditSession; +var assert = require("./test/assertions"); + +function flatten(rangeList) { + var points = []; + rangeList.ranges.forEach(function(r) { + points.push(r.start.row, r.start.column, r.end.row, r.end.column) + }) + return points; +} +function testRangeList(rangeList, points) { + assert.equal("" + flatten(rangeList), "" + points); +} + +module.exports = { + + name: "ACE range_list.js", + + "test: rangeList pointIndex": function() { + var rangeList = new RangeList(); + rangeList.ranges = [ + new Range(1,2,3,4), + new Range(4,2,5,4), + new Range(8,8,9,9) + ]; + + assert.equal(rangeList.pointIndex({row: 0, column: 1}), -1); + assert.equal(rangeList.pointIndex({row: 1, column: 2}), 0); + assert.equal(rangeList.pointIndex({row: 1, column: 3}), 0); + assert.equal(rangeList.pointIndex({row: 3, column: 4}), 0); + assert.equal(rangeList.pointIndex({row: 4, column: 1}), -2); + assert.equal(rangeList.pointIndex({row: 5, column: 1}), 1); + assert.equal(rangeList.pointIndex({row: 8, column: 9}), 2); + assert.equal(rangeList.pointIndex({row: 18, column: 9}), -4); + }, + + "test: rangeList add": function() { + var rangeList = new RangeList(); + rangeList.addList([ + new Range(9,0,9,1), + new Range(1,2,3,4), + new Range(8,8,9,9), + new Range(4,2,5,4), + new Range(3,20,3,24), + new Range(6,6,7,7) + ]); + assert.equal(rangeList.ranges.length, 5); + + rangeList.add(new Range(1,2,3,5)); + assert.range(rangeList.ranges[0], 1,2,3,5); + assert.equal(rangeList.ranges.length, 5); + + rangeList.add(new Range(7,7,7,7)); + assert.range(rangeList.ranges[3], 7,7,7,7); + rangeList.add(new Range(7,8,7,8)); + assert.range(rangeList.ranges[4], 7,8,7,8); + }, + + "test: rangeList add empty": function() { + var rangeList = new RangeList(); + rangeList.addList([ + new Range(7,10,7,10), + new Range(9,10,9,10), + new Range(8,10,8,10) + ]); + assert.equal(rangeList.ranges.length, 3); + + rangeList.add(new Range(9,10,9,10)); + testRangeList(rangeList, [7,10,7,10,8,10,8,10,9,10,9,10]); + }, + + "test: rangeList merge": function() { + var rangeList = new RangeList(); + rangeList.addList([ + new Range(1,2,3,4), + new Range(4,2,5,4), + new Range(6,6,7,7), + new Range(8,8,9,9) + ]); + var removed = []; + + assert.equal(rangeList.ranges.length, 4); + + rangeList.ranges[1].end.row = 7; + removed = rangeList.merge(); + assert.equal(removed.length, 1); + assert.range(rangeList.ranges[1], 4,2,7,7); + assert.equal(rangeList.ranges.length, 3); + + rangeList.ranges[0].end.row = 10; + removed = rangeList.merge(); + assert.range(rangeList.ranges[0], 1,2,10,4); + assert.equal(removed.length, 2); + assert.equal(rangeList.ranges.length, 1); + + rangeList.ranges.push(new Range(10,10,10,10)); + rangeList.ranges.push(new Range(10,10,10,10)); + removed = rangeList.merge(); + assert.equal(rangeList.ranges.length, 2); + }, + + "test: rangeList remove": function() { + var rangeList = new RangeList(); + var list = [ + new Range(1,2,3,4), + new Range(4,2,5,4), + new Range(6,6,7,7), + new Range(8,8,9,9) + ]; + rangeList.addList(list); + assert.equal(rangeList.ranges.length, 4); + rangeList.substractPoint({row: 1, column: 2}); + assert.equal(rangeList.ranges.length, 3); + rangeList.substractPoint({row: 6, column: 7}); + assert.equal(rangeList.ranges.length, 2); + } + +}; + +}); + +if (typeof module !== "undefined" && module === require.main) { + require("asyncjs").test.testcase(module.exports).exec() +} \ No newline at end of file diff --git a/lib/ace/scrollbar.js b/lib/ace/scrollbar.js index 8cd0bf83..95b6128a 100644 --- a/lib/ace/scrollbar.js +++ b/lib/ace/scrollbar.js @@ -130,6 +130,8 @@ var ScrollBar = function(parent) { * Sets the scroll top of the scroll bar. * **/ + // TODO: on chrome 17+ after for small zoom levels after this function + // this.element.scrollTop != scrollTop which makes page to scroll up. this.setScrollTop = function(scrollTop) { this.element.scrollTop = scrollTop; }; diff --git a/lib/ace/selection.js b/lib/ace/selection.js index 2b52dc35..1cc317c7 100644 --- a/lib/ace/selection.js +++ b/lib/ace/selection.js @@ -67,18 +67,18 @@ var Selection = function(session) { this.selectionLead = this.doc.createAnchor(0, 0); this.selectionAnchor = this.doc.createAnchor(0, 0); - var _self = this; + var self = this; this.selectionLead.on("change", function(e) { - _self._emit("changeCursor"); - if (!_self.$isEmpty) - _self._emit("changeSelection"); - if (!_self.$preventUpdateDesiredColumnOnChange && e.old.column != e.value.column) - _self.$updateDesiredColumn(); + self._emit("changeCursor"); + if (!self.$isEmpty) + self._emit("changeSelection"); + if (!self.$keepDesiredColumnOnChange && e.old.column != e.value.column) + self.$desiredColumn = null; }); this.selectionAnchor.on("change", function() { - if (!_self.$isEmpty) - _self._emit("changeSelection"); + if (!self.$isEmpty) + self._emit("changeSelection"); }); }; @@ -91,7 +91,7 @@ var Selection = function(session) { * * Returns `true` if the selection is empty. **/ - this.isEmpty = function() { + this.isEmpty = function() { return (this.$isEmpty || ( this.selectionAnchor.row == this.selectionLead.row && this.selectionAnchor.column == this.selectionLead.column @@ -103,7 +103,7 @@ var Selection = function(session) { * * Returns `true` if the selection is a multi-line. **/ - this.isMultiLine = function() { + this.isMultiLine = function() { if (this.isEmpty()) { return false; } @@ -116,7 +116,7 @@ var Selection = function(session) { * * Gets the current position of the cursor. **/ - this.getCursor = function() { + this.getCursor = function() { return this.selectionLead.getPosition(); }; @@ -127,7 +127,7 @@ var Selection = function(session) { * * Sets the row and column position of the anchor. This function also emits the `'changeSelection'` event. **/ - this.setSelectionAnchor = function(row, column) { + this.setSelectionAnchor = function(row, column) { this.selectionAnchor.setPosition(row, column); if (this.$isEmpty) { @@ -142,7 +142,7 @@ var Selection = function(session) { * Returns an object containing the `row` and `column` of the calling selection anchor. * **/ - this.getSelectionAnchor = function() { + this.getSelectionAnchor = function() { if (this.$isEmpty) return this.getSelectionLead() else @@ -154,7 +154,7 @@ var Selection = function(session) { * * Returns an object containing the `row` and `column` of the calling selection lead. **/ - this.getSelectionLead = function() { + this.getSelectionLead = function() { return this.selectionLead.getPosition(); }; @@ -165,7 +165,7 @@ var Selection = function(session) { * Shifts the selection up (or down, if [[Selection.isBackwards `isBackwards()`]] is true) the given number of columns. * **/ - this.shiftSelection = function(columns) { + this.shiftSelection = function(columns) { if (this.$isEmpty) { this.moveCursorTo(this.selectionLead.row, this.selectionLead.column + columns); return; @@ -191,7 +191,7 @@ var Selection = function(session) { * * Returns `true` if the selection is going backwards in the document. **/ - this.isBackwards = function() { + this.isBackwards = function() { var anchor = this.selectionAnchor; var lead = this.selectionLead; return (anchor.row > lead.row || (anchor.row == lead.row && anchor.column > lead.column)); @@ -202,7 +202,7 @@ var Selection = function(session) { * * [Returns the [[Range `Range`]] for the selected text.]{: #Selection.getRange} **/ - this.getRange = function() { + this.getRange = function() { var anchor = this.selectionAnchor; var lead = this.selectionLead; @@ -222,7 +222,7 @@ var Selection = function(session) { * * [Empties the selection (by de-selecting it). This function also emits the `'changeSelection'` event.]{: #Selection.clearSelection} **/ - this.clearSelection = function() { + this.clearSelection = function() { if (!this.$isEmpty) { this.$isEmpty = true; this._emit("changeSelection"); @@ -234,7 +234,7 @@ var Selection = function(session) { * * Selects all the text in the document. **/ - this.selectAll = function() { + this.selectAll = function() { var lastRow = this.doc.getLength() - 1; this.setSelectionAnchor(lastRow, this.doc.getLine(lastRow).length); this.moveCursorTo(0, 0); @@ -248,7 +248,7 @@ var Selection = function(session) { * Sets the selection to the provided range. * **/ - this.setSelectionRange = function(range, reverse) { + this.setSelectionRange = function(range, reverse) { if (reverse) { this.setSelectionAnchor(range.end.row, range.end.column); this.selectTo(range.start.row, range.start.column); @@ -256,12 +256,7 @@ var Selection = function(session) { this.setSelectionAnchor(range.start.row, range.start.column); this.selectTo(range.end.row, range.end.column); } - this.$updateDesiredColumn(); - }; - - this.$updateDesiredColumn = function() { - var cursor = this.getCursor(); - this.$desiredColumn = this.session.documentToScreenColumn(cursor.row, cursor.column); + this.$desiredColumn = null; }; this.$moveSelection = function(mover) { @@ -280,7 +275,7 @@ var Selection = function(session) { * Moves the selection cursor to the indicated row and column. * **/ - this.selectTo = function(row, column) { + this.selectTo = function(row, column) { this.$moveSelection(function() { this.moveCursorTo(row, column); }); @@ -293,7 +288,7 @@ var Selection = function(session) { * Moves the selection cursor to the row and column indicated by `pos`. * **/ - this.selectToPosition = function(pos) { + this.selectToPosition = function(pos) { this.$moveSelection(function() { this.moveCursorToPosition(pos); }); @@ -304,7 +299,7 @@ var Selection = function(session) { * * Moves the selection up one row. **/ - this.selectUp = function() { + this.selectUp = function() { this.$moveSelection(this.moveCursorUp); }; @@ -313,7 +308,7 @@ var Selection = function(session) { * * Moves the selection down one row. **/ - this.selectDown = function() { + this.selectDown = function() { this.$moveSelection(this.moveCursorDown); }; @@ -322,7 +317,7 @@ var Selection = function(session) { * * Moves the selection right one column. **/ - this.selectRight = function() { + this.selectRight = function() { this.$moveSelection(this.moveCursorRight); }; @@ -331,7 +326,7 @@ var Selection = function(session) { * * Moves the selection left one column. **/ - this.selectLeft = function() { + this.selectLeft = function() { this.$moveSelection(this.moveCursorLeft); }; @@ -340,7 +335,7 @@ var Selection = function(session) { * * Moves the selection to the beginning of the current line. **/ - this.selectLineStart = function() { + this.selectLineStart = function() { this.$moveSelection(this.moveCursorLineStart); }; @@ -349,7 +344,7 @@ var Selection = function(session) { * * Moves the selection to the end of the current line. **/ - this.selectLineEnd = function() { + this.selectLineEnd = function() { this.$moveSelection(this.moveCursorLineEnd); }; @@ -358,7 +353,7 @@ var Selection = function(session) { * * Moves the selection to the end of the file. **/ - this.selectFileEnd = function() { + this.selectFileEnd = function() { this.$moveSelection(this.moveCursorFileEnd); }; @@ -367,7 +362,7 @@ var Selection = function(session) { * * Moves the selection to the start of the file. **/ - this.selectFileStart = function() { + this.selectFileStart = function() { this.$moveSelection(this.moveCursorFileStart); }; @@ -376,7 +371,7 @@ var Selection = function(session) { * * Moves the selection to the first word on the right. **/ - this.selectWordRight = function() { + this.selectWordRight = function() { this.$moveSelection(this.moveCursorWordRight); }; @@ -385,7 +380,7 @@ var Selection = function(session) { * * Moves the selection to the first word on the left. **/ - this.selectWordLeft = function() { + this.selectWordLeft = function() { this.$moveSelection(this.moveCursorWordLeft); }; @@ -394,7 +389,7 @@ var Selection = function(session) { * * Moves the selection to highlight the entire word. **/ - this.selectWord = function() { + this.selectWord = function() { var cursor = this.getCursor(); var range = this.session.getWordRange(cursor.row, cursor.column); this.setSelectionRange(range); @@ -405,7 +400,7 @@ var Selection = function(session) { * * Selects a word, including its right whitespace. **/ - this.selectAWord = function() { + this.selectAWord = function() { var cursor = this.getCursor(); var range = this.session.getAWordRange(cursor.row, cursor.column); this.setSelectionRange(range); @@ -416,7 +411,7 @@ var Selection = function(session) { * * Selects the entire line. **/ - this.selectLine = function() { + this.selectLine = function() { var rowStart = this.selectionLead.row; var rowEnd; @@ -438,7 +433,7 @@ var Selection = function(session) { * * Moves the cursor up one row. **/ - this.moveCursorUp = function() { + this.moveCursorUp = function() { this.moveCursorBy(-1, 0); }; @@ -447,7 +442,7 @@ var Selection = function(session) { * * Moves the cursor down one row. **/ - this.moveCursorDown = function() { + this.moveCursorDown = function() { this.moveCursorBy(1, 0); }; @@ -456,7 +451,7 @@ var Selection = function(session) { * * Moves the cursor left one column. **/ - this.moveCursorLeft = function() { + this.moveCursorLeft = function() { var cursor = this.selectionLead.getPosition(), fold; @@ -482,7 +477,7 @@ var Selection = function(session) { * * Moves the cursor right one column. **/ - this.moveCursorRight = function() { + this.moveCursorRight = function() { var cursor = this.selectionLead.getPosition(), fold; if (fold = this.session.getFoldAt(cursor.row, cursor.column, 1)) { @@ -508,7 +503,7 @@ var Selection = function(session) { * * Moves the cursor to the start of the line. **/ - this.moveCursorLineStart = function() { + this.moveCursorLineStart = function() { var row = this.selectionLead.row; var column = this.selectionLead.column; var screenRow = this.session.documentToScreenRow(row, column); @@ -541,7 +536,7 @@ var Selection = function(session) { * * Moves the cursor to the end of the line. **/ - this.moveCursorLineEnd = function() { + this.moveCursorLineEnd = function() { var lead = this.selectionLead; var lastRowColumnPosition = this.session.getDocumentLastRowColumnPosition(lead.row, lead.column); @@ -556,7 +551,7 @@ var Selection = function(session) { * * Moves the cursor to the end of the file. **/ - this.moveCursorFileEnd = function() { + this.moveCursorFileEnd = function() { var row = this.doc.getLength() - 1; var column = this.doc.getLine(row).length; this.moveCursorTo(row, column); @@ -567,7 +562,7 @@ var Selection = function(session) { * * Moves the cursor to the start of the file. **/ - this.moveCursorFileStart = function() { + this.moveCursorFileStart = function() { this.moveCursorTo(0, 0); }; @@ -576,7 +571,7 @@ var Selection = function(session) { * * Moves the cursor to the word on the right. **/ - this.moveCursorWordRight = function() { + this.moveCursorWordRight = function() { var row = this.selectionLead.row; var column = this.selectionLead.column; var line = this.doc.getLine(row); @@ -623,7 +618,7 @@ var Selection = function(session) { * * Moves the cursor to the word on the left. **/ - this.moveCursorWordLeft = function() { + this.moveCursorWordLeft = function() { var row = this.selectionLead.row; var column = this.selectionLead.column; @@ -676,14 +671,20 @@ var Selection = function(session) { * * Moves the cursor to position indicated by the parameters. Negative numbers move the cursor backwards in the document. **/ - this.moveCursorBy = function(rows, chars) { + this.moveCursorBy = function(rows, chars) { var screenPos = this.session.documentToScreenPosition( this.selectionLead.row, this.selectionLead.column ); - var screenCol = (chars === 0 && this.$desiredColumn) || screenPos.column; - var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenCol); + if (chars === 0) { + if (this.$desiredColumn) + screenPos.column = this.$desiredColumn; + else + this.$desiredColumn = screenPos.column; + } + + var docPos = this.session.screenToDocumentPosition(screenPos.row + rows, screenPos.column); // move the cursor and update the desired column this.moveCursorTo(docPos.row, docPos.column + chars, chars === 0); @@ -695,19 +696,19 @@ var Selection = function(session) { * * Moves the selection to the position indicated by its `row` and `column`. **/ - this.moveCursorToPosition = function(position) { + this.moveCursorToPosition = function(position) { this.moveCursorTo(position.row, position.column); }; /** - * Selection.moveCursorTo(row, column, preventUpdateDesiredColumn) -> Void + * Selection.moveCursorTo(row, column, keepDesiredColumn) -> Void * - row (Number): The row to move to * - column (Number): The column to move to - * - preventUpdateDesiredColumn (Boolean): [If `true`, the cursor move does not respect the previous column]{: #preventUpdateBool} + * - keepDesiredColumn (Boolean): [If `true`, the cursor move does not respect the previous column]{: #preventUpdateBool} * * Moves the cursor to the row and column provided. [If `preventUpdateDesiredColumn` is `true`, then the cursor stays in the same column position as its original point.]{: #preventUpdateBoolDesc} **/ - this.moveCursorTo = function(row, column, preventUpdateDesiredColumn) { + this.moveCursorTo = function(row, column, keepDesiredColumn) { // Ensure the row/column is not inside of a fold. var fold = this.session.getFoldAt(row, column, 1); if (fold) { @@ -715,29 +716,55 @@ var Selection = function(session) { column = fold.start.column; } - this.$preventUpdateDesiredColumnOnChange = true; + this.$keepDesiredColumnOnChange = true; this.selectionLead.setPosition(row, column); - this.$preventUpdateDesiredColumnOnChange = false; + this.$keepDesiredColumnOnChange = false; - if (!preventUpdateDesiredColumn) - this.$updateDesiredColumn(this.selectionLead.column); + if (!keepDesiredColumn) + this.$desiredColumn = null; }; /** - * Selection.moveCursorToScreen(row, column, preventUpdateDesiredColumn) -> Void + * Selection.moveCursorToScreen(row, column, keepDesiredColumn) -> Void * - row (Number): The row to move to * - column (Number): The column to move to - * - preventUpdateDesiredColumn (Boolean): {:preventUpdateBool} + * - keepDesiredColumn (Boolean): {:preventUpdateBool} * * Moves the cursor to the screen position indicated by row and column. {:preventUpdateBoolDesc} **/ - this.moveCursorToScreen = function(row, column, preventUpdateDesiredColumn) { + this.moveCursorToScreen = function(row, column, keepDesiredColumn) { var pos = this.session.screenToDocumentPosition(row, column); - row = pos.row; - column = pos.column; - this.moveCursorTo(row, column, preventUpdateDesiredColumn); + this.moveCursorTo(pos.row, pos.column, keepDesiredColumn); }; + // remove listeners from document + this.detach = function() { + this.selectionLead.detach(); + this.selectionAnchor.detach(); + this.session = this.doc = null; + } + + this.fromOrientedRange = function(range) { + this.setSelectionRange(range, range.cursor == range.start); + this.$desiredColumn = range.desiredColumn || this.$desiredColumn; + } + + this.toOrientedRange = function(range) { + var r = this.getRange(); + if (range) { + range.start.column = r.start.column; + range.start.row = r.start.row; + range.end.column = r.end.column; + range.end.row = r.end.row; + } else { + range = r; + } + + range.cursor = this.isBackwards() ? range.start : range.end; + range.desiredColumn = this.$desiredColumn; + return range; + } + }).call(Selection.prototype); exports.Selection = Selection; diff --git a/lib/ace/split.js b/lib/ace/split.js index 13c7ef1a..06c251ae 100644 --- a/lib/ace/split.js +++ b/lib/ace/split.js @@ -73,7 +73,7 @@ var Split = function(container, theme, splits) { this.$splits = 0; this.$editorCSS = ""; this.$editors = []; - this.$oriantation = this.BESIDE; + this.$orientation = this.BESIDE; this.setSplits(splits || 1); this.$cEditor = this.$editors[0]; @@ -304,27 +304,27 @@ var Split = function(container, theme, splits) { }; /** internal - * Split.getOriantation() -> Number + * Split.getOrientation() -> Number * * Returns the orientation. * **/ - this.getOriantation = function() { - return this.$oriantation; + this.getOrientation = function() { + return this.$orientation; }; /** internal - * Split.setOriantation(oriantation) -> Void + * Split.setOrientation(oriantation) -> Void * - oriantation (Number): * * Sets the orientation. * **/ - this.setOriantation = function(oriantation) { - if (this.$oriantation == oriantation) { + this.setOrientation = function(orientation) { + if (this.$orientation == orientation) { return; } - this.$oriantation = oriantation; + this.$orientation = orientation; this.resize(); }; @@ -339,7 +339,7 @@ var Split = function(container, theme, splits) { var height = this.$container.clientHeight; var editor; - if (this.$oriantation == this.BESIDE) { + if (this.$orientation == this.BESIDE) { var editorWidth = width / this.$splits; for (var i = 0; i < this.$splits; i++) { editor = this.$editors[i]; diff --git a/lib/ace/test/all_browser.js b/lib/ace/test/all_browser.js index 90eab310..d6c349f7 100644 --- a/lib/ace/test/all_browser.js +++ b/lib/ace/test/all_browser.js @@ -9,96 +9,116 @@ var passed = 0 var failed = 0 var log = document.getElementById("log") -var tests = [ - require("ace/anchor_test"), - require("ace/commands/command_manager_test"), - require("ace/document_test"), - require("ace/edit_session_test"), - require("ace/editor_change_document_test"), - require("ace/editor_highlight_selected_word_test"), - require("ace/editor_navigation_test"), - require("ace/editor_text_edit_test"), - require("ace/ext/static_highlight_test"), - require("ace/layer/text_test"), - require("ace/lib/event_emitter_test"), - require("ace/mode/coffee/parser_test"), - require("ace/mode/coffee_tokenizer_test"), - require("ace/mode/coldfusion_test"), - require("ace/mode/css_test"), - require("ace/mode/css_tokenizer_test"), - require("ace/mode/css_worker"), - require("ace/mode/html_test"), - require("ace/mode/html_tokenizer_test"), - require("ace/mode/javascript_test"), - require("ace/mode/javascript_tokenizer_test"), - require("ace/mode/javascript_worker_test"), - require("ace/mode/python_test"), - require("ace/mode/ruby_tokenizer_test"), - require("ace/mode/text_test"), - require("ace/mode/xml_test"), - require("ace/mode/xml_tokenizer_test"), - require("ace/mode/folding/cstyle_test"), - require("ace/mode/folding/html_test"), - require("ace/mode/folding/pythonic_test"), - require("ace/mode/folding/xml_test"), - require("ace/range_test"), - require("ace/search_test"), - require("ace/selection_test"), - require("ace/token_iterator_test"), - require("ace/virtual_renderer_test") -] +var testNames = [ + "ace/anchor_test", + "ace/commands/command_manager_test", + "ace/document_test", + "ace/edit_session_test", + "ace/editor_change_document_test", + "ace/editor_highlight_selected_word_test", + "ace/editor_navigation_test", + "ace/editor_text_edit_test", + "ace/ext/static_highlight_test", + "ace/layer/text_test", + "ace/lib/event_emitter_test", + "ace/mode/coffee/parser_test", + "ace/mode/coffee_highlight_rules_test", + "ace/mode/coldfusion_test", + "ace/mode/css_test", + "ace/mode/css_highlight_rules_test", + "ace/mode/css_worker", + "ace/mode/html_test", + "ace/mode/html_highlight_rules_test", + "ace/mode/javascript_test", + "ace/mode/javascript_highlight_rules_test", + "ace/mode/javascript_worker_test", + "ace/mode/python_test", + "ace/mode/ruby_highlight_rules_test", + "ace/mode/text_test", + "ace/mode/xml_test", + "ace/mode/xml_highlight_rules_test", + "ace/mode/folding/cstyle_test", + "ace/mode/folding/html_test", + "ace/mode/folding/pythonic_test", + "ace/mode/folding/xml_test", + "ace/multi_select_test", + "ace/range_test", + "ace/range_list_test", + "ace/search_test", + "ace/selection_test", + "ace/token_iterator_test", + "ace/virtual_renderer_test" +]; -async.list(tests) - .expand(function(test) { - return AsyncTest.testcase(test) - }, AsyncTest.TestGenerator) - .run() - .each(function(test, next) { - var node = document.createElement("div"); - node.className = test.passed ? "passed" : "failed"; +var html = ["all tests
"]; +for (var i in testNames) { + var href = testNames[i]; + html.push("", href.replace(/^ace\//, "") ,"
"); +} - var name = test.name - if (test.suiteName) - name = test.suiteName + ": " + test.name +var nav = document.createElement("div"); +nav.innerHTML = html.join(""); +nav.style.cssText = "position:absolute;right:0;top:0"; +document.body.appendChild(nav); - var msg = "[" + test.count + "/" + test.index + "] " + name + " " + (test.passed ? "OK" : "FAIL") - if (!test.passed) { - if (test.err.stack) - var err = test.err.stack +if (location.search) + testNames = location.search.substr(1).split(",") + +require(testNames, function() { + var tests = testNames.map(require); + + async.list(tests) + .expand(function(test) { + return AsyncTest.testcase(test) + }, AsyncTest.TestGenerator) + .run() + .each(function(test, next) { + var node = document.createElement("div"); + node.className = test.passed ? "passed" : "failed"; + + var name = test.name + if (test.suiteName) + name = test.suiteName + ": " + test.name + + var msg = "[" + test.count + "/" + test.index + "] " + name + " " + (test.passed ? "OK" : "FAIL") + if (!test.passed) { + if (test.err.stack) + var err = test.err.stack + else + var err = test.err + + console.error(msg); + console.error(err); + msg += "
" + err + "
"; + } else { + console.log(msg); + } + + node.innerHTML = msg; + log.appendChild(node); + + next() + }) + .each(function(test) { + if (test.passed) + passed += 1 else - var err = test.err - - console.error(msg); - console.error(err); - msg += "
" + err + "
"; - } else { - console.log(msg); - } - - node.innerHTML = msg; - log.appendChild(node); - - next() - }) - .each(function(test) { - if (test.passed) - passed += 1 - else - failed += 1 - }) - .end(function() { - log.innerHTML += [ - "
", - "
", - "Summary:
", - "
", - "Total number of tests: " + (passed + failed) + "
", - (passed ? "Passed tests: " + passed + "
" : ""), - (failed ? "Failed tests: " + failed + "
" : "") - ].join("") - console.log("Total number of tests: " + (passed + failed)); - console.log("Passed tests: " + passed); - console.log("Failed tests: " + failed); - }) + failed += 1 + }) + .end(function() { + log.innerHTML += [ + "
", + "
", + "Summary:
", + "
", + "Total number of tests: " + (passed + failed) + "
", + (passed ? "Passed tests: " + passed + "
" : ""), + (failed ? "Failed tests: " + failed + "
" : "") + ].join("") + console.log("Total number of tests: " + (passed + failed)); + console.log("Passed tests: " + passed); + console.log("Failed tests: " + failed); + }) +}); }); diff --git a/lib/ace/test/mockrenderer.js b/lib/ace/test/mockrenderer.js index 2645f5e9..8305705a 100644 --- a/lib/ace/test/mockrenderer.js +++ b/lib/ace/test/mockrenderer.js @@ -81,6 +81,12 @@ MockRenderer.prototype.getTextAreaContainer = function() { return this.container; }; +MockRenderer.prototype.addGutterDecoration = function() { +}; + +MockRenderer.prototype.removeGutterDecoration = function() { +}; + MockRenderer.prototype.moveTextAreaToCursor = function() { }; @@ -174,6 +180,12 @@ MockRenderer.prototype.visualizeFocus = function() { MockRenderer.prototype.setAnnotations = function() { }; +MockRenderer.prototype.setStyle = function() { +}; + +MockRenderer.prototype.unsetStyle = function() { +}; + MockRenderer.prototype.textToScreenCoordinates = function() { return { pageX: 0, diff --git a/lib/ace/theme/clouds.js b/lib/ace/theme/clouds.js index 31db8dd0..11a54d3d 100644 --- a/lib/ace/theme/clouds.js +++ b/lib/ace/theme/clouds.js @@ -75,11 +75,16 @@ exports.cssText = "\ border-left: 0px;\ border-bottom: 1px solid #000000;\ }\ - \ +\ .ace-clouds .ace_marker-layer .ace_selection {\ background: #BDD5FC;\ }\ \ +.ace-clouds.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #FFFFFF;\ + border-radius: 2px;\ +}\ +\ .ace-clouds .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-clouds .ace_marker-layer .ace_selected_word {\ border: 1px solid #BDD5FC;\ }\ - \ +\ .ace-clouds .ace_invisible {\ color: #BFBFBF;\ }\ diff --git a/lib/ace/theme/clouds_midnight.js b/lib/ace/theme/clouds_midnight.js index 96a3fe74..094f95de 100644 --- a/lib/ace/theme/clouds_midnight.js +++ b/lib/ace/theme/clouds_midnight.js @@ -75,11 +75,16 @@ exports.cssText = "\ border-left: 0px;\ border-bottom: 1px solid #7DA5DC;\ }\ - \ +\ .ace-clouds-midnight .ace_marker-layer .ace_selection {\ background: #000000;\ }\ \ +.ace-clouds-midnight.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #191919;\ + border-radius: 2px;\ +}\ +\ .ace-clouds-midnight .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-clouds-midnight .ace_marker-layer .ace_selected_word {\ border: 1px solid #000000;\ }\ - \ +\ .ace-clouds-midnight .ace_invisible {\ color: #BFBFBF;\ }\ diff --git a/lib/ace/theme/cobalt.js b/lib/ace/theme/cobalt.js index a13f8db5..0b461b39 100644 --- a/lib/ace/theme/cobalt.js +++ b/lib/ace/theme/cobalt.js @@ -75,11 +75,16 @@ exports.cssText = "\ border-left: 0px;\ border-bottom: 1px solid #FFFFFF;\ }\ - \ +\ .ace-cobalt .ace_marker-layer .ace_selection {\ background: rgba(179, 101, 57, 0.75);\ }\ \ +.ace-cobalt.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #002240;\ + border-radius: 2px;\ +}\ +\ .ace-cobalt .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-cobalt .ace_marker-layer .ace_selected_word {\ border: 1px solid rgba(179, 101, 57, 0.75);\ }\ - \ +\ .ace-cobalt .ace_invisible {\ color: rgba(255, 255, 255, 0.15);\ }\ @@ -109,6 +114,14 @@ exports.cssText = "\ color:#FF628C;\ }\ \ +.ace-cobalt .ace_constant.ace_character, {\ + color:#FF628C;\ +}\ +\ +.ace-cobalt .ace_constant.ace_character.ace_escape, {\ + color:#FF628C;\ +}\ +\ .ace-cobalt .ace_invalid {\ color:#F8F8F8;\ background-color:#800F00;\ diff --git a/lib/ace/theme/dawn.js b/lib/ace/theme/dawn.js index de78eede..1974a94d 100644 --- a/lib/ace/theme/dawn.js +++ b/lib/ace/theme/dawn.js @@ -75,11 +75,16 @@ exports.cssText = "\ border-left: 0px;\ border-bottom: 1px solid #000000;\ }\ - \ +\ .ace-dawn .ace_marker-layer .ace_selection {\ background: rgba(39, 95, 255, 0.30);\ }\ \ +.ace-dawn.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #F9F9F9;\ + border-radius: 2px;\ +}\ +\ .ace-dawn .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-dawn .ace_marker-layer .ace_selected_word {\ border: 1px solid rgba(39, 95, 255, 0.30);\ }\ - \ +\ .ace-dawn .ace_invisible {\ color: rgba(75, 75, 126, 0.50);\ }\ @@ -109,6 +114,14 @@ exports.cssText = "\ color:#811F24;\ }\ \ +.ace-dawn .ace_constant.ace_character, {\ + color:#811F24;\ +}\ +\ +.ace-dawn .ace_constant.ace_character.ace_escape, {\ + color:#811F24;\ +}\ +\ .ace-dawn .ace_invalid.ace_illegal {\ text-decoration:underline;\ font-style:italic;\ diff --git a/lib/ace/theme/eclipse.js b/lib/ace/theme/eclipse.js index ed2376a0..8f0bc7c9 100644 --- a/lib/ace/theme/eclipse.js +++ b/lib/ace/theme/eclipse.js @@ -67,7 +67,7 @@ exports.cssText = ".ace-eclipse .ace_editor {\ }\ \ .ace-eclipse .ace_cursor {\ - border-left: 1px solid black;\ + border-left: 2px solid black;\ }\ \ .ace-eclipse .ace_line .ace_storage,\ diff --git a/lib/ace/theme/idle_fingers.js b/lib/ace/theme/idle_fingers.js index 7a90540d..9da3d396 100644 --- a/lib/ace/theme/idle_fingers.js +++ b/lib/ace/theme/idle_fingers.js @@ -75,11 +75,16 @@ exports.cssText = "\ 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.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #323232;\ + border-radius: 2px;\ +}\ +\ .ace-idle-fingers .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-idle-fingers .ace_marker-layer .ace_selected_word {\ border: 1px solid rgba(90, 100, 126, 0.88);\ }\ - \ +\ .ace-idle-fingers .ace_invisible {\ color: #404040;\ }\ @@ -109,6 +114,14 @@ exports.cssText = "\ color:#6C99BB;\ }\ \ +.ace-idle-fingers .ace_constant.ace_character, {\ + color:#6C99BB;\ +}\ +\ +.ace-idle-fingers .ace_constant.ace_character.ace_escape, {\ + color:#6C99BB;\ +}\ +\ .ace-idle-fingers .ace_invalid {\ color:#FFFFFF;\ background-color:#FF0000;\ @@ -158,7 +171,7 @@ color:#BC9458;\ \ .ace-idle-fingers .ace_collab.ace_user1 {\ color:#323232;\ -background-color:#FFF980; \ +background-color:#FFF980;\ }"; var dom = require("../lib/dom"); diff --git a/lib/ace/theme/kr_theme.js b/lib/ace/theme/kr_theme.js index 66fe58c2..413d55d2 100644 --- a/lib/ace/theme/kr_theme.js +++ b/lib/ace/theme/kr_theme.js @@ -75,11 +75,16 @@ exports.cssText = "\ 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.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #0B0A09;\ + border-radius: 2px;\ +}\ +\ .ace-kr-theme .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-kr-theme .ace_marker-layer .ace_selected_word {\ border: 1px solid rgba(170, 0, 255, 0.45);\ }\ - \ +\ .ace-kr-theme .ace_invisible {\ color: rgba(255, 177, 111, 0.32);\ }\ @@ -109,6 +114,14 @@ exports.cssText = "\ color:rgba(210, 117, 24, 0.76);\ }\ \ +.ace-kr-theme .ace_constant.ace_character, {\ + color:rgba(210, 117, 24, 0.76);\ +}\ +\ +.ace-kr-theme .ace_constant.ace_character.ace_escape, {\ + color:rgba(210, 117, 24, 0.76);\ +}\ +\ .ace-kr-theme .ace_invalid {\ color:#F8F8F8;\ background-color:#A41300;\ diff --git a/lib/ace/theme/merbivore.js b/lib/ace/theme/merbivore.js index de2f396b..95927960 100644 --- a/lib/ace/theme/merbivore.js +++ b/lib/ace/theme/merbivore.js @@ -75,11 +75,16 @@ exports.cssText = "\ border-left: 0px;\ border-bottom: 1px solid #FFFFFF;\ }\ - \ +\ .ace-merbivore .ace_marker-layer .ace_selection {\ background: #454545;\ }\ \ +.ace-merbivore.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #161616;\ + border-radius: 2px;\ +}\ +\ .ace-merbivore .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-merbivore .ace_marker-layer .ace_selected_word {\ border: 1px solid #454545;\ }\ - \ +\ .ace-merbivore .ace_invisible {\ color: #404040;\ }\ @@ -109,6 +114,14 @@ exports.cssText = "\ color:#1EDAFB;\ }\ \ +.ace-merbivore .ace_constant.ace_character, {\ + color:#1EDAFB;\ +}\ +\ +.ace-merbivore .ace_constant.ace_character.ace_escape, {\ + color:#1EDAFB;\ +}\ +\ .ace-merbivore .ace_constant.ace_language {\ color:#FDC251;\ }\ diff --git a/lib/ace/theme/merbivore_soft.js b/lib/ace/theme/merbivore_soft.js index dce3cebd..107d6df6 100644 --- a/lib/ace/theme/merbivore_soft.js +++ b/lib/ace/theme/merbivore_soft.js @@ -75,11 +75,16 @@ exports.cssText = "\ border-left: 0px;\ border-bottom: 1px solid #FFFFFF;\ }\ - \ +\ .ace-merbivore-soft .ace_marker-layer .ace_selection {\ background: #494949;\ }\ \ +.ace-merbivore-soft.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #1C1C1C;\ + border-radius: 2px;\ +}\ +\ .ace-merbivore-soft .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-merbivore-soft .ace_marker-layer .ace_selected_word {\ border: 1px solid #494949;\ }\ - \ +\ .ace-merbivore-soft .ace_invisible {\ color: #404040;\ }\ @@ -109,6 +114,14 @@ exports.cssText = "\ color:#68C1D8;\ }\ \ +.ace-merbivore-soft .ace_constant.ace_character, {\ + color:#68C1D8;\ +}\ +\ +.ace-merbivore-soft .ace_constant.ace_character.ace_escape, {\ + color:#68C1D8;\ +}\ +\ .ace-merbivore-soft .ace_constant.ace_language {\ color:#E1C582;\ }\ diff --git a/lib/ace/theme/mono_industrial.js b/lib/ace/theme/mono_industrial.js index 21f4e6f8..fdf47fa2 100644 --- a/lib/ace/theme/mono_industrial.js +++ b/lib/ace/theme/mono_industrial.js @@ -75,11 +75,16 @@ exports.cssText = "\ 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.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #222C28;\ + border-radius: 2px;\ +}\ +\ .ace-mono-industrial .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-mono-industrial .ace_marker-layer .ace_selected_word {\ border: 1px solid rgba(145, 153, 148, 0.40);\ }\ - \ +\ .ace-mono-industrial .ace_invisible {\ color: rgba(102, 108, 104, 0.50);\ }\ @@ -113,6 +118,14 @@ exports.cssText = "\ color:#E98800;\ }\ \ +.ace-mono-industrial .ace_constant.ace_character, {\ + color:#E98800;\ +}\ +\ +.ace-mono-industrial .ace_constant.ace_character.ace_escape, {\ + color:#E98800;\ +}\ +\ .ace-mono-industrial .ace_constant.ace_numeric {\ color:#E98800;\ }\ diff --git a/lib/ace/theme/monokai.js b/lib/ace/theme/monokai.js index c1a5a2d8..ba5fca86 100644 --- a/lib/ace/theme/monokai.js +++ b/lib/ace/theme/monokai.js @@ -75,11 +75,16 @@ exports.cssText = "\ border-left: 0px;\ border-bottom: 1px solid #F8F8F0;\ }\ - \ +\ .ace-monokai .ace_marker-layer .ace_selection {\ background: #49483E;\ }\ \ +.ace-monokai.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #272822;\ + border-radius: 2px;\ +}\ +\ .ace-monokai .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-monokai .ace_marker-layer .ace_selected_word {\ border: 1px solid #49483E;\ }\ - \ +\ .ace-monokai .ace_invisible {\ color: #49483E;\ }\ diff --git a/lib/ace/theme/pastel_on_dark.js b/lib/ace/theme/pastel_on_dark.js index 415ffaf2..3399e7ce 100644 --- a/lib/ace/theme/pastel_on_dark.js +++ b/lib/ace/theme/pastel_on_dark.js @@ -75,11 +75,16 @@ exports.cssText = "\ border-left: 0px;\ border-bottom: 1px solid #A7A7A7;\ }\ - \ +\ .ace-pastel-on-dark .ace_marker-layer .ace_selection {\ background: rgba(221, 240, 255, 0.20);\ }\ \ +.ace-pastel-on-dark.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #2C2828;\ + border-radius: 2px;\ +}\ +\ .ace-pastel-on-dark .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-pastel-on-dark .ace_marker-layer .ace_selected_word {\ border: 1px solid rgba(221, 240, 255, 0.20);\ }\ - \ +\ .ace-pastel-on-dark .ace_invisible {\ color: rgba(255, 255, 255, 0.25);\ }\ @@ -113,6 +118,14 @@ exports.cssText = "\ color:#4FB7C5;\ }\ \ +.ace-pastel-on-dark .ace_constant.ace_character, {\ + color:#4FB7C5;\ +}\ +\ +.ace-pastel-on-dark .ace_constant.ace_character.ace_escape, {\ + color:#4FB7C5;\ +}\ +\ .ace-pastel-on-dark .ace_constant.ace_language {\ color:#DE8E30;\ }\ diff --git a/lib/ace/theme/solarized_dark.js b/lib/ace/theme/solarized_dark.js index 0a18111e..35ff5ae9 100644 --- a/lib/ace/theme/solarized_dark.js +++ b/lib/ace/theme/solarized_dark.js @@ -75,11 +75,16 @@ exports.cssText = "\ border-left: 0px;\ border-bottom: 1px solid #D30102;\ }\ - \ +\ .ace-solarized-dark .ace_marker-layer .ace_selection {\ background: #073642;\ }\ \ +.ace-solarized-dark.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #002B36;\ + border-radius: 2px;\ +}\ +\ .ace-solarized-dark .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-solarized-dark .ace_marker-layer .ace_selected_word {\ border: 1px solid #073642;\ }\ - \ +\ .ace-solarized-dark .ace_invisible {\ color: rgba(147, 161, 161, 0.50);\ }\ diff --git a/lib/ace/theme/solarized_light.js b/lib/ace/theme/solarized_light.js index e6866d08..1327ce64 100644 --- a/lib/ace/theme/solarized_light.js +++ b/lib/ace/theme/solarized_light.js @@ -75,11 +75,16 @@ exports.cssText = "\ border-left: 0px;\ border-bottom: 1px solid #000000;\ }\ - \ +\ .ace-solarized-light .ace_marker-layer .ace_selection {\ background: #073642;\ }\ \ +.ace-solarized-light.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #FDF6E3;\ + border-radius: 2px;\ +}\ +\ .ace-solarized-light .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-solarized-light .ace_marker-layer .ace_selected_word {\ border: 1px solid #073642;\ }\ - \ +\ .ace-solarized-light .ace_invisible {\ color: rgba(147, 161, 161, 0.50);\ }\ diff --git a/lib/ace/theme/textmate.js b/lib/ace/theme/textmate.js index 8bc8d7c4..76eb0673 100644 --- a/lib/ace/theme/textmate.js +++ b/lib/ace/theme/textmate.js @@ -84,6 +84,10 @@ exports.cssText = ".ace-tm .ace_editor {\ color: blue;\ }\ \ +.ace-tm .ace_line .ace_constant {\ + color: rgb(197, 6, 11);\ +}\ +\ .ace-tm .ace_line .ace_constant.ace_buildin {\ color: rgb(88, 72, 246);\ }\ @@ -165,7 +169,10 @@ exports.cssText = ".ace-tm .ace_editor {\ .ace-tm .ace_marker-layer .ace_selection {\ background: rgb(181, 213, 255);\ }\ -\ +.ace-tm.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px white;\ + border-radius: 2px;\ +}\ .ace-tm .ace_marker-layer .ace_step {\ background: rgb(252, 255, 0);\ }\ diff --git a/lib/ace/theme/tomorrow.js b/lib/ace/theme/tomorrow.js index c42902f1..14e19d77 100644 --- a/lib/ace/theme/tomorrow.js +++ b/lib/ace/theme/tomorrow.js @@ -75,11 +75,16 @@ exports.cssText = "\ border-left: 0px;\ border-bottom: 1px solid #AEAFAD;\ }\ - \ +\ .ace-tomorrow .ace_marker-layer .ace_selection {\ background: #D6D6D6;\ }\ \ +.ace-tomorrow.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #FFFFFF;\ + border-radius: 2px;\ +}\ +\ .ace-tomorrow .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-tomorrow .ace_marker-layer .ace_selected_word {\ border: 1px solid #D6D6D6;\ }\ - \ +\ .ace-tomorrow .ace_invisible {\ color: #D1D1D1;\ }\ diff --git a/lib/ace/theme/tomorrow_night.js b/lib/ace/theme/tomorrow_night.js index e6638144..621c6bb8 100644 --- a/lib/ace/theme/tomorrow_night.js +++ b/lib/ace/theme/tomorrow_night.js @@ -75,11 +75,16 @@ exports.cssText = "\ border-left: 0px;\ border-bottom: 1px solid #AEAFAD;\ }\ - \ +\ .ace-tomorrow-night .ace_marker-layer .ace_selection {\ background: #373B41;\ }\ \ +.ace-tomorrow-night.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #1D1F21;\ + border-radius: 2px;\ +}\ +\ .ace-tomorrow-night .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-tomorrow-night .ace_marker-layer .ace_selected_word {\ border: 1px solid #373B41;\ }\ - \ +\ .ace-tomorrow-night .ace_invisible {\ color: #4B4E55;\ }\ diff --git a/lib/ace/theme/tomorrow_night_blue.js b/lib/ace/theme/tomorrow_night_blue.js index f81499f3..72ffb2bc 100644 --- a/lib/ace/theme/tomorrow_night_blue.js +++ b/lib/ace/theme/tomorrow_night_blue.js @@ -75,11 +75,16 @@ exports.cssText = "\ border-left: 0px;\ border-bottom: 1px solid #FFFFFF;\ }\ - \ +\ .ace-tomorrow-night-blue .ace_marker-layer .ace_selection {\ background: #003F8E;\ }\ \ +.ace-tomorrow-night-blue.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #002451;\ + border-radius: 2px;\ +}\ +\ .ace-tomorrow-night-blue .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-tomorrow-night-blue .ace_marker-layer .ace_selected_word {\ border: 1px solid #003F8E;\ }\ - \ +\ .ace-tomorrow-night-blue .ace_invisible {\ color: #404F7D;\ }\ diff --git a/lib/ace/theme/tomorrow_night_bright.js b/lib/ace/theme/tomorrow_night_bright.js index e797641a..6d5f2c2f 100644 --- a/lib/ace/theme/tomorrow_night_bright.js +++ b/lib/ace/theme/tomorrow_night_bright.js @@ -75,11 +75,16 @@ exports.cssText = "\ border-left: 0px;\ border-bottom: 1px solid #9F9F9F;\ }\ - \ +\ .ace-tomorrow-night-bright .ace_marker-layer .ace_selection {\ background: #424242;\ }\ \ +.ace-tomorrow-night-bright.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #000000;\ + border-radius: 2px;\ +}\ +\ .ace-tomorrow-night-bright .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-tomorrow-night-bright .ace_marker-layer .ace_selected_word {\ border: 1px solid #424242;\ }\ - \ +\ .ace-tomorrow-night-bright .ace_invisible {\ color: #343434;\ }\ diff --git a/lib/ace/theme/tomorrow_night_eighties.js b/lib/ace/theme/tomorrow_night_eighties.js index cd815ca2..f6a67d4e 100644 --- a/lib/ace/theme/tomorrow_night_eighties.js +++ b/lib/ace/theme/tomorrow_night_eighties.js @@ -75,11 +75,16 @@ exports.cssText = "\ border-left: 0px;\ border-bottom: 1px solid #CCCCCC;\ }\ - \ +\ .ace-tomorrow-night-eighties .ace_marker-layer .ace_selection {\ background: #515151;\ }\ \ +.ace-tomorrow-night-eighties.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #2D2D2D;\ + border-radius: 2px;\ +}\ +\ .ace-tomorrow-night-eighties .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-tomorrow-night-eighties .ace_marker-layer .ace_selected_word {\ border: 1px solid #515151;\ }\ - \ +\ .ace-tomorrow-night-eighties .ace_invisible {\ color: #6A6A6A;\ }\ diff --git a/lib/ace/theme/twilight.js b/lib/ace/theme/twilight.js index f66991ef..842dd234 100644 --- a/lib/ace/theme/twilight.js +++ b/lib/ace/theme/twilight.js @@ -75,11 +75,16 @@ exports.cssText = "\ border-left: 0px;\ border-bottom: 1px solid #A7A7A7;\ }\ - \ +\ .ace-twilight .ace_marker-layer .ace_selection {\ background: rgba(221, 240, 255, 0.20);\ }\ \ +.ace-twilight.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #141414;\ + border-radius: 2px;\ +}\ +\ .ace-twilight .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-twilight .ace_marker-layer .ace_selected_word {\ border: 1px solid rgba(221, 240, 255, 0.20);\ }\ - \ +\ .ace-twilight .ace_invisible {\ color: rgba(255, 255, 255, 0.25);\ }\ @@ -109,6 +114,14 @@ exports.cssText = "\ color:#CF6A4C;\ }\ \ +.ace-twilight .ace_constant.ace_character, {\ + color:#CF6A4C;\ +}\ +\ +.ace-twilight .ace_constant.ace_character.ace_escape, {\ + color:#CF6A4C;\ +}\ +\ .ace-twilight .ace_invalid.ace_illegal {\ color:#F8F8F8;\ background-color:rgba(86, 45, 86, 0.75);\ diff --git a/lib/ace/theme/vibrant_ink.js b/lib/ace/theme/vibrant_ink.js index 3354a2e7..fac89c15 100644 --- a/lib/ace/theme/vibrant_ink.js +++ b/lib/ace/theme/vibrant_ink.js @@ -75,11 +75,16 @@ exports.cssText = "\ border-left: 0px;\ border-bottom: 1px solid #FFFFFF;\ }\ - \ +\ .ace-vibrant-ink .ace_marker-layer .ace_selection {\ background: #6699CC;\ }\ \ +.ace-vibrant-ink.multiselect .ace_selection.start {\ + box-shadow: 0 0 3px 0px #0F0F0F;\ + border-radius: 2px;\ +}\ +\ .ace-vibrant-ink .ace_marker-layer .ace_step {\ background: rgb(198, 219, 174);\ }\ @@ -96,7 +101,7 @@ exports.cssText = "\ .ace-vibrant-ink .ace_marker-layer .ace_selected_word {\ border: 1px solid #6699CC;\ }\ - \ +\ .ace-vibrant-ink .ace_invisible {\ color: #404040;\ }\ @@ -109,6 +114,14 @@ exports.cssText = "\ color:#339999;\ }\ \ +.ace-vibrant-ink .ace_constant.ace_character, {\ + color:#339999;\ +}\ +\ +.ace-vibrant-ink .ace_constant.ace_character.ace_escape, {\ + color:#339999;\ +}\ +\ .ace-vibrant-ink .ace_constant.ace_numeric {\ color:#99CC99;\ }\ diff --git a/lib/ace/tokenizer.js b/lib/ace/tokenizer.js index 802f9e90..8e769103 100644 --- a/lib/ace/tokenizer.js +++ b/lib/ace/tokenizer.js @@ -139,9 +139,8 @@ var Tokenizer = function(rules, flag) { else type = rule.token; - var next = rule.next; - if (next && next !== currentState) { - currentState = next; + if (rule.next) { + currentState = rule.next; state = this.rules[currentState]; mapping = this.matchMappings[currentState]; lastIndex = re.lastIndex; diff --git a/lib/ace/virtual_renderer.js b/lib/ace/virtual_renderer.js index 9be0193e..9bdebaa7 100644 --- a/lib/ace/virtual_renderer.js +++ b/lib/ace/virtual_renderer.js @@ -76,13 +76,13 @@ dom.importCssString(editorCss, "ace_editor"); var VirtualRenderer = function(container, theme) { var _self = this; - + this.container = container; // TODO: this breaks rendering in Cloud9 with multiple ace instances // // Imports CSS once per DOM document ('ace_editor' serves as an identifier). // dom.importCssString(editorCss, "ace_editor", container.ownerDocument); - + dom.addCssClass(container, "ace_editor"); this.setTheme(theme); @@ -100,8 +100,8 @@ var VirtualRenderer = function(container, theme) { this.scroller.appendChild(this.content); this.$gutterLayer = new GutterLayer(this.$gutter); - this.$gutterLayer.on("changeGutterWidth", this.onResize.bind(this, true)); - + this.$gutterLayer.on("changeGutterWidth", this.onResize.bind(this, true)); + this.$markerBack = new MarkerLayer(this.content); var textLayer = this.$textLayer = new TextLayer(this.content); @@ -119,6 +119,8 @@ var VirtualRenderer = function(container, theme) { this.$horizScroll = true; this.$horizScrollAlwaysVisible = true; + this.$animatedScroll = false; + this.scrollBar = new ScrollBar(container); this.scrollBar.addEventListener("scroll", function(e) { _self.session.setScrollTop(e.data); @@ -126,11 +128,18 @@ var VirtualRenderer = function(container, theme) { this.scrollTop = 0; this.scrollLeft = 0; - + event.addListener(this.scroller, "scroll", function() { var scrollLeft = _self.scroller.scrollLeft; _self.scrollLeft = scrollLeft; _self.session.setScrollLeft(scrollLeft); + + if (scrollLeft == 0) { + _self.$gutter.className = "ace_gutter"; + } + else { + _self.$gutter.className = "ace_gutter horscroll"; + } }); this.cursorPos = { @@ -316,6 +325,26 @@ var VirtualRenderer = function(container, theme) { return this.session.adjustWrapLimit(limit); }; + /** + * VirtualRenderer.setAnimatedScroll(shouldAnimate) -> Void + * - shouldAnimate (Boolean): Set to `true` to show animated scrolls + * + * Identifies whether you want to have an animated scroll or not. + * + **/ + this.setAnimatedScroll = function(shouldAnimate){ + this.$animatedScroll = shouldAnimate; + }; + + /** + * VirtualRenderer.getAnimatedScroll() -> Boolean + * + * Returns whether an animated scroll happens or not. + **/ + this.getAnimatedScroll = function() { + return this.$animatedScroll; + }; + /** * VirtualRenderer.setShowInvisibles(showInvisibles) -> Void * - showInvisibles (Boolean): Set to `true` to show invisibles @@ -331,7 +360,7 @@ var VirtualRenderer = function(container, theme) { /** * VirtualRenderer.getShowInvisibles() -> Boolean * - * Returns whether or not invisible characters are being shown or not. + * Returns whether invisible characters are being shown or not. **/ this.getShowInvisibles = function() { return this.$textLayer.showInvisibles; @@ -354,7 +383,7 @@ var VirtualRenderer = function(container, theme) { /** * VirtualRenderer.getShowPrintMargin() -> Boolean * - * Returns whether or not the print margin is being shown or not. + * Returns whetherthe print margin is being shown or not. **/ this.getShowPrintMargin = function() { return this.$showPrintMargin; @@ -377,7 +406,7 @@ var VirtualRenderer = function(container, theme) { /** * VirtualRenderer.getPrintMarginColumn() -> Boolean * - * Returns whether or not the print margin column is being shown or not. + * Returns whether the print margin column is being shown or not. **/ this.getPrintMarginColumn = function() { return this.$printMarginColumn; @@ -464,7 +493,7 @@ var VirtualRenderer = function(container, theme) { // this persists in IE9 if (useragent.isIE) return; - + if (this.layerConfig.lastRow === 0) return; @@ -538,7 +567,7 @@ var VirtualRenderer = function(container, theme) { /** * VirtualRenderer.getHScrollBarAlwaysVisible() -> Boolean * - * Returns whether or not the horizontal scrollbar is set to be always visible. + * Returns whether the horizontal scrollbar is set to be always visible. **/ this.getHScrollBarAlwaysVisible = function() { return this.$horizScrollAlwaysVisible; @@ -579,13 +608,13 @@ var VirtualRenderer = function(container, theme) { // horizontal scrolling if (changes & this.CHANGE_H_SCROLL) { this.scroller.scrollLeft = this.scrollLeft; - + // read the value after writing it since the value might get clipped var scrollLeft = this.scroller.scrollLeft; this.scrollLeft = scrollLeft; this.session.setScrollLeft(scrollLeft); } - + // full if (changes & this.CHANGE_FULL) { this.$textLayer.checkForSizeChanges(); @@ -937,21 +966,27 @@ var VirtualRenderer = function(container, theme) { this.session.setScrollTop(row * this.lineHeight); }; - /** - * VirtualRenderer.scrollToLine(line, center) - * - line (Number): The line to go to - * - center (Boolean): Identifies whether you want the cursor centered or not - * - * Scrolls the editor to the `line` indicated. - * - **/ this.scrollToLine = function(line, center) { var pos = this.$cursorLayer.getPixelPosition({row: line, column: 0}); var offset = pos.top; if (center) offset -= this.$size.scrollerHeight / 2; + if (this.$animatedScroll && Math.abs(offset - this.scrollTop) < 10000) { + var _self = this; + var steps = _self.$calcSteps(this.scrollTop, offset); + + clearInterval(this.$timer); + this.$timer = setInterval(function() { + _self.session.setScrollTop(steps.shift()); + + if (!steps.length) + clearInterval(_self.$timer); + }, 10); + } + else { this.session.setScrollTop(offset); + } }; /** @@ -1013,18 +1048,6 @@ var VirtualRenderer = function(container, theme) { // todo: handle horizontal scrolling }; - /** - * VirtualRenderer.screenToTextCoordinates(pageX, pageY) -> Object - * - pageX (Number): The x-coordinate relative to the left edge of the document - * - pageY (Number): The y-coordinate relative to the top edge of the document - * - * Returns the document position, based on the coordinates provided. - * - * #### Returns - * - * The object returned has two properties: `row` and `column`. - * - **/ this.screenToTextCoordinates = function(pageX, pageY) { var canvasPos = this.scroller.getBoundingClientRect(); @@ -1160,7 +1183,7 @@ var VirtualRenderer = function(container, theme) { return afterLoad(module); _self._loadTheme(moduleName, function() { - require([theme], function(module) { + require([moduleName], function(module) { if (_self.$themeValue !== theme) return; diff --git a/tool/Theme.tmpl.css b/tool/Theme.tmpl.css index 6f2962c3..1d6aca07 100644 --- a/tool/Theme.tmpl.css +++ b/tool/Theme.tmpl.css @@ -34,11 +34,16 @@ border-left: 0px; border-bottom: 1px solid %overwrite%; } - + .%cssClass% .ace_marker-layer .ace_selection { background: %selection%; } +.%cssClass%.multiselect .ace_selection.start { + box-shadow: 0 0 3px 0px %background%; + border-radius: 2px; +} + .%cssClass% .ace_marker-layer .ace_step { background: %step%; } @@ -55,7 +60,7 @@ .%cssClass% .ace_marker-layer .ace_selected_word { %selected_word_highlight% } - + .%cssClass% .ace_invisible { %invisible% } @@ -72,6 +77,14 @@ %constant% } +.%cssClass% .ace_constant.ace_character, { + %constant% +} + +.%cssClass% .ace_constant.ace_character.ace_escape, { + %constant% +} + .%cssClass% .ace_constant.ace_language { %constant.language% } @@ -230,5 +243,5 @@ } .%cssClass% .ace_collab.ace_user1 { - %collab.user1% + %collab.user1% } \ No newline at end of file diff --git a/tool/tmtheme.js b/tool/tmtheme.js old mode 100644 new mode 100755 index bfda3f1f..56866659 --- a/tool/tmtheme.js +++ b/tool/tmtheme.js @@ -8,16 +8,16 @@ function plistToJson(el) { return $plistParse(el.selectSingleNode("dict")); } -function $plistParse(el) { +function $plistParse(el) { if (el.tagName == "dict") { var dict = {}; var key; var childNodes = el.childNodes; for (var i=0, l=childNodes.length; i