summaryrefslogtreecommitdiffstats
path: root/apps/files_texteditor/js/aceeditor/ace-uncompressed.js
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files_texteditor/js/aceeditor/ace-uncompressed.js')
-rwxr-xr-xapps/files_texteditor/js/aceeditor/ace-uncompressed.js3210
1 files changed, 2810 insertions, 400 deletions
diff --git a/apps/files_texteditor/js/aceeditor/ace-uncompressed.js b/apps/files_texteditor/js/aceeditor/ace-uncompressed.js
index 619baf49016..74bb44b16d8 100755
--- a/apps/files_texteditor/js/aceeditor/ace-uncompressed.js
+++ b/apps/files_texteditor/js/aceeditor/ace-uncompressed.js
@@ -40,7 +40,7 @@
* @param module a name for the payload
* @param payload a function to call with (require, exports, module) params
*/
-
+
(function() {
var ACE_NAMESPACE = "";
@@ -49,9 +49,6 @@ var global = (function() {
return this;
})();
-if (typeof requirejs !== "undefined")
- return;
-
var _define = function(module, deps, payload) {
if (typeof module !== 'string') {
if (_define.original)
@@ -68,7 +65,7 @@ var _define = function(module, deps, payload) {
if (!_define.modules)
_define.modules = {};
-
+
_define.modules[module] = payload;
};
@@ -92,11 +89,11 @@ var _require = function(parentId, module, callback) {
var payload = lookup(parentId, module);
if (!payload && _require.original)
return _require.original.apply(window, arguments);
-
+
if (callback) {
callback();
}
-
+
return payload;
}
else {
@@ -115,13 +112,13 @@ var normalizeModule = function(parentId, moduleName) {
if (moduleName.charAt(0) == ".") {
var base = parentId.split("/").slice(0, -1).join("/");
moduleName = base + "/" + moduleName;
-
+
while(moduleName.indexOf(".") !== -1 && previous != moduleName) {
var previous = moduleName;
moduleName = moduleName.replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, "");
}
}
-
+
return moduleName;
};
@@ -141,19 +138,19 @@ var lookup = function(parentId, moduleName) {
if (typeof module === 'function') {
var exports = {};
var mod = {
- id: moduleName,
+ id: moduleName,
uri: '',
exports: exports,
packaged: true
};
-
+
var req = function(module, callback) {
return _require(moduleName, module, callback);
};
-
+
var returnValue = module(req, exports, mod);
exports = returnValue || mod.exports;
-
+
// cache the resulting module object for next time
_define.modules[moduleName] = exports;
return exports;
@@ -163,26 +160,45 @@ var lookup = function(parentId, moduleName) {
};
function exportAce(ns) {
+
+ if (typeof requirejs !== "undefined") {
+
+ var define = global.define;
+ global.define = function(id, deps, callback) {
+ if (typeof callback !== "function")
+ return define.apply(this, arguments);
+
+ return define(id, deps, function(require, exports, module) {
+ if (deps[2] == "module")
+ module.packaged = true;
+ return callback.apply(this, arguments);
+ });
+ };
+ global.define.packaged = true;
+
+ return;
+ }
+
var require = function(module, callback) {
return _require("", module, callback);
};
require.packaged = true;
-
+
var root = global;
if (ns) {
if (!global[ns])
global[ns] = {};
root = global[ns];
}
-
+
if (root.define)
_define.original = root.define;
-
+
root.define = _define;
if (root.require)
_require.original = root.require;
-
+
root.require = require;
}
@@ -225,7 +241,7 @@ exportAce(ACE_NAMESPACE);
*
* ***** END LICENSE BLOCK ***** */
-define('ace/ace', ['require', 'exports', 'module' , 'ace/lib/fixoldbrowsers', 'ace/lib/dom', 'ace/lib/event', 'ace/editor', 'ace/edit_session', 'ace/undomanager', 'ace/virtual_renderer', 'ace/theme/textmate'], function(require, exports, module) {
+define('ace/ace', ['require', 'exports', 'module' , 'ace/lib/fixoldbrowsers', 'ace/lib/dom', 'ace/lib/event', 'ace/editor', 'ace/edit_session', 'ace/undomanager', 'ace/virtual_renderer', 'ace/multi_select', 'ace/worker/worker_client', 'ace/keyboard/hash_handler', 'ace/keyboard/state_handler', 'ace/placeholder', 'ace/config', 'ace/theme/textmate'], function(require, exports, module) {
"use strict";
require("./lib/fixoldbrowsers");
@@ -237,6 +253,14 @@ var Editor = require("./editor").Editor;
var EditSession = require("./edit_session").EditSession;
var UndoManager = require("./undomanager").UndoManager;
var Renderer = require("./virtual_renderer").VirtualRenderer;
+var MultiSelect = require("./multi_select").MultiSelect;
+
+// The following require()s are for inclusion in the built ace file
+require("./worker/worker_client");
+require("./keyboard/hash_handler");
+require("./keyboard/state_handler");
+require("./placeholder");
+require("./config").init();
exports.edit = function(el) {
if (typeof(el) == "string") {
@@ -248,6 +272,7 @@ exports.edit = function(el) {
el.innerHTML = '';
var editor = new Editor(new Renderer(el, require("./theme/textmate")));
+ new MultiSelect(editor);
editor.setSession(doc);
var env = {};
@@ -326,7 +351,7 @@ define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require, ex
RegExp.prototype.exec = function (str) {
var match = real.exec.apply(this, arguments),
name, r2;
- if (match) {
+ if ( typeof(str) == 'string' && match) {
// Fix browsers whose `exec` methods don't consistently return `undefined` for
// nonparticipating capturing groups
if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) {
@@ -391,7 +416,8 @@ define('ace/lib/regexp', ['require', 'exports', 'module' ], function(require, ex
return -1;
};
-});// vim: ts=4 sts=4 sw=4 expandtab
+});
+// vim: ts=4 sts=4 sw=4 expandtab
// -- kriskowal Kris Kowal Copyright (C) 2009-2011 MIT License
// -- tlrobinson Tom Robinson Copyright (C) 2009-2010 MIT License (Narwhal Project)
// -- dantman Daniel Friesen Copyright (C) 2010 XXX TODO License or CLA
@@ -1573,7 +1599,7 @@ exports.hasCssString = function(id, doc) {
if (doc.createStyleSheet && (sheets = doc.styleSheets)) {
while (index < sheets.length)
- if (sheets[index++].title === id) return true;
+ if (sheets[index++].owningElement.id === id) return true;
} else if ((sheets = doc.getElementsByTagName("style"))) {
while (index < sheets.length)
if (sheets[index++].id === id) return true;
@@ -1594,7 +1620,7 @@ exports.importCssString = function importCssString(cssText, id, doc) {
style = doc.createStyleSheet();
style.cssText = cssText;
if (id)
- style.title = id;
+ style.owningElement.id = id;
} else {
style = doc.createElementNS
? doc.createElementNS(XHTML_NS, "style")
@@ -1740,8 +1766,7 @@ exports.getParentWindow = function(document) {
return document.defaultView || document.parentWindow;
};
-});
-/* ***** BEGIN LICENSE BLOCK *****
+});/* ***** 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
@@ -1917,20 +1942,9 @@ else {
}
exports.addMouseWheelListener = function(el, callback) {
- var max = 0;
+ var factor = 8;
var listener = function(e) {
if (e.wheelDelta !== undefined) {
-
- // some versions of Safari (e.g. 5.0.5) report insanely high
- // scroll values. These browsers require a higher factor
- if (Math.abs(e.wheelDeltaY) > max)
- max = Math.abs(e.wheelDeltaY);
-
- if (max > 5000)
- var factor = 400;
- else
- var factor = 8;
-
if (e.wheelDeltaX !== undefined) {
e.wheelX = -e.wheelDeltaX / factor;
e.wheelY = -e.wheelDeltaY / factor;
@@ -2029,7 +2043,7 @@ function normalizeCommandKeys(callback, e, keyCode) {
exports.addCommandKeyListener = function(el, callback) {
var addListener = exports.addListener;
- if (useragent.isOldGecko) {
+ if (useragent.isOldGecko || useragent.isOpera) {
// Old versions of Gecko aka. Firefox < 4.0 didn't repeat the keydown
// event if the user pressed the key for a longer time. Instead, the
// keydown event was fired once and later on only the keypress event.
@@ -2050,18 +2064,6 @@ exports.addCommandKeyListener = function(el, callback) {
lastDown = e.keyIdentifier || e.keyCode;
return normalizeCommandKeys(callback, e, e.keyCode);
});
-
- // repeated keys are fired as keypress and not keydown events
- if (useragent.isMac && useragent.isOpera) {
- addListener(el, "keypress", function(e) {
- var keyId = e.keyIdentifier || e.keyCode;
- if (lastDown !== keyId) {
- return normalizeCommandKeys(callback, e, lastDown);
- } else {
- lastDown = null;
- }
- });
- }
}
};
@@ -2446,7 +2448,7 @@ var Editor = function(renderer, session) {
var container = renderer.getContainerElement();
this.container = container;
this.renderer = renderer;
-
+
this.textInput = new TextInput(renderer.getTextAreaContainer(), this);
this.keyBinding = new KeyBinding(this);
@@ -2558,7 +2560,10 @@ var Editor = function(renderer, session) {
this.onChangeMode();
+ this.$blockScrolling += 1;
this.onCursorChange();
+ this.$blockScrolling -= 1;
+
this.onScrollTopChange();
this.onScrollLeftChange();
this.onSelectionChange();
@@ -2605,6 +2610,7 @@ var Editor = function(renderer, session) {
this.setFontSize = function(size) {
this.container.style.fontSize = size;
+ this.renderer.updateFontSize();
};
this.$highlightBrackets = function() {
@@ -2710,21 +2716,29 @@ var Editor = function(renderer, session) {
this.$updateHighlightActiveLine = function() {
var session = this.getSession();
- if (session.$highlightLineMarker) {
+ if (session.$highlightLineMarker)
session.removeMarker(session.$highlightLineMarker);
- }
+ if (typeof this.$lastrow == "number")
+ this.renderer.removeGutterDecoration(this.$lastrow, "ace_gutter_active_line");
+
session.$highlightLineMarker = null;
+ this.$lastrow = null;
- if (this.getHighlightActiveLine() && (this.getSelectionStyle() != "line" || !this.selection.isMultiLine())) {
+ if (this.getHighlightActiveLine()) {
var cursor = this.getCursorPosition(),
foldLine = this.session.getFoldLine(cursor.row);
- var range;
- if (foldLine) {
- range = new Range(foldLine.start.row, 0, foldLine.end.row + 1, 0);
- } else {
- range = new Range(cursor.row, 0, cursor.row+1, 0);
+
+ if ((this.getSelectionStyle() != "line" || !this.selection.isMultiLine())) {
+ var range;
+ if (foldLine) {
+ range = new Range(foldLine.start.row, 0, foldLine.end.row + 1, 0);
+ } else {
+ range = new Range(cursor.row, 0, cursor.row+1, 0);
+ }
+ session.$highlightLineMarker = session.addMarker(range, "ace_active_line", "background");
}
- session.$highlightLineMarker = session.addMarker(range, "ace_active_line", "background");
+
+ this.renderer.addGutterDecoration(this.$lastrow = cursor.row, "ace_gutter_active_line");
}
};
@@ -2794,16 +2808,7 @@ var Editor = function(renderer, session) {
};
this.onCut = function() {
- if (this.$readOnly)
- return;
-
- var range = this.getSelectionRange();
- this._emit("cut", range);
-
- if (!this.selection.isEmpty()) {
- this.session.remove(range);
- this.clearSelection();
- }
+ this.commands.exec("cut", this);
};
this.insert = function(text) {
@@ -2978,6 +2983,14 @@ var Editor = function(renderer, session) {
return this.$highlightSelectedWord;
};
+ this.setAnimatedScroll = function(shouldAnimate){
+ this.renderer.setAnimatedScroll(shouldAnimate);
+ };
+
+ this.getAnimatedScroll = function(){
+ return this.renderer.getAnimatedScroll();
+ };
+
this.setShowInvisibles = function(showInvisibles) {
if (this.getShowInvisibles() == showInvisibles)
return;
@@ -3032,7 +3045,7 @@ var Editor = function(renderer, session) {
this.$showFoldWidgets = show;
this.renderer.updateFull();
};
-
+
this.getShowFoldWidgets = function() {
return this.renderer.$gutterLayer.getShowFoldWidgets();
};
@@ -3249,7 +3262,7 @@ var Editor = function(renderer, session) {
range.start.row += linesMoved;
range.end.row += linesMoved;
selection.setSelectionRange(range, reverse);
- }
+ }
else {
selection.setSelectionAnchor(rows.last+linesMoved+1, 0);
selection.$moveSelection(function() {
@@ -3413,13 +3426,13 @@ var Editor = function(renderer, session) {
cursor.column -= 2;
pos = this.session.findMatchingBracket(cursor);
}
-
+
if (pos) {
this.clearSelection();
this.moveCursorTo(pos.row, pos.column);
}
};
-
+
this.gotoLine = function(lineNumber, column) {
this.selection.clearSelection();
this.session.unfold({row: lineNumber - 1, column: column || 0});
@@ -3511,12 +3524,19 @@ var Editor = function(renderer, session) {
this.$search.set(options);
var range = this.$search.find(this.session);
+ var replaced = 0;
if (!range)
- return;
+ return replaced;
- this.$tryReplace(range, replacement);
- if (range !== null)
+ if (this.$tryReplace(range, replacement)) {
+ replaced = 1;
+ }
+ if (range !== null) {
this.selection.setSelectionRange(range);
+ this.renderer.scrollSelectionIntoView(range.start, range.end);
+ }
+
+ return replaced;
};
this.replaceAll = function(replacement, options) {
@@ -3525,19 +3545,25 @@ var Editor = function(renderer, session) {
}
var ranges = this.$search.findAll(this.session);
+ var replaced = 0;
if (!ranges.length)
- return;
+ return replaced;
var selection = this.getSelectionRange();
this.clearSelection();
this.selection.moveCursorTo(0, 0);
this.$blockScrolling += 1;
- for (var i = ranges.length - 1; i >= 0; --i)
- this.$tryReplace(ranges[i], replacement);
+ for (var i = ranges.length - 1; i >= 0; --i) {
+ if(this.$tryReplace(ranges[i], replacement)) {
+ replaced++;
+ }
+ }
this.selection.setSelectionRange(selection);
this.$blockScrolling -= 1;
+
+ return replaced;
};
this.$tryReplace = function(range, replacement) {
@@ -3589,8 +3615,23 @@ var Editor = function(renderer, session) {
var range = this.$search.find(this.session);
if (range) {
this.session.unfold(range);
- this.gotoLine(range.end.row+1, range.end.column);
+
+ this.$blockScrolling += 1;
this.selection.setSelectionRange(range);
+ this.$blockScrolling -= 1;
+
+ if (this.getAnimatedScroll()) {
+ var cursor = this.getCursorPosition();
+ if (!this.isRowFullyVisible(cursor.row))
+ this.scrollToLine(cursor.row, true);
+
+ //@todo scroll X
+ //if (!this.isColumnFullyVisible(cursor.column))
+ //this.scrollToRow(cursor.column);
+ }
+ else {
+ this.renderer.scrollSelectionIntoView(range.start, range.end);
+ }
}
};
@@ -4298,7 +4339,7 @@ function DefaultHandlers(editor) {
if (!editor.$mouseHandler.$clickSelection) {
if (!dragCursor) {
editor.moveCursorToPosition(pos);
- editor.selection.clearSelection(pos.row, pos.column);
+ editor.selection.clearSelection();
}
}
@@ -4333,7 +4374,6 @@ function DefaultHandlers(editor) {
if (distance > DRAG_OFFSET) {
state = STATE_SELECT;
var cursor = editor.renderer.screenToTextCoordinates(mousePageX, mousePageY);
- cursor.row = Math.max(0, Math.min(cursor.row, editor.session.getLength()-1));
onStartSelect(cursor);
}
else if ((time - mousedownTime) > editor.getDragDelay()) {
@@ -4360,7 +4400,7 @@ function DefaultHandlers(editor) {
else {
if (!_self.$clickSelection) {
editor.moveCursorToPosition(pos);
- editor.selection.clearSelection(pos.row, pos.column);
+ editor.selection.clearSelection();
}
}
state = STATE_SELECT;
@@ -4369,7 +4409,6 @@ function DefaultHandlers(editor) {
var onUpdateSelectionInterval = function() {
var anchor;
var cursor = editor.renderer.screenToTextCoordinates(mousePageX, mousePageY);
- cursor.row = Math.max(0, Math.min(cursor.row, editor.session.getLength()-1));
if (_self.$clickSelection) {
if (_self.$clickSelection.contains(cursor.row, cursor.column)) {
@@ -4395,8 +4434,6 @@ function DefaultHandlers(editor) {
var onDragSelectionInterval = function() {
dragCursor = editor.renderer.screenToTextCoordinates(mousePageX, mousePageY);
- dragCursor.row = Math.max(0, Math.min(dragCursor.row, editor.session.getLength() - 1));
-
editor.moveCursorToPosition(dragCursor);
};
@@ -4818,7 +4855,6 @@ var MouseEvent = exports.MouseEvent = function(domEvent, editor) {
var pageX = event.getDocumentX(this.domEvent);
var pageY = event.getDocumentY(this.domEvent);
this.$pos = this.editor.renderer.screenToTextCoordinates(pageX, pageY);
- this.$pos.row = Math.max(0, Math.min(this.$pos.row, this.editor.session.getLength()-1));
return this.$pos;
};
@@ -4918,7 +4954,7 @@ function FoldHandler(editor) {
var position = e.getDocumentPosition();
var session = editor.session;
- // If the user dclicked on a fold, then expand it.
+ // If the user clicked on a fold, then expand it.
var fold = session.getFoldAt(position.row, position.column, 1);
if (fold) {
if (e.getAccelKey())
@@ -5198,91 +5234,109 @@ exports.commands = [{
name: "selectup",
bindKey: bindKey("Shift-Up", "Shift-Up"),
exec: function(editor) { editor.getSelection().selectUp(); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "golineup",
bindKey: bindKey("Up", "Up|Ctrl-P"),
exec: function(editor, args) { editor.navigateUp(args.times); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "selecttoend",
bindKey: bindKey("Ctrl-Shift-End|Alt-Shift-Down", "Command-Shift-Down"),
exec: function(editor) { editor.getSelection().selectFileEnd(); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "gotoend",
bindKey: bindKey("Ctrl-End|Ctrl-Down", "Command-End|Command-Down"),
exec: function(editor) { editor.navigateFileEnd(); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "selectdown",
bindKey: bindKey("Shift-Down", "Shift-Down"),
exec: function(editor) { editor.getSelection().selectDown(); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "golinedown",
bindKey: bindKey("Down", "Down|Ctrl-N"),
exec: function(editor, args) { editor.navigateDown(args.times); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "selectwordleft",
bindKey: bindKey("Ctrl-Shift-Left", "Option-Shift-Left"),
exec: function(editor) { editor.getSelection().selectWordLeft(); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "gotowordleft",
bindKey: bindKey("Ctrl-Left", "Option-Left"),
exec: function(editor) { editor.navigateWordLeft(); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "selecttolinestart",
bindKey: bindKey("Alt-Shift-Left", "Command-Shift-Left"),
exec: function(editor) { editor.getSelection().selectLineStart(); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "gotolinestart",
bindKey: bindKey("Alt-Left|Home", "Command-Left|Home|Ctrl-A"),
exec: function(editor) { editor.navigateLineStart(); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "selectleft",
bindKey: bindKey("Shift-Left", "Shift-Left"),
exec: function(editor) { editor.getSelection().selectLeft(); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "gotoleft",
bindKey: bindKey("Left", "Left|Ctrl-B"),
exec: function(editor, args) { editor.navigateLeft(args.times); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "selectwordright",
bindKey: bindKey("Ctrl-Shift-Right", "Option-Shift-Right"),
exec: function(editor) { editor.getSelection().selectWordRight(); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "gotowordright",
bindKey: bindKey("Ctrl-Right", "Option-Right"),
exec: function(editor) { editor.navigateWordRight(); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "selecttolineend",
bindKey: bindKey("Alt-Shift-Right", "Command-Shift-Right"),
exec: function(editor) { editor.getSelection().selectLineEnd(); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "gotolineend",
bindKey: bindKey("Alt-Right|End", "Command-Right|End|Ctrl-E"),
exec: function(editor) { editor.navigateLineEnd(); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "selectright",
bindKey: bindKey("Shift-Right", "Shift-Right"),
exec: function(editor) { editor.getSelection().selectRight(); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "gotoright",
bindKey: bindKey("Right", "Right|Ctrl-F"),
exec: function(editor, args) { editor.navigateRight(args.times); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "selectpagedown",
@@ -5318,11 +5372,13 @@ exports.commands = [{
name: "selectlinestart",
bindKey: bindKey("Shift-Home", "Shift-Home"),
exec: function(editor) { editor.getSelection().selectLineStart(); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "selectlineend",
bindKey: bindKey("Shift-End", "Shift-End"),
exec: function(editor) { editor.getSelection().selectLineEnd(); },
+ multiSelectAction: "forEach",
readOnly: true
}, {
name: "togglerecording",
@@ -5334,17 +5390,37 @@ exports.commands = [{
bindKey: bindKey("Ctrl-Shift-E", "Command-Shift-E"),
exec: function(editor) { editor.commands.replay(editor); },
readOnly: true
+}, {
+ name: "jumptomatching",
+ bindKey: bindKey("Ctrl-Shift-P", "Ctrl-Shift-P"),
+ exec: function(editor) { editor.jumpToMatching(); },
+ multiSelectAction: "forEach",
+ readOnly: true
},
// commands disabled in readOnly mode
{
+ name: "cut",
+ exec: function(editor) {
+ var range = editor.getSelectionRange();
+ editor._emit("cut", range);
+
+ if (!editor.selection.isEmpty()) {
+ editor.session.remove(range);
+ editor.clearSelection();
+ }
+ },
+ multiSelectAction: "forEach"
+}, {
name: "removeline",
bindKey: bindKey("Ctrl-D", "Command-D"),
- exec: function(editor) { editor.removeLines(); }
+ exec: function(editor) { editor.removeLines(); },
+ multiSelectAction: "forEach"
}, {
name: "togglecomment",
bindKey: bindKey("Ctrl-7", "Command-7"),
- exec: function(editor) { editor.toggleCommentLines(); }
+ exec: function(editor) { editor.toggleCommentLines(); },
+ multiSelectAction: "forEach"
}, {
name: "replace",
bindKey: bindKey("Ctrl-R", "Command-Option-F"),
@@ -5396,66 +5472,76 @@ exports.commands = [{
}, {
name: "del",
bindKey: bindKey("Delete", "Delete|Ctrl-D"),
- exec: function(editor) { editor.remove("right"); }
+ exec: function(editor) { editor.remove("right"); },
+ multiSelectAction: "forEach"
}, {
name: "backspace",
bindKey: bindKey(
- "Ctrl-Backspace|Command-Backspace|Option-Backspace|Shift-Backspace|Backspace",
+ "Command-Backspace|Option-Backspace|Shift-Backspace|Backspace",
"Ctrl-Backspace|Command-Backspace|Shift-Backspace|Backspace|Ctrl-H"
),
- exec: function(editor) { editor.remove("left"); }
+ exec: function(editor) { editor.remove("left"); },
+ multiSelectAction: "forEach"
}, {
name: "removetolinestart",
- bindKey: bindKey("Alt-Backspace", "Option-Backspace"),
- exec: function(editor) { editor.removeToLineStart(); }
+ bindKey: bindKey("Alt-Backspace", "Command-Backspace"),
+ exec: function(editor) { editor.removeToLineStart(); },
+ multiSelectAction: "forEach"
}, {
name: "removetolineend",
bindKey: bindKey("Alt-Delete", "Ctrl-K"),
- exec: function(editor) { editor.removeToLineEnd(); }
+ exec: function(editor) { editor.removeToLineEnd(); },
+ multiSelectAction: "forEach"
}, {
name: "removewordleft",
bindKey: bindKey("Ctrl-Backspace", "Alt-Backspace|Ctrl-Alt-Backspace"),
- exec: function(editor) { editor.removeWordLeft(); }
+ exec: function(editor) { editor.removeWordLeft(); },
+ multiSelectAction: "forEach"
}, {
name: "removewordright",
bindKey: bindKey("Ctrl-Delete", "Alt-Delete"),
- exec: function(editor) { editor.removeWordRight(); }
+ exec: function(editor) { editor.removeWordRight(); },
+ multiSelectAction: "forEach"
}, {
name: "outdent",
bindKey: bindKey("Shift-Tab", "Shift-Tab"),
- exec: function(editor) { editor.blockOutdent(); }
+ exec: function(editor) { editor.blockOutdent(); },
+ multiSelectAction: "forEach"
}, {
name: "indent",
bindKey: bindKey("Tab", "Tab"),
- exec: function(editor) { editor.indent(); }
+ exec: function(editor) { editor.indent(); },
+ multiSelectAction: "forEach"
}, {
name: "insertstring",
- exec: function(editor, str) { editor.insert(str); }
+ exec: function(editor, str) { editor.insert(str); },
+ multiSelectAction: "forEach"
}, {
name: "inserttext",
exec: function(editor, args) {
editor.insert(lang.stringRepeat(args.text || "", args.times || 1));
- }
+ },
+ multiSelectAction: "forEach"
}, {
name: "splitline",
bindKey: bindKey(null, "Ctrl-O"),
- exec: function(editor) { editor.splitLine(); }
+ exec: function(editor) { editor.splitLine(); },
+ multiSelectAction: "forEach"
}, {
name: "transposeletters",
bindKey: bindKey("Ctrl-T", "Ctrl-T"),
- exec: function(editor) { editor.transposeLetters(); }
+ exec: function(editor) { editor.transposeLetters(); },
+ multiSelectAction: function(editor) {editor.transposeSelections(1); }
}, {
name: "touppercase",
bindKey: bindKey("Ctrl-U", "Ctrl-U"),
- exec: function(editor) { editor.toUpperCase(); }
+ exec: function(editor) { editor.toUpperCase(); },
+ multiSelectAction: "forEach"
}, {
name: "tolowercase",
bindKey: bindKey("Ctrl-Shift-U", "Ctrl-Shift-U"),
- exec: function(editor) { editor.toLowerCase(); }
-}, {
- name: "jumptomatching",
- bindKey: bindKey("Ctrl-Shift-P", "Ctrl-Shift-P"),
- exec: function(editor) { editor.jumpToMatching(); }
+ exec: function(editor) { editor.toLowerCase(); },
+ multiSelectAction: "forEach"
}];
});
@@ -5499,11 +5585,13 @@ exports.commands = [{
*
* ***** END LICENSE BLOCK ***** */
-define('ace/edit_session', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/lang', 'ace/lib/event_emitter', 'ace/selection', 'ace/mode/text', 'ace/range', 'ace/document', 'ace/background_tokenizer', 'ace/edit_session/folding', 'ace/edit_session/bracket_match'], function(require, exports, module) {
+define('ace/edit_session', ['require', 'exports', 'module' , 'ace/config', 'ace/lib/oop', 'ace/lib/lang', 'ace/lib/net', 'ace/lib/event_emitter', 'ace/selection', 'ace/mode/text', 'ace/range', 'ace/document', 'ace/background_tokenizer', 'ace/edit_session/folding', 'ace/edit_session/bracket_match'], function(require, exports, module) {
"use strict";
+var config = require("./config");
var oop = require("./lib/oop");
var lang = require("./lib/lang");
+var net = require("./lib/net");
var EventEmitter = require("./lib/event_emitter").EventEmitter;
var Selection = require("./selection").Selection;
var TextMode = require("./mode/text").Mode;
@@ -5945,10 +6033,65 @@ var EditSession = function(text, mode) {
this._emit("tokenizerUpdate", e);
};
+ this.$modes = {};
+ this._loadMode = function(mode, callback) {
+ if (this.$modes[mode])
+ return callback(this.$modes[mode]);
+
+ var _self = this;
+ var module;
+ try {
+ module = require(mode);
+ } catch (e) {};
+ if (module)
+ return done(module);
+
+ fetch(function() {
+ require([mode], done);
+ });
+
+ function done(module) {
+ if (_self.$modes[mode])
+ return callback(_self.$modes[mode]);
+
+ _self.$modes[mode] = new module.Mode();
+ _self._emit("loadmode", {
+ name: mode,
+ mode: _self.$modes[mode]
+ });
+ callback(_self.$modes[mode]);
+ }
+
+ function fetch(callback) {
+ if (!config.get("packaged"))
+ return callback();
+
+ var base = mode.split("/").pop();
+ var filename = config.get("modePath") + "/mode-" + base + config.get("suffix");
+ net.loadScript(filename, callback);
+ }
+ };
+
this.$mode = null;
+ this.$origMode = null;
this.setMode = function(mode) {
+ this.$origMode = mode;
+
+ // load on demand
+ if (typeof mode === "string") {
+ var _self = this;
+ this._loadMode(mode, function(module) {
+ if (_self.$origMode !== mode)
+ return;
+
+ _self.setMode(module);
+ });
+ return;
+ }
+
if (this.$mode === mode) return;
this.$mode = mode;
+
this.$stopWorker();
@@ -6847,8 +6990,8 @@ var EditSession = function(text, mode) {
}
this.getScreenLastRowColumn = function(screenRow) {
- //return this.screenToDocumentColumn(screenRow, Number.MAX_VALUE / 10)
- return this.documentToScreenColumn(screenRow, this.doc.getLine(screenRow).length);
+ var pos = this.screenToDocumentPosition(screenRow, Number.MAX_VALUE)
+ return this.documentToScreenColumn(pos.row, pos.column);
};
this.getDocumentLastRowColumn = function(docRow, docColumn) {
@@ -6963,16 +7106,10 @@ var EditSession = function(text, mode) {
docColumn += this.$getStringScreenWidth(line, screenColumn)[1];
- // Need to do some clamping action here.
- if (this.$useWrapMode) {
- if (docColumn >= column) {
- // We remove one character at the end such that the docColumn
- // position returned is not associated to the next row on the
- // screen.
- docColumn = column - 1;
- }
- } else {
- docColumn = Math.min(docColumn, line.length);
+ // We remove one character at the end so that the docColumn
+ // position returned is not associated to the next row on the screen.
+ if (this.$useWrapMode && docColumn >= column) {
+ docColumn = column - 1;
}
if (foldLine) {
@@ -7174,7 +7311,195 @@ require("./edit_session/bracket_match").BracketMatch.call(EditSession.prototype)
exports.EditSession = EditSession;
});
-/* ***** BEGIN LICENSE BLOCK *****
+/* vim:ts=4:sts=4:sw=4:
+ * ***** 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 <fabian AT ajax DOT org>
+ *
+ * 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('ace/config', ['require', 'exports', 'module' , 'ace/lib/lang'], function(require, exports, module) {
+"no use strict";
+
+var lang = require("./lib/lang");
+
+var global = (function() {
+ return this;
+})();
+
+var options = {
+ packaged: false,
+ workerPath: "",
+ modePath: "",
+ themePath: "",
+ suffix: ".js"
+};
+
+exports.get = function(key) {
+ if (!options.hasOwnProperty(key))
+ throw new Error("Unknown confik key: " + key);
+
+ return options[key];
+};
+
+exports.set = function(key, value) {
+ if (!options.hasOwnProperty(key))
+ throw new Error("Unknown confik key: " + key);
+
+ options[key] = value;
+};
+
+exports.all = function() {
+ return lang.copyObject(options);
+};
+
+exports.init = function() {
+ options.packaged = require.packaged || module.packaged || (global.define && define.packaged);
+
+ if (!global.document)
+ return "";
+
+ var scriptOptions = {};
+ var scriptUrl = "";
+ var suffix;
+
+ var scripts = document.getElementsByTagName("script");
+ for (var i=0; i<scripts.length; i++) {
+ var script = scripts[i];
+
+ var src = script.src || script.getAttribute("src");
+ if (!src) {
+ continue;
+ }
+
+ var attributes = script.attributes;
+ for (var j=0, l=attributes.length; j < l; j++) {
+ var attr = attributes[j];
+ if (attr.name.indexOf("data-ace-") === 0) {
+ scriptOptions[deHyphenate(attr.name.replace(/^data-ace-/, ""))] = attr.value;
+ }
+ }
+
+ var m = src.match(/^(?:(.*\/)ace\.js|(.*\/)ace((-uncompressed)?(-noconflict)?\.js))(?:\?|$)/);
+ if (m) {
+ scriptUrl = m[1] || m[2];
+ suffix = m[3];
+ }
+ }
+
+ if (scriptUrl) {
+ scriptOptions.base = scriptOptions.base || scriptUrl;
+ scriptOptions.packaged = true;
+ }
+
+ scriptOptions.suffix = scriptOptions.suffix || suffix;
+ scriptOptions.workerPath = scriptOptions.workerPath || scriptOptions.base;
+ scriptOptions.modePath = scriptOptions.modePath || scriptOptions.base;
+ scriptOptions.themePath = scriptOptions.themePath || scriptOptions.base;
+ delete scriptOptions.base;
+
+ for (var key in scriptOptions)
+ if (typeof scriptOptions[key] !== "undefined")
+ exports.set(key, scriptOptions[key]);
+};
+
+function deHyphenate(str) {
+ return str.replace(/-(.)/g, function(m, m1) { return m1.toUpperCase(); });
+}
+
+});/**
+ * based on code from:
+ *
+ * @license RequireJS text 0.25.0 Copyright (c) 2010-2011, The Dojo Foundation All Rights Reserved.
+ * Available via the MIT or new BSD license.
+ * see: http://github.com/jrburke/requirejs for details
+ */
+define('ace/lib/net', ['require', 'exports', 'module' ], function(require, exports, module) {
+"use strict";
+
+exports.get = function (url, callback) {
+ var xhr = exports.createXhr();
+ 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);
+};
+
+var progIds = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP.4.0'];
+
+exports.createXhr = 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("createXhr(): XMLHttpRequest not available");
+ }
+
+ return xhr;
+};
+
+exports.loadScript = function(path, callback) {
+ var head = document.getElementsByTagName('head')[0];
+ var s = document.createElement('script');
+
+ s.src = path;
+ head.appendChild(s);
+
+ s.onload = callback;
+};
+
+});/* ***** 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
@@ -7235,18 +7560,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");
});
};
@@ -7356,12 +7681,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) {
@@ -7568,14 +7888,14 @@ var Selection = function(session) {
this.moveCursorTo(fold.end.row, fold.end.column);
return;
}
-
+
// first skip space
if (match = this.session.nonTokenRe.exec(rightOfCursor)) {
column += this.session.nonTokenRe.lastIndex;
this.session.nonTokenRe.lastIndex = 0;
rightOfCursor = line.substring(column);
}
-
+
// if at line end proceed with next line
if (column >= line.length) {
this.moveCursorTo(row, line.length);
@@ -7584,7 +7904,7 @@ var Selection = function(session) {
this.moveCursorWordRight();
return;
}
-
+
// advance to the end of the next token
if (match = this.session.tokenRe.exec(rightOfCursor)) {
column += this.session.tokenRe.lastIndex;
@@ -7609,19 +7929,19 @@ var Selection = function(session) {
if (str == null) {
str = this.doc.getLine(row).substring(0, column)
}
-
+
var leftOfCursor = lang.stringReverse(str);
var match;
this.session.nonTokenRe.lastIndex = 0;
this.session.tokenRe.lastIndex = 0;
-
+
// skip whitespace
if (match = this.session.nonTokenRe.exec(leftOfCursor)) {
column -= this.session.nonTokenRe.lastIndex;
leftOfCursor = leftOfCursor.slice(this.session.nonTokenRe.lastIndex);
this.session.nonTokenRe.lastIndex = 0;
}
-
+
// if at begin of the line proceed in line above
if (column <= 0) {
this.moveCursorTo(row, 0);
@@ -7646,8 +7966,14 @@ var Selection = function(session) {
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);
@@ -7657,7 +7983,7 @@ var Selection = function(session) {
this.moveCursorTo(position.row, position.column);
};
- 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) {
@@ -7665,21 +7991,47 @@ 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;
};
- 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;
@@ -7737,7 +8089,7 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
};
(function() {
- 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 &&
@@ -7803,6 +8155,11 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return this.comparePoint(range.start) == 0 && this.comparePoint(range.end) == 0;
}
+ this.intersectsRange = function(range) {
+ var cmp = this.compareRange(range);
+ return (cmp == -1 || cmp == 0 || cmp == 1);
+ }
+
this.isEnd = function(row, column) {
return this.end.row == row && this.end.column == column;
}
@@ -7962,6 +8319,21 @@ var Range = function(startRow, startColumn, endRow, endColumn) {
return Range.fromPoints(start || this.start, end || this.end);
};
+ this.fixOrientation = function() {
+ if (
+ this.start.row < this.end.row
+ || (this.start.row == this.end.row && this.start.column < this.end.column)
+ ) {
+ return false;
+ }
+
+ var temp = this.start;
+ this.end = this.start;
+ this.start = temp;
+ return true;
+ };
+
+
this.isEmpty = function() {
return (this.start.row == this.end.row && this.start.column == this.end.column);
};
@@ -8275,23 +8647,30 @@ var Tokenizer = function(rules, flag) {
var ruleRegExps = [];
var matchTotal = 0;
var mapping = this.matchMappings[key] = {};
-
+
for ( var i = 0; i < state.length; i++) {
+
+ if (state[i].regex instanceof RegExp)
+ state[i].regex = state[i].regex.toString().slice(1, -1);
+
// Count number of matching groups. 2 extra groups from the full match
// And the catch-all on the end (used to force a match);
var matchcount = new RegExp("(?:(" + state[i].regex + ")|(.))").exec("a").length - 2;
-
+
// Replace any backreferences and offset appropriately.
var adjustedregex = state[i].regex.replace(/\\([0-9]+)/g, function (match, digit) {
return "\\" + (parseInt(digit, 10) + matchTotal + 1);
});
-
+
+ if (matchcount > 1 && state[i].token.length !== matchcount-1)
+ throw new Error("Matching groups and length of the token array don't match in rule #" + i + " of state " + key);
+
mapping[matchTotal] = {
rule: i,
len: matchcount
};
matchTotal += matchcount;
-
+
ruleRegExps.push(adjustedregex);
}
@@ -8307,47 +8686,47 @@ var Tokenizer = function(rules, flag) {
var mapping = this.matchMappings[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 rule = null;
var value = [match[0]];
for (var i = 0; i < match.length-2; i++) {
- if (match[i + 1] !== undefined) {
- rule = state[mapping[i].rule];
-
- if (mapping[i].len > 1) {
- value = match.slice(i+2, i+1+mapping[i].len);
- }
-
- // compute token type
- if (typeof rule.token == "function")
- type = rule.token.apply(this, value);
- else
- type = rule.token;
+ if (match[i + 1] === undefined)
+ continue;
- var next = rule.next;
- if (next && next !== currentState) {
- currentState = next;
- state = this.rules[currentState];
- mapping = this.matchMappings[currentState];
- lastIndex = re.lastIndex;
+ rule = state[mapping[i].rule];
- re = this.regExps[currentState];
- re.lastIndex = lastIndex;
- }
- break;
+ if (mapping[i].len > 1)
+ value = match.slice(i+2, i+1+mapping[i].len);
+
+ // compute token type
+ if (typeof rule.token == "function")
+ type = rule.token.apply(this, value);
+ else
+ type = rule.token;
+
+ var next = rule.next;
+ if (next && next !== currentState) {
+ currentState = next;
+ state = this.rules[currentState];
+ mapping = this.matchMappings[currentState];
+ lastIndex = re.lastIndex;
+
+ re = this.regExps[currentState];
+ re.lastIndex = lastIndex;
}
+ break;
}
if (value[0]) {
@@ -8356,13 +8735,15 @@ var Tokenizer = function(rules, flag) {
type = [type];
}
for (var i = 0; i < value.length; i++) {
+ if (!value[i])
+ continue;
+
if ((!rule || rule.merge || type[i] === "text") && token.type === type[i]) {
token.value += value[i];
} else {
- if (token.type) {
+ if (token.type)
tokens.push(token);
- }
-
+
token = {
type: type[i],
value: value[i]
@@ -8370,10 +8751,10 @@ var Tokenizer = function(rules, flag) {
}
}
}
-
+
if (lastIndex == line.length)
break;
-
+
lastIndex = re.lastIndex;
}
@@ -8879,11 +9260,12 @@ var Document = function(text) {
};
this.insert = function(position, text) {
- if (text.length == 0)
+ if (!text || text.length === 0)
return position;
position = this.$clipPosition(position);
+ // only detect new lines if the document has no line break yet
if (this.getLength() <= 1)
this.$detectNewLine(text);
@@ -10106,7 +10488,7 @@ function Folding() {
this.foldAll = function(startRow, endRow) {
var foldWidgets = this.foldWidgets;
- endRow = endRow || foldWidgets.length;
+ endRow = endRow || this.getLength();
for (var row = startRow || 0; row < endRow; row++) {
if (foldWidgets[row] == null)
foldWidgets[row] = this.getFoldWidget(row);
@@ -10195,7 +10577,7 @@ function Folding() {
// sometimes singleline folds can be missed by the code above
if (!range.isMultiLine()) {
fold = this.getFoldAt(range.start.row, range.start.column, 1);
- if (fold && range.isEequal(fold.range)) {
+ if (fold && range.isEqual(fold.range)) {
this.removeFold(fold);
return;
}
@@ -10586,7 +10968,7 @@ var Fold = exports.Fold = function(range, placeholder) {
};
this.addSubFold = function(fold) {
- if (this.range.isEequal(fold))
+ if (this.range.isEqual(fold))
return this;
if (!this.range.containsRange(fold))
@@ -11264,21 +11646,153 @@ Search.SELECTION = 2;
exports.Search = Search;
});
-define('ace/commands/command_manager', ['require', 'exports', 'module' , 'ace/lib/keys'], function(require, exports, module) {
+define('ace/commands/command_manager', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/keyboard/hash_handler', 'ace/lib/event_emitter'], function(require, exports, module) {
"use strict";
-var keyUtil = require("../lib/keys");
+var oop = require("../lib/oop");
+var HashHandler = require("../keyboard/hash_handler").HashHandler;
+var EventEmitter = require("../lib/event_emitter").EventEmitter;
var CommandManager = function(platform, commands) {
- if (typeof platform !== "string")
- throw new TypeError("'platform' argument must be either 'mac' or 'win'");
+ this.platform = platform;
+ this.commands = {};
+ this.commmandKeyBinding = {};
+
+ this.addCommands(commands);
+
+ this.setDefaultHandler("exec", function(e) {
+ e.command.exec(e.editor, e.args || {});
+ });
+};
+
+oop.inherits(CommandManager, HashHandler);
+
+(function() {
+
+ oop.implement(this, EventEmitter);
+
+ this.exec = function(command, editor, args) {
+ if (typeof command === 'string')
+ command = this.commands[command];
+
+ if (!command)
+ return false;
+
+ if (editor && editor.$readOnly && !command.readOnly)
+ return false;
+
+ this._emit("exec", {editor: editor, command: command, args: args});
+ return true;
+ };
+ this.toggleRecording = function() {
+ if (this.$inReplay)
+ return;
+ if (this.recording) {
+ this.macro.pop();
+ this.removeEventListener("exec", this.$addCommandToMacro);
+
+ if (!this.macro.length)
+ this.macro = this.oldMacro;
+
+ return this.recording = false;
+ }
+ if (!this.$addCommandToMacro) {
+ this.$addCommandToMacro = function(e) {
+ this.macro.push([e.command, e.args]);
+ }.bind(this);
+ }
+
+ this.oldMacro = this.macro;
+ this.macro = [];
+ this.on("exec", this.$addCommandToMacro);
+ return this.recording = true;
+ };
+
+ this.replay = function(editor) {
+ if (this.$inReplay || !this.macro)
+ return;
+
+ if (this.recording)
+ return this.toggleRecording();
+
+ try {
+ this.$inReplay = true;
+ this.macro.forEach(function(x) {
+ if (typeof x == "string")
+ this.exec(x, editor);
+ else
+ this.exec(x[0], editor, x[1]);
+ }, this);
+ } finally {
+ this.$inReplay = false;
+ }
+ };
+
+ this.trimMacro = function(m) {
+ return m.map(function(x){
+ if (typeof x[0] != "string")
+ x[0] = x[0].name;
+ if (!x[1])
+ x = x[0];
+ return x;
+ });
+ };
+
+}).call(CommandManager.prototype);
+
+exports.CommandManager = CommandManager;
+
+});
+/* ***** 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 Mozilla Skywriter.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Fabian Jakobs <fabian AT ajax DOT org>
+ * Julian Viereck (julian.viereck@gmail.com)
+ *
+ * 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('ace/keyboard/hash_handler', ['require', 'exports', 'module' , 'ace/lib/keys'], function(require, exports, module) {
+"use strict";
+
+var keyUtil = require("../lib/keys");
+
+function HashHandler(config, platform) {
this.platform = platform;
this.commands = {};
this.commmandKeyBinding = {};
- if (commands)
- commands.forEach(this.addCommand, this);
+ this.addCommands(config);
};
(function() {
@@ -11299,7 +11813,7 @@ var CommandManager = function(platform, commands) {
command = this.commands[name];
delete this.commands[name];
- // exaustive search is brute force but since removeCommand is
+ // exhaustive search is brute force but since removeCommand is
// not a performance critical operation this should be OK
var ckb = this.commmandKeyBinding;
for (var hashId in ckb) {
@@ -11311,7 +11825,7 @@ var CommandManager = function(platform, commands) {
};
this.addCommands = function(commands) {
- Object.keys(commands).forEach(function(name) {
+ commands && Object.keys(commands).forEach(function(name) {
var command = commands[name];
if (typeof command === "string")
return this.bindKey(command, name);
@@ -11357,14 +11871,14 @@ var CommandManager = function(platform, commands) {
var key = typeof binding == "string" ? binding: binding[this.platform];
this.bindKey(key, command);
- }
+ };
function parseKeys(keys, val, ret) {
var key;
var hashId = 0;
- var parts = splitSafe(keys);
+ var parts = splitSafe(keys.toLowerCase());
- for (var i=0, l = parts.length; i < l; i++) {
+ for (var i = 0, l = parts.length; i < l; i++) {
if (keyUtil.KEY_MODS[parts[i]])
hashId = hashId | keyUtil.KEY_MODS[parts[i]];
else
@@ -11374,95 +11888,28 @@ var CommandManager = function(platform, commands) {
return {
key: key,
hashId: hashId
- }
+ };
}
- function splitSafe(s, separator) {
- return (s.toLowerCase()
- .trim()
+ function splitSafe(s) {
+ return (s.trim()
.split(new RegExp("[\\s ]*\\-[\\s ]*", "g"), 999));
}
- this.findKeyCommand = function findKeyCommand(hashId, textOrKey) {
- // Convert keyCode to the string representation.
- if (typeof textOrKey == "number") {
- textOrKey = keyUtil.keyCodeToString(textOrKey);
- }
-
+ this.findKeyCommand = function findKeyCommand(hashId, keyString) {
var ckbr = this.commmandKeyBinding;
- return ckbr[hashId] && ckbr[hashId][textOrKey.toLowerCase()];
+ return ckbr[hashId] && ckbr[hashId][keyString.toLowerCase()];
}
- this.exec = function(command, editor, args) {
- if (typeof command === 'string')
- command = this.commands[command];
-
- if (!command)
- return false;
-
- if (editor && editor.$readOnly && !command.readOnly)
- return false;
-
- command.exec(editor, args || {});
- return true;
- };
-
- this.toggleRecording = function() {
- if (this.$inReplay)
- return;
- if (this.recording) {
- this.macro.pop();
- this.exec = this.normal_exec;
-
- if (!this.macro.length)
- this.macro = this.oldMacro;
-
- return this.recording = false;
- }
- this.oldMacro = this.macro;
- this.macro = [];
- this.normal_exec = this.exec;
- this.exec = function(command, editor, args) {
- this.macro.push([command, args]);
- return this.normal_exec(command, editor, args);
+ this.handleKeyboard = function(data, hashId, keyString, keyCode) {
+ return {
+ command: this.findKeyCommand(hashId, keyString)
};
- return this.recording = true;
};
- this.replay = function(editor) {
- if (this.$inReplay || !this.macro)
- return;
-
- if (this.recording)
- return this.toggleRecording();
-
- try {
- this.$inReplay = true;
- this.macro.forEach(function(x) {
- if (typeof x == "string")
- this.exec(x, editor);
- else
- this.exec(x[0], editor, x[1]);
- }, this)
- } finally {
- this.$inReplay = false;
- }
- };
-
- this.trimMacro = function(m) {
- return m.map(function(x){
- if (typeof x[0] != "string")
- x[0] = x[0].name;
- if (!x[1])
- x = x[0];
- return x
- })
- }
-
-}).call(CommandManager.prototype);
-
-exports.CommandManager = CommandManager;
+}).call(HashHandler.prototype)
+exports.HashHandler = HashHandler;
});
/* vim:ts=4:sts=4:sw=4:
* ***** BEGIN LICENSE BLOCK *****
@@ -11598,13 +12045,15 @@ exports.UndoManager = UndoManager;
*
* ***** END LICENSE BLOCK ***** */
-define('ace/virtual_renderer', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/dom', 'ace/lib/event', 'ace/lib/useragent', 'ace/layer/gutter', 'ace/layer/marker', 'ace/layer/text', 'ace/layer/cursor', 'ace/scrollbar', 'ace/renderloop', 'ace/lib/event_emitter', 'text!ace/css/editor.css'], function(require, exports, module) {
+define('ace/virtual_renderer', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/dom', 'ace/lib/event', 'ace/lib/useragent', 'ace/config', 'ace/lib/net', 'ace/layer/gutter', 'ace/layer/marker', 'ace/layer/text', 'ace/layer/cursor', 'ace/scrollbar', 'ace/renderloop', 'ace/lib/event_emitter', 'text!ace/css/editor.css'], function(require, exports, module) {
"use strict";
var oop = require("./lib/oop");
var dom = require("./lib/dom");
var event = require("./lib/event");
var useragent = require("./lib/useragent");
+var config = require("./config");
+var net = require("./lib/net");
var GutterLayer = require("./layer/gutter").Gutter;
var MarkerLayer = require("./layer/marker").Marker;
var TextLayer = require("./layer/text").Text;
@@ -11618,13 +12067,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);
@@ -11642,8 +12091,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);
@@ -11661,6 +12110,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);
@@ -11668,9 +12119,18 @@ var VirtualRenderer = function(container, theme) {
this.scrollTop = 0;
this.scrollLeft = 0;
-
+
event.addListener(this.scroller, "scroll", function() {
- _self.session.setScrollLeft(_self.scroller.scrollLeft);
+ 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 = {
@@ -11678,7 +12138,7 @@ var VirtualRenderer = function(container, theme) {
column : 0
};
- this.$textLayer.addEventListener("changeCharaterSize", function() {
+ this.$textLayer.addEventListener("changeCharacterSize", function() {
_self.characterWidth = textLayer.getCharacterWidth();
_self.lineHeight = textLayer.getLineHeight();
_self.$updatePrintMargin();
@@ -11731,6 +12191,7 @@ var VirtualRenderer = function(container, theme) {
this.CHANGE_MARKER_BACK = 128;
this.CHANGE_MARKER_FRONT = 256;
this.CHANGE_FULL = 512;
+ this.CHANGE_H_SCROLL = 1024;
oop.implement(this, EventEmitter);
@@ -11829,6 +12290,14 @@ var VirtualRenderer = function(container, theme) {
return this.session.adjustWrapLimit(limit);
};
+ this.setAnimatedScroll = function(shouldAnimate){
+ this.$animatedScroll = shouldAnimate;
+ };
+
+ this.getAnimatedScroll = function() {
+ return this.$animatedScroll;
+ };
+
this.setShowInvisibles = function(showInvisibles) {
if (this.$textLayer.setShowInvisibles(showInvisibles))
this.$loop.schedule(this.CHANGE_TEXT);
@@ -11907,7 +12376,7 @@ var VirtualRenderer = function(container, theme) {
// this persists in IE9
if (useragent.isIE)
return;
-
+
if (this.layerConfig.lastRow === 0)
return;
@@ -11968,7 +12437,7 @@ var VirtualRenderer = function(container, theme) {
};
this.$renderChanges = function(changes) {
- if (!changes || !this.session)
+ if (!changes || !this.session || !this.container.offsetWidth)
return;
// text, scrolling and resize changes can cause the view port size to change
@@ -11980,20 +12449,33 @@ var VirtualRenderer = function(container, theme) {
)
this.$computeLayerConfig();
+ // 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();
+ // update scrollbar first to not lose scroll position when gutter calls resize
+ this.$updateScrollBar();
this.$textLayer.update(this.layerConfig);
if (this.showGutter)
this.$gutterLayer.update(this.layerConfig);
this.$markerBack.update(this.layerConfig);
this.$markerFront.update(this.layerConfig);
this.$cursorLayer.update(this.layerConfig);
- this.$updateScrollBar();
return;
}
// scrolling
if (changes & this.CHANGE_SCROLL) {
+ this.$updateScrollBar();
if (changes & this.CHANGE_TEXT || changes & this.CHANGE_LINES)
this.$textLayer.update(this.layerConfig);
else
@@ -12004,7 +12486,6 @@ var VirtualRenderer = function(container, theme) {
this.$markerBack.update(this.layerConfig);
this.$markerFront.update(this.layerConfig);
this.$cursorLayer.update(this.layerConfig);
- this.$updateScrollBar();
return;
}
@@ -12014,10 +12495,11 @@ var VirtualRenderer = function(container, theme) {
this.$gutterLayer.update(this.layerConfig);
}
else if (changes & this.CHANGE_LINES) {
- this.$updateLines();
- this.$updateScrollBar();
- if (this.showGutter)
- this.$gutterLayer.update(this.layerConfig);
+ if (this.$updateLines()) {
+ this.$updateScrollBar();
+ if (this.showGutter)
+ this.$gutterLayer.update(this.layerConfig);
+ }
} else if (changes & this.CHANGE_GUTTER) {
if (this.showGutter)
this.$gutterLayer.update(this.layerConfig);
@@ -12049,9 +12531,13 @@ var VirtualRenderer = function(container, theme) {
var horizScroll = this.$horizScrollAlwaysVisible || this.$size.scrollerWidth - longestLine < 0;
var horizScrollChanged = this.$horizScroll !== horizScroll;
this.$horizScroll = horizScroll;
- if (horizScrollChanged)
+ if (horizScrollChanged) {
this.scroller.style.overflowX = horizScroll ? "scroll" : "hidden";
-
+ // when we hide scrollbar scroll event isn't emited
+ // leaving session with wrong scrollLeft value
+ if (!horizScroll)
+ this.session.setScrollLeft(0);
+ }
var maxHeight = this.session.getScreenLength() * this.lineHeight;
this.session.setScrollTop(Math.max(0, Math.min(this.scrollTop, maxHeight - this.$size.scrollerHeight)));
@@ -12102,12 +12588,6 @@ var VirtualRenderer = function(container, theme) {
this.content.style.width = longestLine + 2 * this.$padding + "px";
this.content.style.height = minHeight + "px";
- // scroller.scrollWidth was smaller than scrollLeft we needed
- if (this.$desiredScrollLeft) {
- this.scrollToX(this.$desiredScrollLeft);
- this.$desiredScrollLeft = 0;
- }
-
// Horizontal scrollbar visibility may have changed, which changes
// the client height of the scroller
if (horizScrollChanged)
@@ -12138,6 +12618,7 @@ var VirtualRenderer = function(container, theme) {
// else update only the changed rows
this.$textLayer.updateLines(layerConfig, firstRow, lastRow);
+ return true;
};
this.$getLongestLine = function() {
@@ -12190,12 +12671,18 @@ var VirtualRenderer = function(container, theme) {
this.$cursorLayer.showCursor();
};
- this.scrollCursorIntoView = function() {
+ this.scrollSelectionIntoView = function(anchor, lead) {
+ // first scroll anchor into view then scroll lead into view
+ this.scrollCursorIntoView(anchor);
+ this.scrollCursorIntoView(lead);
+ };
+
+ this.scrollCursorIntoView = function(cursor) {
// the editor is not visible
if (this.$size.scrollerHeight === 0)
return;
- var pos = this.$cursorLayer.getPixelPosition();
+ var pos = this.$cursorLayer.getPixelPosition(cursor);
var left = pos.left;
var top = pos.top;
@@ -12213,14 +12700,11 @@ var VirtualRenderer = function(container, theme) {
if (scrollLeft > left) {
if (left < this.$padding + 2 * this.layerConfig.characterWidth)
left = 0;
- this.scrollToX(left);
+ this.session.setScrollLeft(left);
}
if (scrollLeft + this.$size.scrollerWidth < left + this.characterWidth) {
- if (left > this.layerConfig.width + 2 * this.$padding)
- this.$desiredScrollLeft = left;
- else
- this.scrollToX(Math.round(left + this.characterWidth - this.$size.scrollerWidth));
+ this.session.setScrollLeft(Math.round(left + this.characterWidth - this.$size.scrollerWidth));
}
};
@@ -12229,7 +12713,7 @@ var VirtualRenderer = function(container, theme) {
};
this.getScrollLeft = function() {
- return this.session.getScrollTop();
+ return this.session.getScrollLeft();
};
this.getScrollTopRow = function() {
@@ -12244,17 +12728,46 @@ var VirtualRenderer = function(container, theme) {
this.session.setScrollTop(row * this.lineHeight);
};
- this.scrollToLine = function(line, center) {
- var lineHeight = { lineHeight: this.lineHeight };
- var offset = 0;
- for (var l = 1; l < line; l++) {
- offset += this.session.getRowHeight(lineHeight, l-1);
- }
+ this.STEPS = 10;
+ this.$calcSteps = function(fromValue, toValue){
+ var i = 0;
+ var l = this.STEPS;
+ var steps = [];
- if (center) {
+ var func = function(t, x_min, dx) {
+ if ((t /= .5) < 1)
+ return dx / 2 * Math.pow(t, 3) + x_min;
+ return dx / 2 * (Math.pow(t - 2, 3) + 2) + x_min;
+ };
+
+ for (i = 0; i < l; ++i)
+ steps.push(func(i / this.STEPS, fromValue, toValue - fromValue));
+ steps.push(toValue);
+
+ return steps;
+ };
+
+ 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);
}
- this.session.setScrollTop(offset);
};
this.scrollToY = function(scrollTop) {
@@ -12270,8 +12783,9 @@ var VirtualRenderer = function(container, theme) {
if (scrollLeft <= this.$padding)
scrollLeft = 0;
- this.scroller.scrollLeft = scrollLeft;
- scrollLeft = this.scroller.scrollLeft;
+ if (this.scrollLeft !== scrollLeft)
+ this.scrollLeft = scrollLeft;
+ this.$loop.schedule(this.CHANGE_H_SCROLL);
};
this.scrollBy = function(deltaX, deltaY) {
@@ -12287,16 +12801,27 @@ var VirtualRenderer = function(container, theme) {
// todo: handle horizontal scrolling
};
+ this.pixelToScreenCoordinates = function(pageX, pageY) {
+ var canvasPos = this.scroller.getBoundingClientRect();
+
+ var col = Math.round(
+ (pageX + this.scrollLeft - canvasPos.left - this.$padding - dom.getPageScrollLeft()) / this.characterWidth
+ );
+ var row = Math.floor(
+ (pageY + this.scrollTop - canvasPos.top - dom.getPageScrollTop()) / this.lineHeight
+ );
+
+ return {row: row, column: col};
+ };
+
this.screenToTextCoordinates = function(pageX, pageY) {
var canvasPos = this.scroller.getBoundingClientRect();
var col = Math.round(
- (pageX + this.scrollLeft - canvasPos.left - this.$padding - dom.getPageScrollLeft())
- / this.characterWidth
+ (pageX + this.scrollLeft - canvasPos.left - this.$padding - dom.getPageScrollLeft()) / this.characterWidth
);
var row = Math.floor(
- (pageY + this.scrollTop - canvasPos.top - dom.getPageScrollTop())
- / this.lineHeight
+ (pageY + this.scrollTop - canvasPos.top - dom.getPageScrollTop()) / this.lineHeight
);
return this.session.screenToDocumentPosition(row, Math.max(col, 0));
@@ -12356,14 +12881,36 @@ var VirtualRenderer = function(container, theme) {
style.left = "-10000px";
};
+ this._loadTheme = function(name, callback) {
+ if (!config.get("packaged"))
+ return callback();
+
+ var base = name.split("/").pop();
+ var filename = config.get("themePath") + "/theme-" + base + config.get("suffix");
+ net.loadScript(filename, callback);
+ };
+
this.setTheme = function(theme) {
var _self = this;
this.$themeValue = theme;
if (!theme || typeof theme == "string") {
- theme = theme || "ace/theme/textmate";
- require([theme], function(theme) {
- afterLoad(theme);
+ var moduleName = theme || "ace/theme/textmate";
+
+ var module;
+ try {
+ module = require(moduleName);
+ } catch (e) {};
+ if (module)
+ return afterLoad(module);
+
+ _self._loadTheme(moduleName, function() {
+ require([moduleName], function(module) {
+ if (_self.$themeValue !== theme)
+ return;
+
+ afterLoad(module);
+ });
});
} else {
afterLoad(theme);
@@ -12492,11 +13039,11 @@ var Gutter = function(parentEl) {
this.addGutterDecoration = function(row, className){
if (!this.$decorations[row])
this.$decorations[row] = "";
- this.$decorations[row] += " ace_" + className;
+ this.$decorations[row] += " " + className;
};
this.removeGutterDecoration = function(row, className){
- this.$decorations[row] = this.$decorations[row].replace(" ace_" + className, "");
+ this.$decorations[row] = this.$decorations[row].replace(" " + className, "");
};
this.setBreakpoints = function(rows) {
@@ -12723,7 +13270,7 @@ var Marker = function(parentEl) {
};
/**
- * Draws a marker, which spans a range of text in a single line
+ * Draws a marker, which spans a range of text on multiple lines
*/
this.drawTextMarker = function(stringBuilder, range, clazz, layerConfig) {
// selection start
@@ -12798,7 +13345,7 @@ var Marker = function(parentEl) {
};
/**
- * Draws a marker which covers one single full line
+ * Draws a marker which covers part or whole width of a single screen line
*/
this.drawSingleLineMarker = function(stringBuilder, range, clazz, layerConfig, extraLength, type) {
var padding = type === "background" ? 0 : this.$padding;
@@ -12914,7 +13461,7 @@ var Text = function(parentEl) {
var size = this.$measureSizes();
if (size && (this.$characterSize.width !== size.width || this.$characterSize.height !== size.height)) {
this.$characterSize = size;
- this._emit("changeCharaterSize", {data: size});
+ this._emit("changeCharacterSize", {data: size});
}
};
@@ -12933,7 +13480,7 @@ var Text = function(parentEl) {
lineHeight : 1
};
- this.$measureSizes = function() {
+ this.$measureSizes = useragent.isIE || useragent.isOldGecko ? function() {
var n = 1000;
if (!this.$measureNode) {
var measureNode = this.$measureNode = dom.createElement("div");
@@ -12943,7 +13490,7 @@ var Text = function(parentEl) {
style.left = style.top = (-n * 40) + "px";
style.visibility = "hidden";
- style.position = "absolute";
+ style.position = "fixed";
style.overflow = "visible";
style.whiteSpace = "nowrap";
@@ -12960,8 +13507,12 @@ var Text = function(parentEl) {
container = container.parentNode;
container.appendChild(measureNode);
}
-
}
+
+ // Size and width can be null if the editor is not visible or
+ // detached from the document
+ if (!this.element.offsetWidth)
+ return null;
var style = this.$measureNode.style;
var computedStyle = dom.computedStyle(this.element);
@@ -12975,7 +13526,46 @@ var Text = function(parentEl) {
// Size and width can be null if the editor is not visible or
// detached from the document
- if (size.width == 0 && size.height == 0)
+ if (size.width == 0 || size.height == 0)
+ return null;
+
+ return size;
+ }
+ : function() {
+ if (!this.$measureNode) {
+ var measureNode = this.$measureNode = dom.createElement("div");
+ var style = measureNode.style;
+
+ style.width = style.height = "auto";
+ style.left = style.top = -100 + "px";
+
+ style.visibility = "hidden";
+ style.position = "fixed";
+ style.overflow = "visible";
+ style.whiteSpace = "nowrap";
+
+ measureNode.innerHTML = "X";
+
+ var container = this.element.parentNode;
+ while (container && !dom.hasCssClass(container, "ace_editor"))
+ container = container.parentNode;
+
+ if (!container)
+ return this.$measureNode = null;
+
+ container.appendChild(measureNode);
+ }
+
+ var rect = this.$measureNode.getBoundingClientRect();
+
+ var size = {
+ height: rect.height,
+ width: rect.width
+ };
+
+ // Size and width can be null if the editor is not visible or
+ // detached from the document
+ if (size.width == 0 || size.height == 0)
return null;
return size;
@@ -13089,16 +13679,16 @@ var Text = function(parentEl) {
};
this.$renderLinesFragment = function(config, firstRow, lastRow) {
- var fragment = this.element.ownerDocument.createDocumentFragment(),
- row = firstRow,
- fold = this.session.getNextFoldLine(row),
- foldStart = fold ?fold.start.row :Infinity;
+ var fragment = this.element.ownerDocument.createDocumentFragment();
+ var row = firstRow;
+ var foldLine = this.session.getNextFoldLine(row);
+ var foldStart = foldLine ? foldLine.start.row : Infinity;
while (true) {
if (row > foldStart) {
- row = fold.end.row+1;
- fold = this.session.getNextFoldLine(row, fold);
- foldStart = fold ?fold.start.row :Infinity;
+ row = foldLine.end.row+1;
+ foldLine = this.session.getNextFoldLine(row, foldLine);
+ foldStart = foldLine ? foldLine.start.row : Infinity;
}
if (row > lastRow)
break;
@@ -13137,15 +13727,15 @@ var Text = function(parentEl) {
var html = [];
var firstRow = config.firstRow, lastRow = config.lastRow;
- var row = firstRow,
- fold = this.session.getNextFoldLine(row),
- foldStart = fold ?fold.start.row :Infinity;
+ var row = firstRow;
+ var foldLine = this.session.getNextFoldLine(row);
+ var foldStart = foldLine ? foldLine.start.row : Infinity;
while (true) {
if (row > foldStart) {
- row = fold.end.row+1;
- fold = this.session.getNextFoldLine(row, fold);
- foldStart = fold ?fold.start.row :Infinity;
+ row = foldLine.end.row+1;
+ foldLine = this.session.getNextFoldLine(row, foldLine);
+ foldStart = foldLine ? foldLine.start.row :Infinity;
}
if (row > lastRow)
break;
@@ -13446,11 +14036,10 @@ var Cursor = function(parentEl) {
this.element.className = "ace_layer ace_cursor-layer";
parentEl.appendChild(this.element);
- this.cursor = dom.createElement("div");
- this.cursor.className = "ace_cursor ace_hidden";
- this.element.appendChild(this.cursor);
-
this.isVisible = false;
+
+ this.cursors = [];
+ this.cursor = this.addCursor();
};
(function() {
@@ -13464,35 +14053,59 @@ var Cursor = function(parentEl) {
this.session = session;
};
+ this.addCursor = function() {
+ var el = dom.createElement("div");
+ var className = "ace_cursor";
+ if (!this.isVisible)
+ className += " ace_hidden";
+ if (this.overwrite)
+ className += " ace_overwrite";
+
+ el.className = className;
+ this.element.appendChild(el);
+ this.cursors.push(el);
+ return el;
+ };
+
+ this.removeCursor = function() {
+ if (this.cursors.length > 1) {
+ var el = this.cursors.pop();
+ el.parentNode.removeChild(el);
+ return el;
+ }
+ };
+
this.hideCursor = function() {
this.isVisible = false;
- dom.addCssClass(this.cursor, "ace_hidden");
+ for (var i = this.cursors.length; i--; )
+ dom.addCssClass(this.cursors[i], "ace_hidden");
clearInterval(this.blinkId);
};
this.showCursor = function() {
this.isVisible = true;
- dom.removeCssClass(this.cursor, "ace_hidden");
- this.cursor.style.visibility = "visible";
+ for (var i = this.cursors.length; i--; )
+ dom.removeCssClass(this.cursors[i], "ace_hidden");
+
+ this.element.style.visibility = "";
this.restartTimer();
};
this.restartTimer = function() {
clearInterval(this.blinkId);
- if (!this.isVisible) {
+ if (!this.isVisible)
return;
- }
- var cursor = this.cursor;
+ var element = this.element;
this.blinkId = setInterval(function() {
- cursor.style.visibility = "hidden";
+ element.style.visibility = "hidden";
setTimeout(function() {
- cursor.style.visibility = "visible";
+ element.style.visibility = "visible";
}, 400);
}, 1000);
};
- this.getPixelPosition = function(onScreen) {
+ this.getPixelPosition = function(position, onScreen) {
if (!this.config || !this.session) {
return {
left : 0,
@@ -13500,7 +14113,8 @@ var Cursor = function(parentEl) {
};
}
- var position = this.session.selection.getCursor();
+ if (!position)
+ position = this.session.selection.getCursor();
var pos = this.session.documentToScreenPosition(position);
var cursorLeft = Math.round(this.$padding +
pos.column * this.config.characterWidth);
@@ -13516,25 +14130,53 @@ var Cursor = function(parentEl) {
this.update = function(config) {
this.config = config;
- this.pixelPos = this.getPixelPosition(true);
+ if (this.session.selectionMarkerCount > 1) {
+ var selections = this.session.$selectionMarkers;
+ var i = 0, sel, cursorIndex = 0;
- this.cursor.style.left = this.pixelPos.left + "px";
- this.cursor.style.top = this.pixelPos.top + "px";
- this.cursor.style.width = config.characterWidth + "px";
- this.cursor.style.height = config.lineHeight + "px";
+ for (var i = selections.length; i--; ) {
+ sel = selections[i];
+ var pixelPos = this.getPixelPosition(sel.cursor, true);
- var overwrite = this.session.getOverwrite()
- if (overwrite != this.overwrite) {
- this.overwrite = overwrite;
- if (overwrite)
- dom.addCssClass(this.cursor, "ace_overwrite");
- else
- dom.removeCssClass(this.cursor, "ace_overwrite");
+ var style = (this.cursors[cursorIndex++] || this.addCursor()).style;
+
+ style.left = pixelPos.left + "px";
+ style.top = pixelPos.top + "px";
+ style.width = config.characterWidth + "px";
+ style.height = config.lineHeight + "px";
+ }
+ if (cursorIndex > 1)
+ while (this.cursors.length > cursorIndex)
+ this.removeCursor();
+ } else {
+ var pixelPos = this.getPixelPosition(null, true);
+ var style = this.cursor.style;
+ style.left = pixelPos.left + "px";
+ style.top = pixelPos.top + "px";
+ style.width = config.characterWidth + "px";
+ style.height = config.lineHeight + "px";
+
+ while (this.cursors.length > 1)
+ this.removeCursor();
}
+ var overwrite = this.session.getOverwrite();
+ if (overwrite != this.overwrite)
+ this.$setOverite(overwrite);
+
this.restartTimer();
};
+ this.$setOverite = function(overwrite) {
+ this.overwrite = overwrite;
+ for (var i = this.cursors.length; i--; ) {
+ if (overwrite)
+ dom.addCssClass(this.cursors[i], "ace_overwrite");
+ else
+ dom.removeCssClass(this.cursors[i], "ace_overwrite");
+ }
+ };
+
this.destroy = function() {
clearInterval(this.blinkId);
}
@@ -13629,6 +14271,8 @@ var ScrollBar = function(parent) {
this.inner.style.height = height + "px";
};
+ // 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;
};
@@ -13713,11 +14357,10 @@ exports.RenderLoop = RenderLoop;
});
define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/css?family=Droid+Sans+Mono);\n" +
"\n" +
- "\n" +
".ace_editor {\n" +
" position: absolute;\n" +
" overflow: hidden;\n" +
- " font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Droid Sans Mono', 'Courier New', monospace;\n" +
+ " font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', 'Droid Sans Mono', 'Consolas', monospace;\n" +
" font-size: 12px;\n" +
"}\n" +
"\n" +
@@ -13735,12 +14378,6 @@ define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/css?fa
" cursor: text;\n" +
"}\n" +
"\n" +
- "/* setting pointer-events: auto; on node under the mouse, which changes during scroll,\n" +
- " will break mouse wheel scrolling in Safari */\n" +
- ".ace_content * {\n" +
- " pointer-events: none;\n" +
- "}\n" +
- "\n" +
".ace_composition {\n" +
" position: absolute;\n" +
" background: #555;\n" +
@@ -13748,18 +14385,17 @@ define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/css?fa
" z-index: 4;\n" +
"}\n" +
"\n" +
- ".ace_gutter .ace_layer {\n" +
- " position: relative;\n" +
- " min-width: 54px;\n" +
- " text-align: right;\n" +
- "}\n" +
- "\n" +
".ace_gutter {\n" +
" position: absolute;\n" +
" overflow : hidden;\n" +
" height: 100%;\n" +
" width: auto;\n" +
" cursor: default;\n" +
+ " z-index: 1000;\n" +
+ "}\n" +
+ "\n" +
+ ".ace_gutter.horscroll {\n" +
+ " box-shadow: 0px 0px 20px rgba(0,0,0,0.4);\n" +
"}\n" +
"\n" +
".ace_gutter-cell {\n" +
@@ -13838,6 +14474,16 @@ define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/css?fa
" box-sizing: border-box;\n" +
" -moz-box-sizing: border-box;\n" +
" -webkit-box-sizing: border-box;\n" +
+ " /* setting pointer-events: auto; on node under the mouse, which changes\n" +
+ " during scroll, will break mouse wheel scrolling in Safari */\n" +
+ " pointer-events: none;\n" +
+ "}\n" +
+ "\n" +
+ ".ace_gutter .ace_layer {\n" +
+ " position: relative;\n" +
+ " min-width: 40px;\n" +
+ " text-align: right;\n" +
+ " pointer-events: auto;\n" +
"}\n" +
"\n" +
".ace_text-layer {\n" +
@@ -13873,12 +14519,12 @@ define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/css?fa
"\n" +
".ace_marker-layer .ace_selection {\n" +
" position: absolute;\n" +
- " z-index: 4;\n" +
+ " z-index: 5;\n" +
"}\n" +
"\n" +
".ace_marker-layer .ace_bracket {\n" +
" position: absolute;\n" +
- " z-index: 5;\n" +
+ " z-index: 6;\n" +
"}\n" +
"\n" +
".ace_marker-layer .ace_active_line {\n" +
@@ -13886,9 +14532,13 @@ define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/css?fa
" z-index: 2;\n" +
"}\n" +
"\n" +
+ ".ace_gutter .ace_gutter_active_line{\n" +
+ " background-color : #dcdcdc;\n" +
+ "}\n" +
+ "\n" +
".ace_marker-layer .ace_selected_word {\n" +
" position: absolute;\n" +
- " z-index: 6;\n" +
+ " z-index: 4;\n" +
" box-sizing: border-box;\n" +
" -moz-box-sizing: border-box;\n" +
" -webkit-box-sizing: border-box;\n" +
@@ -13935,7 +14585,7 @@ define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/css?fa
" cursor: move;\n" +
"}\n" +
"\n" +
- ".ace_folding-enabled .ace_gutter-cell {\n" +
+ ".ace_folding-enabled > .ace_gutter-cell {\n" +
" padding-right: 13px;\n" +
"}\n" +
"\n" +
@@ -13994,6 +14644,1761 @@ define("text!ace/css/editor.css", [], "@import url(//fonts.googleapis.com/css?fa
"}\n" +
"");
+/* vim:ts=4:sts=4:sw=4:
+ * ***** 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 <amirjanyan AT gmail DOT com>
+ *
+ * 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('ace/multi_select', ['require', 'exports', 'module' , 'ace/range_list', 'ace/range', 'ace/selection', 'ace/mouse/multi_select_handler', 'ace/commands/multi_select_commands', 'ace/search', 'ace/edit_session', 'ace/editor'], function(require, exports, module) {
+
+var RangeList = require("./range_list").RangeList;
+var Range = require("./range").Range;
+var Selection = require("./selection").Selection;
+var onMouseDown = require("./mouse/multi_select_handler").onMouseDown;
+exports.commands = require("./commands/multi_select_commands");
+
+// Todo: session.find or editor.findVolatile that returns range
+var Search = require("./search").Search;
+var search = new Search();
+
+function find(session, needle, dir) {
+ search.$options.wrap = true;
+ search.$options.needle = needle;
+ search.$options.backwards = dir == -1;
+ return search.find(session);
+}
+
+// extend EditSession
+var EditSession = require("./edit_session").EditSession;
+(function() {
+ this.getSelectionMarkers = function() {
+ return this.$selectionMarkers;
+ };
+}).call(EditSession.prototype);
+
+// extend Selection
+(function() {
+ // list of ranges in reverse addition order
+ this.ranges = null;
+
+ // automatically sorted list of ranges
+ this.rangeList = null;
+
+ /**
+ * Selection.addRange(Range) -> Void
+ *
+ * adds a range to selection entering multiselect mode if necessary
+ **/
+ this.addRange = function(range) {
+ if (!this.inMultiSelectMode && this.rangeCount == 0) {
+ var oldRange = this.toOrientedRange();
+ if (!range || !range.isEqual(oldRange)) {
+ this.rangeList.add(oldRange);
+ this.$onAddRange(oldRange);
+ }
+ }
+
+ if (!range)
+ return;
+
+ if (!range.cursor)
+ range.cursor = range.end;
+
+ var removed = this.rangeList.add(range);
+
+ this.$onAddRange(range);
+
+ if (removed.length)
+ this.$onRemoveRange(removed);
+
+ if (this.rangeCount > 0 && !this.inMultiSelectMode) {
+ this._emit("multiSelect");
+ this.inMultiSelectMode = true;
+ this.session.$undoSelect = false;
+ this.rangeList.attach(this.session);
+ }
+ };
+
+ this.toSingleRange = function(range) {
+ range = range || this.ranges[0];
+ var removed = this.rangeList.removeAll();
+ if (removed.length)
+ this.$onRemoveRange(removed);
+
+ range && this.fromOrientedRange(range);
+ };
+
+ /**
+ * Selection.addRange(pos) -> Range
+ * pos: {row, column}
+ *
+ * removes range containing pos (if exists)
+ **/
+ this.substractPoint = function(pos) {
+ var removed = this.rangeList.substractPoint(pos);
+ if (removed) {
+ this.$onRemoveRange(removed);
+ return removed[0];
+ }
+ };
+
+ /**
+ * Selection.mergeOverlappingRanges() -> Void
+ *
+ * merges overlapping ranges ensuring consistency after changes
+ **/
+ this.mergeOverlappingRanges = function() {
+ var removed = this.rangeList.merge();
+ if (removed.length)
+ this.$onRemoveRange(removed);
+ else if(this.ranges[0])
+ this.fromOrientedRange(this.ranges[0]);
+ };
+
+ this.$onAddRange = function(range) {
+ this.rangeCount = this.rangeList.ranges.length;
+ this.ranges.unshift(range);
+ this.fromOrientedRange(range);
+ this._emit("addRange", {range: range});
+ };
+
+ this.$onRemoveRange = function(removed) {
+ this.rangeCount = this.rangeList.ranges.length;
+ if (this.rangeCount == 1 && this.inMultiSelectMode) {
+ var lastRange = this.rangeList.ranges.pop();
+ removed.push(lastRange);
+ this.rangeCount = 0;
+ }
+
+ for (var i = removed.length; i--; ) {
+ var index = this.ranges.indexOf(removed[i]);
+ this.ranges.splice(index, 1);
+ }
+
+ this._emit("removeRange", {ranges: removed});
+
+ if (this.rangeCount == 0 && this.inMultiSelectMode) {
+ this.inMultiSelectMode = false;
+ this._emit("singleSelect");
+ this.session.$undoSelect = true;
+ this.rangeList.detach(this.session);
+ }
+
+ lastRange = lastRange || this.ranges[0];
+ if (lastRange && !lastRange.isEqual(this.getRange()))
+ this.fromOrientedRange(lastRange);
+ };
+
+ // adds multicursor support to selection
+ this.$initRangeList = function() {
+ if (this.rangeList)
+ return;
+
+ this.rangeList = new RangeList();
+ this.ranges = [];
+ this.rangeCount = 0;
+ };
+
+ this.getAllRanges = function() {
+ return this.rangeList.ranges.concat();
+ };
+
+ this.splitIntoLines = function () {
+ if (this.rangeCount > 1) {
+ var ranges = this.rangeList.ranges;
+ var lastRange = ranges[ranges.length - 1];
+ var range = Range.fromPoints(ranges[0].start, lastRange.end);
+
+ this.toSingleRange();
+ this.setSelectionRange(range, lastRange.cursor == lastRange.start);
+ } else {
+ var cursor = this.session.documentToScreenPosition(this.selectionLead);
+ var anchor = this.session.documentToScreenPosition(this.selectionAnchor);
+
+ var rectSel = this.rectangularRangeBlock(cursor, anchor);
+ rectSel.forEach(this.addRange, this);
+ }
+ };
+
+ /**
+ * Selection.rectangularRangeBlock(screenCursor, screenAnchor, includeEmptyLines) -> [Range]
+ * gets list of ranges composing rectangular block on the screen
+ * @includeEmptyLines if true includes ranges inside the block which
+ * are empty becuase of the clipping
+ */
+ this.rectangularRangeBlock = function(screenCursor, screenAnchor, includeEmptyLines) {
+ var rectSel = [];
+
+ var xBackwards = screenCursor.column < screenAnchor.column;
+ if (xBackwards) {
+ var startColumn = screenCursor.column;
+ var endColumn = screenAnchor.column;
+ } else {
+ var startColumn = screenAnchor.column;
+ var endColumn = screenCursor.column;
+ }
+
+ var yBackwards = screenCursor.row < screenAnchor.row;
+ if (yBackwards) {
+ var startRow = screenCursor.row;
+ var endRow = screenAnchor.row;
+ } else {
+ var startRow = screenAnchor.row;
+ var endRow = screenCursor.row;
+ }
+
+ if (startColumn < 0)
+ startColumn = 0;
+ if (startRow < 0)
+ startRow = 0;
+
+ if (startRow == endRow)
+ includeEmptyLines = true;
+
+ for (var row = startRow; row <= endRow; row++) {
+ var range = Range.fromPoints(
+ this.session.screenToDocumentPosition(row, startColumn),
+ this.session.screenToDocumentPosition(row, endColumn)
+ );
+ if (range.isEmpty()) {
+ if (docEnd && isSamePoint(range.end, docEnd))
+ break;
+ var docEnd = range.end;
+ }
+ range.cursor = xBackwards ? range.start : range.end;
+ rectSel.push(range);
+ }
+
+ if (yBackwards)
+ rectSel.reverse();
+
+ if (!includeEmptyLines) {
+ var end = rectSel.length - 1;
+ while (rectSel[end].isEmpty() && end > 0)
+ end--;
+ if (end > 0) {
+ var start = 0;
+ while (rectSel[start].isEmpty())
+ start++;
+ }
+ for (var i = end; i >= start; i--) {
+ if (rectSel[i].isEmpty())
+ rectSel.splice(i, 1);
+ }
+ }
+
+ return rectSel;
+ };
+}).call(Selection.prototype);
+
+// extend Editor
+var Editor = require("./editor").Editor;
+(function() {
+ /**
+ * Editor.updateSelectionMarkers() -> Void
+ *
+ * updates cursor and marker layers
+ **/
+ this.updateSelectionMarkers = function() {
+ this.renderer.updateCursor();
+ this.renderer.updateBackMarkers();
+ };
+
+ /**
+ * Editor.addSelectionMarker(orientedRange) -> Range
+ * - orientedRange: range with cursor
+ *
+ * adds selection and cursor
+ **/
+ this.addSelectionMarker = function(orientedRange) {
+ if (!orientedRange.cursor)
+ orientedRange.cursor = orientedRange.end;
+
+ var style = this.getSelectionStyle();
+ orientedRange.marker = this.session.addMarker(orientedRange, "ace_selection", style);
+
+ this.session.$selectionMarkers.push(orientedRange);
+ this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
+ return orientedRange;
+ };
+
+ this.removeSelectionMarkers = function(ranges) {
+ for (var i = ranges.length; i--; ) {
+ var range = ranges[i];
+ if (!range.marker)
+ continue;
+ this.session.removeMarker(range.marker);
+ var index = this.session.$selectionMarkers.indexOf(range);
+ if (index != -1)
+ this.session.$selectionMarkers.splice(index, 1);
+ }
+ this.session.selectionMarkerCount = this.session.$selectionMarkers.length;
+ };
+
+ this.$onAddRange = function(e) {
+ this.addSelectionMarker(e.range);
+ this.renderer.updateCursor();
+ this.renderer.updateBackMarkers();
+ };
+
+ this.$onRemoveRange = function(e) {
+ this.removeSelectionMarkers(e.ranges);
+ this.renderer.updateCursor();
+ this.renderer.updateBackMarkers();
+ };
+
+ this.$onMultiSelect = function(e) {
+ if (this.inMultiSelectMode)
+ return;
+ this.inMultiSelectMode = true;
+
+ this.setStyle("multiselect");
+ this.keyBinding.addKeyboardHandler(exports.commands.keyboardHandler);
+ this.commands.on("exec", this.$onMultiSelectExec);
+
+ this.renderer.updateCursor();
+ this.renderer.updateBackMarkers();
+ };
+
+ this.$onSingleSelect = function(e) {
+ if (this.session.multiSelect.inVirtualMode)
+ return;
+ this.inMultiSelectMode = false;
+
+ this.unsetStyle("multiselect");
+ this.keyBinding.removeKeyboardHandler(exports.commands.keyboardHandler);
+
+ this.commands.removeEventListener("exec", this.$onMultiSelectExec);
+ this.renderer.updateCursor();
+ this.renderer.updateBackMarkers();
+ };
+
+ this.$onMultiSelectExec = function(e) {
+ var command = e.command;
+ var editor = e.editor;
+ if (!command.multiSelectAction) {
+ command.exec(editor, e.args || {});
+ editor.multiSelect.addRange(editor.multiSelect.toOrientedRange());
+ editor.multiSelect.mergeOverlappingRanges();
+ } else if (command.multiSelectAction == "forEach") {
+ editor.forEachSelection(command, e.args);
+ } else if (command.multiSelectAction == "single") {
+ editor.exitMultiSelectMode();
+ command.exec(editor, e.args || {});
+ } else {
+ command.multiSelectAction(editor, e.args || {});
+ }
+ e.preventDefault();
+ };
+
+ /**
+ * Editor.forEachSelection(cmd, args) -> Void
+ * - cmd: command to execute
+ * - args: arguments to the command
+ *
+ * executes command for each selection range
+ **/
+ this.forEachSelection = function(cmd, args) {
+ if (this.inVirtualSelectionMode)
+ return;
+
+ var session = this.session;
+ var selection = this.selection;
+ var rangeList = selection.rangeList;
+
+ var reg = selection._eventRegistry;
+ selection._eventRegistry = {};
+
+ var tmpSel = new Selection(session);
+ this.inVirtualSelectionMode = true;
+ for (var i = rangeList.ranges.length; i--;) {
+ tmpSel.fromOrientedRange(rangeList.ranges[i]);
+ this.selection = session.selection = tmpSel;
+ cmd.exec(this, args || {});
+ tmpSel.toOrientedRange(rangeList.ranges[i]);
+ }
+ tmpSel.detach();
+
+ this.selection = session.selection = selection;
+ this.inVirtualSelectionMode = false;
+ selection._eventRegistry = reg;
+ selection.mergeOverlappingRanges();
+
+ this.onCursorChange();
+ this.onSelectionChange();
+ };
+
+ /**
+ * Editor.exitMultiSelectMode() -> Void
+ *
+ * removes all selections except the last added one.
+ **/
+ this.exitMultiSelectMode = function() {
+ if (this.inVirtualSelectionMode)
+ return;
+ this.multiSelect.toSingleRange();
+ };
+
+ this.getCopyText = function() {
+ var text = "";
+ if (this.inMultiSelectMode) {
+ var ranges = this.multiSelect.rangeList.ranges;
+ text = [];
+ for (var i = 0; i < ranges.length; i++) {
+ text.push(this.session.getTextRange(ranges[i]));
+ }
+ text = text.join(this.session.getDocument().getNewLineCharacter());
+ } else if (!this.selection.isEmpty()) {
+ text = this.session.getTextRange(this.getSelectionRange());
+ }
+
+ return text;
+ };
+
+
+ // commands
+ /**
+ * Editor.selectMoreLines(dir, skip) -> Void
+ * - dir: -1 up, 1 down
+ * - skip: remove active selection range if true
+ *
+ * adds cursor above or bellow active cursor
+ **/
+ this.selectMoreLines = function(dir, skip) {
+ var range = this.selection.toOrientedRange();
+ var isBackwards = range.cursor == range.end;
+
+ var screenLead = this.session.documentToScreenPosition(range.cursor);
+ if (this.selection.$desiredColumn)
+ screenLead.column = this.selection.$desiredColumn;
+
+ var lead = this.session.screenToDocumentPosition(screenLead.row + dir, screenLead.column);
+
+ if (!range.isEmpty()) {
+ var screenAnchor = this.session.documentToScreenPosition(isBackwards ? range.end : range.start);
+ var anchor = this.session.screenToDocumentPosition(screenAnchor.row + dir, screenAnchor.column);
+ } else {
+ var anchor = lead;
+ }
+
+ if (isBackwards) {
+ var newRange = Range.fromPoints(lead, anchor);
+ newRange.cursor = newRange.start;
+ } else {
+ var newRange = Range.fromPoints(anchor, lead);
+ newRange.cursor = newRange.end;
+ }
+
+ newRange.desiredColumn = screenLead.column;
+ if (!this.selection.inMultiSelectMode) {
+ this.selection.addRange(range);
+ } else {
+ if (skip)
+ var toRemove = range.cursor;
+ }
+
+ this.selection.addRange(newRange);
+ if (toRemove)
+ this.selection.substractPoint(toRemove);
+ };
+
+ /**
+ * Editor.transposeSelections(dir) -> Void
+ * - dir: direction to rotate selections
+ *
+ * contents
+ * empty ranges are expanded to word
+ **/
+ this.transposeSelections = function(dir) {
+ var session = this.session;
+ var sel = session.multiSelect;
+ var all = sel.ranges;
+
+ for (var i = all.length; i--; ) {
+ var range = all[i];
+ if (range.isEmpty()) {
+ var tmp = session.getWordRange(range.start.row, range.start.column);
+ range.start.row = tmp.start.row;
+ range.start.column = tmp.start.column;
+ range.end.row = tmp.end.row;
+ range.end.column = tmp.end.column;
+ }
+ }
+ sel.mergeOverlappingRanges();
+
+ var words = [];
+ for (var i = all.length; i--; ) {
+ var range = all[i];
+ words.unshift(session.getTextRange(range));
+ }
+
+ if (dir < 0)
+ words.unshift(words.pop());
+ else
+ words.push(words.shift());
+
+ for (var i = all.length; i--; ) {
+ var range = all[i];
+ var tmp = range.clone();
+ session.replace(range, words[i]);
+ range.start.row = tmp.start.row;
+ range.start.column = tmp.start.column;
+ }
+ }
+
+ /**
+ * Editor.selectMore(dir, skip) -> Void
+ * - dir: 1 next, -1 previous
+ * - skip: remove active selection range if true
+ *
+ * finds next occurence of text in active selection
+ * and adds it to the selections
+ **/
+ this.selectMore = function (dir, skip) {
+ var session = this.session;
+ var sel = session.multiSelect;
+
+ var range = sel.toOrientedRange();
+ if (range.isEmpty()) {
+ var range = session.getWordRange(range.start.row, range.start.column);
+ range.cursor = range.end;
+ this.multiSelect.addRange(range);
+ }
+ var needle = session.getTextRange(range);
+
+ var newRange = find(session, needle, dir);
+ if (newRange) {
+ newRange.cursor = dir == -1 ? newRange.start : newRange.end;
+ this.multiSelect.addRange(newRange);
+ }
+ if (skip)
+ this.multiSelect.substractPoint(range.cursor);
+ };
+}).call(Editor.prototype);
+
+
+function isSamePoint(p1, p2) {
+ return p1.row == p2.row && p1.column == p2.column;
+}
+
+// patch
+// adds multicursor support to a session
+exports.onSessionChange = function(e) {
+ var session = e.session;
+ if (!session.multiSelect) {
+ session.$selectionMarkers = [];
+ session.selection.$initRangeList();
+ session.multiSelect = session.selection;
+ }
+ this.multiSelect = session.multiSelect;
+
+ var oldSession = e.oldSession;
+ if (oldSession) {
+ // todo use events
+ if (oldSession.multiSelect && oldSession.multiSelect.editor == this)
+ oldSession.multiSelect.editor = null;
+
+ session.multiSelect.removeEventListener("addRange", this.$onAddRange);
+ session.multiSelect.removeEventListener("removeRange", this.$onRemoveRange);
+ session.multiSelect.removeEventListener("multiSelect", this.$onMultiSelect);
+ session.multiSelect.removeEventListener("singleSelect", this.$onSingleSelect);
+ }
+
+ session.multiSelect.on("addRange", this.$onAddRange);
+ session.multiSelect.on("removeRange", this.$onRemoveRange);
+ session.multiSelect.on("multiSelect", this.$onMultiSelect);
+ session.multiSelect.on("singleSelect", this.$onSingleSelect);
+
+ // this.$onSelectionChange = this.onSelectionChange.bind(this);
+
+ if (this.inMultiSelectMode != session.selection.inMultiSelectMode) {
+ if (session.selection.inMultiSelectMode)
+ this.$onMultiSelect();
+ else
+ this.$onSingleSelect();
+ }
+};
+
+/**
+ * MultiSelect(editor) -> Void
+ *
+ * adds multiple selection support to the editor
+ * (note: should be called only once for each editor instance)
+ **/
+function MultiSelect(editor) {
+ editor.$onAddRange = editor.$onAddRange.bind(editor);
+ editor.$onRemoveRange = editor.$onRemoveRange.bind(editor);
+ editor.$onMultiSelect = editor.$onMultiSelect.bind(editor);
+ editor.$onSingleSelect = editor.$onSingleSelect.bind(editor);
+
+ exports.onSessionChange.call(editor, editor);
+ editor.on("changeSession", exports.onSessionChange.bind(editor));
+
+ editor.on("mousedown", onMouseDown);
+ editor.commands.addCommands(exports.commands.defaultCommands);
+}
+
+exports.MultiSelect = MultiSelect;
+
+});/* ***** 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 <amirjanyan AT gmail DOT com>
+ *
+ * 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('ace/range_list', ['require', 'exports', 'module' ], 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;
+});
+/* vim:ts=4:sts=4:sw=4:
+ * ***** 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 <amirjanyan AT gmail DOT com>
+ *
+ * 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('ace/mouse/multi_select_handler', ['require', 'exports', 'module' , 'ace/lib/event'], function(require, exports, module) {
+
+var event = require("../lib/event");
+
+
+// mouse
+function isSamePoint(p1, p2) {
+ return p1.row == p2.row && p1.column == p2.column;
+}
+
+function onMouseDown(e) {
+ var ev = e.domEvent;
+ var alt = ev.altKey;
+ var shift = ev.shiftKey;
+ var ctrl = e.getAccelKey();
+ var button = e.getButton();
+
+ if (!ctrl && !alt) {
+ if (e.editor.inMultiSelectMode) {
+ if (button == 0) {
+ e.editor.exitMultiSelectMode();
+ } else if (button == 2) {
+ var editor = e.editor;
+ var selectionEmpty = editor.selection.isEmpty();
+ editor.textInput.onContextMenu({x: e.clientX, y: e.clientY}, selectionEmpty);
+ event.capture(editor.container, function(){}, editor.textInput.onContextMenuClose);
+ e.stop();
+ }
+ }
+ return;
+ }
+
+ var editor = e.editor;
+ var selection = editor.selection;
+ var isMultiSelect = editor.inMultiSelectMode;
+ var pos = e.getDocumentPosition();
+ var cursor = selection.getCursor();
+ var inSelection = e.inSelection() || (selection.isEmpty() && isSamePoint(pos, cursor));
+
+
+ var mouseX = e.pageX, mouseY = e.pageY;
+ var onMouseSelection = function(e) {
+ mouseX = event.getDocumentX(e);
+ mouseY = event.getDocumentY(e);
+ };
+
+ var blockSelect = function() {
+ var newCursor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
+ var cursor = session.screenToDocumentPosition(newCursor.row, newCursor.column);
+
+ if (isSamePoint(screenCursor, newCursor)
+ && isSamePoint(cursor, selection.selectionLead))
+ return;
+ screenCursor = newCursor;
+
+ editor.selection.moveCursorToPosition(cursor);
+ editor.selection.clearSelection();
+ editor.renderer.scrollCursorIntoView();
+
+ editor.removeSelectionMarkers(rectSel);
+ rectSel = selection.rectangularRangeBlock(screenCursor, screenAnchor);
+ rectSel.forEach(editor.addSelectionMarker, editor);
+ editor.updateSelectionMarkers();
+ };
+
+ var session = editor.session;
+ var screenAnchor = editor.renderer.pixelToScreenCoordinates(mouseX, mouseY);
+ var screenCursor = screenAnchor;
+
+
+
+ if (ctrl && !shift && !alt && button == 0) {
+ if (!isMultiSelect && inSelection)
+ return; // dragging
+
+ if (!isMultiSelect)
+ selection.addRange(selection.toOrientedRange());
+
+
+ var oldRange = selection.rangeList.rangeAtPoint(pos);
+
+ event.capture(editor.container, function(){}, function() {
+ var tmpSel = selection.toOrientedRange();
+
+ if (oldRange && tmpSel.isEmpty() && isSamePoint(oldRange.cursor, tmpSel.cursor))
+ selection.substractPoint(tmpSel.cursor);
+ else
+ selection.addRange(tmpSel);
+ });
+
+ } else if (!shift && alt && button == 0) {
+ e.stop();
+
+ if (isMultiSelect && !ctrl)
+ selection.toSingleRange();
+ else if (!isMultiSelect && ctrl)
+ selection.addRange();
+
+ selection.moveCursorToPosition(pos);
+ selection.clearSelection();
+
+ var rectSel = [];
+
+ var onMouseSelectionEnd = function(e) {
+ clearInterval(timerId);
+ editor.removeSelectionMarkers(rectSel);
+ for (var i = 0; i < rectSel.length; i++)
+ selection.addRange(rectSel[i]);
+ };
+
+ var onSelectionInterval = blockSelect;
+
+ event.capture(editor.container, onMouseSelection, onMouseSelectionEnd);
+ var timerId = setInterval(function() {onSelectionInterval();}, 20);
+
+ return e.preventDefault();
+ }
+}
+
+
+exports.onMouseDown = onMouseDown;
+
+});/* vim:ts=4:sts=4:sw=4:
+ * ***** 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 <amirjanyan AT gmail DOT com>
+ *
+ * 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('ace/commands/multi_select_commands', ['require', 'exports', 'module' , 'ace/keyboard/hash_handler'], function(require, exports, module) {
+
+// commands to enter multiselect mode
+exports.defaultCommands = [{
+ name: "addCursorAbove",
+ exec: function(editor) { editor.selectMoreLines(-1); },
+ bindKey: {win: "Ctrl-Alt-Up", mac: "Ctrl-Alt-Up"},
+ readonly: true
+}, {
+ name: "addCursorBelow",
+ exec: function(editor) { editor.selectMoreLines(1); },
+ bindKey: {win: "Ctrl-Alt-Down", mac: "Ctrl-Alt-Down"},
+ readonly: true
+}, {
+ name: "addCursorAboveSkipCurrent",
+ exec: function(editor) { editor.selectMoreLines(-1, true); },
+ bindKey: {win: "Ctrl-Alt-Shift-Up", mac: "Ctrl-Alt-Shift-Up"},
+ readonly: true
+}, {
+ name: "addCursorBelowSkipCurrent",
+ exec: function(editor) { editor.selectMoreLines(1, true); },
+ bindKey: {win: "Ctrl-Alt-Shift-Down", mac: "Ctrl-Alt-Shift-Down"},
+ readonly: true
+}, {
+ name: "selectMoreBefore",
+ exec: function(editor) { editor.selectMore(-1); },
+ bindKey: {win: "Ctrl-Alt-Left", mac: "Ctrl-Alt-Left"},
+ readonly: true
+}, {
+ name: "selectMoreAfter",
+ exec: function(editor) { editor.selectMore(1); },
+ bindKey: {win: "Ctrl-Alt-Right", mac: "Ctrl-Alt-Right"},
+ readonly: true
+}, {
+ name: "selectNextBefore",
+ exec: function(editor) { editor.selectMore(-1, true); },
+ bindKey: {win: "Ctrl-Alt-Shift-Left", mac: "Ctrl-Alt-Shift-Left"},
+ readonly: true
+}, {
+ name: "selectNextAfter",
+ exec: function(editor) { editor.selectMore(1, true); },
+ bindKey: {win: "Ctrl-Alt-Shift-Right", mac: "Ctrl-Alt-Shift-Right"},
+ readonly: true
+}, {
+ name: "splitIntoLines",
+ exec: function(editor) { editor.multiSelect.splitIntoLines(); },
+ bindKey: {win: "Ctrl-Shift-L", mac: "Ctrl-Shift-L"},
+ readonly: true
+}];
+
+// commands active in multiselect mode
+exports.multiEditCommands = [{
+ name: "singleSelection",
+ bindKey: "esc",
+ exec: function(editor) { editor.exitMultiSelectMode(); },
+ readonly: true
+}];
+
+var HashHandler = require("../keyboard/hash_handler").HashHandler;
+exports.keyboardHandler = new HashHandler(exports.multiEditCommands);
+
+});/* ***** 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 <fabian AT ajax DOT org>
+ *
+ * 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('ace/worker/worker_client', ['require', 'exports', 'module' , 'ace/lib/oop', 'ace/lib/event_emitter', 'ace/config'], function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var EventEmitter = require("../lib/event_emitter").EventEmitter;
+var config = require("../config");
+
+var WorkerClient = function(topLevelNamespaces, packagedJs, mod, classname) {
+
+ this.changeListener = this.changeListener.bind(this);
+
+ if (config.get("packaged")) {
+ this.$worker = new Worker(config.get("workerPath") + "/" + packagedJs);
+ }
+ else {
+ var workerUrl = this.$normalizePath(require.nameToUrl("ace/worker/worker", null, "_"));
+ this.$worker = new Worker(workerUrl);
+
+ var tlns = {};
+ for (var i=0; i<topLevelNamespaces.length; i++) {
+ var ns = topLevelNamespaces[i];
+ var path = this.$normalizePath(require.nameToUrl(ns, null, "_").replace(/.js$/, ""));
+
+ tlns[ns] = path;
+ }
+ }
+
+ this.$worker.postMessage({
+ init : true,
+ tlns: tlns,
+ module: mod,
+ classname: classname
+ });
+
+ this.callbackId = 1;
+ this.callbacks = {};
+
+ var _self = this;
+ this.$worker.onerror = function(e) {
+ window.console && console.log && console.log(e);
+ throw e;
+ };
+ this.$worker.onmessage = function(e) {
+ var msg = e.data;
+ switch(msg.type) {
+ case "log":
+ window.console && console.log && console.log(msg.data);
+ break;
+
+ case "event":
+ _self._emit(msg.name, {data: msg.data});
+ break;
+
+ case "call":
+ var callback = _self.callbacks[msg.id];
+ if (callback) {
+ callback(msg.data);
+ delete _self.callbacks[msg.id];
+ }
+ break;
+ }
+ };
+};
+
+(function(){
+
+ oop.implement(this, EventEmitter);
+
+ this.$normalizePath = function(path) {
+ path = path.replace(/^[a-z]+:\/\/[^\/]+/, ""); // Remove domain name and rebuild it
+ path = location.protocol + "//" + location.host
+ // paths starting with a slash are relative to the root (host)
+ + (path.charAt(0) == "/" ? "" : location.pathname.replace(/\/[^\/]*$/, ""))
+ + "/" + path.replace(/^[\/]+/, "");
+ return path;
+ };
+
+ this.terminate = function() {
+ this._emit("terminate", {});
+ this.$worker.terminate();
+ this.$worker = null;
+ this.$doc.removeEventListener("change", this.changeListener);
+ this.$doc = null;
+ };
+
+ this.send = function(cmd, args) {
+ this.$worker.postMessage({command: cmd, args: args});
+ };
+
+ this.call = function(cmd, args, callback) {
+ if (callback) {
+ var id = this.callbackId++;
+ this.callbacks[id] = callback;
+ args.push(id);
+ }
+ this.send(cmd, args);
+ };
+
+ this.emit = function(event, data) {
+ try {
+ // firefox refuses to clone objects which have function properties
+ // TODO: cleanup event
+ this.$worker.postMessage({event: event, data: {data: data.data}});
+ }
+ catch(ex) {}
+ };
+
+ this.attachToDocument = function(doc) {
+ if(this.$doc)
+ this.terminate();
+
+ this.$doc = doc;
+ this.call("setValue", [doc.getValue()]);
+ doc.on("change", this.changeListener);
+ };
+
+ this.changeListener = function(e) {
+ e.range = {
+ start: e.data.range.start,
+ end: e.data.range.end
+ };
+ this.emit("change", e);
+ };
+
+}).call(WorkerClient.prototype);
+
+exports.WorkerClient = WorkerClient;
+
+});
+/* ***** 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 Mozilla Skywriter.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Julian Viereck (julian.viereck@gmail.com)
+ *
+ * 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('ace/keyboard/state_handler', ['require', 'exports', 'module' ], function(require, exports, module) {
+"use strict";
+
+// If you're developing a new keymapping and want to get an idea what's going
+// on, then enable debugging.
+var DEBUG = false;
+
+function StateHandler(keymapping) {
+ this.keymapping = this.$buildKeymappingRegex(keymapping);
+}
+
+StateHandler.prototype = {
+ /**
+ * Build the RegExp from the keymapping as RegExp can't stored directly
+ * in the metadata JSON and as the RegExp used to match the keys/buffer
+ * need to be adapted.
+ */
+ $buildKeymappingRegex: function(keymapping) {
+ for (var state in keymapping) {
+ this.$buildBindingsRegex(keymapping[state]);
+ }
+ return keymapping;
+ },
+
+ $buildBindingsRegex: function(bindings) {
+ // Escape a given Regex string.
+ bindings.forEach(function(binding) {
+ if (binding.key) {
+ binding.key = new RegExp('^' + binding.key + '$');
+ } else if (Array.isArray(binding.regex)) {
+ if (!('key' in binding))
+ binding.key = new RegExp('^' + binding.regex[1] + '$');
+ binding.regex = new RegExp(binding.regex.join('') + '$');
+ } else if (binding.regex) {
+ binding.regex = new RegExp(binding.regex + '$');
+ }
+ });
+ },
+
+ $composeBuffer: function(data, hashId, key, e) {
+ // Initialize the data object.
+ if (data.state == null || data.buffer == null) {
+ data.state = "start";
+ data.buffer = "";
+ }
+
+ var keyArray = [];
+ if (hashId & 1) keyArray.push("ctrl");
+ if (hashId & 8) keyArray.push("command");
+ if (hashId & 2) keyArray.push("option");
+ if (hashId & 4) keyArray.push("shift");
+ if (key) keyArray.push(key);
+
+ var symbolicName = keyArray.join("-");
+ var bufferToUse = data.buffer + symbolicName;
+
+ // Don't add the symbolic name to the key buffer if the alt_ key is
+ // part of the symbolic name. If it starts with alt_, this means
+ // that the user hit an alt keycombo and there will be a single,
+ // new character detected after this event, which then will be
+ // added to the buffer (e.g. alt_j will result in ∆).
+ //
+ // We test for 2 and not for & 2 as we only want to exclude the case where
+ // the option key is pressed alone.
+ if (hashId != 2) {
+ data.buffer = bufferToUse;
+ }
+
+ var bufferObj = {
+ bufferToUse: bufferToUse,
+ symbolicName: symbolicName,
+ };
+
+ if (e) {
+ bufferObj.keyIdentifier = e.keyIdentifier
+ }
+
+ return bufferObj;
+ },
+
+ $find: function(data, buffer, symbolicName, hashId, key, keyIdentifier) {
+ // Holds the command to execute and the args if a command matched.
+ var result = {};
+
+ // Loop over all the bindings of the keymap until a match is found.
+ this.keymapping[data.state].some(function(binding) {
+ var match;
+
+ // Check if the key matches.
+ if (binding.key && !binding.key.test(symbolicName)) {
+ return false;
+ }
+
+ // Check if the regex matches.
+ if (binding.regex && !(match = binding.regex.exec(buffer))) {
+ return false;
+ }
+
+ // Check if the match function matches.
+ if (binding.match && !binding.match(buffer, hashId, key, symbolicName, keyIdentifier)) {
+ return false;
+ }
+
+ // Check for disallowed matches.
+ if (binding.disallowMatches) {
+ for (var i = 0; i < binding.disallowMatches.length; i++) {
+ if (!!match[binding.disallowMatches[i]]) {
+ return false;
+ }
+ }
+ }
+
+ // If there is a command to execute, then figure out the
+ // command and the arguments.
+ if (binding.exec) {
+ result.command = binding.exec;
+
+ // Build the arguments.
+ if (binding.params) {
+ var value;
+ result.args = {};
+ binding.params.forEach(function(param) {
+ if (param.match != null && match != null) {
+ value = match[param.match] || param.defaultValue;
+ } else {
+ value = param.defaultValue;
+ }
+
+ if (param.type === 'number') {
+ value = parseInt(value);
+ }
+
+ result.args[param.name] = value;
+ });
+ }
+ data.buffer = "";
+ }
+
+ // Handle the 'then' property.
+ if (binding.then) {
+ data.state = binding.then;
+ data.buffer = "";
+ }
+
+ // If no command is set, then execute the "null" fake command.
+ if (result.command == null) {
+ result.command = "null";
+ }
+
+ if (DEBUG) {
+ console.log("KeyboardStateMapper#find", binding);
+ }
+ return true;
+ });
+
+ if (result.command) {
+ return result;
+ } else {
+ data.buffer = "";
+ return false;
+ }
+ },
+
+ /**
+ * This function is called by keyBinding.
+ */
+ handleKeyboard: function(data, hashId, key, keyCode, e) {
+ // If we pressed any command key but no other key, then ignore the input.
+ // Otherwise "shift-" is added to the buffer, and later on "shift-g"
+ // which results in "shift-shift-g" which doesn't make sense.
+ if (hashId != 0 && (key == "" || key == String.fromCharCode(0))) {
+ return null;
+ }
+
+ // Compute the current value of the keyboard input buffer.
+ var r = this.$composeBuffer(data, hashId, key, e);
+ var buffer = r.bufferToUse;
+ var symbolicName = r.symbolicName;
+ var keyId = r.keyIdentifier;
+
+ r = this.$find(data, buffer, symbolicName, hashId, key, keyId);
+ if (DEBUG) {
+ console.log("KeyboardStateMapper#match", buffer, symbolicName, r);
+ }
+
+ return r;
+ }
+}
+
+/**
+ * This is a useful matching function and therefore is defined here so that
+ * users of KeyboardStateMapper can use it.
+ *
+ * @return boolean
+ * If no command key (Command|Option|Shift|Ctrl) is pressed, it
+ * returns true. If the only the Shift key is pressed + a character
+ * true is returned as well. Otherwise, false is returned.
+ * Summing up, the function returns true whenever the user typed
+ * a normal character on the keyboard and no shortcut.
+ */
+exports.matchCharacterOnly = function(buffer, hashId, key, symbolicName) {
+ // If no command keys are pressed, then catch the input.
+ if (hashId == 0) {
+ return true;
+ }
+ // If only the shift key is pressed and a character key, then
+ // catch that input as well.
+ else if ((hashId == 4) && key.length == 1) {
+ return true;
+ }
+ // Otherwise, we let the input got through.
+ else {
+ return false;
+ }
+};
+
+exports.StateHandler = StateHandler;
+});
+/* ***** 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):
+ * Zef Hemel <zef@c9.io>
+ *
+ * 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('ace/placeholder', ['require', 'exports', 'module' , 'ace/range', 'ace/lib/event_emitter', 'ace/lib/oop'], function(require, exports, module) {
+"use strict";
+
+var Range = require('./range').Range;
+var EventEmitter = require("./lib/event_emitter").EventEmitter;
+var oop = require("./lib/oop");
+
+var PlaceHolder = function(session, length, pos, others, mainClass, othersClass) {
+ var _self = this;
+ this.length = length;
+ this.session = session;
+ this.doc = session.getDocument();
+ this.mainClass = mainClass;
+ this.othersClass = othersClass;
+ this.$onUpdate = this.onUpdate.bind(this);
+ this.doc.on("change", this.$onUpdate);
+ this.$others = others;
+
+ this.$onCursorChange = function() {
+ setTimeout(function() {
+ _self.onCursorChange();
+ });
+ };
+
+ this.$pos = pos;
+ // Used for reset
+ var undoStack = session.getUndoManager().$undoStack || session.getUndoManager().$undostack || {length: -1};
+ this.$undoStackDepth = undoStack.length;
+ this.setup();
+
+ session.selection.on("changeCursor", this.$onCursorChange);
+};
+
+(function() {
+
+ oop.implement(this, EventEmitter);
+
+ this.setup = function() {
+ var _self = this;
+ var doc = this.doc;
+ var session = this.session;
+ var pos = this.$pos;
+
+ this.pos = doc.createAnchor(pos.row, pos.column);
+ this.markerId = session.addMarker(new Range(pos.row, pos.column, pos.row, pos.column + this.length), this.mainClass, null, false);
+ this.pos.on("change", function(event) {
+ session.removeMarker(_self.markerId);
+ _self.markerId = session.addMarker(new Range(event.value.row, event.value.column, event.value.row, event.value.column+_self.length), _self.mainClass, null, false);
+ });
+ this.others = [];
+ this.$others.forEach(function(other) {
+ var anchor = doc.createAnchor(other.row, other.column);
+ _self.others.push(anchor);
+ });
+ session.setUndoSelect(false);
+ };
+
+ this.showOtherMarkers = function() {
+ if(this.othersActive) return;
+ var session = this.session;
+ var _self = this;
+ this.othersActive = true;
+ this.others.forEach(function(anchor) {
+ anchor.markerId = session.addMarker(new Range(anchor.row, anchor.column, anchor.row, anchor.column+_self.length), _self.othersClass, null, false);
+ anchor.on("change", function(event) {
+ session.removeMarker(anchor.markerId);
+ anchor.markerId = session.addMarker(new Range(event.value.row, event.value.column, event.value.row, event.value.column+_self.length), _self.othersClass, null, false);
+ });
+ });
+ };
+
+ this.hideOtherMarkers = function() {
+ if(!this.othersActive) return;
+ this.othersActive = false;
+ for (var i = 0; i < this.others.length; i++) {
+ this.session.removeMarker(this.others[i].markerId);
+ }
+ };
+
+ this.onUpdate = function(event) {
+ var delta = event.data;
+ var range = delta.range;
+ if(range.start.row !== range.end.row) return;
+ if(range.start.row !== this.pos.row) return;
+ if (this.$updating) return;
+ this.$updating = true;
+ var lengthDiff = delta.action === "insertText" ? range.end.column - range.start.column : range.start.column - range.end.column;
+
+ if(range.start.column >= this.pos.column && range.start.column <= this.pos.column + this.length + 1) {
+ var distanceFromStart = range.start.column - this.pos.column;
+ this.length += lengthDiff;
+ if(!this.session.$fromUndo) {
+ if(delta.action === "insertText") {
+ for (var i = this.others.length - 1; i >= 0; i--) {
+ var otherPos = this.others[i];
+ var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};
+ if(otherPos.row === range.start.row && range.start.column < otherPos.column)
+ newPos.column += lengthDiff;
+ this.doc.insert(newPos, delta.text);
+ }
+ } else if(delta.action === "removeText") {
+ for (var i = this.others.length - 1; i >= 0; i--) {
+ var otherPos = this.others[i];
+ var newPos = {row: otherPos.row, column: otherPos.column + distanceFromStart};
+ if(otherPos.row === range.start.row && range.start.column < otherPos.column)
+ newPos.column += lengthDiff;
+ this.doc.remove(new Range(newPos.row, newPos.column, newPos.row, newPos.column - lengthDiff));
+ }
+ }
+ // Special case: insert in beginning
+ if(range.start.column === this.pos.column && delta.action === "insertText") {
+ setTimeout(function() {
+ this.pos.setPosition(this.pos.row, this.pos.column - lengthDiff);
+ for (var i = 0; i < this.others.length; i++) {
+ var other = this.others[i];
+ var newPos = {row: other.row, column: other.column - lengthDiff};
+ if(other.row === range.start.row && range.start.column < other.column)
+ newPos.column += lengthDiff;
+ other.setPosition(newPos.row, newPos.column);
+ }
+ }.bind(this), 0);
+ }
+ else if(range.start.column === this.pos.column && delta.action === "removeText") {
+ setTimeout(function() {
+ for (var i = 0; i < this.others.length; i++) {
+ var other = this.others[i];
+ if(other.row === range.start.row && range.start.column < other.column) {
+ other.setPosition(other.row, other.column - lengthDiff);
+ }
+ }
+ }.bind(this), 0);
+ }
+ }
+ this.pos._emit("change", {value: this.pos});
+ for (var i = 0; i < this.others.length; i++) {
+ this.others[i]._emit("change", {value: this.others[i]});
+ }
+ }
+ this.$updating = false;
+ };
+
+ this.onCursorChange = function(event) {
+ if (this.$updating) return;
+ var pos = this.session.selection.getCursor();
+ if(pos.row === this.pos.row && pos.column >= this.pos.column && pos.column <= this.pos.column + this.length) {
+ this.showOtherMarkers();
+ this._emit("cursorEnter", event);
+ } else {
+ this.hideOtherMarkers();
+ this._emit("cursorLeave", event);
+ }
+ };
+
+ this.detach = function() {
+ this.session.removeMarker(this.markerId);
+ this.hideOtherMarkers();
+ this.doc.removeEventListener("change", this.$onUpdate);
+ this.session.selection.removeEventListener("changeCursor", this.$onCursorChange);
+ this.pos.detach();
+ for (var i = 0; i < this.others.length; i++) {
+ this.others[i].detach();
+ }
+ this.session.setUndoSelect(true);
+ };
+
+ this.cancel = function() {
+ if(this.$undoStackDepth === -1)
+ throw Error("Canceling placeholders only supported with undo manager attached to session.");
+ var undoManager = this.session.getUndoManager();
+ var undosRequired = (undoManager.$undoStack || undoManager.$undostack).length - this.$undoStackDepth;
+ for (var i = 0; i < undosRequired; i++) {
+ undoManager.undo(true);
+ }
+ };
+}).call(PlaceHolder.prototype);
+
+
+exports.PlaceHolder = PlaceHolder;
+});
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@@ -14055,7 +16460,7 @@ exports.cssText = ".ace-tm .ace_editor {\
}\
\
.ace-tm .ace_fold {\
- background-color: #0000A2;\
+ background-color: #6B72E6;\
}\
\
.ace-tm .ace_text-layer {\
@@ -14063,7 +16468,7 @@ exports.cssText = ".ace-tm .ace_editor {\
}\
\
.ace-tm .ace_cursor {\
- border-left: 2px solid black;\
+ border-left: 1px solid black;\
}\
\
.ace-tm .ace_cursor.ace_overwrite {\
@@ -14075,10 +16480,15 @@ exports.cssText = ".ace-tm .ace_editor {\
color: rgb(191, 191, 191);\
}\
\
+.ace-tm .ace_line .ace_storage,\
.ace-tm .ace_line .ace_keyword {\
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);\
}\