Skip to content

Commit 04b4c81

Browse files
committed
Fix duplicate attribute removal in WP_HTML_Template
When using false/null to remove a placeholder attribute, duplicate attributes (e.g., `<input disabled="</%d>" disabled>`) now get removed as well. The fix pre-computes duplicate removal edits in compile(), following the existing pattern for text normalization and attribute escaping. This is more efficient than waiting for normalize() to strip them at render time, and correctly handles the case where removing the first attribute would leave the duplicate as the primary attribute. Changes: - Make duplicate_attributes protected in WP_HTML_Tag_Processor - Expose get_duplicate_attributes() in Template's anonymous class - Emit removal edits for all duplicates in compile()
1 parent 245f24a commit 04b4c81

2 files changed

Lines changed: 19 additions & 1 deletion

File tree

src/wp-includes/html-api/class-wp-html-tag-processor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -718,7 +718,7 @@ class WP_HTML_Tag_Processor {
718718
*
719719
* @var (WP_HTML_Span[])[]|null
720720
*/
721-
private $duplicate_attributes = null;
721+
protected $duplicate_attributes = null;
722722

723723
/**
724724
* Which class names to add or remove from a tag.

src/wp-includes/html-api/class-wp-html-template.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ public function get_tag_attributes(): array {
142142
public function create_fragment_at_node( string $html ): ?static {
143143
return $this->create_fragment_at_current_node( $html );
144144
}
145+
146+
public function get_duplicate_attributes(): ?array {
147+
return $this->duplicate_attributes;
148+
}
145149
} )::create_fragment( $this->template_string );
146150

147151
if ( null === $processor ) {
@@ -314,6 +318,20 @@ public function create_fragment_at_node( string $html ): ?static {
314318
}
315319
}
316320
}
321+
322+
// Remove duplicate attributes (invalid HTML, stripped during normalization).
323+
$duplicates = $processor->get_duplicate_attributes();
324+
if ( null !== $duplicates ) {
325+
foreach ( $duplicates as $spans ) {
326+
foreach ( $spans as $span ) {
327+
$this->edits[] = new WP_HTML_Text_Replacement(
328+
$span->start,
329+
$span->length,
330+
'',
331+
);
332+
}
333+
}
334+
}
317335
break;
318336
}
319337
}

0 commit comments

Comments
 (0)