add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / contrib / xml-query-parser / docs / cctree.js
1 /* This code is based on the one originally provided by
2    Geir Landrö in his dTree 2.05 package. You can get it
3    at : www.destroydrop.com/javascript/tree/.
4    
5    Therefore, the DTDDoc team considers that this code is 
6    Copyright (c) 2002-2003 Geir Landrö. Since the original
7    author didn't clearly forbids copies of this part, we
8    assume we're not doing anything wrong in porviding it
9    to you, in a modified or non-modified form.
10 */
11
12 /*   
13    Geir Landrö : Orignal version, for dTree.
14    
15    Michael Koehrsen (10/2004) : Original modification to
16       allow DTDDoc to use this.
17    
18    Stefan Champailler (10/2004) : Make sure that the first
19       level of the tree is not shown (aesthetic stuff).
20 */
21
22 //----------------------------------------------------------------
23 // CCTree
24 // Implements a DHTML tree with the following features:
25 // - Supports a general directed graph as the underlying model.
26 // - Supports a concept of an "always open" node.
27 //----------------------------------------------------------------
28
29 // Private class _CCTreeModelNode
30 function _CCTreeModelNode(id,label,link,alwaysOpen,initiallyOpen)
31 {
32     this.id = id;
33     this.label = label;
34     this.link = link;
35     this.alwaysOpen = alwaysOpen;
36     this.initiallyOpen = initiallyOpen;
37
38     // children and childLabels are parallel arrays.
39     // By default, childLabels[i] == children[i].label,
40     // but the link operation may optionally specify
41     // a child label that is specific to that parent-child 
42     // relationship.  
43     this.children = new Array();
44     this.childLabels = new Array();
45 }
46
47 _CCTreeModelNode.prototype.addChild = function(child,childLabel)
48 {
49     this.children.push(child);
50     if (childLabel) this.childLabels.push(childLabel);
51     else this.childLabels.push(child.label);
52 }
53
54 // Private class _CCDisplayNode
55 function _CCDisplayNode(modelNode,parentNode,treeId,label)
56 {
57     this.modelNode = modelNode;
58     this.parentNode = parentNode;
59     this.treeId = treeId;
60
61     if (label) this.label = label;
62     else this.label = modelNode.label;
63
64     this.isLastChild = false;
65
66     if (this.parentNode) {
67         this.id = this.parentNode.id + ":" + this.modelNode.id;
68
69         /* Stefan Champailler : This little fix is clever ! Let's check the
70            following tree:
71            
72            alpha (1) -+-> beta (69)
73                       \-> beta (69).
74                       
75            This describes a tree with three nodes. Two of them are links
76            (beta). In that case, both the "beta" node have an id of "1:69".
77            So if one calls openNode on any of them, what happens is that only
78            one actually gets opened. To prevent that, I change the id of the
79            node on the fly to make sure there are only unique id's. 
80            
81            Please note this code is not very efficient (and yes, the right
82            number of slash will be added :)) */
83            
84         for( var k=0; k<parentNode.children.length; k++) {
85             if( parentNode.children[k].id == this.id)
86                 this.id = this.id + "/";
87         }
88         
89         /* end of fix */
90     }
91     else this.id = this.modelNode.id;
92
93     CCTree.trees[this.treeId].allDisplayNodes[this.id] = this;
94
95     this.isOpen = this.modelNode.alwaysOpen || this.modelNode.initiallyOpen;
96     if (this.isOpen)
97     {
98         this.constructChildren();
99     }
100 }
101
102 _CCDisplayNode.prototype.toInnerHTML = function()
103 {
104     var indent = "";
105
106     if (this.isOpen && !this.children) this.constructChildren();
107
108     if (this.isLastChild)
109     {
110         if (this.modelNode.alwaysOpen)
111             indent = this.imageTag("joinbottom.gif");
112         else if (this.isOpen)
113             indent = this.imageTag("minusbottom.gif","close")
114         else if (this.modelNode.children.length)
115             indent = this.imageTag("plusbottom.gif","open");
116         else
117             indent = this.imageTag("joinbottom.gif");
118     }
119     else
120     {
121         if (this.modelNode.alwaysOpen)
122             indent = this.imageTag("join.gif");
123         else if (this.isOpen)
124             indent = this.imageTag("minus.gif","close");
125         else if (this.modelNode.children.length)
126             indent = this.imageTag("plus.gif","open");
127         else
128             indent = this.imageTag("join.gif");
129     }
130
131     /* Construct a horizontal line of the tree */
132
133     var currAnc = this.parentNode;
134     while (currAnc)
135     {
136         if (currAnc.isLastChild)
137             indent = this.imageTag("empty.gif") + indent;
138         else
139             indent = this.imageTag("line.gif") + indent;
140         currAnc = currAnc.parentNode;
141     }
142
143     var result = indent + this.nodeContent();
144
145     /* Recurse deeper in the tree */
146     
147     if (this.isOpen && this.children)
148     {
149         var ix;
150         for (ix in this.children)
151         {
152             result += this.children[ix];
153         }
154     }
155
156     return result;
157 }
158
159 _CCDisplayNode.prototype.toString = function()
160 {
161     return "<div class='cctree-node' id='" + this.divId() + "'>" + this.toInnerHTML() + "</div>";
162 }
163
164 _CCDisplayNode.prototype.constructChildren = function()
165 {
166     if (this.modelNode.children.length > 0)
167     {
168         this.children = new Array();
169         var ix;
170         for (ix in this.modelNode.children)
171         {
172             this.children.push(new _CCDisplayNode(this.modelNode.children[ix],
173                                                   this,
174                                                   this.treeId,
175                                                   this.modelNode.childLabels[ix]));
176         }
177         this.children[this.children.length-1].isLastChild = true;
178     }
179 }
180
181 _CCDisplayNode.prototype.imageTag = function(imgName,action)
182 {
183     var href =  null;
184
185     if (action == "open") href="CCTree.trees[" + this.treeId + "].openNode('" + this.id + "')";
186     if (action == "close") href="CCTree.trees[" + this.treeId + "].closeNode('" + this.id +  "')";
187
188     if (href) return "<a href=\"javascript:" + href + "\"><img src='img/" + imgName + "' border='0'></a>";
189     else return "<img src='img/" + imgName + "'>";
190 }
191
192 _CCDisplayNode.prototype.divId = function()
193 {
194     return "CCTree_" + this.treeId + "_" + this.id;
195 }
196
197 _CCDisplayNode.prototype.nodeContent = function()
198 {
199     var target = "";
200
201     if (CCTree.trees[this.treeId].linkTarget) target = " target='" + CCTree.trees[this.treeId].linkTarget + "'";
202
203     if (this.modelNode.link)
204         return "<a href='" + this.modelNode.link + "'" + target + ">" + this.label + "</a>";
205     else return this.label;
206 }
207
208 _CCDisplayNode.prototype.open = function()
209 {
210     this.isOpen = true;
211     // document.all is known to work on IE but not on Konqueror or Mozilla.
212     // So I've changed it to something more portable.
213     
214     //document.all[this.divId()].innerHTML = this.toInnerHTML();
215     document.getElementById(this.divId()).innerHTML = this.toInnerHTML();
216 }
217
218 _CCDisplayNode.prototype.close = function()
219 {
220     this.isOpen = false;
221     //document.all[this.divId()].innerHTML = this.toInnerHTML();
222     document.getElementById(this.divId()).innerHTML = this.toInnerHTML();
223 }
224
225 // Public class CCTree
226 CCTree = function(linkTarget)
227 {
228     // may have multiple roots:
229     this.rootModelNodes = new Array();
230     this.allModelNodes = new Array();
231     this.treeId = CCTree.trees.length;
232     this.allDisplayNodes = new Array(); // indexed by id
233     this.linkTarget = linkTarget;
234     CCTree.trees.push(this);
235 }
236
237 // static variables
238 CCTree.trees = new Array();
239
240 CCTree.prototype.addRootNode = function (id,label,link,alwaysOpen,initiallyOpen)
241 {
242     this.rootModelNodes[id] = this.addNode(id,label,link,alwaysOpen,initiallyOpen);
243 }
244
245 CCTree.prototype.addNode = function(id,label,link,alwaysOpen,initiallyOpen)
246 {
247     var newNode = new _CCTreeModelNode(id,label,link,alwaysOpen,initiallyOpen);
248     this.allModelNodes[id] = newNode;
249     return newNode;
250 }
251
252 CCTree.prototype.linkNodes = function(parentId,childId,childLabel)
253 {
254     this.allModelNodes[parentId].addChild(this.allModelNodes[childId],childLabel);
255 }
256
257 CCTree.prototype.constructDisplayNodes = function()
258 {
259     this.rootDisplayNodes = new Array();
260     var ix;
261     for (ix in this.rootModelNodes)
262     {
263         this.rootDisplayNodes.push(new _CCDisplayNode(this.rootModelNodes[ix],null,this.treeId));
264     }
265     this.rootDisplayNodes[this.rootDisplayNodes.length-1].isLastChild = true;
266 }
267
268 CCTree.prototype.openNode = function(displayNodeId)
269 {
270     this.allDisplayNodes[displayNodeId].open();
271 }
272
273 CCTree.prototype.closeNode = function(displayNodeId) 
274 {
275     this.allDisplayNodes[displayNodeId].close();
276 }
277
278 CCTree.prototype.toString = function()
279 {
280     this.constructDisplayNodes();
281
282     var ix;
283     var result = "";
284
285     for (ix in this.rootDisplayNodes)
286     {
287         result += this.rootDisplayNodes[ix].toString();
288     }
289
290     return result;
291 }