voloko-sdoc 0.0.5 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. data/README +1 -1
  2. data/bin/sdoc +0 -1
  3. data/bin/sdoc-merge +12 -0
  4. data/lib/sdoc.rb +15 -7
  5. data/lib/sdoc/generator/shtml.rb +671 -0
  6. data/lib/sdoc/generator/template/shtml/_context.rhtml +163 -0
  7. data/lib/sdoc/generator/template/shtml/class.rhtml +46 -0
  8. data/lib/sdoc/generator/template/shtml/file.rhtml +37 -0
  9. data/lib/sdoc/generator/template/shtml/index.rhtml +14 -0
  10. data/lib/sdoc/generator/template/shtml/resources/css/main.css +191 -0
  11. data/lib/sdoc/{generators/template/shtml/resources/css/master-frameset.css → generator/template/shtml/resources/css/panel.css} +83 -2
  12. data/lib/sdoc/{generators → generator}/template/shtml/resources/css/reset.css +0 -0
  13. data/lib/sdoc/{generators → generator}/template/shtml/resources/i/arrows.png +0 -0
  14. data/lib/sdoc/{generators → generator}/template/shtml/resources/i/results_bg.png +0 -0
  15. data/lib/sdoc/{generators → generator}/template/shtml/resources/i/tree_bg.png +0 -0
  16. data/lib/sdoc/{generators → generator}/template/shtml/resources/js/jquery-1.3.2.min.js +0 -0
  17. data/lib/sdoc/generator/template/shtml/resources/js/main.js +34 -0
  18. data/lib/sdoc/generator/template/shtml/resources/js/searchdoc.js +600 -0
  19. data/lib/sdoc/{generators/template/shtml/resources/panel.html → generator/template/shtml/resources/panel/index.html} +6 -6
  20. data/lib/sdoc/github.rb +64 -0
  21. data/lib/sdoc/merge.rb +166 -0
  22. metadata +117 -19
  23. data/lib/sdoc/code_objects.rb +0 -17
  24. data/lib/sdoc/generators/shtml_generator.rb +0 -354
  25. data/lib/sdoc/generators/template/shtml/resources/js/searchdoc.js +0 -595
  26. data/lib/sdoc/generators/template/shtml/shtml.rb +0 -615
  27. data/lib/sdoc/options.rb +0 -61
  28. data/test/options_test.rb +0 -33
  29. data/test/sdoc_test.rb +0 -7
@@ -1,595 +0,0 @@
1
- Searchdoc = {};
2
- (function() {
3
- Searchdoc.Searcher = function(data) {
4
- this.data = data;
5
- this.handlers = [];
6
- }
7
-
8
- Searchdoc.Searcher.prototype = new function() {
9
- var CHUNK_SIZE = 1000, // search is performed in chunks of 1000 for non-bloking user input
10
- MAX_RESULTS = 100, // do not search more than 100 results
11
- huid = 0, suid = 0,
12
- runs = 0;
13
-
14
-
15
- this.find = function(query) {
16
- var queries = splitQuery(query),
17
- regexps = buildRegexps(queries),
18
- highlighters = buildHilighters(queries),
19
- state = { from: 0, pass: 0, limit: MAX_RESULTS, n: suid++},
20
- _this = this;
21
- if (this.lastQuery == query) return;
22
- this.lastQuery = query;
23
-
24
- if (!query) return;
25
-
26
- // console.log(runs);
27
- var run = function() {
28
- if (query != _this.lastQuery) return;
29
- triggerResults.call(_this, performSearch(regexps, queries, highlighters, state));
30
- if (state.limit > 0 && state.pass < 3) {
31
- setTimeout(run, 2);
32
- }
33
- runs++;
34
- };
35
- runs = 0;
36
- run();
37
- }
38
-
39
- this.ready = function(fn) {
40
- fn.huid = huid;
41
- this.handlers.push(fn);
42
- }
43
-
44
- function splitQuery(query) {
45
- return jQuery.grep(query.split(/\s+/), function(string) { return !!string });
46
- }
47
-
48
- function buildRegexps(queries) {
49
- return jQuery.map(queries, function(query) { return new RegExp(query.replace(/(.)/g, '([$1])([^$1]*?)'), 'i') });
50
- }
51
-
52
- function buildHilighters(queries) {
53
- return jQuery.map(queries, function(query) {
54
- return jQuery.map( query.split(''), function(l, i){ return '\u0001$' + (i*2+1) + '\u0002$' + (i*2+2) } ).join('')
55
- });
56
- }
57
-
58
- function longMatchRegexp(index, longIndex, regexps) {
59
- for (var i = regexps.length - 1; i >= 0; i--){
60
- if (!index.match(regexps[i]) && !longIndex.match(regexps[i])) return false;
61
- };
62
- return true;
63
- }
64
-
65
- function matchPass1(index, longIndex, queries, regexps) {
66
- if (index.indexOf(queries[0]) != 0) return false;
67
- for (var i=1, l = regexps.length; i < l; i++) {
68
- if (!index.match(regexps[i]) && !longIndex.match(regexps[i])) return false;
69
- };
70
- return true;
71
- }
72
-
73
- function matchPass2(index, longIndex, queries, regexps) {
74
- if (index.indexOf(queries[0]) == -1) return false;
75
- for (var i=1, l = regexps.length; i < l; i++) {
76
- if (!index.match(regexps[i]) && !longIndex.match(regexps[i])) return false;
77
- };
78
- return true;
79
- }
80
-
81
- function matchPassRegexp(index, longIndex, regexps) {
82
- for (var i=0, l = regexps.length; i < l; i++) {
83
- if (!index.match(regexps[i]) && (i == 0 || !longIndex.indexOf(regexps[i]))) return false;
84
- };
85
- return true;
86
- }
87
-
88
- function highlightRegexp(info, regexps, highlighters) {
89
- var result = createResult(info);
90
- for (var i=0, l = regexps.length; i < l; i++) {
91
- result.title = result.title.replace(regexps[i], highlighters[i]);
92
- if (i > 0)
93
- result.namespace = result.namespace.replace(regexps[i], highlighters[i]);
94
- };
95
- return result;
96
- }
97
-
98
- function hltSubstring(string, pos, length) {
99
- return string.substring(0, pos) + '\u0001' + string.substring(pos, pos + length) + '\u0002' + string.substring(pos + length);
100
- }
101
-
102
- function highlightQuery(info, queries, regexps, highlighters) {
103
- var result = createResult(info), pos = 0, lcTitle = result.title.toLowerCase();
104
- pos = lcTitle.indexOf(queries[0]);
105
- if (pos != -1) {
106
- result.title = hltSubstring(result.title, pos, queries[0].length);
107
- }
108
- for (var i=1, l = regexps.length; i < l; i++) {
109
- result.title = result.title.replace(regexps[i], highlighters[i]);
110
- result.namespace = result.namespace.replace(regexps[i], highlighters[i]);
111
- };
112
- return result;
113
- }
114
-
115
- function createResult(info) {
116
- var result = {};
117
- result.title = info[0];
118
- result.namespace = info[1];
119
- result.path = info[2];
120
- result.params = info[3];
121
- result.snippet = info[4];
122
- return result;
123
- }
124
-
125
- function triggerResults(results) {
126
- jQuery.each(this.handlers, function(i, fn) { fn.call(this, results) })
127
- }
128
-
129
- function performSearch(regexps, queries, highlighters, state) {
130
- var searchIndex = data.searchIndex, // search only by title first and then by source
131
- longSearchIndex = data.longSearchIndex,
132
- info = data.info,
133
- result = [],
134
- i = state.from,
135
- l = searchIndex.length,
136
- togo = CHUNK_SIZE;
137
- if (state.pass == 0) {
138
- for (; togo > 0 && i < l && state.limit > 0; i++, togo--) {
139
- if (matchPass1(searchIndex[i], longSearchIndex[i], queries, regexps)) {
140
- info[i].n = state.n;
141
- result.push(highlightQuery(info[i], queries, regexps, highlighters));
142
- state.limit--;
143
- }
144
- };
145
- }
146
- if (searchIndex.length <= i) {
147
- state.pass++;
148
- i = state.from = 0;
149
- }
150
- if (state.pass == 1) {
151
- for (; togo > 0 && i < l && state.limit > 0; i++, togo--) {
152
- if (info[i].n == state.n) continue;
153
- if (matchPass2(searchIndex[i], longSearchIndex[i], queries, regexps)) {
154
- info[i].n = state.n;
155
- result.push(highlightQuery(info[i], queries, regexps, highlighters));
156
- state.limit--;
157
- }
158
- };
159
- }
160
- if (searchIndex.length <= i) {
161
- state.pass++;
162
- i = state.from = 0;
163
- }
164
- if (state.pass == 2) {
165
- for (; togo > 0 && i < l && state.limit > 0; i++, togo--) {
166
- if (info[i].n == state.n) continue;
167
- if (matchPassRegexp(searchIndex[i], longSearchIndex[i], regexps)) {
168
- result.push(highlightRegexp(info[i], regexps, highlighters));
169
- state.limit--;
170
- }
171
- };
172
- }
173
- if (searchIndex.length <= i) {
174
- state.pass++;
175
- state.from = 0;
176
- } else {
177
- state.from = i;
178
- }
179
- return result;
180
- }
181
- }
182
-
183
-
184
-
185
- Searchdoc.Tree = function(element, tree, panel) {
186
- this.$element = $(element);
187
- this.$list = $('ul', element);
188
- this.tree = tree;
189
- this.panel = panel;
190
- this.init();
191
- }
192
-
193
- Searchdoc.Tree.prototype = new function() {
194
- this.init = function() {
195
- var stopper = document.createElement('li');
196
- stopper.className = 'stopper';
197
- this.$list[0].appendChild(stopper);
198
- for (var i=0, l = this.tree.length; i < l; i++) {
199
- buildAndAppendItem.call(this, this.tree[i], 0, stopper);
200
- };
201
- var _this = this;
202
- this.$list.click(function(e) {
203
- var $target = $(e.target),
204
- $li = $target.closest('li');
205
- if ($target.hasClass('icon')) {
206
- _this.toggle($li);
207
- } else {
208
- _this.select($li);
209
- }
210
- })
211
-
212
- $(document).keydown(function(e) {
213
- _this.onkeydown(e);
214
- }).keyup(function(e) {
215
- _this.onkeyup(e);
216
- })
217
-
218
- }
219
-
220
- this.select = function($li) {
221
- var path = $li.data('path');
222
- if (this.$current) this.$current.removeClass('current');
223
- this.$current = $li.addClass('current');
224
- if (path) this.panel.open(path);
225
- }
226
-
227
- this.toggle = function($li) {
228
- var closed = !$li.hasClass('closed'),
229
- children = $li.data('children');
230
- $li.toggleClass('closed');
231
- for (var i=0, l = children.length; i < l; i++) {
232
- toggleVis.call(this, $(children[i].li), !closed);
233
- };
234
- }
235
-
236
- this.onkeyup = function(e) {
237
- if (!this.active) return;
238
- switch(e.keyCode) {
239
- case 37: //Event.KEY_LEFT:
240
- case 38: //Event.KEY_UP:
241
- case 39: //Event.KEY_RIGHT:
242
- case 40: //Event.KEY_DOWN:
243
- this.clearMoveTimeout();
244
- break;
245
- }
246
- }
247
-
248
- this.onkeydown = function(e) {
249
- if (!this.active) return;
250
- switch(e.keyCode) {
251
- case 37: //Event.KEY_LEFT:
252
- this.moveLeft();
253
- e.preventDefault();
254
- break;
255
- case 38: //Event.KEY_UP:
256
- this.moveUp();
257
- e.preventDefault();
258
- this.startMoveTimeout(false);
259
- break;
260
- case 39: //Event.KEY_RIGHT:
261
- this.moveRight();
262
- e.preventDefault();
263
- break;
264
- case 40: //Event.KEY_DOWN:
265
- this.moveDown();
266
- e.preventDefault();
267
- this.startMoveTimeout(true);
268
- break;
269
- case 9: //Event.KEY_TAB:
270
- case 13: //Event.KEY_RETURN:
271
- if (this.$current) this.select(this.$current);
272
- break;
273
- }
274
- }
275
-
276
- this.clearMoveTimeout = function() {
277
- clearTimeout(this.moveTimeout);
278
- this.moveTimeout = null;
279
- }
280
-
281
- this.startMoveTimeout = function(isDown) {
282
- if (this.moveTimeout) this.clearMoveTimeout();
283
- var _this = this;
284
-
285
- var go = function() {
286
- if (!_this.moveTimeout) return;
287
- _this[isDown ? 'moveDown' : 'moveUp']();
288
- _this.moveTimout = setTimeout(go, 100);
289
- }
290
- this.moveTimeout = setTimeout(go, 200);
291
- }
292
-
293
- this.moveRight = function() {
294
- if (!this.$current) {
295
- this.select(this.$list.find('li:first'));
296
- return;
297
- }
298
- if (this.$current.hasClass('closed')) {
299
- this.toggle(this.$current);
300
- }
301
- }
302
-
303
- this.moveLeft = function() {
304
- if (!this.$current) {
305
- this.select(this.$list.find('li:first'));
306
- return;
307
- }
308
- if (!this.$current.hasClass('closed')) {
309
- this.toggle(this.$current);
310
- } else {
311
- var level = this.$current.data('level');
312
- if (level == 0) return;
313
- var $next = this.$current.prevAll('li.level_' + (level - 1) + ':visible:first');
314
- this.$current.removeClass('current');
315
- $next.addClass('current');
316
- scrollIntoView($next, this.$element);
317
- this.$current = $next;
318
- }
319
- }
320
-
321
- this.move = function(isDown) {
322
- if (!this.$current) {
323
- this.select(this.$list.find('li:first'));
324
- return;
325
- }
326
- var $next = this.$current[isDown ? 'nextAll' : 'prevAll']('li:visible:eq(0)');
327
- if ($next.length) {
328
- this.$current.removeClass('current');
329
- $next.addClass('current');
330
- scrollIntoView($next, this.$element);
331
- this.$current = $next;
332
- }
333
- }
334
-
335
- this.moveUp = function() {
336
- this.move(false);
337
- }
338
-
339
- this.moveDown = function() {
340
- this.move(true);
341
- }
342
-
343
- function toggleVis($li, show) {
344
- var closed = $li.hasClass('closed'),
345
- children = $li.data('children');
346
- $li.css('display', show ? '' : 'none')
347
- if (!show && this.$current && $li[0] == this.$current[0]) {
348
- this.$current.removeClass('current');
349
- this.$current = null;
350
- }
351
- for (var i=0, l = children.length; i < l; i++) {
352
- toggleVis.call(this, $(children[i].li), show && !closed);
353
- };
354
- }
355
-
356
- function buildAndAppendItem(item, level, before) {
357
- var li = renderItem(item, level),
358
- list = this.$list[0];
359
- item.li = li;
360
- list.insertBefore(li, before);
361
- for (var i=0, l = item[5].length; i < l; i++) {
362
- buildAndAppendItem.call(this, item[5][i], level + 1, before);
363
- };
364
- return li;
365
- }
366
-
367
- function renderItem(item, level) {
368
- var li = document.createElement('li'),
369
- cnt = document.createElement('div'),
370
- h1 = document.createElement('h1'),
371
- p = document.createElement('p'),
372
- icon, i;
373
-
374
- li.appendChild(cnt);
375
- li.style.paddingLeft = getOffset(level);
376
- cnt.className = 'content';
377
- if (!item[2]) li.className = 'empty';
378
- cnt.appendChild(h1);
379
- // cnt.appendChild(p);
380
- h1.appendChild(document.createTextNode(item[0]));
381
- // p.appendChild(document.createTextNode(item[4]));
382
- if (item[3]) {
383
- i = document.createElement('i');
384
- i.appendChild(document.createTextNode(item[3]));
385
- h1.appendChild(i);
386
- }
387
- if (item[5].length > 0) {
388
- icon = document.createElement('div');
389
- icon.className = 'icon';
390
- cnt.appendChild(icon);
391
- }
392
-
393
- $(li).data('path', item[2])
394
- .data('children', item[5])
395
- .data('level', level)
396
- .css('display', level == 0 ? '' : 'none')
397
- .addClass('level_' + level)
398
- .addClass('closed');
399
- return li;
400
- }
401
-
402
- function getOffset(level) {
403
- return 5 + 18*level + 'px';
404
- }
405
- }
406
-
407
-
408
-
409
- Searchdoc.Panel = function(element, data, tree, frame) {
410
- this.$element = $(element);
411
- this.$input = $('input', element).eq(0);
412
- this.$result = $('.result ul', element).eq(0);
413
- this.frame = frame;
414
- this.$current = null;
415
- this.$view = this.$result.parent();
416
- this.searcher = new Searchdoc.Searcher(data);
417
- this.tree = new Searchdoc.Tree($('.tree', element), tree, this);
418
- this.tree.active = true;
419
- this.init();
420
- }
421
-
422
- Searchdoc.Panel.prototype = new function() {
423
- var suid = 1;
424
-
425
- this.init = function() {
426
- var _this = this;
427
- this.$input.keyup(function() {
428
- _this.search(this.value);
429
- });
430
-
431
- this.$input.keydown(function(e) {
432
- _this.onkeydown(e);
433
- })
434
-
435
- this.$input.keyup(function(e) {
436
- _this.onkeyup(e);
437
- })
438
-
439
- this.searcher.ready(function(results) {
440
- _this.addResults(results);
441
- })
442
-
443
- this.$result.click(function(e) {
444
- _this.$current.removeClass('current');
445
- _this.$current = $(e.target).closest('li').addClass('current');
446
- _this.select();
447
- _this.$input.focus();
448
- });
449
- }
450
-
451
- this.search = function(value) {
452
- value = jQuery.trim(value).toLowerCase();
453
- if (value) {
454
- this.$element.removeClass('panel_tree').addClass('panel_results');
455
- this.tree.active = false;
456
- } else {
457
- this.$element.addClass('panel_tree').removeClass('panel_results');
458
- this.tree.active = true;
459
- }
460
- if (value != this.searcher.lastQuery) {
461
- this.$result.empty();
462
- this.$current = null;
463
- }
464
- this.firstRun = true;
465
- this.searcher.find(value);
466
- }
467
-
468
- this.addResults = function(results) {
469
- var target = this.$result.get(0);
470
- for (var i=0, l = results.length; i < l; i++) {
471
- target.appendChild(renderItem(results[i]));
472
- };
473
- if (this.firstRun && results.length > 0) {
474
- this.firstRun = false;
475
- this.$current = $(target.firstChild);
476
- this.$current.addClass('current');
477
- scrollIntoView(this.$current, this.$view)
478
- }
479
- if (jQuery.browser.msie) this.$element[0].className += '';
480
- }
481
-
482
- this.onkeyup = function(e) {
483
- if (this.tree.active) return;
484
- switch(e.keyCode) {
485
- case 38: //Event.KEY_UP:
486
- this.clearMoveTimeout();
487
- break;
488
- case 40: //Event.KEY_DOWN:
489
- this.clearMoveTimeout();
490
- break;
491
- }
492
- }
493
-
494
- this.onkeydown = function(e) {
495
- if (this.tree.active) return;
496
- switch(e.keyCode) {
497
- case 38: //Event.KEY_UP:
498
- this.moveUp();
499
- e.preventDefault();
500
- this.startMoveTimeout(false);
501
- break;
502
- case 40: //Event.KEY_DOWN:
503
- this.moveDown();
504
- e.preventDefault();
505
- this.startMoveTimeout(true);
506
- break;
507
- case 9: //Event.KEY_TAB:
508
- case 13: //Event.KEY_RETURN:
509
- this.select();
510
- break;
511
- }
512
- }
513
-
514
- this.clearMoveTimeout = function() {
515
- clearTimeout(this.moveTimeout);
516
- this.moveTimeout = null;
517
- }
518
-
519
- this.startMoveTimeout = function(isDown) {
520
- if (this.moveTimeout) this.clearMoveTimeout();
521
- var _this = this;
522
-
523
- var go = function() {
524
- if (!_this.moveTimeout) return;
525
- _this[isDown ? 'moveDown' : 'moveUp']();
526
- _this.moveTimout = setTimeout(go, 100);
527
- }
528
- this.moveTimeout = setTimeout(go, 200);
529
- }
530
-
531
- this.open = function(src) {
532
- this.frame.location = src;
533
- }
534
-
535
- this.select = function() {
536
- this.open(this.$current.data('path'));
537
- }
538
-
539
- this.move = function(isDown) {
540
- if (!this.$current) return;
541
- var $next = this.$current[isDown ? 'next' : 'prev']();
542
- if ($next.length) {
543
- this.$current.removeClass('current');
544
- $next.addClass('current');
545
- scrollIntoView($next, this.$view);
546
- this.$current = $next;
547
- }
548
- }
549
-
550
- this.moveUp = function() {
551
- this.move(false);
552
- }
553
-
554
- this.moveDown = function() {
555
- this.move(true);
556
- }
557
-
558
- function renderItem(result) {
559
- var li = document.createElement('li'),
560
- html = '';
561
- html += '<h1>' + hlt(result.title);
562
- if (result.params) html += '<i>' + result.params + '</i></h1>';
563
- html += '<p>' + hlt(result.namespace) + '</p>';
564
- if (result.snippet) html += '<p class="snippet">' + escapeHTML(result.snippet) + '</p>';
565
- li.innerHTML = html;
566
- jQuery.data(li, 'path', result.path);
567
- return li;
568
- }
569
-
570
- function hlt(html) {
571
- return escapeHTML(html).replace(/\u0001/g, '<b>').replace(/\u0002/g, '</b>')
572
- }
573
-
574
- function escapeHTML(html) {
575
- return html.replace(/[&<>]/g, function(c) {
576
- return '&#' + c.charCodeAt(0) + ';';
577
- });
578
- }
579
-
580
- }
581
-
582
- function scrollIntoView($element, $view) {
583
- var offset, viewHeight, viewScroll, height;
584
- offset = $element[0].offsetTop;
585
- height = $element[0].offsetHeight;
586
- viewHeight = $view[0].offsetHeight;
587
- viewScroll = $view[0].scrollTop;
588
- if (offset - viewScroll + height > viewHeight) {
589
- $view[0].scrollTop = offset - viewHeight + height;
590
- }
591
- if (offset < viewScroll) {
592
- $view[0].scrollTop = offset;
593
- }
594
- }
595
- })()