diff --git a/lib/experimental/html/class-wp-html-tag-processor.php b/lib/experimental/html/class-wp-html-tag-processor.php
index afdf6c66073cd..5b9772689434b 100644
--- a/lib/experimental/html/class-wp-html-tag-processor.php
+++ b/lib/experimental/html/class-wp-html-tag-processor.php
@@ -1402,6 +1402,32 @@ public function get_attribute( $name ) {
return html_entity_decode( $raw_value );
}
+ /**
+ * Returns the names of all attributes in the currently-opened tag.
+ *
+ * Example:
+ *
+ * $p = new WP_HTML_Tag_Processor( '
+ *
+ * @since 6.2.0
+ *
+ * @param string $prefix Prefix of attributes whose value is requested.
+ * @return array|null List of attribute names, or `null` if not at a tag.
+ */
+ function get_attribute_names() {
+ if ( null === $this->tag_name_starts_at ) {
+ return null;
+ }
+
+ return array_keys( $this->attributes );
+ }
+
/**
* Returns the lowercase name of the currently-opened tag.
*
diff --git a/phpunit/html/wp-html-tag-processor-test.php b/phpunit/html/wp-html-tag-processor-test.php
index cab14962491ac..d9e831eb275b4 100644
--- a/phpunit/html/wp-html-tag-processor-test.php
+++ b/phpunit/html/wp-html-tag-processor-test.php
@@ -151,6 +151,18 @@ public function test_attributes_parser_treats_slash_as_attribute_separator() {
$this->assertSame( 'test', $p->get_attribute( 'e' ), 'Accessing an existing e="test" did not return "test"' );
}
+ /**
+ * @covers WP_HTML_Tag_Processor::get_attribute_names
+ */
+ public function test_get_attribute_names() {
+ $p = new WP_HTML_Tag_Processor( '