PluginProbe
Gutenberg / 22.7.0
Gutenberg v22.7.0
24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 All 403 releases
← All changes | lib/class-wp-theme-json-gutenberg.php +57 -540 23.2.222.7.0 View file →
@@ -289,9 +289,8 @@
289 289 'margin-right' => array( 'spacing', 'margin', 'right' ),
290 290 'margin-bottom' => array( 'spacing', 'margin', 'bottom' ),
291 291 'margin-left' => array( 'spacing', 'margin', 'left' ),
292 292 'min-height' => array( 'dimensions', 'minHeight' ),
293 - 'min-width' => array( 'dimensions', 'minWidth' ),
294 293 'outline-color' => array( 'outline', 'color' ),
295 294 'outline-offset' => array( 'outline', 'offset' ),
296 295 'outline-style' => array( 'outline', 'style' ),
297 296 'outline-width' => array( 'outline', 'width' ),
@@ -345,9 +344,8 @@
345 344 array( 'layout', 'wideSize' ),
346 345 ),
347 346 'background-image' => array(
348 347 array( 'background', 'backgroundImage', 'url' ),
349 - array( 'background', 'gradient' ),
350 348 ),
351 349 );
352 350
353 351
@@ -398,9 +396,8 @@
398 396 'useRootPaddingAwareAlignments' => null,
399 397 'background' => array(
400 398 'backgroundImage' => null,
401 399 'backgroundSize' => null,
402 - 'gradient' => null,
403 400 ),
404 401 'border' => array(
405 402 'color' => null,
406 403 'radius' => null,
@@ -432,9 +429,8 @@
432 429 'defaultAspectRatios' => null,
433 430 'dimensionSizes' => null,
434 431 'height' => null,
435 432 'minHeight' => null,
436 - 'minWidth' => null,
437 433 'width' => null,
438 434 ),
439 435 'layout' => array(
440 436 'contentSize' => null,
@@ -532,9 +528,8 @@
532 528 'backgroundAttachment' => null,
533 529 'backgroundPosition' => null,
534 530 'backgroundRepeat' => null,
535 531 'backgroundSize' => null,
536 - 'gradient' => null,
537 532 ),
538 533 'border' => array(
539 534 'color' => null,
540 535 'radius' => null,
@@ -553,9 +548,8 @@
553 548 'dimensions' => array(
554 549 'aspectRatio' => null,
555 550 'height' => null,
556 551 'minHeight' => null,
557 - 'minWidth' => null,
558 552 'width' => null,
559 553 ),
560 554 'filter' => array(
561 555 'duotone' => null,
@@ -615,47 +609,12 @@
615 609 * @since 7.0.0
616 610 * @var array
617 611 */
618 612 const VALID_BLOCK_PSEUDO_SELECTORS = array(
619 - 'core/button' => array( ':hover', ':focus', ':focus-visible', ':active' ),
620 - 'core/navigation-link' => array( ':hover', ':focus', ':focus-visible', ':active' ),
613 + 'core/button' => array( ':hover', ':focus', ':focus-visible', ':active' ),
621 614 );
622 615
623 616 /**
624 - * Responsive breakpoint state keys and their corresponding CSS media queries.
625 - * These are available for all blocks and wrap their styles in the given media query.
626 - * Keep in sync with RESPONSIVE_BREAKPOINTS in packages/global-styles-engine/src/core/render.tsx.
627 - *
628 - * @since 7.1.0
629 - * @var array
630 - */
631 - const RESPONSIVE_BREAKPOINTS = array(
632 - 'mobile' => '@media (width <= 480px)',
633 - 'tablet' => '@media (480px < width <= 782px)',
634 - );
635 -
636 - /**
637 - * Custom states for blocks that map to CSS class selectors rather than
638 - * CSS pseudo-selectors. Values use the '@' prefix (e.g. '@current') to
639 - * distinguish them from real CSS pseudo-selectors.
640 - *
641 - * The CSS selector for each state is defined in the block's block.json
642 - * under `selectors.states`, e.g.:
643 - *
644 - * "selectors": { "states": { "@current": ".some-css-selector" } }
645 - *
646 - * This constant controls which states are valid in theme.json for a given
647 - * block. Blocks listed here also inherit their VALID_BLOCK_PSEUDO_SELECTORS
648 - * as valid sub-states, producing compound selectors such as
649 - * `.wp-block-navigation-item.current-menu-item:hover`.
650 - *
651 - * @var array
652 - */
653 - const VALID_BLOCK_CUSTOM_STATES = array(
654 - 'core/navigation-link' => array( '@current' ),
655 - );
656 -
657 - /**
658 617 * The valid elements that can be found under styles.
659 618 *
660 619 * @since 5.8.0
661 620 * @since 6.1.0 Added `heading`, `button`, and `caption` elements.
@@ -800,9 +759,8 @@
800 759 */
801 760 const APPEARANCE_TOOLS_OPT_INS = array(
802 761 array( 'background', 'backgroundImage' ),
803 762 array( 'background', 'backgroundSize' ),
804 - array( 'background', 'gradient' ),
805 763 array( 'border', 'color' ),
806 764 array( 'border', 'radius' ),
807 765 array( 'border', 'style' ),
808 766 array( 'border', 'width' ),
@@ -812,9 +770,8 @@
812 770 array( 'color', 'caption' ),
813 771 array( 'dimensions', 'aspectRatio' ),
814 772 array( 'dimensions', 'height' ),
815 773 array( 'dimensions', 'minHeight' ),
816 - array( 'dimensions', 'minWidth' ),
817 774 array( 'dimensions', 'width' ),
818 775 // BEGIN EXPERIMENTAL.
819 776 // Allow `position.fixed` to be opted-in by default.
820 777 // Sticky position support was backported to WordPress 6.2 in https://core.trac.wordpress.org/ticket/57618.
@@ -1065,14 +1022,13 @@
1065 1022 $schema = array();
1066 1023 $schema_styles_elements = array();
1067 1024
1068 1025 /*
1069 - * Set allowed element pseudo selectors and responsive breakpoint states.
1026 + * Set allowed element pseudo selectors based on per element allow list.
1070 1027 * Target data structure in schema:
1071 1028 * e.g.
1072 1029 * - top level elements: `$schema['styles']['elements']['link'][':hover']`.
1073 1030 * - block level elements: `$schema['styles']['blocks']['core/button']['elements']['link'][':hover']`.
1074 - * - block responsive elements: `$schema['styles']['blocks']['core/button']['tablet']['elements']['link'][':hover']`.
1075 1031 */
1076 1032 foreach ( $valid_element_names as $element ) {
1077 1033 $schema_styles_elements[ $element ] = $styles_non_top_level;
1078 1034
@@ -1080,13 +1036,8 @@
1080 1036 foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] as $pseudo_selector ) {
1081 1037 $schema_styles_elements[ $element ][ $pseudo_selector ] = $styles_non_top_level;
1082 1038 }
1083 1039 }
1084 -
1085 - // Add responsive breakpoint states for elements.
1086 - foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint_state ) {
1087 - $schema_styles_elements[ $element ][ $breakpoint_state ] = $styles_non_top_level;
1088 - }
1089 1040 }
1090 1041
1091 1042 $schema_styles_blocks = array();
1092 1043 $schema_settings_blocks = array();
@@ -1092,15 +1043,15 @@
1092 1043 $schema_settings_blocks = array();
1093 1044
1094 1045 /*
1095 1046 * Generate a schema for blocks.
1096 - * - Block styles can contain `elements`, `variations`, and responsive breakpoint state definitions.
1047 + * - Block styles can contain `elements` & `variations` definitions.
1097 1048 * - Variations definitions cannot be nested.
1098 - * - Variations can contain styles for inner `blocks`, `elements`, and responsive breakpoint states.
1099 - * - Variation inner `blocks` styles can contain `elements` and responsive breakpoint states.
1049 + * - Variations can contain styles for inner `blocks`.
1050 + * - Variation inner `blocks` styles can contain `elements`.
1100 1051 *
1101 - * As each variation needs both a `blocks` schema and responsive `blocks` schemas
1102 - * for further nested inner `blocks`, the overall schema is generated in multiple passes.
1052 + * As each variation needs a `blocks` schema but further nested
1053 + * inner `blocks`, the overall schema will be generated in multiple passes.
1103 1054 */
1104 1055 foreach ( $valid_block_names as $block ) {
1105 1056 $schema_settings_blocks[ $block ] = static::VALID_SETTINGS;
1106 1057 $schema_styles_blocks[ $block ] = $styles_non_top_level;
@@ -1105,20 +1056,8 @@
1105 1056 $schema_settings_blocks[ $block ] = static::VALID_SETTINGS;
1106 1057 $schema_styles_blocks[ $block ] = $styles_non_top_level;
1107 1058 $schema_styles_blocks[ $block ]['elements'] = $schema_styles_elements;
1108 1059
1109 - // Add responsive breakpoint states for all blocks.
1110 - foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint_state ) {
1111 - $schema_styles_blocks[ $block ][ $breakpoint_state ] = $styles_non_top_level;
1112 - $schema_styles_blocks[ $block ][ $breakpoint_state ]['elements'] = $schema_styles_elements;
1113 -
1114 - if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] ) ) {
1115 - foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] as $pseudo_selector ) {
1116 - $schema_styles_blocks[ $block ][ $breakpoint_state ][ $pseudo_selector ] = $styles_non_top_level;
1117 - }
1118 - }
1119 - }
1120 -
1121 1060 // Add pseudo-selectors for blocks that support them.
1122 1061 if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] ) ) {
1123 1062 foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] as $pseudo_selector ) {
1124 1063 $schema_styles_blocks[ $block ][ $pseudo_selector ] = $styles_non_top_level;
@@ -1123,23 +1062,8 @@
1123 1062 foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] as $pseudo_selector ) {
1124 1063 $schema_styles_blocks[ $block ][ $pseudo_selector ] = $styles_non_top_level;
1125 1064 }
1126 1065 }
1127 -
1128 - // Add custom states for blocks that support them (e.g. '@current' for navigation).
1129 - if ( isset( static::VALID_BLOCK_CUSTOM_STATES[ $block ] ) ) {
1130 - foreach ( static::VALID_BLOCK_CUSTOM_STATES[ $block ] as $custom_state ) {
1131 - $custom_state_schema = $styles_non_top_level;
1132 - // The same pseudo-selectors valid for the block at the top level
1133 - // are also valid within each custom state.
1134 - if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] ) ) {
1135 - foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] as $pseudo ) {
1136 - $custom_state_schema[ $pseudo ] = $styles_non_top_level;
1137 - }
1138 - }
1139 - $schema_styles_blocks[ $block ][ $custom_state ] = $custom_state_schema;
1140 - }
1141 - }
1142 1066 }
1143 1067
1144 1068 $block_style_variation_styles = static::VALID_STYLES;
1145 1069 $block_style_variation_styles['blocks'] = $schema_styles_blocks;
@@ -1163,21 +1087,8 @@
1163 1087 if ( ! empty( $style_variation_names ) ) {
1164 1088 foreach ( $style_variation_names as $variation_name ) {
1165 1089 $variation_schema = $block_style_variation_styles;
1166 1090
1167 - // Add responsive breakpoint states to block style variations.
1168 - foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint_state ) {
1169 - $variation_schema[ $breakpoint_state ] = $styles_non_top_level;
1170 - $variation_schema[ $breakpoint_state ]['elements'] = $schema_styles_elements;
1171 - $variation_schema[ $breakpoint_state ]['blocks'] = $schema_styles_blocks;
1172 -
1173 - if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] ) ) {
1174 - foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] as $pseudo_selector ) {
1175 - $variation_schema[ $breakpoint_state ][ $pseudo_selector ] = $styles_non_top_level;
1176 - }
1177 - }
1178 - }
1179 -
1180 1091 // Add pseudo-selectors to variations for blocks that support them.
1181 1092 if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] ) ) {
1182 1093 foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] as $pseudo_selector ) {
1183 1094 $variation_schema[ $pseudo_selector ] = $styles_non_top_level;
@@ -1378,13 +1289,8 @@
1378 1289
1379 1290 if ( ! empty( $style_selectors ) ) {
1380 1291 static::$blocks_metadata[ $block_name ]['styleVariations'] = $style_selectors;
1381 1292 }
1382 -
1383 - // If the block has custom states defined in block.json, store their selectors.
1384 - if ( ! empty( $block_type->selectors['states'] ) && is_array( $block_type->selectors['states'] ) ) {
1385 - static::$blocks_metadata[ $block_name ]['states'] = $block_type->selectors['states'];
1386 - }
1387 1293 }
1388 1294
1389 1295 return static::$blocks_metadata;
1390 1296 }
@@ -1979,13 +1885,8 @@
1979 1885 }
1980 1886 }
1981 1887 }
1982 1888 }
1983 -
1984 - if ( ! empty( $options['media_query'] ) && ! empty( $block_rules ) ) {
1985 - $block_rules = $options['media_query'] . '{' . $block_rules . '}';
1986 - }
1987 -
1988 1889 return $block_rules;
1989 1890 }
1990 1891
1991 1892 /**
@@ -2146,9 +2047,8 @@
2146 2047 * Given a selector and a declaration list,
2147 2048 * creates the corresponding ruleset.
2148 2049 *
2149 2050 * @since 5.8.0
2150 - * @since 7.1.0 Skip declarations whose value is not a plain string (booleans, arrays, objects, etc.).
2151 2051 *
2152 2052 * @param string $selector CSS selector.
2153 2053 * @param array $declarations List of declarations.
2154 2054 * @return string The resulting CSS ruleset.
@@ -2160,20 +2060,9 @@
2160 2060
2161 2061 $declaration_block = array_reduce(
2162 2062 $declarations,
2163 2063 static function ( $carry, $element ) {
2164 - $value = $element['value'];
2165 -
2166 - if ( is_numeric( $value ) ) {
2167 - $value = (string) $value;
2168 - }
2169 -
2170 - if ( ! is_string( $value ) ) {
2171 - return $carry;
2172 - }
2173 -
2174 - return $carry .= $element['name'] . ': ' . $value . ';';
2175 - },
2064 + return $carry .= $element['name'] . ': ' . $element['value'] . ';'; },
2176 2065 ''
2177 2066 );
2178 2067
2179 2068 return $selector . '{' . $declaration_block . '}';
@@ -2612,23 +2501,14 @@
2612 2501 * If the value is a URL, it will be converted to a CSS `url()` value.
2613 2502 * For an uploaded image (images with a database ID), apply size and position
2614 2503 * defaults equal to those applied in block supports in lib/background.php.
2615 2504 */
2616 - if ( 'background-image' === $css_property ) {
2617 - $background_image_input = array();
2618 - if ( ! empty( $value ) ) {
2619 - $background_image_input['backgroundImage'] = $value;
2620 - }
2621 - $gradient_value = $styles['background']['gradient'] ?? null;
2622 - if ( ! empty( $gradient_value ) ) {
2623 - $background_image_input['gradient'] = $gradient_value;
2624 - }
2625 - if ( ! empty( $background_image_input ) ) {
2626 - $background_styles = gutenberg_style_engine_get_styles(
2627 - array( 'background' => $background_image_input )
2628 - );
2629 - $value = $background_styles['declarations'][ $css_property ] ?? null;
2630 - }
2505 + if ( 'background-image' === $css_property && ! empty( $value ) ) {
2506 + $background_styles = gutenberg_style_engine_get_styles(
2507 + array( 'background' => array( 'backgroundImage' => $value ) )
2508 + );
2509 +
2510 + $value = $background_styles['declarations'][ $css_property ];
2631 2511 }
2632 2512 if ( empty( $value ) && static::ROOT_BLOCK_SELECTOR !== $selector && ! empty( $styles['background']['backgroundImage']['id'] ) ) {
2633 2513 if ( 'background-size' === $css_property ) {
2634 2514 $value = 'cover';
@@ -3144,209 +3024,61 @@
3144 3024 'name' => $name,
3145 3025 'path' => $node_path,
3146 3026 'selector' => $selector,
3147 3027 'selectors' => $feature_selectors,
3148 - 'elements' => $selectors[ $name ]['elements'] ?? array(),
3149 3028 'duotone' => $duotone_selector,
3150 3029 'variations' => $variation_selectors,
3151 3030 'css' => $selector,
3152 3031 );
3153 3032
3154 - // Responsive block nodes: emit one node per breakpoint that has styles.
3155 - // These are rendered immediately after the base block node so that
3156 - // the cascade order is: .block{} → @media{.block{}}
3157 - foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) {
3158 - if ( isset( $theme_json['styles']['blocks'][ $name ][ $breakpoint ] ) ) {
3159 - $nodes[] = array(
3160 - 'name' => $name,
3161 - 'path' => array( 'styles', 'blocks', $name, $breakpoint ),
3162 - 'media_query' => static::RESPONSIVE_BREAKPOINTS[ $breakpoint ],
3163 - 'selector' => $selector,
3164 - 'selectors' => $feature_selectors,
3165 - 'elements' => $selectors[ $name ]['elements'] ?? array(),
3166 - 'variations' => $variation_selectors,
3167 - 'css' => $selector,
3168 - );
3169 - }
3170 - }
3171 -
3172 3033 // Handle any pseudo selectors for the block.
3173 3034 if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $name ] ) ) {
3174 3035 foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $name ] as $pseudo_selector ) {
3175 - $has_pseudo = isset( $theme_json['styles']['blocks'][ $name ][ $pseudo_selector ] );
3176 - $has_responsive_pseudo = false;
3177 - foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) {
3178 - if ( isset( $theme_json['styles']['blocks'][ $name ][ $breakpoint ][ $pseudo_selector ] ) ) {
3179 - $has_responsive_pseudo = true;
3180 - break;
3181 - }
3182 - }
3183 -
3184 - if ( ! $has_pseudo && ! $has_responsive_pseudo ) {
3185 - continue;
3186 - }
3187 -
3188 - /*
3189 - * Append the pseudo-selector to each feature selector so that
3190 - * get_feature_declarations_for_node generates CSS scoped to the
3191 - * pseudo-state (e.g. '.wp-block-button:hover') rather than the
3192 - * default state (e.g. '.wp-block-button').
3193 - */
3194 - $pseudo_feature_selectors = array();
3195 - foreach ( $feature_selectors ?? array() as $feature => $feature_selector ) {
3196 - if ( is_array( $feature_selector ) ) {
3197 - $pseudo_feature_selectors[ $feature ] = array();
3198 - foreach ( $feature_selector as $subfeature => $subfeature_selector ) {
3199 - $pseudo_feature_selectors[ $feature ][ $subfeature ] = static::append_to_selector( $subfeature_selector, $pseudo_selector );
3200 - }
3201 - } else {
3202 - $pseudo_feature_selectors[ $feature ] = static::append_to_selector( $feature_selector, $pseudo_selector );
3203 - }
3204 - }
3205 -
3206 - if ( $has_pseudo ) {
3036 + if ( isset( $theme_json['styles']['blocks'][ $name ][ $pseudo_selector ] ) ) {
3207 3037 $nodes[] = array(
3208 3038 'name' => $name,
3209 3039 'path' => array( 'styles', 'blocks', $name, $pseudo_selector ),
3210 3040 'selector' => static::append_to_selector( $selector, $pseudo_selector ),
3211 - 'selectors' => $pseudo_feature_selectors,
3212 - 'elements' => $selectors[ $name ]['elements'] ?? array(),
3041 + 'selectors' => $feature_selectors,
3213 3042 'duotone' => $duotone_selector,
3214 3043 'variations' => $variation_selectors,
3215 3044 'css' => static::append_to_selector( $selector, $pseudo_selector ),
3216 3045 );
3217 3046 }
3218 -
3219 - // Responsive pseudo nodes: emit one node per breakpoint that has
3220 - // this pseudo state, immediately after the default pseudo node.
3221 - // Cascade order: .block:hover{} → @media{.block:hover{}}
3222 - foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) {
3223 - if ( isset( $theme_json['styles']['blocks'][ $name ][ $breakpoint ][ $pseudo_selector ] ) ) {
3224 - $nodes[] = array(
3225 - 'name' => $name,
3226 - 'path' => array( 'styles', 'blocks', $name, $breakpoint, $pseudo_selector ),
3227 - 'media_query' => static::RESPONSIVE_BREAKPOINTS[ $breakpoint ],
3228 - 'selector' => static::append_to_selector( $selector, $pseudo_selector ),
3229 - 'selectors' => $pseudo_feature_selectors,
3230 - 'elements' => $selectors[ $name ]['elements'] ?? array(),
3231 - 'variations' => $variation_selectors,
3232 - 'css' => static::append_to_selector( $selector, $pseudo_selector ),
3233 - );
3234 - }
3235 - }
3236 3047 }
3237 3048 }
3238 -
3239 - // Handle custom states (e.g. '@current' for navigation).
3240 - if ( isset( static::VALID_BLOCK_CUSTOM_STATES[ $name ] ) ) {
3241 - foreach ( static::VALID_BLOCK_CUSTOM_STATES[ $name ] as $custom_state ) {
3242 - if (
3243 - isset( $theme_json['styles']['blocks'][ $name ][ $custom_state ] ) &&
3244 - isset( $selectors[ $name ]['states'][ $custom_state ] )
3245 - ) {
3246 - $custom_css_selector = $selectors[ $name ]['states'][ $custom_state ];
3247 - $nodes[] = array(
3248 - 'name' => $name,
3249 - 'path' => array( 'styles', 'blocks', $name, $custom_state ),
3250 - 'selector' => $custom_css_selector,
3251 - 'selectors' => $feature_selectors,
3252 - 'elements' => $selectors[ $name ]['elements'] ?? array(),
3253 - 'duotone' => $duotone_selector,
3254 - 'variations' => $variation_selectors,
3255 - 'css' => $custom_css_selector,
3256 - );
3257 -
3258 - // Sub-pseudo-selectors within the custom state.
3259 - if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $name ] ) ) {
3260 - foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $name ] as $pseudo ) {
3261 - if ( isset( $theme_json['styles']['blocks'][ $name ][ $custom_state ][ $pseudo ] ) ) {
3262 - $compound_css_selector = static::append_to_selector( $custom_css_selector, $pseudo );
3263 - $nodes[] = array(
3264 - 'name' => $name,
3265 - 'path' => array( 'styles', 'blocks', $name, $custom_state, $pseudo ),
3266 - 'selector' => $compound_css_selector,
3267 - 'selectors' => $feature_selectors,
3268 - 'elements' => $selectors[ $name ]['elements'] ?? array(),
3269 - 'duotone' => $duotone_selector,
3270 - 'variations' => $variation_selectors,
3271 - 'css' => $compound_css_selector,
3272 - );
3273 - }
3274 - }
3275 - }
3276 - }
3277 - }
3278 - }
3279 3049 }
3280 3050 if ( isset( $theme_json['styles']['blocks'][ $name ]['elements'] ) ) {
3281 3051 foreach ( $theme_json['styles']['blocks'][ $name ]['elements'] as $element => $node ) {
3282 - $element_path = array( 'styles', 'blocks', $name, 'elements', $element );
3052 + $node_path = array( 'styles', 'blocks', $name, 'elements', $element );
3283 3053 if ( $include_node_paths_only ) {
3284 3054 $nodes[] = array(
3285 - 'path' => $element_path,
3055 + 'path' => $node_path,
3286 3056 );
3287 3057 continue;
3288 3058 }
3289 3059
3290 - $element_selector = $selectors[ $name ]['elements'][ $element ];
3291 -
3292 3060 $nodes[] = array(
3293 - 'path' => $element_path,
3294 - 'selector' => $element_selector,
3061 + 'path' => $node_path,
3062 + 'selector' => $selectors[ $name ]['elements'][ $element ],
3295 3063 );
3296 3064
3297 - // Responsive element nodes: one node per breakpoint that has
3298 - // styles for this element. Cascade: a{} → @media{a{}}
3299 - foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) {
3300 - if ( isset( $theme_json['styles']['blocks'][ $name ][ $breakpoint ]['elements'][ $element ] ) ) {
3301 - $nodes[] = array(
3302 - 'path' => array( 'styles', 'blocks', $name, $breakpoint, 'elements', $element ),
3303 - 'selector' => $element_selector,
3304 - 'media_query' => static::RESPONSIVE_BREAKPOINTS[ $breakpoint ],
3305 - );
3306 - }
3307 - }
3308 -
3309 3065 // Handle any pseudo selectors for the element.
3310 3066 if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] ) ) {
3311 3067 foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element ] as $pseudo_selector ) {
3312 - // Create element pseudo node if default or any responsive breakpoint has the pseudo.
3313 - $has_element_pseudo = isset( $theme_json['styles']['blocks'][ $name ]['elements'][ $element ][ $pseudo_selector ] );
3314 - if ( ! $has_element_pseudo ) {
3315 - foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $bp ) {
3316 - if ( isset( $theme_json['styles']['blocks'][ $name ][ $bp ]['elements'][ $element ][ $pseudo_selector ] ) ) {
3317 - $has_element_pseudo = true;
3318 - break;
3319 - }
3320 - }
3321 - }
3322 -
3323 - if ( $has_element_pseudo ) {
3324 - $element_pseudo_path = array( 'styles', 'blocks', $name, 'elements', $element );
3068 + if ( isset( $theme_json['styles']['blocks'][ $name ]['elements'][ $element ][ $pseudo_selector ] ) ) {
3069 + $node_path = array( 'styles', 'blocks', $name, 'elements', $element );
3325 3070 if ( $include_node_paths_only ) {
3326 3071 $nodes[] = array(
3327 - 'path' => $element_pseudo_path,
3072 + 'path' => $node_path,
3328 3073 );
3329 3074 continue;
3330 3075 }
3331 3076
3332 3077 $nodes[] = array(
3333 - 'path' => $element_pseudo_path,
3334 - 'selector' => static::append_to_selector( $element_selector, $pseudo_selector ),
3078 + 'path' => $node_path,
3079 + 'selector' => static::append_to_selector( $selectors[ $name ]['elements'][ $element ], $pseudo_selector ),
3335 3080 );
3336 -
3337 - // Responsive element pseudo nodes: one node per breakpoint
3338 - // that has this pseudo state for this element.
3339 - // Cascade: a:hover{} → @media{a:hover{}}
3340 - foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) {
3341 - if ( isset( $theme_json['styles']['blocks'][ $name ][ $breakpoint ]['elements'][ $element ][ $pseudo_selector ] ) ) {
3342 - $nodes[] = array(
3343 - 'path' => array( 'styles', 'blocks', $name, $breakpoint, 'elements', $element ),
3344 - 'selector' => static::append_to_selector( $element_selector, $pseudo_selector ),
3345 - 'media_query' => static::RESPONSIVE_BREAKPOINTS[ $breakpoint ],
3346 - );
3347 - }
3348 - }
3349 3081 }
3350 3082 }
3351 3083 }
3352 3084 }
@@ -3371,9 +3103,8 @@
3371 3103 $use_root_padding = isset( $this->theme_json['settings']['useRootPaddingAwareAlignments'] ) && true === $this->theme_json['settings']['useRootPaddingAwareAlignments'];
3372 3104 $selector = $block_metadata['selector'];
3373 3105 $settings = $this->theme_json['settings'] ?? null;
3374 3106 $is_root_selector = static::ROOT_BLOCK_SELECTOR === $selector;
3375 - $media_query = $block_metadata['media_query'] ?? null;
3376 3107
3377 3108 $feature_declarations = static::get_feature_declarations_for_node( $block_metadata, $node );
3378 3109
3379 3110 // Update text indent selector for paragraph blocks based on the textIndent setting.
@@ -3378,21 +3109,17 @@
3378 3109
3379 3110 // Update text indent selector for paragraph blocks based on the textIndent setting.
3380 3111 $block_name = $block_metadata['name'] ?? null;
3381 3112 $feature_declarations = static::update_paragraph_text_indent_selector( $feature_declarations, $settings, $block_name );
3382 - $block_elements = $block_metadata['elements'] ?? array();
3383 3113
3384 3114 // Update button width declarations for percentage values to use calc() with block gap.
3385 3115 $feature_declarations = static::update_button_width_declarations( $feature_declarations, $settings );
3386 3116
3387 3117 // If there are style variations, generate the declarations for them, including any feature selectors the block may have.
3388 - // Responsive nodes (those with a media_query) do not process variations — variation responsive
3389 - // CSS is handled by the variation's own responsive nodes or the existing variation loop.
3390 3118 $style_variation_declarations = array();
3391 3119 $style_variation_custom_css = array();
3392 - $style_variation_responsive_css = array();
3393 3120 $style_variation_layout_metadata = array();
3394 - if ( ! $media_query && ! empty( $block_metadata['variations'] ) ) {
3121 + if ( ! empty( $block_metadata['variations'] ) ) {
3395 3122 foreach ( $block_metadata['variations'] as $style_variation ) {
3396 3123 $style_variation_node = _wp_array_get( $this->theme_json, $style_variation['path'], array() );
3397 3124 $clean_style_variation_selector = trim( $style_variation['selector'] );
3398 3125
@@ -3452,139 +3179,11 @@
3452 3179 'metadata' => $variation_metadata_with_selector,
3453 3180 'node' => $style_variation_node,
3454 3181 );
3455 3182 }
3456 -
3457 - // Store responsive breakpoint CSS for the style variation.
3458 - // This includes both base properties and feature-level selectors.
3459 - $variation_responsive_css = '';
3460 -
3461 - foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) {
3462 - if ( ! isset( $style_variation_node[ $breakpoint ] ) ) {
3463 - continue;
3464 - }
3465 -
3466 - $breakpoint_node = $style_variation_node[ $breakpoint ];
3467 - $breakpoint_media = static::RESPONSIVE_BREAKPOINTS[ $breakpoint ];
3468 - // Process feature-level declarations for this breakpoint.
3469 - $breakpoint_feature_declarations = static::get_feature_declarations_for_node( $block_metadata, $breakpoint_node );
3470 - $breakpoint_feature_declarations = static::update_paragraph_text_indent_selector( $breakpoint_feature_declarations, $settings, $block_name );
3471 - $breakpoint_feature_declarations = static::update_button_width_declarations( $breakpoint_feature_declarations, $settings );
3472 - foreach ( $breakpoint_feature_declarations as $feature_selector => $feature_decl ) {
3473 - $clean_feature_selector = preg_replace( '/,\s+/', ',', $feature_selector );
3474 - $shortened_selector = str_replace( $block_metadata['selector'], '', $clean_feature_selector );
3475 -
3476 - if ( $block_metadata['selector'] && ! str_contains( $clean_feature_selector, $block_metadata['selector'] ) ) {
3477 - /*
3478 - * Feature selector is block-level (e.g. `.wp-block-button` for
3479 - * dimensions/width) — apply the variation class directly to it.
3480 - */
3481 - $feature_element_selector = str_replace( $shortened_selector, '', $clean_style_variation_selector );
3482 - $combined_selectors = str_replace( $feature_element_selector, '', $clean_style_variation_selector );
3483 - } else {
3484 - // Prepend the variation selector to the current selector.
3485 - $split_selectors = explode( ',', $shortened_selector );
3486 - $updated_selectors = array_map(
3487 - static function ( $split_selector ) use ( $clean_style_variation_selector ) {
3488 - return $clean_style_variation_selector . $split_selector;
3489 - },
3490 - $split_selectors
3491 - );
3492 - $combined_selectors = implode( ',', $updated_selectors );
3493 - }
3494 -
3495 - $feature_ruleset = static::to_ruleset( ':root :where(' . $combined_selectors . ')', $feature_decl );
3496 - $variation_responsive_css .= $breakpoint_media . '{' . $feature_ruleset . '}';
3497 - }
3498 -
3499 - // Process base properties for this breakpoint.
3500 - $breakpoint_declarations = static::compute_style_properties( $breakpoint_node, $settings, null, $this->theme_json );
3501 - if ( ! empty( $breakpoint_declarations ) ) {
3502 - $base_ruleset = static::to_ruleset( ':root :where(' . $style_variation['selector'] . ')', $breakpoint_declarations );
3503 - $variation_responsive_css .= $breakpoint_media . '{' . $base_ruleset . '}';
3504 - }
3505 -
3506 - $breakpoint_pseudo_declarations = static::process_pseudo_selectors( $breakpoint_node, $style_variation['selector'], $settings, $block_name );
3507 - foreach ( $breakpoint_pseudo_declarations as $pseudo_selector => $pseudo_declarations ) {
3508 - if ( empty( $pseudo_declarations ) ) {
3509 - continue;
3510 - }
3511 - $pseudo_ruleset = static::to_ruleset( ':root :where(' . $pseudo_selector . ')', $pseudo_declarations );
3512 - $variation_responsive_css .= $breakpoint_media . '{' . $pseudo_ruleset . '}';
3513 - }
3514 -
3515 - // Process custom CSS for this breakpoint.
3516 - if ( isset( $breakpoint_node['css'] ) ) {
3517 - $breakpoint_custom_css = static::process_blocks_custom_css( $breakpoint_node['css'], $style_variation['selector'] );
3518 - $variation_responsive_css .= $breakpoint_media . '{' . $breakpoint_custom_css . '}';
3519 - }
3520 -
3521 - // Process blockGap responsive layout styles for this variation.
3522 - if ( isset( $breakpoint_node['spacing']['blockGap'] ) ) {
3523 - $variation_layout_metadata = $style_variation;
3524 - $variation_layout_metadata['selector'] = $style_variation['selector'] . $block_metadata['css'];
3525 - $variation_responsive_css .= $this->get_layout_styles(
3526 - $variation_layout_metadata,
3527 - array(
3528 - 'node' => $breakpoint_node,
3529 - 'media_query' => $breakpoint_media,
3530 - )
3531 - );
3532 - }
3533 -
3534 - // Process nested element styles for this breakpoint state.
3535 - if ( isset( $breakpoint_node['elements'] ) && ! empty( $block_elements ) ) {
3536 - foreach ( $breakpoint_node['elements'] as $element_name => $element_node ) {
3537 - if ( ! isset( $block_elements[ $element_name ] ) ) {
3538 - continue;
3539 - }
3540 -
3541 - $clean_element_selector = preg_replace( '/,\s+/', ',', $block_elements[ $element_name ] );
3542 - $shortened_selector = str_replace( $block_metadata['selector'], '', $clean_element_selector );
3543 - $split_selectors = explode( ',', $shortened_selector );
3544 - $updated_selectors = array_map(
3545 - static function ( $split_selector ) use ( $clean_style_variation_selector ) {
3546 - return $clean_style_variation_selector . $split_selector;
3547 - },
3548 - $split_selectors
3549 - );
3550 - $variation_element_selector = implode( ',', $updated_selectors );
3551 -
3552 - $element_declarations = static::compute_style_properties( $element_node, $settings, null, $this->theme_json );
3553 - if ( ! empty( $element_declarations ) ) {
3554 - $element_ruleset = static::to_ruleset( ':root :where(' . $variation_element_selector . ')', $element_declarations );
3555 - $variation_responsive_css .= $breakpoint_media . '{' . $element_ruleset . '}';
3556 - }
3557 -
3558 - if ( isset( $element_node['css'] ) ) {
3559 - $element_custom_css = static::process_blocks_custom_css( $element_node['css'], $variation_element_selector );
3560 - $variation_responsive_css .= $breakpoint_media . '{' . $element_custom_css . '}';
3561 - }
3562 -
3563 - if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element_name ] ) ) {
3564 - foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element_name ] as $pseudo_selector ) {
3565 - if ( ! isset( $element_node[ $pseudo_selector ] ) ) {
3566 - continue;
3567 - }
3568 -
3569 - $pseudo_declarations = static::compute_style_properties( $element_node[ $pseudo_selector ], $settings, null, $this->theme_json );
3570 - if ( empty( $pseudo_declarations ) ) {
3571 - continue;
3572 - }
3573 -
3574 - $pseudo_selector_ruleset = static::to_ruleset( ':root :where(' . static::append_to_selector( $variation_element_selector, $pseudo_selector ) . ')', $pseudo_declarations );
3575 - $variation_responsive_css .= $breakpoint_media . '{' . $pseudo_selector_ruleset . '}';
3576 - }
3577 - }
3578 - }
3579 - }
3580 - }
3581 -
3582 - if ( ! empty( $variation_responsive_css ) ) {
3583 - $style_variation_responsive_css[ $style_variation['selector'] ] = $variation_responsive_css;
3584 - }
3585 3183 }
3586 3184 }
3185 +
3587 3186 /*
3588 3187 * Get a reference to element name from path.
3589 3188 * $block_metadata['path'] = array( 'styles','elements','link' );
3590 3189 * Make sure that $block_metadata['path'] describes an element node, like [ 'styles', 'element', 'link' ].
@@ -3600,8 +3199,25 @@
3600 3199 $element_pseudo_allowed = static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ];
3601 3200 }
3602 3201
3603 3202 /*
3203 + * Check if we're processing a block pseudo-selector.
3204 + * $block_metadata['path'] = array( 'styles', 'blocks', 'core/button', ':hover' );
3205 + */
3206 + $is_processing_block_pseudo = false;
3207 + $block_pseudo_selector = null;
3208 + if ( in_array( 'blocks', $block_metadata['path'], true ) && count( $block_metadata['path'] ) >= 4 ) {
3209 + $block_name = static::get_block_name_from_metadata_path( $block_metadata ); // 'core/button'
3210 + $last_path_element = $block_metadata['path'][ count( $block_metadata['path'] ) - 1 ]; // ':hover'
3211 +
3212 + if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block_name ] ) &&
3213 + in_array( $last_path_element, static::VALID_BLOCK_PSEUDO_SELECTORS[ $block_name ], true ) ) {
3214 + $is_processing_block_pseudo = true;
3215 + $block_pseudo_selector = $last_path_element;
3216 + }
3217 + }
3218 +
3219 + /*
3604 3220 * Check for allowed pseudo classes (e.g. ":hover") from the $selector ("a:hover").
3605 3221 * This also resets the array keys.
3606 3222 */
3607 3223 $pseudo_matches = array_values(
@@ -3628,14 +3244,17 @@
3628 3244 isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ] )
3629 3245 && in_array( $pseudo_selector, static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ], true )
3630 3246 ) {
3631 3247 $declarations = static::compute_style_properties( $node[ $pseudo_selector ], $settings, null, $this->theme_json, $selector, $use_root_padding );
3248 + } elseif ( $is_processing_block_pseudo ) {
3249 + // Process block pseudo-selector styles.
3250 + // For block pseudo-selectors, we need to get the block data first, then access the pseudo-selector.
3251 + $block_name = static::get_block_name_from_metadata_path( $block_metadata ); // 'core/button'
3252 + $block_data = _wp_array_get( $this->theme_json, array( 'styles', 'blocks', $block_name ), array() );
3253 + $pseudo_data = $block_data[ $block_pseudo_selector ] ?? array();
3254 +
3255 + $declarations = static::compute_style_properties( $pseudo_data, $settings, null, $this->theme_json, $selector, $use_root_padding );
3632 3256 } else {
3633 - /*
3634 - * For block pseudo-selector nodes (e.g. ':hover'), $node has already had any
3635 - * feature-selector properties (e.g. writingMode) removed by get_feature_declarations_for_node,
3636 - * so those properties are not output twice.
3637 - */
3638 3257 $declarations = static::compute_style_properties( $node, $settings, null, $this->theme_json, $selector, $use_root_padding );
3639 3258 }
3640 3259
3641 3260 $block_rules = '';
@@ -3746,32 +3365,20 @@
3746 3365 }
3747 3366 if ( isset( $style_variation_custom_css[ $style_variation_selector ] ) ) {
3748 3367 $block_rules .= $style_variation_custom_css[ $style_variation_selector ];
3749 3368 }
3750 - if ( isset( $style_variation_responsive_css[ $style_variation_selector ] ) ) {
3751 - $block_rules .= $style_variation_responsive_css[ $style_variation_selector ];
3752 - }
3753 3369 }
3754 3370
3755 - // Compute selector for block custom CSS.
3756 - $css_feature_selector = $block_metadata['selectors']['css'] ?? null;
3757 - if ( is_array( $css_feature_selector ) ) {
3758 - $css_feature_selector = $css_feature_selector['root'] ?? null;
3759 - }
3760 - $css_selector = is_string( $css_feature_selector ) ? $css_feature_selector : $selector;
3761 -
3762 3371 // 7. Generate and append any custom CSS rules.
3763 3372 if ( isset( $node['css'] ) && ! $is_root_selector ) {
3373 + $css_feature_selector = $block_metadata['selectors']['css'] ?? null;
3374 + if ( is_array( $css_feature_selector ) ) {
3375 + $css_feature_selector = $css_feature_selector['root'] ?? null;
3376 + }
3377 + $css_selector = is_string( $css_feature_selector ) ? $css_feature_selector : $selector;
3764 3378 $block_rules .= $this->process_blocks_custom_css( $node['css'], $css_selector );
3765 3379 }
3766 3380
3767 - // 8. Wrap the entire block output in a media query if this is a responsive node.
3768 - // Responsive nodes are created by get_block_nodes() for each breakpoint and carry
3769 - // a 'media_query' key.
3770 - if ( $media_query && ! empty( $block_rules ) ) {
3771 - $block_rules = $media_query . '{' . $block_rules . '}';
3772 - }
3773 -
3774 3381 return $block_rules;
3775 3382 }
3776 3383
3777 3384 /**
@@ -4265,12 +3872,8 @@
4265 3872 if ( empty( $input ) ) {
4266 3873 continue;
4267 3874 }
4268 3875
4269 - $block_name = in_array( 'blocks', $metadata['path'], true )
4270 - ? static::get_block_name_from_metadata_path( $metadata )
4271 - : null;
4272 -
4273 3876 // The global styles custom CSS is not sanitized, but can only be edited by users with 'edit_css' capability.
4274 3877 if ( isset( $input['css'] ) && current_user_can( 'edit_css' ) ) {
4275 3878 $output = $input;
4276 3879 } else {
@@ -4294,36 +3897,8 @@
4294 3897 }
4295 3898 }
4296 3899 }
4297 3900
4298 - // Re-add and process responsive breakpoint styles.
4299 - foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) {
4300 - if ( isset( $input[ $breakpoint ] ) ) {
4301 - $output[ $breakpoint ] = static::remove_insecure_styles( $input[ $breakpoint ] );
4302 -
4303 - if ( isset( $input[ $breakpoint ]['elements'] ) ) {
4304 - $output[ $breakpoint ]['elements'] = static::remove_insecure_element_styles( $input[ $breakpoint ]['elements'] );
4305 - }
4306 -
4307 - if ( isset( $input[ $breakpoint ]['blocks'] ) ) {
4308 - $output[ $breakpoint ]['blocks'] = static::remove_insecure_inner_block_styles( $input[ $breakpoint ]['blocks'] );
4309 - }
4310 -
4311 - if ( $block_name && isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block_name ] ) ) {
4312 - foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block_name ] as $pseudo_selector ) {
4313 - if ( isset( $input[ $breakpoint ][ $pseudo_selector ] ) ) {
4314 - $output[ $breakpoint ][ $pseudo_selector ] = static::remove_insecure_styles( $input[ $breakpoint ][ $pseudo_selector ] );
4315 - }
4316 - }
4317 - }
4318 -
4319 - // Responsive custom CSS is allowed for users with 'edit_css' capability.
4320 - if ( isset( $input[ $breakpoint ]['css'] ) && current_user_can( 'edit_css' ) ) {
4321 - $output[ $breakpoint ]['css'] = $input[ $breakpoint ]['css'];
4322 - }
4323 - }
4324 - }
4325 -
4326 3901 if ( ! empty( $output ) ) {
4327 3902 _wp_array_set( $sanitized, $metadata['path'], $output );
4328 3903 }
4329 3904
@@ -4343,36 +3918,8 @@
4343 3918 if ( isset( $variation_input['elements'] ) ) {
4344 3919 $variation_output['elements'] = static::remove_insecure_element_styles( $variation_input['elements'] );
4345 3920 }
4346 3921
4347 - // Re-add and process responsive breakpoint styles for variations.
4348 - foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) {
4349 - if ( isset( $variation_input[ $breakpoint ] ) ) {
4350 - $variation_output[ $breakpoint ] = static::remove_insecure_styles( $variation_input[ $breakpoint ] );
4351 -
4352 - if ( isset( $variation_input[ $breakpoint ]['elements'] ) ) {
4353 - $variation_output[ $breakpoint ]['elements'] = static::remove_insecure_element_styles( $variation_input[ $breakpoint ]['elements'] );
4354 - }
4355 -
4356 - if ( isset( $variation_input[ $breakpoint ]['blocks'] ) ) {
4357 - $variation_output[ $breakpoint ]['blocks'] = static::remove_insecure_inner_block_styles( $variation_input[ $breakpoint ]['blocks'] );
4358 - }
4359 -
4360 - if ( $block_name && isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block_name ] ) ) {
4361 - foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block_name ] as $pseudo_selector ) {
4362 - if ( isset( $variation_input[ $breakpoint ][ $pseudo_selector ] ) ) {
4363 - $variation_output[ $breakpoint ][ $pseudo_selector ] = static::remove_insecure_styles( $variation_input[ $breakpoint ][ $pseudo_selector ] );
4364 - }
4365 - }
4366 - }
4367 -
4368 - // Responsive custom CSS is allowed for users with 'edit_css' capability.
4369 - if ( isset( $variation_input[ $breakpoint ]['css'] ) && current_user_can( 'edit_css' ) ) {
4370 - $variation_output[ $breakpoint ]['css'] = $variation_input[ $breakpoint ]['css'];
4371 - }
4372 - }
4373 - }
4374 -
4375 3922 if ( ! empty( $variation_output ) ) {
4376 3923 _wp_array_set( $sanitized, $variation['path'], $variation_output );
4377 3924 }
4378 3925 }
@@ -4431,23 +3978,8 @@
4431 3978 }
4432 3979 }
4433 3980 }
4434 3981
4435 - // Re-add and process responsive breakpoint styles for elements.
4436 - foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) {
4437 - if ( isset( $element_input[ $breakpoint ] ) ) {
4438 - $element_output[ $breakpoint ] = static::remove_insecure_styles( $element_input[ $breakpoint ] );
4439 -
4440 - if ( isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element_name ] ) ) {
4441 - foreach ( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $element_name ] as $pseudo_selector ) {
4442 - if ( isset( $element_input[ $breakpoint ][ $pseudo_selector ] ) ) {
4443 - $element_output[ $breakpoint ][ $pseudo_selector ] = static::remove_insecure_styles( $element_input[ $breakpoint ][ $pseudo_selector ] );
4444 - }
4445 - }
4446 - }
4447 - }
4448 - }
4449 -
4450 3982 $sanitized[ $element_name ] = $element_output;
4451 3983 }
4452 3984 }
4453 3985 return $sanitized;
@@ -4467,23 +3999,8 @@
4467 3999 $block_output = static::remove_insecure_styles( $block_input );
4468 4000
4469 4001 if ( isset( $block_input['elements'] ) ) {
4470 4002 $block_output['elements'] = static::remove_insecure_element_styles( $block_input['elements'] );
4471 - }
4472 -
4473 - // Re-add and process responsive breakpoint styles for inner blocks.
4474 - foreach ( array_keys( static::RESPONSIVE_BREAKPOINTS ) as $breakpoint ) {
4475 - if ( isset( $block_input[ $breakpoint ] ) ) {
4476 - $block_output[ $breakpoint ] = static::remove_insecure_styles( $block_input[ $breakpoint ] );
4477 -
4478 - if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block_type ] ) ) {
4479 - foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block_type ] as $pseudo_selector ) {
4480 - if ( isset( $block_input[ $breakpoint ][ $pseudo_selector ] ) ) {
4481 - $block_output[ $breakpoint ][ $pseudo_selector ] = static::remove_insecure_styles( $block_input[ $breakpoint ][ $pseudo_selector ] );
4482 - }
4483 - }
4484 - }
4485 - }
4486 4003 }
4487 4004
4488 4005 $sanitized[ $block_type ] = $block_output;
4489 4006 }