Commit 970ea07c authored by alexpott's avatar alexpott

Revert "Issue #2273923 by mpdonadio, pfrenssen, dawehner, xjm, cilefen: Remove...

Revert "Issue #2273923 by mpdonadio, pfrenssen, dawehner, xjm, cilefen: Remove html => TRUE option from l() and link generator"

This reverts commit 0bcabf50.
parent fb40bd6f
......@@ -508,7 +508,7 @@ services:
arguments: ['@request_stack', '@config.factory' ]
link_generator:
class: Drupal\Core\Utility\LinkGenerator
arguments: ['@url_generator', '@module_handler', '@renderer']
arguments: ['@url_generator', '@module_handler']
router:
class: Drupal\Core\Routing\AccessAwareRouter
arguments: ['@router.no_access_checks', '@access_manager', '@current_user']
......
......@@ -638,8 +638,6 @@ function drupal_http_header_attributes(array $attributes = array()) {
*
* @param string|array $text
* The link text for the anchor tag as a translated string or render array.
* Strings will be sanitized automatically. If you need to output HTML in the
* link text you should use a render array.
* @param string $path
* The internal path or external URL being linked to, such as "node/34" or
* "http://example.com/foo". After the url() function is called to construct
......@@ -655,6 +653,11 @@ function drupal_http_header_attributes(array $attributes = array()) {
* must be a string; other elements are more flexible, as they just need
* to work as an argument for the constructor of the class
* Drupal\Core\Template\Attribute($options['attributes']).
* - 'html' (default FALSE): Whether $text is HTML or just plain-text. For
* example, to make an image tag into a link, this must be set to TRUE, or
* you will see the escaped HTML image tag. $text is not sanitized if
* 'html' is TRUE. The calling function must ensure that $text is already
* safe.
* - 'language': An optional language object. If the path being linked to is
* internal to the site, $options['language'] is used to determine whether
* the link is "active", or pointing to the current page (the language as
......@@ -707,6 +710,7 @@ function _l($text, $path, array $options = array()) {
$variables['options'] += array(
'attributes' => array(),
'query' => array(),
'html' => FALSE,
'language' => NULL,
'set_active_class' => FALSE,
);
......@@ -751,9 +755,8 @@ function _l($text, $path, array $options = array()) {
// in an HTML argument context, we need to encode it properly.
$url = String::checkPlain(_url($variables['path'], $variables['options']));
// Sanitize the link text.
$text = SafeMarkup::escape($variables['text']);
// Sanitize the link text if necessary.
$text = $variables['options']['html'] ? $variables['text'] : String::checkPlain($variables['text']);
return SafeMarkup::set('<a href="' . $url . '"' . $attributes . '>' . $text . '</a>');
}
......
......@@ -327,30 +327,26 @@ function template_preprocess_menu_local_task(&$variables) {
$link += array(
'localized_options' => array(),
);
$link_text = $link['title'];
if (!empty($variables['element']['#active'])) {
// Add text to indicate active tab for non-visual users.
$active = '<span class="visually-hidden">' . t('(active tab)') . '</span>';
$variables['attributes']['class'] = array('active');
// Build up an inline template which will be autoescaped.
$link_text = array(
'#type' => 'inline_template',
'#template' => '{{ title }}<span class="visually-hidden">{% trans %}(active tab){% endtrans %}></span>',
'#context' => array('title' => $link['title']),
);
$title = drupal_render($link_text);
}
else {
// @todo Remove expicit escaping when https://www.drupal.org/node/2338081
// gets fixed.
$title = String::checkPlain($link['title']);
// If the link does not contain HTML already, String::checkPlain() it now.
// After we set 'html'=TRUE the link will not be sanitized by l().
if (empty($link['localized_options']['html'])) {
$link['title'] = String::checkPlain($link['title']);
}
$link['localized_options']['html'] = TRUE;
$link_text = t('!local-task-title!active', array('!local-task-title' => $link['title'], '!active' => $active));
}
$link['localized_options']['set_active_class'] = TRUE;
$variables['link'] = array(
'#type' => 'link',
'#title' => $title,
'#title' => $link_text,
'#url' => $link['url'],
'#options' => $link['localized_options'],
);
......
......@@ -43,11 +43,6 @@ function tablesort_init($header) {
function tablesort_header(&$cell_content, array &$cell_attributes, array $header, array $ts) {
// Special formatting for the currently sorted column header.
if (isset($cell_attributes['field'])) {
$text = array(
'cell_content' => array(
'#markup' => $cell_content,
),
);
$title = t('sort by @s', array('@s' => $cell_content));
if ($cell_content == $ts['name']) {
// aria-sort is a WAI-ARIA property that indicates if items in a table
......@@ -56,24 +51,24 @@ function tablesort_header(&$cell_content, array &$cell_attributes, array $header
$cell_attributes['aria-sort'] = ($ts['sort'] == 'asc') ? 'ascending' : 'descending';
$ts['sort'] = (($ts['sort'] == 'asc') ? 'desc' : 'asc');
$cell_attributes['class'][] = 'active';
$tablesort_indicator = array(
'#theme' => 'tablesort_indicator',
'#style' => $ts['sort'],
);
$image = drupal_render($tablesort_indicator);
}
else {
// If the user clicks a different header, we want to sort ascending
// initially.
// If the user clicks a different header, we want to sort ascending initially.
$ts['sort'] = 'asc';
$image = '';
}
// Append the sort indicator to the cell content.
$text['image'] = [
'#theme' => 'tablesort_indicator',
'#style' => $ts['sort'],
];
$cell_content = \Drupal::l($text, new Url('<current>', [], [
$cell_content = \Drupal::l($cell_content . $image, new Url('<current>', [], [
'attributes' => array('title' => $title),
'query' => array_merge($ts['query'], array(
'sort' => $ts['sort'],
'order' => $cell_content,
)),
'html' => TRUE,
]));
unset($cell_attributes['field'], $cell_attributes['sort']);
......
......@@ -580,6 +580,9 @@ function template_preprocess_status_messages(&$variables) {
* - title: The link text.
* - url: (optional) The url object to link to. If omitted, no a tag is
* printed out.
* - html: (optional) Whether or not 'title' is HTML. If set, the title
* will not be passed through
* \Drupal\Component\Utility\String::checkPlain().
* - attributes: (optional) Attributes for the anchor, or for the <span>
* tag used in its place if no 'href' is supplied. If element 'class' is
* included, it must be an array of one or more class names.
......@@ -661,7 +664,7 @@ function template_preprocess_links(&$variables) {
$keys = ['title', 'url'];
$link_element = array(
'#type' => 'link',
'#title' => is_array($link['title']) ? drupal_render($link['title']) : SafeMarkup::escape($link['title']),
'#title' => $link['title'],
'#options' => array_diff_key($link, array_combine($keys, $keys)),
'#url' => $link['url'],
'#ajax' => $link['ajax'],
......@@ -703,7 +706,8 @@ function template_preprocess_links(&$variables) {
}
// Handle title-only text items.
$item['text'] = $link_element['#title'];
$text = (!empty($link['html']) ? $link['title'] : String::checkPlain($link['title']));
$item['text'] = $text;
if (isset($link['attributes'])) {
$item['text_attributes'] = new Attribute($link['attributes']);
}
......
......@@ -97,6 +97,7 @@ public static function preRenderActionsDropbutton(&$element, FormStateInterface
$button = drupal_render($element[$key]);
$dropbuttons[$dropbutton]['#links'][$key] = array(
'title' => $button,
'html' => TRUE,
);
}
}
......
......@@ -12,7 +12,7 @@
use Drupal\Component\Utility\String;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Link;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Path\AliasManagerInterface;
use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\Core\Template\Attribute;
use Drupal\Core\Url;
......@@ -36,13 +36,6 @@ class LinkGenerator implements LinkGeneratorInterface {
*/
protected $moduleHandler;
/**
* The renderer service.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/**
* Constructs a LinkGenerator instance.
*
......@@ -50,13 +43,10 @@ class LinkGenerator implements LinkGeneratorInterface {
* The url generator.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer service.
*/
public function __construct(UrlGeneratorInterface $url_generator, ModuleHandlerInterface $module_handler, RendererInterface $renderer) {
public function __construct(UrlGeneratorInterface $url_generator, ModuleHandlerInterface $module_handler) {
$this->urlGenerator = $url_generator;
$this->moduleHandler = $module_handler;
$this->renderer = $renderer;
}
/**
......@@ -85,7 +75,8 @@ public function generate($text, Url $url) {
// Start building a structured representation of our link to be altered later.
$variables = array(
'text' => is_array($text) ? $this->renderer->render($text) : $text,
// @todo Inject the service when drupal_render() is converted to one.
'text' => is_array($text) ? drupal_render($text) : $text,
'url' => $url,
'options' => $url->getOptions(),
);
......@@ -94,6 +85,7 @@ public function generate($text, Url $url) {
$variables['options'] += array(
'attributes' => array(),
'query' => array(),
'html' => FALSE,
'language' => NULL,
'set_active_class' => FALSE,
'absolute' => FALSE,
......@@ -143,10 +135,9 @@ public function generate($text, Url $url) {
// it here in an HTML argument context, we need to encode it properly.
$url = String::checkPlain($url->toString());
// Make sure the link text is sanitized.
$safe_text = SafeMarkup::escape($variables['text']);
return SafeMarkup::set('<a href="' . $url . '"' . $attributes . '>' . $safe_text . '</a>');
// Sanitize the link text if necessary.
$text = $variables['options']['html'] ? $variables['text'] : String::checkPlain($variables['text']);
return SafeMarkup::set('<a href="' . $url . '"' . $attributes . '>' . $text . '</a>');
}
}
......@@ -18,28 +18,16 @@ interface LinkGeneratorInterface {
/**
* Renders a link to a URL.
*
* Examples:
* @code
* $link_generator = \Drupal::service('link_generator');
* $installer_url = \Drupal\Core\Url::fromUri('base://core/install.php');
* $installer_link = $link_generator->generate($text, $installer_url);
* $external_url = \Drupal\Core\Url::fromUri('http://example.com', ['query' => ['foo' => 'bar']]);
* $external_link = $link_generator->generate($text, $external_url);
* $internal_url = \Drupal\Core\Url::fromRoute('system.admin');
* $internal_link = $link_generator->generate($text, $internal_url);
* @endcode
* However, for links enclosed in translatable text you should use t() and
* embed the HTML anchor tag directly in the translated string. For example:
* @code
* $text = t('Visit the <a href="@url">content types</a> page', array('@url' => \Drupal::url('node.overview_types')));
* t('Visit the <a href="@url">content types</a> page', array('@url' => \Drupal::url('node.overview_types')));
* @endcode
* This keeps the context of the link title ('settings' in the example) for
* translators.
*
* @param string|array $text
* The link text for the anchor tag as a translated string or render array.
* Strings will be sanitized automatically. If you need to output HTML in
* the link text you should use a render array.
* @param \Drupal\Core\Url $url
* The URL object used for the link. Amongst its options, the following may
* be set to affect the generated link:
......@@ -48,6 +36,11 @@ interface LinkGeneratorInterface {
* must be a string; other elements are more flexible, as they just need
* to work as an argument for the constructor of the class
* Drupal\Core\Template\Attribute($options['attributes']).
* - html: Whether $text is HTML or just plain-text. For
* example, to make an image tag into a link, this must be set to TRUE, or
* you will see the escaped HTML image tag. $text is not sanitized if
* 'html' is TRUE. The calling function must ensure that $text is already
* safe. Defaults to FALSE.
* - language: An optional language object. If the path being linked to is
* internal to the site, $options['language'] is used to determine whether
* the link is "active", or pointing to the current page (the language as
......
......@@ -103,6 +103,7 @@ public function buildComponents(array &$build, array $entities, array $displays,
'#url' => Url::fromUri($link_href),
'#options' => array(
'attributes' => array('class' => array('feed-image')),
'html' => TRUE,
),
);
}
......@@ -119,16 +120,14 @@ public function buildComponents(array &$build, array $entities, array $displays,
if ($display->getComponent('more_link')) {
$title_stripped = strip_tags($entity->label());
$title = array(
'#type' => 'inline_template',
'#template' => '{% trans %}More<span class="visually-hidden"> posts about {{title}}</span>{% endtrans %}',
'#context' => array('title' => $title_stripped),
);
$build[$id]['more_link'] = array(
'#type' => 'link',
'#title' => $title,
'#title' => t('More<span class="visually-hidden"> posts about @title</span>', array(
'@title' => $title_stripped,
)),
'#url' => Url::fromRoute('entity.aggregator_feed.canonical', ['aggregator_feed' => $entity->id()]),
'#options' => array(
'html' => TRUE,
'attributes' => array(
'title' => $title_stripped,
),
......
......@@ -42,7 +42,7 @@ function block_help($route_name, RouteMatchInterface $route_match) {
$demo_theme = $route_match->getParameter('theme') ?: \Drupal::config('system.theme')->get('default');
$themes = list_themes();
$output = '<p>' . t('This page provides a drag-and-drop interface for adding a block to a region, and for controlling the order of blocks within regions. To add a block to a region, or to configure its specific title and visibility settings, click the block title under <em>Place blocks</em>. Since not all themes implement the same regions, or display regions in the same way, blocks are positioned on a per-theme basis. Remember that your changes will not be saved until you click the <em>Save blocks</em> button at the bottom of the page.') . '</p>';
$output .= '<p>' . \Drupal::l(t('Demonstrate block regions (@theme)', array('@theme' => $themes[$demo_theme]->info['name'])), new Url('block.admin_demo', array('theme' => $demo_theme))) . '</p>';
$output .= '<p>' . \Drupal::l(t('Demonstrate block regions (!theme)', array('!theme' => $themes[$demo_theme]->info['name'])), new Url('block.admin_demo', array('theme' => $demo_theme))) . '</p>';
return $output;
}
}
......
......@@ -207,34 +207,24 @@ function checkBookNode(EntityInterface $node, $nodes, $previous = FALSE, $up = F
// Check previous, up, and next links.
if ($previous) {
$text = array(
'#type' => 'inline_template',
'#template' => '<b>‹</b> {{ label }}',
'#context' => array('label' => $previous->label()),
);
/** @var \Drupal\Core\Url $url */
$url = $previous->urlInfo();
$url->setOptions(array('attributes' => array('rel' => array('prev'), 'title' => t('Go to previous page'))));
$this->assertRaw(\Drupal::l($text, $url), 'Previous page link found.');
$url->setOptions(array('html' => TRUE, 'attributes' => array('rel' => array('prev'), 'title' => t('Go to previous page'))));
$this->assertRaw(\Drupal::l('<b>‹</b> ' . $previous->label(), $url), 'Previous page link found.');
}
if ($up) {
/** @var \Drupal\Core\Url $url */
$url = $up->urlInfo();
$url->setOptions(array('attributes' => array('title' => t('Go to parent page'))));
$url->setOptions(array('html'=> TRUE, 'attributes' => array('title' => t('Go to parent page'))));
$this->assertRaw(\Drupal::l('Up', $url), 'Up page link found.');
}
if ($next) {
$text = array(
'#type' => 'inline_template',
'#template' => '{{ label }} <b>›</b>',
'#context' => array('label' => $next->label()),
);
/** @var \Drupal\Core\Url $url */
$url = $next->urlInfo();
$url->setOptions(array('attributes' => array('rel' => array('next'), 'title' => t('Go to next page'))));
$this->assertRaw(\Drupal::l($text, $url), 'Next page link found.');
$url->setOptions(array('html'=> TRUE, 'attributes' => array('rel' => array('next'), 'title' => t('Go to next page'))));
$this->assertRaw(\Drupal::l($next->label() . ' <b>›</b>', $url), 'Next page link found.');
}
// Compute the expected breadcrumb.
......
......@@ -39,6 +39,7 @@ function hook_comment_links_alter(array &$links, CommentInterface $entity, array
'comment-report' => array(
'title' => t('Report'),
'url' => Url::fromRoute('comment_test.report', ['comment' => $entity->id()], ['query' => ['token' => \Drupal::getContainer()->get('csrf_token')->get("comment/{$entity->id()}/report")]]),
'html' => TRUE,
),
),
);
......
......@@ -151,6 +151,7 @@ public function buildCommentedEntityLinks(FieldableEntityInterface $entity, arra
elseif ($this->currentUser->isAnonymous()) {
$links['comment-forbidden'] = array(
'title' => $this->commentManager->forbiddenMessage($entity, $field_name),
'html' => TRUE,
);
}
}
......@@ -185,6 +186,7 @@ public function buildCommentedEntityLinks(FieldableEntityInterface $entity, arra
elseif ($this->currentUser->isAnonymous()) {
$links['comment-forbidden'] = array(
'title' => $this->commentManager->forbiddenMessage($entity, $field_name),
'html' => TRUE,
);
}
}
......
......@@ -247,6 +247,7 @@ protected static function buildLinks(CommentInterface $entity, EntityInterface $
$links['comment-delete'] = array(
'title' => t('Delete'),
'url' => $entity->urlInfo('delete-form'),
'html' => TRUE,
);
}
......@@ -254,6 +255,7 @@ protected static function buildLinks(CommentInterface $entity, EntityInterface $
$links['comment-edit'] = array(
'title' => t('Edit'),
'url' => $entity->urlInfo('edit-form'),
'html' => TRUE,
);
}
if ($entity->access('create')) {
......@@ -265,16 +267,19 @@ protected static function buildLinks(CommentInterface $entity, EntityInterface $
'field_name' => $entity->getFieldName(),
'pid' => $entity->id(),
]),
'html' => TRUE,
);
}
if (!$entity->isPublished() && $entity->access('approve')) {
$links['comment-approve'] = array(
'title' => t('Approve'),
'url' => Url::fromRoute('comment.approve', ['comment' => $entity->id()]),
'html' => TRUE,
);
}
if (empty($links) && \Drupal::currentUser()->isAnonymous()) {
$links['comment-forbidden']['title'] = \Drupal::service('comment.manager')->forbiddenMessage($commented_entity, $entity->getFieldName());
$links['comment-forbidden']['html'] = TRUE;
}
}
......@@ -283,6 +288,7 @@ protected static function buildLinks(CommentInterface $entity, EntityInterface $
$links['comment-translations'] = array(
'title' => t('Translate'),
'url' => $entity->urlInfo('drupal:content-translation-overview'),
'html' => TRUE,
);
}
......
......@@ -38,6 +38,7 @@ function comment_test_comment_links_alter(array &$links, CommentInterface &$enti
'comment-report' => array(
'title' => t('Report'),
'url' => Url::fromRoute('comment_test.report', ['comment' => $entity->id()], ['query' => ['token' => \Drupal::getContainer()->get('csrf_token')->get("comment/{$entity->id()}/report")]]),
'html' => TRUE,
),
),
);
......
......@@ -8,9 +8,8 @@
namespace Drupal\dblog\Controller;
use Drupal\Component\Utility\Html;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Unicode;
use Drupal\Component\Utility\String;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Controller\ControllerBase;
use Drupal\Core\Database\Connection;
......@@ -176,15 +175,14 @@ public function overview() {
foreach ($result as $dblog) {
$message = $this->formatMessage($dblog);
if ($message && isset($dblog->wid)) {
// Truncate link_text to 56 chars of message. This is a rare case where
// it is acceptable to call SafeMarkup::set() as we are truncating text
// that has already passed through SafeMarkup::set().
$log_text = SafeMarkup::set(Unicode::truncate(Xss::filter($message, array()), 56, TRUE, TRUE));
// Truncate link_text to 56 chars of message.
$log_text = Unicode::truncate(Xss::filter($message, array()), 56, TRUE, TRUE);
$message = $this->l($log_text, new Url('dblog.event', array('event_id' => $dblog->wid), array(
'attributes' => array(
// Provide a title for the link for useful hover hints.
'title' => Unicode::truncate(strip_tags($message), 256, TRUE, TRUE),
),
'html' => TRUE,
)));
}
$username = array(
......
......@@ -77,10 +77,7 @@ public function testIntegration() {
'variables' => array(
'@token1' => $this->randomMachineName(),
'!token2' => $this->randomMachineName(),
'link' => \Drupal::l(array(
'#type' => 'inline_template',
'#template' => '<object>Link</object>',
), new Url('<front>')),
'link' => \Drupal::l('<object>Link</object>', new Url('<front>')),
),
);
$logger_factory = $this->container->get('logger.factory');
......
......@@ -121,6 +121,9 @@ public function render() {
'#type' => 'link',
'#url' => Url::fromRoute($short_type == 'view' ? 'field_ui.entity_view_mode_add_type' : 'field_ui.entity_form_mode_add_type', ['entity_type_id' => $entity_type]),
'#title' => t('Add new %label @entity-type', array('%label' => $this->entityTypes[$entity_type]->getLabel(), '@entity-type' => $this->entityType->getLowercaseLabel())),
'#options' => array(
'html' => TRUE,
),
),
'colspan' => count($table['#header']),
);
......
......@@ -8,7 +8,6 @@
namespace Drupal\image\Tests;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Url;
use Drupal\field\Entity\FieldStorageConfig;
/**
......@@ -27,22 +26,6 @@ class ImageFieldDisplayTest extends ImageFieldTestBase {
*/
public static $modules = array('field_ui');
/**
* The link generator.
*
* @var \Drupal\Core\Utility\LinkGeneratorInterface
*/
protected $linkGenerator;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->linkGenerator = $this->container->get('link_generator');
}
/**
* Test image formatters on node display for public files.
*/
......@@ -125,8 +108,7 @@ function _testImageFieldFormatters($scheme) {
'#width' => 40,
'#height' => 20,
);
$default_output = $this->linkGenerator->generate($image, Url::fromUri(file_create_url($image_uri)));
$default_output = '<a href="' . file_create_url($image_uri) . '">' . drupal_render($image) . '</a>';
$this->drupalGet('node/' . $nid);
$cache_tags_header = $this->drupalGetHeader('X-Drupal-Cache-Tags');
$this->assertTrue(!preg_match('/ image_style\:/', $cache_tags_header), 'No image style cache tag found.');
......
......@@ -555,6 +555,7 @@ function hook_node_links_alter(array &$links, NodeInterface $entity, array &$con
'node-report' => array(
'title' => t('Report'),
'href' => "node/{$entity->id()}/report",
'html' => TRUE,
'query' => array('token' => \Drupal::getContainer()->get('csrf_token')->get("node/{$entity->id()}/report")),
),
),
......
......@@ -149,6 +149,7 @@ protected static function buildLinks(NodeInterface $entity, $view_mode) {
)),
'url' => $entity->urlInfo(),
'language' => $entity->language(),
'html' => TRUE,
'attributes' => array(
'rel' => 'tag',
'title' => $node_title_stripped,
......
......@@ -152,6 +152,7 @@ function theme_responsive_image_formatter($variables) {
if (isset($variables['path']['path'])) {
$path = $variables['path']['path'];
$options = isset($variables['path']['options']) ? $variables['path']['options'] : array();
$options['html'] = TRUE;
return \Drupal::l($responsive_image, Url::fromUri($path, $options));
}
......
......@@ -8,7 +8,6 @@
namespace Drupal\responsive_image\Tests;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Url;
use Drupal\image\Tests\ImageFieldTestBase;
/**
......@@ -35,20 +34,11 @@ class ResponsiveImageFieldDisplayTest extends ImageFieldTestBase {
public static $modules = array('field_ui', 'responsive_image', 'responsive_image_test_module');
/**
* The link generator.
*
* @var \Drupal\Core\Utility\LinkGeneratorInterface
*/
protected $linkGenerator;
/**
* {@inheritdoc}
* Drupal\simpletest\WebTestBase\setUp().
*/
protected function setUp() {
parent::setUp();
$this->linkGenerator = $this->container->get('link_generator');
// Create user.
$this->admin_user = $this->drupalCreateUser(array(
'administer responsive images',
......@@ -170,8 +160,7 @@ protected function doTestResponsiveImageFieldFormatters($scheme, $empty_styles =
'#width' => 40,
'#height' => 20,
);
$default_output = $this->linkGenerator->generate($image, Url::fromUri(file_create_url($image_uri)));
$default_output = '<a href="' . file_create_url($image_uri) . '">' . drupal_render($image) . '</a>';
$this->drupalGet('node/' . $nid);
$cache_tags_header = $this->drupalGetHeader('X-Drupal-Cache-Tags');
$this->assertTrue(!preg_match('/ image_style\:/', $cache_tags_header), 'No image style cache tag found.');
......
......@@ -8,8 +8,8 @@
use Drupal\Core\Access\AccessResult;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Cache\Cache;
use Drupal\Component\Utility\NestedArray;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Routing\UrlMatcher;
use Drupal\Core\Url;
use Drupal\shortcut\Entity\ShortcutSet;
use Drupal\shortcut\ShortcutSetInterface;
......@@ -339,13 +339,9 @@ function shortcut_preprocess_page(&$variables) {
),
'#prefix' => '<div class="add-or-remove-shortcuts ' . $link_mode . '-shortcut">',
'#type' => 'link',
'#title' => array(
'#type' => 'inline_template',
'#template' => '<span class="icon"></span><span class="text">{{ link_text }}</span>',
'#context' => array('link_text' => $link_text),
),
'#title' => '<span class="icon"></span><span class="text">'. $link_text .'</span>',
'#url' => Url::fromRoute($route_name, $route_parameters),
'#options' => array('query' => $query),
'#options' => array('query' => $query, 'html' => TRUE),
'#suffix' => '</div>',
);
}
......
......@@ -294,9 +294,6 @@ protected function getAllOptions(\SimpleXMLElement $element) {
* TRUE if the assertion succeeded, FALSE otherwise.
*/
protected function assertLink($label, $index = 0, $message = '', $group = 'Other') {
// $this->xpath will escape entities, so we need to decode them first
// to avoid double escaping leading to failed tests.
$label = html_entity_decode($label);
$links = $this->xpath('//a[normalize-space(text())=:label]', array(':label' => $label));
$message = ($message ? $message : String::format('Link with label %label found.', array('%label' => $label)));
return $this->assert(isset($links[$index]), $message, $group);
......
......@@ -211,15 +211,6 @@ function testLinks() {
'key' => 'value',
)
),
'render array' => array(
'title' => array(
'#type' => 'inline_template',
'#template' => '<span class="unescaped">{{ text }}</span>',
'#context' => array(
'text' => 'potentially unsafe text that <should> be escaped',
),
),
),
);
$expected_links = '';
......@@ -230,7 +221,6 @@ function testLinks() {
$expected_links .= '<li class="router-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '">' . String::checkPlain('Test route') . '</a></li>';
$query = array('key' => 'value');
$expected_links .= '<li class="query-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1', $query) . '">' . String::checkPlain('Query test route') . '</a></li>';
$expected_links .= '<li class="render-array"><span class="unescaped">' . String::checkPlain('potentially unsafe text that <should> be escaped') . '</span></li>';
$expected_links .= '</ul>';
// Verify that passing a string as heading works.
......@@ -270,7 +260,6 @@ function testLinks() {
$expected_links .= '<li class="router-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1') . '">' . String::checkPlain('Test route') . '</a></li>';
$query = array('key' => 'value');
$expected_links .= '<li class="query-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1', $query) . '">' . String::checkPlain('Query test route') . '</a></li>';
$expected_links .= '<li class="render-array"><span class="unescaped">' . String::checkPlain('potentially unsafe text that <should> be escaped') . '</span></li>';
$expected_links .= '</ul>';
$expected = $expected_heading . $expected_links;
$this->assertThemeOutput('links', $variables, $expected);
......@@ -287,7 +276,6 @@ function testLinks() {
$query = array('key' => 'value');
$encoded_query = String::checkPlain(Json::encode($query));
$expected_links .= '<li data-drupal-link-query="'.$encoded_query.'" data-drupal-link-system-path="router_test/test1" class="query-test"><a href="' . \Drupal::urlGenerator()->generate('router_test.1', $query) . '" data-drupal-link-query="'.$encoded_query.'" data-drupal-link-system-path="router_test/test1">' . String::checkPlain('Query test route') . '</a></li>';
$expected_links .= '<li class="render-array"><span class="unescaped">' . String::checkPlain('potentially unsafe text that <should> be escaped') . '</span></li>';
$expected_links .= '</ul>';
$expected = $expected_heading . $expected_links;
$this->assertThemeOutput('links', $variables, $expected);
......