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/render layout support updates #3976

Conversation

tellthemachines
Copy link
Contributor

@tellthemachines tellthemachines commented Feb 3, 2023

Trac ticket: https://core.trac.wordpress.org/ticket/57584

Includes changes from:

I also added some tests for wp_render_layout_support_flag (from WordPress/gutenberg#47719) and updated some of the server block fixtures because the change to add classnames to the inner block wrapper caused the order in which layout classes are added to switch.

To test the child layout changes, add the following markup in the editor, save and check that child block 1 occupies all the leftover width of its container:

<!-- wp:group {"layout":{"type":"flex","flexWrap":"nowrap","verticalAlignment":"stretch"}} -->
<div class="wp-block-group"><!-- wp:paragraph {"style":{"layout":{"selfStretch":"fill"}},"backgroundColor":"luminous-vivid-amber"} -->
<p class="has-luminous-vivid-amber-background-color has-background">1 </p>
<!-- /wp:paragraph -->

<!-- wp:paragraph {"backgroundColor":"luminous-vivid-amber"} -->
<p class="has-luminous-vivid-amber-background-color has-background">2</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group -->

This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.

Comment on lines 320 to 329
function wp_get_classnames_from_last_tag( $html ) {
$tags = new WP_HTML_Tag_Processor( $html );
$last_classnames = '';

while ( $tags->next_tag() ) {
$last_classnames = $tags->get_attribute( 'class' );
}

return (string) $last_classnames;
}
Copy link
Member

Choose a reason for hiding this comment

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

Suggestion: I only see a single use of this method. Maybe we should avoid introducing a public method and use WP_HTML_Tag_Processor directly.

The functions are always public in PHP, and we can only deprecate them after the release.

Copy link
Member

Choose a reason for hiding this comment

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

@Mamaduka Agreed. Can we instead inline this logic in the wp_render_layout_support_flag() function please? This means we can avoid introducing this function.

If there is eventually another change that needs something like this, we can always introduce a new function, but right now it seems unnecessary.

Copy link

@ntsekouras ntsekouras left a comment

Choose a reason for hiding this comment

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

Besides @Mamaduka 's comment about the new function vs inlining, I tested and this looks good to me. Thanks!

I've also tested the layout changes on the packages update PR and also tested the stack setting(having the updated packages) with this markup:

<!-- wp:group {"style":{"dimensions":{"minHeight":"400px"}},"layout":{"type":"flex","orientation":"vertical"}} -->
<div class="wp-block-group" style="min-height:400px"><!-- wp:heading {"style":{"layout":{"selfStretch":"fill","flexSize":null}},"backgroundColor":"light-green-cyan"} -->
<h2 class="wp-block-heading has-light-green-cyan-background-color has-background">1</h2>
<!-- /wp:heading -->

<!-- wp:paragraph {"style":{"layout":{"selfStretch":"fixed","flexSize":"123px"}},"backgroundColor":"luminous-vivid-orange"} -->
<p class="has-luminous-vivid-orange-background-color has-background">2</p>
<!-- /wp:paragraph --></div>
<!-- /wp:group -->

*/
public function test_layout_support_flag_renders_classnames_on_wrapper( $args, $expected_output ) {
$actual_output = wp_render_layout_support_flag( $args['block_content'], $args['block'] );
$this->assertEquals( $expected_output, $actual_output );
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
$this->assertEquals( $expected_output, $actual_output );
$this->assertSame( $expected_output, $actual_output );

$outer_class_names = array();

if ( $has_child_layout && ( 'fixed' === $block['attrs']['style']['layout']['selfStretch'] || 'fill' === $block['attrs']['style']['layout']['selfStretch'] ) ) {

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change

Comment on lines 346 to 347
if ( ! $support_layout
&& ! $has_child_layout ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if ( ! $support_layout
&& ! $has_child_layout ) {
if ( ! $support_layout && ! $has_child_layout ) {

);

$outer_class_names[] = $container_content_class;

Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change


/**
* The first chunk of innerContent contains the block markup up until the inner blocks start.
* We want to target the opening tag of the inner blocks wrapper, which is the last tag in that chunk.
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
* We want to target the opening tag of the inner blocks wrapper, which is the last tag in that chunk.
* This targets the opening tag of the inner blocks wrapper, which is the last tag in that chunk.

* @param string $html markup to be processed.
* @return string String of inner wrapper classnames.
*/
function wp_get_classnames_from_last_tag( $html ) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Obligatory "Naming things is hard", but I wonder if more context in this function name is needed.

Why?

"Tag" could mean one of at least two things when it comes to WordPress: a taxonomy type or a HTML element.

@hellofromtonya @felixarntz Any thoughts on the naming here?

Copy link
Member

Choose a reason for hiding this comment

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

I think the name is okay (WordPress core already uses the word "tag" for both of the two meanings in various function names), but more importantly I think this conversation shouldn't really be relevant given @Mamaduka's feedback that we should not need to introduce this function in the first place.

Copy link
Member

@felixarntz felixarntz left a comment

Choose a reason for hiding this comment

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

@tellthemachines Looks almost good to go from my perspective, though I agree with @Mamaduka that we should not unnecessarily introduce a new function here when its logic is rather specific and only needed in a single place.

Comment on lines 320 to 329
function wp_get_classnames_from_last_tag( $html ) {
$tags = new WP_HTML_Tag_Processor( $html );
$last_classnames = '';

while ( $tags->next_tag() ) {
$last_classnames = $tags->get_attribute( 'class' );
}

return (string) $last_classnames;
}
Copy link
Member

Choose a reason for hiding this comment

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

@Mamaduka Agreed. Can we instead inline this logic in the wp_render_layout_support_flag() function please? This means we can avoid introducing this function.

If there is eventually another change that needs something like this, we can always introduce a new function, but right now it seems unnecessary.

* @param string $html markup to be processed.
* @return string String of inner wrapper classnames.
*/
function wp_get_classnames_from_last_tag( $html ) {
Copy link
Member

Choose a reason for hiding this comment

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

I think the name is okay (WordPress core already uses the word "tag" for both of the two meanings in various function names), but more importantly I think this conversation shouldn't really be relevant given @Mamaduka's feedback that we should not need to introduce this function in the first place.

* The first chunk of innerContent contains the block markup up until the inner blocks start.
* We want to target the opening tag of the inner blocks wrapper, which is the last tag in that chunk.
*/
$inner_content_classnames = isset( $block['innerContent'][0] ) && 'string' === gettype( $block['innerContent'][0] ) ? wp_get_classnames_from_last_tag( $block['innerContent'][0] ) : '';
Copy link
Member

Choose a reason for hiding this comment

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

See above, can we inline that logic here in a dedicated if ( isset( $block['innerContent'][0] ) && 'string' === gettype( $block['innerContent'][0] ) ) block?

@tellthemachines
Copy link
Contributor Author

Thanks for the feedback folks! I've made all the requested changes, so this should be ready for another round.

@felixarntz
Copy link
Member

@tellthemachines I tried to fix the merge conflict in the fixtures with latest trunk here, hopefully I did it right 🤞

If there are test failures, I'll check and can hopefully fix it. Apologies, not really familiar with the fixtures.

Copy link
Contributor

@dream-encode dream-encode left a comment

Choose a reason for hiding this comment

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

Seems all feedback was addressed. Looks good to merge.

Copy link
Member

@felixarntz felixarntz left a comment

Choose a reason for hiding this comment

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

@felixarntz
Copy link
Member

Noting that the test failures here are unrelated and intermittent, fixed via https://core.trac.wordpress.org/changeset/55280.

@felixarntz
Copy link
Member

Committed in https://core.trac.wordpress.org/changeset/55282.

@felixarntz felixarntz closed this Feb 7, 2023
dmsnell added a commit to WordPress/gutenberg that referenced this pull request Aug 30, 2023
…lasses.

In #45364 (WordPress/wordpress-develop#3976) the Block Supports was extended to
add layout class names using the HTML API, new in WordPress 6.2. The initial
patch opened up two opportunities to refine the code, however:

 - There are multiple instances of the `WP_HTML_Tag_Processor` created when a
   single one suffices. (There is an exception in that a second processor is
   necessary in order to find an inner block wrapper).

 - The code relies on the incidental fact that searching by a whitespace-separated
   list of class names works if the class names in the target tag are in the same
   order.

In this patch the use of the HTML API is refactored to address these opportunities
and clean up a few places where there could be stronger consistency with other use
patterns of the HTML API:

 - Multiple instances of the Tag Processor have been combined to remove overhead,
   extra variables, and code confusion. The new flow is more linear throughout the
   function instead of branching.

 - Updated HTML is returned via `get_updated_html()` instead of casting to a string.

 - The matching logic to find the inner block wrapper has been commented and the
   condition uses the null-coalescing operator now that WordPress requires PHP 7.0+.

 - When attempting to find the inner block wrapper at the end, a custom comparison
   is made against the `class` attribute instead of relying on `next_tag()` to find
   a tag with the given set of class names.

The last refactor is important as a preliminary step to WordPress/wordpress-develop#5096
where `has_class()` and `class_list()` methods are being introduced to the Tag Processor.
In that patch the implicit functionality of matching `'class_name' => 'more than one class'`
is removed since that's not a single class name, but many.
dmsnell added a commit to WordPress/gutenberg that referenced this pull request Sep 1, 2023
…lasses.

In #45364 (WordPress/wordpress-develop#3976) the Block Supports was extended to
add layout class names using the HTML API, new in WordPress 6.2. The initial
patch opened up two opportunities to refine the code, however:

 - There are multiple instances of the `WP_HTML_Tag_Processor` created when a
   single one suffices. (There is an exception in that a second processor is
   necessary in order to find an inner block wrapper).

 - The code relies on the incidental fact that searching by a whitespace-separated
   list of class names works if the class names in the target tag are in the same
   order.

In this patch the use of the HTML API is refactored to address these opportunities
and clean up a few places where there could be stronger consistency with other use
patterns of the HTML API:

 - Multiple instances of the Tag Processor have been combined to remove overhead,
   extra variables, and code confusion. The new flow is more linear throughout the
   function instead of branching.

 - Updated HTML is returned via `get_updated_html()` instead of casting to a string.

 - The matching logic to find the inner block wrapper has been commented and the
   condition uses the null-coalescing operator now that WordPress requires PHP 7.0+.

 - When attempting to find the inner block wrapper at the end, a custom comparison
   is made against the `class` attribute instead of relying on `next_tag()` to find
   a tag with the given set of class names.

The last refactor is important as a preliminary step to WordPress/wordpress-develop#5096
where `has_class()` and `class_list()` methods are being introduced to the Tag Processor.
In that patch the implicit functionality of matching `'class_name' => 'more than one class'`
is removed since that's not a single class name, but many.
dmsnell added a commit to WordPress/gutenberg that referenced this pull request Sep 4, 2023
…lasses.

In #45364 (WordPress/wordpress-develop#3976) the Block Supports was extended to
add layout class names using the HTML API, new in WordPress 6.2. The initial
patch opened up two opportunities to refine the code, however:

 - There are multiple instances of the `WP_HTML_Tag_Processor` created when a
   single one suffices. (There is an exception in that a second processor is
   necessary in order to find an inner block wrapper).

 - The code relies on the incidental fact that searching by a whitespace-separated
   list of class names works if the class names in the target tag are in the same
   order.

In this patch the use of the HTML API is refactored to address these opportunities
and clean up a few places where there could be stronger consistency with other use
patterns of the HTML API:

 - Multiple instances of the Tag Processor have been combined to remove overhead,
   extra variables, and code confusion. The new flow is more linear throughout the
   function instead of branching.

 - Updated HTML is returned via `get_updated_html()` instead of casting to a string.

 - The matching logic to find the inner block wrapper has been commented and the
   condition uses the null-coalescing operator now that WordPress requires PHP 7.0+.

 - When attempting to find the inner block wrapper at the end, a custom comparison
   is made against the `class` attribute instead of relying on `next_tag()` to find
   a tag with the given set of class names.

The last refactor is important as a preliminary step to WordPress/wordpress-develop#5096
where `has_class()` and `class_list()` methods are being introduced to the Tag Processor.
In that patch the implicit functionality of matching `'class_name' => 'more than one class'`
is removed since that's not a single class name, but many.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants