// $Id: dhtml_menu.js,v 1.49 2009/11/12 21:47:59 arancaytar Exp $ /** * @file dhtml_menu.js * The Javascript code for DHTML Menu */ (function($) { Drupal.dhtmlMenu = {}; Drupal.dhtmlMenu.animation = {show:{}, hide:{}, count:0}; /** * Initialize the module's JS functions */ Drupal.behaviors.dhtmlMenu = { attach: function() { var settings = Drupal.settings.dhtmlMenu; // Initialize the animation effects from the settings. for (i in settings.animation.effects) { if (settings.animation.effects[i]) { Drupal.dhtmlMenu.animation.show[i] = 'show'; Drupal.dhtmlMenu.animation.hide[i] = 'hide'; Drupal.dhtmlMenu.animation.count++; } } // Sanitize by removing "expanded" on menus already marked "collapsed". $('li.dhtml-menu.collapsed.expanded').removeClass('expanded'); /* Relevant only on "open-only" menus: * The links of expanded items should be marked for emphasis. */ if (settings.nav == 'open') { $('li.dhtml-menu.expanded').addClass('dhtml-menu-open'); } /* Relevant only when hovering: * * If a context menu is opened (as most users do when opening links in a * new tab), the mouseleave event will be triggered. Although the context * menu still works, having the menu close underneath it is confusing. * * This code will "freeze" the menu's collapse if the body is left * (which happens when a context menu opens), and only release it when the cursor * reenters the menu. * * Note that due to the order in which events are called, * the hovering collapse must work asynchronously so * this event is triggered before the collapse. */ else if (settings.nav == 'hover') { var freeze = false; $('ul.menu').mouseenter(function() {freeze = false}); $('body').mouseleave(function() {freeze = true}); } /* Relevant only on bullet-icon expansion: * Create the markup for the bullet overlay, and the amount to shift it to the right in RTL mode. */ else if (settings.nav == 'bullet') { var bullet = $(''); var rtl = $('html').attr('dir') == 'rtl' ? Math.ceil($('.menu li').css('margin-right').replace('px', '')) + 1 : 0; } /* Relevant only when adding cloned links: * Create the markup for the cloned list item container. */ else if (settings.nav == 'clone') { // Note: a single long class is used here to avoid matching the .dhtml-menu.leaf selector later on. var cloned = $('
  • '); } /* Add jQuery effects and listeners to all menu items. */ $('ul.menu li.dhtml-menu:not(.leaf)').each(function() { var li = $(this); var link = $(this).find('a:first'); var ul = $(this).find('ul:first'); // Only work on menus with an actual sub-menu. if (link.length && ul.length) { /* When using cloned items: * - Clone the menu link and mark it as a clone. */ if (settings.nav == 'clone') { link.clone().prependTo(ul).wrap(cloned); } /* When using double-click: * - Add a dblclick event handler that allows the normal link action to complete. */ else if (settings.nav == 'doubleclick') { link.dblclick(function(e) { return true; }); } /* When using bullet expansion: * - Change the icon to a folder image * - Add the clickable overlay and its handler * - In RTL mode, shift the overlay to the right of the text. * - @TODO: Explore whether "float:right" in dhtml_menu-rtl.css could solve this. */ else if (settings.nav == 'bullet') { li.addClass('dhtml-folder'); var b = bullet.clone().prependTo(link).click(function(e) { Drupal.dhtmlMenu.toggleMenu(li, link, ul); if (settings.effects.remember) { Drupal.dhtmlMenu.cookieSet(); } return false; }); // When using RTL, each overlay must be shifted to the other side of the link text, individually. if (rtl) { // Shift the overlay right by the width of the text and the distance between text and icon. b.css('right', '-' + (Math.ceil(link.css('width').replace('px', '')) + rtl) + 'px'); } } /* When using hover expansion: * - Add mouse-hovering events. */ else if (settings.nav == 'hover') { link.mouseenter(function(e) { Drupal.dhtmlMenu.switchMenu(li, link, ul, true); }); li.mouseleave(function(e) { // Only collapse the menu if it was initially collapsed. if (li.hasClass('start-collapsed')) { /* As explained earlier, this event fires before the body event. * We need to wait to make sure that the user isn't browsing a * context menu right now, in which case the menu isn't collapsed. */ setTimeout(function() { if (!freeze) { Drupal.dhtmlMenu.switchMenu(li, link, ul, false); } }, 10); } }); } /* When using menus that cannot collapse: * Toggle the menu normally, but only if the menu is closed. */ else if (settings.nav == 'open') { link.click(function(e) { // Don't collapse expanded menus. if (li.hasClass('expanded')) { return true; } Drupal.dhtmlMenu.toggleMenu(li, link, ul); $('.dhtml-menu-open').removeClass('dhtml-menu-open'); $('li.dhtml-menu.expanded').addClass('dhtml-menu-open'); return false; }); } // These three options make links simply toggle when clicked. if (settings.nav == 'clone' || settings.nav == 'doubleclick' || settings.nav == 'none') { link.click(function(e) { Drupal.dhtmlMenu.toggleMenu(li, link, ul); if (settings.effects.remember) { Drupal.dhtmlMenu.cookieSet(); } return false; }); } } }); // When using LTR, all icons can be shifted as one, as the text width is not relevant. if (settings.nav == 'bullet' && !rtl) { // Shift overlay to the left by the width of the icon and the distance between icon and text. var shift = '-' + (Math.ceil(($('.menu li').css('margin-left').replace('px', ''))) + 16) + 'px'; // Shift the overlay using a negative left-hand offset, and the text using a negative right-hand margin. $('.dhtml-menu-icon').css('left', shift).css('margin-right', shift); } } } /** * Toggles the menu's state between open and closed. * * @param li * Object. The
  • element that will be expanded or collapsed. * @param link * Object. The element representing the menu link anchor. * @param ul * Object. The