Index: dhtml_menu.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/dhtml_menu/dhtml_menu.module,v
retrieving revision 1.29.2.18
diff -u -p -r1.29.2.18 dhtml_menu.module
--- dhtml_menu.module	9 Apr 2009 18:06:53 -0000	1.29.2.18
+++ dhtml_menu.module	3 Jun 2009 12:58:34 -0000
@@ -101,14 +106,10 @@ function dhtml_menu_theme_menu_item($lin
    * rendered already. Since we are done on this recursion level,
    * one element must be popped off the stack.
    */
-  $stack = _dhtml_menu_stack();
-
-  // Move to the last element in the stack (the current item).
-  end($stack);
+  $item = _dhtml_menu_stack();
 
   // If this item should not have DHTML, then return to the "parent" function.
-  $current = current($stack);
-  if (!empty($current['dhtml_disabled'])) {
+  if (!empty($item['dhtml_disabled'])) {
     $extra_class .= ' no-dhtml ';
     return $function($link, $has_children, $menu, $in_active_trail, $extra_class);
   }
@@ -118,7 +119,7 @@ function dhtml_menu_theme_menu_item($lin
   // If there are children, but they were not loaded...
   if ($has_children && !$menu) {
     // Load the tree below the current position.
-    $tree = _dhtml_menu_subtree($stack);
+    $tree = _dhtml_menu_subtree($item);
 
     // Render it...
     $menu = menu_tree_output($tree);
@@ -126,7 +127,7 @@ function dhtml_menu_theme_menu_item($lin
   }
 
   // If the current item can expand, and is neither saved as open nor in the active trail, close it.
-  if ($menu && !($in_active_trail || in_array(substr(key($stack), 5), $cookie))) {
+  if ($menu && !($in_active_trail || in_array(substr($item['options']['attributes']['id'], 5), $cookie))) {
     $extra_class .= ' collapsed start-collapsed ';
   }
 
@@ -146,12 +147,10 @@ function dhtml_menu_theme_menu_item($lin
 function _dhtml_menu_stack($link = FALSE) {
   static $stack = array();
   if ($link) {
-    $stack[$link['localized_options']['attributes']['id']] = $link;
+    array_push($stack, $link);
   }
   else {
-    $copy = $stack;
-    array_pop($stack);
-    return $copy;
+    return array_pop($stack);
   }
 }
 
@@ -159,39 +158,34 @@ function _dhtml_menu_stack($link = FALSE
  * Traverses the menu tree and returns the sub-tree of the item
  * indicated by the parameter.
  *
- * @param $stack
- *   An array of menu item links that are nested in each other in the tree.
+ * @param $item
+ *   An menu item whose children should be found.
  *
  * @return
- *   The items below the lowest item in the stack.
+ *   The items below the passed menu item.
  */
-function _dhtml_menu_subtree($stack) {
+function _dhtml_menu_subtree($item) {
   static $index = array();
   static $indexed = array();
 
-  reset($stack);
-  $start = current($stack);
-
   // This looks expensive, but menu_tree_all_data uses static caching.
-  $tree = menu_tree_all_data($start['menu_name']);
+  $tree = menu_tree_all_data($item['menu_name']);
 
-  if (!isset($indexed[$start['menu_name']])) {
+  // Index the tree to find the path to this item.
+  if (!isset($indexed[$item['menu_name']])) {
     $index += _dhtml_menu_index($tree);
-    $indexed[$start['menu_name']] = TRUE;
+    $indexed[$item['menu_name']] = TRUE;
   }
-
   // Traverse the tree.
-  foreach ($stack as $item) {
-    $key = $index[$item['mlid']];
+  foreach ($index[$item['mlid']]['parents'] as $mlid) {
+    $key = $index[$mlid]['key'];
     if (!isset($tree[$key])) {
-      if (is_array($tree)) {
-        $tree = $tree[key($tree)]['below'];
-      }
-      if (!isset($tree[$key])) return array();
+      return array();
     }
     $tree = $tree[$key]['below'];
   }
-  return is_array($tree) ? $tree : array();
+  $key = $index[$item['mlid']]['key'];
+  return isset($tree[$key]) ? $tree[$key]['below'] : array();
 }
 
 /**
@@ -204,12 +198,16 @@ function _dhtml_menu_subtree($stack) {
  * @return
  *   An array associating mlid values with the internal keys of the menu tree.
  */
-function _dhtml_menu_index($tree) {
+function _dhtml_menu_index($tree, $ancestors = array(), $parent = NULL) {
   $index = array();
+  if ($parent) $ancestors[] = $parent;
   foreach ($tree as $key => $item) {
-    $index[$item['link']['mlid']] = $key;
+    $index[$item['link']['mlid']] = array(
+      'key' => $key,
+      'parents' => $ancestors,
+    );
     if (!empty($item['below'])) {
-      $index += _dhtml_menu_index($item['below']);
+      $index += _dhtml_menu_index($item['below'], $ancestors, $item['link']['mlid']);
     }
   }
   return $index;
