@wordpress/style-engine 0.12.0 → 0.14.1-next.d6164808d3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/README.md +206 -42
  3. package/build/index.js +7 -5
  4. package/build/index.js.map +1 -1
  5. package/build/styles/typography/index.js +7 -1
  6. package/build/styles/typography/index.js.map +1 -1
  7. package/build/styles/utils.js +5 -5
  8. package/build/styles/utils.js.map +1 -1
  9. package/build-module/index.js +6 -4
  10. package/build-module/index.js.map +1 -1
  11. package/build-module/styles/typography/index.js +7 -1
  12. package/build-module/styles/typography/index.js.map +1 -1
  13. package/build-module/styles/utils.js +5 -5
  14. package/build-module/styles/utils.js.map +1 -1
  15. package/build-types/index.d.ts +4 -4
  16. package/build-types/index.d.ts.map +1 -1
  17. package/build-types/styles/color/background.d.ts +1 -1
  18. package/build-types/styles/color/gradient.d.ts +1 -1
  19. package/build-types/styles/color/index.d.ts +1 -1
  20. package/build-types/styles/color/text.d.ts +1 -1
  21. package/build-types/styles/typography/index.d.ts +1 -1
  22. package/build-types/styles/typography/index.d.ts.map +1 -1
  23. package/build-types/styles/utils.d.ts +6 -6
  24. package/build-types/types.d.ts +3 -4
  25. package/build-types/types.d.ts.map +1 -1
  26. package/class-wp-style-engine-css-declarations.php +61 -10
  27. package/class-wp-style-engine-css-rule.php +125 -0
  28. package/class-wp-style-engine-css-rules-store.php +144 -0
  29. package/class-wp-style-engine-processor.php +143 -0
  30. package/class-wp-style-engine.php +265 -144
  31. package/package.json +2 -2
  32. package/phpunit/class-wp-style-engine-css-declarations-test.php +129 -3
  33. package/phpunit/class-wp-style-engine-css-rule-test.php +127 -0
  34. package/phpunit/class-wp-style-engine-css-rules-store-test.php +171 -0
  35. package/phpunit/class-wp-style-engine-processor-test.php +266 -0
  36. package/phpunit/class-wp-style-engine-test.php +223 -22
  37. package/src/index.ts +4 -4
  38. package/src/styles/typography/index.ts +13 -0
  39. package/src/styles/utils.ts +5 -5
  40. package/src/test/index.js +64 -11
  41. package/src/types.ts +3 -4
  42. package/tsconfig.tsbuildinfo +1 -1
@@ -18,18 +18,11 @@ if ( class_exists( 'WP_Style_Engine' ) ) {
18
18
  * CSS styles generation.
19
19
  *
20
20
  * This class is for internal core usage and is not supposed to be used by extenders (plugins and/or themes).
21
- * This is a low-level API that may need to do breaking changes. Please, use gutenberg_style_engine_get_styles instead.
21
+ * This is a low-level API that may need to do breaking changes. Please, use wp_style_engine_get_styles instead.
22
22
  *
23
23
  * @access private
24
24
  */
25
25
  class WP_Style_Engine {
26
- /**
27
- * Container for the main instance of the class.
28
- *
29
- * @var WP_Style_Engine|null
30
- */
31
- private static $instance = null;
32
-
33
26
  /**
34
27
  * Style definitions that contain the instructions to
35
28
  * parse/output valid Gutenberg styles from a block's attributes.
@@ -222,48 +215,33 @@ class WP_Style_Engine {
222
215
  );
223
216
 
224
217
  /**
225
- * Utility method to retrieve the main instance of the class.
226
- *
227
- * The instance will be created if it does not exist yet.
228
- *
229
- * @return WP_Style_Engine The main instance.
230
- */
231
- public static function get_instance() {
232
- if ( null === self::$instance ) {
233
- self::$instance = new self();
234
- }
235
-
236
- return self::$instance;
237
- }
238
-
239
- /**
240
- * Extracts the slug in kebab case from a preset string, e.g., "heavenly-blue" from 'var:preset|color|heavenlyBlue'.
218
+ * Util: Extracts the slug in kebab case from a preset string, e.g., "heavenly-blue" from 'var:preset|color|heavenlyBlue'.
241
219
  *
242
220
  * @param string? $style_value A single css preset value.
243
221
  * @param string $property_key The CSS property that is the second element of the preset string. Used for matching.
244
222
  *
245
- * @return string|null The slug, or null if not found.
223
+ * @return string The slug, or empty string if not found.
246
224
  */
247
225
  protected static function get_slug_from_preset_value( $style_value, $property_key ) {
248
- if ( is_string( $style_value ) && strpos( $style_value, "var:preset|{$property_key}|" ) !== false ) {
226
+ if ( is_string( $style_value ) && str_contains( $style_value, "var:preset|{$property_key}|" ) ) {
249
227
  $index_to_splice = strrpos( $style_value, '|' ) + 1;
250
228
  return _wp_to_kebab_case( substr( $style_value, $index_to_splice ) );
251
229
  }
252
- return null;
230
+ return '';
253
231
  }
254
232
 
255
233
  /**
256
- * Generates a css var string, eg var(--wp--preset--color--background) from a preset string, eg. `var:preset|space|50`.
234
+ * Util: Generates a css var string, eg var(--wp--preset--color--background) from a preset string, eg. `var:preset|space|50`.
257
235
  *
258
236
  * @param string $style_value A single css preset value.
259
237
  * @param array $css_vars The css var patterns used to generate the var string.
260
238
  *
261
- * @return string|null The css var, or null if no match for slug found.
239
+ * @return string The css var, or an empty string if no match for slug found.
262
240
  */
263
241
  protected static function get_css_var_value( $style_value, $css_vars ) {
264
242
  foreach ( $css_vars as $property_key => $css_var_pattern ) {
265
243
  $slug = static::get_slug_from_preset_value( $style_value, $property_key );
266
- if ( $slug ) {
244
+ if ( static::is_valid_style_value( $slug ) ) {
267
245
  $var = strtr(
268
246
  $css_var_pattern,
269
247
  array( '$slug' => $slug )
@@ -271,26 +249,89 @@ class WP_Style_Engine {
271
249
  return "var($var)";
272
250
  }
273
251
  }
274
- return null;
252
+ return '';
275
253
  }
276
254
 
277
255
  /**
278
- * Checks whether an incoming block style value is valid.
256
+ * Util: Checks whether an incoming block style value is valid.
279
257
  *
280
258
  * @param string? $style_value A single css preset value.
281
259
  *
282
260
  * @return boolean
283
261
  */
284
262
  protected static function is_valid_style_value( $style_value ) {
285
- if ( '0' === $style_value ) {
286
- return true;
263
+ return '0' === $style_value || ! empty( $style_value );
264
+ }
265
+
266
+ /**
267
+ * Stores a CSS rule using the provided CSS selector and CSS declarations.
268
+ *
269
+ * @param string $store_name A valid store key.
270
+ * @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.
271
+ * @param array $css_declarations An array of parsed CSS property => CSS value pairs.
272
+ *
273
+ * @return void.
274
+ */
275
+ public static function store_css_rule( $store_name, $css_selector, $css_declarations ) {
276
+ if ( empty( $store_name ) || empty( $css_selector ) || empty( $css_declarations ) ) {
277
+ return;
287
278
  }
279
+ static::get_store( $store_name )->add_rule( $css_selector )->add_declarations( $css_declarations );
280
+ }
288
281
 
289
- if ( empty( $style_value ) ) {
290
- return false;
282
+ /**
283
+ * Returns a store by store key.
284
+ *
285
+ * @param string $store_name A store key.
286
+ *
287
+ * @return WP_Style_Engine_CSS_Rules_Store
288
+ */
289
+ public static function get_store( $store_name ) {
290
+ return WP_Style_Engine_CSS_Rules_Store::get_store( $store_name );
291
+ }
292
+
293
+ /**
294
+ * Returns classnames and CSS based on the values in a styles object.
295
+ * Return values are parsed based on the instructions in BLOCK_STYLE_DEFINITIONS_METADATA.
296
+ *
297
+ * @param array $block_styles The style object.
298
+ * @param array $options array(
299
+ * 'selector' => (string) When a selector is passed, `generate()` will return a full CSS rule `$selector { ...rules }`, otherwise a concatenated string of properties and values.
300
+ * 'convert_vars_to_classnames' => (boolean) Whether to skip converting CSS var:? values to var( --wp--preset--* ) values. Default is `false`.
301
+ * );.
302
+ *
303
+ * @return array array(
304
+ * 'declarations' => (array) An array of parsed CSS property => CSS value pairs.
305
+ * 'classnames' => (array) A flat array of classnames.
306
+ * );
307
+ */
308
+ public static function parse_block_styles( $block_styles, $options ) {
309
+ $parsed_styles = array(
310
+ 'classnames' => array(),
311
+ 'declarations' => array(),
312
+ );
313
+ if ( empty( $block_styles ) || ! is_array( $block_styles ) ) {
314
+ return $parsed_styles;
315
+ }
316
+
317
+ // Collect CSS and classnames.
318
+ foreach ( static::BLOCK_STYLE_DEFINITIONS_METADATA as $definition_group_key => $definition_group_style ) {
319
+ if ( empty( $block_styles[ $definition_group_key ] ) ) {
320
+ continue;
321
+ }
322
+ foreach ( $definition_group_style as $style_definition ) {
323
+ $style_value = _wp_array_get( $block_styles, $style_definition['path'], null );
324
+
325
+ if ( ! static::is_valid_style_value( $style_value ) ) {
326
+ continue;
327
+ }
328
+
329
+ $parsed_styles['classnames'] = array_merge( $parsed_styles['classnames'], static::get_classnames( $style_value, $style_definition ) );
330
+ $parsed_styles['declarations'] = array_merge( $parsed_styles['declarations'], static::get_css_declarations( $style_value, $style_definition, $options ) );
331
+ }
291
332
  }
292
333
 
293
- return true;
334
+ return $parsed_styles;
294
335
  }
295
336
 
296
337
  /**
@@ -302,12 +343,11 @@ class WP_Style_Engine {
302
343
  * @return array An array of CSS classnames.
303
344
  */
304
345
  protected static function get_classnames( $style_value, $style_definition ) {
305
- $classnames = array();
306
-
307
346
  if ( empty( $style_value ) ) {
308
- return $classnames;
347
+ return array();
309
348
  }
310
349
 
350
+ $classnames = array();
311
351
  if ( ! empty( $style_definition['classnames'] ) ) {
312
352
  foreach ( $style_definition['classnames'] as $classname => $property_key ) {
313
353
  if ( true === $property_key ) {
@@ -334,27 +374,27 @@ class WP_Style_Engine {
334
374
  *
335
375
  * @param array $style_value A single raw style value from the generate() $block_styles array.
336
376
  * @param array<string> $style_definition A single style definition from BLOCK_STYLE_DEFINITIONS_METADATA.
337
- * @param boolean $should_skip_css_vars Whether to skip compiling CSS var values.
377
+ * @param array $options array(
378
+ * 'convert_vars_to_classnames' => (boolean) Whether to skip converting CSS var:? values to var( --wp--preset--* ) values. Default is `false`.
379
+ * );.
338
380
  *
339
381
  * @return array An array of CSS definitions, e.g., array( "$property" => "$value" ).
340
382
  */
341
- protected static function get_css_declarations( $style_value, $style_definition, $should_skip_css_vars = false ) {
342
- if (
343
- isset( $style_definition['value_func'] ) &&
344
- is_callable( $style_definition['value_func'] )
345
- ) {
346
- return call_user_func( $style_definition['value_func'], $style_value, $style_definition, $should_skip_css_vars );
383
+ protected static function get_css_declarations( $style_value, $style_definition, $options ) {
384
+ if ( isset( $style_definition['value_func'] ) && is_callable( $style_definition['value_func'] ) ) {
385
+ return call_user_func( $style_definition['value_func'], $style_value, $style_definition, $options );
347
386
  }
348
387
 
349
- $css_declarations = array();
350
- $style_property_keys = $style_definition['property_keys'];
388
+ $css_declarations = array();
389
+ $style_property_keys = $style_definition['property_keys'];
390
+ $should_skip_css_vars = isset( $options['convert_vars_to_classnames'] ) && true === $options['convert_vars_to_classnames'];
351
391
 
352
392
  // Build CSS var values from var:? values, e.g, `var(--wp--css--rule-slug )`
353
393
  // Check if the value is a CSS preset and there's a corresponding css_var pattern in the style definition.
354
- if ( is_string( $style_value ) && strpos( $style_value, 'var:' ) !== false ) {
394
+ if ( is_string( $style_value ) && str_contains( $style_value, 'var:' ) ) {
355
395
  if ( ! $should_skip_css_vars && ! empty( $style_definition['css_vars'] ) ) {
356
396
  $css_var = static::get_css_var_value( $style_value, $style_definition['css_vars'] );
357
- if ( $css_var ) {
397
+ if ( static::is_valid_style_value( $css_var ) ) {
358
398
  $css_declarations[ $style_property_keys['default'] ] = $css_var;
359
399
  }
360
400
  }
@@ -365,87 +405,28 @@ class WP_Style_Engine {
365
405
  // If the input contains an array, assume box model-like properties
366
406
  // for styles such as margins and padding.
367
407
  if ( is_array( $style_value ) ) {
408
+ // Bail out early if the `'individual'` property is not defined.
409
+ if ( ! isset( $style_property_keys['individual'] ) ) {
410
+ return $css_declarations;
411
+ }
412
+
368
413
  foreach ( $style_value as $key => $value ) {
369
- if ( is_string( $value ) && strpos( $value, 'var:' ) !== false && ! $should_skip_css_vars && ! empty( $style_definition['css_vars'] ) ) {
414
+ if ( is_string( $value ) && str_contains( $value, 'var:' ) && ! $should_skip_css_vars && ! empty( $style_definition['css_vars'] ) ) {
370
415
  $value = static::get_css_var_value( $value, $style_definition['css_vars'] );
371
416
  }
372
- $individual_property = sprintf( $style_property_keys['individual'], _wp_to_kebab_case( $key ) );
373
- if ( static::is_valid_style_value( $style_value ) ) {
374
- $css_declarations[ $individual_property ] = $value;
375
- }
376
- }
377
- } else {
378
- $css_declarations[ $style_property_keys['default'] ] = $style_value;
379
- }
380
-
381
- return $css_declarations;
382
- }
383
-
384
- /**
385
- * Returns classnames and CSS based on the values in a block attributes.styles object.
386
- * Return values are parsed based on the instructions in BLOCK_STYLE_DEFINITIONS_METADATA.
387
- *
388
- * @param array $block_styles Styles from a block's attributes object.
389
- * @param array $options array(
390
- * 'selector' => (string) When a selector is passed, `generate()` will return a full CSS rule `$selector { ...rules }`, otherwise a concatenated string of properties and values.
391
- * 'convert_vars_to_classnames' => (boolean) Whether to skip converting CSS var:? values to var( --wp--preset--* ) values. Default is `false`.
392
- * );.
393
- *
394
- * @return array|null array(
395
- * 'css' => (string) A CSS ruleset formatted to be placed in an HTML `style` attribute or tag. Default is a string of inline styles.
396
- * 'classnames' => (string) Classnames separated by a space.
397
- * );
398
- */
399
- public function get_block_supports_styles( $block_styles, $options ) {
400
- if ( empty( $block_styles ) || ! is_array( $block_styles ) ) {
401
- return null;
402
- }
403
417
 
404
- $css_declarations = array();
405
- $classnames = array();
406
- $should_skip_css_vars = isset( $options['convert_vars_to_classnames'] ) && true === $options['convert_vars_to_classnames'];
407
-
408
- // Collect CSS and classnames.
409
- foreach ( static::BLOCK_STYLE_DEFINITIONS_METADATA as $definition_group_key => $definition_group_style ) {
410
- if ( empty( $block_styles[ $definition_group_key ] ) ) {
411
- continue;
412
- }
413
- foreach ( $definition_group_style as $style_definition ) {
414
- $style_value = _wp_array_get( $block_styles, $style_definition['path'], null );
418
+ $individual_property = sprintf( $style_property_keys['individual'], _wp_to_kebab_case( $key ) );
415
419
 
416
- if ( ! static::is_valid_style_value( $style_value ) ) {
417
- continue;
420
+ if ( $individual_property && static::is_valid_style_value( $value ) ) {
421
+ $css_declarations[ $individual_property ] = $value;
418
422
  }
419
-
420
- $classnames = array_merge( $classnames, static::get_classnames( $style_value, $style_definition ) );
421
- $css_declarations = array_merge( $css_declarations, static::get_css_declarations( $style_value, $style_definition, $should_skip_css_vars ) );
422
- }
423
- }
424
-
425
- // Build CSS rules output.
426
- $css_selector = isset( $options['selector'] ) ? $options['selector'] : null;
427
- $style_rules = new WP_Style_Engine_CSS_Declarations( $css_declarations );
428
-
429
- // The return object.
430
- $styles_output = array();
431
- $css = $style_rules->get_declarations_string();
432
-
433
- // Return css, if any.
434
- if ( ! empty( $css ) ) {
435
- $styles_output['css'] = $css;
436
- $styles_output['declarations'] = $style_rules->get_declarations();
437
- // Return an entire rule if there is a selector.
438
- if ( $css_selector ) {
439
- $styles_output['css'] = $css_selector . ' { ' . $css . ' }';
440
423
  }
441
- }
442
424
 
443
- // Return classnames, if any.
444
- if ( ! empty( $classnames ) ) {
445
- $styles_output['classnames'] = implode( ' ', array_unique( $classnames ) );
425
+ return $css_declarations;
446
426
  }
447
427
 
448
- return $styles_output;
428
+ $css_declarations[ $style_property_keys['default'] ] = $style_value;
429
+ return $css_declarations;
449
430
  }
450
431
 
451
432
  /**
@@ -455,17 +436,17 @@ class WP_Style_Engine {
455
436
  * "border-{top|right|bottom|left}-{color|width|style}: {value};" or,
456
437
  * "border-image-{outset|source|width|repeat|slice}: {value};"
457
438
  *
458
- * @param array $style_value A single raw Gutenberg style attributes value for a CSS property.
459
- * @param array $individual_property_definition A single style definition from BLOCK_STYLE_DEFINITIONS_METADATA.
460
- * @param boolean $should_skip_css_vars Whether to skip compiling CSS var values.
439
+ * @param array $style_value A single raw Gutenberg style attributes value for a CSS property.
440
+ * @param array $individual_property_definition A single style definition from BLOCK_STYLE_DEFINITIONS_METADATA.
441
+ * @param array $options array(
442
+ * 'convert_vars_to_classnames' => (boolean) Whether to skip converting CSS var:? values to var( --wp--preset--* ) values. Default is `false`.
443
+ * );.
461
444
  *
462
445
  * @return array An array of CSS definitions, e.g., array( "$property" => "$value" ).
463
446
  */
464
- protected static function get_individual_property_css_declarations( $style_value, $individual_property_definition, $should_skip_css_vars ) {
465
- $css_declarations = array();
466
-
447
+ protected static function get_individual_property_css_declarations( $style_value, $individual_property_definition, $options ) {
467
448
  if ( ! is_array( $style_value ) || empty( $style_value ) || empty( $individual_property_definition['path'] ) ) {
468
- return $css_declarations;
449
+ return array();
469
450
  }
470
451
 
471
452
  // The first item in $individual_property_definition['path'] array tells us the style property, e.g., "border".
@@ -473,6 +454,8 @@ class WP_Style_Engine {
473
454
  // The second item in $individual_property_definition['path'] array refers to the individual property marker, e.g., "top".
474
455
  $definition_group_key = $individual_property_definition['path'][0];
475
456
  $individual_property_key = $individual_property_definition['path'][1];
457
+ $should_skip_css_vars = isset( $options['convert_vars_to_classnames'] ) && true === $options['convert_vars_to_classnames'];
458
+ $css_declarations = array();
476
459
 
477
460
  foreach ( $style_value as $css_property => $value ) {
478
461
  if ( empty( $value ) ) {
@@ -485,7 +468,7 @@ class WP_Style_Engine {
485
468
 
486
469
  if ( $style_definition && isset( $style_definition['property_keys']['individual'] ) ) {
487
470
  // Set a CSS var if there is a valid preset value.
488
- if ( is_string( $value ) && strpos( $value, 'var:' ) !== false && ! $should_skip_css_vars && ! empty( $individual_property_definition['css_vars'] ) ) {
471
+ if ( is_string( $value ) && str_contains( $value, 'var:' ) && ! $should_skip_css_vars && ! empty( $individual_property_definition['css_vars'] ) ) {
489
472
  $value = static::get_css_var_value( $value, $individual_property_definition['css_vars'] );
490
473
  }
491
474
  $individual_css_property = sprintf( $style_definition['property_keys']['individual'], $individual_property_key );
@@ -494,31 +477,169 @@ class WP_Style_Engine {
494
477
  }
495
478
  return $css_declarations;
496
479
  }
480
+
481
+ /**
482
+ * Returns compiled CSS from css_declarations.
483
+ *
484
+ * @param array $css_declarations An array of parsed CSS property => CSS value pairs.
485
+ * @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.
486
+ *
487
+ * @return string A compiled CSS string.
488
+ */
489
+ public static function compile_css( $css_declarations, $css_selector ) {
490
+ if ( empty( $css_declarations ) || ! is_array( $css_declarations ) ) {
491
+ return '';
492
+ }
493
+
494
+ // Return an entire rule if there is a selector.
495
+ if ( $css_selector ) {
496
+ $css_rule = new WP_Style_Engine_CSS_Rule( $css_selector, $css_declarations );
497
+ return $css_rule->get_css();
498
+ }
499
+
500
+ $css_declarations = new WP_Style_Engine_CSS_Declarations( $css_declarations );
501
+ return $css_declarations->get_declarations_string();
502
+ }
503
+
504
+ /**
505
+ * Returns a compiled stylesheet from stored CSS rules.
506
+ *
507
+ * @param WP_Style_Engine_CSS_Rule[] $css_rules An array of WP_Style_Engine_CSS_Rule objects from a store or otherwise.
508
+ *
509
+ * @return string A compiled stylesheet from stored CSS rules.
510
+ */
511
+ public static function compile_stylesheet_from_css_rules( $css_rules ) {
512
+ $processor = new WP_Style_Engine_Processor();
513
+ $processor->add_rules( $css_rules );
514
+ return $processor->get_css();
515
+ }
497
516
  }
498
517
 
499
518
  /**
500
- * Global public interface method to WP_Style_Engine->get_block_supports_styles to generate block styles from a single block style object.
501
- * See: https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/
519
+ * Global public interface method to generate styles from a single style object, e.g.,
520
+ * the value of a block's attributes.style object or the top level styles in theme.json.
521
+ * See: https://developer.wordpress.org/block-editor/reference-guides/theme-json-reference/theme-json-living/#styles and
522
+ * https://developer.wordpress.org/block-editor/reference-guides/block-api/block-supports/
502
523
  *
503
524
  * Example usage:
504
525
  *
505
- * $styles = wp_style_engine_get_block_supports_styles( array( 'color' => array( 'text' => '#cccccc' ) ) );
506
- * // Returns `array( 'css' => 'color: #cccccc', 'classnames' => 'has-color' )`.
526
+ * $styles = wp_style_engine_get_styles( array( 'color' => array( 'text' => '#cccccc' ) ) );
527
+ * // Returns `array( 'css' => 'color: #cccccc', 'declarations' => array( 'color' => '#cccccc' ), 'classnames' => 'has-color' )`.
507
528
  *
508
529
  * @access public
509
530
  *
510
- * @param array $block_styles The value of a block's attributes.style.
511
- * @param array<string> $options An array of options to determine the output.
531
+ * @param array $block_styles The style object.
532
+ * @param array<string|boolean> $options array(
533
+ * 'context' => (string|null) An identifier describing the origin of the style object, e.g., 'block-supports' or 'global-styles'. Default is 'block-supports'.
534
+ * When set, the style engine will attempt to store the CSS rules, where a selector is also passed.
535
+ * 'convert_vars_to_classnames' => (boolean) Whether to skip converting CSS var:? values to var( --wp--preset--* ) values. Default is `false`.
536
+ * 'selector' => (string) When a selector is passed, `generate()` will return a full CSS rule `$selector { ...rules }`, otherwise a concatenated string of properties and values.
537
+ * );.
512
538
  *
513
- * @return array<string>|null array(
514
- * 'styles' => (string) A CSS ruleset formatted to be placed in an HTML `style` attribute or tag.
515
- * 'classnames' => (string) Classnames separated by a space.
539
+ * @return array<string|array> array(
540
+ * 'css' => (string) A CSS ruleset or declarations block formatted to be placed in an HTML `style` attribute or tag.
541
+ * 'declarations' => (array) An array of property/value pairs representing parsed CSS declarations.
542
+ * 'classnames' => (string) Classnames separated by a space.
516
543
  * );
517
544
  */
518
- function wp_style_engine_get_block_supports_styles( $block_styles, $options = array() ) {
519
- if ( class_exists( 'WP_Style_Engine' ) ) {
520
- $style_engine = WP_Style_Engine::get_instance();
521
- return $style_engine->get_block_supports_styles( $block_styles, $options );
545
+ function wp_style_engine_get_styles( $block_styles, $options = array() ) {
546
+ if ( ! class_exists( 'WP_Style_Engine' ) ) {
547
+ return array();
522
548
  }
523
- return null;
549
+
550
+ $options = wp_parse_args(
551
+ $options,
552
+ array(
553
+ 'selector' => null,
554
+ 'context' => null,
555
+ 'convert_vars_to_classnames' => false,
556
+ )
557
+ );
558
+
559
+ $parsed_styles = WP_Style_Engine::parse_block_styles( $block_styles, $options );
560
+
561
+ // Output.
562
+ $styles_output = array();
563
+
564
+ if ( ! empty( $parsed_styles['declarations'] ) ) {
565
+ $styles_output['css'] = WP_Style_Engine::compile_css( $parsed_styles['declarations'], $options['selector'] );
566
+ $styles_output['declarations'] = $parsed_styles['declarations'];
567
+ if ( ! empty( $options['context'] ) ) {
568
+ WP_Style_Engine::store_css_rule( $options['context'], $options['selector'], $parsed_styles['declarations'] );
569
+ }
570
+ }
571
+
572
+ if ( ! empty( $parsed_styles['classnames'] ) ) {
573
+ $styles_output['classnames'] = implode( ' ', array_unique( $parsed_styles['classnames'] ) );
574
+ }
575
+
576
+ return array_filter( $styles_output );
577
+ }
578
+
579
+ /**
580
+ * Returns compiled CSS from a collection of selectors and declarations.
581
+ * This won't add to any store, but is useful for returning a compiled style sheet from any CSS selector + declarations combos.
582
+ *
583
+ * @access public
584
+ *
585
+ * @param array<array> $css_rules array(
586
+ * array(
587
+ * 'selector' => (string) A CSS selector.
588
+ * declarations' => (boolean) An array of CSS definitions, e.g., array( "$property" => "$value" ).
589
+ * )
590
+ * );.
591
+ * @param array<string> $options array(
592
+ * 'context' => (string|null) An identifier describing the origin of the style object, e.g., 'block-supports' or 'global-styles'. Default is 'block-supports'.
593
+ * When set, the style engine will attempt to store the CSS rules.
594
+ * );.
595
+ *
596
+ * @return string A compiled CSS string.
597
+ */
598
+ function wp_style_engine_get_stylesheet_from_css_rules( $css_rules, $options = array() ) {
599
+ if ( ! class_exists( 'WP_Style_Engine' ) || empty( $css_rules ) ) {
600
+ return '';
601
+ }
602
+
603
+ $options = wp_parse_args(
604
+ $options,
605
+ array(
606
+ 'context' => null,
607
+ )
608
+ );
609
+
610
+ $css_rule_objects = array();
611
+ foreach ( $css_rules as $css_rule ) {
612
+ if ( empty( $css_rule['selector'] ) || empty( $css_rule['declarations'] ) || ! is_array( $css_rule['declarations'] ) ) {
613
+ continue;
614
+ }
615
+
616
+ if ( ! empty( $options['context'] ) ) {
617
+ WP_Style_Engine::store_css_rule( $options['context'], $css_rule['selector'], $css_rule['declarations'] );
618
+ }
619
+
620
+ $css_rule_objects[] = new WP_Style_Engine_CSS_Rule( $css_rule['selector'], $css_rule['declarations'] );
621
+ }
622
+
623
+ if ( empty( $css_rule_objects ) ) {
624
+ return '';
625
+ }
626
+
627
+ return WP_Style_Engine::compile_stylesheet_from_css_rules( $css_rule_objects );
628
+ }
629
+
630
+ /**
631
+ * Returns compiled CSS from a store, if found.
632
+ *
633
+ * @access public
634
+ *
635
+ * @param string $store_name A valid store name.
636
+ *
637
+ * @return string A compiled CSS string.
638
+ */
639
+ function wp_style_engine_get_stylesheet_from_store( $store_name ) {
640
+ if ( ! class_exists( 'WP_Style_Engine' ) || empty( $store_name ) ) {
641
+ return '';
642
+ }
643
+
644
+ return WP_Style_Engine::compile_stylesheet_from_css_rules( WP_Style_Engine::get_store( $store_name )->get_all_rules() );
524
645
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/style-engine",
3
- "version": "0.12.0",
3
+ "version": "0.14.1-next.d6164808d3.0",
4
4
  "description": "WordPress Style engine.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -34,5 +34,5 @@
34
34
  "publishConfig": {
35
35
  "access": "public"
36
36
  },
37
- "gitHead": "9d9d33bbdf317a4381b8ca1713e43bb50df653b3"
37
+ "gitHead": "ba8a396d2f418e53a6c4c50575582f3f3eb11ff7"
38
38
  }