Skip to content
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
20 changes: 17 additions & 3 deletions src/wp-includes/class-wp-theme-json.php
Original file line number Diff line number Diff line change
Expand Up @@ -3894,8 +3894,18 @@ public function get_styles_for_block( $block_metadata ) {
// Only store if the variation has blockGap defined.
if ( isset( $style_variation_node['spacing']['blockGap'] ) ) {
// Append block selector to the variation selector for proper targeting.
$variation_metadata_with_selector = $style_variation;
$variation_metadata_with_selector['selector'] = $style_variation['selector'] . $block_metadata['css'];
$variation_metadata_with_selector = $style_variation;
$variation_metadata_with_selector['selector'] = $style_variation['selector'] . $block_metadata['css'];

/*
* `get_layout_styles()` reads `name` as a block name, to check that the block
* supports layout at all. A variation node's `name` is the variation slug,
* which is never a registered block, so the check fails and every variation
* gap rule is discarded. Pass the block the variation belongs to, so the
* support check answers the question it is actually asking.
*/
$variation_metadata_with_selector['name'] = $block_name;

$style_variation_layout_metadata[ $style_variation['selector'] ] = array(
'metadata' => $variation_metadata_with_selector,
'node' => $style_variation_node,
Expand Down Expand Up @@ -3951,7 +3961,11 @@ public function get_styles_for_block( $block_metadata ) {
if ( isset( $breakpoint_node['spacing']['blockGap'] ) ) {
$variation_layout_metadata = $style_variation;
$variation_layout_metadata['selector'] = $style_variation['selector'] . $block_metadata['css'];
$variation_responsive_css .= $this->get_layout_styles(

// The variation slug is not a block name here either. See above.
$variation_layout_metadata['name'] = $block_name;

$variation_responsive_css .= $this->get_layout_styles(
$variation_layout_metadata,
array(
'node' => $breakpoint_node,
Expand Down
187 changes: 187 additions & 0 deletions tests/phpunit/tests/theme/wpThemeJson.php
Original file line number Diff line number Diff line change
Expand Up @@ -7829,6 +7829,193 @@ public function test_opt_in_to_block_style_variations() {
$this->assertSame( $expected, $button_variations );
}

/**
* Tests that a block style variation declaring `spacing.blockGap` emits a layout
* gap rule scoped to the variation.
*
* The variation node carries the variation slug in its `name`, which
* `get_layout_styles()` reads as a block name. The metadata passed to that
* method therefore has to name the block the variation belongs to.
*
* @ticket 66044
*
* @covers WP_Theme_JSON::get_styles_for_block
*/
public function test_block_style_variation_with_block_gap_emits_layout_styles() {
$registry = WP_Block_Styles_Registry::get_instance();
$registry->register( 'core/group', array( 'name' => 'custom-group' ) );

$theme_json = new WP_Theme_JSON(
array(
'version' => WP_Theme_JSON::LATEST_SCHEMA,
'settings' => array(
'spacing' => array(
'blockGap' => true,
),
),
'styles' => array(
'blocks' => array(
'core/group' => array(
'variations' => array(
'custom-group' => array(
'spacing' => array(
'blockGap' => '3em',
),
),
),
),
),
),
),
'blocks'
);

$stylesheet = $theme_json->get_stylesheet(
array( 'styles' ),
array( 'custom' ),
array(
'include_block_style_variations' => true,
'skip_root_layout_styles' => true,
)
);

$registry->unregister( 'core/group', 'custom-group' );

$this->assertStringContainsString(
':root :where(.wp-block-group.is-style-custom-group.wp-block-group-is-layout-flex){gap: 3em;}',
$stylesheet,
'The variation should emit a gap rule scoped to itself.'
);
}

/**
* Tests that a block style variation declaring `spacing.blockGap` inside a
* viewport breakpoint emits a layout gap rule within the media query.
*
* The responsive branch takes its own copy of the variation metadata, so it
* needs the owning block name for the same reason the base branch does.
*
* @ticket 66044
*
* @covers WP_Theme_JSON::get_styles_for_block
*/
public function test_block_style_variation_with_responsive_block_gap_emits_layout_styles() {
$registry = WP_Block_Styles_Registry::get_instance();
$registry->register( 'core/group', array( 'name' => 'custom-group' ) );

$theme_json = new WP_Theme_JSON(
array(
'version' => WP_Theme_JSON::LATEST_SCHEMA,
'settings' => array(
'spacing' => array(
'blockGap' => true,
),
'viewport' => array(
'mobile' => '599px',
),
),
'styles' => array(
'blocks' => array(
'core/group' => array(
'variations' => array(
'custom-group' => array(
'spacing' => array(
'blockGap' => '3em',
),
'@mobile' => array(
'spacing' => array(
'blockGap' => '1em',
),
),
),
),
),
),
),
),
'blocks'
);

$stylesheet = $theme_json->get_stylesheet(
array( 'styles' ),
array( 'custom' ),
array(
'include_block_style_variations' => true,
'skip_root_layout_styles' => true,
)
);

$registry->unregister( 'core/group', 'custom-group' );

$this->assertStringContainsString(
'@media (width <= 599px)',
$stylesheet,
'The breakpoint media query should be emitted.'
);
$this->assertStringContainsString(
':root :where(.wp-block-group.is-style-custom-group.wp-block-group-is-layout-flex){gap: 1em;}',
$stylesheet,
'The variation should emit a gap rule inside the breakpoint.'
);
}

/**
* Tests that the layout support check still applies to a variation's blockGap.
*
* The variation metadata carries the block it belongs to, so a block without
* layout support emits no gap rule -- the check is answered, not skipped.
*
* @ticket 66044
*
* @covers WP_Theme_JSON::get_styles_for_block
*/
public function test_block_style_variation_block_gap_respects_layout_support() {
$registry = WP_Block_Styles_Registry::get_instance();
$registry->register( 'core/paragraph', array( 'name' => 'custom-paragraph' ) );

$theme_json = new WP_Theme_JSON(
array(
'version' => WP_Theme_JSON::LATEST_SCHEMA,
'settings' => array(
'spacing' => array(
'blockGap' => true,
),
),
'styles' => array(
'blocks' => array(
'core/paragraph' => array(
'variations' => array(
'custom-paragraph' => array(
'spacing' => array(
'blockGap' => '3em',
),
),
),
),
),
),
),
'blocks'
);

$stylesheet = $theme_json->get_stylesheet(
array( 'styles' ),
array( 'custom' ),
array(
'include_block_style_variations' => true,
'skip_root_layout_styles' => true,
)
);

$registry->unregister( 'core/paragraph', 'custom-paragraph' );

$this->assertStringNotContainsString(
'is-style-custom-paragraph',
$stylesheet,
'core/paragraph has no layout support, so its variation should emit no gap rule.'
);
}

/**
* Tests that block-level settings inherit global default settings when not explicitly set.
*
Expand Down
Loading