first commit
[step2_drupal.git] / devel / krumo / docs / media / lib / classTree.js
blob5989426f084cceb577f9d96914f6f782a0690cf2
1 /*----------------------------------------\\r
2 |      Cross Browser Tree Widget 1.1      |\r
3 |-----------------------------------------|\r
4 | Created by Emil A. Eklund (eae@eae.net) |\r
5 |    For WebFX (http://webfx.eae.net/)    |\r
6 |-----------------------------------------|\r
7 | This script is  provided as is  without |\r
8 | any warranty whatsoever. It may be used |\r
9 | free of charge for non commerical sites |\r
10 | For commerical use contact  the  author |\r
11 | of this script for further details.     |\r
12 |-----------------------------------------|\r
13 | Created 2000-12-11 | Updated 2001-09-06 |\r
14 \----------------------------------------*/\r
16 var webFXTreeConfig = {\r
17         rootIcon        : 'media/images/empty.png',\r
18         openRootIcon    : 'media/images/empty.png',\r
19         folderIcon      : 'media/images/empty.png',\r
20         openFolderIcon  : 'media/images/empty.png',\r
21         fileIcon        : 'media/images/empty.png',\r
22         iIcon           : 'media/images/I.png',\r
23         lIcon           : 'media/images/L.png',\r
24         lMinusIcon      : 'media/images/Lminus.png',\r
25         lPlusIcon       : 'media/images/Lplus.png',\r
26         tIcon           : 'media/images/T.png',\r
27         tMinusIcon      : 'media/images/Tminus.png',\r
28         tPlusIcon       : 'media/images/Tplus.png',\r
29         blankIcon       : 'media/images/blank.png',\r
30         defaultText     : 'Tree Item',\r
31         defaultAction   : 'javascript:void(0);',\r
32         defaultTarget   : 'right',\r
33         defaultBehavior : 'classic'\r
34 };\r
36 var webFXTreeHandler = {\r
37         idCounter : 0,\r
38         idPrefix  : "webfx-tree-object-",\r
39         all       : {},\r
40         behavior  : null,\r
41         selected  : null,\r
42         getId     : function() { return this.idPrefix + this.idCounter++; },\r
43         toggle    : function (oItem) { this.all[oItem.id.replace('-plus','')].toggle(); },\r
44         select    : function (oItem) { this.all[oItem.id.replace('-icon','')].select(); },\r
45         focus     : function (oItem) { this.all[oItem.id.replace('-anchor','')].focus(); },\r
46         blur      : function (oItem) { this.all[oItem.id.replace('-anchor','')].blur(); },\r
47         keydown   : function (oItem) { return this.all[oItem.id].keydown(window.event.keyCode); },\r
48         cookies   : new WebFXCookie()\r
49 };\r
51 /*\r
52  * WebFXCookie class\r
53  */\r
55 function WebFXCookie() {\r
56         if (document.cookie.length) { this.cookies = ' ' + document.cookie; }\r
57 }\r
59 WebFXCookie.prototype.setCookie = function (key, value) {\r
60         document.cookie = key + "=" + escape(value);\r
61 }\r
63 WebFXCookie.prototype.getCookie = function (key) {\r
64         if (this.cookies) {\r
65                 var start = this.cookies.indexOf(' ' + key + '=');\r
66                 if (start == -1) { return null; }\r
67                 var end = this.cookies.indexOf(";", start);\r
68                 if (end == -1) { end = this.cookies.length; }\r
69                 end -= start;\r
70                 var cookie = this.cookies.substr(start,end);\r
71                 return unescape(cookie.substr(cookie.indexOf('=') + 1, cookie.length - cookie.indexOf('=') + 1));\r
72         }\r
73         else { return null; }\r
74 }\r
76 /*\r
77  * WebFXTreeAbstractNode class\r
78  */\r
80 function WebFXTreeAbstractNode(sText, sAction, sTarget) {\r
81         this.childNodes  = [];\r
82         this.id     = webFXTreeHandler.getId();\r
83         this.text   = sText || webFXTreeConfig.defaultText;\r
84         this.action = sAction || webFXTreeConfig.defaultAction;\r
85         this.targetWindow = sTarget || webFXTreeConfig.defaultTarget;\r
86         this._last  = false;\r
87         webFXTreeHandler.all[this.id] = this;\r
88 }\r
90 WebFXTreeAbstractNode.prototype.add = function (node) {\r
91         node.parentNode = this;\r
92         this.childNodes[this.childNodes.length] = node;\r
93         var root = this;\r
94         if (this.childNodes.length >=2) {\r
95                 this.childNodes[this.childNodes.length -2]._last = false;\r
96         }\r
97         while (root.parentNode) { root = root.parentNode; }\r
98         if (root.rendered) {\r
99                 if (this.childNodes.length >= 2) {\r
100                         document.getElementById(this.childNodes[this.childNodes.length -2].id + '-plus').src = ((this.childNodes[this.childNodes.length -2].folder)?webFXTreeConfig.tMinusIcon:webFXTreeConfig.tIcon);\r
101                         if (this.childNodes[this.childNodes.length -2].folder) {\r
102                                 this.childNodes[this.childNodes.length -2].plusIcon = webFXTreeConfig.tPlusIcon;\r
103                                 this.childNodes[this.childNodes.length -2].minusIcon = webFXTreeConfig.tMinusIcon;\r
104                         }\r
105                         this.childNodes[this.childNodes.length -2]._last = false;\r
106                 }\r
107                 this._last = true;\r
108                 var foo = this;\r
109                 while (foo.parentNode) {\r
110                         for (var i = 0; i < foo.parentNode.childNodes.length; i++) {\r
111                                 if (foo.id == foo.parentNode.childNodes[i].id) { break; }\r
112                         }\r
113                         if (++i == foo.parentNode.childNodes.length) { foo.parentNode._last = true; }\r
114                         else { foo.parentNode._last = false; }\r
115                         foo = foo.parentNode;\r
116                 }\r
117                 document.getElementById(this.id + '-cont').insertAdjacentHTML("beforeEnd", node.toString());\r
118                 if ((!this.folder) && (!this.openIcon)) {\r
119                         this.icon = webFXTreeConfig.folderIcon;\r
120                         this.openIcon = webFXTreeConfig.openFolderIcon;\r
121                 }\r
122                 this.folder = true;\r
123                 this.indent();\r
124                 this.expand();\r
125         }\r
126         return node;\r
129 WebFXTreeAbstractNode.prototype.toggle = function() {\r
130         if (this.folder) {\r
131                 if (this.open) { this.collapse(); }\r
132                 else { this.expand(); }\r
133         }\r
136 WebFXTreeAbstractNode.prototype.select = function() {\r
137         document.getElementById(this.id + '-anchor').focus();\r
140 WebFXTreeAbstractNode.prototype.focus = function() {\r
141         webFXTreeHandler.selected = this;\r
142         if ((this.openIcon) && (webFXTreeHandler.behavior != 'classic')) { document.getElementById(this.id + '-icon').src = this.openIcon; }\r
143         document.getElementById(this.id + '-anchor').style.backgroundColor = 'highlight';\r
144         document.getElementById(this.id + '-anchor').style.color = 'highlighttext';\r
145         document.getElementById(this.id + '-anchor').focus();\r
148 WebFXTreeAbstractNode.prototype.blur = function() {\r
149         if ((this.openIcon) && (webFXTreeHandler.behavior != 'classic')) { document.getElementById(this.id + '-icon').src = this.icon; }\r
150         document.getElementById(this.id + '-anchor').style.backgroundColor = 'transparent';\r
151         document.getElementById(this.id + '-anchor').style.color = 'menutext';\r
154 WebFXTreeAbstractNode.prototype.doExpand = function() {\r
155         if (webFXTreeHandler.behavior == 'classic') { document.getElementById(this.id + '-icon').src = this.openIcon; }\r
156         if (this.childNodes.length) {  document.getElementById(this.id + '-cont').style.display = 'block'; }\r
157         this.open = true;\r
158         webFXTreeHandler.cookies.setCookie(this.id.substr(18,this.id.length - 18), '1');\r
161 WebFXTreeAbstractNode.prototype.doCollapse = function() {\r
162         if (webFXTreeHandler.behavior == 'classic') { document.getElementById(this.id + '-icon').src = this.icon; }\r
163         if (this.childNodes.length) { document.getElementById(this.id + '-cont').style.display = 'none'; }\r
164         this.open = false;\r
165         webFXTreeHandler.cookies.setCookie(this.id.substr(18,this.id.length - 18), '0');\r
168 WebFXTreeAbstractNode.prototype.expandAll = function() {\r
169         this.expandChildren();\r
170         if ((this.folder) && (!this.open)) { this.expand(); }\r
173 WebFXTreeAbstractNode.prototype.expandChildren = function() {\r
174         for (var i = 0; i < this.childNodes.length; i++) {\r
175                 this.childNodes[i].expandAll();\r
176 } }\r
178 WebFXTreeAbstractNode.prototype.collapseAll = function() {\r
179         if ((this.folder) && (this.open)) { this.collapse(); }\r
180         this.collapseChildren();\r
183 WebFXTreeAbstractNode.prototype.collapseChildren = function() {\r
184         for (var i = 0; i < this.childNodes.length; i++) {\r
185                 this.childNodes[i].collapseAll();\r
186 } }\r
188 WebFXTreeAbstractNode.prototype.indent = function(lvl, del, last, level) {\r
189         /*\r
190          * Since we only want to modify items one level below ourself,\r
191          * and since the rightmost indentation position is occupied by\r
192          * the plus icon we set this to -2\r
193          */\r
194         if (lvl == null) { lvl = -2; }\r
195         var state = 0;\r
196         for (var i = this.childNodes.length - 1; i >= 0 ; i--) {\r
197                 state = this.childNodes[i].indent(lvl + 1, del, last, level);\r
198                 if (state) { return; }\r
199         }\r
200         if (del) {\r
201                 if (level >= this._level) {\r
202                         if (this.folder) {\r
203                                 document.getElementById(this.id + '-plus').src = (this.open)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.lPlusIcon;\r
204                                 this.plusIcon = webFXTreeConfig.lPlusIcon;\r
205                                 this.minusIcon = webFXTreeConfig.lMinusIcon;\r
206                         }\r
207                         else { document.getElementById(this.id + '-plus').src = webFXTreeConfig.lIcon; }\r
208                         return 1;\r
209                 }\r
210         }\r
211         var foo = document.getElementById(this.id + '-indent-' + lvl);\r
212         if (foo) {\r
213                 if ((del) && (last)) { foo._last = true; }\r
214                 if (foo._last) { foo.src =  webFXTreeConfig.blankIcon; }\r
215                 else { foo.src =  webFXTreeConfig.iIcon; }\r
216         }\r
217         return 0;\r
220 /*\r
221  * WebFXTree class\r
222  */\r
224 function WebFXTree(sText, sAction, sBehavior, sIcon, sOpenIcon) {\r
225         this.base = WebFXTreeAbstractNode;\r
226         this.base(sText, sAction);\r
227         this.icon      = sIcon || webFXTreeConfig.rootIcon;\r
228         this.openIcon  = sOpenIcon || webFXTreeConfig.openRootIcon;\r
229         /* Defaults to open */\r
230         this.open      = (webFXTreeHandler.cookies.getCookie(this.id.substr(18,this.id.length - 18)) == '0')?false:true;\r
231         this.folder    = true;\r
232         this.rendered  = false;\r
233         if (!webFXTreeHandler.behavior) {  webFXTreeHandler.behavior = sBehavior || webFXTreeConfig.defaultBehavior; }\r
234         this.targetWindow = 'right';\r
237 WebFXTree.prototype = new WebFXTreeAbstractNode;\r
239 WebFXTree.prototype.setBehavior = function (sBehavior) {\r
240         webFXTreeHandler.behavior =  sBehavior;\r
241 };\r
243 WebFXTree.prototype.getBehavior = function (sBehavior) {\r
244         return webFXTreeHandler.behavior;\r
245 };\r
247 WebFXTree.prototype.getSelected = function() {\r
248         if (webFXTreeHandler.selected) { return webFXTreeHandler.selected; }\r
249         else { return null; }\r
252 WebFXTree.prototype.remove = function() { }\r
254 WebFXTree.prototype.expand = function() {\r
255         this.doExpand();\r
258 WebFXTree.prototype.collapse = function() {\r
259         this.focus();\r
260         this.doCollapse();\r
263 WebFXTree.prototype.getFirst = function() {\r
264         return null;\r
267 WebFXTree.prototype.getLast = function() {\r
268         return null;\r
271 WebFXTree.prototype.getNextSibling = function() {\r
272         return null;\r
275 WebFXTree.prototype.getPreviousSibling = function() {\r
276         return null;\r
279 WebFXTree.prototype.keydown = function(key) {\r
280         if (key == 39) { this.expand(); return false; }\r
281         if (key == 37) { this.collapse(); return false; }\r
282         if ((key == 40) && (this.open)) { this.childNodes[0].select(); return false; }\r
283         return true;\r
286 WebFXTree.prototype.toString = function() {\r
287         var str = "<div id=\"" + this.id + "\" ondblclick=\"webFXTreeHandler.toggle(this);\" class=\"webfx-tree-item\" onkeydown=\"return webFXTreeHandler.keydown(this)\">";\r
288         str += "<img id=\"" + this.id + "-icon\" class=\"webfx-tree-icon\" src=\"" + ((webFXTreeHandler.behavior == 'classic' && this.open)?this.openIcon:this.icon) + "\" onclick=\"webFXTreeHandler.select(this);\"><a href=\"" + this.action + "\" id=\"" + this.id + "-anchor\" target=\"" + this.targetWindow + "\" onfocus=\"webFXTreeHandler.focus(this);\" onblur=\"webFXTreeHandler.blur(this);\">" + this.text + "</a></div>";\r
289         str += "<div id=\"" + this.id + "-cont\" class=\"webfx-tree-container\" style=\"display: " + ((this.open)?'block':'none') + ";\">";\r
290         for (var i = 0; i < this.childNodes.length; i++) {\r
291                 str += this.childNodes[i].toString(i, this.childNodes.length);\r
292         }\r
293         str += "</div>";\r
294         this.rendered = true;\r
295         return str;\r
296 };\r
298 /*\r
299  * WebFXTreeItem class\r
300  */\r
302 function WebFXTreeItem(sText, sAction, eParent, sIcon, sOpenIcon) {\r
303         this.base = WebFXTreeAbstractNode;\r
304         this.base(sText, sAction);\r
305         /* Defaults to close */\r
306         this.open = (webFXTreeHandler.cookies.getCookie(this.id.substr(18,this.id.length - 18)) == '1')?true:false;\r
307         if (eParent) { eParent.add(this); }\r
308         if (sIcon) { this.icon = sIcon; }\r
309         if (sOpenIcon) { this.openIcon = sOpenIcon; }\r
312 WebFXTreeItem.prototype = new WebFXTreeAbstractNode;\r
314 WebFXTreeItem.prototype.remove = function() {\r
315         var parentNode = this.parentNode;\r
316         var prevSibling = this.getPreviousSibling(true);\r
317         var nextSibling = this.getNextSibling(true);\r
318         var folder = this.parentNode.folder;\r
319         var last = ((nextSibling) && (nextSibling.parentNode) && (nextSibling.parentNode.id == parentNode.id))?false:true;\r
320         this.getPreviousSibling().focus();\r
321         this._remove();\r
322         if (parentNode.childNodes.length == 0) {\r
323                 parentNode.folder = false;\r
324                 parentNode.open = false;\r
325         }\r
326         if (last) {\r
327                 if (parentNode.id == prevSibling.id) {\r
328                         document.getElementById(parentNode.id + '-icon').src = webFXTreeConfig.fileIcon;\r
329                 }\r
330                 else { }\r
331         }\r
332         if ((!prevSibling.parentNode) || (prevSibling.parentNode != parentNode)) {\r
333                 parentNode.indent(null, true, last, this._level);\r
334         }\r
335         if (document.getElementById(prevSibling.id + '-plus')) {\r
336                 if (nextSibling) {\r
337                         if ((parentNode == prevSibling) && (parentNode.getNextSibling))  { document.getElementById(prevSibling.id + '-plus').src = webFXTreeConfig.tIcon; }\r
338                         else if (nextSibling.parentNode != prevSibling) { document.getElementById(prevSibling.id + '-plus').src = webFXTreeConfig.lIcon; }\r
339                 }\r
340                 else { document.getElementById(prevSibling.id + '-plus').src = webFXTreeConfig.lIcon; }\r
341         }\r
344 WebFXTreeItem.prototype._remove = function() {\r
345         for (var i = this.childNodes.length - 1; i >= 0; i--) {\r
346                 this.childNodes[i]._remove();\r
347         }\r
348         for (var i = 0; i < this.parentNode.childNodes.length; i++) {\r
349                 if (this.id == this.parentNode.childNodes[i].id) {\r
350                         for (var j = i; j < this.parentNode.childNodes.length; j++) {\r
351                                 this.parentNode.childNodes[i] = this.parentNode.childNodes[i+1]\r
352                         }\r
353                         this.parentNode.childNodes.length = this.parentNode.childNodes.length - 1;\r
354                         if (i + 1 == this.parentNode.childNodes.length) { this.parentNode._last = true; }\r
355                 }\r
356         }\r
357         webFXTreeHandler.all[this.id] = null;\r
358         if (document.getElementById(this.id)) {\r
359                 document.getElementById(this.id).innerHTML = "";\r
360                 document.getElementById(this.id).removeNode();\r
361         }\r
364 WebFXTreeItem.prototype.expand = function() {\r
365         this.doExpand();\r
366         document.getElementById(this.id + '-plus').src = this.minusIcon;\r
369 WebFXTreeItem.prototype.collapse = function() {\r
370         this.focus();\r
371         this.doCollapse();\r
372         document.getElementById(this.id + '-plus').src = this.plusIcon;\r
375 WebFXTreeItem.prototype.getFirst = function() {\r
376         return this.childNodes[0];\r
379 WebFXTreeItem.prototype.getLast = function() {\r
380         if (this.childNodes[this.childNodes.length - 1].open) { return this.childNodes[this.childNodes.length - 1].getLast(); }\r
381         else { return this.childNodes[this.childNodes.length - 1]; }\r
384 WebFXTreeItem.prototype.getNextSibling = function() {\r
385         for (var i = 0; i < this.parentNode.childNodes.length; i++) {\r
386                 if (this == this.parentNode.childNodes[i]) { break; }\r
387         }\r
388         if (++i == this.parentNode.childNodes.length) { return this.parentNode.getNextSibling(); }\r
389         else { return this.parentNode.childNodes[i]; }\r
392 WebFXTreeItem.prototype.getPreviousSibling = function(b) {\r
393         for (var i = 0; i < this.parentNode.childNodes.length; i++) {\r
394                 if (this == this.parentNode.childNodes[i]) { break; }\r
395         }\r
396         if (i == 0) { return this.parentNode; }\r
397         else {\r
398                 if ((this.parentNode.childNodes[--i].open) || (b && this.parentNode.childNodes[i].folder)) { return this.parentNode.childNodes[i].getLast(); }\r
399                 else { return this.parentNode.childNodes[i]; }\r
400 } }\r
402 WebFXTreeItem.prototype.keydown = function(key) {\r
403         if ((key == 39) && (this.folder)) {\r
404                 if (!this.open) { this.expand(); return false; }\r
405                 else { this.getFirst().select(); return false; }\r
406         }\r
407         else if (key == 37) {\r
408                 if (this.open) { this.collapse(); return false; }\r
409                 else { this.parentNode.select(); return false; }\r
410         }\r
411         else if (key == 40) {\r
412                 if (this.open) { this.getFirst().select(); return false; }\r
413                 else {\r
414                         var sib = this.getNextSibling();\r
415                         if (sib) { sib.select(); return false; }\r
416         } }\r
417         else if (key == 38) { this.getPreviousSibling().select(); return false; }\r
418         return true;\r
421 WebFXTreeItem.prototype.toString = function (nItem, nItemCount) {\r
422         var foo = this.parentNode;\r
423         var indent = '';\r
424         if (nItem + 1 == nItemCount) { this.parentNode._last = true; }\r
425         var i = 0;\r
426         while (foo.parentNode) {\r
427                 foo = foo.parentNode;\r
428                 indent = "<img id=\"" + this.id + "-indent-" + i + "\" src=\"" + ((foo._last)?webFXTreeConfig.blankIcon:webFXTreeConfig.iIcon) + "\">" + indent;\r
429                 i++;\r
430         }\r
431         this._level = i;\r
432         if (this.childNodes.length) { this.folder = 1; }\r
433         else { this.open = false; }\r
434         if ((this.folder) || (webFXTreeHandler.behavior != 'classic')) {\r
435                 if (!this.icon) { this.icon = webFXTreeConfig.folderIcon; }\r
436                 if (!this.openIcon) { this.openIcon = webFXTreeConfig.openFolderIcon; }\r
437         }\r
438         else if (!this.icon) { this.icon = webFXTreeConfig.fileIcon; }\r
439         var label = this.text;\r
440         label = label.replace('<', '<');\r
441         label = label.replace('>', '>');\r
442         var str = "<div id=\"" + this.id + "\" ondblclick=\"webFXTreeHandler.toggle(this);\" class=\"webfx-tree-item\" onkeydown=\"return webFXTreeHandler.keydown(this)\">";\r
443         str += indent;\r
444         str += "<img id=\"" + this.id + "-plus\" src=\"" + ((this.folder)?((this.open)?((this.parentNode._last)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.tMinusIcon):((this.parentNode._last)?webFXTreeConfig.lPlusIcon:webFXTreeConfig.tPlusIcon)):((this.parentNode._last)?webFXTreeConfig.lIcon:webFXTreeConfig.tIcon)) + "\" onclick=\"webFXTreeHandler.toggle(this);\">"\r
445         str += "<img id=\"" + this.id + "-icon\" src=\"" + ((webFXTreeHandler.behavior == 'classic' && this.open)?this.openIcon:this.icon) + "\" onclick=\"webFXTreeHandler.select(this);\"><a href=\"" + this.action + "\" id=\"" + this.id + "-anchor\" target=\"" + this.targetWindow + "\" onfocus=\"webFXTreeHandler.focus(this);\" onblur=\"webFXTreeHandler.blur(this);\">" + label + "</a></div>";\r
446         str += "<div id=\"" + this.id + "-cont\" class=\"webfx-tree-container\" style=\"display: " + ((this.open)?'block':'none') + ";\">";\r
447         for (var i = 0; i < this.childNodes.length; i++) {\r
448                 str += this.childNodes[i].toString(i,this.childNodes.length);\r
449         }\r
450         str += "</div>";\r
451         this.plusIcon = ((this.parentNode._last)?webFXTreeConfig.lPlusIcon:webFXTreeConfig.tPlusIcon);\r
452         this.minusIcon = ((this.parentNode._last)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.tMinusIcon);\r
453         return str;\r