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

Check child layout exists before generating classname. #61392

Merged
merged 2 commits into from
May 7, 2024
Merged
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
184 changes: 94 additions & 90 deletions lib/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -573,112 +573,116 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
return $block_content;
}

$outer_class_names = array();
$container_content_class = wp_unique_id( 'wp-container-content-' );
$child_layout_declarations = array();
$child_layout_styles = array();

$self_stretch = isset( $block['attrs']['style']['layout']['selfStretch'] ) ? $block['attrs']['style']['layout']['selfStretch'] : null;

if ( 'fixed' === $self_stretch && isset( $block['attrs']['style']['layout']['flexSize'] ) ) {
$child_layout_declarations['flex-basis'] = $block['attrs']['style']['layout']['flexSize'];
$child_layout_declarations['box-sizing'] = 'border-box';
} elseif ( 'fill' === $self_stretch ) {
$child_layout_declarations['flex-grow'] = '1';
}
$outer_class_names = array();

$column_start = isset( $block['attrs']['style']['layout']['columnStart'] ) ? $block['attrs']['style']['layout']['columnStart'] : null;
$column_span = isset( $block['attrs']['style']['layout']['columnSpan'] ) ? $block['attrs']['style']['layout']['columnSpan'] : null;
if ( $column_start && $column_span ) {
$child_layout_declarations['grid-column'] = "$column_start / span $column_span";
} elseif ( $column_start ) {
$child_layout_declarations['grid-column'] = "$column_start";
} elseif ( $column_span ) {
$child_layout_declarations['grid-column'] = "span $column_span";
}
// Child layout specific logic.
if ( $child_layout ) {
$container_content_class = wp_unique_id( 'wp-container-content-' );
$child_layout_declarations = array();
$child_layout_styles = array();

$row_start = isset( $block['attrs']['style']['layout']['rowStart'] ) ? $block['attrs']['style']['layout']['rowStart'] : null;
$row_span = isset( $block['attrs']['style']['layout']['rowSpan'] ) ? $block['attrs']['style']['layout']['rowSpan'] : null;
if ( $row_start && $row_span ) {
$child_layout_declarations['grid-row'] = "$row_start / span $row_span";
} elseif ( $row_start ) {
$child_layout_declarations['grid-row'] = "$row_start";
} elseif ( $row_span ) {
$child_layout_declarations['grid-row'] = "span $row_span";
}
$self_stretch = isset( $block['attrs']['style']['layout']['selfStretch'] ) ? $block['attrs']['style']['layout']['selfStretch'] : null;

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

$minimum_column_width = isset( $block['parentLayout']['minimumColumnWidth'] ) ? $block['parentLayout']['minimumColumnWidth'] : null;
$column_count = isset( $block['parentLayout']['columnCount'] ) ? $block['parentLayout']['columnCount'] : null;
$column_start = isset( $block['attrs']['style']['layout']['columnStart'] ) ? $block['attrs']['style']['layout']['columnStart'] : null;
$column_span = isset( $block['attrs']['style']['layout']['columnSpan'] ) ? $block['attrs']['style']['layout']['columnSpan'] : null;
if ( $column_start && $column_span ) {
$child_layout_declarations['grid-column'] = "$column_start / span $column_span";
} elseif ( $column_start ) {
$child_layout_declarations['grid-column'] = "$column_start";
} elseif ( $column_span ) {
$child_layout_declarations['grid-column'] = "span $column_span";
}

/*
* If columnSpan or columnStart is set, and the parent grid is responsive, i.e. if it has a minimumColumnWidth set,
* the columnSpan should be removed once the grid is smaller than the span, and columnStart should be removed
* once the grid has less columns than the start.
* If there's a minimumColumnWidth, the grid is responsive. But if the minimumColumnWidth value wasn't changed, it won't be set.
* In that case, if columnCount doesn't exist, we can assume that the grid is responsive.
*/
if ( ( $column_span || $column_start ) && ( $minimum_column_width || ! $column_count ) ) {
$column_span_number = floatval( $column_span );
$column_start_number = floatval( $column_start );
$highest_number = max( $column_span_number, $column_start_number );
$parent_column_width = $minimum_column_width ? $minimum_column_width : '12rem';
$parent_column_value = floatval( $parent_column_width );
$parent_column_unit = explode( $parent_column_value, $parent_column_width );
$row_start = isset( $block['attrs']['style']['layout']['rowStart'] ) ? $block['attrs']['style']['layout']['rowStart'] : null;
$row_span = isset( $block['attrs']['style']['layout']['rowSpan'] ) ? $block['attrs']['style']['layout']['rowSpan'] : null;
if ( $row_start && $row_span ) {
$child_layout_declarations['grid-row'] = "$row_start / span $row_span";
} elseif ( $row_start ) {
$child_layout_declarations['grid-row'] = "$row_start";
} elseif ( $row_span ) {
$child_layout_declarations['grid-row'] = "span $row_span";
}

$child_layout_styles[] = array(
'selector' => ".$container_content_class",
'declarations' => $child_layout_declarations,
);

$minimum_column_width = isset( $block['parentLayout']['minimumColumnWidth'] ) ? $block['parentLayout']['minimumColumnWidth'] : null;
$column_count = isset( $block['parentLayout']['columnCount'] ) ? $block['parentLayout']['columnCount'] : null;

/*
* If there is no unit, the width has somehow been mangled so we reset both unit and value
* to defaults.
* Additionally, the unit should be one of px, rem or em, so that also needs to be checked.
* If columnSpan or columnStart is set, and the parent grid is responsive, i.e. if it has a minimumColumnWidth set,
* the columnSpan should be removed once the grid is smaller than the span, and columnStart should be removed
* once the grid has less columns than the start.
* If there's a minimumColumnWidth, the grid is responsive. But if the minimumColumnWidth value wasn't changed, it won't be set.
* In that case, if columnCount doesn't exist, we can assume that the grid is responsive.
*/
if ( count( $parent_column_unit ) <= 1 ) {
$parent_column_unit = 'rem';
$parent_column_value = 12;
} else {
$parent_column_unit = $parent_column_unit[1];
if ( ( $column_span || $column_start ) && ( $minimum_column_width || ! $column_count ) ) {
$column_span_number = floatval( $column_span );
$column_start_number = floatval( $column_start );
$highest_number = max( $column_span_number, $column_start_number );
$parent_column_width = $minimum_column_width ? $minimum_column_width : '12rem';
$parent_column_value = floatval( $parent_column_width );
$parent_column_unit = explode( $parent_column_value, $parent_column_width );

/*
* If there is no unit, the width has somehow been mangled so we reset both unit and value
* to defaults.
* Additionally, the unit should be one of px, rem or em, so that also needs to be checked.
*/
if ( count( $parent_column_unit ) <= 1 ) {
$parent_column_unit = 'rem';
$parent_column_value = 12;
} else {
$parent_column_unit = $parent_column_unit[1];

if ( ! in_array( $parent_column_unit, array( 'px', 'rem', 'em' ), true ) ) {
$parent_column_unit = 'rem';
if ( ! in_array( $parent_column_unit, array( 'px', 'rem', 'em' ), true ) ) {
$parent_column_unit = 'rem';
}
}

/*
* A default gap value is used for this computation because custom gap values may not be
* viable to use in the computation of the container query value.
*/
$default_gap_value = 'px' === $parent_column_unit ? 24 : 1.5;
$container_query_value = $highest_number * $parent_column_value + ( $highest_number - 1 ) * $default_gap_value;
$container_query_value = $container_query_value . $parent_column_unit;
// If a span is set we want to preserve it as long as possible, otherwise we just reset the value.
$grid_column_value = $column_span ? '1/-1' : 'auto';

$child_layout_styles[] = array(
'rules_group' => "@container (max-width: $container_query_value )",
'selector' => ".$container_content_class",
'declarations' => array(
'grid-column' => $grid_column_value,
),
);
}

/*
* A default gap value is used for this computation because custom gap values may not be
* viable to use in the computation of the container query value.
* Add to the style engine store to enqueue and render layout styles.
* Return styles here just to check if any exist.
*/
$default_gap_value = 'px' === $parent_column_unit ? 24 : 1.5;
$container_query_value = $highest_number * $parent_column_value + ( $highest_number - 1 ) * $default_gap_value;
$container_query_value = $container_query_value . $parent_column_unit;
// If a span is set we want to preserve it as long as possible, otherwise we just reset the value.
$grid_column_value = $column_span ? '1/-1' : 'auto';

$child_layout_styles[] = array(
'rules_group' => "@container (max-width: $container_query_value )",
'selector' => ".$container_content_class",
'declarations' => array(
'grid-column' => $grid_column_value,
),
$child_css = gutenberg_style_engine_get_stylesheet_from_css_rules(
$child_layout_styles,
array(
'context' => 'block-supports',
'prettify' => false,
)
);
}

/*
* Add to the style engine store to enqueue and render layout styles.
* Return styles here just to check if any exist.
*/
$child_css = gutenberg_style_engine_get_stylesheet_from_css_rules(
$child_layout_styles,
array(
'context' => 'block-supports',
'prettify' => false,
)
);

if ( $child_css ) {
$outer_class_names[] = $container_content_class;
if ( $child_css ) {
$outer_class_names[] = $container_content_class;
}
}

// Prep the processor for modifying the block output.
Expand Down
22 changes: 22 additions & 0 deletions phpunit/block-supports/layout-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ public function data_gutenberg_get_layout_style() {
* @param string $expected_output The expected output.
*/
public function test_layout_support_flag_renders_classnames_on_wrapper( $args, $expected_output ) {
switch_theme( 'default' );
$actual_output = gutenberg_render_layout_support_flag( $args['block_content'], $args['block'] );
$this->assertEquals( $expected_output, $actual_output );
}
Expand Down Expand Up @@ -481,6 +482,27 @@ public function data_layout_support_flag_renders_classnames_on_wrapper() {
),
'expected_output' => '<div class="wp-block-group"><div class="wp-block-group__inner-wrapper is-layout-flow wp-block-group-is-layout-flow"></div></div>',
),
'block with child layout' => array(
'args' => array(
'block_content' => '<p>Some text.</p>',
'block' => array(
'blockName' => 'core/paragraph',
'attrs' => array(
'style' => array(
'layout' => array(
'columnSpan' => '2',
),
),
),
'innerBlocks' => array(),
'innerHTML' => '<p>Some text.</p>',
'innerContent' => array(
'<p>Some text.</p>',
),
),
),
'expected_output' => '<p class="wp-container-content-1">Some text.</p>', // The generated classname number assumes `wp_unique_id` will not have run previously in this test.
),
);
}

Expand Down
Loading