Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WP_HTML_Tag_Processor: Implement get_attribute_names() method #46685

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
25 changes: 25 additions & 0 deletions lib/experimental/html/class-wp-html-tag-processor.php
Original file line number Diff line number Diff line change
Expand Up @@ -1412,6 +1412,31 @@ public function get_attribute( $name ) {
return html_entity_decode( $raw_value );
}

/**
* Returns the names of all attributes in the currently-opened tag.
*
* Example:
* <code>
* $p = new WP_HTML_Tag_Processor( '<div enabled class="test" data-test-id="14">Test</div>' );
* $p->next_tag( [ 'class_name' => 'test' ] ) === true;
* $p->get_attribute_names() === array( 'enabled', 'class', 'data-test-id' );
*
* $p->next_tag( [] ) === false;
* $p->get_attribute_names() === null;
* </code>
*
* @since 6.2.0
*
* @return array|null List of attribute names, or `null` if not at a tag.
*/
function get_attribute_names() {
if ( $this->is_closing_tag || null === $this->tag_name_starts_at ) {
return null;
}

return array_keys( $this->attributes );
}

/**
* Returns the lowercase name of the currently-opened tag.
*
Expand Down
94 changes: 94 additions & 0 deletions phpunit/html/wp-html-tag-processor-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,19 @@ public function test_get_attribute_returns_null_when_not_in_open_tag() {
$this->assertNull( $p->get_attribute( 'class' ), 'Accessing an attribute of a non-existing tag did not return null' );
}

/**
* @ticket 56299
*
* @covers next_tag
* @covers get_attribute
*/
public function test_get_attribute_returns_null_when_in_closing_tag() {
$p = new WP_HTML_Tag_Processor( '<div class="test">Test</div>' );
$this->assertTrue( $p->next_tag( 'div' ), 'Querying an existing tag did not return true' );
$this->assertTrue( $p->next_tag( array( 'tag_closers' => 'visit' ) ), 'Querying an existing closing tag did not return true' );
$this->assertNull( $p->get_attribute( 'class' ), 'Accessing an attribute of a closing tag did not return null' );
}

/**
* @ticket 56299
*
Expand Down Expand Up @@ -195,6 +208,87 @@ public function test_set_attribute_is_case_insensitive() {
$this->assertEquals( '<div data-enabled="abc">Test</div>', $p->get_updated_html(), 'A case-insensitive set_attribute call did not update the existing attribute.' );
}

/**
* @ticket 56299
*
* @covers get_attribute_names
*/
public function test_get_attribute_names_returns_null_before_finding_tags() {
$p = new WP_HTML_Tag_Processor( '<div class="test">Test</div>' );
$this->assertNull( $p->get_attribute_names() );
}

/**
* @ticket 56299
*
* @covers get_attribute_names
*/
public function test_get_attribute_names_returns_null_when_not_in_open_tag() {
$p = new WP_HTML_Tag_Processor( '<div class="test">Test</div>' );
$p->next_tag( 'p' );
$this->assertNull( $p->get_attribute_names(), 'Accessing attributes of a non-existing tag did not return null' );
}

/**
* @ticket 56299
*
* @covers get_attribute_names
*/
public function test_get_attribute_names_returns_null_when_in_closing_tag() {
$p = new WP_HTML_Tag_Processor( '<div class="test">Test</div>' );
$p->next_tag( 'div' );
$p->next_tag( array( 'tag_closers' => 'visit' ) );
$this->assertNull( $p->get_attribute_names(), 'Accessing attributes of a closing tag did not return null' );
}

/**
* @ticket 56299
*
* @covers get_attribute_names
*/
public function test_get_attribute_names_returns_empty_array_when_no_attributes_present() {
$p = new WP_HTML_Tag_Processor( '<div>Test</div>' );
$p->next_tag( 'div' );
$this->assertSame( array(), $p->get_attribute_names(), 'Accessing the attributes on a tag without any did not return an empty array' );
}

/**
* @ticket 56299
*
* @covers get_attribute_names
*/
public function test_get_attribute_names_returns_attribute_names() {
$p = new WP_HTML_Tag_Processor( '<div enabled class="test" data-test-id="14">Test</div>' );
$p->next_tag();
$this->assertSame(
array( 'enabled', 'class', 'data-test-id' ),
$p->get_attribute_names()
);
}

/**
* @ticket 56299
*
* @covers set_attribute
* @covers get_updated_html
* @covers get_attribute_names
*/
public function test_get_attribute_names_returns_attribute_added_by_set_attribute() {
$p = new WP_HTML_Tag_Processor( '<div class="test">Test</div>' );
$p->next_tag();
$p->set_attribute( 'test-attribute', 'test-value' );
$this->assertSame(
'<div test-attribute="test-value" class="test">Test</div>',
$p->get_updated_html(),
"Updated HTML doesn't include attribute added via set_attribute"
);
$this->assertSame(
array( 'test-attribute', 'class' ),
$p->get_attribute_names(),
"Accessing attribute names doesn't find attribute added via set_attribute"
);
}

/**
* @ticket 56299
*
Expand Down