Changeset 62444 for trunk/src/wp-includes/class-wp-theme-json.php
- Timestamp:
- 06/02/2026 06:03:58 AM (3 days ago)
- File:
-
- 1 edited
-
trunk/src/wp-includes/class-wp-theme-json.php (modified) (23 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/class-wp-theme-json.php
r62415 r62444 646 646 647 647 /** 648 * Responsive breakpoint state keys and their corresponding CSS media queries. 649 * These are available for all blocks and wrap their styles in the given media query. 650 * Keep in sync with RESPONSIVE_BREAKPOINTS in packages/global-styles-engine/src/core/render.tsx. 651 * 652 * @since 7.1.0 653 * @var array 654 */ 655 const RESPONSIVE_BREAKPOINTS = array( 656 'mobile' => '@media (width <= 480px)', 657 'tablet' => '@media (480px < width <= 782px)', 658 ); 659 660 /** 648 661 * The valid elements that can be found under styles. 649 662 * … … 1055 1068 1056 1069 /* 1057 * Set allowed element pseudo selectors based on per element allow list.1070 * Set allowed element pseudo selectors and responsive breakpoint states. 1058 1071 * Target data structure in schema: 1059 1072 * e.g. 1060 1073 * - top level elements: `$schema['styles']['elements']['link'][':hover']`. 1061 1074 * - block level elements: `$schema['styles']['blocks']['core/button']['elements']['link'][':hover']`. 1075 * - block responsive elements: `$schema['styles']['blocks']['core/button']['tablet']['elements']['link'][':hover']`. 1062 1076 */ 1063 1077 foreach ( $valid_element_names as $element ) { … … 1069 1083 } 1070 1084 } 1085 1086 // Add responsive breakpoint states for elements. 1087 foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint_state ) { 1088 $schema_styles_elements[ $element ][ $breakpoint_state ] = $styles_non_top_level; 1089 } 1071 1090 } 1072 1091 … … 1076 1095 /* 1077 1096 * Generate a schema for blocks. 1078 * - Block styles can contain `elements` & `variations`definitions.1097 * - Block styles can contain `elements`, `variations`, and responsive breakpoint state definitions. 1079 1098 * - Variations definitions cannot be nested. 1080 * - Variations can contain styles for inner `blocks` .1081 * - Variation inner `blocks` styles can contain `elements` .1099 * - Variations can contain styles for inner `blocks`, `elements`, and responsive breakpoint states. 1100 * - Variation inner `blocks` styles can contain `elements` and responsive breakpoint states. 1082 1101 * 1083 * As each variation needs a `blocks` schema but further nested1084 * inner `blocks`, the overall schema will begenerated in multiple passes.1102 * As each variation needs both a `blocks` schema and responsive `blocks` schemas 1103 * for further nested inner `blocks`, the overall schema is generated in multiple passes. 1085 1104 */ 1086 1105 foreach ( $valid_block_names as $block ) { … … 1088 1107 $schema_styles_blocks[ $block ] = $styles_non_top_level; 1089 1108 $schema_styles_blocks[ $block ]['elements'] = $schema_styles_elements; 1109 1110 // Add responsive breakpoint states for all blocks. 1111 foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint_state ) { 1112 $schema_styles_blocks[ $block ][ $breakpoint_state ] = $styles_non_top_level; 1113 $schema_styles_blocks[ $block ][ $breakpoint_state ]['elements'] = $schema_styles_elements; 1114 1115 if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] ) ) { 1116 foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] as $pseudo_selector ) { 1117 $schema_styles_blocks[ $block ][ $breakpoint_state ][ $pseudo_selector ] = $styles_non_top_level; 1118 } 1119 } 1120 } 1090 1121 1091 1122 // Add pseudo-selectors for blocks that support them … … 1119 1150 foreach ( $style_variation_names as $variation_name ) { 1120 1151 $variation_schema = $block_style_variation_styles; 1152 1153 // Add responsive breakpoint states to block style variations. 1154 foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint_state ) { 1155 $variation_schema[ $breakpoint_state ] = $styles_non_top_level; 1156 $variation_schema[ $breakpoint_state ]['elements'] = $schema_styles_elements; 1157 $variation_schema[ $breakpoint_state ]['blocks'] = $schema_styles_blocks; 1158 1159 if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] ) ) { 1160 foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] as $pseudo_selector ) { 1161 $variation_schema[ $breakpoint_state ][ $pseudo_selector ] = $styles_non_top_level; 1162 } 1163 } 1164 } 1121 1165 1122 1166 // Add pseudo-selectors to variations for blocks that support them … … 1887 1931 } 1888 1932 } 1933 1934 if ( ! empty( $options['media_query'] ) && ! empty( $block_rules ) ) { 1935 $block_rules = $options['media_query'] . '{' . $block_rules . '}'; 1936 } 1937 1889 1938 return $block_rules; 1890 1939 } … … 2874 2923 2875 2924 $variation_selectors = array(); 2925 2876 2926 if ( $include_variations && isset( $node['variations'] ) ) { 2877 2927 foreach ( $node['variations'] as $variation => $node ) { … … 2888 2938 'selector' => $selector, 2889 2939 'selectors' => $feature_selectors, 2940 'elements' => $selectors[ $name ]['elements'] ?? array(), 2890 2941 'duotone' => $duotone_selector, 2891 'features' => $feature_selectors,2892 2942 'variations' => $variation_selectors, 2893 2943 'css' => $selector, 2894 2944 ); 2895 2945 2946 // Responsive block nodes: emit one node per breakpoint that has styles. 2947 // These are rendered immediately after the base block node so that 2948 // the cascade order is: .block{} → @media{.block{}} 2949 foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) { 2950 if ( isset( $theme_json['styles']['blocks'][ $name ][ $breakpoint ] ) ) { 2951 $nodes[] = array( 2952 'name' => $name, 2953 'path' => array( 'styles', 'blocks', $name, $breakpoint ), 2954 'media_query' => static::RESPONSIVE_BREAKPOINTS[ $breakpoint ], 2955 'selector' => $selector, 2956 'selectors' => $feature_selectors, 2957 'elements' => $selectors[ $name ]['elements'] ?? array(), 2958 'variations' => $variation_selectors, 2959 'css' => $selector, 2960 ); 2961 } 2962 } 2963 2896 2964 // Handle any pseudo selectors for the block. 2897 2965 if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $name ] ) ) { 2898 2966 foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $name ] as $pseudo_selector ) { 2899 if ( isset( $theme_json['styles']['blocks'][ $name ][ $pseudo_selector ] ) ) { 2967 $has_pseudo = isset( $theme_json['styles']['blocks'][ $name ][ $pseudo_selector ] ); 2968 $has_responsive_pseudo = false; 2969 foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) { 2970 if ( isset( $theme_json['styles']['blocks'][ $name ][ $breakpoint ][ $pseudo_selector ] ) ) { 2971 $has_responsive_pseudo = true; 2972 break; 2973 } 2974 } 2975 2976 if ( ! $has_pseudo && ! $has_responsive_pseudo ) { 2977 continue; 2978 } 2979 2980 /* 2981 * Append the pseudo-selector to each feature selector so that 2982 * get_feature_declarations_for_node generates CSS scoped to the 2983 * pseudo-state (e.g. '.wp-block-button:hover') rather than the 2984 * default state (e.g. '.wp-block-button'). 2985 */ 2986 $pseudo_feature_selectors = array(); 2987 foreach ( $feature_selectors ?? array() as $feature => $feature_selector ) { 2988 if ( is_array( $feature_selector ) ) { 2989 $pseudo_feature_selectors[ $feature ] = array(); 2990 foreach ( $feature_selector as $subfeature => $subfeature_selector ) { 2991 $pseudo_feature_selectors[ $feature ][ $subfeature ] = static::append_to_selector( $subfeature_selector, $pseudo_selector ); 2992 } 2993 } else { 2994 $pseudo_feature_selectors[ $feature ] = static::append_to_selector( $feature_selector, $pseudo_selector ); 2995 } 2996 } 2997 2998 if ( $has_pseudo ) { 2900 2999 $nodes[] = array( 2901 3000 'name' => $name, 2902 3001 'path' => array( 'styles', 'blocks', $name, $pseudo_selector ), 2903 3002 'selector' => static::append_to_selector( $selector, $pseudo_selector ), 2904 'selectors' => $feature_selectors, 3003 'selectors' => $pseudo_feature_selectors, 3004 'elements' => $selectors[ $name ]['elements'] ?? array(), 2905 3005 'duotone' => $duotone_selector, 2906 3006 'variations' => $variation_selectors, … … 2908 3008 ); 2909 3009 } 2910 } 2911 } 2912 } 2913 3010 3011 // Responsive pseudo nodes: emit one node per breakpoint that has 3012 // this pseudo state, immediately after the default pseudo node. 3013 // Cascade order: .block:hover{} → @media{.block:hover{}} 3014 foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) { 3015 if ( isset( $theme_json['styles']['blocks'][ $name ][ $breakpoint ][ $pseudo_selector ] ) ) { 3016 $nodes[] = array( 3017 'name' => $name, 3018 'path' => array( 'styles', 'blocks', $name, $breakpoint, $pseudo_selector ), 3019 'media_query' => static::RESPONSIVE_BREAKPOINTS[ $breakpoint ], 3020 'selector' => static::append_to_selector( $selector, $pseudo_selector ), 3021 'selectors' => $pseudo_feature_selectors, 3022 'elements' => $selectors[ $name ]['elements'] ?? array(), 3023 'variations' => $variation_selectors, 3024 'css' => static::append_to_selector( $selector, $pseudo_selector ), 3025 ); 3026 } 3027 } 3028 } 3029 } 3030 } 2914 3031 if ( isset( $theme_json['styles']['blocks'][ $name ]['elements'] ) ) { 2915 3032 foreach ( $theme_json['styles']['blocks'][ $name ]['elements'] as $element => $node ) { 2916 $node_path = array( 'styles', 'blocks', $name, 'elements', $element ); 2917 3033 $element_path = array( 'styles', 'blocks', $name, 'elements', $element ); 2918 3034 if ( $include_node_paths_only ) { 2919 3035 $nodes[] = array( 2920 'path' => $ node_path,3036 'path' => $element_path, 2921 3037 ); 2922 3038 continue; 2923 3039 } 2924 3040 3041 $element_selector = $selectors[ $name ]['elements'][ $element ]; 3042 2925 3043 $nodes[] = array( 2926 'path' => $ node_path,2927 'selector' => $ selectors[ $name ]['elements'][ $element ],3044 'path' => $element_path, 3045 'selector' => $element_selector, 2928 3046 ); 3047 3048 // Responsive element nodes: one node per breakpoint that has 3049 // styles for this element. Cascade: a{} → @media{a{}} 3050 foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) { 3051 if ( isset( $theme_json['styles']['blocks'][ $name ][ $breakpoint ]['elements'][ $element ] ) ) { 3052 $nodes[] = array( 3053 'path' => array( 'styles', 'blocks', $name, $breakpoint, 'elements', $element ), 3054 'selector' => $element_selector, 3055 'media_query' => static::RESPONSIVE_BREAKPOINTS[ $breakpoint ], 3056 ); 3057 } 3058 } 2929 3059 2930 3060 // Handle any pseudo selectors for the element. 2931 3061 if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] ) ) { 2932 3062 foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] as $pseudo_selector ) { 2933 if ( isset( $theme_json['styles']['blocks'][ $name ]['elements'][ $element ][ $pseudo_selector ] ) ) { 2934 $node_path = array( 'styles', 'blocks', $name, 'elements', $element ); 3063 // Create element pseudo node if default or any responsive breakpoint has the pseudo. 3064 $has_element_pseudo = isset( $theme_json['styles']['blocks'][ $name ]['elements'][ $element ][ $pseudo_selector ] ); 3065 if ( ! $has_element_pseudo ) { 3066 foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $bp ) { 3067 if ( isset( $theme_json['styles']['blocks'][ $name ][ $bp ]['elements'][ $element ][ $pseudo_selector ] ) ) { 3068 $has_element_pseudo = true; 3069 break; 3070 } 3071 } 3072 } 3073 3074 if ( $has_element_pseudo ) { 3075 $element_pseudo_path = array( 'styles', 'blocks', $name, 'elements', $element ); 3076 if ( $include_node_paths_only ) { 3077 $nodes[] = array( 3078 'path' => $element_pseudo_path, 3079 ); 3080 continue; 3081 } 2935 3082 2936 3083 $nodes[] = array( 2937 'path' => $ node_path,2938 'selector' => static::append_to_selector( $ selectors[ $name ]['elements'][ $element ], $pseudo_selector ),3084 'path' => $element_pseudo_path, 3085 'selector' => static::append_to_selector( $element_selector, $pseudo_selector ), 2939 3086 ); 3087 3088 // Responsive element pseudo nodes: one node per breakpoint 3089 // that has this pseudo state for this element. 3090 // Cascade: a:hover{} → @media{a:hover{}} 3091 foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) { 3092 if ( isset( $theme_json['styles']['blocks'][ $name ][ $breakpoint ]['elements'][ $element ][ $pseudo_selector ] ) ) { 3093 $nodes[] = array( 3094 'path' => array( 'styles', 'blocks', $name, $breakpoint, 'elements', $element ), 3095 'selector' => static::append_to_selector( $element_selector, $pseudo_selector ), 3096 'media_query' => static::RESPONSIVE_BREAKPOINTS[ $breakpoint ], 3097 ); 3098 } 3099 } 2940 3100 } 2941 3101 } … … 2966 3126 $feature_declarations = static::get_feature_declarations_for_node( $block_metadata, $node ); 2967 3127 $is_root_selector = static::ROOT_BLOCK_SELECTOR === $selector; 3128 $media_query = $block_metadata['media_query'] ?? null; 2968 3129 2969 3130 // Update text indent selector for paragraph blocks based on the textIndent setting. 2970 3131 $block_name = $block_metadata['name'] ?? null; 2971 3132 $feature_declarations = static::update_paragraph_text_indent_selector( $feature_declarations, $settings, $block_name ); 3133 $block_elements = $block_metadata['elements'] ?? array(); 2972 3134 2973 3135 // If there are style variations, generate the declarations for them, including any feature selectors the block may have. 2974 3136 $style_variation_declarations = array(); 2975 3137 $style_variation_custom_css = array(); 3138 $style_variation_responsive_css = array(); 2976 3139 $style_variation_layout_metadata = array(); 2977 if ( ! empty( $block_metadata['variations'] ) ) {3140 if ( ! $media_query && ! empty( $block_metadata['variations'] ) ) { 2978 3141 foreach ( $block_metadata['variations'] as $style_variation ) { 2979 3142 $style_variation_node = _wp_array_get( $this->theme_json, $style_variation['path'], array() ); … … 3018 3181 $block_name = $block_metadata['name']; 3019 3182 } elseif ( in_array( 'blocks', $block_metadata['path'], true ) && count( $block_metadata['path'] ) >= 3 ) { 3020 $block_name = $block_metadata['path'][2];3183 $block_name = static::get_block_name_from_metadata_path( $block_metadata ); 3021 3184 } else { 3022 3185 $block_name = null; … … 3041 3204 ); 3042 3205 } 3206 3207 // Store responsive breakpoint CSS for the style variation. 3208 // This includes both base properties and feature-level selectors. 3209 $variation_responsive_css = ''; 3210 3211 foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) { 3212 if ( ! isset( $style_variation_node[ $breakpoint ] ) ) { 3213 continue; 3214 } 3215 3216 $breakpoint_node = $style_variation_node[ $breakpoint ]; 3217 $breakpoint_media = static::RESPONSIVE_BREAKPOINTS[ $breakpoint ]; 3218 // Process feature-level declarations for this breakpoint. 3219 $breakpoint_feature_declarations = static::get_feature_declarations_for_node( $block_metadata, $breakpoint_node ); 3220 $breakpoint_feature_declarations = static::update_paragraph_text_indent_selector( $breakpoint_feature_declarations, $settings, $block_name ); 3221 foreach ( $breakpoint_feature_declarations as $feature_selector => $feature_decl ) { 3222 $clean_feature_selector = preg_replace( '/,\s+/', ',', $feature_selector ); 3223 $shortened_selector = str_replace( $block_metadata['selector'], '', $clean_feature_selector ); 3224 3225 if ( $block_metadata['selector'] && ! str_contains( $clean_feature_selector, $block_metadata['selector'] ) ) { 3226 /* 3227 * Feature selector is block-level (e.g. `.wp-block-button` for 3228 * dimensions/width) — apply the variation class directly to it. 3229 */ 3230 $feature_element_selector = str_replace( $shortened_selector, '', $clean_style_variation_selector ); 3231 $combined_selectors = str_replace( $feature_element_selector, '', $clean_style_variation_selector ); 3232 } else { 3233 // Prepend the variation selector to the current selector. 3234 $split_selectors = explode( ',', $shortened_selector ); 3235 $updated_selectors = array_map( 3236 static function ( $split_selector ) use ( $clean_style_variation_selector ) { 3237 return $clean_style_variation_selector . $split_selector; 3238 }, 3239 $split_selectors 3240 ); 3241 $combined_selectors = implode( ',', $updated_selectors ); 3242 } 3243 3244 $feature_ruleset = static::to_ruleset( ':root :where(' . $combined_selectors . ')', $feature_decl ); 3245 $variation_responsive_css .= $breakpoint_media . '{' . $feature_ruleset . '}'; 3246 } 3247 3248 // Process base properties for this breakpoint. 3249 $breakpoint_declarations = static::compute_style_properties( $breakpoint_node, $settings, null, $this->theme_json ); 3250 if ( ! empty( $breakpoint_declarations ) ) { 3251 $base_ruleset = static::to_ruleset( ':root :where(' . $style_variation['selector'] . ')', $breakpoint_declarations ); 3252 $variation_responsive_css .= $breakpoint_media . '{' . $base_ruleset . '}'; 3253 } 3254 3255 $breakpoint_pseudo_declarations = static::process_pseudo_selectors( $breakpoint_node, $style_variation['selector'], $settings, $block_name ); 3256 foreach ( $breakpoint_pseudo_declarations as $pseudo_selector => $pseudo_declarations ) { 3257 if ( empty( $pseudo_declarations ) ) { 3258 continue; 3259 } 3260 $pseudo_ruleset = static::to_ruleset( ':root :where(' . $pseudo_selector . ')', $pseudo_declarations ); 3261 $variation_responsive_css .= $breakpoint_media . '{' . $pseudo_ruleset . '}'; 3262 } 3263 3264 // Process custom CSS for this breakpoint. 3265 if ( isset( $breakpoint_node['css'] ) ) { 3266 $breakpoint_custom_css = static::process_blocks_custom_css( $breakpoint_node['css'], $style_variation['selector'] ); 3267 $variation_responsive_css .= $breakpoint_media . '{' . $breakpoint_custom_css . '}'; 3268 } 3269 3270 // Process blockGap responsive layout styles for this variation. 3271 if ( isset( $breakpoint_node['spacing']['blockGap'] ) ) { 3272 $variation_layout_metadata = $style_variation; 3273 $variation_layout_metadata['selector'] = $style_variation['selector'] . $block_metadata['css']; 3274 $variation_responsive_css .= $this->get_layout_styles( 3275 $variation_layout_metadata, 3276 array( 3277 'node' => $breakpoint_node, 3278 'media_query' => $breakpoint_media, 3279 ) 3280 ); 3281 } 3282 3283 // Process nested element styles for this breakpoint state. 3284 if ( isset( $breakpoint_node['elements'] ) && ! empty( $block_elements ) ) { 3285 foreach ( $breakpoint_node['elements'] as $element_name => $element_node ) { 3286 if ( ! isset( $block_elements[ $element_name ] ) ) { 3287 continue; 3288 } 3289 3290 $clean_element_selector = preg_replace( '/,\s+/', ',', $block_elements[ $element_name ] ); 3291 $shortened_selector = str_replace( $block_metadata['selector'], '', $clean_element_selector ); 3292 $split_selectors = explode( ',', $shortened_selector ); 3293 $updated_selectors = array_map( 3294 static function ( $split_selector ) use ( $clean_style_variation_selector ) { 3295 return $clean_style_variation_selector . $split_selector; 3296 }, 3297 $split_selectors 3298 ); 3299 $variation_element_selector = implode( ',', $updated_selectors ); 3300 3301 $element_declarations = static::compute_style_properties( $element_node, $settings, null, $this->theme_json ); 3302 if ( ! empty( $element_declarations ) ) { 3303 $element_ruleset = static::to_ruleset( ':root :where(' . $variation_element_selector . ')', $element_declarations ); 3304 $variation_responsive_css .= $breakpoint_media . '{' . $element_ruleset . '}'; 3305 } 3306 3307 if ( isset( $element_node['css'] ) ) { 3308 $element_custom_css = static::process_blocks_custom_css( $element_node['css'], $variation_element_selector ); 3309 $variation_responsive_css .= $breakpoint_media . '{' . $element_custom_css . '}'; 3310 } 3311 3312 if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element_name ] ) ) { 3313 foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element_name ] as $pseudo_selector ) { 3314 if ( ! isset( $element_node[ $pseudo_selector ] ) ) { 3315 continue; 3316 } 3317 3318 $pseudo_declarations = static::compute_style_properties( $element_node[ $pseudo_selector ], $settings, null, $this->theme_json ); 3319 if ( empty( $pseudo_declarations ) ) { 3320 continue; 3321 } 3322 3323 $pseudo_selector_ruleset = static::to_ruleset( ':root :where(' . static::append_to_selector( $variation_element_selector, $pseudo_selector ) . ')', $pseudo_declarations ); 3324 $variation_responsive_css .= $breakpoint_media . '{' . $pseudo_selector_ruleset . '}'; 3325 } 3326 } 3327 } 3328 } 3329 } 3330 3331 if ( ! empty( $variation_responsive_css ) ) { 3332 $style_variation_responsive_css[ $style_variation['selector'] ] = $variation_responsive_css; 3333 } 3043 3334 } 3044 3335 } … … 3066 3357 $block_pseudo_selector = null; 3067 3358 if ( in_array( 'blocks', $block_metadata['path'], true ) && count( $block_metadata['path'] ) >= 4 ) { 3068 $block_name = $block_metadata['path'][2]; // 'core/button'3359 $block_name = static::get_block_name_from_metadata_path( $block_metadata ); // 'core/button' 3069 3360 $last_path_element = $block_metadata['path'][ count( $block_metadata['path'] ) - 1 ]; // ':hover' 3070 3361 … … 3108 3399 // Process block pseudo-selector styles 3109 3400 // For block pseudo-selectors, we need to get the block data first, then access the pseudo-selector 3110 $block_name = $block_metadata['path'][2]; // 'core/button'3401 $block_name = static::get_block_name_from_metadata_path( $block_metadata ); // 'core/button' 3111 3402 $block_data = _wp_array_get( $this->theme_json, array( 'styles', 'blocks', $block_name ), array() ); 3112 3403 $pseudo_data = $block_data[ $block_pseudo_selector ] ?? array(); … … 3225 3516 $block_rules .= $style_variation_custom_css[ $style_variation_selector ]; 3226 3517 } 3518 if ( isset( $style_variation_responsive_css[ $style_variation_selector ] ) ) { 3519 $block_rules .= $style_variation_responsive_css[ $style_variation_selector ]; 3520 } 3227 3521 } 3228 3522 … … 3230 3524 if ( isset( $node['css'] ) && ! $is_root_selector ) { 3231 3525 $block_rules .= $this->process_blocks_custom_css( $node['css'], $selector ); 3526 } 3527 3528 // 8. Wrap the entire block output in a media query if this is a responsive node. 3529 // Responsive nodes are created by get_block_nodes() for each breakpoint and carry 3530 // a 'media_query' key. 3531 if ( $media_query && ! empty( $block_rules ) ) { 3532 $block_rules = $media_query . '{' . $block_rules . '}'; 3232 3533 } 3233 3534 … … 3727 4028 } 3728 4029 4030 $block_name = in_array( 'blocks', $metadata['path'], true ) 4031 ? static::get_block_name_from_metadata_path( $metadata ) 4032 : null; 4033 3729 4034 // The global styles custom CSS is not sanitized, but can only be edited by users with 'edit_css' capability. 3730 4035 if ( isset( $input['css'] ) && current_user_can( 'edit_css' ) ) { … … 3752 4057 } 3753 4058 4059 // Re-add and process responsive breakpoint styles. 4060 foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) { 4061 if ( isset( $input[ $breakpoint ] ) ) { 4062 $output[ $breakpoint ] = static::remove_insecure_styles( $input[ $breakpoint ] ); 4063 4064 if ( isset( $input[ $breakpoint ]['elements'] ) ) { 4065 $output[ $breakpoint ]['elements'] = static::remove_insecure_element_styles( $input[ $breakpoint ]['elements'] ); 4066 } 4067 4068 if ( isset( $input[ $breakpoint ]['blocks'] ) ) { 4069 $output[ $breakpoint ]['blocks'] = static::remove_insecure_inner_block_styles( $input[ $breakpoint ]['blocks'] ); 4070 } 4071 4072 if ( $block_name && isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block_name ] ) ) { 4073 foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block_name ] as $pseudo_selector ) { 4074 if ( isset( $input[ $breakpoint ][ $pseudo_selector ] ) ) { 4075 $output[ $breakpoint ][ $pseudo_selector ] = static::remove_insecure_styles( $input[ $breakpoint ][ $pseudo_selector ] ); 4076 } 4077 } 4078 } 4079 4080 // Responsive custom CSS is allowed for users with 'edit_css' capability. 4081 if ( isset( $input[ $breakpoint ]['css'] ) && current_user_can( 'edit_css' ) ) { 4082 $output[ $breakpoint ]['css'] = $input[ $breakpoint ]['css']; 4083 } 4084 } 4085 } 4086 3754 4087 if ( ! empty( $output ) ) { 3755 4088 _wp_array_set( $sanitized, $metadata['path'], $output ); … … 3773 4106 } 3774 4107 4108 // Re-add and process responsive breakpoint styles for variations. 4109 foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) { 4110 if ( isset( $variation_input[ $breakpoint ] ) ) { 4111 $variation_output[ $breakpoint ] = static::remove_insecure_styles( $variation_input[ $breakpoint ] ); 4112 4113 if ( isset( $variation_input[ $breakpoint ]['elements'] ) ) { 4114 $variation_output[ $breakpoint ]['elements'] = static::remove_insecure_element_styles( $variation_input[ $breakpoint ]['elements'] ); 4115 } 4116 4117 if ( isset( $variation_input[ $breakpoint ]['blocks'] ) ) { 4118 $variation_output[ $breakpoint ]['blocks'] = static::remove_insecure_inner_block_styles( $variation_input[ $breakpoint ]['blocks'] ); 4119 } 4120 4121 if ( $block_name && isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block_name ] ) ) { 4122 foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block_name ] as $pseudo_selector ) { 4123 if ( isset( $variation_input[ $breakpoint ][ $pseudo_selector ] ) ) { 4124 $variation_output[ $breakpoint ][ $pseudo_selector ] = static::remove_insecure_styles( $variation_input[ $breakpoint ][ $pseudo_selector ] ); 4125 } 4126 } 4127 } 4128 4129 // Responsive custom CSS is allowed for users with 'edit_css' capability. 4130 if ( isset( $variation_input[ $breakpoint ]['css'] ) && current_user_can( 'edit_css' ) ) { 4131 $variation_output[ $breakpoint ]['css'] = $variation_input[ $breakpoint ]['css']; 4132 } 4133 } 4134 } 4135 3775 4136 if ( ! empty( $variation_output ) ) { 3776 4137 _wp_array_set( $sanitized, $variation['path'], $variation_output ); … … 3833 4194 } 3834 4195 4196 // Re-add and process responsive breakpoint styles for elements. 4197 foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) { 4198 if ( isset( $element_input[ $breakpoint ] ) ) { 4199 $element_output[ $breakpoint ] = static::remove_insecure_styles( $element_input[ $breakpoint ] ); 4200 4201 if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element_name ] ) ) { 4202 foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element_name ] as $pseudo_selector ) { 4203 if ( isset( $element_input[ $breakpoint ][ $pseudo_selector ] ) ) { 4204 $element_output[ $breakpoint ][ $pseudo_selector ] = static::remove_insecure_styles( $element_input[ $breakpoint ][ $pseudo_selector ] ); 4205 } 4206 } 4207 } 4208 } 4209 } 4210 3835 4211 $sanitized[ $element_name ] = $element_output; 3836 4212 } … … 3854 4230 if ( isset( $block_input['elements'] ) ) { 3855 4231 $block_output['elements'] = static::remove_insecure_element_styles( $block_input['elements'] ); 4232 } 4233 4234 // Re-add and process responsive breakpoint styles for inner blocks. 4235 foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) { 4236 if ( isset( $block_input[ $breakpoint ] ) ) { 4237 $block_output[ $breakpoint ] = static::remove_insecure_styles( $block_input[ $breakpoint ] ); 4238 4239 if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block_type ] ) ) { 4240 foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block_type ] as $pseudo_selector ) { 4241 if ( isset( $block_input[ $breakpoint ][ $pseudo_selector ] ) ) { 4242 $block_output[ $breakpoint ][ $pseudo_selector ] = static::remove_insecure_styles( $block_input[ $breakpoint ][ $pseudo_selector ] ); 4243 } 4244 } 4245 } 4246 } 3856 4247 } 3857 4248 … … 4844 5235 return $valid_variations; 4845 5236 } 5237 5238 /** 5239 * Extracts the block name from the block metadata path. 5240 * 5241 * @since 7.1 5242 * 5243 * @param array $block_metadata Block metadata. 5244 * @return string|null The block name or null if not found. 5245 */ 5246 private static function get_block_name_from_metadata_path( $block_metadata ) { 5247 return $block_metadata['path'][2] ?? null; 5248 } 4846 5249 }
Note: See TracChangeset
for help on using the changeset viewer.