From d2502eb0912ddac789490dd1baa4a08105a53375 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9?= <583546+oandregal@users.noreply.github.com> Date: Fri, 22 Oct 2021 16:47:51 +0200 Subject: [PATCH] Editor defaults for themes with no editor styles and for when user disables theme styles (#35736) --- lib/class-wp-theme-json-gutenberg.php | 36 ++++---- .../get-global-styles-and-settings.php | 22 ++--- lib/global-styles.php | 87 ++++++++----------- packages/edit-post/src/editor.js | 17 +++- .../class-wp-theme-json-schema-v0-test.php | 4 +- phpunit/class-wp-theme-json-test.php | 18 ++-- 6 files changed, 95 insertions(+), 89 deletions(-) diff --git a/lib/class-wp-theme-json-gutenberg.php b/lib/class-wp-theme-json-gutenberg.php index 6af3d01cf6b582..f84696e019d23a 100644 --- a/lib/class-wp-theme-json-gutenberg.php +++ b/lib/class-wp-theme-json-gutenberg.php @@ -1261,30 +1261,34 @@ private static function get_setting_nodes( $theme_json, $selectors = array() ) { * Returns the stylesheet that results of processing * the theme.json structure this object represents. * - * @param string $type Type of stylesheet. It accepts: - * 'all': css variables, block classes, preset classes. The default. - * 'block_styles': only block & preset classes. - * 'css_variables': only css variables. - * 'presets': only css variables and preset classes. - * @param array $origins A list of origins to include. By default it includes 'core', 'theme', and 'user'. + * @param array $types Types of styles to load. Will load all by default. It accepts: + * 'variables': only the CSS Custom Properties for presets & custom ones. + * 'styles': only the styles section in theme.json. + * 'presets': only the classes for the presets. + * @param array $origins A list of origins to include. By default it includes 'core', 'theme', and 'user'. * * @return string Stylesheet. */ - public function get_stylesheet( $type = 'all', $origins = self::VALID_ORIGINS ) { + public function get_stylesheet( $types = array( 'variables', 'styles', 'presets' ), $origins = self::VALID_ORIGINS ) { $blocks_metadata = self::get_blocks_metadata(); $style_nodes = self::get_style_nodes( $this->theme_json, $blocks_metadata ); $setting_nodes = self::get_setting_nodes( $this->theme_json, $blocks_metadata ); - switch ( $type ) { - case 'block_styles': - return $this->get_block_classes( $style_nodes ) . $this->get_preset_classes( $setting_nodes, $origins ); - case 'css_variables': - return $this->get_css_variables( $setting_nodes, $origins ); - case 'presets': - return $this->get_css_variables( $setting_nodes, $origins ) . $this->get_preset_classes( $setting_nodes, $origins ); - default: - return $this->get_css_variables( $setting_nodes, $origins ) . $this->get_block_classes( $style_nodes ) . $this->get_preset_classes( $setting_nodes, $origins ); + $stylesheet = ''; + + if ( in_array( 'variables', $types, true ) ) { + $stylesheet .= $this->get_css_variables( $setting_nodes, $origins ); + } + + if ( in_array( 'styles', $types, true ) ) { + $stylesheet .= $this->get_block_classes( $style_nodes ); } + + if ( in_array( 'presets', $types, true ) ) { + $stylesheet .= $this->get_preset_classes( $setting_nodes, $origins ); + } + + return $stylesheet; } /** diff --git a/lib/compat/wordpress-5.9/get-global-styles-and-settings.php b/lib/compat/wordpress-5.9/get-global-styles-and-settings.php index 67ec9d032e8e03..ef82e922d5a471 100644 --- a/lib/compat/wordpress-5.9/get-global-styles-and-settings.php +++ b/lib/compat/wordpress-5.9/get-global-styles-and-settings.php @@ -68,18 +68,18 @@ function gutenberg_get_global_styles( $path = array(), $block_name = '', $origin /** * Returns the stylesheet resulting of merging core, theme, and user data. * - * @param string $type Type of the stylesheet. Optional. - * It accepts 'all', 'block_styles', 'css_variables', 'presets'. - * If empty, it'll resolve to all (theme with theme.json support) - * or 'presets' (theme without theme.json support). + * @param array $types Types of styles to load. Optional. + * It accepts 'variables', 'styles', 'presets' as values. + * If empty, it'll load all for themes with theme.json support + * and only [ 'variables', 'presets' ] for themes without theme.json support. * * @return string Stylesheet. */ -function gutenberg_get_global_stylesheet( $type = '' ) { +function gutenberg_get_global_stylesheet( $types = array() ) { // Return cached value if it can be used and exists. // It's cached by theme to make sure that theme switching clears the cache. $can_use_cached = ( - ( 'all' === $type ) && + ( empty( $types ) ) && ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) && ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ) && ( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) && @@ -95,10 +95,10 @@ function gutenberg_get_global_stylesheet( $type = '' ) { $supports_theme_json = WP_Theme_JSON_Resolver_Gutenberg::theme_has_support(); $supports_link_color = get_theme_support( 'experimental-link-color' ); - if ( empty( $type ) && ! $supports_theme_json ) { - $type = 'presets'; - } elseif ( empty( $type ) ) { - $type = 'all'; + if ( empty( $types ) && ! $supports_theme_json ) { + $types = array( 'variables', 'presets' ); + } elseif ( empty( $types ) ) { + $types = array( 'variables', 'styles', 'presets' ); } $origins = array( 'core', 'theme', 'user' ); @@ -113,7 +113,7 @@ function gutenberg_get_global_stylesheet( $type = '' ) { $theme_supports = gutenberg_get_default_block_editor_settings(); $tree = WP_Theme_JSON_Resolver_Gutenberg::get_merged_data( $theme_supports ); - $stylesheet = $tree->get_stylesheet( $type, $origins ); + $stylesheet = $tree->get_stylesheet( $types, $origins ); if ( $can_use_cached ) { // Cache for a minute. diff --git a/lib/global-styles.php b/lib/global-styles.php index 30963769f0a069..64bda774374b5e 100644 --- a/lib/global-styles.php +++ b/lib/global-styles.php @@ -9,43 +9,15 @@ * Takes a tree adhering to the theme.json schema and generates * the corresponding stylesheet. * - * @param WP_Theme_JSON_Gutenberg $tree Input tree. - * @param string $type Type of stylesheet. It accepts 'all', 'block_styles', 'css_variables', 'presets'. + * @param WP_Theme_JSON_Gutenberg $tree Input tree. + * @param array $types Which styles to load. It accepts 'variables', 'styles', 'presets'. By default, it'll load all. * * @return string Stylesheet. */ -function gutenberg_experimental_global_styles_get_stylesheet( $tree, $type = null ) { - // Check if we can use cached. - $can_use_cached = ( - ( 'all' === $type ) && - ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) && - ( ! defined( 'SCRIPT_DEBUG' ) || ! SCRIPT_DEBUG ) && - ( ! defined( 'REST_REQUEST' ) || ! REST_REQUEST ) && - ! is_admin() - ); - - $transient_name = 'gutenberg_global_styles_' . get_stylesheet(); - if ( $can_use_cached ) { - // Check if we have the styles already cached. - // It's cached by theme to make sure that theme switching - // is inmediately reflected. - $cached = get_transient( $transient_name ); - if ( $cached ) { - return $cached; - } - } - +function gutenberg_experimental_global_styles_get_stylesheet( $tree, $types = array( 'variables', 'styles', 'presets' ) ) { + $origins = array( 'core', 'theme', 'user' ); $supports_theme_json = WP_Theme_JSON_Resolver_Gutenberg::theme_has_support(); $supports_link_color = get_theme_support( 'experimental-link-color' ); - - // Only modify the $type if the consumer hasn't provided any. - if ( null === $type && ! $supports_theme_json ) { - $type = 'presets'; - } elseif ( null === $type ) { - $type = 'all'; - } - - $origins = array( 'core', 'theme', 'user' ); if ( ! $supports_theme_json && ! $supports_link_color ) { // In this case we only enqueue the core presets (CSS Custom Properties + the classes). $origins = array( 'core' ); @@ -55,13 +27,7 @@ function gutenberg_experimental_global_styles_get_stylesheet( $tree, $type = nul $origins = array( 'core', 'theme' ); } - $stylesheet = $tree->get_stylesheet( $type, $origins ); - - if ( $can_use_cached ) { - // Cache for a minute. - // This cache doesn't need to be any longer, we only want to avoid spikes on high-traffic sites. - set_transient( $transient_name, $stylesheet, MINUTE_IN_SECONDS ); - } + $stylesheet = $tree->get_stylesheet( $types, $origins ); return $stylesheet; } @@ -128,12 +94,6 @@ function_exists( 'gutenberg_is_edit_site_page' ) && } if ( 'other' === $context ) { - $block_styles = array( 'css' => gutenberg_experimental_global_styles_get_stylesheet( $consolidated, 'block_styles' ) ); - $css_variables = array( - 'css' => gutenberg_experimental_global_styles_get_stylesheet( $consolidated, 'css_variables' ), - '__experimentalNoWrapper' => true, - ); - // Make sure the styles array exists. // In some contexts, like the navigation editor, it doesn't. if ( ! isset( $settings['styles'] ) ) { @@ -148,10 +108,39 @@ function_exists( 'gutenberg_is_edit_site_page' ) && } } - // Add the new ones. - $styles_without_existing_global_styles[] = $css_variables; - $styles_without_existing_global_styles[] = $block_styles; - $settings['styles'] = $styles_without_existing_global_styles; + $new_global_styles = array(); + $new_presets = array( + array( + 'css' => 'variables', + '__unstableType' => 'presets', + '__experimentalNoWrapper' => true, + ), + array( + 'css' => 'presets', + '__unstableType' => 'presets', + ), + ); + foreach ( $new_presets as $new_style ) { + $style_css = gutenberg_experimental_global_styles_get_stylesheet( $consolidated, array( $new_style['css'] ) ); + if ( '' !== $style_css ) { + $new_style['css'] = $style_css; + $new_global_styles[] = $new_style; + } + } + + $new_block_classes = array( + 'css' => 'styles', + '__unstableType' => 'theme', + ); + if ( WP_Theme_JSON_Resolver_Gutenberg::theme_has_support() ) { + $style_css = gutenberg_experimental_global_styles_get_stylesheet( $consolidated, array( $new_block_classes['css'] ) ); + if ( '' !== $style_css ) { + $new_block_classes['css'] = $style_css; + $new_global_styles[] = $new_block_classes; + } + } + + $settings['styles'] = array_merge( $styles_without_existing_global_styles, $new_global_styles ); } // Copied from get_block_editor_settings() at wordpress-develop/block-editor.php. diff --git a/packages/edit-post/src/editor.js b/packages/edit-post/src/editor.js index c35519b7617312..ed280e35867fee 100644 --- a/packages/edit-post/src/editor.js +++ b/packages/edit-post/src/editor.js @@ -161,9 +161,22 @@ function Editor( { ] ); const styles = useMemo( () => { - return hasThemeStyles && settings.styles?.length + const themeStyles = []; + const presetStyles = []; + settings.styles.forEach( ( style ) => { + if ( ! style.__unstableType || style.__unstableType === 'theme' ) { + themeStyles.push( style ); + } else { + presetStyles.push( style ); + } + } ); + const defaultEditorStyles = [ + ...settings.defaultEditorStyles, + ...presetStyles, + ]; + return hasThemeStyles && themeStyles.length ? settings.styles - : settings.defaultEditorStyles; + : defaultEditorStyles; }, [ settings, hasThemeStyles ] ); if ( ! post ) { diff --git a/phpunit/class-wp-theme-json-schema-v0-test.php b/phpunit/class-wp-theme-json-schema-v0-test.php index 9815644188343a..5056a39edd5542 100644 --- a/phpunit/class-wp-theme-json-schema-v0-test.php +++ b/phpunit/class-wp-theme-json-schema-v0-test.php @@ -476,11 +476,11 @@ function test_get_stylesheet() { ); $this->assertEquals( 'body{color: var(--wp--preset--color--grey);}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; }a{color: #111;}h1{font-size: 1em;}h2{font-size: 2em;}.wp-block-group{padding-top: 12px;padding-bottom: 24px;}.wp-block-group a{color: #333;}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{color: #222;}.wp-block-post-title{font-size: 5em;}.wp-block-post-title a{color: #555;}.wp-block-query-title{font-size: 5em;}.wp-block-query-title a{color: #555;}.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;}', - $theme_json->get_stylesheet( 'block_styles' ) + $theme_json->get_stylesheet( array( 'styles', 'presets' ) ) ); $this->assertEquals( '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;}', - $theme_json->get_stylesheet( 'css_variables' ) + $theme_json->get_stylesheet( array( 'variables' ) ) ); } diff --git a/phpunit/class-wp-theme-json-test.php b/phpunit/class-wp-theme-json-test.php index c51966217fd2a7..173198c34b7361 100644 --- a/phpunit/class-wp-theme-json-test.php +++ b/phpunit/class-wp-theme-json-test.php @@ -230,7 +230,7 @@ function test_get_stylesheet_support_for_shorthand_and_longhand_values() { ); $this->assertEquals( '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-block-group{border-radius: 10px;margin: 1em;padding: 24px;}.wp-block-image{border-top-left-radius: 10px;border-bottom-right-radius: 1em;margin-bottom: 30px;padding-top: 15px;}', - $theme_json->get_stylesheet( 'block_styles' ) + $theme_json->get_stylesheet( array( 'styles', 'presets' ) ) ); } @@ -260,7 +260,7 @@ function test_get_stylesheet_skips_disabled_protected_properties() { $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; }'; $this->assertEquals( $expected, $theme_json->get_stylesheet() ); - $this->assertEquals( $expected, $theme_json->get_stylesheet( 'block_styles' ) ); + $this->assertEquals( $expected, $theme_json->get_stylesheet( array( 'styles', 'presets' ) ) ); } function test_get_stylesheet_renders_enabled_protected_properties() { @@ -289,7 +289,7 @@ function test_get_stylesheet_renders_enabled_protected_properties() { $expected = 'body{--wp--style--block-gap: 1em;}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-top: 0; margin-bottom: 0; }.wp-site-blocks > * + * { margin-top: var( --wp--style--block-gap ); }.wp-block-columns{--wp--style--block-gap: 24px;}'; $this->assertEquals( $expected, $theme_json->get_stylesheet() ); - $this->assertEquals( $expected, $theme_json->get_stylesheet( 'block_styles' ) ); + $this->assertEquals( $expected, $theme_json->get_stylesheet( array( 'styles', 'presets' ) ) ); } function test_get_stylesheet() { @@ -418,11 +418,11 @@ function test_get_stylesheet() { ); $this->assertEquals( 'body{color: var(--wp--preset--color--grey);}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-top: 0; margin-bottom: 0; }.wp-site-blocks > * + * { margin-top: var( --wp--style--block-gap ); }a{background-color: #333;color: #111;}.wp-block-group{border-radius: 10px;padding: 24px;}.wp-block-group a{color: #111;}h1,h2,h3,h4,h5,h6{color: #123456;}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{background-color: #333;color: #111;font-size: 60px;}.wp-block-post-date{color: #123456;}.wp-block-post-date a{background-color: #777;color: #555;}.wp-block-image{border-top-left-radius: 10px;border-bottom-right-radius: 1em;margin-bottom: 30px;}.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;}', - $theme_json->get_stylesheet( 'block_styles' ) + $theme_json->get_stylesheet( array( 'styles', 'presets' ) ) ); $this->assertEquals( '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;}', - $theme_json->get_stylesheet( 'css_variables' ) + $theme_json->get_stylesheet( array( 'variables' ) ) ); } @@ -449,7 +449,7 @@ function test_get_stylesheet_preset_classes_work_with_compounded_selectors() { $this->assertEquals( 'h1.has-white-color,h2.has-white-color,h3.has-white-color,h4.has-white-color,h5.has-white-color,h6.has-white-color{color: var(--wp--preset--color--white) !important;}h1.has-white-background-color,h2.has-white-background-color,h3.has-white-background-color,h4.has-white-background-color,h5.has-white-background-color,h6.has-white-background-color{background-color: var(--wp--preset--color--white) !important;}h1.has-white-border-color,h2.has-white-border-color,h3.has-white-border-color,h4.has-white-border-color,h5.has-white-border-color,h6.has-white-border-color{border-color: var(--wp--preset--color--white) !important;}', - $theme_json->get_stylesheet( 'block_styles' ) + $theme_json->get_stylesheet( array( 'styles', 'presets' ) ) ); } @@ -489,7 +489,7 @@ function test_get_stylesheet_preset_rules_come_after_block_rules() { ); $this->assertEquals( '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-block-group{color: red;}.wp-block-group.has-grey-color{color: var(--wp--preset--color--grey) !important;}.wp-block-group.has-grey-background-color{background-color: var(--wp--preset--color--grey) !important;}.wp-block-group.has-grey-border-color{border-color: var(--wp--preset--color--grey) !important;}', - $theme_json->get_stylesheet( 'block_styles' ) + $theme_json->get_stylesheet( array( 'styles', 'presets' ) ) ); } @@ -524,11 +524,11 @@ function test_get_stylesheet_generates_proper_classes_from_slugs() { $this->assertEquals( '.has-grey-color{color: var(--wp--preset--color--grey) !important;}.has-dark-grey-color{color: var(--wp--preset--color--dark-grey) !important;}.has-light-grey-color{color: var(--wp--preset--color--light-grey) !important;}.has-white-2-black-color{color: var(--wp--preset--color--white-2-black) !important;}.has-grey-background-color{background-color: var(--wp--preset--color--grey) !important;}.has-dark-grey-background-color{background-color: var(--wp--preset--color--dark-grey) !important;}.has-light-grey-background-color{background-color: var(--wp--preset--color--light-grey) !important;}.has-white-2-black-background-color{background-color: var(--wp--preset--color--white-2-black) !important;}.has-grey-border-color{border-color: var(--wp--preset--color--grey) !important;}.has-dark-grey-border-color{border-color: var(--wp--preset--color--dark-grey) !important;}.has-light-grey-border-color{border-color: var(--wp--preset--color--light-grey) !important;}.has-white-2-black-border-color{border-color: var(--wp--preset--color--white-2-black) !important;}', - $theme_json->get_stylesheet( 'block_styles' ) + $theme_json->get_stylesheet( array( 'styles', 'presets' ) ) ); $this->assertEquals( 'body{--wp--preset--color--grey: grey;--wp--preset--color--dark-grey: grey;--wp--preset--color--light-grey: grey;--wp--preset--color--white-2-black: grey;}', - $theme_json->get_stylesheet( 'css_variables' ) + $theme_json->get_stylesheet( array( 'variables' ) ) ); }