Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
144 commits
Select commit Hold shift + click to select a range
aaee111
Apply patch from <select> parser PR
sirreal Jul 22, 2025
9ab745d
Update reset_insertion_mode_appropriately
sirreal Jul 22, 2025
1acfce7
Deprecate the has_element_in_select_scope method
sirreal Jul 22, 2025
aac853d
Update "normal" end tag handling to include SELECT
sirreal Jul 22, 2025
89c113d
Update INPUT handling to account for SELECT
sirreal Jul 22, 2025
f75a08f
Update HR tag handling
sirreal Jul 22, 2025
099f013
Update SELECT insertion handling
sirreal Jul 22, 2025
7fe3598
Update OPTION, OPTGROUP insertion handling
sirreal Jul 22, 2025
20e0807
Remove in_select and in_select_in_table step methods
sirreal Jul 22, 2025
45edeae
Deprecate unused insertion mode constants
sirreal Jul 22, 2025
446cdaa
Adjust html5lib-test expectation
sirreal Jul 22, 2025
0ed0a68
Add close option tag comments, do not handle cloning
sirreal Jul 22, 2025
8beb128
Update has_element_in_scope with SELECT
sirreal Jul 22, 2025
6be6287
Bail when parsing SELECTEDCONTENT requiring clone
sirreal Jul 22, 2025
9e79bb2
Update html5lib-tests
sirreal Jul 22, 2025
661399e
Initial plan
Copilot Dec 12, 2025
2c0960c
Add script_data_{$handle} filter for classic scripts
Copilot Dec 12, 2025
f4afe13
Fix test docblocks - remove TBD ticket annotations
Copilot Dec 12, 2025
d3cd233
Implement script_data_{$handle} filter correctly - outputs JSON scrip…
Copilot Dec 12, 2025
4e490ee
Optimize print_script_data method - extract charset check outside loo…
Copilot Dec 12, 2025
14e4ff9
Remove redundant is_array check and improve test naming
Copilot Dec 12, 2025
16c9b3f
Refactor: Integrate script_data filter directly into do_item() method
Copilot Dec 12, 2025
3edd50e
Add comment explaining wp_print_inline_script_tag return parameter
Copilot Dec 12, 2025
0fbee29
Address code review feedback
Copilot Dec 16, 2025
d89d333
Add JSON_INVALID_UTF8_SUBSTITUTE flag for better UTF-8 handling
Copilot Dec 17, 2025
d9f018f
Revert "Add JSON_INVALID_UTF8_SUBSTITUTE flag for better UTF-8 handling"
Copilot Dec 18, 2025
cf669ad
Add JSON_INVALID_UTF8_SUBSTITUTE flag to avoid fallback overhead
Copilot Dec 18, 2025
592c169
Add test for xlink serialization
sirreal Jun 9, 2026
8df62fd
Serialize adjusted foreign attributes with prefixes
sirreal Jun 9, 2026
0ac7e6d
HTML API: Expand foreign attribute serialization coverage
sirreal Jun 9, 2026
e90ce8a
HTML API: Simplify adjusted attribute serialization
sirreal Jun 9, 2026
292d78c
HTML API: Remove ticket annotations from data providers
sirreal Jun 9, 2026
bcb7c8e
Add type annotations to HTML API serialize tests
sirreal Jun 9, 2026
fe2e0e3
Add html api fuzzer tooling
sirreal Jun 8, 2026
75f7f22
Improve HTML fuzzer payload policy metadata
sirreal Jun 8, 2026
924be67
Tighten HTML fuzzer triage classifications
sirreal Jun 8, 2026
cd28974
Harden HTML fuzzer tree comparison and triage
sirreal Jun 8, 2026
749bc0a
Add PHP Codex triage orchestrator
sirreal Jun 8, 2026
3c3a496
Normalize fuzzer tree scalars
sirreal Jun 8, 2026
3a30214
Restrict HTML fuzzer payloads to UTF-8
sirreal Jun 8, 2026
11002cb
Handle DOM oracle limitations in HTML API fuzzer
sirreal Jun 9, 2026
a0a377d
Add tmux runner for continuous HTML API fuzzing
sirreal Jun 9, 2026
3a1993e
Handle presumptuous tag tokens in HTML API fuzzing
sirreal Jun 9, 2026
c65143c
Expand HTML API fuzzer generator coverage
sirreal Jun 9, 2026
7561552
Add normalize idempotence invariant to fuzzer
sirreal Jun 9, 2026
e53ed75
Merge branch 'trunk' into html-api/update-select-tag-parsing
sirreal Jun 9, 2026
95c0559
Update html5lib-tests from 9fb614afaa42ce8787840f057b32084308e76549
sirreal Jun 9, 2026
171c24f
HTML API: Set select deprecation versions to 7.1.0.
sirreal Jun 9, 2026
120619b
HTML API: Empty the deprecated select scope check.
sirreal Jun 9, 2026
8f0bf91
HTML API: Use isset() for context node checks in select handling.
sirreal Jun 9, 2026
e9826a6
HTML API: Remove redundant OPTION end tag comment.
sirreal Jun 9, 2026
e30d007
HTML API: Document customizable select support in class docs.
sirreal Jun 9, 2026
c863814
HTML API: Treat SELECT as a button and list item scope boundary.
sirreal Jun 9, 2026
b57696a
Merge branch 'html-api/update-select-tag-parsing' into html-api-fuzz
sirreal Jun 9, 2026
08f1539
HTML API: Detect CDATA by adjusted node namespace
sirreal Jun 9, 2026
3beee24
HTML API: Ignore slash inside unquoted attribute values
sirreal Jun 9, 2026
d43bb4b
Merge branch 'fix/html-api-cdata-namespace' into html-api-fuzz
sirreal Jun 9, 2026
58caad0
Merge branch 'fix/html-api-unquoted-slash-self-closing' into html-api…
sirreal Jun 9, 2026
06cc59b
Add compact Git metadata to HTML API fuzzer
sirreal Jun 9, 2026
c424557
HTML API: Test nested anchors in MathML text integration points
sirreal Jun 9, 2026
779e594
HTML API: Queue virtual closers after non-current removals
sirreal Jun 9, 2026
9fada16
Merge branch 'fix/html-api-mathml-nested-anchor' into html-api-fuzz
sirreal Jun 9, 2026
f171219
Merge branch 'trunk' into fix/html-processor-xlink-href-normalize
sirreal Jun 10, 2026
d7b50c6
Merge branch 'fix/html-processor-xlink-href-normalize' into html-api-…
sirreal Jun 10, 2026
0d64955
HTML API: Preserve decoded carriage returns in serialization
sirreal Jun 10, 2026
5736702
HTML API: Preserve XMP rawtext serialization
sirreal Jun 10, 2026
d676e28
HTML API: Visit implied body at EOF after head
sirreal Jun 10, 2026
14926c4
HTML API: Limit leading newline serialization to HTML elements
sirreal Jun 10, 2026
7e4ecc7
HTML API: Handle adoption agency fallback end tags
sirreal Jun 10, 2026
7a34cea
HTML API: Normalize raw attribute carriage returns before serialization
sirreal Jun 10, 2026
58dab55
Mark EOF stack events as virtual
sirreal Jun 10, 2026
c86078c
HTML API: Correct @since tags to 7.1.0.
sirreal Jun 10, 2026
b19c465
HTML API: Derive removed anchor breadcrumb depth from stack position.
sirreal Jun 10, 2026
579ad58
HTML API: Fix @since version for step_in_body_any_other_end_tag().
sirreal Jun 10, 2026
a0e7779
HTML API: Fix @since tags to reference 7.1.0.
sirreal Jun 10, 2026
c076626
Add graceful shutdown note
sirreal Jun 10, 2026
dfa18d5
Overhaul HTML API fuzzer oracle, invariants, and throughput
sirreal Jun 10, 2026
1dd112a
Merge PR #41: HTML API: Fix nested anchors in MathML text integration…
sirreal Jun 10, 2026
6b8d48c
Merge PR #42: HTML API: Preserve decoded carriage returns in serializ…
sirreal Jun 10, 2026
00600da
Merge PR #43: HTML API: Preserve XMP rawtext serialization
sirreal Jun 10, 2026
f5caa48
Merge PR #44: HTML API: Handle adoption agency fallback end tags
sirreal Jun 10, 2026
186b78a
Merge PR #45: HTML API: Limit leading newline serialization to HTML e…
sirreal Jun 10, 2026
10a0da0
Merge PR #46: HTML API: Visit implied body at EOF after head
sirreal Jun 10, 2026
130ec16
HTML API: Pin heading end tag handling in MathML text integration point
sirreal Jun 10, 2026
eee3332
Add per-lane SQLite result store library
sirreal Jun 10, 2026
bc35e0e
Add stop.php and honor STOP files in the codex orchestrator
sirreal Jun 10, 2026
24628fe
Record attempts in SQLite, prune seed artifacts, stop gracefully
sirreal Jun 10, 2026
206ea84
Merge updated PR #41: add MathML text-integration-point heading end-t…
sirreal Jun 10, 2026
10b3976
HTML API: Pin virtual closer ordering before a same-name opener.
sirreal Jun 10, 2026
44abb52
Merge updated PR #41: same-name opener virtual-closer test and identi…
sirreal Jun 10, 2026
bcd7c1a
Match scalar tolerance per occurrence instead of scrubbing whole lines
sirreal Jun 10, 2026
b65751a
Backtrack at the ambiguous CR alignment in scalar tolerance
sirreal Jun 10, 2026
d8e89f3
Run synthetic tree-comparison assertions without the DOM oracle
sirreal Jun 10, 2026
1c3e106
Gate scalar tolerance to attribute and tag lines
sirreal Jun 10, 2026
12a1b0c
Match escaped tree scalars possessively
sirreal Jun 10, 2026
a67c8dd
Restore HTML API fuzz stop utility
sirreal Jun 10, 2026
26c5a21
Classify comment-opener attribute names as attribute lines
sirreal Jun 10, 2026
7cd2617
Drop dead line keys from encoding-mismatch classifier
sirreal Jun 10, 2026
fcca0ee
Document tolerance gating and known classification gaps
sirreal Jun 10, 2026
b72dc7e
Track oracle disagreements as fuzz findings
sirreal Jun 11, 2026
53c4ef3
Add source-built Lexbor tree oracle
sirreal Jun 11, 2026
c39ba48
Wire selectable DOM oracle through fuzzer
sirreal Jun 11, 2026
2d9905d
Cover Lexbor oracle replay metadata
sirreal Jun 11, 2026
dc24f2c
Merge branch 'trunk' into html-api-fuzz
sirreal Jun 11, 2026
b2abcaa
HTML API: Preserve IFRAME, NOEMBED, and NOFRAMES contents when serial…
sirreal Jun 11, 2026
ae3a8be
HTML API: Stop escaping XMP contents when serializing.
sirreal Jun 11, 2026
cee0661
HTML API: Add tests for attribute value input preprocessing.
sirreal Jun 11, 2026
82a26aa
HTML API: Apply input preprocessing in get_attribute().
sirreal Jun 11, 2026
48d8fb4
HTML API: Add tests for class updates over preprocessed values.
sirreal Jun 11, 2026
d1f852c
HTML API: Apply input preprocessing when flushing class updates.
sirreal Jun 11, 2026
020155a
HTML API: Add tests for NULL bytes in attribute names.
sirreal Jun 11, 2026
442e820
HTML API: Replace NULL bytes in comparable attribute names.
sirreal Jun 11, 2026
135157f
HTML API: Add tests for NULL bytes in tag names.
sirreal Jun 11, 2026
5b8ad27
HTML API: Replace NULL bytes in tag names at the read boundary.
sirreal Jun 11, 2026
f6f58fd
HTML API: Add test for NULL bytes in API-supplied class values.
sirreal Jun 11, 2026
ba93ef4
HTML API: Stop replacing NULL bytes in API-supplied class values.
sirreal Jun 11, 2026
9baceb6
HTML API: Avoid re-scanning attribute values without CR or NULL bytes.
sirreal Jun 11, 2026
3b415d1
HTML API: Add tests for character references preceding replaced bytes.
sirreal Jun 11, 2026
8f5e8b2
HTML API: Replace NULL bytes after decoding attribute values.
sirreal Jun 11, 2026
e18f389
HTML API: Detect ambiguous character reference followers by ASCII only.
sirreal Jun 11, 2026
449bf72
HTML API: Add tests for tag-name queries over replaced names.
sirreal Jun 11, 2026
5c52634
HTML API: Match tag-name queries against replaced names.
sirreal Jun 11, 2026
5292c7d
HTML API: Add test for case-insensitive class update flushing.
sirreal Jun 11, 2026
8c26adf
HTML API: Flush class updates for any case spelling of "class".
sirreal Jun 11, 2026
e41d168
HTML API: Pin edge cases of replaced names and document boundaries.
sirreal Jun 11, 2026
78d58d0
HTML API: Add tests for serializing decoded carriage returns.
sirreal Jun 11, 2026
4127e36
HTML API: Serialize decoded carriage returns as character references.
sirreal Jun 11, 2026
9c3302f
HTML API: Pin serialization of NULL bytes in API-supplied values.
sirreal Jun 11, 2026
96c6fb8
HTML API: Consolidate serializer NULL-byte handling.
sirreal Jun 11, 2026
3a74497
HTML API: Pin rawtext serialization and reparse round trips.
sirreal Jun 11, 2026
5a3cbf1
Merge PR #53: HTML API input preprocessing
sirreal Jun 11, 2026
ce2af0e
Merge updated PR #42: decoded carriage return serialization
sirreal Jun 11, 2026
ce08149
Merge PR #51: preserve rawtext contents
sirreal Jun 11, 2026
adbe354
Merge PR #17: classic script data filter
sirreal Jun 11, 2026
5c3b731
Document merged PR rationale
sirreal Jun 11, 2026
57d458d
Fix script data test tag assertion
sirreal Jun 11, 2026
088b775
Update merge note for script data test fix
sirreal Jun 11, 2026
63b2c4a
Use Lexbor master for source oracle
sirreal Jun 11, 2026
05cf434
Improve HTML API fuzz terminal payload coverage
sirreal Jun 11, 2026
1a14d7c
Document br mutation oracle follow-up
sirreal Jun 11, 2026
b269d6b
Expand known element normalization coverage
sirreal Jun 12, 2026
64f160c
Add explicit comment form fuzz coverage
sirreal Jun 12, 2026
e504903
Preserve Lexbor SVG adjusted names
sirreal Jun 12, 2026
b80297d
Add in-process probe mode to fuzzer minimizer
sirreal Jun 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ wp-tests-config.php
/packagehash.txt
/.gutenberg-hash
/artifacts
/tools/html-api-fuzz/oracles/lexbor/build
/setup.log
/coverage

Expand Down
29 changes: 29 additions & 0 deletions merged-prs-2026-06-11.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# PR merges for html-api-fuzz

Date: 2026-06-11

All included PRs were merged into `html-api-fuzz` with merge commits. Trunk was checked before and after these merges; `origin/trunk` is already an ancestor of this branch, so Git had no trunk merge commit to create.

## Merged

- PR #53, `origin/spec-compliant-getters`
- Merge commit: `5a3cbf19df`
- Why: Aligns HTML API input preprocessing and getter behavior with the spec, reducing fuzzer/oracle noise around NULL bytes, carriage returns, and decoded source values. This also gives the rebuilt #42 branch the helper behavior it expects.

- PR #42, `origin/html-api-fuzz-fiz/decoded-cr`
- Merge commit: `ce2af0eff6`
- Why: Updates the earlier #42 merge to the current PR head. It preserves decoded carriage returns as `&#13;` during serialization, normalizes NULL bytes through the shared serializer path, and removes the old `get_attribute_for_serialization()` workaround that #53 makes unnecessary.

- PR #51, `origin/html-api-normalize-restore-missing-text-content`
- Merge commit: `ce08149069`
- Why: Addresses issue #50 and the latest fuzzer `normalize-tree-changed` failures where raw text was dropped from `IFRAME`, `NOEMBED`, `NOFRAMES`, and related rawtext serialization paths.

- PR #17, `origin/copilot/add-script-data-filter`
- Merge commit: `adbe354c94`
- Why: Addresses issue #16 by adding the classic-script `script_data_{$handle}` JSON data hook. This is separate from the HTML API fuzzer stack, so it was kept in its own merge commit.
- Follow-up: `57d458df91` corrects the new test's script-tag assertion to match WordPress's emitted attribute order.

## Not merged

- Trunk: already present; no-op.
- Other open PRs: either already contained in this branch or not tied to the existing issues identified in this pass.
103 changes: 102 additions & 1 deletion src/wp-includes/class-wp-scripts.php
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,108 @@ public function do_item( $handle, $group = false ) {
$attr['data-wp-fetchpriority'] = $original_fetchpriority;
}

$tag = $translations . $before_script;
/**
* Filters data associated with a given script.
*
* Scripts may require data that is required for initialization or is essential
* to have immediately available on page load. These are suitable use cases for
* this data.
*
* The dynamic portion of the hook name, `$handle`, refers to the script handle.
*
* This is best suited to pass essential data that must be available to the script for
* initialization or immediately on page load. It does not replace the REST API or
* fetching data from the client.
*
* Example:
*
* add_filter(
* 'script_data_my-script-handle',
* function ( array $data ): array {
* $data['myConfig'] = array( 'key' => 'value' );
* return $data;
* }
* );
*
* If the filter returns no data (an empty array), nothing will be embedded in the page.
*
* The data for a given script, if provided, will be JSON serialized in a script
* tag with an ID of the form `wp-script-data-{$handle}` and type `application/json`.
*
* The data can be read on the client with a pattern like this:
*
* Example:
*
* const dataContainer = document.getElementById( 'wp-script-data-my-script-handle' );
* let data = {};
* if ( dataContainer ) {
* try {
* data = JSON.parse( dataContainer.textContent );
* } catch {}
* }
* // data.myConfig.key === 'value';
* initMyScriptWithData( data );
*
* @since 7.1.0
*
* @param array $data The data associated with the script.
*/
$script_data = apply_filters( "script_data_{$handle}", array() );

$script_data_tag = '';
if ( ! empty( $script_data ) ) {
/*
* This data will be printed as JSON inside a script tag like this:
* <script type="application/json"></script>
*
* A script tag must be closed by a sequence beginning with `</`. It's impossible to
* close a script tag without using `<`. We ensure that `<` is escaped and `/` can
* remain unescaped, so `</script>` will be printed as `\u003C/script>`.
*
* - JSON_HEX_TAG: All < and > are converted to \u003C and \u003E.
* - JSON_UNESCAPED_SLASHES: Don't escape /.
* - JSON_INVALID_UTF8_SUBSTITUTE: Substitute invalid UTF-8 sequences with U+FFFD (�)
* instead of failing. This avoids the overhead of `wp_json_encode()`'s fallback
* re-encoding and ensures consistent handling with the standard replacement character.
*
* If the page will use UTF-8 encoding, it's safe to print unescaped unicode:
*
* - JSON_UNESCAPED_UNICODE: Encode multibyte Unicode characters literally (instead of as `\uXXXX`).
* - JSON_UNESCAPED_LINE_TERMINATORS: The line terminators are kept unescaped when
* JSON_UNESCAPED_UNICODE is supplied. It uses the same behaviour as it was
* before PHP 7.1 without this constant. Available as of PHP 7.1.0.
*
* The JSON specification requires encoding in UTF-8, so if the generated HTML page
* is not encoded in UTF-8 then it's not safe to include those literals. They must
* be escaped to avoid encoding issues.
*
* @see https://www.rfc-editor.org/rfc/rfc8259.html for details on encoding requirements.
* @see https://www.php.net/manual/en/json.constants.php for details on these constants.
* @see https://html.spec.whatwg.org/#script-data-state for details on script tag parsing.
*/
$json_encode_flags = JSON_HEX_TAG | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS | JSON_INVALID_UTF8_SUBSTITUTE;
if ( ! is_utf8_charset() ) {
$json_encode_flags = JSON_HEX_TAG | JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_SUBSTITUTE;
}

/*
* Return the data script tag as a string (third parameter false) rather than echoing it.
* This allows it to be included with the script tag in the concatenated output.
*/
$script_data_tag = wp_print_inline_script_tag(
wp_json_encode(
$script_data,
$json_encode_flags
),
array(
'type' => 'application/json',
'id' => "wp-script-data-{$handle}",
),
false
);
}

$tag = $translations . $before_script . $script_data_tag;
$tag .= wp_get_script_tag( $attr );
$tag .= $after_script;

Expand Down
20 changes: 14 additions & 6 deletions src/wp-includes/html-api/class-wp-html-decoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ public static function decode( $context, $text ): string {
* 7 === $token_length; // `&notin;`
*
* @since 6.6.0
* @since 7.1.0 Detects ambiguous followers of semicolon-less references
* by ASCII classification only, independent of the locale.
*
* @global WP_Token_Map $html5_named_character_references Mappings for HTML5 named character references.
*
Expand Down Expand Up @@ -377,14 +379,20 @@ public static function read_character_reference( $context, $text, $at = 0, &$mat
* At this point though there's a match for an entry in the named
* character reference table but the match doesn't end in `;`.
* It may be allowed if it's followed by something unambiguous.
*
* Only an ASCII alphanumeric or U+003D EQUALS SIGN is ambiguous.
* `ctype_alnum()` must be avoided here: its classification of
* bytes 0x80 and above depends on the process locale, but only
* these specific ASCII characters prevent decoding.
*
* @see https://html.spec.whatwg.org/#named-character-reference-state
*/
$follower = $after_name < $length ? $text[ $after_name ] : '';
$ambiguous_follower = (
$after_name < $length &&
$name_at < $length &&
(
ctype_alnum( $text[ $after_name ] ) ||
'=' === $text[ $after_name ]
)
( 'a' <= $follower && 'z' >= $follower ) ||
( 'A' <= $follower && 'Z' >= $follower ) ||
( '0' <= $follower && '9' >= $follower ) ||
'=' === $follower
);

// It's non-ambiguous, safe to leave it in.
Expand Down
37 changes: 16 additions & 21 deletions src/wp-includes/html-api/class-wp-html-open-elements.php
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ public function has_element_in_specific_scope( string $tag_name, $termination_li
* > - th
* > - marquee
* > - object
* > - select
* > - template
* > - MathML mi
* > - MathML mo
Expand Down Expand Up @@ -312,6 +313,7 @@ public function has_element_in_scope( string $tag_name ): bool {
'TH',
'MARQUEE',
'OBJECT',
'SELECT',
'TEMPLATE',

'math MI',
Expand Down Expand Up @@ -362,6 +364,7 @@ public function has_element_in_list_item_scope( string $tag_name ): bool {
'MARQUEE',
'OBJECT',
'OL',
'SELECT',
'TEMPLATE',
'UL',

Expand Down Expand Up @@ -410,6 +413,7 @@ public function has_element_in_button_scope( string $tag_name ): bool {
'TH',
'MARQUEE',
'OBJECT',
'SELECT',
'TEMPLATE',

'math MI',
Expand Down Expand Up @@ -459,9 +463,8 @@ public function has_element_in_table_scope( string $tag_name ): bool {
/**
* Returns whether a particular element is in select scope.
*
* This test differs from the others like it, in that its rules are inverted.
* Instead of arriving at a match when one of any tag in a termination group
* is reached, this one terminates if any other tag is reached.
* The "select scope" concept was removed from the HTML standard along with the
* customizable `<select>` changes, so nothing is ever in select scope.
*
* > The stack of open elements is said to have a particular element in select scope when it has
* > that element in the specific scope consisting of all element types except the following:
Expand All @@ -471,24 +474,13 @@ public function has_element_in_table_scope( string $tag_name ): bool {
* @since 6.4.0 Stub implementation (throws).
* @since 6.7.0 Full implementation.
*
* @see https://html.spec.whatwg.org/#has-an-element-in-select-scope
* @deprecated 7.1.0 This method is no longer part of the HTML standard.
*
* @param string $tag_name Name of tag to check.
* @return bool Whether the given element is in SELECT scope.
* @return bool Always false; select scope no longer exists.
*/
public function has_element_in_select_scope( string $tag_name ): bool {
foreach ( $this->walk_up() as $node ) {
if ( $node->node_name === $tag_name ) {
return true;
}

if (
'OPTION' !== $node->node_name &&
'OPTGROUP' !== $node->node_name
) {
return false;
}
}
_deprecated_function( __METHOD__, '7.1.0' );

return false;
}
Expand Down Expand Up @@ -588,7 +580,7 @@ public function remove_node( WP_HTML_Token $token ): bool {

$position_from_start = $this->count() - $position_from_end - 1;
array_splice( $this->stack, $position_from_start, 1 );
$this->after_element_pop( $item );
$this->after_element_pop( $item, 0 === $position_from_end );
return true;
}

Expand Down Expand Up @@ -697,6 +689,7 @@ public function after_element_push( WP_HTML_Token $item ): void {
case 'TH':
case 'MARQUEE':
case 'OBJECT':
case 'SELECT':
case 'TEMPLATE':
case 'math MI':
case 'math MO':
Expand Down Expand Up @@ -731,9 +724,10 @@ public function after_element_push( WP_HTML_Token $item ): void {
*
* @since 6.4.0
*
* @param WP_HTML_Token $item Element that was removed from the stack of open elements.
* @param WP_HTML_Token $item Element that was removed from the stack of open elements.
* @param bool $invoke_pop_handler Whether to call the pop handler.
*/
public function after_element_pop( WP_HTML_Token $item ): void {
public function after_element_pop( WP_HTML_Token $item, bool $invoke_pop_handler = true ): void {
/*
* When adding support for new elements, expand this switch to trap
* cases where the precalculated value needs to change.
Expand All @@ -753,6 +747,7 @@ public function after_element_pop( WP_HTML_Token $item ): void {
case 'TH':
case 'MARQUEE':
case 'OBJECT':
case 'SELECT':
case 'TEMPLATE':
case 'math MI':
case 'math MO':
Expand All @@ -767,7 +762,7 @@ public function after_element_pop( WP_HTML_Token $item ): void {
break;
}

if ( null !== $this->pop_handler ) {
if ( $invoke_pop_handler && null !== $this->pop_handler ) {
call_user_func( $this->pop_handler, $item );
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/wp-includes/html-api/class-wp-html-processor-state.php
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,8 @@ class WP_HTML_Processor_State {
*
* @since 6.7.0
*
* @see https://html.spec.whatwg.org/#parsing-main-inselect
* @deprecated 7.1.0 The "in select" insertion mode was removed from the standard.
*
* @see WP_HTML_Processor_State::$insertion_mode
*
* @var string
Expand All @@ -221,7 +222,8 @@ class WP_HTML_Processor_State {
*
* @since 6.7.0
*
* @see https://html.spec.whatwg.org/#parsing-main-inselectintable
* @deprecated 7.1.0 The "in select in table" insertion mode was removed from the standard.
*
* @see WP_HTML_Processor_State::$insertion_mode
*
* @var string
Expand Down
Loading