diff --git a/docs/designers-developers/developers/themes/theme-json.md b/docs/designers-developers/developers/themes/theme-json.md index 8a523a264fafa6..3db274fbe70e0c 100644 --- a/docs/designers-developers/developers/themes/theme-json.md +++ b/docs/designers-developers/developers/themes/theme-json.md @@ -167,6 +167,7 @@ Each block will declare which style properties it exposes. This has been coined | Group | Yes | Yes | Yes | Yes | | Columns | Yes | Yes | Yes | Yes | | Media & text | Yes | Yes | Yes | Yes | +| Site Title | Yes | Yes | - | Yes | [1] The heading block represents 6 distinct HTML elements: H1-H6. It comes with selectors to target each individual element (ex: core/heading/h1 for H1, etc). @@ -180,6 +181,7 @@ Each block will declare which style properties it exposes. This has been coined | Group | - | - | | Columns | - | - | | Media & text | - | - | +| Site Title | Yes | Yes | [1] The heading block represents 6 distinct HTML elements: H1-H6. It comes with selectors to target each individual element (ex: core/heading/h1 for H1, etc). @@ -379,6 +381,19 @@ The list of features that are currently supported are: "text": } } + }, + "core/site-title": { + "styles": { + "color": { + "background": , + "gradient": , + "text": + }, + "typography": { + "fontSize": , + "lineHeight": + } + } } } ``` diff --git a/lib/blocks.php b/lib/blocks.php index c4118c01c38ab1..df85df02b74428 100644 --- a/lib/blocks.php +++ b/lib/blocks.php @@ -218,3 +218,189 @@ function gutenberg_register_legacy_social_link_blocks() { } } add_action( 'init', 'gutenberg_register_legacy_social_link_blocks' ); + +/** + * Renders the classNames and styles for blocks + * + * @param string $block_content Output of the current block. + * @param array $block Block Object. + * @return string New block output. + */ +function gutenberg_experimental_apply_classnames_and_styles( $block_content, $block ) { + if ( ! isset( $block['attrs'] ) ) { + return $block_content; + } + + $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] ); + // If no render_callback, assume styles have been previously handled. + if ( ! $block_type || ! $block_type->render_callback ) { + return $block_content; + } + // Check what style features the block supports. + $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 ); + + if ( ! count( $attributes ) ) { + return $block_content; + } + + $dom = new DOMDocument( '1.0', 'utf-8' ); + + // Suppress warnings from this method from polluting the front-end. + // @codingStandardsIgnoreStart + if ( ! @$dom->loadHTML( $block_content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD | LIBXML_COMPACT ) ) { + // @codingStandardsIgnoreEnd + return $block_content; + } + + $xpath = new DOMXPath( $dom ); + $block_root = $xpath->query( '/*' )[0]; + + if ( empty( $block_root ) ) { + return $block_content; + } + + // Some inline styles may be added without ending ';', add this if necessary. + $current_styles = trim( $block_root->getAttribute( 'style' ), ' ' ); + if ( strlen( $current_styles ) > 0 && substr( $current_styles, -1 ) !== ';' ) { + $current_styles = $current_styles . ';'; + }; + + // Merge and dedupe new and existing classes and styles. + $classes_to_add = esc_attr( implode( ' ', array_key_exists( 'css_classes', $attributes ) ? $attributes['css_classes'] : array() ) ); + $styles_to_add = esc_attr( implode( ' ', array_key_exists( 'inline_styles', $attributes ) ? $attributes['inline_styles'] : array() ) ); + $new_classes = implode( ' ', array_unique( explode( ' ', ltrim( $block_root->getAttribute( 'class' ) . ' ' ) . $classes_to_add ) ) ); + $new_styles = implode( ' ', array_unique( explode( ' ', $current_styles . ' ' . $styles_to_add ) ) ); + + // Apply new styles and classes. + if ( ! empty( $new_classes ) ) { + $block_root->setAttribute( 'class', $new_classes ); + } + + if ( ! empty( $new_styles ) ) { + $block_root->setAttribute( 'style', $new_styles ); + } + + return $dom->saveHtml(); +} +add_filter( 'render_block', 'gutenberg_experimental_apply_classnames_and_styles', 10, 2 ); + +/** + * Build an array with CSS classes and inline styles defining the colors + * which 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. + * @return array Colors CSS classes and inline styles. + */ +function gutenberg_experimental_build_css_colors( $attributes, $block_attributes, $supports ) { + // 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'] ); + + // Apply required generic class. + if ( $has_custom_text_color || $has_named_text_color ) { + $attributes['css_classes'][] = 'has-text-color'; + } + // Apply color class or inline style. + if ( $has_named_text_color ) { + $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'] ); + } + } + + // Link Colors. + if ( in_array( 'link-color', $supports, true ) ) { + $has_link_color = isset( $block_attributes['style']['color']['link'] ); + // Apply required class and style. + if ( $has_link_color ) { + $attributes['css_classes'][] = '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. + $index_to_splice = strrpos( $block_attributes['style']['color']['link'], '|' ) + 1; + $link_color_name = substr( $block_attributes['style']['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_attributes['style']['color']['link'] ); + } + } + } + + // Background Colors. + if ( in_array( 'background-color', $supports, true ) ) { + $has_named_background_color = array_key_exists( 'backgroundColor', $block_attributes ); + $has_custom_background_color = isset( $block_attributes['style']['color']['background'] ); + + // Apply required background class. + if ( $has_custom_background_color || $has_named_background_color ) { + $attributes['css_classes'][] = 'has-background'; + } + // Apply background color classes or styles. + if ( $has_named_background_color ) { + $attributes['css_classes'][] = sprintf( 'has-%s-background-color', $block_attributes['backgroundColor'] ); + } elseif ( $has_custom_background_color ) { + $attributes['inline_styles'][] = sprintf( 'background-color: %s;', $block_attributes['style']['color']['background'] ); + } + } + + // Gradients. + if ( in_array( 'background', $supports, true ) ) { + $has_named_gradient = array_key_exists( 'gradient', $block_attributes ); + $has_custom_gradient = isset( $block_attributes['style']['color']['gradient'] ); + + if ( $has_named_gradient || $has_custom_gradient ) { + $attributes['css_classes'][] = 'has-background'; + } + // Apply required background class. + if ( $has_named_gradient ) { + $attributes['css_classes'][] = sprintf( 'has-%s-gradient-background', $block_attributes['gradient'] ); + } elseif ( $has_custom_gradient ) { + $attributes['inline_styles'][] = sprintf( 'background: %s;', $block_attributes['style']['color']['gradient'] ); + } + } + + return $attributes; +} + +/** + * Build an array with CSS classes and inline styles defining the font sizes + * which 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. + * @return array Font size CSS classes and inline styles. + */ +function gutenberg_experimental_build_css_typography( $attributes, $block_attributes, $supports ) { + // Font Size. + if ( in_array( 'font-size', $supports, true ) ) { + $has_named_font_size = array_key_exists( 'fontSize', $block_attributes ); + $has_custom_font_size = isset( $block_attributes['style']['typography']['fontSize'] ); + + // Apply required class or style. + if ( $has_named_font_size ) { + $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'] ); + } + } + + // Line Height. + if ( in_array( 'line-height', $supports, true ) ) { + $has_line_height = isset( $block_attributes['style']['typography']['lineHeight'] ); + // Add the style (no classes for line-height). + if ( $has_line_height ) { + $attributes['inline_styles'][] = sprintf( 'line-height: %s;', $block_attributes['style']['typography']['lineHeight'] ); + } + } + + return $attributes; +} diff --git a/lib/global-styles.php b/lib/global-styles.php index 9e23f31eaba109..0971f3d8538687 100644 --- a/lib/global-styles.php +++ b/lib/global-styles.php @@ -273,6 +273,7 @@ function gutenberg_experimental_global_styles_get_supported_styles( $supports ) 'color' => array( '__experimentalColor' ), 'background-color' => array( '__experimentalColor' ), 'background' => array( '__experimentalColor', 'gradients' ), + 'link-color' => array( '__experimentalColor', 'linkColor' ), 'line-height' => array( '__experimentalLineHeight' ), 'font-size' => array( '__experimentalFontSize' ), ); diff --git a/packages/block-library/src/site-title/block.json b/packages/block-library/src/site-title/block.json index 4e4050aacc3a41..bc172dd36d90e2 100644 --- a/packages/block-library/src/site-title/block.json +++ b/packages/block-library/src/site-title/block.json @@ -12,6 +12,11 @@ }, "supports": { "html": false, - "lightBlockWrapper": true + "lightBlockWrapper": true, + "__experimentalColor": { + "gradients": true + }, + "__experimentalFontSize": true, + "__experimentalLineHeight": true } } diff --git a/phpunit/class-block-context-test.php b/phpunit/class-block-context-test.php index 2d075bf4a5db49..e9e79949d45eae 100644 --- a/phpunit/class-block-context-test.php +++ b/phpunit/class-block-context-test.php @@ -196,5 +196,4 @@ function test_default_context_is_filterable() { $this->assertEquals( array( 'example' => 'ok' ), $provided_context[0] ); } - } diff --git a/phpunit/class-block-supported-styles-test.php b/phpunit/class-block-supported-styles-test.php new file mode 100644 index 00000000000000..0399944bb84d79 --- /dev/null +++ b/phpunit/class-block-supported-styles-test.php @@ -0,0 +1,591 @@ +registered_block_names ) ) { + $block_name = array_pop( $this->registered_block_names ); + unregister_block_type( $block_name ); + } + } + + /** + * Registers a block type. + * + * @param string|WP_Block_Type $name Block type name including namespace, or alternatively a + * complete WP_Block_Type instance. In case a WP_Block_Type + * is provided, the $args parameter will be ignored. + * @param array $args { + * Optional. Array of block type arguments. Any arguments may be defined, however the + * ones described below are supported by default. Default empty array. + * + * @type callable $render_callback Callback used to render blocks of this block type. + * } + */ + protected function register_block_type( $name, $args ) { + register_block_type( $name, $args ); + + $this->registered_block_names[] = $name; + } + + /** + * Retrieves attribute such as 'class' or 'style' from the rendered block string. + * + * @param string $attribute Name of attribute to get. + * @param string $block String of rendered block to check. + */ + private function get_attribute_from_block( $attribute, $block ) { + $start_index = strpos( $block, $attribute . '="' ) + strlen( $attribute ) + 2; + $split_arr = substr( $block, $start_index ); + $end_index = strpos( $split_arr, '"' ); + return substr( $split_arr, 0, $end_index ); + } + + /** + * Runs assertions that the rendered output has expected class/style attrs. + * + * @param array $block Block to render. + * @param string $expected_classes Expected output class attr string. + * @param string $expected_styles Expected output styles attr string. + */ + private function assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ) { + $styled_block = apply_filters( 'render_block', $this->block_content, $block ); + $class_list = $this->get_attribute_from_block( 'class', $styled_block ); + $style_list = $this->get_attribute_from_block( 'style', $styled_block ); + + $this->assertEquals( $expected_classes, $class_list ); + $this->assertEquals( $expected_styles, $style_list ); + } + + /** + * Example block content to test with. + * + * @var string + */ + private $block_content = '
So say we all.
'; + + /** + * Tests color support for named color support for named colors. + */ + function test_named_color_support() { + $block_type_settings = array( + 'attributes' => array(), + 'supports' => array( + '__experimentalColor' => true, + ), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array( + 'textColor' => 'red', + 'backgroundColor' => 'black', + // The following should not be applied (subcatagories of color support). + 'gradient' => 'some-gradient', + ), + '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. + */ + function test_custom_color_support() { + $block_type_settings = array( + 'attributes' => array(), + 'supports' => array( + '__experimentalColor' => true, + ), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array( + 'style' => array( + 'color' => array( + 'text' => '#000', + 'background' => '#fff', + // The following should not be applied (subcatagories of color support). + 'gradient' => 'some-gradient', + 'style' => array( 'color' => array( 'link' => '#fff' ) ), + ), + ), + ), + '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. + */ + function test_named_link_color_support() { + $block_type_settings = array( + 'attributes' => array(), + '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( + 'style' => array( 'color' => array( 'link' => 'var:preset|color|red' ) ), + ), + '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. + */ + function test_custom_link_color_support() { + $block_type_settings = array( + 'attributes' => array(), + '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( + 'style' => array( 'color' => array( 'link' => '#fff' ) ), + ), + '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. + */ + function test_named_gradient_support() { + $block_type_settings = array( + 'attributes' => array(), + '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( + 'gradient' => 'red', + ), + '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. + */ + function test_custom_gradient_support() { + $block_type_settings = array( + 'attributes' => array(), + '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( + 'style' => array( 'color' => array( 'gradient' => 'some-gradient-style' ) ), + ), + '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(), + 'supports' => array(), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array( + 'textColor' => 'red', + 'backgroundColor' => 'black', + 'style' => array( + 'color' => array( + 'text' => '#000', + 'background' => '#fff', + 'link' => '#ggg', + 'gradient' => 'some-gradient', + ), + ), + ), + 'innerBlock' => array(), + 'innerContent' => array(), + 'innerHTML' => array(), + ); + + $expected_classes = 'wp-block-example foo-bar-class'; + $expected_styles = 'test:style;'; + + $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); + } + + /** + * Tests support for named font sizes. + */ + function test_named_font_size() { + $block_type_settings = array( + 'attributes' => array(), + 'supports' => array( + '__experimentalFontSize' => true, + ), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array( + 'fontSize' => 'large', + ), + '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. + */ + function test_custom_font_size() { + $block_type_settings = array( + 'attributes' => array(), + 'supports' => array( + '__experimentalFontSize' => true, + ), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array( + 'style' => array( 'typography' => array( 'fontSize' => '10' ) ), + ), + '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(), + 'supports' => array(), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array( + 'fontSize' => 'large', + 'style' => array( 'typography' => array( 'fontSize' => '10' ) ), + ), + 'innerBlock' => array(), + 'innerContent' => array(), + 'innerHTML' => array(), + ); + + $expected_classes = 'wp-block-example foo-bar-class'; + $expected_styles = 'test:style;'; + + $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); + } + + /** + * Tests line height support. + */ + function test_line_height() { + $block_type_settings = array( + 'attributes' => array(), + 'supports' => array( + '__experimentalLineHeight' => true, + ), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array( + 'style' => array( 'typography' => array( 'lineHeight' => '10' ) ), + ), + '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(), + 'supports' => array(), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array( + 'style' => array( 'typography' => array( 'lineHeight' => '10' ) ), + ), + 'innerBlock' => array(), + 'innerContent' => array(), + 'innerHTML' => array(), + ); + + $expected_classes = 'wp-block-example foo-bar-class'; + $expected_styles = 'test:style;'; + + $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); + } + + /** + * Tests all support flags together to ensure they work together as expected. + */ + function test_all_supported() { + $block_type_settings = array( + 'attributes' => array(), + 'supports' => array( + '__experimentalColor' => array( + 'gradients' => true, + 'linkColor' => true, + ), + '__experimentalFontSize' => true, + '__experimentalLineHeight' => true, + ), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array( + 'style' => array( + 'color' => array( + 'text' => '#000', + 'background' => '#fff', + 'gradient' => 'some-gradient', + 'style' => array( 'color' => array( 'link' => '#fff' ) ), + ), + 'typography' => array( + 'lineHeight' => '20', + 'fontSize' => '10', + ), + ), + ), + 'innerBlock' => array(), + 'innerContent' => array(), + 'innerHTML' => array(), + ); + + $expected_classes = 'wp-block-example foo-bar-class has-text-color has-background'; + $expected_styles = 'test:style; color: #000; background-color: #fff; background: some-gradient; font-size: 10px; line-height: 20;'; + + $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); + } + + /** + * Tests that only styles for the supported flag are added. + * Verify one support enabled does not imply multiple supports enabled. + */ + function test_one_supported() { + $block_type_settings = array( + 'attributes' => array(), + 'supports' => array( + '__experimentalFontSize' => true, + ), + 'render_callback' => true, + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array( + 'style' => array( + 'color' => array( + 'text' => '#000', + 'background' => '#fff', + 'gradient' => 'some-gradient', + 'style' => array( 'color' => array( 'link' => '#fff' ) ), + ), + 'typography' => array( + 'lineHeight' => '20', + 'fontSize' => '10', + ), + ), + ), + '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 there is no change without 'render_callback' in block_type. + */ + function test_render_callback_required() { + $block_type_settings = array( + 'attributes' => array(), + 'supports' => array( + '__experimentalColor' => array( + 'gradients' => true, + 'linkColor' => true, + ), + '__experimentalFontSize' => true, + '__experimentalLineHeight' => true, + ), + ); + $this->register_block_type( 'core/example', $block_type_settings ); + + $block = array( + 'blockName' => 'core/example', + 'attrs' => array( + 'style' => array( + 'color' => array( + 'text' => '#000', + 'background' => '#fff', + 'gradient' => 'some-gradient', + 'style' => array( 'color' => array( 'link' => '#fff' ) ), + ), + 'typography' => array( + 'lineHeight' => '20', + 'fontSize' => '10', + ), + ), + ), + 'innerBlock' => array(), + 'innerContent' => array(), + 'innerHTML' => array(), + ); + + $expected_classes = 'wp-block-example foo-bar-class'; + $expected_styles = 'test:style;'; + + $this->assert_styles_and_classes_match( $block, $expected_classes, $expected_styles ); + } +}