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

Add a has_class method to the public WP_HTML_Tag_Processor API #46232

Closed
wants to merge 2 commits into from

Conversation

adamziel
Copy link
Contributor

@adamziel adamziel commented Dec 1, 2022

Part of #44410

What?

Adds a has_class method to WP_HTML_Tag_Processor to provide an idiomatic, nuance-aware way of testing for the presence of a CSS class name:

// <div class="is-foo"></div>
$tags->has_class( 'is-foo' ); // true

// <div class="is-foo"></div>
$tags->has_class( 'not-is-foo' ); // false

// <div class="is-bar"></div>
$tags->has_class( 'is-foo' ); // false

// is-bar\tis-foo\ris-another-class'></div>
$tags->has_class( 'is-foo' ); // true

Testing Instructions

  • Confirm the unit tests pass
  • Confirm the code is sound

cc @dmsnell @getdave @aristath

@adamziel adamziel self-assigned this Dec 1, 2022
@adamziel adamziel added [Type] Enhancement A suggestion for improvement. [Feature] Block API API that allows to express the block paradigm. [Type] Code Quality Issues or PRs that relate to code quality Developer Experience Ideas about improving block and theme developer experience labels Dec 1, 2022
@dmsnell
Copy link
Member

dmsnell commented Dec 1, 2022

As a broad thought I'm a bit skeptical of this even though I suggested it.

For one, I feel like it's starting to get confusing the way we have string_contains_a_class_name. That's not semantic to HTML and worse, it's not accurate. It's less accurate than the existing code, which should be fine for all cases except where we have HTML-entity-encoded class names.

For example, the example in the docblock shouldn't find bold inside of <a class="button bold"></a> (or maybe the code works and the example is wrong?)

I'd like to be sure we really need this before we introduce a second way to query class names. Im worried that the normative use-case ->next_tag( [ 'class_name' => '…' ] ) will be supplanted by the imperative version instead, which will confuse people and not perform the way they want.

while ( $tags->next_tag() ) {
	if ( $tags->has_class( '' ) ) {
		…
	}
}

If we do go this route I'd be curious about building it as a separate system than the one shared by the query engine. Build a proper decoded, though of course as we saw earlier that's much more complicated. It's something I think we could make a more justified case for out of the main loop, but again something I want to know that we need before we put it out there and encourage people to use it.

@adamziel
Copy link
Contributor Author

adamziel commented Dec 1, 2022

@dmsnell I refactored this one to use preg_match instead of recycling parts of the query scanner – would you give it another look?

For one, I feel like it's starting to get confusing the way we have string_contains_a_class_name. That's not semantic to HTML and worse, it's not accurate. It's less accurate than the existing code, which should be fine for all cases except where we have HTML-entity-encoded class names.

What do you mean by not accurate? It used the same code as the query matcher, so should be accurate to that extent.

For example, the example in the docblock shouldn't find bold inside of <a class="button bold"></a> (or maybe the code works and the example is wrong?)

The code example was correct, it used the string offset arguments to limit the search to the button bold part of the string.

I'd like to be sure we really need this before we introduce a second way to query class names. Im worried that the normative use-case ->next_tag( [ 'class_name' => '…' ] ) will be supplanted by the imperative version instead, which will confuse people and not perform the way they want.

while ( $tags->next_tag() ) {
	if ( $tags->has_class( '…' ) ) {
		…
	}
}

If that happened then yeah, it would be problematic. I don't think it will happen, though. People can already ditch the query matcher and manually match the tag names, and I didn't see it happening. We'll know for sure after 6.2 is released and the WP_HTML_Tag_processor gets noticed in the wider community, but I remain optimistic.

If we do go this route I'd be curious about building it as a separate system than the one shared by the query engine. Build a proper decoded, though of course as we saw earlier that's much more complicated. It's something I think we could make a more justified case for out of the main loop, but again something I want to know that we need before we put it out there and encourage people to use it.

This may be worth a shot. At the same time, I'd wait for more feature requests to help shape the scope.

@adamziel adamziel mentioned this pull request Dec 1, 2022
26 tasks
}

$classes = $this->get_attribute( 'class' );
if ( null === $classes ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note that if $this->is_closing_tag() then get_attribute() will return null as well, so we may not need to double-check $this->is_closing_tag

@dmsnell
Copy link
Member

dmsnell commented Dec 2, 2022

Concerning being more wrong I'm glad it was just the example code and not the real code that was wrong.

Concerning the value of the API I'm still skeptical, especially as long as we're not handling entities properly.

I'd really like to know this is wanted and necessary before we add it. Counterpoint is something like most operations I've seen related to classes simply need to seek to a tag with a given class, and then they add or remove classes not based on whether a class exists, but whether or not some value in the attribute set exists.

@adamziel
Copy link
Contributor Author

adamziel commented Dec 2, 2022

Let's keep it on a backburner, then, and revisit at some other time. cc @getdave @aristath

@adamziel
Copy link
Contributor Author

adamziel commented Feb 7, 2023

I'll close this PR for now.

@adamziel adamziel closed this Feb 7, 2023
@gziolo gziolo deleted the add-tag-processor-has-class branch February 7, 2023 14:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Developer Experience Ideas about improving block and theme developer experience [Feature] Block API API that allows to express the block paradigm. [Type] Code Quality Issues or PRs that relate to code quality [Type] Enhancement A suggestion for improvement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants