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

101 changes: 87 additions & 14 deletions src/wp-includes/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,53 @@ function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false
function wp_render_layout_support_flag( $block_content, $block ) {
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
$support_layout = block_has_support( $block_type, array( '__experimentalLayout' ), false );
$has_child_layout = isset( $block['attrs']['style']['layout']['selfStretch'] );

if ( ! $support_layout ) {
if ( ! $support_layout && ! $has_child_layout ) {
return $block_content;
}
$outer_class_names = array();

if ( $has_child_layout && ( 'fixed' === $block['attrs']['style']['layout']['selfStretch'] || 'fill' === $block['attrs']['style']['layout']['selfStretch'] ) ) {
$container_content_class = wp_unique_id( 'wp-container-content-' );

$child_layout_styles = array();

if ( 'fixed' === $block['attrs']['style']['layout']['selfStretch'] && isset( $block['attrs']['style']['layout']['flexSize'] ) ) {
$child_layout_styles[] = array(
'selector' => ".$container_content_class",
'declarations' => array(
'flex-basis' => $block['attrs']['style']['layout']['flexSize'],
'box-sizing' => 'border-box',
),
);
} elseif ( 'fill' === $block['attrs']['style']['layout']['selfStretch'] ) {
$child_layout_styles[] = array(
'selector' => ".$container_content_class",
'declarations' => array(
'flex-grow' => '1',
),
);
}

wp_style_engine_get_stylesheet_from_css_rules(
$child_layout_styles,
array(
'context' => 'block-supports',
'prettify' => false,
)
);

$outer_class_names[] = $container_content_class;
}

// Return early if only child layout exists.
if ( ! $support_layout && ! empty( $outer_class_names ) ) {
$content = new WP_HTML_Tag_Processor( $block_content );
$content->next_tag();
$content->add_class( implode( ' ', $outer_class_names ) );
return (string) $content;
}

$global_settings = wp_get_global_settings();
$block_gap = _wp_array_get( $global_settings, array( 'spacing', 'blockGap' ), null );
Expand All @@ -341,7 +384,6 @@ function wp_render_layout_support_flag( $block_content, $block ) {

$class_names = array();
$layout_definitions = _wp_array_get( $global_layout_settings, array( 'definitions' ), array() );
$block_classname = wp_get_block_default_classname( $block['blockName'] );
$container_class = wp_unique_id( 'wp-container-' );
$layout_classname = '';

Expand Down Expand Up @@ -417,7 +459,7 @@ function wp_render_layout_support_flag( $block_content, $block ) {
$should_skip_gap_serialization = wp_should_skip_block_supports_serialization( $block_type, 'spacing', 'blockGap' );

$style = wp_get_layout_style(
".$block_classname.$container_class",
".$container_class.$container_class",
$used_layout,
$has_block_gap_support,
$gap_value,
Expand All @@ -432,18 +474,49 @@ function wp_render_layout_support_flag( $block_content, $block ) {
}
}

/*
* This assumes the hook only applies to blocks with a single wrapper.
* A limitation of this hook is that nested inner blocks wrappers are not yet supported.
*/
$content = preg_replace(
'/' . preg_quote( 'class="', '/' ) . '/',
'class="' . esc_attr( implode( ' ', $class_names ) ) . ' ',
$block_content,
1
);
$content_with_outer_classnames = '';

if ( ! empty( $outer_class_names ) ) {
$content_with_outer_classnames = new WP_HTML_Tag_Processor( $block_content );
$content_with_outer_classnames->next_tag();
foreach ( $outer_class_names as $outer_class_name ) {
$content_with_outer_classnames->add_class( $outer_class_name );
}

$content_with_outer_classnames = (string) $content_with_outer_classnames;
}

/**
* The first chunk of innerContent contains the block markup up until the inner blocks start.
* This targets the opening tag of the inner blocks wrapper, which is the last tag in that chunk.
*/
$inner_content_classnames = '';

if ( isset( $block['innerContent'][0] ) && 'string' === gettype( $block['innerContent'][0] ) ) {
$tags = new WP_HTML_Tag_Processor( $block['innerContent'][0] );
$last_classnames = '';
while ( $tags->next_tag() ) {
$last_classnames = $tags->get_attribute( 'class' );
}

$inner_content_classnames = (string) $last_classnames;
}

$content = $content_with_outer_classnames ? new WP_HTML_Tag_Processor( $content_with_outer_classnames ) : new WP_HTML_Tag_Processor( $block_content );

if ( $inner_content_classnames ) {
$content->next_tag( array( 'class_name' => $inner_content_classnames ) );
foreach ( $class_names as $class_name ) {
$content->add_class( $class_name );
}
} else {
$content->next_tag();
foreach ( $class_names as $class_name ) {
$content->add_class( $class_name );
}
}

return $content;
return (string) $content;
}

// Register the block support.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

<div class="is-layout-flow wp-block-column">
<div class="wp-block-column is-layout-flow">

<p>Column One, Paragraph One</p>

Expand Down
6 changes: 3 additions & 3 deletions tests/phpunit/data/blocks/fixtures/core__columns.server.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

<div class="is-layout-flex wp-container-1 wp-block-columns has-3-columns">
<div class="wp-block-columns has-3-columns is-layout-flex wp-container-1">

<div class="is-layout-flow wp-block-column">
<div class="wp-block-column is-layout-flow">

<p>Column One, Paragraph One</p>

Expand All @@ -11,7 +11,7 @@
</div>


<div class="is-layout-flow wp-block-column">
<div class="wp-block-column is-layout-flow">

<p>Column Two, Paragraph One</p>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

<div class="is-layout-flex wp-container-1 wp-block-columns has-3-columns">
<div class="wp-block-columns has-3-columns is-layout-flex wp-container-1">

<p class="layout-column-1">Column One, Paragraph One</p>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

<figure class="is-layout-flex wp-block-gallery has-nested-images columns-default is-cropped columns-2 wp-block-gallery-1">
<figure class="wp-block-gallery has-nested-images columns-default is-cropped columns-2 wp-block-gallery-1 is-layout-flex">

<figure class="wp-block-image size-large">
<img src="https://cldup.com/uuUqE_dXzy.jpg" alt="Image gallery image" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@

<figure class="is-layout-flex wp-block-gallery has-nested-images is-cropped columns-1 wp-block-gallery-1" >
<figure class="wp-block-gallery has-nested-images is-cropped columns-1 wp-block-gallery-1 is-layout-flex" >

<figure class="wp-block-image size-large">
<img src="https://cldup.com/uuUqE_dXzy.jpg" alt="Image gallery image" />
Expand Down
84 changes: 84 additions & 0 deletions tests/phpunit/tests/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,88 @@ public function test_outer_container_not_restored_for_aligned_image_block_with_t

$this->assertSame( $expected, wp_restore_image_outer_container( $block_content, $block ) );
}

/**
* @ticket 57584
*
* @dataProvider data_layout_support_flag_renders_classnames_on_wrapper
*
* @covers ::wp_render_layout_support_flag
*
* @param array $args Dataset to test.
* @param string $expected_output The expected output.
*/
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->assertSame( $expected_output, $actual_output );
}

/**
* Data provider for test_layout_support_flag_renders_classnames_on_wrapper.
*
* @return array
*/
public function data_layout_support_flag_renders_classnames_on_wrapper() {
return array(
'single wrapper block layout with flow type' => array(
'args' => array(
'block_content' => '<div class="wp-block-group"></div>',
'block' => array(
'blockName' => 'core/group',
'attrs' => array(
'layout' => array(
'type' => 'default',
),
),
'innerBlocks' => array(),
'innerHTML' => '<div class="wp-block-group"></div>',
'innerContent' => array(
'<div class="wp-block-group"></div>',
),
),
),
'expected_output' => '<div class="wp-block-group is-layout-flow"></div>',
),
'single wrapper block layout with constrained type' => array(
'args' => array(
'block_content' => '<div class="wp-block-group"></div>',
'block' => array(
'blockName' => 'core/group',
'attrs' => array(
'layout' => array(
'type' => 'constrained',
),
),
'innerBlocks' => array(),
'innerHTML' => '<div class="wp-block-group"></div>',
'innerContent' => array(
'<div class="wp-block-group"></div>',
),
),
),
'expected_output' => '<div class="wp-block-group is-layout-constrained"></div>',
),
'multiple wrapper block layout with flow type' => array(
'args' => array(
'block_content' => '<div class="wp-block-group"><div class="wp-block-group__inner-wrapper"></div></div>',
'block' => array(
'blockName' => 'core/group',
'attrs' => array(
'layout' => array(
'type' => 'default',
),
),
'innerBlocks' => array(),
'innerHTML' => '<div class="wp-block-group"><div class="wp-block-group__inner-wrapper"></div></div>',
'innerContent' => array(
'<div class="wp-block-group"><div class="wp-block-group__inner-wrapper">',
' ',
' </div></div>',
),
),
),
'expected_output' => '<div class="wp-block-group"><div class="wp-block-group__inner-wrapper is-layout-flow"></div></div>',
),
);
}
}