mirror of
https://github.com/lucaspalomodevelop/core.git
synced 2026-03-19 19:15:22 +00:00
196 lines
4.8 KiB
JavaScript
196 lines
4.8 KiB
JavaScript
/*
|
|
* 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);
|