Make menu zebra coloring more robust. Signed-off-by: Antonio Ospite diff -pruN framework/template.php framework_ao2/template.php --- framework/template.php 2008-11-28 07:14:30.000000000 +0100 +++ framework_ao2/template.php 2009-03-07 17:58:48.000000000 +0100 @@ -104,22 +104,61 @@ function phptemplate_get_ie6_styles() { /** * Adds even and odd classes to
  • tags in ul.menu lists + * + * Detect menu depth changes, the zebra coloring "state machine" follows these + * rules: + * - An item with a 'first' class is always odd in its list, it starts a new + * submenu increasing menu depth. + * - An item with a 'last' class decrease the menu depth. + * - Items in the same submenu get alternating odd/even class. + * + * This depth detection makes the processing more robust in case some other + * modules (namely dhtml_menu) preprocess the menu not following the original + * item order (for instance dhtml_menu uses a recursive function to do its + * preprocessing). + * + * NOTE: this currently doesn't work well if a submenu has only one item, + * because this sigle element is labeled only as 'last' and not also as + * 'first', see: + * http://drupal.org/node/393632 */ -function phptemplate_menu_item($link, $has_children, $menu = '', $in_active_trail = FALSE, $extra_class = NULL) { - static $zebra = FALSE; - $zebra = !$zebra; +function phptemplate_menu_item($link, $has_children, $menu = '', + $in_active_trail = FALSE, $extra_class = NULL) { + static $zebra = array(); + static $depth = 0; + + /* A new sublist starts, increase menu depth */ + if (preg_match('/first/', $extra_class)) { + $depth += 1; + $zebra[$depth] = FALSE; + } else { + $zebra[$depth] = ! $zebra[$depth]; + } + $class = ($menu ? 'expanded' : ($has_children ? 'collapsed' : 'leaf')); + if (!empty($extra_class)) { $class .= ' '. $extra_class; } if ($in_active_trail) { $class .= ' active-trail'; } - if ($zebra) { - $class .= ' even'; + if ($zebra[$depth] == FALSE) { + $class .= ' odd'; } else { - $class .= ' odd'; + $class .= ' even'; } + + /* A sublist ends, do some cleanup and decrease menu depth */ + if (preg_match('/last/', $extra_class)) { + $zebra[$depth] = TRUE; + unset($zebra[$depth]); + /* protect for underflow in the case of the NOTE above */ + if ($depth > 0) { + $depth -= 1; + } + } + return '
  • '. $link . $menu ."
  • \n"; }