Index: dhtml_menu.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/dhtml_menu/dhtml_menu.module,v
retrieving revision 1.29.2.1
diff -u -p -r1.29.2.1 dhtml_menu.module
--- dhtml_menu.module	18 Jul 2008 20:13:06 -0000	1.29.2.1
+++ dhtml_menu.module	4 Nov 2008 02:23:45 -0000
@@ -45,10 +45,11 @@ function dhtml_menu_theme_registry_alter
  * follow the recursion of menu_tree_output().
  */
 function dhtml_menu_theme_menu_item_link($link) {
-  // The ID is the mlid or a stripped form of the link path. It just must be unique.
-  $id = isset($link['mlid']) ? $link['mlid'] : preg_replace('/[^a-z0-9]/', '0', $link['href']);
-  $link['localized_options']['attributes']['id'] = "menu-". $id;
+  if (!isset($link['menu_name']) || !isset($link['mlid'])) return theme_menu_item_link($link);
 
+  // TODO: When the menu appears multiple times on a page, validation breaks.
+  $link['localized_options']['attributes']['id'] = "menu-". $link['mlid'];
+  
   // Each link in series is another level of recursion. Add it to the stack.
   _dhtml_menu_stack($link);
 
@@ -126,16 +127,23 @@ function _dhtml_menu_stack($link = FALSE
  *   The items below the lowest item in the stack.
  */
 function _dhtml_menu_subtree($stack) {
+  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']);
-  foreach ($stack as $item) {
-    // Generate the sortable array key of an item:
-    $path[] = (50000 + $item['weight']) .' '. $item['title'] .' '. $item['mlid'];
+
+  if (!isset($indexed[$start['menu_name']])) {
+    $index += _dhtml_menu_index($tree);
+    $indexed[$start['menu_name']] = TRUE;
   }
 
   // Traverse the tree.
-  foreach ($path as $key) {
+  foreach ($stack as $item) {
+    $key = $index[$item['mlid']];
     if (!isset($tree[$key])) {
       $tree = $tree[key($tree)]['below'];
       if (!isset($tree[$key])) return array();
@@ -146,6 +154,27 @@ function _dhtml_menu_subtree($stack) {
 }
 
 /**
+ * Indexes the menu tree by mlid. This is needed to identify the items
+ * without relying on titles. This function is recursive.
+ *
+ * @param $tree
+ *   A tree of menu items such as the return value of menu_tree_all_data()
+ *
+ * @return
+ *   An array associating mlid values with the internal keys of the menu tree.
+ */
+function _dhtml_menu_index($tree) {
+  $index = array();
+  foreach ($tree as $key => $item) {
+    $index[$item['link']['mlid']] = $key;
+    if (!empty($item['below'])) {
+      $index += _dhtml_menu_index($item['below']);
+    }
+  }
+  return $index;
+}
+
+/**
  * Implementation of hook_menu().
  * Adds a settings page.
  */
