dm-is-published 0.0.6 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. data/Gemfile +22 -0
  2. data/Guardfile +13 -0
  3. data/{LICENSE → LICENSE.txt} +1 -1
  4. data/README.rdoc +37 -5
  5. data/Rakefile +30 -56
  6. data/VERSION +1 -1
  7. data/dm-is-published.gemspec +93 -45
  8. data/docs/apple-touch-icon.png +0 -0
  9. data/docs/classes/DataMapper.html +81 -0
  10. data/docs/classes/DataMapper/Is.html +81 -0
  11. data/docs/classes/DataMapper/Is/Published.html +364 -0
  12. data/docs/classes/DataMapper/Is/Published/ClassMethods.html +237 -0
  13. data/docs/classes/DataMapper/Is/Published/InstanceMethods.html +132 -0
  14. data/docs/classes/DataMapper/Is/Published/ResourceInstanceMethods.html +133 -0
  15. data/docs/created.rid +4 -0
  16. data/docs/css/github.css +129 -0
  17. data/docs/css/main.css +333 -0
  18. data/docs/css/panel.css +384 -0
  19. data/docs/css/reset.css +48 -0
  20. data/docs/favicon.ico +0 -0
  21. data/docs/files/README_rdoc.html +226 -0
  22. data/docs/files/lib/dm-is-published_rb.html +84 -0
  23. data/docs/files/lib/is/published_rb.html +104 -0
  24. data/docs/i/arrows.png +0 -0
  25. data/docs/i/results_bg.png +0 -0
  26. data/docs/i/tree_bg.png +0 -0
  27. data/docs/index.html +13 -0
  28. data/docs/js/highlight.pack.js +1 -0
  29. data/docs/js/jquery-1.3.2.min.js +19 -0
  30. data/docs/js/jquery-effect.js +593 -0
  31. data/docs/js/main.js +24 -0
  32. data/docs/js/navigation.js +142 -0
  33. data/docs/js/search_index.js +1 -0
  34. data/docs/js/searchdoc.js +449 -0
  35. data/docs/js/searcher.js +228 -0
  36. data/docs/panel/index.html +73 -0
  37. data/docs/panel/links.html +12 -0
  38. data/docs/panel/tree.js +1 -0
  39. data/lib/dm-is-published.rb +3 -7
  40. data/lib/{dm-is-published/is → is}/published.rb +26 -10
  41. data/spec/{integration/published_spec.rb → dm-is-published_spec.rb} +48 -11
  42. data/spec/spec_helper.rb +12 -9
  43. metadata +264 -95
  44. data/.gitignore +0 -33
  45. data/History.rdoc +0 -4
  46. data/TODO +0 -0
  47. data/lib/dm-is-published/is/version.rb +0 -7
@@ -0,0 +1,24 @@
1
+ function toggleSource(id)
2
+ {
3
+ var src = $('#' + id).toggle();
4
+ var isVisible = src.is(':visible');
5
+ $('#l_' + id).html(isVisible ? 'hide' : 'show');
6
+ if (!src.data('syntax-higlighted')) {
7
+ src.data('syntax-higlighted', 1);
8
+ hljs.highlightBlock(src[0]);
9
+ }
10
+ }
11
+
12
+ window.highlight = function(url) {
13
+ var hash = url.match(/#([^#]+)$/)
14
+ if(hash) {
15
+ $('a[name=' + hash[1] + ']').parent().effect('highlight', {}, 'slow')
16
+ }
17
+ }
18
+
19
+ $(function() {
20
+ highlight('#' + location.hash);
21
+ $('.description pre').each(function() {
22
+ hljs.highlightBlock(this);
23
+ });
24
+ });
@@ -0,0 +1,142 @@
1
+ /*
2
+ * Navigation allows movement using the arrow keys through the search results.
3
+ *
4
+ * When using this library you will need to set scrollIntoView to the
5
+ * appropriate function for your layout. Use scrollInWindow if the container
6
+ * is not scrollable and scrollInElement if the container is a separate
7
+ * scrolling region.
8
+ */
9
+ Navigation = new function() {
10
+ this.initNavigation = function() {
11
+ var _this = this;
12
+
13
+ $(document).keydown(function(e) {
14
+ _this.onkeydown(e);
15
+ }).keyup(function(e) {
16
+ _this.onkeyup(e);
17
+ });
18
+
19
+ this.navigationActive = true;
20
+ }
21
+
22
+ this.setNavigationActive = function(state) {
23
+ this.navigationActive = state;
24
+ this.clearMoveTimeout();
25
+ }
26
+
27
+ this.onkeyup = function(e) {
28
+ if (!this.navigationActive) return;
29
+
30
+ switch(e.keyCode) {
31
+ case 37: //Event.KEY_LEFT:
32
+ case 38: //Event.KEY_UP:
33
+ case 39: //Event.KEY_RIGHT:
34
+ case 40: //Event.KEY_DOWN:
35
+ this.clearMoveTimeout();
36
+ break;
37
+ }
38
+ }
39
+
40
+ this.onkeydown = function(e) {
41
+ if (!this.navigationActive) return;
42
+ switch(e.keyCode) {
43
+ case 37: //Event.KEY_LEFT:
44
+ if (this.moveLeft()) e.preventDefault();
45
+ break;
46
+ case 38: //Event.KEY_UP:
47
+ if (e.keyCode == 38 || e.ctrlKey) {
48
+ if (this.moveUp()) e.preventDefault();
49
+ this.startMoveTimeout(false);
50
+ }
51
+ break;
52
+ case 39: //Event.KEY_RIGHT:
53
+ if (this.moveRight()) e.preventDefault();
54
+ break;
55
+ case 40: //Event.KEY_DOWN:
56
+ if (e.keyCode == 40 || e.ctrlKey) {
57
+ if (this.moveDown()) e.preventDefault();
58
+ this.startMoveTimeout(true);
59
+ }
60
+ break;
61
+ case 13: //Event.KEY_RETURN:
62
+ if (this.$current)
63
+ e.preventDefault();
64
+ this.select(this.$current);
65
+ break;
66
+ }
67
+ if (e.ctrlKey && e.shiftKey) this.select(this.$current);
68
+ }
69
+
70
+ this.clearMoveTimeout = function() {
71
+ clearTimeout(this.moveTimeout);
72
+ this.moveTimeout = null;
73
+ }
74
+
75
+ this.startMoveTimeout = function(isDown) {
76
+ if (!$.browser.mozilla && !$.browser.opera) return;
77
+ if (this.moveTimeout) this.clearMoveTimeout();
78
+ var _this = this;
79
+
80
+ var go = function() {
81
+ if (!_this.moveTimeout) return;
82
+ _this[isDown ? 'moveDown' : 'moveUp']();
83
+ _this.moveTimout = setTimeout(go, 100);
84
+ }
85
+ this.moveTimeout = setTimeout(go, 200);
86
+ }
87
+
88
+ this.moveRight = function() {
89
+ }
90
+
91
+ this.moveLeft = function() {
92
+ }
93
+
94
+ this.move = function(isDown) {
95
+ }
96
+
97
+ this.moveUp = function() {
98
+ return this.move(false);
99
+ }
100
+
101
+ this.moveDown = function() {
102
+ return this.move(true);
103
+ }
104
+
105
+ /*
106
+ * Scrolls to the given element in the scrollable element view.
107
+ */
108
+ this.scrollInElement = function(element, view) {
109
+ var offset, viewHeight, viewScroll, height;
110
+ offset = element.offsetTop;
111
+ height = element.offsetHeight;
112
+ viewHeight = view.offsetHeight;
113
+ viewScroll = view.scrollTop;
114
+
115
+ if (offset - viewScroll + height > viewHeight) {
116
+ view.scrollTop = offset - viewHeight + height;
117
+ }
118
+ if (offset < viewScroll) {
119
+ view.scrollTop = offset;
120
+ }
121
+ }
122
+
123
+ /*
124
+ * Scrolls to the given element in the window. The second argument is
125
+ * ignored
126
+ */
127
+ this.scrollInWindow = function(element, ignored) {
128
+ var offset, viewHeight, viewScroll, height;
129
+ offset = element.offsetTop;
130
+ height = element.offsetHeight;
131
+ viewHeight = window.innerHeight;
132
+ viewScroll = window.scrollY;
133
+
134
+ if (offset - viewScroll + height > viewHeight) {
135
+ window.scrollTo(window.scrollX, offset - viewHeight + height);
136
+ }
137
+ if (offset < viewScroll) {
138
+ window.scrollTo(window.scrollX, offset);
139
+ }
140
+ }
141
+ }
142
+
@@ -0,0 +1 @@
1
+ var search_data = {"index":{"searchIndex":["datamapper","is","published","classmethods","instancemethods","resourceinstancemethods","all()","is_published()","publish_states_as_json()","publishable?()","publishable?()","readme"],"longSearchIndex":["datamapper","datamapper::is","datamapper::is::published","datamapper::is::published::classmethods","datamapper::is::published::instancemethods","datamapper::is::published::resourceinstancemethods","datamapper::is::published::classmethods#all()","datamapper::is::published#is_published()","datamapper::is::published::classmethods#publish_states_as_json()","datamapper::is::published::instancemethods#publishable?()","datamapper::is::published::resourceinstancemethods#publishable?()",""],"info":[["DataMapper","","classes/DataMapper.html","",""],["DataMapper::Is","","classes/DataMapper/Is.html","",""],["DataMapper::Is::Published","","classes/DataMapper/Is/Published.html","","<p>dm-is-published\n<p>This plugin makes it very easy to add different states to your models, like\n‘draft’ vs …\n"],["DataMapper::Is::Published::ClassMethods","","classes/DataMapper/Is/Published/ClassMethods.html","",""],["DataMapper::Is::Published::InstanceMethods","","classes/DataMapper/Is/Published/InstanceMethods.html","",""],["DataMapper::Is::Published::ResourceInstanceMethods","","classes/DataMapper/Is/Published/ResourceInstanceMethods.html","",""],["all","DataMapper::Is::Published::ClassMethods","classes/DataMapper/Is/Published/ClassMethods.html#method-i-all","(*args)","<p>Overriding the normal #all method to add some extra sugar.\n<p>Examples\n\n<pre class=\"ruby\"><span class=\"ruby-constant\">Article</span>.<span class=\"ruby-identifier\">all</span> =<span class=\"ruby-operator\">&gt;</span> <span class=\"ruby-identifier\">returns</span> <span class=\"ruby-identifier\">all</span> <span class=\"ruby-constant\">Articles</span> <span class=\"ruby-operator\">...</span>\n</pre>\n"],["is_published","DataMapper::Is::Published","classes/DataMapper/Is/Published.html#method-i-is_published","(*args)","<p>method that adds a basic published status attribute to your model\n<p>params \n<p><code>states</code> - an array of 'states' ...\n"],["publish_states_as_json","DataMapper::Is::Published::ClassMethods","classes/DataMapper/Is/Published/ClassMethods.html#method-i-publish_states_as_json","()","<p>Returns a JSON representation of the publish states, where each state is\nrepresented as a lowercase …\n"],["publishable?","DataMapper::Is::Published::InstanceMethods","classes/DataMapper/Is/Published/InstanceMethods.html#method-i-publishable-3F","()","<p>Ensuring all models using this plugin responds to publishable? with true.\n<p>Examples\n\n<pre>@published_model.publishable? ...</pre>\n"],["publishable?","DataMapper::Is::Published::ResourceInstanceMethods","classes/DataMapper/Is/Published/ResourceInstanceMethods.html#method-i-publishable-3F","()","<p>Ensuring all models NOT using this plugin responds to publishable? with\nfalse.\n<p>Examples\n\n<pre>@unpublished_model.publishable? ...</pre>\n"],["README","","files/README_rdoc.html","","<p>dm-is-published\n<p>This plugin makes it very easy to add different states to your models, like\n‘draft’ vs …\n"]]}}
@@ -0,0 +1,449 @@
1
+ Searchdoc = {};
2
+
3
+ // navigation.js ------------------------------------------
4
+
5
+ Searchdoc.Navigation = new function() {
6
+ this.initNavigation = function() {
7
+ var _this = this;
8
+
9
+ $(document).keydown(function(e) {
10
+ _this.onkeydown(e);
11
+ }).keyup(function(e) {
12
+ _this.onkeyup(e);
13
+ });
14
+
15
+ this.navigationActive = true;
16
+ }
17
+
18
+ this.setNavigationActive = function(state) {
19
+ this.navigationActive = state;
20
+ this.clearMoveTimeout();
21
+ }
22
+
23
+
24
+ this.onkeyup = function(e) {
25
+ if (!this.navigationActive) return;
26
+ switch(e.keyCode) {
27
+ case 37: //Event.KEY_LEFT:
28
+ case 38: //Event.KEY_UP:
29
+ case 39: //Event.KEY_RIGHT:
30
+ case 40: //Event.KEY_DOWN:
31
+ case 73: // i - qwerty
32
+ case 74: // j
33
+ case 75: // k
34
+ case 76: // l
35
+ case 67: // c - dvorak
36
+ case 72: // h
37
+ case 84: // t
38
+ case 78: // n
39
+ this.clearMoveTimeout();
40
+ break;
41
+ }
42
+ }
43
+
44
+ this.onkeydown = function(e) {
45
+ if (!this.navigationActive) return;
46
+ switch(e.keyCode) {
47
+ case 37: //Event.KEY_LEFT:
48
+ case 74: // j (qwerty)
49
+ case 72: // h (dvorak)
50
+ if (this.moveLeft()) e.preventDefault();
51
+ break;
52
+ case 38: //Event.KEY_UP:
53
+ case 73: // i (qwerty)
54
+ case 67: // c (dvorak)
55
+ if (e.keyCode == 38 || e.ctrlKey) {
56
+ if (this.moveUp()) e.preventDefault();
57
+ this.startMoveTimeout(false);
58
+ }
59
+ break;
60
+ case 39: //Event.KEY_RIGHT:
61
+ case 76: // l (qwerty)
62
+ case 78: // n (dvorak)
63
+ if (this.moveRight()) e.preventDefault();
64
+ break;
65
+ case 40: //Event.KEY_DOWN:
66
+ case 75: // k (qwerty)
67
+ case 84: // t (dvorak)
68
+ if (e.keyCode == 40 || e.ctrlKey) {
69
+ if (this.moveDown()) e.preventDefault();
70
+ this.startMoveTimeout(true);
71
+ }
72
+ break;
73
+ case 9: //Event.KEY_TAB:
74
+ case 13: //Event.KEY_RETURN:
75
+ if (this.$current) this.select(this.$current);
76
+ break;
77
+ case 83: // s (qwerty)
78
+ case 79: // o (dvorak)
79
+ if (e.ctrlKey) {
80
+ $('#search').focus();
81
+ e.preventDefault();
82
+ }
83
+ break;
84
+ }
85
+ if (e.ctrlKey && e.shiftKey) this.select(this.$current);
86
+ }
87
+
88
+ this.clearMoveTimeout = function() {
89
+ clearTimeout(this.moveTimeout);
90
+ this.moveTimeout = null;
91
+ }
92
+
93
+ this.startMoveTimeout = function(isDown) {
94
+ if (!$.browser.mozilla && !$.browser.opera) return;
95
+ if (this.moveTimeout) this.clearMoveTimeout();
96
+ var _this = this;
97
+
98
+ var go = function() {
99
+ if (!_this.moveTimeout) return;
100
+ _this[isDown ? 'moveDown' : 'moveUp']();
101
+ _this.moveTimout = setTimeout(go, 100);
102
+ }
103
+ this.moveTimeout = setTimeout(go, 200);
104
+ }
105
+
106
+ this.moveRight = function() {
107
+ }
108
+
109
+ this.moveLeft = function() {
110
+ }
111
+
112
+ this.move = function(isDown) {
113
+ }
114
+
115
+ this.moveUp = function() {
116
+ return this.move(false);
117
+ }
118
+
119
+ this.moveDown = function() {
120
+ return this.move(true);
121
+ }
122
+ }
123
+
124
+
125
+ // scrollIntoView.js --------------------------------------
126
+
127
+ function scrollIntoView(element, view) {
128
+ var offset, viewHeight, viewScroll, height;
129
+ offset = element.offsetTop;
130
+ height = element.offsetHeight;
131
+ viewHeight = view.offsetHeight;
132
+ viewScroll = view.scrollTop;
133
+ if (offset - viewScroll + height > viewHeight) {
134
+ view.scrollTop = offset - viewHeight + height;
135
+ }
136
+ if (offset < viewScroll) {
137
+ view.scrollTop = offset;
138
+ }
139
+ }
140
+
141
+ // panel.js -----------------------------------------------
142
+
143
+ Searchdoc.Panel = function(element, data, tree, frame) {
144
+ this.$element = $(element);
145
+ this.$input = $('input', element).eq(0);
146
+ this.$result = $('.result ul', element).eq(0);
147
+ this.frame = frame;
148
+ this.$current = null;
149
+ this.$view = this.$result.parent();
150
+ this.data = data;
151
+ this.searcher = new Searcher(data.index);
152
+
153
+ this.tree = new Searchdoc.Tree($('.tree', element), tree, this);
154
+ this.init();
155
+ }
156
+
157
+ Searchdoc.Panel.prototype = $.extend({}, Searchdoc.Navigation, new function() {
158
+ var suid = 1;
159
+
160
+ this.init = function() {
161
+ var _this = this;
162
+ var observer = function() {
163
+ _this.search(_this.$input[0].value);
164
+ };
165
+ this.$input.keyup(observer);
166
+ this.$input.click(observer); // mac's clear field
167
+
168
+ this.searcher.ready(function(results, isLast) {
169
+ _this.addResults(results, isLast);
170
+ })
171
+
172
+ this.$result.click(function(e) {
173
+ _this.$current.removeClass('current');
174
+ _this.$current = $(e.target).closest('li').addClass('current');
175
+ _this.select();
176
+ _this.$input.focus();
177
+ });
178
+
179
+ this.initNavigation();
180
+ this.setNavigationActive(false);
181
+ }
182
+
183
+ this.search = function(value, selectFirstMatch) {
184
+ value = jQuery.trim(value).toLowerCase();
185
+ this.selectFirstMatch = selectFirstMatch;
186
+ if (value) {
187
+ this.$element.removeClass('panel_tree').addClass('panel_results');
188
+ this.tree.setNavigationActive(false);
189
+ this.setNavigationActive(true);
190
+ } else {
191
+ this.$element.addClass('panel_tree').removeClass('panel_results');
192
+ this.tree.setNavigationActive(true);
193
+ this.setNavigationActive(false);
194
+ }
195
+ if (value != this.lastQuery) {
196
+ this.lastQuery = value;
197
+ this.firstRun = true;
198
+ this.searcher.find(value);
199
+ }
200
+ }
201
+
202
+ this.addResults = function(results, isLast) {
203
+ var target = this.$result.get(0);
204
+ if (this.firstRun && (results.length > 0 || isLast)) {
205
+ this.$current = null;
206
+ this.$result.empty();
207
+ }
208
+ for (var i=0, l = results.length; i < l; i++) {
209
+ target.appendChild(renderItem.call(this, results[i]));
210
+ };
211
+ if (this.firstRun && results.length > 0) {
212
+ this.firstRun = false;
213
+ this.$current = $(target.firstChild);
214
+ this.$current.addClass('current');
215
+ if (this.selectFirstMatch) this.select();
216
+ scrollIntoView(this.$current[0], this.$view[0])
217
+ }
218
+ if (jQuery.browser.msie) this.$element[0].className += '';
219
+ }
220
+
221
+ this.open = function(src) {
222
+ this.frame.location.href = '../' + src;
223
+ if (this.frame.highlight) this.frame.highlight(src);
224
+ }
225
+
226
+ this.select = function() {
227
+ this.open(this.$current.data('path'));
228
+ }
229
+
230
+ this.move = function(isDown) {
231
+ if (!this.$current) return;
232
+ var $next = this.$current[isDown ? 'next' : 'prev']();
233
+ if ($next.length) {
234
+ this.$current.removeClass('current');
235
+ $next.addClass('current');
236
+ scrollIntoView($next[0], this.$view[0]);
237
+ this.$current = $next;
238
+ }
239
+ return true;
240
+ }
241
+
242
+ function renderItem(result) {
243
+ var li = document.createElement('li'),
244
+ html = '', badge = result.badge;
245
+ html += '<h1>' + hlt(result.title);
246
+ if (result.params) html += '<i>' + result.params + '</i>';
247
+ html += '</h1>';
248
+ html += '<p>';
249
+ if (typeof badge != 'undefined') {
250
+ html += '<span class="badge badge_' + (badge % 6 + 1) + '">' + escapeHTML(this.data.badges[badge] || 'unknown') + '</span>';
251
+ }
252
+ html += hlt(result.namespace) + '</p>';
253
+ if (result.snippet) html += '<p class="snippet">' + escapeHTML(result.snippet) + '</p>';
254
+ li.innerHTML = html;
255
+ jQuery.data(li, 'path', result.path);
256
+ return li;
257
+ }
258
+
259
+ function hlt(html) {
260
+ return escapeHTML(html).replace(/\u0001/g, '<b>').replace(/\u0002/g, '</b>')
261
+ }
262
+
263
+ function escapeHTML(html) {
264
+ return html.replace(/[&<>]/g, function(c) {
265
+ return '&#' + c.charCodeAt(0) + ';';
266
+ });
267
+ }
268
+
269
+ });
270
+
271
+ // tree.js ------------------------------------------------
272
+
273
+ Searchdoc.Tree = function(element, tree, panel) {
274
+ this.$element = $(element);
275
+ this.$list = $('ul', element);
276
+ this.tree = tree;
277
+ this.panel = panel;
278
+ this.init();
279
+ }
280
+
281
+ Searchdoc.Tree.prototype = $.extend({}, Searchdoc.Navigation, new function() {
282
+ this.init = function() {
283
+ var stopper = document.createElement('li');
284
+ stopper.className = 'stopper';
285
+ this.$list[0].appendChild(stopper);
286
+ for (var i=0, l = this.tree.length; i < l; i++) {
287
+ buildAndAppendItem.call(this, this.tree[i], 0, stopper);
288
+ };
289
+ var _this = this;
290
+ this.$list.click(function(e) {
291
+ var $target = $(e.target),
292
+ $li = $target.closest('li');
293
+ if ($target.hasClass('icon')) {
294
+ _this.toggle($li);
295
+ } else {
296
+ _this.select($li);
297
+ }
298
+ })
299
+
300
+ this.initNavigation();
301
+ if (jQuery.browser.msie) document.body.className += '';
302
+ }
303
+
304
+ this.select = function($li) {
305
+ this.highlight($li);
306
+ var path = $li[0].searchdoc_tree_data.path;
307
+ if (path) this.panel.open(path);
308
+ }
309
+
310
+ this.highlight = function($li) {
311
+ if (this.$current) this.$current.removeClass('current');
312
+ this.$current = $li.addClass('current');
313
+ }
314
+
315
+ this.toggle = function($li) {
316
+ var closed = !$li.hasClass('closed'),
317
+ children = $li[0].searchdoc_tree_data.children;
318
+ $li.toggleClass('closed');
319
+ for (var i=0, l = children.length; i < l; i++) {
320
+ toggleVis.call(this, $(children[i].li), !closed);
321
+ };
322
+ }
323
+
324
+ this.moveRight = function() {
325
+ if (!this.$current) {
326
+ this.highlight(this.$list.find('li:first'));
327
+ return;
328
+ }
329
+ if (this.$current.hasClass('closed')) {
330
+ this.toggle(this.$current);
331
+ }
332
+ }
333
+
334
+ this.moveLeft = function() {
335
+ if (!this.$current) {
336
+ this.highlight(this.$list.find('li:first'));
337
+ return;
338
+ }
339
+ if (!this.$current.hasClass('closed')) {
340
+ this.toggle(this.$current);
341
+ } else {
342
+ var level = this.$current[0].searchdoc_tree_data.level;
343
+ if (level == 0) return;
344
+ var $next = this.$current.prevAll('li.level_' + (level - 1) + ':visible:first');
345
+ this.$current.removeClass('current');
346
+ $next.addClass('current');
347
+ scrollIntoView($next[0], this.$element[0]);
348
+ this.$current = $next;
349
+ }
350
+ }
351
+
352
+ this.move = function(isDown) {
353
+ if (!this.$current) {
354
+ this.highlight(this.$list.find('li:first'));
355
+ return true;
356
+ }
357
+ var next = this.$current[0];
358
+ if (isDown) {
359
+ do {
360
+ next = next.nextSibling;
361
+ if (next && next.style && next.style.display != 'none') break;
362
+ } while(next);
363
+ } else {
364
+ do {
365
+ next = next.previousSibling;
366
+ if (next && next.style && next.style.display != 'none') break;
367
+ } while(next);
368
+ }
369
+ if (next && next.className.indexOf('stopper') == -1) {
370
+ this.$current.removeClass('current');
371
+ $(next).addClass('current');
372
+ scrollIntoView(next, this.$element[0]);
373
+ this.$current = $(next);
374
+ }
375
+ return true;
376
+ }
377
+
378
+ function toggleVis($li, show) {
379
+ var closed = $li.hasClass('closed'),
380
+ children = $li[0].searchdoc_tree_data.children;
381
+ $li.css('display', show ? '' : 'none')
382
+ if (!show && this.$current && $li[0] == this.$current[0]) {
383
+ this.$current.removeClass('current');
384
+ this.$current = null;
385
+ }
386
+ for (var i=0, l = children.length; i < l; i++) {
387
+ toggleVis.call(this, $(children[i].li), show && !closed);
388
+ };
389
+ }
390
+
391
+ function buildAndAppendItem(item, level, before) {
392
+ var li = renderItem(item, level),
393
+ list = this.$list[0];
394
+ item.li = li;
395
+ list.insertBefore(li, before);
396
+ for (var i=0, l = item[3].length; i < l; i++) {
397
+ buildAndAppendItem.call(this, item[3][i], level + 1, before);
398
+ };
399
+ return li;
400
+ }
401
+
402
+ function renderItem(item, level) {
403
+ var li = document.createElement('li'),
404
+ cnt = document.createElement('div'),
405
+ h1 = document.createElement('h1'),
406
+ p = document.createElement('p'),
407
+ icon, i;
408
+
409
+ li.appendChild(cnt);
410
+ li.style.paddingLeft = getOffset(level);
411
+ cnt.className = 'content';
412
+ if (!item[1]) li.className = 'empty ';
413
+ cnt.appendChild(h1);
414
+ // cnt.appendChild(p);
415
+ h1.appendChild(document.createTextNode(item[0]));
416
+ // p.appendChild(document.createTextNode(item[4]));
417
+ if (item[2]) {
418
+ i = document.createElement('i');
419
+ i.appendChild(document.createTextNode(item[2]));
420
+ h1.appendChild(i);
421
+ }
422
+ if (item[3].length > 0) {
423
+ icon = document.createElement('div');
424
+ icon.className = 'icon';
425
+ cnt.appendChild(icon);
426
+ }
427
+
428
+ // user direct assignement instead of $()
429
+ // it's 8x faster
430
+ // $(li).data('path', item[1])
431
+ // .data('children', item[3])
432
+ // .data('level', level)
433
+ // .css('display', level == 0 ? '' : 'none')
434
+ // .addClass('level_' + level)
435
+ // .addClass('closed');
436
+ li.searchdoc_tree_data = {
437
+ path: item[1],
438
+ children: item[3],
439
+ level: level
440
+ }
441
+ li.style.display = level == 0 ? '' : 'none';
442
+ li.className += 'level_' + level + ' closed';
443
+ return li;
444
+ }
445
+
446
+ function getOffset(level) {
447
+ return 5 + 18*level + 'px';
448
+ }
449
+ });