Skip to content

Commit

Permalink
Support TEXTAREA and TITLE elements.
Browse files Browse the repository at this point in the history
  • Loading branch information
dmsnell committed Jan 25, 2024
1 parent 85185a4 commit 0145fef
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 5 deletions.
25 changes: 22 additions & 3 deletions src/wp-includes/html-api/class-wp-html-template.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class WP_HTML_Template extends WP_HTML_Tag_Processor {
*
* This function looks for placeholders in the template string and will replace
* them with appropriately-escaped substitutions from the given arguments, if
* provided and if those arguments are strings.
* provided and if those arguments are strings or valid attribute values.
*
* Example:
*
Expand Down Expand Up @@ -64,7 +64,7 @@ class WP_HTML_Template extends WP_HTML_Tag_Processor {
* If provided any other type of value the attribute will be ignored and its existing value persists.
*
* - If multiple HTML attributes are specified for a given tag they will be applied as if calling
* `set_attribute()` in the order they are specified in the temlpate. This includes any attributes
* `set_attribute()` in the order they are specified in the template. This includes any attributes
* assigned through the attribute spread syntax.
*
* - Substitutions in text nodes may only contain string values. If provided any other type of value
Expand All @@ -74,7 +74,7 @@ class WP_HTML_Template extends WP_HTML_Tag_Processor {
* it may provide the ability to nest pre-rendered HTML into the template, but this functionality
* is deferred for a future update.
*
* - This function will not replace content inside of TEXTAREA, TITLE, SCRIPT, or STYLE elements.
* - This function will not replace content inside of SCRIPT, or STYLE elements.
*
* @since 6.5.0
*
Expand Down Expand Up @@ -162,6 +162,25 @@ static function ( $matches ) use ( $args ) {
$processor->set_attribute( $attribute_name, $new_value );
}
}

// Update TEXTAREA and TITLE contents.
$tag_name = $processor->get_tag();
if ( 'TEXTAREA' === $tag_name || 'TITLE' === $tag_name ) {
// Replace placeholders inside these RCDATA tags.
$new_text = preg_replace_callback(
'~</%([^>]+)>~',
static function ( $matches ) use ( $args ) {
return is_string( $args[ $matches[1] ] )
? $args[ $matches[1] ]
: '';
},
$text
);

if ( $new_text !== $text ) {
$processor->set_modifiable_text( $new_text );
}
}
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/wp-includes/html-api/class-wp-html.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class WP_HTML {
*
* This function looks for placeholders in the template string and will replace
* them with appropriately-escaped substitutions from the given arguments, if
* provided and if those arguments are strings.
* provided and if those arguments are strings or valid attribute values.
*
* Example:
*
Expand Down Expand Up @@ -58,7 +58,7 @@ class WP_HTML {
* If provided any other type of value the attribute will be ignored and its existing value persists.
*
* - If multiple HTML attributes are specified for a given tag they will be applied as if calling
* `set_attribute()` in the order they are specified in the temlpate. This includes any attributes
* `set_attribute()` in the order they are specified in the template. This includes any attributes
* assigned through the attribute spread syntax.
*
* - Substitutions in text nodes may only contain string values. If provided any other type of value
Expand All @@ -68,6 +68,8 @@ class WP_HTML {
* it may provide the ability to nest pre-rendered HTML into the template, but this functionality
* is deferred for a future update.
*
* - This function will not replace content inside of SCRIPT, or STYLE elements.
*
* @since 6.5.0
*
* @access private
Expand Down
18 changes: 18 additions & 0 deletions tests/phpunit/tests/html-api/wpHtmlTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,4 +85,22 @@ public function test_cannot_break_out_of_tag_with_malicious_attribute_name() {
"Should not have found any other tags but found {$processor->get_tag()} instead."
);
}

/**
* Ensures that basic replacement inside a TEXTAREA subtitutes placeholders.
*
* @ticket 60229
*/
public function test_replaces_textarea_placeholders() {
$html = WP_HTML_Template::render(
'<textarea>The </%big> one.</textarea>',
array( 'big' => '<HUGE> (</textarea>)' )
);

$this->assertSame(
'<textarea>The <HUGE> (&lt;/textarea>) one.</textarea>',
$html,
'Should have replaced placeholder with RCDATA escaping rules.'
);
}
}

0 comments on commit 0145fef

Please sign in to comment.