Changeset 54159 for trunk/src/wp-includes/class-wp-theme-json.php
- Timestamp:
- 09/14/2022 02:19:16 PM (2 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/class-wp-theme-json.php
r54133 r54159 178 178 * `text-decoration`, `text-transform`, and `filter` properties, 179 179 * simplified the metadata structure. 180 * @since 6.1.0 Added the `border-*-color`, `border-*-width`, `border-*-style`, 181 * `--wp--style--root--padding-*`, and `box-shadow` properties, 182 * removed the `--wp--style--block-gap` property. 180 183 * @var array 181 184 */ 182 185 const PROPERTIES_METADATA = array( 183 'background' => array( 'color', 'gradient' ), 184 'background-color' => array( 'color', 'background' ), 185 'border-radius' => array( 'border', 'radius' ), 186 'border-top-left-radius' => array( 'border', 'radius', 'topLeft' ), 187 'border-top-right-radius' => array( 'border', 'radius', 'topRight' ), 188 'border-bottom-left-radius' => array( 'border', 'radius', 'bottomLeft' ), 189 'border-bottom-right-radius' => array( 'border', 'radius', 'bottomRight' ), 190 'border-color' => array( 'border', 'color' ), 191 'border-width' => array( 'border', 'width' ), 192 'border-style' => array( 'border', 'style' ), 193 'color' => array( 'color', 'text' ), 194 'font-family' => array( 'typography', 'fontFamily' ), 195 'font-size' => array( 'typography', 'fontSize' ), 196 'font-style' => array( 'typography', 'fontStyle' ), 197 'font-weight' => array( 'typography', 'fontWeight' ), 198 'letter-spacing' => array( 'typography', 'letterSpacing' ), 199 'line-height' => array( 'typography', 'lineHeight' ), 200 'margin' => array( 'spacing', 'margin' ), 201 'margin-top' => array( 'spacing', 'margin', 'top' ), 202 'margin-right' => array( 'spacing', 'margin', 'right' ), 203 'margin-bottom' => array( 'spacing', 'margin', 'bottom' ), 204 'margin-left' => array( 'spacing', 'margin', 'left' ), 205 'padding' => array( 'spacing', 'padding' ), 206 'padding-top' => array( 'spacing', 'padding', 'top' ), 207 'padding-right' => array( 'spacing', 'padding', 'right' ), 208 'padding-bottom' => array( 'spacing', 'padding', 'bottom' ), 209 'padding-left' => array( 'spacing', 'padding', 'left' ), 210 '--wp--style--block-gap' => array( 'spacing', 'blockGap' ), 211 'text-decoration' => array( 'typography', 'textDecoration' ), 212 'text-transform' => array( 'typography', 'textTransform' ), 213 'filter' => array( 'filter', 'duotone' ), 186 'background' => array( 'color', 'gradient' ), 187 'background-color' => array( 'color', 'background' ), 188 'border-radius' => array( 'border', 'radius' ), 189 'border-top-left-radius' => array( 'border', 'radius', 'topLeft' ), 190 'border-top-right-radius' => array( 'border', 'radius', 'topRight' ), 191 'border-bottom-left-radius' => array( 'border', 'radius', 'bottomLeft' ), 192 'border-bottom-right-radius' => array( 'border', 'radius', 'bottomRight' ), 193 'border-color' => array( 'border', 'color' ), 194 'border-width' => array( 'border', 'width' ), 195 'border-style' => array( 'border', 'style' ), 196 'border-top-color' => array( 'border', 'top', 'color' ), 197 'border-top-width' => array( 'border', 'top', 'width' ), 198 'border-top-style' => array( 'border', 'top', 'style' ), 199 'border-right-color' => array( 'border', 'right', 'color' ), 200 'border-right-width' => array( 'border', 'right', 'width' ), 201 'border-right-style' => array( 'border', 'right', 'style' ), 202 'border-bottom-color' => array( 'border', 'bottom', 'color' ), 203 'border-bottom-width' => array( 'border', 'bottom', 'width' ), 204 'border-bottom-style' => array( 'border', 'bottom', 'style' ), 205 'border-left-color' => array( 'border', 'left', 'color' ), 206 'border-left-width' => array( 'border', 'left', 'width' ), 207 'border-left-style' => array( 'border', 'left', 'style' ), 208 'color' => array( 'color', 'text' ), 209 'font-family' => array( 'typography', 'fontFamily' ), 210 'font-size' => array( 'typography', 'fontSize' ), 211 'font-style' => array( 'typography', 'fontStyle' ), 212 'font-weight' => array( 'typography', 'fontWeight' ), 213 'letter-spacing' => array( 'typography', 'letterSpacing' ), 214 'line-height' => array( 'typography', 'lineHeight' ), 215 'margin' => array( 'spacing', 'margin' ), 216 'margin-top' => array( 'spacing', 'margin', 'top' ), 217 'margin-right' => array( 'spacing', 'margin', 'right' ), 218 'margin-bottom' => array( 'spacing', 'margin', 'bottom' ), 219 'margin-left' => array( 'spacing', 'margin', 'left' ), 220 'padding' => array( 'spacing', 'padding' ), 221 'padding-top' => array( 'spacing', 'padding', 'top' ), 222 'padding-right' => array( 'spacing', 'padding', 'right' ), 223 'padding-bottom' => array( 'spacing', 'padding', 'bottom' ), 224 'padding-left' => array( 'spacing', 'padding', 'left' ), 225 '--wp--style--root--padding' => array( 'spacing', 'padding' ), 226 '--wp--style--root--padding-top' => array( 'spacing', 'padding', 'top' ), 227 '--wp--style--root--padding-right' => array( 'spacing', 'padding', 'right' ), 228 '--wp--style--root--padding-bottom' => array( 'spacing', 'padding', 'bottom' ), 229 '--wp--style--root--padding-left' => array( 'spacing', 'padding', 'left' ), 230 'text-decoration' => array( 'typography', 'textDecoration' ), 231 'text-transform' => array( 'typography', 'textTransform' ), 232 'filter' => array( 'filter', 'duotone' ), 233 'box-shadow' => array( 'shadow' ), 214 234 ); 215 235 … … 255 275 * and `typography`, and renamed others according to the new schema. 256 276 * @since 6.0.0 Added `color.defaultDuotone`. 277 * @since 6.1.0 Added `layout.definitions` and `useRootPaddingAwareAlignments`. 257 278 * @var array 258 279 */ 259 280 const VALID_SETTINGS = array( 260 'appearanceTools' => null, 261 'border' => array( 281 'appearanceTools' => null, 282 'useRootPaddingAwareAlignments' => null, 283 'border' => array( 262 284 'color' => null, 263 285 'radius' => null, … … 265 287 'width' => null, 266 288 ), 267 'color' => array(289 'color' => array( 268 290 'background' => null, 269 291 'custom' => null, … … 279 301 'text' => null, 280 302 ), 281 'custom' => null,282 'layout' => array(303 'custom' => null, 304 'layout' => array( 283 305 'contentSize' => null, 284 306 'wideSize' => null, 285 307 ), 286 'spacing' => array(308 'spacing' => array( 287 309 'blockGap' => null, 288 310 'margin' => null, … … 290 312 'units' => null, 291 313 ), 292 'typography' => array(314 'typography' => array( 293 315 'customFontSize' => null, 294 316 'dropCap' => null, … … 311 333 * added new properties for `border`, `filter`, `spacing`, 312 334 * and `typography`. 335 * @since 6.1.0 Added new side properties for `border`, 336 * updated `blockGap` to be allowed at any level. 313 337 * @var array 314 338 */ … … 319 343 'style' => null, 320 344 'width' => null, 345 'top' => null, 346 'right' => null, 347 'bottom' => null, 348 'left' => null, 321 349 ), 322 350 'color' => array( … … 331 359 'margin' => null, 332 360 'padding' => null, 333 'blockGap' => 'top',361 'blockGap' => null, 334 362 ), 335 363 'typography' => array( … … 382 410 'button' => 'wp-element-button', 383 411 'caption' => 'wp-element-caption', 412 ); 413 414 /** 415 * List of block support features that can have their related styles 416 * generated under their own feature level selector rather than the block's. 417 * 418 * @since 6.1.0 419 * @var string[] 420 */ 421 const BLOCK_SUPPORT_FEATURE_LEVEL_SELECTORS = array( 422 '__experimentalBorder' => 'border', 423 'color' => 'color', 424 'spacing' => 'spacing', 425 'typography' => 'typography', 384 426 ); 385 427 … … 657 699 * @since 5.8.0 658 700 * @since 5.9.0 Added `duotone` key with CSS selector. 701 * @since 6.1.0 Added `features` key with block support feature level selectors. 659 702 * 660 703 * @return array Block metadata. … … 684 727 ) { 685 728 static::$blocks_metadata[ $block_name ]['duotone'] = $block_type->supports['color']['__experimentalDuotone']; 729 } 730 731 // Generate block support feature level selectors if opted into 732 // for the current block. 733 $features = array(); 734 foreach ( static::BLOCK_SUPPORT_FEATURE_LEVEL_SELECTORS as $key => $feature ) { 735 if ( 736 isset( $block_type->supports[ $key ]['__experimentalSelector'] ) && 737 $block_type->supports[ $key ]['__experimentalSelector'] 738 ) { 739 $features[ $feature ] = static::scope_selector( 740 static::$blocks_metadata[ $block_name ]['selector'], 741 $block_type->supports[ $key ]['__experimentalSelector'] 742 ); 743 } 744 } 745 746 if ( ! empty( $features ) ) { 747 static::$blocks_metadata[ $block_name ]['features'] = $features; 686 748 } 687 749 … … 811 873 812 874 if ( in_array( 'styles', $types, true ) ) { 875 $root_block_key = array_search( static::ROOT_BLOCK_SELECTOR, array_column( $style_nodes, 'selector' ), true ); 876 877 if ( false !== $root_block_key ) { 878 $stylesheet .= $this->get_root_layout_rules( static::ROOT_BLOCK_SELECTOR, $style_nodes[ $root_block_key ] ); 879 } 813 880 $stylesheet .= $this->get_block_classes( $style_nodes ); 881 } elseif ( in_array( 'base-layout-styles', $types, true ) ) { 882 // Base layout styles are provided as part of `styles`, so only output separately if explicitly requested. 883 // For backwards compatibility, the Columns block is explicitly included, to support a different default gap value. 884 $base_styles_nodes = array( 885 array( 886 'path' => array( 'styles' ), 887 'selector' => static::ROOT_BLOCK_SELECTOR, 888 ), 889 array( 890 'path' => array( 'styles', 'blocks', 'core/columns' ), 891 'selector' => '.wp-block-columns', 892 'name' => 'core/columns', 893 ), 894 ); 895 896 foreach ( $base_styles_nodes as $base_style_node ) { 897 $stylesheet .= $this->get_layout_styles( $base_style_node ); 898 } 814 899 } 815 900 … … 885 970 * and no longer returns preset classes. 886 971 * Removed the `$setting_nodes` parameter. 972 * @since 6.1.0 Moved most internal logic to `get_styles_for_block()`. 887 973 * 888 974 * @param array $style_nodes Nodes with styles. … … 899 985 } 900 986 987 return $block_rules; 988 } 989 990 /** 991 * Get the CSS layout rules for a particular block from theme.json layout definitions. 992 * 993 * @since 6.1.0 994 * 995 * @param array $block_metadata Metadata about the block to get styles for. 996 * 997 * @return string Layout styles for the block. 998 */ 999 protected function get_layout_styles( $block_metadata ) { 1000 $block_rules = ''; 1001 $block_type = null; 1002 1003 // Skip outputting layout styles if explicitly disabled. 1004 if ( current_theme_supports( 'disable-layout-styles' ) ) { 1005 return $block_rules; 1006 } 1007 1008 if ( isset( $block_metadata['name'] ) ) { 1009 $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block_metadata['name'] ); 1010 if ( ! block_has_support( $block_type, array( '__experimentalLayout' ), false ) ) { 1011 return $block_rules; 1012 } 1013 } 1014 1015 $selector = isset( $block_metadata['selector'] ) ? $block_metadata['selector'] : ''; 1016 $has_block_gap_support = _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'blockGap' ) ) !== null; 1017 $has_fallback_gap_support = ! $has_block_gap_support; // This setting isn't useful yet: it exists as a placeholder for a future explicit fallback gap styles support. 1018 $node = _wp_array_get( $this->theme_json, $block_metadata['path'], array() ); 1019 $layout_definitions = _wp_array_get( $this->theme_json, array( 'settings', 'layout', 'definitions' ), array() ); 1020 $layout_selector_pattern = '/^[a-zA-Z0-9\-\.\ *+>:\(\)]*$/'; // Allow alphanumeric classnames, spaces, wildcard, sibling, child combinator and pseudo class selectors. 1021 1022 // Gap styles will only be output if the theme has block gap support, or supports a fallback gap. 1023 // Default layout gap styles will be skipped for themes that do not explicitly opt-in to blockGap with a `true` or `false` value. 1024 if ( $has_block_gap_support || $has_fallback_gap_support ) { 1025 $block_gap_value = null; 1026 // Use a fallback gap value if block gap support is not available. 1027 if ( ! $has_block_gap_support ) { 1028 $block_gap_value = static::ROOT_BLOCK_SELECTOR === $selector ? '0.5em' : null; 1029 if ( ! empty( $block_type ) ) { 1030 $block_gap_value = _wp_array_get( $block_type->supports, array( 'spacing', 'blockGap', '__experimentalDefault' ), null ); 1031 } 1032 } else { 1033 $block_gap_value = static::get_property_value( $node, array( 'spacing', 'blockGap' ) ); 1034 } 1035 1036 // Support split row / column values and concatenate to a shorthand value. 1037 if ( is_array( $block_gap_value ) ) { 1038 if ( isset( $block_gap_value['top'] ) && isset( $block_gap_value['left'] ) ) { 1039 $gap_row = static::get_property_value( $node, array( 'spacing', 'blockGap', 'top' ) ); 1040 $gap_column = static::get_property_value( $node, array( 'spacing', 'blockGap', 'left' ) ); 1041 $block_gap_value = $gap_row === $gap_column ? $gap_row : $gap_row . ' ' . $gap_column; 1042 } else { 1043 // Skip outputting gap value if not all sides are provided. 1044 $block_gap_value = null; 1045 } 1046 } 1047 1048 // If the block should have custom gap, add the gap styles. 1049 if ( null !== $block_gap_value && false !== $block_gap_value && '' !== $block_gap_value ) { 1050 foreach ( $layout_definitions as $layout_definition_key => $layout_definition ) { 1051 // Allow outputting fallback gap styles for flex layout type when block gap support isn't available. 1052 if ( ! $has_block_gap_support && 'flex' !== $layout_definition_key ) { 1053 continue; 1054 } 1055 1056 $class_name = sanitize_title( _wp_array_get( $layout_definition, array( 'className' ), false ) ); 1057 $spacing_rules = _wp_array_get( $layout_definition, array( 'spacingStyles' ), array() ); 1058 1059 if ( 1060 ! empty( $class_name ) && 1061 ! empty( $spacing_rules ) 1062 ) { 1063 foreach ( $spacing_rules as $spacing_rule ) { 1064 $declarations = array(); 1065 if ( 1066 isset( $spacing_rule['selector'] ) && 1067 preg_match( $layout_selector_pattern, $spacing_rule['selector'] ) && 1068 ! empty( $spacing_rule['rules'] ) 1069 ) { 1070 // Iterate over each of the styling rules and substitute non-string values such as `null` with the real `blockGap` value. 1071 foreach ( $spacing_rule['rules'] as $css_property => $css_value ) { 1072 $current_css_value = is_string( $css_value ) ? $css_value : $block_gap_value; 1073 if ( static::is_safe_css_declaration( $css_property, $current_css_value ) ) { 1074 $declarations[] = array( 1075 'name' => $css_property, 1076 'value' => $current_css_value, 1077 ); 1078 } 1079 } 1080 1081 if ( ! $has_block_gap_support ) { 1082 // For fallback gap styles, use lower specificity, to ensure styles do not unintentionally override theme styles. 1083 $format = static::ROOT_BLOCK_SELECTOR === $selector ? ':where(.%2$s%3$s)' : ':where(%1$s.%2$s%3$s)'; 1084 $layout_selector = sprintf( 1085 $format, 1086 $selector, 1087 $class_name, 1088 $spacing_rule['selector'] 1089 ); 1090 } else { 1091 $format = static::ROOT_BLOCK_SELECTOR === $selector ? '%s .%s%s' : '%s.%s%s'; 1092 $layout_selector = sprintf( 1093 $format, 1094 $selector, 1095 $class_name, 1096 $spacing_rule['selector'] 1097 ); 1098 } 1099 $block_rules .= static::to_ruleset( $layout_selector, $declarations ); 1100 } 1101 } 1102 } 1103 } 1104 } 1105 } 1106 1107 // Output base styles. 1108 if ( 1109 static::ROOT_BLOCK_SELECTOR === $selector 1110 ) { 1111 $valid_display_modes = array( 'block', 'flex', 'grid' ); 1112 foreach ( $layout_definitions as $layout_definition ) { 1113 $class_name = sanitize_title( _wp_array_get( $layout_definition, array( 'className' ), false ) ); 1114 $base_style_rules = _wp_array_get( $layout_definition, array( 'baseStyles' ), array() ); 1115 1116 if ( 1117 ! empty( $class_name ) && 1118 ! empty( $base_style_rules ) 1119 ) { 1120 // Output display mode. This requires special handling as `display` is not exposed in `safe_style_css_filter`. 1121 if ( 1122 ! empty( $layout_definition['displayMode'] ) && 1123 is_string( $layout_definition['displayMode'] ) && 1124 in_array( $layout_definition['displayMode'], $valid_display_modes, true ) 1125 ) { 1126 $layout_selector = sprintf( 1127 '%s .%s', 1128 $selector, 1129 $class_name 1130 ); 1131 $block_rules .= static::to_ruleset( 1132 $layout_selector, 1133 array( 1134 array( 1135 'name' => 'display', 1136 'value' => $layout_definition['displayMode'], 1137 ), 1138 ) 1139 ); 1140 } 1141 1142 foreach ( $base_style_rules as $base_style_rule ) { 1143 $declarations = array(); 1144 1145 if ( 1146 isset( $base_style_rule['selector'] ) && 1147 preg_match( $layout_selector_pattern, $base_style_rule['selector'] ) && 1148 ! empty( $base_style_rule['rules'] ) 1149 ) { 1150 foreach ( $base_style_rule['rules'] as $css_property => $css_value ) { 1151 if ( static::is_safe_css_declaration( $css_property, $css_value ) ) { 1152 $declarations[] = array( 1153 'name' => $css_property, 1154 'value' => $css_value, 1155 ); 1156 } 1157 } 1158 1159 $layout_selector = sprintf( 1160 '%s .%s%s', 1161 $selector, 1162 $class_name, 1163 $base_style_rule['selector'] 1164 ); 1165 $block_rules .= static::to_ruleset( $layout_selector, $declarations ); 1166 } 1167 } 1168 } 1169 } 1170 } 901 1171 return $block_rules; 902 1172 } … … 1328 1598 * @since 5.8.0 1329 1599 * @since 5.9.0 Added the `$settings` and `$properties` parameters. 1330 * @since 6.1.0 Added the `$theme_json` parameter. 1331 * 1332 * @param array $styles Styles to process. 1333 * @param array $settings Theme settings. 1334 * @param array $properties Properties metadata. 1335 * @param array $theme_json Theme JSON array. 1336 * @return array Returns the modified $declarations. 1337 */ 1338 protected static function compute_style_properties( $styles, $settings = array(), $properties = null, $theme_json = null ) { 1600 * @since 6.1.0 Added `$theme_json`, `$selector`, and `$use_root_padding` parameters. 1601 * 1602 * @param array $styles Styles to process. 1603 * @param array $settings Theme settings. 1604 * @param array $properties Properties metadata. 1605 * @param array $theme_json Theme JSON array. 1606 * @param string $selector The style block selector. 1607 * @param boolean $use_root_padding Whether to add custom properties at root level. 1608 * @return array Returns the modified $declarations. 1609 */ 1610 protected static function compute_style_properties( $styles, $settings = array(), $properties = null, $theme_json = null, $selector = null, $use_root_padding = null ) { 1339 1611 if ( null === $properties ) { 1340 1612 $properties = static::PROPERTIES_METADATA; … … 1346 1618 } 1347 1619 1620 $root_variable_duplicates = array(); 1621 1348 1622 foreach ( $properties as $css_property => $value_path ) { 1349 1623 $value = static::get_property_value( $styles, $value_path, $theme_json ); 1624 1625 if ( str_starts_with( $css_property, '--wp--style--root--' ) && ( static::ROOT_BLOCK_SELECTOR !== $selector || ! $use_root_padding ) ) { 1626 continue; 1627 } 1628 // Root-level padding styles don't currently support strings with CSS shorthand values. 1629 // This may change: https://github.com/WordPress/gutenberg/issues/40132. 1630 if ( '--wp--style--root--padding' === $css_property && is_string( $value ) ) { 1631 continue; 1632 } 1633 1634 if ( str_starts_with( $css_property, '--wp--style--root--' ) && $use_root_padding ) { 1635 $root_variable_duplicates[] = substr( $css_property, strlen( '--wp--style--root--' ) ); 1636 } 1350 1637 1351 1638 // Look up protected properties, keyed by value path. … … 1373 1660 } 1374 1661 1662 // If a variable value is added to the root, the corresponding property should be removed. 1663 foreach ( $root_variable_duplicates as $duplicate ) { 1664 $discard = array_search( $duplicate, array_column( $declarations, 'name' ), true ); 1665 if ( is_numeric( $discard ) ) { 1666 array_splice( $declarations, $discard, 1 ); 1667 } 1668 } 1669 1375 1670 return $declarations; 1376 1671 } … … 1397 1692 */ 1398 1693 protected static function get_property_value( $styles, $path, $theme_json = null ) { 1399 $value = _wp_array_get( $styles, $path , '');1694 $value = _wp_array_get( $styles, $path ); 1400 1695 1401 1696 /* … … 1430 1725 } 1431 1726 1432 if ( '' === $value ||is_array( $value ) ) {1727 if ( is_array( $value ) ) { 1433 1728 return $value; 1434 1729 } … … 1623 1918 } 1624 1919 1920 $feature_selectors = null; 1921 if ( isset( $selectors[ $name ]['features'] ) ) { 1922 $feature_selectors = $selectors[ $name ]['features']; 1923 } 1924 1625 1925 $nodes[] = array( 1626 1926 'name' => $name, … … 1628 1928 'selector' => $selector, 1629 1929 'duotone' => $duotone_selector, 1930 'features' => $feature_selectors, 1630 1931 ); 1631 1932 … … 1660 1961 * @since 6.1.0 1661 1962 * 1662 * @param array $block_metadata Meta data about the block to get styles for. 1963 * @param array $block_metadata Metadata about the block to get styles for. 1964 * 1663 1965 * @return array Styles for the block. 1664 1966 */ 1665 1967 public function get_styles_for_block( $block_metadata ) { 1666 1667 $node = _wp_array_get( $this->theme_json, $block_metadata['path'], array() ); 1668 1669 $selector = $block_metadata['selector']; 1670 $settings = _wp_array_get( $this->theme_json, array( 'settings' ) ); 1968 $node = _wp_array_get( $this->theme_json, $block_metadata['path'], array() ); 1969 $use_root_padding = isset( $this->theme_json['settings']['useRootPaddingAwareAlignments'] ) && true === $this->theme_json['settings']['useRootPaddingAwareAlignments']; 1970 $selector = $block_metadata['selector']; 1971 $settings = _wp_array_get( $this->theme_json, array( 'settings' ) ); 1972 1973 /* 1974 * Process style declarations for block support features the current 1975 * block contains selectors for. Values for a feature with a custom 1976 * selector are filtered from the theme.json node before it is 1977 * processed as normal. 1978 */ 1979 $feature_declarations = array(); 1980 1981 if ( ! empty( $block_metadata['features'] ) ) { 1982 foreach ( $block_metadata['features'] as $feature_name => $feature_selector ) { 1983 if ( ! empty( $node[ $feature_name ] ) ) { 1984 // Create temporary node containing only the feature data 1985 // to leverage existing `compute_style_properties` function. 1986 $feature = array( $feature_name => $node[ $feature_name ] ); 1987 // Generate the feature's declarations only. 1988 $new_feature_declarations = static::compute_style_properties( $feature, $settings, null, $this->theme_json ); 1989 1990 // Merge new declarations with any that already exist for 1991 // the feature selector. This may occur when multiple block 1992 // support features use the same custom selector. 1993 if ( isset( $feature_declarations[ $feature_selector ] ) ) { 1994 $feature_declarations[ $feature_selector ] = array_merge( $feature_declarations[ $feature_selector ], $new_feature_declarations ); 1995 } else { 1996 $feature_declarations[ $feature_selector ] = $new_feature_declarations; 1997 } 1998 // Remove the feature from the block's node now the 1999 // styles will be included under the feature level selector. 2000 unset( $node[ $feature_name ] ); 2001 } 2002 } 2003 } 1671 2004 1672 2005 /* … … 1710 2043 && in_array( $pseudo_selector, static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ], true ) 1711 2044 ) { 1712 $declarations = static::compute_style_properties( $node[ $pseudo_selector ], $settings, null, $this->theme_json );2045 $declarations = static::compute_style_properties( $node[ $pseudo_selector ], $settings, null, $this->theme_json, $selector, $use_root_padding ); 1713 2046 } else { 1714 $declarations = static::compute_style_properties( $node, $settings, null, $this->theme_json );2047 $declarations = static::compute_style_properties( $node, $settings, null, $this->theme_json, $selector, $use_root_padding ); 1715 2048 } 1716 2049 … … 1729 2062 } 1730 2063 1731 /*1732 * Reset default browser margin on the root body element.1733 * This is set on the root selector **before** generating the ruleset1734 * from the `theme.json`. This is to ensure that if the `theme.json` declares1735 * `margin` in its `spacing` declaration for the `body` element then these1736 * user-generated values take precedence in the CSS cascade.1737 * @link https://github.com/WordPress/gutenberg/issues/36147.1738 */1739 if ( static::ROOT_BLOCK_SELECTOR === $selector ) {1740 $block_rules .= 'body { margin: 0; }';1741 }1742 1743 2064 // 2. Generate and append the rules that use the general selector. 1744 2065 $block_rules .= static::to_ruleset( $selector, $declarations ); … … 1750 2071 } 1751 2072 1752 if ( static::ROOT_BLOCK_SELECTOR === $selector ) { 1753 $block_rules .= '.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }'; 1754 $block_rules .= '.wp-site-blocks > .alignright { float: right; margin-left: 2em; }'; 1755 $block_rules .= '.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }'; 1756 1757 $has_block_gap_support = _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'blockGap' ) ) !== null; 1758 if ( $has_block_gap_support ) { 1759 $block_rules .= '.wp-site-blocks > * { margin-block-start: 0; margin-block-end: 0; }'; 1760 $block_rules .= '.wp-site-blocks > * + * { margin-block-start: var( --wp--style--block-gap ); }'; 1761 } 2073 // 4. Generate Layout block gap styles. 2074 if ( 2075 static::ROOT_BLOCK_SELECTOR !== $selector && 2076 ! empty( $block_metadata['name'] ) 2077 ) { 2078 $block_rules .= $this->get_layout_styles( $block_metadata ); 2079 } 2080 2081 // 5. Generate and append the feature level rulesets. 2082 foreach ( $feature_declarations as $feature_selector => $individual_feature_declarations ) { 2083 $block_rules .= static::to_ruleset( $feature_selector, $individual_feature_declarations ); 1762 2084 } 1763 2085 1764 2086 return $block_rules; 2087 } 2088 2089 /** 2090 * Outputs the CSS for layout rules on the root. 2091 * 2092 * @since 6.1.0 2093 * 2094 * @param string $selector The root node selector. 2095 * @param array $block_metadata The metadata for the root block. 2096 * @return string The additional root rules CSS. 2097 */ 2098 public function get_root_layout_rules( $selector, $block_metadata ) { 2099 $css = ''; 2100 $settings = _wp_array_get( $this->theme_json, array( 'settings' ) ); 2101 $use_root_padding = isset( $this->theme_json['settings']['useRootPaddingAwareAlignments'] ) && true === $this->theme_json['settings']['useRootPaddingAwareAlignments']; 2102 2103 /* 2104 * Reset default browser margin on the root body element. 2105 * This is set on the root selector **before** generating the ruleset 2106 * from the `theme.json`. This is to ensure that if the `theme.json` declares 2107 * `margin` in its `spacing` declaration for the `body` element then these 2108 * user-generated values take precedence in the CSS cascade. 2109 * @link https://github.com/WordPress/gutenberg/issues/36147. 2110 */ 2111 $css .= 'body { margin: 0;'; 2112 2113 /* 2114 * If there are content and wide widths in theme.json, output them 2115 * as custom properties on the body element so all blocks can use them. 2116 */ 2117 if ( isset( $settings['layout']['contentSize'] ) || isset( $settings['layout']['wideSize'] ) ) { 2118 $content_size = isset( $settings['layout']['contentSize'] ) ? $settings['layout']['contentSize'] : $settings['layout']['wideSize']; 2119 $content_size = static::is_safe_css_declaration( 'max-width', $content_size ) ? $content_size : 'initial'; 2120 $wide_size = isset( $settings['layout']['wideSize'] ) ? $settings['layout']['wideSize'] : $settings['layout']['contentSize']; 2121 $wide_size = static::is_safe_css_declaration( 'max-width', $wide_size ) ? $wide_size : 'initial'; 2122 $css .= '--wp--style--global--content-size: ' . $content_size . ';'; 2123 $css .= '--wp--style--global--wide-size: ' . $wide_size . ';'; 2124 } 2125 2126 $css .= ' }'; 2127 2128 if ( $use_root_padding ) { 2129 // Top and bottom padding are applied to the outer block container. 2130 $css .= '.wp-site-blocks { padding-top: var(--wp--style--root--padding-top); padding-bottom: var(--wp--style--root--padding-bottom); }'; 2131 // Right and left padding are applied to the first container with `.has-global-padding` class. 2132 $css .= '.has-global-padding { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); }'; 2133 // Nested containers with `.has-global-padding` class do not get padding. 2134 $css .= '.has-global-padding :where(.has-global-padding) { padding-right: 0; padding-left: 0; }'; 2135 // Alignfull children of the container with left and right padding have negative margins so they can still be full width. 2136 $css .= '.has-global-padding > .alignfull { margin-right: calc(var(--wp--style--root--padding-right) * -1); margin-left: calc(var(--wp--style--root--padding-left) * -1); }'; 2137 // The above rule is negated for alignfull children of nested containers. 2138 $css .= '.has-global-padding :where(.has-global-padding) > .alignfull { margin-right: 0; margin-left: 0; }'; 2139 // Some of the children of alignfull blocks without content width should also get padding: text blocks and non-alignfull container blocks. 2140 $css .= '.has-global-padding > .alignfull:where(:not(.has-global-padding)) > :where([class*="wp-block-"]:not(.alignfull):not([class*="__"]),p,h1,h2,h3,h4,h5,h6,ul,ol) { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); }'; 2141 // The above rule also has to be negated for blocks inside nested `.has-global-padding` blocks. 2142 $css .= '.has-global-padding :where(.has-global-padding) > .alignfull:where(:not(.has-global-padding)) > :where([class*="wp-block-"]:not(.alignfull):not([class*="__"]),p,h1,h2,h3,h4,h5,h6,ul,ol) { padding-right: 0; padding-left: 0; }'; 2143 } 2144 2145 $css .= '.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }'; 2146 $css .= '.wp-site-blocks > .alignright { float: right; margin-left: 2em; }'; 2147 $css .= '.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }'; 2148 2149 $block_gap_value = _wp_array_get( $this->theme_json, array( 'styles', 'spacing', 'blockGap' ), '0.5em' ); 2150 $has_block_gap_support = _wp_array_get( $this->theme_json, array( 'settings', 'spacing', 'blockGap' ) ) !== null; 2151 if ( $has_block_gap_support ) { 2152 $block_gap_value = static::get_property_value( $this->theme_json, array( 'styles', 'spacing', 'blockGap' ) ); 2153 $css .= '.wp-site-blocks > * { margin-block-start: 0; margin-block-end: 0; }'; 2154 $css .= ".wp-site-blocks > * + * { margin-block-start: $block_gap_value; }"; 2155 2156 // For backwards compatibility, ensure the legacy block gap CSS variable is still available. 2157 $css .= "$selector { --wp--style--block-gap: $block_gap_value; }"; 2158 } 2159 $css .= $this->get_layout_styles( $block_metadata ); 2160 2161 return $css; 1765 2162 } 1766 2163
Note: See TracChangeset
for help on using the changeset viewer.