diff --git a/core/includes/theme.inc b/core/includes/theme.inc index abde750..3870138 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -402,7 +402,7 @@ function theme_get_setting($setting_name, $theme = NULL) { */ function theme_render_and_autoescape($arg) { // Bubbles argument's cacheability & attachment metadata if necessary. - if (($arg instanceof CacheableDependencyInterface || $arg instanceof AttachmentsInterface) && !($arg instanceof MarkupInterface)) { + if (!($arg instanceof RenderableInterface) && ($arg instanceof CacheableDependencyInterface || $arg instanceof AttachmentsInterface)) { $arg_bubbleable = []; if ($arg instanceof CacheableDependencyInterface) { $arg_bubbleable['#cache']['contexts'] = $arg->getCacheContexts(); diff --git a/core/tests/Drupal/KernelTests/Core/Theme/ThemeRenderAndAutoescapeTest.php b/core/tests/Drupal/KernelTests/Core/Theme/ThemeRenderAndAutoescapeTest.php index cbbb75a..cc65ffe 100644 --- a/core/tests/Drupal/KernelTests/Core/Theme/ThemeRenderAndAutoescapeTest.php +++ b/core/tests/Drupal/KernelTests/Core/Theme/ThemeRenderAndAutoescapeTest.php @@ -8,6 +8,7 @@ namespace Drupal\KernelTests\Core\Theme; use Drupal\Component\Utility\Html; +use Drupal\Core\GeneratedLink; use Drupal\Core\Link; use Drupal\Core\Render\RenderContext; use Drupal\Core\Render\Markup; @@ -87,6 +88,26 @@ public function testThemeEscapeAndRenderNotPrintable() { theme_render_and_autoescape(new NonPrintable()); } + /** + * Ensure cache metadata is bubbled when using theme_render_and_autoescape(). + */ + public function testBubblingMetadata() { + $link = new GeneratedLink(); + $link->setGeneratedLink(''); + $link->addCacheTags(['foo']); + + $context = new RenderContext(); + // Use a closure here since we need to render with a render context. + $theme_render_and_autoescape = function () use ($link) { + return theme_render_and_autoescape($link); + }; + /** @var \Drupal\Core\Render\RendererInterface $renderer */ + $renderer = \Drupal::service('renderer'); + $output = $renderer->executeInRenderContext($context, $theme_render_and_autoescape); + $this->assertEquals('', $output); + $this->assertEquals(['foo'], $context->pop()->getCacheTags()); + } + } class NonPrintable { } diff --git a/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php b/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php index cb09022..de1ba20 100644 --- a/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php +++ b/core/tests/Drupal/Tests/Core/Template/TwigExtensionTest.php @@ -7,8 +7,10 @@ namespace Drupal\Tests\Core\Template; +use Drupal\Core\GeneratedLink; use Drupal\Core\Render\RenderableInterface; use Drupal\Core\Render\RendererInterface; +use Drupal\Core\Routing\UrlGeneratorInterface; use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Core\Template\Loader\StringLoader; use Drupal\Core\Template\TwigEnvironment; @@ -240,6 +242,45 @@ public function providerTestRenderVar() { return $data; } + /** + * @covers ::escapeFilter + */ + public function testEscapeWithGeneratedLink() { + $renderer = $this->prophesize(RendererInterface::class); + $twig = new \Twig_Environment(NULL, [ + 'debug' => TRUE, + 'cache' => FALSE, + 'autoescape' => 'html', + 'optimizations' => 0, + ] + ); + + $twig_extension = new TwigExtension($renderer->reveal()); + $twig->addExtension($twig_extension->setUrlGenerator($this->prophesize(UrlGeneratorInterface::class)->reveal())); + $link = new GeneratedLink(); + $link->setGeneratedLink(''); + $link->addCacheTags(['foo']); + + $result = $twig_extension->escapeFilter($twig, $link, 'html', NULL, TRUE); + $renderer->render(["#cache" => ["contexts" => [], "tags" => ["foo"], "max-age" => -1], "#attached" => []])->shouldHaveBeenCalled(); + $this->assertEquals('', $result); + } + + /** + * @covers ::renderVar + */ + public function testRenderVarWithGeneratedLink() { + $renderer = $this->prophesize(RendererInterface::class); + $twig_extension = new TwigExtension($renderer->reveal()); + $link = new GeneratedLink(); + $link->setGeneratedLink(''); + $link->addCacheTags(['foo']); + + $result = $twig_extension->renderVar($link); + $renderer->render(["#cache" => ["contexts" => [], "tags" => ["foo"], "max-age" => -1], "#attached" => []])->shouldHaveBeenCalled(); + $this->assertEquals('', $result); + } + } class TwigExtensionTestString {