wp/wp-includes/style-engine.php
changeset 21 48c4eec2b7e6
equal deleted inserted replaced
20:7b1b88e27a20 21:48c4eec2b7e6
       
     1 <?php
       
     2 /**
       
     3  * Style engine: Public functions
       
     4  *
       
     5  * This file contains a variety of public functions developers can use to interact with
       
     6  * the Style Engine API.
       
     7  *
       
     8  * @package WordPress
       
     9  * @subpackage StyleEngine
       
    10  * @since 6.1.0
       
    11  */
       
    12 
       
    13 /**
       
    14  * Global public interface method to generate styles from a single style object,
       
    15  * e.g. the value of a block's attributes.style object or the top level styles in theme.json.
       
    16  *
       
    17  * Example usage:
       
    18  *
       
    19  *     $styles = wp_style_engine_get_styles(
       
    20  *         array(
       
    21  *             'color' => array( 'text' => '#cccccc' ),
       
    22  *         )
       
    23  *     );
       
    24  *
       
    25  * Returns:
       
    26  *
       
    27  *     array(
       
    28  *         'css'          => 'color: #cccccc',
       
    29  *         'declarations' => array( 'color' => '#cccccc' ),
       
    30  *         'classnames'   => 'has-color',
       
    31  *     )
       
    32  *
       
    33  * @since 6.1.0
       
    34  *
       
    35  * @see https://developer.wordpress.org/block-editor/reference-guides/theme-json-reference/theme-json-living/#styles
       
    36  * @see https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/
       
    37  *
       
    38  * @param array $block_styles The style object.
       
    39  * @param array $options {
       
    40  *     Optional. An array of options. Default empty array.
       
    41  *
       
    42  *     @type string|null $context                    An identifier describing the origin of the style object,
       
    43  *                                                   e.g. 'block-supports' or 'global-styles'. Default null.
       
    44  *                                                   When set, the style engine will attempt to store the CSS rules,
       
    45  *                                                   where a selector is also passed.
       
    46  *     @type bool        $convert_vars_to_classnames Whether to skip converting incoming CSS var patterns,
       
    47  *                                                   e.g. `var:preset|<PRESET_TYPE>|<PRESET_SLUG>`,
       
    48  *                                                   to `var( --wp--preset--* )` values. Default false.
       
    49  *     @type string      $selector                   Optional. When a selector is passed,
       
    50  *                                                   the value of `$css` in the return value will comprise
       
    51  *                                                   a full CSS rule `$selector { ...$css_declarations }`,
       
    52  *                                                   otherwise, the value will be a concatenated string
       
    53  *                                                   of CSS declarations.
       
    54  * }
       
    55  * @return array {
       
    56  *     @type string   $css          A CSS ruleset or declarations block
       
    57  *                                  formatted to be placed in an HTML `style` attribute or tag.
       
    58  *     @type string[] $declarations An associative array of CSS definitions,
       
    59  *                                  e.g. `array( "$property" => "$value", "$property" => "$value" )`.
       
    60  *     @type string   $classnames   Classnames separated by a space.
       
    61  * }
       
    62  */
       
    63 function wp_style_engine_get_styles( $block_styles, $options = array() ) {
       
    64 	$options = wp_parse_args(
       
    65 		$options,
       
    66 		array(
       
    67 			'selector'                   => null,
       
    68 			'context'                    => null,
       
    69 			'convert_vars_to_classnames' => false,
       
    70 		)
       
    71 	);
       
    72 
       
    73 	$parsed_styles = WP_Style_Engine::parse_block_styles( $block_styles, $options );
       
    74 
       
    75 	// Output.
       
    76 	$styles_output = array();
       
    77 
       
    78 	if ( ! empty( $parsed_styles['declarations'] ) ) {
       
    79 		$styles_output['css']          = WP_Style_Engine::compile_css( $parsed_styles['declarations'], $options['selector'] );
       
    80 		$styles_output['declarations'] = $parsed_styles['declarations'];
       
    81 		if ( ! empty( $options['context'] ) ) {
       
    82 			WP_Style_Engine::store_css_rule( $options['context'], $options['selector'], $parsed_styles['declarations'] );
       
    83 		}
       
    84 	}
       
    85 
       
    86 	if ( ! empty( $parsed_styles['classnames'] ) ) {
       
    87 		$styles_output['classnames'] = implode( ' ', array_unique( $parsed_styles['classnames'] ) );
       
    88 	}
       
    89 
       
    90 	return array_filter( $styles_output );
       
    91 }
       
    92 
       
    93 /**
       
    94  * Returns compiled CSS from a collection of selectors and declarations.
       
    95  * Useful for returning a compiled stylesheet from any collection of CSS selector + declarations.
       
    96  *
       
    97  * Example usage:
       
    98  *
       
    99  *     $css_rules = array(
       
   100  *         array(
       
   101  *             'selector'     => '.elephant-are-cool',
       
   102  *             'declarations' => array(
       
   103  *                 'color' => 'gray',
       
   104  *                 'width' => '3em',
       
   105  *             ),
       
   106  *         ),
       
   107  *     );
       
   108  *
       
   109  *     $css = wp_style_engine_get_stylesheet_from_css_rules( $css_rules );
       
   110  *
       
   111  * Returns:
       
   112  *
       
   113  *     .elephant-are-cool{color:gray;width:3em}
       
   114  *
       
   115  * @since 6.1.0
       
   116  * @since 6.6.0 Added support for `$rules_group` in the `$css_rules` array.
       
   117  *
       
   118  * @param array $css_rules {
       
   119  *     Required. A collection of CSS rules.
       
   120  *
       
   121  *     @type array ...$0 {
       
   122  *         @type string   $rules_group  A parent CSS selector in the case of nested CSS,
       
   123  *                                      or a CSS nested @rule, such as `@media (min-width: 80rem)` or `@layer module`.
       
   124  *         @type string   $selector     A CSS selector.
       
   125  *         @type string[] $declarations An associative array of CSS definitions,
       
   126  *                                      e.g. `array( "$property" => "$value", "$property" => "$value" )`.
       
   127  *     }
       
   128  * }
       
   129  * @param array $options {
       
   130  *     Optional. An array of options. Default empty array.
       
   131  *
       
   132  *     @type string|null $context  An identifier describing the origin of the style object,
       
   133  *                                 e.g. 'block-supports' or 'global-styles'. Default 'block-supports'.
       
   134  *                                 When set, the style engine will attempt to store the CSS rules.
       
   135  *     @type bool        $optimize Whether to optimize the CSS output, e.g. combine rules.
       
   136  *                                 Default false.
       
   137  *     @type bool        $prettify Whether to add new lines and indents to output.
       
   138  *                                 Defaults to whether the `SCRIPT_DEBUG` constant is defined.
       
   139  * }
       
   140  * @return string A string of compiled CSS declarations, or empty string.
       
   141  */
       
   142 function wp_style_engine_get_stylesheet_from_css_rules( $css_rules, $options = array() ) {
       
   143 	if ( empty( $css_rules ) ) {
       
   144 		return '';
       
   145 	}
       
   146 
       
   147 	$options = wp_parse_args(
       
   148 		$options,
       
   149 		array(
       
   150 			'context' => null,
       
   151 		)
       
   152 	);
       
   153 
       
   154 	$css_rule_objects = array();
       
   155 	foreach ( $css_rules as $css_rule ) {
       
   156 		if ( empty( $css_rule['selector'] ) || empty( $css_rule['declarations'] ) || ! is_array( $css_rule['declarations'] ) ) {
       
   157 			continue;
       
   158 		}
       
   159 
       
   160 		$rules_group = $css_rule['rules_group'] ?? null;
       
   161 		if ( ! empty( $options['context'] ) ) {
       
   162 			WP_Style_Engine::store_css_rule( $options['context'], $css_rule['selector'], $css_rule['declarations'], $rules_group );
       
   163 		}
       
   164 
       
   165 		$css_rule_objects[] = new WP_Style_Engine_CSS_Rule( $css_rule['selector'], $css_rule['declarations'], $rules_group );
       
   166 	}
       
   167 
       
   168 	if ( empty( $css_rule_objects ) ) {
       
   169 		return '';
       
   170 	}
       
   171 
       
   172 	return WP_Style_Engine::compile_stylesheet_from_css_rules( $css_rule_objects, $options );
       
   173 }
       
   174 
       
   175 /**
       
   176  * Returns compiled CSS from a store, if found.
       
   177  *
       
   178  * @since 6.1.0
       
   179  *
       
   180  * @param string $context A valid context name, corresponding to an existing store key.
       
   181  * @param array  $options {
       
   182  *     Optional. An array of options. Default empty array.
       
   183  *
       
   184  *     @type bool $optimize Whether to optimize the CSS output, e.g. combine rules.
       
   185  *                          Default false.
       
   186  *     @type bool $prettify Whether to add new lines and indents to output.
       
   187  *                          Defaults to whether the `SCRIPT_DEBUG` constant is defined.
       
   188  * }
       
   189  * @return string A compiled CSS string.
       
   190  */
       
   191 function wp_style_engine_get_stylesheet_from_context( $context, $options = array() ) {
       
   192 	return WP_Style_Engine::compile_stylesheet_from_css_rules( WP_Style_Engine::get_store( $context )->get_all_rules(), $options );
       
   193 }