Skip to content

Commit

Permalink
Migrate layout styles to style engine store.
Browse files Browse the repository at this point in the history
  • Loading branch information
ramonjd committed Jul 25, 2022
1 parent 313019d commit 7a58ac9
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 98 deletions.
70 changes: 37 additions & 33 deletions lib/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,8 @@ function gutenberg_register_layout_support( $block_type ) {
* @return string CSS style.
*/
function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support = false, $gap_value = null, $should_skip_gap_serialization = false, $fallback_gap_value = '0.5em', $block_spacing = null ) {
$layout_type = isset( $layout['type'] ) ? $layout['type'] : 'default';

$style = '';
$layout_type = isset( $layout['type'] ) ? $layout['type'] : 'default';
$layout_styles = array();
if ( 'default' === $layout_type ) {
$content_size = isset( $layout['contentSize'] ) ? $layout['contentSize'] : '';
$wide_size = isset( $layout['wideSize'] ) ? $layout['wideSize'] : '';
Expand All @@ -55,14 +54,14 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
$wide_max_width_value = wp_strip_all_tags( explode( ';', $wide_max_width_value )[0] );

if ( $content_size || $wide_size ) {
$style = "$selector > :where(:not(.alignleft):not(.alignright):not(.alignfull)) {";
$style .= 'max-width: ' . esc_html( $all_max_width_value ) . ';';
$style .= 'margin-left: auto !important;';
$style .= 'margin-right: auto !important;';
$style .= '}';
$layout_styles[ "$selector > :where(:not(.alignleft):not(.alignright):not(.alignfull))" ] = array(
'max-width' => $all_max_width_value,
'margin-left' => 'auto !important',
'margin-right' => 'auto !important',
);

$style .= "$selector > .alignwide { max-width: " . esc_html( $wide_max_width_value ) . ';}';
$style .= "$selector .alignfull { max-width: none; }";
$layout_styles[ "$selector > .alignwide" ] = array( 'max-width' => $wide_max_width_value );
$layout_styles[ "$selector .alignfull" ] = array( 'max-width' => 'none' );

if ( isset( $block_spacing ) ) {
$block_spacing_values = gutenberg_style_engine_get_block_supports_styles(
Expand All @@ -74,12 +73,12 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
// Handle negative margins for alignfull children of blocks with custom padding set.
// They're added separately because padding might only be set on one side.
if ( isset( $block_spacing_values['declarations']['padding-right'] ) ) {
$padding_right = $block_spacing_values['declarations']['padding-right'];
$style .= "$selector > .alignfull { margin-right:calc($padding_right * -1); }";
$padding_right = $block_spacing_values['declarations']['padding-right'];
$layout_styles[ "$selector > .alignfull" ] = array( 'margin-right' => "calc($padding_right * -1)" );
}
if ( isset( $block_spacing_values['declarations']['padding-left'] ) ) {
$padding_left = $block_spacing_values['declarations']['padding-left'];
$style .= "$selector > .alignfull { margin-left: calc($padding_left * -1); }";
$padding_left = $block_spacing_values['declarations']['padding-left'];
$layout_styles[ "$selector > .alignfull" ] = array( 'margin-left' => "calc($padding_left * -1)" );
}
}
}
Expand All @@ -89,8 +88,16 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
$gap_value = isset( $gap_value['top'] ) ? $gap_value['top'] : null;
}
if ( $gap_value && ! $should_skip_gap_serialization ) {
$style .= "$selector > * { margin-block-start: 0; margin-block-end: 0; }";
$style .= "$selector > * + * { margin-block-start: $gap_value; margin-block-end: 0; }";
$layout_styles[ "$selector > *" ] =
array(
'margin-block-start' => '0',
'margin-block-end' => '0',
);
$layout_styles[ "$selector > * + *" ] =
array(
'margin-block-start' => $gap_value,
'margin-block-end' => '0',
);
}
}
} elseif ( 'flex' === $layout_type ) {
Expand All @@ -113,7 +120,7 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
}

if ( ! empty( $layout['flexWrap'] ) && 'nowrap' === $layout['flexWrap'] ) {
$style .= "$selector { flex-wrap: nowrap; }";
$layout_styles[ $selector ] = array( 'flex-wrap' => 'nowrap' );
}

if ( $has_block_gap_support ) {
Expand All @@ -123,9 +130,7 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
$gap_value = $gap_row === $gap_column ? $gap_row : $gap_row . ' ' . $gap_column;
}
if ( $gap_value && ! $should_skip_gap_serialization ) {
$style .= "$selector {";
$style .= "gap: $gap_value;";
$style .= '}';
$layout_styles[ $selector ] = array( 'gap' => $gap_value );
}
}

Expand All @@ -136,29 +141,29 @@ function gutenberg_get_layout_style( $selector, $layout, $has_block_gap_support
* by custom css.
*/
if ( ! empty( $layout['justifyContent'] ) && array_key_exists( $layout['justifyContent'], $justify_content_options ) ) {
$style .= "$selector {";
$style .= "justify-content: {$justify_content_options[ $layout['justifyContent'] ]};";
$style .= '}';
$layout_styles[ $selector ] = array( 'justify-content' => $justify_content_options[ $layout['justifyContent'] ] );
}

if ( ! empty( $layout['verticalAlignment'] ) && array_key_exists( $layout['verticalAlignment'], $vertical_alignment_options ) ) {
$style .= "$selector {";
$style .= "align-items: {$vertical_alignment_options[ $layout['verticalAlignment'] ]};";
$style .= '}';
$layout_styles[ $selector ] = array( 'align-items' => $vertical_alignment_options[ $layout['verticalAlignment'] ] );
}
} else {
$style .= "$selector {";
$style .= 'flex-direction: column;';
$layout_styles[ $selector ] = array(
'flex-direction' => 'column',
'align-items' => 'flex-start',
);
if ( ! empty( $layout['justifyContent'] ) && array_key_exists( $layout['justifyContent'], $justify_content_options ) ) {
$style .= "align-items: {$justify_content_options[ $layout['justifyContent'] ]};";
$layout_styles[ $selector ] = array( 'align-items' => $justify_content_options[ $layout['justifyContent'] ] );
} else {
$style .= 'align-items: flex-start;';
$layout_styles[ $selector ] = array( 'align-items' => 'flex-start' );
}
$style .= '}';
}
}

return $style;
if ( ! empty( $layout_styles ) ) {
gutenberg_style_engine_add_to_store( 'layout-block-supports', $layout_styles );
return gutenberg_style_engine_get_stylesheet( 'layout-block-supports' );
}
}

/**
Expand Down Expand Up @@ -249,7 +254,6 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
// Only add container class and enqueue block support styles if unique styles were generated.
if ( ! empty( $style ) ) {
$class_names[] = $container_class;
wp_enqueue_block_support_styles( $style );
}

// This assumes the hook only applies to blocks with a single wrapper.
Expand Down
181 changes: 116 additions & 65 deletions packages/style-engine/class-wp-style-engine.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ class WP_Style_Engine {
* @var array<string, WP_Style_Engine_CSS_Rules_Store|null>
*/
private static $stores = array(
'block-supports' => null,
'layout-block-supports' => null,
'block-supports' => null,
);

/**
Expand Down Expand Up @@ -320,16 +321,29 @@ public static function get_instance() {
* @param array $css_declarations An array of parsed CSS property => CSS value pairs.
* @param string $store_key A valid key corresponding to an existing store in static::$stores.
*
* @return string A compiled CSS string.
* @return void.
*/
public function store_css_rule( $css_selector, $css_declarations, $store_key ) {
public static function store_css_rule( $css_selector, $css_declarations, $store_key ) {
if ( ! $css_selector || ! isset( static::$stores[ $store_key ] ) ) {
return false;
return;
}
$css_declarations = new WP_Style_Engine_CSS_Declarations( $css_declarations );
$stored_css_rule = static::$stores[ $store_key ]->add_rule( $css_selector );
$stored_css_rule->add_declarations( $css_declarations );
return true;
}

/**
* Returns a store by store key.
*
* @param string $store_key A valid key corresponding to an existing store in static::$stores.
*
* @return WP_Style_Engine_CSS_Rules_Store|null The store, if found, otherwise `null`.
*/
public static function get_store( $store_key ) {
if ( ! isset( static::$stores[ $store_key ] ) ) {
return null;
}
return static::$stores[ $store_key ];
}

/**
Expand Down Expand Up @@ -368,19 +382,14 @@ protected static function render_styles( $callable, $priority = 10 ) {
* Fetches, processes and compiles stored styles, then renders them to the page.
*/
public static function process_and_enqueue_stored_styles() {
foreach ( static::$stores as $store_key => $store_instance ) {
if ( ! $store_instance ) {
continue;
}

$processor = new WP_Style_Engine_Processor( $store_instance );
$styles_output = $processor->get_css();

if ( ! empty( $styles_output ) ) {
wp_register_style( $store_key, false, array(), true, true );
wp_add_inline_style( $store_key, $styles_output );
wp_enqueue_style( $store_key );
}
// 1. Block supports
// @TODO we could loop through static::$stores to enqueue and get the key.
$styles_output = static::compile_stylesheet_from_store( 'block-supports' ) . static::compile_stylesheet_from_store( 'layout-block-supports' );

if ( ! empty( $styles_output ) ) {
wp_register_style( 'block-supports', false, array(), true, true );
wp_add_inline_style( 'block-supports', $styles_output );
wp_enqueue_style( 'block-supports' );
}
}

Expand Down Expand Up @@ -521,42 +530,6 @@ protected static function get_css_declarations( $style_value, $style_definition,
return $css_declarations;
}

/**
* Returns compiled CSS from parsed css_declarations.
*
* @param array $css_declarations An array of parsed CSS property => CSS value pairs.
* @param string $css_selector When a selector is passed, the function will return a full CSS rule `$selector { ...rules }`, otherwise a concatenated string of properties and values.
*
* @return string A compiled CSS string.
*/
public function compile_css( $css_declarations, $css_selector ) {
if ( empty( $css_declarations ) || ! is_array( $css_declarations ) ) {
return '';
}

// Return an entire rule if there is a selector.
if ( $css_selector ) {
$css_rule = new WP_Style_Engine_CSS_Rule( $css_selector, $css_declarations );
return $css_rule->get_css();
} else {
$css_declarations = new WP_Style_Engine_CSS_Declarations( $css_declarations );
return $css_declarations->get_declarations_string();
}
}
/**
* Returns a string of classnames,
*
* @param string $classnames A flat array of classnames.
*
* @return string A string of classnames separate by a space.
*/
public function compile_classnames( $classnames ) {
if ( empty( $classnames ) || ! is_array( $classnames ) ) {
return null;
}
return implode( ' ', array_unique( $classnames ) );
}

/**
* Style value parser that returns a CSS definition array comprising style properties
* that have keys representing individual style properties, otherwise known as longhand CSS properties.
Expand Down Expand Up @@ -603,6 +576,59 @@ protected static function get_individual_property_css_declarations( $style_value
}
return $css_declarations;
}

/**
* Returns compiled CSS from parsed css_declarations.
*
* @param array $css_declarations An array of parsed CSS property => CSS value pairs.
* @param string $css_selector When a selector is passed, the function will return a full CSS rule `$selector { ...rules }`, otherwise a concatenated string of properties and values.
*
* @return string A compiled CSS string.
*/
public function compile_css( $css_declarations, $css_selector ) {
if ( empty( $css_declarations ) || ! is_array( $css_declarations ) ) {
return '';
}

// Return an entire rule if there is a selector.
if ( $css_selector ) {
$css_rule = new WP_Style_Engine_CSS_Rule( $css_selector, $css_declarations );
return $css_rule->get_css();
} else {
$css_declarations = new WP_Style_Engine_CSS_Declarations( $css_declarations );
return $css_declarations->get_declarations_string();
}
}

/**
* Returns a string of classnames,
*
* @param string $classnames A flat array of classnames.
*
* @return string A string of classnames separate by a space.
*/
public function compile_classnames( $classnames ) {
if ( empty( $classnames ) || ! is_array( $classnames ) ) {
return null;
}
return implode( ' ', array_unique( $classnames ) );
}

/**
* Returns a compiled stylesheet from stored CSS rules.
*
* @param string $store_key A valid key corresponding to an existing store in static::$stores.
*
* @return string A compiled stylesheet from stored CSS rules.
*/
public static function compile_stylesheet_from_store( $store_key ) {
$store = static::get_store( $store_key );
if ( $store ) {
$processor = new WP_Style_Engine_Processor( $store );
return $processor->get_css();
}
return '';
}
}

/**
Expand Down Expand Up @@ -647,7 +673,7 @@ function wp_style_engine_get_block_supports_styles( $block_styles, $options = ar
$styles_output['css'] = $style_engine->compile_css( $parsed_styles['css_declarations'], $options['selector'] );
$styles_output['declarations'] = $parsed_styles['css_declarations'];
if ( true === $options['enqueue'] ) {
$style_engine->store_css_rule( $options['selector'], $parsed_styles['css_declarations'], 'block-supports' );
$style_engine::store_css_rule( $options['selector'], $parsed_styles['css_declarations'], 'block-supports' );
}
}

Expand All @@ -661,22 +687,47 @@ function wp_style_engine_get_block_supports_styles( $block_styles, $options = ar
}

/**
* Global public interface method to parse block styles from a single block style object
* and then, via the `enqueue` flag, will enqueue them for rendering on the frontend in a block-supports inline style tag.
* Global public interface method to register styles to be enqueued and rendered.
*
* @access public
*
* @param string $store_key A valid store key.
* @param array $css_rules array(
* 'selector' => (string) A CSS selector.
* 'css_declarations' => (boolean) An array of CSS definitions, e.g., array( "$property" => "$value" ).
* );.
*
* @return WP_Style_Engine_CSS_Rules_Store|null The store, if found, otherwise `null`.
*/
function wp_style_engine_add_to_store( $store_key, $css_rules = array() ) {
if ( empty( $store_key ) || empty( $css_rules ) ) {
return null;
}
if ( class_exists( 'WP_Style_Engine' ) ) {
$style_engine = WP_Style_Engine::get_instance();
foreach ( $css_rules as $selector => $css_declarations ) {
$style_engine::store_css_rule( $selector, $css_declarations, $store_key );
}
return $style_engine::get_store( $store_key );
}
}

/**
* Returns a compiled stylesheet from stored CSS rules.
*
* @access public
*
* @param string $selector A CSS selector.
* @param array $css_declarations An array of CSS definitions, e.g., array( "$property" => "$value" ).
* @param string $store_key A valid store key.
*
* @return boolean Whether the storage process was successful.
* @return string A compiled stylesheet from stored CSS rules.
*/
function wp_style_engine_enqueue_block_supports_styles( $selector, $css_declarations ) {
if ( empty( $selector ) || empty( $css_declarations ) ) {
return false;
function wp_style_engine_get_stylesheet( $store_key ) {
if ( empty( $store_key ) ) {
return null;
}
if ( class_exists( 'WP_Style_Engine' ) ) {
return WP_Style_Engine::get_instance()->store_css_rule( $selector, $css_declarations, 'block-supports' );
return WP_Style_Engine::get_instance()::compile_stylesheet_from_store( $store_key );
}
return false;
return null;
}

0 comments on commit 7a58ac9

Please sign in to comment.