varTree={/** default class name for root ul */TREE:"tree",/** default class name for li with hidden list */MORE:"plus",/** default class name for li with visible list */LESS:"minus",/** default class name for clicked link */HERE:"here",/** default id where to put the toc */TOC:"toc",/** default id where to fin titles */ARTICLE:"article",ini:function(){if(Tree.reLessmore)return;Tree.reLessmore=newRegExp(" *("+Tree.LESS+"|"+Tree.MORE+") *","gi");Tree.reHere=newRegExp(" *("+Tree.HERE+") *","gi");},create:function(nav,article){Tree.ini();// en onload, FF passe l'événement
if(nav&&nav.stopPropagation){nav=null;article=null;}// if nothing provide, try default
if(!nav)nav=document.getElementById(Tree.TOC);if(!article)article=document.getElementById(Tree.ARTICLE);// nothing to do, go out
if(!nav)return;// seems ids
if(nav.nodeType!=1)nav=document.getElementById(nav);if(!nav)return;if(article&&article.nodeType!=1)article=document.getElementById(article);if(!article)article=document.getElementsByTagName("body")[0];// Get the list of headers <h>
varhList=Tree.getElementsByTagRE(/\bH[1-9]\b/i,article);// if very few headers, go out
if(hList.length<3)return;// create the root element, and be sur to keep a hand on it
if(document.createElementNS)vartree=document.createElementNS("http://www.w3.org/1999/xhtml",'div');elsevartree=document.createElement('div');tree.className="autotoc "+Tree.TREE;// the current list to which append items
varul=tree;// current item
varli;// current item
varlevel=1;// number of level visible
varlevel_plus=0;// loop on header
for(vari=0;i<hList.length; ++i){// the link
if(document.createElementNS)vara=document.createElementNS("http://www.w3.org/1999/xhtml",'a');elsevara=document.createElement('a');// take id of header if available
varid=hList[i].id;// if not, build an automatic id
if(!id){id="h_"+i;hList[i].id=id;}a.href="#"+id;// just the text of the header (without tags)
if(hList[i].textContent){a.textContent=hList[i].textContent;}elseif(hList[i].innerText){a.innerText=hList[i].innerText;}// Now build ul/li according to the level of the title
varhn=Number(hList[i].nodeName.substring(1));// current level deeper than last one, inser a list in last item
if(hn>level){if(document.createElementNS)ul=document.createElementNS("http://www.w3.org/1999/xhtml",'ul');elseul=document.createElement('ul');// deeper than visible levels
if(li&&level>level_plus)li.className+=" "+Tree.MORE;// append list to last item
if(li)li.appendChild(ul);}// current level higher than last one, catch the relevant list where to append item
elseif(hn<level){for(varj=level-hn;j>0;j--){if(ul&&ul.parentNode&&ul.parentNode.parentNode&&ul.parentNode.parentNode.nodeName.toLowerCase()=="ul")ul=ul.parentNode.parentNode;elsebreak;}}// changer le niveau courant
level=hn;// container is a div, probably root h1
if(ul.nodeName.toLowerCase()=='div'){if(document.createElementNS)li=document.createElementNS("http://www.w3.org/1999/xhtml",'header');elseli=document.createElement('header');// append link
li.appendChild(a);// append current item in the right list level
ul.appendChild(li);// add children list as sibling (not child)
li=ul;continue;}// create current item
if(document.createElementNS)li=document.createElementNS("http://www.w3.org/1999/xhtml",'li');elseli=document.createElement('li');// add an event on all li to have a selected class effect
li.onclick=function(e){returnTree.click(this,e);}// set a class for header level
li.className=li.className+" "+hList[i].nodeName.toLowerCase();// append link
li.appendChild(a);// append current item in the right list level
ul.appendChild(li);}// Attach the tree
nav.appendChild(tree);},/** Last li clicked */here:"",loaded:false,load:function(id,href){Tree.ini();// compile Regexp
// page address without ?query= or #hash
if(!href)href=location.protocol+"//"+location.host+location.pathname;// on FF and onload, test if root is not an event
// instanceof do not work on IE
if(id&&id.stopPropagation){id=null;}root=id;if(id&&typeofid=='string')root=document.getElementById(id);if(!root&&document)root=document.documentElement;// case seems sometimes significant
varreHereDel=newRegExp(' *'+Tree.HERE+' *');varnodeset=root.getElementsByTagName("li");for(vari=0;i<nodeset.length; ++i){li=nodeset[i];li.onclick=function(e){returnTree.click(this,e);}// hilite current link in this item
varlinks=li.getElementsByTagName("a");for(varj=0;j<links.length;j++){a=links[j];// avoid .../n2 = .../n20
// alert(a.href.replace(/\/$/, '')+'/'+' '+href.indexOf(a.href.replace(/\/$/, '')+'/'));
if(href.indexOf(a.href.replace(/\/$/,'')+'/')!==0&&(a.href+'/').indexOf(href+'/')!==0)continue;// open parents
Tree.open(li);// class on li or a ?
if(a.className.indexOf(Tree.HERE)!=-1)a.className=a.className.replace(reHereDel,'');a.className += " "+Tree.HERE;// bout de branche
if(li.getElementsByTagName("li").length==0){if(li.className.indexOf(Tree.HERE)!=-1)li.className=li.className.replace(reHereDel,'');li.className += " "+Tree.HERE;}}}Tree.loaded=true;},click:function(li,e){Tree.ini();// useful for lists with inline event onclick to have REgExp
if(Tree.className!=null)li=this;if(!li)returnfalse;varret=false;varclassName="";if(li.className.indexOf(Tree.LESS)>-1)className=" "+Tree.MORE;elseif(li.className.indexOf(Tree.MORE)>-1)className=" "+Tree.LESS;// if click in a link, force open
varev=e||event,src=ev.target||ev.srcElement;while(src&&src.tagName.toLowerCase()!="li"){if(src.tagName.toLowerCase()=='a'){className=" "+Tree.LESS;ret=true;// hilite the clicked item
if(Tree.a)Tree.a.className=Tree.a.className.replace(Tree.reHere,' ');src.className=src.className.replace(Tree.reHere,' ')+" "+Tree.HERE;Tree.a=src;break;}src=src.parentNode;}// change class only if already less or more
if(li.className.search(Tree.reLessmore)>-1)li.className=li.className.replace(Tree.reLessmore,' ')+className;// stop propagation
if(ev&&document.all)ev.cancelBubble=true;if(ev&&ev.stopPropagation)ev.stopPropagation();returnret;},open:function(){varli;// don't forget or may produce some strange var collapse
for(i=arguments.length-1;i>=0;i--){li=arguments[i];if(li.className==null)li=document.getElementById(arguments[i]);if(!li)continue;while(li&&li.tagName.toLowerCase()=='li'){// avoid icon in front of single item
if(li.className.match(Tree.reLessmore)||li.getElementsByTagName('UL').length>0)li.className=li.className.replace(Tree.reLessmore,' ')+" "+Tree.LESS;li=li.parentNode.parentNode;// get a possible li ancestor (jump an ul container)
}}},getElementsByTagRE:function(re,node){if(!node)node=document.getElementsByTagName("BODY")[0];// array of nodes to filter
varnodeset=node.getElementsByTagName("*");if(!re||re=="*")returnnodeset;if(!re.test)re=newRegExp(re);re.ignoreCase=true;// array to return
varselect=[];for(i=0;i<nodeset.length; ++i)if(re.test(nodeset[i].nodeName.toLowerCase()))select.push(nodeset[i]);returnselect;},props:function(o){tmp='';for(xino)tmp += x+" ";// ": " + o[x] + "\n";
alert(tmp);}}// if loaded as bottom script, create trees ?
if(window.document.body){// Tree.create("toc");
// Tree.load("nav");
}else{if(window.addEventListener){if(!Tree.loaded)window.addEventListener('load',Tree.load,false);window.addEventListener('load',Tree.create,false);}elseif(window.attachEvent){if(!Tree.loaded)window.attachEvent('onload',Tree.load);window.attachEvent('onload',Tree.create);}}