Skip to content
152 changes: 56 additions & 96 deletions tests/phpunit/tests/html-api/wpHtmlProcessorModifiableText.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,137 +28,97 @@ public function test_modifiable_text_special_textarea() {
}

/**
* PRE elements ignore the first newline in their content.
* PRE and LISTING elements ignore the first newline in their content.
* Setting the modifiable text with a leading newline should ensure that the leading newline
* is present in the resulting TEXTAREA.
* is present in the resulting element.
*
* @ticket 64607
*
* @dataProvider data_modifiable_text_special_pre_tags
*
* @param string $tag_name The tag name to test (e.g. 'pre', 'listing').
*/
public function test_modifiable_text_special_pre() {
public function test_modifiable_text_special_pre_tags( string $tag_name ) {
$set_text = "\nAFTER NEWLINE";
$processor = WP_HTML_Processor::create_fragment( '<pre>REPLACEME<!--x--></pre>' );
$processor = WP_HTML_Processor::create_fragment( "<{$tag_name}>REPLACEME<!--x--></{$tag_name}>" );
$processor->next_tag();
$processor->next_token();
$this->assertSame( '#text', $processor->get_token_type() );
$processor->set_modifiable_text( $set_text );
$this->assertSame( $set_text, $processor->get_modifiable_text() );
$this->assertEqualHTML(
<<<HTML
<pre>
{$set_text}<!--x--></pre>
<{$tag_name}>
{$set_text}<!--x--></{$tag_name}>
HTML,
$processor->get_updated_html(),
'<body>',
'Should have preserved the leading newline in the TEXTAREA content.'
"Should have preserved the leading newline in the {$tag_name} content."
);
}

/**
* Data provider.
*
* @ticket 64607
* @return array[]
*/
public function test_modifiable_text_special_pre_leading_whitespace() {
$set_text = "\nAFTER NEWLINE.";
$processor = WP_HTML_Processor::create_fragment( "<pre>\nREPLACEME<!--x--></pre>" );
$processor->next_tag();
$processor->next_token();
$this->assertSame( '#text', $processor->get_token_type() );
// This is an empty text node because of how the HTML Processor works.
$this->assertSame( '', $processor->get_modifiable_text() );
$processor->set_modifiable_text( $set_text );
$this->assertSame( $set_text, $processor->get_modifiable_text() );
$this->assertEqualHTML(
<<<HTML
<pre>
{$set_text}REPLACEME<!--x--></pre>
HTML,
$processor->get_updated_html(),
'<body>',
'Should have preserved the leading newline in the TEXTAREA content.'
);

$processor = WP_HTML_Processor::create_fragment( "<pre>\nREPLACEME<!--x--></pre>" );
$processor->next_tag();
$processor->next_token();
$processor->next_token();
$this->assertSame( '#text', $processor->get_token_type() );
// This is an empty text node because of how the HTML Processor works.
$this->assertSame( 'REPLACEME', $processor->get_modifiable_text() );
$processor->set_modifiable_text( $set_text );
$this->assertSame( $set_text, $processor->get_modifiable_text() );
$this->assertEqualHTML(
<<<HTML
<pre>
{$set_text}<!--x--></pre>
HTML,
$processor->get_updated_html(),
'<body>',
'Should have preserved the leading newline in the TEXTAREA content.'
);

$processor = WP_HTML_Processor::create_fragment( '<pre> REPLACEME<!--x--></pre>' );
$processor->next_tag();
$processor->next_token();
$this->assertSame( '#text', $processor->get_token_type() );
// This is an empty text node because of how the HTML Processor works.
$this->assertSame( ' ', $processor->get_modifiable_text() );
$processor->set_modifiable_text( $set_text );
$this->assertSame( $set_text, $processor->get_modifiable_text() );
$this->assertEqualHTML(
<<<HTML
<pre>
{$set_text}REPLACEME<!--x--></pre>
HTML,
$processor->get_updated_html(),
'<body>',
'Should have preserved the leading newline in the TEXTAREA content.'
);

$processor = WP_HTML_Processor::create_fragment( '<pre> REPLACEME<!--x--></pre>' );
$processor->next_tag();
$processor->next_token();
$processor->next_token();
$this->assertSame( '#text', $processor->get_token_type() );
// This is an empty text node because of how the HTML Processor works.
$this->assertSame( 'REPLACEME', $processor->get_modifiable_text() );
$processor->set_modifiable_text( $set_text );
$this->assertSame( $set_text, $processor->get_modifiable_text() );
$this->assertEqualHTML(
<<<HTML
<pre>
{$set_text}<!--x--></pre>
HTML,
$processor->get_updated_html(),
'<body>',
'Should have preserved the leading newline in the TEXTAREA content.'
public static function data_modifiable_text_special_pre_tags() {
return array(
'PRE' => array( 'pre' ),
'LISTING' => array( 'listing' ),
);
}

/**
* LISTING elements ignore the first newline in their content.
* Setting the modifiable text with a leading newline should ensure that the leading newline
* is present in the resulting TEXTAREA.
*
* @todo Leading whitespace mage split into multiple text nodes. Add appropriate tests.
* PRE and LISTING elements ignore the first newline in their content.
* Leading whitespace may split into multiple text nodes in the HTML Processor.
* Setting the modifiable text with a leading newline should ensure that the
* leading newline is present in the resulting element.
*
* @ticket 64607
*
* @dataProvider data_modifiable_text_special_leading_whitespace
*
* @param string $html HTML containing the element to test.
* @param int $advance_n_tokens Count of times to run `next_token()` after `next_tag()`.
* @param string $initial_text Expected modifiable text before the update.
* @param string $expected_html Expected HTML output after setting modifiable text.
*/
public function test_modifiable_text_special_listing() {
$set_text = "\nAFTER NEWLINE";
$processor = WP_HTML_Processor::create_fragment( '<listing>REPLACEME<!--x--></listing>' );
public function test_modifiable_text_special_leading_whitespace( string $html, int $advance_n_tokens, string $initial_text, string $expected_html ) {
$set_text = "\nAFTER NEWLINE.";
$processor = WP_HTML_Processor::create_fragment( $html );
$processor->next_tag();
$processor->next_token();
while ( --$advance_n_tokens >= 0 ) {
$processor->next_token();
}
$this->assertSame( '#text', $processor->get_token_type() );
$this->assertSame( $initial_text, $processor->get_modifiable_text() );
$processor->set_modifiable_text( $set_text );
$this->assertSame( $set_text, $processor->get_modifiable_text() );
$this->assertEqualHTML(
<<<HTML
<listing>
{$set_text}<!--x--></listing>
HTML,
$expected_html,
$processor->get_updated_html(),
'<body>',
'Should have preserved the leading newline in the TEXTAREA content.'
'Should have preserved the leading newline in the element content.'
);
}

/**
* Data provider.
*
* @return Generator
*/
public static function data_modifiable_text_special_leading_whitespace() {
$set_text = "\nAFTER NEWLINE.";

foreach ( self::data_modifiable_text_special_pre_tags() as $tag_data ) {
$tag_name = $tag_data[0];
$TAG = strtoupper( $tag_name );

yield "{$TAG} with leading newline, first text node" => array( "<{$tag_name}>\nREPLACEME<!--x--></{$tag_name}>", 1, '', "<{$tag_name}>\n{$set_text}REPLACEME<!--x--></{$tag_name}>" );
yield "{$TAG} with leading newline, second text node" => array( "<{$tag_name}>\nREPLACEME<!--x--></{$tag_name}>", 2, 'REPLACEME', "<{$tag_name}>\n{$set_text}<!--x--></{$tag_name}>" );
yield "{$TAG} with leading space, first text node" => array( "<{$tag_name}> REPLACEME<!--x--></{$tag_name}>", 1, ' ', "<{$tag_name}>\n{$set_text}REPLACEME<!--x--></{$tag_name}>" );
yield "{$TAG} with leading space, second text node" => array( "<{$tag_name}> REPLACEME<!--x--></{$tag_name}>", 2, 'REPLACEME', "<{$tag_name}>\n {$set_text}<!--x--></{$tag_name}>" );
}
}
}