+++ /dev/null
-/* This code is based on the one originally provided by
- Geir Landrö in his dTree 2.05 package. You can get it
- at : www.destroydrop.com/javascript/tree/.
-
- Therefore, the DTDDoc team considers that this code is
- Copyright (c) 2002-2003 Geir Landrö. Since the original
- author didn't clearly forbids copies of this part, we
- assume we're not doing anything wrong in porviding it
- to you, in a modified or non-modified form.
-*/
-
-/*
- Geir Landrö : Orignal version, for dTree.
-
- Michael Koehrsen (10/2004) : Original modification to
- allow DTDDoc to use this.
-
- Stefan Champailler (10/2004) : Make sure that the first
- level of the tree is not shown (aesthetic stuff).
-*/
-
-//----------------------------------------------------------------
-// CCTree
-// Implements a DHTML tree with the following features:
-// - Supports a general directed graph as the underlying model.
-// - Supports a concept of an "always open" node.
-//----------------------------------------------------------------
-
-// Private class _CCTreeModelNode
-function _CCTreeModelNode(id,label,link,alwaysOpen,initiallyOpen)
-{
- this.id = id;
- this.label = label;
- this.link = link;
- this.alwaysOpen = alwaysOpen;
- this.initiallyOpen = initiallyOpen;
-
- // children and childLabels are parallel arrays.
- // By default, childLabels[i] == children[i].label,
- // but the link operation may optionally specify
- // a child label that is specific to that parent-child
- // relationship.
- this.children = new Array();
- this.childLabels = new Array();
-}
-
-_CCTreeModelNode.prototype.addChild = function(child,childLabel)
-{
- this.children.push(child);
- if (childLabel) this.childLabels.push(childLabel);
- else this.childLabels.push(child.label);
-}
-
-// Private class _CCDisplayNode
-function _CCDisplayNode(modelNode,parentNode,treeId,label)
-{
- this.modelNode = modelNode;
- this.parentNode = parentNode;
- this.treeId = treeId;
-
- if (label) this.label = label;
- else this.label = modelNode.label;
-
- this.isLastChild = false;
-
- if (this.parentNode) {
- this.id = this.parentNode.id + ":" + this.modelNode.id;
-
- /* Stefan Champailler : This little fix is clever ! Let's check the
- following tree:
-
- alpha (1) -+-> beta (69)
- \-> beta (69).
-
- This describes a tree with three nodes. Two of them are links
- (beta). In that case, both the "beta" node have an id of "1:69".
- So if one calls openNode on any of them, what happens is that only
- one actually gets opened. To prevent that, I change the id of the
- node on the fly to make sure there are only unique id's.
-
- Please note this code is not very efficient (and yes, the right
- number of slash will be added :)) */
-
- for( var k=0; k<parentNode.children.length; k++) {
- if( parentNode.children[k].id == this.id)
- this.id = this.id + "/";
- }
-
- /* end of fix */
- }
- else this.id = this.modelNode.id;
-
- CCTree.trees[this.treeId].allDisplayNodes[this.id] = this;
-
- this.isOpen = this.modelNode.alwaysOpen || this.modelNode.initiallyOpen;
- if (this.isOpen)
- {
- this.constructChildren();
- }
-}
-
-_CCDisplayNode.prototype.toInnerHTML = function()
-{
- var indent = "";
-
- if (this.isOpen && !this.children) this.constructChildren();
-
- if (this.isLastChild)
- {
- if (this.modelNode.alwaysOpen)
- indent = this.imageTag("joinbottom.gif");
- else if (this.isOpen)
- indent = this.imageTag("minusbottom.gif","close")
- else if (this.modelNode.children.length)
- indent = this.imageTag("plusbottom.gif","open");
- else
- indent = this.imageTag("joinbottom.gif");
- }
- else
- {
- if (this.modelNode.alwaysOpen)
- indent = this.imageTag("join.gif");
- else if (this.isOpen)
- indent = this.imageTag("minus.gif","close");
- else if (this.modelNode.children.length)
- indent = this.imageTag("plus.gif","open");
- else
- indent = this.imageTag("join.gif");
- }
-
- /* Construct a horizontal line of the tree */
-
- var currAnc = this.parentNode;
- while (currAnc)
- {
- if (currAnc.isLastChild)
- indent = this.imageTag("empty.gif") + indent;
- else
- indent = this.imageTag("line.gif") + indent;
- currAnc = currAnc.parentNode;
- }
-
- var result = indent + this.nodeContent();
-
- /* Recurse deeper in the tree */
-
- if (this.isOpen && this.children)
- {
- var ix;
- for (ix in this.children)
- {
- result += this.children[ix];
- }
- }
-
- return result;
-}
-
-_CCDisplayNode.prototype.toString = function()
-{
- return "<div class='cctree-node' id='" + this.divId() + "'>" + this.toInnerHTML() + "</div>";
-}
-
-_CCDisplayNode.prototype.constructChildren = function()
-{
- if (this.modelNode.children.length > 0)
- {
- this.children = new Array();
- var ix;
- for (ix in this.modelNode.children)
- {
- this.children.push(new _CCDisplayNode(this.modelNode.children[ix],
- this,
- this.treeId,
- this.modelNode.childLabels[ix]));
- }
- this.children[this.children.length-1].isLastChild = true;
- }
-}
-
-_CCDisplayNode.prototype.imageTag = function(imgName,action)
-{
- var href = null;
-
- if (action == "open") href="CCTree.trees[" + this.treeId + "].openNode('" + this.id + "')";
- if (action == "close") href="CCTree.trees[" + this.treeId + "].closeNode('" + this.id + "')";
-
- if (href) return "<a href=\"javascript:" + href + "\"><img src='img/" + imgName + "' border='0'></a>";
- else return "<img src='img/" + imgName + "'>";
-}
-
-_CCDisplayNode.prototype.divId = function()
-{
- return "CCTree_" + this.treeId + "_" + this.id;
-}
-
-_CCDisplayNode.prototype.nodeContent = function()
-{
- var target = "";
-
- if (CCTree.trees[this.treeId].linkTarget) target = " target='" + CCTree.trees[this.treeId].linkTarget + "'";
-
- if (this.modelNode.link)
- return "<a href='" + this.modelNode.link + "'" + target + ">" + this.label + "</a>";
- else return this.label;
-}
-
-_CCDisplayNode.prototype.open = function()
-{
- this.isOpen = true;
- // document.all is known to work on IE but not on Konqueror or Mozilla.
- // So I've changed it to something more portable.
-
- //document.all[this.divId()].innerHTML = this.toInnerHTML();
- document.getElementById(this.divId()).innerHTML = this.toInnerHTML();
-}
-
-_CCDisplayNode.prototype.close = function()
-{
- this.isOpen = false;
- //document.all[this.divId()].innerHTML = this.toInnerHTML();
- document.getElementById(this.divId()).innerHTML = this.toInnerHTML();
-}
-
-// Public class CCTree
-CCTree = function(linkTarget)
-{
- // may have multiple roots:
- this.rootModelNodes = new Array();
- this.allModelNodes = new Array();
- this.treeId = CCTree.trees.length;
- this.allDisplayNodes = new Array(); // indexed by id
- this.linkTarget = linkTarget;
- CCTree.trees.push(this);
-}
-
-// static variables
-CCTree.trees = new Array();
-
-CCTree.prototype.addRootNode = function (id,label,link,alwaysOpen,initiallyOpen)
-{
- this.rootModelNodes[id] = this.addNode(id,label,link,alwaysOpen,initiallyOpen);
-}
-
-CCTree.prototype.addNode = function(id,label,link,alwaysOpen,initiallyOpen)
-{
- var newNode = new _CCTreeModelNode(id,label,link,alwaysOpen,initiallyOpen);
- this.allModelNodes[id] = newNode;
- return newNode;
-}
-
-CCTree.prototype.linkNodes = function(parentId,childId,childLabel)
-{
- this.allModelNodes[parentId].addChild(this.allModelNodes[childId],childLabel);
-}
-
-CCTree.prototype.constructDisplayNodes = function()
-{
- this.rootDisplayNodes = new Array();
- var ix;
- for (ix in this.rootModelNodes)
- {
- this.rootDisplayNodes.push(new _CCDisplayNode(this.rootModelNodes[ix],null,this.treeId));
- }
- this.rootDisplayNodes[this.rootDisplayNodes.length-1].isLastChild = true;
-}
-
-CCTree.prototype.openNode = function(displayNodeId)
-{
- this.allDisplayNodes[displayNodeId].open();
-}
-
-CCTree.prototype.closeNode = function(displayNodeId)
-{
- this.allDisplayNodes[displayNodeId].close();
-}
-
-CCTree.prototype.toString = function()
-{
- this.constructDisplayNodes();
-
- var ix;
- var result = "";
-
- for (ix in this.rootDisplayNodes)
- {
- result += this.rootDisplayNodes[ix].toString();
- }
-
- return result;
-}