Changeset 54160
- Timestamp:
- 09/14/2022 03:50:01 PM (2 years ago)
- Location:
- trunk
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/block-editor.php
r54159 r54160 210 210 'disableCustomFontSizes' => get_theme_support( 'disable-custom-font-sizes' ), 211 211 'disableCustomGradients' => get_theme_support( 'disable-custom-gradients' ), 212 'disableLayoutStyles' => get_theme_support( 'disable-layout-styles' ),213 212 'enableCustomLineHeight' => get_theme_support( 'custom-line-height' ), 214 213 'enableCustomSpacing' => get_theme_support( 'custom-spacing' ), … … 419 418 $global_styles[] = $block_classes; 420 419 } 421 } else {422 // If there is no `theme.json` file, ensure base layout styles are still available.423 $block_classes = array(424 'css' => 'base-layout-styles',425 '__unstableType' => 'base-layout',426 'isGlobalStyles' => true,427 );428 $actual_css = wp_get_global_stylesheet( array( $block_classes['css'] ) );429 if ( '' !== $actual_css ) {430 $block_classes['css'] = $actual_css;431 $global_styles[] = $block_classes;432 }433 420 } 434 421 … … 488 475 unset( $editor_settings['__experimentalFeatures']['spacing']['padding'] ); 489 476 } 490 if ( isset( $editor_settings['__experimentalFeatures']['spacing']['customSpacingSize'] ) ) {491 $editor_settings['disableCustomSpacingSizes'] = ! $editor_ettings['__experimentalFeatures']['spacing']['customSpacingSize'];492 unset( $editor_settings['__experimentalFeatures']['spacing']['customSpacingSize'] );493 }494 if ( isset( $editor_settings['__experimentalFeatures']['spacing']['spacingSizes'] ) ) {495 $spacing_sizes_by_origin = $editor_settings['__experimentalFeatures']['spacing']['spacingSizes'];496 $editor_settings['spacingSizes'] = isset( $spacing_sizes_by_origin['custom'] ) ?497 $spacing_sizes_by_origin['custom'] : (498 isset( $spacing_sizes_by_origin['theme'] ) ?499 $spacing_sizes_by_origin['theme'] :500 $spacing_sizes_by_origin['default']501 );502 }503 477 504 478 $editor_settings['__unstableResolvedAssets'] = _wp_get_iframed_editor_assets(); 505 479 $editor_settings['localAutosaveInterval'] = 15; 506 $editor_settings['disableLayoutStyles'] = current_theme_supports( 'disable-layout-styles' );507 480 $editor_settings['__experimentalDiscussionSettings'] = array( 508 481 'commentOrder' => get_option( 'comment_order' ), -
trunk/src/wp-includes/class-wp-theme-json-resolver.php
r54159 r54160 231 231 232 232 return $with_theme_supports; 233 }234 235 /**236 * Gets the styles for blocks from the block.json file.237 *238 * @since 6.1.0239 *240 * @return WP_Theme_JSON241 */242 public static function get_block_data() {243 $registry = WP_Block_Type_Registry::get_instance();244 $blocks = $registry->get_all_registered();245 $config = array( 'version' => 1 );246 foreach ( $blocks as $block_name => $block_type ) {247 if ( isset( $block_type->supports['__experimentalStyle'] ) ) {248 $config['styles']['blocks'][ $block_name ] = static::remove_json_comments( $block_type->supports['__experimentalStyle'] );249 }250 251 if (252 isset( $block_type->supports['spacing']['blockGap']['__experimentalDefault'] ) &&253 null === _wp_array_get( $config, array( 'styles', 'blocks', $block_name, 'spacing', 'blockGap' ), null )254 ) {255 // Ensure an empty placeholder value exists for the block, if it provides a default blockGap value.256 // The real blockGap value to be used will be determined when the styles are rendered for output.257 $config['styles']['blocks'][ $block_name ]['spacing']['blockGap'] = null;258 }259 }260 261 // Core here means it's the lower level part of the styles chain.262 // It can be a core or a third-party block.263 return new WP_Theme_JSON( $config, 'core' );264 }265 266 /**267 * When given an array, this will remove any keys with the name `//`.268 *269 * @param array $array The array to filter.270 * @return array The filtered array.271 */272 private static function remove_json_comments( $array ) {273 unset( $array['//'] );274 foreach ( $array as $k => $v ) {275 if ( is_array( $v ) ) {276 $array[ $k ] = static::remove_json_comments( $v );277 }278 }279 280 return $array;281 233 } 282 234 … … 419 371 * @since 5.9.0 Added user data, removed the `$settings` parameter, 420 372 * added the `$origin` parameter. 421 * @since 6.1.0 Added block data.422 373 * 423 374 * @param string $origin Optional. To what level should we merge data. … … 432 383 $result = new WP_Theme_JSON(); 433 384 $result->merge( static::get_core_data() ); 434 $result->merge( static::get_block_data() );435 385 $result->merge( static::get_theme_data() ); 436 386 -
trunk/src/wp-includes/class-wp-theme-json.php
r54159 r54160 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.183 180 * @var array 184 181 */ 185 182 const PROPERTIES_METADATA = array( 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' ), 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' ), 234 214 ); 235 215 … … 275 255 * and `typography`, and renamed others according to the new schema. 276 256 * @since 6.0.0 Added `color.defaultDuotone`. 277 * @since 6.1.0 Added `layout.definitions` and `useRootPaddingAwareAlignments`.278 257 * @var array 279 258 */ 280 259 const VALID_SETTINGS = array( 281 'appearanceTools' => null, 282 'useRootPaddingAwareAlignments' => null, 283 'border' => array( 260 'appearanceTools' => null, 261 'border' => array( 284 262 'color' => null, 285 263 'radius' => null, … … 287 265 'width' => null, 288 266 ), 289 'color' 267 'color' => array( 290 268 'background' => null, 291 269 'custom' => null, … … 301 279 'text' => null, 302 280 ), 303 'custom' 304 'layout' 281 'custom' => null, 282 'layout' => array( 305 283 'contentSize' => null, 306 284 'wideSize' => null, 307 285 ), 308 'spacing' 286 'spacing' => array( 309 287 'blockGap' => null, 310 288 'margin' => null, … … 312 290 'units' => null, 313 291 ), 314 'typography' 292 'typography' => array( 315 293 'customFontSize' => null, 316 294 'dropCap' => null, … … 333 311 * added new properties for `border`, `filter`, `spacing`, 334 312 * and `typography`. 335 * @since 6.1.0 Added new side properties for `border`,336 * updated `blockGap` to be allowed at any level.337 313 * @var array 338 314 */ … … 343 319 'style' => null, 344 320 'width' => null, 345 'top' => null,346 'right' => null,347 'bottom' => null,348 'left' => null,349 321 ), 350 322 'color' => array( … … 359 331 'margin' => null, 360 332 'padding' => null, 361 'blockGap' => null,333 'blockGap' => 'top', 362 334 ), 363 335 'typography' => array( … … 410 382 'button' => 'wp-element-button', 411 383 'caption' => 'wp-element-caption', 412 );413 414 /**415 * List of block support features that can have their related styles416 * generated under their own feature level selector rather than the block's.417 *418 * @since 6.1.0419 * @var string[]420 */421 const BLOCK_SUPPORT_FEATURE_LEVEL_SELECTORS = array(422 '__experimentalBorder' => 'border',423 'color' => 'color',424 'spacing' => 'spacing',425 'typography' => 'typography',426 384 ); 427 385 … … 699 657 * @since 5.8.0 700 658 * @since 5.9.0 Added `duotone` key with CSS selector. 701 * @since 6.1.0 Added `features` key with block support feature level selectors.702 659 * 703 660 * @return array Block metadata. … … 727 684 ) { 728 685 static::$blocks_metadata[ $block_name ]['duotone'] = $block_type->supports['color']['__experimentalDuotone']; 729 }730 731 // Generate block support feature level selectors if opted into732 // 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;748 686 } 749 687 … … 873 811 874 812 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 }880 813 $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 }899 814 } 900 815 … … 970 885 * and no longer returns preset classes. 971 886 * Removed the `$setting_nodes` parameter. 972 * @since 6.1.0 Moved most internal logic to `get_styles_for_block()`.973 887 * 974 888 * @param array $style_nodes Nodes with styles. … … 985 899 } 986 900 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.0994 *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 === $selector1110 ) {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_name1130 );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 }1171 901 return $block_rules; 1172 902 } … … 1598 1328 * @since 5.8.0 1599 1329 * @since 5.9.0 Added the `$settings` and `$properties` parameters. 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 ) { 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 ) { 1611 1339 if ( null === $properties ) { 1612 1340 $properties = static::PROPERTIES_METADATA; … … 1618 1346 } 1619 1347 1620 $root_variable_duplicates = array();1621 1622 1348 foreach ( $properties as $css_property => $value_path ) { 1623 1349 $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 }1637 1350 1638 1351 // Look up protected properties, keyed by value path. … … 1660 1373 } 1661 1374 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 1670 1375 return $declarations; 1671 1376 } … … 1692 1397 */ 1693 1398 protected static function get_property_value( $styles, $path, $theme_json = null ) { 1694 $value = _wp_array_get( $styles, $path );1399 $value = _wp_array_get( $styles, $path, '' ); 1695 1400 1696 1401 /* … … 1725 1430 } 1726 1431 1727 if ( is_array( $value ) ) {1432 if ( '' === $value || is_array( $value ) ) { 1728 1433 return $value; 1729 1434 } … … 1918 1623 } 1919 1624 1920 $feature_selectors = null;1921 if ( isset( $selectors[ $name ]['features'] ) ) {1922 $feature_selectors = $selectors[ $name ]['features'];1923 }1924 1925 1625 $nodes[] = array( 1926 1626 'name' => $name, … … 1928 1628 'selector' => $selector, 1929 1629 'duotone' => $duotone_selector, 1930 'features' => $feature_selectors,1931 1630 ); 1932 1631 … … 1961 1660 * @since 6.1.0 1962 1661 * 1963 * @param array $block_metadata Metadata about the block to get styles for. 1964 * 1662 * @param array $block_metadata Meta data about the block to get styles for. 1965 1663 * @return array Styles for the block. 1966 1664 */ 1967 1665 public function get_styles_for_block( $block_metadata ) { 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 } 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' ) ); 2004 1671 2005 1672 /* … … 2043 1710 && in_array( $pseudo_selector, static::VALID_ELEMENT_PSEUDO_SELECTORS[ $current_element ], true ) 2044 1711 ) { 2045 $declarations = static::compute_style_properties( $node[ $pseudo_selector ], $settings, null, $this->theme_json , $selector, $use_root_padding);1712 $declarations = static::compute_style_properties( $node[ $pseudo_selector ], $settings, null, $this->theme_json ); 2046 1713 } else { 2047 $declarations = static::compute_style_properties( $node, $settings, null, $this->theme_json , $selector, $use_root_padding);1714 $declarations = static::compute_style_properties( $node, $settings, null, $this->theme_json ); 2048 1715 } 2049 1716 … … 2062 1729 } 2063 1730 1731 /* 1732 * Reset default browser margin on the root body element. 1733 * This is set on the root selector **before** generating the ruleset 1734 * from the `theme.json`. This is to ensure that if the `theme.json` declares 1735 * `margin` in its `spacing` declaration for the `body` element then these 1736 * 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 2064 1743 // 2. Generate and append the rules that use the general selector. 2065 1744 $block_rules .= static::to_ruleset( $selector, $declarations ); … … 2071 1750 } 2072 1751 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 ); 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 } 2084 1762 } 2085 1763 2086 1764 return $block_rules; 2087 }2088 2089 /**2090 * Outputs the CSS for layout rules on the root.2091 *2092 * @since 6.1.02093 *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 ruleset2106 * from the `theme.json`. This is to ensure that if the `theme.json` declares2107 * `margin` in its `spacing` declaration for the `body` element then these2108 * 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 them2115 * 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;2162 1765 } 2163 1766 -
trunk/src/wp-includes/global-styles-and-settings.php
r54159 r54160 108 108 $supports_theme_json = WP_Theme_JSON_Resolver::theme_has_support(); 109 109 if ( empty( $types ) && ! $supports_theme_json ) { 110 $types = array( 'variables', 'presets' , 'base-layout-styles');110 $types = array( 'variables', 'presets' ); 111 111 } elseif ( empty( $types ) ) { 112 112 $types = array( 'variables', 'styles', 'presets' ); -
trunk/src/wp-includes/theme.json
r54159 r54160 3 3 "settings": { 4 4 "appearanceTools": false, 5 "useRootPaddingAwareAlignments": false,6 5 "border": { 7 6 "color": false, … … 14 13 "custom": true, 15 14 "customDuotone": true, 16 "customGradient": true,17 "defaultDuotone": true,15 "customGradient": true, 16 "defaultDuotone": true, 18 17 "defaultGradients": true, 19 18 "defaultPalette": true, … … 186 185 ], 187 186 "text": true 188 },189 "layout": {190 "definitions": {191 "default": {192 "name": "default",193 "slug": "flow",194 "className": "is-layout-flow",195 "baseStyles": [196 {197 "selector": " > .alignleft",198 "rules": {199 "float": "left",200 "margin-inline-start": "0",201 "margin-inline-end": "2em"202 }203 },204 {205 "selector": " > .alignright",206 "rules": {207 "float": "right",208 "margin-inline-start": "2em",209 "margin-inline-end": "0"210 }211 },212 {213 "selector": " > .aligncenter",214 "rules": {215 "margin-left": "auto !important",216 "margin-right": "auto !important"217 }218 }219 ],220 "spacingStyles": [221 {222 "selector": " > *",223 "rules": {224 "margin-block-start": "0",225 "margin-block-end": "0"226 }227 },228 {229 "selector": " > * + *",230 "rules": {231 "margin-block-start": null,232 "margin-block-end": "0"233 }234 }235 ]236 },237 "constrained": {238 "name": "constrained",239 "slug": "constrained",240 "className": "is-layout-constrained",241 "baseStyles": [242 {243 "selector": " > .alignleft",244 "rules": {245 "float": "left",246 "margin-inline-start": "0",247 "margin-inline-end": "2em"248 }249 },250 {251 "selector": " > .alignright",252 "rules": {253 "float": "right",254 "margin-inline-start": "2em",255 "margin-inline-end": "0"256 }257 },258 {259 "selector": " > .aligncenter",260 "rules": {261 "margin-left": "auto !important",262 "margin-right": "auto !important"263 }264 },265 {266 "selector": " > :where(:not(.alignleft):not(.alignright):not(.alignfull))",267 "rules": {268 "max-width": "var(--wp--style--global--content-size)",269 "margin-left": "auto !important",270 "margin-right": "auto !important"271 }272 },273 {274 "selector": " > .alignwide",275 "rules": {276 "max-width": "var(--wp--style--global--wide-size)"277 }278 }279 ],280 "spacingStyles": [281 {282 "selector": " > *",283 "rules": {284 "margin-block-start": "0",285 "margin-block-end": "0"286 }287 },288 {289 "selector": " > * + *",290 "rules": {291 "margin-block-start": null,292 "margin-block-end": "0"293 }294 }295 ]296 },297 "flex": {298 "name": "flex",299 "slug": "flex",300 "className": "is-layout-flex",301 "displayMode": "flex",302 "baseStyles": [303 {304 "selector": "",305 "rules": {306 "flex-wrap": "wrap",307 "align-items": "center"308 }309 },310 {311 "selector": " > *",312 "rules": {313 "margin": "0"314 }315 }316 ],317 "spacingStyles": [318 {319 "selector": "",320 "rules": {321 "gap": null322 }323 }324 ]325 }326 }327 187 }, 328 188 "spacing": { … … 330 190 "margin": false, 331 191 "padding": false, 332 "customSpacingSize": true, 333 "units": [ "px", "em", "rem", "vh", "vw", "%" ], 334 "spacingScale": { 335 "operator": "*", 336 "increment": 1.5, 337 "steps": 7, 338 "mediumStep": 1.5, 339 "unit": "rem" 340 } 192 "units": [ "px", "em", "rem", "vh", "vw", "%" ] 341 193 }, 342 194 "typography": { … … 389 241 }, 390 242 "styles": { 391 "elements": { 392 "button": { 393 "color": { 394 "text": "#fff", 395 "background": "#32373c" 396 }, 397 "spacing": { 398 "padding": "calc(0.667em + 2px) calc(1.333em + 2px)" 399 }, 400 "typography": { 401 "fontSize": "inherit", 402 "fontFamily": "inherit", 403 "lineHeight": "inherit", 404 "textDecoration": "none" 405 }, 406 "border": { 407 "width": "0" 408 } 409 }, 410 "link": { 411 "typography": { 412 "textDecoration": "underline" 413 } 414 } 415 }, 416 "spacing": { 417 "blockGap": "24px", 418 "padding": { 419 "top": "0px", 420 "right": "0px", 421 "bottom": "0px", 422 "left": "0px" 423 } 424 } 243 "spacing": { "blockGap": "24px" } 425 244 } 426 245 } -
trunk/src/wp-includes/theme.php
r54159 r54160 4028 4028 ); 4029 4029 register_theme_feature( 4030 'disable-layout-styles',4031 array(4032 'description' => __( 'Whether the theme disables generated layout styles.' ),4033 'show_in_rest' => true,4034 )4035 );4036 register_theme_feature(4037 4030 'editor-color-palette', 4038 4031 array( -
trunk/tests/phpunit/tests/blocks/editor.php
r54159 r54160 203 203 $settings = get_default_block_editor_settings(); 204 204 205 $this->assertCount( 1 9, $settings );205 $this->assertCount( 18, $settings ); 206 206 $this->assertFalse( $settings['alignWide'] ); 207 207 $this->assertIsArray( $settings['allowedMimeTypes'] ); … … 250 250 $this->assertFalse( $settings['disableCustomFontSizes'] ); 251 251 $this->assertFalse( $settings['disableCustomGradients'] ); 252 $this->assertFalse( $settings['disableLayoutStyles'] );253 252 $this->assertFalse( $settings['enableCustomLineHeight'] ); 254 253 $this->assertFalse( $settings['enableCustomSpacing'] ); -
trunk/tests/phpunit/tests/rest-api/rest-themes-controller.php
r54159 r54160 397 397 $this->assertArrayHasKey( 'disable-custom-font-sizes', $theme_supports ); 398 398 $this->assertArrayHasKey( 'disable-custom-gradients', $theme_supports ); 399 $this->assertArrayHasKey( 'disable-layout-styles', $theme_supports );400 399 $this->assertArrayHasKey( 'editor-color-palette', $theme_supports ); 401 400 $this->assertArrayHasKey( 'editor-font-sizes', $theme_supports ); … … 408 407 $this->assertArrayHasKey( 'title-tag', $theme_supports ); 409 408 $this->assertArrayHasKey( 'wp-block-styles', $theme_supports ); 410 $this->assertCount( 2 2, $theme_supports );409 $this->assertCount( 21, $theme_supports ); 411 410 } 412 411 -
trunk/tests/phpunit/tests/theme/wpThemeJson.php
r54159 r54160 424 424 ); 425 425 426 $expected = 'body { margin: 0; } .wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.wp-site-blocks > * { margin-block-start: 0; margin-block-end: 0; }.wp-site-blocks > * + * { margin-block-start: 1em; }body { --wp--style--block-gap: 1em; }';426 $expected = 'body { margin: 0; }body{--wp--style--block-gap: 1em;}.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.wp-site-blocks > * { margin-block-start: 0; margin-block-end: 0; }.wp-site-blocks > * + * { margin-block-start: var( --wp--style--block-gap ); }'; 427 427 $this->assertSame( $expected, $theme_json->get_stylesheet() ); 428 428 $this->assertSame( $expected, $theme_json->get_stylesheet( array( 'styles' ) ) ); … … 545 545 ), 546 546 ), 547 'spacing' => array(548 'blockGap' => '24px',549 ),550 547 ), 551 548 'misc' => 'value', … … 554 551 555 552 $variables = 'body{--wp--preset--color--grey: grey;--wp--preset--font-family--small: 14px;--wp--preset--font-family--big: 41px;}.wp-block-group{--wp--custom--base-font: 16;--wp--custom--line-height--small: 1.2;--wp--custom--line-height--medium: 1.4;--wp--custom--line-height--large: 1.8;}'; 556 $styles = 'body { margin: 0; } .wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }body{color: var(--wp--preset--color--grey);}a:where(:not(.wp-element-button)){background-color: #333;color: #111;}.wp-block-group{border-radius: 10px;padding: 24px;}.wp-block-group a:where(:not(.wp-element-button)){color: #111;}h1,h2,h3,h4,h5,h6{color: #123456;}h1 a:where(:not(.wp-element-button)),h2 a:where(:not(.wp-element-button)),h3 a:where(:not(.wp-element-button)),h4 a:where(:not(.wp-element-button)),h5 a:where(:not(.wp-element-button)),h6 a:where(:not(.wp-element-button)){background-color: #333;color: #111;font-size: 60px;}.wp-block-post-date{color: #123456;}.wp-block-post-date a:where(:not(.wp-element-button)){background-color: #777;color: #555;}.wp-block-image{border-top-left-radius: 10px;border-bottom-right-radius: 1em;margin-bottom: 30px;}';553 $styles = 'body { margin: 0; }body{color: var(--wp--preset--color--grey);}.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }a:where(:not(.wp-element-button)){background-color: #333;color: #111;}.wp-block-group{border-radius: 10px;padding: 24px;}.wp-block-group a:where(:not(.wp-element-button)){color: #111;}h1,h2,h3,h4,h5,h6{color: #123456;}h1 a:where(:not(.wp-element-button)),h2 a:where(:not(.wp-element-button)),h3 a:where(:not(.wp-element-button)),h4 a:where(:not(.wp-element-button)),h5 a:where(:not(.wp-element-button)),h6 a:where(:not(.wp-element-button)){background-color: #333;color: #111;font-size: 60px;}.wp-block-post-date{color: #123456;}.wp-block-post-date a:where(:not(.wp-element-button)){background-color: #777;color: #555;}.wp-block-image{border-top-left-radius: 10px;border-bottom-right-radius: 1em;margin-bottom: 30px;}'; 557 554 $presets = '.has-grey-color{color: var(--wp--preset--color--grey) !important;}.has-grey-background-color{background-color: var(--wp--preset--color--grey) !important;}.has-grey-border-color{border-color: var(--wp--preset--color--grey) !important;}.has-small-font-family{font-family: var(--wp--preset--font-family--small) !important;}.has-big-font-family{font-family: var(--wp--preset--font-family--big) !important;}'; 558 555 $all = $variables . $styles . $presets; … … 2679 2676 'core/group' => array( 2680 2677 'spacing' => array( 2681 'margin' => 'valid value',2682 ' display' => 'none',2678 'margin' => 'valid value', 2679 'blockGap' => 'invalid value', 2683 2680 ), 2684 2681 ), … … 2993 2990 ); 2994 2991 2995 $expected = 'body { margin: 0; } .wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }body{background-color: #ffffff;color: #000000;}.wp-element-button, .wp-block-button__link{background-color: #000000;color: #ffffff;}';2992 $expected = 'body { margin: 0; }body{background-color: #ffffff;color: #000000;}.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.wp-element-button, .wp-block-button__link{background-color: #000000;color: #ffffff;}'; 2996 2993 $this->assertSame( $expected, $theme_json->get_stylesheet() ); 2997 2994 } … … 3025 3022 ); 3026 3023 3027 $expected = 'body { margin: 0; } .wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }body{background-color: #ffffff;}.wp-element-button, .wp-block-button__link{color: #ffffff;}';3024 $expected = 'body { margin: 0; }body{background-color: #ffffff;}.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.wp-element-button, .wp-block-button__link{color: #ffffff;}'; 3028 3025 $this->assertSame( $expected, $theme_json->get_stylesheet() ); 3029 3026 } … … 3057 3054 ); 3058 3055 3059 $expected = 'body { margin: 0; } .wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }body{background-color: #ffffff;color: #ffffff;}.wp-element-button, .wp-block-button__link{color: #ffffff;}';3056 $expected = 'body { margin: 0; }body{background-color: #ffffff;color: #ffffff;}.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.wp-element-button, .wp-block-button__link{color: #ffffff;}'; 3060 3057 $this->assertSame( $expected, $theme_json->get_stylesheet() ); 3061 3058 } … … 3081 3078 ); 3082 3079 3083 $expected = 'body { margin: 0; } .wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }body{background-color: #ffffff;}';3080 $expected = 'body { margin: 0; }body{background-color: #ffffff;}.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }'; 3084 3081 $this->assertSame( $expected, $theme_json->get_stylesheet() ); 3085 3082 } 3086 3083 3087 /**3088 * @dataProvider data_get_layout_definitions3089 *3090 * @ticket 564673091 *3092 * @param array $layout_definitions Layout definitions as stored in core theme.json.3093 */3094 public function test_get_stylesheet_generates_layout_styles( $layout_definitions ) {3095 $theme_json = new WP_Theme_JSON(3096 array(3097 'version' => WP_Theme_JSON::LATEST_SCHEMA,3098 'settings' => array(3099 'layout' => array(3100 'definitions' => $layout_definitions,3101 ),3102 'spacing' => array(3103 'blockGap' => true,3104 ),3105 ),3106 'styles' => array(3107 'spacing' => array(3108 'blockGap' => '1em',3109 ),3110 ),3111 ),3112 'default'3113 );3114 3115 // Results also include root site blocks styles.3116 $this->assertSame(3117 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.wp-site-blocks > * { margin-block-start: 0; margin-block-end: 0; }.wp-site-blocks > * + * { margin-block-start: 1em; }body { --wp--style--block-gap: 1em; }body .is-layout-flow > *{margin-block-start: 0;margin-block-end: 0;}body .is-layout-flow > * + *{margin-block-start: 1em;margin-block-end: 0;}body .is-layout-flex{gap: 1em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}',3118 $theme_json->get_stylesheet( array( 'styles' ) )3119 );3120 }3121 3122 /**3123 * @dataProvider data_get_layout_definitions3124 *3125 * @ticket 564673126 *3127 * @param array $layout_definitions Layout definitions as stored in core theme.json.3128 */3129 public function test_get_stylesheet_generates_layout_styles_with_spacing_presets( $layout_definitions ) {3130 $theme_json = new WP_Theme_JSON(3131 array(3132 'version' => WP_Theme_JSON::LATEST_SCHEMA,3133 'settings' => array(3134 'layout' => array(3135 'definitions' => $layout_definitions,3136 ),3137 'spacing' => array(3138 'blockGap' => true,3139 ),3140 ),3141 'styles' => array(3142 'spacing' => array(3143 'blockGap' => 'var:preset|spacing|60',3144 ),3145 ),3146 ),3147 'default'3148 );3149 3150 // Results also include root site blocks styles.3151 $this->assertSame(3152 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.wp-site-blocks > * { margin-block-start: 0; margin-block-end: 0; }.wp-site-blocks > * + * { margin-block-start: var(--wp--preset--spacing--60); }body { --wp--style--block-gap: var(--wp--preset--spacing--60); }body .is-layout-flow > *{margin-block-start: 0;margin-block-end: 0;}body .is-layout-flow > * + *{margin-block-start: var(--wp--preset--spacing--60);margin-block-end: 0;}body .is-layout-flex{gap: var(--wp--preset--spacing--60);}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}',3153 $theme_json->get_stylesheet( array( 'styles' ) )3154 );3155 }3156 3157 /**3158 * @dataProvider data_get_layout_definitions3159 *3160 * @ticket 564673161 *3162 * @param array $layout_definitions Layout definitions as stored in core theme.json.3163 */3164 public function test_get_stylesheet_generates_fallback_gap_layout_styles( $layout_definitions ) {3165 $theme_json = new WP_Theme_JSON(3166 array(3167 'version' => WP_Theme_JSON::LATEST_SCHEMA,3168 'settings' => array(3169 'layout' => array(3170 'definitions' => $layout_definitions,3171 ),3172 'spacing' => array(3173 'blockGap' => null,3174 ),3175 ),3176 'styles' => array(3177 'spacing' => array(3178 'blockGap' => '1em',3179 ),3180 ),3181 ),3182 'default'3183 );3184 $stylesheet = $theme_json->get_stylesheet( array( 'styles' ) );3185 3186 // Results also include root site blocks styles.3187 $this->assertSame(3188 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }:where(.is-layout-flex){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}',3189 $stylesheet3190 );3191 }3192 3193 /**3194 * @dataProvider data_get_layout_definitions3195 *3196 * @ticket 564673197 *3198 * @param array $layout_definitions Layout definitions as stored in core theme.json.3199 */3200 public function test_get_stylesheet_generates_base_fallback_gap_layout_styles( $layout_definitions ) {3201 $theme_json = new WP_Theme_JSON(3202 array(3203 'version' => WP_Theme_JSON::LATEST_SCHEMA,3204 'settings' => array(3205 'layout' => array(3206 'definitions' => $layout_definitions,3207 ),3208 'spacing' => array(3209 'blockGap' => null,3210 ),3211 ),3212 ),3213 'default'3214 );3215 $stylesheet = $theme_json->get_stylesheet( array( 'base-layout-styles' ) );3216 3217 // Note the `base-layout-styles` includes a fallback gap for the Columns block for backwards compatibility.3218 $this->assertSame(3219 ':where(.is-layout-flex){gap: 0.5em;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}:where(.wp-block-columns.is-layout-flex){gap: 2em;}',3220 $stylesheet3221 );3222 }3223 3224 /**3225 * @dataProvider data_get_layout_definitions3226 *3227 * @ticket 564673228 *3229 * @param array $layout_definitions Layout definitions as stored in core theme.json.3230 */3231 public function test_get_stylesheet_skips_layout_styles( $layout_definitions ) {3232 add_theme_support( 'disable-layout-styles' );3233 $theme_json = new WP_Theme_JSON(3234 array(3235 'version' => WP_Theme_JSON::LATEST_SCHEMA,3236 'settings' => array(3237 'layout' => array(3238 'definitions' => $layout_definitions,3239 ),3240 'spacing' => array(3241 'blockGap' => null,3242 ),3243 ),3244 ),3245 'default'3246 );3247 $stylesheet = $theme_json->get_stylesheet( array( 'base-layout-styles' ) );3248 remove_theme_support( 'disable-layout-styles' );3249 3250 // All Layout styles should be skipped.3251 $this->assertSame(3252 '',3253 $stylesheet3254 );3255 }3256 3257 /**3258 * @dataProvider data_get_layout_definitions3259 *3260 * @ticket 564673261 *3262 * @param array $layout_definitions Layout definitions as stored in core theme.json.3263 */3264 public function test_get_stylesheet_generates_valid_block_gap_values_and_skips_null_or_false_values( $layout_definitions ) {3265 $theme_json = new WP_Theme_JSON(3266 array(3267 'version' => WP_Theme_JSON::LATEST_SCHEMA,3268 'settings' => array(3269 'layout' => array(3270 'definitions' => $layout_definitions,3271 ),3272 'spacing' => array(3273 'blockGap' => true,3274 ),3275 ),3276 'styles' => array(3277 'spacing' => array(3278 'blockGap' => '1rem',3279 ),3280 'blocks' => array(3281 'core/post-content' => array(3282 'color' => array(3283 'text' => 'gray', // This value should not render block layout styles.3284 ),3285 ),3286 'core/social-links' => array(3287 'spacing' => array(3288 'blockGap' => '0', // This value should render block layout gap as zero.3289 ),3290 ),3291 'core/buttons' => array(3292 'spacing' => array(3293 'blockGap' => 0, // This value should render block layout gap as zero.3294 ),3295 ),3296 'core/columns' => array(3297 'spacing' => array(3298 'blockGap' => false, // This value should be ignored. The block will use the global layout value.3299 ),3300 ),3301 ),3302 ),3303 ),3304 'default'3305 );3306 3307 $this->assertEquals(3308 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }.wp-site-blocks > * { margin-block-start: 0; margin-block-end: 0; }.wp-site-blocks > * + * { margin-block-start: 1rem; }body { --wp--style--block-gap: 1rem; }body .is-layout-flow > *{margin-block-start: 0;margin-block-end: 0;}body .is-layout-flow > * + *{margin-block-start: 1rem;margin-block-end: 0;}body .is-layout-flex{gap: 1rem;}body .is-layout-flow > .alignleft{float: left;margin-inline-start: 0;margin-inline-end: 2em;}body .is-layout-flow > .alignright{float: right;margin-inline-start: 2em;margin-inline-end: 0;}body .is-layout-flow > .aligncenter{margin-left: auto !important;margin-right: auto !important;}body .is-layout-flex{display: flex;}body .is-layout-flex{flex-wrap: wrap;align-items: center;}.wp-block-post-content{color: gray;}.wp-block-social-links.is-layout-flow > *{margin-block-start: 0;margin-block-end: 0;}.wp-block-social-links.is-layout-flow > * + *{margin-block-start: 0;margin-block-end: 0;}.wp-block-social-links.is-layout-flex{gap: 0;}.wp-block-buttons.is-layout-flow > *{margin-block-start: 0;margin-block-end: 0;}.wp-block-buttons.is-layout-flow > * + *{margin-block-start: 0;margin-block-end: 0;}.wp-block-buttons.is-layout-flex{gap: 0;}',3309 $theme_json->get_stylesheet()3310 );3311 }3312 3313 /**3314 * Data provider for layout tests.3315 *3316 * @ticket 564673317 *3318 * @return array3319 */3320 public function data_get_layout_definitions() {3321 return array(3322 'layout definitions' => array(3323 array(3324 'default' => array(3325 'name' => 'default',3326 'slug' => 'flow',3327 'className' => 'is-layout-flow',3328 'baseStyles' => array(3329 array(3330 'selector' => ' > .alignleft',3331 'rules' => array(3332 'float' => 'left',3333 'margin-inline-start' => '0',3334 'margin-inline-end' => '2em',3335 ),3336 ),3337 array(3338 'selector' => ' > .alignright',3339 'rules' => array(3340 'float' => 'right',3341 'margin-inline-start' => '2em',3342 'margin-inline-end' => '0',3343 ),3344 ),3345 array(3346 'selector' => ' > .aligncenter',3347 'rules' => array(3348 'margin-left' => 'auto !important',3349 'margin-right' => 'auto !important',3350 ),3351 ),3352 ),3353 'spacingStyles' => array(3354 array(3355 'selector' => ' > *',3356 'rules' => array(3357 'margin-block-start' => '0',3358 'margin-block-end' => '0',3359 ),3360 ),3361 array(3362 'selector' => ' > * + *',3363 'rules' => array(3364 'margin-block-start' => null,3365 'margin-block-end' => '0',3366 ),3367 ),3368 ),3369 ),3370 'flex' => array(3371 'name' => 'flex',3372 'slug' => 'flex',3373 'className' => 'is-layout-flex',3374 'displayMode' => 'flex',3375 'baseStyles' => array(3376 array(3377 'selector' => '',3378 'rules' => array(3379 'flex-wrap' => 'wrap',3380 'align-items' => 'center',3381 ),3382 ),3383 ),3384 'spacingStyles' => array(3385 array(3386 'selector' => '',3387 'rules' => array(3388 'gap' => null,3389 ),3390 ),3391 ),3392 ),3393 ),3394 ),3395 );3396 }3397 3398 /**3399 * @ticket 564673400 */3401 function test_get_styles_for_block_with_padding_aware_alignments() {3402 $theme_json = new WP_Theme_JSON(3403 array(3404 'version' => 2,3405 'styles' => array(3406 'spacing' => array(3407 'padding' => array(3408 'top' => '10px',3409 'right' => '12px',3410 'bottom' => '10px',3411 'left' => '12px',3412 ),3413 ),3414 ),3415 'settings' => array(3416 'useRootPaddingAwareAlignments' => true,3417 ),3418 )3419 );3420 3421 $metadata = array(3422 'path' => array(3423 '0' => 'styles',3424 ),3425 'selector' => 'body',3426 );3427 3428 $expected = 'body { margin: 0; }.wp-site-blocks { padding-top: var(--wp--style--root--padding-top); padding-bottom: var(--wp--style--root--padding-bottom); }.has-global-padding { padding-right: var(--wp--style--root--padding-right); padding-left: var(--wp--style--root--padding-left); }.has-global-padding :where(.has-global-padding) { padding-right: 0; padding-left: 0; }.has-global-padding > .alignfull { margin-right: calc(var(--wp--style--root--padding-right) * -1); margin-left: calc(var(--wp--style--root--padding-left) * -1); }.has-global-padding :where(.has-global-padding) > .alignfull { margin-right: 0; margin-left: 0; }.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); }.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; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }body{--wp--style--root--padding-top: 10px;--wp--style--root--padding-right: 12px;--wp--style--root--padding-bottom: 10px;--wp--style--root--padding-left: 12px;}';3429 $root_rules = $theme_json->get_root_layout_rules( WP_Theme_JSON::ROOT_BLOCK_SELECTOR, $metadata );3430 $style_rules = $theme_json->get_styles_for_block( $metadata );3431 $this->assertSame( $expected, $root_rules . $style_rules );3432 }3433 3434 /**3435 * @ticket 564673436 */3437 function test_get_styles_for_block_without_padding_aware_alignments() {3438 $theme_json = new WP_Theme_JSON(3439 array(3440 'version' => 2,3441 'styles' => array(3442 'spacing' => array(3443 'padding' => array(3444 'top' => '10px',3445 'right' => '12px',3446 'bottom' => '10px',3447 'left' => '12px',3448 ),3449 ),3450 ),3451 )3452 );3453 3454 $metadata = array(3455 'path' => array(3456 '0' => 'styles',3457 ),3458 'selector' => 'body',3459 );3460 3461 $expected = 'body { margin: 0; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }body{padding-top: 10px;padding-right: 12px;padding-bottom: 10px;padding-left: 12px;}';3462 $root_rules = $theme_json->get_root_layout_rules( WP_Theme_JSON::ROOT_BLOCK_SELECTOR, $metadata );3463 $style_rules = $theme_json->get_styles_for_block( $metadata );3464 $this->assertSame( $expected, $root_rules . $style_rules );3465 }3466 3467 /**3468 * @ticket 564673469 */3470 function test_get_styles_for_block_with_content_width() {3471 $theme_json = new WP_Theme_JSON(3472 array(3473 'version' => 2,3474 'settings' => array(3475 'layout' => array(3476 'contentSize' => '800px',3477 'wideSize' => '1000px',3478 ),3479 ),3480 )3481 );3482 3483 $metadata = array(3484 'path' => array(3485 '0' => 'settings',3486 ),3487 'selector' => 'body',3488 );3489 3490 $expected = 'body { margin: 0;--wp--style--global--content-size: 800px;--wp--style--global--wide-size: 1000px; }.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }.wp-site-blocks > .alignright { float: right; margin-left: 2em; }.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }';3491 $root_rules = $theme_json->get_root_layout_rules( WP_Theme_JSON::ROOT_BLOCK_SELECTOR, $metadata );3492 $style_rules = $theme_json->get_styles_for_block( $metadata );3493 $this->assertSame( $expected, $root_rules . $style_rules );3494 }3495 3084 }
Note: See TracChangeset
for help on using the changeset viewer.