# HG changeset patch # User Anders Johnsen # Date 1218380981 -7200 # Node ID 4c121c2aa8442d4774b3d52539370355b7cae1b7 # Parent 5e05c03d15581befd591759107ffb9407f931d9b Added candydoc files for docs. diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/CANDYDOC.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/candydoc/CANDYDOC.txt Sun Aug 10 17:09:41 2008 +0200 @@ -0,0 +1,56 @@ + +CanDyDOC is fileset for creating advanced documentation of programs written +in D programming language. CanDyDOC adds some eye-candy and advanced navigation +features to .html documents that are generated by D compiler and known as DDOC. +Produced result is AJAX web-application that is compatible with all mainstream +web browsers. + +This is a fork of the original candydoc, distributed with DSSS. For more +information on DSSS and DSSS' fork of candydoc, see +http://www.dsource.org/projects/dsss/ + +CanDyDOC includes following files: + - candy.ddoc + File with DDOC macro definitions. You haven't to touch it. + + - modules.ddoc + You should enumerate all modules that would be avaible for navigation + here. + + - style.css + Cascading style sheet file that defines look of produced documentation. + You can leave this file without changes or adjust fonts, colors, etc + here. See it for documentation. + + - ie56hack.css + CSS file to force Internet Explorer 5/6 browser show documentation + as it looks like in standard-compliant browsers. + + - tree.js + JavaScript implementing tree control that looks like native one. + + - util.js + Common cross-browser routines. + + - explorer.js + Heart of every documentation's page. Controls generation, behaviour and + navigation of a page. + + - numerous of image files in 'img' folder. + +How to use: + 1) Put 'candydoc' directory in place where documentation will be. + 2) Modify modules.ddoc file: enumerate all modules that should be avaible + for navigation. + 3) Modify style.css file if you want to change style of documentation. Or + leave it unmodified to apply defaul theme. + 4) Run documentation compilation with candy.ddoc and modules.ddoc specified + on command line. + 5) Enjoy a result :) + +Known bugs: + - Explorer window doesn't work on Safari browser. + - Scroll bar positions are not adjusted after explorer's tab change in Opera + browser. So it is posible to see nothing on some tab: solution is to + return to a previous tab, scroll it to top and then return back. + - Overlapping of some elements when too few horizontal place avaible. diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/candy.ddoc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/candydoc/candy.ddoc Sun Aug 10 17:09:41 2008 +0200 @@ -0,0 +1,51 @@ +DDOC = + + + +$(TITLE) + + + + + + +
+
+ + + +

$(TITLE)

$(BODY)
+ Page was generated with + + on $(DATETIME) +
+
+$(ADD_MODULES) + + + +DDOC_DECL = + +$(DT $0) + + + +DDOC_PSYMBOL = +$0 + + + +DDOC_MEMBERS = + +$(DL $0) + + + +DDOC_PARAM_ID = +$0 + + +DDOC_PARAM =$0 +ADD_MODULES = +MODULE =explorer.packageExplorer.addModule("$0"); +MODULE_FULL =explorer.packageExplorer.addModuleFull("$0"); diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/explorer.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/candydoc/explorer.js Sun Aug 10 17:09:41 2008 +0200 @@ -0,0 +1,319 @@ +/* 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.addModule2 = function(mod, full) + { + 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) { + if (full) + node.setRef(mod + ".html"); + else + node.setRef(path[i] + ".html"); + } + } + } + + this.addModuleFull = function(mod) + { + this.addModule2(mod, true); + } + + this.addModule = function(mod) + { + this.addModule2(mod, false); + } +} + + + +/////////////////////////////////////////////////////////////////////////////// +// 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 = ""; + } +} diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/ie56hack.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/candydoc/ie56hack.css Sun Aug 10 17:09:41 2008 +0200 @@ -0,0 +1,21 @@ +/* This file is a part of CanDyDOC fileset. + File is written by Victor Nakoryakov and placed into the public domain. + + This file is CSS to work around IE6 and earlier bugs. It's included just + in these browsers. */ + + +/* Some magic to emulate unsupported "position: fixed" style. */ +#tabarea +{ + _position: absolute; + _top: expression(eval(document.body.scrollTop+8)); +} + +/* ditto */ +#explorerclient +{ + _position: absolute; + _top: expression(eval(document.body.scrollTop+24)); + _height: expression(eval(document.body.clientHeight-48)); +} diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/bg.gif Binary file doc/candydoc/img/bg.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/candydoc.gif Binary file doc/candydoc/img/candydoc.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/outline/alias.gif Binary file doc/candydoc/img/outline/alias.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/outline/bg.gif Binary file doc/candydoc/img/outline/bg.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/outline/class.gif Binary file doc/candydoc/img/outline/class.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/outline/enum.gif Binary file doc/candydoc/img/outline/enum.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/outline/func.gif Binary file doc/candydoc/img/outline/func.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/outline/module.gif Binary file doc/candydoc/img/outline/module.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/outline/package.gif Binary file doc/candydoc/img/outline/package.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/outline/struct.gif Binary file doc/candydoc/img/outline/struct.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/outline/template.gif Binary file doc/candydoc/img/outline/template.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/outline/var.gif Binary file doc/candydoc/img/outline/var.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/package/bg.gif Binary file doc/candydoc/img/package/bg.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/tree/shim.gif Binary file doc/candydoc/img/tree/shim.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/tree/tb.gif Binary file doc/candydoc/img/tree/tb.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/tree/tbr.gif Binary file doc/candydoc/img/tree/tbr.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/tree/tbrm.gif Binary file doc/candydoc/img/tree/tbrm.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/tree/tbrp.gif Binary file doc/candydoc/img/tree/tbrp.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/tree/tr.gif Binary file doc/candydoc/img/tree/tr.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/tree/trm.gif Binary file doc/candydoc/img/tree/trm.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/img/tree/trp.gif Binary file doc/candydoc/img/tree/trp.gif has changed diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/modules.ddoc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/candydoc/modules.ddoc Sun Aug 10 17:09:41 2008 +0200 @@ -0,0 +1,2 @@ +MODULES = + $(MODULE_FULL ast.Decl) diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/style.css --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/candydoc/style.css Sun Aug 10 17:09:41 2008 +0200 @@ -0,0 +1,169 @@ +/* This file is a part of CanDyDOC fileset. + File is written by Victor Nakoryakov and placed into the public domain. + + This file is main CSS file of CanDyDOC. You may adjust some part of + parameters to control how result documentation would looks like. See + further documentation for details. */ + + + +/* This controls how background would looks like and + sets some document-scope defaults. */ +body +{ + /* These parameters control default font. */ + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10pt; + color: #666666; + + /* These control look of background. Note that you have to use + fixed background to keep documentation good-looking in + IE6 and earlier. Otherwise whole *explorer* will jerk while + scrolling. If you do not want to use background at all use + some invalid url, e.g. url(foo). */ + background-color: #e6fcea; + background: url(img/bg.gif) fixed; + + /* Don't touch. Necessary for IE6 and earlier. */ + height: 100%; +} + + + +/* Style applied to all tables. Actualy there are two: one table is + that contains contant and footer with CanDyDOC logo, and others + are that contains functions' parameters description. */ +table +{ + font-family: Verdana, Arial, Helvetica, sans-serif; + font-size: 10pt; + color: #666666; + text-align: justify; +} + + +/* Style used for all hyperlinks. */ +a:link { color: #009900; text-decoration: none } +a:visited { color: #009999; text-decoration: none } +a:hover { color: #0033cc; text-decoration: none } +a:active { color: #0033cc; text-decoration: none } + +/* +table.matrix +{ + border-left: double 3px #666666; + border-right: double 3px #666666; + margin-left: 3em; +} +*/ + +/* Style appled to declarations. E.g. 'void foo(int a, float b);' */ +span.decl { font-size: 10pt; font-weight: bold; color: #000000; text-align: left } +/* Style appled to current declaration's symbol. E.g. 'foo' in 'void foo(int a, float b);' */ +span.currsymbol { font-size: 12pt; color: #009900 } +/* Style appled to function's parameters. E.g. 'a' and 'b' in 'void foo(int a, float b);' */ +span.funcparam { font-style: italic; font-weight: normal; color: #331200 } + +/* Style for div that actualy contains documenation. */ +#content +{ + padding-right: 8px; + position: absolute; + left: 245px; + top: 8px; + text-align: justify; +} + +/* Style for table that is inside div considered above. Contains documentaton + itself and footer with CanDyDOC logo. */ +table.content +{ + margin-bottom: 8px; + border-spacing: 0px; + border-collapse: collapse; + background-color: #ffffff; +} + +/* Style for cell of above considered table that contains documentation itself. */ +#docbody +{ + padding: 8px 20px 8px 20px; + border: solid 1px #009900; +} + +/* Style for cell that contains CanDyDOC logo. */ +#docfooter +{ + height: 16px; + background-color: #ddeedd; + padding: 0px 8px 0px 8px; + border: solid 1px #009900; +} + +/* Style applied to currently active tab of explorer window. */ +span.activetab +{ + background-color: #0033cc; + border-top: solid 2px #009900; + color: #ffffff; + font-weight: bold; + padding-left: 4px; + padding-right: 4px; + padding-top: 1px; + margin-right: 1px; +} + +/* Style applied to currently inactive tab of explorer window. */ +span.inactivetab +{ + background-color: #000066; + color: #cccccc; + font-weight: normal; + padding-left: 4px; + padding-right: 4px; + padding-top: 0px; + margin-right: 1px; +} + +/* Style applied to div that contains tabs of explorer. Note that if + you want to change it's position you have to change position of + #explorerclient, #content and corresponding values in ie56hack.css */ +#tabarea +{ + position: fixed; + top: 8px; + width: 205px; + height: 16px; + cursor: default; +} + + +/* Style applied to div that contains tree in explorer. Note that if + you want to change it's position you have to change position of + #tabarea, #content and corresponding values in ie56hack.css */ +#explorerclient +{ + position: fixed; + top: 24px; + bottom: 8px; + width: 205px; + overflow: auto; + background-color: #fcfffc; + border: solid 2px #0033cc; + padding: 4px; + cursor: default; + color: Black; +} + +/* Following 3 styles control appearance of marker that appears + if you click some entity in outline window. */ +div.markertop { border-left: solid 2px #0033cc;} +div.markermiddle{ border-left: dotted 2px #0033cc;} +div.markerbottom{ border-left: dotted 2px #66cc66;} + +/* Style applied to preformated text used to show examples. */ +pre.d_code +{ + border: dotted 1px #9c9; + background-color: #eeffee; +} \ No newline at end of file diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/tree.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/candydoc/tree.js Sun Aug 10 17:09:41 2008 +0200 @@ -0,0 +1,374 @@ +/* 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 native style tree control. */ + +var pmNone = 0; +var pmPlus = 1; +var pmMinus = 2; + +var hlNone = 0; +var hlGrey = 1; +var hlSelected = 2; + +function TreeView(hrefMode) +{ + this.domEntry = document.createElement("div"); + this.children = new Array(); + this.selection = null; + this.hrefMode = hrefMode; + + this.createBranch = function(text, iconSrc) + { + var root = new TreeNode(text, iconSrc, this.hrefMode); + root.owner = this; + this.children[ this.children.length ] = root; + this.domEntry.appendChild( root.domEntry ); + return root; + } + + this.branch = function(text) + { + var ret = null; + for (var i = 0; i < this.children.length; ++i) + if (this.children[i].textElement.data == text) + { + ret = this.children[i]; + break; + } + + return ret; + } + + this.domEntry.style.fontSize = "10px"; + this.domEntry.style.cursor = "default"; + this.domEntry.style.whiteSpace = "nowrap"; +} + +var idCounter = 0; +function TreeNode(text, iconSrc, hrefMode) +{ + this.id = idCounter++; + this.parentNode = null; + this.children = new Array(); + this.domEntry = document.createElement("div"); + this.icon = document.createElement("img"); + this.textElement = document.createTextNode(text); + this.textSpan = document.createElement("span"); + this.lineDiv = document.createElement("div"); + this.hierarchyImgs = new Array(); + this.onclick = null; + + function createIcon() + { + var img = document.createElement("img"); + img.style.verticalAlign = "middle"; + img.style.position = "relative"; + img.style.top = "-1px"; + img.width = 16; + img.height = 16; + return img; + } + + function createHierarchyImage() + { + var img = createIcon(); + img.pointsTop = false; + img.pointsBottom = false; + img.pointsRight = false; + img.pmState = pmNone; + return img; + } + + function genHierarchyImageSrc(hierarchyImg) + { + var name = ""; + if (hierarchyImg.pointsTop) + name += "t"; + + if (hierarchyImg.pointsBottom) + name += "b"; + + if (hierarchyImg.pointsRight) + name += "r"; + + if (hierarchyImg.pmState == pmPlus) + name += "p"; + else if (hierarchyImg.pmState == pmMinus) + name += "m"; + + if (name == "") + name = "shim"; + + return "candydoc/img/tree/" + name + ".gif"; + } + + function setSrc(icon, src) + { + icon.src = src; + // After src change width and height are reseted in IE. + // Bug workaround: + icon.width = 16; + icon.height = 16; + } + + this.createChild = function(text, iconSrc) + { + var child = new TreeNode(text, iconSrc, this.owner.hrefMode); + this.children[ this.children.length ] = child; + this.domEntry.appendChild( child.domEntry ); + child.parentNode = this; + child.owner = this.owner; + + // insert hierarchy images according to deepness level + // of created child. + + if (this.children.length > 1) + { + // there were already added child before. So copy `level-1` + // hierarchy images from it. + + var prevAddedChild = this.children[ this.children.length - 2 ]; + + for (var i = 0; i < prevAddedChild.hierarchyImgs.length - 1; ++i) + { + var prevAddedChildImg = prevAddedChild.hierarchyImgs[i]; + var img = createHierarchyImage(); + setSrc(img, prevAddedChildImg.src); + img.pointsTop = prevAddedChildImg.pointsTop; + img.pointsBottom = prevAddedChildImg.pointsBottom; + img.pointsRight = prevAddedChildImg.pointsRight; + img.pmState = prevAddedChildImg.pmState; + + child.hierarchyImgs[ child.hierarchyImgs.length ] = img; + child.lineDiv.insertBefore(img, child.icon); + } + + // change last hierarchy image of prevAddedChild from |_ to |- + var lastHierarchyImg = prevAddedChild.hierarchyImgs[ prevAddedChild.hierarchyImgs.length - 1 ]; + lastHierarchyImg.pointsBottom = true; + setSrc(lastHierarchyImg, genHierarchyImageSrc(lastHierarchyImg)); + + // change hierarchy images of prevAddedChild's children on it's last + // level to | + prevAddedChild.addHierarchyTBLine(prevAddedChild.hierarchyImgs.length - 1); + } + else + { + // this is a first child. So copy `level-2` + // hierarchy images from parent, i.e. this. + + for (var i = 0; i < this.hierarchyImgs.length - 1; ++i) + { + var parentImg = this.hierarchyImgs[i]; + var img = createHierarchyImage(); + setSrc(img, parentImg.src); + img.pointsTop = parentImg.pointsTop; + img.pointsBottom = parentImg.pointsBottom; + img.pointsRight = parentImg.pointsRight; + img.pmState = parentImg.pmState; + + child.hierarchyImgs[ child.hierarchyImgs.length ] = img; + child.lineDiv.insertBefore(img, child.icon); + } + + if (this.hierarchyImgs.length > 0) // we are not root + { + // change last hierarchy image of parent (i.e. this): add minus to it + var lastHierarchyImg = this.hierarchyImgs[ this.hierarchyImgs.length - 1]; + lastHierarchyImg.pmState = pmMinus; + setSrc(lastHierarchyImg, genHierarchyImageSrc(lastHierarchyImg)); + lastHierarchyImg.owner = this; + lastHierarchyImg.onclick = new Function("e", "this.owner.processPMClick(e);"); + + // make decision on image on `level-1`. It depends on parent's (ie this) + // image on same level. + var parentL1HierarchyImg = lastHierarchyImg; + var l1HierarchyImg = createHierarchyImage(); + if (parentL1HierarchyImg.pointsBottom) + { + l1HierarchyImg.pointsTop = true; + l1HierarchyImg.pointsBottom = true; + } + setSrc(l1HierarchyImg, genHierarchyImageSrc(l1HierarchyImg)); + child.hierarchyImgs[ child.hierarchyImgs.length ] = l1HierarchyImg; + child.lineDiv.insertBefore(l1HierarchyImg, child.icon); + } + } + + // in any case on last level our child will have icon |_ + var img = createHierarchyImage(); + img.pointsTop = true; + img.pointsRight = true; + setSrc(img, genHierarchyImageSrc(img)); + + child.hierarchyImgs[ child.hierarchyImgs.length ] = img; + child.lineDiv.insertBefore(img, child.icon); + + return child; + } + + this.lastChild = function() + { + return this.children[ this.children.length - 1 ]; + } + + this.child = function(text) + { + var ret = null; + for (var i = 0; i < this.children.length; ++i) + if (this.children[i].textElement.data == text) + { + ret = this.children[i]; + break; + } + + return ret; + } + + this.addHierarchyTBLine = function(level) + { + for (var i = 0; i < this.children.length; ++i) + { + var img = this.children[i].hierarchyImgs[level]; + img.pointsTop = true; + img.pointsBottom = true; + setSrc(img, genHierarchyImageSrc(img)); + this.children[i].addHierarchyTBLine(level); + } + } + + this.expand = function() + { + var img = this.hierarchyImgs[ this.hierarchyImgs.length - 1 ]; + + if (img.pmState == pmPlus) + { + img.pmState = pmMinus; + setSrc(img, genHierarchyImageSrc(img)); + + for (var i = 0; i < this.children.length; ++i) + this.children[i].domEntry.style.display = ""; + } + } + + this.collapse = function() + { + var img = this.hierarchyImgs[ this.hierarchyImgs.length - 1 ]; + + if (img.pmState == pmMinus) + { + img.pmState = pmPlus; + setSrc(img, genHierarchyImageSrc(img)); + + for (var i = 0; i < this.children.length; ++i) + this.children[i].domEntry.style.display = "none"; + } + } + + this.toggle = function() + { + var img = this.hierarchyImgs[ this.hierarchyImgs.length - 1 ]; + if (img.pmState == pmMinus) + this.collapse(); + else + this.expand(); + } + + this.select = function() + { + if (this.owner.selection != this) + { + if (this.owner.selection) + this.owner.selection.setHighlight(hlNone); + + this.owner.selection = this; + this.setHighlight(hlSelected); + } + } + + this.setHighlight = function(mode) + { + if (mode == hlNone) + { + this.textSpan.style.backgroundColor = ""; + this.textSpan.style.color = ""; + this.textSpan.style.border = ""; + } + else if (mode == hlGrey) + { + this.textSpan.style.backgroundColor = "#aaaaaa"; + this.textSpan.style.color = ""; + this.textSpan.style.border = ""; + } + else if (mode == hlSelected) + { + this.textSpan.style.backgroundColor = "3399cc"; + this.textSpan.style.color = "white"; + this.textSpan.style.border = "dotted 1px red"; + } + } + + this.setOnclick = function(proc) + { + this.onclick = proc; + } + + this.setRef = function(url) + { + if (this.anchor) + this.anchor.href = url; + } + + this.processPMClick = function(e) + { + this.toggle(); + + // prevent this line selection, stop bubbling + if (e) + e.stopPropagation(); // Mozilla way + if (window.event) + window.event.cancelBubble = true; // IE way + } + + this.processOnclick = function() + { + this.select(); + if (this.onclick instanceof Function) + this.onclick(); + } + + /////////////////////////////////////////////////////////////////////////// + if (iconSrc) + this.icon.src = iconSrc; + else + { + this.icon.width = 0; + this.icon.height = 0; + } + + this.icon.style.verticalAlign = "middle"; + this.icon.style.position = "relative"; + this.icon.style.top = "-1px"; + this.icon.style.paddingRight = "2px"; + + if (!hrefMode) + { + this.textSpan.appendChild( this.textElement ); + } + else + { + this.anchor = document.createElement("a"); + this.anchor.appendChild( this.textElement ); + this.textSpan.appendChild( this.anchor ); + } + + this.lineDiv.appendChild( this.icon ); + this.lineDiv.appendChild( this.textSpan ); + this.domEntry.appendChild( this.lineDiv ); + + this.lineDiv.owner = this; + + if (!hrefMode) + this.lineDiv.onclick = new Function("this.owner.processOnclick();"); +} diff -r 5e05c03d1558 -r 4c121c2aa844 doc/candydoc/util.js --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/doc/candydoc/util.js Sun Aug 10 17:09:41 2008 +0200 @@ -0,0 +1,41 @@ +/* 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 cross-browser utility functions. */ + +function getLeft(elem) +{ + var ret = 0; + while (elem.offsetParent) + { + ret += elem.offsetLeft; + elem = elem.offsetParent; + } + + return ret; +} + +function getTop(elem) +{ + var ret = 0; + while (elem.offsetParent) + { + ret += elem.offsetTop; + elem = elem.offsetParent; + } + + return ret; +} + +function getWindowHeight() +{ + var ret = 0; + if (typeof(window.innerHeight) == "number") + ret = window.innerHeight; + else if (document.documentElement && document.documentElement.clientHeight) + ret = document.documentElement.clientHeight; + else if (document.body && document.body.clientHeight) + ret = document.body.clientHeight; + + return ret; +}