]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/src/javascript/widgets/xtree.js
removing old opac images and css
[working/Evergreen.git] / Open-ILS / src / javascript / widgets / xtree.js
1 /*----------------------------------------------------------------------------\
2 |                       Cross Browser Tree Widget 1.17                        |
3 |-----------------------------------------------------------------------------|
4 |                          Created by Emil A Eklund                           |
5 |                  (http://webfx.eae.net/contact.html#emil)                   |
6 |                      For WebFX (http://webfx.eae.net/)                      |
7 |-----------------------------------------------------------------------------|
8 | An object based tree widget,  emulating the one found in microsoft windows, |
9 | with persistence using cookies. Works in IE 5+, Mozilla and konqueror 3.    |
10 |-----------------------------------------------------------------------------|
11 |                   Copyright (c) 1999 - 2002 Emil A Eklund                   |
12 |-----------------------------------------------------------------------------|
13 | This software is provided "as is", without warranty of any kind, express or |
14 | implied, including  but not limited  to the warranties of  merchantability, |
15 | fitness for a particular purpose and noninfringement. In no event shall the |
16 | authors or  copyright  holders be  liable for any claim,  damages or  other |
17 | liability, whether  in an  action of  contract, tort  or otherwise, arising |
18 | from,  out of  or in  connection with  the software or  the  use  or  other |
19 | dealings in the software.                                                   |
20 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
21 | This  software is  available under the  three different licenses  mentioned |
22 | below.  To use this software you must chose, and qualify, for one of those. |
23 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
24 | The WebFX Non-Commercial License          http://webfx.eae.net/license.html |
25 | Permits  anyone the right to use the  software in a  non-commercial context |
26 | free of charge.                                                             |
27 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
28 | The WebFX Commercial license           http://webfx.eae.net/commercial.html |
29 | Permits the  license holder the right to use  the software in a  commercial |
30 | context. Such license must be specifically obtained, however it's valid for |
31 | any number of  implementations of the licensed software.                    |
32 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
33 | GPL - The GNU General Public License    http://www.gnu.org/licenses/gpl.txt |
34 | Permits anyone the right to use and modify the software without limitations |
35 | as long as proper  credits are given  and the original  and modified source |
36 | code are included. Requires  that the final product, software derivate from |
37 | the original  source or any  software  utilizing a GPL  component, such  as |
38 | this, is also licensed under the GPL license.                               |
39 |-----------------------------------------------------------------------------|
40 | Dependencies: xtree.css (To set up the CSS of the tree classes)             |
41 |-----------------------------------------------------------------------------|
42 | 2001-01-10 | Original Version Posted.                                       |
43 | 2001-03-18 | Added getSelected and get/setBehavior  that can make it behave |
44 |            | more like windows explorer, check usage for more information.  |
45 | 2001-09-23 | Version 1.1 - New features included  keyboard  navigation (ie) |
46 |            | and the ability  to add and  remove nodes dynamically and some |
47 |            | other small tweaks and fixes.                                  |
48 | 2002-01-27 | Version 1.11 - Bug fixes and improved mozilla support.         |
49 | 2002-06-11 | Version 1.12 - Fixed a bug that prevented the indentation line |
50 |            | from  updating correctly  under some  circumstances.  This bug |
51 |            | happened when removing the last item in a subtree and items in |
52 |            | siblings to the remove subtree where not correctly updated.    |
53 | 2002-06-13 | Fixed a few minor bugs cased by the 1.12 bug-fix.              |
54 | 2002-08-20 | Added usePersistence flag to allow disable of cookies.         |
55 | 2002-10-23 | (1.14) Fixed a plus icon issue                                 |
56 | 2002-10-29 | (1.15) Last changes broke more than they fixed. This version   |
57 |            | is based on 1.13 and fixes the bugs 1.14 fixed withou breaking |
58 |            | lots of other things.                                          |
59 | 2003-02-15 | The  selected node can now be made visible even when  the tree |
60 |            | control  loses focus.  It uses a new class  declaration in the |
61 |            | css file '.webfx-tree-item a.selected-inactive', by default it |
62 |            | puts a light-gray rectangle around the selected node.          |
63 | 2003-03-16 | Adding target support after lots of lobbying...                |
64 |-----------------------------------------------------------------------------|
65 | Created 2000-12-11 | All changes are in the log above. | Updated 2003-03-16 |
66 \----------------------------------------------------------------------------*/
67
68 var webFXTreeConfig = {
69         rootIcon        : '/images/xtree/foldericon.png',
70         openRootIcon    : '/images/xtree/openfoldericon.png',
71         folderIcon      : '/images/xtree/foldericon.png',
72         openFolderIcon  : '/images/xtree/openfoldericon.png',
73         fileIcon        : '/images/xtree/file.png',
74         iIcon           : '/images/xtree/I.png',
75         lIcon           : '/images/xtree/L.png',
76         lMinusIcon      : '/images/xtree/Lminus.png',
77         lPlusIcon       : '/images/xtree/Lplus.png',
78         tIcon           : '/images/xtree/T.png',
79         tMinusIcon      : '/images/xtree/Tminus.png',
80         tPlusIcon       : '/images/xtree/Tplus.png',
81         blankIcon       : '/images/xtree/blank.png',
82         defaultText     : 'Tree Item',
83         defaultAction   : 'javascript:void(0);',
84         defaultBehavior : 'classic',
85         usePersistence  : true
86 };
87
88 var webFXTreeHandler = {
89         idCounter : 0,
90         idPrefix  : "webfx-tree-object-",
91         all       : {},
92         behavior  : null,
93         selected  : null,
94         onSelect  : null, /* should be part of tree, not handler */
95         getId     : function() { return this.idPrefix + this.idCounter++; },
96         toggle    : function (oItem) { this.all[oItem.id.replace('-plus','')].toggle(); },
97         select    : function (oItem) { this.all[oItem.id.replace('-icon','')].select(); },
98         focus     : function (oItem) { this.all[oItem.id.replace('-anchor','')].focus(); },
99         blur      : function (oItem) { this.all[oItem.id.replace('-anchor','')].blur(); },
100         keydown   : function (oItem, e) { return this.all[oItem.id].keydown(e.keyCode); },
101         cookies   : new WebFXCookie(),
102         insertHTMLBeforeEnd     :       function (oElement, sHTML) {
103                 if (oElement.insertAdjacentHTML != null) {
104                         oElement.insertAdjacentHTML("BeforeEnd", sHTML)
105                         return;
106                 }
107                 var df; // DocumentFragment
108                 var r = oElement.ownerDocument.createRange();
109                 r.selectNodeContents(oElement);
110                 r.collapse(false);
111                 df = r.createContextualFragment(sHTML);
112                 oElement.appendChild(df);
113         }
114 };
115
116 /*
117  * WebFXCookie class
118  */
119
120 function WebFXCookie() {
121         if (document.cookie.length) { this.cookies = ' ' + document.cookie; }
122 }
123
124 WebFXCookie.prototype.setCookie = function (key, value) {
125         document.cookie = key + "=" + escape(value);
126 }
127
128 WebFXCookie.prototype.getCookie = function (key) {
129         if (this.cookies) {
130                 var start = this.cookies.indexOf(' ' + key + '=');
131                 if (start == -1) { return null; }
132                 var end = this.cookies.indexOf(";", start);
133                 if (end == -1) { end = this.cookies.length; }
134                 end -= start;
135                 var cookie = this.cookies.substr(start,end);
136                 return unescape(cookie.substr(cookie.indexOf('=') + 1, cookie.length - cookie.indexOf('=') + 1));
137         }
138         else { return null; }
139 }
140
141 /*
142  * WebFXTreeAbstractNode class
143  */
144
145 function WebFXTreeAbstractNode(sText, sAction) {
146         this.childNodes  = [];
147         this.id     = webFXTreeHandler.getId();
148         this.text   = sText || webFXTreeConfig.defaultText;
149         this.action = sAction || webFXTreeConfig.defaultAction;
150         this._last  = false;
151         webFXTreeHandler.all[this.id] = this;
152 }
153
154 /*
155  * To speed thing up if you're adding multiple nodes at once (after load)
156  * use the bNoIdent parameter to prevent automatic re-indentation and call
157  * the obj.ident() method manually once all nodes has been added.
158  */
159
160 WebFXTreeAbstractNode.prototype.add = function (node, bNoIdent) {
161         node.parentNode = this;
162         this.childNodes[this.childNodes.length] = node;
163         var root = this;
164         if (this.childNodes.length >= 2) {
165                 this.childNodes[this.childNodes.length - 2]._last = false;
166         }
167         while (root.parentNode) { root = root.parentNode; }
168         if (root.rendered) {
169                 if (this.childNodes.length >= 2) {
170                         getById(this.childNodes[this.childNodes.length - 2].id + '-plus').src = ((this.childNodes[this.childNodes.length -2].folder)?((this.childNodes[this.childNodes.length -2].open)?webFXTreeConfig.tMinusIcon:webFXTreeConfig.tPlusIcon):webFXTreeConfig.tIcon);
171                         this.childNodes[this.childNodes.length - 2].plusIcon = webFXTreeConfig.tPlusIcon;
172                         this.childNodes[this.childNodes.length - 2].minusIcon = webFXTreeConfig.tMinusIcon;
173                         this.childNodes[this.childNodes.length - 2]._last = false;
174                 }
175                 this._last = true;
176                 var foo = this;
177                 while (foo.parentNode) {
178                         for (var i = 0; i < foo.parentNode.childNodes.length; i++) {
179                                 if (foo.id == foo.parentNode.childNodes[i].id) { break; }
180                         }
181                         if (i == foo.parentNode.childNodes.length - 1) { foo.parentNode._last = true; }
182                         else { foo.parentNode._last = false; }
183                         foo = foo.parentNode;
184                 }
185                 webFXTreeHandler.insertHTMLBeforeEnd(getById(this.id + '-cont'), node.toString());
186                 if ((!this.folder) && (!this.openIcon)) {
187                         this.icon = webFXTreeConfig.folderIcon;
188                         this.openIcon = webFXTreeConfig.openFolderIcon;
189                 }
190                 if (!this.folder) { this.folder = true; this.collapse(true); }
191                 if (!bNoIdent) { this.indent(); }
192         }
193         return node;
194 }
195
196 WebFXTreeAbstractNode.prototype.toggle = function() {
197         if (this.folder) {
198                 if (this.open) { this.collapse(); }
199                 else { this.expand(); }
200 }       }
201
202 WebFXTreeAbstractNode.prototype.select = function() {
203         var a = getById(this.id + '-anchor');
204         if(a) a.focus();
205 }
206
207 WebFXTreeAbstractNode.prototype.deSelect = function() {
208         var a = getById(this.id + '-anchor');
209         if(a) a.className = '';
210         webFXTreeHandler.selected = null;
211 }
212
213 WebFXTreeAbstractNode.prototype.focus = function() {
214         if ((webFXTreeHandler.selected) && (webFXTreeHandler.selected != this)) { webFXTreeHandler.selected.deSelect(); }
215         webFXTreeHandler.selected = this;
216         if ((this.openIcon) && (webFXTreeHandler.behavior != 'classic')) { getById(this.id + '-icon').src = this.openIcon; }
217         getById(this.id + '-anchor').className = 'selected';
218         getById(this.id + '-anchor').focus();
219         if (webFXTreeHandler.onSelect) { webFXTreeHandler.onSelect(this); }
220 }
221
222 WebFXTreeAbstractNode.prototype.blur = function() {
223         if ((this.openIcon) && (webFXTreeHandler.behavior != 'classic')) { getById(this.id + '-icon').src = this.icon; }
224         getById(this.id + '-anchor').className = 'selected-inactive';
225 }
226
227 WebFXTreeAbstractNode.prototype.doExpand = function() {
228         if (webFXTreeHandler.behavior == 'classic') { getById(this.id + '-icon').src = this.openIcon; }
229         if (this.childNodes.length) {  getById(this.id + '-cont').style.display = 'block'; }
230         this.open = true;
231         if (webFXTreeConfig.usePersistence) {
232                 webFXTreeHandler.cookies.setCookie(this.id.substr(18,this.id.length - 18), '1');
233 }       }
234
235 WebFXTreeAbstractNode.prototype.doCollapse = function() {
236         if (webFXTreeHandler.behavior == 'classic') { getById(this.id + '-icon').src = this.icon; }
237         if (this.childNodes.length) { getById(this.id + '-cont').style.display = 'none'; }
238         this.open = false;
239         if (webFXTreeConfig.usePersistence) {
240                 webFXTreeHandler.cookies.setCookie(this.id.substr(18,this.id.length - 18), '0');
241 }       }
242
243 WebFXTreeAbstractNode.prototype.expandAll = function() {
244         this.expandChildren();
245         if ((this.folder) && (!this.open)) { this.expand(); }
246 }
247
248 WebFXTreeAbstractNode.prototype.expandChildren = function() {
249         for (var i = 0; i < this.childNodes.length; i++) {
250                 this.childNodes[i].expandAll();
251 } }
252
253 WebFXTreeAbstractNode.prototype.collapseAll = function() {
254         this.collapseChildren();
255         if ((this.folder) && (this.open)) { this.collapse(true); }
256 }
257
258 WebFXTreeAbstractNode.prototype.collapseChildren = function() {
259         for (var i = 0; i < this.childNodes.length; i++) {
260                 this.childNodes[i].collapseAll();
261 } }
262
263 WebFXTreeAbstractNode.prototype.indent = function(lvl, del, last, level, nodesLeft) {
264         /*
265          * Since we only want to modify items one level below ourself,
266          * and since the rightmost indentation position is occupied by
267          * the plus icon we set this to -2
268          */
269         if (lvl == null) { lvl = -2; }
270         var state = 0;
271         for (var i = this.childNodes.length - 1; i >= 0 ; i--) {
272                 state = this.childNodes[i].indent(lvl + 1, del, last, level);
273                 if (state) { return; }
274         }
275         if (del) {
276                 if ((level >= this._level) && (getById(this.id + '-plus'))) {
277                         if (this.folder) {
278                                 getById(this.id + '-plus').src = (this.open)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.lPlusIcon;
279                                 this.plusIcon = webFXTreeConfig.lPlusIcon;
280                                 this.minusIcon = webFXTreeConfig.lMinusIcon;
281                         }
282                         else if (nodesLeft) { getById(this.id + '-plus').src = webFXTreeConfig.lIcon; }
283                         return 1;
284         }       }
285         var foo = getById(this.id + '-indent-' + lvl);
286         if (foo) {
287                 if ((foo._last) || ((del) && (last))) { foo.src =  webFXTreeConfig.blankIcon; }
288                 else { foo.src =  webFXTreeConfig.iIcon; }
289         }
290         return 0;
291 }
292
293 /*
294  * WebFXTree class
295  */
296
297 function WebFXTree(sText, sAction, sBehavior, sIcon, sOpenIcon) {
298         this.base = WebFXTreeAbstractNode;
299         this.base(sText, sAction);
300         this.icon      = sIcon || webFXTreeConfig.rootIcon;
301         this.openIcon  = sOpenIcon || webFXTreeConfig.openRootIcon;
302         /* Defaults to open */
303         if (webFXTreeConfig.usePersistence) {
304                 this.open  = (webFXTreeHandler.cookies.getCookie(this.id.substr(18,this.id.length - 18)) == '0')?false:true;
305         } else { this.open  = true; }
306         this.folder    = true;
307         this.rendered  = false;
308         this.onSelect  = null;
309         if (!webFXTreeHandler.behavior) {  webFXTreeHandler.behavior = sBehavior || webFXTreeConfig.defaultBehavior; }
310 }
311
312 WebFXTree.prototype = new WebFXTreeAbstractNode;
313
314 WebFXTree.prototype.setBehavior = function (sBehavior) {
315         webFXTreeHandler.behavior =  sBehavior;
316 };
317
318 WebFXTree.prototype.getBehavior = function (sBehavior) {
319         return webFXTreeHandler.behavior;
320 };
321
322 WebFXTree.prototype.getSelected = function() {
323         if (webFXTreeHandler.selected) { return webFXTreeHandler.selected; }
324         else { return null; }
325 }
326
327 WebFXTree.prototype.remove = function() { }
328
329 WebFXTree.prototype.expand = function() {
330         this.doExpand();
331 }
332
333 WebFXTree.prototype.collapse = function(b) {
334         if (!b) { this.focus(); }
335         this.doCollapse();
336 }
337
338 WebFXTree.prototype.getFirst = function() {
339         return null;
340 }
341
342 WebFXTree.prototype.getLast = function() {
343         return null;
344 }
345
346 WebFXTree.prototype.getNextSibling = function() {
347         return null;
348 }
349
350 WebFXTree.prototype.getPreviousSibling = function() {
351         return null;
352 }
353
354 WebFXTree.prototype.keydown = function(key) {
355         if (key == 39) {
356                 if (!this.open) { this.expand(); }
357                 else if (this.childNodes.length) { this.childNodes[0].select(); }
358                 return false;
359         }
360         if (key == 37) { this.collapse(); return false; }
361         if ((key == 40) && (this.open) && (this.childNodes.length)) { this.childNodes[0].select(); return false; }
362         return true;
363 }
364
365 WebFXTree.prototype.toString = function() {
366         var str = "<div id=\"" + this.id + "\" ondblclick=\"webFXTreeHandler.toggle(this);\" class=\"webfx-tree-item\" onkeydown=\"return webFXTreeHandler.keydown(this, event)\">" +
367                 "<img id=\"" + this.id + "-icon\" class=\"webfx-tree-icon\" src=\"" + ((webFXTreeHandler.behavior == 'classic' && this.open)?this.openIcon:this.icon) + "\" onclick=\"webFXTreeHandler.select(this);\">" +
368                 "<a href=\"" + this.action + "\" id=\"" + this.id + "-anchor\" onfocus=\"webFXTreeHandler.focus(this);\" onblur=\"webFXTreeHandler.blur(this);\"" +
369                 (this.target ? " target=\"" + this.target + "\"" : "") +
370                 ">" + this.text + "</a></div>" +
371                 "<div id=\"" + this.id + "-cont\" class=\"webfx-tree-container\" style=\"display: " + ((this.open)?'block':'none') + ";\">";
372         var sb = [];
373         for (var i = 0; i < this.childNodes.length; i++) {
374                 sb[i] = this.childNodes[i].toString(i, this.childNodes.length);
375         }
376         this.rendered = true;
377         return str + sb.join("") + "</div>";
378 };
379
380 /*
381  * WebFXTreeItem class
382  */
383
384 function WebFXTreeItem(sText, sAction, eParent, sIcon, sOpenIcon) {
385         this.base = WebFXTreeAbstractNode;
386         this.base(sText, sAction);
387         /* Defaults to close */
388         if (webFXTreeConfig.usePersistence) {
389                 this.open = (webFXTreeHandler.cookies.getCookie(this.id.substr(18,this.id.length - 18)) == '1')?true:false;
390         } else { this.open = false; }
391         if (sIcon) { this.icon = sIcon; }
392         if (sOpenIcon) { this.openIcon = sOpenIcon; }
393         if (eParent) { eParent.add(this); }
394 }
395
396 WebFXTreeItem.prototype = new WebFXTreeAbstractNode;
397
398 WebFXTreeItem.prototype.remove = function() {
399         var iconSrc = getById(this.id + '-plus').src;
400         var parentNode = this.parentNode;
401         var prevSibling = this.getPreviousSibling(true);
402         var nextSibling = this.getNextSibling(true);
403         var folder = this.parentNode.folder;
404         var last = ((nextSibling) && (nextSibling.parentNode) && (nextSibling.parentNode.id == parentNode.id))?false:true;
405         this.getPreviousSibling().focus();
406         this._remove();
407         if (parentNode.childNodes.length == 0) {
408                 getById(parentNode.id + '-cont').style.display = 'none';
409                 parentNode.doCollapse();
410                 parentNode.folder = false;
411                 parentNode.open = false;
412         }
413         if (!nextSibling || last) { parentNode.indent(null, true, last, this._level, parentNode.childNodes.length); }
414         if ((prevSibling == parentNode) && !(parentNode.childNodes.length)) {
415                 prevSibling.folder = false;
416                 prevSibling.open = false;
417                 iconSrc = getById(prevSibling.id + '-plus').src;
418                 iconSrc = iconSrc.replace('minus', '').replace('plus', '');
419                 getById(prevSibling.id + '-plus').src = iconSrc;
420                 getById(prevSibling.id + '-icon').src = webFXTreeConfig.fileIcon;
421         }
422         if (getById(prevSibling.id + '-plus')) {
423                 if (parentNode == prevSibling.parentNode) {
424                         iconSrc = iconSrc.replace('minus', '').replace('plus', '');
425                         getById(prevSibling.id + '-plus').src = iconSrc;
426 }       }       }
427
428 WebFXTreeItem.prototype._remove = function() {
429         for (var i = this.childNodes.length - 1; i >= 0; i--) {
430                 this.childNodes[i]._remove();
431         }
432         for (var i = 0; i < this.parentNode.childNodes.length; i++) {
433                 if (this == this.parentNode.childNodes[i]) {
434                         for (var j = i; j < this.parentNode.childNodes.length; j++) {
435                                 this.parentNode.childNodes[j] = this.parentNode.childNodes[j+1];
436                         }
437                         this.parentNode.childNodes.length -= 1;
438                         if (i + 1 == this.parentNode.childNodes.length) { this.parentNode._last = true; }
439                         break;
440         }       }
441         webFXTreeHandler.all[this.id] = null;
442         var tmp = getById(this.id);
443         if (tmp) { tmp.parentNode.removeChild(tmp); }
444         tmp = getById(this.id + '-cont');
445         if (tmp) { tmp.parentNode.removeChild(tmp); }
446 }
447
448 WebFXTreeItem.prototype.expand = function() {
449         this.doExpand();
450         getById(this.id + '-plus').src = this.minusIcon;
451 }
452
453 WebFXTreeItem.prototype.collapse = function(b) {
454         if (!b) { this.focus(); }
455         this.doCollapse();
456         getById(this.id + '-plus').src = this.plusIcon;
457 }
458
459 WebFXTreeItem.prototype.getFirst = function() {
460         return this.childNodes[0];
461 }
462
463 WebFXTreeItem.prototype.getLast = function() {
464         if (this.childNodes[this.childNodes.length - 1].open) { return this.childNodes[this.childNodes.length - 1].getLast(); }
465         else { return this.childNodes[this.childNodes.length - 1]; }
466 }
467
468 WebFXTreeItem.prototype.getNextSibling = function() {
469         for (var i = 0; i < this.parentNode.childNodes.length; i++) {
470                 if (this == this.parentNode.childNodes[i]) { break; }
471         }
472         if (++i == this.parentNode.childNodes.length) { return this.parentNode.getNextSibling(); }
473         else { return this.parentNode.childNodes[i]; }
474 }
475
476 WebFXTreeItem.prototype.getPreviousSibling = function(b) {
477         for (var i = 0; i < this.parentNode.childNodes.length; i++) {
478                 if (this == this.parentNode.childNodes[i]) { break; }
479         }
480         if (i == 0) { return this.parentNode; }
481         else {
482                 if ((this.parentNode.childNodes[--i].open) || (b && this.parentNode.childNodes[i].folder)) { return this.parentNode.childNodes[i].getLast(); }
483                 else { return this.parentNode.childNodes[i]; }
484 } }
485
486 WebFXTreeItem.prototype.keydown = function(key) {
487         if ((key == 39) && (this.folder)) {
488                 if (!this.open) { this.expand(); }
489                 else { this.getFirst().select(); }
490                 return false;
491         }
492         else if (key == 37) {
493                 if (this.open) { this.collapse(); }
494                 else { this.parentNode.select(); }
495                 return false;
496         }
497         else if (key == 40) {
498                 if (this.open) { this.getFirst().select(); }
499                 else {
500                         var sib = this.getNextSibling();
501                         if (sib) { sib.select(); }
502                 }
503                 return false;
504         }
505         else if (key == 38) { this.getPreviousSibling().select(); return false; }
506         return true;
507 }
508
509 WebFXTreeItem.prototype.toString = function (nItem, nItemCount) {
510         var foo = this.parentNode;
511         var indent = '';
512         if (nItem + 1 == nItemCount) { this.parentNode._last = true; }
513         var i = 0;
514         while (foo.parentNode) {
515                 foo = foo.parentNode;
516                 indent = "<img id=\"" + this.id + "-indent-" + i + "\" src=\"" + ((foo._last)?webFXTreeConfig.blankIcon:webFXTreeConfig.iIcon) + "\">" + indent;
517                 i++;
518         }
519         this._level = i;
520         if (this.childNodes.length) { this.folder = 1; }
521         else { this.open = false; }
522         if ((this.folder) || (webFXTreeHandler.behavior != 'classic')) {
523                 if (!this.icon) { this.icon = webFXTreeConfig.folderIcon; }
524                 if (!this.openIcon) { this.openIcon = webFXTreeConfig.openFolderIcon; }
525         }
526         else if (!this.icon) { this.icon = webFXTreeConfig.fileIcon; }
527         var label = this.text.replace(/</g, '&lt;').replace(/>/g, '&gt;');
528         var str = "<div id=\"" + this.id + "\" ondblclick=\"webFXTreeHandler.toggle(this);\" class=\"webfx-tree-item\" onkeydown=\"return webFXTreeHandler.keydown(this, event)\">" +
529                 indent +
530                 "<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);\">" +
531                 "<img id=\"" + this.id + "-icon\" class=\"webfx-tree-icon\" src=\"" + ((webFXTreeHandler.behavior == 'classic' && this.open)?this.openIcon:this.icon) + "\" onclick=\"webFXTreeHandler.select(this);\">" +
532                 "<a href=\"" + this.action + "\" id=\"" + this.id + "-anchor\" onfocus=\"webFXTreeHandler.focus(this);\" onblur=\"webFXTreeHandler.blur(this);\"" +
533                 (this.target ? " target=\"" + this.target + "\"" : "") +
534                 ">" + label + "</a></div>" +
535                 "<div id=\"" + this.id + "-cont\" class=\"webfx-tree-container\" style=\"display: " + ((this.open)?'block':'none') + ";\">";
536         var sb = [];
537         for (var i = 0; i < this.childNodes.length; i++) {
538                 sb[i] = this.childNodes[i].toString(i,this.childNodes.length);
539         }
540         this.plusIcon = ((this.parentNode._last)?webFXTreeConfig.lPlusIcon:webFXTreeConfig.tPlusIcon);
541         this.minusIcon = ((this.parentNode._last)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.tMinusIcon);
542         return str + sb.join("") + "</div>";
543 }