| @@ -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,34 +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 | - * Custom states for blocks that map to CSS class selectors rather than | |
| 625 | - * CSS pseudo-selectors. Values use the '@' prefix (e.g. '@current') to | |
| 626 | - * distinguish them from real CSS pseudo-selectors. | |
| 627 | - * | |
| 628 | - * The CSS selector for each state is defined in the block's block.json | |
| 629 | - * under `selectors.states`, e.g.: | |
| 630 | - * | |
| 631 | - * "selectors": { "states": { "@current": ".some-css-selector" } } | |
| 632 | - * | |
| 633 | - * This constant controls which states are valid in theme.json for a given | |
| 634 | - * block. Blocks listed here also inherit their VALID_BLOCK_PSEUDO_SELECTORS | |
| 635 | - * as valid sub-states, producing compound selectors such as | |
| 636 | - * `.wp-block-navigation-item.current-menu-item:hover`. | |
| 637 | - * | |
| 638 | - * @var array | |
| 639 | - */ | |
| 640 | - const VALID_BLOCK_CUSTOM_STATES = array( | |
| 641 | - 'core/navigation-link' => array( '@current' ), | |
| 642 | - ); | |
| 643 | - | |
| 644 | - /** | |
| 645 | 617 | * The valid elements that can be found under styles. |
| 646 | 618 | * |
| 647 | 619 | * @since 5.8.0 |
| 648 | 620 | * @since 6.1.0 Added `heading`, `button`, and `caption` elements. |
| @@ -787,9 +759,8 @@ | ||
| 787 | 759 | */ |
| 788 | 760 | const APPEARANCE_TOOLS_OPT_INS = array( |
| 789 | 761 | array( 'background', 'backgroundImage' ), |
| 790 | 762 | array( 'background', 'backgroundSize' ), |
| 791 | - array( 'background', 'gradient' ), | |
| 792 | 763 | array( 'border', 'color' ), |
| 793 | 764 | array( 'border', 'radius' ), |
| 794 | 765 | array( 'border', 'style' ), |
| 795 | 766 | array( 'border', 'width' ), |
| @@ -799,9 +770,8 @@ | ||
| 799 | 770 | array( 'color', 'caption' ), |
| 800 | 771 | array( 'dimensions', 'aspectRatio' ), |
| 801 | 772 | array( 'dimensions', 'height' ), |
| 802 | 773 | array( 'dimensions', 'minHeight' ), |
| 803 | - array( 'dimensions', 'minWidth' ), | |
| 804 | 774 | array( 'dimensions', 'width' ), |
| 805 | 775 | // BEGIN EXPERIMENTAL. |
| 806 | 776 | // Allow `position.fixed` to be opted-in by default. |
| 807 | 777 | // Sticky position support was backported to WordPress 6.2 in https://core.trac.wordpress.org/ticket/57618. |
| @@ -1092,23 +1062,8 @@ | ||
| 1092 | 1062 | foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] as $pseudo_selector ) { |
| 1093 | 1063 | $schema_styles_blocks[ $block ][ $pseudo_selector ] = $styles_non_top_level; |
| 1094 | 1064 | } |
| 1095 | 1065 | } |
| 1096 | - | |
| 1097 | - // Add custom states for blocks that support them (e.g. '@current' for navigation). | |
| 1098 | - if ( isset( static::VALID_BLOCK_CUSTOM_STATES[ $block ] ) ) { | |
| 1099 | - foreach ( static::VALID_BLOCK_CUSTOM_STATES[ $block ] as $custom_state ) { | |
| 1100 | - $custom_state_schema = $styles_non_top_level; | |
| 1101 | - // The same pseudo-selectors valid for the block at the top level | |
| 1102 | - // are also valid within each custom state. | |
| 1103 | - if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] ) ) { | |
| 1104 | - foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $block ] as $pseudo ) { | |
| 1105 | - $custom_state_schema[ $pseudo ] = $styles_non_top_level; | |
| 1106 | - } | |
| 1107 | - } | |
| 1108 | - $schema_styles_blocks[ $block ][ $custom_state ] = $custom_state_schema; | |
| 1109 | - } | |
| 1110 | - } | |
| 1111 | 1066 | } |
| 1112 | 1067 | |
| 1113 | 1068 | $block_style_variation_styles = static::VALID_STYLES; |
| 1114 | 1069 | $block_style_variation_styles['blocks'] = $schema_styles_blocks; |
| @@ -1334,13 +1289,8 @@ | ||
| 1334 | 1289 | |
| 1335 | 1290 | if ( ! empty( $style_selectors ) ) { |
| 1336 | 1291 | static::$blocks_metadata[ $block_name ]['styleVariations'] = $style_selectors; |
| 1337 | 1292 | } |
| 1338 | - | |
| 1339 | - // If the block has custom states defined in block.json, store their selectors. | |
| 1340 | - if ( ! empty( $block_type->selectors['states'] ) && is_array( $block_type->selectors['states'] ) ) { | |
| 1341 | - static::$blocks_metadata[ $block_name ]['states'] = $block_type->selectors['states']; | |
| 1342 | - } | |
| 1343 | 1293 | } |
| 1344 | 1294 | |
| 1345 | 1295 | return static::$blocks_metadata; |
| 1346 | 1296 | } |
| @@ -2097,9 +2047,8 @@ | ||
| 2097 | 2047 | * Given a selector and a declaration list, |
| 2098 | 2048 | * creates the corresponding ruleset. |
| 2099 | 2049 | * |
| 2100 | 2050 | * @since 5.8.0 |
| 2101 | - * @since 7.1.0 Skip declarations whose value is not a plain string (booleans, arrays, objects, etc.). | |
| 2102 | 2051 | * |
| 2103 | 2052 | * @param string $selector CSS selector. |
| 2104 | 2053 | * @param array $declarations List of declarations. |
| 2105 | 2054 | * @return string The resulting CSS ruleset. |
| @@ -2111,20 +2060,9 @@ | ||
| 2111 | 2060 | |
| 2112 | 2061 | $declaration_block = array_reduce( |
| 2113 | 2062 | $declarations, |
| 2114 | 2063 | static function ( $carry, $element ) { |
| 2115 | - $value = $element['value']; | |
| 2116 | - | |
| 2117 | - if ( is_numeric( $value ) ) { | |
| 2118 | - $value = (string) $value; | |
| 2119 | - } | |
| 2120 | - | |
| 2121 | - if ( ! is_string( $value ) ) { | |
| 2122 | - return $carry; | |
| 2123 | - } | |
| 2124 | - | |
| 2125 | - return $carry .= $element['name'] . ': ' . $value . ';'; | |
| 2126 | - }, | |
| 2064 | + return $carry .= $element['name'] . ': ' . $element['value'] . ';'; }, | |
| 2127 | 2065 | '' |
| 2128 | 2066 | ); |
| 2129 | 2067 | |
| 2130 | 2068 | return $selector . '{' . $declaration_block . '}'; |
| @@ -2563,23 +2501,14 @@ | ||
| 2563 | 2501 | * If the value is a URL, it will be converted to a CSS `url()` value. |
| 2564 | 2502 | * For an uploaded image (images with a database ID), apply size and position |
| 2565 | 2503 | * defaults equal to those applied in block supports in lib/background.php. |
| 2566 | 2504 | */ |
| 2567 | - if ( 'background-image' === $css_property ) { | |
| 2568 | - $background_image_input = array(); | |
| 2569 | - if ( ! empty( $value ) ) { | |
| 2570 | - $background_image_input['backgroundImage'] = $value; | |
| 2571 | - } | |
| 2572 | - $gradient_value = $styles['background']['gradient'] ?? null; | |
| 2573 | - if ( ! empty( $gradient_value ) ) { | |
| 2574 | - $background_image_input['gradient'] = $gradient_value; | |
| 2575 | - } | |
| 2576 | - if ( ! empty( $background_image_input ) ) { | |
| 2577 | - $background_styles = gutenberg_style_engine_get_styles( | |
| 2578 | - array( 'background' => $background_image_input ) | |
| 2579 | - ); | |
| 2580 | - $value = $background_styles['declarations'][ $css_property ] ?? null; | |
| 2581 | - } | |
| 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 ]; | |
| 2582 | 2511 | } |
| 2583 | 2512 | if ( empty( $value ) && static::ROOT_BLOCK_SELECTOR !== $selector && ! empty( $styles['background']['backgroundImage']['id'] ) ) { |
| 2584 | 2513 | if ( 'background-size' === $css_property ) { |
| 2585 | 2514 | $value = 'cover'; |
| @@ -3104,31 +3033,13 @@ | ||
| 3104 | 3033 | // Handle any pseudo selectors for the block. |
| 3105 | 3034 | if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $name ] ) ) { |
| 3106 | 3035 | foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $name ] as $pseudo_selector ) { |
| 3107 | 3036 | if ( isset( $theme_json['styles']['blocks'][ $name ][ $pseudo_selector ] ) ) { |
| 3108 | - /* | |
| 3109 | - * Append the pseudo-selector to each feature selector so that | |
| 3110 | - * get_feature_declarations_for_node generates CSS scoped to the | |
| 3111 | - * pseudo-state (e.g. '.wp-block-button:hover') rather than the | |
| 3112 | - * default state (e.g. '.wp-block-button'). | |
| 3113 | - */ | |
| 3114 | - $pseudo_feature_selectors = array(); | |
| 3115 | - foreach ( $feature_selectors ?? array() as $feature => $feature_selector ) { | |
| 3116 | - if ( is_array( $feature_selector ) ) { | |
| 3117 | - $pseudo_feature_selectors[ $feature ] = array(); | |
| 3118 | - foreach ( $feature_selector as $subfeature => $subfeature_selector ) { | |
| 3119 | - $pseudo_feature_selectors[ $feature ][ $subfeature ] = static::append_to_selector( $subfeature_selector, $pseudo_selector ); | |
| 3120 | - } | |
| 3121 | - } else { | |
| 3122 | - $pseudo_feature_selectors[ $feature ] = static::append_to_selector( $feature_selector, $pseudo_selector ); | |
| 3123 | - } | |
| 3124 | - } | |
| 3125 | - | |
| 3126 | 3037 | $nodes[] = array( |
| 3127 | 3038 | 'name' => $name, |
| 3128 | 3039 | 'path' => array( 'styles', 'blocks', $name, $pseudo_selector ), |
| 3129 | 3040 | 'selector' => static::append_to_selector( $selector, $pseudo_selector ), |
| 3130 | - 'selectors' => $pseudo_feature_selectors, | |
| 3041 | + 'selectors' => $feature_selectors, | |
| 3131 | 3042 | 'duotone' => $duotone_selector, |
| 3132 | 3043 | 'variations' => $variation_selectors, |
| 3133 | 3044 | 'css' => static::append_to_selector( $selector, $pseudo_selector ), |
| 3134 | 3045 | ); |
| @@ -3134,47 +3045,8 @@ | ||
| 3134 | 3045 | ); |
| 3135 | 3046 | } |
| 3136 | 3047 | } |
| 3137 | 3048 | } |
| 3138 | - | |
| 3139 | - // Handle custom states (e.g. '@current' for navigation). | |
| 3140 | - if ( isset( static::VALID_BLOCK_CUSTOM_STATES[ $name ] ) ) { | |
| 3141 | - foreach ( static::VALID_BLOCK_CUSTOM_STATES[ $name ] as $custom_state ) { | |
| 3142 | - if ( | |
| 3143 | - isset( $theme_json['styles']['blocks'][ $name ][ $custom_state ] ) && | |
| 3144 | - isset( $selectors[ $name ]['states'][ $custom_state ] ) | |
| 3145 | - ) { | |
| 3146 | - $custom_css_selector = $selectors[ $name ]['states'][ $custom_state ]; | |
| 3147 | - $nodes[] = array( | |
| 3148 | - 'name' => $name, | |
| 3149 | - 'path' => array( 'styles', 'blocks', $name, $custom_state ), | |
| 3150 | - 'selector' => $custom_css_selector, | |
| 3151 | - 'selectors' => $feature_selectors, | |
| 3152 | - 'duotone' => $duotone_selector, | |
| 3153 | - 'variations' => $variation_selectors, | |
| 3154 | - 'css' => $custom_css_selector, | |
| 3155 | - ); | |
| 3156 | - | |
| 3157 | - // Sub-pseudo-selectors within the custom state. | |
| 3158 | - if ( isset( static::VALID_BLOCK_PSEUDO_SELECTORS[ $name ] ) ) { | |
| 3159 | - foreach ( static::VALID_BLOCK_PSEUDO_SELECTORS[ $name ] as $pseudo ) { | |
| 3160 | - if ( isset( $theme_json['styles']['blocks'][ $name ][ $custom_state ][ $pseudo ] ) ) { | |
| 3161 | - $compound_css_selector = static::append_to_selector( $custom_css_selector, $pseudo ); | |
| 3162 | - $nodes[] = array( | |
| 3163 | - 'name' => $name, | |
| 3164 | - 'path' => array( 'styles', 'blocks', $name, $custom_state, $pseudo ), | |
| 3165 | - 'selector' => $compound_css_selector, | |
| 3166 | - 'selectors' => $feature_selectors, | |
| 3167 | - 'duotone' => $duotone_selector, | |
| 3168 | - 'variations' => $variation_selectors, | |
| 3169 | - 'css' => $compound_css_selector, | |
| 3170 | - ); | |
| 3171 | - } | |
| 3172 | - } | |
| 3173 | - } | |
| 3174 | - } | |
| 3175 | - } | |
| 3176 | - } | |
| 3177 | 3049 | } |
| 3178 | 3050 | if ( isset( $theme_json['styles']['blocks'][ $name ]['elements'] ) ) { |
| 3179 | 3051 | foreach ( $theme_json['styles']['blocks'][ $name ]['elements'] as $element => $node ) { |
| 3180 | 3052 | $node_path = array( 'styles', 'blocks', $name, 'elements', $element ); |
| @@ -3327,8 +3199,25 @@ | ||
| 3327 | 3199 | $element_pseudo_allowed = static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ]; |
| 3328 | 3200 | } |
| 3329 | 3201 | |
| 3330 | 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 | + /* | |
| 3331 | 3220 | * Check for allowed pseudo classes (e.g. ":hover") from the $selector ("a:hover"). |
| 3332 | 3221 | * This also resets the array keys. |
| 3333 | 3222 | */ |
| 3334 | 3223 | $pseudo_matches = array_values( |
| @@ -3355,14 +3244,17 @@ | ||
| 3355 | 3244 | isset( static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ] ) |
| 3356 | 3245 | && in_array( $pseudo_selector, static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ], true ) |
| 3357 | 3246 | ) { |
| 3358 | 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 ); | |
| 3359 | 3256 | } else { |
| 3360 | - /* | |
| 3361 | - * For block pseudo-selector nodes (e.g. ':hover'), $node has already had any | |
| 3362 | - * feature-selector properties (e.g. writingMode) removed by get_feature_declarations_for_node, | |
| 3363 | - * so those properties are not output twice. | |
| 3364 | - */ | |
| 3365 | 3257 | $declarations = static::compute_style_properties( $node, $settings, null, $this->theme_json, $selector, $use_root_padding ); |
| 3366 | 3258 | } |
| 3367 | 3259 | |
| 3368 | 3260 | $block_rules = ''; |