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 00:25:09 -0000
@@ -198,22 +198,56 @@ Drupal.admin.behaviors.hover = function 
     );
   }
 
+  var maxHeight = $(window).height() - 50;
+  $('li.expandable', $adminMenu).hover(
+    function () {
+      var $li = $(this);
+      var $uls = $li.find('> ul');
+      // make sure there is enough room at the bottom
+      var height = $uls.height() * 1.1;
+      // needs to move faster if list is taller
+      var multiplier = height / maxHeight;
+      // need to save height here so it can revert on mouseout.
+      $li.data('origHeight', $li.height());
+      // make sure dropdown appears directly below parent list item.
+      $uls.show().css({ paddingTop: $li.data('origHeight') });
+      // don't do any animation if list shorter than max.
+      if (multiplier > 1) {
+        $li.css({ height: maxHeight, overflow: 'hidden' })
+          .mousemove(function(e) {
+            var offset = $li.offset();
+            var relativeY = ((e.pageY - offset.top) * multiplier) - ($li.data('origHeight') * multiplier);
+            if (relativeY > $li.data('origHeight')) {
+              $uls.css('top', -relativeY + $li.data('origHeight'));
+            };
+          });
+      }
+    },
+    function () {
+      // put things back to normal
+      $(this).height($(this).data('origHeight'))
+        .find('ul').css({ top: 0 }).hide();
+    }
+  );
+  return;
+
+
   // Delayed mouseout.
   $('li.expandable', $adminMenu).hover(
     function () {
       // Stop the timer.
       clearTimeout(this.sfTimer);
       // Display child lists.
-      $('> ul', this)
-        .css({left: 'auto', display: 'block'})
+      $uls = $('> ul', this);
+      $uls.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 $uls = $('> ul', this);
       this.sfTimer = setTimeout(function () {
-        uls.css({left: '-999em', display: 'none'});
+        $uls.css({left: '-999em', display: 'none'});
       }, 400);
     }
   );
