Skip to content
Closed
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
Try combining margin and spacing styles in PHP output, roll out logic…
… to children of site blocks
  • Loading branch information
andrewserong committed Feb 21, 2023
commit 50e3aa510e92c1d3fb19ab3a6f745482a0615599
181 changes: 91 additions & 90 deletions lib/class-wp-theme-json-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -1196,6 +1196,69 @@ protected function get_block_classes( $style_nodes ) {
return $block_rules;
}

/**
* Gets the CSS layout rules for a particular block from theme.json layout definitions.
*
* @since 6.3.0
*
* @param string $selector_format The selector to use for the layout rules with `%s` as a placeholder for the layout rule's selector.
* @param array $layout_definition The layout definition to get styles for.
* @param array $rules_type The key for the set of layout rules to use (e.g. 'marginStyles' or 'spacingStyles').
* @return string CSS string containing the layout rules.
*/
protected function construct_layout_rules( $selector_format, $layout_definition, $rules_type, $replacement_value ) {
$layout_rules = _wp_array_get( $layout_definition, array( $rules_type ), array() );
$layout_selector_pattern = '/^[a-zA-Z0-9\-\.\ *+>:\(\)]*$/'; // Allow alphanumeric classnames, spaces, wildcard, sibling, child combinator and pseudo class selectors.

$block_rules = '';

if (
! empty( $selector_format ) &&
! empty( $layout_rules )
) {
foreach ( $layout_rules as $layout_rule ) {
if (
isset( $layout_rule['selector'] ) &&
preg_match( $layout_selector_pattern, $layout_rule['selector'] ) &&
! empty( $layout_rule['rules'] )
) {
$declarations = array();
foreach ( $layout_rule['rules'] as $css_property => $css_value ) {
if ( is_string( $css_value ) ) {
if ( static::is_safe_css_declaration( $css_property, $css_value ) ) {
$declarations[] = array(
'name' => $css_property,
'value' => $css_value,
);
}
} elseif ( isset( $replacement_value ) && ! is_array( $replacement_value ) ) {
$declarations[] = array(
'name' => $css_property,
'value' => $replacement_value,
);
} elseif ( isset( $replacement_value[ $css_property ] ) ) {
if ( static::is_safe_css_declaration( $css_property, $replacement_value[ $css_property ] ) ) {
$declarations[] = array(
'name' => $css_property,
'value' => $replacement_value[ $css_property ],
);
}
}
}

$layout_selector = sprintf(
$selector_format,
$layout_rule['selector'],
);

$block_rules .= static::to_ruleset( $layout_selector, $declarations );
}
}
}

return $block_rules;
}

/**
* Gets the CSS layout rules for a particular block from theme.json layout definitions.
*
Expand Down Expand Up @@ -1272,54 +1335,23 @@ protected function get_layout_styles( $block_metadata ) {
// Add layout aware margin rules for each supported layout type.
foreach ( $layout_definitions as $layout_definition_key => $layout_definition ) {
$class_name = sanitize_title( _wp_array_get( $layout_definition, array( 'className' ), '' ) );
$margin_rules = _wp_array_get( $layout_definition, array( 'marginStyles' ), array() );

if (
! empty( $class_name ) &&
! empty( $margin_rules )
) {
foreach ( $margin_rules as $margin_rule ) {
if (
isset( $margin_rule['selector'] ) &&
preg_match( $layout_selector_pattern, $margin_rule['selector'] ) &&
! empty( $margin_rule['rules'] )
) {
$declarations = array();
foreach ( $margin_rule['rules'] as $css_property => $css_value ) {
if ( is_string( $css_value ) ) {
if ( static::is_safe_css_declaration( $css_property, $css_value ) ) {
$declarations[] = array(
'name' => $css_property,
'value' => $css_value,
);
}
} elseif ( isset( $margin_styles['declarations'][ $css_property ] ) ) {
if ( static::is_safe_css_declaration( $css_property, $margin_styles['declarations'][ $css_property ] ) ) {
$declarations[] = array(
'name' => $css_property,
'value' => $margin_styles['declarations'][ $css_property ],
);
}
}
}
$layout_selector = sprintf(
'.%s%s%s',
$class_name,
$margin_rule['selector'],
$selector
);
$block_rules .= $this->construct_layout_rules(
'.' . $class_name . '%s' . $selector,
$layout_definition,
'marginStyles',
$margin_styles['declarations']
);

$block_rules .= static::to_ruleset( $layout_selector, $declarations );
}
}
// Add layout aware margin rule for children of the root site blocks class.
if ( 'default' === $layout_definition_key ) {
$block_rules .= $this->construct_layout_rules(
'.wp-site-blocks%s' . $selector,
$layout_definition,
'marginStyles',
$margin_styles['declarations']
);
}
}
// Add layout aware margin rule for children of the root site blocks class.
$block_rules .= sprintf(
'.wp-site-blocks > * + %s {%s}',
$selector,
$margin_styles['css']
);
}
}

Expand All @@ -1331,53 +1363,22 @@ protected function get_layout_styles( $block_metadata ) {
continue;
}

$class_name = sanitize_title( _wp_array_get( $layout_definition, array( 'className' ), false ) );
$spacing_rules = _wp_array_get( $layout_definition, array( 'spacingStyles' ), array() );
$class_name = sanitize_title( _wp_array_get( $layout_definition, array( 'className' ), false ) );
$layout_selector_format = '';

if (
! empty( $class_name ) &&
! empty( $spacing_rules )
) {
foreach ( $spacing_rules as $spacing_rule ) {
$declarations = array();
if (
isset( $spacing_rule['selector'] ) &&
preg_match( $layout_selector_pattern, $spacing_rule['selector'] ) &&
! empty( $spacing_rule['rules'] )
) {
// Iterate over each of the styling rules and substitute non-string values such as `null` with the real `blockGap` value.
foreach ( $spacing_rule['rules'] as $css_property => $css_value ) {
$current_css_value = is_string( $css_value ) ? $css_value : $block_gap_value;
if ( static::is_safe_css_declaration( $css_property, $current_css_value ) ) {
$declarations[] = array(
'name' => $css_property,
'value' => $current_css_value,
);
}
}

if ( ! $has_block_gap_support ) {
// For fallback gap styles, use lower specificity, to ensure styles do not unintentionally override theme styles.
$format = static::ROOT_BLOCK_SELECTOR === $selector ? ':where(.%2$s%3$s)' : ':where(%1$s.%2$s%3$s)';
$layout_selector = sprintf(
$format,
$selector,
$class_name,
$spacing_rule['selector']
);
} else {
$format = static::ROOT_BLOCK_SELECTOR === $selector ? '%s .%s%s' : '%s.%s%s';
$layout_selector = sprintf(
$format,
$selector,
$class_name,
$spacing_rule['selector']
);
}
$block_rules .= static::to_ruleset( $layout_selector, $declarations );
}
}
if ( ! $has_block_gap_support ) {
// For fallback gap styles, use lower specificity, to ensure styles do not unintentionally override theme styles.
$layout_selector_format = static::ROOT_BLOCK_SELECTOR === $selector ? ":where(.$class_name%s)" : ":where($selector.$class_name%s)";
} else {
$layout_selector_format = static::ROOT_BLOCK_SELECTOR === $selector ? "$selector .$class_name%s" : "$selector.$class_name%s";
}

$block_rules .= $this->construct_layout_rules(
$layout_selector_format,
$layout_definition,
'spacingStyles',
$block_gap_value
);
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion phpunit/class-wp-theme-json-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ public function test_get_stylesheet_generates_layout_styles( $layout_definitions

// Results also include root site blocks styles.
$this->assertEquals(
'body { margin: 0;}.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.wp-site-blocks > * { margin-block-start: 0; margin-block-end: 0; }.wp-site-blocks > * + * { margin-block-start: 1em; }body { --wp--style--block-gap: 1em; }body .is-layout-flow > *{margin-block-start: 0;margin-block-end: 0;}body .is-layout-flow > * + *{margin-block-start: 1em;margin-block-end: 0;}body .is-layout-flex{gap: 1em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}.wp-block-group{margin-top: 25px;margin-bottom: 50px;}.is-layout-flow > .wp-block-group{margin-block-start: 0;margin-bottom: 50px;}.is-layout-flow > * + .wp-block-group{margin-top: 25px;margin-bottom: 50px;}.is-layout-flow > *:last-child.wp-block-group{margin-top: 25px;margin-block-end: 0;}.wp-site-blocks > * + .wp-block-group {margin-top:25px;margin-bottom:50px;}',
'body { margin: 0;}.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.wp-site-blocks > * { margin-block-start: 0; margin-block-end: 0; }.wp-site-blocks > * + * { margin-block-start: 1em; }body { --wp--style--block-gap: 1em; }body .is-layout-flow > *{margin-block-start: 0;margin-block-end: 0;}body .is-layout-flow > * + *{margin-block-start: 1em;margin-block-end: 0;}body .is-layout-flex{gap: 1em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}.wp-block-group{margin-top: 25px;margin-bottom: 50px;}.is-layout-flow > .wp-block-group{margin-block-start: 0;margin-bottom: 50px;}.is-layout-flow > * + .wp-block-group{margin-top: 25px;margin-bottom: 50px;}.is-layout-flow > *:last-child.wp-block-group{margin-top: 25px;margin-block-end: 0;}.wp-site-blocks > .wp-block-group{margin-block-start: 0;margin-bottom: 50px;}.wp-site-blocks > * + .wp-block-group{margin-top: 25px;margin-bottom: 50px;}.wp-site-blocks > *:last-child.wp-block-group{margin-top: 25px;margin-block-end: 0;}',
$theme_json->get_stylesheet( array( 'styles' ) )
);
}
Expand Down