Issue #2999549 by mtift, Daniel Korte, mherchel, alexpott, larowlan: Allow button tag in LinkGenerator for better accessibility
(cherry picked from commit 8ed835c0bc
)
merge-requests/64/head
parent
2ee538c275
commit
485db38e54
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Core;
|
||||
|
||||
/**
|
||||
* This class holds a <button> generated from the <button> route.
|
||||
*
|
||||
* Unlike \Drupal\Core\Render\Element\Button, this is not for generating
|
||||
* buttons for forms. This class is for putting a button in a list of links
|
||||
* such as a multi-level menu.
|
||||
*/
|
||||
class GeneratedButton extends GeneratedLink {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
const TAG = 'button';
|
||||
|
||||
}
|
|
@ -7,6 +7,7 @@ use Drupal\Component\Utility\Html;
|
|||
use Drupal\Component\Render\MarkupInterface;
|
||||
use Drupal\Core\Extension\ModuleHandlerInterface;
|
||||
use Drupal\Core\GeneratedLink;
|
||||
use Drupal\Core\GeneratedButton;
|
||||
use Drupal\Core\GeneratedNoLink;
|
||||
use Drupal\Core\Link;
|
||||
use Drupal\Core\Render\RendererInterface;
|
||||
|
@ -165,19 +166,41 @@ class LinkGenerator implements LinkGeneratorInterface {
|
|||
if ($url->isExternal()) {
|
||||
$generated_link = new GeneratedLink();
|
||||
$attributes['href'] = $url->toString(FALSE);
|
||||
return $this->doGenerate($generated_link, $attributes, $variables);
|
||||
}
|
||||
elseif ($url->isRouted() && $url->getRouteName() === '<nolink>') {
|
||||
if ($url->isRouted() && $url->getRouteName() === '<nolink>') {
|
||||
$generated_link = new GeneratedNoLink();
|
||||
unset($attributes['href']);
|
||||
return $this->doGenerate($generated_link, $attributes, $variables);
|
||||
}
|
||||
else {
|
||||
$generated_url = $url->toString(TRUE);
|
||||
$generated_link = GeneratedLink::createFromObject($generated_url);
|
||||
// The result of the URL generator is a plain-text URL to use as the href
|
||||
// attribute, and it is escaped by \Drupal\Core\Template\Attribute.
|
||||
$attributes['href'] = $generated_url->getGeneratedUrl();
|
||||
if ($url->isRouted() && $url->getRouteName() === '<button>') {
|
||||
$generated_link = new GeneratedButton();
|
||||
$attributes['type'] = 'button';
|
||||
unset($attributes['href']);
|
||||
return $this->doGenerate($generated_link, $attributes, $variables);
|
||||
}
|
||||
$generated_url = $url->toString(TRUE);
|
||||
$generated_link = GeneratedLink::createFromObject($generated_url);
|
||||
// The result of the URL generator is a plain-text URL to use as the href
|
||||
// attribute, and it is escaped by \Drupal\Core\Template\Attribute.
|
||||
$attributes['href'] = $generated_url->getGeneratedUrl();
|
||||
return $this->doGenerate($generated_link, $attributes, $variables);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the link.
|
||||
*
|
||||
* @param Drupal\Core\GeneratedLink $generated_link
|
||||
* The generated link, along with its associated cacheability metadata.
|
||||
* @param array $attributes
|
||||
* The attributes of the generated link.
|
||||
* @param array $variables
|
||||
* The link text, url, and other options.
|
||||
*
|
||||
* @return Drupal\Core\GeneratedLink
|
||||
* The generated link, along with its associated cacheability metadata.
|
||||
*/
|
||||
protected function doGenerate($generated_link, $attributes, $variables) {
|
||||
if (!($variables['text'] instanceof MarkupInterface)) {
|
||||
$variables['text'] = Html::escape($variables['text']);
|
||||
}
|
||||
|
|
|
@ -412,6 +412,13 @@ system.theme_settings_theme:
|
|||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
'<button>':
|
||||
path: ''
|
||||
options:
|
||||
_no_path: TRUE
|
||||
requirements:
|
||||
_access: 'TRUE'
|
||||
|
||||
'<current>':
|
||||
path: '<current>'
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
namespace Drupal\Tests\Core\Utility;
|
||||
|
||||
use Drupal\Component\Render\MarkupInterface;
|
||||
use Drupal\Core\GeneratedButton;
|
||||
use Drupal\Core\GeneratedNoLink;
|
||||
use Drupal\Core\GeneratedUrl;
|
||||
use Drupal\Core\Language\Language;
|
||||
|
@ -199,6 +200,26 @@ class LinkGeneratorTest extends UnitTestCase {
|
|||
$this->assertSame('<a href="">Test</a>', (string) $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the generate() method with the <button> route.
|
||||
*
|
||||
* @covers ::generate
|
||||
*/
|
||||
public function testGenerateButton() {
|
||||
$this->urlGenerator->expects($this->never())
|
||||
->method('generateFromRoute');
|
||||
$this->moduleHandler->expects($this->once())
|
||||
->method('alter')
|
||||
->with('link', $this->isType('array'));
|
||||
|
||||
$url = Url::fromRoute('<button>');
|
||||
$url->setUrlGenerator($this->urlGenerator);
|
||||
|
||||
$result = $this->linkGenerator->generate('Test', $url);
|
||||
$this->assertTrue($result instanceof GeneratedButton);
|
||||
$this->assertSame('<button type="button">Test</button>', (string) $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the generate() method with an external URL.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue