diff --git a/lib/ace/commands/default_commands.js b/lib/ace/commands/default_commands.js
index 7c112300..b8583c06 100644
--- a/lib/ace/commands/default_commands.js
+++ b/lib/ace/commands/default_commands.js
@@ -32,8 +32,8 @@ define(function(require, exports, module) {
"use strict";
var lang = require("../lib/lang");
+var config = require("../config");
-var SearchBox = require("ace/ext/searchbox");
function bindKey(win, mac) {
return {
win: win,
@@ -95,7 +95,7 @@ exports.commands = [{
name: "find",
bindKey: bindKey("Ctrl-F", "Command-F"),
exec: function(editor) {
- SearchBox.SearchBox(editor, editor.getSelectionRange());
+ config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor)});
},
readOnly: true
}, {
@@ -343,21 +343,9 @@ exports.commands = [{
multiSelectAction: "forEach"
}, {
name: "replace",
- bindKey: bindKey("Ctrl-R", "Command-Option-F"),
+ bindKey: bindKey("Ctrl-H", "Command-Option-F"),
exec: function(editor) {
- SearchBox.SearchBox(editor, editor.getSelectionRange(), true);
- }
-}, {
- name: "replaceall",
- bindKey: bindKey("Ctrl-Shift-R", "Command-Shift-Option-F"),
- exec: function(editor) {
- var needle = prompt("Find:");
- if (!needle)
- return;
- var replacement = prompt("Replacement:");
- if (!replacement)
- return;
- editor.replaceAll(replacement, {needle: needle});
+ config.loadModule("ace/ext/searchbox", function(e) {e.Search(editor, true)});
}
}, {
name: "undo",
diff --git a/lib/ace/css/editor.css b/lib/ace/css/editor.css
index 5eea817f..73702bdf 100644
--- a/lib/ace/css/editor.css
+++ b/lib/ace/css/editor.css
@@ -366,118 +366,3 @@
.ace_italic {
font-style: italic;
}
-
-
-/* ------------------------------------------------------------------------------------------
- * Editor Search Form
- * --------------------------------------------------------------------------------------- */
- .ace_search {
- background-color: #ddd;
- border: 1px solid #cbcbcb;
- border-top: 0 none;
- max-width: 297px;
- overflow: hidden;
- padding: 4px;
- padding-right: 6px;
- padding-bottom: 0;
- position: absolute;
- top: 0px;
- z-index: 99;
-}
-.ace_search.left {
- border-left: 0 none;
- border-radius: 0px 0px 5px 0px;
- left: 0;
-}
-.ace_search.right {
- border-radius: 0px 0px 0px 5px;
- border-right: 0 none;
- right: 0;
-}
-
-.ace_search_form {
- border-radius: 3px;
- border: 1px solid #cbcbcb;
- float: left;
- margin-bottom: 4px;
- overflow: hidden;
-}
-.ace_search label {
- float: left;
- color: #656565;
-}
-.ace_search input {
- background-color: white;
- border-right: 1px solid #cbcbcb;
- border: 0 none;
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
- display: block;
- float: left;
- height: 22px;
- outline: 0;
- padding: 0 7px;
- width: 214px;
-}
-.ace_searchbtn,
-.ace_replacebtn {
- background: #fff;
- border: 0 none;
- border-left: 1px solid #dcdcdc;
- cursor: pointer;
- display: block;
- float: left;
- height: 22px;
- margin: 0;
- padding: 0;
- position: relative;
-}
-.ace_searchbtn:last-child,
-.ace_replacebtn:last-child {
- border-top-right-radius: 3px;
- border-bottom-right-radius: 3px;
-}
-.ace_searchbtn:disabled {
- background: none;
- cursor: default;
-}
-.ace_searchbtn {
- background-position: 50% 50%;
- background-repeat: no-repeat;
- width: 27px;
-}
-.ace_searchbtn.prev {
- background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADFJREFUeNpiSU1NZUAC/6E0I0yACYskCpsJiySKIiY0SUZk40FyTEgCjGgKwTRAgAEAQJUIPCE+qfkAAAAASUVORK5CYII=);
-}
-.ace_searchbtn.next {
- background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNpiTE1NZQCC/0DMyIAKwGJMUAYDEo3M/s+EpvM/mkKwCQxYjIeLMaELoLMBAgwAU7UJObTKsvAAAAAASUVORK5CYII=);
-}
-.ace_searchbtn_close {
- background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAcCAYAAABRVo5BAAAAZ0lEQVR42u2SUQrAMAhDvazn8OjZBilCkYVVxiis8H4CT0VrAJb4WHT3C5xU2a2IQZXJjiQIRMdkEoJ5Q2yMqpfDIo+XY4k6h+YXOyKqTIj5REaxloNAd0xiKmAtsTHqW8sR2W5f7gCu5nWFUpVjZwAAAABJRU5ErkJggg==) no-repeat 50% 0;
- border-radius: 50%;
- border: 0 none;
- color: #656565;
- cursor: pointer;
- display: block;
- float: right;
- font-family: Arial;
- font-size: 16px;
- height: 14px;
- line-height: 16px;
- margin: 5px 1px 9px 5px;
- padding: 0;
- text-align: center;
- width: 14px;
-}
-.ace_searchbtn_close:hover {
- background-color: #656565;
- background-position: 50% 100%;
- color: white;
-}
-.ace_replacebtn.prev {
- width: 54px
-}
-.ace_replacebtn.next {
- width: 27px
-}
\ No newline at end of file
diff --git a/lib/ace/ext/searchbox.css b/lib/ace/ext/searchbox.css
new file mode 100644
index 00000000..2b828c8d
--- /dev/null
+++ b/lib/ace/ext/searchbox.css
@@ -0,0 +1,115 @@
+
+
+/* ------------------------------------------------------------------------------------------
+ * Editor Search Form
+ * --------------------------------------------------------------------------------------- */
+ .ace_search {
+ background-color: #ddd;
+ border: 1px solid #cbcbcb;
+ border-top: 0 none;
+ max-width: 297px;
+ overflow: hidden;
+ padding: 4px;
+ padding-right: 6px;
+ padding-bottom: 0;
+ position: absolute;
+ top: 0px;
+ z-index: 99;
+}
+.ace_search.left {
+ border-left: 0 none;
+ border-radius: 0px 0px 5px 0px;
+ left: 0;
+}
+.ace_search.right {
+ border-radius: 0px 0px 0px 5px;
+ border-right: 0 none;
+ right: 0;
+}
+
+.ace_search_form, .ace_replace_form {
+ border-radius: 3px;
+ border: 1px solid #cbcbcb;
+ float: left;
+ margin-bottom: 4px;
+ overflow: hidden;
+}
+.ace_search label {
+ float: left;
+ color: #656565;
+}
+.ace_search input {
+ background-color: white;
+ border-right: 1px solid #cbcbcb;
+ border: 0 none;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ display: block;
+ float: left;
+ height: 22px;
+ outline: 0;
+ padding: 0 7px;
+ width: 214px;
+}
+.ace_searchbtn,
+.ace_replacebtn {
+ background: #fff;
+ border: 0 none;
+ border-left: 1px solid #dcdcdc;
+ cursor: pointer;
+ display: block;
+ float: left;
+ height: 22px;
+ margin: 0;
+ padding: 0;
+ position: relative;
+}
+.ace_searchbtn:last-child,
+.ace_replacebtn:last-child {
+ border-top-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+}
+.ace_searchbtn:disabled {
+ background: none;
+ cursor: default;
+}
+.ace_searchbtn {
+ background-position: 50% 50%;
+ background-repeat: no-repeat;
+ width: 27px;
+}
+.ace_searchbtn.prev {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADFJREFUeNpiSU1NZUAC/6E0I0yACYskCpsJiySKIiY0SUZk40FyTEgCjGgKwTRAgAEAQJUIPCE+qfkAAAAASUVORK5CYII=);
+}
+.ace_searchbtn.next {
+ background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNpiTE1NZQCC/0DMyIAKwGJMUAYDEo3M/s+EpvM/mkKwCQxYjIeLMaELoLMBAgwAU7UJObTKsvAAAAAASUVORK5CYII=);
+}
+.ace_searchbtn_close {
+ background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAcCAYAAABRVo5BAAAAZ0lEQVR42u2SUQrAMAhDvazn8OjZBilCkYVVxiis8H4CT0VrAJb4WHT3C5xU2a2IQZXJjiQIRMdkEoJ5Q2yMqpfDIo+XY4k6h+YXOyKqTIj5REaxloNAd0xiKmAtsTHqW8sR2W5f7gCu5nWFUpVjZwAAAABJRU5ErkJggg==) no-repeat 50% 0;
+ border-radius: 50%;
+ border: 0 none;
+ color: #656565;
+ cursor: pointer;
+ display: block;
+ float: right;
+ font-family: Arial;
+ font-size: 16px;
+ height: 14px;
+ line-height: 16px;
+ margin: 5px 1px 9px 5px;
+ padding: 0;
+ text-align: center;
+ width: 14px;
+}
+.ace_searchbtn_close:hover {
+ background-color: #656565;
+ background-position: 50% 100%;
+ color: white;
+}
+.ace_replacebtn.prev {
+ width: 54px
+}
+.ace_replacebtn.next {
+ width: 27px
+}
\ No newline at end of file
diff --git a/lib/ace/ext/searchbox.js b/lib/ace/ext/searchbox.js
index 1df7cd6d..9f62411b 100644
--- a/lib/ace/ext/searchbox.js
+++ b/lib/ace/ext/searchbox.js
@@ -31,219 +31,219 @@
define(function(require, exports, module) {
"use strict";
-var dom = require("ace/lib/dom");
-var event = require("ace/lib/event");
-var Range = require("ace/range").Range;
-
-exports.SearchBox = function (editor, range, showReplaceForm) {
- var _self = this;
- var sb = null;//search box
- var n = null;//needle
- var r = null;//replace
- var p = null;//parent DOM node
+var dom = require("../lib/dom");
+var lang = require("../lib/lang");
+var event = require("../lib/event");
+var searchboxCss = require("../requirejs/text!./searchbox.css");
+var HashHandler = require("../keyboard/hash_handler").HashHandler;
+var keyUtil = require("../lib/keys");
- var needle = editor.session.getTextRange(range);
+dom.importCssString(searchboxCss, "ace_searchbox");
+
+var html = '
\
+
\
+
\
+ \
+ \
+ \
+
\
+
\
+ \
+ \
+ \
+
\
+
'.replace(/>\s+/g, ">");
+
+var SearchBox = function(editor, range, showReplaceForm) {
+ var div = dom.createElement("div");
+ div.innerHTML = html;
+ this.element = div.firstChild;
+
+ this.$init();
+ this.setEditor(editor);
+};
+
+(function() {
+ this.setEditor = function(editor) {
+ editor.searchBox = this;
+ editor.container.appendChild(this.element);
+ this.editor = editor;
+ };
this.$init = function() {
+ var sb = this.element;
- p = editor.container.parentNode;
- sb = p.querySelector(".ace_search"); //the complete form
+ this.searchBox = sb.querySelector(".ace_search_form");
+ this.replaceBox = sb.querySelector(".ace_replace_form");
+ this.searchInput = this.searchBox.querySelector(".ace_search_field");
+ this.replaceInput = this.replaceBox.querySelector(".ace_search_field");
- if(!sb) {
-
- //Create the elements
- sb = document.createElement("div");
- sb.setAttribute("class", "ace_search right");
- p.appendChild( sb );
+ var _this = this;
+ event.addListener(sb, "mousedown", function(e) {
+ setTimeout(function(){
+ _this.activeInput.focus();
+ }, 0);
+ event.stopPropagation(e);
+ });
+ event.addListener(sb, "click", function(e) {
+ var t = e.target;
+ var action = t.getAttribute("action");
+ if (action && _this[action])
+ _this[action]();
+ event.stopPropagation(e);
+ });
- var c = document.createElement("button"); //cancel btn
- c.setAttribute("type","button");
- c.setAttribute("class","ace_searchbtn_close");
- sb.appendChild( c );
- c.onclick = _self.hide;
-
- var sf = document.createElement("div"); //search form
- sf.setAttribute("id", "ace_search_form");
- sf.setAttribute("class", "ace_search_form");
- sb.appendChild( sf );
-
- n = document.createElement("input"); //needle
- n.setAttribute("class", "ace_search_field");
- n.setAttribute("id", "ace_search_field");
- n.setAttribute("placeholder", "Search for");
- n.setAttribute("type", "text");
- sf.appendChild( n );
-
- var sp = document.createElement("button");
- sp.setAttribute("type","button");
- sp.setAttribute("class","ace_searchbtn prev");
- sf.appendChild( sp );
- sp.onclick = _self.findPrev;
-
- var sn = document.createElement("button");
- sn.setAttribute("type","button");
- sn.setAttribute("class","ace_searchbtn next");
- sf.appendChild( sn );
- sn.onclick = _self.findNext;
-
- var rf = document.createElement("div"); //replace form
- rf.setAttribute("id", "ace_replace_form");
- rf.setAttribute("class", "ace_search_form");
- rf.setAttribute("style", "display: none");
- sb.appendChild( rf);
-
- r = document.createElement("input"); //needle
- r.setAttribute("class", "ace_search_field");
- r.setAttribute("id", "ace_replace_field");
- r.setAttribute("placeholder", "Replace with");
- r.setAttribute("type", "text");
- rf.appendChild( r );
-
- var rr = document.createElement("button");
- rr.setAttribute("type","button");
- rr.setAttribute("class","ace_replacebtn prev");
- rr.innerHTML = "Replace";
- rf.appendChild( rr );
- rr.onclick = _self.replace;
-
- var ra = document.createElement("button");
- ra.setAttribute("type","button");
- ra.setAttribute("class","ace_replacebtn next");
- ra.innerHTML = "All";
- rf.appendChild( ra );
- ra.onclick = _self.replaceAll;
-
-
- } else {
- sb.removeAttribute("style");
- n = sb.querySelector("#ace_search_field");
- r = sb.querySelector("#ace_replace_field");
- }
-
- console.log( "showReplaceForm", showReplaceForm );
- if( showReplaceForm ) {
- p.querySelector("#ace_replace_form").removeAttribute("style");
- }
-
-
- if( needle )
- n.value = needle;
-
- //set initial focus and select text in input
- n.focus();
- n.select();
-
- //keybinging outsite of the searchbox
- _self.$searchKeybingin = {
- handleKeyboard: function(data, hashId, keyString, keyCode) {
- console.log("MERGE");
- if (keyString == "esc")
- return {command: this.command};
- },
- command: {
- exec: function(editor) {
- _self.hide();
- }
+ event.addCommandKeyListener(sb, function(e, hashId, keyCode) {
+ var keyString = keyUtil.keyCodeToString(keyCode);
+ var command = _this.$searchBarKb.findKeyCommand(hashId, keyString);
+ if (command && command.exec) {
+ command.exec(_this);
+ event.stopEvent(e);
}
- };
- editor.keyBinding.addKeyboardHandler(this.$searchKeybingin);
+ });
- n.onkeydown = searchonkeydown;
- r.onkeydown = searchonkeydown;
- function searchonkeydown(e) {
+ this.$onChange = lang.delayedCall(function() {
+ _this.find(false, false);
+ });
- var cmdKey = e.metaKey || e.ctrlKey;
-
- console.log(cmdKey);
-
- if( cmdKey ) {
- if( e.which == 70 ) { //f key
- var rf = p.querySelector("#ace_replace_form");
- if( e.altKey && rf.hasAttribute("style") ) {
- p.querySelector("#ace_replace_form").removeAttribute("style");
- } else {
- _self.hide();
- }
- return false;
- }
- }
-
- if( e.which === 9 ) { //tab
- if( e.target == n ) {
- r.focus();
- r.select();
- } else {
- n.focus();
- n.select();
- }
- return false;
- }
- }
-
- n.onpaste = function(e) {
- //I do this because the onpaste event is fired before the value of the input actually changes
- setTimeout(function() {
- e.target.onkeyup();
- }, 100);
- }
- n.onkeyup = function(e){
- console.log("KEYUP", e);
- if(!e) {
- e = {};
- e.which = 0;
- }
-
- if( e.which === 27 ) { //esc key
- _self.hide();
- } else if( e.which === 13 ) { //enter key
- _self.findNext( );
- } else {
- editor.moveCursorTo( range.start.row, range.start.column );
- _self.findNext();
- }
- };
- r.onkeyup = function(e){
- if( e.which === 27 ) { //esc key
- _self.hide();
- } else if( e.which === 13 ) { //enter key
- editor.moveCursorTo( range.start.row, range.start.column );
- _self.replace();
- }
- };
+ event.addListener(this.searchInput, "input", function() {
+ _this.$onChange.schedule(20);
+ });
+ event.addListener(this.searchInput, "focus", function() {
+ _this.activeInput = _this.searchInput;
+ });
+ event.addListener(this.replaceInput, "focus", function() {
+ _this.activeInput = _this.replaceInput;
+ });
};
- this.findPrev = function() {
- editor.find(n.value, {
- backwards: true,
+ //keybinging outsite of the searchbox
+ this.$closeSearchBarKb = new HashHandler([{
+ bindKey: "Esc",
+ name: "closeSearchBar",
+ exec: function(editor) {
+ editor.searchBox.hide();
+ }
+ }]);
+
+ //keybinging outsite of the searchbox
+ this.$searchBarKb = new HashHandler();
+ this.$searchBarKb.bindKeys({
+ "Ctrl-f|Command-f|Ctrl-H|Command-Option-F": function(sb) {
+ var isReplace = sb.isReplace = !sb.isReplace;
+ sb.replaceBox.style.display = isReplace ? "" : "none";
+ sb[isReplace ? "replaceInput" : "searchInput"].focus();
+ },
+ "esc": function(sb) {
+ setTimeout(function() { sb.hide();});
+ },
+ "Return": function(sb) {
+ if (sb.activeInput == sb.replaceInput)
+ sb.replace();
+ sb.findNext();
+ },
+ "Shift-Return": function(sb) {
+ if (sb.activeInput == sb.replaceInput)
+ sb.replace();
+ sb.findPrev();
+ },
+ "Tab": function(sb) {
+ (sb.activeInput == sb.replaceInput ? sb.searchInput : sb.replaceInput).focus();
+ }
+ });
+
+
+ this.find = function(skipCurrent, backwards) {
+ this.editor.find(this.searchInput.value, {
+ skipCurrent: skipCurrent,
+ backwards: backwards,
wrap: true
});
+ this.editor.session.highlight(this.editor.$search.$options.re);
};
this.findNext = function() {
- editor.find(n.value, {
- backwards: false,
- wrap: true
- });
+ this.find(true, false);
+ };
+ this.findPrev = function() {
+ this.find(true, true);
};
this.replace = function() {
- editor.replace( r.value );
- _self.findNext();
+ this.editor.replace(this.replaceInput.value);
+ this.findNext();
};
this.replaceAll = function() {
- editor.replaceAll( r.value );
+ this.editor.replaceAll(this.replaceInput.value);
};
this.hide = function () {
- n.value = "";
- r.value = "";
- sb.setAttribute("style", "display: none");
- sb.querySelector("#ace_replace_form").setAttribute("style", "display: none");
- editor.keyBinding.removeKeyboardHandler(this.$searchKeybingin);
- editor.focus();
+ this.element.style.display = "none";
+ this.editor.keyBinding.removeKeyboardHandler(this.$searchKeybingin);
+ this.editor.focus();
+ };
+ this.show = function(value, isReplace) {
+ this.element.style.display = "";
+ this.replaceBox.style.display = isReplace ? "" : "none";
+
+ this.isReplace = isReplace;
+
+ if (value)
+ this.searchInput.value = value;
+ this.searchInput.focus();
+ this.searchInput.select();
+
+ this.editor.keyBinding.addKeyboardHandler(this.$closeSearchBarKb);
};
- _self.$init();
+}).call(SearchBox.prototype);
+
+exports.SearchBox = SearchBox;
+
+exports.Search = function(editor, isReplace) {
+ var sb = editor.searchBox || new SearchBox(editor);
+ sb.show(editor.session.getTextRange(), isReplace);
};
+
+exports.ISearch = function(session, options) {
+ this.$changeListener = this.$changeListener.bind(this);
+ this.startRange = session.selection.toOrientedRange();
+ this.options = options || {};
+};
+
+(function(){
+ this.setSession = function(session) {
+ if (this.session) {
+ this.session.removeListener(this.$changeListener);
+ }
+ this.session = session;
+ this.session.addListener(this.$changeListener);
+ };
+ this.setSearchString = function() {
+
+ };
+ this.getValue = function() {
+ if (this.value == null)
+ this.value = this.session.getValue();
+ return this.value;
+ };
+ this.$changeListener = function() {
+ this.value = null;
+ };
+ this.find = function() {
+
+ };
+ this.$edgeBefore = function() {
+ this.cursor = this.startRange[this.options.backwards ? "start" : "end"];
+ };
+ this.$edgeAfter = function() {
+
+ };
+ this.next = function(dir) {
+
+ };
+}).call(exports.ISearch.prototype);
+
+
});
@@ -251,7 +251,7 @@ exports.SearchBox = function (editor, range, showReplaceForm) {
* TODO
* --------------------------------------------------------------------------------------- */
/*
-- move search form to the left if it masks current word
+- move search form to the left if it masks current word
- includ all options that search has. ex: regex
- searchbox.searchbox is not that pretty. we should have just searchbox
- disable prev button if it makes sence