diff --git a/core/includes/theme.inc b/core/includes/theme.inc index cc277c5..d0f860f 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -360,61 +360,29 @@ function theme_get_setting($setting_name, $theme = NULL) { } /** - * Helper function to automatically escape variables in theme functions. + * Helper function to escape and render variables in theme functions. * - * You use this method in theme functions to ensure that the result is safe. - * This mimics the behavior of the autoescape in Twig. - * - * @see \Drupal\Core\Template\TwigExtension::escapeFilter() + * Use this method in theme functions to ensure that the result is safe for + * output inside HTML fragments. This mimics the behavior of the auto-escape + * functionality in Twig. * * @param mixed $arg - * The string, object, or render array to escape if needed. + * The string, object, or render array to escape and render. * * @return string - * HTML string. + * The rendered string. + * + * @see \Drupal\Core\Template\TwigExtension::escapeFilter() */ -function theme_autoescape($arg) { - // @see - if ($arg instanceOf SafeStringInterface) { - return (string) $arg; - } - $return = NULL; - - if (is_scalar($arg)) { - $return = (string) $arg; - } - elseif (is_object($arg)) { - if ($arg instanceof RenderableInterface) { - $arg = $arg->toRenderable(); - } - elseif (method_exists($arg, '__toString')) { - $return = (string) $arg; - } - // You can't throw exceptions in the magic PHP __toString methods, see - // http://php.net/manual/en/language.oop5.magic.php#object.tostring so - // we also support a toString method. - elseif (method_exists($arg, 'toString')) { - $return = $arg->toString(); - } - else { - throw new \Exception(t('Object of type "@class" cannot be printed.', array('@class' => get_class($arg)))); - } - } - - // We have a string or an object converted to a string: Autoescape it! - if (isset($return)) { - return SafeMarkup::isSafe($return, 'html') ? $return: Html::escape($return); - } - - // This is a normal render array, which is safe by definition, with - // special simple cases already handled. +function theme_escape_and_render($arg) { + /** @var \Drupal\Core\Template\TwigEnvironment $environment */ + $environment = \Drupal::service('twig'); - // Early return if this element was pre-rendered (no need to re-render). - if (isset($arg['#printed']) && $arg['#printed'] == TRUE && isset($arg['#markup']) && strlen($arg['#markup']) > 0) { - return (string) $arg['#markup']; + $return = \Drupal::service('twig.extension')->escapeFilter($environment, $arg, 'html', NULL, TRUE); + if ($return instanceof SafeStringInterface) { + $return = (string) $return; } - $arg['#printed'] = FALSE; - return (string) \Drupal::service('renderer')->render($arg); + return $return; } /** diff --git a/core/tests/Drupal/KernelTests/Core/Theme/ThemeAutoescapeTest.php b/core/tests/Drupal/KernelTests/Core/Theme/ThemeAutoescapeTest.php index 7cfaba1..afacc4b 100644 --- a/core/tests/Drupal/KernelTests/Core/Theme/ThemeAutoescapeTest.php +++ b/core/tests/Drupal/KernelTests/Core/Theme/ThemeAutoescapeTest.php @@ -20,14 +20,6 @@ class ThemeAutoescapeTest extends KernelTestBase { /** - * Modules to enable. - * - * @var array - */ - public static $modules = []; - - - /** * Tests automatic escaping. * * @dataProvider providerTestThemeAutoescape @@ -37,7 +29,7 @@ public function testThemeAutoescape($arg, $expected) { $renderer = \Drupal::service('renderer'); $context = new RenderContext(); $renderer->executeInRenderContext($context, function() use ($expected, $arg) { - $this->assertSame($expected, theme_autoescape($arg)); + $this->assertSame($expected, theme_escape_and_render($arg)); }); } @@ -46,11 +38,11 @@ public function testThemeAutoescape($arg, $expected) { */ public function providerTestThemeAutoescape() { return [ - ['', ''], + ['', NULL], ['a', 'a'], ['>', '>'], - [SafeString::create('hi'), 'hi'], - [['#markup' => 'hi'], 'hi'], + [SafeString::create(''), ''], + [['#markup' => ''], ''], ['', Html::escape('')], ]; }