/lenasys/trunk

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/lenasys/trunk

« back to all changes in this revision

Viewing changes to js/ace/ext-searchbox.js

  • Committer: Gustav Hatvigsson
  • Date: 2013-05-31 06:15:46 UTC
  • mfrom: (90.1.20 lenasys2)
  • Revision ID: gustav.hartvigsson@gmail.com-20130531061546-vj8z28sq375kvghq
Merged Jonsson:s changes:
Fixed the layout on cms index so the arrows and dots marks expanded objects.
Fixed so the course content is sorted by course occasion and not by name

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ***** BEGIN LICENSE BLOCK *****
 
2
 * Distributed under the BSD license:
 
3
 *
 
4
 * Copyright (c) 2010, Ajax.org B.V.
 
5
 * All rights reserved.
 
6
 *
 
7
 * Redistribution and use in source and binary forms, with or without
 
8
 * modification, are permitted provided that the following conditions are met:
 
9
 *     * Redistributions of source code must retain the above copyright
 
10
 *       notice, this list of conditions and the following disclaimer.
 
11
 *     * Redistributions in binary form must reproduce the above copyright
 
12
 *       notice, this list of conditions and the following disclaimer in the
 
13
 *       documentation and/or other materials provided with the distribution.
 
14
 *     * Neither the name of Ajax.org B.V. nor the
 
15
 *       names of its contributors may be used to endorse or promote products
 
16
 *       derived from this software without specific prior written permission.
 
17
 *
 
18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 
20
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 
21
 * DISCLAIMED. IN NO EVENT SHALL AJAX.ORG B.V. BE LIABLE FOR ANY
 
22
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
23
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 
24
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 
25
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
26
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 
27
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
28
 *
 
29
 * ***** END LICENSE BLOCK ***** */
 
30
 
 
31
define('ace/ext/searchbox', ['require', 'exports', 'module' , 'ace/lib/dom', 'ace/lib/lang', 'ace/lib/event', 'ace/keyboard/hash_handler', 'ace/lib/keys'], function(require, exports, module) {
 
32
 
 
33
 
 
34
var dom = require("../lib/dom");
 
35
var lang = require("../lib/lang");
 
36
var event = require("../lib/event");
 
37
var searchboxCss = "\
 
38
/* ------------------------------------------------------------------------------------------\
 
39
* Editor Search Form\
 
40
* --------------------------------------------------------------------------------------- */\
 
41
.ace_search {\
 
42
background-color: #ddd;\
 
43
border: 1px solid #cbcbcb;\
 
44
border-top: 0 none;\
 
45
max-width: 297px;\
 
46
overflow: hidden;\
 
47
margin: 0;\
 
48
padding: 4px;\
 
49
padding-right: 6px;\
 
50
padding-bottom: 0;\
 
51
position: absolute;\
 
52
top: 0px;\
 
53
z-index: 99;\
 
54
}\
 
55
.ace_search.left {\
 
56
border-left: 0 none;\
 
57
border-radius: 0px 0px 5px 0px;\
 
58
left: 0;\
 
59
}\
 
60
.ace_search.right {\
 
61
border-radius: 0px 0px 0px 5px;\
 
62
border-right: 0 none;\
 
63
right: 0;\
 
64
}\
 
65
.ace_search_form, .ace_replace_form {\
 
66
border-radius: 3px;\
 
67
border: 1px solid #cbcbcb;\
 
68
float: left;\
 
69
margin-bottom: 4px;\
 
70
overflow: hidden;\
 
71
}\
 
72
.ace_search_field {\
 
73
background-color: white;\
 
74
border-right: 1px solid #cbcbcb;\
 
75
border: 0 none;\
 
76
-webkit-box-sizing: border-box;\
 
77
-moz-box-sizing: border-box;\
 
78
box-sizing: border-box;\
 
79
display: block;\
 
80
float: left;\
 
81
height: 22px;\
 
82
outline: 0;\
 
83
padding: 0 7px;\
 
84
width: 214px;\
 
85
margin: 0;\
 
86
}\
 
87
.ace_searchbtn,\
 
88
.ace_replacebtn {\
 
89
background: #fff;\
 
90
border: 0 none;\
 
91
border-left: 1px solid #dcdcdc;\
 
92
cursor: pointer;\
 
93
display: block;\
 
94
float: left;\
 
95
height: 22px;\
 
96
margin: 0;\
 
97
padding: 0;\
 
98
position: relative;\
 
99
}\
 
100
.ace_searchbtn:last-child,\
 
101
.ace_replacebtn:last-child {\
 
102
border-top-right-radius: 3px;\
 
103
border-bottom-right-radius: 3px;\
 
104
}\
 
105
.ace_searchbtn:disabled {\
 
106
background: none;\
 
107
cursor: default;\
 
108
}\
 
109
.ace_searchbtn {\
 
110
background-position: 50% 50%;\
 
111
background-repeat: no-repeat;\
 
112
width: 27px;\
 
113
}\
 
114
.ace_searchbtn.prev {\
 
115
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADFJREFUeNpiSU1NZUAC/6E0I0yACYskCpsJiySKIiY0SUZk40FyTEgCjGgKwTRAgAEAQJUIPCE+qfkAAAAASUVORK5CYII=);    \
 
116
}\
 
117
.ace_searchbtn.next {\
 
118
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAFCAYAAAB4ka1VAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNpiTE1NZQCC/0DMyIAKwGJMUAYDEo3M/s+EpvM/mkKwCQxYjIeLMaELoLMBAgwAU7UJObTKsvAAAAAASUVORK5CYII=);    \
 
119
}\
 
120
.ace_searchbtn_close {\
 
121
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAcCAYAAABRVo5BAAAAZ0lEQVR42u2SUQrAMAhDvazn8OjZBilCkYVVxiis8H4CT0VrAJb4WHT3C5xU2a2IQZXJjiQIRMdkEoJ5Q2yMqpfDIo+XY4k6h+YXOyKqTIj5REaxloNAd0xiKmAtsTHqW8sR2W5f7gCu5nWFUpVjZwAAAABJRU5ErkJggg==) no-repeat 50% 0;\
 
122
border-radius: 50%;\
 
123
border: 0 none;\
 
124
color: #656565;\
 
125
cursor: pointer;\
 
126
display: block;\
 
127
float: right;\
 
128
font-family: Arial;\
 
129
font-size: 16px;\
 
130
height: 14px;\
 
131
line-height: 16px;\
 
132
margin: 5px 1px 9px 5px;\
 
133
padding: 0;\
 
134
text-align: center;\
 
135
width: 14px;\
 
136
}\
 
137
.ace_searchbtn_close:hover {\
 
138
background-color: #656565;\
 
139
background-position: 50% 100%;\
 
140
color: white;\
 
141
}\
 
142
.ace_replacebtn.prev {\
 
143
width: 54px\
 
144
}\
 
145
.ace_replacebtn.next {\
 
146
width: 27px\
 
147
}";
 
148
var HashHandler = require("../keyboard/hash_handler").HashHandler;
 
149
var keyUtil = require("../lib/keys");
 
150
 
 
151
dom.importCssString(searchboxCss, "ace_searchbox");
 
152
 
 
153
var html = '<div class="ace_search right">\
 
154
    <button type="button" action="hide" class="ace_searchbtn_close"></button>\
 
155
    <div class="ace_search_form">\
 
156
        <input class="ace_search_field" placeholder="Search for" spellcheck="false"></input>\
 
157
        <button type="button" action="findNext" class="ace_searchbtn next"></button>\
 
158
        <button type="button" action="findPrev" class="ace_searchbtn prev"></button>\
 
159
    </div>\
 
160
    <div class="ace_replace_form">\
 
161
        <input class="ace_search_field" placeholder="Replace with" spellcheck="false"></input>\
 
162
        <button type="button" action="replace" class="ace_replacebtn">Replace</button>\
 
163
        <button type="button" action="replaceAll" class="ace_replacebtn">All</button>\
 
164
    </div>\
 
165
</div>'.replace(/>\s+/g, ">");
 
166
 
 
167
var SearchBox = function(editor, range, showReplaceForm) {
 
168
    var div = dom.createElement("div");
 
169
    div.innerHTML = html;
 
170
    this.element = div.firstChild;
 
171
 
 
172
    this.$init();
 
173
    this.setEditor(editor);
 
174
};
 
175
 
 
176
(function() {
 
177
    this.setEditor = function(editor) {
 
178
        editor.searchBox = this;
 
179
        editor.container.appendChild(this.element);
 
180
        this.editor = editor;
 
181
    };
 
182
 
 
183
    this.$init = function() {
 
184
        var sb = this.element;
 
185
 
 
186
        this.searchBox = sb.querySelector(".ace_search_form");
 
187
        this.replaceBox = sb.querySelector(".ace_replace_form");
 
188
        this.searchInput = this.searchBox.querySelector(".ace_search_field");
 
189
        this.replaceInput = this.replaceBox.querySelector(".ace_search_field");
 
190
 
 
191
        var _this = this;
 
192
        event.addListener(sb, "mousedown", function(e) {
 
193
            setTimeout(function(){
 
194
                _this.activeInput.focus();
 
195
            }, 0);
 
196
            event.stopPropagation(e);
 
197
        });
 
198
        event.addListener(sb, "click", function(e) {
 
199
            var t = e.target;
 
200
            var action = t.getAttribute("action");
 
201
            if (action && _this[action])
 
202
                _this[action]();
 
203
            event.stopPropagation(e);
 
204
        });
 
205
 
 
206
        event.addCommandKeyListener(sb, function(e, hashId, keyCode) {
 
207
            var keyString = keyUtil.keyCodeToString(keyCode);
 
208
            var command = _this.$searchBarKb.findKeyCommand(hashId, keyString);
 
209
            if (command && command.exec) {
 
210
                command.exec(_this);
 
211
                event.stopEvent(e);
 
212
            }
 
213
        });
 
214
 
 
215
        this.$onChange = lang.delayedCall(function() {
 
216
            _this.find(false, false);
 
217
        });
 
218
 
 
219
        event.addListener(this.searchInput, "input", function() {
 
220
            _this.$onChange.schedule(20);
 
221
        });
 
222
        event.addListener(this.searchInput, "focus", function() {
 
223
            _this.activeInput = _this.searchInput;
 
224
        });
 
225
        event.addListener(this.replaceInput, "focus", function() {
 
226
            _this.activeInput = _this.replaceInput;
 
227
        });
 
228
    };
 
229
    this.$closeSearchBarKb = new HashHandler([{
 
230
        bindKey: "Esc",
 
231
        name: "closeSearchBar",
 
232
        exec: function(editor) {
 
233
            editor.searchBox.hide();
 
234
        }
 
235
    }]);
 
236
    this.$searchBarKb = new HashHandler();
 
237
    this.$searchBarKb.bindKeys({
 
238
        "Ctrl-f|Command-f|Ctrl-H|Command-Option-F": function(sb) {
 
239
            var isReplace = sb.isReplace = !sb.isReplace;
 
240
            sb.replaceBox.style.display = isReplace ? "" : "none";
 
241
            sb[isReplace ? "replaceInput" : "searchInput"].focus();
 
242
        },
 
243
        "esc": function(sb) {
 
244
            setTimeout(function() { sb.hide();});
 
245
        },
 
246
        "Return": function(sb) {
 
247
            if (sb.activeInput == sb.replaceInput)
 
248
                sb.replace();
 
249
            sb.findNext();
 
250
        },
 
251
        "Shift-Return": function(sb) {
 
252
            if (sb.activeInput == sb.replaceInput)
 
253
                sb.replace();
 
254
            sb.findPrev();
 
255
        },
 
256
        "Tab": function(sb) {
 
257
            (sb.activeInput == sb.replaceInput ? sb.searchInput : sb.replaceInput).focus();
 
258
        }
 
259
    });
 
260
 
 
261
 
 
262
    this.find = function(skipCurrent, backwards) {
 
263
        this.editor.find(this.searchInput.value, {
 
264
            skipCurrent: skipCurrent,
 
265
            backwards: backwards,
 
266
            wrap: true
 
267
        });
 
268
        this.editor.session.highlight(this.editor.$search.$options.re);
 
269
    };
 
270
    this.findNext = function() {
 
271
        this.find(true, false);
 
272
    };
 
273
    this.findPrev = function() {
 
274
        this.find(true, true);
 
275
    };
 
276
    this.replace = function() {
 
277
        this.editor.replace(this.replaceInput.value);
 
278
        this.findNext();
 
279
    };
 
280
    this.replaceAll = function() {
 
281
        this.editor.replaceAll(this.replaceInput.value);
 
282
    };
 
283
 
 
284
    this.hide = function () {
 
285
        this.element.style.display = "none";
 
286
        this.editor.keyBinding.removeKeyboardHandler(this.$closeSearchBarKb);
 
287
        this.editor.focus();
 
288
    };
 
289
    this.show = function(value, isReplace) {
 
290
        this.element.style.display = "";
 
291
        this.replaceBox.style.display = isReplace ? "" : "none";
 
292
 
 
293
        this.isReplace = isReplace;
 
294
 
 
295
        if (value)
 
296
            this.searchInput.value = value;
 
297
        this.searchInput.focus();
 
298
        this.searchInput.select();
 
299
 
 
300
        this.editor.keyBinding.addKeyboardHandler(this.$closeSearchBarKb);
 
301
    };
 
302
 
 
303
}).call(SearchBox.prototype);
 
304
 
 
305
exports.SearchBox = SearchBox;
 
306
 
 
307
exports.Search = function(editor, isReplace) {
 
308
    var sb = editor.searchBox || new SearchBox(editor);
 
309
    sb.show(editor.session.getTextRange(), isReplace);
 
310
};
 
311
 
 
312
 
 
313
exports.ISearch = function(session, options) {
 
314
    this.$changeListener = this.$changeListener.bind(this);
 
315
    this.startRange = session.selection.toOrientedRange();
 
316
    this.options = options || {};
 
317
};
 
318
 
 
319
(function(){
 
320
    this.setSession = function(session) {
 
321
        if (this.session) {
 
322
            this.session.removeListener(this.$changeListener);
 
323
        }
 
324
        this.session = session;
 
325
        this.session.addListener(this.$changeListener);
 
326
    };
 
327
    this.setSearchString = function() {
 
328
 
 
329
    };
 
330
    this.getValue = function() {
 
331
        if (this.value == null)
 
332
            this.value = this.session.getValue();
 
333
        return this.value;
 
334
    };
 
335
    this.$changeListener = function() {
 
336
        this.value = null;
 
337
    };
 
338
    this.find = function() {
 
339
 
 
340
    };
 
341
    this.$edgeBefore = function() {
 
342
        this.cursor = this.startRange[this.options.backwards ? "start" : "end"];
 
343
    };
 
344
    this.$edgeAfter = function() {
 
345
 
 
346
    };
 
347
    this.next = function(dir) {
 
348
 
 
349
    };
 
350
}).call(exports.ISearch.prototype);
 
351
 
 
352
 
 
353
});