summaryrefslogtreecommitdiffstats
path: root/src/usr/local/www/tree/tree.js
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr/local/www/tree/tree.js')
-rw-r--r--src/usr/local/www/tree/tree.js195
1 files changed, 195 insertions, 0 deletions
diff --git a/src/usr/local/www/tree/tree.js b/src/usr/local/www/tree/tree.js
new file mode 100644
index 0000000..8e9651e
--- /dev/null
+++ b/src/usr/local/www/tree/tree.js
@@ -0,0 +1,195 @@
+/*
+ * Content-separated javascript tree widget
+ * Copyright (C) 2005 SilverStripe Limited
+ * Feel free to use this on your websites, but please leave this message in the fies
+ * http://www.silverstripe.com/blog
+*/
+
+/*
+ * Initialise all trees identified by <ul class="tree">
+ */
+function autoInit_trees() {
+ var candidates = document.getElementsByTagName('ul');
+ for(var i=0;i<candidates.length;i++) {
+ if(candidates[i].className && candidates[i].className.indexOf('tree') != -1) {
+ initTree(candidates[i]);
+ candidates[i].className = candidates[i].className.replace(/ ?unformatted ?/, ' ');
+ }
+ }
+}
+
+/*
+ * Initialise a tree node, converting all its LIs appropriately
+ */
+function initTree(el) {
+ var i,j;
+ var spanA, spanB, spanC;
+ var startingPoint, stoppingPoint, childUL;
+
+ // Find all LIs to process
+ for(i=0;i<el.childNodes.length;i++) {
+ if(el.childNodes[i].tagName && el.childNodes[i].tagName.toLowerCase() == 'li') {
+ var li = el.childNodes[i];
+
+ // Create our extra spans
+ spanA = document.createElement('span');
+ spanB = document.createElement('span');
+ spanC = document.createElement('span');
+ spanA.appendChild(spanB);
+ spanB.appendChild(spanC);
+ spanA.className = 'a ' + li.className.replace('closed','spanClosed');
+ spanA.onMouseOver = function() {};
+ spanB.className = 'b';
+ spanB.onclick = treeToggle;
+ spanC.className = 'c';
+
+
+ // Find the UL within the LI, if it exists
+ stoppingPoint = li.childNodes.length;
+ startingPoint = 0;
+ childUL = null;
+ for(j=0;j<li.childNodes.length;j++) {
+ if(li.childNodes[j].tagName && li.childNodes[j].tagName.toLowerCase() == 'div') {
+ startingPoint = j + 1;
+ continue;
+ }
+
+ if(li.childNodes[j].tagName && li.childNodes[j].tagName.toLowerCase() == 'ul') {
+ childUL = li.childNodes[j];
+ stoppingPoint = j;
+ break;
+ }
+ }
+
+ // Move all the nodes up until that point into spanC
+ for(j=startingPoint;j<stoppingPoint;j++) {
+ spanC.appendChild(li.childNodes[startingPoint]);
+ }
+
+ // Insert the outermost extra span into the tree
+ if(li.childNodes.length > startingPoint) li.insertBefore(spanA, li.childNodes[startingPoint]);
+ else li.appendChild(spanA);
+
+ // Process the children
+ if(childUL != null) {
+ if(initTree(childUL)) {
+ addClass(li, 'children', 'closed');
+ addClass(spanA, 'children', 'spanClosed');
+ }
+ }
+ }
+ }
+
+ if(li) {
+ // li and spanA will still be set to the last item
+
+ addClass(li, 'last', 'closed');
+ addClass(spanA, 'last', 'spanClosed');
+ return true;
+ } else {
+ return false;
+ }
+
+}
+
+
+/*
+ * +/- toggle the tree, where el is the <span class="b"> node
+ * force, will force it to "open" or "close"
+ */
+function treeToggle(el, force) {
+ el = this;
+
+ while(el != null && (!el.tagName || el.tagName.toLowerCase() != "li")) el = el.parentNode;
+
+ // Get UL within the LI
+ var childSet = findChildWithTag(el, 'ul');
+ var topSpan = findChildWithTag(el, 'span');
+
+ if( force != null ){
+
+ if( force == "open"){
+ treeOpen( topSpan, el );
+ }
+ else if( force == "close" ){
+ treeClose( topSpan, el );
+ }
+
+ }
+
+ else if( childSet != null) {
+ // Is open, close it
+ if(!el.className.match(/(^| )closed($| )/)) {
+ treeClose( topSpan, el );
+ // Is closed, open it
+ } else {
+ treeOpen( topSpan, el );
+ }
+ }
+}
+
+
+function treeOpen( a, b ){
+ removeClass(a,'spanClosed');
+ removeClass(b,'closed');
+}
+
+
+function treeClose( a, b ){
+ addClass(a,'spanClosed');
+ addClass(b,'closed');
+}
+
+/*
+ * Find the a child of el of type tag
+ */
+function findChildWithTag(el, tag) {
+ for(var i=0;i<el.childNodes.length;i++) {
+ if(el.childNodes[i].tagName != null && el.childNodes[i].tagName.toLowerCase() == tag) return el.childNodes[i];
+ }
+ return null;
+}
+
+/*
+ * Functions to add and remove class names
+ * Mac IE hates unnecessary spaces
+ */
+function addClass(el, cls, forceBefore) {
+ if(forceBefore != null && el.className.match(new RegExp('(^| )' + forceBefore))) {
+ el.className = el.className.replace(new RegExp("( |^)" + forceBefore), '$1' + cls + ' ' + forceBefore);
+
+ } else if(!el.className.match(new RegExp('(^| )' + cls + '($| )'))) {
+ el.className += ' ' + cls;
+ el.className = el.className.replace(/(^ +)|( +$)/g, '');
+ }
+}
+function removeClass(el, cls) {
+ var old = el.className;
+ var newCls = ' ' + el.className + ' ';
+ newCls = newCls.replace(new RegExp(' (' + cls + ' +)+','g'), ' ');
+ el.className = newCls.replace(/(^ +)|( +$)/g, '');
+}
+
+/*
+ * Handlers for automated loading
+ */
+ _LOADERS = Array();
+
+function callAllLoaders() {
+ var i, loaderFunc;
+ for(i=0;i<_LOADERS.length;i++) {
+ loaderFunc = _LOADERS[i];
+ if(loaderFunc != callAllLoaders) loaderFunc();
+ }
+}
+
+function appendLoader(loaderFunc) {
+ if(window.onload && window.onload != callAllLoaders)
+ _LOADERS[_LOADERS.length] = window.onload;
+
+ window.onload = callAllLoaders;
+
+ _LOADERS[_LOADERS.length] = loaderFunc;
+}
+
+appendLoader(autoInit_trees);
OpenPOWER on IntegriCloud