discourse-legacysite-perl/site/slowtwitch.com/cgi-bin/articles/admin/templates/browser/browser.html
2024-06-17 21:49:12 +10:00

1235 lines
34 KiB
HTML

<html>
<head>
<script language="Javascript">
tree = null;
ready = false;
/***************************************************************************************
* Javascript global variables *
**************************************************************************************/
var NODE_EXPAND_BUTTON_FAKE = "<%Links::Browser::JFunction::node_expand_button_fake()%>";
var NODE_EXPAND_BUTTON_PLUS = "<%Links::Browser::JFunction::node_expand_button_plus()%>";
var NODE_EXPAND_BUTTON_LESS = "<%Links::Browser::JFunction::node_expand_button_less()%>";
var NODE_UNSELECTED_BUTTON = "<%Links::Browser::JFunction::node_unselected_button()%>";
var MAX_LOAD_FULL = <%max_load_full%>;
var TOTAL_CATEGORIES = <%total_categories%>;
LEFT_FRAME_ID = 0;
RIGHT_FRAME_ID = 1;
CODE_FRAME_ID = 2;
CAN_UPDATE = 0;
/***************************************************************************************
* Javascript UnloadedNode class *
**************************************************************************************/
/**
* An unloaded node is a node which could potentially
* be expanded but which information is not yet stored
* in the memory. When clicked, it has to perform a
* network access to upload the document state and re
* draw the tree.
*/
function UnloadedNode (id, fatherId, name, nbLinks)
{
this.setId (id);
this.setFatherId (fatherId);
this.setName (name);
this.setNumberOfLinks (nbLinks);
this.selected = false;
}
/**
* Sets the number of links for an Unloaded Node.
*/
function UnloadedNode_setNumberOfLinks (nbLinks)
{
this.numberOfLinks = nbLinks;
}
UnloadedNode.prototype.setNumberOfLinks = UnloadedNode_setNumberOfLinks;
/**
* Gets the number of links for an Unloaded Node.
*/
function UnloadedNode_getNumberOfLinks()
{
return this.numberOfLinks;
}
UnloadedNode.prototype.getNumberOfLinks = UnloadedNode_getNumberOfLinks;
/**
* This method should always return
* false because an UnloadedNode is
* never loaded !
*/
function UnloadedNode_isLoaded()
{
return false;
}
UnloadedNode.prototype.isLoaded = UnloadedNode_isLoaded;
/**
* This method tells if a node is
* the same as another according
* to it's ID number
*/
function UnloadedNode_equals (aNode)
{
return this.id == aNode.id;
}
UnloadedNode.prototype.equals = UnloadedNode_equals;
/**
* This method sets the ID of a
* node to the specified ID. Should
* normally be used only by the
* constructor
*/
function UnloadedNode_setId (id)
{
this.id = id;
}
UnloadedNode.prototype.setId = UnloadedNode_setId;
/**
* Returns the current node's ID.
*/
function UnloadedNode_getId()
{
return this.id;
}
UnloadedNode.prototype.getId = UnloadedNode_getId;
/**
* This method sets the fatherId of a
* node to the specified fatherId. Should
* normally be used only by the constructor.
*/
function UnloadedNode_setFatherId (fatherId)
{
this.fatherId = fatherId;
}
UnloadedNode.prototype.setFatherId = UnloadedNode_setFatherId;
/**
* returns the current node's fatherId.
*/
function UnloadedNode_getFatherId()
{
return this.fatherId;
}
UnloadedNode.prototype.getFatherId = UnloadedNode_getFatherId;
/**
* This method sets the name of the
* current node.
*/
function UnloadedNode_setName (name)
{
this.name = name;
}
UnloadedNode.prototype.setName = UnloadedNode_setName;
/**
* This method returns the name of the
* current node.
*/
function UnloadedNode_getName()
{
return this.name;
}
UnloadedNode.prototype.getName = UnloadedNode_getName;
/**
* Sets whether the node is expanded or not.
*/
function UnloadedNode_setExpanded (expanded)
{
alert ("Cannot set the expanded property on Unloaded nodes !");
}
UnloadedNode.prototype.setExpanded = UnloadedNode_setExpanded;
/**
* returns true if the node is expanded,
* false otherwise. An unloaded node can never
* be expanded because otherwise it would
* necessarily be loaded !
*/
function UnloadedNode_isExpanded()
{
return false;
}
UnloadedNode.prototype.isExpanded = UnloadedNode_isExpanded;
/**
* Sets whether the node is selected or not.
*/
function UnloadedNode_setSelected (selected)
{
this.selected = selected;
}
UnloadedNode.prototype.setSelected = UnloadedNode_setSelected;
/**
* returns true if the node is currently
* selected, false otherwise.
*/
function UnloadedNode_isSelected()
{
return this.selected;
}
UnloadedNode.prototype.isSelected = UnloadedNode_isSelected;
/**
* adds a child to this node. Does not
* currently lookup in the sub-tree to
* check if the node has been inserted.
*
* this function should never be called
* on an unloaded node !
*/
function UnloadedNode_addChild (aChild)
{
alert ("Software error : addChild should never be called on an Unloaded node!");
}
UnloadedNode.prototype.addChild = UnloadedNode_addChild;
/**
* removes a child from a node. Does
* not currently lookup in the sub-tree to
* check if the node to remove is there
* but only in the children array.
*
* this function should never be called
* on an unloaded node !
*/
function UnloadedNode_delChild (aChild)
{
alert ("Software error : addChild should never be called on an Unloaded node!");
}
UnloadedNode.prototype.delChild = UnloadedNode_delChild;
/**
* Returns the array of current node's children.
*
* this function should never be called
* on an unloaded node !
*/
function UnloadedNode_getChildArray()
{
alert ("Software error : getChildArray should never be called on an Unloaded node!");
}
UnloadedNode.prototype.getChildArray = UnloadedNode_getChildArray;
/**
* Returns true if the node is a leaf,
* false otherwise. An unloaded node
* shall never be a leaf !
*/
function UnloadedNode_isLeaf()
{
return false;
}
UnloadedNode.prototype.isLeaf = UnloadedNode_isLeaf;
/**
* Lookup for a node the id of which is
* id in the current subtree. If the node
* is found, returns it, otherwise returns
* null.
*
* An unloaded node knows itself only,
* therefore we do not search the
* subtree.
*/
function UnloadedNode_lookup (id)
{
if (this.id == id) return this;
else return null;
}
UnloadedNode.prototype.lookup = UnloadedNode_lookup;
/**
* Returns an HTML representation of this node.
*/
function UnloadedNode_toHtml()
{
return '<a name="' + this.getId() + '"></a>' +
this.expandButtonHtml() +
this.folderHtml() +
"&nbsp; " +
this.name +
" (" +
this.getNumberOfLinks() +
")</p>\n";
}
UnloadedNode.prototype.toHtml = UnloadedNode_toHtml;
/**
* Returns HTML code that represents the
* button which is being clicked to expand
* or unexpand a node.
*/
function UnloadedNode_expandButtonHtml()
{
var node_id = this.getId();
if (this.isLeaf())
{
alert ("Software error: An Unloaded Node can never be a Leaf !");
}
else
{
if (this.isExpanded())
{
alert ("Software error: An Unloaded Node can never be expanded !");
}
else
{
return '<a href="#" onClick="return parent.clickEvent(' +
"'" + 'UnloadedNode' + "', " +
"'" + 'expand' + "', " +
node_id +
')"><img src="' +
NODE_EXPAND_BUTTON_PLUS +
'" border=0></a>';
}
}
}
UnloadedNode.prototype.expandButtonHtml = UnloadedNode_expandButtonHtml;
/**
* Returns HTML code that represents the
* folder which is being clicked to be selected.
*/
function UnloadedNode_folderHtml()
{
var node_id = this.getId();
return '<a name="' + node_id + '" href="#" onClick="return parent.clickEvent(' +
"'" + 'UnloadedNode' + "', " +
"'" + 'select' + "', " +
node_id +
')"><img src="' +
NODE_UNSELECTED_BUTTON +
'" border=0></a>';
}
UnloadedNode.prototype.folderHtml = UnloadedNode_folderHtml;
/***************************************************************************************
* Javascript LoadedNode class *
**************************************************************************************/
/**
* A loaded node is a node which has been
* already loaded in memory, i.e. a node which
* knows its children (even if it has no children)
*/
function LoadedNode (id, fatherId, name, nbLinks)
{
this.setId (id);
this.setFatherId (fatherId);
this.setName (name);
if (nbLinks == null) this.setNumberOfLinks ("");
else this.setNumberOfLinks (nbLinks);
this.expanded = false;
this.child = new Array();
}
/**
* Sets the number of links for an Unloaded Node.
*/
function LoadedNode_setNumberOfLinks (nbLinks)
{
this.numberOfLinks = nbLinks;
}
LoadedNode.prototype.setNumberOfLinks = LoadedNode_setNumberOfLinks;
/**
* Gets the number of links for an Unloaded Node.
*/
function LoadedNode_getNumberOfLinks()
{
return this.numberOfLinks;
}
LoadedNode.prototype.getNumberOfLinks = LoadedNode_getNumberOfLinks;
/**
* This method should always return
* true because a LoadedNode is always
* loaded !
*/
function LoadedNode_isLoaded()
{
return true;
}
LoadedNode.prototype.isLoaded = LoadedNode_isLoaded;
/**
* This method tells if a node is
* the same as another according
* to it's ID number.
*/
function LoadedNode_equals (aNode)
{
return this.id == aNode.id;
}
LoadedNode.prototype.equals = LoadedNode_equals;
/**
* This method sets the ID of a
* node to the specified ID. Should
* normally be used only by the
* constructor.
*/
function LoadedNode_setId (id)
{
this.id = id;
}
LoadedNode.prototype.setId = LoadedNode_setId;
/**
* returns the current node's ID.
*/
function LoadedNode_getId()
{
return this.id;
}
LoadedNode.prototype.getId = LoadedNode_getId;
/**
* This method sets the fatherId of a
* node to the specified fatherId. Should
* normally be used only by the constructor.
*/
function LoadedNode_setFatherId (fatherId)
{
this.fatherId = fatherId;
}
LoadedNode.prototype.setFatherId = LoadedNode_setFatherId;
/**
* returns the current node's fatherId.
*/
function LoadedNode_getFatherId()
{
return this.fatherId;
}
LoadedNode.prototype.getFatherId = LoadedNode_getFatherId;
/**
* this method sets the name of the
* current node.
*/
function LoadedNode_setName (name)
{
this.name = name;
}
LoadedNode.prototype.setName = LoadedNode_setName;
/**
* this method returns the name of the
* current node.
*/
function LoadedNode_getName()
{
return this.name;
}
LoadedNode.prototype.getName = LoadedNode_getName;
/**
* Sets whether the node is expanded or not.
*/
function LoadedNode_setExpanded (expanded)
{
this.expanded = expanded;
}
LoadedNode.prototype.setExpanded = LoadedNode_setExpanded;
/**
* returns true if the node is expanded,
* false otherwise.
*/
function LoadedNode_isExpanded()
{
return this.expanded;
}
LoadedNode.prototype.isExpanded = LoadedNode_isExpanded;
/**
* Sets whether the node is selected or not.
*/
function LoadedNode_setSelected (selected)
{
this.selected = selected;
}
LoadedNode.prototype.setSelected = LoadedNode_setSelected;
/**
* returns true if the node is currently
* selected, false otherwise.
*/
function LoadedNode_isSelected()
{
return this.selected;
}
LoadedNode.prototype.isSelected = LoadedNode_isSelected;
/**
* adds a child to this node. Does not
* currently lookup in the sub-tree to
* check if the node has been inserted.
*/
function LoadedNode_addChild (aChild)
{
for (var i=0; i<this.child.length; i++)
{
if (this.child[i].equals (aChild)) return;
}
for (var i=this.child.length; i>0; i--)
{
if (this.child[i-1].getName().toUpperCase() < aChild.getName().toUpperCase())
{
this.child[i] = aChild;
return;
}
else
{
this.child[i] = this.child[i-1];
}
}
this.child[0] = aChild;
}
LoadedNode.prototype.addChild = LoadedNode_addChild;
/**
* removes a child from a node. Does
* not currently lookup in the sub-tree to
* check if the node to remove is there
* but only in the children array.
*/
function LoadedNode_delChild (aChild)
{
var newChildArray = new Array();
for (var i=0; i<this.child.length; i++)
{
if (this.child[i].equals (aChild))
{
;
}
else
{
newChildArray[newChildArray.length] = this.child[i];
}
}
this.child = newChildArray;
}
LoadedNode.prototype.delChild = LoadedNode_delChild;
/**
* Returns the array of current node's children.
*/
function LoadedNode_getChildArray()
{
return this.child;
}
LoadedNode.prototype.getChildArray = LoadedNode_getChildArray;
/**
* Returns true if the node is a leaf,
* false otherwise.
*/
function LoadedNode_isLeaf()
{
return this.child.length == 0;
}
LoadedNode.prototype.isLeaf = LoadedNode_isLeaf;
/**
* Lookup for a node the id of which is
* id in the current subtree. If the node
* is found, returns it, otherwise returns
* null.
*/
function LoadedNode_lookup (id)
{
if (this.id == id) return this;
else
{
for (var i=0; i<this.child.length; i++)
{
var lookup = this.child[i].lookup(id);
if (lookup != null) return lookup;
}
}
return null;
}
LoadedNode.prototype.lookup = LoadedNode_lookup;
/**
* Returns an HTML representation of this node.
*/
function LoadedNode_toHtml()
{
if (this.getId() == 0) {
return this.expandButtonHtml() +
this.folderHtml() +
"&nbsp; " +
this.name +
"</p>\n";
}
else {
return '<a name="' + this.getId() + '"></a>' +
this.expandButtonHtml() +
this.folderHtml() +
"&nbsp; " +
this.name +
" (" +
this.getNumberOfLinks() +
")</p>\n";
}
}
LoadedNode.prototype.toHtml = LoadedNode_toHtml;
/**
* Returns HTML code that represents the
* button which is being clicked to expand
* or unexpand a node.
*/
function LoadedNode_expandButtonHtml()
{
var node_id = this.getId();
if (this.isLeaf())
{
return '<img src="' + NODE_EXPAND_BUTTON_FAKE + '" border=0></img>';
}
else
{
if (this.isExpanded())
{
return '<a href="#" onClick="return parent.clickEvent(' +
"'" + 'LoadedNode' + "', " +
"'" + 'unexpand' + "', " +
node_id +
')"><img src="' +
NODE_EXPAND_BUTTON_LESS +
'" border=0></a>';
}
else
{
return '<a href="#" onClick="return parent.clickEvent(' +
"'" + 'LoadedNode' + "', " +
"'" + 'expand' + "', " +
node_id +
')"><img src="' +
NODE_EXPAND_BUTTON_PLUS +
'" border=0></a>';
}
}
}
LoadedNode.prototype.expandButtonHtml = LoadedNode_expandButtonHtml;
/**
* Returns HTML code that represents the
* folder which is being clicked to be selected.
*/
function LoadedNode_folderHtml()
{
var node_id = this.getId();
if (<%is_rooted%> && (node_id == 0)) {
return '<img src="' +
NODE_UNSELECTED_BUTTON +
'" border=0>';
}
else {
return '<a name="' + node_id + '" href="#" onClick="return parent.clickEvent(' +
"'" + 'LoadedNode' + "', " +
"'" + 'select' + "', " +
node_id +
')"><img src="' +
NODE_UNSELECTED_BUTTON +
'" border=0></a>';
}
}
LoadedNode.prototype.folderHtml = LoadedNode_folderHtml;
/***************************************************************************************
* Javascript Tree class *
**************************************************************************************/
/**
* Builds a new Tree object
*/
function Tree()
{
this.nodes = new Array();
this.nodes[<%id%>] = new LoadedNode (<%id%>, <%fatherid%>, "<%name%>", <%nb_links%>);
this.selectedNodeId = null;
this.foo = this;
}
/**
* This method unselects all the nodes. Added to
* see if it can fix the netscape 4 / linux selection
* "Feature".
*/
function Tree_unselect()
{
for (var i=0; i < this.nodes.length; i++)
{
var node = this.nodes[i];
if (node != null)
{
node.setSelected (false);
}
}
}
Tree.prototype.unselect = Tree_unselect;
/**
* Searches the tree for a node the
* id of which would be aNodeId, null
* if this node does not exist in the
* tree.
*/
function Tree_lookup (aNodeId)
{
return this.nodes[aNodeId];
}
Tree.prototype.lookup = Tree_lookup;
/**
* This function takes as input a node id
* and a boolean and sets the node machine
* the given node id 'expanded' property.
*/
function Tree_setExpandedNodeId (aNodeId, expanded)
{
var node = this.lookup (aNodeId);
if (node != null) node.setExpanded (expanded);
}
Tree.prototype.setExpandedNodeId = Tree_setExpandedNodeId;
/**
* This function returns the currently
* selected node, if it exists.
*/
function Tree_getSelectedNodeId()
{
return this.selectedNodeId;
}
Tree.prototype.getSelectedNodeId = Tree_getSelectedNodeId;
/**
* This function changes the currently
* selected node.
*/
function Tree_setSelectedNodeId (aNodeId)
{
var selectedNode = this.lookup (this.getSelectedNodeId());
var nodeToSelect = this.lookup (aNodeId);
if (nodeToSelect == null) return;
else
{
if (selectedNode == null)
{
/* if the selected node is null,
then we do nothing with it. */
}
else
{
/* else, we deselect it. */
selectedNode.setSelected (false);
}
/* then we select the new node */
nodeToSelect.setSelected (true);
}
}
Tree.prototype.setSelectedNodeId = Tree_setSelectedNodeId;
/**
* Adds a node to the tree.
*/
function Tree_addNode (aNode)
{
var fathernode = this.lookup (aNode.getFatherId());
if (fathernode == null)
{
alert ("Software error: Cannot add node " +
aNode.getName() +
" because node with id " +
aNode.getFatherId() +
" does not exist.");
return;
}
this.delNode (aNode);
if (fathernode.isLoaded())
{
fathernode.addChild (aNode);
this.nodes[aNode.getId()] = aNode;
}
else
{
fathernode = new LoadedNode (fathernode.getId(),
fathernode.getFatherId(),
fathernode.getName(),
fathernode.getNumberOfLinks());
this.addNode (fathernode);
this.addNode (aNode);
}
}
Tree.prototype.addNode = Tree_addNode;
/**
* deletes a node from the tree.
*/
function Tree_delNode (aNode)
{
var node = this.lookup (aNode.getId());
var fathernode = this.lookup (aNode.getFatherId());
if (node == null || fathernode == null) return;
else
{
(this.lookup (node.getFatherId())).delChild (node);
this.nodes[node.getId()] = null;
}
}
Tree.prototype.delNode = Tree_delNode;
/**
* Returns an HTML representation of the Tree.
*/
function Tree_toHtml()
{
return '<html><head>\n' +
'<body bgcolor="#FFFFFF">' +
'<p><font face="Tahoma,Arial,Helvetica" size="2"><%if not is_admin%><b>Editor:</b><br><%Name%> (<%owner_links%>)<br><br><%endif%><b>Category Browser:</b><br>' +
this.toHtml_nodeLevel (<%id%>, 0) +
'</font></p></body></html>';
}
Tree.prototype.toHtml = Tree_toHtml;
function Tree_toHtml_nodeLevel (nodeid, level)
{
var node = this.lookup (nodeid);
result = '<p style="margin-top:5;margin-bottom:5"><nobr>';
if (node == null) ;
else
{
var width = 10 * level;
var leftspace = '<img src="' + NODE_EXPAND_BUTTON_FAKE + '" width="' + width + '" height=1 border=0>';
result += leftspace + node.toHtml() + "\n";
if (node.isExpanded())
{
level++;
var childArray = node.getChildArray();
for (var i=0; i<childArray.length; i++)
{
result += this.toHtml_nodeLevel (childArray[i].getId(), level);
}
}
}
return result;
}
Tree.prototype.toHtml_nodeLevel = Tree_toHtml_nodeLevel;
/**************************************************************************************
* Javascript main control subroutines *
**************************************************************************************/
function refresh_tree_empty()
{
frames[CODE_FRAME_ID].location.replace ("<%Links::Browser::JFunction::tree_reload_empty()%>&anticache=" + anticache());
return false;
}
function refresh_tree_full()
{
frames[CODE_FRAME_ID].location.replace ("<%Links::Browser::JFunction::tree_reload_full()%>&anticache=" + anticache());
return false;
}
/**
* This function is triggered when the user adds a node
* in order to update the tree if necessary.
*/
function user_add_node (id)
{
var node_to_refresh = tree.lookup (id);
if (node_to_refresh.isLoaded())
{
frames[CODE_FRAME_ID].location.replace ("<%Links::Browser::JFunction::user_add_node()%>&category_id=" +
"&anticache=" + anticache());
}
else
{
/*
* if the node is not loaded, then we need not do anything
* because it will be updated whenever the user expands it.
*/
;
}
}
/**
* This function redraws the javascript tree.
*/
function draw_tree()
{
if (tree != null)
{
frames[LEFT_FRAME_ID].document.open();
frames[LEFT_FRAME_ID].document.writeln (tree.toHtml());
frames[LEFT_FRAME_ID].document.close();
}
}
/**
* This method loads the information which is related to node
* with id id into the tree structure.
*/
function tree_loadnode (id)
{
frames[CODE_FRAME_ID].location.replace ("<%Links::Browser::JFunction::tree_loadnode()%>&category_id=" + id +
"&anticache=" + anticache());
}
/**
* A cool comment goes here
*/
function list_links (id)
{
/* frames[RIGHT_FRAME_ID].location */
}
/**
* Triggered when the user selects a node.
*/
function select_node (id)
{
tree.setSelectedNodeId (id);
frames[RIGHT_FRAME_ID].location.replace ("<%Links::Browser::JFunction::tree_selectnode()%>&category_id=" + id +
"&anticache=" + anticache());
draw_tree();
set_location (id);
}
/**
* This function is triggered whenever an user wants to move
* node with id from to node with id to.
*/
function move_node (from, to)
{
frames[LEFT_FRAME_ID].document.body.innerHTML = '<H2><BLINK>Querying database...</BLINK></H2>';
frames[RIGHT_FRAME_ID].location.replace ("<%Links::Browser::JFunction::tree_movenode()%>&category_from=" + from +
"&category_to=" + to + "&anticache=" + anticache());
}
/**
* this function is moves a link from a category to
* another category which is clicked by the user.
*/
function link_move (linkid, oldcategoryid, newcategoryid)
{
frames[RIGHT_FRAME_ID].location.replace ("<%Links::Browser::JFunction::movelink()%>&old_category_id=" + oldcategoryid +
"&new_category_id=" + newcategoryid +
"&link_id=" + linkid + "&anticache=" + anticache());
}
/**
* this function is copies a link from a category to
* another category which is clicked by the user.
*/
function link_copy (linkid, oldcategoryid, newcategoryid)
{
frames[RIGHT_FRAME_ID].location.replace ("<%Links::Browser::JFunction::copylink()%>&old_category_id=" + oldcategoryid +
"&new_category_id=" + newcategoryid +
"&link_id=" + linkid + "&anticache=" + anticache());
}
/**
* clickEvent function. This is the main function, it
* is supposed to trigger the right functions according
* to the user actions and the state of the program.
*/
function clickEvent (classname, action, id)
{
if (ready == null || !ready) return false;
if (classname == "LoadedNode")
{
var node = tree.lookup (id);
if (action == "expand")
{
node.setExpanded (true);
draw_tree();
set_location (id);
}
else if (action == "unexpand")
{
node.setExpanded (false);
draw_tree();
set_location (id);
}
else if (action == "select")
{
/*
* Can't click on root node if base is set.
*/
if (<%is_rooted%> && (id == 0)) {
return false;
}
/*
* We test if the right frame is a move frame. If so, when
* user clicks on a node then we must trigger a move action,
* otherwise it is a normal select action.
*/
if (frames[RIGHT_FRAME_ID].move_from && typeof(frames[RIGHT_FRAME_ID].move_from) != "function")
{
CAN_UPDATE = 1;
move_node (frames[RIGHT_FRAME_ID].move_from, id);
}
else if (frames[RIGHT_FRAME_ID].link_move && typeof(frames[RIGHT_FRAME_ID].link_move) != "function")
{
CAN_UPDATE = 1;
link_move (frames[RIGHT_FRAME_ID].link_move, frames[RIGHT_FRAME_ID].old_category_id, id)
}
else if (frames[RIGHT_FRAME_ID].link_copy && typeof(frames[RIGHT_FRAME_ID].link_copy) != "function")
{
CAN_UPDATE = 1;
link_copy (frames[RIGHT_FRAME_ID].link_copy, frames[RIGHT_FRAME_ID].old_category_id, id)
}
else if (frames[RIGHT_FRAME_ID].related_to && typeof(frames[RIGHT_FRAME_ID].related_to) != "function")
{
frames[RIGHT_FRAME_ID].document.related_form.related_to.value = id;
frames[RIGHT_FRAME_ID].document.related_form.category_id.value = frames[RIGHT_FRAME_ID].related_to;
frames[RIGHT_FRAME_ID].document.related_form.submit();
}
else
{
select_node (id);
}
}
else
{
alert ("Software error: '" + action + "' is not a valid action");
}
}
else if (classname == "UnloadedNode")
{
if (action == "expand")
{
frames[LEFT_FRAME_ID].document.body.innerHTML = '<H2><BLINK>Querying database...</BLINK></H2>';
tree_loadnode (id);
return false;
}
else if (action == "unexpand")
{
alert ("Software error: unexpand should never happen on an UnloadedNode !");
}
else if (action == "select")
{
/*
* We test if the right frame is a move frame. If so, when
* user clicks on a node then we must trigger a move action,
* otherwise it is a normal select action.
*/
if (frames[RIGHT_FRAME_ID].move_from && typeof(frames[RIGHT_FRAME_ID].move_from) != "function")
{
CAN_UPDATE = 1;
move_node (frames[RIGHT_FRAME_ID].move_from, id);
}
else if (frames[RIGHT_FRAME_ID].link_move && typeof(frames[RIGHT_FRAME_ID].link_move) != "function")
{
CAN_UPDATE = 1;
link_move (frames[RIGHT_FRAME_ID].link_move, frames[RIGHT_FRAME_ID].old_category_id, id)
}
else if (frames[RIGHT_FRAME_ID].link_copy && typeof(frames[RIGHT_FRAME_ID].link_copy) != "function")
{
CAN_UPDATE = 1;
link_copy (frames[RIGHT_FRAME_ID].link_copy, frames[RIGHT_FRAME_ID].old_category_id, id)
}
else if (frames[RIGHT_FRAME_ID].related_to && typeof(frames[RIGHT_FRAME_ID].related_to) != "function")
{
frames[RIGHT_FRAME_ID].document.related_form.related_to.value = id;
frames[RIGHT_FRAME_ID].document.related_form.category_id.value = frames[RIGHT_FRAME_ID].related_to;
frames[RIGHT_FRAME_ID].document.related_form.submit();
}
else
{
select_node (id);
}
}
else
{
alert ("Software error: '" + action + "' is not a valid action");
}
}
return false;
}
/**
* This function returns a 10 bytes long random string
* in order to cheat the navigator's cache.
*/
function anticache()
{
var elements = [ 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' ];
var result = "";
for (var i=0; i<10; i++) result += elements[Math.round((elements.length - 1) * Math.random())];
return result;
}
/**
* This function is triggered when the whole frameset is loaded.
*/
function frameset_onLoad()
{
tree = new Tree();
frames[LEFT_FRAME_ID].location = "about:blank";
frames[RIGHT_FRAME_ID].location = "about:blank";
frames[CODE_FRAME_ID].location = "about:blank";
setTimeout('frames[LEFT_FRAME_ID].location = "<%Links::Browser::JFunction::tree_panel_url%>&anticache=" + anticache();', 100);
setTimeout('frames[RIGHT_FRAME_ID].location = "<%Links::Browser::JFunction::info_panel_url%>&anticache=" + anticache();', 100);
setTimeout('frames[CODE_FRAME_ID].location = "<%Links::Browser::JFunction::code_panel_url%>&anticache=" + anticache();', 100);
ready = true;
}
/**
* Set the location, this prevents the tree from redrawing and positioning
* up at the top again. Only works in IE 5.5, but Netscape behave nicely.
*/
function set_location (node_id) {
if (document.all) {
if (isIE()) {
frames[LEFT_FRAME_ID].location.hash = node_id;
}
}
}
function isIE() {
var ver = window.navigator.appVersion;
var pos = ver.search('MSIE ');
var ie = false;
if ( pos == -1 ) {
return ie;
}
if ( ver.substr(pos + 5, 1) > 5 ) {
ie = true;
}
else if ( ver.substr(pos + 5, 1) == 5 ) {
var v = ver.substr(pos + 7, 1);
if ( !isNaN(v) && v >= 5 ) {
ie = true;
}
}
return ie;
}
/***************************************************************************************
* Javascript and HTML startup *
**************************************************************************************/
</script>
<title>Gossamer Links</title>
</head>
<script language="Javascript">
document.writeln (
'<FRAMESET COLS="25%,74%,1" FRAMEBORDER="0" onLoad="frameset_onLoad()">' +
'<FRAME NAME="left" scrolling="auto" src="about:blank"></FRAME>' +
'<FRAME NAME="right" scrolling="auto" src="about:blank"></FRAME>' +
'<FRAME NAME="code" scrolling="no" src="about:blank"></FRAME>' +
'</FRAMESET>' );
</script>
<NOSCRIPT>
<BODY BGCOLOR="#FFFFFF"><CENTER><H1>
You will need to have JavaScript enabled in order to use the Category Browser.
</H1></CENTER></BODY>
</NOSCRIPT>
</HTML>