Skip to content

HTML API: Respect newlines setting modifiable HTML#25

Closed
sirreal wants to merge 18 commits intotrunkfrom
html-api/set-mod-html-leading-newlines
Closed

HTML API: Respect newlines setting modifiable HTML#25
sirreal wants to merge 18 commits intotrunkfrom
html-api/set-mod-html-leading-newlines

Conversation

@sirreal
Copy link
Owner

@sirreal sirreal commented Feb 5, 2026


This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

@sirreal sirreal requested a review from Copilot February 5, 2026 18:46

This comment was marked as outdated.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 7 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

* If the intention is to start with a leading newline, ensure that it is preserved
* by adding an additional leading newline.
*/
if ( 'TEXTAREA' === $this->get_tag() && str_starts_with( $plaintext_content, "\n" ) ) {
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The check only handles leading \n but should also handle leading \r and \r\n to be consistent with the text node handling on lines 3779-3784. When users provide content starting with \r or \r\n, these will be normalized to \n during HTML parsing, and the leading newline will be incorrectly stripped. To fix this, consider using the same approach as line 3781: check if the first character is a newline variant using 1 === strspn( $plaintext_content, "\n\r", 0, 1 ) or check for both "\n" and "\r" explicitly.

Suggested change
if ( 'TEXTAREA' === $this->get_tag() && str_starts_with( $plaintext_content, "\n" ) ) {
if ( 'TEXTAREA' === $this->get_tag() && 1 === strspn( $plaintext_content, "\n\r", 0, 1 ) ) {

Copilot uses AI. Check for mistakes.
Comment on lines +647 to +656
public function test_modifiable_text_special_textarea() {
$processor = new WP_HTML_Tag_Processor( '<textarea></textarea>' );
$processor->next_token();
$processor->set_modifiable_text( "\nAFTER NEWLINE" );
$this->assertSame(
"\nAFTER NEWLINE",
$processor->get_modifiable_text(),
'Should have preserved the leading newline in the content.'
);
}
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test coverage for TEXTAREA with leading carriage return (\r) and carriage return + newline (\r\n) is missing. Similar to the WP_HTML_Processor tests, this test should also cover these newline variants to ensure consistent behavior across different newline representations.

Copilot uses AI. Check for mistakes.
@sirreal sirreal force-pushed the html-api/set-mod-html-leading-newlines branch from 749ad1b to b7ddbb4 Compare February 6, 2026 11:48
@sirreal sirreal marked this pull request as ready for review February 6, 2026 11:48
@sirreal sirreal requested a review from Copilot February 6, 2026 11:48
@github-actions

This comment was marked as outdated.

This comment was marked as outdated.

This comment was marked as outdated.

Comment on lines 12 to 78
/**
* TEXTAREA 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.
*
* @ticket 64609
*/
public function test_modifiable_text_special_textarea() {
$processor = WP_HTML_Processor::create_fragment( '<textarea></textarea>' );
$processor->next_token();
$processor->set_modifiable_text( "\nAFTER NEWLINE" );
$this->assertSame(
"\nAFTER NEWLINE",
$processor->get_modifiable_text(),
'Should have preserved the leading newline in the TEXTAREA content.'
);
}

/**
* TEXTAREA elements ignore the first newline in their content.
* Setting the modifiable text with a leading carriage return should be normalized
* and ensure the leading newline is present in the resulting TEXTAREA.
*
* @ticket 64609
*/
public function test_modifiable_text_special_textarea_carriage_return() {
$processor = WP_HTML_Processor::create_fragment( '<textarea></textarea>' );
$processor->next_token();
$processor->set_modifiable_text( "\rCR" );
// Newline normalization transforms \r into \n, and special handling should preserve it.
$this->assertSame(
"\nCR",
$processor->get_modifiable_text(),
'Should have normalized carriage return and preserved the leading newline in the TEXTAREA content.'
);
$this->assertEqualHTML(
"<textarea>\n\nCR</textarea>",
$processor->get_updated_html(),
'<body>',
'Should have doubled the newline in the output HTML to preserve the leading newline.'
);
}

/**
* TEXTAREA elements ignore the first newline in their content.
* Setting the modifiable text with a leading carriage return + newline should be normalized
* and ensure the leading newline is present in the resulting TEXTAREA.
*
* @ticket 64609
*/
public function test_modifiable_text_special_textarea_carriage_return_newline() {
$processor = WP_HTML_Processor::create_fragment( '<textarea></textarea>' );
$processor->next_token();
$processor->set_modifiable_text( "\r\nCR-N" );
// Newline normalization transforms \r\n into \n, and special handling should preserve it.
$this->assertSame(
"\nCR-N",
$processor->get_modifiable_text(),
'Should have normalized carriage return + newline and preserved the leading newline in the TEXTAREA content.'
);
$this->assertEqualHTML(
"<textarea>\n\nCR-N</textarea>",
$processor->get_updated_html(),
'<body>',
'Should have doubled the newline in the output HTML to preserve the leading newline.'
);
}
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Combine these three nearly-identical TEXTAREA tests into a single test using a data provider.

Copy link

Copilot AI commented Feb 6, 2026

@sirreal I've opened a new pull request, #28, to work on those changes. Once the pull request is ready, I'll request review from you.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated no new comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +648 to +652
$processor = new WP_HTML_Tag_Processor( '<textarea></textarea>' );
$processor->next_token();
$processor->set_modifiable_text( "\nAFTER NEWLINE" );
$this->assertSame(
"\nAFTER NEWLINE",
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test only asserts get_modifiable_text() after setting textarea content, but doesn’t assert the serialized output (get_updated_html()). Since the newline-stripping behavior is an HTML parsing/serialization concern (TEXTAREA drops the first LF), please also assert the updated HTML contains the extra leading newline needed to preserve the intended leading newline (and consider asserting next_token() / set_modifiable_text() return true to validate test setup).

Copilot uses AI. Check for mistakes.
@sirreal sirreal closed this Feb 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants