style-engine.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  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. * Global public interface method to generate styles from a single style object, e.g.,
  14. * the value of a block's attributes.style object or the top level styles in theme.json.
  15. * See: https://developer.wordpress.org/block-editor/reference-guides/theme-json-reference/theme-json-living/#styles and
  16. * https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/
  17. *
  18. * Example usage:
  19. *
  20. * $styles = wp_style_engine_get_styles( array( 'color' => array( 'text' => '#cccccc' ) ) );
  21. * // Returns `array( 'css' => 'color: #cccccc', 'declarations' => array( 'color' => '#cccccc' ), 'classnames' => 'has-color' )`.
  22. *
  23. * @access public
  24. * @since 6.1.0
  25. *
  26. * @param array $block_styles The style object.
  27. * @param array $options {
  28. * Optional. An array of options. Default empty array.
  29. *
  30. * @type string|null $context An identifier describing the origin of the style object, e.g., 'block-supports' or 'global-styles'. Default is `null`.
  31. * When set, the style engine will attempt to store the CSS rules, where a selector is also passed.
  32. * @type bool $convert_vars_to_classnames Whether to skip converting incoming CSS var patterns, e.g., `var:preset|<PRESET_TYPE>|<PRESET_SLUG>`, to var( --wp--preset--* ) values. Default `false`.
  33. * @type string $selector Optional. When a selector is passed, the value of `$css` in the return value will comprise a full CSS rule `$selector { ...$css_declarations }`,
  34. * otherwise, the value will be a concatenated string of CSS declarations.
  35. * }
  36. *
  37. * @return array {
  38. * @type string $css A CSS ruleset or declarations block formatted to be placed in an HTML `style` attribute or tag.
  39. * @type string[] $declarations An associative array of CSS definitions, e.g., array( "$property" => "$value", "$property" => "$value" ).
  40. * @type string $classnames Classnames separated by a space.
  41. * }
  42. */
  43. function wp_style_engine_get_styles( $block_styles, $options = array() ) {
  44. $options = wp_parse_args(
  45. $options,
  46. array(
  47. 'selector' => null,
  48. 'context' => null,
  49. 'convert_vars_to_classnames' => false,
  50. )
  51. );
  52. $parsed_styles = WP_Style_Engine::parse_block_styles( $block_styles, $options );
  53. // Output.
  54. $styles_output = array();
  55. if ( ! empty( $parsed_styles['declarations'] ) ) {
  56. $styles_output['css'] = WP_Style_Engine::compile_css( $parsed_styles['declarations'], $options['selector'] );
  57. $styles_output['declarations'] = $parsed_styles['declarations'];
  58. if ( ! empty( $options['context'] ) ) {
  59. WP_Style_Engine::store_css_rule( $options['context'], $options['selector'], $parsed_styles['declarations'] );
  60. }
  61. }
  62. if ( ! empty( $parsed_styles['classnames'] ) ) {
  63. $styles_output['classnames'] = implode( ' ', array_unique( $parsed_styles['classnames'] ) );
  64. }
  65. return array_filter( $styles_output );
  66. }
  67. /**
  68. * Returns compiled CSS from a collection of selectors and declarations.
  69. * Useful for returning a compiled stylesheet from any collection of CSS selector + declarations.
  70. *
  71. * Example usage:
  72. * $css_rules = array( array( 'selector' => '.elephant-are-cool', 'declarations' => array( 'color' => 'gray', 'width' => '3em' ) ) );
  73. * $css = wp_style_engine_get_stylesheet_from_css_rules( $css_rules );
  74. * // Returns `.elephant-are-cool{color:gray;width:3em}`.
  75. *
  76. * @since 6.1.0
  77. *
  78. * @param array $css_rules {
  79. * Required. A collection of CSS rules.
  80. *
  81. * @type array ...$0 {
  82. * @type string $selector A CSS selector.
  83. * @type string[] $declarations An associative array of CSS definitions, e.g., array( "$property" => "$value", "$property" => "$value" ).
  84. * }
  85. * }
  86. * @param array $options {
  87. * Optional. An array of options. Default empty array.
  88. *
  89. * @type string|null $context An identifier describing the origin of the style object, e.g., 'block-supports' or 'global-styles'. Default is 'block-supports'.
  90. * When set, the style engine will attempt to store the CSS rules.
  91. * @type bool $optimize Whether to optimize the CSS output, e.g., combine rules. Default is `false`.
  92. * @type bool $prettify Whether to add new lines and indents to output. Default is the test of whether the global constant `SCRIPT_DEBUG` is defined.
  93. * }
  94. *
  95. * @return string A string of compiled CSS declarations, or empty string.
  96. */
  97. function wp_style_engine_get_stylesheet_from_css_rules( $css_rules, $options = array() ) {
  98. if ( empty( $css_rules ) ) {
  99. return '';
  100. }
  101. $options = wp_parse_args(
  102. $options,
  103. array(
  104. 'context' => null,
  105. )
  106. );
  107. $css_rule_objects = array();
  108. foreach ( $css_rules as $css_rule ) {
  109. if ( empty( $css_rule['selector'] ) || empty( $css_rule['declarations'] ) || ! is_array( $css_rule['declarations'] ) ) {
  110. continue;
  111. }
  112. if ( ! empty( $options['context'] ) ) {
  113. WP_Style_Engine::store_css_rule( $options['context'], $css_rule['selector'], $css_rule['declarations'] );
  114. }
  115. $css_rule_objects[] = new WP_Style_Engine_CSS_Rule( $css_rule['selector'], $css_rule['declarations'] );
  116. }
  117. if ( empty( $css_rule_objects ) ) {
  118. return '';
  119. }
  120. return WP_Style_Engine::compile_stylesheet_from_css_rules( $css_rule_objects, $options );
  121. }
  122. /**
  123. * Returns compiled CSS from a store, if found.
  124. *
  125. * @since 6.1.0
  126. *
  127. * @param string $context A valid context name, corresponding to an existing store key.
  128. * @param array $options {
  129. * Optional. An array of options. Default empty array.
  130. *
  131. * @type bool $optimize Whether to optimize the CSS output, e.g., combine rules. Default is `false`.
  132. * @type bool $prettify Whether to add new lines and indents to output. Default is the test of whether the global constant `SCRIPT_DEBUG` is defined.
  133. * }
  134. *
  135. * @return string A compiled CSS string.
  136. */
  137. function wp_style_engine_get_stylesheet_from_context( $context, $options = array() ) {
  138. return WP_Style_Engine::compile_stylesheet_from_css_rules( WP_Style_Engine::get_store( $context )->get_all_rules(), $options );
  139. }