Index: admin_menu.js =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/admin_menu/admin_menu.js,v retrieving revision 1.7.2.7.2.18 diff -u -p -r1.7.2.7.2.18 admin_menu.js --- admin_menu.js 20 Feb 2010 23:44:04 -0000 1.7.2.7.2.18 +++ admin_menu.js 12 Mar 2010 05:05:34 -0000 @@ -198,22 +198,59 @@ Drupal.admin.behaviors.hover = function ); } + var maxHeight = $(window).height() - $adminMenu.height(); + $('li.expandable > ul', $adminMenu).mousemove(function (e) { + // Bail out if the hovered link does not belong to this list. + // @todo Better way? + if (e.target.parentNode.parentNode != this) { + return; + } + var $ul = $(this); + var $li = $ul.parent(); + var liOffset = $li.offset().top; + var liHeight = $li.height(); + // @todo This doesn't handle child-child-child-trees. + var multiplier = $ul.height() / maxHeight; + // No animation if the tree fits into the visible viewport. + if (multiplier > 1) { + // @todo Child trees overlay parent trees. + // $ul.css('zIndex', -10); + // Based on the current cursor position, subtract vertical offset of the + // list item, and subtract... + var relativeY = e.pageY - liOffset - liHeight; + // Child trees below a top-level item are positioned below the item, not + // next to it. We therefore have to subtract the list item height. + if (!$li.parents('li.expandable').length) { + relativeY -= liHeight; + } + if (e.pageY > liOffset + liHeight) { + $ul.css('top', liOffset - relativeY); + } + // When reaching the bottom offset of the list item, unset the custom + // positioning. + else { + $ul.css('top', ''); + } + } + }); + return; + // Delayed mouseout. $('li.expandable', $adminMenu).hover( function () { // Stop the timer. clearTimeout(this.sfTimer); // Display child lists. - $('> ul', this) - .css({left: 'auto', display: 'block'}) + $ul = $('> ul', this); + $ul.css({left: 'auto', display: 'block'}) // Immediately hide nephew lists. .parent().siblings('li').children('ul').css({left: '-999em', display: 'none'}); }, function () { // Start the timer. - var uls = $('> ul', this); + var $ul = $('> ul', this); this.sfTimer = setTimeout(function () { - uls.css({left: '-999em', display: 'none'}); + $ul.css({left: '-999em', display: 'none'}); }, 400); } );