/***************************************************************** DynamicTopicTree is a class to support dynamic rendering of topic trees, with drag-n-drop reparenting. ******************************************************************/ /** Flag indicating that the user might be dragging a node. */ var DttMayBeDragging = 0; var DttObject = 0; /** Constructor @param hierDivId (String) : (required) container DIV for the topic tree */ DynamicTopicTree = function (viewPath, webName, hierDivId) { /** Save the dynamic topic tree object. This global is used by the topic mouseover/out handlers. @global */ DttObject = this; /** CGI Path of topic view URL (i.e. %SCRIPTURL%/view%SCRIPTSUFFIX%) @privileged */ this._dttViewPath = viewPath; this._dttWeb = webName; /** Name of the DIV that will contain the topic tree. @privileged */ this._hierDivId = hierDivId; /** Store for topic information (indexed by topic name). @example var ref = __request()._storage["hamlet"]; @privileged */ this._dttNodes = { }; /** Tree node id counter. @privileged */ this._dttNodeId = 10000; /** Add handlers to detect mouse down/up events. This helps us determine whether the user might be dragging an object. */ document.onmousedown = function() { DttMayBeDragging = 1; DttObject._dttMouseOutTopic(); }; document.onmouseup = function() { DttMayBeDragging = 0; }; /** Create the popup window that is used for displaying additional information about topics. */ this._initializePopup (); } /* DynamicTopicTree class */ DynamicTopicTree.prototype = { /** Create a complete topic tree. @param hierArray (Datastructure) : (required) array containing all topic information */ createTopicTree : function (hierArray) { /* create the WebHome node */ this._createNode("WebHome", 1, 1, 0, 1); for (var i = 0; i < hierArray.length; i += 1) { if (!hierArray[i]) { continue; } /* retrieve name/parent of i'th topic */ var c = hierArray[i].child; var p = hierArray[i].parent; /* "NO_PARENT is the default node for topics with undefined parents */ /* Also, for topics with themselves as parent! (yes, it can happen ... found out the hard way :-( */ if (!p || p == c) { p = "NO_PARENT"; this._createNode(p, 1, 1, 1, 0); } /* if necessary, create parent and current topic nodes */ if (!this._dttNodes[p]) { this._createNode(p, 1); } if (!this._dttNodes[c]) { this._createNode(c, 0); } var pNode = this._dttNodes[p][0]; var pUl = this._dttNodes[p][1]; /* The parent's UL can be missing, if 'p' was previously added to the tree as a child of another node */ if (!pUl) { pUl = document.createElement("ul"); pNode.appendChild(pUl); this._dttNodes[p][1] = pUl; } var cNode = this._dttNodes[c][0]; /* add current topic's LI to parent's UL */ pUl.appendChild(cNode); /* add the rest of the topic information as an attribute to the topic node's A element */ /* FIXME: Don't understand why this kludge is required. */ hierArray[i].summary = hierArray[i].summary.replace(/<nop>/gi,""); var aNode = cNode.getElementsByTagName("a")[0]; aNode.info = hierArray[i]; /* add mouseover and mouseout handlers */ aNode.onmouseover = this._dttMouseOverTopic; aNode.onmouseout = this._dttMouseOutTopic; /* if parent is in another web, then add it as a child of another special node: "OTHER_WEB" */ if (p.indexOf('.') != -1) { this._createNode("OTHER_WEB", 1, 1, 1, 0); ul = this._dttNodes["OTHER_WEB"][1]; ul.appendChild(pNode); pNode.noDrag = "true"; pNode.noChildren = "true"; } /* alert ('NODE: ' + c + ' PARENT: ' + p); */ } /* finally, add the top level nodes of the tree to the specified DIV */ var hierDiv = document.getElementById(this._hierDivId); hierDiv.appendChild(this._dttNodes["WebHome"][0]); if (this._dttNodes["NO_PARENT"]) { hierDiv.appendChild(this._dttNodes["NO_PARENT"][0]); } if (this._dttNodes["OTHER_WEB"]) { hierDiv.appendChild(this._dttNodes["OTHER_WEB"][0]); } } , /** Create a new topic tree node. @param topicName (String) : (required) topic name @param hasChildren (Boolean) : (optional) topic has children @param noDrag (Boolean) : (optional) tree node cannot be dragged @param noChildren (Boolean) : (optional) tree node cannot have children @param noSiblings (Boolean) : (optional) tree node cannot have siblings @privileged HTML generated: - The attributes on the LI element are optional. - The inner UL is generated only if hasChildren is defined.