- Hide admin for non-super users
- Easy change password for any user
- Enforceable minimum password length
+* Switched to PEAR's HTML_TreeMenu to avoid license issue
Version 3.0.0-dev-4
-------------------
* Insert and edit row aren't smart - eg. it will quote everything including
'current_timestamp' in a timestamp field. We need to detect if they're
inserting into a timestamp field with a magic value and then not quote it.
-* Insert needs the ability to use functions. It should also be able to handle
+* -Insert needs the ability to use functions. It should also be able to handle
some keywords (like DEFAULT) though it might be able to use function tech i
- to accomplish this.
+ to accomplish this. (chriskl)
* Preserve spaces when displaying user data (half done) (chriskl)
Views
------
* Support contrib/tsearch for easy full text indexes
+* Search for object feature
Principles
----------
* if you click on a database it shows a list of database objects in that
* database.
*
- * $Id: browser.php,v 1.7 2003/04/23 03:36:12 chriskl Exp $
+ * $Id: browser.php,v 1.8 2003/05/12 09:55:14 chriskl Exp $
*/
// Include application functions
include_once('libraries/lib.inc.php');
- // Include tree classes
- include_once('classes/class.tree/class.tree.php');
+ // Include tree classe
+ include_once('classes/HTML_TreeMenu/TreeMenu.php');
// Output header
- $misc->printHeader();
+ $misc->printHeader('', "<script src=\"classes/HTML_TreeMenu/TreeMenu.js\" type=\"text/javascript\"></script>");
$misc->printBody('browser');
-
+
// Construct expanding tree
- $tree = new Tree ('classes/class.tree');
- $tree->set_frame ('detail');
- $root = $tree->open_tree ('<a href=\"all_db.php\" target=\"detail\">'. htmlspecialchars($conf['servers'][$_SESSION['webdbServerID']]['desc']) .'</a>', '');
+ $menu = new HTML_TreeMenu();
+ $root = new HTML_TreeNode(array(
+ 'text' => addslashes(htmlspecialchars(($conf['servers'][$_SESSION['webdbServerID']]['desc']))),
+ 'link' => 'all_db.php',
+ 'icon' => 'folder.gif',
+ 'expandedIcon' => 'folder-expanded.gif',
+ 'expanded' => true,
+ 'linkTarget' => 'detail'));
+
+ // Add root node to menu
+ $menu->addItem($root);
+
+ /**
+ * Helper function for adding nodes
+ * @param $schemanode Node onto which to add
+ */
+ function addNodes(&$schemanode, $querystr) {
+ global $data, $localData, $lang, $conf;
+
+ // Tables
+ if ($data->hasTables()) {
+ $table_node = &new HTML_TreeNode(array(
+ 'text' => addslashes($lang['strtables']),
+ 'link' => addslashes(htmlspecialchars("tables.php?{$querystr}")),
+ 'icon' => "../../../images/themes/{$conf['theme']}/tables.gif",
+ 'expandedIcon' => "../../../images/themes/{$conf['theme']}/tables.gif",
+ 'expanded' => false,
+ 'linkTarget' => 'detail'));
+
+ // Add table folder to schema
+ $schemanode->addItem($table_node);
+
+ $tables = &$localData->getTables();
+ while (!$tables->EOF) {
+ $item_node = &new HTML_TreeNode(array(
+ 'text' => addslashes(htmlspecialchars($tables->f[$data->tbFields['tbname']])),
+ 'link' => addslashes(htmlspecialchars("tblproperties.php?{$querystr}&table=" .
+ urlencode($tables->f[$data->tbFields['tbname']]))),
+ 'icon' => "../../../images/themes/{$conf['theme']}/tables.gif",
+ 'expandedIcon' => "../../../images/themes/{$conf['theme']}/tables.gif",
+ 'expanded' => false,
+ 'linkTarget' => 'detail'));
+
+ // Add table folder to schema
+ $table_node->addItem($item_node);
+
+ $tables->moveNext();
+ }
+ }
+ // Views
+ if ($data->hasViews()) {
+ $view_node = &new HTML_TreeNode(array(
+ 'text' => addslashes($lang['strviews']),
+ 'link' => addslashes(htmlspecialchars("views.php?{$querystr}")),
+ 'icon' => "../../../images/themes/{$conf['theme']}/views.gif",
+ 'expandedIcon' => "../../../images/themes/{$conf['theme']}/views.gif",
+ 'expanded' => false,
+ 'linkTarget' => 'detail'));
+
+ // Add folder to schema
+ $schemanode->addItem($view_node);
+ }
+ // Sequences
+ if ($data->hasSequences()) {
+ $seq_node = &new HTML_TreeNode(array(
+ 'text' => addslashes($lang['strsequences']),
+ 'link' => addslashes(htmlspecialchars("sequences.php?{$querystr}")),
+ 'icon' => "../../../images/themes/{$conf['theme']}/sequences.gif",
+ 'expandedIcon' => "../../../images/themes/{$conf['theme']}/sequences.gif",
+ 'expanded' => false,
+ 'linkTarget' => 'detail'));
+
+ // Add folder to schema
+ $schemanode->addItem($seq_node);
+ }
+ // Functions
+ if ($data->hasFunctions()) {
+ $func_node = &new HTML_TreeNode(array(
+ 'text' => addslashes($lang['strfunctions']),
+ 'link' => addslashes(htmlspecialchars("functions.php?{$querystr}")),
+ 'icon' => "../../../images/themes/{$conf['theme']}/functions.gif",
+ 'expandedIcon' => "../../../images/themes/{$conf['theme']}/functions.gif",
+ 'expanded' => false,
+ 'linkTarget' => 'detail'));
+
+ // Add folder to schema
+ $schemanode->addItem($func_node);
+ }
+ // Types
+ if ($data->hasTypes()) {
+ $func_node = &new HTML_TreeNode(array(
+ 'text' => addslashes($lang['strtypes']),
+ 'link' => addslashes(htmlspecialchars("types.php?{$querystr}")),
+ 'icon' => "../../../images/themes/{$conf['theme']}/document.gif",
+ 'expandedIcon' => "../../../images/themes/{$conf['theme']}/document.gif",
+ 'expanded' => false,
+ 'linkTarget' => 'detail'));
+
+ // Add folder to schema
+ $schemanode->addItem($func_node);
+ }
+ }
$databases = &$data->getDatabases();
while (!$databases->EOF) {
// If database is selected, show folder, otherwise show document
if (isset($_REQUEST['database']) && $_REQUEST['database'] == $databases->f[$data->dbFields['dbname']]) {
- $node = $tree->add_folder($root, addslashes(htmlspecialchars($databases->f[$data->dbFields['dbname']])),
- 'database.php?database=' . urlencode($databases->f[$data->dbFields['dbname']]), 'detail');
-
+ $db_node = &new HTML_TreeNode(array(
+ 'text' => addslashes(htmlspecialchars($databases->f[$data->dbFields['dbname']])),
+ 'link' => addslashes(htmlspecialchars('database.php?database=' . urlencode($databases->f[$data->dbFields['dbname']]))),
+ 'icon' => "../../../images/themes/{$conf['theme']}/database.gif",
+ 'expandedIcon' => "../../../images/themes/{$conf['theme']}/database.gif",
+ 'expanded' => true,
+ 'linkTarget' => 'detail'));
+
+ // If database supports schemas, add the extra level of hierarchy
if ($data->hasSchemas()) {
$schemas = &$localData->getSchemas();
while (!$schemas->EOF) {
// Construct database & schema query string
$querystr = 'database=' . urlencode($databases->f[$data->dbFields['dbname']]). '&schema=' .
urlencode($schemas->f[$data->nspFields['nspname']]);
- $schemanode = $tree->add_folder($node, addslashes($schemas->f[$data->nspFields['nspname']]),
- "schema.php?{$querystr}", 'detail');
- if ($data->hasTables()) {
- $tables = &$localData->getTables();
- $table_node = $tree->add_folder($schemanode, $lang['strtables'],
- 'tables.php?database=' . urlencode($databases->f[$data->dbFields['dbname']]) . '&schema=' .
- urlencode($schemas->f[$data->nspFields['nspname']]), 'detail');
- while (!$tables->EOF) {
- $tree->add_document($table_node, addslashes($tables->f[$data->tbFields['tbname']]),
- 'tblproperties.php?database=' . urlencode($databases->f[$data->dbFields['dbname']]) . '&schema=' .
- urlencode($schemas->f[$data->nspFields['nspname']]) . '&table=' .
- urlencode($tables->f[$data->tbFields['tbname']]), 'detail', "../../images/themes/{$conf['theme']}/tables.gif");
- $tables->moveNext();
- }
- }
- if ($data->hasViews())
- $tree->add_document($schemanode, $lang['strviews'], "views.php?{$querystr}", 'detail', "../../images/themes/{$conf['theme']}/views.gif");
- if ($data->hasSequences())
- $tree->add_document($schemanode, $lang['strsequences'], "sequences.php?{$querystr}", 'detail', "../../images/themes/{$conf['theme']}/sequences.gif");
- if ($data->hasFunctions())
- $tree->add_document($schemanode, $lang['strfunctions'], "functions.php?{$querystr}", 'detail', "../../images/themes/{$conf['theme']}/functions.gif");
-// if ($data->hasOperators())
-// $tree->add_document($schemanode, $lang['stroperators'], "operators.php?{$querystr}", 'detail', "../../images/themes/{$conf['theme']}/operators.gif");
- if ($data->hasTypes())
- $tree->add_document($schemanode, $lang['strtypes'], "types.php?{$querystr}", 'detail');
-// if ($data->hasAggregates())
-// $tree->add_document($schemanode, $lang['straggregates'], 'aggregates.php{$querystr}", 'detail');
+ $schemanode = &new HTML_TreeNode(array(
+ 'text' => addslashes(htmlspecialchars($schemas->f[$data->nspFields['nspname']])),
+ 'link' => addslashes(htmlspecialchars("schema.php?{$querystr}")),
+ 'icon' => 'folder.gif',
+ 'expandedIcon' => 'folder-expanded.gif',
+ // Auto-expand your personal schema. @@ This currently also opens the first
+ // schema if your own schema doesn't exist...
+// 'expanded' => ($schemas->f[$data->nspFields['nspname']] == $_SESSION['webdbUsername']),
+ 'expanded' => false,
+ 'linkTarget' => 'detail'));
+
+ addNodes(&$schemanode, $querystr);
+
+ // Add schema to database
+ $db_node->addItem($schemanode);
+
$schemas->moveNext();
}
}
// Database doesn't support schemas
else {
- if ($data->hasTables()) {
- $tables = &$localData->getTables();
- $table_node = $tree->add_folder($node, $lang['strtables'],
- 'tables.php?database=' . urlencode($databases->f[$data->dbFields['dbname']]), 'detail');
- while (!$tables->EOF) {
- $tree->add_document($table_node, addslashes($tables->f[$data->tbFields['tbname']]),
- 'tblproperties.php?database=' . urlencode($databases->f[$data->dbFields['dbname']]) . '&table=' .
- urlencode($tables->f[$data->tbFields['tbname']]), 'detail', "../../images/themes/{$conf['theme']}/tables.gif");
- $tables->moveNext();
- }
- }
- if ($data->hasViews())
- $tree->add_document($node, $lang['strviews'], 'views.php?database=' . urlencode($databases->f[$data->dbFields['dbname']]), 'detail', "../../images/themes/{$conf['theme']}/views.gif");
- if ($data->hasSequences())
- $tree->add_document($node, $lang['strsequences'], 'sequences.php?database=' . urlencode($databases->f[$data->dbFields['dbname']]), 'detail', "../../images/themes/{$conf['theme']}/sequences.gif");
- if ($data->hasFunctions())
- $tree->add_document($node, $lang['strfunctions'], 'functions.php?database=' . urlencode($databases->f[$data->dbFields['dbname']]), 'detail', "../../images/themes/{$conf['theme']}/functions.gif");
-// if ($data->hasOperators())
-// $tree->add_document($node, $lang['stroperators'], 'operators.php?database=' . urlencode($databases->f[$data->dbFields['dbname']]), 'detail', "../../images/themes/{$conf['theme']}/operators.gif");
- if ($data->hasTypes())
- $tree->add_document($node, $lang['strtypes'], 'types.php?database=' . urlencode($databases->f[$data->dbFields['dbname']]), 'detail');
-// if ($data->hasAggregates())
-// $tree->add_document($node, $lang['straggregates'], 'aggregates.php?database=' . urlencode($databases->f[$data->dbFields['dbname']]), 'detail');
+ // Construct database query string
+ $querystr = 'database=' . urlencode($databases->f[$data->dbFields['dbname']]);
+
+ addNodes(&$db_node, $querystr);
}
- } else {
- $node = $tree->add_document($root, addslashes(htmlspecialchars($databases->f[$data->dbFields['dbname']])),
- "{$_SERVER['PHP_SELF']}?database=" . urlencode($databases->f[$data->dbFields['dbname']]), '_self', "../../images/themes/{$conf['theme']}/database.gif");
- }
+ // Add node to menu
+ $root->addItem($db_node);
+
+ } else {
+ $db_node = &new HTML_TreeNode(array(
+ 'text' => addslashes(htmlspecialchars($databases->f[$data->dbFields['dbname']])),
+ 'link' => addslashes(htmlspecialchars("{$_SERVER['PHP_SELF']}?database=" . urlencode($databases->f[$data->dbFields['dbname']]))),
+ 'icon' => "../../../images/themes/{$conf['theme']}/database.gif",
+ 'expandedIcon' => "../../../images/themes/{$conf['theme']}/database.gif",
+ 'expanded' => false,
+ 'linkTarget' => '_self'));
+
+ // Add node to menu
+ $root->addItem($db_node);
+ }
+
$databases->moveNext();
}
- $tree->close_tree ( );
+ // Create the presentation class
+ $treeMenu = &new HTML_TreeMenu_DHTML($menu, array('images' => 'classes/HTML_TreeMenu/images', 'defaultClass' => 'treeMenuDefault'));
+
+ // Actually display the menu
+ $treeMenu->printMenu();
// Output footer
$misc->printFooter();
--- /dev/null
+// +-----------------------------------------------------------------------+
+// | Copyright (c) 2002-2003, Richard Heyes, Harald Radi |
+// | All rights reserved. |
+// | |
+// | Redistribution and use in source and binary forms, with or without |
+// | modification, are permitted provided that the following conditions |
+// | are met: |
+// | |
+// | o Redistributions of source code must retain the above copyright |
+// | notice, this list of conditions and the following disclaimer. |
+// | o Redistributions in binary form must reproduce the above copyright |
+// | notice, this list of conditions and the following disclaimer in the |
+// | documentation and/or other materials provided with the distribution.|
+// | o The names of the authors may not be used to endorse or promote |
+// | products derived from this software without specific prior written |
+// | permission. |
+// | |
+// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+// | |
+// +-----------------------------------------------------------------------+
+// | Author: Richard Heyes <richard@phpguru.org> |
+// | Harald Radi <harald.radi@nme.at> |
+// +-----------------------------------------------------------------------+
+//
+// $Id: TreeMenu.js,v 1.1 2003/05/12 09:55:14 chriskl Exp $
+
+
+/**
+* TreeMenu class
+*/
+ function TreeMenu(iconpath, myname, linkTarget, defaultClass, usePersistence, noTopLevelImages)
+ {
+ // Properties
+ this.iconpath = iconpath;
+ this.myname = myname;
+ this.linkTarget = linkTarget;
+ this.defaultClass = defaultClass;
+ this.usePersistence = usePersistence;
+ this.noTopLevelImages = noTopLevelImages;
+ this.n = new Array();
+
+ this.nodeRefs = new Array();
+ this.branches = new Array();
+ this.branchStatus = new Array();
+ this.layerRelations = new Array();
+ this.childParents = new Array();
+ this.cookieStatuses = new Array();
+
+ this.preloadImages();
+ }
+
+/**
+* Adds a node to the tree
+*/
+ TreeMenu.prototype.addItem = function (newNode)
+ {
+ newIndex = this.n.length;
+ this.n[newIndex] = newNode;
+
+ return this.n[newIndex];
+ }
+
+/**
+* Preload images hack for Mozilla
+*/
+ TreeMenu.prototype.preloadImages = function ()
+ {
+ var plustop = new Image; plustop.src = this.iconpath + '/plustop.gif';
+ var plusbottom = new Image; plusbottom.src = this.iconpath + '/plusbottom.gif';
+ var plus = new Image; plus.src = this.iconpath + '/plus.gif';
+
+ var minustop = new Image; minustop.src = this.iconpath + '/minustop.gif';
+ var minusbottom = new Image; minusbottom.src = this.iconpath + '/minusbottom.gif';
+ var minus = new Image; minus.src = this.iconpath + '/minus.gif';
+
+ var branchtop = new Image; branchtop.src = this.iconpath + '/branchtop.gif';
+ var branchbottom = new Image; branchbottom.src = this.iconpath + '/branchbottom.gif';
+ var branch = new Image; branch.src = this.iconpath + '/branch.gif';
+
+ var linebottom = new Image; linebottom.src = this.iconpath + '/linebottom.gif';
+ var line = new Image; line.src = this.iconpath + '/line.gif';
+ }
+
+/**
+* Main function that draws the menu and assigns it
+* to the layer (or document.write()s it)
+*/
+ TreeMenu.prototype.drawMenu = function ()// OPTIONAL ARGS: nodes = [], level = [], prepend = '', expanded = false, visbility = 'inline', parentLayerID = null
+ {
+ /**
+ * Necessary variables
+ */
+ var output = '';
+ var modifier = '';
+ var layerID = '';
+ var parentLayerID = '';
+
+ /**
+ * Parse any optional arguments
+ */
+ var nodes = arguments[0] ? arguments[0] : this.n
+ var level = arguments[1] ? arguments[1] : [];
+ var prepend = arguments[2] ? arguments[2] : '';
+ var expanded = arguments[3] ? arguments[3] : false;
+ var visibility = arguments[4] ? arguments[4] : 'inline';
+ var parentLayerID = arguments[5] ? arguments[5] : null;
+
+ var currentlevel = level.length;
+
+ for (var i=0; i<nodes.length; i++) {
+
+ level[currentlevel] = i+1;
+ layerID = this.myname + '_' + 'node_' + this.implode('_', level);
+
+ /**
+ * Store this object in the nodeRefs array
+ */
+ this.nodeRefs[layerID] = nodes[i];
+
+ /**
+ * Store the child/parent relationship
+ */
+ this.childParents[layerID] = parentLayerID;
+
+ /**
+ * Gif modifier
+ */
+ if (i == 0 && parentLayerID == null) {
+ modifier = nodes.length > 1 ? "top" : 'single';
+ } else if(i == (nodes.length-1)) {
+ modifier = "bottom";
+ } else {
+ modifier = "";
+ }
+
+ /**
+ * Single root branch is always expanded
+ */
+ if (!this.doesMenu() || (parentLayerID == null && (nodes.length == 1 || this.noTopLevelImages))) {
+ expanded = true;
+
+ } else if (nodes[i].expanded) {
+ expanded = true;
+
+ } else {
+ expanded = false;
+ }
+
+ /**
+ * Make sure visibility is correct based on parent status
+ */
+ visibility = this.checkParentVisibility(layerID) ? visibility : 'none';
+
+ /**
+ * Setup branch status and build an indexed array
+ * of branch layer ids
+ */
+ if (nodes[i].n.length > 0) {
+ this.branchStatus[layerID] = expanded;
+ this.branches[this.branches.length] = layerID;
+ }
+
+ /**
+ * Setup toggle relationship
+ */
+ if (!this.layerRelations[parentLayerID]) {
+ this.layerRelations[parentLayerID] = new Array();
+ }
+ this.layerRelations[parentLayerID][this.layerRelations[parentLayerID].length] = layerID;
+
+ /**
+ * Branch images
+ */
+ var gifname = nodes[i].n.length && this.doesMenu() && nodes[i].isDynamic ? (expanded ? 'minus' : 'plus') : 'branch';
+ var iconimg = nodes[i].icon ? this.stringFormat('<img src="{0}/{1}" width="20" height="20" align="top" id="icon_{2}">', this.iconpath, nodes[i].icon, layerID) : '';
+
+ /**
+ * Add event handlers
+ */
+ var eventHandlers = "";
+ for (j in nodes[i].events) {
+ eventHandlers += this.stringFormat('{0}="{1}" ', j, nodes[i].events[j]);
+ }
+
+ /**
+ * Build the html to write to the document
+ * IMPORTANT:
+ * document.write()ing the string: '<div style="display:...' will screw up nn4.x
+ */
+ var layerTag = this.doesMenu() ? this.stringFormat('<div id="{0}" style="display: {1}" class="{2}">', layerID, visibility, (nodes[i].cssClass ? nodes[i].cssClass : this.defaultClass)) : this.stringFormat('<div class="{0}">', nodes[i].cssClass ? nodes[i].cssClass : this.defaultClass);
+ var onMDown = this.doesMenu() && nodes[i].n.length && nodes[i].isDynamic ? this.stringFormat('onmousedown="{0}.toggleBranch(\'{1}\', true)" style="cursor: pointer; cursor: hand"', this.myname, layerID) : '';
+ var imgTag = this.stringFormat('<img src="{0}/{1}{2}.gif" width="20" height="20" align="top" border="0" name="img_{3}" {4}>', this.iconpath, gifname, modifier, layerID, onMDown);
+ var linkTarget= nodes[i].linkTarget ? nodes[i].linkTarget : this.linkTarget;
+ var linkStart = nodes[i].link ? this.stringFormat('<a href="{0}" target="{1}">', nodes[i].link, linkTarget) : '';
+ var linkEnd = nodes[i].link ? '</a>' : '';
+
+ output = this.stringFormat('{0}<nobr>{1}{2}{3}{4}<span {5}>{6}</span>{7}</nobr><br></div>',
+ layerTag,
+ prepend,
+ parentLayerID == null && (nodes.length == 1 || this.noTopLevelImages) ? '' : imgTag,
+ iconimg,
+ linkStart,
+ eventHandlers,
+ nodes[i].title,
+ linkEnd);
+
+ /**
+ * Write out the HTML. Uses document.write for speed over layers and
+ * innerHTML. This however means no dynamic adding/removing nodes on
+ * the client side. This could be conditional I guess if dynamic
+ * adding/removing is required.
+ */
+ document.write(output + "\r\n");
+
+ /**
+ * Traverse sub nodes ?
+ */
+ if (nodes[i].n.length) {
+ /**
+ * Determine what to prepend. If there is only one root
+ * node then the prepend to pass to children is nothing.
+ * Otherwise it depends on where we are in the tree.
+ */
+ if (parentLayerID == null && (nodes.length == 1 || this.noTopLevelImages)) {
+ var newPrepend = '';
+
+ } else if (i < (nodes.length - 1)) {
+ var newPrepend = prepend + this.stringFormat('<img src="{0}/line.gif" width="20" height="20" align="top">', this.iconpath);
+
+ } else {
+ var newPrepend = prepend + this.stringFormat('<img src="{0}/linebottom.gif" width="20" height="20" align="top">', this.iconpath);
+ }
+
+ this.drawMenu(nodes[i].n,
+ level,
+ newPrepend,
+ nodes[i].expanded,
+ expanded ? 'inline' : 'none',
+ layerID);
+ }
+ }
+ }
+
+/**
+* Toggles a branches visible status. Called from resetBranches()
+* and also when a +/- graphic is clicked.
+*/
+ TreeMenu.prototype.toggleBranch = function (layerID, updateStatus) // OPTIONAL ARGS: fireEvents = true
+ {
+ var currentDisplay = this.getLayer(layerID).style.display;
+ var newDisplay = (this.branchStatus[layerID] && currentDisplay == 'inline') ? 'none' : 'inline';
+ var fireEvents = arguments[2] != null ? arguments[2] : true;
+
+ for (var i=0; i<this.layerRelations[layerID].length; i++) {
+
+ if (this.branchStatus[this.layerRelations[layerID][i]]) {
+ this.toggleBranch(this.layerRelations[layerID][i], false);
+ }
+
+ this.getLayer(this.layerRelations[layerID][i]).style.display = newDisplay;
+ }
+
+ if (updateStatus) {
+ this.branchStatus[layerID] = !this.branchStatus[layerID];
+
+ /**
+ * Persistence
+ */
+ if (this.doesPersistence() && !arguments[2] && this.usePersistence) {
+ this.setExpandedStatusForCookie(layerID, this.branchStatus[layerID]);
+ }
+
+ /**
+ * Fire custom events
+ */
+ if (fireEvents) {
+ nodeObject = this.nodeRefs[layerID];
+
+ if (nodeObject.ontoggle != null) {
+ eval(nodeObject.ontoggle);
+ }
+
+ if (newDisplay == 'none' && nodeObject.oncollapse != null) {
+ eval(nodeObject.oncollapse);
+ } else if (newDisplay == 'inline' && nodeObject.onexpand != null){
+ eval(nodeObject.onexpand);
+ }
+ }
+
+ // Swap image
+ this.swapImage(layerID);
+ }
+
+ // Swap icon
+ this.swapIcon(layerID);
+ }
+
+/**
+* Swaps the plus/minus branch images
+*/
+ TreeMenu.prototype.swapImage = function (layerID)
+ {
+ var imgSrc = document.images['img_' + layerID].src;
+
+ var re = /^(.*)(plus|minus)(bottom|top|single)?.gif$/
+ if (matches = imgSrc.match(re)) {
+
+ document.images['img_' + layerID].src = this.stringFormat('{0}{1}{2}{3}',
+ matches[1],
+ matches[2] == 'plus' ? 'minus' : 'plus',
+ matches[3] ? matches[3] : '',
+ '.gif');
+ }
+ }
+
+/**
+* Swaps the icon for the expanded icon if one
+* has been supplied.
+*/
+ TreeMenu.prototype.swapIcon = function (layerID)
+ {
+ if (document.images['icon_' + layerID]) {
+ var imgSrc = document.images['icon_' + layerID].src;
+
+ if (this.nodeRefs[layerID].icon && this.nodeRefs[layerID].expandedIcon) {
+ //alert(imgSrc.indexOf(this.nodeRefs[layerID].expandedIcon));
+ var newSrc = (imgSrc.indexOf(this.nodeRefs[layerID].expandedIcon) == -1 ? this.nodeRefs[layerID].expandedIcon : this.nodeRefs[layerID].icon);
+
+ document.images['icon_' + layerID].src = this.iconpath + '/' + newSrc;
+ }
+ }
+ }
+
+/**
+* Can the browser handle the dynamic menu?
+*/
+ TreeMenu.prototype.doesMenu = function ()
+ {
+ return (is_ie4up || is_nav6up || is_gecko || is_opera7);
+ }
+
+/**
+* Can the browser handle save the branch status
+*/
+ TreeMenu.prototype.doesPersistence = function ()
+ {
+ return (is_ie4up || is_gecko || is_nav6up || is_opera7);
+ }
+
+/**
+* Returns the appropriate layer accessor
+*/
+ TreeMenu.prototype.getLayer = function (layerID)
+ {
+ if (is_ie4) {
+ return document.all(layerID);
+
+ } else if (document.getElementById(layerID)) {
+ return document.getElementById(layerID);
+
+ } else if (document.all(layerID)) {
+ return document.all(layerID);
+ }
+ }
+
+/**
+* Save the status of the layer
+*/
+ TreeMenu.prototype.setExpandedStatusForCookie = function (layerID, expanded)
+ {
+ this.cookieStatuses[layerID] = expanded;
+ this.saveCookie();
+ }
+
+/**
+* Load the status of the layer
+*/
+ TreeMenu.prototype.getExpandedStatusFromCookie = function (layerID)
+ {
+ if (this.cookieStatuses[layerID]) {
+ return this.cookieStatuses[layerID];
+ }
+
+ return false;
+ }
+
+/**
+* Saves the cookie that holds which branches are expanded.
+* Only saves the details of the branches which are expanded.
+*/
+ TreeMenu.prototype.saveCookie = function ()
+ {
+ var cookieString = new Array();
+
+ for (var i in this.cookieStatuses) {
+ if (this.cookieStatuses[i] == true) {
+ cookieString[cookieString.length] = i;
+ }
+ }
+
+ document.cookie = 'TreeMenuBranchStatus=' + cookieString.join(':');
+ }
+
+/**
+* Reads cookie parses it for status info and
+* stores that info in the class member.
+*/
+ TreeMenu.prototype.loadCookie = function ()
+ {
+ var cookie = document.cookie.split('; ');
+
+ for (var i=0; i < cookie.length; i++) {
+ var crumb = cookie[i].split('=');
+ if ('TreeMenuBranchStatus' == crumb[0] && crumb[1]) {
+ var expandedBranches = crumb[1].split(':');
+ for (var j=0; j<expandedBranches.length; j++) {
+ this.cookieStatuses[expandedBranches[j]] = true;
+ }
+ }
+ }
+ }
+
+/**
+* Reset branch status
+*/
+ TreeMenu.prototype.resetBranches = function ()
+ {
+ if (!this.doesPersistence()) {
+ return false;
+ }
+
+ this.loadCookie();
+
+ for (var i=0; i<this.branches.length; i++) {
+ var status = this.getExpandedStatusFromCookie(this.branches[i]);
+ // Only update if it's supposed to be expanded and it's not already
+ if (status == true && this.branchStatus[this.branches[i]] != true) {
+ if (this.checkParentVisibility(this.branches[i])) {
+ this.toggleBranch(this.branches[i], true, false);
+ } else {
+ this.branchStatus[this.branches[i]] = true;
+ this.swapImage(this.branches[i]);
+ }
+ }
+ }
+ }
+
+/**
+* Checks whether a branch should be open
+* or not based on its parents' status
+*/
+ TreeMenu.prototype.checkParentVisibility = function (layerID)
+ {
+ if (this.in_array(this.childParents[layerID], this.branches)
+ && this.branchStatus[this.childParents[layerID]]
+ && this.checkParentVisibility(this.childParents[layerID]) ) {
+
+ return true;
+
+ } else if (this.childParents[layerID] == null) {
+ return true;
+ }
+
+ return false;
+ }
+
+/**
+* New C# style string formatter
+*/
+ TreeMenu.prototype.stringFormat = function (strInput)
+ {
+ var idx = 0;
+
+ for (var i=1; i<arguments.length; i++) {
+ while ((idx = strInput.indexOf('{' + (i - 1) + '}', idx)) != -1) {
+ strInput = strInput.substring(0, idx) + arguments[i] + strInput.substr(idx + 3);
+ }
+ }
+
+ return strInput;
+ }
+
+/**
+* Also much adored, the PHP implode() function
+*/
+ TreeMenu.prototype.implode = function (seperator, input)
+ {
+ var output = '';
+
+ for (var i=0; i<input.length; i++) {
+ if (i == 0) {
+ output += input[i];
+ } else {
+ output += seperator + input[i];
+ }
+ }
+
+ return output;
+ }
+
+/**
+* Aah, all the old favourites are coming out...
+*/
+ TreeMenu.prototype.in_array = function (item, arr)
+ {
+ for (var i=0; i<arr.length; i++) {
+ if (arr[i] == item) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+/**
+* TreeNode Class
+*/
+ function TreeNode(title, icon, link, expanded, isDynamic, cssClass, linkTarget, expandedIcon)
+ {
+ this.title = title;
+ this.icon = icon;
+ this.expandedIcon = expandedIcon;
+ this.link = link;
+ this.expanded = expanded;
+ this.isDynamic = isDynamic;
+ this.cssClass = cssClass;
+ this.linkTarget = linkTarget;
+ this.n = new Array();
+ this.events = new Array();
+ this.handlers = null;
+ this.oncollapse = null;
+ this.onexpand = null;
+ this.ontoggle = null;
+ }
+
+/**
+* Adds a node to an already existing node
+*/
+ TreeNode.prototype.addItem = function (newNode)
+ {
+ newIndex = this.n.length;
+ this.n[newIndex] = newNode;
+
+ return this.n[newIndex];
+ }
+
+/**
+* Sets an event for this particular node
+*/
+ TreeNode.prototype.setEvent = function (eventName, eventHandler)
+ {
+ switch (eventName.toLowerCase()) {
+ case 'onexpand':
+ this.onexpand = eventHandler;
+ break;
+
+ case 'oncollapse':
+ this.oncollapse = eventHandler;
+ break;
+
+ case 'ontoggle':
+ this.ontoggle = eventHandler;
+ break;
+
+ default:
+ this.events[eventName] = eventHandler;
+ }
+ }
+
+/**
+* That's the end of the tree classes. What follows is
+* the browser detection code.
+*/
+
+
+//<!--
+// Ultimate client-side JavaScript client sniff. Version 3.03
+// (C) Netscape Communications 1999-2001. Permission granted to reuse and distribute.
+// Revised 17 May 99 to add is_nav5up and is_ie5up (see below).
+// Revised 20 Dec 00 to add is_gecko and change is_nav5up to is_nav6up
+// also added support for IE5.5 Opera4&5 HotJava3 AOLTV
+// Revised 22 Feb 01 to correct Javascript Detection for IE 5.x, Opera 4,
+// correct Opera 5 detection
+// add support for winME and win2k
+// synch with browser-type-oo.js
+// Revised 26 Mar 01 to correct Opera detection
+// Revised 02 Oct 01 to add IE6 detection
+
+// Everything you always wanted to know about your JavaScript client
+// but were afraid to ask. Creates "is_" variables indicating:
+// (1) browser vendor:
+// is_nav, is_ie, is_opera, is_hotjava, is_webtv, is_TVNavigator, is_AOLTV
+// (2) browser version number:
+// is_major (integer indicating major version number: 2, 3, 4 ...)
+// is_minor (float indicating full version number: 2.02, 3.01, 4.04 ...)
+// (3) browser vendor AND major version number
+// is_nav2, is_nav3, is_nav4, is_nav4up, is_nav6, is_nav6up, is_gecko, is_ie3,
+// is_ie4, is_ie4up, is_ie5, is_ie5up, is_ie5_5, is_ie5_5up, is_ie6, is_ie6up, is_hotjava3, is_hotjava3up,
+// is_opera2, is_opera3, is_opera4, is_opera5, is_opera5up
+// (4) JavaScript version number:
+// is_js (float indicating full JavaScript version number: 1, 1.1, 1.2 ...)
+// (5) OS platform and version:
+// is_win, is_win16, is_win32, is_win31, is_win95, is_winnt, is_win98, is_winme, is_win2k
+// is_os2
+// is_mac, is_mac68k, is_macppc
+// is_unix
+// is_sun, is_sun4, is_sun5, is_suni86
+// is_irix, is_irix5, is_irix6
+// is_hpux, is_hpux9, is_hpux10
+// is_aix, is_aix1, is_aix2, is_aix3, is_aix4
+// is_linux, is_sco, is_unixware, is_mpras, is_reliant
+// is_dec, is_sinix, is_freebsd, is_bsd
+// is_vms
+//
+// See http://www.it97.de/JavaScript/JS_tutorial/bstat/navobj.html and
+// http://www.it97.de/JavaScript/JS_tutorial/bstat/Browseraol.html
+// for detailed lists of userAgent strings.
+//
+// Note: you don't want your Nav4 or IE4 code to "turn off" or
+// stop working when new versions of browsers are released, so
+// in conditional code forks, use is_ie5up ("IE 5.0 or greater")
+// is_opera5up ("Opera 5.0 or greater") instead of is_ie5 or is_opera5
+// to check version in code which you want to work on future
+// versions.
+
+/**
+* Severly curtailed all this as only certain elements
+* are required by TreeMenu, specifically:
+* o is_ie4up
+* o is_nav6up
+* o is_gecko
+*/
+
+ // convert all characters to lowercase to simplify testing
+ var agt=navigator.userAgent.toLowerCase();
+
+ // *** BROWSER VERSION ***
+ // Note: On IE5, these return 4, so use is_ie5up to detect IE5.
+ var is_major = parseInt(navigator.appVersion);
+ var is_minor = parseFloat(navigator.appVersion);
+
+ // Note: Opera and WebTV spoof Navigator. We do strict client detection.
+ // If you want to allow spoofing, take out the tests for opera and webtv.
+ var is_nav = ((agt.indexOf('mozilla')!=-1) && (agt.indexOf('spoofer')==-1)
+ && (agt.indexOf('compatible') == -1) && (agt.indexOf('opera')==-1)
+ && (agt.indexOf('webtv')==-1) && (agt.indexOf('hotjava')==-1));
+ var is_nav6up = (is_nav && (is_major >= 5));
+ var is_gecko = (agt.indexOf('gecko') != -1);
+
+
+ var is_ie = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
+ var is_ie4 = (is_ie && (is_major == 4) && (agt.indexOf("msie 4")!=-1) );
+ var is_ie4up = (is_ie && (is_major >= 4));
+
+ var is_opera = (agt.indexOf("opera") != -1);
+ var is_opera7 = is_opera && (agt.indexOf("opera 7") != -1);
+//--> end hide JavaScript
--- /dev/null
+<?php
+// +-----------------------------------------------------------------------+
+// | Copyright (c) 2002-2003, Richard Heyes, Harald Radi |
+// | All rights reserved. |
+// | |
+// | Redistribution and use in source and binary forms, with or without |
+// | modification, are permitted provided that the following conditions |
+// | are met: |
+// | |
+// | o Redistributions of source code must retain the above copyright |
+// | notice, this list of conditions and the following disclaimer. |
+// | o Redistributions in binary form must reproduce the above copyright |
+// | notice, this list of conditions and the following disclaimer in the |
+// | documentation and/or other materials provided with the distribution.|
+// | o The names of the authors may not be used to endorse or promote |
+// | products derived from this software without specific prior written |
+// | permission. |
+// | |
+// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
+// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
+// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
+// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
+// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
+// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
+// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
+// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
+// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
+// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
+// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
+// | |
+// +-----------------------------------------------------------------------+
+// | Author: Richard Heyes <richard@phpguru.org> |
+// | Harald Radi <harald.radi@nme.at> |
+// +-----------------------------------------------------------------------+
+//
+// $Id: TreeMenu.php,v 1.1 2003/05/12 09:55:14 chriskl Exp $
+
+/**
+* HTML_TreeMenu Class
+*
+* A simple couple of PHP classes and some not so simple
+* Jabbascript which produces a tree menu. In IE this menu
+* is dynamic, with branches being collapsable. In IE5+ the
+* status of the collapsed/open branches persists across page
+* refreshes.In any other browser the tree is static. Code is
+* based on work of Harald Radi.
+*
+* Usage.
+*
+* After installing the package, copy the example php script to
+* your servers document root. Also place the TreeMenu.js and the
+* images folder in the same place. Running the script should
+* then produce the tree.
+*
+* Thanks go to Chip Chapin (http://www.chipchapin.com) for many
+* excellent ideas and improvements.
+*
+* @author Richard Heyes <richard@php.net>
+* @author Harald Radi <harald.radi@nme.at>
+* @access public
+* @package HTML_TreeMenu
+*/
+
+class HTML_TreeMenu
+{
+ /**
+ * Indexed array of subnodes
+ * @var array
+ */
+ var $items;
+
+ /**
+ * Constructor
+ *
+ * @access public
+ */
+ function HTML_TreeMenu()
+ {
+ // Not much to do here :(
+ }
+
+ /**
+ * This function adds an item to the the tree.
+ *
+ * @access public
+ * @param object $node The node to add. This object should be
+ * a HTML_TreeNode object.
+ * @return object Returns a reference to the new node inside
+ * the tree.
+ */
+ function &addItem(&$node)
+ {
+ $this->items[] = &$node;
+ return $this->items[count($this->items) - 1];
+ }
+
+ /**
+ * Import method for creating HTML_TreeMenu objects/structures
+ * out of existing tree objects/structures. Currently supported
+ * are Wolfram Kriesings' PEAR Tree class, and Richard Heyes' (me!)
+ * Tree class (available here: http://www.phpguru.org/). This
+ * method is intended to be used statically, eg:
+ * $treeMenu = &HTML_TreeMenu::import($myTreeStructureObj);
+ *
+ * @param array $params An array of parameters that determine
+ * how the import happens. This can consist of:
+ * structure => The tree structure
+ * type => The type of the structure, currently
+ * can be either 'heyes' or 'kriesing'
+ * nodeOptions => Default options for each node
+ *
+ * @return object The resulting HTML_TreeMenu object
+ */
+ function createFromStructure($params)
+ {
+ if (!isset($params['nodeOptions'])) {
+ $params['nodeOptions'] = array();
+ }
+
+ switch (@$params['type']) {
+
+ /**
+ * Wolfram Kriesings' PEAR Tree class
+ */
+ case 'kriesing':
+ $className = strtolower(get_class($params['structure']->dataSourceClass));
+ $isXMLStruct = strpos($className,'_xml') !== false ? true : false;
+
+ // Get the entire tree, the $nodes are sorted like in the tree view
+ // from top to bottom, so we can easily put them in the nodes
+ $nodes = $params['structure']->getNode();
+
+ // Make a new menu and fill it with the values from the tree
+ $treeMenu = new HTML_TreeMenu();
+ $curNode[0] = &$treeMenu; // we need the current node as the reference to the
+
+ foreach ( $nodes as $aNode ) {
+ $events = array();
+ $data = array();
+
+ // In an XML, all the attributes are saved in an array, but since they might be
+ // used as the parameters, we simply extract them here if we handle an XML-structure
+ if ( $isXMLStruct && sizeof($aNode['attributes']) ){
+ foreach ( $aNode['attributes'] as $key=>$val ) {
+ if ( !$aNode[$key] ) { // dont overwrite existing values
+ $aNode[$key] = $val;
+ }
+ }
+ }
+
+ // Process all the data that are saved in $aNode and put them in the data and/or events array
+ foreach ( $aNode as $key=>$val ) {
+ if ( !is_array($val) ) {
+ // Dont get the recursive data in here! they are always arrays
+ if ( substr($key,0,2) == 'on' ){ // get the events
+ $events[$key] = $val;
+ }
+
+ // I put it in data too, so in case an options starts with 'on' its also passed to the node ... not too cool i know
+ $data[$key] = $val;
+ }
+ }
+
+ // Normally the text is in 'name' in the Tree class, so we check both but 'text' is used if found
+ $data['text'] = $aNode['text'] ? $aNode['text'] : $aNode['name'];
+
+ // Add the item to the proper node
+ $thisNode = &$curNode[$aNode['level']]->addItem( new HTML_TreeNode( $data , $events ) );
+ $curNode[$aNode['level']+1] = &$thisNode;
+ }
+ break;
+
+ /**
+ * Richard Heyes' (me!) Tree class
+ */
+ case 'heyes':
+ default:
+ // Need to create a HTML_TreeMenu object ?
+ if (!isset($params['treeMenu'])) {
+ $treeMenu = &new HTML_TreeMenu();
+ } else {
+ $treeMenu = &$params['treeMenu'];
+ }
+
+ // Loop thru the trees nodes
+ foreach ($params['structure']->nodes->nodes as $node) {
+ $tag = $node->getTag();
+ $parentNode = &$treeMenu->addItem(new HTML_TreeNode(array_merge($params['nodeOptions'], $tag)));
+
+ // Recurse ?
+ if (!empty($node->nodes->nodes)) {
+ $recurseParams['structure'] = $node;
+ $recurseParams['nodeOptions'] = $params['nodeOptions'];
+ $recurseParams['treeMenu'] = &$parentNode;
+ HTML_TreeMenu::createFromStructure($recurseParams);
+ }
+ }
+ break;
+
+ }
+
+ return $treeMenu;
+ }
+
+ /**
+ * Creates a treeMenu from XML. The structure of your XML should be
+ * like so:
+ *
+ * <treemenu>
+ * <node text="First node" icon="folder.gif" expandedIcon="folder-expanded.gif" />
+ * <node text="Second node" icon="folder.gif" expandedIcon="folder-expanded.gif">
+ * <node text="Sub node" icon="folder.gif" expandedIcon="folder-expanded.gif" />
+ * </node>
+ * <node text="Third node" icon="folder.gif" expandedIcon="folder-expanded.gif">
+ * </treemenu>
+ *
+ * Any of the options you can supply to the HTML_TreeNode constructor can be supplied as
+ * attributes to the <node> tag. If there are no subnodes for a particular node, you can
+ * use the XML shortcut <node ... /> instead of <node ... ></node>. The $xml argument can
+ * be either the XML as a string, or an pre-created XML_Tree object. Also, this method
+ * REQUIRES my own Tree class to work (http://phpguru.org/tree.html). If this has not
+ * been include()ed or require()ed this method will die().
+ *
+ * @param mixed $xml This can be either a string containing the XML, or an XML_Tree object
+ * (the PEAR::XML_Tree package).
+ * @return object The HTML_TreeMenu object
+ */
+ function createFromXML($xml)
+ {
+ if (!class_exists('Tree')) {
+ die('Could not find Tree class');
+ }
+
+ // Supplied $xml is a string
+ if (is_string($xml)) {
+ require_once('XML/Tree.php');
+ $xmlTree = &new XML_Tree();
+ $xmlTree->getTreeFromString($xml);
+
+ // Supplied $xml is an XML_Tree object
+ } else {
+ $xmlTree = $xml;
+ }
+
+ // Now process the XML_Tree object, setting the XML attributes
+ // to be the tag data (with out the XML tag name or contents).
+ $treeStructure = Tree::createFromXMLTree($xmlTree, true);
+ $treeStructure->nodes->traverse(create_function('&$node', '$tagData = $node->getTag(); $node->setTag($tagData["attributes"]);'));
+
+
+ return HTML_TreeMenu::createFromStructure(array('structure' => $treeStructure));
+ }
+} // HTML_TreeMenu
+
+
+/**
+* HTML_TreeNode class
+*
+* This class is supplementary to the above and provides a way to
+* add nodes to the tree. A node can have other nodes added to it.
+*
+* @author Richard Heyes <richard@php.net>
+* @author Harald Radi <harald.radi@nme.at>
+* @access public
+* @package HTML_TreeMenu
+*/
+class HTML_TreeNode
+{
+ /**
+ * The text for this node.
+ * @var string
+ */
+ var $text;
+
+ /**
+ * The link for this node.
+ * @var string
+ */
+ var $link;
+
+ /**
+ * The icon for this node.
+ * @var string
+ */
+ var $icon;
+
+ /**
+ * The icon to show when expanded for this node.
+ * @var string
+ */
+ var $expandedIcon;
+
+ /**
+ * The css class for this node
+ * @var string
+ */
+ var $cssClass;
+
+ /**
+ * The link target for this node
+ * @var string
+ */
+ var $linkTarget;
+
+ /**
+ * Indexed array of subnodes
+ * @var array
+ */
+ var $items;
+
+ /**
+ * Whether this node is expanded or not
+ * @var bool
+ */
+ var $expanded;
+
+ /**
+ * Whether this node is dynamic or not
+ * @var bool
+ */
+ var $isDynamic;
+
+ /**
+ * Should this node be made visible?
+ * @var bool
+ */
+ var $ensureVisible;
+
+ /**
+ * The parent node. Null if top level
+ * @var object
+ */
+ var $parent;
+
+ /**
+ * Javascript event handlers;
+ * @var array
+ */
+ var $events;
+
+ /**
+ * Constructor
+ *
+ * @access public
+ * @param array $options An array of options which you can pass to change
+ * the way this node looks/acts. This can consist of:
+ * o text The title of the node, defaults to blank
+ * o link The link for the node, defaults to blank
+ * o icon The icon for the node, defaults to blank
+ * o expandedIcon The icon to show when the node is expanded
+ * o class The CSS class for this node, defaults to blank
+ * o expanded The default expanded status of this node, defaults to false
+ * This doesn't affect non dynamic presentation types
+ * o linkTarget Target for the links. Defaults to linkTarget of the
+ * HTML_TreeMenu_Presentation.
+ * o isDynamic If this node is dynamic or not. Only affects
+ * certain presentation types.
+ * o ensureVisible If true this node will be made visible despite the expanded
+ * settings, and client side persistence. Will not affect
+ * some presentation styles, such as Listbox. Default is false
+ * @param array $events An array of javascript events and the corresponding event handlers.
+ * Additionally to the standard javascript events you can specify handlers
+ * for the 'onexpand', 'oncollapse' and 'ontoggle' events which will be fired
+ * whenever a node is collapsed and/or expanded.
+ */
+ function HTML_TreeNode($options = array(), $events = array())
+ {
+ $this->text = '';
+ $this->link = '';
+ $this->icon = '';
+ $this->expandedIcon = '';
+ $this->cssClass = '';
+ $this->expanded = false;
+ $this->isDynamic = true;
+ $this->ensureVisible = false;
+ $this->linkTarget = null;
+
+ $this->parent = null;
+ $this->events = $events;
+
+ foreach ($options as $option => $value) {
+ $this->$option = $value;
+ }
+ }
+
+ /**
+ * Allows setting of various parameters after the initial
+ * constructor call. Possible options you can set are:
+ * o text
+ * o link
+ * o icon
+ * o cssClass
+ * o expanded
+ * o isDynamic
+ * o ensureVisible
+ * ie The same options as in the constructor
+ *
+ * @access public
+ * @param string $option Option to set
+ * @param string $value Value to set the option to
+ */
+ function setOption($option, $value)
+ {
+ $this->$option = $value;
+ }
+
+ /**
+ * Adds a new subnode to this node.
+ *
+ * @access public
+ * @param object $node The new node
+ */
+ function &addItem(&$node)
+ {
+ $node->parent = &$this;
+ $this->items[] = &$node;
+
+ /**
+ * If the subnode has ensureVisible set it needs
+ * to be handled, and all parents set accordingly.
+ */
+ if ($node->ensureVisible) {
+ $this->_ensureVisible();
+ }
+
+ return $this->items[count($this->items) - 1];
+ }
+
+ /**
+ * Private function to handle ensureVisible stuff
+ *
+ * @access private
+ */
+ function _ensureVisible()
+ {
+ $this->ensureVisible = true;
+ $this->expanded = true;
+
+ if (!is_null($this->parent)) {
+ $this->parent->_ensureVisible();
+ }
+ }
+} // HTML_TreeNode
+
+
+/**
+* HTML_TreeMenu_Presentation class
+*
+* Base class for other presentation classes to
+* inherit from.
+*/
+class HTML_TreeMenu_Presentation
+{
+ /**
+ * The TreeMenu structure
+ * @var object
+ */
+ var $menu;
+
+ /**
+ * Base constructor simply sets the menu object
+ *
+ * @param object $structure The menu structure
+ */
+ function HTML_TreeMenu_Presentation(&$structure)
+ {
+ $this->menu = &$structure;
+ }
+
+ /**
+ * Prints the HTML generated by the toHTML() method.
+ * toHTML() must therefore be defined by the derived
+ * class.
+ *
+ * @access public
+ * @param array Options to set. Any options taken by
+ * the presentation class can be specified
+ * here.
+ */
+ function printMenu($options = array())
+ {
+ foreach ($options as $option => $value) {
+ $this->$option = $value;
+ }
+
+ echo $this->toHTML();
+ }
+}
+
+
+/**
+* HTML_TreeMenu_DHTML class
+*
+* This class is a presentation class for the tree structure
+* created using the TreeMenu/TreeNode. It presents the
+* traditional tree, static for browsers that can't handle
+* the DHTML.
+*/
+class HTML_TreeMenu_DHTML extends HTML_TreeMenu_Presentation
+{
+ /**
+ * Dynamic status of the treemenu. If true (default) this has no effect. If
+ * false it will override all dynamic status vars and set the menu to be
+ * fully expanded an non-dynamic.
+ */
+ var $isDynamic;
+
+ /**
+ * Path to the images
+ * @var string
+ */
+ var $images;
+
+ /**
+ * Target for the links generated
+ * @var string
+ */
+ var $linkTarget;
+
+ /**
+ * Whether to use clientside persistence or not
+ * @var bool
+ */
+ var $userPersistence;
+
+ /**
+ * The default CSS class for the nodes
+ */
+ var $defaultClass;
+
+ /**
+ * Whether to skip first level branch images
+ * @var bool
+ */
+ var $noTopLevelImages;
+
+ /**
+ * Constructor, takes the tree structure as
+ * an argument and an array of options which
+ * can consist of:
+ * o images - The path to the images folder. Defaults to "images"
+ * o linkTarget - The target for the link. Defaults to "_self"
+ * o defaultClass - The default CSS class to apply to a node. Default is none.
+ * o usePersistence - Whether to use clientside persistence. This persistence
+ * is achieved using cookies. Default is true.
+ * o noTopLevelImages - Whether to skip displaying the first level of images if
+ * there is multiple top level branches.
+ *
+ * And also a boolean for whether the entire tree is dynamic or not.
+ * This overrides any perNode dynamic settings.
+ *
+ * @param object $structure The menu structure
+ * @param array $options Array of options
+ * @param bool $isDynamic Whether the tree is dynamic or not
+ */
+ function HTML_TreeMenu_DHTML(&$structure, $options = array(), $isDynamic = true)
+ {
+ $this->HTML_TreeMenu_Presentation($structure);
+ $this->isDynamic = $isDynamic;
+
+ // Defaults
+ $this->images = 'images';
+ $this->linkTarget = '_self';
+ $this->defaultClass = '';
+ $this->usePersistence = true;
+ $this->noTopLevelImages = false;
+
+ foreach ($options as $option => $value) {
+ $this->$option = $value;
+ }
+ }
+
+ /**
+ * Returns the HTML for the menu. This method can be
+ * used instead of printMenu() to use the menu system
+ * with a template system.
+ *
+ * @access public
+ * @return string The HTML for the menu
+ */
+ function toHTML()
+ {
+ static $count = 0;
+ $menuObj = 'objTreeMenu_' . ++$count;
+
+ $html = "\n";
+ $html .= '<script language="javascript" type="text/javascript">' . "\n\t";
+ $html .= sprintf('%s = new TreeMenu("%s", "%s", "%s", "%s", %s, %s);',
+ $menuObj,
+ $this->images,
+ $menuObj,
+ $this->linkTarget,
+ $this->defaultClass,
+ $this->usePersistence ? 'true' : 'false',
+ $this->noTopLevelImages ? 'true' : 'false');
+
+ $html .= "\n";
+
+ /**
+ * Loop through subnodes
+ */
+ if (isset($this->menu->items)) {
+ for ($i=0; $i<count($this->menu->items); $i++) {
+ $html .= $this->_nodeToHTML($this->menu->items[$i], $menuObj);
+ }
+ }
+
+ $html .= sprintf("\n\t%s.drawMenu();", $menuObj);
+ if ($this->usePersistence && $this->isDynamic) {
+ $html .= sprintf("\n\t%s.resetBranches();", $menuObj);
+ }
+ $html .= "\n</script>";
+
+ return $html;
+ }
+
+ /**
+ * Prints a node of the menu
+ *
+ * @access private
+ */
+ function _nodeToHTML($nodeObj, $prefix, $return = 'newNode')
+ {
+ $expanded = $this->isDynamic ? ($nodeObj->expanded ? 'true' : 'false') : 'true';
+ $isDynamic = $this->isDynamic ? ($nodeObj->isDynamic ? 'true' : 'false') : 'false';
+ $html = sprintf("\t %s = %s.addItem(new TreeNode('%s', %s, %s, %s, %s, '%s', '%s', %s));\n",
+ $return,
+ $prefix,
+ $nodeObj->text,
+ !empty($nodeObj->icon) ? "'" . $nodeObj->icon . "'" : 'null',
+ !empty($nodeObj->link) ? "'" . $nodeObj->link . "'" : 'null',
+ $expanded,
+ $isDynamic,
+ $nodeObj->cssClass,
+ $nodeObj->linkTarget,
+ !empty($nodeObj->expandedIcon) ? "'" . $nodeObj->expandedIcon . "'" : 'null');
+
+ foreach ($nodeObj->events as $event => $handler) {
+ $html .= sprintf("\t %s.setEvent('%s', '%s');\n",
+ $return,
+ $event,
+ str_replace(array("\r", "\n", "'"), array('\r', '\n', "\'"), $handler));
+ }
+
+ /**
+ * Loop through subnodes
+ */
+ if (!empty($nodeObj->items)) {
+ for ($i=0; $i<count($nodeObj->items); $i++) {
+ $html .= $this->_nodeToHTML($nodeObj->items[$i], $return, $return . '_' . ($i + 1));
+ }
+ }
+
+ return $html;
+ }
+} // End class HTML_TreeMenu_DHTML
+
+
+/**
+* HTML_TreeMenu_Listbox class
+*
+* This class presents the menu as a listbox
+*/
+class HTML_TreeMenu_Listbox extends HTML_TreeMenu_Presentation
+{
+ /**
+ * The text that is displayed in the first option
+ * @var string
+ */
+ var $promoText;
+
+ /**
+ * The character used for indentation
+ * @var string
+ */
+ var $indentChar;
+
+ /**
+ * How many of the indent chars to use
+ * per indentation level
+ * @var integer
+ */
+ var $indentNum;
+
+ /**
+ * Target for the links generated
+ * @var string
+ */
+ var $linkTarget;
+
+ /**
+ * Constructor
+ *
+ * @param object $structure The menu structure
+ * @param array $options Options whic affect the display of the listbox.
+ * These can consist of:
+ * o promoText The text that appears at the the top of the listbox
+ * Defaults to "Select..."
+ * o indentChar The character to use for indenting the nodes
+ * Defaults to " "
+ * o indentNum How many of the indentChars to use per indentation level
+ * Defaults to 2
+ * o linkTarget Target for the links. Defaults to "_self"
+ * o submitText Text for the submit button. Defaults to "Go"
+ */
+ function HTML_TreeMenu_Listbox($structure, $options = array())
+ {
+ $this->HTML_TreeMenu_Presentation($structure);
+
+ $this->promoText = 'Select...';
+ $this->indentChar = ' ';
+ $this->indentNum = 2;
+ $this->linkTarget = '_self';
+ $this->submitText = 'Go';
+
+ foreach ($options as $option => $value) {
+ $this->$option = $value;
+ }
+ }
+
+ /**
+ * Returns the HTML generated
+ */
+ function toHTML()
+ {
+ static $count = 0;
+ $nodeHTML = '';
+
+ /**
+ * Loop through subnodes
+ */
+ if (isset($this->menu->items)) {
+ for ($i=0; $i<count($this->menu->items); $i++) {
+ $nodeHTML .= $this->_nodeToHTML($this->menu->items[$i]);
+ }
+ }
+
+ return sprintf('<form target="%s" action="" onsubmit="var link = this.%s.options[this.%s.selectedIndex].value; if (link) {this.action = link; return true} else return false"><select name="%s"><option value="">%s</option>%s</select> <input type="submit" value="%s" /></form>',
+ $this->linkTarget,
+ 'HTML_TreeMenu_Listbox_' . ++$count,
+ 'HTML_TreeMenu_Listbox_' . $count,
+ 'HTML_TreeMenu_Listbox_' . $count,
+ $this->promoText,
+ $nodeHTML,
+ $this->submitText);
+ }
+
+ /**
+ * Returns HTML for a single node
+ *
+ * @access private
+ */
+ function _nodeToHTML($node, $prefix = '')
+ {
+ $html = sprintf('<option value="%s">%s%s</option>', $node->link, $prefix, $node->text);
+
+ /**
+ * Loop through subnodes
+ */
+ if (isset($node->items)) {
+ for ($i=0; $i<count($node->items); $i++) {
+ $html .= $this->_nodeToHTML($node->items[$i], $prefix . str_repeat($this->indentChar, $this->indentNum));
+ }
+ }
+
+ return $html;
+ }
+} // End class HTML_TreeMenu_Listbox
+?>
+++ /dev/null
-
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
- 675 Mass Ave, Cambridge, MA 02139, USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-\f
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-\f
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-\f
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-\f
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-\f
- Appendix: How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) 19yy <name of author>
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) 19yy name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Library General
-Public License instead of this License.
+++ /dev/null
-class.tree 1.2 0
+++ /dev/null
-<?php
- // class.tree.php3 v1.01
- // (c) 1999, 2000, 2001 Patrick Hess <hess@posi.de>
-
- class Tree {
- var $tree_basefrm = "_top";
- var $tree_gbase;
-
- // internal data
- var $tree_path;
- var $tree_count = 1;
- var $usetextlinks = true;
- var $startallopen = false;
-
- var $tree_ftv2folderclosed;
- var $tree_ftv2folderopen;
- var $tree_ftv2doc;
-
- function Tree ($t_path = "class.tree")
- {
- $this->tree_path = $t_path;
- }
-
- function set_frame ($t_frame)
- // (c) Gildas LE NADAN, 10 march 2000
- // This method should be called before method open_tree
- // if you want to change the default target frame
- {
- $this->tree_basefrm = $t_frame;
- }
-
- function set_textlinks ($tlval)
- {
- $this->usetextlinks = $tlval;
- }
-
- function set_startallopen ($saaval)
- {
- $this->startallopen = $saaval;
- }
-
- function open_tree ($t_text, $t_url, $t_frame="",
- $t_gbase="ftv2")
- {
- $this->tree_gbase = $t_gbase;
- $this->tree_ftv2folderclosed = "$this->tree_gbase/ftv2folderclosed.gif";
- $this->tree_ftv2folderopen = "$this->tree_gbase/ftv2folderopen.gif";
- $this->tree_ftv2doc = "$this->tree_gbase/ftv2doc.gif";
-
- $tree_ftv2blank = "$this->tree_gbase/ftv2blank.gif";
- $tree_ftv2lastnode = "$this->tree_gbase/ftv2lastnode.gif";
- $tree_ftv2link = "$this->tree_gbase/ftv2link.gif";
- $tree_ftv2mlastnode = "$this->tree_gbase/ftv2mlastnode.gif";
- $tree_ftv2mnode = "$this->tree_gbase/ftv2mnode.gif";
- $tree_ftv2node = "$this->tree_gbase/ftv2node.gif";
- $tree_ftv2plastnode = "$this->tree_gbase/ftv2plastnode.gif";
- $tree_ftv2pnode = "$this->tree_gbase/ftv2pnode.gif";
- $tree_ftv2vertline = "$this->tree_gbase/ftv2vertline.gif";
- if($t_frame) {
- $this->tree_basefrm = $t_frame;
- }
-
- echo "<script type=\"text/javascript\">\n";
-
- if ($this->usetextlinks) echo "var USETEXTLINKS = 1;\n";
- else echo "var USETEXTLINKS = 0;\n";
-
- if ($this->startallopen) echo "var STARTALLOPEN = 1;\n";
- else echo "var STARTALLOPEN = 0;\n";
-
-?>
-classPath = <?php echo "\"$this->tree_path\";\n"; ?>
-ftv2blank = <?php echo "\"$tree_ftv2blank\""; ?>;
-ftv2doc = <?php echo "\"$this->tree_ftv2doc\""; ?>;
-ftv2folderclosed = <?php echo "\"$this->tree_ftv2folderclosed\""; ?>;
-ftv2folderopen = <?php echo "\"$this->tree_ftv2folderopen\""; ?>;
-ftv2lastnode = <?php echo "\"$tree_ftv2lastnode\""; ?>;
-ftv2link = <?php echo "\"$tree_ftv2link\""; ?>;
-ftv2mlastnode = <?php echo "\"$tree_ftv2mlastnode\""; ?>;
-ftv2mnode = <?php echo "\"$tree_ftv2mnode\""; ?>;
-ftv2node = <?php echo "\"$tree_ftv2node\""; ?>;
-ftv2plastnode = <?php echo "\"$tree_ftv2plastnode\""; ?>;
-ftv2pnode = <?php echo "\"$tree_ftv2pnode\""; ?>;
-ftv2vertline = <?php echo "\"$tree_ftv2vertline\""; ?>;
-basefrm = <?php echo "\"$this->tree_basefrm\""; ?>;
-</script>
-<script src=<?php echo "\"$this->tree_path/ua.js\""; ?> type="text/javascript">
-</script>
-<script src=<?php echo "\"$this->tree_path/ftiens4.js\""; ?> type="text/javascript"></script>
-<script type="text/javascript">
-<?php echo "\n";
-
- $jsvn = "foldersTree";
- echo "$jsvn = gFld(\"$t_text\", \"$t_url\", \"$this->tree_ftv2folderopen\", \"$this->tree_ftv2folderclosed\");\n";
- return ($jsvn);
- }
-
- function add_folder ($t_parent, $t_text, $t_url, $t_frame,
- $t_imgopen = "", $t_imgclosed = "")
- {
- $jsvn = "aux".$this->tree_count;
- $this->tree_count++;
- if (!strlen($t_imgopen))
- $t_imgopen = $this->tree_ftv2folderopen;
- if (!strlen($t_imgclosed))
- $t_imgclosed = $this->tree_ftv2folderclosed;
-
- echo "$jsvn = insFld($t_parent, gFld (\"$t_text\", ";
- echo "\"$t_url\", \"$t_frame\", \"$t_imgopen\", \"$t_imgclosed\"));\n";
-
- return ($jsvn);
- }
-
- function add_document ($t_parent, $t_text, $t_url, $t_frame, $t_img = "")
- {
- if (!strlen($t_img)) $t_img = $this->tree_ftv2doc;
- echo "insDoc($t_parent, gLnk ($t_parent, \"$t_text\", ";
- echo "\"$t_url\", \"$t_frame\", \"$t_img\"));\n";
- }
-
- function close_tree ( )
- {
- echo "\ninitializeDocument();\n</script>";
- }
- }
-
-?>
-
+++ /dev/null
-//****************************************************************
-// You are free to copy the "Folder-Tree" script as long as you
-// keep this copyright notice:
-// Script found in: http://www.geocities.com/marcelino_martins/foldertree.html
-// Author: Marcelino Alves Martins (http://www.mmartins.com)
-// 1997--2001.
-// Modified: Patrick Hess (posi@posi.de) March 2000, October 2001^M
-// changed: global variables define the path to the^M
-// .gif files (classPath), the names of the^M
-// images (ftv2folderopen, ftv2*, ...) and the^M
-// destination frame (basefrm)^M
-//****************************************************************
-
-// Log of changes:
-// 10 Aug 01 - Support for Netscape 6
-//
-// 17 Feb 98 - Fix initialization flashing problem with Netscape
-//
-// 27 Jan 98 - Root folder starts open; support for USETEXTLINKS;
-// make the ftien4 a js file
-
-
-// Definition of class Folder
-// *****************************************************************
-
-function Folder(folderDescription, hreference, framename, open, closed) //constructor
-{
- //constant data
- this.imgopen = open;
- this.imgclosed = closed;
- this.desc = folderDescription
- this.hreference = hreference
- this.framename = framename
- this.id = -1
- this.navObj = 0
- this.iconImg = 0
- this.nodeImg = 0
- this.isLastNode = 0
-
- //dynamic data
- this.isOpen = true
- this.iconSrc = classPath + "/" + this.imgopen // classPath + "/" + ftv2folderopen
- this.children = new Array
- this.nChildren = 0
-
- //methods
- this.initialize = initializeFolder
- this.setState = setStateFolder
- this.addChild = addChild
- this.createIndex = createEntryIndex
- this.escondeBlock = escondeBlock
- this.esconde = escondeFolder
- this.mostra = mostra
- this.renderOb = drawFolder
- this.totalHeight = totalHeight
- this.subEntries = folderSubEntries
- this.outputLink = outputFolderLink
- this.blockStart = blockStart
- this.blockEnd = blockEnd
-}
-
-function initializeFolder(level, lastNode, leftSide)
-{
- var j=0
- var i=0
- var numberOfFolders
- var numberOfDocs
- var nc
-
- nc = this.nChildren
-
- this.createIndex()
-
- var auxEv = ""
-
- if (browserVersion > 0)
- auxEv = "<a href='javascript:clickOnNode("+this.id+")'>"
- else
- auxEv = "<a>"
-
- if (level>0)
- if (lastNode) //the last child in the children array
- {
- this.renderOb(leftSide + auxEv + "<img name='nodeIcon" + this.id + "' id='nodeIcon" + this.id + "' src='" + classPath + "/" + ftv2mlastnode + "' width=16 height=22 border=0></a>")
- leftSide = leftSide + "<img src='" + classPath + "/" + ftv2blank + "' width=16 height=22>"
- this.isLastNode = 1
- }
- else
- {
- this.renderOb(leftSide + auxEv + "<img name='nodeIcon" + this.id + "' id='nodeIcon" + this.id + "' src='" + classPath + "/" + ftv2mnode + "' width=16 height=22 border=0></a>")
- leftSide = leftSide + "<img src='" + classPath + "/" + ftv2vertline + "' width=16 height=22>"
- this.isLastNode = 0
- }
- else
- this.renderOb("")
-
- if (nc > 0)
- {
- level = level + 1
- for (i=0 ; i < this.nChildren; i++)
- {
- if (i == this.nChildren-1)
- this.children[i].initialize(level, 1, leftSide)
- else
- this.children[i].initialize(level, 0, leftSide)
- }
- }
-}
-
-function setStateFolder(isOpen)
-{
- var subEntries
- var totalHeight
- var fIt = 0
- var i=0
-
- if (isOpen == this.isOpen)
- return
-
- if (browserVersion == 2)
- {
- totalHeight = 0
- for (i=0; i < this.nChildren; i++)
- totalHeight = totalHeight + this.children[i].navObj.clip.height
- subEntries = this.subEntries()
- if (this.isOpen)
- totalHeight = 0 - totalHeight
- for (fIt = this.id + subEntries + 1; fIt < nEntries; fIt++)
- indexOfEntries[fIt].navObj.moveBy(0, totalHeight)
- }
- this.isOpen = isOpen
- propagateChangesInState(this)
-}
-
-function propagateChangesInState(folder)
-{
- var i=0
-
- if (folder.isOpen)
- {
- if (folder.nodeImg)
- if (folder.isLastNode)
- folder.nodeImg.src = classPath + "/" + ftv2mlastnode
- else
- folder.nodeImg.src = classPath + "/" + ftv2mnode
- folder.iconImg.src = classPath + "/" + folder.imgopen // classPath + "/" + ftv2folderopen
- for (i=0; i<folder.nChildren; i++)
- folder.children[i].mostra()
- }
- else
- {
- if (folder.nodeImg)
- if (folder.isLastNode)
- folder.nodeImg.src = classPath + "/" + ftv2plastnode
- else
- folder.nodeImg.src = classPath + "/" + ftv2pnode
- folder.iconImg.src = classPath + "/" + folder.imgclosed // classPath + "/" + ftv2folderclosed
- for (i=0; i<folder.nChildren; i++)
- folder.children[i].esconde()
- }
-}
-
-function escondeFolder()
-{
- this.escondeBlock()
-
- this.setState(0)
-}
-
-function drawFolder(leftSide)
-{
-
- var idParam = "id='folder" + this.id + "'"
-
- if (browserVersion == 2) {
- if (!doc.yPos)
- doc.yPos=20
- }
-
- this.blockStart("folder")
-
- doc.write("<tr><td>")
- doc.write(leftSide)
- this.outputLink()
- doc.write("<img id='folderIcon" + this.id + "' name='folderIcon" + this.id + "' src='" + this.iconSrc+"' border=0></a>")
- doc.write("</td><td valign=middle nowrap>")
- if (USETEXTLINKS)
- {
- this.outputLink()
- doc.write(this.desc + "</a>")
- }
- else
- doc.write(this.desc)
- doc.write("</td>")
-
- this.blockEnd()
-
- if (browserVersion == 1) {
- this.navObj = doc.all["folder"+this.id]
- this.iconImg = doc.all["folderIcon"+this.id]
- this.nodeImg = doc.all["nodeIcon"+this.id]
- } else if (browserVersion == 2) {
- this.navObj = doc.layers["folder"+this.id]
- this.iconImg = this.navObj.document.images["folderIcon"+this.id]
- this.nodeImg = this.navObj.document.images["nodeIcon"+this.id]
- doc.yPos=doc.yPos+this.navObj.clip.height
- } else if (browserVersion == 3) {
- this.navObj = doc.getElementById("folder"+this.id)
- this.iconImg = doc.getElementById("folderIcon"+this.id)
- this.nodeImg = doc.getElementById("nodeIcon"+this.id)
- }
-}
-
-function outputFolderLink()
-{
- if (this.hreference)
- {
- doc.write("<a href='" + this.hreference + "' TARGET=\""+this.framename+"\" ")
- if (browserVersion > 0)
- doc.write("onClick='javascript:clickOnFolder("+this.id+")'")
- doc.write(">")
- }
- else
- doc.write("<a>")
-// doc.write("<a href='javascript:clickOnFolder("+this.id+")'>")
-}
-
-function addChild(childNode)
-{
- this.children[this.nChildren] = childNode
- this.nChildren++
- return childNode
-}
-
-function folderSubEntries()
-{
- var i = 0
- var se = this.nChildren
-
- for (i=0; i < this.nChildren; i++){
- if (this.children[i].children) //is a folder
- se = se + this.children[i].subEntries()
- }
-
- return se
-}
-
-
-// Definition of class Item (a document or link inside a Folder)
-// *************************************************************
-
-function Item(itemDescription, itemLink, image) // Constructor
-{
- // constant data
- this.docimage = image
- this.desc = itemDescription
- this.link = itemLink
- this.id = -1 //initialized in initalize()
- this.navObj = 0 //initialized in render()
- this.iconImg = 0 //initialized in render()
- this.iconSrc = classPath + "/" + this.docimage // ftv2doc
-
- // methods
- this.initialize = initializeItem
- this.createIndex = createEntryIndex
- this.esconde = escondeBlock
- this.mostra = mostra
- this.renderOb = drawItem
- this.totalHeight = totalHeight
- this.blockStart = blockStart
- this.blockEnd = blockEnd
-}
-
-function initializeItem(level, lastNode, leftSide)
-{
- this.createIndex()
-
- if (level>0)
- if (lastNode) //the last 'brother' in the children array
- {
- this.renderOb(leftSide + "<img src='" + classPath + "/" + ftv2lastnode + "' width=16 height=22>")
- leftSide = leftSide + "<img src='" + classPath + "/" + ftv2blank + "' width=16 height=22>"
- }
- else
- {
- this.renderOb(leftSide + "<img src='" + classPath + "/" + ftv2node + "' width=16 height=22>")
- leftSide = leftSide + "<img src='" + classPath + "/" + ftv2vertline + "' width=16 height=22>"
- }
- else
- this.renderOb("")
-}
-
-function drawItem(leftSide)
-{
- this.blockStart("item")
-
- doc.write("<tr><td>")
- doc.write(leftSide)
- doc.write("<a href=" + this.link + ">")
- doc.write("<img id='itemIcon"+this.id+"' ")
- doc.write("src='"+this.iconSrc+"' border=0>")
- doc.write("</a>")
- doc.write("</td><td valign=middle nowrap>")
- if (USETEXTLINKS)
- doc.write("<a href=" + this.link + ">" + this.desc + "</a>")
- else
- doc.write(this.desc)
-
- this.blockEnd()
-
- if (browserVersion == 1) {
- this.navObj = doc.all["item"+this.id]
- this.iconImg = doc.all["itemIcon"+this.id]
- } else if (browserVersion == 2) {
- this.navObj = doc.layers["item"+this.id]
- this.iconImg = this.navObj.document.images["itemIcon"+this.id]
- doc.yPos=doc.yPos+this.navObj.clip.height
- } else if (browserVersion == 3) {
- this.navObj = doc.getElementById("item"+this.id)
- this.iconImg = doc.getElementById("itemIcon"+this.id)
- }
-}
-
-
-// Methods common to both objects (pseudo-inheritance)
-// ********************************************************
-
-function mostra()
-{
- if (browserVersion == 1 || browserVersion == 3)
- this.navObj.style.display = "block"
- else
- this.navObj.visibility = "show"
-}
-
-function escondeBlock()
-{
- if (browserVersion == 1 || browserVersion == 3) {
- if (this.navObj.style.display == "none")
- return
- this.navObj.style.display = "none"
- } else {
- if (this.navObj.visibility == "hidden")
- return
- this.navObj.visibility = "hidden"
- }
-}
-
-function blockStart(idprefix) {
- var idParam = "id='" + idprefix + this.id + "'"
-
- if (browserVersion == 2)
- doc.write("<layer "+ idParam + " top=" + doc.yPos + " visibility=show>")
-
- if (browserVersion == 3) //N6 has bug on display property with tables
- doc.write("<div " + idParam + " style='display:block; position:block;'>")
-
- doc.write("<table border=0 cellspacing=0 cellpadding=0 ")
-
- if (browserVersion == 1)
- doc.write(idParam + " style='display:block; position:block; '>")
- else
- doc.write(">")
-}
-
-function blockEnd() {
- doc.write("</table>")
-
- if (browserVersion == 2)
- doc.write("</layer>")
- if (browserVersion == 3)
- doc.write("</div>")
-}
-
-function createEntryIndex()
-{
- this.id = nEntries
- indexOfEntries[nEntries] = this
- nEntries++
-}
-
-// total height of subEntries open
-function totalHeight() //used with browserVersion == 2
-{
- var h = this.navObj.clip.height
- var i = 0
-
- if (this.isOpen) //is a folder and _is_ open
- for (i=0 ; i < this.nChildren; i++)
- h = h + this.children[i].totalHeight()
-
- return h
-}
-
-
-// Events
-// *********************************************************
-
-function clickOnFolder(folderId)
-{
- var clicked = indexOfEntries[folderId]
-
- if (!clicked.isOpen)
- clickOnNode(folderId)
-
- return
-
- if (clicked.isSelected)
- return
-}
-
-function clickOnNode(folderId)
-{
- var clickedFolder = 0
- var state = 0
-
- clickedFolder = indexOfEntries[folderId]
- state = clickedFolder.isOpen
-
- clickedFolder.setState(!state) //open<->close
-}
-
-
-// Auxiliary Functions for Folder-Tree backward compatibility
-// ***********************************************************
-
-function gFld(description, hreference, framename, open, closed)
-{
- folder = new Folder(description, hreference, framename, open, closed)
- return folder
-}
-
-function gLnk(target, description, linkData, framename, image)
-{
- fullLink = ""
-
- if (target==0)
- {
- fullLink = "'"+linkData+"' target=\""+framename+"\""
- }
- else
- {
- if (target==1)
- // fullLink = "'http://"+linkData+"' target=_blank"
- fullLink = "'"+linkData+"' target=_blank"
- else
- // fullLink = "'http://"+linkData+"' target=\""+framename+"\""
- fullLink = "'"+linkData+"' target=\""+framename+"\""
- }
-
- linkItem = new Item(description, fullLink, image)
- return linkItem
-}
-
-function insFld(parentFolder, childFolder)
-{
- return parentFolder.addChild(childFolder)
-}
-
-function insDoc(parentFolder, document)
-{
- parentFolder.addChild(document)
-}
-
-
-// Global variables
-// ****************
-
-//These two variables are overwriten on defineMyTree.js if needed be
-//USETEXTLINKS = 0
-//STARTALLOPEN = 0
-indexOfEntries = new Array
-nEntries = 0
-doc = document
-browserVersion = 0
-selectedFolder=0
-
-
-// Main function
-// *************
-
-// This function uses an object (navigator) defined in
-// ua.js, imported in the main html page (left frame).
-function initializeDocument()
-{
- switch(navigator.family)
- {
- case 'opera':
- case 'ie4':
- browserVersion = 1 //IE4
- break;
- case 'nn4':
- browserVersion = 2 //NS4
- break;
- case 'gecko':
- browserVersion = 3 //NS6
- break;
- default:
- browserVersion = 0 //other
- break;
- }
-
- //foldersTree (with the site's data) is created in an external .js
- foldersTree.initialize(0, 1, "")
-
- if (browserVersion == 2)
- doc.write("<layer top="+indexOfEntries[nEntries-1].navObj.top+"> </layer>")
-
- //The tree starts in full display
- if (!STARTALLOPEN)
- if (browserVersion > 0) {
- // close the whole tree
- clickOnNode(0)
- // open the root folder
- clickOnNode(0)
- }
-
- /* not used, ph 10/2001
- if (browserVersion == 0)
- doc.write("<table border=0><tr><td><br><br><font size=-1>This tree only expands or contracts with DHTML capable browsers</font></table>")
- */
-}
-
+++ /dev/null
-// ua.js - Detect Browser
-// Requires JavaScript 1.1
-/*
-The contents of this file are subject to the Netscape Public
-License Version 1.1 (the "License"); you may not use this file
-except in compliance with the License. You may obtain a copy of
-the License at http://www.mozilla.org/NPL/
-
-Software distributed under the License is distributed on an "AS
-IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
-implied. See the License for the specific language governing
-rights and limitations under the License.
-
-The Initial Developer of the Original Code is Bob Clary.
-
-Contributor(s): Bob Clary, Original Work, Copyright 1999-2000
- Bob Clary, Netscape Communications, Copyright 2001
-
-Alternatively, the contents of this file may be used under the
-terms of the GNU Public License (the "GPL"), in which case the
-provisions of the GPL are applicable instead of those above.
-If you wish to allow use of your version of this file only
-under the terms of the GPL and not to allow others to use your
-version of this file under the NPL, indicate your decision by
-deleting the provisions above and replace them with the notice
-and other provisions required by the GPL. If you do not delete
-the provisions above, a recipient may use your version of this
-file under either the NPL or the GPL.
-*/
-
-// work around bug in xpcdom Mozilla 0.9.1
-window.saveNavigator = window.navigator;
-
-// Handy functions
-function noop() {}
-function noerror() { return true; }
-
-function defaultOnError(msg, url, line)
-{
- // customize this for your site
- if (top.location.href.indexOf('_files/errors/') == -1)
- top.location = '/evangelism/xbProjects/_files/errors/index.html?msg=' + escape(msg) + '&url=' + escape(url) + '&line=' + escape(line);
-}
-
-// Display Error page...
-// XXX: more work to be done here
-//
-function reportError(message)
-{
- // customize this for your site
- if (top.location.href.indexOf('_files/errors/') == -1)
- top.location = '/evangelism/xbProjects/_files/errors/index.html?msg=' + escape(message);
-}
-
-function pageRequires(cond, msg, redirectTo)
-{
- if (!cond)
- {
- msg = 'This page requires ' + msg;
- top.location = redirectTo + '?msg=' + escape(msg);
- }
- // return cond so can use in <A> onclick handlers to exclude browsers
- // from pages they do not support.
- return cond;
-}
-
-function detectBrowser()
-{
- var oldOnError = window.onerror;
- var element = null;
-
- window.onerror = defaultOnError;
-
- navigator.OS = '';
- navigator.version = 0;
- navigator.org = '';
- navigator.family = '';
-
- var platform;
- if (typeof(window.navigator.platform) != 'undefined')
- {
- platform = window.navigator.platform.toLowerCase();
- if (platform.indexOf('win') != -1)
- navigator.OS = 'win';
- else if (platform.indexOf('mac') != -1)
- navigator.OS = 'mac';
- else if (platform.indexOf('unix') != -1 || platform.indexOf('linux') != -1 || platform.indexOf('sun') != -1)
- navigator.OS = 'nix';
- }
-
- var i = 0;
- var ua = window.navigator.userAgent.toLowerCase();
-
- if (ua.indexOf('opera') != -1)
- {
- i = ua.indexOf('opera');
- navigator.family = 'opera';
- navigator.org = 'opera';
- navigator.version = parseFloat('0' + ua.substr(i+6), 10);
- }
- else if ((i = ua.indexOf('msie')) != -1)
- {
- navigator.org = 'microsoft';
- navigator.version = parseFloat('0' + ua.substr(i+5), 10);
-
- if (navigator.version < 4)
- navigator.family = 'ie3';
- else
- navigator.family = 'ie4'
- }
- else if (typeof(window.controllers) != 'undefined' && typeof(window.locationbar) != 'undefined')
- {
- i = ua.lastIndexOf('/')
- navigator.version = parseFloat('0' + ua.substr(i+1), 10);
- navigator.family = 'gecko';
-
- if (ua.indexOf('netscape') != -1)
- navigator.org = 'netscape';
- else if (ua.indexOf('compuserve') != -1)
- navigator.org = 'compuserve';
- else
- navigator.org = 'mozilla';
- }
- else if ((ua.indexOf('mozilla') !=-1) && (ua.indexOf('spoofer')==-1) && (ua.indexOf('compatible') == -1) && (ua.indexOf('opera')==-1)&& (ua.indexOf('webtv')==-1) && (ua.indexOf('hotjava')==-1))
- {
- var is_major = parseFloat(navigator.appVersion);
-
- if (is_major < 4)
- navigator.version = is_major;
- else
- {
- i = ua.lastIndexOf('/')
- navigator.version = parseFloat('0' + ua.substr(i+1), 10);
- }
- navigator.org = 'netscape';
- navigator.family = 'nn' + parseInt(navigator.appVersion);
- }
- else if ((i = ua.indexOf('aol')) != -1 )
- {
- // aol
- navigator.family = 'aol';
- navigator.org = 'aol';
- navigator.version = parseFloat('0' + ua.substr(i+4), 10);
- }
-
- navigator.DOMCORE1 = (typeof(document.getElementsByTagName) != 'undefined' && typeof(document.createElement) != 'undefined');
- navigator.DOMCORE2 = (navigator.DOMCORE1 && typeof(document.getElementById) != 'undefined' && typeof(document.createElementNS) != 'undefined');
- navigator.DOMHTML = (navigator.DOMCORE1 && typeof(document.getElementById) != 'undefined');
- navigator.DOMCSS1 = ( (navigator.family == 'gecko') || (navigator.family == 'ie4') );
-
- navigator.DOMCSS2 = false;
- if (navigator.DOMCORE1)
- {
- element = document.createElement('p');
- navigator.DOMCSS2 = (typeof(element.style) == 'object');
- }
-
- navigator.DOMEVENTS = (typeof(document.createEvent) != 'undefined');
-
- window.onerror = oldOnError;
-}
-
-detectBrowser();
-
+++ /dev/null
-<?php
-
-
-
-/*
-
- +-----------------------------------------------------------------------+
-
- | Copyright (c) 2002, Richard Heyes, Harald Radi |
-
- | All rights reserved. |
-
- | |
-
- | Redistribution and use in source and binary forms, with or without |
-
- | modification, are permitted provided that the following conditions |
-
- | are met: |
-
- | |
-
- | o Redistributions of source code must retain the above copyright |
-
- | notice, this list of conditions and the following disclaimer. |
-
- | o Redistributions in binary form must reproduce the above copyright |
-
- | notice, this list of conditions and the following disclaimer in the |
-
- | documentation and/or other materials provided with the distribution.|
-
- | o The names of the authors may not be used to endorse or promote |
-
- | products derived from this software without specific prior written |
-
- | permission. |
-
- | |
-
- | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
-
- | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
-
- | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
-
- | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
-
- | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
-
- | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
-
- | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
-
- | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
-
- | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
-
- | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
-
- | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
-
- | |
-
- +-----------------------------------------------------------------------+
-
- | Author: Richard Heyes <richard@phpguru.org> |
-
- | Harald Radi <harald.radi@nme.at> |
-
- +-----------------------------------------------------------------------+
-
-*/
-
-
-
-require_once('tree.inc.php');
-
-
-
-class HTML_TreeMenu
-
-{
-
-
-
- var $items;
-
- var $layer;
-
- var $images;
-
- var $menuobj;
-
-
-
- function HTML_TreeMenu($layer, $images, $linkTarget = '_self', $usePersistence = false)
-
- {
-
- $this->menuobj = 'objTreeMenu';
-
- $this->layer = $layer;
-
- $this->images = $images;
-
- $this->linkTarget = $linkTarget;
-
- $this->usePersistence = $usePersistence;
-
- }
-
-
-
- function &addItem(&$menu)
-
- {
-
- $this->items[] = &$menu;
-
- return $this->items[count($this->items) - 1];
-
- }
-
-
-
- function printMenu()
-
- {
-
- echo "\n";
-
-
-
- echo '<script language="javascript" type="text/javascript">' . "\n\t";
-
- echo sprintf('%s = new TreeMenu("%s", "%s", "%s", "%s");',
-
- $this->menuobj,
-
- $this->layer,
-
- $this->images,
-
- $this->menuobj,
-
- $this->linkTarget);
-
-
-
- echo "\n";
-
-
-
- if (isset($this->items))
-
- {
-
- for ($i=0; $i<count($this->items); $i++)
-
- {
-
- $this->items[$i]->_printMenu($this->menuobj . ".n[$i]");
-
- }
-
- }
-
-
-
- echo sprintf("\n\t%s.drawMenu();", $this->menuobj);
-
- if ($this->usePersistence)
-
- {
-
- echo sprintf("\n\t%s.resetBranches();", $this->menuobj);
-
- }
-
- echo "\n</script>";
-
- }
-
-}
-
-
-
-class HTML_TreeNode
-
-{
-
- var $text;
-
- var $link;
-
- var $icon;
-
- var $items;
-
- var $expanded;
-
-
-
- function HTML_TreeNode($text = null, $link = null, $icon = null, $expanded = false, $isDynamic = true)
-
- {
-
- $this->text = (string)$text;
-
- $this->link = (string)$link;
-
- $this->icon = (string)$icon;
-
- $this->expanded = $expanded;
-
- $this->isDynamic = $isDynamic;
-
- }
-
-
-
- function &addItem(&$node)
-
- {
-
- $this->items[] = &$node;
-
- return $this->items[count($this->items) - 1];
-
- }
-
-
-
- function _printMenu($prefix)
-
- {
-
- echo sprintf("\t%s = new TreeNode('%s', %s, %s, %s, %s);\n",
-
- $prefix,
-
- $this->text,
-
- !empty($this->icon) ? "'" . $this->icon . "'" : 'null',
-
- !empty($this->link) ? "'" . $this->link . "'" : 'null',
-
- $this->expanded ? 'true' : 'false',
-
- $this->isDynamic ? 'true' : 'false');
-
-
-
- if (!empty($this->items)) {
-
- for ($i=0; $i<count($this->items); $i++) {
-
- $this->items[$i]->_printMenu($prefix . ".n[$i]");
-
- }
-
- }
-
- }
-
-}
-
-?>
-
+++ /dev/null
-<script language="javascript">
-
-
-
-/*
-
- +-----------------------------------------------------------------------+
-
- | Copyright (c) 2002, Richard Heyes, Harald Radi |
-
- | All rights reserved. |
-
- | |
-
- | Redistribution and use in source and binary forms, with or without |
-
- | modification, are permitted provided that the following conditions |
-
- | are met: |
-
- | |
-
- | o Redistributions of source code must retain the above copyright |
-
- | notice, this list of conditions and the following disclaimer. |
-
- | o Redistributions in binary form must reproduce the above copyright |
-
- | notice, this list of conditions and the following disclaimer in the |
-
- | documentation and/or other materials provided with the distribution.|
-
- | o The names of the authors may not be used to endorse or promote |
-
- | products derived from this software without specific prior written |
-
- | permission. |
-
- | |
-
- | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
-
- | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
-
- | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
-
- | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
-
- | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
-
- | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
-
- | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
-
- | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
-
- | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
-
- | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
-
- | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
-
- | |
-
- +-----------------------------------------------------------------------+
-
- | Author: Richard Heyes <richard@phpguru.org> |
-
- | Harald Radi <harald.radi@nme.at> |
-
- +-----------------------------------------------------------------------+
-
-*/
-
-function TreeMenu(layer, iconpath, myname, linkTarget)
-
-{
-
- // Properties
-
- this.layer = layer;
-
- this.iconpath = iconpath;
-
- this.myname = myname;
-
- this.linkTarget = linkTarget;
-
- this.n = new Array();
-
-
-
- this.branches = new Array();
-
- this.branchStatus = new Array();
-
- this.layerRelations = new Array();
-
- this.childParents = new Array();
-
-
-
- // Methods
-
- this.preloadImages = preloadImages;
-
- this.drawMenu = drawMenu;
-
- this.toggleBranch = toggleBranch;
-
- this.swapImage = swapImage;
-
- this.doesMenu = doesMenu;
-
- this.doesPersistence = doesPersistence;
-
- this.getLayer = getLayer;
-
- this.saveExpandedStatus = saveExpandedStatus;
-
- this.loadExpandedStatus = loadExpandedStatus;
-
- this.resetBranches = resetBranches;
-
- this.checkParentVisibility = checkParentVisibility;
-
-
-
- this.preloadImages();
-
-}
-
-
-
-function TreeNode(title, icon, link, expanded, isDynamic)
-
-{
-
- this.title = title;
-
- this.icon = icon;
-
- this.link = link;
-
- this.expanded = expanded;
-
- this.isDynamic = isDynamic;
-
- this.n = new Array();
-
-}
-
-
-
-function preloadImages()
-
-{
-
- var plustop = new Image; plustop.src = this.iconpath + '/plustop.gif';
-
- var plusbottom = new Image; plusbottom.src = this.iconpath + '/plusbottom.gif';
-
- var plus = new Image; plus.src = this.iconpath + '/plus.gif';
-
-
-
- var minustop = new Image; minustop.src = this.iconpath + '/minustop.gif';
-
- var minusbottom = new Image; minusbottom.src = this.iconpath + '/minusbottom.gif';
-
- var minus = new Image; minus.src = this.iconpath + '/minus.gif';
-
-
-
- var branchtop = new Image; branchtop.src = this.iconpath + '/branchtop.gif';
-
- var branchbottom = new Image; branchbottom.src = this.iconpath + '/branchbottom.gif';
-
- var branch = new Image; branch.src = this.iconpath + '/branch.gif';
-
-
-
- var linebottom = new Image; linebottom.src = this.iconpath + '/linebottom.gif';
-
- var line = new Image; line.src = this.iconpath + '/line.gif';
-
-}
-
-
-
-/**
-
-* Main function that draws the menu and assigns it
-
-* to the layer (or document.write()s it)
-
-*/
-
-function drawMenu()// OPTIONAL ARGS: nodes = [], level = [], prepend = '', expanded = false, visbility = 'inline', parentLayerID = null
-
-{
-
- /**
-
- * Necessary variables
-
- */
-
- var output = '';
-
- var modifier = '';
-
- var layerID = '';
-
- var parentLayerID = '';
-
-
-
- /**
-
- * Parse any optional arguments
-
- */
-
- var nodes = arguments[0] ? arguments[0] : this.n
-
- var level = arguments[1] ? arguments[1] : [];
-
- var prepend = arguments[2] ? arguments[2] : '';
-
- var expanded = arguments[3] ? arguments[3] : false;
-
- var visibility = arguments[4] ? arguments[4] : 'inline';
-
- var parentLayerID = arguments[5] ? arguments[5] : null;
-
-
-
- var currentlevel = level.length;
-
-
-
- for (var i=0; i<nodes.length; i++)
-
- {
-
- level[currentlevel] = i+1;
-
- layerID = this.layer + '_' + 'node_' + implode('_', level);
-
-
-
- /**
-
- * Store the child/parent relationship
-
- */
-
- this.childParents[layerID] = parentLayerID;
-
-
-
- /**
-
- * Gif modifier
-
- */
-
- if (i == 0 && parentLayerID == null)
-
- {
-
- modifier = nodes.length > 1 ? "top" : 'single';
-
- }
-
- else if(i == (nodes.length-1))
-
- {
-
- modifier = "bottom";
-
- }
-
- else
-
- {
-
- modifier = "";
-
- }
-
-
-
- /**
-
- * Single root branch is always expanded
-
- */
-
- if (!doesMenu() || (parentLayerID == null && nodes.length == 1))
-
- {
-
- expanded = true;
-
-
-
- }
-
- else if (nodes[i].expanded)
-
- {
-
- expanded = true;
-
-
-
- }
-
- else
-
- {
-
- expanded = false;
-
- }
-
-
-
- /**
-
- * Setup branch status and build an indexed array
-
- * of branch layer ids
-
- */
-
- if (nodes[i].n.length > 0)
-
- {
-
- this.branchStatus[layerID] = expanded;
-
- this.branches[this.branches.length] = layerID;
-
- }
-
-
-
- /**
-
- * Setup toggle relationship
-
- */
-
- if (!this.layerRelations[parentLayerID])
-
- {
-
- this.layerRelations[parentLayerID] = new Array();
-
- }
-
- this.layerRelations[parentLayerID][this.layerRelations[parentLayerID].length] = layerID;
-
-
-
- /**
-
- * Branch images
-
- */
-
- var gifname = nodes[i].n.length && this.doesMenu() && nodes[i].isDynamic ? (expanded ? 'minus' : 'plus') : 'branch';
-
- var iconimg = nodes[i].icon ? sprintf('<img src="%s/%s" width="20" height="20" align="top">', this.iconpath, nodes[i].icon) : '';
-
-
-
- /**
-
- * Build the html to write to the document
-
- */
-
- var divTag = sprintf('<div id="%s" style="display: %s; behavior: url(#default#userdata)">', layerID, visibility);
-
- var onMDown = doesMenu() && nodes[i].n.length && nodes[i].isDynamic ? sprintf('onmousedown="%s.toggleBranch(\'%s\', true)" style="cursor: pointer; cursor: hand"', this.myname, layerID) : '';
-
- var imgTag = sprintf('<img src="%s/%s%s.gif" width="20" height="20" align="top" border="0" name="img_%s" %s />', this.iconpath, gifname, modifier, layerID, onMDown);
-
- var linkStart = nodes[i].link ? sprintf('<a href="%s" target="%s">', nodes[i].link, this.linkTarget) : '';
-
- var linkEnd = nodes[i].link ? '</a>' : '';
-
-
-
- output = sprintf('%s<nobr>%s%s%s%s%s%s</nobr><br></div>',
-
- divTag,
-
- prepend,
-
- parentLayerID == null && nodes.length == 1 ? '' : imgTag,
-
- iconimg,
-
- linkStart,
-
- nodes[i].title,
-
- linkEnd);
-
-
-
- /**
-
- * Write out the HTML. Uses document.write for speed over layers and
-
- * innerHTML. This however means no dynamic adding/removing nodes on
-
- * the client side. This could be conditional I guess if dynamic
-
- * adding/removing is required.
-
- */
-
- if (this.doesMenu())
-
- {
-
- //this.getLayer(this.layer).innerHTML += output
-
- document.write(output);
-
-
-
- }
-
- else
-
- {
-
- document.write(output);
-
- }
-
-
-
- /**
-
- * Traverse sub nodes ?
-
- */
-
- if (nodes[i].n.length)
-
- {
-
- /**
-
- * Determine what to prepend. If there is only one root
-
- * node then the prepend to pass to children is nothing.
-
- * Otherwise it depends on where we are in the tree.
-
- */
-
- if (parentLayerID == null && nodes.length == 1)
-
- {
-
- var newPrepend = '';
-
-
-
- }
-
- else if (i < (nodes.length - 1))
-
- {
-
- var newPrepend = prepend + sprintf('<img src="%s/line.gif" width="20" height="20" align="top">', this.iconpath);
-
-
-
- }
-
- else
-
- {
-
- var newPrepend = prepend + sprintf('<img src="%s/linebottom.gif" width="20" height="20" align="top">', this.iconpath);
-
- }
-
-
-
- this.drawMenu(nodes[i].n,
-
- explode('_', implode('_', level)), // Seemingly necessary to enforce passing by value
-
- newPrepend,
-
- nodes[i].expanded,
-
- expanded ? 'inline' : 'none',
-
- layerID);
-
- }
-
- }
-
-}
-
-
-
-function toggleBranch(layerID, updateStatus) // OPTIONAL ARGS: noSave = false
-
-{
-
- var currentDisplay = this.getLayer(layerID).style.display;
-
- var newDisplay = (this.branchStatus[layerID] && currentDisplay == 'inline') ? 'none' : 'inline'
-
-
-
- for (var i=0; i<this.layerRelations[layerID].length; i++)
-
- {
-
- if (this.branchStatus[this.layerRelations[layerID][i]])
-
- {
-
- this.toggleBranch(this.layerRelations[layerID][i], false);
-
- }
-
-
-
- this.getLayer(this.layerRelations[layerID][i]).style.display = newDisplay;
-
- }
-
-
-
- if (updateStatus)
-
- {
-
- this.branchStatus[layerID] = !this.branchStatus[layerID];
-
-
-
- /**
-
- * Persistence
-
- */
-
- if (this.doesPersistence() && !arguments[2])
-
- {
-
- this.saveExpandedStatus(layerID, this.branchStatus[layerID]);
-
- }
-
- // Swap image
-
- this.swapImage(layerID);
-
- }
-
-}
-
-
-
-/**
-
-* Swaps the plus/minus branch images
-
-*/
-
-function swapImage(layerID)
-
-{
-
- imgSrc = document.images['img_' + layerID].src;
-
- re = /^(.*)(plus|minus)(bottom|top|single)?.gif$/
-
- if (matches = imgSrc.match(re))
-
- {
-
- document.images['img_' + layerID].src = sprintf('%s%s%s%s',
-
- matches[1],
-
- matches[2] == 'plus' ? 'minus' : 'plus',
-
- matches[3] ? matches[3] : '',
-
- '.gif');
-
- }
-
-}
-
-
-
-/**
-
-* Can the browser handle the dynamic menu?
-
-*/
-
-
-
-function doesMenu()
-
-{
-
- var doc_ieb;
-
- var doc_all;
-
-
-
- // Detect all functions before using them
-
- doc_eib = (document.getElementById) ? true : false;
-
- doc_all = (document.all) ? true : false;
-
-
-
- return (doc_eib || doc_all);
-
-}
-
-
-
-/**
-
-* Can the browser handle save the branch status
-
-*/
-
-function doesPersistence()
-
-{
-
- var doc_ieb;
-
- var doc_all;
-
-
-
- // Detect all functions before using them
-
- doc_eib = (document.getElementById) ? true : false;
-
- doc_all = (document.all) ? true : false;
-
- return (doc_eib && doc_all);
-
-}
-
-
-
-/**
-
-* Returns the appropriate layer accessor
-
-*/
-
-function getLayer(layerID)
-
-{
-
- if (document.getElementById(layerID))
-
- {
-
- return document.getElementById(layerID);
-
- }
-
- else if (document.all(layerID))
-
- {
-
- return document.all(layerID);
-
- }
-
-}
-
-
-
-/**
-
-* Save the status of the layer
-
-*/
-
-function saveExpandedStatus(layerID, expanded)
-
-{
-
- document.all(layerID).setAttribute("expandedStatus", expanded);
-
- document.all(layerID).save(layerID);
-
-}
-
-
-
-/**
-
-* Load the status of the layer
-
-*/
-
-function loadExpandedStatus(layerID)
-
-{
-
- document.all(layerID).load(layerID);
-
- if (val = document.all(layerID).getAttribute("expandedStatus"))
-
- {
-
- return val;
-
- }
-
- else
-
- {
-
- return null;
-
- }
-
-}
-
-
-
-/**
-
-* Reset branch status
-
-*/
-
-function resetBranches()
-
-{
-
- if (!this.doesPersistence())
-
- {
-
- return false;
-
- }
-
-
-
- for (var i=0; i<this.branches.length; i++)
-
- {
-
- var status = this.loadExpandedStatus(this.branches[i]);
-
- // Only update if it's supposed to be expanded and it's not already
-
- if (status == 'true' && this.branchStatus[this.branches[i]] != true)
-
- {
-
- if (this.checkParentVisibility(this.branches[i]))
-
- {
-
- this.toggleBranch(this.branches[i], true, true);
-
- }
-
- else
-
- {
-
- this.branchStatus[this.branches[i]] = true;
-
- this.swapImage(this.branches[i]);
-
- }
-
- }
-
- }
-
-}
-
-
-
-/**
-
-* Checks whether a branch should be open
-
-* or not based on its parents' status
-
-*/
-
-function checkParentVisibility(layerID)
-
-{
-
- if (in_array(this.childParents[layerID], this.branches) && this.branchStatus[this.childParents[layerID]] && this.checkParentVisibility(this.childParents[layerID]))
-
- {
-
- return true;
-
-
-
- } else if (this.childParents[layerID] == null)
-
- {
-
- return true;
-
- }
-
-
-
- return false;
-
-}
-
-
-
-/**
-
-* Javascript mini implementation of sprintf()
-
-*/
-
-function sprintf(strInput)
-
-{
-
- var strOutput = '';
-
- var currentArg = 1;
-
-
-
- for (var i=0; i<strInput.length; i++)
-
- {
-
- if (strInput.charAt(i) == '%' && i != (strInput.length - 1) && typeof(arguments[currentArg]) != 'undefined')
-
- {
-
- switch (strInput.charAt(++i))
-
- {
-
- case 's':
-
- strOutput += arguments[currentArg];
-
- break;
-
- case '%':
-
- strOutput += '%';
-
- break;
-
- }
-
- currentArg++;
-
- }
-
- else
-
- {
-
- strOutput += strInput.charAt(i);
-
- }
-
- }
-
- return strOutput;
-
-}
-
-
-
-function explode(seperator, input)
-
-{
-
- var output = [];
-
- var tmp = '';
-
- skipEmpty = arguments[2] ? true : false;
-
-
-
- for (var i=0; i<input.length; i++)
-
- {
-
- if (input.charAt(i) == seperator)
-
- {
-
- if (tmp == '' && skipEmpty)
-
- {
-
- continue;
-
- }
-
- else
-
- {
-
- output[output.length] = tmp;
-
- tmp = '';
-
- }
-
- }
-
- else
-
- {
-
- tmp += input.charAt(i);
-
- }
-
- }
-
- if (tmp != '' || !skipEmpty)
-
- {
-
- output[output.length] = tmp;
-
- }
-
- return output;
-
-}
-
-
-
-function implode(seperator, input)
-
-{
-
- var output = '';
-
- for (var i=0; i<input.length; i++)
-
- {
-
- if (i == 0)
-
- {
-
- output += input[i];
-
- }
-
- else
-
- {
-
- output += seperator + input[i];
-
- }
-
- }
-
- return output;
-
-}
-
-
-
-function in_array(item, arr)
-
-{
-
- for (var i=0; i<arr.length; i++)
-
- {
-
- if (arr[i] == item)
-
- {
-
- return true;
-
- }
-
- }
-
- return false;
-
-}
-
-</script>
-