scratch – Blame information for rev
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
115 | office | 1 | /* |
2 | Copyright (c) 2009 Vladimir Kolesnikov |
||
3 | |||
4 | Permission is hereby granted, free of charge, to any person obtaining |
||
5 | a copy of this software and associated documentation files (the |
||
6 | "Software"), to deal in the Software without restriction, including |
||
7 | without limitation the rights to use, copy, modify, merge, publish, |
||
8 | distribute, sublicense, and/or sell copies of the Software, and to |
||
9 | permit persons to whom the Software is furnished to do so, subject to |
||
10 | the following conditions: |
||
11 | |||
12 | The above copyright notice and this permission notice shall be |
||
13 | included in all copies or substantial portions of the Software. |
||
14 | |||
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
||
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
||
17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
||
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
||
19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
||
20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
||
21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
||
22 | */ |
||
23 | |||
24 | Searchdoc = {}; |
||
25 | |||
26 | // navigation.js ------------------------------------------ |
||
27 | |||
28 | Searchdoc.Navigation = new function() { |
||
29 | this.initNavigation = function() { |
||
30 | var _this = this; |
||
31 | |||
32 | $(document).keydown(function(e) { |
||
33 | _this.onkeydown(e); |
||
34 | }).keyup(function(e) { |
||
35 | _this.onkeyup(e); |
||
36 | }); |
||
37 | |||
38 | this.navigationActive = true; |
||
39 | } |
||
40 | |||
41 | this.setNavigationActive = function(state) { |
||
42 | this.navigationActive = state; |
||
43 | this.clearMoveTimeout(); |
||
44 | } |
||
45 | |||
46 | |||
47 | this.onkeyup = function(e) { |
||
48 | if (!this.navigationActive) return; |
||
49 | switch(e.keyCode) { |
||
50 | case 37: //Event.KEY_LEFT: |
||
51 | case 38: //Event.KEY_UP: |
||
52 | case 39: //Event.KEY_RIGHT: |
||
53 | case 40: //Event.KEY_DOWN: |
||
54 | case 73: // i - qwerty |
||
55 | case 74: // j |
||
56 | case 75: // k |
||
57 | case 76: // l |
||
58 | case 67: // c - dvorak |
||
59 | case 72: // h |
||
60 | case 84: // t |
||
61 | case 78: // n |
||
62 | this.clearMoveTimeout(); |
||
63 | break; |
||
64 | } |
||
65 | } |
||
66 | |||
67 | this.onkeydown = function(e) { |
||
68 | if (!this.navigationActive) return; |
||
69 | switch(e.keyCode) { |
||
70 | case 37: //Event.KEY_LEFT: |
||
71 | case 74: // j (qwerty) |
||
72 | case 72: // h (dvorak) |
||
73 | if (this.moveLeft()) e.preventDefault(); |
||
74 | break; |
||
75 | case 38: //Event.KEY_UP: |
||
76 | case 73: // i (qwerty) |
||
77 | case 67: // c (dvorak) |
||
78 | if (e.keyCode == 38 || e.ctrlKey) { |
||
79 | if (this.moveUp()) e.preventDefault(); |
||
80 | this.startMoveTimeout(false); |
||
81 | } |
||
82 | break; |
||
83 | case 39: //Event.KEY_RIGHT: |
||
84 | case 76: // l (qwerty) |
||
85 | case 78: // n (dvorak) |
||
86 | if (this.moveRight()) e.preventDefault(); |
||
87 | break; |
||
88 | case 40: //Event.KEY_DOWN: |
||
89 | case 75: // k (qwerty) |
||
90 | case 84: // t (dvorak) |
||
91 | if (e.keyCode == 40 || e.ctrlKey) { |
||
92 | if (this.moveDown()) e.preventDefault(); |
||
93 | this.startMoveTimeout(true); |
||
94 | } |
||
95 | break; |
||
96 | case 9: //Event.KEY_TAB: |
||
97 | case 13: //Event.KEY_RETURN: |
||
98 | if (this.$current) this.select(this.$current); |
||
99 | break; |
||
100 | } |
||
101 | if (e.ctrlKey && e.shiftKey) this.select(this.$current); |
||
102 | } |
||
103 | |||
104 | this.clearMoveTimeout = function() { |
||
105 | clearTimeout(this.moveTimeout); |
||
106 | this.moveTimeout = null; |
||
107 | } |
||
108 | |||
109 | this.startMoveTimeout = function(isDown) { |
||
110 | if (!$.browser.mozilla && !$.browser.opera) return; |
||
111 | if (this.moveTimeout) this.clearMoveTimeout(); |
||
112 | var _this = this; |
||
113 | |||
114 | var go = function() { |
||
115 | if (!_this.moveTimeout) return; |
||
116 | _this[isDown ? 'moveDown' : 'moveUp'](); |
||
117 | _this.moveTimout = setTimeout(go, 100); |
||
118 | } |
||
119 | this.moveTimeout = setTimeout(go, 200); |
||
120 | } |
||
121 | |||
122 | this.moveRight = function() { |
||
123 | } |
||
124 | |||
125 | this.moveLeft = function() { |
||
126 | } |
||
127 | |||
128 | this.move = function(isDown) { |
||
129 | } |
||
130 | |||
131 | this.moveUp = function() { |
||
132 | return this.move(false); |
||
133 | } |
||
134 | |||
135 | this.moveDown = function() { |
||
136 | return this.move(true); |
||
137 | } |
||
138 | } |
||
139 | |||
140 | |||
141 | // scrollIntoView.js -------------------------------------- |
||
142 | |||
143 | function scrollIntoView(element, view) { |
||
144 | var offset, viewHeight, viewScroll, height; |
||
145 | offset = element.offsetTop; |
||
146 | height = element.offsetHeight; |
||
147 | viewHeight = view.offsetHeight; |
||
148 | viewScroll = view.scrollTop; |
||
149 | if (offset - viewScroll + height > viewHeight) { |
||
150 | view.scrollTop = offset - viewHeight + height; |
||
151 | } |
||
152 | if (offset < viewScroll) { |
||
153 | view.scrollTop = offset; |
||
154 | } |
||
155 | } |
||
156 | |||
157 | |||
158 | // searcher.js -------------------------------------------- |
||
159 | |||
160 | Searchdoc.Searcher = function(data) { |
||
161 | this.data = data; |
||
162 | this.handlers = []; |
||
163 | } |
||
164 | |||
165 | Searchdoc.Searcher.prototype = new function() { |
||
166 | var CHUNK_SIZE = 1000, // search is performed in chunks of 1000 for non-bloking user input |
||
167 | MAX_RESULTS = 100, // do not try to find more than 100 results |
||
168 | huid = 1, suid = 1, |
||
169 | runs = 0; |
||
170 | |||
171 | |||
172 | this.find = function(query) { |
||
173 | var queries = splitQuery(query), |
||
174 | regexps = buildRegexps(queries), |
||
175 | highlighters = buildHilighters(queries), |
||
176 | state = { from: 0, pass: 0, limit: MAX_RESULTS, n: suid++}, |
||
177 | _this = this; |
||
178 | this.currentSuid = state.n; |
||
179 | |||
180 | if (!query) return; |
||
181 | |||
182 | var run = function() { |
||
183 | // stop current search thread if new search started |
||
184 | if (state.n != _this.currentSuid) return; |
||
185 | |||
186 | var results = performSearch(_this.data, regexps, queries, highlighters, state), |
||
187 | hasMore = (state.limit > 0 && state.pass < 3); |
||
188 | |||
189 | triggerResults.call(_this, results, !hasMore); |
||
190 | if (hasMore) { |
||
191 | setTimeout(run, 2); |
||
192 | } |
||
193 | runs++; |
||
194 | }; |
||
195 | runs = 0; |
||
196 | |||
197 | // start search thread |
||
198 | run(); |
||
199 | } |
||
200 | |||
201 | /* ----- Events ------ */ |
||
202 | this.ready = function(fn) { |
||
203 | fn.huid = huid; |
||
204 | this.handlers.push(fn); |
||
205 | } |
||
206 | |||
207 | /* ----- Utilities ------ */ |
||
208 | function splitQuery(query) { |
||
209 | return jQuery.grep(query.split(/(\s+|\(\)?)/), function(string) { return string.match(/\S/) }); |
||
210 | } |
||
211 | |||
212 | function buildRegexps(queries) { |
||
213 | return jQuery.map(queries, function(query) { return new RegExp(query.replace(/(.)/g, '([$1])([^$1]*?)'), 'i') }); |
||
214 | } |
||
215 | |||
216 | function buildHilighters(queries) { |
||
217 | return jQuery.map(queries, function(query) { |
||
218 | return jQuery.map( query.split(''), function(l, i){ return '\u0001$' + (i*2+1) + '\u0002$' + (i*2+2) } ).join('') |
||
219 | }); |
||
220 | } |
||
221 | |||
222 | // function longMatchRegexp(index, longIndex, regexps) { |
||
223 | // for (var i = regexps.length - 1; i >= 0; i--){ |
||
224 | // if (!index.match(regexps[i]) && !longIndex.match(regexps[i])) return false; |
||
225 | // }; |
||
226 | // return true; |
||
227 | // } |
||
228 | |||
229 | |||
230 | /* ----- Mathchers ------ */ |
||
231 | function matchPass1(index, longIndex, queries, regexps) { |
||
232 | if (index.indexOf(queries[0]) != 0) return false; |
||
233 | for (var i=1, l = regexps.length; i < l; i++) { |
||
234 | if (!index.match(regexps[i]) && !longIndex.match(regexps[i])) return false; |
||
235 | }; |
||
236 | return true; |
||
237 | } |
||
238 | |||
239 | function matchPass2(index, longIndex, queries, regexps) { |
||
240 | if (index.indexOf(queries[0]) == -1) return false; |
||
241 | for (var i=1, l = regexps.length; i < l; i++) { |
||
242 | if (!index.match(regexps[i]) && !longIndex.match(regexps[i])) return false; |
||
243 | }; |
||
244 | return true; |
||
245 | } |
||
246 | |||
247 | function matchPassRegexp(index, longIndex, queries, regexps) { |
||
248 | if (!index.match(regexps[0])) return false; |
||
249 | for (var i=1, l = regexps.length; i < l; i++) { |
||
250 | if (!index.match(regexps[i]) && !longIndex.match(regexps[i])) return false; |
||
251 | }; |
||
252 | return true; |
||
253 | } |
||
254 | |||
255 | |||
256 | /* ----- Highlighters ------ */ |
||
257 | function highlightRegexp(info, queries, regexps, highlighters) { |
||
258 | var result = createResult(info); |
||
259 | for (var i=0, l = regexps.length; i < l; i++) { |
||
260 | result.title = result.title.replace(regexps[i], highlighters[i]); |
||
261 | if (i > 0) |
||
262 | result.namespace = result.namespace.replace(regexps[i], highlighters[i]); |
||
263 | }; |
||
264 | return result; |
||
265 | } |
||
266 | |||
267 | function hltSubstring(string, pos, length) { |
||
268 | return string.substring(0, pos) + '\u0001' + string.substring(pos, pos + length) + '\u0002' + string.substring(pos + length); |
||
269 | } |
||
270 | |||
271 | function highlightQuery(info, queries, regexps, highlighters) { |
||
272 | var result = createResult(info), pos = 0, lcTitle = result.title.toLowerCase(); |
||
273 | pos = lcTitle.indexOf(queries[0]); |
||
274 | if (pos != -1) { |
||
275 | result.title = hltSubstring(result.title, pos, queries[0].length); |
||
276 | } |
||
277 | for (var i=1, l = regexps.length; i < l; i++) { |
||
278 | result.title = result.title.replace(regexps[i], highlighters[i]); |
||
279 | result.namespace = result.namespace.replace(regexps[i], highlighters[i]); |
||
280 | }; |
||
281 | return result; |
||
282 | } |
||
283 | |||
284 | function createResult(info) { |
||
285 | var result = {}; |
||
286 | result.title = info[0]; |
||
287 | result.namespace = info[1]; |
||
288 | result.path = info[2]; |
||
289 | result.params = info[3]; |
||
290 | result.snippet = info[4]; |
||
291 | result.badge = info[6]; |
||
292 | return result; |
||
293 | } |
||
294 | |||
295 | /* ----- Searching ------ */ |
||
296 | function performSearch(data, regexps, queries, highlighters, state) { |
||
297 | var searchIndex = data.searchIndex, // search by title first and then by source |
||
298 | longSearchIndex = data.longSearchIndex, |
||
299 | info = data.info, |
||
300 | result = [], |
||
301 | i = state.from, |
||
302 | l = searchIndex.length, |
||
303 | togo = CHUNK_SIZE, |
||
304 | matchFunc, hltFunc; |
||
305 | |||
306 | while (state.pass < 3 && state.limit > 0 && togo > 0) { |
||
307 | if (state.pass == 0) { |
||
308 | matchFunc = matchPass1; |
||
309 | hltFunc = highlightQuery; |
||
310 | } else if (state.pass == 1) { |
||
311 | matchFunc = matchPass2; |
||
312 | hltFunc = highlightQuery; |
||
313 | } else if (state.pass == 2) { |
||
314 | matchFunc = matchPassRegexp; |
||
315 | hltFunc = highlightRegexp; |
||
316 | } |
||
317 | |||
318 | for (; togo > 0 && i < l && state.limit > 0; i++, togo--) { |
||
319 | if (info[i].n == state.n) continue; |
||
320 | if (matchFunc(searchIndex[i], longSearchIndex[i], queries, regexps)) { |
||
321 | info[i].n = state.n; |
||
322 | result.push(hltFunc(info[i], queries, regexps, highlighters)); |
||
323 | state.limit--; |
||
324 | } |
||
325 | }; |
||
326 | if (searchIndex.length <= i) { |
||
327 | state.pass++; |
||
328 | i = state.from = 0; |
||
329 | } else { |
||
330 | state.from = i; |
||
331 | } |
||
332 | } |
||
333 | return result; |
||
334 | } |
||
335 | |||
336 | function triggerResults(results, isLast) { |
||
337 | jQuery.each(this.handlers, function(i, fn) { fn.call(this, results, isLast) }) |
||
338 | } |
||
339 | } |
||
340 | |||
341 | |||
342 | |||
343 | |||
344 | // panel.js ----------------------------------------------- |
||
345 | |||
346 | Searchdoc.Panel = function(element, data, tree, frame) { |
||
347 | this.$element = $(element); |
||
348 | this.$input = $('input', element).eq(0); |
||
349 | this.$result = $('.result ul', element).eq(0); |
||
350 | this.frame = frame; |
||
351 | this.$current = null; |
||
352 | this.$view = this.$result.parent(); |
||
353 | this.data = data; |
||
354 | this.searcher = new Searchdoc.Searcher(data.index); |
||
355 | this.tree = new Searchdoc.Tree($('.tree', element), tree, this); |
||
356 | this.init(); |
||
357 | } |
||
358 | |||
359 | Searchdoc.Panel.prototype = $.extend({}, Searchdoc.Navigation, new function() { |
||
360 | var suid = 1; |
||
361 | |||
362 | this.init = function() { |
||
363 | var _this = this; |
||
364 | var observer = function() { |
||
365 | _this.search(_this.$input[0].value); |
||
366 | }; |
||
367 | this.$input.keyup(observer); |
||
368 | this.$input.click(observer); // mac's clear field |
||
369 | |||
370 | this.searcher.ready(function(results, isLast) { |
||
371 | _this.addResults(results, isLast); |
||
372 | }) |
||
373 | |||
374 | this.$result.click(function(e) { |
||
375 | _this.$current.removeClass('current'); |
||
376 | _this.$current = $(e.target).closest('li').addClass('current'); |
||
377 | _this.select(); |
||
378 | _this.$input.focus(); |
||
379 | }); |
||
380 | |||
381 | this.initNavigation(); |
||
382 | this.setNavigationActive(false); |
||
383 | } |
||
384 | |||
385 | this.search = function(value, selectFirstMatch) { |
||
386 | value = jQuery.trim(value).toLowerCase(); |
||
387 | this.selectFirstMatch = selectFirstMatch; |
||
388 | if (value) { |
||
389 | this.$element.removeClass('panel_tree').addClass('panel_results'); |
||
390 | this.tree.setNavigationActive(false); |
||
391 | this.setNavigationActive(true); |
||
392 | } else { |
||
393 | this.$element.addClass('panel_tree').removeClass('panel_results'); |
||
394 | this.tree.setNavigationActive(true); |
||
395 | this.setNavigationActive(false); |
||
396 | } |
||
397 | if (value != this.lastQuery) { |
||
398 | this.lastQuery = value; |
||
399 | this.firstRun = true; |
||
400 | this.searcher.find(value); |
||
401 | } |
||
402 | } |
||
403 | |||
404 | this.addResults = function(results, isLast) { |
||
405 | var target = this.$result.get(0); |
||
406 | if (this.firstRun && (results.length > 0 || isLast)) { |
||
407 | this.$current = null; |
||
408 | this.$result.empty(); |
||
409 | } |
||
410 | for (var i=0, l = results.length; i < l; i++) { |
||
411 | target.appendChild(renderItem.call(this, results[i])); |
||
412 | }; |
||
413 | if (this.firstRun && results.length > 0) { |
||
414 | this.firstRun = false; |
||
415 | this.$current = $(target.firstChild); |
||
416 | this.$current.addClass('current'); |
||
417 | if (this.selectFirstMatch) this.select(); |
||
418 | scrollIntoView(this.$current[0], this.$view[0]) |
||
419 | } |
||
420 | if (jQuery.browser.msie) this.$element[0].className += ''; |
||
421 | } |
||
422 | |||
423 | this.open = function(src) { |
||
424 | this.frame.location.href = src; |
||
425 | if (this.frame.highlight) this.frame.highlight(src); |
||
426 | } |
||
427 | |||
428 | this.select = function() { |
||
429 | this.open(this.$current.data('path')); |
||
430 | } |
||
431 | |||
432 | this.move = function(isDown) { |
||
433 | if (!this.$current) return; |
||
434 | var $next = this.$current[isDown ? 'next' : 'prev'](); |
||
435 | if ($next.length) { |
||
436 | this.$current.removeClass('current'); |
||
437 | $next.addClass('current'); |
||
438 | scrollIntoView($next[0], this.$view[0]); |
||
439 | this.$current = $next; |
||
440 | } |
||
441 | return true; |
||
442 | } |
||
443 | |||
444 | function renderItem(result) { |
||
445 | var li = document.createElement('li'), |
||
446 | html = '', badge = result.badge; |
||
447 | html += '<h1>' + hlt(result.title); |
||
448 | if (result.params) html += '<i>' + result.params + '</i>'; |
||
449 | html += '</h1>'; |
||
450 | html += '<p>'; |
||
451 | if (typeof badge != 'undefined') { |
||
452 | html += '<span class="badge badge_' + (badge % 6 + 1) + '">' + escapeHTML(this.data.badges[badge] || 'unknown') + '</span>'; |
||
453 | } |
||
454 | html += hlt(result.namespace) + '</p>'; |
||
455 | if (result.snippet) html += '<p class="snippet">' + escapeHTML(result.snippet) + '</p>'; |
||
456 | li.innerHTML = html; |
||
457 | jQuery.data(li, 'path', result.path); |
||
458 | return li; |
||
459 | } |
||
460 | |||
461 | function hlt(html) { |
||
462 | return escapeHTML(html).replace(/\u0001/g, '<b>').replace(/\u0002/g, '</b>') |
||
463 | } |
||
464 | |||
465 | function escapeHTML(html) { |
||
466 | return html.replace(/[&<>]/g, function(c) {> |
||
467 | <> return '&#' + c.charCodeAt(0) + ';';> |
||
468 | <> });> |
||
469 | <> }> |
||
470 | |||
471 | <>}); > |
||
472 | |||
473 | <>// tree.js ------------------------------------------------> |
||
474 | |||
475 | <>Searchdoc.Tree = function(element, tree, panel) {> |
||
476 | <> this.$element = $(element);> |
||
477 | <> this.$list = $('ul', element);> |
||
478 | <> this.tree = tree;> |
||
479 | <> this.panel = panel;> |
||
480 | <> this.init();> |
||
481 | <>}> |
||
482 | |||
483 | <>Searchdoc.Tree.prototype = $.extend({}, Searchdoc.Navigation, new function() {> |
||
484 | <> this.init = function() {> |
||
485 | <> var stopper = document.createElement('li');> |
||
486 | <> stopper.className = 'stopper';> |
||
487 | <> this.$list[0].appendChild(stopper);> |
||
488 | <> for (var i=0, l = this.tree.length; i < l; i++) {> |
||
489 | <> buildAndAppendItem.call(this, this.tree[i], 0, stopper);> |
||
490 | <> };> |
||
491 | <> var _this = this;> |
||
492 | <> this.$list.click(function(e) {> |
||
493 | <> var $target = $(e.target),> |
||
494 | <> $li = $target.closest('li');> |
||
495 | <> if ($target.hasClass('icon')) {> |
||
496 | <> _this.toggle($li);> |
||
497 | <> } else {> |
||
498 | <> _this.select($li);> |
||
499 | <> }> |
||
500 | <> })> |
||
501 | |||
502 | <> this.initNavigation();> |
||
503 | <> if (jQuery.browser.msie) document.body.className += '';> |
||
504 | <> }> |
||
505 | |||
506 | <> this.select = function($li) {> |
||
507 | <> this.highlight($li);> |
||
508 | <> var path = $li[0].searchdoc_tree_data.path;> |
||
509 | <> if (path) this.panel.open(path);> |
||
510 | <> }> |
||
511 | |||
512 | <> this.highlight = function($li) {> |
||
513 | <> if (this.$current) this.$current.removeClass('current');> |
||
514 | <> this.$current = $li.addClass('current');> |
||
515 | <> }> |
||
516 | |||
517 | <> this.toggle = function($li) {> |
||
518 | <> var closed = !$li.hasClass('closed'),> |
||
519 | <> children = $li[0].searchdoc_tree_data.children;> |
||
520 | <> $li.toggleClass('closed');> |
||
521 | <> for (var i=0, l = children.length; i < l; i++) {> |
||
522 | <> toggleVis.call(this, $(children[i].li), !closed);> |
||
523 | <> };> |
||
524 | <> }> |
||
525 | |||
526 | <> this.moveRight = function() {> |
||
527 | <> if (!this.$current) {> |
||
528 | <> this.highlight(this.$list.find('li:first'));> |
||
529 | <> return;> |
||
530 | <> }> |
||
531 | <> if (this.$current.hasClass('closed')) {> |
||
532 | <> this.toggle(this.$current);> |
||
533 | <> }> |
||
534 | <> }> |
||
535 | |||
536 | <> this.moveLeft = function() {> |
||
537 | <> if (!this.$current) {> |
||
538 | <> this.highlight(this.$list.find('li:first'));> |
||
539 | <> return;> |
||
540 | <> }> |
||
541 | <> if (!this.$current.hasClass('closed')) {> |
||
542 | <> this.toggle(this.$current);> |
||
543 | <> } else {> |
||
544 | <> var level = this.$current[0].searchdoc_tree_data.level;> |
||
545 | <> if (level == 0) return;> |
||
546 | <> var $next = this.$current.prevAll('li.level_' + (level - 1) + ':visible:first');> |
||
547 | <> this.$current.removeClass('current');> |
||
548 | <> $next.addClass('current');> |
||
549 | <> scrollIntoView($next[0], this.$element[0]);> |
||
550 | <> this.$current = $next;> |
||
551 | <> }> |
||
552 | <> }> |
||
553 | |||
554 | <> this.move = function(isDown) {> |
||
555 | <> if (!this.$current) {> |
||
556 | <> this.highlight(this.$list.find('li:first'));> |
||
557 | <> return true;> |
||
558 | <> } > |
||
559 | <> var next = this.$current[0];> |
||
560 | <> if (isDown) {> |
||
561 | <> do {> |
||
562 | <> next = next.nextSibling;> |
||
563 | <> if (next && next.style && next.style.display != 'none') break;> |
||
564 | <> } while(next);> |
||
565 | <> } else {> |
||
566 | <> do {> |
||
567 | <> next = next.previousSibling;> |
||
568 | <> if (next && next.style && next.style.display != 'none') break;> |
||
569 | <> } while(next);> |
||
570 | <> }> |
||
571 | <> if (next && next.className.indexOf('stopper') == -1) {> |
||
572 | <> this.$current.removeClass('current');> |
||
573 | <> $(next).addClass('current');> |
||
574 | <> scrollIntoView(next, this.$element[0]);> |
||
575 | <> this.$current = $(next);> |
||
576 | <> }> |
||
577 | <> return true;> |
||
578 | <> }> |
||
579 | |||
580 | <> function toggleVis($li, show) {> |
||
581 | <> var closed = $li.hasClass('closed'),> |
||
582 | <> children = $li[0].searchdoc_tree_data.children;> |
||
583 | <> $li.css('display', show ? '' : 'none')> |
||
584 | <> if (!show && this.$current && $li[0] == this.$current[0]) {> |
||
585 | <> this.$current.removeClass('current');> |
||
586 | <> this.$current = null;> |
||
587 | <> }> |
||
588 | <> for (var i=0, l = children.length; i < l; i++) {> |
||
589 | <> toggleVis.call(this, $(children[i].li), show && !closed);> |
||
590 | <> };> |
||
591 | <> }> |
||
592 | |||
593 | <> function buildAndAppendItem(item, level, before) {> |
||
594 | <> var li = renderItem(item, level),> |
||
595 | <> list = this.$list[0];> |
||
596 | <> item.li = li;> |
||
597 | <> list.insertBefore(li, before);> |
||
598 | <> for (var i=0, l = item[3].length; i < l; i++) {> |
||
599 | <> buildAndAppendItem.call(this, item[3][i], level + 1, before);> |
||
600 | <> };> |
||
601 | <> return li;> |
||
602 | <> }> |
||
603 | |||
604 | <> function renderItem(item, level) {> |
||
605 | <> var li = document.createElement('li'),> |
||
606 | <> cnt = document.createElement('div'),> |
||
607 | <> h1 = document.createElement('h1'),> |
||
608 | <> p = document.createElement('p'),> |
||
609 | <> icon, i;> |
||
610 | |||
611 | <> li.appendChild(cnt);> |
||
612 | <> li.style.paddingLeft = getOffset(level);> |
||
613 | <> cnt.className = 'content';> |
||
614 | <> if (!item[1]) li.className = 'empty ';> |
||
615 | <> cnt.appendChild(h1);> |
||
616 | <> // cnt.appendChild(p);> |
||
617 | <> h1.appendChild(document.createTextNode(item[0]));> |
||
618 | <> // p.appendChild(document.createTextNode(item[4]));> |
||
619 | <> if (item[2]) {> |
||
620 | <> i = document.createElement('i');> |
||
621 | <> i.appendChild(document.createTextNode(item[2]));> |
||
622 | <> h1.appendChild(i);> |
||
623 | <> }> |
||
624 | <> if (item[3].length > 0) {> |
||
625 | <> icon = document.createElement('div');> |
||
626 | <> icon.className = 'icon';> |
||
627 | <> cnt.appendChild(icon);> |
||
628 | <> }> |
||
629 | |||
630 | <> // user direct assignement instead of $()> |
||
631 | <> // it's 8x faster> |
||
632 | <> // $(li).data('path', item[1])> |
||
633 | <> // .data('children', item[3])> |
||
634 | <> // .data('level', level)> |
||
635 | <> // .css('display', level == 0 ? '' : 'none')> |
||
636 | <> // .addClass('level_' + level)> |
||
637 | <> // .addClass('closed');> |
||
638 | <> li.searchdoc_tree_data = {> |
||
639 | <> path: item[1],> |
||
640 | <> children: item[3],> |
||
641 | <> level: level> |
||
642 | <> }> |
||
643 | <> li.style.display = level == 0 ? '' : 'none';> |
||
644 | <> li.className += 'level_' + level + ' closed';> |
||
645 | <> return li;> |
||
646 | <> }> |
||
647 | |||
648 | <> function getOffset(level) {> |
||
649 | <> return 5 + 18*level + 'px';> |
||
650 | <> }> |
||
651 | <>});> |