summaryrefslogtreecommitdiffstats
path: root/bitbake/lib/toaster/toastergui/static/js/jquery.treetable.js
diff options
context:
space:
mode:
Diffstat (limited to 'bitbake/lib/toaster/toastergui/static/js/jquery.treetable.js')
-rw-r--r--bitbake/lib/toaster/toastergui/static/js/jquery.treetable.js620
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='#'>&nbsp;</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);