+++ /dev/null
-/*----------------------------------------------------------------------------\\r
-| XLoadTree 1.11 |\r
-|-----------------------------------------------------------------------------|\r
-| Created by Erik Arvidsson |\r
-| (http://webfx.eae.net/contact.html#erik) |\r
-| For WebFX (http://webfx.eae.net/) |\r
-|-----------------------------------------------------------------------------|\r
-| An extension to xTree that allows sub trees to be loaded at runtime by |\r
-| reading XML files from the server. Works with IE5+ and Mozilla 1.0+ |\r
-|-----------------------------------------------------------------------------|\r
-| Copyright (c) 1999 - 2002 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
-| 2001-09-27 | Original Version Posted. |\r
-| 2002-01-19 | Added some simple error handling and string templates for |\r
-| | reporting the errors. |\r
-| 2002-01-28 | Fixed loading issues in IE50 and IE55 that made the tree load |\r
-| | twice. |\r
-| 2002-10-10 | (1.1) Added reload method that reloads the XML file from the |\r
-| | server. |\r
-/ 2003-05-06 | Added support for target attribute |\r
-|-----------------------------------------------------------------------------|\r
-| Dependencies: xtree.js - original xtree library |\r
-| xtree.css - simple css styling of xtree |\r
-| xmlextras.js - provides xml http objects and xml document |\r
-| objects |\r
-|-----------------------------------------------------------------------------|\r
-| Created 2001-09-27 | All changes are in the log above. | Updated 2003-05-06 |\r
-\----------------------------------------------------------------------------*/\r
-\r
-\r
-webFXTreeConfig.loadingText = "Loading...";\r
-webFXTreeConfig.loadErrorTextTemplate = "Error loading \"%1%\"";\r
-webFXTreeConfig.emptyErrorTextTemplate = "Error \"%1%\" does not contain any tree items";\r
-\r
-/*\r
- * WebFXLoadTree class\r
- */\r
-\r
-function WebFXLoadTree(sText, sXmlSrc, sAction, sBehavior, sIcon, sOpenIcon) {\r
- // call super\r
- this.WebFXTree = WebFXTree;\r
- this.WebFXTree(sText, sAction, sBehavior, sIcon, sOpenIcon);\r
-\r
- // setup default property values\r
- this.src = sXmlSrc;\r
- this.loading = false;\r
- this.loaded = false;\r
- this.errorText = "";\r
-\r
- // check start state and load if open\r
- if (this.open)\r
- _startLoadXmlTree(this.src, this);\r
- else {\r
- // and create loading item if not\r
- this._loadingItem = new WebFXTreeItem(webFXTreeConfig.loadingText);\r
- this.add(this._loadingItem);\r
- }\r
-}\r
-\r
-WebFXLoadTree.prototype = new WebFXTree;\r
-\r
-// override the expand method to load the xml file\r
-WebFXLoadTree.prototype._webfxtree_expand = WebFXTree.prototype.expand;\r
-WebFXLoadTree.prototype.expand = function() {\r
- if (!this.loaded && !this.loading) {\r
- // load\r
- _startLoadXmlTree(this.src, this);\r
- }\r
- this._webfxtree_expand();\r
-};\r
-\r
-/*\r
- * WebFXLoadTreeItem class\r
- */\r
-\r
-function WebFXLoadTreeItem(sText, sXmlSrc, sAction, eParent, sIcon, sOpenIcon) {\r
- // call super\r
- this.WebFXTreeItem = WebFXTreeItem;\r
- this.WebFXTreeItem(sText, sAction, eParent, sIcon, sOpenIcon);\r
-\r
- // setup default property values\r
- this.src = sXmlSrc;\r
- this.loading = false;\r
- this.loaded = false;\r
- this.errorText = "";\r
-\r
- // check start state and load if open\r
- if (this.open)\r
- _startLoadXmlTree(this.src, this);\r
- else {\r
- // and create loading item if not\r
- this._loadingItem = new WebFXTreeItem(webFXTreeConfig.loadingText);\r
- this.add(this._loadingItem);\r
- }\r
-}\r
-\r
-WebFXLoadTreeItem.prototype = new WebFXTreeItem;\r
-\r
-// override the expand method to load the xml file\r
-WebFXLoadTreeItem.prototype._webfxtreeitem_expand = WebFXTreeItem.prototype.expand;\r
-WebFXLoadTreeItem.prototype.expand = function() {\r
- if (!this.loaded && !this.loading) {\r
- // load\r
- _startLoadXmlTree(this.src, this);\r
- }\r
- this._webfxtreeitem_expand();\r
-};\r
-\r
-// reloads the src file if already loaded\r
-WebFXLoadTree.prototype.reload =\r
-WebFXLoadTreeItem.prototype.reload = function () {\r
- // if loading do nothing\r
- if (this.loaded) {\r
- var open = this.open;\r
- // remove\r
- while (this.childNodes.length > 0)\r
- this.childNodes[this.childNodes.length - 1].remove();\r
-\r
- this.loaded = false;\r
-\r
- this._loadingItem = new WebFXTreeItem(webFXTreeConfig.loadingText);\r
- this.add(this._loadingItem);\r
-\r
- if (open)\r
- this.expand();\r
- }\r
- else if (this.open && !this.loading)\r
- _startLoadXmlTree(this.src, this);\r
-};\r
-\r
-/*\r
- * Helper functions\r
- */\r
-\r
-// creates the xmlhttp object and starts the load of the xml document\r
-function _startLoadXmlTree(sSrc, jsNode) {\r
- if (jsNode.loading || jsNode.loaded)\r
- return;\r
- jsNode.loading = true;\r
- var xmlHttp = XmlHttp.create();\r
- xmlHttp.open("GET", sSrc, true); // async\r
- xmlHttp.onreadystatechange = function () {\r
- if (xmlHttp.readyState == 4) {\r
- _xmlFileLoaded(xmlHttp.responseXML, jsNode);\r
- }\r
- };\r
- // call in new thread to allow ui to update\r
- window.setTimeout(function () {\r
- xmlHttp.send(null);\r
- }, 10);\r
-}\r
-\r
-\r
-// Converts an xml tree to a js tree. See article about xml tree format\r
-function _xmlTreeToJsTree(oNode) {\r
- // retreive attributes\r
- var text = oNode.getAttribute("text");\r
- var action = oNode.getAttribute("action");\r
- var parent = null;\r
- var icon = oNode.getAttribute("icon");\r
- var openIcon = oNode.getAttribute("openIcon");\r
- var src = oNode.getAttribute("src");\r
- var target = oNode.getAttribute("target");\r
- // create jsNode\r
- var jsNode;\r
- if (src != null && src != "")\r
- jsNode = new WebFXLoadTreeItem(text, src, action, parent, icon, openIcon);\r
- else\r
- jsNode = new WebFXTreeItem(text, action, parent, icon, openIcon);\r
-\r
- if (target != "")\r
- jsNode.target = target;\r
-\r
- // go through childNOdes\r
- var cs = oNode.childNodes;\r
- var l = cs.length;\r
- for (var i = 0; i < l; i++) {\r
- if (cs[i].tagName == "tree")\r
- jsNode.add( _xmlTreeToJsTree(cs[i]), true );\r
- }\r
-\r
- return jsNode;\r
-}\r
-\r
-// Inserts an xml document as a subtree to the provided node\r
-function _xmlFileLoaded(oXmlDoc, jsParentNode) {\r
- if (jsParentNode.loaded)\r
- return;\r
-\r
- var bIndent = false;\r
- var bAnyChildren = false;\r
- jsParentNode.loaded = true;\r
- jsParentNode.loading = false;\r
-\r
- // check that the load of the xml file went well\r
- if( oXmlDoc == null || oXmlDoc.documentElement == null) {\r
- alert(oXmlDoc.xml);\r
- jsParentNode.errorText = parseTemplateString(webFXTreeConfig.loadErrorTextTemplate,\r
- jsParentNode.src);\r
- }\r
- else {\r
- // there is one extra level of tree elements\r
- var root = oXmlDoc.documentElement;\r
-\r
- // loop through all tree children\r
- var cs = root.childNodes;\r
- var l = cs.length;\r
- for (var i = 0; i < l; i++) {\r
- if (cs[i].tagName == "tree") {\r
- bAnyChildren = true;\r
- bIndent = true;\r
- jsParentNode.add( _xmlTreeToJsTree(cs[i]), true);\r
- }\r
- }\r
-\r
- // if no children we got an error\r
- if (!bAnyChildren)\r
- jsParentNode.errorText = parseTemplateString(webFXTreeConfig.emptyErrorTextTemplate,\r
- jsParentNode.src);\r
- }\r
-\r
- // remove dummy\r
- if (jsParentNode._loadingItem != null) {\r
- jsParentNode._loadingItem.remove();\r
- bIndent = true;\r
- }\r
-\r
- if (bIndent) {\r
- // indent now that all items are added\r
- jsParentNode.indent();\r
- }\r
-\r
- // show error in status bar\r
- if (jsParentNode.errorText != "")\r
- window.status = jsParentNode.errorText;\r
-}\r
-\r
-// parses a string and replaces %n% with argument nr n\r
-function parseTemplateString(sTemplate) {\r
- var args = arguments;\r
- var s = sTemplate;\r
-\r
- s = s.replace(/\%\%/g, "%");\r
-\r
- for (var i = 1; i < args.length; i++)\r
- s = s.replace( new RegExp("\%" + i + "\%", "g"), args[i] )\r
-\r
- return s;\r
-}
\ No newline at end of file
--- /dev/null
+/*----------------------------------------------------------------------------\\r
+| XLoadTree 2 PRE RELEASE |\r
+| |\r
+| This is a pre release and redistribution is discouraged. |\r
+| Watch http://webfx.eae.net for the final version |\r
+| |\r
+|-----------------------------------------------------------------------------|\r
+| Created by Erik Arvidsson & Emil A Eklund |\r
+| (http://webfx.eae.net/contact.html#erik) |\r
+| (http://webfx.eae.net/contact.html#emil) |\r
+| For WebFX (http://webfx.eae.net/) |\r
+|-----------------------------------------------------------------------------|\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
+|-----------------------------------------------------------------------------|\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
+| 2004-02-21 | Pre release distributed to a few selected tester |\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
+\----------------------------------------------------------------------------*/\r
+\r
+\r
+webFXTreeConfig.loadingText = "Loading...";\r
+webFXTreeConfig.loadingIcon = "images/loading.gif";\r
+\r
+\r
+function WebFXLoadTree(sText, sXmlSrc, oAction, sBehavior, sIcon, sOpenIcon)\r
+{\r
+ WebFXTree.call(this, sText, oAction, sBehavior, sIcon, sOpenIcon);\r
+\r
+ // setup default property values\r
+ this.src = sXmlSrc;\r
+ this.loading = !sXmlSrc;\r
+ this.loaded = !sXmlSrc;\r
+ this.errorText = "";\r
+\r
+ if (this.src)\r
+ {\r
+ /// add loading Item\r
+ this._loadingItem = WebFXLoadTree.createLoadingItem();\r
+ this.add(this._loadingItem);\r
+\r
+ if (this.getExpanded())\r
+ WebFXLoadTree.loadXmlDocument(this);\r
+ }\r
+}\r
+\r
+WebFXLoadTree.createLoadingItem = function ()\r
+{\r
+ return new WebFXTreeItem(webFXTreeConfig.loadingText, null, null,\r
+ webFXTreeConfig.loadingIcon);\r
+};\r
+\r
+WebFXLoadTree.prototype = new WebFXTree;\r
+\r
+WebFXLoadTree.prototype.setExpanded = function (b)\r
+{\r
+ WebFXTree.prototype.setExpanded.call(this, b);\r
+\r
+ if (this.src && b)\r
+ {\r
+ if (!this.loaded && !this.loading)\r
+ {\r
+ // load\r
+ WebFXLoadTree.loadXmlDocument(this);\r
+ }\r
+ }\r
+};\r
+\r
+function WebFXLoadTreeItem(sText, sXmlSrc, oAction, eParent, sIcon, sOpenIcon)\r
+{\r
+ WebFXTreeItem.call(this, sText, oAction, eParent, sIcon, sOpenIcon);\r
+\r
+// setup default property values\r
+ this.src = sXmlSrc;\r
+ this.loading = !sXmlSrc;\r
+ this.loaded = !sXmlSrc;\r
+ this.errorText = "";\r
+\r
+ if (this.src)\r
+ {\r
+ /// add loading Item\r
+ this._loadingItem = WebFXLoadTree.createLoadingItem();\r
+ this.add(this._loadingItem);\r
+\r
+ if (this.getExpanded())\r
+ WebFXLoadTree.loadXmlDocument(this);\r
+ }\r
+}\r
+\r
+WebFXLoadTreeItem.prototype = new WebFXTreeItem;\r
+\r
+WebFXLoadTreeItem.prototype.setExpanded = function (b)\r
+{\r
+ WebFXTreeItem.prototype.setExpanded.call(this, b);\r
+\r
+ if (this.src && b)\r
+ {\r
+ if (!this.loaded && !this.loading)\r
+ {\r
+ // load\r
+ WebFXLoadTree.loadXmlDocument(this);\r
+ }\r
+ }\r
+};\r
+\r
+// reloads the src file if already loaded\r
+WebFXLoadTree.prototype.reload =\r
+WebFXLoadTreeItem.prototype.reload = function ()\r
+{\r
+ // if loading do nothing\r
+ if (this.loaded)\r
+ {\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
+ this.remove(this.childNodes[this.childNodes.length - 1]);\r
+\r
+ this.loaded = false;\r
+\r
+ this._loadingItem = WebFXLoadTree.createLoadingItem();\r
+ this.add(this._loadingItem);\r
+\r
+ if (expanded)\r
+ this.setExpanded(true);\r
+\r
+ t.setSuspendRedraw(sr);\r
+ this.update();\r
+ }\r
+ else if (this.open && !this.loading)\r
+ WebFXLoadTree.loadXmlDocument(this);\r
+};\r
+\r
+\r
+\r
+WebFXLoadTree.prototype.setSrc =\r
+WebFXLoadTreeItem.prototype.setSrc = function (sSrc)\r
+{\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
+ // remove\r
+ while (this.childNodes.length > 0)\r
+ this.remove(this.childNodes[this.childNodes.length - 1]);\r
+ });\r
+ this.update();\r
+\r
+ this.loaded = false;\r
+ this.loading = false;\r
+ if (this._loadingItem)\r
+ {\r
+ this._loadingItem.dispose();\r
+ this._loadingItem = null;\r
+ }\r
+ this.src = sSrc;\r
+\r
+ if (sSrc)\r
+ {\r
+ this._loadingItem = WebFXLoadTree.createLoadingItem();\r
+ this.add(this._loadingItem);\r
+ }\r
+\r
+ this.setExpanded(expanded);\r
+};\r
+\r
+WebFXLoadTree.prototype.getSrc =\r
+WebFXLoadTreeItem.prototype.getSrc = function ()\r
+{\r
+ return this.src;\r
+};\r
+\r
+WebFXLoadTree.prototype.dispose = function ()\r
+{\r
+ WebFXTree.prototype.dispose.call(this);\r
+ if (this._xmlHttp)\r
+ {\r
+ if (this._xmlHttp.dispose)\r
+ this._xmlHttp.dispose();\r
+ try\r
+ {\r
+ this._xmlHttp.onreadystatechange = null;\r
+ this._xmlHttp.abort();\r
+ }\r
+ catch (ex) {}\r
+ this._xmlHttp = null;\r
+ }\r
+};\r
+\r
+WebFXLoadTreeItem.prototype.dispose = function ()\r
+{\r
+ WebFXTreeItem.prototype.dispose.call(this);\r
+ if (this._xmlHttp)\r
+ {\r
+ if (this._xmlHttp.dispose)\r
+ this._xmlHttp.dispose();\r
+ try\r
+ {\r
+ this._xmlHttp.onreadystatechange = null;\r
+ this._xmlHttp.abort();\r
+ }\r
+ catch (ex) {}\r
+ this._xmlHttp = null;\r
+ }\r
+};\r
+\r
+\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
+ // 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
+ this.select();\r
+ if (bFocus)\r
+ window.setTimeout("WebFXTreeAbstractNode._onTimeoutFocus(\"" + this.getId() + "\")", 10);\r
+ return;\r
+ }\r
+\r
+ var parts = sPath.split("/");\r
+ var remainingPath = parts.slice(1).join("/");\r
+\r
+ if (sPath.charAt(0) == "/")\r
+ {\r
+ this.getTree().openPath(remainingPath, bSelect, bFocus);\r
+ }\r
+ else\r
+ {\r
+ // open\r
+ this.setExpanded(true);\r
+ if (this.loaded)\r
+ {\r
+ parts = sPath.split("/");\r
+ var ti = this.findChildByText(parts[0]);\r
+ if (!ti)\r
+ throw "Could not find child node with text \"" + parts[0] + "\"";\r
+\r
+ ti.openPath(remainingPath, bSelect, bFocus);\r
+ }\r
+ else\r
+ {\r
+ this._pathToOpen = sPath;\r
+ }\r
+ }\r
+};\r
+\r
+\r
+// Opera has some serious attribute problems. We need to use getAttribute\r
+// for certain attributes\r
+WebFXLoadTree._attrs = ["text", "src", "action", "id", "target"];\r
+\r
+WebFXLoadTree.createItemFromElement = function (oNode)\r
+{\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
+ 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
+ name = WebFXLoadTree._attrs[i];\r
+ value = oNode.getAttribute(name);\r
+ if (value)\r
+ jsAttrs[name] = value;\r
+ }\r
+\r
+ var action;\r
+ if (jsAttrs.onaction)\r
+ action = new Function(jsAttrs.onaction);\r
+ else if (jsAttrs.action)\r
+ action = jsAttrs.action;\r
+ var jsNode = new WebFXLoadTreeItem(jsAttrs.html || "", jsAttrs.src, action,\r
+ null, jsAttrs.icon, jsAttrs.openIcon);\r
+ if (jsAttrs.text)\r
+ jsNode.setText(jsAttrs.text);\r
+\r
+ if (jsAttrs.target)\r
+ jsNode.target = jsAttrs.target;\r
+ if (jsAttrs.id)\r
+ jsNode.setId(jsAttrs.id);\r
+ if (jsAttrs.toolTip)\r
+ jsNode.toolTip = jsAttrs.toolTip;\r
+ if (jsAttrs.expanded)\r
+ jsNode.setExpanded(jsAttrs.expanded != "false");\r
+ if (jsAttrs.onload)\r
+ jsNode.onload = new Function(jsAttrs.onload);\r
+ if (jsAttrs.onerror)\r
+ jsNode.onerror = new Function(jsAttrs.onerror);\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
+ jsNode.add(WebFXLoadTree.createItemFromElement(cs[i]));\r
+ }\r
+\r
+ return jsNode;\r
+};\r
+\r
+WebFXLoadTree.loadXmlDocument = function (jsNode)\r
+{\r
+ if (jsNode.loading || jsNode.loaded)\r
+ return;\r
+ jsNode.loading = true;\r
+ var id = jsNode.getId();\r
+ jsNode._xmlHttp = XmlHttp.create();\r
+ jsNode._xmlHttp.open("GET", jsNode.src, true); // async\r
+ jsNode._xmlHttp.onreadystatechange = new Function("WebFXLoadTree._onload(\"" + id + "\")");\r
+\r
+ // call in new thread to allow ui to update\r
+ window.setTimeout("WebFXLoadTree._ontimeout(\"" + id + "\")", 10);\r
+};\r
+\r
+WebFXLoadTree._onload = function (sId)\r
+{\r
+ var jsNode = webFXTreeHandler.all[sId];\r
+ if (jsNode._xmlHttp.readyState == 4)\r
+ {\r
+ WebFXLoadTree.documentLoaded(jsNode);\r
+ webFXLoadTreeQueue.remove(jsNode);\r
+ if (jsNode._xmlHttp.dispose)\r
+ jsNode._xmlHttp.dispose();\r
+ jsNode._xmlHttp = null;\r
+ }\r
+};\r
+\r
+WebFXLoadTree._ontimeout = function (sId)\r
+{\r
+ var jsNode = webFXTreeHandler.all[sId];\r
+ webFXLoadTreeQueue.add(jsNode);\r
+};\r
+\r
+\r
+\r
+// Inserts an xml document as a subtree to the provided node\r
+WebFXLoadTree.documentLoaded = function (jsNode)\r
+{\r
+ if (jsNode.loaded)\r
+ return;\r
+\r
+ jsNode.errorText = "";\r
+ jsNode.loaded = true;\r
+ jsNode.loading = false;\r
+\r
+ var t = jsNode.getTree();\r
+ var oldSuspend = t.getSuspendRedraw();\r
+ t.setSuspendRedraw(true);\r
+\r
+ 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 = "Error loading " + jsNode.src + " (" + jsNode._xmlHttp.status + ": " + jsNode._xmlHttp.statusText + ")";\r
+ }\r
+ else\r
+ {\r
+ jsNode.errorText = "Error loading " + jsNode.src + " (" + doc.parseError.reason + ")";\r
+ }\r
+ }\r
+ else\r
+ {\r
+ // there is one extra level of tree elements\r
+ var root = doc.documentElement;\r
+\r
+ // loop through all tree children\r
+ 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
+ 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 = "Error loading " + jsNode.src + " (???)";\r
+ }\r
+ }\r
+\r
+ if (jsNode.errorText != "")\r
+ {\r
+ jsNode._loadingItem.icon = "images/exclamation.16.gif";\r
+ jsNode._loadingItem.text = jsNode.errorText;\r
+ jsNode._loadingItem.action = WebFXLoadTree._reloadParent;\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
+ jsNode.onerror();\r
+ }\r
+ else\r
+ {\r
+ // remove dummy\r
+ if (jsNode._loadingItem != null)\r
+ jsNode.remove(jsNode._loadingItem);\r
+\r
+ if (jsNode._pathToOpen)\r
+ jsNode.openPath(jsNode._pathToOpen, jsNode._selectPathOnLoad, jsNode._focusPathOnLoad);\r
+\r
+ t.setSuspendRedraw(oldSuspend);\r
+ jsNode.update();\r
+ if (typeof jsNode.onload == "function")\r
+ jsNode.onload();\r
+ }\r
+};\r
+\r
+WebFXLoadTree._reloadParent = function ()\r
+{\r
+ this.getParent().reload();\r
+};\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+var webFXLoadTreeQueue = {\r
+ _nodes: [],\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
+ this._nodes.push(jsNode);\r
+ if (this._nodes.length == 1)\r
+ this._send();\r
+ }\r
+ else\r
+ {\r
+ jsNode._xmlHttp.send(null);\r
+ }\r
+ },\r
+\r
+\r
+ remove: function (jsNode)\r
+ {\r
+ if (this._ie || this._opera)\r
+ {\r
+ arrayHelper.remove(this._nodes, jsNode);\r
+ if (this._nodes.length > 0)\r
+ this._send();\r
+ }\r
+ },\r
+\r
+ // IE only\r
+ _send: function ()\r
+ {\r
+ var id = this._nodes[0].getId();\r
+ var jsNode = webFXTreeHandler.all[id];\r
+ if (!jsNode)\r
+ return;\r
+ // if no _xmlHttp then remove it\r
+ if (!jsNode._xmlHttp)\r
+ this.remove(jsNode);\r
+ else\r
+ jsNode._xmlHttp.send(null);\r
+ }\r
+};\r
-//<script>\r
+/*----------------------------------------------------------------------------\\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
function getDomDocumentPrefix() {\r
if (getDomDocumentPrefix.prefix)\r
return getDomDocumentPrefix.prefix;\r
- \r
+\r
var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];\r
var o;\r
for (var i = 0; i < prefixes.length; i++) {\r
}\r
catch (ex) {};\r
}\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
+\r
var prefixes = ["MSXML2", "Microsoft", "MSXML", "MSXML3"];\r
var o;\r
for (var i = 0; i < prefixes.length; i++) {\r
}\r
catch (ex) {};\r
}\r
- \r
+\r
throw new Error("Could not find an installed XML parser");\r
}\r
\r
try {\r
if (window.XMLHttpRequest) {\r
var req = new XMLHttpRequest();\r
- \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.onreadystatechange();\r
}, false);\r
}\r
- \r
+\r
return req;\r
}\r
if (window.ActiveXObject) {\r
// DOM2\r
if (document.implementation && document.implementation.createDocument) {\r
var doc = document.implementation.createDocument("", "", null);\r
- \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.onreadystatechange();\r
}, false);\r
}\r
- \r
+\r
return doc;\r
}\r
if (window.ActiveXObject)\r
\r
// XMLDocument did not extend the Document interface in some versions\r
// of Mozilla. Extend both!\r
- XMLDocument.prototype.loadXML = \r
- Document.prototype.loadXML = function (s) {\r
- \r
- // parse the string to a new doc \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
+\r
// remove all initial children\r
while (this.hasChildNodes())\r
this.removeChild(this.lastChild);\r
- \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
+\r
/*\r
* xml getter\r
*\r
* Usage: var sXml = oNode.xml\r
*\r
*/\r
- // XMLDocument did not extend the Document interface in some versions\r
- // of Mozilla. Extend both!\r
- XMLDocument.prototype.__defineGetter__("xml", function () {\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
- Document.prototype.__defineGetter__("xml", function () {\r
- return (new XMLSerializer()).serializeToString(this);\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
+++ /dev/null
-.webfx-tree-container {
- margin: 0px;
- padding: 0px;
- font: icon;
- white-space: nowrap;
-}
-
-.webfx-tree-item {
- padding: 0px;
- margin: 0px;
- font: icon;
- color: WindowText;
- white-space: nowrap;
- height: 16px;
-}
-
-.webfx-tree-item a, .webfx-tree-item a:active, .webfx-tree-item a:hover {
- margin-left: 3px;
- padding: 0px 2px 1px 2px;
-}
-
-.webfx-tree-item a {
- color: black;
- text-decoration: none;
-}
-
-.webfx-tree-item a:hover {
- color: blue;
- text-decoration: underline;
-}
-
-.webfx-tree-item a:active {
- background: highlight;
- color: highlighttext;
- text-decoration: none;
-}
-
-.webfx-tree-item img {
- vertical-align: middle;
- border: 0px;
-}
-
-.webfx-tree-icon {
- width: 16px;
- height: 16px;
-}
\ No newline at end of file
+++ /dev/null
-/*----------------------------------------------------------------------------\
-| Cross Browser Tree Widget 1.17 |
-|-----------------------------------------------------------------------------|
-| Created by Emil A Eklund |
-| (http://webfx.eae.net/contact.html#emil) |
-| For WebFX (http://webfx.eae.net/) |
-|-----------------------------------------------------------------------------|
-| An object based tree widget, emulating the one found in microsoft windows, |
-| with persistence using cookies. Works in IE 5+, Mozilla and konqueror 3. |
-|-----------------------------------------------------------------------------|
-| Copyright (c) 1999 - 2002 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, |
-| fitness for a particular purpose and noninfringement. In no event shall the |
-| authors or copyright holders be liable for any claim, damages or other |
-| liability, whether in an action of contract, tort or otherwise, arising |
-| from, out of or in connection with the software or the use or other |
-| dealings in the software. |
-| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
-| This software is available under the three different licenses mentioned |
-| below. To use this software you must chose, and qualify, for one of those. |
-| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
-| The WebFX Non-Commercial License http://webfx.eae.net/license.html |
-| Permits anyone the right to use the software in a non-commercial context |
-| free of charge. |
-| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
-| The WebFX Commercial license http://webfx.eae.net/commercial.html |
-| Permits the license holder the right to use the software in a commercial |
-| context. Such license must be specifically obtained, however it's valid for |
-| any number of implementations of the licensed software. |
-| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
-| GPL - The GNU General Public License http://www.gnu.org/licenses/gpl.txt |
-| Permits anyone the right to use and modify the software without limitations |
-| as long as proper credits are given and the original and modified source |
-| code are included. Requires that the final product, software derivate from |
-| the original source or any software utilizing a GPL component, such as |
-| this, is also licensed under the GPL license. |
-|-----------------------------------------------------------------------------|
-| Dependencies: xtree.css (To set up the CSS of the tree classes) |
-|-----------------------------------------------------------------------------|
-| 2001-01-10 | Original Version Posted. |
-| 2001-03-18 | Added getSelected and get/setBehavior that can make it behave |
-| | more like windows explorer, check usage for more information. |
-| 2001-09-23 | Version 1.1 - New features included keyboard navigation (ie) |
-| | and the ability to add and remove nodes dynamically and some |
-| | other small tweaks and fixes. |
-| 2002-01-27 | Version 1.11 - Bug fixes and improved mozilla support. |
-| 2002-06-11 | Version 1.12 - Fixed a bug that prevented the indentation line |
-| | from updating correctly under some circumstances. This bug |
-| | happened when removing the last item in a subtree and items in |
-| | siblings to the remove subtree where not correctly updated. |
-| 2002-06-13 | Fixed a few minor bugs cased by the 1.12 bug-fix. |
-| 2002-08-20 | Added usePersistence flag to allow disable of cookies. |
-| 2002-10-23 | (1.14) Fixed a plus icon issue |
-| 2002-10-29 | (1.15) Last changes broke more than they fixed. This version |
-| | is based on 1.13 and fixes the bugs 1.14 fixed withou breaking |
-| | lots of other things. |
-| 2003-02-15 | The selected node can now be made visible even when the tree |
-| | control loses focus. It uses a new class declaration in the |
-| | css file '.webfx-tree-item a.selected-inactive', by default it |
-| | puts a light-gray rectangle around the selected node. |
-| 2003-03-16 | Adding target support after lots of lobbying... |
-|-----------------------------------------------------------------------------|
-| Created 2000-12-11 | All changes are in the log above. | Updated 2003-03-16 |
-\----------------------------------------------------------------------------*/
-
-var webFXTreeConfig = {
- rootIcon : 'images/foldericon.png',
- openRootIcon : 'images/openfoldericon.png',
- folderIcon : 'images/foldericon.png',
- openFolderIcon : 'images/openfoldericon.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',
- blankIcon : 'images/blank.png',
- defaultText : 'Tree Item',
- defaultAction : 'javascript:void(0);',
- defaultBehavior : 'classic',
- usePersistence : true
-};
-
-var webFXTreeHandler = {
- idCounter : 0,
- idPrefix : "webfx-tree-object-",
- all : {},
- behavior : null,
- selected : null,
- onSelect : null, /* should be part of tree, not handler */
- getId : function() { return this.idPrefix + this.idCounter++; },
- toggle : function (oItem) { this.all[oItem.id.replace('-plus','')].toggle(); },
- select : function (oItem) { this.all[oItem.id.replace('-icon','')].select(); },
- focus : function (oItem) { this.all[oItem.id.replace('-anchor','')].focus(); },
- blur : function (oItem) { this.all[oItem.id.replace('-anchor','')].blur(); },
- keydown : function (oItem, e) { return this.all[oItem.id].keydown(e.keyCode); },
- cookies : new WebFXCookie(),
- insertHTMLBeforeEnd : function (oElement, sHTML) {
- if (oElement.insertAdjacentHTML != null) {
- oElement.insertAdjacentHTML("BeforeEnd", sHTML)
- return;
- }
- var df; // DocumentFragment
- var r = oElement.ownerDocument.createRange();
- r.selectNodeContents(oElement);
- r.collapse(false);
- df = r.createContextualFragment(sHTML);
- oElement.appendChild(df);
- }
-};
-
-/*
- * WebFXCookie class
- */
-
-function WebFXCookie() {
- if (document.cookie.length) { this.cookies = ' ' + document.cookie; }
-}
-
-WebFXCookie.prototype.setCookie = function (key, value) {
- document.cookie = key + "=" + escape(value);
-}
-
-WebFXCookie.prototype.getCookie = function (key) {
- if (this.cookies) {
- var start = this.cookies.indexOf(' ' + key + '=');
- if (start == -1) { return null; }
- var end = this.cookies.indexOf(";", start);
- if (end == -1) { end = this.cookies.length; }
- end -= start;
- var cookie = this.cookies.substr(start,end);
- return unescape(cookie.substr(cookie.indexOf('=') + 1, cookie.length - cookie.indexOf('=') + 1));
- }
- else { return null; }
-}
-
-/*
- * WebFXTreeAbstractNode class
- */
-
-function WebFXTreeAbstractNode(sText, sAction) {
- this.childNodes = [];
- this.id = webFXTreeHandler.getId();
- this.text = sText || webFXTreeConfig.defaultText;
- this.action = sAction || webFXTreeConfig.defaultAction;
- this._last = false;
- webFXTreeHandler.all[this.id] = this;
-}
-
-/*
- * To speed thing up if you're adding multiple nodes at once (after load)
- * use the bNoIdent parameter to prevent automatic re-indentation and call
- * the obj.ident() method manually once all nodes has been added.
- */
-
-WebFXTreeAbstractNode.prototype.add = function (node, bNoIdent) {
- node.parentNode = this;
- this.childNodes[this.childNodes.length] = node;
- var root = this;
- if (this.childNodes.length >= 2) {
- this.childNodes[this.childNodes.length - 2]._last = false;
- }
- while (root.parentNode) { root = root.parentNode; }
- if (root.rendered) {
- if (this.childNodes.length >= 2) {
- document.getElementById(this.childNodes[this.childNodes.length - 2].id + '-plus').src = ((this.childNodes[this.childNodes.length -2].folder)?((this.childNodes[this.childNodes.length -2].open)?webFXTreeConfig.tMinusIcon:webFXTreeConfig.tPlusIcon):webFXTreeConfig.tIcon);
- this.childNodes[this.childNodes.length - 2].plusIcon = webFXTreeConfig.tPlusIcon;
- this.childNodes[this.childNodes.length - 2].minusIcon = webFXTreeConfig.tMinusIcon;
- this.childNodes[this.childNodes.length - 2]._last = false;
- }
- this._last = true;
- var foo = this;
- while (foo.parentNode) {
- for (var i = 0; i < foo.parentNode.childNodes.length; i++) {
- if (foo.id == foo.parentNode.childNodes[i].id) { break; }
- }
- if (i == foo.parentNode.childNodes.length - 1) { foo.parentNode._last = true; }
- else { foo.parentNode._last = false; }
- foo = foo.parentNode;
- }
- webFXTreeHandler.insertHTMLBeforeEnd(document.getElementById(this.id + '-cont'), node.toString());
- if ((!this.folder) && (!this.openIcon)) {
- this.icon = webFXTreeConfig.folderIcon;
- this.openIcon = webFXTreeConfig.openFolderIcon;
- }
- if (!this.folder) { this.folder = true; this.collapse(true); }
- if (!bNoIdent) { this.indent(); }
- }
- return node;
-}
-
-WebFXTreeAbstractNode.prototype.toggle = function() {
- if (this.folder) {
- if (this.open) { this.collapse(); }
- else { this.expand(); }
-} }
-
-WebFXTreeAbstractNode.prototype.select = function() {
- document.getElementById(this.id + '-anchor').focus();
-}
-
-WebFXTreeAbstractNode.prototype.deSelect = function() {
- document.getElementById(this.id + '-anchor').className = '';
- webFXTreeHandler.selected = null;
-}
-
-WebFXTreeAbstractNode.prototype.focus = function() {
- if ((webFXTreeHandler.selected) && (webFXTreeHandler.selected != this)) { webFXTreeHandler.selected.deSelect(); }
- webFXTreeHandler.selected = this;
- if ((this.openIcon) && (webFXTreeHandler.behavior != 'classic')) { document.getElementById(this.id + '-icon').src = this.openIcon; }
- document.getElementById(this.id + '-anchor').className = 'selected';
- document.getElementById(this.id + '-anchor').focus();
- if (webFXTreeHandler.onSelect) { webFXTreeHandler.onSelect(this); }
-}
-
-WebFXTreeAbstractNode.prototype.blur = function() {
- if ((this.openIcon) && (webFXTreeHandler.behavior != 'classic')) { document.getElementById(this.id + '-icon').src = this.icon; }
- document.getElementById(this.id + '-anchor').className = 'selected-inactive';
-}
-
-WebFXTreeAbstractNode.prototype.doExpand = function() {
- if (webFXTreeHandler.behavior == 'classic') { document.getElementById(this.id + '-icon').src = this.openIcon; }
- if (this.childNodes.length) { document.getElementById(this.id + '-cont').style.display = 'block'; }
- this.open = true;
- if (webFXTreeConfig.usePersistence) {
- webFXTreeHandler.cookies.setCookie(this.id.substr(18,this.id.length - 18), '1');
-} }
-
-WebFXTreeAbstractNode.prototype.doCollapse = function() {
- if (webFXTreeHandler.behavior == 'classic') { document.getElementById(this.id + '-icon').src = this.icon; }
- if (this.childNodes.length) { document.getElementById(this.id + '-cont').style.display = 'none'; }
- this.open = false;
- if (webFXTreeConfig.usePersistence) {
- webFXTreeHandler.cookies.setCookie(this.id.substr(18,this.id.length - 18), '0');
-} }
-
-WebFXTreeAbstractNode.prototype.expandAll = function() {
- this.expandChildren();
- if ((this.folder) && (!this.open)) { this.expand(); }
-}
-
-WebFXTreeAbstractNode.prototype.expandChildren = function() {
- for (var i = 0; i < this.childNodes.length; i++) {
- this.childNodes[i].expandAll();
-} }
-
-WebFXTreeAbstractNode.prototype.collapseAll = function() {
- this.collapseChildren();
- if ((this.folder) && (this.open)) { this.collapse(true); }
-}
-
-WebFXTreeAbstractNode.prototype.collapseChildren = function() {
- for (var i = 0; i < this.childNodes.length; i++) {
- this.childNodes[i].collapseAll();
-} }
-
-WebFXTreeAbstractNode.prototype.indent = function(lvl, del, last, level, nodesLeft) {
- /*
- * Since we only want to modify items one level below ourself,
- * and since the rightmost indentation position is occupied by
- * the plus icon we set this to -2
- */
- if (lvl == null) { lvl = -2; }
- var state = 0;
- for (var i = this.childNodes.length - 1; i >= 0 ; i--) {
- state = this.childNodes[i].indent(lvl + 1, del, last, level);
- if (state) { return; }
- }
- if (del) {
- if ((level >= this._level) && (document.getElementById(this.id + '-plus'))) {
- if (this.folder) {
- document.getElementById(this.id + '-plus').src = (this.open)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.lPlusIcon;
- this.plusIcon = webFXTreeConfig.lPlusIcon;
- this.minusIcon = webFXTreeConfig.lMinusIcon;
- }
- else if (nodesLeft) { document.getElementById(this.id + '-plus').src = webFXTreeConfig.lIcon; }
- return 1;
- } }
- var foo = document.getElementById(this.id + '-indent-' + lvl);
- if (foo) {
- if ((foo._last) || ((del) && (last))) { foo.src = webFXTreeConfig.blankIcon; }
- else { foo.src = webFXTreeConfig.iIcon; }
- }
- return 0;
-}
-
-/*
- * WebFXTree class
- */
-
-function WebFXTree(sText, sAction, sBehavior, sIcon, sOpenIcon) {
- this.base = WebFXTreeAbstractNode;
- this.base(sText, sAction);
- this.icon = sIcon || webFXTreeConfig.rootIcon;
- this.openIcon = sOpenIcon || webFXTreeConfig.openRootIcon;
- /* Defaults to open */
- if (webFXTreeConfig.usePersistence) {
- this.open = (webFXTreeHandler.cookies.getCookie(this.id.substr(18,this.id.length - 18)) == '0')?false:true;
- } else { this.open = true; }
- this.folder = true;
- this.rendered = false;
- this.onSelect = null;
- if (!webFXTreeHandler.behavior) { webFXTreeHandler.behavior = sBehavior || webFXTreeConfig.defaultBehavior; }
-}
-
-WebFXTree.prototype = new WebFXTreeAbstractNode;
-
-WebFXTree.prototype.setBehavior = function (sBehavior) {
- webFXTreeHandler.behavior = sBehavior;
-};
-
-WebFXTree.prototype.getBehavior = function (sBehavior) {
- return webFXTreeHandler.behavior;
-};
-
-WebFXTree.prototype.getSelected = function() {
- if (webFXTreeHandler.selected) { return webFXTreeHandler.selected; }
- else { return null; }
-}
-
-WebFXTree.prototype.remove = function() { }
-
-WebFXTree.prototype.expand = function() {
- this.doExpand();
-}
-
-WebFXTree.prototype.collapse = function(b) {
- if (!b) { this.focus(); }
- this.doCollapse();
-}
-
-WebFXTree.prototype.getFirst = function() {
- return null;
-}
-
-WebFXTree.prototype.getLast = function() {
- return null;
-}
-
-WebFXTree.prototype.getNextSibling = function() {
- return null;
-}
-
-WebFXTree.prototype.getPreviousSibling = function() {
- return null;
-}
-
-WebFXTree.prototype.keydown = function(key) {
- if (key == 39) {
- if (!this.open) { this.expand(); }
- else if (this.childNodes.length) { this.childNodes[0].select(); }
- return false;
- }
- if (key == 37) { this.collapse(); return false; }
- if ((key == 40) && (this.open) && (this.childNodes.length)) { this.childNodes[0].select(); return false; }
- return true;
-}
-
-WebFXTree.prototype.toString = function() {
- var str = "<div id=\"" + this.id + "\" ondblclick=\"webFXTreeHandler.toggle(this);\" class=\"webfx-tree-item\" onkeydown=\"return webFXTreeHandler.keydown(this, event)\">" +
- "<img id=\"" + this.id + "-icon\" class=\"webfx-tree-icon\" src=\"" + ((webFXTreeHandler.behavior == 'classic' && this.open)?this.openIcon:this.icon) + "\" onclick=\"webFXTreeHandler.select(this);\">" +
- "<a href=\"" + this.action + "\" id=\"" + this.id + "-anchor\" onfocus=\"webFXTreeHandler.focus(this);\" onblur=\"webFXTreeHandler.blur(this);\"" +
- (this.target ? " target=\"" + this.target + "\"" : "") +
- ">" + this.text + "</a></div>" +
- "<div id=\"" + this.id + "-cont\" class=\"webfx-tree-container\" style=\"display: " + ((this.open)?'block':'none') + ";\">";
- var sb = [];
- for (var i = 0; i < this.childNodes.length; i++) {
- sb[i] = this.childNodes[i].toString(i, this.childNodes.length);
- }
- this.rendered = true;
- return str + sb.join("") + "</div>";
-};
-
-/*
- * WebFXTreeItem class
- */
-
-function WebFXTreeItem(sText, sAction, eParent, sIcon, sOpenIcon) {
- this.base = WebFXTreeAbstractNode;
- this.base(sText, sAction);
- /* Defaults to close */
- if (webFXTreeConfig.usePersistence) {
- this.open = (webFXTreeHandler.cookies.getCookie(this.id.substr(18,this.id.length - 18)) == '1')?true:false;
- } else { this.open = false; }
- if (sIcon) { this.icon = sIcon; }
- if (sOpenIcon) { this.openIcon = sOpenIcon; }
- if (eParent) { eParent.add(this); }
-}
-
-WebFXTreeItem.prototype = new WebFXTreeAbstractNode;
-
-WebFXTreeItem.prototype.remove = function() {
- var iconSrc = document.getElementById(this.id + '-plus').src;
- var parentNode = this.parentNode;
- var prevSibling = this.getPreviousSibling(true);
- var nextSibling = this.getNextSibling(true);
- var folder = this.parentNode.folder;
- var last = ((nextSibling) && (nextSibling.parentNode) && (nextSibling.parentNode.id == parentNode.id))?false:true;
- this.getPreviousSibling().focus();
- this._remove();
- if (parentNode.childNodes.length == 0) {
- document.getElementById(parentNode.id + '-cont').style.display = 'none';
- parentNode.doCollapse();
- parentNode.folder = false;
- parentNode.open = false;
- }
- if (!nextSibling || last) { parentNode.indent(null, true, last, this._level, parentNode.childNodes.length); }
- if ((prevSibling == parentNode) && !(parentNode.childNodes.length)) {
- prevSibling.folder = false;
- prevSibling.open = false;
- iconSrc = document.getElementById(prevSibling.id + '-plus').src;
- iconSrc = iconSrc.replace('minus', '').replace('plus', '');
- document.getElementById(prevSibling.id + '-plus').src = iconSrc;
- document.getElementById(prevSibling.id + '-icon').src = webFXTreeConfig.fileIcon;
- }
- if (document.getElementById(prevSibling.id + '-plus')) {
- if (parentNode == prevSibling.parentNode) {
- iconSrc = iconSrc.replace('minus', '').replace('plus', '');
- document.getElementById(prevSibling.id + '-plus').src = iconSrc;
-} } }
-
-WebFXTreeItem.prototype._remove = function() {
- for (var i = this.childNodes.length - 1; i >= 0; i--) {
- this.childNodes[i]._remove();
- }
- for (var i = 0; i < this.parentNode.childNodes.length; i++) {
- if (this == this.parentNode.childNodes[i]) {
- for (var j = i; j < this.parentNode.childNodes.length; j++) {
- this.parentNode.childNodes[j] = this.parentNode.childNodes[j+1];
- }
- this.parentNode.childNodes.length -= 1;
- if (i + 1 == this.parentNode.childNodes.length) { this.parentNode._last = true; }
- break;
- } }
- webFXTreeHandler.all[this.id] = null;
- var tmp = document.getElementById(this.id);
- if (tmp) { tmp.parentNode.removeChild(tmp); }
- tmp = document.getElementById(this.id + '-cont');
- if (tmp) { tmp.parentNode.removeChild(tmp); }
-}
-
-WebFXTreeItem.prototype.expand = function() {
- this.doExpand();
- document.getElementById(this.id + '-plus').src = this.minusIcon;
-}
-
-WebFXTreeItem.prototype.collapse = function(b) {
- if (!b) { this.focus(); }
- this.doCollapse();
- document.getElementById(this.id + '-plus').src = this.plusIcon;
-}
-
-WebFXTreeItem.prototype.getFirst = function() {
- return this.childNodes[0];
-}
-
-WebFXTreeItem.prototype.getLast = function() {
- if (this.childNodes[this.childNodes.length - 1].open) { return this.childNodes[this.childNodes.length - 1].getLast(); }
- else { return this.childNodes[this.childNodes.length - 1]; }
-}
-
-WebFXTreeItem.prototype.getNextSibling = function() {
- for (var i = 0; i < this.parentNode.childNodes.length; i++) {
- if (this == this.parentNode.childNodes[i]) { break; }
- }
- if (++i == this.parentNode.childNodes.length) { return this.parentNode.getNextSibling(); }
- else { return this.parentNode.childNodes[i]; }
-}
-
-WebFXTreeItem.prototype.getPreviousSibling = function(b) {
- for (var i = 0; i < this.parentNode.childNodes.length; i++) {
- if (this == this.parentNode.childNodes[i]) { break; }
- }
- if (i == 0) { return this.parentNode; }
- else {
- if ((this.parentNode.childNodes[--i].open) || (b && this.parentNode.childNodes[i].folder)) { return this.parentNode.childNodes[i].getLast(); }
- else { return this.parentNode.childNodes[i]; }
-} }
-
-WebFXTreeItem.prototype.keydown = function(key) {
- if ((key == 39) && (this.folder)) {
- if (!this.open) { this.expand(); }
- else { this.getFirst().select(); }
- return false;
- }
- else if (key == 37) {
- if (this.open) { this.collapse(); }
- else { this.parentNode.select(); }
- return false;
- }
- else if (key == 40) {
- if (this.open) { this.getFirst().select(); }
- else {
- var sib = this.getNextSibling();
- if (sib) { sib.select(); }
- }
- return false;
- }
- else if (key == 38) { this.getPreviousSibling().select(); return false; }
- return true;
-}
-
-WebFXTreeItem.prototype.toString = function (nItem, nItemCount) {
- var foo = this.parentNode;
- var indent = '';
- if (nItem + 1 == nItemCount) { this.parentNode._last = true; }
- var i = 0;
- while (foo.parentNode) {
- foo = foo.parentNode;
- indent = "<img id=\"" + this.id + "-indent-" + i + "\" src=\"" + ((foo._last)?webFXTreeConfig.blankIcon:webFXTreeConfig.iIcon) + "\">" + indent;
- i++;
- }
- this._level = i;
- if (this.childNodes.length) { this.folder = 1; }
- else { this.open = false; }
- if ((this.folder) || (webFXTreeHandler.behavior != 'classic')) {
- if (!this.icon) { this.icon = webFXTreeConfig.folderIcon; }
- if (!this.openIcon) { this.openIcon = webFXTreeConfig.openFolderIcon; }
- }
- else if (!this.icon) { this.icon = webFXTreeConfig.fileIcon; }
- var label = this.text.replace(/</g, '<').replace(/>/g, '>');
- var str = "<div id=\"" + this.id + "\" ondblclick=\"webFXTreeHandler.toggle(this);\" class=\"webfx-tree-item\" onkeydown=\"return webFXTreeHandler.keydown(this, event)\">" +
- indent +
- "<img id=\"" + this.id + "-plus\" src=\"" + ((this.folder)?((this.open)?((this.parentNode._last)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.tMinusIcon):((this.parentNode._last)?webFXTreeConfig.lPlusIcon:webFXTreeConfig.tPlusIcon)):((this.parentNode._last)?webFXTreeConfig.lIcon:webFXTreeConfig.tIcon)) + "\" onclick=\"webFXTreeHandler.toggle(this);\">" +
- "<img id=\"" + this.id + "-icon\" class=\"webfx-tree-icon\" src=\"" + ((webFXTreeHandler.behavior == 'classic' && this.open)?this.openIcon:this.icon) + "\" onclick=\"webFXTreeHandler.select(this);\">" +
- "<a href=\"" + this.action + "\" id=\"" + this.id + "-anchor\" onfocus=\"webFXTreeHandler.focus(this);\" onblur=\"webFXTreeHandler.blur(this);\"" +
- (this.target ? " target=\"" + this.target + "\"" : "") +
- ">" + label + "</a></div>" +
- "<div id=\"" + this.id + "-cont\" class=\"webfx-tree-container\" style=\"display: " + ((this.open)?'block':'none') + ";\">";
- var sb = [];
- for (var i = 0; i < this.childNodes.length; i++) {
- sb[i] = this.childNodes[i].toString(i,this.childNodes.length);
- }
- this.plusIcon = ((this.parentNode._last)?webFXTreeConfig.lPlusIcon:webFXTreeConfig.tPlusIcon);
- this.minusIcon = ((this.parentNode._last)?webFXTreeConfig.lMinusIcon:webFXTreeConfig.tMinusIcon);
- return str + sb.join("") + "</div>";
-}
\ No newline at end of file
--- /dev/null
+/*----------------------------------------------------------------------------\
+| XTree 2 PRE RELEASE |
+| |
+| This is a pre release and redistribution is discouraged. |
+| Watch http://webfx.eae.net for the final version |
+| |
+|-----------------------------------------------------------------------------|
+| Created by Erik Arvidsson & Emil A Eklund |
+| (http://webfx.eae.net/contact.html#erik) |
+| (http://webfx.eae.net/contact.html#emil) |
+| For WebFX (http://webfx.eae.net/) |
+|-----------------------------------------------------------------------------|
+| A tree menu system for IE 5.5+, Mozilla 1.4+, Opera 7, KHTML |
+|-----------------------------------------------------------------------------|
+| Copyright (c) 1999 - 2004 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, |
+| fitness for a particular purpose and noninfringement. In no event shall the |
+| authors or copyright holders be liable for any claim, damages or other |
+| liability, whether in an action of contract, tort or otherwise, arising |
+| from, out of or in connection with the software or the use or other |
+| dealings in the software. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| This software is available under the three different licenses mentioned |
+| below. To use this software you must chose, and qualify, for one of those. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| The WebFX Non-Commercial License http://webfx.eae.net/license.html |
+| Permits anyone the right to use the software in a non-commercial context |
+| free of charge. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| The WebFX Commercial license http://webfx.eae.net/commercial.html |
+| Permits the license holder the right to use the software in a commercial |
+| context. Such license must be specifically obtained, however it's valid for |
+| any number of implementations of the licensed software. |
+| - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
+| GPL - The GNU General Public License http://www.gnu.org/licenses/gpl.txt |
+| Permits anyone the right to use and modify the software without limitations |
+| as long as proper credits are given and the original and modified source |
+| code are included. Requires that the final product, software derivate from |
+| the original source or any software utilizing a GPL component, such as |
+| this, is also licensed under the GPL license. |
+|-----------------------------------------------------------------------------|
+| 2004-02-21 | Pre release distributed to a few selected tester |
+|-----------------------------------------------------------------------------|
+| Dependencies: xtree2.css Used to define the look and feel |
+|-----------------------------------------------------------------------------|
+| Created 2003-??-?? | All changes are in the log above. | Updated 2004-02-21 |
+\----------------------------------------------------------------------------*/
+
+
+//
+// WebFXTreePersisitance
+function WebFXTreePersistence() {}
+WebFXTreePersistence.prototype.getExpanded = function (oNode) { return false; };
+WebFXTreePersistence.prototype.setExpanded = function (oNode, bOpen) {};
+
+
+
+// Cookie handling
+function WebFXCookie() {}
+
+WebFXCookie.prototype.setCookie = function (sName, sValue, nDays)
+{
+ var expires = "";
+ if (typeof nDays == "number")
+ {
+ var d = new Date();
+ d.setTime(d.getTime() + nDays * 24 * 60 * 60 * 1000);
+ expires = "; expires=" + d.toGMTString();
+ }
+
+ document.cookie = sName + "=" + escape(sValue) + expires + "; path=/";
+};
+
+WebFXCookie.prototype.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)
+{
+ this.setCookie(name, "", -1);
+};
+
+
+//
+// persistence using cookies
+//
+// This is uses one cookie with the ids of the expanded nodes separated using '+'
+//
+function WebFXTreeCookiePersistence()
+{
+ this._openedMap = {};
+ this._cookies = new WebFXCookie;
+ var s = this._cookies.getCookie(this.cookieName);
+ if (s)
+ {
+ var a = s.split("+");
+ for (var i = a.length - 1; i >= 0; i--)
+ this._openedMap[a[i]] = true;
+ }
+}
+
+WebFXTreeCookiePersistence.prototype = new WebFXTreePersistence;
+
+WebFXTreeCookiePersistence.prototype.cookieName = "webfx-tree-cookie-persistence"
+
+WebFXTreeCookiePersistence.prototype.getExpanded = function (oNode)
+{
+ return oNode.id in this._openedMap;
+};
+
+WebFXTreeCookiePersistence.prototype.setExpanded = function (oNode, bOpen)
+{
+ var old = this.getExpanded(oNode);
+ if (old != bOpen)
+ {
+ if (bOpen)
+ this._openedMap[oNode.id] = true;
+ else
+ delete this._openedMap[oNode.id];
+
+ var res = [];
+ var i = 0;
+ for (var id in this._openedMap)
+ res[i++] = id;
+ this._cookies.setCookie(this.cookieName, res.join("+"));
+ }
+};
+
+
+
+// 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)
+ return i;
+ }
+ return -1;
+ },
+
+ insertBefore: function (a, o, o2)
+ {
+ var i = this.indexOf(a, o2);
+ if (i == -1)
+ a.push(o);
+ else
+ a.splice(i, 0, o);
+ },
+
+ remove: function (a, o)
+ {
+ var i = this.indexOf(a, o);
+ if (i != -1)
+ a.splice(i, 1);
+ }
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// 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',
+ defaultAction : null,
+ defaultBehavior : 'classic',
+ usePersistence : true
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// WebFX Tree Handler object //
+///////////////////////////////////////////////////////////////////////////////
+
+var webFXTreeHandler = {
+ ie: /msie/i.test(navigator.userAgent),
+ idCounter : 0,
+ idPrefix : "wfxt-",
+ getUniqueId: function ()
+ {
+ return this.idPrefix + this.idCounter++;
+ },
+ all : {},
+ getNodeById: function (sId)
+ {
+ return all[sId];
+ },
+ addNode: function (oNode)
+ {
+ this.all[oNode.id] = oNode;
+ },
+ removeNode: function (oNode)
+ {
+ delete this.all[oNode.id];
+ },
+
+ handleEvent: function (e)
+ {
+ var el = e.target || e.srcElement;
+ while (el != null && !this.all[el.id])
+ el = el.parentNode;
+
+ 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);
+ }
+ return false;
+ },
+
+ dispose: function ()
+ {
+ if (this.disposed) return;
+ for (var id in this.all)
+ this.all[id].dispose();
+ this.disposed = true;
+ },
+
+ opera: /opera/i.test(navigator.userAgent),
+
+ htmlToText: function (s)
+ {
+ return String(s).replace(/\s+|<([^>])+>|&|<|>|"| /gi, this._htmlToText);
+ },
+
+ _htmlToText: function (s)
+ {
+ switch (s)
+ {
+ case "&":
+ return "&";
+ case "<":
+ return "<";
+ case ">":
+ return ">";
+ case """:
+ return "\"";
+ case " ":
+ return String.fromCharCode(160);
+ default:
+ if (/\s+/.test(s))
+ return " ";
+ if (/^<BR/gi.test(s))
+ return "\n";
+ return "";
+ }
+ },
+
+ textToHtml: function (s)
+ {
+ return String(s).replace(/&|<|>|\n|\"\u00A0/g, this._textToHtml);
+ },
+
+ _textToHtml: function (s)
+ {
+ switch (s)
+ {
+ case "&":
+ return "&";
+ case "<":
+ return "<";
+ case ">":
+ return ">";
+ case "\n":
+ return "<BR>";
+ case "\"":
+ return """; // so we can use this in attributes
+ default:
+ return " ";
+ }
+ },
+
+ persistenceManager: new WebFXTreeCookiePersistence()
+};
+
+
+///////////////////////////////////////////////////////////////////////////////
+// WebFXTreeAbstractNode
+///////////////////////////////////////////////////////////////////////////////
+
+function WebFXTreeAbstractNode(sText, oAction)
+{
+ this.childNodes = [];
+ if (sText) this.text = sText;
+ if (oAction) this.action = oAction;
+ this.id = webFXTreeHandler.getUniqueId();
+ if (webFXTreeConfig.usePersistence)
+ this.open = webFXTreeHandler.persistenceManager.getExpanded(this);
+ webFXTreeHandler.addNode(this);
+}
+
+
+var _p = WebFXTreeAbstractNode.prototype;
+_p._selected = false;
+_p.indentWidth = 19;
+_p.open = false;
+_p.text = webFXTreeConfig.defaultText;
+_p.action = null;
+_p.target = null;
+_p.toolTip = null;
+_p._focused = false;
+
+/* begin tree model */
+
+_p.add = function (oChild, oBefore)
+{
+ var oldLast;
+ var emptyBefore = this.childNodes.length == 0;
+ var p = oChild.parentNode;
+
+ if (oBefore == null)
+ { // append
+ if (p != null)
+ p.remove(oChild);
+ oldLast = this.getLastChild();
+ this.childNodes.push(oChild);
+ }
+ else
+ { // insertBefore
+ if (oBefore.parentNode != this)
+ throw new Error("Can only add nodes before siblings");
+ if (p != null)
+ p.remove(oChild);
+
+ arrayHelper.insertBefore(this.childNodes, oChild, oBefore);
+ }
+
+ oChild.parentNode = this;
+ var t = this.getTree();
+ if (t)
+ oChild.tree = t;
+ var d = this.getDepth();
+ if (d != null)
+ oChild.depth = d + 1;
+
+ 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)
+ {
+ oldLast.updateExpandIcon();
+ }
+ if (emptyBefore)
+ {
+ this.setExpanded(this.getExpanded());
+ // if we are using classic expand will not update icon
+ if (t && t.getBehavior() != "classic")
+ this.updateIcon();
+ }
+ }
+
+ return oChild;
+};
+
+
+
+_p.remove = function (oChild)
+{
+ // backwards compatible. If no argument remove the node
+ 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())
+ {
+ this.select();
+ window.setTimeout("WebFXTreeAbstractNode._onTimeoutFocus(\"" + this.id + "\")", 10);
+ }
+ else
+ this.select();
+ }
+
+ var wasLast = oChild.isLastSibling();
+
+ if (oChild.parentNode != this)
+ throw new Error("Can only remove children");
+ arrayHelper.remove(this.childNodes, oChild);
+
+ oChild.parentNode = null;
+ oChild.tree = null;
+ oChild.depth = null;
+
+ if (t && this.getCreated() && !t.getSuspendRedraw())
+ {
+ var el = this.getChildrenElement();
+ var childEl = oChild.getElement();
+ el.removeChild(childEl);
+ if (wasLast)
+ {
+ var newLast = this.getLastChild();
+ if (newLast)
+ newLast.updateExpandIcon();
+ }
+ if (!this.hasChildren())
+ {
+ //this.setExpanded(this.getExpanded());
+ el.style.display = "none";
+ this.updateExpandIcon();
+ this.updateIcon();
+ }
+ }
+
+ return oChild;
+};
+
+WebFXTreeAbstractNode._onTimeoutFocus = function (sId)
+{
+ var jsNode = webFXTreeHandler.all[sId];
+ jsNode.focus();
+};
+
+_p.getId = function ()
+{
+ return this.id;
+};
+
+_p.getTree = function ()
+{
+ throw new Error("getTree called on Abstract Node");
+};
+
+_p.getDepth = function ()
+{
+ throw new Error("getDepth called on Abstract Node");
+};
+
+_p.getCreated = function ()
+{
+ var t = this.getTree();
+ return t && t.rendered;
+};
+
+_p.getParent = function ()
+{
+ return this.parentNode;
+};
+
+_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 ()
+{
+ return this.childNodes;
+};
+
+_p.getFirstChild = function ()
+{
+ return this.childNodes[0];
+};
+
+_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.getNextSibling = function ()
+{
+ var p = this.parentNode;
+ if (p == null) return null;
+ var cs = p.childNodes;
+ return cs[arrayHelper.indexOf(cs, this) + 1]
+};
+
+_p.hasChildren = function ()
+{
+ return this.childNodes.length > 0;
+};
+
+
+_p.isLastSibling = function ()
+{
+ return this.parentNode && this == this.parentNode.getLastChild();
+};
+
+_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)
+ return this.childNodes[i];
+ n--;
+ }
+ }
+ return null;
+};
+
+_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)
+ return this.childNodes[i];
+ n--;
+ }
+
+ var res;
+ for (var i = 0; i < this.childNodes.length; i++)
+ {
+ res = this.childNodes[i].findNodeByText(s, n);
+ if (res)
+ return res;
+ }
+ return null;
+};
+
+/* end tree model */
+
+_p.setId = function (sId)
+{
+ var el = this.getElement();
+ webFXTreeHandler.removeNode(this);
+ this.id = sId;
+ if (el)
+ el.id = sId;
+ webFXTreeHandler.addNode(this);
+};
+
+_p.isSelected = function ()
+{
+ return this._selected;
+};
+
+_p.select = function () { this._setSelected(true); };
+_p.deselect = function () { this._setSelected(false); };
+
+_p._setSelected = function (b)
+{
+ var t = this.getTree();
+ if (!t) return;
+ 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)
+ {
+ var oldFireChange = t._fireChange;
+ wasFocused = si._focused;
+ t._fireChange = false;
+ si._setSelected(false);
+ t._fireChange = oldFireChange;
+ }
+
+ var el = this.getRowElement();
+ if (el)
+ {
+ el.className = this.getRowClassName();
+ }
+ if (b)
+ {
+ t._selectedItem = this;
+ t._fireOnChange();
+ t.setSelected(this);
+ if (wasFocused)
+ this.focus();
+ }
+
+ if (t.getBehavior() != "classic")
+ this.updateIcon();
+ }
+};
+
+
+_p.getExpanded = function ()
+{
+ return this.open;
+};
+
+_p.setExpanded = function (b)
+{
+ var ce;
+ this.open = b;
+ var t = this.getTree();
+ if (this.hasChildren())
+ {
+ var si = t ? t.getSelected() : null;
+ if (!b && this.contains(si))
+ this.select();
+
+ var el = this.getElement();
+ if (el)
+ {
+ ce = this.getChildrenElement();
+ if (ce)
+ ce.style.display = b ? "block" : "none";
+ var eie = this.getExpandIconElement();
+ if (eie)
+ eie.src = this.getExpandIconSrc();
+ }
+
+ if (webFXTreeConfig.usePersistence)
+ webFXTreeHandler.persistenceManager.setExpanded(this, b);
+ }
+ else
+ {
+ ce = this.getChildrenElement();
+ if (ce)
+ ce.style.display = "none";
+ }
+ if (t && t.getBehavior() == "classic")
+ this.updateIcon();
+};
+
+_p.toggle = function ()
+{
+ this.setExpanded(!this.getExpanded());
+};
+
+_p.expand = function ()
+{
+ this.setExpanded(true);
+};
+
+_p.collapse = function ()
+{
+ this.setExpanded(false);
+};
+
+_p.collapseChildren = function()
+{
+ var cs = this.childNodes;
+ for (var i = 0; i < cs.length; i++)
+ cs[i].collapseAll();
+};
+
+_p.collapseAll = function()
+{
+ this.collapseChildren();
+ this.collapse();
+};
+
+_p.expandChildren = function()
+{
+ var cs = this.childNodes;
+ for (var i = 0; i < cs.length; i++)
+ cs[i].expandAll();
+};
+
+_p.expandAll = function ()
+{
+ this.expandChildren();
+ this.expand();
+};
+
+_p.reveal = function ()
+{
+ var p = this.getParent();
+ if (p)
+ {
+ p.setExpanded(true);
+ p.reveal();
+ }
+};
+
+_p.openPath = function (sPath, bSelect, bFocus)
+{
+ if (sPath == "")
+ {
+ if (bSelect)
+ this.select();
+ 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)
+ t.openPath(remainingPath, bSelect, bFocus);
+ else
+ throw "Invalid path";
+ }
+ else
+ {
+ // open
+ this.setExpanded(true);
+ parts = sPath.split("/");
+ var ti = this.findChildByText(parts[0]);
+ if (!ti)
+ throw "Could not find child node with text \"" + parts[0] + "\"";
+ ti.openPath(remainingPath, bSelect, bFocus);
+ }
+};
+
+_p.focus = function ()
+{
+ var el = this.getLabelElement();
+ if (el)
+ el.focus();
+};
+
+_p.getFocused = function ()
+{
+ return this._focused;
+};
+
+// HTML generation
+
+_p.toHtml = function ()
+{
+ var childrenSb = [];
+ var cs = this.childNodes;
+ var l = cs.length;
+ for (var y = 0; y < l; y++)
+ childrenSb[y] = cs[y].toHtml();
+
+ var t = this.getTree();
+ var hideLines = !t.getShowLines() || t == this.parentNode && !t.getShowRootLines();
+
+ var childrenHtml = "<div class=\"webfx-tree-children" +
+ (hideLines ? "-nolines" : "") + "\" style=\"" +
+ this.getLineStyle() +
+ (this.getExpanded() && this.hasChildren() ? "" : "display:none;") +
+ "\">" +
+ childrenSb.join("") +
+ "</div>";
+
+ return "<div class=\"webfx-tree-item\" id=\"" +
+ this.id + "\"" + this.getEventHandlersHtml() + ">" +
+ this.getRowHtml() +
+ childrenHtml +
+ "</div>";
+};
+
+_p.getRowHtml = function ()
+{
+ var t = this.getTree();
+ return "<div class=\"" + this.getRowClassName() + "\" style=\"padding-left:" +
+ (this.getDepth() - 1) * this.indentWidth + "px\">" +
+ this.getExpandIconHtml() +
+ //"<span class=\"webfx-tree-icon-and-label\">" +
+ this.getIconHtml() +
+ this.getLabelHtml() +
+ //"</span>" +
+ "</div>";
+};
+
+_p.getRowClassName = function ()
+{
+ return "webfx-tree-row" + (this.isSelected() ? " selected" : "") +
+ (this.action ? "" : " no-action");
+};
+
+_p.getLabelHtml = function ()
+{
+ var toolTip = this.getToolTip();
+ var target = this.getTarget();
+ return "<a href=\"" + webFXTreeHandler.textToHtml(this._getHref()) +
+ "\" class=\"webfx-tree-item-label\"" +
+ (toolTip ? " title=\"" + webFXTreeHandler.textToHtml(toolTip) + "\"" : "") +
+ (target ? " target=\"" + target + "\"" : "") +
+ " onfocus=\"webFXTreeHandler.handleEvent(event)\"" +
+ " onblur=\"webFXTreeHandler.handleEvent(event)\">" +
+ this.getHtml() + "</a>";
+};
+
+_p._getHref = function ()
+{
+ if (typeof this.action == "string")
+ return this.action;
+ else
+ return "#";
+};
+
+_p.getEventHandlersHtml = function ()
+{
+ return "";
+};
+
+_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 ()
+{
+ throw new Error("getIconSrc called on Abstract Node");
+};
+
+_p.getExpandIconHtml = function ()
+{
+ // here we are not using textToHtml since the file names rarerly contains
+ // HTML...
+ return "<img class=\"webfx-tree-expand-icon\" src=\"" +
+ this.getExpandIconSrc() + "\">";
+};
+
+
+_p.getExpandIconSrc = function ()
+{
+ var src;
+ var t = this.getTree();
+ var hideLines = !t.getShowLines() || t == this.parentNode && !t.getShowRootLines();
+
+ if (this.hasChildren())
+ {
+ var bits = 0;
+ /*
+ Bitmap used to determine which icon to use
+ 1 Plus
+ 2 Minus
+ 4 T Line
+ 8 L Line
+ */
+
+ if (t && t.getShowExpandIcons())
+ {
+ if (this.getExpanded())
+ bits = 2;
+ else
+ bits = 1;
+ }
+
+ if (t && !hideLines)
+ {
+ if (this.isLastSibling())
+ bits += 4;
+ else
+ bits += 8;
+ }
+
+ switch (bits)
+ {
+ case 1:
+ return webFXTreeConfig.plusIcon;
+ case 2:
+ return webFXTreeConfig.minusIcon;
+ case 4:
+ return webFXTreeConfig.lIcon;
+ case 5:
+ return webFXTreeConfig.lPlusIcon;
+ case 6:
+ return webFXTreeConfig.lMinusIcon;
+ case 8:
+ return webFXTreeConfig.tIcon;
+ case 9:
+ return webFXTreeConfig.tPlusIcon;
+ case 10:
+ return webFXTreeConfig.tMinusIcon;
+ default: // 0
+ return webFXTreeConfig.blankIcon;
+ }
+ }
+ else
+ {
+ if (t && hideLines)
+ return webFXTreeConfig.blankIcon;
+ else if (this.isLastSibling())
+ return webFXTreeConfig.lIcon;
+ else
+ return webFXTreeConfig.tIcon;
+ }
+};
+
+_p.getLineStyle = function ()
+{
+ return "background-position:" + this.getLineStyle2() + ";";
+};
+
+_p.getLineStyle2 = function ()
+{
+ return (this.isLastSibling() ? "-100" : (this.getDepth() - 1) * this.indentWidth) + "px 0";
+};
+
+// End HTML generation
+
+// DOM
+// this returns the div for the tree node
+_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 ()
+{
+ var el = this.getElement();
+ if (!el) return null;
+ return el.firstChild;
+};
+
+// plus/minus image
+_p.getExpandIconElement = function ()
+{
+ var el = this.getRowElement();
+ if (!el) return null;
+ return el.firstChild;
+};
+
+_p.getIconElement = function ()
+{
+ var el = this.getRowElement();
+ if (!el) return null;
+ return el.childNodes[1];
+};
+
+// anchor element
+_p.getLabelElement = function ()
+{
+ var el = this.getRowElement();
+ if (!el) return null;
+ return el.lastChild;
+};
+
+// the div containing the children
+_p.getChildrenElement = function ()
+{
+ var el = this.getElement();
+ if (!el) return null;
+ return el.lastChild;
+};
+
+
+// IE uses about:blank if not attached to document and this can cause Win2k3
+// to fail
+if (webFXTreeHandler.ie)
+{
+ _p.create = function ()
+ {
+ var dummy = document.createElement("div");
+ dummy.style.display = "none";
+ document.body.appendChild(dummy);
+ dummy.innerHTML = this.toHtml();
+ var res = dummy.removeChild(dummy.firstChild);
+ document.body.removeChild(dummy);
+ return res;
+ };
+}
+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)
+{
+ this.icon = s;
+ if (this.getCreated())
+ this.updateIcon();
+};
+
+_p.getIcon = function ()
+{
+ return this.icon;
+};
+
+_p.setOpenIcon = function (s)
+{
+ this.openIcon = s;
+ if (this.getCreated())
+ this.updateIcon();
+};
+
+_p.getOpenIcon = function ()
+{
+ return this.openIcon;
+};
+
+_p.setText = function (s)
+{
+ this.setHtml(webFXTreeHandler.textToHtml(s));
+};
+
+_p.getText = function ()
+{
+ return webFXTreeHandler.htmlToText(this.getHtml());
+};
+
+_p.setHtml = function (s)
+{
+ this.text = s;
+ var el = this.getLabelElement();
+ if (el)
+ el.innerHTML = s;
+};
+
+_p.getHtml = function ()
+{
+ return this.text;
+};
+
+_p.setTarget = function (s)
+{
+ this.target = s;
+};
+
+_p.getTarget = function ()
+{
+ return this.target;
+};
+
+_p.setToolTip = function (s)
+{
+ this.toolTip = s;
+ var el = this.getLabelElement();
+ if (el)
+ el.title = s;
+};
+
+_p.getToolTip = function ()
+{
+ return this.toolTip;
+};
+
+_p.setAction = function (oAction)
+{
+ this.action = oAction;
+ var el = this.getLabelElement();
+ if (el)
+ el.href = this._getHref();
+ el = this.getRowElement();
+ if (el)
+ el.className = this.getRowClassName();
+};
+
+_p.getAction = function ()
+{
+ return this.action;
+};
+
+// update methods
+
+_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);
+
+ var si = t.getSelected();
+ if (si && si.getFocused())
+ si.focus();
+};
+
+_p.updateExpandIcon = function ()
+{
+ var t = this.getTree();
+ if (t.suspendRedraw) return;
+ var img = this.getExpandIconElement();
+ img.src = this.getExpandIconSrc();
+ var cel = this.getChildrenElement();
+ cel.style.backgroundPosition = this.getLineStyle2();
+};
+
+_p.updateIcon = function ()
+{
+ var t = this.getTree();
+ if (t.suspendRedraw) return;
+ var img = this.getIconElement();
+ img.src = this.getIconSrc();
+};
+
+// End DOM
+
+
+_p._callSuspended = function (f)
+{
+ var t = this.getTree();
+ var sr = t.getSuspendRedraw();
+ t.setSuspendRedraw(true);
+ f.call(this);
+ t.setSuspendRedraw(sr);
+};
+
+// Event handlers
+
+_p._onMouseDown = function (e)
+{
+ var el = e.target || e.srcElement;
+ // expand icon
+ if (/webfx-tree-expand-icon/.test(el.className) && this.hasChildren())
+ {
+ this.toggle();
+ 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
+ {
+ // in case we are not clicking on the label
+ if (webFXTreeHandler.ie)
+ window.setTimeout("WebFXTreeAbstractNode._onTimeoutFocus(\"" + this.id + "\")", 10);
+ else
+ this.focus();
+ }
+ var rowEl = this.getRowElement();
+ if (rowEl)
+ rowEl.className = this.getRowClassName();
+
+ return false;
+};
+
+_p._onClick = function (e)
+{
+ var el = e.target || e.srcElement;
+ // expand icon
+ if (/webfx-tree-expand-icon/.test(el.className) && this.hasChildren())
+ return false;
+
+ if (typeof this.action == "function")
+ this.action();
+ else if (this.action != null)
+ window.open(this.action, this.target || "_self");
+ return false;
+};
+
+
+_p._onDblClick = function (e)
+{
+ var el = e.target || e.srcElement;
+ // expand icon
+ if (/webfx-tree-expand-icon/.test(el.className) && this.hasChildren())
+ return;
+
+ this.toggle();
+};
+
+_p._onFocus = function (e)
+{
+ this.select();
+ this._focused = true;
+};
+
+_p._onBlur = function (e)
+{
+ this._focused = false;
+};
+
+_p._onKeyDown = function (e)
+{
+ var n;
+ var rv = true;
+ switch (e.keyCode)
+ {
+ case 39: // RIGHT
+ if (e.altKey)
+ {
+ rv = true;
+ break;
+ }
+ if (this.hasChildren())
+ {
+ if (!this.getExpanded())
+ this.setExpanded(true);
+ else
+ {
+ this.getFirstChild().focus();
+ }
+ }
+ rv = false;
+ break;
+ case 37: // LEFT
+ if (e.altKey)
+ {
+ rv = true;
+ break;
+ }
+ if (this.hasChildren() && this.getExpanded())
+ this.setExpanded(false);
+ else
+ {
+ var p = this.getParent();
+ var t = this.getTree();
+ // don't go to root if hidden
+ if (p && (t.showRootNode || p != t))
+ {
+ p.focus();
+ }
+ }
+ rv = false;
+ break;
+
+ case 40: // DOWN
+ n = this.getNextShownNode();
+ if (n)
+ {
+ n.focus();
+ }
+ rv = false;
+ break;
+ case 38: // UP
+ n = this.getPreviousShownNode()
+ if (n)
+ {
+ n.focus();
+ }
+ rv = false;
+ break;
+ }
+
+ 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)
+ e.preventDefault();
+ e.returnValue = false;
+ return false;
+ }
+};
+
+// End event handlers
+
+_p.dispose = function ()
+{
+ if (this.disposed) return;
+ for (var i = this.childNodes.length - 1; i >= 0; i--)
+ this.childNodes[i].dispose();
+ this.tree = null;
+ this.parentNode = null;
+ this.childNodes = null;
+ this.disposed = true;
+};
+
+// Some methods that are usable when navigating the tree using the arrows
+_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())
+ return this.getFirstChild();
+ else
+ {
+ var p = this;
+ var next;
+ while (p != null)
+ {
+ next = p.getNextSibling();
+ if (next != null)
+ return next;
+ p = p.getParent();
+ }
+ return null;
+ }
+};
+
+_p.getPreviousShownNode = function ()
+{
+ var ps = this.getPreviousSibling();
+ if (ps != null)
+ {
+ return ps.getLastShownDescendant();
+ }
+ var p = this.getParent();
+ var t = this.getTree();
+ if (!t.showRootNode && p == t)
+ return null;
+ return p;
+};
+
+
+
+
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// WebFXTree
+///////////////////////////////////////////////////////////////////////////////
+
+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;
+}
+
+_p = WebFXTree.prototype = new WebFXTreeAbstractNode;
+_p.indentWidth = 19;
+_p.open = true;
+_p._selectedItem = null;
+_p._fireChange = true;
+_p.rendered = false;
+_p.suspendRedraw = false;
+_p.showLines = true;
+_p.showExpandIcons = true;
+_p.showRootNode = true;
+_p.showRootLines = true;
+
+_p.getTree = function ()
+{
+ return this;
+};
+
+_p.getDepth = function ()
+{
+ return 0;
+};
+
+_p.getCreated = function ()
+{
+ return this.rendered;
+};
+
+
+/* end tree model */
+
+_p.getExpanded = function ()
+{
+ return !this.showRootNode || WebFXTreeAbstractNode.prototype.getExpanded.call(this);
+};
+
+_p.setExpanded = function (b)
+{
+ if (!this.showRootNode)
+ this.open = b;
+ else
+ WebFXTreeAbstractNode.prototype.setExpanded.call(this, b);
+};
+
+_p.getExpandIconHtml = function ()
+{
+ return "";
+};
+
+// we don't have an expand icon here
+_p.getIconElement = function ()
+{
+ var el = this.getRowElement();
+ if (!el) return null;
+ return el.firstChild;
+};
+
+// no expand icon for root element
+_p.getExpandIconElement = function (oDoc)
+{
+ return null;
+};
+
+_p.updateExpandIcon = function ()
+{
+ // no expand icon
+};
+
+_p.getRowClassName = function ()
+{
+ return WebFXTreeAbstractNode.prototype.getRowClassName.call(this) +
+ (this.showRootNode ? "" : " webfx-tree-hide-root");
+};
+
+
+// if classic then the openIcon is used for expanded, otherwise openIcon is used
+// for selected
+
+_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)
+ return this.openIcon;
+ if (!open && this.icon)
+ return this.icon;
+ // fall back on default icons
+ return open ? webFXTreeConfig.openRootIcon : webFXTreeConfig.rootIcon;
+};
+
+_p.getEventHandlersHtml = function ()
+{
+ return " onclick=\"return webFXTreeHandler.handleEvent(event)\" " +
+ "onmousedown=\"return webFXTreeHandler.handleEvent(event)\" " +
+ "ondblclick=\"return webFXTreeHandler.handleEvent(event)\" " +
+ "onkeydown=\"return webFXTreeHandler.handleEvent(event)\" " +
+ "onkeypress=\"return webFXTreeHandler.handleEvent(event)\"";
+};
+
+_p.setSelected = function (o)
+{
+ if (this._selectedItem != o)
+ {
+ if (o)
+ o._setSelected(true);
+ }
+};
+
+_p._fireOnChange = function ()
+{
+ if (this._fireChange && typeof this.onchange == "function")
+ this.onchange();
+};
+
+_p.getSelected = function ()
+{
+ return this._selectedItem;
+};
+
+_p.setBehavior = function (s)
+{
+ this.behavior = s;
+};
+
+_p.getBehavior = function ()
+{
+ return this.behavior || webFXTreeConfig.defaultBehavior;
+};
+
+_p.setShowLines = function (b)
+{
+ if (this.showLines != b)
+ {
+ this.showLines = b;
+ if (this.rendered)
+ this.update();
+ }
+};
+
+_p.getShowLines = function ()
+{
+ return this.showLines;
+};
+
+_p.setShowRootLines = function (b)
+{
+ if (this.showRootLines != b)
+ {
+ this.showRootLines = b;
+ if (this.rendered)
+ this.update();
+ }
+};
+
+_p.getShowRootLines = function ()
+{
+ return this.showRootLines;
+};
+
+_p.setShowExpandIcons = function (b)
+{
+ if (this.showExpandIcons != b)
+ {
+ this.showExpandIcons = b;
+ if (this.rendered)
+ this.getTree().update();
+ }
+};
+
+_p.getShowExpandIcons = function ()
+{
+ return this.showExpandIcons;
+};
+
+_p.setShowRootNode = function (b)
+{
+ if (this.showRootNode != b)
+ {
+ this.showRootNode = b;
+ if (this.rendered)
+ this.getTree().update();
+ }
+};
+
+_p.getShowRoootNode = function ()
+{
+ return this.showRootNode;
+};
+
+_p.onchange = function () {};
+
+_p.create = function ()
+{
+ var el = WebFXTreeAbstractNode.prototype.create.call(this);
+ this.rendered = true;
+ return el;
+};
+
+_p.write = function ()
+{
+ document.write(this.toHtml());
+ this.rendered = true;
+};
+
+_p.setSuspendRedraw = function (b)
+{
+ this.suspendRedraw = b;
+};
+
+_p.getSuspendRedraw = function ()
+{
+ return this.suspendRedraw;
+};
+
+
+
+///////////////////////////////////////////////////////////////////////////////
+// WebFXTreeItem
+///////////////////////////////////////////////////////////////////////////////
+
+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);
+}
+
+_p = WebFXTreeItem.prototype = new WebFXTreeAbstractNode;
+_p.tree = null;
+
+/* tree model */
+
+_p.getDepth = function ()
+{
+ if (this.depth != null)
+ return this.depth;
+ if (this.parentNode)
+ {
+ var pd = this.parentNode.getDepth();
+ return this.depth = (pd != null ? pd + 1 : null);
+ }
+ return null;
+};
+
+_p.getTree = function ()
+{
+ if (this.tree)
+ return this.tree;
+ if (this.parentNode)
+ return this.tree = this.parentNode.getTree();
+ return null;
+};
+
+_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 ()
+{
+ var behavior = this.getTree() ? this.getTree().getBehavior() : webFXTreeConfig.defaultBehavior;
+ var open = behavior == "classic" && this.getExpanded() ||
+ behavior != "classic" && this.isSelected();
+ if (open && this.openIcon)
+ return this.openIcon;
+ if (!open && this.icon)
+ return this.icon;
+
+ // fall back on default icons
+ if (this.hasChildren())
+ return open ? webFXTreeConfig.openFolderIcon : webFXTreeConfig.folderIcon;
+ return webFXTreeConfig.fileIcon;
+};
+
+/* end tree model */
+
+
+
+
+if (window.attachEvent)
+{
+ window.attachEvent("onunload", function ()
+ {
+ for (var id in webFXTreeHandler.all)
+ webFXTreeHandler.all[id].dispose();
+ });
+}