diff --git a/includes/common.inc b/includes/common.inc index 0f7c014b5f..84998dfa04 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -5770,7 +5770,22 @@ function drupal_pre_render_conditional_comments($elements) { } /** - * TODO + * Pre-render callback: Renders a generic HTML tag with attributes. + * + * @param array $elements + * An associative array containing: + * - #tag: The tag name to output. Typical tags added to the HTML HEAD: + * - meta: To provide meta information, such as a page refresh. + * - link: To refer to stylesheets and other contextual information. + * - script: To load JavaScript. + * The value of #tag is escaped. + * - #attributes: (optional) An array of HTML attributes to apply to the + * tag. The attributes are escaped, see \Drupal\Core\Template\Attribute. + * - #value: (optional) A string containing tag content, such as inline + * CSS. The value of #value will be XSS admin filtered if it is not safe. + * + * @return array + * The render array. */ function drupal_pre_render_htmltag(array $elements) { $void_elements = array( @@ -5781,24 +5796,27 @@ function drupal_pre_render_htmltag(array $elements) { $attributes = isset($elements['#attributes']) ? drupal_attributes($elements['#attributes']) : ''; - $open_tag = '<' . $elements['#tag'] . $attributes; - $close_tag = ''; + $tag = check_plain($elements['#tag']); + + $open_tag = '<' . $tag . $attributes; + $close_tag = ''; // Construct a void element. - if (in_array($elements['#tag'], $void_elements, TRUE)) { + if (in_array($tag, $void_elements, TRUE)) { $open_tag .= ' />'; - $close_tag = ''; + $close_tag = "\n"; $elements['#markup'] = NULL; } else { $open_tag .= '>'; + $close_tag .= "\n"; $elements['#markup'] = $elements['#value']; } - $open_tag .= $elements['#value_prefix']; - $close_tag = $elements['#value_suffix'] . $close_tag; + $elements['#markup'] = $elements['#value_prefix'] . $elements['#markup']; + $elements['#markup'] .= $elements['#value_suffix']; $elements['#prefix'] .= $open_tag; - $elements['#suffix'] = $close_tag . $elements['#suffix'] ."\n"; + $elements['#suffix'] = $close_tag . $elements['#suffix']; $elements['#children'] = $elements['#markup']; diff --git a/modules/simpletest/tests/theme.test b/modules/simpletest/tests/theme.test index 3136b53452..5a043d59ee 100644 --- a/modules/simpletest/tests/theme.test +++ b/modules/simpletest/tests/theme.test @@ -546,44 +546,200 @@ class RenderElementTypesTestCase extends DrupalWebTestCase { ), 'expected' => 'title test' . "\n", ), - // Test html tag with nested elements. array( - 'name' => "#type 'html_tag' with nested elements", + 'name' => 'Value prefix/suffix.', + 'value' => array( + '#type' => 'html_tag', + '#value' => 'value', + '#tag' => 'p', + ), + 'expected' => '

value

' . "\n", + ), + array( + 'name' => 'Normal element without a value should not result in a void element.', + 'value' => array( + '#type' => 'html_tag', + '#value' => NULL, + '#tag' => 'p', + ), + 'expected' => '

' . "\n", + ), + array( + 'name' => 'A void element.', + 'value' => array( + '#type' => 'html_tag', + '#tag' => 'br', + ), + 'expected' => '
' . "\n", + ), + array( + 'name' => 'Attributes.', 'value' => array( '#type' => 'html_tag', '#tag' => 'div', - 'child1' => array( - '#type' => 'html_tag', - '#tag' => 'em', - '#value' => 'test', + '#attributes' => array( + 'class' => 'test', + 'id' => 'id' ), - 'child2' => array( - '#type' => 'html_tag', - '#tag' => 'span', - '#value' => 'value', + '#value' => 'value', + ), + 'expected' => '
value
' . "\n", + ), + array( + 'name' => 'Ensure that #tag is sanitised.', + 'value' => array( + '#type' => 'html_tag', + '#tag' => 'p> 'value', + ), + 'expected' => 'value' . "\n", + ), + array( + 'name' => '', + 'value' => array( + '#type' => 'html_tag', + '#tag' => 'p', + '#value' => '', + ), + 'expected' => '

' . "\n", + ), + array( + 'name' => 'Ensure that nested render arrays render properly.', + 'value' => array( + '#type' => 'html_tag', + '#tag' => 'p', + '#value' => NULL, + [ + ['#markup' => 'value1'], + ['#markup' => 'value2'], + ], + ), + 'expected' => '

value1value2

' . "\n", + ), + array( + 'name' => 'Ensure svg elements (rect)', + 'value' => array( + '#type' => 'html_tag', + '#tag' => 'rect', + '#attributes' => array( + 'width' => 25, + 'height' => 25, + 'x' => 5, + 'y' => 10, ), ), - 'expected' => '
test' . "\n" . 'value' . "\n" . '
' . "\n", + 'expected' => '' . "\n", ), - // Test html tag with nested elements. array( - 'name' => "#type 'html_tag' with nested elements", + 'name' => 'Ensure svg elements (circle)', + 'value' => array( + '#type' => 'html_tag', + '#tag' => 'circle', + '#attributes' => array( + 'cx' => 100, + 'cy' => 100, + 'r' => 100, + ), + ), + 'expected' => '' . "\n", + ), + array( + 'name' => 'Ensure svg elements (polygon)', + 'value' => array( + '#type' => 'html_tag', + '#tag' => 'polygon', + '#attributes' => array( + 'points' => '60,20 100,40 100,80 60,100 20,80 20,40', + ), + ), + 'expected' => '' . "\n", + ), + array( + 'name' => 'Ensure svg elements (use)', + 'value' => array( + '#type' => 'html_tag', + '#tag' => 'use', + '#attributes' => array( + 'x' => 50, + 'y' => 10, + 'width' => 50, + 'height' => 50, + ), + ), + 'expected' => '' . "\n", + ), + array( + 'name' => 'Ensure svg elements (path)', + 'value' => array( + '#type' => 'html_tag', + '#tag' => 'path', + '#attributes' => array( + 'd' => 'M 100 100 L 300 100 L 200 300 z', + 'fill' => 'orange', + 'stroke' => 'black', + 'stroke-width' => 3, + ), + ), + 'expected' => '' . "\n", + ), + array( + 'name' => 'Ensure svg elements (stop)', + 'value' => array( + '#type' => 'html_tag', + '#tag' => 'stop', + '#attributes' => array( + 'offset' => '5%', + 'stop-color' => '#F60', + ), + ), + 'expected' => '' . "\n", + ), + array( + 'name' => 'Ensure svg elements (linearGradient)', 'value' => array( '#type' => 'html_tag', - '#tag' => 'div', - '#value' => 'title test', - 'child1' => array( + '#tag' => 'linearGradient', + '#value' => NULL, + array( '#type' => 'html_tag', - '#tag' => 'em', - '#value' => 'test', + '#tag' => 'stop', + '#value' => NULL, + '#attributes' => array( + 'offset' => '5%', + 'stop-color' => '#F60', + ), ), - 'child2' => array( + array( '#type' => 'html_tag', - '#tag' => 'span', - '#value' => 'value', + '#tag' => 'stop', + '#value' => NULL, + '#attributes' => array( + 'offset' => '95%', + 'stop-color' => '#FF6', + ), + ), + ), + 'expected' => '' . "\n" . '' . "\n" . '' . "\n", + ), + array( + 'name' => 'Simple link.', + 'value' => array( + '#type' => 'html_tag', + '#tag' => 'link', + ), + 'expected' => '' . "\n", + ), + array( + 'name' => 'Conditional link.', + 'value' => array( + '#type' => 'html_tag', + '#tag' => 'link', + '#browsers' => array( + 'IE' => TRUE, + '!IE' => FALSE, ), ), - 'expected' => '
title test
' . "\n", + 'expected' => "\n" . '' . "\n", ), );