diff options
Diffstat (limited to 'bitbake/lib/toaster/toastergui/static/js/jquery.treetable.js')
-rw-r--r-- | bitbake/lib/toaster/toastergui/static/js/jquery.treetable.js | 620 |
1 files changed, 620 insertions, 0 deletions
diff --git a/bitbake/lib/toaster/toastergui/static/js/jquery.treetable.js b/bitbake/lib/toaster/toastergui/static/js/jquery.treetable.js new file mode 100644 index 0000000000..42e7427cc0 --- /dev/null +++ b/bitbake/lib/toaster/toastergui/static/js/jquery.treetable.js | |||
@@ -0,0 +1,620 @@ | |||
1 | /* | ||
2 | * jQuery treetable Plugin 3.1.0 | ||
3 | * http://ludo.cubicphuse.nl/jquery-treetable | ||
4 | * | ||
5 | * Copyright 2013, Ludo van den Boom | ||
6 | * Dual licensed under the MIT or GPL Version 2 licenses. | ||
7 | */ | ||
8 | (function() { | ||
9 | var $, Node, Tree, methods; | ||
10 | |||
11 | $ = jQuery; | ||
12 | |||
13 | Node = (function() { | ||
14 | function Node(row, tree, settings) { | ||
15 | var parentId; | ||
16 | |||
17 | this.row = row; | ||
18 | this.tree = tree; | ||
19 | this.settings = settings; | ||
20 | |||
21 | // TODO Ensure id/parentId is always a string (not int) | ||
22 | this.id = this.row.data(this.settings.nodeIdAttr); | ||
23 | |||
24 | // TODO Move this to a setParentId function? | ||
25 | parentId = this.row.data(this.settings.parentIdAttr); | ||
26 | if (parentId != null && parentId !== "") { | ||
27 | this.parentId = parentId; | ||
28 | } | ||
29 | |||
30 | this.treeCell = $(this.row.children(this.settings.columnElType)[this.settings.column]); | ||
31 | this.expander = $(this.settings.expanderTemplate); | ||
32 | this.indenter = $(this.settings.indenterTemplate); | ||
33 | this.children = []; | ||
34 | this.initialized = false; | ||
35 | this.treeCell.prepend(this.indenter); | ||
36 | } | ||
37 | |||
38 | Node.prototype.addChild = function(child) { | ||
39 | return this.children.push(child); | ||
40 | }; | ||
41 | |||
42 | Node.prototype.ancestors = function() { | ||
43 | var ancestors, node; | ||
44 | node = this; | ||
45 | ancestors = []; | ||
46 | while (node = node.parentNode()) { | ||
47 | ancestors.push(node); | ||
48 | } | ||
49 | return ancestors; | ||
50 | }; | ||
51 | |||
52 | Node.prototype.collapse = function() { | ||
53 | if (this.collapsed()) { | ||
54 | return this; | ||
55 | } | ||
56 | |||
57 | this.row.removeClass("expanded").addClass("collapsed"); | ||
58 | |||
59 | this._hideChildren(); | ||
60 | this.expander.attr("title", this.settings.stringExpand); | ||
61 | |||
62 | if (this.initialized && this.settings.onNodeCollapse != null) { | ||
63 | this.settings.onNodeCollapse.apply(this); | ||
64 | } | ||
65 | |||
66 | return this; | ||
67 | }; | ||
68 | |||
69 | Node.prototype.collapsed = function() { | ||
70 | return this.row.hasClass("collapsed"); | ||
71 | }; | ||
72 | |||
73 | // TODO destroy: remove event handlers, expander, indenter, etc. | ||
74 | |||
75 | Node.prototype.expand = function() { | ||
76 | if (this.expanded()) { | ||
77 | return this; | ||
78 | } | ||
79 | |||
80 | this.row.removeClass("collapsed").addClass("expanded"); | ||
81 | |||
82 | if (this.initialized && this.settings.onNodeExpand != null) { | ||
83 | this.settings.onNodeExpand.apply(this); | ||
84 | } | ||
85 | |||
86 | if ($(this.row).is(":visible")) { | ||
87 | this._showChildren(); | ||
88 | } | ||
89 | |||
90 | this.expander.attr("title", this.settings.stringCollapse); | ||
91 | |||
92 | return this; | ||
93 | }; | ||
94 | |||
95 | Node.prototype.expanded = function() { | ||
96 | return this.row.hasClass("expanded"); | ||
97 | }; | ||
98 | |||
99 | Node.prototype.hide = function() { | ||
100 | this._hideChildren(); | ||
101 | this.row.hide(); | ||
102 | return this; | ||
103 | }; | ||
104 | |||
105 | Node.prototype.isBranchNode = function() { | ||
106 | if(this.children.length > 0 || this.row.data(this.settings.branchAttr) === true) { | ||
107 | return true; | ||
108 | } else { | ||
109 | return false; | ||
110 | } | ||
111 | }; | ||
112 | |||
113 | Node.prototype.updateBranchLeafClass = function(){ | ||
114 | this.row.removeClass('branch'); | ||
115 | this.row.removeClass('leaf'); | ||
116 | this.row.addClass(this.isBranchNode() ? 'branch' : 'leaf'); | ||
117 | }; | ||
118 | |||
119 | Node.prototype.level = function() { | ||
120 | return this.ancestors().length; | ||
121 | }; | ||
122 | |||
123 | Node.prototype.parentNode = function() { | ||
124 | if (this.parentId != null) { | ||
125 | return this.tree[this.parentId]; | ||
126 | } else { | ||
127 | return null; | ||
128 | } | ||
129 | }; | ||
130 | |||
131 | Node.prototype.removeChild = function(child) { | ||
132 | var i = $.inArray(child, this.children); | ||
133 | return this.children.splice(i, 1) | ||
134 | }; | ||
135 | |||
136 | Node.prototype.render = function() { | ||
137 | var handler, | ||
138 | settings = this.settings, | ||
139 | target; | ||
140 | |||
141 | if (settings.expandable === true && this.isBranchNode()) { | ||
142 | handler = function(e) { | ||
143 | $(this).parents("table").treetable("node", $(this).parents("tr").data(settings.nodeIdAttr)).toggle(); | ||
144 | return e.preventDefault(); | ||
145 | }; | ||
146 | |||
147 | this.indenter.html(this.expander); | ||
148 | target = settings.clickableNodeNames === true ? this.treeCell : this.expander; | ||
149 | |||
150 | target.off("click.treetable").on("click.treetable", handler); | ||
151 | target.off("keydown.treetable").on("keydown.treetable", function(e) { | ||
152 | if (e.keyCode == 13) { | ||
153 | handler.apply(this, [e]); | ||
154 | } | ||
155 | }); | ||
156 | } | ||
157 | |||
158 | this.indenter[0].style.paddingLeft = "" + (this.level() * settings.indent) + "px"; | ||
159 | |||
160 | return this; | ||
161 | }; | ||
162 | |||
163 | Node.prototype.reveal = function() { | ||
164 | if (this.parentId != null) { | ||
165 | this.parentNode().reveal(); | ||
166 | } | ||
167 | return this.expand(); | ||
168 | }; | ||
169 | |||
170 | Node.prototype.setParent = function(node) { | ||
171 | if (this.parentId != null) { | ||
172 | this.tree[this.parentId].removeChild(this); | ||
173 | } | ||
174 | this.parentId = node.id; | ||
175 | this.row.data(this.settings.parentIdAttr, node.id); | ||
176 | return node.addChild(this); | ||
177 | }; | ||
178 | |||
179 | Node.prototype.show = function() { | ||
180 | if (!this.initialized) { | ||
181 | this._initialize(); | ||
182 | } | ||
183 | this.row.show(); | ||
184 | if (this.expanded()) { | ||
185 | this._showChildren(); | ||
186 | } | ||
187 | return this; | ||
188 | }; | ||
189 | |||
190 | Node.prototype.toggle = function() { | ||
191 | if (this.expanded()) { | ||
192 | this.collapse(); | ||
193 | } else { | ||
194 | this.expand(); | ||
195 | } | ||
196 | return this; | ||
197 | }; | ||
198 | |||
199 | Node.prototype._hideChildren = function() { | ||
200 | var child, _i, _len, _ref, _results; | ||
201 | _ref = this.children; | ||
202 | _results = []; | ||
203 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { | ||
204 | child = _ref[_i]; | ||
205 | _results.push(child.hide()); | ||
206 | } | ||
207 | return _results; | ||
208 | }; | ||
209 | |||
210 | Node.prototype._initialize = function() { | ||
211 | var settings = this.settings; | ||
212 | |||
213 | this.render(); | ||
214 | |||
215 | if (settings.expandable === true && settings.initialState === "collapsed") { | ||
216 | this.collapse(); | ||
217 | } else { | ||
218 | this.expand(); | ||
219 | } | ||
220 | |||
221 | if (settings.onNodeInitialized != null) { | ||
222 | settings.onNodeInitialized.apply(this); | ||
223 | } | ||
224 | |||
225 | return this.initialized = true; | ||
226 | }; | ||
227 | |||
228 | Node.prototype._showChildren = function() { | ||
229 | var child, _i, _len, _ref, _results; | ||
230 | _ref = this.children; | ||
231 | _results = []; | ||
232 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { | ||
233 | child = _ref[_i]; | ||
234 | _results.push(child.show()); | ||
235 | } | ||
236 | return _results; | ||
237 | }; | ||
238 | |||
239 | return Node; | ||
240 | })(); | ||
241 | |||
242 | Tree = (function() { | ||
243 | function Tree(table, settings) { | ||
244 | this.table = table; | ||
245 | this.settings = settings; | ||
246 | this.tree = {}; | ||
247 | |||
248 | // Cache the nodes and roots in simple arrays for quick access/iteration | ||
249 | this.nodes = []; | ||
250 | this.roots = []; | ||
251 | } | ||
252 | |||
253 | Tree.prototype.collapseAll = function() { | ||
254 | var node, _i, _len, _ref, _results; | ||
255 | _ref = this.nodes; | ||
256 | _results = []; | ||
257 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { | ||
258 | node = _ref[_i]; | ||
259 | _results.push(node.collapse()); | ||
260 | } | ||
261 | return _results; | ||
262 | }; | ||
263 | |||
264 | Tree.prototype.expandAll = function() { | ||
265 | var node, _i, _len, _ref, _results; | ||
266 | _ref = this.nodes; | ||
267 | _results = []; | ||
268 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { | ||
269 | node = _ref[_i]; | ||
270 | _results.push(node.expand()); | ||
271 | } | ||
272 | return _results; | ||
273 | }; | ||
274 | |||
275 | Tree.prototype.findLastNode = function (node) { | ||
276 | if (node.children.length > 0) { | ||
277 | return this.findLastNode(node.children[node.children.length - 1]); | ||
278 | } else { | ||
279 | return node; | ||
280 | } | ||
281 | }; | ||
282 | |||
283 | Tree.prototype.loadRows = function(rows) { | ||
284 | var node, row, i; | ||
285 | |||
286 | if (rows != null) { | ||
287 | for (i = 0; i < rows.length; i++) { | ||
288 | row = $(rows[i]); | ||
289 | |||
290 | if (row.data(this.settings.nodeIdAttr) != null) { | ||
291 | node = new Node(row, this.tree, this.settings); | ||
292 | this.nodes.push(node); | ||
293 | this.tree[node.id] = node; | ||
294 | |||
295 | if (node.parentId != null) { | ||
296 | this.tree[node.parentId].addChild(node); | ||
297 | } else { | ||
298 | this.roots.push(node); | ||
299 | } | ||
300 | } | ||
301 | } | ||
302 | } | ||
303 | |||
304 | for (i = 0; i < this.nodes.length; i++) { | ||
305 | node = this.nodes[i].updateBranchLeafClass(); | ||
306 | } | ||
307 | |||
308 | return this; | ||
309 | }; | ||
310 | |||
311 | Tree.prototype.move = function(node, destination) { | ||
312 | // Conditions: | ||
313 | // 1: +node+ should not be inserted as a child of +node+ itself. | ||
314 | // 2: +destination+ should not be the same as +node+'s current parent (this | ||
315 | // prevents +node+ from being moved to the same location where it already | ||
316 | // is). | ||
317 | // 3: +node+ should not be inserted in a location in a branch if this would | ||
318 | // result in +node+ being an ancestor of itself. | ||
319 | var nodeParent = node.parentNode(); | ||
320 | if (node !== destination && destination.id !== node.parentId && $.inArray(node, destination.ancestors()) === -1) { | ||
321 | node.setParent(destination); | ||
322 | this._moveRows(node, destination); | ||
323 | |||
324 | // Re-render parentNode if this is its first child node, and therefore | ||
325 | // doesn't have the expander yet. | ||
326 | if (node.parentNode().children.length === 1) { | ||
327 | node.parentNode().render(); | ||
328 | } | ||
329 | } | ||
330 | |||
331 | if(nodeParent){ | ||
332 | nodeParent.updateBranchLeafClass(); | ||
333 | } | ||
334 | if(node.parentNode()){ | ||
335 | node.parentNode().updateBranchLeafClass(); | ||
336 | } | ||
337 | node.updateBranchLeafClass(); | ||
338 | return this; | ||
339 | }; | ||
340 | |||
341 | Tree.prototype.removeNode = function(node) { | ||
342 | // Recursively remove all descendants of +node+ | ||
343 | this.unloadBranch(node); | ||
344 | |||
345 | // Remove node from DOM (<tr>) | ||
346 | node.row.remove(); | ||
347 | |||
348 | // Clean up Tree object (so Node objects are GC-ed) | ||
349 | delete this.tree[node.id]; | ||
350 | this.nodes.splice($.inArray(node, this.nodes), 1); | ||
351 | } | ||
352 | |||
353 | Tree.prototype.render = function() { | ||
354 | var root, _i, _len, _ref; | ||
355 | _ref = this.roots; | ||
356 | for (_i = 0, _len = _ref.length; _i < _len; _i++) { | ||
357 | root = _ref[_i]; | ||
358 | |||
359 | // Naming is confusing (show/render). I do not call render on node from | ||
360 | // here. | ||
361 | root.show(); | ||
362 | } | ||
363 | return this; | ||
364 | }; | ||
365 | |||
366 | Tree.prototype.sortBranch = function(node, sortFun) { | ||
367 | // First sort internal array of children | ||
368 | node.children.sort(sortFun); | ||
369 | |||
370 | // Next render rows in correct order on page | ||
371 | this._sortChildRows(node); | ||
372 | |||
373 | return this; | ||
374 | }; | ||
375 | |||
376 | Tree.prototype.unloadBranch = function(node) { | ||
377 | var children, i; | ||
378 | |||
379 | for (i = 0; i < node.children.length; i++) { | ||
380 | this.removeNode(node.children[i]); | ||
381 | } | ||
382 | |||
383 | // Reset node's collection of children | ||
384 | node.children = []; | ||
385 | |||
386 | node.updateBranchLeafClass(); | ||
387 | |||
388 | return this; | ||
389 | }; | ||
390 | |||
391 | Tree.prototype._moveRows = function(node, destination) { | ||
392 | var children = node.children, i; | ||
393 | |||
394 | node.row.insertAfter(destination.row); | ||
395 | node.render(); | ||
396 | |||
397 | // Loop backwards through children to have them end up on UI in correct | ||
398 | // order (see #112) | ||
399 | for (i = children.length - 1; i >= 0; i--) { | ||
400 | this._moveRows(children[i], node); | ||
401 | } | ||
402 | }; | ||
403 | |||
404 | // Special _moveRows case, move children to itself to force sorting | ||
405 | Tree.prototype._sortChildRows = function(parentNode) { | ||
406 | return this._moveRows(parentNode, parentNode); | ||
407 | }; | ||
408 | |||
409 | return Tree; | ||
410 | })(); | ||
411 | |||
412 | // jQuery Plugin | ||
413 | methods = { | ||
414 | init: function(options, force) { | ||
415 | var settings; | ||
416 | |||
417 | settings = $.extend({ | ||
418 | branchAttr: "ttBranch", | ||
419 | clickableNodeNames: false, | ||
420 | column: 0, | ||
421 | columnElType: "td", // i.e. 'td', 'th' or 'td,th' | ||
422 | expandable: false, | ||
423 | expanderTemplate: "<a href='#'> </a>", | ||
424 | indent: 19, | ||
425 | indenterTemplate: "<span class='indenter'></span>", | ||
426 | initialState: "collapsed", | ||
427 | nodeIdAttr: "ttId", // maps to data-tt-id | ||
428 | parentIdAttr: "ttParentId", // maps to data-tt-parent-id | ||
429 | stringExpand: "Expand", | ||
430 | stringCollapse: "Collapse", | ||
431 | |||
432 | // Events | ||
433 | onInitialized: null, | ||
434 | onNodeCollapse: null, | ||
435 | onNodeExpand: null, | ||
436 | onNodeInitialized: null | ||
437 | }, options); | ||
438 | |||
439 | return this.each(function() { | ||
440 | var el = $(this), tree; | ||
441 | |||
442 | if (force || el.data("treetable") === undefined) { | ||
443 | tree = new Tree(this, settings); | ||
444 | tree.loadRows(this.rows).render(); | ||
445 | |||
446 | el.addClass("treetable").data("treetable", tree); | ||
447 | |||
448 | if (settings.onInitialized != null) { | ||
449 | settings.onInitialized.apply(tree); | ||
450 | } | ||
451 | } | ||
452 | |||
453 | return el; | ||
454 | }); | ||
455 | }, | ||
456 | |||
457 | destroy: function() { | ||
458 | return this.each(function() { | ||
459 | return $(this).removeData("treetable").removeClass("treetable"); | ||
460 | }); | ||
461 | }, | ||
462 | |||
463 | collapseAll: function() { | ||
464 | this.data("treetable").collapseAll(); | ||
465 | return this; | ||
466 | }, | ||
467 | |||
468 | collapseNode: function(id) { | ||
469 | var node = this.data("treetable").tree[id]; | ||
470 | |||
471 | if (node) { | ||
472 | node.collapse(); | ||
473 | } else { | ||
474 | throw new Error("Unknown node '" + id + "'"); | ||
475 | } | ||
476 | |||
477 | return this; | ||
478 | }, | ||
479 | |||
480 | expandAll: function() { | ||
481 | this.data("treetable").expandAll(); | ||
482 | return this; | ||
483 | }, | ||
484 | |||
485 | expandNode: function(id) { | ||
486 | var node = this.data("treetable").tree[id]; | ||
487 | |||
488 | if (node) { | ||
489 | if (!node.initialized) { | ||
490 | node._initialize(); | ||
491 | } | ||
492 | |||
493 | node.expand(); | ||
494 | } else { | ||
495 | throw new Error("Unknown node '" + id + "'"); | ||
496 | } | ||
497 | |||
498 | return this; | ||
499 | }, | ||
500 | |||
501 | loadBranch: function(node, rows) { | ||
502 | var settings = this.data("treetable").settings, | ||
503 | tree = this.data("treetable").tree; | ||
504 | |||
505 | // TODO Switch to $.parseHTML | ||
506 | rows = $(rows); | ||
507 | |||
508 | if (node == null) { // Inserting new root nodes | ||
509 | this.append(rows); | ||
510 | } else { | ||
511 | var lastNode = this.data("treetable").findLastNode(node); | ||
512 | rows.insertAfter(lastNode.row); | ||
513 | } | ||
514 | |||
515 | this.data("treetable").loadRows(rows); | ||
516 | |||
517 | // Make sure nodes are properly initialized | ||
518 | rows.filter("tr").each(function() { | ||
519 | tree[$(this).data(settings.nodeIdAttr)].show(); | ||
520 | }); | ||
521 | |||
522 | if (node != null) { | ||
523 | // Re-render parent to ensure expander icon is shown (#79) | ||
524 | node.render().expand(); | ||
525 | } | ||
526 | |||
527 | return this; | ||
528 | }, | ||
529 | |||
530 | move: function(nodeId, destinationId) { | ||
531 | var destination, node; | ||
532 | |||
533 | node = this.data("treetable").tree[nodeId]; | ||
534 | destination = this.data("treetable").tree[destinationId]; | ||
535 | this.data("treetable").move(node, destination); | ||
536 | |||
537 | return this; | ||
538 | }, | ||
539 | |||
540 | node: function(id) { | ||
541 | return this.data("treetable").tree[id]; | ||
542 | }, | ||
543 | |||
544 | removeNode: function(id) { | ||
545 | var node = this.data("treetable").tree[id]; | ||
546 | |||
547 | if (node) { | ||
548 | this.data("treetable").removeNode(node); | ||
549 | } else { | ||
550 | throw new Error("Unknown node '" + id + "'"); | ||
551 | } | ||
552 | |||
553 | return this; | ||
554 | }, | ||
555 | |||
556 | reveal: function(id) { | ||
557 | var node = this.data("treetable").tree[id]; | ||
558 | |||
559 | if (node) { | ||
560 | node.reveal(); | ||
561 | } else { | ||
562 | throw new Error("Unknown node '" + id + "'"); | ||
563 | } | ||
564 | |||
565 | return this; | ||
566 | }, | ||
567 | |||
568 | sortBranch: function(node, columnOrFunction) { | ||
569 | var settings = this.data("treetable").settings, | ||
570 | prepValue, | ||
571 | sortFun; | ||
572 | |||
573 | columnOrFunction = columnOrFunction || settings.column; | ||
574 | sortFun = columnOrFunction; | ||
575 | |||
576 | if ($.isNumeric(columnOrFunction)) { | ||
577 | sortFun = function(a, b) { | ||
578 | var extractValue, valA, valB; | ||
579 | |||
580 | extractValue = function(node) { | ||
581 | var val = node.row.find("td:eq(" + columnOrFunction + ")").text(); | ||
582 | // Ignore trailing/leading whitespace and use uppercase values for | ||
583 | // case insensitive ordering | ||
584 | return $.trim(val).toUpperCase(); | ||
585 | } | ||
586 | |||
587 | valA = extractValue(a); | ||
588 | valB = extractValue(b); | ||
589 | |||
590 | if (valA < valB) return -1; | ||
591 | if (valA > valB) return 1; | ||
592 | return 0; | ||
593 | }; | ||
594 | } | ||
595 | |||
596 | this.data("treetable").sortBranch(node, sortFun); | ||
597 | return this; | ||
598 | }, | ||
599 | |||
600 | unloadBranch: function(node) { | ||
601 | this.data("treetable").unloadBranch(node); | ||
602 | return this; | ||
603 | } | ||
604 | }; | ||
605 | |||
606 | $.fn.treetable = function(method) { | ||
607 | if (methods[method]) { | ||
608 | return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); | ||
609 | } else if (typeof method === 'object' || !method) { | ||
610 | return methods.init.apply(this, arguments); | ||
611 | } else { | ||
612 | return $.error("Method " + method + " does not exist on jQuery.treetable"); | ||
613 | } | ||
614 | }; | ||
615 | |||
616 | // Expose classes to world | ||
617 | this.TreeTable || (this.TreeTable = {}); | ||
618 | this.TreeTable.Node = Node; | ||
619 | this.TreeTable.Tree = Tree; | ||
620 | }).call(this); | ||