Commit 31a3fe83 authored by catch's avatar catch

Issue #2694535 by WidgetsBurritos, samuel.mortenson, Manuel Garcia, idebr,...

Issue #2694535 by WidgetsBurritos, samuel.mortenson, Manuel Garcia, idebr, tstoeckler, metzlerd, larowlan: Support rect property and nested render arrays in html_tag for dynamic SVGs
parent da86c03c
......@@ -41,6 +41,7 @@ class HtmlTag extends RenderElement {
static protected $voidElements = [
'area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input',
'keygen', 'link', 'meta', 'param', 'source', 'track', 'wbr',
'rect', 'circle', 'polygon', 'ellipse', 'stop', 'use', 'path',
];
/**
......@@ -59,7 +60,7 @@ public function getInfo() {
}
/**
* Pre-render callback: Renders a generic HTML tag with attributes into #markup.
* Pre-render callback: Renders a generic HTML tag with attributes.
*
* @param array $element
* An associative array containing:
......@@ -84,21 +85,27 @@ public static function preRenderHtmlTag($element) {
// An HTML tag should not contain any special characters. Escape them to
// ensure this cannot be abused.
$escaped_tag = HtmlUtility::escape($element['#tag']);
$markup = '<' . $escaped_tag . $attributes;
$open_tag = '<' . $escaped_tag . $attributes;
$close_tag = '</' . $escaped_tag . ">\n";
$prefix = isset($element['#prefix']) ? $element['#prefix'] . $open_tag : $open_tag;
$suffix = isset($element['#suffix']) ? $close_tag . $element['#suffix'] : $close_tag;
// Construct a void element.
if (in_array($element['#tag'], self::$voidElements)) {
$markup .= " />\n";
$prefix .= " />\n";
$suffix = '';
}
// Construct all other elements.
else {
$markup .= '>';
$markup .= $element['#value'] instanceof MarkupInterface ? $element['#value'] : Xss::filterAdmin($element['#value']);
$markup .= '</' . $escaped_tag . ">\n";
$prefix .= '>';
$markup = $element['#value'] instanceof MarkupInterface ? $element['#value'] : Xss::filterAdmin($element['#value']);
$element['#markup'] = Markup::create($markup);
}
if (!empty($element['#noscript'])) {
$markup = "<noscript>$markup</noscript>";
$prefix = '<noscript>' . $prefix;
$suffix .= '</noscript>';
}
$element['#markup'] = Markup::create($markup);
$element['#prefix'] = Markup::create($prefix);
$element['#suffix'] = Markup::create($suffix);
return $element;
}
......
......@@ -182,7 +182,7 @@ public function testRender() {
$output = \Drupal::service('renderer')->renderRoot($build);
$this->assertEquals('core', \Drupal::theme()->getActiveTheme()->getName());
$this->assertEquals($expected, $build['#children']);
$this->assertEquals($expected, $build['#markup']);
$this->assertEquals($expected, $output);
}
......
......@@ -3,14 +3,14 @@
namespace Drupal\Tests\Core\Render\Element;
use Drupal\Core\Render\Markup;
use Drupal\Tests\UnitTestCase;
use Drupal\Tests\Core\Render\RendererTestBase;
use Drupal\Core\Render\Element\HtmlTag;
/**
* @coversDefaultClass \Drupal\Core\Render\Element\HtmlTag
* @group Render
*/
class HtmlTagTest extends UnitTestCase {
class HtmlTagTest extends RendererTestBase {
/**
* @covers ::getInfo
......@@ -29,8 +29,12 @@ public function testGetInfo() {
*/
public function testPreRenderHtmlTag($element, $expected) {
$result = HtmlTag::preRenderHtmlTag($element);
$this->assertArrayHasKey('#markup', $result);
$this->assertEquals($expected, $result['#markup']);
foreach ($result as &$child) {
if (is_array($child) && isset($child['#tag'])) {
$child = HtmlTag::preRenderHtmlTag($child);
}
}
$this->assertEquals($expected, (string) $this->renderer->renderRoot($result));
}
/**
......@@ -92,6 +96,112 @@ public function providerPreRenderHtmlTag() {
];
$tags[] = [$element, "<p>value</p>\n"];
// Ensure that nested render arrays render properly.
$element = [
'#tag' => 'p',
'#value' => NULL,
[
['#markup' => '<b>value1</b>'],
['#markup' => '<b>value2</b>'],
],
];
$tags[] = [$element, "<p><b>value1</b><b>value2</b></p>\n"];
// Ensure svg elements.
$element = [
'#tag' => 'rect',
'#attributes' => [
'width' => 25,
'height' => 25,
'x' => 5,
'y' => 10,
],
];
$tags[] = [$element, '<rect width="25" height="25" x="5" y="10" />' . "\n"];
$element = [
'#tag' => 'circle',
'#attributes' => [
'cx' => 100,
'cy' => 100,
'r' => 100,
],
];
$tags[] = [$element, '<circle cx="100" cy="100" r="100" />' . "\n"];
$element = [
'#tag' => 'polygon',
'#attributes' => [
'points' => '60,20 100,40 100,80 60,100 20,80 20,40',
],
];
$tags[] = [$element, '<polygon points="60,20 100,40 100,80 60,100 20,80 20,40" />' . "\n"];
$element = [
'#tag' => 'ellipse',
'#attributes' => [
'cx' => 60,
'cy' => 60,
'rx' => 50,
'ry' => 25,
],
];
$tags[] = [$element, '<ellipse cx="60" cy="60" rx="50" ry="25" />' . "\n"];
$element = [
'#tag' => 'use',
'#attributes' => [
'x' => 50,
'y' => 10,
'width' => 50,
'height' => 50,
],
];
$tags[] = [$element, '<use x="50" y="10" width="50" height="50" />' . "\n"];
$element = [
'#tag' => 'path',
'#attributes' => [
'd' => 'M 100 100 L 300 100 L 200 300 z',
'fill' => 'orange',
'stroke' => 'black',
'stroke-width' => 3,
],
];
$tags[] = [$element, '<path d="M 100 100 L 300 100 L 200 300 z" fill="orange" stroke="black" stroke-width="3" />' . "\n"];
$element = [
'#tag' => 'stop',
'#attributes' => [
'offset' => '5%',
'stop-color' => '#F60',
],
];
$tags[] = [$element, '<stop offset="5%" stop-color="#F60" />' . "\n"];
// Nested svg elements.
$element = [
'#tag' => 'linearGradient',
'#value' => NULL,
[
'#tag' => 'stop',
'#value' => NULL,
'#attributes' => [
'offset' => '5%',
'stop-color' => '#F60',
],
],
[
'#tag' => 'stop',
'#value' => NULL,
'#attributes' => [
'offset' => '95%',
'stop-color' => '#FF6',
],
],
];
$tags[] = [$element, '<linearGradient><stop offset="5%" stop-color="#F60" />' . "\n" . '<stop offset="95%" stop-color="#FF6" />' . "\n" . '</linearGradient>' . "\n"];
return $tags;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment