core/core.services.yml | 1 - core/includes/common.inc | 62 ++------ core/includes/theme.inc | 102 +++---------- core/lib/Drupal/Core/Utility/LinkGenerator.php | 68 ++------- .../Drupal/Core/Utility/LinkGeneratorInterface.php | 8 +- core/misc/ajax.js | 4 +- .../Drupal/system/Controller/SystemController.php | 63 ++++++++ .../Drupal/system/Tests/Theme/FunctionsTest.php | 46 +----- core/modules/system/system.module | 18 ++- .../Tests/Core/Utility/LinkGeneratorTest.php | 154 ++++++-------------- 10 files changed, 178 insertions(+), 348 deletions(-) diff --git a/core/core.services.yml b/core/core.services.yml index 2a57e23..919b112 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -274,7 +274,6 @@ services: arguments: ['@url_generator', '@module_handler', '@language_manager', '@path.alias_manager.cached'] calls: - [setRequest, ['@?request']] - - [setCurrentUser, ['@?current_user']] router.dynamic: class: Symfony\Cmf\Component\Routing\DynamicRouter arguments: ['@router.request_context', '@router.matcher', '@url_generator'] diff --git a/core/includes/common.inc b/core/includes/common.inc index 3357ff2..be0eeef 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -1216,10 +1216,9 @@ function drupal_http_header_attributes(array $attributes = array()) { * well as the path must match). This element is also used by url(). * - 'set_active_class' (default FALSE): Whether l() should compare the $path, * language and query options to the current URL to determine whether the - * link is "active", and if so, apply an "active" class to the link. It is - * important to use this sparingly as any content containing a link - * generated by l() with active class processing enabled is incompatible - * with render caching elements on more than a per-page basis. + * link is "active". If so, an "active" class will be applied to the link. + * It is important to use this sparingly since it is usually unnecessary and + * requires extra processing. * For anonymous users, the "active" class will be calculated on the server, * because most sites serve each anonymous user the same cached page anyway. * For authenticated users, the "active" class will be calculated on the @@ -1259,53 +1258,18 @@ function l($text, $path, array $options = array()) { // Set the "active" class if the 'set_active_class' option is not empty. if (!empty($variables['options']['set_active_class'])) { - if (\Drupal::currentUser()->isAuthenticated()) { - // Add a "data-drupal-link-query" attribute to let the drupal.active-link - // library know the query in a standardized manner. - if (!empty($variables['options']['query'])) { - $query = $variables['options']['query']; - ksort($query); - $variables['options']['attributes']['data-drupal-link-query'] = Json::encode($query); - } - - // Add a "data-drupal-link-system-path" attribute to let the - // drupal.active-link library know the path in a standardized manner. - if (!isset($variables['options']['attributes']['data-drupal-link-system-path'])) { - $variables['options']['attributes']['data-drupal-link-system-path'] = \Drupal::service('path.alias_manager.cached')->getSystemPath($path); - } + // Add a "data-drupal-link-query" attribute to let the drupal.active-link + // library know the query in a standardized manner. + if (!empty($variables['options']['query'])) { + $query = $variables['options']['query']; + ksort($query); + $variables['options']['attributes']['data-drupal-link-query'] = Json::encode($query); } - else { - // Because l() is called very often we statically cache values that require - // an extra function call. - static $drupal_static_fast; - if (!isset($drupal_static_fast['active'])) { - $drupal_static_fast['active'] = &drupal_static(__FUNCTION__); - } - $active = &$drupal_static_fast['active']; - if (!isset($active)) { - $active = array( - 'path' => current_path(), - 'front_page' => drupal_is_front_page(), - 'language' => language(Language::TYPE_URL)->id, - 'query' => \Drupal::service('request')->query->all(), - ); - } - // Determine whether this link is "active', meaning that it links to the - // current page. It is important that we stop checking "active" conditions - // if we know the link is not active. This helps ensure that l() remains - // fast. - // An active link's path is equal to the current path. - $variables['url_is_active'] = ($path == $active['path'] || ($path == '' && $active['front_page'])) - // The language of an active link is equal to the current language. - && (empty($variables['options']['language']) || $variables['options']['language']->id == $active['language']) - // The query parameters of an active link are equal to the current parameters. - && ($variables['options']['query'] == $active['query']); - - // Add the "active" class if appropriate. - if ($variables['url_is_active']) { - $variables['options']['attributes']['class'][] = 'active'; - } + // Add a "data-drupal-link-system-path" attribute to let the + // drupal.active-link library know the path in a standardized manner. + if (!isset($variables['options']['attributes']['data-drupal-link-system-path'])) { + $variables['options']['attributes']['data-drupal-link-system-path'] = \Drupal::service('path.alias_manager.cached')->getSystemPath($path); } } diff --git a/core/includes/theme.inc b/core/includes/theme.inc index dfef814..b26c75a 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -1193,8 +1193,8 @@ function template_preprocess_status_messages(&$variables) { * route_name + route_parameters or href (path), language and query options * to the current URL for each of the links, to determine whether the link * is "active". If so, an "active" class will be applied to the list item - * containing the link. It is important to use this sparingly as this is - * incompatible with render caching elements on more than a per-page basis. + * containing the link. It is important to use this sparingly since it is + * usually unnecessary and requires extra processing. * For anonymous users, the "active" class will be calculated on the server, * because most sites serve each anonymous user the same cached page anyway. * For authenticated users, the "active" class will be calculated on the @@ -1300,88 +1300,30 @@ function theme_links($variables) { // only if the 'set_active_class' option is not empty. if (isset($link['href']) || isset($link['route_name'])) { if (!empty($variables['set_active_class'])) { - // @see \Drupal\Core\Utility\LinkGenerator::generate() - if (isset($link['route_name'])) { - if (\Drupal::currentUser()->isAuthenticated()) { - // Add a "data-drupal-link-query" attribute to let the - // drupal.active-link library know the query in a standardized - // manner. - if (!empty($link['query'])) { - $query = $link['query']; - ksort($query); - $li_attributes['data-drupal-link-query'] = Json::encode($query); - } - - // Add a "data-drupal-link-system-path" attribute to let the - // drupal.active-link library know the path in a standardized manner. - $path = \Drupal::service('url_generator')->getPathFromRoute($link['route_name'], $link['route_parameters']); - $li_attributes['data-drupal-link-system-path'] = \Drupal::service('path.alias_manager')->getSystemPath($path); - } - else { - // Determine whether this link is "active", meaning that it has the - // same URL path and query string as the current page. - $url_is_active = $link['route_name'] == $active_route['route_name'] - // The language of an active link is equal to the current language. - && (empty($link['language']) || $link['language']->id == $active_route['language']) - && $link['route_parameters'] == $active_route['parameters']; - - // Add the "active" class if appropriate. - if ($url_is_active) { - $li_attributes['class'][] = 'active'; - } - } + if (!empty($link['language'])) { + $li_attributes['hreflang'] = $link['language']->id; } - elseif (isset($link['href'])) { - // @see l() - if (\Drupal::currentUser()->isAuthenticated()) { - // Add a "data-drupal-link-query" attribute to let the - // drupal.active-link library know the query in a standardized - // manner. - if (!empty($link['query'])) { - $query = $link['query']; - ksort($query); - $li_attributes['data-drupal-link-query'] = Json::encode($query); - } - // Add a "data-drupal-link-system-path" attribute to let the - // drupal.active-link library know the path in a standardized - // manner. - $li_attributes['data-drupal-link-system-path'] = \Drupal::service('path.alias_manager.cached')->getSystemPath($link['href']); - } - else { - // Because l() is called very often we statically cache values that - // require an extra function call. - static $drupal_static_fast; - if (!isset($drupal_static_fast['active'])) { - $drupal_static_fast['active'] = &drupal_static('l'); - } - $active = &$drupal_static_fast['active']; - if (!isset($active)) { - $active = array( - 'path' => current_path(), - 'front_page' => drupal_is_front_page(), - 'language' => language(Language::TYPE_URL)->id, - 'query' => \Drupal::service('request')->query->all(), - ); - } + // Add a "data-drupal-link-query" attribute to let the + // drupal.active-link library know the query in a standardized + // manner. + if (!empty($link['query'])) { + $query = $link['query']; + ksort($query); + $li_attributes['data-drupal-link-query'] = Json::encode($query); + } - // Determine whether this link is "active', meaning that it links to - // the current page. It is important that we stop checking "active" - // conditions if we know the link is not active. This helps ensure - // that l() remains fast. - // An active link's path is equal to the current path. - $url_is_active = ($link['href'] == $active['path'] || ($link['href'] == '' && $active['front_page'])) - // The language of an active link is equal to the current language. - && (empty($link['language']) || $link['language']->id == $active['language']) - // The query parameters of an active link are equal to the current parameters. - && (empty($link['query']) || $link['query'] == $active['query']); - - // Add the "active" class if appropriate. - if ($url_is_active) { - $li_attributes['class'][] = 'active'; - } - } + if (isset($link['route_name'])) { + $path = \Drupal::service('url_generator')->getPathFromRoute($link['route_name'], $link['route_parameters']); + } + else { + $path = $link['href']; } + + // Add a "data-drupal-link-system-path" attribute to let the + // drupal.active-link library know the path in a standardized + // manner. + $li_attributes['data-drupal-link-system-path'] = \Drupal::service('path.alias_manager.cached')->getSystemPath($path); } $item = drupal_render($link_element); diff --git a/core/lib/Drupal/Core/Utility/LinkGenerator.php b/core/lib/Drupal/Core/Utility/LinkGenerator.php index 0a8a9dd..ba2b06e 100644 --- a/core/lib/Drupal/Core/Utility/LinkGenerator.php +++ b/core/lib/Drupal/Core/Utility/LinkGenerator.php @@ -25,13 +25,6 @@ class LinkGenerator implements LinkGeneratorInterface { /** - * Stores some information about the current request, like the language. - * - * @var array - */ - protected $active; - - /** * The url generator. * * @var \Drupal\Core\Routing\UrlGeneratorInterface @@ -60,13 +53,6 @@ class LinkGenerator implements LinkGeneratorInterface { protected $aliasManager; /** - * The current user. - * - * @var \Drupal\Core\Session\AccountInterface - */ - protected $currentUser; - - /** * Constructs a LinkGenerator instance. * * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator @@ -105,16 +91,6 @@ public function setRequest(Request $request) { } /** - * Sets the current user. - * - * @param \Drupal\Core\Session\AccountInterface $current_user - * The current user service. - */ - public function setCurrentUser(AccountInterface $current_user) { - $this->currentUser = $current_user; - } - - /** * {@inheritdoc} */ public function getActive() { @@ -160,39 +136,19 @@ public function generate($text, $route_name, array $parameters = array(), array // Set the "active" class if the 'set_active_class' option is not empty. if (!empty($variables['options']['set_active_class'])) { - if ($this->currentUser->isAuthenticated()) { - // Add a "data-drupal-link-query" attribute to let the - // drupal.active-link library know the query in a standardized manner. - if (!empty($variables['options']['query'])) { - $query = $variables['options']['query']; - ksort($query); - $variables['options']['attributes']['data-drupal-link-query'] = Json::encode($query); - } - - // Add a "data-drupal-link-system-path" attribute to let the - // drupal.active-link library know the path in a standardized manner. - if (!isset($variables['options']['attributes']['data-drupal-link-system-path'])) { - $path = $this->urlGenerator->getPathFromRoute($route_name, $parameters); - $variables['options']['attributes']['data-drupal-link-system-path'] = $this->aliasManager->getSystemPath($path); - } + // Add a "data-drupal-link-query" attribute to let the + // drupal.active-link library know the query in a standardized manner. + if (!empty($variables['options']['query'])) { + $query = $variables['options']['query']; + ksort($query); + $variables['options']['attributes']['data-drupal-link-query'] = Json::encode($query); } - else { - // This is only needed for the active class. The generator also combines - // the parameters and $options['query'] and adds parameters that are not - // path slugs as query strings. - $full_parameters = $parameters + (array) $variables['options']['query']; - - // Determine whether this link is "active", meaning that it has the same - // URL path and query string as the current page. - $variables['url_is_active'] = $route_name == $this->active['route_name'] - // The language of an active link is equal to the current language. - && (empty($variables['options']['language']) || $variables['options']['language']->id == $this->active['language']) - && $full_parameters == $this->active['parameters']; - - // Add the "active" class if appropriate. - if ($variables['url_is_active']) { - $variables['options']['attributes']['class'][] = 'active'; - } + + // Add a "data-drupal-link-system-path" attribute to let the + // drupal.active-link library know the path in a standardized manner. + if (!isset($variables['options']['attributes']['data-drupal-link-system-path'])) { + $path = $this->urlGenerator->getPathFromRoute($route_name, $parameters); + $variables['options']['attributes']['data-drupal-link-system-path'] = $this->aliasManager->getSystemPath($path); } } diff --git a/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php b/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php index 7772520..b832873 100644 --- a/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php +++ b/core/lib/Drupal/Core/Utility/LinkGeneratorInterface.php @@ -57,11 +57,9 @@ * well as the path must match). * - 'set_active_class' (default FALSE): Whether this method should compare * the $route_name, $parameters, language and query options to the current - * URL to determine whether the link is "active", and if so, apply an - * "active" class to the link. It is important to use this sparingly as - * any content containing a link generated with active class processing - * enabled is incompatible with render caching elements on more than a - * per-page basis. + * URL to determine whether the link is "active". If so, an "active" class + * will be applied to the link. It is important to use this sparingly + * since it is usually unnecessary and requires extra processing. * * @return string * An HTML string containing a link to the given route and parameters. diff --git a/core/misc/ajax.js b/core/misc/ajax.js index ad9dcae..63eb4a7 100644 --- a/core/misc/ajax.js +++ b/core/misc/ajax.js @@ -597,7 +597,7 @@ Drupal.AjaxCommands.prototype = { case 'empty': case 'remove': settings = response.settings || ajax.settings || drupalSettings; - Drupal.detachBehaviors(wrapper, settings); + Drupal.detachBehaviors(wrapper.get(0), settings); } // Add the new content to the page. @@ -625,7 +625,7 @@ Drupal.AjaxCommands.prototype = { if (new_content.parents('html').length > 0) { // Apply any settings from the returned JSON if available. settings = response.settings || ajax.settings || drupalSettings; - Drupal.attachBehaviors(new_content, settings); + Drupal.attachBehaviors(new_content.get(0), settings); } }, diff --git a/core/modules/system/lib/Drupal/system/Controller/SystemController.php b/core/modules/system/lib/Drupal/system/Controller/SystemController.php index 6145a11..d25554dc 100644 --- a/core/modules/system/lib/Drupal/system/Controller/SystemController.php +++ b/core/modules/system/lib/Drupal/system/Controller/SystemController.php @@ -7,6 +7,7 @@ namespace Drupal\system\Controller; +use Drupal\Component\Utility\Json; use Drupal\Core\Controller\ControllerBase; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Entity\Query\QueryFactory; @@ -161,4 +162,66 @@ public function themeSetDefault() { return system_theme_default(); } + /** + * #post_render_cache callback; sets the "active" class on relevant links. + * + * This is a PHP implementation of the drupal.active-link JavaScript library. + * + * @param array $element + * A renderable array with the following keys: + * - #markup + * - #attached + * @param array $context + * An array with the following keys: + * - path: the system path of the currently active page + * - front: whether the current page is the front page (which implies the + * current path might also be ) + * - language: the language code of the currently active page + * - query: the query string for the currently active page + * + * @return array + * The updated renderable array. + */ + public static function setLinkActiveClass(array $element, array $context) { + // Ensure we only manipulate HTML markup. + if (substr($element['#markup'], 0, 9) !== '"') === FALSE)) { + return $element; + } + + // Build XPath query to find links that should get the "active" class. + $query = '//*['; + // An active link's path is equal to the current path. + $query .= '@data-drupal-link-system-path="' . $context['path'] . '"'; + if ($context['front']) { + $query .= ' or @data-drupal-link-system-path=""'; + } + // The language of an active link is equal to the current language. + if ($context['language']) { + $query .= ' and (not(@hreflang) or @hreflang="' . $context['language'] . '")'; + } + // The query parameters of an active link are equal to the current + // parameters. + if ($context['query']) { + $query .= ' and @data-drupal-link-query="' . Json::encode($context['query']) . '"'; + } + $query .= ']'; + + // Set the "active" class on all matching HTML elements. + $dom = new \DOMDocument(); + @$dom->loadHTML($element['#markup']); + $xpath = new \DOMXPath($dom); + foreach ($xpath->query($query) as $node) { + $node->setAttribute('class', $node->getAttribute('class') . ' active'); + } + $element['#markup'] = $dom->saveHTML(); + + return $element; + } + } diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php index 0426364..97335d2 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Theme/FunctionsTest.php @@ -227,17 +227,7 @@ function testLinks() { $expected = $expected_heading . $expected_links; $this->assertThemeOutput('links', $variables, $expected); - // Set the current path to the front page path and current query to empty. - // Required to verify the "active" class in expected links below, and - // because the current path and query are different when running tests - // manually via simpletest.module ('batch') and the testing framework (''). - _current_path(\Drupal::config('system.site')->get('page.front')); - \Drupal::service('request')->query->replace(array()); - drupal_static_reset('l'); - drupal_static_reset('drupal_is_front_page'); - - // Verify that setting the "active" class on the links works. - // Case 1: data- attributes are set when authenticated (paths + routes). + // Verify the data- attributes for setting the "active" class on links. $this->container->set('current_user', new UserSession(array('uid' => 1))); $variables['set_active_class'] = TRUE; $expected_links = ''; @@ -249,40 +239,6 @@ function testLinks() { $expected_links .= ''; $expected = $expected_heading . $expected_links; $this->assertThemeOutput('links', $variables, $expected); - - // Verify that setting the "active" class on the links works. - // Case 2: "active" class is set when anonymous (path). - $this->container->set('current_user', new UserSession(array('uid' => 0))); - $expected_links = ''; - $expected_links .= ''; - $expected = $expected_heading . $expected_links; - $this->assertThemeOutput('links', $variables, $expected); - - // Set the current path to the test route. - _current_path('router_test/test1'); - $request = Request::create('/router_test/test1', 'GET'); - $request->attributes->set(RouteObjectInterface::ROUTE_NAME, 'router_test.1'); - \Drupal::service('link_generator')->setRequest($request); - drupal_static_reset('l'); - drupal_static_reset('drupal_is_front_page'); - - // Verify that setting the "active" class on the links works. - // Case 2: "active" class is set when anonymous (route). - $this->container->set('current_user', new UserSession(array('uid' => 0))); - $expected_links = ''; - $expected_links .= ''; - $expected = $expected_heading . $expected_links; - $this->assertThemeOutput('links', $variables, $expected); } /** diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 449201c..9295d6a 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -2131,6 +2131,7 @@ function system_filetransfer_info() { * Implements hook_page_build(). * * @see template_preprocess_maintenance_page() + * @see \Drupal\system\Controller\SystemController::setLinkActiveClass() */ function system_page_build(&$page) { // Ensure the same CSS is loaded in template_preprocess_maintenance_page(). @@ -2151,12 +2152,27 @@ function system_page_build(&$page) { ); } - // Load the active-link library if this is an authenticated user. + // Handle setting the "active" class on links by: + // - loading the active-link library if the current user is authenticated; + // - applying a post-render cache callback if the current user is anonymous. // @see l() // @see \Drupal\Core\Utility\LinkGenerator::generate() + // @see theme_links() + // @see \Drupal\system\Controller\SystemController::setLinkActiveClass if (\Drupal::currentUser()->isAuthenticated()) { $page['#attached']['library'][] = array('system', 'drupal.active-link'); } + else { + $page['#post_render_cache']['\Drupal\system\Controller\SystemController::setLinkActiveClass'] = array( + // Collect the current state that determines whether a link is active. + array( + 'path' => current_path(), + 'front' => drupal_is_front_page(), + 'language' => language(\Drupal\Core\Language\Language::TYPE_URL)->id, + 'query' => \Drupal::service('request')->query->all(), + ) + ); + } } /** diff --git a/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php b/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php index 1301fe6..eec43a6 100644 --- a/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php +++ b/core/tests/Drupal/Tests/Core/Utility/LinkGeneratorTest.php @@ -57,13 +57,6 @@ class LinkGeneratorTest extends UnitTestCase { protected $aliasManager; /** - * The mocked current user service. - * - * @var \Drupal\Core\Session\AccountInterface|\PHPUnit_Framework_MockObject_MockObject - */ - protected $currentUser; - - /** * Contains the LinkGenerator default options. */ protected $defaultOptions = array( @@ -95,9 +88,8 @@ protected function setUp() { $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface'); $this->languageManager = $this->getMock('Drupal\Core\Language\LanguageManager'); $this->aliasManager = $this->getMock('\Drupal\Core\Path\AliasManagerInterface'); - $this->currentUser = $this->getMock('\Drupal\Core\Session\AccountInterface'); - $this->linkGenerator = new LinkGenerator($this->urlGenerator, $this->moduleHandler, $this->languageManager, $this->aliasManager, $this->currentUser); + $this->linkGenerator = new LinkGenerator($this->urlGenerator, $this->moduleHandler, $this->languageManager, $this->aliasManager); } /** @@ -319,79 +311,15 @@ public function testGenerateWithHtml() { } /** - * Provides test data for testing the active class on the link method. - * - * @see \Drupal\Tests\Core\Utility\LinkGeneratorTest::testGenerateActive() - * - * @return array - * Returns some test data. - */ - public function providerTestGenerateActive() { - return array( - // Anonymous: generate "active" class. - array(FALSE, array( - // Render a link with a path different from the current path. - 0 => array('method' => 'assertNotTag', 'attributes' => array('class' => 'active')), - // Render a link with the same path as the current path. - 1 => array('method' => 'assertTag', 'attributes' => array('class' => 'active')), - // Render a link with the same path as the current path, but with the - // set_active_class option disabled. - 2 => array('method' => 'assertNotTag', 'attributes' => array('class' => 'active')), - // Render a link with the same path and language as the current path. - 3 => array('method' => 'assertTag', 'attributes' => array('class' => 'active')), - // Render a link with the same path but a different language than the current - // path. - 4 => array('method' => 'assertNotTag', 'attributes' => array('class' => 'active', 'hreflang' => 'de')), - // Render a link with the same path and query parameter as the current path. - 5 => array('method' => 'assertTag', 'attributes' => array('class' => 'active')), - // Render a link with the same path but a different query parameter than the - // current path. - 6 => array('method' => 'assertNotTag', 'attributes' => array('class' => 'active')), - // Render a link with the same path and query parameter as the current path. - 7 => array('method' => 'assertTag', 'attributes' => array('class' => 'active')), - )), - // Authenticated: generate data attributes for drupal.active-link library. - array(TRUE, array( - // Render a link with a path different from the current path. - 0 => array('method' => 'assertTag', 'attributes' => array('data-drupal-link-system-path' => 'test-route-1')), - // Render a link with the same path as the current path. - 1 => array('method' => 'assertTag', 'attributes' => array('data-drupal-link-system-path' => 'test-route-1')), - // Render a link with the same path as the current path, but with the - // set_active_class option disabled. - 2 => array('method' => 'assertNotTag', 'attributes' => array('data-drupal-link-system-path' => 'test-route-1')), - // Render a link with the same path and language as the current path. - 3 => array('method' => 'assertTag', 'attributes' => array('data-drupal-link-system-path' => 'test-route-1')), - // Render a link with the same path but a different language than the current - // path. - 4 => array('method' => 'assertTag', 'attributes' => array('data-drupal-link-system-path' => 'test-route-1', 'hreflang' => 'de')), - // Render a link with the same path and query parameter as the current path. - 5 => array('method' => 'assertTag', 'attributes' => array('data-drupal-link-system-path' => 'test-route-3', 'data-drupal-link-query' => 'regexp:/.*value.*example_1.*/')), - // Render a link with the same path but a different query parameter than the - // current path. - 6 => array('method' => 'assertTag', 'attributes' => array('data-drupal-link-system-path' => 'test-route-3', 'data-drupal-link-query' => 'regexp:/.*value.*example_2.*/')), - // Render a link with the same path and query parameter as the current path. - 7 => array('method' => 'assertTag', 'attributes' => array('data-drupal-link-system-path' => 'test-route-4/1', 'data-drupal-link-query' => 'regexp:/.*value.*example_1.*/')), - )), - ); - } - - /** * Tests the active class on the link method. * * @see \Drupal\Core\Utility\LinkGenerator::generate() - * @see \Drupal\Tests\Core\Utility\LinkGeneratorTest::providerTestGenerateActive() - * - * @dataProvider providerTestGenerateActive * * @todo Test that the active class is added on the front page when generating * links to the front page when drupal_is_front_page() is converted to a * service. */ - public function testGenerateActive($is_authenticated, $expected_results) { - $this->currentUser->expects($this->exactly(7)) - ->method('isAuthenticated') - ->will($this->returnValue($is_authenticated)); - + public function testGenerateActive() { $this->urlGenerator->expects($this->exactly(8)) ->method('generateFromRoute') ->will($this->returnValueMap(array( @@ -400,38 +328,34 @@ public function testGenerateActive($is_authenticated, $expected_results) { array('test_route_4', array('object' => '1'), FALSE, '/test-route-4/1'), ))); - if ($is_authenticated) { - $this->urlGenerator->expects($this->exactly(7)) - ->method('getPathFromRoute') - ->will($this->returnValueMap(array( - array('test_route_1', array(), 'test-route-1'), - array('test_route_3', array(), 'test-route-3'), - array('test_route_4', array('object' => '1'), 'test-route-4/1'), - ))); - - $this->aliasManager->expects($this->exactly(7)) - ->method('getSystemPath') - ->will($this->returnValueMap(array( - array('test-route-1', NULL, 'test-route-1'), - array('test-route-3', NULL, 'test-route-3'), - array('test-route-4/1', NULL, 'test-route-4/1'), - ))); - } + $this->urlGenerator->expects($this->exactly(7)) + ->method('getPathFromRoute') + ->will($this->returnValueMap(array( + array('test_route_1', array(), 'test-route-1'), + array('test_route_3', array(), 'test-route-3'), + array('test_route_4', array('object' => '1'), 'test-route-4/1'), + ))); + + $this->aliasManager->expects($this->exactly(7)) + ->method('getSystemPath') + ->will($this->returnValueMap(array( + array('test-route-1', NULL, 'test-route-1'), + array('test-route-3', NULL, 'test-route-3'), + array('test-route-4/1', NULL, 'test-route-4/1'), + ))); $this->moduleHandler->expects($this->exactly(8)) ->method('alter'); $this->setUpLanguageManager(); - $this->linkGenerator->setCurrentUser($this->currentUser); - // Render a link with a path different from the current path. $request = new Request(array(), array(), array('system_path' => 'test-route-2')); $this->linkGenerator->setRequest($request); $result = $this->linkGenerator->generate('Test', 'test_route_1', array(), array('set_active_class' => TRUE)); - $this->$expected_results[0]['method'](array( + $this->assertTag(array( 'tag' => 'a', - 'attributes' => $expected_results[0]['attributes'], + 'attributes' => array('data-drupal-link-system-path' => 'test-route-1'), ), $result); // Render a link with the same path as the current path. @@ -442,9 +366,9 @@ public function testGenerateActive($is_authenticated, $expected_results) { $request->attributes->set('_raw_variables', $raw_variables); $this->linkGenerator->setRequest($request); $result = $this->linkGenerator->generate('Test', 'test_route_1', array(), array('set_active_class' => TRUE)); - $this->$expected_results[1]['method'](array( + $this->assertTag(array( 'tag' => 'a', - 'attributes' => $expected_results[1]['attributes'], + 'attributes' => array('data-drupal-link-system-path' => 'test-route-1'), ), $result); // Render a link with the same path as the current path, but with the @@ -456,16 +380,16 @@ public function testGenerateActive($is_authenticated, $expected_results) { $request->attributes->set('_raw_variables', $raw_variables); $this->linkGenerator->setRequest($request); $result = $this->linkGenerator->generate('Test', 'test_route_1', array(), array('set_active_class' => FALSE)); - $this->$expected_results[2]['method'](array( + $this->assertNotTag(array( 'tag' => 'a', - 'attributes' => $expected_results[2]['attributes'], + 'attributes' => array('data-drupal-link-system-path' => 'test-route-1'), ), $result); // Render a link with the same path and language as the current path. $result = $this->linkGenerator->generate('Test', 'test_route_1', array(), array('set_active_class' => TRUE)); - $this->$expected_results[3]['method'](array( + $this->assertTag(array( 'tag' => 'a', - 'attributes' => $expected_results[3]['attributes'], + 'attributes' => array('data-drupal-link-system-path' => 'test-route-1'), ), $result); // Render a link with the same path but a different language than the current @@ -479,9 +403,12 @@ public function testGenerateActive($is_authenticated, $expected_results) { 'set_active_class' => TRUE, ) ); - $this->$expected_results[4]['method'](array( + $this->assertTag(array( 'tag' => 'a', - 'attributes' => $expected_results[4]['attributes'], + 'attributes' => array( + 'data-drupal-link-system-path' => 'test-route-1', + 'hreflang' => 'de', + ), ), $result); // Render a link with the same path and query parameter as the current path. @@ -498,9 +425,12 @@ public function testGenerateActive($is_authenticated, $expected_results) { 'set_active_class' => TRUE, ) ); - $this->$expected_results[5]['method'](array( + $this->assertTag(array( 'tag' => 'a', - 'attributes' => $expected_results[5]['attributes'], + 'attributes' => array( + 'data-drupal-link-system-path' => 'test-route-3', + 'data-drupal-link-query' => 'regexp:/.*value.*example_1.*/', + ), ), $result); // Render a link with the same path but a different query parameter than the @@ -514,9 +444,12 @@ public function testGenerateActive($is_authenticated, $expected_results) { 'set_active_class' => TRUE, ) ); - $this->$expected_results[6]['method'](array( + $this->assertTag(array( 'tag' => 'a', - 'attributes' => $expected_results[6]['attributes'], + 'attributes' => array( + 'data-drupal-link-system-path' => 'test-route-3', + 'data-drupal-link-query' => 'regexp:/.*value.*example_2.*/', + ), ), $result); // Render a link with the same path and query parameter as the current path. @@ -533,9 +466,12 @@ public function testGenerateActive($is_authenticated, $expected_results) { 'set_active_class' => TRUE, ) ); - $this->$expected_results[7]['method'](array( + $this->assertTag(array( 'tag' => 'a', - 'attributes' => $expected_results[7]['attributes'], + 'attributes' => array( + 'data-drupal-link-system-path' => 'test-route-4/1', + 'data-drupal-link-query' => 'regexp:/.*value.*example_1.*/', + ), ), $result); }