You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ga...@apache.org on 2013/10/29 16:40:35 UTC
[50/51] [partial] working replacement
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9abd128c/src/fauxton/assets/js/libs/ace/autocomplete.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/ace/autocomplete.js b/src/fauxton/assets/js/libs/ace/autocomplete.js
new file mode 100644
index 0000000..5b9312f
--- /dev/null
+++ b/src/fauxton/assets/js/libs/ace/autocomplete.js
@@ -0,0 +1,350 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
+ *
+ * Copyright (c) 2012, Ajax.org B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Ajax.org B.V. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+"use strict";
+
+var HashHandler = require("./keyboard/hash_handler").HashHandler;
+var AcePopup = require("./autocomplete/popup").AcePopup;
+var util = require("./autocomplete/util");
+var event = require("./lib/event");
+var lang = require("./lib/lang");
+var snippetManager = require("./snippets").snippetManager;
+
+var Autocomplete = function() {
+ this.keyboardHandler = new HashHandler();
+ this.keyboardHandler.bindKeys(this.commands);
+
+ this.blurListener = this.blurListener.bind(this);
+ this.changeListener = this.changeListener.bind(this);
+ this.mousedownListener = this.mousedownListener.bind(this);
+ this.mousewheelListener = this.mousewheelListener.bind(this);
+
+ this.changeTimer = lang.delayedCall(function() {
+ this.updateCompletions(true);
+ }.bind(this))
+};
+
+(function() {
+ this.$init = function() {
+ this.popup = new AcePopup(document.body || document.documentElement);
+ this.popup.on("click", function(e) {
+ this.insertMatch();
+ e.stop();
+ }.bind(this));
+ };
+
+ this.openPopup = function(editor, prefix, keepPopupPosition) {
+ if (!this.popup)
+ this.$init();
+
+ this.popup.setData(this.completions.filtered);
+
+ var renderer = editor.renderer;
+ if (!keepPopupPosition) {
+ this.popup.setFontSize(editor.getFontSize());
+
+ var lineHeight = renderer.layerConfig.lineHeight;
+
+ var pos = renderer.$cursorLayer.getPixelPosition(this.base, true);
+ pos.left -= this.popup.getTextLeftOffset();
+
+ var rect = editor.container.getBoundingClientRect();
+ pos.top += rect.top - renderer.layerConfig.offset;
+ pos.left += rect.left;
+ pos.left += renderer.$gutterLayer.gutterWidth;
+
+ this.popup.show(pos, lineHeight);
+ }
+ };
+
+ this.detach = function() {
+ this.editor.keyBinding.removeKeyboardHandler(this.keyboardHandler);
+ this.editor.off("changeSelection", this.changeListener);
+ this.editor.off("blur", this.changeListener);
+ this.editor.off("mousedown", this.mousedownListener);
+ this.editor.off("mousewheel", this.mousewheelListener);
+ this.changeTimer.cancel();
+
+ if (this.popup)
+ this.popup.hide();
+
+ this.activated = false;
+ this.completions = this.base = null;
+ };
+
+ this.changeListener = function(e) {
+ var cursor = this.editor.selection.lead;
+ if (cursor.row != this.base.row || cursor.column < this.base.column) {
+ this.detach();
+ }
+ if (this.activated)
+ this.changeTimer.schedule();
+ else
+ this.detach();
+ };
+
+ this.blurListener = function() {
+ if (document.activeElement != this.editor.textInput.getElement())
+ this.detach();
+ };
+
+ this.mousedownListener = function(e) {
+ this.detach();
+ };
+
+ this.mousewheelListener = function(e) {
+ this.detach();
+ };
+
+ this.goTo = function(where) {
+ var row = this.popup.getRow();
+ var max = this.popup.session.getLength() - 1;
+
+ switch(where) {
+ case "up": row = row < 0 ? max : row - 1; break;
+ case "down": row = row >= max ? -1 : row + 1; break;
+ case "start": row = 0; break;
+ case "end": row = max; break;
+ }
+
+ this.popup.setRow(row);
+ };
+
+ this.insertMatch = function(data) {
+ if (!data)
+ data = this.popup.getData(this.popup.getRow());
+ if (!data)
+ return false;
+ if (data.completer && data.completer.insertMatch) {
+ data.completer.insertMatch(this.editor);
+ } else {
+ if (this.completions.filterText) {
+ var ranges = this.editor.selection.getAllRanges();
+ for (var i = 0, range; range = ranges[i]; i++) {
+ range.start.column -= this.completions.filterText.length;
+ this.editor.session.remove(range);
+ }
+ }
+ if (data.snippet)
+ snippetManager.insertSnippet(this.editor, data.snippet);
+ else
+ this.editor.execCommand("insertstring", data.value || data);
+ }
+ this.detach();
+ };
+
+ this.commands = {
+ "Up": function(editor) { editor.completer.goTo("up"); },
+ "Down": function(editor) { editor.completer.goTo("down"); },
+ "Ctrl-Up|Ctrl-Home": function(editor) { editor.completer.goTo("start"); },
+ "Ctrl-Down|Ctrl-End": function(editor) { editor.completer.goTo("end"); },
+
+ "Esc": function(editor) { editor.completer.detach(); },
+ "Space": function(editor) { editor.completer.detach(); editor.insert(" ");},
+ "Return": function(editor) { editor.completer.insertMatch(); },
+ "Shift-Return": function(editor) { editor.completer.insertMatch(true); },
+ "Tab": function(editor) { editor.completer.insertMatch(); },
+
+ "PageUp": function(editor) { editor.completer.popup.gotoPageUp(); },
+ "PageDown": function(editor) { editor.completer.popup.gotoPageDown(); }
+ };
+
+ this.gatherCompletions = function(editor, callback) {
+ var session = editor.getSession();
+ var pos = editor.getCursorPosition();
+
+ var line = session.getLine(pos.row);
+ var prefix = util.retrievePrecedingIdentifier(line, pos.column);
+
+ this.base = editor.getCursorPosition();
+ this.base.column -= prefix.length;
+
+ var matches = [];
+ util.parForEach(editor.completers, function(completer, next) {
+ completer.getCompletions(editor, session, pos, prefix, function(err, results) {
+ if (!err)
+ matches = matches.concat(results);
+ next();
+ });
+ }, function() {
+ callback(null, {
+ prefix: prefix,
+ matches: matches
+ });
+ });
+ return true;
+ };
+
+ this.showPopup = function(editor) {
+ if (this.editor)
+ this.detach();
+
+ this.activated = true;
+
+ this.editor = editor;
+ if (editor.completer != this) {
+ if (editor.completer)
+ editor.completer.detach();
+ editor.completer = this;
+ }
+
+ editor.keyBinding.addKeyboardHandler(this.keyboardHandler);
+ editor.on("changeSelection", this.changeListener);
+ editor.on("blur", this.blurListener);
+ editor.on("mousedown", this.mousedownListener);
+ editor.on("mousewheel", this.mousewheelListener);
+
+ this.updateCompletions();
+ };
+
+ this.updateCompletions = function(keepPopupPosition) {
+ if (keepPopupPosition && this.base && this.completions) {
+ var pos = this.editor.getCursorPosition();
+ var prefix = this.editor.session.getTextRange({start: this.base, end: pos});
+ if (prefix == this.completions.filterText)
+ return;
+ this.completions.setFilter(prefix);
+ if (!this.completions.filtered.length)
+ return this.detach();
+ this.openPopup(this.editor, prefix, keepPopupPosition);
+ return;
+ }
+ this.gatherCompletions(this.editor, function(err, results) {
+ var matches = results && results.matches;
+ if (!matches || !matches.length)
+ return this.detach();
+ // TODO reenable this when we have proper change tracking
+ // if (matches.length == 1)
+ // return this.insertMatch(matches[0]);
+
+ this.completions = new FilteredList(matches);
+ this.completions.setFilter(results.prefix);
+ if (!this.completions.filtered.length)
+ return this.detach();
+ this.openPopup(this.editor, results.prefix, keepPopupPosition);
+ }.bind(this));
+ };
+
+ this.cancelContextMenu = function() {
+ var stop = function(e) {
+ this.editor.off("nativecontextmenu", stop);
+ if (e && e.domEvent)
+ event.stopEvent(e.domEvent);
+ }.bind(this);
+ setTimeout(stop, 10);
+ this.editor.on("nativecontextmenu", stop);
+ };
+
+}).call(Autocomplete.prototype);
+
+Autocomplete.startCommand = {
+ name: "startAutocomplete",
+ exec: function(editor) {
+ if (!editor.completer)
+ editor.completer = new Autocomplete();
+ editor.completer.showPopup(editor);
+ // needed for firefox on mac
+ editor.completer.cancelContextMenu();
+ },
+ bindKey: "Ctrl-Space|Ctrl-Shift-Space|Alt-Space"
+};
+
+var FilteredList = function(array, filterText, mutateData) {
+ this.all = array;
+ this.filtered = array;
+ this.filterText = filterText || "";
+};
+(function(){
+ this.setFilter = function(str) {
+ if (str.length > this.filterText && str.lastIndexOf(this.filterText, 0) === 0)
+ var matches = this.filtered;
+ else
+ var matches = this.all;
+
+ this.filterText = str;
+ matches = this.filterCompletions(matches, this.filterText);
+ matches = matches.sort(function(a, b) {
+ return b.exactMatch - a.exactMatch || b.score - a.score;
+ });
+
+ // make unique
+ var prev = null;
+ matches = matches.filter(function(item){
+ var caption = item.value || item.caption || item.snippet;
+ if (caption === prev) return false;
+ prev = caption;
+ return true;
+ });
+
+ this.filtered = matches;
+ };
+ this.filterCompletions = function(items, needle) {
+ var results = [];
+ var upper = needle.toUpperCase();
+ var lower = needle.toLowerCase();
+ loop: for (var i = 0, item; item = items[i]; i++) {
+ var caption = item.value || item.caption || item.snippet;
+ if (!caption) continue;
+ var lastIndex = -1;
+ var matchMask = 0;
+ var penalty = 0;
+ var index, distance;
+ // caption char iteration is faster in Chrome but slower in Firefox, so lets use indexOf
+ for (var j = 0; j < needle.length; j++) {
+ // TODO add penalty on case mismatch
+ var i1 = caption.indexOf(lower[j], lastIndex + 1);
+ var i2 = caption.indexOf(upper[j], lastIndex + 1);
+ index = (i1 >= 0) ? ((i2 < 0 || i1 < i2) ? i1 : i2) : i2;
+ if (index < 0)
+ continue loop;
+ distance = index - lastIndex - 1;
+ if (distance > 0) {
+ // first char mismatch should be more sensitive
+ if (lastIndex === -1)
+ penalty += 10;
+ penalty += distance;
+ }
+ matchMask = matchMask | (1 << index);
+ lastIndex = index;
+ }
+ item.matchMask = matchMask;
+ item.exactMatch = penalty ? 0 : 1;
+ item.score = (item.score || 0) - penalty;
+ results.push(item);
+ }
+ return results;
+ };
+}).call(FilteredList.prototype);
+
+exports.Autocomplete = Autocomplete;
+exports.FilteredList = FilteredList;
+
+});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9abd128c/src/fauxton/assets/js/libs/ace/autocomplete/popup.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/ace/autocomplete/popup.js b/src/fauxton/assets/js/libs/ace/autocomplete/popup.js
new file mode 100644
index 0000000..891cf1e
--- /dev/null
+++ b/src/fauxton/assets/js/libs/ace/autocomplete/popup.js
@@ -0,0 +1,316 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
+ *
+ * Copyright (c) 2012, Ajax.org B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Ajax.org B.V. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+"use strict";
+
+var EditSession = require("../edit_session").EditSession;
+var Renderer = require("../virtual_renderer").VirtualRenderer;
+var Editor = require("../editor").Editor;
+var Range = require("../range").Range;
+var event = require("../lib/event");
+var lang = require("../lib/lang");
+var dom = require("../lib/dom");
+
+var $singleLineEditor = function(el) {
+ var renderer = new Renderer(el);
+
+ renderer.$maxLines = 4;
+
+ var editor = new Editor(renderer);
+
+ editor.setHighlightActiveLine(false);
+ editor.setShowPrintMargin(false);
+ editor.renderer.setShowGutter(false);
+ editor.renderer.setHighlightGutterLine(false);
+
+ editor.$mouseHandler.$focusWaitTimout = 0;
+
+ return editor;
+};
+
+var AcePopup = function(parentNode) {
+ var el = dom.createElement("div");
+ var popup = new $singleLineEditor(el);
+
+ if (parentNode)
+ parentNode.appendChild(el);
+ el.style.display = "none";
+ popup.renderer.content.style.cursor = "default";
+ popup.renderer.setStyle("ace_autocomplete");
+
+ popup.setOption("displayIndentGuides", false);
+
+ var noop = function(){};
+
+ popup.focus = noop;
+ popup.$isFocused = true;
+
+ popup.renderer.$cursorLayer.restartTimer = noop;
+ popup.renderer.$cursorLayer.element.style.opacity = 0;
+
+ popup.renderer.$maxLines = 8;
+ popup.renderer.$keepTextAreaAtCursor = false;
+
+ popup.setHighlightActiveLine(false);
+ // set default highlight color
+ popup.session.highlight("");
+ popup.session.$searchHighlight.clazz = "ace_highlight-marker";
+
+ popup.on("mousedown", function(e) {
+ var pos = e.getDocumentPosition();
+ popup.moveCursorToPosition(pos);
+ popup.selection.clearSelection();
+ selectionMarker.start.row = selectionMarker.end.row = pos.row;
+ e.stop();
+ });
+
+ var lastMouseEvent;
+ var hoverMarker = new Range(-1,0,-1,Infinity);
+ var selectionMarker = new Range(-1,0,-1,Infinity);
+ selectionMarker.id = popup.session.addMarker(selectionMarker, "ace_active-line", "fullLine");
+ popup.setSelectOnHover = function(val) {
+ if (!val) {
+ hoverMarker.id = popup.session.addMarker(hoverMarker, "ace_line-hover", "fullLine");
+ } else if (hoverMarker.id) {
+ popup.session.removeMarker(hoverMarker.id);
+ hoverMarker.id = null;
+ }
+ }
+ popup.setSelectOnHover(false);
+ popup.on("mousemove", function(e) {
+ if (!lastMouseEvent) {
+ lastMouseEvent = e;
+ return;
+ }
+ if (lastMouseEvent.x == e.x && lastMouseEvent.y == e.y) {
+ return;
+ }
+ lastMouseEvent = e;
+ lastMouseEvent.scrollTop = popup.renderer.scrollTop;
+ var row = lastMouseEvent.getDocumentPosition().row;
+ if (hoverMarker.start.row != row) {
+ if (!hoverMarker.id)
+ popup.setRow(row);
+ setHoverMarker(row);
+ }
+ });
+ popup.renderer.on("beforeRender", function() {
+ if (lastMouseEvent && hoverMarker.start.row != -1) {
+ lastMouseEvent.$pos = null;
+ var row = lastMouseEvent.getDocumentPosition().row;
+ if (!hoverMarker.id)
+ popup.setRow(row);
+ setHoverMarker(row, true);
+ }
+ });
+ popup.renderer.on("afterRender", function() {
+ var row = popup.getRow();
+ var t = popup.renderer.$textLayer;
+ var selected = t.element.childNodes[row - t.config.firstRow];
+ if (selected == t.selectedNode)
+ return;
+ if (t.selectedNode)
+ dom.removeCssClass(t.selectedNode, "ace_selected");
+ t.selectedNode = selected;
+ if (selected)
+ dom.addCssClass(selected, "ace_selected");
+ });
+ var hideHoverMarker = function() { setHoverMarker(-1) };
+ var setHoverMarker = function(row, suppressRedraw) {
+ if (row !== hoverMarker.start.row) {
+ hoverMarker.start.row = hoverMarker.end.row = row;
+ if (!suppressRedraw)
+ popup.session._emit("changeBackMarker");
+ popup._emit("changeHoverMarker");
+ }
+ };
+ popup.getHoveredRow = function() {
+ return hoverMarker.start.row;
+ };
+
+ event.addListener(popup.container, "mouseout", hideHoverMarker);
+ popup.on("hide", hideHoverMarker);
+ popup.on("changeSelection", hideHoverMarker);
+
+ popup.session.doc.getLength = function() {
+ return popup.data.length;
+ };
+ popup.session.doc.getLine = function(i) {
+ var data = popup.data[i];
+ if (typeof data == "string")
+ return data;
+ return (data && data.value) || "";
+ };
+
+ var bgTokenizer = popup.session.bgTokenizer;
+ bgTokenizer.$tokenizeRow = function(i) {
+ var data = popup.data[i];
+ var tokens = [];
+ if (!data)
+ return tokens;
+ if (typeof data == "string")
+ data = {value: data};
+ if (!data.caption)
+ data.caption = data.value;
+
+ var last = -1;
+ var flag, c;
+ for (var i = 0; i < data.caption.length; i++) {
+ c = data.caption[i];
+ flag = data.matchMask & (1 << i) ? 1 : 0;
+ if (last !== flag) {
+ tokens.push({type: data.className || "" + ( flag ? "completion-highlight" : ""), value: c});
+ last = flag;
+ } else {
+ tokens[tokens.length - 1].value += c;
+ }
+ }
+
+ if (data.meta) {
+ var maxW = popup.renderer.$size.scrollerWidth / popup.renderer.layerConfig.characterWidth;
+ if (data.meta.length + data.caption.length < maxW - 2)
+ tokens.push({type: "rightAlignedText", value: data.meta});
+ }
+ return tokens;
+ };
+ bgTokenizer.$updateOnChange = noop;
+ bgTokenizer.start = noop;
+
+ popup.session.$computeWidth = function() {
+ return this.screenWidth = 0;
+ }
+
+ // public
+ popup.data = [];
+ popup.setData = function(list) {
+ popup.data = list || [];
+ popup.setValue(lang.stringRepeat("\n", list.length), -1);
+ popup.setRow(0);
+ };
+ popup.getData = function(row) {
+ return popup.data[row];
+ };
+
+ popup.getRow = function() {
+ return selectionMarker.start.row;
+ };
+ popup.setRow = function(line) {
+ line = Math.max(-1, Math.min(this.data.length, line));
+ if (selectionMarker.start.row != line) {
+ popup.selection.clearSelection();
+ selectionMarker.start.row = selectionMarker.end.row = line || 0;
+ popup.session._emit("changeBackMarker");
+ popup.moveCursorTo(line || 0, 0);
+ if (popup.isOpen)
+ popup._signal("select");
+ }
+ };
+
+ popup.hide = function() {
+ this.container.style.display = "none";
+ this._signal("hide");
+ popup.isOpen = false;
+ };
+ popup.show = function(pos, lineHeight) {
+ var el = this.container;
+ var screenHeight = window.innerHeight;
+ var renderer = this.renderer;
+ // var maxLines = Math.min(renderer.$maxLines, this.session.getLength());
+ var maxH = renderer.$maxLines * lineHeight * 1.4;
+ var top = pos.top + this.$borderSize;
+ if (top + maxH > screenHeight - lineHeight) {
+ el.style.top = "";
+ el.style.bottom = screenHeight - top + "px";
+ } else {
+ top += lineHeight;
+ el.style.top = top + "px";
+ el.style.bottom = "";
+ }
+
+ el.style.left = pos.left + "px";
+ el.style.display = "";
+ this.renderer.$textLayer.checkForSizeChanges();
+
+ this._signal("show");
+ lastMouseEvent = null;
+ popup.isOpen = true;
+ };
+
+ popup.getTextLeftOffset = function() {
+ return this.$borderSize + this.renderer.$padding + this.$imageSize;
+ };
+
+ popup.$imageSize = 0;
+ popup.$borderSize = 1;
+
+ return popup;
+};
+
+dom.importCssString("\
+.ace_autocomplete.ace-tm .ace_marker-layer .ace_active-line {\
+ background-color: #CAD6FA;\
+ z-index: 1;\
+}\
+.ace_autocomplete.ace-tm .ace_line-hover {\
+ border: 1px solid #abbffe;\
+ margin-top: -1px;\
+ background: rgba(233,233,253,0.4);\
+}\
+.ace_autocomplete .ace_line-hover {\
+ position: absolute;\
+ z-index: 2;\
+}\
+.ace_rightAlignedText {\
+ color: gray;\
+ display: inline-block;\
+ position: absolute;\
+ right: 4px;\
+ text-align: right;\
+ z-index: -1;\
+}\
+.ace_autocomplete .ace_completion-highlight{\
+ color: #000;\
+ text-shadow: 0 0 0.01em;\
+}\
+.ace_autocomplete {\
+ width: 280px;\
+ z-index: 200000;\
+ background: #fbfbfb;\
+ color: #444;\
+ border: 1px lightgray solid;\
+ position: fixed;\
+ box-shadow: 2px 3px 5px rgba(0,0,0,.2);\
+ line-height: 1.4;\
+}");
+
+exports.AcePopup = AcePopup;
+
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9abd128c/src/fauxton/assets/js/libs/ace/autocomplete/text_completer.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/ace/autocomplete/text_completer.js b/src/fauxton/assets/js/libs/ace/autocomplete/text_completer.js
new file mode 100644
index 0000000..87a25fb
--- /dev/null
+++ b/src/fauxton/assets/js/libs/ace/autocomplete/text_completer.js
@@ -0,0 +1,78 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
+ *
+ * Copyright (c) 2012, Ajax.org B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Ajax.org B.V. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+ var Range = require("ace/range").Range;
+
+ var splitRegex = /[^a-zA-Z_0-9\$\-]+/;
+
+ function getWordIndex(doc, pos) {
+ var textBefore = doc.getTextRange(Range.fromPoints({row: 0, column:0}, pos));
+ return textBefore.split(splitRegex).length - 1;
+ }
+
+ /**
+ * Does a distance analysis of the word `prefix` at position `pos` in `doc`.
+ * @return Map
+ */
+ function wordDistance(doc, pos) {
+ var prefixPos = getWordIndex(doc, pos);
+ var words = doc.getValue().split(splitRegex);
+ var wordScores = Object.create(null);
+
+ var currentWord = words[prefixPos];
+
+ words.forEach(function(word, idx) {
+ if (!word || word === currentWord) return;
+
+ var distance = Math.abs(prefixPos - idx);
+ var score = words.length - distance;
+ if (wordScores[word]) {
+ wordScores[word] = Math.max(score, wordScores[word]);
+ } else {
+ wordScores[word] = score;
+ }
+ });
+ return wordScores;
+ }
+
+ exports.getCompletions = function(editor, session, pos, prefix, callback) {
+ var wordScore = wordDistance(session, pos, prefix);
+ var wordList = Object.keys(wordScore);
+ callback(null, wordList.map(function(word) {
+ return {
+ name: word,
+ value: word,
+ score: wordScore[word],
+ meta: "local"
+ };
+ }));
+ };
+});
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9abd128c/src/fauxton/assets/js/libs/ace/autocomplete/util.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/ace/autocomplete/util.js b/src/fauxton/assets/js/libs/ace/autocomplete/util.js
new file mode 100644
index 0000000..8b7c115
--- /dev/null
+++ b/src/fauxton/assets/js/libs/ace/autocomplete/util.js
@@ -0,0 +1,74 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
+ *
+ * Copyright (c) 2012, Ajax.org B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Ajax.org B.V. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+"use strict";
+
+exports.parForEach = function(array, fn, callback) {
+ var completed = 0;
+ var arLength = array.length;
+ if (arLength === 0)
+ callback();
+ for (var i = 0; i < arLength; i++) {
+ fn(array[i], function(result, err) {
+ completed++;
+ if (completed === arLength)
+ callback(result, err);
+ });
+ }
+}
+
+var ID_REGEX = /[a-zA-Z_0-9\$-]/;
+
+exports.retrievePrecedingIdentifier = function(text, pos, regex) {
+ regex = regex || ID_REGEX;
+ var buf = [];
+ for (var i = pos-1; i >= 0; i--) {
+ if (regex.test(text[i]))
+ buf.push(text[i]);
+ else
+ break;
+ }
+ return buf.reverse().join("");
+}
+
+exports.retrieveFollowingIdentifier = function(text, pos, regex) {
+ regex = regex || ID_REGEX;
+ var buf = [];
+ for (var i = pos; i < text.length; i++) {
+ if (regex.test(text[i]))
+ buf.push(text[i]);
+ else
+ break;
+ }
+ return buf;
+}
+
+});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9abd128c/src/fauxton/assets/js/libs/ace/background_tokenizer.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/ace/background_tokenizer.js b/src/fauxton/assets/js/libs/ace/background_tokenizer.js
new file mode 100644
index 0000000..217be1b
--- /dev/null
+++ b/src/fauxton/assets/js/libs/ace/background_tokenizer.js
@@ -0,0 +1,255 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
+ *
+ * Copyright (c) 2010, Ajax.org B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Ajax.org B.V. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+"use strict";
+
+var oop = require("./lib/oop");
+var EventEmitter = require("./lib/event_emitter").EventEmitter;
+
+
+/**
+ *
+ *
+ * Tokenizes the current [[Document `Document`]] in the background, and caches the tokenized rows for future use.
+ *
+ * If a certain row is changed, everything below that row is re-tokenized.
+ *
+ * @class BackgroundTokenizer
+ **/
+
+/**
+ * Creates a new `BackgroundTokenizer` object.
+ * @param {Tokenizer} tokenizer The tokenizer to use
+ * @param {Editor} editor The editor to associate with
+ *
+ *
+ *
+ * @constructor
+ **/
+
+var BackgroundTokenizer = function(tokenizer, editor) {
+ this.running = false;
+ this.lines = [];
+ this.states = [];
+ this.currentLine = 0;
+ this.tokenizer = tokenizer;
+
+ var self = this;
+
+ this.$worker = function() {
+ if (!self.running) { return; }
+
+ var workerStart = new Date();
+ var currentLine = self.currentLine;
+ var endLine = -1;
+ var doc = self.doc;
+
+ while (self.lines[currentLine])
+ currentLine++;
+
+ var startLine = currentLine;
+
+ var len = doc.getLength();
+ var processedLines = 0;
+ self.running = false;
+ while (currentLine < len) {
+ self.$tokenizeRow(currentLine);
+ endLine = currentLine;
+ do {
+ currentLine++;
+ } while (self.lines[currentLine]);
+
+ // only check every 5 lines
+ processedLines ++;
+ if ((processedLines % 5 == 0) && (new Date() - workerStart) > 20) {
+ self.running = setTimeout(self.$worker, 20);
+ self.currentLine = currentLine;
+ return;
+ }
+ }
+ self.currentLine = currentLine;
+
+ if (startLine <= endLine)
+ self.fireUpdateEvent(startLine, endLine);
+ };
+};
+
+(function(){
+
+ oop.implement(this, EventEmitter);
+
+ /**
+ * Sets a new tokenizer for this object.
+ *
+ * @param {Tokenizer} tokenizer The new tokenizer to use
+ *
+ **/
+ this.setTokenizer = function(tokenizer) {
+ this.tokenizer = tokenizer;
+ this.lines = [];
+ this.states = [];
+
+ this.start(0);
+ };
+
+ /**
+ * Sets a new document to associate with this object.
+ * @param {Document} doc The new document to associate with
+ **/
+ this.setDocument = function(doc) {
+ this.doc = doc;
+ this.lines = [];
+ this.states = [];
+
+ this.stop();
+ };
+
+ /**
+ * Fires whenever the background tokeniziers between a range of rows are going to be updated.
+ *
+ * @event update
+ * @param {Object} e An object containing two properties, `first` and `last`, which indicate the rows of the region being updated.
+ *
+ **/
+ /**
+ * Emits the `'update'` event. `firstRow` and `lastRow` are used to define the boundaries of the region to be updated.
+ * @param {Number} firstRow The starting row region
+ * @param {Number} lastRow The final row region
+ *
+ **/
+ this.fireUpdateEvent = function(firstRow, lastRow) {
+ var data = {
+ first: firstRow,
+ last: lastRow
+ };
+ this._emit("update", {data: data});
+ };
+
+ /**
+ * Starts tokenizing at the row indicated.
+ *
+ * @param {Number} startRow The row to start at
+ *
+ **/
+ this.start = function(startRow) {
+ this.currentLine = Math.min(startRow || 0, this.currentLine, this.doc.getLength());
+
+ // remove all cached items below this line
+ this.lines.splice(this.currentLine, this.lines.length);
+ this.states.splice(this.currentLine, this.states.length);
+
+ this.stop();
+ // pretty long delay to prevent the tokenizer from interfering with the user
+ this.running = setTimeout(this.$worker, 700);
+ };
+
+ this.scheduleStart = function() {
+ if (!this.running)
+ this.running = setTimeout(this.$worker, 700);
+ }
+
+ this.$updateOnChange = function(delta) {
+ var range = delta.range;
+ var startRow = range.start.row;
+ var len = range.end.row - startRow;
+
+ if (len === 0) {
+ this.lines[startRow] = null;
+ } else if (delta.action == "removeText" || delta.action == "removeLines") {
+ this.lines.splice(startRow, len + 1, null);
+ this.states.splice(startRow, len + 1, null);
+ } else {
+ var args = Array(len + 1);
+ args.unshift(startRow, 1);
+ this.lines.splice.apply(this.lines, args);
+ this.states.splice.apply(this.states, args);
+ }
+
+ this.currentLine = Math.min(startRow, this.currentLine, this.doc.getLength());
+
+ this.stop();
+ };
+
+ /**
+ * Stops tokenizing.
+ *
+ **/
+ this.stop = function() {
+ if (this.running)
+ clearTimeout(this.running);
+ this.running = false;
+ };
+
+ /**
+ * Gives list of tokens of the row. (tokens are cached)
+ *
+ * @param {Number} row The row to get tokens at
+ *
+ *
+ *
+ **/
+ this.getTokens = function(row) {
+ return this.lines[row] || this.$tokenizeRow(row);
+ };
+
+ /**
+ * [Returns the state of tokenization at the end of a row.]{: #BackgroundTokenizer.getState}
+ *
+ * @param {Number} row The row to get state at
+ **/
+ this.getState = function(row) {
+ if (this.currentLine == row)
+ this.$tokenizeRow(row);
+ return this.states[row] || "start";
+ };
+
+ this.$tokenizeRow = function(row) {
+ var line = this.doc.getLine(row);
+ var state = this.states[row - 1];
+
+ var data = this.tokenizer.getLineTokens(line, state, row);
+
+ if (this.states[row] + "" !== data.state + "") {
+ this.states[row] = data.state;
+ this.lines[row + 1] = null;
+ if (this.currentLine > row + 1)
+ this.currentLine = row + 1;
+ } else if (this.currentLine == row) {
+ this.currentLine = row + 1;
+ }
+
+ return this.lines[row] = data.tokens;
+ };
+
+}).call(BackgroundTokenizer.prototype);
+
+exports.BackgroundTokenizer = BackgroundTokenizer;
+});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9abd128c/src/fauxton/assets/js/libs/ace/background_tokenizer_test.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/ace/background_tokenizer_test.js b/src/fauxton/assets/js/libs/ace/background_tokenizer_test.js
new file mode 100644
index 0000000..7a4cc78
--- /dev/null
+++ b/src/fauxton/assets/js/libs/ace/background_tokenizer_test.js
@@ -0,0 +1,85 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
+ *
+ * Copyright (c) 2010, Ajax.org B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Ajax.org B.V. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+if (typeof process !== "undefined") {
+ require("amd-loader");
+}
+
+define(function(require, exports, module) {
+"use strict";
+
+var EditSession = require("./edit_session").EditSession;
+var JavaScriptMode = require("./mode/javascript").Mode;
+var Range = require("./range").Range;
+var assert = require("./test/assertions");
+
+function forceTokenize(session){
+ for (var i = 0, l = session.getLength(); i < l; i++)
+ session.getTokens(i)
+}
+
+function testStates(session, states) {
+ for (var i = 0, l = session.getLength(); i < l; i++)
+ assert.equal(session.bgTokenizer.states[i], states[i])
+ assert.ok(l == states.length)
+}
+
+module.exports = {
+
+ "test background tokenizer update on session change" : function() {
+ var doc = new EditSession([
+ "/*",
+ "*/",
+ "var juhu"
+ ]);
+ doc.setMode("./mode/javascript")
+
+ forceTokenize(doc)
+ testStates(doc, ["comment_regex_allowed", "start", "no_regex"])
+
+ doc.remove(new Range(0,2,1,2))
+ testStates(doc, [null, "no_regex"])
+
+ forceTokenize(doc)
+ testStates(doc, ["comment_regex_allowed", "comment_regex_allowed"])
+
+ doc.insert({row:0, column:2}, "\n*/")
+ testStates(doc, [undefined, undefined, "comment_regex_allowed"])
+
+ forceTokenize(doc)
+ testStates(doc, ["comment_regex_allowed", "start", "no_regex"])
+ }
+};
+
+});
+
+if (typeof module !== "undefined" && module === require.main) {
+ require("asyncjs").test.testcase(module.exports).exec()
+}
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9abd128c/src/fauxton/assets/js/libs/ace/commands/command_manager.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/ace/commands/command_manager.js b/src/fauxton/assets/js/libs/ace/commands/command_manager.js
new file mode 100644
index 0000000..72a9942
--- /dev/null
+++ b/src/fauxton/assets/js/libs/ace/commands/command_manager.js
@@ -0,0 +1,112 @@
+define(function(require, exports, module) {
+"use strict";
+
+var oop = require("../lib/oop");
+var HashHandler = require("../keyboard/hash_handler").HashHandler;
+var EventEmitter = require("../lib/event_emitter").EventEmitter;
+
+/**
+ * @class CommandManager
+ *
+ *
+ **/
+
+/**
+ * new CommandManager(platform, commands)
+ * @param {String} platform Identifier for the platform; must be either `'mac'` or `'win'`
+ * @param {Array} commands A list of commands
+ *
+ **/
+
+var CommandManager = function(platform, commands) {
+ HashHandler.call(this, commands, platform);
+ this.byName = this.commands;
+ this.setDefaultHandler("exec", function(e) {
+ return 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;
+
+ var e = {editor: editor, command: command, args: args};
+ var retvalue = this._emit("exec", e);
+ this._signal("afterExec", e);
+
+ return retvalue === false ? false : true;
+ };
+
+ this.toggleRecording = function(editor) {
+ if (this.$inReplay)
+ return;
+
+ editor && editor._emit("changeStatus");
+ 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(editor);
+
+ 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;
+
+});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9abd128c/src/fauxton/assets/js/libs/ace/commands/command_manager_test.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/ace/commands/command_manager_test.js b/src/fauxton/assets/js/libs/ace/commands/command_manager_test.js
new file mode 100644
index 0000000..76d973b
--- /dev/null
+++ b/src/fauxton/assets/js/libs/ace/commands/command_manager_test.js
@@ -0,0 +1,199 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
+ *
+ * Copyright (c) 2010, Ajax.org B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Ajax.org B.V. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+if (typeof process !== "undefined") {
+ require("amd-loader");
+}
+
+define(function(require, exports, module) {
+"use strict";
+
+var CommandManager = require("./command_manager").CommandManager;
+var keys = require("../lib/keys");
+var assert = require("../test/assertions");
+
+module.exports = {
+
+ setUp: function() {
+ this.command = {
+ name: "gotoline",
+ bindKey: {
+ mac: "Command-L",
+ win: "Ctrl-L"
+ },
+ called: false,
+ exec: function(editor) { this.called = true; }
+ };
+
+ this.cm = new CommandManager("mac", [this.command]);
+ },
+
+ "test: register command": function() {
+ this.cm.exec("gotoline");
+ assert.ok(this.command.called);
+ },
+
+ "test: mac hotkeys": function() {
+ var command = this.cm.findKeyCommand(keys.KEY_MODS.command, "l");
+ assert.equal(command, this.command);
+
+ var command = this.cm.findKeyCommand(keys.KEY_MODS.ctrl, "l");
+ assert.equal(command, undefined);
+ },
+
+ "test: win hotkeys": function() {
+ var cm = new CommandManager("win", [this.command]);
+
+ var command = cm.findKeyCommand(keys.KEY_MODS.command, "l");
+ assert.equal(command, undefined);
+
+ var command = cm.findKeyCommand(keys.KEY_MODS.ctrl, "l");
+ assert.equal(command, this.command);
+ },
+
+ "test: remove command by object": function() {
+ this.cm.removeCommand(this.command);
+
+ this.cm.exec("gotoline");
+ assert.ok(!this.command.called);
+
+ var command = this.cm.findKeyCommand(keys.KEY_MODS.command, "l");
+ assert.equal(command, null);
+ },
+
+ "test: remove command by name": function() {
+ this.cm.removeCommand("gotoline");
+
+ this.cm.exec("gotoline");
+ assert.ok(!this.command.called);
+
+ var command = this.cm.findKeyCommand(keys.KEY_MODS.command, "l");
+ assert.equal(command, null);
+ },
+
+ "test: adding a new command with the same name as an existing one should remove the old one first": function() {
+ var command = {
+ name: "gotoline",
+ bindKey: {
+ mac: "Command-L",
+ win: "Ctrl-L"
+ },
+ called: false,
+ exec: function(editor) { this.called = true; }
+ };
+ this.cm.addCommand(command);
+
+ this.cm.exec("gotoline");
+ assert.ok(command.called);
+ assert.ok(!this.command.called);
+
+ assert.equal(this.cm.findKeyCommand(keys.KEY_MODS.command, "l"), command);
+ },
+
+ "test: adding commands and recording a macro": function() {
+ var called = "";
+ this.cm.addCommands({
+ togglerecording: function(editor) {
+ editor.cm.toggleRecording(editor);
+ },
+ replay: function(editor) {
+ editor.cm.replay();
+ },
+ cm1: function(editor, arg) {
+ called += "1" + (arg || "");
+ },
+ cm2: function(editor) {
+ called += "2";
+ }
+ });
+
+
+ var statusUpdateEmitted = false;
+ this._emit = function() {statusUpdateEmitted = true};
+
+ this.cm.exec("togglerecording", this);
+ assert.ok(this.cm.recording);
+ assert.ok(statusUpdateEmitted);
+
+ this.cm.exec("cm1", this, "-");
+ this.cm.exec("cm2");
+ this.cm.exec("replay", this);
+ assert.ok(!this.cm.recording);
+ assert.equal(called, "1-2");
+
+ called = "";
+ this.cm.exec("replay", this);
+ assert.equal(called, "1-2");
+ },
+
+ "test: bindkeys": function() {
+ this.cm.bindKeys({
+ "Ctrl-L|Command-C": "cm1",
+ "Ctrl-R": "cm2"
+ });
+
+ var command = this.cm.findKeyCommand(keys.KEY_MODS.command, "c");
+ assert.equal(command, "cm1");
+
+ var command = this.cm.findKeyCommand(keys.KEY_MODS.ctrl, "r");
+ assert.equal(command, "cm2");
+
+ this.cm.bindKeys({
+ "Ctrl-R": null
+ });
+
+ var command = this.cm.findKeyCommand(keys.KEY_MODS.ctrl, "r");
+ assert.equal(command, null);
+ },
+
+ "test: binding keys without modifiers": function() {
+ this.cm.bindKeys({
+ "R": "cm1",
+ "Shift-r": "cm2",
+ "Return": "cm4",
+ "Enter": "cm3"
+ });
+
+ var command = this.cm.findKeyCommand(-1, "r");
+ assert.equal(command, "cm1");
+
+ var command = this.cm.findKeyCommand(-1, "R");
+ assert.equal(command, "cm2");
+
+ var command = this.cm.findKeyCommand(0, "return");
+ assert.equal(command, "cm3");
+ }
+};
+
+});
+
+if (typeof module !== "undefined" && module === require.main) {
+ require("asyncjs").test.testcase(module.exports).exec();
+}
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9abd128c/src/fauxton/assets/js/libs/ace/commands/default_commands.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/ace/commands/default_commands.js b/src/fauxton/assets/js/libs/ace/commands/default_commands.js
new file mode 100644
index 0000000..9c663d1
--- /dev/null
+++ b/src/fauxton/assets/js/libs/ace/commands/default_commands.js
@@ -0,0 +1,490 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
+ *
+ * Copyright (c) 2010, Ajax.org B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Ajax.org B.V. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+"use strict";
+
+var lang = require("../lib/lang");
+var config = require("../config");
+
+function bindKey(win, mac) {
+ return {
+ win: win,
+ mac: mac
+ };
+}
+
+exports.commands = [{
+ name: "showSettingsMenu",
+ bindKey: bindKey("Ctrl-,", "Command-,"),
+ exec: function(editor) {
+ config.loadModule("ace/ext/settings_menu", function(module) {
+ module.init(editor);
+ editor.showSettingsMenu();
+ });
+ },
+ readOnly: true
+}, {
+ name: "selectall",
+ bindKey: bindKey("Ctrl-A", "Command-A"),
+ exec: function(editor) { editor.selectAll(); },
+ readOnly: true
+}, {
+ name: "centerselection",
+ bindKey: bindKey(null, "Ctrl-L"),
+ exec: function(editor) { editor.centerSelection(); },
+ readOnly: true
+}, {
+ name: "gotoline",
+ bindKey: bindKey("Ctrl-L", "Command-L"),
+ exec: function(editor) {
+ var line = parseInt(prompt("Enter line number:"), 10);
+ if (!isNaN(line)) {
+ editor.gotoLine(line);
+ }
+ },
+ readOnly: true
+}, {
+ name: "fold",
+ bindKey: bindKey("Alt-L|Ctrl-F1", "Command-Alt-L|Command-F1"),
+ exec: function(editor) { editor.session.toggleFold(false); },
+ readOnly: true
+}, {
+ name: "unfold",
+ bindKey: bindKey("Alt-Shift-L|Ctrl-Shift-F1", "Command-Alt-Shift-L|Command-Shift-F1"),
+ exec: function(editor) { editor.session.toggleFold(true); },
+ readOnly: true
+}, {
+ name: "foldall",
+ bindKey: bindKey("Alt-0", "Command-Option-0"),
+ exec: function(editor) { editor.session.foldAll(); },
+ readOnly: true
+}, {
+ name: "unfoldall",
+ bindKey: bindKey("Alt-Shift-0", "Command-Option-Shift-0"),
+ exec: function(editor) { editor.session.unfold(); },
+ readOnly: true
+}, {
+ name: "findnext",
+ bindKey: bindKey("Ctrl-K", "Command-G"),
+ exec: function(editor) { editor.findNext(); },
+ readOnly: true
+}, {
+ name: "findprevious",
+ bindKey: bindKey("Ctrl-Shift-K", "Command-Shift-G"),
+ exec: function(editor) { editor.findPrevious(); },
+ readOnly: true
+}, {
+ name: "find",
+ bindKey: bindKey("Ctrl-F", "Command-F"),
+ exec: function(editor) {
+ config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor)});
+ },
+ readOnly: true
+}, {
+ name: "overwrite",
+ bindKey: "Insert",
+ exec: function(editor) { editor.toggleOverwrite(); },
+ readOnly: true
+}, {
+ name: "selecttostart",
+ bindKey: bindKey("Ctrl-Shift-Home", "Command-Shift-Up"),
+ exec: function(editor) { editor.getSelection().selectFileStart(); },
+ multiSelectAction: "forEach",
+ readOnly: true,
+ group: "fileJump"
+}, {
+ name: "gotostart",
+ bindKey: bindKey("Ctrl-Home", "Command-Home|Command-Up"),
+ exec: function(editor) { editor.navigateFileStart(); },
+ multiSelectAction: "forEach",
+ readOnly: true,
+ group: "fileJump"
+}, {
+ 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", "Command-Shift-Down"),
+ exec: function(editor) { editor.getSelection().selectFileEnd(); },
+ multiSelectAction: "forEach",
+ readOnly: true,
+ group: "fileJump"
+}, {
+ name: "gotoend",
+ bindKey: bindKey("Ctrl-End", "Command-End|Command-Down"),
+ exec: function(editor) { editor.navigateFileEnd(); },
+ multiSelectAction: "forEach",
+ readOnly: true,
+ group: "fileJump"
+}, {
+ 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",
+ bindKey: "Shift-PageDown",
+ exec: function(editor) { editor.selectPageDown(); },
+ readOnly: true
+}, {
+ name: "pagedown",
+ bindKey: bindKey(null, "Option-PageDown"),
+ exec: function(editor) { editor.scrollPageDown(); },
+ readOnly: true
+}, {
+ name: "gotopagedown",
+ bindKey: bindKey("PageDown", "PageDown|Ctrl-V"),
+ exec: function(editor) { editor.gotoPageDown(); },
+ readOnly: true
+}, {
+ name: "selectpageup",
+ bindKey: "Shift-PageUp",
+ exec: function(editor) { editor.selectPageUp(); },
+ readOnly: true
+}, {
+ name: "pageup",
+ bindKey: bindKey(null, "Option-PageUp"),
+ exec: function(editor) { editor.scrollPageUp(); },
+ readOnly: true
+}, {
+ name: "gotopageup",
+ bindKey: "PageUp",
+ exec: function(editor) { editor.gotoPageUp(); },
+ readOnly: true
+}, {
+ name: "scrollup",
+ bindKey: bindKey("Ctrl-Up", null),
+ exec: function(e) { e.renderer.scrollBy(0, -2 * e.renderer.layerConfig.lineHeight); },
+ readOnly: true
+}, {
+ name: "scrolldown",
+ bindKey: bindKey("Ctrl-Down", null),
+ exec: function(e) { e.renderer.scrollBy(0, 2 * e.renderer.layerConfig.lineHeight); },
+ readOnly: true
+}, {
+ name: "selectlinestart",
+ bindKey: "Shift-Home",
+ exec: function(editor) { editor.getSelection().selectLineStart(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
+ name: "selectlineend",
+ bindKey: "Shift-End",
+ exec: function(editor) { editor.getSelection().selectLineEnd(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
+ name: "togglerecording",
+ bindKey: bindKey("Ctrl-Alt-E", "Command-Option-E"),
+ exec: function(editor) { editor.commands.toggleRecording(editor); },
+ readOnly: true
+}, {
+ name: "replaymacro",
+ bindKey: bindKey("Ctrl-Shift-E", "Command-Shift-E"),
+ exec: function(editor) { editor.commands.replay(editor); },
+ readOnly: true
+}, {
+ name: "jumptomatching",
+ bindKey: bindKey("Ctrl-P", "Ctrl-Shift-P"),
+ exec: function(editor) { editor.jumpToMatching(); },
+ multiSelectAction: "forEach",
+ readOnly: true
+}, {
+ name: "selecttomatching",
+ bindKey: bindKey("Ctrl-Shift-P", null),
+ exec: function(editor) { editor.jumpToMatching(true); },
+ 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(); },
+ multiSelectAction: "forEachLine"
+}, {
+ name: "duplicateSelection",
+ bindKey: bindKey("Ctrl-Shift-D", "Command-Shift-D"),
+ exec: function(editor) { editor.duplicateSelection(); },
+ multiSelectAction: "forEach"
+}, {
+ name: "sortlines",
+ bindKey: bindKey("Ctrl-Alt-S", "Command-Alt-S"),
+ exec: function(editor) { editor.sortLines(); },
+ multiSelectAction: "forEachLine"
+}, {
+ name: "togglecomment",
+ bindKey: bindKey("Ctrl-/", "Command-/"),
+ exec: function(editor) { editor.toggleCommentLines(); },
+ multiSelectAction: "forEachLine"
+}, {
+ name: "toggleBlockComment",
+ bindKey: bindKey("Ctrl-Shift-/", "Command-Shift-/"),
+ exec: function(editor) { editor.toggleBlockComment(); },
+ multiSelectAction: "forEach"
+}, {
+ name: "modifyNumberUp",
+ bindKey: bindKey("Ctrl-Shift-Up", "Alt-Shift-Up"),
+ exec: function(editor) { editor.modifyNumber(1); },
+ multiSelectAction: "forEach"
+}, {
+ name: "modifyNumberDown",
+ bindKey: bindKey("Ctrl-Shift-Down", "Alt-Shift-Down"),
+ exec: function(editor) { editor.modifyNumber(-1); },
+ multiSelectAction: "forEach"
+}, {
+ name: "replace",
+ bindKey: bindKey("Ctrl-H", "Command-Option-F"),
+ exec: function(editor) {
+ config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor, true)});
+ }
+}, {
+ name: "undo",
+ bindKey: bindKey("Ctrl-Z", "Command-Z"),
+ exec: function(editor) { editor.undo(); }
+}, {
+ name: "redo",
+ bindKey: bindKey("Ctrl-Shift-Z|Ctrl-Y", "Command-Shift-Z|Command-Y"),
+ exec: function(editor) { editor.redo(); }
+}, {
+ name: "copylinesup",
+ bindKey: bindKey("Alt-Shift-Up", "Command-Option-Up"),
+ exec: function(editor) { editor.copyLinesUp(); }
+}, {
+ name: "movelinesup",
+ bindKey: bindKey("Alt-Up", "Option-Up"),
+ exec: function(editor) { editor.moveLinesUp(); }
+}, {
+ name: "copylinesdown",
+ bindKey: bindKey("Alt-Shift-Down", "Command-Option-Down"),
+ exec: function(editor) { editor.copyLinesDown(); }
+}, {
+ name: "movelinesdown",
+ bindKey: bindKey("Alt-Down", "Option-Down"),
+ exec: function(editor) { editor.moveLinesDown(); }
+}, {
+ name: "del",
+ bindKey: bindKey("Delete", "Delete|Ctrl-D|Shift-Delete"),
+ exec: function(editor) { editor.remove("right"); },
+ multiSelectAction: "forEach"
+}, {
+ name: "backspace",
+ bindKey: bindKey(
+ "Shift-Backspace|Backspace",
+ "Ctrl-Backspace|Shift-Backspace|Backspace|Ctrl-H"
+ ),
+ exec: function(editor) { editor.remove("left"); },
+ multiSelectAction: "forEach"
+}, {
+ name: "cut_or_delete",
+ bindKey: bindKey("Shift-Delete", null),
+ exec: function(editor) {
+ if (editor.selection.isEmpty()) {
+ editor.remove("left");
+ } else {
+ return false;
+ }
+ },
+ multiSelectAction: "forEach"
+}, {
+ name: "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(); },
+ multiSelectAction: "forEach"
+}, {
+ name: "removewordleft",
+ bindKey: bindKey("Ctrl-Backspace", "Alt-Backspace|Ctrl-Alt-Backspace"),
+ exec: function(editor) { editor.removeWordLeft(); },
+ multiSelectAction: "forEach"
+}, {
+ name: "removewordright",
+ bindKey: bindKey("Ctrl-Delete", "Alt-Delete"),
+ exec: function(editor) { editor.removeWordRight(); },
+ multiSelectAction: "forEach"
+}, {
+ name: "outdent",
+ bindKey: bindKey("Shift-Tab", "Shift-Tab"),
+ exec: function(editor) { editor.blockOutdent(); },
+ multiSelectAction: "forEach"
+}, {
+ name: "indent",
+ bindKey: bindKey("Tab", "Tab"),
+ exec: function(editor) { editor.indent(); },
+ multiSelectAction: "forEach"
+},{
+ name: "blockoutdent",
+ bindKey: bindKey("Ctrl-[", "Ctrl-["),
+ exec: function(editor) { editor.blockOutdent(); },
+ multiSelectAction: "forEachLine"
+},{
+ name: "blockindent",
+ bindKey: bindKey("Ctrl-]", "Ctrl-]"),
+ exec: function(editor) { editor.blockIndent(); },
+ multiSelectAction: "forEachLine"
+}, {
+ name: "insertstring",
+ 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(); },
+ multiSelectAction: "forEach"
+}, {
+ name: "transposeletters",
+ bindKey: bindKey("Ctrl-T", "Ctrl-T"),
+ exec: function(editor) { editor.transposeLetters(); },
+ multiSelectAction: function(editor) {editor.transposeSelections(1); }
+}, {
+ name: "touppercase",
+ bindKey: bindKey("Ctrl-U", "Ctrl-U"),
+ exec: function(editor) { editor.toUpperCase(); },
+ multiSelectAction: "forEach"
+}, {
+ name: "tolowercase",
+ bindKey: bindKey("Ctrl-Shift-U", "Ctrl-Shift-U"),
+ exec: function(editor) { editor.toLowerCase(); },
+ multiSelectAction: "forEach"
+}];
+
+});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9abd128c/src/fauxton/assets/js/libs/ace/commands/incremental_search_commands.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/ace/commands/incremental_search_commands.js b/src/fauxton/assets/js/libs/ace/commands/incremental_search_commands.js
new file mode 100644
index 0000000..ebe979c
--- /dev/null
+++ b/src/fauxton/assets/js/libs/ace/commands/incremental_search_commands.js
@@ -0,0 +1,180 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
+ *
+ * Copyright (c) 2010, Ajax.org B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Ajax.org B.V. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var config = require("../config");
+var oop = require("../lib/oop");
+var HashHandler = require("../keyboard/hash_handler").HashHandler;
+var occurStartCommand = require("./occur_commands").occurStartCommand;
+
+// These commands can be installed in a normal key handler to start iSearch:
+exports.iSearchStartCommands = [{
+ name: "iSearch",
+ bindKey: {win: "Ctrl-F", mac: "Command-F"},
+ exec: function(editor, options) {
+ config.loadModule(["core", "ace/incremental_search"], function(e) {
+ var iSearch = e.iSearch = e.iSearch || new e.IncrementalSearch();
+ iSearch.activate(editor, options.backwards);
+ if (options.jumpToFirstMatch) iSearch.next(options);
+ });
+ },
+ readOnly: true
+}, {
+ name: "iSearchBackwards",
+ exec: function(editor, jumpToNext) { editor.execCommand('iSearch', {backwards: true}); },
+ readOnly: true
+}, {
+ name: "iSearchAndGo",
+ bindKey: {win: "Ctrl-K", mac: "Command-G"},
+ exec: function(editor, jumpToNext) { editor.execCommand('iSearch', {jumpToFirstMatch: true, useCurrentOrPrevSearch: true}); },
+ readOnly: true
+}, {
+ name: "iSearchBackwardsAndGo",
+ bindKey: {win: "Ctrl-Shift-K", mac: "Command-Shift-G"},
+ exec: function(editor) { editor.execCommand('iSearch', {jumpToFirstMatch: true, backwards: true, useCurrentOrPrevSearch: true}); },
+ readOnly: true
+}];
+
+// These commands are only available when incremental search mode is active:
+exports.iSearchCommands = [{
+ name: "restartSearch",
+ bindKey: {win: "Ctrl-F", mac: "Command-F"},
+ exec: function(iSearch) {
+ iSearch.cancelSearch(true);
+ },
+ readOnly: true,
+ isIncrementalSearchCommand: true
+}, {
+ name: "searchForward",
+ bindKey: {win: "Ctrl-S|Ctrl-K", mac: "Ctrl-S|Command-G"},
+ exec: function(iSearch, options) {
+ options.useCurrentOrPrevSearch = true;
+ iSearch.next(options);
+ },
+ readOnly: true,
+ isIncrementalSearchCommand: true
+}, {
+ name: "searchBackward",
+ bindKey: {win: "Ctrl-R|Ctrl-Shift-K", mac: "Ctrl-R|Command-Shift-G"},
+ exec: function(iSearch, options) {
+ options.useCurrentOrPrevSearch = true;
+ options.backwards = true;
+ iSearch.next(options);
+ },
+ readOnly: true,
+ isIncrementalSearchCommand: true
+}, {
+ name: "extendSearchTerm",
+ exec: function(iSearch, string) {
+ iSearch.addChar(string);
+ },
+ readOnly: true,
+ isIncrementalSearchCommand: true
+}, {
+ name: "extendSearchTermSpace",
+ bindKey: "space",
+ exec: function(iSearch) { iSearch.addChar(' '); },
+ readOnly: true,
+ isIncrementalSearchCommand: true
+}, {
+ name: "shrinkSearchTerm",
+ bindKey: "backspace",
+ exec: function(iSearch) {
+ iSearch.removeChar();
+ },
+ readOnly: true,
+ isIncrementalSearchCommand: true
+}, {
+ name: 'confirmSearch',
+ bindKey: 'return',
+ exec: function(iSearch) { iSearch.deactivate(); },
+ readOnly: true,
+ isIncrementalSearchCommand: true
+}, {
+ name: 'cancelSearch',
+ bindKey: 'esc|Ctrl-G',
+ exec: function(iSearch) { iSearch.deactivate(true); },
+ readOnly: true,
+ isIncrementalSearchCommand: true
+}, {
+ name: 'occurisearch',
+ bindKey: 'Ctrl-O',
+ exec: function(iSearch) {
+ var options = oop.mixin({}, iSearch.$options);
+ iSearch.deactivate();
+ occurStartCommand.exec(iSearch.$editor, options);
+ },
+ readOnly: true,
+ isIncrementalSearchCommand: true
+}];
+
+function IncrementalSearchKeyboardHandler(iSearch) {
+ this.$iSearch = iSearch;
+}
+
+oop.inherits(IncrementalSearchKeyboardHandler, HashHandler);
+
+;(function() {
+
+ this.attach = function(editor) {
+ var iSearch = this.$iSearch;
+ HashHandler.call(this, exports.iSearchCommands, editor.commands.platform);
+ this.$commandExecHandler = editor.commands.addEventListener('exec', function(e) {
+ if (!e.command.isIncrementalSearchCommand) return undefined;
+ e.stopPropagation();
+ e.preventDefault();
+ return e.command.exec(iSearch, e.args || {});
+ });
+ }
+
+ this.detach = function(editor) {
+ if (!this.$commandExecHandler) return;
+ editor.commands.removeEventListener('exec', this.$commandExecHandler);
+ delete this.$commandExecHandler;
+ }
+
+ var handleKeyboard$super = this.handleKeyboard;
+ this.handleKeyboard = function(data, hashId, key, keyCode) {
+ var cmd = handleKeyboard$super.call(this, data, hashId, key, keyCode);
+ if (cmd.command) { return cmd; }
+ if (hashId == -1) {
+ var extendCmd = this.commands.extendSearchTerm;
+ if (extendCmd) { return {command: extendCmd, args: key}; }
+ }
+ return {command: "null", passEvent: hashId == 0 || hashId == 4};
+ }
+
+}).call(IncrementalSearchKeyboardHandler.prototype);
+
+
+exports.IncrementalSearchKeyboardHandler = IncrementalSearchKeyboardHandler;
+
+});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9abd128c/src/fauxton/assets/js/libs/ace/commands/multi_select_commands.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/ace/commands/multi_select_commands.js b/src/fauxton/assets/js/libs/ace/commands/multi_select_commands.js
new file mode 100644
index 0000000..ff59f04
--- /dev/null
+++ b/src/fauxton/assets/js/libs/ace/commands/multi_select_commands.js
@@ -0,0 +1,97 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
+ *
+ * Copyright (c) 2010, Ajax.org B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Ajax.org B.V. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(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-Alt-L", mac: "Ctrl-Alt-L"},
+ readonly: true
+}, {
+ name: "alignCursors",
+ exec: function(editor) { editor.alignCursors(); },
+ bindKey: {win: "Ctrl-Alt-A", mac: "Ctrl-Alt-A"}
+}];
+
+// commands active only in multiselect mode
+exports.multiSelectCommands = [{
+ name: "singleSelection",
+ bindKey: "esc",
+ exec: function(editor) { editor.exitMultiSelectMode(); },
+ readonly: true,
+ isAvailable: function(editor) {return editor && editor.inMultiSelectMode}
+}];
+
+var HashHandler = require("../keyboard/hash_handler").HashHandler;
+exports.keyboardHandler = new HashHandler(exports.multiSelectCommands);
+
+});
http://git-wip-us.apache.org/repos/asf/couchdb/blob/9abd128c/src/fauxton/assets/js/libs/ace/commands/occur_commands.js
----------------------------------------------------------------------
diff --git a/src/fauxton/assets/js/libs/ace/commands/occur_commands.js b/src/fauxton/assets/js/libs/ace/commands/occur_commands.js
new file mode 100644
index 0000000..b45fbf6
--- /dev/null
+++ b/src/fauxton/assets/js/libs/ace/commands/occur_commands.js
@@ -0,0 +1,110 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Distributed under the BSD license:
+ *
+ * Copyright (c) 2010, Ajax.org B.V.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of Ajax.org B.V. nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+define(function(require, exports, module) {
+
+var config = require("../config"),
+ Occur = require("../occur").Occur;
+
+// These commands can be installed in a normal command handler to start occur:
+var occurStartCommand = {
+ name: "occur",
+ exec: function(editor, options) {
+ var alreadyInOccur = !!editor.session.$occur;
+ var occurSessionActive = new Occur().enter(editor, options);
+ if (occurSessionActive && !alreadyInOccur)
+ OccurKeyboardHandler.installIn(editor);
+ },
+ readOnly: true
+};
+
+var occurCommands = [{
+ name: "occurexit",
+ bindKey: 'esc|Ctrl-G',
+ exec: function(editor) {
+ var occur = editor.session.$occur;
+ if (!occur) return;
+ occur.exit(editor, {});
+ if (!editor.session.$occur) OccurKeyboardHandler.uninstallFrom(editor);
+ },
+ readOnly: true
+}, {
+ name: "occuraccept",
+ bindKey: 'enter',
+ exec: function(editor) {
+ var occur = editor.session.$occur;
+ if (!occur) return;
+ occur.exit(editor, {translatePosition: true});
+ if (!editor.session.$occur) OccurKeyboardHandler.uninstallFrom(editor);
+ },
+ readOnly: true
+}];
+
+var HashHandler = require("../keyboard/hash_handler").HashHandler;
+var oop = require("../lib/oop");
+
+
+function OccurKeyboardHandler() {}
+
+oop.inherits(OccurKeyboardHandler, HashHandler);
+
+;(function() {
+
+ this.isOccurHandler = true;
+
+ this.attach = function(editor) {
+ HashHandler.call(this, occurCommands, editor.commands.platform);
+ this.$editor = editor;
+ }
+
+ var handleKeyboard$super = this.handleKeyboard;
+ this.handleKeyboard = function(data, hashId, key, keyCode) {
+ var cmd = handleKeyboard$super.call(this, data, hashId, key, keyCode);
+ return (cmd && cmd.command) ? cmd : undefined;
+ }
+
+}).call(OccurKeyboardHandler.prototype);
+
+OccurKeyboardHandler.installIn = function(editor) {
+ var handler = new this();
+ editor.keyBinding.addKeyboardHandler(handler);
+ editor.commands.addCommands(occurCommands);
+}
+
+OccurKeyboardHandler.uninstallFrom = function(editor) {
+ editor.commands.removeCommands(occurCommands);
+ var handler = editor.getKeyboardHandler();
+ if (handler.isOccurHandler)
+ editor.keyBinding.removeKeyboardHandler(handler);
+}
+
+exports.occurStartCommand = occurStartCommand;
+
+});