var menuData =
{
// construction du menu en notation JSON
menuObject : [
],
// méthodes de construction du menu en HTML
referenceChannel : undefined,
anchorElement : undefined,
focusedElement : undefined,
channelIDSelected : undefined,
hasVisibleNodeChildren : false,
buildMenu : function(elt, visibleNode)
{
var frag = document.createDocumentFragment();
var oldNode = elt.cloneNode(false);
menuData.anchorElement = oldNode;
menuData.channelIDSelected = visibleNode ;
//menuData.buildSubMenu(elt, menuData.menuObject, 1);
menuData.buildSubMenu(oldNode, menuData.menuObject, 1);
frag.appendChild(oldNode);
elt.parentNode.replaceChild(frag,elt);
menuData.anchorElement.select("li.extensible").each(function(item) {
item.addClassName("collapsed");
item.addClassName("collapsed-level"+item.level);
});
var referenceChannel= $(visibleNode);
menuData.focusedElement = referenceChannel;
if (referenceChannel != undefined && referenceChannel != null)
{
level = referenceChannel.level ;
if ( ! menuData.hasVisibleNodeChildren && (level == 2 || level == 3 || level == 4))
referenceChannel.addClassName("focusedLevel"+level) ;
else if (level == 1)
referenceChannel.addClassName("focused");
if (!referenceChannel.hasClassName("extensible"))
referenceChannel = referenceChannel.up("li.extensible");
if (referenceChannel != undefined)
{
referenceChannel.expandMenu();
menuData.referenceChannel = referenceChannel;
}
}
menuData.anchorElement.observe("click", menuClickObserver);
$(document).observe("mouseover", menuOverObserver);
},
buildSubMenu : function(elt, children, level)
{
var ul = new Element("ul");
children.each(function(item) {
var li = new Element("li", {id : item.id});
li.level=level;
if (item.children.length > 0)
{
if (item.id == menuData.channelIDSelected)
menuData.hasVisibleNodeChildren = true ;
li.update("
"+item.label+"
");
li.addClassName("extensible");
li.collapseMenu=menuFct.collapseMenu;
li.expandMenu=menuFct.expandMenu;
var subUl = menuData.buildSubMenu(li, item.children, level+1);
subUl.hide();
}
else
li.update(""+item.label+"
");
ul.insert(li);
});
elt.insert(ul);
return ul;
}
};
var menuFct =
{
collapseMenu : function ()
{
var elt = $(this);
if (elt.hasClassName("collapsed"))
return;
elt.removeClassName("expanded");
elt.removeClassName("expanded-level"+elt.level);
elt.addClassName("collapsed");
elt.addClassName("collapsed-level"+elt.level);
var toHide = elt.childElements()[1];
Effect.BlindUp(toHide, { duration: 0.2 });
// collapse children recursively
elt.select('li.expanded').each(function(child)
{
child.collapseMenu() ;
}) ;
},
expandMenu : function ()
{
var elt = $(this);
// expand if not done yet
if (!elt.hasClassName("expanded"))
{
elt.addClassName("expanded");
elt.addClassName("expanded-level"+elt.level);
elt.removeClassName("collapsed");
elt.removeClassName("collapsed-level"+elt.level);
var toShow = elt.childElements()[1];
Effect.BlindDown(toShow, { duration: 0.3 });
}
// collapse sibblings
elt.siblings().each(function(sib) {
if (sib.match("li.extensible", "expanded"))
sib.collapseMenu();
});
// expand father recursively
var fatherToExpand = elt.up('.extensible');
if (fatherToExpand != undefined)
fatherToExpand.expandMenu();
}
};
var backToRefID = null;
function menuOverObserver(e)
{
var element = Event.element(e);
if (element.descendantOf(menuData.anchorElement)) // Over menu
{
// Just entered -> Cancel the back to reference channel callback
if (backToRefID != null) {
clearTimeout(backToRefID);
backToRefID = null;
}
}
// Not over menu and trigger not set yet
else if (backToRefID == null)
{
// Trigger the back to reference channel callback
backToRefID = setTimeout(function()
{
// open the reference node
if (menuData.referenceChannel != undefined)
{
menuData.referenceChannel.expandMenu();
// collpase the children of the reference element
menuData.referenceChannel.select('.expanded').each(function(child)
{
child.collapseMenu() ;
}) ;
}
// collapse the brothers of the active element
if (menuData.focusedElement != undefined)
{
menuData.focusedElement.siblings().each(function(sib) {
if (sib.match("li.extensible", "expanded"))
sib.collapseMenu() ;
}) ;
}
}, 5000);
}
}
function menuClickObserver(e)
{
var elt = Event.element(e);
// Skip links
if (elt.match("a div")||elt.match("a")) return;
// Get the first extensible parent
var extensibleParent = elt.match("li.extensible")?elt:elt.up("li.extensible");
// If not found, we're not in the menu
if (extensibleParent == undefined) return;
if (extensibleParent.expandMenu != undefined) // If found
{
if (extensibleParent.hasClassName("expanded"))
extensibleParent.collapseMenu();
else
extensibleParent.expandMenu();
e.stop();
}
}