/ddoc/candydoc/explorer.js
http://github.com/baryluk/cords · JavaScript · 305 lines · 225 code · 53 blank · 27 comment · 54 complexity · 383e8c672290e1edf3a1d1dc45c38f44 MD5 · raw file
- /* This file is a part of CanDyDOC fileset.
- File is written by Victor Nakoryakov and placed into the public domain.
- This file is javascript with classes that represents explorer window.
- And things related to navigation. */
-
- var explorer = new Explorer();
- ///////////////////////////////////////////////////////////////////////////////
- // Current symbol marker class constructor
- ///////////////////////////////////////////////////////////////////////////////
- function Marker()
- {
- this.top = document.createElement("div");
- this.middle = document.createElement("div");
- this.bottom = document.createElement("div");
- this.container = document.createElement("div");
-
- this.setTo = function(term)
- {
- // find definition related to `term`
- var def = term.nextSibling;
- while (def && def.nodeName != "DD")
- def = def.nextSibling;
-
- var defHeight = 0;
- var childrenHeight = 0; // children of current declaration
- if (def)
- {
- defHeight = def.offsetHeight;
- var child = def.firstChild;
-
- // traverse until DL tag, until children definition
- while (child && child.nodeName != "DL")
- child = child.nextSibling;
-
- if (child)
- childrenHeight = child.offsetHeight;
- }
-
- this.top.style.height = term.offsetHeight;
- this.middle.style.height = defHeight - childrenHeight;
- this.bottom.style.height = childrenHeight;
-
- if (childrenHeight == 0)
- this.bottom.style.display = "none";
- else
- this.bottom.style.display = "";
-
- this.container.style.left = getLeft(term) - 8;
- this.container.style.top = getTop(term);
- this.container.style.display = "";
- }
-
- ///////////////////////////////////////////////////////////////////////////
- this.container.style.position = "absolute";
- this.container.style.display = "none";
-
- this.top.className = "markertop";
- this.middle.className = "markermiddle";
- this.bottom.className = "markerbottom";
-
- this.container.appendChild(this.top);
- this.container.appendChild(this.middle);
- this.container.appendChild(this.bottom);
-
- //document.body.appendChild( this.container );
-
- // Workaround bug in IE 5/6. We can not append anything to document body until
- // full page load.
- window.marker = this;
- if (window.addEventListener)
- window.addEventListener("load", new Function("document.body.appendChild( window.marker.container );"), false);
- else if (window.attachEvent)
- window.attachEvent("onload", new Function("document.body.appendChild( window.marker.container );"));
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Outline class constructor
- ///////////////////////////////////////////////////////////////////////////////
- function Outline()
- {
- this.tree = new TreeView();
- this.mountPoint = null;
- this.writeEnabled = false;
- this.marker = new Marker();
- this.classRegExp = new RegExp;
- this.structRegExp = new RegExp;
- this.enumRegExp = new RegExp;
- this.templateRegExp = new RegExp;
- this.aliasRegExp = new RegExp;
- this.funcRegExp = new RegExp;
-
- this.incSymbolLevel = function()
- {
- if (this.mountPoint == null)
- this.mountPoint = this.tree.children[ 0 ];
- else
- this.mountPoint = this.mountPoint.lastChild();
- }
- this.decSymbolLevel = function()
- {
- // place icons near items according to extracted below type
- for (var i = 0; i < this.mountPoint.children.length; ++i)
- {
- child = this.mountPoint.children[i];
- var term = child.termRef;
-
- // find first span node
- var n = term.firstChild;
- while (n && n.nodeName != "SPAN")
- n = n.nextSibling;
-
- if (!n) // shouldn't happen
- continue;
-
- var iconSrc;
- if (n.firstChild.nodeName == "#text")
- {
- var text = n.firstChild.data; // text before declaration
-
- if ( this.classRegExp.test(text) )
- iconSrc = "candydoc/img/outline/class.gif";
- else if ( this.structRegExp.test(text) )
- iconSrc = "candydoc/img/outline/struct.gif";
- else if ( this.enumRegExp.test(text) )
- iconSrc = "candydoc/img/outline/enum.gif";
- else if ( this.templateRegExp.test(text) )
- iconSrc = "candydoc/img/outline/template.gif";
- else if ( this.aliasRegExp.test(text) )
- iconSrc = "candydoc/img/outline/alias.gif";
- else // function or variable? check whether '(' ')' exists on the right
- {
- var np = n.firstChild;
- while (np && np.nodeName != "SCRIPT") // find our script "onDecl"
- np = np.nextSibling;
-
- if (np && np.nextSibling && np.nextSibling.nodeName == "#text" &&
- this.funcRegExp.test(np.nextSibling.data))
- {
- iconSrc = "candydoc/img/outline/func.gif";
- }
- else
- iconSrc = "candydoc/img/outline/var.gif";
- }
- }
- else // enum member ?
- iconSrc = "candydoc/img/outline/var.gif";
-
- child.icon.src = iconSrc;
- child.icon.width = 16;
- child.icon.height = 16;
- }
-
- this.mountPoint = this.mountPoint.parentNode;
- }
- this.addDecl = function(decl)
- {
- function getLastLeaf(elem)
- {
- if (elem.childNodes.length > 0)
- return getLastLeaf(elem.lastChild);
- else
- return elem;
- }
- function getCurrentTerm()
- {
- var ret = getLastLeaf( document.getElementById("content") );
- while (ret && ret.nodeName != "DT")
- ret = ret.parentNode;
-
- return ret;
- }
-
- if (this.writeEnabled)
- {
- var node = this.mountPoint.createChild(decl);
- node.termRef = getCurrentTerm();
- node.setOnclick( new Function("explorer.outline.mark(this.termRef);") );
- }
- }
- this.mark = function(term)
- {
- this.marker.setTo(term);
- window.scrollTo(0, getTop(term) - getWindowHeight() / 6);
- }
-
-
- this.classRegExp.compile("(.*\b)?class(\b.*)?");
- this.structRegExp.compile("(.*\b)?struct(\b.*)?");
- this.enumRegExp.compile("(.*\b)?enum(\b.*)?");
- this.templateRegExp.compile("(.*\b)?template(\b.*)?");
- this.aliasRegExp.compile("(.*\b)?alias(\b.*)?");
- this.funcRegExp.compile(/.*\(.*/);
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Package explorer class constructor
- ///////////////////////////////////////////////////////////////////////////////
- function PackageExplorer()
- {
- this.tree = new TreeView(true);
-
- this.addModule = function(mod)
- {
- var moduleIco = "candydoc/img/outline/module.gif";
- var packageIco = "candydoc/img/outline/package.gif";
- var path = mod.split("\.");
- var node = this.tree.branch(path[0]);
- if ( !node )
- node = this.tree.createBranch(path[0], (path.length == 1) ? moduleIco : packageIco);
-
- for (var i = 1; i < path.length; ++i)
- {
- var prev = node;
- node = node.child(path[i]);
- if (!node)
- node = prev.createChild(path[i], (path.length == i + 1) ? moduleIco : packageIco);
-
- if (path.length == i + 1)
- node.setRef(path[i] + ".html");
- }
- }
- }
- ///////////////////////////////////////////////////////////////////////////////
- // Explorer class constructor
- ///////////////////////////////////////////////////////////////////////////////
- function Explorer()
- {
- this.outline = new Outline();
- this.packageExplorer = new PackageExplorer();
- this.tabs = new Array();
- this.tabCount = 0;
-
- this.initialize = function(moduleName)
- {
- this.tabArea = document.getElementById("tabarea");
- this.clientArea = document.getElementById("explorerclient");
-
- // prevent text selection
- this.tabArea.onmousedown = new Function("return false;");
- this.tabArea.onclick = new Function("return true;");
- this.tabArea.onselectstart = new Function("return false;");
- this.clientArea.onmousedown = new Function("return false;");
- this.clientArea.onclick = new Function("return true;");
- this.clientArea.onselectstart = new Function("return false;");
-
- this.outline.tree.createBranch( moduleName, "candydoc/img/outline/module.gif" );
-
- // create tabs
- this.createTab("Outline", this.outline.tree.domEntry);
- this.createTab("Package", this.packageExplorer.tree.domEntry);
- }
-
- this.createTab = function(name, domEntry)
- {
- var tab = new Object();
- this.tabs[name] = tab;
- this.tabCount++;
-
- tab.domEntry = domEntry;
- tab.labelSpan = document.createElement("span");
-
- if (this.tabCount > 1)
- {
- tab.labelSpan.className = "inactivetab";
- tab.domEntry.style.display = "none";
- }
- else
- {
- tab.labelSpan.className = "activetab";
- tab.domEntry.style.display = "";
- }
-
- tab.labelSpan.appendChild( document.createTextNode(name) );
- tab.labelSpan.owner = this;
- tab.labelSpan.onclick = new Function("this.owner.setSelection('" + name + "');");
-
- this.tabArea.appendChild( tab.labelSpan );
- this.clientArea.appendChild( domEntry );
- }
-
- this.setSelection = function(tabName)
- {
- for (name in this.tabs)
- {
- this.tabs[name].labelSpan.className = "inactivetab";
- this.tabs[name].domEntry.style.display = "none";
- }
-
- this.tabs[tabName].labelSpan.className = "activetab";
- this.tabs[tabName].domEntry.style.display = "";
- }
- }