diff --git includes/common.inc includes/common.inc index bda9d52..712f6c4 100644 --- includes/common.inc +++ includes/common.inc @@ -2271,10 +2271,8 @@ function l($text, $path, array $options = array()) { 'html' => FALSE, ); - $item = menu_get_item(); - $active_href = (($item['type'] & MENU_LINKS_TO_PARENT) == MENU_LINKS_TO_PARENT ? $item['tab_root_href'] : $item['href']); // Append active class. - if (($path == $active_href || ($path == '' && drupal_is_front_page())) && + if (($path == $_GET['q'] || ($path == '' && drupal_is_front_page())) && (empty($options['language']) || $options['language']->language == $language_url->language)) { $options['attributes']['class'][] = 'active'; } diff --git includes/menu.inc includes/menu.inc index 3d24f1b..b28a1b3 100644 --- includes/menu.inc +++ includes/menu.inc @@ -971,6 +971,7 @@ function menu_tree_output($tree) { } } + $router_item = menu_get_item(); $num_items = count($items); foreach ($items as $i => $data) { $class = array(); @@ -995,7 +996,14 @@ function menu_tree_output($tree) { // Set a class if the link is in the active trail. if ($data['link']['in_active_trail']) { $class[] = 'active-trail'; - $data['localized_options']['attributes']['class'][] = 'active-trail'; + $data['link']['localized_options']['attributes']['class'][] = 'active-trail'; + } + // Normally, l() compares the href of every link with $_GET['q'] and sets + // the active class accordingly. But local tasks do not appear in menu + // trees, so if the current path is a local task, and this link is its + // tab root, then we have to set the class manually. + if ($data['link']['href'] == $router_item['tab_root_href'] && $data['link']['href'] != $_GET['q']) { + $data['link']['localized_options']['attributes']['class'][] = 'active'; } // Allow menu-specific theme overrides. @@ -1731,6 +1739,7 @@ function menu_navigation_links($menu_name, $level = 0) { } // Create a single level of links. + $router_item = menu_get_item(); $links = array(); foreach ($tree as $item) { if (!$item['link']['hidden']) { @@ -1740,6 +1749,14 @@ function menu_navigation_links($menu_name, $level = 0) { $l['title'] = $item['link']['title']; if ($item['link']['in_active_trail']) { $class = ' active-trail'; + $l['attributes']['class'][] = 'active-trail'; + } + // Normally, l() compares the href of every link with $_GET['q'] and sets + // the active class accordingly. But local tasks do not appear in menu + // trees, so if the current path is a local task, and this link is its + // tab root, then we have to set the class manually. + if ($item['link']['href'] == $router_item['tab_root_href'] && $item['link']['href'] != $_GET['q']) { + $l['attributes']['class'][] = 'active'; } // Keyed with the unique mlid to generate classes in theme_links(). $links['menu-' . $item['link']['mlid'] . $class] = $l; @@ -1846,6 +1863,16 @@ function menu_local_tasks($level = 0) { for ($p = $item['tab_parent']; ($tasks[$p]['type'] & MENU_LINKS_TO_PARENT) == MENU_LINKS_TO_PARENT; $p = $tasks[$p]['tab_parent']); // Use the path of the parent instead. $link['href'] = $tasks[$p]['href']; + // Mark the link as active, if the current path happens to be the + // path of the default local task itself (i.e., instead of its + // tab_parent_href or tab_root_href). Normally, links for default + // local tasks link to their parent, but the path of default local + // tasks can still be accessed directly, in which case this link + // would not be marked as active, since l() only compares the href + // with $_GET['q']. + if ($link['href'] != $_GET['q']) { + $link['localized_options']['attributes']['class'][] = 'active'; + } $tabs_current[] = array( '#theme' => 'menu_local_task', '#link' => $link, @@ -1915,6 +1942,13 @@ function menu_local_tasks($level = 0) { } // We check for the active tab. if ($item['path'] == $path) { + // Mark the link as active, if the current path is a (second-level) + // local task of a default local task. Since this default local task + // links to its parent, l() will not mark it as active, as it only + // compares the link's href to $_GET['q']. + if ($link['href'] != $_GET['q']) { + $link['localized_options']['attributes']['class'][] = 'active'; + } $tabs_current[] = array( '#theme' => 'menu_local_task', '#link' => $link, diff --git modules/simpletest/tests/menu.test modules/simpletest/tests/menu.test index 7b03e84..5e4d2a5 100644 --- modules/simpletest/tests/menu.test +++ modules/simpletest/tests/menu.test @@ -566,18 +566,18 @@ class MenuBreadcrumbTestCase extends DrupalWebTestCase { 'menu-test/breadcrumb/tasks' => $title, ); $this->assertBreadcrumb('menu-test/breadcrumb/tasks', $trail, $title, $tree); - $this->assertBreadcrumb('menu-test/breadcrumb/tasks/first', $trail, $title, $tree, FALSE); - $this->assertBreadcrumb('menu-test/breadcrumb/tasks/first/first', $trail, $title, $tree, FALSE); + $this->assertBreadcrumb('menu-test/breadcrumb/tasks/first', $trail, $title, $tree); + $this->assertBreadcrumb('menu-test/breadcrumb/tasks/first/first', $trail, $title, $tree); $trail += array( 'menu-test/breadcrumb/tasks' => t('Breadcrumbs test: Local tasks'), ); - $this->assertBreadcrumb('menu-test/breadcrumb/tasks/first/second', $trail, $title, $tree, FALSE); - $this->assertBreadcrumb('menu-test/breadcrumb/tasks/second', $trail, $title, $tree, FALSE); - $this->assertBreadcrumb('menu-test/breadcrumb/tasks/second/first', $trail, $title, $tree, FALSE); + $this->assertBreadcrumb('menu-test/breadcrumb/tasks/first/second', $trail, $title, $tree); + $this->assertBreadcrumb('menu-test/breadcrumb/tasks/second', $trail, $title, $tree); + $this->assertBreadcrumb('menu-test/breadcrumb/tasks/second/first', $trail, $title, $tree); $trail += array( 'menu-test/breadcrumb/tasks/second' => t('Second'), ); - $this->assertBreadcrumb('menu-test/breadcrumb/tasks/second/second', $trail, $title, $tree, FALSE); + $this->assertBreadcrumb('menu-test/breadcrumb/tasks/second/second', $trail, $title, $tree); // Verify Taxonomy administration breadcrumbs. $trail = $admin + array( @@ -1043,8 +1043,8 @@ class MenuBreadcrumbTestCase extends DrupalWebTestCase { else { $xpath .= '//'; } - $last_active = ($last_active ? 'and contains(@class, :class-active)' : ''); - $xpath .= 'li[contains(@class, :class-trail)]/a[contains(@href, :href) ' . $last_active . 'and contains(text(), :title)]'; + $xpath_last_active = ($last_active ? 'and contains(@class, :class-active)' : ''); + $xpath .= 'li[contains(@class, :class-trail)]/a[contains(@href, :href) ' . $xpath_last_active . 'and contains(text(), :title)]'; $args = array( ':class-trail' => 'active-trail', ':class-active' => 'active',