Artifact 9da5605d97dbb6357d7254002ef64e5227d51db2
1 /* This file is a part of CanDyDOC fileset.
2 File is written by Victor Nakoryakov and placed into the public domain.
3
4 This file is javascript with classes that represents explorer window.
5 And things related to navigation. */
6
7 var explorer = new Explorer();
8
9 ///////////////////////////////////////////////////////////////////////////////
10 // Current symbol marker class constructor
11 ///////////////////////////////////////////////////////////////////////////////
12 function Marker()
13 {
14 this.top = document.createElement("div");
15 this.middle = document.createElement("div");
16 this.bottom = document.createElement("div");
17 this.container = document.createElement("div");
18
19 this.setTo = function(term)
20 {
21 // find definition related to `term`
22 var def = term.nextSibling;
23 while (def && def.nodeName != "DD")
24 def = def.nextSibling;
25
26 var defHeight = 0;
27 var childrenHeight = 0; // children of current declaration
28 if (def)
29 {
30 defHeight = def.offsetHeight;
31 var child = def.firstChild;
32
33 // traverse until DL tag, until children definition
34 while (child && child.nodeName != "DL")
35 child = child.nextSibling;
36
37 if (child)
38 childrenHeight = child.offsetHeight;
39 }
40
41 this.top.style.height = term.offsetHeight;
42 this.middle.style.height = defHeight - childrenHeight;
43 this.bottom.style.height = childrenHeight;
44
45 if (childrenHeight == 0)
46 this.bottom.style.display = "none";
47 else
48 this.bottom.style.display = "";
49
50 this.container.style.left = getLeft(term) - 8;
51 this.container.style.top = getTop(term);
52 this.container.style.display = "";
53 }
54
55 ///////////////////////////////////////////////////////////////////////////
56 this.container.style.position = "absolute";
57 this.container.style.display = "none";
58
59 this.top.className = "markertop";
60 this.middle.className = "markermiddle";
61 this.bottom.className = "markerbottom";
62
63 this.container.appendChild(this.top);
64 this.container.appendChild(this.middle);
65 this.container.appendChild(this.bottom);
66
67 //document.body.appendChild( this.container );
68
69 // Workaround bug in IE 5/6. We can not append anything to document body until
70 // full page load.
71 window.marker = this;
72 if (window.addEventListener)
73 window.addEventListener("load", new Function("document.body.appendChild( window.marker.container );"), false);
74 else if (window.attachEvent)
75 window.attachEvent("onload", new Function("document.body.appendChild( window.marker.container );"));
76 }
77
78 ///////////////////////////////////////////////////////////////////////////////
79 // Outline class constructor
80 ///////////////////////////////////////////////////////////////////////////////
81 function Outline()
82 {
83 this.tree = new TreeView();
84 this.mountPoint = null;
85 this.writeEnabled = false;
86 this.marker = new Marker();
87 this.classRegExp = new RegExp;
88 this.structRegExp = new RegExp;
89 this.enumRegExp = new RegExp;
90 this.templateRegExp = new RegExp;
91 this.aliasRegExp = new RegExp;
92 this.funcRegExp = new RegExp;
93
94 this.incSymbolLevel = function()
95 {
96 if (this.mountPoint == null)
97 this.mountPoint = this.tree.children[ 0 ];
98 else
99 this.mountPoint = this.mountPoint.lastChild();
100 }
101
102 this.decSymbolLevel = function()
103 {
104 // place icons near items according to extracted below type
105 for (var i = 0; i < this.mountPoint.children.length; ++i)
106 {
107 child = this.mountPoint.children[i];
108 var term = child.termRef;
109
110 // find first span node
111 var n = term.firstChild;
112 while (n && n.nodeName != "SPAN")
113 n = n.nextSibling;
114
115 if (!n) // shouldn't happen
116 continue;
117
118 var iconSrc;
119 if (n.firstChild.nodeName == "#text")
120 {
121 var text = n.firstChild.data; // text before declaration
122
123 if ( this.classRegExp.test(text) )
124 iconSrc = "candydoc/img/outline/class.gif";
125 else if ( this.structRegExp.test(text) )
126 iconSrc = "candydoc/img/outline/struct.gif";
127 else if ( this.enumRegExp.test(text) )
128 iconSrc = "candydoc/img/outline/enum.gif";
129 else if ( this.templateRegExp.test(text) )
130 iconSrc = "candydoc/img/outline/template.gif";
131 else if ( this.aliasRegExp.test(text) )
132 iconSrc = "candydoc/img/outline/alias.gif";
133 else // function or variable? check whether '(' ')' exists on the right
134 {
135 var np = n.firstChild;
136 while (np && np.nodeName != "SCRIPT") // find our script "onDecl"
137 np = np.nextSibling;
138
139 if (np && np.nextSibling && np.nextSibling.nodeName == "#text" &&
140 this.funcRegExp.test(np.nextSibling.data))
141 {
142 iconSrc = "candydoc/img/outline/func.gif";
143 }
144 else
145 iconSrc = "candydoc/img/outline/var.gif";
146 }
147 }
148 else // enum member ?
149 iconSrc = "candydoc/img/outline/var.gif";
150
151 child.icon.src = iconSrc;
152 child.icon.width = 16;
153 child.icon.height = 16;
154 }
155
156 this.mountPoint = this.mountPoint.parentNode;
157 }
158
159 this.addDecl = function(decl)
160 {
161 function getLastLeaf(elem)
162 {
163 if (elem.childNodes.length > 0)
164 return getLastLeaf(elem.lastChild);
165 else
166 return elem;
167 }
168
169 function getCurrentTerm()
170 {
171 var ret = getLastLeaf( document.getElementById("content") );
172 while (ret && ret.nodeName != "DT")
173 ret = ret.parentNode;
174
175 return ret;
176 }
177
178 if (this.writeEnabled)
179 {
180 var node = this.mountPoint.createChild(decl);
181 node.termRef = getCurrentTerm();
182 node.setOnclick( new Function("explorer.outline.mark(this.termRef);") );
183 }
184 }
185
186 this.mark = function(term)
187 {
188 this.marker.setTo(term);
189 window.scrollTo(0, getTop(term) - getWindowHeight() / 6);
190 }
191
192
193 this.classRegExp.compile("(.*\b)?class(\b.*)?");
194 this.structRegExp.compile("(.*\b)?struct(\b.*)?");
195 this.enumRegExp.compile("(.*\b)?enum(\b.*)?");
196 this.templateRegExp.compile("(.*\b)?template(\b.*)?");
197 this.aliasRegExp.compile("(.*\b)?alias(\b.*)?");
198 this.funcRegExp.compile(/.*\(.*/);
199 }
200
201
202
203
204 ///////////////////////////////////////////////////////////////////////////////
205 // Package explorer class constructor
206 ///////////////////////////////////////////////////////////////////////////////
207 function PackageExplorer()
208 {
209 this.tree = new TreeView(true);
210
211 this.addModule = function(mod)
212 {
213 var moduleIco = "candydoc/img/outline/module.gif";
214 var packageIco = "candydoc/img/outline/package.gif";
215
216 var path = mod.split("\.");
217 var node = this.tree.branch(path[0]);
218 if ( !node )
219 {
220 node = this.tree.createBranch(path[0], (path.length == 1) ? moduleIco : packageIco);
221 // modified by k.inaba : link for toplevel module
222 if (path.length == 1)
223 node.setRef(path[0] + ".html");
224 }
225
226 for (var i = 1; i < path.length; ++i)
227 {
228 var prev = node;
229 node = node.child(path[i]);
230 if (!node)
231 node = prev.createChild(path[i], (path.length == i + 1) ? moduleIco : packageIco);
232
233 if (path.length == i + 1)
234 node.setRef(path[i] + ".html");
235 }
236 }
237 }
238
239
240
241 ///////////////////////////////////////////////////////////////////////////////
242 // Explorer class constructor
243 ///////////////////////////////////////////////////////////////////////////////
244 function Explorer()
245 {
246 this.outline = new Outline();
247 this.packageExplorer = new PackageExplorer();
248 this.tabs = new Array();
249 this.tabCount = 0;
250
251 this.initialize = function(moduleName)
252 {
253 this.tabArea = document.getElementById("tabarea");
254 this.clientArea = document.getElementById("explorerclient");
255
256 // prevent text selection
257 this.tabArea.onmousedown = new Function("return false;");
258 this.tabArea.onclick = new Function("return true;");
259 this.tabArea.onselectstart = new Function("return false;");
260 this.clientArea.onmousedown = new Function("return false;");
261 this.clientArea.onclick = new Function("return true;");
262 this.clientArea.onselectstart = new Function("return false;");
263
264 this.outline.tree.createBranch( moduleName, "candydoc/img/outline/module.gif" );
265
266 // create tabs
267 this.createTab("Outline", this.outline.tree.domEntry);
268 this.createTab("Package", this.packageExplorer.tree.domEntry);
269 }
270
271 this.createTab = function(name, domEntry)
272 {
273 var tab = new Object();
274 this.tabs[name] = tab;
275 this.tabCount++;
276
277 tab.domEntry = domEntry;
278 tab.labelSpan = document.createElement("span");
279
280 if (this.tabCount > 1)
281 {
282 tab.labelSpan.className = "inactivetab";
283 tab.domEntry.style.display = "none";
284 }
285 else
286 {
287 tab.labelSpan.className = "activetab";
288 tab.domEntry.style.display = "";
289 }
290
291 tab.labelSpan.appendChild( document.createTextNode(name) );
292 tab.labelSpan.owner = this;
293 tab.labelSpan.onclick = new Function("this.owner.setSelection('" + name + "');");
294
295 this.tabArea.appendChild( tab.labelSpan );
296 this.clientArea.appendChild( domEntry );
297 }
298
299 this.setSelection = function(tabName)
300 {
301 for (name in this.tabs)
302 {
303 this.tabs[name].labelSpan.className = "inactivetab";
304 this.tabs[name].domEntry.style.display = "none";
305 }
306
307 this.tabs[tabName].labelSpan.className = "activetab";
308 this.tabs[tabName].domEntry.style.display = "";
309 }
310 }