Updated XLoadTree to latest version.
authorjollytoad <jollytoad>
Tue, 19 Jul 2005 15:28:24 +0000 (15:28 +0000)
committerjollytoad <jollytoad>
Tue, 19 Jul 2005 15:28:24 +0000 (15:28 +0000)
(Removes dep on xmlextras.js)

browser.php
xloadtree/xloadtree2.js
xloadtree/xmlextras.js [deleted file]
xloadtree/xtree2.js

index 97dbabab1786bc5c030feb6c29cc1d5ed6d28171..ecfb029cf5281542f0bd45686b8c5dad43f453a8 100644 (file)
@@ -5,7 +5,7 @@
         * if you click on a database it shows a list of database objects in that
         * database.
         *
-        * $Id: browser.php,v 1.47 2005/07/19 11:17:28 jollytoad Exp $
+        * $Id: browser.php,v 1.48 2005/07/19 15:28:24 jollytoad Exp $
         */
 
        // Include application functions
        
        // Output header
        $misc->printHeader('', '
-               <script src="xloadtree/xmlextras.js" type="text/javascript"></script>
                <script src="xloadtree/xtree2.js" type="text/javascript"></script>
                <script src="xloadtree/xloadtree2.js" type="text/javascript"></script>
                <style type="text/css">
-                       .webfx-tree-children { background-image: url("' . $misc->icon('I')  .'"); }
+                       .webfx-tree-children { background-image: url("' . $misc->icon('I') '"); }
                </style>');
        
        $misc->printBody('browser');
index 234613274a33b815e50245f701e94e7493ba0d62..f5e5f05c6876d3e0352f76c1ab4161182f7e5102 100644 (file)
@@ -12,7 +12,7 @@
 |-----------------------------------------------------------------------------|\r
 | A tree menu system for IE 5.5+, Mozilla 1.4+, Opera 7.5+                    |\r
 |-----------------------------------------------------------------------------|\r
-|         Copyright (c) 1999 - 2004 Erik Arvidsson & Emil A Eklund            |\r
+|         Copyright (c) 1999 - 2005 Erik Arvidsson & Emil A Eklund            |\r
 |-----------------------------------------------------------------------------|\r
 | This software is provided "as is", without warranty of any kind, express or |\r
 | implied, including  but not limited  to the warranties of  merchantability, |\r
 | this, is also licensed under the GPL license.                               |\r
 |-----------------------------------------------------------------------------|\r
 | 2004-02-21 | Pre release distributed to a few selected tester               |\r
+| 2005-06-06 | Removed dependency on XML Extras                               |\r
 |-----------------------------------------------------------------------------|\r
 | Dependencies: xtree2.js Supplies the tree control                           |\r
 |-----------------------------------------------------------------------------|\r
-| Created 2003-??-?? | All changes are in the log above. | Updated 2004-02-21 |\r
+| Created 2003-??-?? | All changes are in the log above. | Updated 2004-06-06 |\r
 \----------------------------------------------------------------------------*/\r
 \r
 \r
 webFXTreeConfig.loadingText = "Loading...";\r
 webFXTreeConfig.loadingIcon = "images/loading.gif";\r
-webFXTreeConfig.errorIcon = "images/exclamation.16.gif";\r
-webFXTreeConfig.errorLoadingText = "Error Loading";\r
-webFXTreeConfig.reloadText = "Click to reload";\r
 \r
 \r
-function WebFXLoadTree(sText, sXmlSrc, oAction, sBehavior, sIcon, sOpenIcon)\r
-{\r
+function WebFXLoadTree(sText, sXmlSrc, oAction, sBehavior, sIcon, sOpenIcon) {\r
        WebFXTree.call(this, sText, oAction, sBehavior, sIcon, sOpenIcon);\r
 \r
        // setup default property values\r
@@ -66,41 +63,36 @@ function WebFXLoadTree(sText, sXmlSrc, oAction, sBehavior, sIcon, sOpenIcon)
        this.loaded = !sXmlSrc;\r
        this.errorText = "";\r
 \r
-       if (this.src)\r
-       {\r
+       if (this.src) {\r
                /// add loading Item\r
                this._loadingItem = WebFXLoadTree.createLoadingItem();\r
                this.add(this._loadingItem);\r
 \r
-               if (this.getExpanded())\r
+               if (this.getExpanded()) {\r
                        WebFXLoadTree.loadXmlDocument(this);\r
+               }\r
        }\r
 }\r
 \r
-WebFXLoadTree.createLoadingItem = function ()\r
-{\r
+WebFXLoadTree.createLoadingItem = function () {\r
        return new WebFXTreeItem(webFXTreeConfig.loadingText, null, null,\r
                                                         webFXTreeConfig.loadingIcon);\r
 };\r
 \r
-WebFXLoadTree.prototype = new WebFXTree;\r
+_p = WebFXLoadTree.prototype = new WebFXTree;\r
 \r
-WebFXLoadTree.prototype.setExpanded = function (b)\r
-{\r
+_p.setExpanded = function (b) {\r
        WebFXTree.prototype.setExpanded.call(this, b);\r
 \r
-       if (this.src && b)\r
-       {\r
-               if (!this.loaded && !this.loading)\r
-               {\r
+       if (this.src && b) {\r
+               if (!this.loaded && !this.loading) {\r
                        // load\r
                        WebFXLoadTree.loadXmlDocument(this);\r
                }\r
        }\r
 };\r
 \r
-function WebFXLoadTreeItem(sText, sXmlSrc, oAction, eParent, sIcon, sOpenIcon)\r
-{\r
+function WebFXLoadTreeItem(sText, sXmlSrc, oAction, eParent, sIcon, sOpenIcon) {\r
        WebFXTreeItem.call(this, sText, oAction, eParent, sIcon, sOpenIcon);\r
 \r
 // setup default property values\r
@@ -109,27 +101,24 @@ function WebFXLoadTreeItem(sText, sXmlSrc, oAction, eParent, sIcon, sOpenIcon)
        this.loaded = !sXmlSrc;\r
        this.errorText = "";\r
 \r
-       if (this.src)\r
-       {\r
+       if (this.src) {\r
                /// add loading Item\r
                this._loadingItem = WebFXLoadTree.createLoadingItem();\r
                this.add(this._loadingItem);\r
 \r
-               if (this.getExpanded())\r
+               if (this.getExpanded()) {\r
                        WebFXLoadTree.loadXmlDocument(this);\r
+               }\r
        }\r
 }\r
 \r
-WebFXLoadTreeItem.prototype = new WebFXTreeItem;\r
+_p = WebFXLoadTreeItem.prototype = new WebFXTreeItem;\r
 \r
-WebFXLoadTreeItem.prototype.setExpanded = function (b)\r
-{\r
+_p.setExpanded = function (b) {\r
        WebFXTreeItem.prototype.setExpanded.call(this, b);\r
 \r
-       if (this.src && b)\r
-       {\r
-               if (!this.loaded && !this.loading)\r
-               {\r
+       if (this.src && b) {\r
+               if (!this.loaded && !this.loading) {\r
                        // load\r
                        WebFXLoadTree.loadXmlDocument(this);\r
                }\r
@@ -138,48 +127,46 @@ WebFXLoadTreeItem.prototype.setExpanded = function (b)
 \r
 // reloads the src file if already loaded\r
 WebFXLoadTree.prototype.reload =\r
-WebFXLoadTreeItem.prototype.reload = function ()\r
-{\r
+_p.reload = function () {\r
        // if loading do nothing\r
-       if (this.loaded)\r
-       {\r
+       if (this.loaded) {\r
                var t = this.getTree();\r
                var expanded = this.getExpanded();\r
                var sr = t.getSuspendRedraw();\r
                t.setSuspendRedraw(true);\r
 \r
                // remove\r
-               while (this.childNodes.length > 0)\r
+               while (this.childNodes.length > 0) {\r
                        this.remove(this.childNodes[this.childNodes.length - 1]);\r
+               }\r
 \r
                this.loaded = false;\r
 \r
                this._loadingItem = WebFXLoadTree.createLoadingItem();\r
                this.add(this._loadingItem);\r
 \r
-               if (expanded)\r
+               if (expanded) {\r
                        this.setExpanded(true);\r
+               }\r
 \r
                t.setSuspendRedraw(sr);\r
                this.update();\r
-       }\r
-       else if (this.open && !this.loading)\r
+       } else if (this.open && !this.loading) {\r
                WebFXLoadTree.loadXmlDocument(this);\r
+       }\r
 };\r
 \r
 \r
 \r
 WebFXLoadTree.prototype.setSrc =\r
-WebFXLoadTreeItem.prototype.setSrc = function (sSrc)\r
-{\r
+_p.setSrc = function (sSrc) {\r
        var oldSrc = this.src;\r
        if (sSrc == oldSrc) return;\r
 \r
        var expanded = this.getExpanded();\r
 \r
        // remove all\r
-       this._callSuspended(function ()\r
-       {\r
+       this._callSuspended(function () {\r
                // remove\r
                while (this.childNodes.length > 0)\r
                        this.remove(this.childNodes[this.childNodes.length - 1]);\r
@@ -188,15 +175,13 @@ WebFXLoadTreeItem.prototype.setSrc = function (sSrc)
 \r
        this.loaded = false;\r
        this.loading = false;\r
-       if (this._loadingItem)\r
-       {\r
+       if (this._loadingItem) {\r
                this._loadingItem.dispose();\r
                this._loadingItem = null;\r
        }\r
        this.src = sSrc;\r
 \r
-       if (sSrc)\r
-       {\r
+       if (sSrc) {\r
                this._loadingItem = WebFXLoadTree.createLoadingItem();\r
                this.add(this._loadingItem);\r
        }\r
@@ -205,41 +190,35 @@ WebFXLoadTreeItem.prototype.setSrc = function (sSrc)
 };\r
 \r
 WebFXLoadTree.prototype.getSrc =\r
-WebFXLoadTreeItem.prototype.getSrc = function ()\r
-{\r
+_p.getSrc = function () {\r
        return this.src;\r
 };\r
 \r
-WebFXLoadTree.prototype.dispose = function ()\r
-{\r
+WebFXLoadTree.prototype.dispose = function () {\r
        WebFXTree.prototype.dispose.call(this);\r
        if (this._xmlHttp)\r
        {\r
-               if (this._xmlHttp.dispose)\r
+               if (this._xmlHttp.dispose) {\r
                        this._xmlHttp.dispose();\r
-               try\r
-               {\r
+               }\r
+               try {\r
                        this._xmlHttp.onreadystatechange = null;\r
                        this._xmlHttp.abort();\r
-               }\r
-               catch (ex) {}\r
+               } catch (ex) {}\r
                this._xmlHttp = null;\r
        }\r
 };\r
 \r
-WebFXLoadTreeItem.prototype.dispose = function ()\r
-{\r
+_p.dispose = function () {\r
        WebFXTreeItem.prototype.dispose.call(this);\r
-       if (this._xmlHttp)\r
-       {\r
-               if (this._xmlHttp.dispose)\r
+       if (this._xmlHttp) {\r
+               if (this._xmlHttp.dispose) {\r
                        this._xmlHttp.dispose();\r
-               try\r
-               {\r
+               }\r
+               try {\r
                        this._xmlHttp.onreadystatechange = null;\r
                        this._xmlHttp.abort();\r
-               }\r
-               catch (ex) {}\r
+               } catch (ex) {}\r
                this._xmlHttp = null;\r
        }\r
 };\r
@@ -247,45 +226,40 @@ WebFXLoadTreeItem.prototype.dispose = function ()
 \r
 // The path is divided by '/' and the item is identified by the text\r
 WebFXLoadTree.prototype.openPath =\r
-WebFXLoadTreeItem.prototype.openPath = function (sPath, bSelect, bFocus)\r
-{\r
+_p.openPath = function (sPath, bSelect, bFocus) {\r
        // remove any old pending paths to open\r
        delete this._pathToOpen;\r
        //delete this._pathToOpenById;\r
        this._selectPathOnLoad = bSelect;\r
        this._focusPathOnLoad = bFocus;\r
 \r
-       if (sPath == "")\r
-       {\r
-               if (bSelect)\r
+       if (sPath == "") {\r
+               if (bSelect) {\r
                        this.select();\r
-               if (bFocus)\r
+               }\r
+               if (bFocus) {\r
                        window.setTimeout("WebFXTreeAbstractNode._onTimeoutFocus(\"" + this.getId() + "\")", 10);\r
+               }\r
                return;\r
        }\r
 \r
        var parts = sPath.split("/");\r
        var remainingPath = parts.slice(1).join("/");\r
 \r
-       if (sPath.charAt(0) == "/")\r
-       {\r
+       if (sPath.charAt(0) == "/") {\r
                this.getTree().openPath(remainingPath, bSelect, bFocus);\r
-       }\r
-       else\r
-       {\r
+       } else {\r
                // open\r
                this.setExpanded(true);\r
-               if (this.loaded)\r
-               {\r
+               if (this.loaded) {\r
                        parts = sPath.split("/");\r
                        var ti = this.findChildByText(parts[0]);\r
-                       if (!ti)\r
+                       if (!ti) {\r
                                throw "Could not find child node with text \"" + parts[0] + "\"";\r
+                       }\r
 \r
                        ti.openPath(remainingPath, bSelect, bFocus);\r
-               }\r
-               else\r
-               {\r
+               } else {\r
                        this._pathToOpen = sPath;\r
                }\r
        }\r
@@ -296,76 +270,80 @@ WebFXLoadTreeItem.prototype.openPath = function (sPath, bSelect, bFocus)
 // for certain attributes\r
 WebFXLoadTree._attrs = ["text", "src", "action", "id", "target"];\r
 \r
-WebFXLoadTree.createItemFromElement = function (oNode)\r
-{\r
+WebFXLoadTree.createItemFromElement = function (oNode) {\r
        var jsAttrs = {};\r
        var domAttrs = oNode.attributes;\r
        var i, l;\r
 \r
        l = domAttrs.length;\r
-       for (i = 0; i < l; i++)\r
-       {\r
-               if (domAttrs[i] == null)\r
-               {\r
+       for (i = 0; i < l; i++) {\r
+               if (domAttrs[i] == null) {\r
                        continue;\r
                }\r
                jsAttrs[domAttrs[i].nodeName] = domAttrs[i].nodeValue;\r
        }\r
 \r
-\r
        var name, val;\r
-       for (i = 0; i < WebFXLoadTree._attrs.length; i++)\r
-       {\r
+       for (i = 0; i < WebFXLoadTree._attrs.length; i++) {\r
                name = WebFXLoadTree._attrs[i];\r
                value = oNode.getAttribute(name);\r
-               if (value)\r
+               if (value) {\r
                        jsAttrs[name] = value;\r
+               }\r
        }\r
 \r
        var action;\r
-       if (jsAttrs.onaction)\r
+       if (jsAttrs.onaction) {\r
                action = new Function(jsAttrs.onaction);\r
-       else if (jsAttrs.action)\r
+       } else if (jsAttrs.action) {\r
                action = jsAttrs.action;\r
+       }\r
        var jsNode = new WebFXLoadTreeItem(jsAttrs.html || "", jsAttrs.src, action,\r
                                                                           null, jsAttrs.icon, jsAttrs.openIcon);\r
-       if (jsAttrs.text)\r
+       if (jsAttrs.text) {\r
                jsNode.setText(jsAttrs.text);\r
+       }\r
 \r
-       if (jsAttrs.target)\r
+       if (jsAttrs.target) {\r
                jsNode.target = jsAttrs.target;\r
-       if (jsAttrs.id)\r
+       }\r
+       if (jsAttrs.id) {\r
                jsNode.setId(jsAttrs.id);\r
-       if (jsAttrs.toolTip)\r
+       }\r
+       if (jsAttrs.toolTip) {\r
                jsNode.toolTip = jsAttrs.toolTip;\r
-       if (jsAttrs.expanded)\r
+       }\r
+       if (jsAttrs.expanded) {\r
                jsNode.setExpanded(jsAttrs.expanded != "false");\r
-       if (jsAttrs.onload)\r
+       }\r
+       if (jsAttrs.onload) {\r
                jsNode.onload = new Function(jsAttrs.onload);\r
-       if (jsAttrs.onerror)\r
+       }\r
+       if (jsAttrs.onerror) {\r
                jsNode.onerror = new Function(jsAttrs.onerror);\r
+       }\r
 \r
        jsNode.attributes = jsAttrs;\r
 \r
        // go through childNodes\r
        var cs = oNode.childNodes;\r
        l = cs.length;\r
-       for (i = 0; i < l; i++)\r
-       {\r
-               if (cs[i].tagName == "tree")\r
+       for (i = 0; i < l; i++) {\r
+               if (cs[i].tagName == "tree") {\r
                        jsNode.add(WebFXLoadTree.createItemFromElement(cs[i]));\r
+               }\r
        }\r
 \r
        return jsNode;\r
 };\r
 \r
-WebFXLoadTree.loadXmlDocument = function (jsNode)\r
-{\r
-       if (jsNode.loading || jsNode.loaded)\r
+WebFXLoadTree.loadXmlDocument = function (jsNode) {\r
+       if (jsNode.loading || jsNode.loaded) {\r
                return;\r
+       }\r
        jsNode.loading = true;\r
        var id = jsNode.getId();\r
-       jsNode._xmlHttp = XmlHttp.create();\r
+       jsNode._xmlHttp = window.XMLHttpRequest ? new XMLHttpRequest : new window.ActiveXObject("Microsoft.XmlHttp");\r
        jsNode._xmlHttp.open("GET", jsNode.src, true);  // async\r
        jsNode._xmlHttp.onreadystatechange = new Function("WebFXLoadTree._onload(\"" + id + "\")");\r
 \r
@@ -373,11 +351,9 @@ WebFXLoadTree.loadXmlDocument = function (jsNode)
        window.setTimeout("WebFXLoadTree._ontimeout(\"" + id + "\")", 10);\r
 };\r
 \r
-WebFXLoadTree._onload = function (sId)\r
-{\r
+WebFXLoadTree._onload = function (sId) {\r
        var jsNode = webFXTreeHandler.all[sId];\r
-       if (jsNode._xmlHttp.readyState == 4)\r
-       {\r
+       if (jsNode._xmlHttp.readyState == 4) {\r
                WebFXLoadTree.documentLoaded(jsNode);\r
                webFXLoadTreeQueue.remove(jsNode);\r
                if (jsNode._xmlHttp.dispose)\r
@@ -386,8 +362,7 @@ WebFXLoadTree._onload = function (sId)
        }\r
 };\r
 \r
-WebFXLoadTree._ontimeout = function (sId)\r
-{\r
+WebFXLoadTree._ontimeout = function (sId) {\r
        var jsNode = webFXTreeHandler.all[sId];\r
        webFXLoadTreeQueue.add(jsNode);\r
 };\r
@@ -395,10 +370,10 @@ WebFXLoadTree._ontimeout = function (sId)
 \r
 \r
 // Inserts an xml document as a subtree to the provided node\r
-WebFXLoadTree.documentLoaded = function (jsNode)\r
-{\r
-       if (jsNode.loaded)\r
+WebFXLoadTree.documentLoaded = function (jsNode) {\r
+       if (jsNode.loaded) {\r
                return;\r
+       }\r
 \r
        jsNode.errorText = "";\r
        jsNode.loaded = true;\r
@@ -411,19 +386,13 @@ WebFXLoadTree.documentLoaded = function (jsNode)
        var doc = jsNode._xmlHttp.responseXML;\r
 \r
        // check that the load of the xml file went well\r
-       if(!doc || doc.parserError && doc.parseError.errorCode != 0 || !doc.documentElement)\r
-       {\r
-               if (!doc || doc.parseError.errorCode == 0)\r
-               {\r
-                       jsNode.errorText = webFXTreeConfig.errorLoadingText + " " + jsNode.src + " (" + jsNode._xmlHttp.status + ": " + jsNode._xmlHttp.statusText + ")";\r
-               }\r
-               else\r
-               {\r
-                       jsNode.errorText =  webFXTreeConfig.errorLoadingText + " " + jsNode.src + " (" + doc.parseError.reason + ")";\r
+       if(!doc || doc.parserError && doc.parseError.errorCode != 0 || !doc.documentElement) {\r
+               if (!doc || doc.parseError.errorCode == 0) {\r
+                       jsNode.errorText = "Error loading " + jsNode.src + " (" + jsNode._xmlHttp.status + ": " + jsNode._xmlHttp.statusText + ")";\r
+               } else {\r
+                       jsNode.errorText = "Error loading " + jsNode.src + " (" + doc.parseError.reason + ")";\r
                }\r
-       }\r
-       else\r
-       {\r
+       } else {\r
                // there is one extra level of tree elements\r
                var root = doc.documentElement;\r
 \r
@@ -431,54 +400,51 @@ WebFXLoadTree.documentLoaded = function (jsNode)
                var count = 0;\r
                var cs = root.childNodes;\r
                var l = cs.length;\r
-               for (var i = 0; i < l; i++)\r
-               {\r
-                       if (cs[i].tagName == "tree")\r
-                       {\r
+               for (var i = 0; i < l; i++) {\r
+                       if (cs[i].tagName == "tree") {\r
                                jsNode.add(WebFXLoadTree.createItemFromElement(cs[i]));\r
                                count++;\r
                        }\r
                }\r
 \r
                // if no children we got an error\r
-               if (count == 0)\r
-               {\r
-                       jsNode.errorText =  webFXTreeConfig.errorLoadingText + " " + jsNode.src + " (???)";\r
+               if (count == 0) {\r
+                       jsNode.errorText = "Error loading " + jsNode.src + " (???)";\r
                }\r
        }\r
 \r
-       if (jsNode.errorText != "")\r
-       {\r
-               jsNode._loadingItem.icon = webFXTreeConfig.errorIcon;\r
+       if (jsNode.errorText != "") {\r
+               jsNode._loadingItem.icon = "images/exclamation.16.gif";\r
                jsNode._loadingItem.text = jsNode.errorText;\r
                jsNode._loadingItem.action = WebFXLoadTree._reloadParent;\r
-               jsNode._loadingItem.toolTip = webFXTreeConfig.reloadText;\r
+               jsNode._loadingItem.toolTip = "Click to reload";\r
 \r
                t.setSuspendRedraw(oldSuspend);\r
 \r
                jsNode._loadingItem.update();\r
 \r
-               if (typeof jsNode.onerror == "function")\r
+               if (typeof jsNode.onerror == "function") {\r
                        jsNode.onerror();\r
-       }\r
-       else\r
-       {\r
+               }\r
+       } else {\r
                // remove dummy\r
-               if (jsNode._loadingItem != null)\r
+               if (jsNode._loadingItem != null) {\r
                        jsNode.remove(jsNode._loadingItem);\r
+               }\r
 \r
-               if (jsNode._pathToOpen)\r
+               if (jsNode._pathToOpen) {\r
                        jsNode.openPath(jsNode._pathToOpen, jsNode._selectPathOnLoad, jsNode._focusPathOnLoad);\r
+               }\r
 \r
                t.setSuspendRedraw(oldSuspend);\r
                jsNode.update();\r
-               if (typeof jsNode.onload == "function")\r
+               if (typeof jsNode.onload == "function") {\r
                        jsNode.onload();\r
+               }\r
        }\r
 };\r
 \r
-WebFXLoadTree._reloadParent = function ()\r
-{\r
+WebFXLoadTree._reloadParent = function () {\r
        this.getParent().reload();\r
 };\r
 \r
@@ -490,45 +456,41 @@ WebFXLoadTree._reloadParent = function ()
 \r
 var webFXLoadTreeQueue = {\r
        _nodes: [],\r
-       _ie:    /msie/i.test(navigator.userAgent),\r
-       _opera: /opera/i.test(navigator.userAgent),\r
+       _ie: /msie/i.test(navigator.userAgent),\r
+       _opera: /opera/i.test(navigator.userAgent),\r
 \r
-       add: function (jsNode)\r
-       {\r
-               if (this._ie || this._opera)\r
-               {\r
+       add: function (jsNode) {\r
+               if (this._ie || this._opera) {\r
                        this._nodes.push(jsNode);\r
-                       if (this._nodes.length == 1)\r
+                       if (this._nodes.length == 1) {\r
                                this._send();\r
-               }\r
-               else\r
-               {\r
+                       }\r
+               } else {\r
                        jsNode._xmlHttp.send(null);\r
                }\r
        },\r
 \r
-\r
-       remove: function (jsNode)\r
-       {\r
-               if (this._ie || this._opera)\r
-               {\r
+       remove: function (jsNode) {\r
+               if (this._ie || this._opera) {\r
                        arrayHelper.remove(this._nodes, jsNode);\r
-                       if (this._nodes.length > 0)\r
+                       if (this._nodes.length > 0) {\r
                                this._send();\r
+                       }\r
                }\r
        },\r
 \r
        // IE only\r
-       _send:  function ()\r
-       {\r
+       _send:  function () {\r
                var id = this._nodes[0].getId();\r
                var jsNode = webFXTreeHandler.all[id];\r
-               if (!jsNode)\r
+               if (!jsNode) {\r
                        return;\r
+               }\r
                // if no _xmlHttp then remove it\r
-               if (!jsNode._xmlHttp)\r
+               if (!jsNode._xmlHttp) {\r
                        this.remove(jsNode);\r
-               else\r
+               } else {\r
                        jsNode._xmlHttp.send(null);\r
+               }\r
        }\r
 };\r
diff --git a/xloadtree/xmlextras.js b/xloadtree/xmlextras.js
deleted file mode 100644 (file)
index 6a67512..0000000
+++ /dev/null
@@ -1,232 +0,0 @@
-/*----------------------------------------------------------------------------\\r
-|                               XML Extras 1.01                               |\r
-|-----------------------------------------------------------------------------|\r
-|                         Created by Erik Arvidsson                           |\r
-|                  (http://webfx.eae.net/contact.html#erik)                   |\r
-|                      For WebFX (http://webfx.eae.net/)                      |\r
-|-----------------------------------------------------------------------------|\r
-| A library that makes working with XML documents in Mozilla more similar to  |\r
-| working with MSXML.                                                         |\r
-|-----------------------------------------------------------------------------|\r
-|                   Copyright (c) 1999 - 2003 Erik Arvidsson                  |\r
-|-----------------------------------------------------------------------------|\r
-| This software is provided "as is", without warranty of any kind, express or |\r
-| implied, including  but not limited  to the warranties of  merchantability, |\r
-| fitness for a particular purpose and noninfringement. In no event shall the |\r
-| authors or  copyright  holders be  liable for any claim,  damages or  other |\r
-| liability, whether  in an  action of  contract, tort  or otherwise, arising |\r
-| from,  out of  or in  connection with  the software or  the  use  or  other |\r
-| dealings in the software.                                                   |\r
-| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |\r
-| This  software is  available under the  three different licenses  mentioned |\r
-| below.  To use this software you must chose, and qualify, for one of those. |\r
-| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |\r
-| The WebFX Non-Commercial License          http://webfx.eae.net/license.html |\r
-| Permits  anyone the right to use the  software in a  non-commercial context |\r
-| free of charge.                                                             |\r
-| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |\r
-| The WebFX Commercial license           http://webfx.eae.net/commercial.html |\r
-| Permits the  license holder the right to use  the software in a  commercial |\r
-| context. Such license must be specifically obtained, however it's valid for |\r
-| any number of  implementations of the licensed software.                    |\r
-| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |\r
-| GPL - The GNU General Public License    http://www.gnu.org/licenses/gpl.txt |\r
-| Permits anyone the right to use and modify the software without limitations |\r
-| as long as proper  credits are given  and the original  and modified source |\r
-| code are included. Requires  that the final product, software derivate from |\r
-| the original  source or any  software  utilizing a GPL  component, such  as |\r
-| this, is also licensed under the GPL license.                               |\r
-|-----------------------------------------------------------------------------|\r
-| ????-??-?? | Original Version Posted.                                       |\r
-| 2003-09-25 | Added support for parseError getters. Also changed to extend   |\r
-|            | only XMLDocument instead of Document                           |\r
-|-----------------------------------------------------------------------------|\r
-| Created ????-??-?? | All changes are in the log above. | Updated 2003-09-25 |\r
-\----------------------------------------------------------------------------*/\r
-\r
-\r
-//////////////////\r
-// Helper Stuff //\r
-//////////////////\r
-\r
-// used to find the Automation server name\r
-function getDomDocumentPrefix() {\r
-       if (getDomDocumentPrefix.prefix)\r
-               return getDomDocumentPrefix.prefix;\r
-\r
-       var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];\r
-       var o;\r
-       for (var i = 0; i < prefixes.length; i++) {\r
-               try {\r
-                       // try to create the objects\r
-                       o = new ActiveXObject(prefixes[i] + ".DomDocument");\r
-                       return getDomDocumentPrefix.prefix = prefixes[i];\r
-               }\r
-               catch (ex) {};\r
-       }\r
-\r
-       throw new Error("Could not find an installed XML parser");\r
-}\r
-\r
-function getXmlHttpPrefix() {\r
-       if (getXmlHttpPrefix.prefix)\r
-               return getXmlHttpPrefix.prefix;\r
-\r
-       var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];\r
-       var o;\r
-       for (var i = 0; i < prefixes.length; i++) {\r
-               try {\r
-                       // try to create the objects\r
-                       o = new ActiveXObject(prefixes[i] + ".XmlHttp");\r
-                       return getXmlHttpPrefix.prefix = prefixes[i];\r
-               }\r
-               catch (ex) {};\r
-       }\r
-\r
-       throw new Error("Could not find an installed XML parser");\r
-}\r
-\r
-//////////////////////////\r
-// Start the Real stuff //\r
-//////////////////////////\r
-\r
-\r
-// XmlHttp factory\r
-function XmlHttp() {}\r
-\r
-XmlHttp.create = function () {\r
-       try {\r
-               if (window.XMLHttpRequest) {\r
-                       var req = new XMLHttpRequest();\r
-\r
-                       // some versions of Moz do not support the readyState property\r
-                       // and the onreadystate event so we patch it!\r
-                       if (req.readyState == null) {\r
-                               req.readyState = 1;\r
-                               req.addEventListener("load", function () {\r
-                                       req.readyState = 4;\r
-                                       if (typeof req.onreadystatechange == "function")\r
-                                               req.onreadystatechange();\r
-                               }, false);\r
-                       }\r
-\r
-                       return req;\r
-               }\r
-               if (window.ActiveXObject) {\r
-                       return new ActiveXObject(getXmlHttpPrefix() + ".XmlHttp");\r
-               }\r
-       }\r
-       catch (ex) {}\r
-       // fell through\r
-       throw new Error("Your browser does not support XmlHttp objects");\r
-};\r
-\r
-// XmlDocument factory\r
-function XmlDocument() {}\r
-\r
-XmlDocument.create = function () {\r
-       try {\r
-               // DOM2\r
-               if (document.implementation && document.implementation.createDocument) {\r
-                       var doc = document.implementation.createDocument("", "", null);\r
-\r
-                       // some versions of Moz do not support the readyState property\r
-                       // and the onreadystate event so we patch it!\r
-                       if (doc.readyState == null) {\r
-                               doc.readyState = 1;\r
-                               doc.addEventListener("load", function () {\r
-                                       doc.readyState = 4;\r
-                                       if (typeof doc.onreadystatechange == "function")\r
-                                               doc.onreadystatechange();\r
-                               }, false);\r
-                       }\r
-\r
-                       return doc;\r
-               }\r
-               if (window.ActiveXObject)\r
-                       return new ActiveXObject(getDomDocumentPrefix() + ".DomDocument");\r
-       }\r
-       catch (ex) {}\r
-       throw new Error("Your browser does not support XmlDocument objects");\r
-};\r
-\r
-// Create the loadXML method and xml getter for Mozilla\r
-if (window.DOMParser &&\r
-       window.XMLSerializer &&\r
-       window.Node && Node.prototype && Node.prototype.__defineGetter__) {\r
-\r
-       // XMLDocument did not extend the Document interface in some versions\r
-       // of Mozilla. Extend both!\r
-       //XMLDocument.prototype.loadXML =\r
-       XMLDocument.prototype.loadXML = function (s) {\r
-\r
-               // parse the string to a new doc\r
-               var doc2 = (new DOMParser()).parseFromString(s, "text/xml");\r
-\r
-               // remove all initial children\r
-               while (this.hasChildNodes())\r
-                       this.removeChild(this.lastChild);\r
-\r
-               // insert and import nodes\r
-               for (var i = 0; i < doc2.childNodes.length; i++) {\r
-                       this.appendChild(this.importNode(doc2.childNodes[i], true));\r
-               }\r
-       };\r
-\r
-\r
-       /*\r
-        * xml getter\r
-        *\r
-        * This serializes the DOM tree to an XML String\r
-        *\r
-        * Usage: var sXml = oNode.xml\r
-        *\r
-        */\r
-\r
-       // Node, should really be XMLNode but there is no such interface\r
-       Node.prototype.__defineGetter__("xml", function () {\r
-               return (new XMLSerializer()).serializeToString(this);\r
-       });\r
-\r
-       XMLDocument.prototype.__defineGetter__("parseError", function () {\r
-               var hasError = !this.documentElement ||\r
-                       this.documentElement.localName == "parsererror" &&\r
-                       this.documentElement.getAttribute("xmlns") == "http://www.mozilla.org/newlayout/xml/parsererror.xml";\r
-               var res = {\r
-                       errorCode:      0,\r
-                       filepos:        0,      // not supported\r
-                       line:           0,\r
-                       linepos:        0,\r
-                       reason:         "",\r
-                       srcText:        "",\r
-                       url:            ""\r
-               };\r
-               if (hasError) {\r
-                       res.errorCode = -1;\r
-                       try {\r
-                               res.srcText = this.getElementsByTagName("sourcetext")[0].firstChild.data;\r
-                               res.srcText = res.srcText.replace( /\n\-\^$/, "");\r
-                       }\r
-                       catch (ex) {\r
-                               res.srcText = "";\r
-                       }\r
-\r
-                       try {\r
-                               // now we need to parse the first text node\r
-                               var s = this.documentElement.firstChild.data;\r
-\r
-                               var re = /XML Parsing Error\: (.+)\nLocation\: (.+)\nLine Number (\d+)\, Column (\d+)/;\r
-                               var a = re.exec( s );\r
-                               res.reason = a[1];\r
-                               res.url = a[2];\r
-                               res.line = a[3];\r
-                               res.linepos = a[4];\r
-                       }\r
-                       catch (ex) {\r
-                               res.reason = "Uknown";\r
-                       }\r
-               }\r
-\r
-               return res;\r
-       });\r
-}
\ No newline at end of file
index 26244bae724cd987d88134935b4351fbc3017599..c2bb27add15dd0a6c164809a18907c3e9fd1f80b 100644 (file)
@@ -12,7 +12,7 @@
 |-----------------------------------------------------------------------------|
 | A tree menu system for IE 5.5+, Mozilla 1.4+, Opera 7, KHTML                |
 |-----------------------------------------------------------------------------|
-|         Copyright (c) 1999 - 2004 Erik Arvidsson & Emil A Eklund            |
+|         Copyright (c) 1999 - 2005 Erik Arvidsson & Emil A Eklund            |
 |-----------------------------------------------------------------------------|
 | This software is provided "as is", without warranty of any kind, express or |
 | implied, including  but not limited  to the warranties of  merchantability, |
 | this, is also licensed under the GPL license.                               |
 |-----------------------------------------------------------------------------|
 | 2004-02-21 | Pre release distributed to a few selected tester               |
+| 2005-06-06 | Added single tab index to improve keyboard navigation          |
 |-----------------------------------------------------------------------------|
 | Dependencies: xtree2.css Used to define the look and feel                   |
 |-----------------------------------------------------------------------------|
-| Created 2003-??-?? | All changes are in the log above. | Updated 2004-02-21 |
+| Created 2003-??-?? | All changes are in the log above. | Updated 2004-06-06 |
 \----------------------------------------------------------------------------*/
 
 
 //
 // WebFXTreePersisitance
 function WebFXTreePersistence() {}
-WebFXTreePersistence.prototype.getExpanded = function (oNode) { return false; };
-WebFXTreePersistence.prototype.setExpanded = function (oNode, bOpen) {};
+var _p = WebFXTreePersistence.prototype;
+_p.getExpanded = function (oNode) { return false; };
+_p.setExpanded = function (oNode, bOpen) {};
 
 
 
 // Cookie handling
 function WebFXCookie() {}
 
-WebFXCookie.prototype.setCookie = function (sName, sValue, nDays)
-{
+_p = WebFXCookie.prototype;
+
+_p.setCookie = function (sName, sValue, nDays) {
        var expires = "";
-       if (typeof nDays == "number")
-       {
+       if (typeof nDays == "number") {
                var d = new Date();
                d.setTime(d.getTime() + nDays * 24 * 60 * 60 * 1000);
                expires = "; expires=" + d.toGMTString();
@@ -73,15 +75,13 @@ WebFXCookie.prototype.setCookie = function (sName, sValue, nDays)
        document.cookie = sName + "=" + escape(sValue) + expires + "; path=/";
 };
 
-WebFXCookie.prototype.getCookie = function (sName)
-{
+_p.getCookie = function (sName) {
        var re = new RegExp("(\;|^)[^;]*(" + sName + ")\=([^;]*)(;|$)");
        var res = re.exec(document.cookie);
        return res != null ? unescape(res[3]) : null;
 };
 
-WebFXCookie.prototype.removeCookie = function (name)
-{
+_p.removeCookie = function (name) {
        this.setCookie(name, "", -1);
 };
 
@@ -91,37 +91,33 @@ WebFXCookie.prototype.removeCookie = function (name)
 //
 // This is uses one cookie with the ids of the expanded nodes separated using '+'
 //
-function WebFXTreeCookiePersistence()
-{
+function WebFXTreeCookiePersistence() {
        this._openedMap = {};
        this._cookies = new WebFXCookie;
        var s = this._cookies.getCookie(this.cookieName);
-       if (s)
-       {
+       if (s) {
                var a = s.split("+");
                for (var i = a.length - 1; i >= 0; i--)
                        this._openedMap[a[i]] = true;
        }
 }
 
-WebFXTreeCookiePersistence.prototype = new WebFXTreePersistence;
+_p = WebFXTreeCookiePersistence.prototype = new WebFXTreePersistence;
 
-WebFXTreeCookiePersistence.prototype.cookieName = "webfx-tree-cookie-persistence"
+_p.cookieName = "webfx-tree-cookie-persistence"
 
-WebFXTreeCookiePersistence.prototype.getExpanded = function (oNode)
-{
+_p.getExpanded = function (oNode) {
        return oNode.id in this._openedMap;
 };
 
-WebFXTreeCookiePersistence.prototype.setExpanded = function (oNode, bOpen)
-{
+_p.setExpanded = function (oNode, bOpen) {
        var old = this.getExpanded(oNode);
-       if (old != bOpen)
-       {
-               if (bOpen)
+       if (old != bOpen) {
+               if (bOpen) {
                        this._openedMap[oNode.id] = true;
-               else
+               } else {
                        delete this._openedMap[oNode.id];
+               }
 
                var res = [];
                var i = 0;
@@ -134,32 +130,30 @@ WebFXTreeCookiePersistence.prototype.setExpanded = function (oNode, bOpen)
 
 
 // this object provides a few useful methods when working with arrays
-var arrayHelper =
-{
-       indexOf:                function (a, o)
-       {
-               for (var i = 0; i < a.length; i++)
-               {
-                       if (a[i] == o)
+var arrayHelper = {
+       indexOf: function (a, o) {
+               for (var i = 0; i < a.length; i++) {
+                       if (a[i] == o) {
                                return i;
+                       }
                }
                return -1;
        },
 
-       insertBefore:   function (a, o, o2)
-       {
+       insertBefore: function (a, o, o2) {
                var i = this.indexOf(a, o2);
-               if (i == -1)
+               if (i == -1) {
                        a.push(o);
-               else
+               } else {
                        a.splice(i, 0, o);
+               }
        },
 
-       remove:                 function (a, o)
-       {
+       remove: function (a, o) {
                var i = this.indexOf(a, o);
-               if (i != -1)
+               if (i != -1) {
                        a.splice(i, 1);
+               }
        }
 };
 
@@ -167,24 +161,24 @@ var arrayHelper =
 // WebFX Tree Config object                                                  //
 ///////////////////////////////////////////////////////////////////////////////
 var webFXTreeConfig = {
-       rootIcon        : 'images/folder.png',
-       openRootIcon    : 'images/openfolder.png',
-       folderIcon      : 'images/folder.png',
-       openFolderIcon  : 'images/openfolder.png',
-       fileIcon        : 'images/file.png',
-       iIcon           : 'images/I.png',
-       lIcon           : 'images/L.png',
-       lMinusIcon      : 'images/Lminus.png',
-       lPlusIcon       : 'images/Lplus.png',
-       tIcon           : 'images/T.png',
-       tMinusIcon      : 'images/Tminus.png',
-       tPlusIcon       : 'images/Tplus.png',
-       plusIcon        : 'images/plus.png',
-       minusIcon       : 'images/minus.png',
-       blankIcon       : 'images/blank.png',
-       defaultText     : 'Tree Item',
+       rootIcon        : "images/folder.png",
+       openRootIcon    : "images/openfolder.png",
+       folderIcon      : "images/folder.png",
+       openFolderIcon  : "images/openfolder.png",
+       fileIcon        : "images/file.png",
+       iIcon           : "images/I.png",
+       lIcon           : "images/L.png",
+       lMinusIcon      : "images/Lminus.png",
+       lPlusIcon       : "images/Lplus.png",
+       tIcon           : "images/T.png",
+       tMinusIcon      : "images/Tminus.png",
+       tPlusIcon       : "images/Tplus.png",
+       plusIcon        : "images/plus.png",
+       minusIcon       : "images/minus.png",
+       blankIcon       : "images/blank.png",
+       defaultText     : "Tree Item",
        defaultAction   : null,
-       defaultBehavior : 'classic',
+       defaultBehavior : "classic",
        usePersistence  : true
 };
 
@@ -193,75 +187,54 @@ var webFXTreeConfig = {
 ///////////////////////////////////////////////////////////////////////////////
 
 var webFXTreeHandler = {
-       ie:             /msie/i.test(navigator.userAgent),
-       idCounter : 0,
-       idPrefix  : "wfxt-",
-       getUniqueId:    function ()
-       {
+       ie: /msie/i.test(navigator.userAgent),
+       opera: /opera/i.test(navigator.userAgent),
+       idCounter: 0,
+       idPrefix: "wfxt-",
+       getUniqueId: function () {
                return this.idPrefix + this.idCounter++;
        },
-       all       : {},
-       getNodeById:    function (sId)
-       {
+       all: {},
+       getNodeById: function (sId) {
                return all[sId];
        },
-       addNode:        function (oNode)
-       {
+       addNode: function (oNode) {
                this.all[oNode.id] = oNode;
        },
-       removeNode:     function (oNode)
-       {
+       removeNode:     function (oNode) {
                delete this.all[oNode.id];
        },
 
-       handleEvent:    function (e)
-       {
+       handleEvent: function (e) {
                var el = e.target || e.srcElement;
-               while (el != null && !this.all[el.id])
+               while (el != null && !this.all[el.id]) {
                        el = el.parentNode;
+               }
 
-               if (el == null)
+               if (el == null) {
                        return false;
+               }
                var node = this.all[el.id];
-               switch (e.type)
-               {
-                       case "mousedown":
-                               return node._onMouseDown(e);
-                       case "click":
-                               return node._onClick(e);
-                       case "dblclick":
-                               return node._onDblClick(e);
-                       case "focus":
-                               return node._onFocus(e);
-                       case "blur":
-                               return node._onBlur(e);
-                       case "keydown":
-                               return node._onKeyDown(e);
-                       case "keypress":
-                               return node._onKeyPress(e);
+               if (typeof node["_on" + e.type] == "function") {
+                       return node["_on" + e.type](e);
                }
                return false;
        },
 
-       dispose:        function ()
-       {
+       dispose: function () {
                if (this.disposed) return;
-               for (var id in this.all)
+               for (var id in this.all) {
                        this.all[id].dispose();
+               }
                this.disposed = true;
        },
 
-       opera:          /opera/i.test(navigator.userAgent),
-
-       htmlToText:             function (s)
-       {
+       htmlToText: function (s) {
                return String(s).replace(/\s+|<([^>])+>|&amp;|&lt;|&gt;|&quot;|&nbsp;/gi, this._htmlToText);
        },
 
-       _htmlToText:    function (s)
-       {
-               switch (s)
-               {
+       _htmlToText: function (s) {
+               switch (s) {
                        case "&amp;":
                                return "&";
                        case "&lt;":
@@ -273,23 +246,22 @@ var webFXTreeHandler = {
                        case "&nbsp;":
                                return String.fromCharCode(160);
                        default:
-                               if (/\s+/.test(s))
+                               if (/\s+/.test(s)) {
                                        return " ";
-                               if (/^<BR/gi.test(s))
+                               }
+                               if (/^<BR/gi.test(s)) {
                                        return "\n";
+                               }
                                return "";
                }
        },
 
-       textToHtml:             function (s)
-       {
+       textToHtml: function (s) {
                return String(s).replace(/&|<|>|\n|\"\u00A0/g, this._textToHtml);
        },
 
-       _textToHtml:    function (s)
-       {
-               switch (s)
-               {
+       _textToHtml: function (s) {
+               switch (s) {
                        case "&":
                                return "&amp;";
                        case "<":
@@ -305,7 +277,7 @@ var webFXTreeHandler = {
                }
        },
 
-       persistenceManager:     new WebFXTreeCookiePersistence()
+       persistenceManager: new WebFXTreeCookiePersistence()
 };
 
 
@@ -313,19 +285,19 @@ var webFXTreeHandler = {
 // WebFXTreeAbstractNode
 ///////////////////////////////////////////////////////////////////////////////
 
-function WebFXTreeAbstractNode(sText, oAction)
-{
+function WebFXTreeAbstractNode(sText, oAction) {
        this.childNodes = [];
        if (sText) this.text = sText;
        if (oAction) this.action = oAction;
        this.id = webFXTreeHandler.getUniqueId();
-       if (webFXTreeConfig.usePersistence)
+       if (webFXTreeConfig.usePersistence) {
                this.open = webFXTreeHandler.persistenceManager.getExpanded(this);
+       }
        webFXTreeHandler.addNode(this);
 }
 
 
-var _p = WebFXTreeAbstractNode.prototype;
+_p = WebFXTreeAbstractNode.prototype;
 _p._selected = false;
 _p.indentWidth = 19;
 _p.open = false;
@@ -337,50 +309,65 @@ _p._focused = false;
 
 /* begin tree model */
 
-_p.add = function (oChild, oBefore)
-{
+_p.add = function (oChild, oBefore) {
        var oldLast;
        var emptyBefore = this.childNodes.length == 0;
        var p = oChild.parentNode;
 
-       if (oBefore == null)
-       { // append
+       if (oBefore == null) { // append
                if (p != null)
                        p.remove(oChild);
                oldLast = this.getLastChild();
                this.childNodes.push(oChild);
-       }
-       else
-       { // insertBefore
-               if (oBefore.parentNode != this)
+       } else { // insertBefore
+               if (oBefore.parentNode != this) {
                        throw new Error("Can only add nodes before siblings");
-               if (p != null)
+               }
+               if (p != null) {
                        p.remove(oChild);
+               }
 
                arrayHelper.insertBefore(this.childNodes, oChild, oBefore);
        }
 
+       if (oBefore) {
+               if (oBefore == this.firstChild) {
+                       this.firstChild = oChild;
+               }
+               oChild.previousSibling = oBefore.previousSibling;
+               oBefore.previousSibling = oChild;
+               oChild.nextSibling = oBefore;
+       } else {
+               if (!this.firstChild) {
+                       this.firstChild = oChild;
+               }
+               if (this.lastChild) {
+                       this.lastChild.nextSibling = oChild;
+               }
+               oChild.previousSibling = this.lastChild;
+               this.lastChild = oChild;
+       }
+
        oChild.parentNode = this;
        var t = this.getTree();
-       if (t)
+       if (t) {
                oChild.tree = t;
+       }
        var d = this.getDepth();
-       if (d != null)
+       if (d != null) {
                oChild.depth = d + 1;
+       }
 
-       if (this.getCreated() && !t.getSuspendRedraw())
-       {
+       if (this.getCreated() && !t.getSuspendRedraw()) {
                var el = this.getChildrenElement();
                var newEl = oChild.create();
                var refEl = oBefore ? oBefore.getElement() : null;
                el.insertBefore(newEl, refEl);
 
-               if (oldLast)
-               {
+               if (oldLast) {
                        oldLast.updateExpandIcon();
                }
-               if (emptyBefore)
-               {
+               if (emptyBefore) {
                        this.setExpanded(this.getExpanded());
                        // if we are using classic expand will not update icon
                        if (t && t.getBehavior() != "classic")
@@ -393,54 +380,62 @@ _p.add = function (oChild, oBefore)
 
 
 
-_p.remove = function (oChild)
-{
+_p.remove = function (oChild) {
        // backwards compatible. If no argument remove the node
-       if (arguments.length == 0)
-       {
-               if (this.parentNode)
+       if (arguments.length == 0) {
+               if (this.parentNode) {
                        return this.parentNode.remove(this);
+               }
                return null;
        }
 
        // if we remove selected or tree with the selected we should select this
        var t = this.getTree();
        var si = t ? t.getSelected() : null;
-       if (si == oChild || oChild.contains(si))
-       {
-               if (si.getFocused())
-               {
+       if (si == oChild || oChild.contains(si)) {
+               if (si.getFocused()) {
                        this.select();
                        window.setTimeout("WebFXTreeAbstractNode._onTimeoutFocus(\"" + this.id + "\")", 10);
-               }
-               else
+               } else {
                        this.select();
+               }
        }
 
-       var wasLast = oChild.isLastSibling();
-
-       if (oChild.parentNode != this)
+       if (oChild.parentNode != this) {
                throw new Error("Can only remove children");
+       }
        arrayHelper.remove(this.childNodes, oChild);
 
+       if (this.lastChild == oChild) {
+               this.lastChild = oChild.previousSibling;
+       }
+       if (this.firstChild == oChild) {
+               this.firstChild = oChild.nextSibling;
+       }
+       if (oChild.previousSibling) {
+               oChild.previousSibling.nextSibling = oChild.nextSibling;
+       }
+       if (oChild.nextSibling) {
+               oChild.nextSibling.previousSibling = oChild.previousSibling;
+       }
+
+       var wasLast = oChild.isLastSibling();
+
        oChild.parentNode = null;
        oChild.tree = null;
        oChild.depth = null;
 
-       if (t && this.getCreated() && !t.getSuspendRedraw())
-       {
+       if (t && this.getCreated() && !t.getSuspendRedraw()) {
                var el = this.getChildrenElement();
                var childEl = oChild.getElement();
                el.removeChild(childEl);
-               if (wasLast)
-               {
+               if (wasLast) {
                        var newLast = this.getLastChild();
-                       if (newLast)
+                       if (newLast) {
                                newLast.updateExpandIcon();
+                       }
                }
-               if (!this.hasChildren())
-               {
-                       //this.setExpanded(this.getExpanded());
+               if (!this.hasChildren()) {
                        el.style.display = "none";
                        this.updateExpandIcon();
                        this.updateIcon();
@@ -450,160 +445,148 @@ _p.remove = function (oChild)
        return oChild;
 };
 
-WebFXTreeAbstractNode._onTimeoutFocus = function (sId)
-{
+WebFXTreeAbstractNode._onTimeoutFocus = function (sId) {
        var jsNode = webFXTreeHandler.all[sId];
        jsNode.focus();
 };
 
-_p.getId = function ()
-{
+_p.getId = function () {
        return this.id;
 };
 
-_p.getTree = function ()
-{
+_p.getTree = function () {
        throw new Error("getTree called on Abstract Node");
 };
 
-_p.getDepth = function ()
-{
+_p.getDepth = function () {
        throw new Error("getDepth called on Abstract Node");
 };
 
-_p.getCreated = function ()
-{
+_p.getCreated = function () {
        var t = this.getTree();
        return t && t.rendered;
 };
 
-_p.getParent = function ()
-{
+_p.getParent = function () {
        return this.parentNode;
 };
 
-_p.contains = function (oDescendant)
-{
+_p.contains = function (oDescendant) {
        if (oDescendant == null) return false;
        if (oDescendant == this) return true;
        var p = oDescendant.parentNode;
        return this.contains(p);
 };
 
-_p.getChildren = _p.getChildNodes = function ()
-{
+_p.getChildren = _p.getChildNodes = function () {
        return this.childNodes;
 };
 
-_p.getFirstChild = function ()
-{
+_p.getFirstChild = function () {
        return this.childNodes[0];
 };
 
-_p.getLastChild = function ()
-{
+_p.getLastChild = function () {
        return this.childNodes[this.childNodes.length - 1];
 };
 
-_p.getPreviousSibling = function ()
-{
-       var p = this.parentNode;
-       if (p == null) return null;
-       var cs = p.childNodes;
-       return cs[arrayHelper.indexOf(cs, this) - 1]
+_p.getPreviousSibling = function () {
+       return this.previousSibling;
+       //var p = this.parentNode;
+       //if (p == null) return null;
+       //var cs = p.childNodes;
+       //return cs[arrayHelper.indexOf(cs, this) - 1]
 };
 
-_p.getNextSibling = function ()
-{
-       var p = this.parentNode;
-       if (p == null) return null;
-       var cs = p.childNodes;
-       return cs[arrayHelper.indexOf(cs, this) + 1]
+_p.getNextSibling = function () {
+       return this.nextSibling;
+       //var p = this.parentNode;
+       //if (p == null) return null;
+       //var cs = p.childNodes;
+       //return cs[arrayHelper.indexOf(cs, this) + 1]
 };
 
-_p.hasChildren = function ()
-{
+_p.hasChildren = function () {
        return this.childNodes.length > 0;
 };
 
-
-_p.isLastSibling = function ()
-{
-       return this.parentNode && this == this.parentNode.getLastChild();
+_p.isLastSibling = function () {
+       return this.nextSibling == null;
+       //return this.parentNode && this == this.parentNode.getLastChild();
 };
 
-_p.findChildByText = function (s, n)
-{
-       if (!n)
+_p.findChildByText = function (s, n) {
+       if (!n) {
                n = 0;
+       }
        var isRe = s instanceof RegExp;
-       for (var i = 0; i < this.childNodes.length; i++)
-       {
-               if (isRe && s.test(this.childNodes[i].getText()) || this.childNodes[i].getText() == s)
-               {
-                       if (n == 0)
+       for (var i = 0; i < this.childNodes.length; i++) {
+               if (isRe && s.test(this.childNodes[i].getText()) ||
+                       this.childNodes[i].getText() == s) {
+                       if (n == 0) {
                                return this.childNodes[i];
+                       }
                        n--;
                }
        }
        return null;
 };
 
-_p.findNodeByText = function (s, n)
-{
-       if (!n)
+_p.findNodeByText = function (s, n) {
+       if (!n) {
                n = 0;
+       }
        var isRe = s instanceof RegExp;
-
-       if (isRe && s.test(this.getText()) || this.getText() == s)
-       {
-               if (n == 0)
+       if (isRe && s.test(this.getText()) || this.getText() == s) {
+               if (n == 0) {
                        return this.childNodes[i];
+               }
                n--;
        }
 
        var res;
-       for (var i = 0; i < this.childNodes.length; i++)
-       {
+       for (var i = 0; i < this.childNodes.length; i++) {
                res = this.childNodes[i].findNodeByText(s, n);
-               if (res)
+               if (res) {
                        return res;
+               }
        }
        return null;
 };
 
 /* end tree model */
 
-_p.setId = function (sId)
-{
+_p.setId = function (sId) {
        var el = this.getElement();
        webFXTreeHandler.removeNode(this);
        this.id = sId;
-       if (el)
+       if (el) {
                el.id = sId;
+       }
        webFXTreeHandler.addNode(this);
 };
 
-_p.isSelected = function ()
-{
+_p.isSelected = function () {
        return this._selected;
 };
 
-_p.select = function () { this._setSelected(true); };
-_p.deselect = function () { this._setSelected(false); };
+_p.select = function () {
+       this._setSelected(true);
+};
+
+_p.deselect = function () {
+       this._setSelected(false);
+};
 
-_p._setSelected = function (b)
-{
+_p._setSelected = function (b) {
        var t = this.getTree();
        if (!t) return;
-       if (this._selected != b)
-       {
+       if (this._selected != b) {
                this._selected = b;
 
                var wasFocused = false; // used to keep focus state
                var si = t.getSelected();
-               if (b && si != null && si != this)
-               {
+               if (b && si != null && si != this) {
                        var oldFireChange = t._fireChange;
                        wasFocused = si._focused;
                        t._fireChange = false;
@@ -612,170 +595,171 @@ _p._setSelected = function (b)
                }
 
                var el = this.getRowElement();
-               if (el)
-               {
+               if (el) {
                        el.className = this.getRowClassName();
                }
-               if (b)
-               {
+               if (b) {
+                       this._setTabIndex(t.tabIndex);
                        t._selectedItem = this;
                        t._fireOnChange();
                        t.setSelected(this);
-                       if (wasFocused)
+                       if (wasFocused) {
                                this.focus();
+                       }
+               } else {
+                       this._setTabIndex(-1);
                }
 
-               if (t.getBehavior() != "classic")
+               if (t.getBehavior() != "classic") {
                        this.updateIcon();
+               }
        }
 };
 
 
-_p.getExpanded = function ()
-{
+_p.getExpanded = function () {
        return this.open;
 };
 
-_p.setExpanded = function (b)
-{
+_p.setExpanded = function (b) {
        var ce;
        this.open = b;
        var t = this.getTree();
-       if (this.hasChildren())
-       {
+       if (this.hasChildren()) {
                var si = t ? t.getSelected() : null;
-               if (!b && this.contains(si))
+               if (!b && this.contains(si)) {
                        this.select();
+               }
 
                var el = this.getElement();
-               if (el)
-               {
+               if (el) {
                        ce = this.getChildrenElement();
-                       if (ce)
+                       if (ce) {
                                ce.style.display = b ? "block" : "none";
+                       }
                        var eie = this.getExpandIconElement();
-                       if (eie)
+                       if (eie) {
                                eie.src = this.getExpandIconSrc();
+                       }
                }
 
-               if (webFXTreeConfig.usePersistence)
+               if (webFXTreeConfig.usePersistence) {
                        webFXTreeHandler.persistenceManager.setExpanded(this, b);
-       }
-       else
-       {
+               }
+       } else {
                ce = this.getChildrenElement();
                if (ce)
                        ce.style.display = "none";
        }
-       if (t && t.getBehavior() == "classic")
+       if (t && t.getBehavior() == "classic") {
                this.updateIcon();
+       }
 };
 
-_p.toggle = function ()
-{
+_p.toggle = function () {
        this.setExpanded(!this.getExpanded());
 };
 
-_p.expand = function ()
-{
+_p.expand = function () {
        this.setExpanded(true);
 };
 
-_p.collapse = function ()
-{
+_p.collapse = function () {
        this.setExpanded(false);
 };
 
-_p.collapseChildren = function()
-{
+_p.collapseChildren = function () {
        var cs = this.childNodes;
-       for (var i = 0; i < cs.length; i++)
+       for (var i = 0; i < cs.length; i++) {
                cs[i].collapseAll();
+       }
 };
 
-_p.collapseAll = function()
-{
+_p.collapseAll = function () {
        this.collapseChildren();
        this.collapse();
 };
 
-_p.expandChildren = function()
-{
+_p.expandChildren = function () {
        var cs = this.childNodes;
-       for (var i = 0; i < cs.length; i++)
+       for (var i = 0; i < cs.length; i++) {
                cs[i].expandAll();
+       }
 };
 
-_p.expandAll = function ()
-{
+_p.expandAll = function () {
        this.expandChildren();
        this.expand();
 };
 
-_p.reveal = function ()
-{
+_p.reveal = function () {
        var p = this.getParent();
-       if (p)
-       {
+       if (p) {
                p.setExpanded(true);
                p.reveal();
        }
 };
 
-_p.openPath = function (sPath, bSelect, bFocus)
-{
-       if (sPath == "")
-       {
-               if (bSelect)
+_p.openPath = function (sPath, bSelect, bFocus) {
+       if (sPath == "") {
+               if (bSelect) {
                        this.select();
-               if (bFocus)
+               }
+               if (bFocus) {
                        window.setTimeout("WebFXTreeAbstractNode._onTimeoutFocus(\"" + this.id + "\")", 10);
+               }
                return;
        }
 
        var parts = sPath.split("/");
        var remainingPath = parts.slice(1).join("/");
        var t = this.getTree();
-       if (sPath.charAt(0) == "/")
-       {
-               if (t)
+       if (sPath.charAt(0) == "/") {
+               if (t) {
                        t.openPath(remainingPath, bSelect, bFocus);
-               else
+               } else {
                        throw "Invalid path";
-       }
-       else
-       {
+               }
+       } else {
                // open
                this.setExpanded(true);
                parts = sPath.split("/");
                var ti = this.findChildByText(parts[0]);
-               if (!ti)
+               if (!ti) {
                        throw "Could not find child node with text \"" + parts[0] + "\"";
+               }
                ti.openPath(remainingPath, bSelect, bFocus);
        }
 };
 
-_p.focus = function ()
-{
+_p.focus = function () {
        var el = this.getLabelElement();
-       if (el)
+       if (el) {
                el.focus();
+       }
 };
 
-_p.getFocused = function ()
-{
+_p.getFocused = function () {
        return this._focused;
 };
 
+_p._setTabIndex = function (i) {
+       var a = this.getLabelElement();
+       if (a) {
+               a.setAttribute("tabindex", i);
+       }
+};
+
+
 // HTML generation
 
-_p.toHtml = function ()
-{
-       var childrenSb = [];
+_p.toHtml = function () {
+       var sb = [];
        var cs = this.childNodes;
        var l = cs.length;
-       for (var y = 0; y < l; y++)
-               childrenSb[y] = cs[y].toHtml();
+       for (var y = 0; y < l; y++) {
+               sb[y] = cs[y].toHtml();
+       }
 
        var t = this.getTree();
        var hideLines = !t.getShowLines() || t == this.parentNode && !t.getShowRootLines();
@@ -785,7 +769,7 @@ _p.toHtml = function ()
                this.getLineStyle() +
                (this.getExpanded() && this.hasChildren() ? "" : "display:none;") +
                "\">" +
-               childrenSb.join("") +
+               sb.join("") +
                "</div>";
 
        return "<div class=\"webfx-tree-item\" id=\"" +
@@ -795,11 +779,10 @@ _p.toHtml = function ()
                "</div>";
 };
 
-_p.getRowHtml = function ()
-{
+_p.getRowHtml = function () {
        var t = this.getTree();
        return "<div class=\"" + this.getRowClassName() + "\" style=\"padding-left:" +
-               (this.getDepth() - 1) * this.indentWidth + "px\">" +
+               Math.max(0, (this.getDepth() - 1) * this.indentWidth) + "px\">" +
                this.getExpandIconHtml() +
                //"<span class=\"webfx-tree-icon-and-label\">" +
                this.getIconHtml() +
@@ -808,18 +791,16 @@ _p.getRowHtml = function ()
                "</div>";
 };
 
-_p.getRowClassName = function ()
-{
+_p.getRowClassName = function () {
        return "webfx-tree-row" + (this.isSelected() ? " selected" : "") +
                (this.action ? "" : " no-action");
 };
 
-_p.getLabelHtml = function ()
-{
+_p.getLabelHtml = function () {
        var toolTip = this.getToolTip();
        var target = this.getTarget();
        return "<a href=\"" + webFXTreeHandler.textToHtml(this._getHref()) +
-               "\" class=\"webfx-tree-item-label\"" +
+               "\" class=\"webfx-tree-item-label\" tabindex=\"-1\"" +
                (toolTip ? " title=\"" + webFXTreeHandler.textToHtml(toolTip) + "\"" : "") +
                (target ? " target=\"" + target + "\"" : "") +
                " onfocus=\"webFXTreeHandler.handleEvent(event)\"" +
@@ -827,33 +808,28 @@ _p.getLabelHtml = function ()
                this.getHtml() + "</a>";
 };
 
-_p._getHref = function ()
-{
+_p._getHref = function () {
        if (typeof this.action == "string")
                return this.action;
        else
                return "#";
 };
 
-_p.getEventHandlersHtml = function ()
-{
+_p.getEventHandlersHtml = function () {
        return "";
 };
 
-_p.getIconHtml = function ()
-{
+_p.getIconHtml = function () {
        // here we are not using textToHtml since the file names rarerly contains
        // HTML...
        return "<img class=\"webfx-tree-icon\" src=\"" + this.getIconSrc() + "\">";
 };
 
-_p.getIconSrc = function ()
-{
+_p.getIconSrc = function () {
        throw new Error("getIconSrc called on Abstract Node");
 };
 
-_p.getExpandIconHtml = function ()
-{
+_p.getExpandIconHtml = function () {
        // here we are not using textToHtml since the file names rarerly contains
        // HTML...
        return "<img class=\"webfx-tree-expand-icon\" src=\"" +
@@ -861,14 +837,12 @@ _p.getExpandIconHtml = function ()
 };
 
 
-_p.getExpandIconSrc = function ()
-{
+_p.getExpandIconSrc = function () {
        var src;
        var t = this.getTree();
        var hideLines = !t.getShowLines() || t == this.parentNode && !t.getShowRootLines();
 
-       if (this.hasChildren())
-       {
+       if (this.hasChildren()) {
                var bits = 0;
                /*
                        Bitmap used to determine which icon to use
@@ -878,24 +852,23 @@ _p.getExpandIconSrc = function ()
                        8  L Line
                */
 
-               if (t && t.getShowExpandIcons())
-               {
-                       if (this.getExpanded())
+               if (t && t.getShowExpandIcons()) {
+                       if (this.getExpanded()) {
                                bits = 2;
-                       else
+                       } else {
                                bits = 1;
+                       }
                }
 
-               if (t && !hideLines)
-               {
-                       if (this.isLastSibling())
+               if (t && !hideLines) {
+                       if (this.isLastSibling()) {
                                bits += 4;
-                       else
+                       } else {
                                bits += 8;
+                       }
                }
 
-               switch (bits)
-               {
+               switch (bits) {
                        case 1:
                                return webFXTreeConfig.plusIcon;
                        case 2:
@@ -915,25 +888,22 @@ _p.getExpandIconSrc = function ()
                        default:        // 0
                                return webFXTreeConfig.blankIcon;
                }
-       }
-       else
-       {
-               if (t && hideLines)
+       } else {
+               if (t && hideLines) {
                        return webFXTreeConfig.blankIcon;
-               else if (this.isLastSibling())
+               } else if (this.isLastSibling()) {
                        return webFXTreeConfig.lIcon;
-               else
+               } else {
                        return webFXTreeConfig.tIcon;
+               }
        }
 };
 
-_p.getLineStyle = function ()
-{
+_p.getLineStyle = function () {
        return "background-position:" + this.getLineStyle2() + ";";
 };
 
-_p.getLineStyle2 = function ()
-{
+_p.getLineStyle2 = function () {
        return (this.isLastSibling() ? "-100" : (this.getDepth() - 1) * this.indentWidth) + "px 0";
 };
 
@@ -941,45 +911,39 @@ _p.getLineStyle2 = function ()
 
 // DOM
 // this returns the div for the tree node
-_p.getElement = function ()
-{
+_p.getElement = function () {
        return document.getElementById(this.id);
 };
 
 // the row is the div that is used to draw the node without the children
-_p.getRowElement = function ()
-{
+_p.getRowElement = function () {
        var el = this.getElement();
        if (!el) return null;
        return el.firstChild;
 };
 
 // plus/minus image
-_p.getExpandIconElement = function ()
-{
+_p.getExpandIconElement = function () {
        var el = this.getRowElement();
        if (!el) return null;
        return el.firstChild;
 };
 
-_p.getIconElement = function ()
-{
+_p.getIconElement = function () {
        var el = this.getRowElement();
        if (!el) return null;
        return el.childNodes[1];
 };
 
 // anchor element
-_p.getLabelElement = function ()
-{
+_p.getLabelElement = function () {
        var el = this.getRowElement();
        if (!el) return null;
        return el.lastChild;
 };
 
 // the div containing the children
-_p.getChildrenElement = function ()
-{
+_p.getChildrenElement = function () {
        var el = this.getElement();
        if (!el) return null;
        return el.lastChild;
@@ -988,10 +952,8 @@ _p.getChildrenElement = function ()
 
 // IE uses about:blank if not attached to document and this can cause Win2k3
 // to fail
-if (webFXTreeHandler.ie)
-{
-       _p.create = function ()
-       {
+if (webFXTreeHandler.ie) {
+       _p.create = function () {
                var dummy = document.createElement("div");
                dummy.style.display = "none";
                document.body.appendChild(dummy);
@@ -1000,124 +962,111 @@ if (webFXTreeHandler.ie)
                document.body.removeChild(dummy);
                return res;
        };
-}
-else
-{
-       _p.create = function ()
-       {
+} else {
+       _p.create = function () {
                var dummy = document.createElement("div");
                dummy.innerHTML = this.toHtml();
                return dummy.removeChild(dummy.firstChild);
        };
-
 }
 
 // Getters and setters for some common fields
 
-_p.setIcon = function (s)
-{
+_p.setIcon = function (s) {
        this.icon = s;
-       if (this.getCreated())
+       if (this.getCreated()) {
                this.updateIcon();
+       }
 };
 
-_p.getIcon = function ()
-{
+_p.getIcon = function () {
        return this.icon;
 };
 
-_p.setOpenIcon = function (s)
-{
+_p.setOpenIcon = function (s) {
        this.openIcon = s;
-       if (this.getCreated())
+       if (this.getCreated()) {
                this.updateIcon();
+       }
 };
 
-_p.getOpenIcon = function ()
-{
+_p.getOpenIcon = function () {
        return this.openIcon;
 };
 
-_p.setText = function (s)
-{
+_p.setText = function (s) {
        this.setHtml(webFXTreeHandler.textToHtml(s));
 };
 
-_p.getText = function ()
-{
+_p.getText = function () {
        return webFXTreeHandler.htmlToText(this.getHtml());
 };
 
-_p.setHtml = function (s)
-{
+_p.setHtml = function (s) {
        this.text = s;
        var el = this.getLabelElement();
-       if (el)
+       if (el) {
                el.innerHTML = s;
+       }
 };
 
-_p.getHtml = function ()
-{
+_p.getHtml = function () {
        return this.text;
 };
 
-_p.setTarget = function (s)
-{
+_p.setTarget = function (s) {
        this.target = s;
 };
 
-_p.getTarget = function ()
-{
+_p.getTarget = function () {
        return this.target;
 };
 
-_p.setToolTip = function (s)
-{
+_p.setToolTip = function (s) {
        this.toolTip = s;
        var el = this.getLabelElement();
-       if (el)
+       if (el) {
                el.title = s;
+       }
 };
 
-_p.getToolTip = function ()
-{
+_p.getToolTip = function () {
        return this.toolTip;
 };
 
-_p.setAction = function (oAction)
-{
+_p.setAction = function (oAction) {
        this.action = oAction;
        var el = this.getLabelElement();
-       if (el)
+       if (el) {
                el.href = this._getHref();
+       }
        el = this.getRowElement();
-       if (el)
+       if (el) {
                el.className = this.getRowClassName();
+       }
 };
 
-_p.getAction = function ()
-{
+_p.getAction = function () {
        return this.action;
 };
 
 // update methods
 
-_p.update = function ()
-{
+_p.update = function () {
        var t = this.getTree();
        if (t.suspendRedraw) return;
        var el = this.getElement();
        if (!el || !el.parentNode) return;
        var newEl = this.create();
        el.parentNode.replaceChild(newEl, el);
-
+       this.setTabIndex(this.tabIndex); // in case root had the tab index
        var si = t.getSelected();
-       if (si && si.getFocused())
+       if (si && si.getFocused()) {
                si.focus();
+       }
 };
 
-_p.updateExpandIcon = function ()
-{
+_p.updateExpandIcon = function () {
        var t = this.getTree();
        if (t.suspendRedraw) return;
        var img = this.getExpandIconElement();
@@ -1126,8 +1075,7 @@ _p.updateExpandIcon = function ()
        cel.style.backgroundPosition = this.getLineStyle2();
 };
 
-_p.updateIcon = function ()
-{
+_p.updateIcon = function () {
        var t = this.getTree();
        if (t.suspendRedraw) return;
        var img = this.getIconElement();
@@ -1136,9 +1084,7 @@ _p.updateIcon = function ()
 
 // End DOM
 
-
-_p._callSuspended = function (f)
-{
+_p._callSuspended = function (f) {
        var t = this.getTree();
        var sr = t.getSuspendRedraw();
        t.setSuspendRedraw(true);
@@ -1148,108 +1094,100 @@ _p._callSuspended = function (f)
 
 // Event handlers
 
-_p._onMouseDown = function (e)
-{
+_p._onmousedown = function (e) {
        var el = e.target || e.srcElement;
        // expand icon
-       if (/webfx-tree-expand-icon/.test(el.className) && this.hasChildren())
-       {
+       if (/webfx-tree-expand-icon/.test(el.className) && this.hasChildren()) {
                this.toggle();
-               if ( webFXTreeHandler.ie )
+               if (webFXTreeHandler.ie) {
                        window.setTimeout("WebFXTreeAbstractNode._onTimeoutFocus(\"" + this.id + "\")", 10);
+               }
                return false;
        }
 
        this.select();
-       if (!/webfx-tree-item-label/.test(el.className) && !webFXTreeHandler.opera)     // opera cancels the click if focus is called
-       {
+       if (/*!/webfx-tree-item-label/.test(el.className) && */!webFXTreeHandler.opera) { // opera cancels the click if focus is called
+               
                // in case we are not clicking on the label
-               if (webFXTreeHandler.ie)
+               if (webFXTreeHandler.ie) {
                        window.setTimeout("WebFXTreeAbstractNode._onTimeoutFocus(\"" + this.id + "\")", 10);
-               else
+               } else {
                        this.focus();
+               }
        }
        var rowEl = this.getRowElement();
-       if (rowEl)
+       if (rowEl) {
                rowEl.className = this.getRowClassName();
+       }
 
        return false;
 };
 
-_p._onClick = function (e)
-{
+_p._onclick = function (e) {
        var el = e.target || e.srcElement;
        // expand icon
-       if (/webfx-tree-expand-icon/.test(el.className) && this.hasChildren())
+       if (/webfx-tree-expand-icon/.test(el.className) && this.hasChildren()) {
                return false;
+       }
 
-       if (typeof this.action == "function")
+       if (typeof this.action == "function") {
                this.action();
-       else if (this.action != null)
+       } else if (this.action != null) {
                window.open(this.action, this.target || "_self");
+       }
        return false;
 };
 
 
-_p._onDblClick = function (e)
-{
+_p._ondblclick = function (e) {
        var el = e.target || e.srcElement;
        // expand icon
-       if (/webfx-tree-expand-icon/.test(el.className) && this.hasChildren())
+       if (/webfx-tree-expand-icon/.test(el.className) && this.hasChildren()) {
                return;
+       }
 
        this.toggle();
 };
 
-_p._onFocus = function (e)
-{
+_p._onfocus = function (e) {
        this.select();
        this._focused = true;
 };
 
-_p._onBlur = function (e)
-{
+_p._onblur = function (e) {
        this._focused = false;
 };
 
-_p._onKeyDown = function (e)
-{
+_p._onkeydown = function (e) {
        var n;
        var rv = true;
-       switch (e.keyCode)
-       {
+       switch (e.keyCode) {
                case 39:        // RIGHT
-                       if (e.altKey)
-                       {
+                       if (e.altKey) {
                                rv = true;
                                break;
                        }
-                       if (this.hasChildren())
-                       {
-                               if (!this.getExpanded())
+                       if (this.hasChildren()) {
+                               if (!this.getExpanded()) {
                                        this.setExpanded(true);
-                               else
-                               {
+                               } else {
                                        this.getFirstChild().focus();
                                }
                        }
                        rv = false;
                        break;
                case 37:        // LEFT
-                       if (e.altKey)
-                       {
+                       if (e.altKey) {
                                rv = true;
                                break;
                        }
-                       if (this.hasChildren() && this.getExpanded())
+                       if (this.hasChildren() && this.getExpanded()) {
                                this.setExpanded(false);
-                       else
-                       {
+                       } else {
                                var p = this.getParent();
                                var t = this.getTree();
                                // don't go to root if hidden
-                               if (p && (t.showRootNode || p != t))
-                               {
+                               if (p && (t.showRootNode || p != t)) {
                                        p.focus();
                                }
                        }
@@ -1258,34 +1196,32 @@ _p._onKeyDown = function (e)
 
                case 40:        // DOWN
                        n = this.getNextShownNode();
-                       if (n)
-                       {
+                       if (n) {
                                n.focus();
                        }
                        rv = false;
                        break;
                case 38:        // UP
                        n = this.getPreviousShownNode()
-                       if (n)
-                       {
+                       if (n) {
                                n.focus();
                        }
                        rv = false;
                        break;
        }
 
-       if (!rv && e.preventDefault)
+       if (!rv && e.preventDefault) {
                e.preventDefault();
+       }
        e.returnValue = rv;
        return rv;
 };
 
-_p._onKeyPress = function (e)
-{
-       if (!e.altKey && e.keyCode >= 37 && e.keyCode <= 40)
-       {
-               if (e.preventDefault)
+_p._onkeypress = function (e) {
+       if (!e.altKey && e.keyCode >= 37 && e.keyCode <= 40) {
+               if (e.preventDefault) {
                        e.preventDefault();
+               }
                e.returnValue = false;
                return false;
        }
@@ -1293,11 +1229,11 @@ _p._onKeyPress = function (e)
 
 // End event handlers
 
-_p.dispose = function ()
-{
+_p.dispose = function () {
        if (this.disposed) return;
-       for (var i = this.childNodes.length - 1; i >= 0; i--)
+       for (var i = this.childNodes.length - 1; i >= 0; i--) {
                this.childNodes[i].dispose();
+       }
        this.tree = null;
        this.parentNode = null;
        this.childNodes = null;
@@ -1305,44 +1241,41 @@ _p.dispose = function ()
 };
 
 // Some methods that are usable when navigating the tree using the arrows
-_p.getLastShownDescendant = function ()
-{
-       if (!this.getExpanded() || !this.hasChildren())
+_p.getLastShownDescendant = function () {
+       if (!this.getExpanded() || !this.hasChildren()) {
                return this;
+       }
        // we know there is at least 1 child
        return this.getLastChild().getLastShownDescendant();
 };
 
-_p.getNextShownNode = function ()
-{
-       if (this.hasChildren() && this.getExpanded())
+_p.getNextShownNode = function () {
+       if (this.hasChildren() && this.getExpanded()) {
                return this.getFirstChild();
-       else
-       {
+       } else {
                var p = this;
                var next;
-               while (p != null)
-               {
+               while (p != null) {
                        next = p.getNextSibling();
-                       if (next != null)
+                       if (next != null) {
                                return next;
+                       }
                        p = p.getParent();
                }
                return null;
        }
 };
 
-_p.getPreviousShownNode = function ()
-{
+_p.getPreviousShownNode = function () {
        var ps = this.getPreviousSibling();
-       if (ps != null)
-       {
+       if (ps != null) {
                return ps.getLastShownDescendant();
        }
        var p = this.getParent();
        var t = this.getTree();
-       if (!t.showRootNode && p == t)
+       if (!t.showRootNode && p == t) {
                return null;
+       }
        return p;
 };
 
@@ -1356,16 +1289,11 @@ _p.getPreviousShownNode = function ()
 // WebFXTree
 ///////////////////////////////////////////////////////////////////////////////
 
-function WebFXTree(sText, oAction, sBehavior, sIcon, sOpenIcon)
-{
+function WebFXTree(sText, oAction, sBehavior, sIcon, sOpenIcon) {
        WebFXTreeAbstractNode.call(this, sText, oAction);
-
-       if (sIcon)
-               this.icon = sIcon;
-       if (sOpenIcon)
-               this.openIcon = sOpenIcon;
-       if (sBehavior)
-               this.behavior = sBehavior;
+       if (sIcon) this.icon = sIcon;
+       if (sOpenIcon) this.openIcon = sOpenIcon;
+       if (sBehavior) this.behavior = sBehavior;
 }
 
 _p = WebFXTree.prototype = new WebFXTreeAbstractNode;
@@ -1380,63 +1308,54 @@ _p.showExpandIcons = true;
 _p.showRootNode = true;
 _p.showRootLines = true;
 
-_p.getTree = function ()
-{
+_p.getTree = function () {
        return this;
 };
 
-_p.getDepth = function ()
-{
+_p.getDepth = function () {
        return 0;
 };
 
-_p.getCreated = function ()
-{
+_p.getCreated = function () {
        return this.rendered;
 };
 
 
 /* end tree model */
 
-_p.getExpanded = function ()
-{
+_p.getExpanded = function () {
        return !this.showRootNode || WebFXTreeAbstractNode.prototype.getExpanded.call(this);
 };
 
-_p.setExpanded = function (b)
-{
-       if (!this.showRootNode)
+_p.setExpanded = function (b) {
+       if (!this.showRootNode) {
                this.open = b;
-       else
+       } else {
                WebFXTreeAbstractNode.prototype.setExpanded.call(this, b);
+       }
 };
 
-_p.getExpandIconHtml = function ()
-{
+_p.getExpandIconHtml = function () {
        return "";
 };
 
 // we don't have an expand icon here
-_p.getIconElement = function ()
-{
+_p.getIconElement = function () {
        var el = this.getRowElement();
        if (!el) return null;
        return el.firstChild;
 };
 
 // no expand icon for root element
-_p.getExpandIconElement = function (oDoc)
-{
+_p.getExpandIconElement = function (oDoc) {
        return null;
 };
 
-_p.updateExpandIcon = function ()
-{
+_p.updateExpandIcon = function () {
        // no expand icon
 };
 
-_p.getRowClassName = function ()
-{
+_p.getRowClassName = function () {
        return WebFXTreeAbstractNode.prototype.getRowClassName.call(this) +
                (this.showRootNode ? "" : " webfx-tree-hide-root");
 };
@@ -1445,21 +1364,21 @@ _p.getRowClassName = function ()
 // if classic then the openIcon is used for expanded, otherwise openIcon is used
 // for selected
 
-_p.getIconSrc = function ()
-{
+_p.getIconSrc = function () {
        var behavior = this.getTree() ? this.getTree().getBehavior() : webFXTreeConfig.defaultBehavior;
        var open = behavior == "classic" && this.getExpanded() ||
                           behavior != "classic" && this.isSelected();
-       if (open && this.openIcon)
+       if (open && this.openIcon) {
                return this.openIcon;
-       if (!open && this.icon)
+       }
+       if (!open && this.icon) {
                return this.icon;
+       }
        // fall back on default icons
        return open ? webFXTreeConfig.openRootIcon : webFXTreeConfig.rootIcon;
 };
 
-_p.getEventHandlersHtml = function ()
-{
+_p.getEventHandlersHtml = function () {
        return " onclick=\"return webFXTreeHandler.handleEvent(event)\" " +
                "onmousedown=\"return webFXTreeHandler.handleEvent(event)\" " +
                "ondblclick=\"return webFXTreeHandler.handleEvent(event)\" " +
@@ -1467,118 +1386,116 @@ _p.getEventHandlersHtml = function ()
                "onkeypress=\"return webFXTreeHandler.handleEvent(event)\"";
 };
 
-_p.setSelected = function (o)
-{
-       if (this._selectedItem != o)
-       {
-               if (o)
-                       o._setSelected(true);
+_p.setSelected = function (o) {
+       if (this._selectedItem != o && o) {
+               o._setSelected(true);
        }
 };
 
-_p._fireOnChange = function ()
-{
-       if (this._fireChange && typeof this.onchange == "function")
+_p._fireOnChange = function () {
+       if (this._fireChange && typeof this.onchange == "function") {
                this.onchange();
+       }
 };
 
-_p.getSelected = function ()
-{
+_p.getSelected = function () {
        return this._selectedItem;
 };
 
-_p.setBehavior = function (s)
-{
+_p.tabIndex = "";
+
+_p.setTabIndex = function (i) {
+       var n = this._selectedItem || (this.showRootNode ? this : this.firstChild);
+       this.tabIndex = i;
+       if (n) {
+               n._setTabIndex(i);
+       }       
+};
+
+_p.getTabIndex = function () {
+       return this.tabIndex;
+};
+
+_p.setBehavior = function (s) {
        this.behavior = s;
 };
 
-_p.getBehavior = function ()
-{
+_p.getBehavior = function () {
        return this.behavior || webFXTreeConfig.defaultBehavior;
 };
 
-_p.setShowLines = function (b)
-{
-       if (this.showLines != b)
-       {
+_p.setShowLines = function (b) {
+       if (this.showLines != b) {
                this.showLines = b;
-               if (this.rendered)
+               if (this.rendered) {
                        this.update();
+               }
        }
 };
 
-_p.getShowLines = function ()
-{
+_p.getShowLines = function () {
        return this.showLines;
 };
 
-_p.setShowRootLines = function (b)
-{
-       if (this.showRootLines != b)
-       {
+_p.setShowRootLines = function (b) {
+       if (this.showRootLines != b) {
                this.showRootLines = b;
-               if (this.rendered)
+               if (this.rendered) {
                        this.update();
+               }
        }
 };
 
-_p.getShowRootLines = function ()
-{
+_p.getShowRootLines = function () {
        return this.showRootLines;
 };
 
-_p.setShowExpandIcons = function (b)
-{
-       if (this.showExpandIcons != b)
-       {
+_p.setShowExpandIcons = function (b) {
+       if (this.showExpandIcons != b) {
                this.showExpandIcons = b;
-               if (this.rendered)
+               if (this.rendered) {
                        this.getTree().update();
+               }
        }
 };
 
-_p.getShowExpandIcons = function ()
-{
+_p.getShowExpandIcons = function () {
        return this.showExpandIcons;
 };
 
-_p.setShowRootNode = function (b)
-{
-       if (this.showRootNode != b)
-       {
+_p.setShowRootNode = function (b) {
+       if (this.showRootNode != b) {
                this.showRootNode = b;
-               if (this.rendered)
+               if (this.rendered) {
                        this.getTree().update();
+               }
        }
 };
 
-_p.getShowRoootNode = function ()
-{
+_p.getShowRoootNode = function () {
        return this.showRootNode;
 };
 
 _p.onchange = function () {};
 
-_p.create = function ()
-{
+_p.create = function () {
        var el = WebFXTreeAbstractNode.prototype.create.call(this);
+       this.setTabIndex(this.tabIndex);
        this.rendered = true;
        return el;
 };
 
-_p.write = function ()
-{
+_p.write = function () {
        document.write(this.toHtml());
+       this.setTabIndex(this.tabIndex);
        this.rendered = true;
 };
 
-_p.setSuspendRedraw = function (b)
-{
+_p.setSuspendRedraw = function (b) {
        this.suspendRedraw = b;
 };
 
-_p.getSuspendRedraw = function ()
-{
+_p.getSuspendRedraw = function () {
        return this.suspendRedraw;
 };
 
@@ -1588,15 +1505,11 @@ _p.getSuspendRedraw = function ()
 // WebFXTreeItem
 ///////////////////////////////////////////////////////////////////////////////
 
-function WebFXTreeItem(sText, oAction, eParent, sIcon, sOpenIcon)
-{
+function WebFXTreeItem(sText, oAction, eParent, sIcon, sOpenIcon) {
        WebFXTreeAbstractNode.call(this, sText, oAction);
-       if (sIcon)
-               this.icon = sIcon;
-       if (sOpenIcon)
-               this.openIcon = sOpenIcon;
-       if (eParent)
-               eParent.add(this);
+       if (sIcon) this.icon = sIcon;
+       if (sOpenIcon) this.openIcon = sOpenIcon;
+       if (eParent) eParent.add(this);
 }
 
 _p = WebFXTreeItem.prototype = new WebFXTreeAbstractNode;
@@ -1604,48 +1517,49 @@ _p.tree = null;
 
 /* tree model */
 
-_p.getDepth = function ()
-{
-       if (this.depth != null)
+_p.getDepth = function () {
+       if (this.depth != null) {
                return this.depth;
-       if (this.parentNode)
-       {
+       }
+       if (this.parentNode) {
                var pd = this.parentNode.getDepth();
                return this.depth = (pd != null ? pd + 1 : null);
        }
        return null;
 };
 
-_p.getTree = function ()
-{
-       if (this.tree)
+_p.getTree = function () {
+       if (this.tree) {
                return this.tree;
-       if (this.parentNode)
+       }
+       if (this.parentNode) {
                return this.tree = this.parentNode.getTree();
+       }
        return null;
 };
 
-_p.getCreated = function ()
-{
+_p.getCreated = function () {
        var t = this.getTree();
        return t && t.getCreated();
 };
 
 // if classic then the openIcon is used for expanded, otherwise openIcon is used
 // for selected
-_p.getIconSrc = function ()
-{
+_p.getIconSrc = function () {
        var behavior = this.getTree() ? this.getTree().getBehavior() : webFXTreeConfig.defaultBehavior;
        var open = behavior == "classic" && this.getExpanded() ||
                   behavior != "classic" && this.isSelected();
-       if (open && this.openIcon)
+       if (open && this.openIcon) {
                return this.openIcon;
-       if (!open && this.icon)
+       }
+       if (!open && this.icon) {
                return this.icon;
+       }
 
        // fall back on default icons
-       if (this.hasChildren())
+       if (this.hasChildren()) {
                return open ? webFXTreeConfig.openFolderIcon : webFXTreeConfig.folderIcon;
+       }
        return webFXTreeConfig.fileIcon;
 };
 
@@ -1654,10 +1568,8 @@ _p.getIconSrc = function ()
 
 
 
-if (window.attachEvent)
-{
-       window.attachEvent("onunload", function ()
-       {
+if (window.attachEvent) {
+       window.attachEvent("onunload", function () {
                for (var id in webFXTreeHandler.all)
                        webFXTreeHandler.all[id].dispose();
        });