Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
0840074
Enqueuing block support styles version 1.
ramonjd Jul 15, 2022
6a42821
Linter, this one's for you.
ramonjd Jul 15, 2022
1f2b4a8
Post trunk merge cleanup and update tests.
ramonjd Jul 15, 2022
5a51073
Removed spacing around curly braces in CSS rules. Updated tests.
ramonjd Jul 18, 2022
55576b9
Splitting `wp_style_engine_enqueue_block_supports_styles` and `wp_sty…
ramonjd Jul 19, 2022
acc6209
Integrate the processor class
ramonjd Jul 24, 2022
7a22c5b
Migrate layout styles to style engine store.
ramonjd Jul 25, 2022
7a6aa60
Update packages/style-engine/class-wp-style-engine.php
ramonjd Jul 27, 2022
49b1433
Tweaks for #42452 (#42691)
aristath Jul 27, 2022
d7893a6
Adding check for the context argument.
ramonjd Jul 28, 2022
bc6e39a
Updating the processor so that it's ignorant of stores. Why? So that …
ramonjd Jul 29, 2022
e8a621d
dump var_dump()
ramonjd Jul 29, 2022
9ba5232
Improve the processor
aristath Jul 29, 2022
b41af7d
remove trailing commas - compatibility with PHP < 7.2
aristath Jul 29, 2022
4ccf650
rename css_declarations to declarations
aristath Jul 29, 2022
e30e4fb
remove unused variable
aristath Jul 29, 2022
062b920
Switch parse_block_styles from public to protected static
ramonjd Aug 1, 2022
5e4164a
Now that all methods are static, there's no need to call `get_instanc…
ramonjd Aug 1, 2022
fcebf93
Revert get_instance() in wp_style_engine_add_to_store because we want…
ramonjd Aug 1, 2022
d0d5fe5
Adding a test for the 'enqueue' flag.
ramonjd Aug 1, 2022
e59eb10
Update lib/block-supports/layout.php
ramonjd Aug 1, 2022
5d7b827
Adding a test for the 'enqueue' flag.
ramonjd Aug 1, 2022
4d9f6c8
Merge branch 'try/style-engine-enqueue-block-supports-styles' of gith…
ramonjd Aug 1, 2022
8d021ee
Add named stores to the processor
aristath Aug 1, 2022
5f60026
avoid setting var for something that only gets used once
aristath Aug 1, 2022
a63f9cb
Only use "else" if absolutely necessary
aristath Aug 1, 2022
0eaef08
Add a set_name method
aristath Aug 1, 2022
e4c791b
combine & simplify conditions
aristath Aug 1, 2022
787f793
use empty() instead of isset() checks here
aristath Aug 1, 2022
7dd5773
shorten it
aristath Aug 1, 2022
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
Migrate layout styles to style engine store.
  • Loading branch information
ramonjd authored and aristath committed Jul 29, 2022
commit 7a22c5bb93421d7d8e902c9d1be6bedd4a5fca2d
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_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 @@ -253,7 +258,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 );
}
}

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() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The enqueue and WP hook logic could well live in Gutenberg itself, e.g., script-loader.php with the style engine only taking care of parse + store + compile

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 @@ -522,42 +531,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 @@ -604,6 +577,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 @@ -650,7 +676,7 @@ function wp_style_engine_get_styles( $block_styles, $options = array() ) {
$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 @@ -664,22 +690,47 @@ function wp_style_engine_get_styles( $block_styles, $options = array() ) {
}

/**
* 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;
}