Changeset 61473
- Timestamp:
- 01/12/2026 12:18:12 PM (5 weeks ago)
- Location:
- trunk
- Files:
-
- 9 edited
-
src/wp-admin/menu.php (modified) (1 diff)
-
src/wp-includes/block-editor.php (modified) (1 diff)
-
src/wp-includes/class-wp-theme-json-resolver.php (modified) (1 diff)
-
src/wp-includes/class-wp-theme-json.php (modified) (9 diffs)
-
src/wp-includes/global-styles-and-settings.php (modified) (5 diffs)
-
src/wp-includes/script-loader.php (modified) (1 diff)
-
tests/phpunit/tests/template.php (modified) (2 diffs)
-
tests/phpunit/tests/theme/wpThemeJson.php (modified) (2 diffs)
-
tests/phpunit/tests/theme/wpThemeJsonResolver.php (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-admin/menu.php
r61438 r61473 238 238 239 239 // Font Library menu item. 240 $submenu['themes.php'][ 8] = array( __( 'Fonts' ), 'edit_theme_options', 'font-library.php' );240 $submenu['themes.php'][9] = array( __( 'Fonts' ), 'edit_theme_options', 'font-library.php' ); 241 241 242 242 $customize_url = add_query_arg( 'return', urlencode( remove_query_arg( wp_removable_query_args(), wp_unslash( $_SERVER['REQUEST_URI'] ) ) ), 'customize.php' ); -
trunk/src/wp-includes/block-editor.php
r61431 r61473 526 526 } 527 527 528 if ( wp_theme_has_theme_json() ) { 529 $block_classes = array( 530 'css' => 'styles', 531 '__unstableType' => 'theme', 532 'isGlobalStyles' => true, 533 ); 534 $actual_css = wp_get_global_stylesheet( array( $block_classes['css'] ) ); 535 if ( '' !== $actual_css ) { 536 $block_classes['css'] = $actual_css; 537 $global_styles[] = $block_classes; 538 } 539 540 /* 541 * Add the custom CSS as a separate stylesheet so any invalid CSS 542 * entered by users does not break other global styles. 543 */ 544 $global_styles[] = array( 545 'css' => wp_get_global_stylesheet( array( 'custom-css' ) ), 546 '__unstableType' => 'user', 547 'isGlobalStyles' => true, 548 ); 549 } else { 550 // If there is no `theme.json` file, ensure base layout styles are still available. 551 $block_classes = array( 552 'css' => 'base-layout-styles', 553 '__unstableType' => 'base-layout', 554 'isGlobalStyles' => true, 555 ); 556 $actual_css = wp_get_global_stylesheet( array( $block_classes['css'] ) ); 557 if ( '' !== $actual_css ) { 558 $block_classes['css'] = $actual_css; 559 $global_styles[] = $block_classes; 560 } 561 } 528 $block_classes = array( 529 'css' => 'styles', 530 '__unstableType' => 'theme', 531 'isGlobalStyles' => true, 532 ); 533 $actual_css = wp_get_global_stylesheet( array( $block_classes['css'] ) ); 534 if ( '' !== $actual_css ) { 535 $block_classes['css'] = $actual_css; 536 $global_styles[] = $block_classes; 537 } 538 539 // Get any additional css from the customizer and add it before global styles custom CSS. 540 $global_styles[] = array( 541 'css' => wp_get_custom_css(), 542 '__unstableType' => 'user', 543 'isGlobalStyles' => false, 544 ); 545 546 /* 547 * Add the custom CSS as a separate stylesheet so any invalid CSS 548 * entered by users does not break other global styles. 549 */ 550 $global_styles[] = array( 551 'css' => wp_get_global_stylesheet( array( 'custom-css' ) ), 552 '__unstableType' => 'user', 553 'isGlobalStyles' => true, 554 ); 562 555 563 556 $editor_settings['styles'] = array_merge( $global_styles, get_block_editor_theme_styles() ); -
trunk/src/wp-includes/class-wp-theme-json-resolver.php
r61400 r61473 481 481 } 482 482 483 /*484 * Bail early if the theme does not support a theme.json.485 *486 * Since wp_theme_has_theme_json() only supports the active487 * theme, the extra condition for whether $theme is the active theme is488 * present here.489 */490 if ( $theme->get_stylesheet() === get_stylesheet() && ! wp_theme_has_theme_json() ) {491 return array();492 }493 494 483 $user_cpt = array(); 495 484 $post_type_filter = 'wp_global_styles'; -
trunk/src/wp-includes/class-wp-theme-json.php
r61431 r61473 1327 1327 * @since 6.6.0 Added boolean `skip_root_layout_styles` and `include_block_style_variations` options 1328 1328 * to control styles output as desired. 1329 * @since 7.0.0 Deprecated 'base-layout-styles' type; added `base_layout_styles` option for classic themes. 1329 1330 * 1330 1331 * @param string[] $types Types of styles to load. Will load all by default. It accepts: … … 1332 1333 * - `styles`: only the styles section in theme.json. 1333 1334 * - `presets`: only the classes for the presets. 1334 * - `base-layout-styles`: only the base layout styles. 1335 * - `base-layout-styles`: only the base layout styles. Deprecated in 7.0.0. 1335 1336 * - `custom-css`: only the custom CSS. 1336 1337 * @param string[] $origins A list of origins to include. By default it includes VALID_ORIGINS. … … 1341 1342 * @type string $root_selector Overwrites and forces a given selector to be used on the root node 1342 1343 * @type bool $skip_root_layout_styles Omits root layout styles from the generated stylesheet. Default false. 1344 * @type bool $base_layout_styles When true generates only base layout styles without alignment rules. Default false. 1343 1345 * @type bool $include_block_style_variations Includes styles for block style variations in the generated stylesheet. Default false. 1344 1346 * } … … 1396 1398 if ( in_array( 'styles', $types, true ) ) { 1397 1399 if ( false !== $root_style_key && empty( $options['skip_root_layout_styles'] ) ) { 1398 $stylesheet .= $this->get_root_layout_rules( $style_nodes[ $root_style_key ]['selector'], $style_nodes[ $root_style_key ] );1400 $stylesheet .= $this->get_root_layout_rules( $style_nodes[ $root_style_key ]['selector'], $style_nodes[ $root_style_key ], $options ); 1399 1401 } 1400 1402 $stylesheet .= $this->get_block_classes( $style_nodes ); 1401 } elseif ( in_array( 'base-layout-styles', $types, true ) ) {1402 $root_selector = static::ROOT_BLOCK_SELECTOR;1403 $columns_selector = '.wp-block-columns';1404 $post_template_selector = '.wp-block-post-template';1405 if ( ! empty( $options['scope'] ) ) {1406 $root_selector = static::scope_selector( $options['scope'], $root_selector );1407 $columns_selector = static::scope_selector( $options['scope'], $columns_selector );1408 $post_template_selector = static::scope_selector( $options['scope'], $post_template_selector );1409 }1410 if ( ! empty( $options['root_selector'] ) ) {1411 $root_selector = $options['root_selector'];1412 }1413 /*1414 * Base layout styles are provided as part of `styles`, so only output separately if explicitly requested.1415 * For backwards compatibility, the Columns block is explicitly included, to support a different default gap value.1416 */1417 $base_styles_nodes = array(1418 array(1419 'path' => array( 'styles' ),1420 'selector' => $root_selector,1421 ),1422 array(1423 'path' => array( 'styles', 'blocks', 'core/columns' ),1424 'selector' => $columns_selector,1425 'name' => 'core/columns',1426 ),1427 array(1428 'path' => array( 'styles', 'blocks', 'core/post-template' ),1429 'selector' => $post_template_selector,1430 'name' => 'core/post-template',1431 ),1432 );1433 1434 foreach ( $base_styles_nodes as $base_style_node ) {1435 $stylesheet .= $this->get_layout_styles( $base_style_node, $types );1436 }1437 1403 } 1438 1404 … … 1625 1591 * @since 6.5.3 Add types parameter to check if only base layout styles are needed. 1626 1592 * @since 6.6.0 Updated layout style specificity to be compatible with overall 0-1-0 specificity in global styles. 1593 * @since 7.0.0 Replaced `$types` parameter with `$options` array; base layout styles controlled via `base_layout_styles` option. 1627 1594 * 1628 1595 * @param array $block_metadata Metadata about the block to get styles for. 1629 * @param array $ types Optional. Types of styles to output. If empty, all styles will be output.1596 * @param array $options Optional. An array of options for now used for internal purposes only. 1630 1597 * @return string Layout styles for the block. 1631 1598 */ 1632 protected function get_layout_styles( $block_metadata, $ types = array() ) {1599 protected function get_layout_styles( $block_metadata, $options = array() ) { 1633 1600 $block_rules = ''; 1634 1601 $block_type = null; … … 1778 1745 $declarations = array(); 1779 1746 1780 // Skip outputting base styles for flow and constrained layout types if theme doesn't support theme.json. The 'base-layout-styles' type flags this. 1781 if ( in_array( 'base-layout-styles', $types, true ) && ( 'default' === $layout_definition['name'] || 'constrained' === $layout_definition['name'] ) ) { 1747 // Skip outputting base styles for flow and constrained layout types when base_layout_styles is enabled. 1748 // These themes don't use .wp-site-blocks wrapper, so these layout-specific alignment styles aren't needed. 1749 if ( ! empty( $options['base_layout_styles'] ) && ( 'default' === $layout_definition['name'] || 'constrained' === $layout_definition['name'] ) ) { 1782 1750 continue; 1783 1751 } … … 3056 3024 * @since 6.6.0 Use `ROOT_CSS_PROPERTIES_SELECTOR` for CSS custom properties and improved consistency of root padding rules. 3057 3025 * Updated specificity of body margin reset and first/last child selectors. 3026 * @since 7.0.0 Added `$options` parameter to control alignment styles output for classic themes. 3058 3027 * 3059 3028 * @param string $selector The root node selector. 3060 3029 * @param array $block_metadata The metadata for the root block. 3030 * @param array $options Optional. An array of options for now used for internal purposes only. 3061 3031 * @return string The additional root rules CSS. 3062 3032 */ 3063 public function get_root_layout_rules( $selector, $block_metadata ) {3033 public function get_root_layout_rules( $selector, $block_metadata, $options = array() ) { 3064 3034 $css = ''; 3065 3035 $settings = $this->theme_json['settings'] ?? array(); … … 3102 3072 } 3103 3073 3104 $css .= '.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }'; 3105 $css .= '.wp-site-blocks > .alignright { float: right; margin-left: 2em; }'; 3106 $css .= '.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }'; 3074 // Skip outputting alignment styles when base_layout_styles is enabled. 3075 // These styles target .wp-site-blocks which is only used by block themes. 3076 if ( empty( $options['base_layout_styles'] ) ) { 3077 $css .= '.wp-site-blocks > .alignleft { float: left; margin-right: 2em; }'; 3078 $css .= '.wp-site-blocks > .alignright { float: right; margin-left: 2em; }'; 3079 $css .= '.wp-site-blocks > .aligncenter { justify-content: center; margin-left: auto; margin-right: auto; }'; 3080 } 3107 3081 3108 3082 // Block gap styles will be output unless explicitly set to `null`. See static::PROTECTED_PROPERTIES. … … 3116 3090 $css .= static::ROOT_CSS_PROPERTIES_SELECTOR . " { --wp--style--block-gap: $block_gap_value; }"; 3117 3091 } 3118 $css .= $this->get_layout_styles( $block_metadata );3092 $css .= $this->get_layout_styles( $block_metadata, $options ); 3119 3093 3120 3094 return $css; -
trunk/src/wp-includes/global-styles-and-settings.php
r61470 r61473 40 40 */ 41 41 $origin = 'custom'; 42 if ( 43 ! wp_theme_has_theme_json() || 44 ( isset( $context['origin'] ) && 'base' === $context['origin'] ) 45 ) { 42 if ( isset( $context['origin'] ) && 'base' === $context['origin'] ) { 46 43 $origin = 'theme'; 47 44 } … … 141 138 * @since 6.1.0 Added 'base-layout-styles' support. 142 139 * @since 6.6.0 Resolves relative paths in theme.json styles to theme absolute paths. 140 * @since 7.0.0 Deprecated 'base-layout-styles' type; classic themes now receive full styles 141 * with layout-specific alignment rules skipped via `base_layout_styles` option. 143 142 * 144 143 * @param array $types Optional. Types of styles to load. 145 144 * See {@see 'WP_Theme_JSON::get_stylesheet'} for all valid types. 146 * If empty, it'll load the following: 147 * - for themes without theme.json: 'variables', 'presets', 'base-layout-styles'. 148 * - for themes with theme.json: 'variables', 'presets', 'styles'. 145 * If empty, will load: 'variables', 'presets', 'styles'. 149 146 * @return string Stylesheet. 150 147 */ … … 181 178 } 182 179 183 $tree = WP_Theme_JSON_Resolver::resolve_theme_file_uris( WP_Theme_JSON_Resolver::get_merged_data() ); 184 $supports_theme_json = wp_theme_has_theme_json(); 185 186 if ( empty( $types ) && ! $supports_theme_json ) { 187 $types = array( 'variables', 'presets', 'base-layout-styles' ); 188 } elseif ( empty( $types ) ) { 180 $tree = WP_Theme_JSON_Resolver::resolve_theme_file_uris( WP_Theme_JSON_Resolver::get_merged_data() ); 181 182 if ( empty( $types ) ) { 189 183 $types = array( 'variables', 'styles', 'presets' ); 184 } 185 186 /* 187 * Enable base layout styles only mode for classic themes without theme.json. 188 * This skips alignment styles that target .wp-site-blocks which is only used by block themes. 189 */ 190 $options = array(); 191 if ( ! wp_is_block_theme() && ! wp_theme_has_theme_json() ) { 192 $options['base_layout_styles'] = true; 190 193 } 191 194 … … 205 208 */ 206 209 $origins = array( 'default', 'theme', 'custom' ); 207 $styles_variables = $tree->get_stylesheet( array( 'variables' ), $origins );210 $styles_variables = $tree->get_stylesheet( array( 'variables' ), $origins, $options ); 208 211 $types = array_diff( $types, array( 'variables' ) ); 209 212 } … … 223 226 * @see wp_add_global_styles_for_blocks 224 227 */ 225 $origins = array( 'default', 'theme', 'custom' ); 226 /* 227 * If the theme doesn't have theme.json but supports both appearance tools and color palette, 228 * the 'theme' origin should be included so color palette presets are also output. 229 */ 230 if ( ! $supports_theme_json && ( current_theme_supports( 'appearance-tools' ) || current_theme_supports( 'border' ) ) && current_theme_supports( 'editor-color-palette' ) ) { 231 $origins = array( 'default', 'theme' ); 232 } elseif ( ! $supports_theme_json ) { 233 $origins = array( 'default' ); 234 } 235 $styles_rest = $tree->get_stylesheet( $types, $origins ); 228 $origins = array( 'default', 'theme', 'custom' ); 229 $styles_rest = $tree->get_stylesheet( $types, $origins, $options ); 236 230 } 237 231 -
trunk/src/wp-includes/script-loader.php
r61469 r61473 2515 2515 $stylesheet = wp_get_global_stylesheet(); 2516 2516 2517 if ( $is_block_theme ) { 2518 /* 2519 * Dequeue the Customizer's custom CSS 2520 * and add it before the global styles custom CSS. 2521 */ 2522 remove_action( 'wp_head', 'wp_custom_css_cb', 101 ); 2523 2524 /* 2525 * Get the custom CSS from the Customizer and add it to the global stylesheet. 2526 * Always do this in Customizer preview for the sake of live preview since it be empty. 2527 */ 2528 $custom_css = trim( wp_get_custom_css() ); 2529 if ( $custom_css || is_customize_preview() ) { 2530 if ( is_customize_preview() ) { 2531 /* 2532 * When in the Customizer preview, wrap the Custom CSS in milestone comments to allow customize-preview.js 2533 * to locate the CSS to replace for live previewing. Make sure that the milestone comments are omitted from 2534 * the stored Custom CSS if by chance someone tried to add them, which would be highly unlikely, but it 2535 * would break live previewing. 2536 */ 2537 $before_milestone = '/*BEGIN_CUSTOMIZER_CUSTOM_CSS*/'; 2538 $after_milestone = '/*END_CUSTOMIZER_CUSTOM_CSS*/'; 2539 $custom_css = str_replace( array( $before_milestone, $after_milestone ), '', $custom_css ); 2540 $custom_css = $before_milestone . "\n" . $custom_css . "\n" . $after_milestone; 2541 } 2542 $custom_css = "\n" . $custom_css; 2543 } 2544 $stylesheet .= $custom_css; 2545 2546 // Add the global styles custom CSS at the end. 2547 $stylesheet .= wp_get_global_stylesheet( array( 'custom-css' ) ); 2548 } 2517 /* 2518 * Dequeue the Customizer's custom CSS 2519 * and add it before the global styles custom CSS. 2520 */ 2521 remove_action( 'wp_head', 'wp_custom_css_cb', 101 ); 2522 2523 /* 2524 * Get the custom CSS from the Customizer and add it to the global stylesheet. 2525 * Always do this in Customizer preview for the sake of live preview since it be empty. 2526 */ 2527 $custom_css = trim( wp_get_custom_css() ); 2528 if ( $custom_css || is_customize_preview() ) { 2529 if ( is_customize_preview() ) { 2530 /* 2531 * When in the Customizer preview, wrap the Custom CSS in milestone comments to allow customize-preview.js 2532 * to locate the CSS to replace for live previewing. Make sure that the milestone comments are omitted from 2533 * the stored Custom CSS if by chance someone tried to add them, which would be highly unlikely, but it 2534 * would break live previewing. 2535 */ 2536 $before_milestone = '/*BEGIN_CUSTOMIZER_CUSTOM_CSS*/'; 2537 $after_milestone = '/*END_CUSTOMIZER_CUSTOM_CSS*/'; 2538 $custom_css = str_replace( array( $before_milestone, $after_milestone ), '', $custom_css ); 2539 $custom_css = $before_milestone . "\n" . $custom_css . "\n" . $after_milestone; 2540 } 2541 $custom_css = "\n" . $custom_css; 2542 } 2543 $stylesheet .= $custom_css; 2544 2545 // Add the global styles custom CSS at the end. 2546 $stylesheet .= wp_get_global_stylesheet( array( 'custom-css' ) ); 2549 2547 2550 2548 if ( empty( $stylesheet ) ) { -
trunk/tests/phpunit/tests/template.php
r61469 r61473 1562 1562 'normal-css', 1563 1563 'normal-inline-css', 1564 'wp-custom-css',1565 1564 ), 1566 1565 'BODY' => array( … … 1624 1623 'normal-css', 1625 1624 'normal-inline-css', 1626 'wp-custom-css',1627 1625 ), 1628 1626 'BODY' => array( -
trunk/tests/phpunit/tests/theme/wpThemeJson.php
r61190 r61473 1217 1217 ), 1218 1218 ), 1219 'styles' => array( 1220 'spacing' => array( 1221 'blockGap' => '1em', 1222 ), 1223 ), 1219 1224 ), 1220 1225 'default' 1221 1226 ); 1222 $stylesheet = $theme_json->get_stylesheet( array( 'base-layout-styles' ) ); 1223 1224 // Note the `base-layout-styles` includes a fallback gap for the Columns block for backwards compatibility. 1227 // Set base_layout_styles to true to generate only base layout styles without alignment rules. 1228 $stylesheet = $theme_json->get_stylesheet( array( 'styles' ), null, array( 'base_layout_styles' => true ) ); 1229 1230 // Verify that layout styles are still generated, but without .wp-site-blocks alignment rules and flow/constrained base styles. 1225 1231 $this->assertSame( 1226 ':where( .is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}:where(.wp-block-columns.is-layout-flex){gap: 2em;}:where(.wp-block-columns.is-layout-grid){gap: 2em;}:where(.wp-block-post-template.is-layout-flex){gap: 1.25em;}:where(.wp-block-post-template.is-layout-grid){gap: 1.25em;}',1232 ':where(body) { margin: 0; }:where(.is-layout-flex){gap: 0.5em;}:where(.is-layout-grid){gap: 0.5em;}body .is-layout-flex{display: flex;}.is-layout-flex{flex-wrap: wrap;align-items: center;}.is-layout-flex > :is(*, div){margin: 0;}body .is-layout-grid{display: grid;}.is-layout-grid > :is(*, div){margin: 0;}', 1227 1233 $stylesheet 1228 1234 ); … … 1246 1252 'default' 1247 1253 ); 1248 $stylesheet = $theme_json->get_stylesheet( array( ' base-layout-styles' ));1254 $stylesheet = $theme_json->get_stylesheet( array( 'styles' ), null ); 1249 1255 remove_theme_support( 'disable-layout-styles' ); 1250 1256 1251 // All Layout styles should be skipped .1257 // All Layout styles should be skipped when disable-layout-styles theme support is added. 1252 1258 $this->assertSame( 1253 1259 '', -
trunk/tests/phpunit/tests/theme/wpThemeJsonResolver.php
r60729 r61473 735 735 * @covers WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles 736 736 */ 737 public function test_get_user_data_from_wp_global_styles_ does_not_run_for_theme_without_support() {738 // The 'default' theme does not support theme.json .737 public function test_get_user_data_from_wp_global_styles_runs_for_classic_themes() { 738 // The 'default' theme does not support theme.json (classic theme). 739 739 switch_theme( 'default' ); 740 740 wp_set_current_user( self::$administrator_id ); 741 741 $theme = wp_get_theme(); 742 742 743 $start_queries = get_num_queries(); 744 745 // When theme.json is not supported, the method should not run a query and always return an empty result. 746 $user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme ); 747 $this->assertEmpty( $user_cpt, 'User CPT is expected to be empty.' ); 748 $this->assertSame( 0, get_num_queries() - $start_queries, 'Unexpected SQL query detected for theme without theme.json support.' ); 749 743 // Classic themes should now be able to access user global styles data. 744 // When should_create_post is true, it should create a post. 750 745 $user_cpt = WP_Theme_JSON_Resolver::get_user_data_from_wp_global_styles( $theme, true ); 751 $this->assertEmpty( $user_cpt, 'User CPT is expected to be empty.' ); 752 $this->assertSame( 0, get_num_queries() - $start_queries, 'Unexpected SQL query detected for theme without theme.json support.' ); 746 $this->assertIsArray( $user_cpt, 'User CPT should be an array for classic themes.' ); 747 $this->assertArrayHasKey( 'ID', $user_cpt, 'User CPT should have an ID for classic themes.' ); 748 749 // Clean up the created post. 750 if ( isset( $user_cpt['ID'] ) ) { 751 wp_delete_post( $user_cpt['ID'], true ); 752 } 753 753 } 754 754
Note: See TracChangeset
for help on using the changeset viewer.