Repository navigation
Conversation
Improve support for content appearing after BODY, HTML nodes where
possible. Some HTML may be representable by the HTML API without
introducing ordering problems.
When HTML moves to the "after-{body,html,…}" insertion modes, BODY and
HTML remain on the stack of open elements. Certain content is inserted
in place (comments), some content is inserted in BODY (white space
text), and most other content will switch back to the "in body"
insertion mode.
The difficulty with the HTML API is that the result in the tree may be
out-of-order compared to the positioning of the corresponding tokens in
the HTML input text. For example:
</body>FOO<!-- comment -->
Produces this tree where the ordering is the same even though a BODY
closer is reached:
[DOCUMENT]
└HTML
├HEAD
├BODY
│ └#text: FOO
└#comment: comment
Compare with this case:
</body><!-- comment -->FOO
The tree is identical, the FOO text is _out of order_ in the tree
compared to the HTML string. This case continues to be invalid because
when the FOO text needs to be reached, the parser would have already
reached a BODY tag closer and content outside of the body:
[DOCUMENT]
└HTML
├HEAD
├BODY
│ └#text: FOO
└#comment: comment
This approach deviates from the explicit steps in the spec and will pop
the BODY and HTML tags from the stack of open elements when content
should appear outside of them. Flags are set for each "after-" mode to
prevent returning to BODY and then continuing to produce content
outside, which would produce the unsupported out-of-order behavior.
See https://html.spec.whatwg.org/#parsing-main-afterbody.
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the Core Committers: Use this line as a base for the props when committing in SVN: To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
Test using WordPress PlaygroundThe changes in this pull request can previewed and tested using a WordPress Playground instance. WordPress Playground is an experimental project that creates a full WordPress instance entirely within the browser. Some things to be aware of
For more details about these limitations and more, check out the Limitations page in the WordPress Playground documentation. |
|
This work was originally included in #7165. It was reverted in the PR to land a simpler initial version and is now proposed on its own as an enhancement. |
|
I'm wondering if here we could lean on some of the work I've explored for XML well-formedness error-recovery. Imagine we start with "proper HTML parsing in tree-order node traversal" but you could opt-in to certain errors. $processor->parser_tolerance( WP_HTML_Processor::VISIT_NODES_OUT_OF_ORDER, true );
$processor->parser_tolerance( WP_HTML_Processor::OVERLOOK_FOSTERED_NODES, true );I'm concerned with patches like this because I think there's a real semantic challenge when thinking about operations like |
|
@dmsnell and I spoke the other day where we discussed an alternate approach to this. Collect the tokens that appear after body or after html and visit them at the very end of the HTML document. This would potentially avoid some confusing state juggling. We didn't go into detail on the implementation, so that approach still needs to be evaluated. |
…e-after-body-html-content # Conflicts: # src/wp-includes/html-api/class-wp-html-processor.php
…re count. This branch replaces the `bail()` and `break` in the comment cases of the "after body", "after after body" and "after after frameset" insertion modes with code that inserts the comment. PHPStan now finds 12 unreachable statements in the HTML Processor, not the 15 that phpstan.neon.dist expects, and reports the ignore count as an error.
A backward seek reparses the document from the start, but it kept the flags that record content produced after BODY and after HTML. The reparse then bailed with "Cannot produce out-of-order content." on content that parsed without error the first time. Reset both flags with the rest of the parser state. See #65967.
Rename `$has_procuded_after_html_content` to `$has_produced_after_html_content`. See #65967.
Cover the full parser on comments, processing instructions and whitespace after the BODY and HTML end tags: - Breadcrumbs and depth of every node in the supported shapes. - `ERROR_UNSUPPORTED` at the first token the processor cannot visit in document order after it has visited a node outside of BODY. - `serialize()` of full documents, and `normalize()`, which parses a BODY fragment and so keeps this content inside BODY. The expected trees come from PHP 8.5's `Dom\HTMLDocument`. It parses `<?pi data?>` as a bogus comment; the HTML standard now parses it as a processing instruction, which goes to the same place in the tree. See #65967.
Improve support for content appearing after BODY, HTML nodes where
possible. Some HTML may be representable by the HTML API without
introducing ordering problems.
When HTML moves to the "after-{body,html,…}" insertion modes, BODY and
HTML remain on the stack of open elements. Certain content is inserted
in place (comments), some content is inserted in BODY (white space
text), and most other content will switch back to the "in body"
insertion mode.
The difficulty with the HTML API is that the result in the tree may be
out-of-order compared to the positioning of the corresponding tokens in
the HTML input text. For example:
Produces this tree where the ordering is the same even though a BODY
closer is reached:
Compare with this case:
The tree is identical, the FOO text is out of order in the tree
compared to the HTML string. This case continues to be invalid because
when the FOO text needs to be reached, the parser would have already
reached a BODY tag closer and content outside of the body:
This approach deviates from the explicit steps in the spec and will pop
the BODY and HTML tags from the stack of open elements when content
should appear outside of them. Flags are set for each "after-" mode to
prevent returning to BODY and then continuing to produce content
outside, which would produce the unsupported out-of-order behavior.
See https://html.spec.whatwg.org/#parsing-main-afterbody.
Trac ticket: https://core.trac.wordpress.org/ticket/65967
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.