Index: CHANGELOG.txt
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/admin_menu/CHANGELOG.txt,v
retrieving revision 1.33.2.48.2.44
diff -u -p -r1.33.2.48.2.44 CHANGELOG.txt
--- CHANGELOG.txt	23 Jul 2009 10:52:40 -0000	1.33.2.48.2.44
+++ CHANGELOG.txt	23 Jul 2009 22:36:35 -0000
@@ -6,6 +6,7 @@ Admin Menu x.x-x.x, xxxx-xx-xx
 
 Admin Menu 6.x-3.x, xxxx-xx-xx
 ------------------------------
+#527908 by markus_petrux, sun: Changed admin menu into a renderable array.
 #420812 by sun, smk-ka: Added support for hook_js().
 by sun: Fixed destination query string of current page not applied to links.
 by sun: Changed Drupal.admin.attachBehaviors() to accept local JS settings.
Index: admin_menu.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/admin_menu/admin_menu.inc,v
retrieving revision 1.11.2.20.2.19
diff -u -p -r1.11.2.20.2.19 admin_menu.inc
--- admin_menu.inc	22 Jul 2009 20:33:17 -0000	1.11.2.20.2.19
+++ admin_menu.inc	23 Jul 2009 22:46:26 -0000
@@ -3,10 +3,46 @@
 
 /**
  * @file
- * Menu build functions for Administration menu.
+ * Menu builder functions for Administration menu.
  */
 
 /**
+ * Build the administration menu as renderable menu links.
+ *
+ * @param $tree
+ *   A data structure representing the administration menu tree as returned from
+ *   menu_tree_all_data().
+ *
+ * @return
+ *   The complete administration menu, suitable for theme_admin_menu_links().
+ *
+ * @see theme_admin_menu_links()
+ * @see admin_menu_menu_alter()
+ */
+function admin_menu_links_menu($tree) {
+  $links = array();
+  foreach ($tree as $data) {
+    // Skip menu callbacks (mostly dynamic items).
+    if (isset($data['link']['type']) && $data['link']['type'] == MENU_CALLBACK) {
+      continue;
+    }
+    // Omit alias lookups.
+    $data['link']['localized_options']['alias'] = TRUE;
+
+    $links[$data['link']['mlid']] = array(
+      '#title' => $data['link']['title'],
+      '#href' => $data['link']['href'],
+      '#options' => $data['link']['localized_options'],
+      '#weight' => $data['link']['weight'],
+    );
+    if ($data['below']) {
+      $links[$data['link']['mlid']] += admin_menu_links_menu($data['below']);
+    }
+  }
+  return $links;
+}
+
+/**
  * Build icon menu links; mostly containing maintenance helpers.
  *
  * @see theme_admin_menu_links()
@@ -15,7 +51,8 @@ function admin_menu_links_icon() {
   $destination = drupal_get_destination();
 
   $links = array(
-    '#weight' => -10,
+    '#theme' => 'admin_menu_links',
+    '#weight' => -100,
   );
   $links['icon'] = array(
     '#title' => theme('admin_menu_icon'),
@@ -108,7 +145,7 @@ function admin_menu_links_icon() {
     // Add variable editor.
     $links['icon']['devel-variables'] = array(
       '#title' => t('Variable editor'),
-      '#weight' => 20,
+      '#weight' => 30,
       '#access' => user_access('access devel information'),
       '#href' => 'devel/variable',
     );
@@ -123,6 +160,10 @@ function admin_menu_links_icon() {
  * @see theme_admin_menu_links()
  */
 function admin_menu_links_user() {
+  $links = array(
+    '#theme' => 'admin_menu_links',
+    '#weight' => 100,
+  );
   // Add link to show current authenticated/anonymous users.
   $links['user-counter'] = array(
     '#title' => admin_menu_get_user_count(),
Index: admin_menu.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/admin_menu/admin_menu.module,v
retrieving revision 1.43.2.17.2.22
diff -u -p -r1.43.2.17.2.22 admin_menu.module
--- admin_menu.module	23 Jul 2009 10:52:40 -0000	1.43.2.17.2.22
+++ admin_menu.module	23 Jul 2009 22:47:14 -0000
@@ -410,19 +410,20 @@ function admin_menu_output() {
     $content['#prefix'] = '<div id="admin-menu" class="' . $class_site . '"><div id="admin-menu-wrapper"><ul>';
     $content['#suffix'] = '</ul></div></div>';
 
-    // Add menu additions.
+    // Load menu builder functions.
     module_load_include('inc', 'admin_menu');
-    $content['icon'] = admin_menu_links_icon();
-    $content['icon']['#theme'] = 'admin_menu_links';
-    $content['user'] = admin_menu_links_user();
-    $content['user']['#theme'] = 'admin_menu_links';
 
     // Add administration menu.
-    // @todo How can we use #theme here?
-    $content['menu'] = array(
-      '#weight' => 10,
-      '#value' => admin_menu_tree_output(menu_tree_all_data('admin_menu')),
-    );
+    $content['menu'] = admin_menu_links_menu(menu_tree_all_data('admin_menu'));
+    $content['menu']['#theme'] = 'admin_menu_links';
+    // Ensure the menu tree is rendered between the icon and user links.
+    $content['menu']['#weight'] = 0;
+    // Do not sort the menu tree, since it already is sorted.
+    $content['menu']['#sorted'] = TRUE;
+
+    // Add menu additions.
+    $content['icon'] = admin_menu_links_icon();
+    $content['user'] = admin_menu_links_user();
 
     // Allow modules to alter the output.
     drupal_alter('admin_menu_output', $content);
@@ -468,7 +469,10 @@ function theme_admin_menu_links(&$elemen
   }
 
   $output = '';
-  foreach (element_children($elements, TRUE) as $path) {
+  if (!isset($elements['#sorted'])) {
+    uasort($elements, 'element_sort');
+  }
+  foreach (element_children($elements) as $path) {
     // Early-return nothing if user does not have access.
     if (isset($elements[$path]['#access']) && !$elements[$path]['#access']) {
       continue;
@@ -477,6 +481,10 @@ function theme_admin_menu_links(&$elemen
       '#attributes' => array(),
       '#options' => array(),
     );
+    // Inherit #sorted flag from parent item.
+    if (isset($elements['#sorted'])) {
+      $elements[$path]['#sorted'] = TRUE;
+    }
     // Render children to determine whether this link is expandable.
     $children = theme('admin_menu_links', $elements[$path], $depth + 1);
     if (!empty($children)) {
@@ -545,82 +553,6 @@ function theme_admin_menu_links(&$elemen
 }
 
 /**
- * Return a rendered menu tree.
- *
- * @param $tree
- *   A data structure representing the tree as returned from
- *   menu_tree_all_data().
- * @param $depth
- *   Current recursion level; internal use only.
- *
- * @return
- *   The complete, rendered administration menu.
- */
-function admin_menu_tree_output($tree, $depth = 0) {
-  $output = '';
-
-  foreach ($tree as $data) {
-    // Skip menu callbacks (mostly dynamic items).
-    if (isset($data['link']['type']) && $data['link']['type'] == MENU_CALLBACK) {
-      continue;
-    }
-    $link = admin_menu_item_link($data['link']);
-
-    if ($data['below']) {
-      $output .= theme_admin_menu_item($link, $data['link']['has_children'], admin_menu_tree_output($data['below'], $depth + 1), $data['link']['in_active_trail']);
-    }
-    else {
-      $output .= theme_admin_menu_item($link, $data['link']['has_children'], '', $data['link']['in_active_trail']);
-    }
-  }
-  // @todo Use $element['#theme'] + $element['#children'] here instead.
-  if ($output) {
-    if ($depth > 0) {
-      $output = "\n<ul>" . $output . '</ul>';
-    }
-  }
-  return $output;
-}
-
-/**
- * High-performance implementation of theme_menu_item_link().
- *
- * This saves us a theme() call and does only the absolute minimum to get
- * the admin menu links rendered.
- *
- * @param $link
- *   A menu item link.
- */
-function admin_menu_item_link($link) {
-  // Omit alias lookups.
-  $link['localized_options']['alias'] = TRUE;
-
-  return '<a href="' . check_url(url($link['href'], $link['localized_options'])) . '">' . (!empty($link['localized_options']['html']) ? $link['title'] : check_plain($link['title'])) . '</a>';
-}
-
-/**
- * Generate the HTML output for a single menu item and submenu.
- *
- * @param $link
- *   A rendered menu item link.
- * @param $has_children
- *   Whether this item has children.
- * @param $menu
- *   A string containing any rendered children of this item.
- * @param $in_active_trail
- *   Whether this item is in the active menu trail.
- *
- * @see theme_menu_item()
- */
-function theme_admin_menu_item($link, $has_children, $menu = '', $in_active_trail = FALSE) {
-  $class = ($menu || $has_children ? 'expandable' : '');
-  if ($in_active_trail) {
-    $class .= ' active-trail';
-  }
-  return '<li' . (!empty($class) ? ' class="' . $class . '"' : '') . '>' . $link . $menu . '</li>';
-}
-
-/**
  * Implementation of hook_translated_menu_link_alter().
  *
  * Here is where we make changes to links that need dynamic information such
