Issue #2478443 by Wim Leers: Set the 'is-active' class for anonymous users in a Response Filter instead of a #post_render_cache callback
parent
a4fac14a6d
commit
046965dfc1
|
@ -1362,3 +1362,9 @@ services:
|
|||
arguments: ['@controller_resolver', '@theme.manager', '@plugin.manager.element_info', '@render_cache', '%renderer.config%']
|
||||
email.validator:
|
||||
class: Egulias\EmailValidator\EmailValidator
|
||||
|
||||
response_filter.active_link:
|
||||
class: Drupal\Core\EventSubscriber\ActiveLinkResponseFilter
|
||||
arguments: ['@current_user', '@path.current', '@path.matcher', '@language_manager']
|
||||
tags:
|
||||
- { name: event_subscriber }
|
||||
|
|
|
@ -0,0 +1,246 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Core\EventSubscriber\ActiveLinkResponseFilter.
|
||||
*/
|
||||
|
||||
namespace Drupal\Core\EventSubscriber;
|
||||
|
||||
use Drupal\Component\Serialization\Json;
|
||||
use Drupal\Core\Language\LanguageInterface;
|
||||
use Drupal\Core\Language\LanguageManagerInterface;
|
||||
use Drupal\Core\Path\CurrentPathStack;
|
||||
use Drupal\Core\Path\PathMatcherInterface;
|
||||
use Drupal\Core\Routing\RouteMatchInterface;
|
||||
use Drupal\Core\Session\AccountInterface;
|
||||
use Drupal\Core\Url;
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
|
||||
/**
|
||||
* Subscribes to filter HTML responses, to set the 'is-active' class on links.
|
||||
*
|
||||
* Only for anonymous users; for authenticated users, the active-link asset
|
||||
* library is loaded.
|
||||
*
|
||||
* @see system_page_attachments()
|
||||
*/
|
||||
class ActiveLinkResponseFilter implements EventSubscriberInterface {
|
||||
|
||||
/**
|
||||
* The current user.
|
||||
*
|
||||
* @var \Drupal\Core\Session\AccountInterface
|
||||
*/
|
||||
protected $currentUser;
|
||||
|
||||
/**
|
||||
* The current path.
|
||||
*
|
||||
* @var \Drupal\Core\Path\CurrentPathStack
|
||||
*/
|
||||
protected $currentPath;
|
||||
|
||||
/**
|
||||
* The path matcher.
|
||||
*
|
||||
* @var \Drupal\Core\Path\PathMatcherInterface
|
||||
*/
|
||||
protected $pathMatcher;
|
||||
|
||||
/**
|
||||
* The language manager.
|
||||
*
|
||||
* @var \Drupal\Core\Language\LanguageManagerInterface
|
||||
*/
|
||||
protected $languageManager;
|
||||
|
||||
/**
|
||||
* Constructs a new ActiveLinkResponseFilter instance.
|
||||
*
|
||||
* @param \Drupal\Core\Session\AccountInterface $current_user
|
||||
* The current user.
|
||||
* @param \Drupal\Core\Path\CurrentPathStack $current_path
|
||||
* The current path.
|
||||
* @param \Drupal\Core\Path\PathMatcherInterface $path_matcher
|
||||
* The path matcher.
|
||||
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
|
||||
* The language manager.
|
||||
*/
|
||||
public function __construct(AccountInterface $current_user, CurrentPathStack $current_path, PathMatcherInterface $path_matcher, LanguageManagerInterface $language_manager) {
|
||||
$this->currentUser = $current_user;
|
||||
$this->currentPath = $current_path;
|
||||
$this->pathMatcher = $path_matcher;
|
||||
$this->languageManager = $language_manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the 'is-active' class on links.
|
||||
*
|
||||
* @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
|
||||
* The response event.
|
||||
*/
|
||||
public function onResponse(FilterResponseEvent $event) {
|
||||
// Only care about HTML responses.
|
||||
if (stripos($event->getResponse()->headers->get('Content-Type'), 'text/html') === FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
// For authenticated users, the 'is-active' class is set in JavaScript.
|
||||
// @see system_page_attachments()
|
||||
if ($this->currentUser->isAuthenticated()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$response = $event->getResponse();
|
||||
$response->setContent(static::setLinkActiveClass(
|
||||
$response->getContent(),
|
||||
ltrim($this->currentPath->getPath(), '/'),
|
||||
$this->pathMatcher->isFrontPage(),
|
||||
$this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_URL)->getId(),
|
||||
$event->getRequest()->query->all()
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the "is-active" class on relevant links.
|
||||
*
|
||||
* This is a PHP implementation of the drupal.active-link JavaScript library.
|
||||
*
|
||||
* @param string $html_markup.
|
||||
* The HTML markup to update.
|
||||
* @param string $current_path
|
||||
* The system path of the currently active page.
|
||||
* @param bool $is_front
|
||||
* Whether the current page is the front page (which implies the current
|
||||
* path might also be <front>).
|
||||
* @param string $url_language
|
||||
* The language code of the current URL.
|
||||
* @param array $query
|
||||
* The query string for the current URL.
|
||||
*
|
||||
* @return string
|
||||
* The updated HTML markup.
|
||||
*
|
||||
* @todo Once a future version of PHP supports parsing HTML5 properly
|
||||
* (i.e. doesn't fail on https://drupal.org/comment/7938201#comment-7938201)
|
||||
* then we can get rid of this manual parsing and use DOMDocument instead.
|
||||
*/
|
||||
public static function setLinkActiveClass($html_markup, $current_path, $is_front, $url_language, array $query) {
|
||||
$search_key_current_path = 'data-drupal-link-system-path="' . $current_path . '"';
|
||||
$search_key_front = 'data-drupal-link-system-path="<front>"';
|
||||
|
||||
// An active link's path is equal to the current path, so search the HTML
|
||||
// for an attribute with that value.
|
||||
$offset = 0;
|
||||
while (strpos($html_markup, $search_key_current_path, $offset) !== FALSE || ($is_front && strpos($html_markup, $search_key_front, $offset) !== FALSE)) {
|
||||
$pos_current_path = strpos($html_markup, $search_key_current_path, $offset);
|
||||
$pos_front = strpos($html_markup, $search_key_front, $offset);
|
||||
|
||||
// Determine which of the two values is the next match: the exact path, or
|
||||
// the <front> special case.
|
||||
$pos_match = NULL;
|
||||
if ($pos_front === FALSE) {
|
||||
$pos_match = $pos_current_path;
|
||||
}
|
||||
elseif ($pos_current_path === FALSE) {
|
||||
$pos_match = $pos_front;
|
||||
}
|
||||
elseif ($pos_current_path < $pos_front) {
|
||||
$pos_match = $pos_current_path;
|
||||
}
|
||||
else {
|
||||
$pos_match = $pos_front;
|
||||
}
|
||||
|
||||
// Find beginning and ending of opening tag.
|
||||
$pos_tag_start = NULL;
|
||||
for ($i = $pos_match; $pos_tag_start === NULL && $i > 0; $i--) {
|
||||
if ($html_markup[$i] === '<') {
|
||||
$pos_tag_start = $i;
|
||||
}
|
||||
}
|
||||
$pos_tag_end = NULL;
|
||||
for ($i = $pos_match; $pos_tag_end === NULL && $i < strlen($html_markup); $i++) {
|
||||
if ($html_markup[$i] === '>') {
|
||||
$pos_tag_end = $i;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the HTML: this will be the opening part of a single tag, e.g.:
|
||||
// <a href="/" data-drupal-link-system-path="<front>">
|
||||
$tag = substr($html_markup, $pos_tag_start, $pos_tag_end - $pos_tag_start + 1);
|
||||
|
||||
// Parse it into a DOMDocument so we can reliably read and modify
|
||||
// attributes.
|
||||
$dom = new \DOMDocument();
|
||||
@$dom->loadHTML('<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body>' . $tag . '</body></html>');
|
||||
$node = $dom->getElementsByTagName('body')->item(0)->firstChild;
|
||||
|
||||
// Ensure we don't set the "active" class twice on the same element.
|
||||
$class = $node->getAttribute('class');
|
||||
$add_active = !in_array('is-active', explode(' ', $class));
|
||||
|
||||
// The language of an active link is equal to the current language.
|
||||
if ($add_active && $url_language) {
|
||||
if ($node->hasAttribute('hreflang') && $node->getAttribute('hreflang') !== $url_language) {
|
||||
$add_active = FALSE;
|
||||
}
|
||||
}
|
||||
// The query parameters of an active link are equal to the current
|
||||
// parameters.
|
||||
if ($add_active) {
|
||||
if ($query) {
|
||||
if (!$node->hasAttribute('data-drupal-link-query') || $node->getAttribute('data-drupal-link-query') !== Json::encode($query)) {
|
||||
$add_active = FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($node->hasAttribute('data-drupal-link-query')) {
|
||||
$add_active = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only if the path, the language and the query match, we set the
|
||||
// "is-active" class.
|
||||
if ($add_active) {
|
||||
if (strlen($class) > 0) {
|
||||
$class .= ' ';
|
||||
}
|
||||
$class .= 'is-active';
|
||||
$node->setAttribute('class', $class);
|
||||
|
||||
// Get the updated tag.
|
||||
$updated_tag = $dom->saveXML($node, LIBXML_NOEMPTYTAG);
|
||||
// saveXML() added a closing tag, remove it.
|
||||
$updated_tag = substr($updated_tag, 0, strrpos($updated_tag, '<'));
|
||||
|
||||
$html_markup = str_replace($tag, $updated_tag, $html_markup);
|
||||
|
||||
// Ensure we only search the remaining HTML.
|
||||
$offset = $pos_tag_end - strlen($tag) + strlen($updated_tag);
|
||||
}
|
||||
else {
|
||||
// Ensure we only search the remaining HTML.
|
||||
$offset = $pos_tag_end + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return $html_markup;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getSubscribedEvents() {
|
||||
// Should run after any other response subscriber that modifies the markup.
|
||||
$events[KernelEvents::RESPONSE][] = ['onResponse', -512];
|
||||
|
||||
return $events;
|
||||
}
|
||||
|
||||
}
|
|
@ -165,6 +165,7 @@ class HtmlRenderer implements MainContentRendererInterface {
|
|||
list($version) = explode('.', \Drupal::VERSION, 2);
|
||||
|
||||
$response = new CacheableResponse($content, 200,[
|
||||
'Content-Type' => 'text/html; charset=UTF-8',
|
||||
'X-Generator' => 'Drupal ' . $version . ' (https://www.drupal.org)'
|
||||
]);
|
||||
|
||||
|
|
|
@ -328,132 +328,4 @@ class SystemController extends ControllerBase {
|
|||
return $build;
|
||||
}
|
||||
|
||||
/**
|
||||
* #post_render_cache callback; sets the "is-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 <front>)
|
||||
* - language: the language code of the currently active page
|
||||
* - query: the query string for the currently active page
|
||||
*
|
||||
* @return array
|
||||
* The updated renderable array.
|
||||
*
|
||||
* @todo Once a future version of PHP supports parsing HTML5 properly
|
||||
* (i.e. doesn't fail on https://drupal.org/comment/7938201#comment-7938201)
|
||||
* then we can get rid of this manual parsing and use DOMDocument instead.
|
||||
*/
|
||||
public static function setLinkActiveClass(array $element, array $context) {
|
||||
$search_key_current_path = 'data-drupal-link-system-path="' . $context['path'] . '"';
|
||||
$search_key_front = 'data-drupal-link-system-path="<front>"';
|
||||
|
||||
// An active link's path is equal to the current path, so search the HTML
|
||||
// for an attribute with that value.
|
||||
$offset = 0;
|
||||
while (strpos($element['#markup'], $search_key_current_path, $offset) !== FALSE || ($context['front'] && strpos($element['#markup'], $search_key_front, $offset) !== FALSE)) {
|
||||
$pos_current_path = strpos($element['#markup'], $search_key_current_path, $offset);
|
||||
$pos_front = strpos($element['#markup'], $search_key_front, $offset);
|
||||
|
||||
// Determine which of the two values is the next match: the exact path, or
|
||||
// the <front> special case.
|
||||
$pos_match = NULL;
|
||||
if ($pos_front === FALSE) {
|
||||
$pos_match = $pos_current_path;
|
||||
}
|
||||
elseif ($pos_current_path === FALSE) {
|
||||
$pos_match = $pos_front;
|
||||
}
|
||||
elseif ($pos_current_path < $pos_front) {
|
||||
$pos_match = $pos_current_path;
|
||||
}
|
||||
else {
|
||||
$pos_match = $pos_front;
|
||||
}
|
||||
|
||||
// Find beginning and ending of opening tag.
|
||||
$pos_tag_start = NULL;
|
||||
for ($i = $pos_match; $pos_tag_start === NULL && $i > 0; $i--) {
|
||||
if ($element['#markup'][$i] === '<') {
|
||||
$pos_tag_start = $i;
|
||||
}
|
||||
}
|
||||
$pos_tag_end = NULL;
|
||||
for ($i = $pos_match; $pos_tag_end === NULL && $i < strlen($element['#markup']); $i++) {
|
||||
if ($element['#markup'][$i] === '>') {
|
||||
$pos_tag_end = $i;
|
||||
}
|
||||
}
|
||||
|
||||
// Get the HTML: this will be the opening part of a single tag, e.g.:
|
||||
// <a href="/" data-drupal-link-system-path="<front>">
|
||||
$tag = substr($element['#markup'], $pos_tag_start, $pos_tag_end - $pos_tag_start + 1);
|
||||
|
||||
// Parse it into a DOMDocument so we can reliably read and modify
|
||||
// attributes.
|
||||
$dom = new \DOMDocument();
|
||||
@$dom->loadHTML('<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head><body>' . $tag . '</body></html>');
|
||||
$node = $dom->getElementsByTagName('body')->item(0)->firstChild;
|
||||
|
||||
// Ensure we don't set the "active" class twice on the same element.
|
||||
$class = $node->getAttribute('class');
|
||||
$add_active = !in_array('is-active', explode(' ', $class));
|
||||
|
||||
// The language of an active link is equal to the current language.
|
||||
if ($add_active && $context['language']) {
|
||||
if ($node->hasAttribute('hreflang') && $node->getAttribute('hreflang') !== $context['language']) {
|
||||
$add_active = FALSE;
|
||||
}
|
||||
}
|
||||
// The query parameters of an active link are equal to the current
|
||||
// parameters.
|
||||
if ($add_active) {
|
||||
if ($context['query']) {
|
||||
if (!$node->hasAttribute('data-drupal-link-query') || $node->getAttribute('data-drupal-link-query') !== Json::encode($context['query'])) {
|
||||
$add_active = FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($node->hasAttribute('data-drupal-link-query')) {
|
||||
$add_active = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Only if the path, the language and the query match, we set the
|
||||
// "is-active" class.
|
||||
if ($add_active) {
|
||||
if (strlen($class) > 0) {
|
||||
$class .= ' ';
|
||||
}
|
||||
$class .= 'is-active';
|
||||
$node->setAttribute('class', $class);
|
||||
|
||||
// Get the updated tag.
|
||||
$updated_tag = $dom->saveXML($node, LIBXML_NOEMPTYTAG);
|
||||
// saveXML() added a closing tag, remove it.
|
||||
$updated_tag = substr($updated_tag, 0, strrpos($updated_tag, '<'));
|
||||
|
||||
$element['#markup'] = str_replace($tag, $updated_tag, $element['#markup']);
|
||||
|
||||
// Ensure we only search the remaining HTML.
|
||||
$offset = $pos_tag_end - strlen($tag) + strlen($updated_tag);
|
||||
}
|
||||
else {
|
||||
// Ensure we only search the remaining HTML.
|
||||
$offset = $pos_tag_end + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return $element;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -515,7 +515,7 @@ function system_filetransfer_info() {
|
|||
* Implements hook_page_attachments().
|
||||
*
|
||||
* @see template_preprocess_maintenance_page()
|
||||
* @see \Drupal\system\Controller\SystemController::setLinkActiveClass()
|
||||
* @see \Drupal\Core\EventSubscriber\ActiveLinkResponseFilter
|
||||
*/
|
||||
function system_page_attachments(array &$page) {
|
||||
// Ensure the same CSS is loaded in template_preprocess_maintenance_page().
|
||||
|
@ -596,25 +596,14 @@ function system_page_attachments(array &$page) {
|
|||
|
||||
// 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.
|
||||
// - applying a response filter if the current user is anonymous.
|
||||
// @see l()
|
||||
// @see \Drupal\Core\Utility\LinkGenerator::generate()
|
||||
// @see template_preprocess_links()
|
||||
// @see \Drupal\system\Controller\SystemController::setLinkActiveClass
|
||||
// @see \Drupal\Core\EventSubscriber\ActiveLinkResponseFilter
|
||||
if (\Drupal::currentUser()->isAuthenticated()) {
|
||||
$page['#attached']['library'][] = 'core/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' => \Drupal::routeMatch()->getRouteName() ? Url::fromRouteMatch(\Drupal::routeMatch())->getInternalPath() : '',
|
||||
'front' => \Drupal::service('path.matcher')->isFrontPage(),
|
||||
'language' => \Drupal::languageManager()->getCurrentLanguage(LanguageInterface::TYPE_URL)->getId(),
|
||||
'query' => \Drupal::request()->query->all(),
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,27 +2,26 @@
|
|||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\Tests\system\Unit\Controller\SystemControllerTest.
|
||||
* Contains \Drupal\Tests\Core\EventSubscriber\ActiveLinkResponseFilterTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\Tests\system\Unit\Controller;
|
||||
namespace Drupal\Tests\Core\EventSubscriber;
|
||||
|
||||
use Drupal\Component\Serialization\Json;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Drupal\Core\EventSubscriber\ActiveLinkResponseFilter;
|
||||
use Drupal\Core\Template\Attribute;
|
||||
use Drupal\system\Controller\SystemController;
|
||||
use Drupal\Tests\UnitTestCase;
|
||||
|
||||
/**
|
||||
* @coversDefaultClass \Drupal\system\Controller\SystemController
|
||||
* @group system
|
||||
* @coversDefaultClass \Drupal\Core\EventSubscriber\ActiveLinkResponseFilter
|
||||
* @group EventSubscriber
|
||||
*/
|
||||
class SystemControllerTest extends UnitTestCase {
|
||||
class ActiveLinkResponseFilterTest extends UnitTestCase {
|
||||
|
||||
/**
|
||||
* Provides test data for testSetLinkActiveClass().
|
||||
*
|
||||
* @see \Drupal\system\Controller\SystemController::setLinkActiveClass()
|
||||
* @see \Drupal\Core\EventSubscriber\ActiveLinkResponseFilter::setLinkActiveClass()
|
||||
*/
|
||||
public function providerTestSetLinkActiveClass() {
|
||||
// Define all the variations that *don't* affect whether or not an
|
||||
|
@ -244,14 +243,6 @@ class SystemControllerTest extends UnitTestCase {
|
|||
$situations[] = array('context' => $context, 'is active' => FALSE, 'attributes' => $attributes + array('hreflang' => 'en', 'data-drupal-link-query' => ""));
|
||||
$situations[] = array('context' => $context, 'is active' => FALSE, 'attributes' => $attributes + array('hreflang' => 'en', 'data-drupal-link-query' => TRUE));
|
||||
|
||||
// Helper function to generate a stubbed renderable array.
|
||||
$create_element = function ($markup) {
|
||||
return array(
|
||||
'#markup' => $markup,
|
||||
'#attached' => array(),
|
||||
);
|
||||
};
|
||||
|
||||
// Loop over the surrounding HTML variations.
|
||||
$data = array();
|
||||
for ($h = 0; $h < count($html); $h++) {
|
||||
|
@ -292,7 +283,7 @@ class SystemControllerTest extends UnitTestCase {
|
|||
$target_markup = $create_markup(new Attribute($active_attributes));
|
||||
}
|
||||
|
||||
$data[] = array($create_element($source_markup), $situation['context'], $create_element($target_markup));
|
||||
$data[] = array($source_markup, $situation['context']['path'], $situation['context']['front'], $situation['context']['language'], $situation['context']['query'], $target_markup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -301,9 +292,12 @@ class SystemControllerTest extends UnitTestCase {
|
|||
// Test case to verify that the 'is-active' class is not added multiple
|
||||
// times.
|
||||
$data[] = [
|
||||
0 => ['#markup' => '<a data-drupal-link-system-path="<front>">Once</a> <a data-drupal-link-system-path="<front>">Twice</a>'],
|
||||
1 => ['path' => '', 'front' => TRUE, 'language' => 'en', 'query' => []],
|
||||
2 => ['#markup' => '<a data-drupal-link-system-path="<front>" class="is-active">Once</a> <a data-drupal-link-system-path="<front>" class="is-active">Twice</a>'],
|
||||
0 => '<a data-drupal-link-system-path="<front>">Once</a> <a data-drupal-link-system-path="<front>">Twice</a>',
|
||||
1 => '',
|
||||
2 => TRUE,
|
||||
3 => 'en',
|
||||
4 => [],
|
||||
5 => '<a data-drupal-link-system-path="<front>" class="is-active">Once</a> <a data-drupal-link-system-path="<front>" class="is-active">Twice</a>',
|
||||
];
|
||||
|
||||
// Test cases to verify that the 'is-active' class is added when on the
|
||||
|
@ -316,14 +310,20 @@ class SystemControllerTest extends UnitTestCase {
|
|||
$front_path_link = '<a data-drupal-link-system-path="myfrontpage">Front Path</a>';
|
||||
$front_path_link_active = '<a data-drupal-link-system-path="myfrontpage" class="is-active">Front Path</a>';
|
||||
$data[] = [
|
||||
0 => ['#markup' => $front_path_link . ' ' . $front_special_link],
|
||||
1 => ['path' => 'myfrontpage', 'front' => TRUE, 'language' => 'en', 'query' => []],
|
||||
2 => ['#markup' => $front_path_link_active . ' ' . $front_special_link_active],
|
||||
0 => $front_path_link . ' ' . $front_special_link,
|
||||
1 => 'myfrontpage',
|
||||
2 => TRUE,
|
||||
3 => 'en',
|
||||
4 => [],
|
||||
5 => $front_path_link_active . ' ' . $front_special_link_active,
|
||||
];
|
||||
$data[] = [
|
||||
0 => ['#markup' => $front_special_link . ' ' . $front_path_link],
|
||||
1 => ['path' => 'myfrontpage', 'front' => TRUE, 'language' => 'en', 'query' => []],
|
||||
2 => ['#markup' => $front_special_link_active . ' ' . $front_path_link_active],
|
||||
0 => $front_special_link . ' ' . $front_path_link,
|
||||
1 => 'myfrontpage',
|
||||
2 => TRUE,
|
||||
3 => 'en',
|
||||
4 => [],
|
||||
5 => $front_special_link_active . ' ' . $front_path_link_active,
|
||||
];
|
||||
|
||||
return $data;
|
||||
|
@ -332,25 +332,25 @@ class SystemControllerTest extends UnitTestCase {
|
|||
/**
|
||||
* Tests setLinkActiveClass().
|
||||
*
|
||||
* @param array $element
|
||||
* A renderable array with the following keys:
|
||||
* - #markup
|
||||
* - #attached
|
||||
* @param array $context
|
||||
* The page context to simulate. 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 <front>)
|
||||
* - language: the language code of the currently active page
|
||||
* - query: the query string for the currently active page
|
||||
* @param array $expected_element
|
||||
* The returned renderable array.
|
||||
* @param string $html_markup
|
||||
* The original HTML markup.
|
||||
* @param string $current_path
|
||||
* The system path of the currently active page.
|
||||
* @param bool $is_front
|
||||
* Whether the current page is the front page (which implies the current
|
||||
* path might also be <front>).
|
||||
* @param string $url_language
|
||||
* The language code of the current URL.
|
||||
* @param array $query
|
||||
* The query string for the current URL.
|
||||
* @param string $expected_html_markup
|
||||
* The expected updated HTML markup.
|
||||
*
|
||||
* @dataProvider providerTestSetLinkActiveClass
|
||||
* @covers ::setLinkActiveClass
|
||||
*/
|
||||
public function testSetLinkActiveClass(array $element, array $context, $expected_element) {
|
||||
$this->assertSame($expected_element, SystemController::setLinkActiveClass($element, $context));
|
||||
public function testSetLinkActiveClass($html_markup, $current_path, $is_front, $url_language, array $query, $expected_html_markup) {
|
||||
$this->assertSame($expected_html_markup, ActiveLinkResponseFilter::setLinkActiveClass($html_markup, $current_path, $is_front, $url_language, $query));
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue