@@ -842,6 +842,7 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n
842
842
foreach ( $ valid_block_names as $ block ) {
843
843
// Build the schema for each block style variation.
844
844
$ style_variation_names = array ();
845
+
845
846
if (
846
847
! empty ( $ input ['styles ' ]['blocks ' ][ $ block ]['variations ' ] ) &&
847
848
is_array ( $ input ['styles ' ]['blocks ' ][ $ block ]['variations ' ] ) &&
@@ -853,9 +854,14 @@ protected static function sanitize( $input, $valid_block_names, $valid_element_n
853
854
);
854
855
}
855
856
857
+ $ schema_styles_variations = array ();
858
+ $ block_style_variation_styles = static ::VALID_STYLES ;
859
+ $ block_style_variation_styles ['blocks ' ] = null ;
860
+ $ block_style_variation_styles ['elements ' ] = null ;
861
+
856
862
$ schema_styles_variations = array ();
857
863
if ( ! empty ( $ style_variation_names ) ) {
858
- $ schema_styles_variations = array_fill_keys ( $ style_variation_names , $ styles_non_top_level );
864
+ $ schema_styles_variations = array_fill_keys ( $ style_variation_names , $ block_style_variation_styles );
859
865
}
860
866
861
867
$ schema_settings_blocks [ $ block ] = static ::VALID_SETTINGS ;
@@ -978,12 +984,34 @@ protected static function prepend_to_selector( $selector, $to_prepend ) {
978
984
*/
979
985
protected static function get_blocks_metadata () {
980
986
// NOTE: the compat/6.1 version of this method in Gutenberg did not have these changes.
981
- $ registry = WP_Block_Type_Registry::get_instance ();
982
- $ blocks = $ registry ->get_all_registered ();
987
+ $ registry = WP_Block_Type_Registry::get_instance ();
988
+ $ blocks = $ registry ->get_all_registered ();
989
+ $ style_registry = WP_Block_Styles_Registry::get_instance ();
983
990
984
991
// Is there metadata for all currently registered blocks?
985
992
$ blocks = array_diff_key ( $ blocks , static ::$ blocks_metadata );
993
+
986
994
if ( empty ( $ blocks ) ) {
995
+ // New block styles may have been registered within WP_Block_Styles_Registry.
996
+ // Update block metadata for any new block style variations.
997
+ $ registered_styles = $ style_registry ->get_all_registered ();
998
+ foreach ( static ::$ blocks_metadata as $ block_name => $ block_metadata ) {
999
+ if ( ! empty ( $ registered_styles [ $ block_name ] ) ) {
1000
+ $ style_selectors = $ block_metadata ['styleVariations ' ] ?? array ();
1001
+
1002
+ foreach ( $ registered_styles [ $ block_name ] as $ block_style ) {
1003
+ if ( ! isset ( $ style_selectors [ $ block_style ['name ' ] ] ) ) {
1004
+ $ style_selectors [ $ block_style ['name ' ] ] = static ::append_to_selector (
1005
+ '.is-style- ' . $ block_style ['name ' ] . '.is-style- ' . $ block_style ['name ' ],
1006
+ $ block_metadata ['selector ' ]
1007
+ );
1008
+ }
1009
+ }
1010
+
1011
+ static ::$ blocks_metadata [ $ block_name ]['styleVariations ' ] = $ style_selectors ;
1012
+ }
1013
+ }
1014
+
987
1015
return static ::$ blocks_metadata ;
988
1016
}
989
1017
@@ -1007,7 +1035,7 @@ protected static function get_blocks_metadata() {
1007
1035
1008
1036
if ( $ duotone_support ) {
1009
1037
$ root_selector = wp_get_block_css_selector ( $ block_type );
1010
- $ duotone_selector = WP_Theme_JSON_Gutenberg ::scope_selector ( $ root_selector , $ duotone_support );
1038
+ $ duotone_selector = static ::scope_selector ( $ root_selector , $ duotone_support );
1011
1039
}
1012
1040
}
1013
1041
@@ -1016,12 +1044,21 @@ protected static function get_blocks_metadata() {
1016
1044
}
1017
1045
1018
1046
// If the block has style variations, append their selectors to the block metadata.
1047
+ $ style_selectors = array ();
1019
1048
if ( ! empty ( $ block_type ->styles ) ) {
1020
- $ style_selectors = array ();
1021
1049
foreach ( $ block_type ->styles as $ style ) {
1022
1050
// The style variation classname is duplicated in the selector to ensure that it overrides core block styles.
1023
1051
$ style_selectors [ $ style ['name ' ] ] = static ::append_to_selector ( '.is-style- ' . $ style ['name ' ] . '.is-style- ' . $ style ['name ' ], static ::$ blocks_metadata [ $ block_name ]['selector ' ] );
1024
1052
}
1053
+ }
1054
+
1055
+ // Block style variations can be registered through the WP_Block_Styles_Registry as well as block.json.
1056
+ $ registered_styles = $ style_registry ->get_registered_styles_for_block ( $ block_name );
1057
+ foreach ( $ registered_styles as $ style ) {
1058
+ $ style_selectors [ $ style ['name ' ] ] = static ::append_to_selector ( '.is-style- ' . $ style ['name ' ] . '.is-style- ' . $ style ['name ' ], static ::$ blocks_metadata [ $ block_name ]['selector ' ] );
1059
+ }
1060
+
1061
+ if ( ! empty ( $ style_selectors ) ) {
1025
1062
static ::$ blocks_metadata [ $ block_name ]['styleVariations ' ] = $ style_selectors ;
1026
1063
}
1027
1064
}
@@ -1194,7 +1231,8 @@ public function get_stylesheet( $types = array( 'variables', 'styles', 'presets'
1194
1231
}
1195
1232
1196
1233
if ( in_array ( 'styles ' , $ types , true ) ) {
1197
- if ( false !== $ root_style_key ) {
1234
+ $ skip_root_layout_styles = $ options ['skip_root_layout_styles ' ] ?? false ;
1235
+ if ( false !== $ root_style_key && ! $ skip_root_layout_styles ) {
1198
1236
$ stylesheet .= $ this ->get_root_layout_rules ( $ style_nodes [ $ root_style_key ]['selector ' ], $ style_nodes [ $ root_style_key ] );
1199
1237
}
1200
1238
$ stylesheet .= $ this ->get_block_classes ( $ style_nodes );
@@ -1747,6 +1785,10 @@ protected static function compute_preset_classes( $settings, $selector, $origins
1747
1785
* @return string Scoped selector.
1748
1786
*/
1749
1787
public static function scope_selector ( $ scope , $ selector ) {
1788
+ if ( ! $ selector || ! $ scope ) {
1789
+ return $ selector ;
1790
+ }
1791
+
1750
1792
$ scopes = explode ( ', ' , $ scope );
1751
1793
$ selectors = explode ( ', ' , $ selector );
1752
1794
@@ -2379,38 +2421,85 @@ private static function get_block_nodes( $theme_json, $selectors = array() ) {
2379
2421
}
2380
2422
2381
2423
foreach ( $ theme_json ['styles ' ]['blocks ' ] as $ name => $ node ) {
2382
- $ selector = null ;
2383
- if ( isset ( $ selectors [ $ name ]['selector ' ] ) ) {
2384
- $ selector = $ selectors [ $ name ]['selector ' ];
2385
- }
2424
+ $ selector = $ selectors [ $ name ]['selector ' ] ?? null ;
2425
+ $ duotone_selector = $ selectors [ $ name ]['duotone ' ] ?? null ;
2426
+ $ feature_selectors = $ selectors [ $ name ]['selectors ' ] ?? null ;
2427
+ $ variations = $ node ['variations ' ] ?? array ();
2428
+ $ variation_selectors = array ();
2429
+ $ variation_nodes = array ();
2430
+
2431
+ // TODO: Should we be supporting recursive variations and block type styles?
2432
+ foreach ( $ variations as $ variation => $ variation_node ) {
2433
+ $ variation_selector = $ selectors [ $ name ]['styleVariations ' ][ $ variation ];
2434
+ $ variation_selectors [] = array (
2435
+ 'path ' => array ( 'styles ' , 'blocks ' , $ name , 'variations ' , $ variation ),
2436
+ 'selector ' => $ variation_selector ,
2437
+ );
2386
2438
2387
- $ duotone_selector = null ;
2388
- if ( isset ( $ selectors [ $ name ]['duotone ' ] ) ) {
2389
- $ duotone_selector = $ selectors [ $ name ]['duotone ' ];
2390
- }
2439
+ $ variation_blocks = $ variation_node ['blocks ' ] ?? array ();
2440
+ $ variation_elements = $ variation_node ['elements ' ] ?? array ();
2391
2441
2392
- $ feature_selectors = null ;
2393
- if ( isset ( $ selectors [ $ name ]['selectors ' ] ) ) {
2394
- $ feature_selectors = $ selectors [ $ name ]['selectors ' ] ;
2395
- }
2442
+ foreach ( $ variation_blocks as $ variation_block => $ variation_block_node ) {
2443
+ $ variation_block_selector = static :: scope_selector ( $ variation_selector , $ selectors [ $ variation_block ]['selector ' ] ?? null );
2444
+ $ variation_duotone_selector = static :: scope_selector ( $ variation_selector , $ selectors [ $ variation_block ]['duotone ' ] ?? null ) ;
2445
+ $ variation_feature_selectors = $ selectors [ $ variation_block ][ ' selectors ' ] ?? null ;
2396
2446
2397
- $ variation_selectors = array ();
2398
- if ( isset ( $ node ['variations ' ] ) ) {
2399
- foreach ( $ node ['variations ' ] as $ variation => $ node ) {
2400
- $ variation_selectors [] = array (
2401
- 'path ' => array ( 'styles ' , 'blocks ' , $ name , 'variations ' , $ variation ),
2402
- 'selector ' => $ selectors [ $ name ]['styleVariations ' ][ $ variation ],
2447
+ if ( $ variation_feature_selectors ) {
2448
+ foreach ( $ variation_feature_selectors as $ feature => $ feature_selector ) {
2449
+ if ( is_string ( $ feature_selector ) ) {
2450
+ $ variation_feature_selectors [ $ feature ] = static ::scope_selector ( $ variation_selector , $ feature_selector );
2451
+ }
2452
+
2453
+ if ( is_array ( $ feature_selector ) ) {
2454
+ foreach ( $ feature_selector as $ subfeature => $ subfeature_selector ) {
2455
+ $ variation_feature_selectors [ $ feature ][ $ subfeature ] = static ::scope_selector ( $ variation_selector , $ subfeature_selector );
2456
+ }
2457
+ }
2458
+ }
2459
+ }
2460
+
2461
+ $ variation_nodes [] = array (
2462
+ 'name ' => $ variation_block ,
2463
+ 'path ' => array ( 'styles ' , 'blocks ' , $ name , 'variations ' , $ variation , 'blocks ' , $ variation_block ),
2464
+ 'selector ' => $ variation_block_selector ,
2465
+ 'selectors ' => $ variation_feature_selectors ,
2466
+ 'duotone ' => $ variation_duotone_selector ,
2403
2467
);
2404
2468
}
2469
+
2470
+ foreach ( $ variation_elements as $ variation_element => $ variation_element_node ) {
2471
+ // TODO: See if there is a way to clean up the generation of element selectors.
2472
+ // The following code varies from standard block element selectors only to avoid
2473
+ // that the $selectors[ $name ]['elements'][ $variation_element ] value would
2474
+ // nest the block's root selector.
2475
+ $ nodes [] = array (
2476
+ 'path ' => array ( 'styles ' , 'blocks ' , $ name , 'variations ' , $ variation , 'elements ' , $ variation_element ),
2477
+ 'selector ' => static ::scope_selector ( $ variation_selector , static ::ELEMENTS [ $ variation_element ] ),
2478
+ );
2479
+
2480
+ // Handle any pseudo selectors for the element.
2481
+ if ( isset ( static ::VALID_ELEMENT_PSEUDO_SELECTORS [ $ variation_element ] ) ) {
2482
+ foreach ( static ::VALID_ELEMENT_PSEUDO_SELECTORS [ $ variation_element ] as $ pseudo_selector ) {
2483
+ if ( isset ( $ variation_element_node [ $ pseudo_selector ] ) ) {
2484
+ $ pseudo_element_selector = static ::append_to_selector ( static ::ELEMENTS [ $ variation_element ], $ pseudo_selector );
2485
+ $ nodes [] = array (
2486
+ 'path ' => array ( 'styles ' , 'blocks ' , $ name , 'variations ' , $ variation , 'elements ' , $ variation_element ),
2487
+ 'selector ' => static ::scope_selector ( $ variation_selector , $ pseudo_element_selector ),
2488
+ );
2489
+ }
2490
+ }
2491
+ }
2492
+ }
2405
2493
}
2406
2494
2407
2495
$ nodes [] = array (
2408
- 'name ' => $ name ,
2409
- 'path ' => array ( 'styles ' , 'blocks ' , $ name ),
2410
- 'selector ' => $ selector ,
2411
- 'selectors ' => $ feature_selectors ,
2412
- 'duotone ' => $ duotone_selector ,
2413
- 'variations ' => $ variation_selectors ,
2496
+ 'name ' => $ name ,
2497
+ 'path ' => array ( 'styles ' , 'blocks ' , $ name ),
2498
+ 'selector ' => $ selector ,
2499
+ 'selectors ' => $ feature_selectors ,
2500
+ 'duotone ' => $ duotone_selector ,
2501
+ 'variations ' => $ variation_selectors ,
2502
+ 'variation_nodes ' => $ variation_nodes ,
2414
2503
);
2415
2504
2416
2505
if ( isset ( $ theme_json ['styles ' ]['blocks ' ][ $ name ]['elements ' ] ) ) {
@@ -2489,6 +2578,28 @@ static function ( $split_selector ) use ( $clean_style_variation_selector ) {
2489
2578
}
2490
2579
}
2491
2580
2581
+ $ style_variation_block_declarations = array ();
2582
+ if ( ! empty ( $ block_metadata ['variation_nodes ' ] ) ) {
2583
+ foreach ( $ block_metadata ['variation_nodes ' ] as $ variation_node ) {
2584
+ $ style_variation_block_node = _wp_array_get ( $ this ->theme_json , $ variation_node ['path ' ], array () );
2585
+ $ variation_block_declarations = static ::get_feature_declarations_for_node ( $ variation_node , $ style_variation_block_node );
2586
+
2587
+ foreach ( $ variation_block_declarations as $ current_selector => $ new_declarations ) {
2588
+ $ style_variation_block_declarations [ $ current_selector ] = $ new_declarations ;
2589
+ }
2590
+
2591
+ // Note that `get_feature_declarations_for_node` will also unset
2592
+ // feature values so they aren't duplicated in declarations via
2593
+ // the call below.
2594
+ $ style_variation_block_declarations [ $ variation_node ['selector ' ] ] = static ::compute_style_properties (
2595
+ $ style_variation_block_node ,
2596
+ $ settings ,
2597
+ null ,
2598
+ $ this ->theme_json
2599
+ );
2600
+ }
2601
+ }
2602
+
2492
2603
/*
2493
2604
* Get a reference to element name from path.
2494
2605
* $block_metadata['path'] = array( 'styles','elements','link' );
@@ -2590,6 +2701,11 @@ static function ( $pseudo_selector ) use ( $selector ) {
2590
2701
$ block_rules .= static ::to_ruleset ( $ style_variation_selector , $ individual_style_variation_declarations );
2591
2702
}
2592
2703
2704
+ // 7. Generate and append the block style variations for inner blocks and elements.
2705
+ foreach ( $ style_variation_block_declarations as $ style_variation_block_selector => $ indvidial_style_variation_block_declaration ) {
2706
+ $ block_rules .= static ::to_ruleset ( $ style_variation_block_selector , $ indvidial_style_variation_block_declaration );
2707
+ }
2708
+
2593
2709
return $ block_rules ;
2594
2710
}
2595
2711
@@ -3228,6 +3344,35 @@ public function get_raw_data() {
3228
3344
return $ this ->theme_json ;
3229
3345
}
3230
3346
3347
+ /**
3348
+ * Converts block styles registered through the `WP_Block_Styles_Registry`
3349
+ * with a style object, into theme.json format.
3350
+ *
3351
+ * @since 6.5.0
3352
+ *
3353
+ * @return array Styles configuration adhering to the theme.json schema.
3354
+ */
3355
+ public static function get_from_block_styles_registry () {
3356
+ $ variations_data = array ();
3357
+ $ registry = WP_Block_Styles_Registry::get_instance ();
3358
+ $ styles = $ registry ->get_all_registered ();
3359
+
3360
+ foreach ( $ styles as $ block_name => $ variations ) {
3361
+ foreach ( $ variations as $ variation_name => $ variation ) {
3362
+ if ( ! empty ( $ variation ['style_data ' ] ) ) {
3363
+ $ variations_data [ $ block_name ]['variations ' ][ $ variation_name ] = $ variation ['style_data ' ];
3364
+ }
3365
+ }
3366
+ }
3367
+
3368
+ return array (
3369
+ 'version ' => static ::LATEST_SCHEMA ,
3370
+ 'styles ' => array (
3371
+ 'blocks ' => $ variations_data ,
3372
+ ),
3373
+ );
3374
+ }
3375
+
3231
3376
/**
3232
3377
* Transforms the given editor settings according the
3233
3378
* add_theme_support format to the theme.json format.
0 commit comments