diff --git a/lib/blocks.php b/lib/blocks.php index e2298c33ca9a59..366f4f87b3b542 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -242,9 +242,9 @@ function gutenberg_experimental_apply_classnames_and_styles( $block_content, $bl $supports = gutenberg_experimental_global_styles_get_supported_styles( $block_type->supports ); $attributes = array(); - $attributes = gutenberg_experimental_build_css_colors( $attributes, $block['attrs'], $supports ); - $attributes = gutenberg_experimental_build_css_typography( $attributes, $block['attrs'], $supports ); - $attributes = gutenberg_build_css_block_alignment( $attributes, $block['attrs'], $supports ); + $attributes = gutenberg_experimental_build_css_colors( $attributes, $block['attrs'], $supports, $block_type ); + $attributes = gutenberg_experimental_build_css_typography( $attributes, $block['attrs'], $supports, $block_type ); + $attributes = gutenberg_build_css_block_alignment( $attributes, $block['attrs'], $supports, $block_type ); if ( ! count( $attributes ) ) { return $block_content; @@ -295,20 +295,23 @@ function gutenberg_experimental_apply_classnames_and_styles( $block_content, $bl * Add CSS classes and inline styles for colors to the incoming attributes array. * This will be applied to the block markup in the front-end. * - * @param array $attributes comprehensive list of attributes to be applied. - * @param array $block_attributes block attributes. - * @param array $supports style features the block attributes. + * @param array $attributes comprehensive list of attributes to be applied. + * @param array $block_attributes block attributes. + * @param array $supports style features the block attributes. + * @param object $block_type registered block type class. * @return array Colors CSS classes and inline styles. */ -function gutenberg_experimental_build_css_colors( $attributes, $block_attributes, $supports ) { +function gutenberg_experimental_build_css_colors( $attributes, $block_attributes, $supports, $block_type ) { // Text Colors. // Check support for text colors. if ( in_array( 'color', $supports, true ) ) { - $has_named_text_color = array_key_exists( 'textColor', $block_attributes ); - $has_custom_text_color = isset( $block_attributes['style']['color']['text'] ); + $has_named_text_color = array_key_exists( 'textColor', $block_attributes ); + $has_custom_text_color = isset( $block_attributes['style']['color']['text'] ); + $has_named_text_color_default = isset( $block_type->attributes['textColor']['default'] ); + $has_custom_text_color_default = isset( $block_type->attributes['style']['default']['color']['text'] ); // Apply required generic class. - if ( $has_custom_text_color || $has_named_text_color ) { + if ( $has_custom_text_color || $has_named_text_color || $has_named_text_color_default || $has_custom_text_color_default ) { $attributes['css_classes'][] = 'has-text-color'; } // Apply color class or inline style. @@ -316,15 +319,24 @@ function gutenberg_experimental_build_css_colors( $attributes, $block_attributes $attributes['css_classes'][] = sprintf( 'has-%s-color', $block_attributes['textColor'] ); } elseif ( $has_custom_text_color ) { $attributes['inline_styles'][] = sprintf( 'color: %s;', $block_attributes['style']['color']['text'] ); + // Fallback to default value if defined. + } elseif ( $has_named_text_color_default ) { + $attributes['css_classes'][] = sprintf( 'has-%s-color', $block_type->attributes['textColor']['default'] ); + } elseif ( $has_custom_text_color_default ) { + $attributes['inline_styles'][] = sprintf( 'color: %s;', $block_type->attributes['style']['default']['color']['text'] ); } } // Link Colors. if ( in_array( '--wp--style--color--link', $supports, true ) ) { - $has_link_color = isset( $block_attributes['style']['color']['link'] ); + $has_link_color = isset( $block_attributes['style']['color']['link'] ); + $has_link_color_default = isset( $block_type->attributes['style']['default']['color']['link'] ); // Apply required class and style. - if ( $has_link_color ) { + if ( $has_link_color || $has_link_color_default ) { $attributes['css_classes'][] = 'has-link-color'; + } + + if ( $has_link_color ) { // If link is a named color. if ( strpos( $block_attributes['style']['color']['link'], 'var:preset|color|' ) !== false ) { // Get the name from the string and add proper styles. @@ -334,6 +346,17 @@ function gutenberg_experimental_build_css_colors( $attributes, $block_attributes } else { $attributes['inline_styles'][] = sprintf( '--wp--style--color--link: %s;', $block_attributes['style']['color']['link'] ); } + // Fallback to default value if defined. + } elseif ( $has_link_color_default ) { + // If link is a named color. + if ( strpos( $block_type->attributes['style']['default']['color']['link'], 'var:preset|color|' ) !== false ) { + // Get the name from the string and add proper styles. + $index_to_splice = strrpos( $block_type->attributes['style']['default']['color']['link'], '|' ) + 1; + $link_color_name = substr( $block_type->attributes['style']['default']['color']['link'], $index_to_splice ); + $attributes['inline_styles'][] = sprintf( '--wp--style--color--link:var(--wp--preset--color--%s);', $link_color_name ); + } else { + $attributes['inline_styles'][] = sprintf( '--wp--style--color--link: %s;', $block_type->attributes['style']['default']['color']['link'] ); + } } } @@ -370,6 +393,32 @@ function gutenberg_experimental_build_css_colors( $attributes, $block_attributes } } + // Fallback to default values for background and gradient if neither have been set. + if ( ! isset( $attributes['css_classes'] ) || ! in_array( 'has-background', $attributes['css_classes'], true ) ) { + $has_named_background_default = isset( $block_type->attributes['backgroundColor']['default'] ); + $has_custom_background_default = isset( $block_type->attributes['style']['default']['color']['background'] ); + + // Check backrgound support and apply default background if exists. + if ( in_array( 'background-color', $supports, true ) && ( $has_named_background_default || $has_custom_background_default ) ) { + if ( $has_named_background_default ) { + $attributes['css_classes'][] = 'has-background'; + $attributes['css_classes'][] = sprintf( 'has-%s-background-color', $block_type->attributes['backgroundColor']['default'] ); + } elseif ( $has_custom_background_default ) { + $attributes['css_classes'][] = 'has-background'; + $attributes['inline_styles'][] = sprintf( 'background-color: %s;', $block_type->attributes['style']['default']['color']['background'] ); + } + // Check gradient support and apply default background if exists. + } elseif ( in_array( 'background', $supports, true ) ) { + if ( isset( $block_type->attributes['gradient']['default'] ) ) { + $attributes['css_classes'][] = 'has-background'; + $attributes['css_classes'][] = sprintf( 'has-%s-gradient-background', $block_type->attributes['gradient']['default'] ); + } elseif ( isset( $block_type->attributes['style']['default']['color']['gradient'] ) ) { + $attributes['css_classes'][] = 'has-background'; + $attributes['inline_styles'][] = sprintf( 'background: %s;', $block_type->attributes['style']['default']['color']['gradient'] ); + } + } + } + return $attributes; } @@ -377,12 +426,13 @@ function gutenberg_experimental_build_css_colors( $attributes, $block_attributes * Add CSS classes and inline styles for font sizes to the incoming attributes array. * This will be applied to the block markup in the front-end. * - * @param array $attributes comprehensive list of attributes to be applied. - * @param array $block_attributes block attributes. - * @param array $supports style features the block attributes. + * @param array $attributes comprehensive list of attributes to be applied. + * @param array $block_attributes block attributes. + * @param array $supports style features the block attributes. + * @param object $block_type registered block type class. * @return array Font size CSS classes and inline styles. */ -function gutenberg_experimental_build_css_typography( $attributes, $block_attributes, $supports ) { +function gutenberg_experimental_build_css_typography( $attributes, $block_attributes, $supports, $block_type ) { // Font Size. if ( in_array( 'font-size', $supports, true ) ) { $has_named_font_size = array_key_exists( 'fontSize', $block_attributes ); @@ -393,6 +443,11 @@ function gutenberg_experimental_build_css_typography( $attributes, $block_attrib $attributes['css_classes'][] = sprintf( 'has-%s-font-size', $block_attributes['fontSize'] ); } elseif ( $has_custom_font_size ) { $attributes['inline_styles'][] = sprintf( 'font-size: %spx;', $block_attributes['style']['typography']['fontSize'] ); + // Fallback to default value if defined. + } elseif ( isset( $block_type->attributes['fontSize']['default'] ) ) { + $attributes['css_classes'][] = sprintf( 'has-%s-font-size', $block_type->attributes['fontSize']['default'] ); + } elseif ( isset( $block_type->attributes['style']['default']['typography']['fontSize'] ) ) { + $attributes['inline_styles'][] = sprintf( 'font-size: %spx;', $block_type->attributes['style']['default']['typography']['fontSize'] ); } } @@ -402,6 +457,9 @@ function gutenberg_experimental_build_css_typography( $attributes, $block_attrib // Add the style (no classes for line-height). if ( $has_line_height ) { $attributes['inline_styles'][] = sprintf( 'line-height: %s;', $block_attributes['style']['typography']['lineHeight'] ); + // Fallback to default value if defined. + } elseif ( isset( $block_type->attributes['style']['default']['typography']['lineHeight'] ) ) { + $attributes['inline_styles'][] = sprintf( 'line-height: %s;', $block_type->attributes['style']['default']['typography']['lineHeight'] ); } } @@ -412,17 +470,25 @@ function gutenberg_experimental_build_css_typography( $attributes, $block_attrib * Add CSS classes for block alignment to the incoming attributes array. * This will be applied to the block markup in the front-end. * - * @param array $attributes comprehensive list of attributes to be applied. - * @param array $block_attributes block attributes. - * @param array $supports style features the block attributes. + * @param array $attributes comprehensive list of attributes to be applied. + * @param array $block_attributes block attributes. + * @param array $supports style features the block attributes. + * @param object $block_type registered block type class. * @return array Block alignment CSS classes and inline styles. */ -function gutenberg_build_css_block_alignment( $attributes, $block_attributes, $supports ) { +function gutenberg_build_css_block_alignment( $attributes, $block_attributes, $supports, $block_type ) { if ( in_array( 'block-align', $supports, true ) ) { $has_block_alignment = array_key_exists( 'align', $block_attributes ); - if ( $has_block_alignment ) { - $attributes['css_classes'][] = sprintf( 'align%s', $block_attributes['align'] ); + // Don't apply style or default if attribute is saved to be ''. + // This is used as the none option when a default value is defined. + if ( '' !== $block_attributes['align'] ) { + if ( $has_block_alignment ) { + $attributes['css_classes'][] = sprintf( 'align%s', $block_attributes['align'] ); + // Fallback to default value if defined. + } elseif ( isset( $block_type->attributes['align']['default'] ) ) { + $attributes['css_classes'][] = sprintf( 'align%s', $block_type->attributes['align']['default'] ); + } } } diff --git a/phpunit/class-block-supported-styles-test.php b/phpunit/class-block-supported-styles-test.php index c4596be98e9ca1..d96a686e966aad 100644 --- a/phpunit/class-block-supported-styles-test.php +++ b/phpunit/class-block-supported-styles-test.php @@ -89,7 +89,7 @@ private function assert_styles_and_classes_match( $block, $expected_classes, $ex private $block_content = '
'; /** - * Tests color support for named color support for named colors. + * Tests color support for named colors. */ function test_named_color_support() { $block_type_settings = array( @@ -120,6 +120,38 @@ function test_named_color_support() { $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); } + /** + * Tests default color support for named color default values. + */ + function test_named_color_support_default() { + $block_type_settings = array( + 'attributes' => array( + 'textColor' => array( 'default' => 'red' ), + 'backgroundColor' => array( 'default' => 'black' ), + // The following should not be applied (subcatagories of color support). + 'gradient' => array( 'default' => 'blue' ), + ), + 'supports' => array( + '__experimentalColor' => true, + ), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array(), + 'innerBlock' => array(), + 'innerContent' => array(), + 'innerHTML' => array(), + ); + + $expected_classes = 'wp-block-example foo-bar-class has-text-color has-red-color has-background has-black-background-color'; + $expected_styles = 'test:style; '; + + $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); + } + /** * Tests color support for custom colors. */ @@ -142,7 +174,7 @@ function test_custom_color_support() { 'background' => '#fff', // The following should not be applied (subcatagories of color support). 'gradient' => 'some-gradient', - 'style' => array( 'color' => array( 'link' => '#fff' ) ), + 'link' => '#fff', ), ), ), @@ -157,6 +189,45 @@ function test_custom_color_support() { $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); } + /** + * Tests color support for custom color default values. + */ + function test_custom_color_support_default() { + $block_type_settings = array( + 'attributes' => array( + 'style' => array( + 'default' => array( + 'color' => array( + 'text' => '#000', + 'background' => '#fff', + // The following should not be applied (subcatagories of color support). + 'gradient' => 'some-gradient', + 'link' => '#fff', + ), + ), + ), + ), + 'supports' => array( + '__experimentalColor' => true, + ), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array(), + 'innerBlock' => array(), + 'innerContent' => array(), + 'innerHTML' => array(), + ); + + $expected_styles = 'test:style; color: #000; background-color: #fff;'; + $expected_classes = 'wp-block-example foo-bar-class has-text-color has-background'; + + $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); + } + /** * Tests link color support for named colors. */ @@ -188,6 +259,43 @@ function test_named_link_color_support() { $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); } + /** + * Tests link color support for named color default value. + */ + function test_named_link_color_support_default() { + $block_type_settings = array( + 'attributes' => array( + 'style' => array( + 'default' => array( + 'color' => array( + 'link' => 'var:preset|color|red', + ), + ), + ), + ), + 'supports' => array( + '__experimentalColor' => array( + 'linkColor' => true, + ), + ), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array(), + 'innerBlock' => array(), + 'innerContent' => array(), + 'innerHTML' => array(), + ); + + $expected_classes = 'wp-block-example foo-bar-class has-link-color'; + $expected_styles = 'test:style; --wp--style--color--link:var(--wp--preset--color--red);'; + + $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); + } + /** * Tests link color support for custom colors. */ @@ -219,6 +327,43 @@ function test_custom_link_color_support() { $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); } + /** + * Tests link color support for custom colors default value. + */ + function test_custom_link_color_support_default() { + $block_type_settings = array( + 'attributes' => array( + 'style' => array( + 'default' => array( + 'color' => array( + 'link' => '#fff', + ), + ), + ), + ), + 'supports' => array( + '__experimentalColor' => array( + 'linkColor' => true, + ), + ), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array(), + 'innerBlock' => array(), + 'innerContent' => array(), + 'innerHTML' => array(), + ); + + $expected_classes = 'wp-block-example foo-bar-class has-link-color'; + $expected_styles = 'test:style; --wp--style--color--link: #fff;'; + + $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); + } + /** * Tests gradient color support for named gradients. */ @@ -250,6 +395,37 @@ function test_named_gradient_support() { $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); } + /** + * Tests gradient color support for named gradients default values. + */ + function test_named_gradient_support_default() { + $block_type_settings = array( + 'attributes' => array( + 'gradient' => array( 'default' => 'red' ), + ), + 'supports' => array( + '__experimentalColor' => array( + 'gradients' => true, + ), + ), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array(), + 'innerBlock' => array(), + 'innerContent' => array(), + 'innerHTML' => array(), + ); + + $expected_classes = 'wp-block-example foo-bar-class has-background has-red-gradient-background'; + $expected_styles = 'test:style; '; + + $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); + } + /** * Tests gradient color support for custom gradients. */ @@ -281,12 +457,63 @@ function test_custom_gradient_support() { $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); } + /** + * Tests gradient color support for custom gradients default values. + */ + function test_custom_gradient_support_default() { + $block_type_settings = array( + 'attributes' => array( + 'style' => array( + 'default' => array( + 'color' => array( + 'gradient' => 'some-gradient-style', + ), + ), + ), + ), + 'supports' => array( + '__experimentalColor' => array( + 'gradients' => true, + ), + ), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array(), + 'innerBlock' => array(), + 'innerContent' => array(), + 'innerHTML' => array(), + ); + + $expected_classes = 'wp-block-example foo-bar-class has-background'; + $expected_styles = 'test:style; background: some-gradient-style;'; + + $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); + } + /** * Tests that style attributes for colors are not applied without the support flag. */ function test_color_unsupported() { $block_type_settings = array( - 'attributes' => array(), + 'attributes' => array( + 'textColor' => array( 'default' => 'red' ), + 'backgroundColor' => array( 'default' => 'black' ), + 'gradient' => array( 'default' => 'blue' ), + 'style' => array( + 'default' => array( + 'color' => array( + 'text' => '#000', + 'background' => '#fff', + 'link' => '#ggg', + 'gradient' => 'some-gradient', + ), + ), + ), + ), 'supports' => array(), 'render_callback' => true, ); @@ -346,6 +573,35 @@ function test_named_font_size() { $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); } + /** + * Tests support for named font sizes default values. + */ + function test_named_font_size_default() { + $block_type_settings = array( + 'attributes' => array( + 'fontSize' => array( 'default' => 'large' ), + ), + 'supports' => array( + '__experimentalFontSize' => true, + ), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array(), + 'innerBlock' => array(), + 'innerContent' => array(), + 'innerHTML' => array(), + ); + + $expected_classes = 'wp-block-example foo-bar-class has-large-font-size'; + $expected_styles = 'test:style; '; + + $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); + } + /** * Tests support for custom font sizes. */ @@ -375,12 +631,56 @@ function test_custom_font_size() { $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); } + /** + * Tests support for custom font size default values. + */ + function test_custom_font_size_default() { + $block_type_settings = array( + 'attributes' => array( + 'style' => array( + 'default' => array( + 'typography' => array( + 'fontSize' => '10', + ), + ), + ), + ), + 'supports' => array( + '__experimentalFontSize' => true, + ), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array(), + 'innerBlock' => array(), + 'innerContent' => array(), + 'innerHTML' => array(), + ); + + $expected_classes = 'wp-block-example foo-bar-class '; + $expected_styles = 'test:style; font-size: 10px;'; + + $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); + } + /** * Tests that font size attributes are not applied without support flag. */ function test_font_size_unsupported() { $block_type_settings = array( - 'attributes' => array(), + 'attributes' => array( + 'fontSize' => array( 'default' => 'large' ), + 'style' => array( + 'default' => array( + 'typography' => array( + 'fontSize' => '10', + ), + ), + ), + ), 'supports' => array(), 'render_callback' => true, ); @@ -432,12 +732,55 @@ function test_line_height() { $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); } + /** + * Tests line height support default values. + */ + function test_line_height_default() { + $block_type_settings = array( + 'attributes' => array( + 'style' => array( + 'default' => array( + 'typography' => array( + 'lineHeight' => '10', + ), + ), + ), + ), + 'supports' => array( + '__experimentalLineHeight' => true, + ), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array(), + 'innerBlock' => array(), + 'innerContent' => array(), + 'innerHTML' => array(), + ); + + $expected_classes = 'wp-block-example foo-bar-class '; + $expected_styles = 'test:style; line-height: 10;'; + + $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); + } + /** * Tests line height not applied without support flag. */ function test_line_height_unsupported() { $block_type_settings = array( - 'attributes' => array(), + 'attributes' => array( + 'style' => array( + 'default' => array( + 'typography' => array( + 'lineHeight' => '10', + ), + ), + ), + ), 'supports' => array(), 'render_callback' => true, ); @@ -488,12 +831,43 @@ function test_block_alignment() { $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); } + /** + * Tests support for block alignment default values. + */ + function test_block_alignment_default() { + $block_type_settings = array( + 'attributes' => array( + 'align' => array( 'default' => 'wide' ), + ), + 'supports' => array( + 'align' => true, + ), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array(), + 'innerBlock' => array(), + 'innerContent' => array(), + 'innerHTML' => array(), + ); + + $expected_classes = 'wp-block-example foo-bar-class alignwide'; + $expected_styles = 'test:style; '; + + $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); + } + /** * Tests block alignment requires support to be added. */ function test_block_alignment_unsupported() { $block_type_settings = array( - 'attributes' => array(), + 'attributes' => array( + 'align' => array( 'default' => 'wide' ), + ), 'supports' => array(), 'render_callback' => true, );