diff --git a/backport-changelog/7.0/11686.md b/backport-changelog/7.0/11686.md new file mode 100644 index 00000000000000..665562870ebb98 --- /dev/null +++ b/backport-changelog/7.0/11686.md @@ -0,0 +1,3 @@ +https://github.com/WordPress/wordpress-develop/pull/11686 + +* https://github.com/WordPress/gutenberg/pull/78217 \ No newline at end of file diff --git a/lib/block-supports/custom-css.php b/lib/block-supports/custom-css.php index 7faa0d9f40cd7f..00649856e110c4 100644 --- a/lib/block-supports/custom-css.php +++ b/lib/block-supports/custom-css.php @@ -10,17 +10,28 @@ * * @param array $parsed_block The parsed block. * @return array The same parsed block with custom CSS class name added if appropriate. + * + * @phpstan-param array{ + * blockName: string|null, + * attrs: array{ + * className?: string, + * style?: array{ + * css?: string, + * ... + * }, + * ... + * }, + * ... + * } $parsed_block */ function gutenberg_render_custom_css_support_styles( $parsed_block ) { - $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $parsed_block['blockName'] ); - - if ( ! block_has_support( $block_type, 'customCSS', true ) ) { + $custom_css = $parsed_block['attrs']['style']['css'] ?? null; + if ( ! is_string( $custom_css ) || '' === trim( $custom_css ) ) { return $parsed_block; } - $custom_css = trim( $parsed_block['attrs']['style']['css'] ?? '' ); - - if ( empty( $custom_css ) ) { + $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $parsed_block['blockName'] ); + if ( ! block_has_support( $block_type, 'customCSS', true ) ) { return $parsed_block; } @@ -30,9 +41,10 @@ function gutenberg_render_custom_css_support_styles( $parsed_block ) { } // Generate a unique class name for this block instance. - $class_name = wp_unique_id_from_values( $parsed_block, 'wp-custom-css-' ); - $updated_class_name = isset( $parsed_block['attrs']['className'] ) - ? $parsed_block['attrs']['className'] . " $class_name" + $class_name = wp_unique_id_from_values( $parsed_block, 'wp-custom-css-' ); + $existing_class_name = $parsed_block['attrs']['className'] ?? null; + $updated_class_name = is_string( $existing_class_name ) + ? "$existing_class_name $class_name" : $class_name; _wp_array_set( $parsed_block, array( 'attrs', 'className' ), $updated_class_name ); @@ -64,18 +76,40 @@ function gutenberg_enqueue_block_custom_css() { /** * Applies the custom CSS class name to the block's rendered HTML. * - * The class name is generated in `gutenberg_render_custom_css_support_styles` + * The class name is generated in {@see gutenberg_render_custom_css_support_styles()} * and stored in block attributes. This filter adds it to the actual markup. * * @param string $block_content Rendered block content. * @param array $block Block object. * @return string Filtered block content. + * + * @phpstan-param array{ + * attrs: array{ + * className?: string, + * ... + * }, + * ... + * } $block */ function gutenberg_render_custom_css_class_name( $block_content, $block ) { - $class_string = $block['attrs']['className'] ?? ''; - preg_match( '/\bwp-custom-css-\S+\b/', $class_string, $matches ); + $class_name_attr = $block['attrs']['className'] ?? null; + + if ( ! is_string( $class_name_attr ) || ! str_contains( $class_name_attr, 'wp-custom-css-' ) ) { + return $block_content; + } - if ( empty( $matches ) ) { + // Parse out the 'wp-custom-css-*' class name added by gutenberg_render_custom_css_support_styles(). + $custom_class_name = null; + $token_delimiter = " \t\f\r\n"; + $class_token = strtok( $class_name_attr, $token_delimiter ); + while ( false !== $class_token ) { + if ( str_starts_with( $class_token, 'wp-custom-css-' ) ) { + $custom_class_name = $class_token; + break; + } + $class_token = strtok( $token_delimiter ); + } + if ( null === $custom_class_name ) { return $block_content; } @@ -83,7 +117,7 @@ function gutenberg_render_custom_css_class_name( $block_content, $block ) { if ( $tags->next_tag() ) { $tags->add_class( 'has-custom-css' ); - $tags->add_class( $matches[0] ); + $tags->add_class( $custom_class_name ); } return $tags->get_updated_html(); diff --git a/phpunit/block-supports/custom-css-test.php b/phpunit/block-supports/custom-css-test.php index 7cfce4b2e53374..e6e5544d66b021 100644 --- a/phpunit/block-supports/custom-css-test.php +++ b/phpunit/block-supports/custom-css-test.php @@ -339,6 +339,44 @@ public function test_render_custom_css_class_name_extracts_class_from_mixed_clas $this->assertStringContainsString( 'wp-custom-css-mixed123', $result, 'Custom CSS class should be extracted and added.' ); } + /** + * Tests that custom CSS class surrounded by ASCII whitespace (other than space) is extracted. + * + * @covers ::gutenberg_render_custom_css_class_name + */ + public function test_render_custom_css_class_name_extracts_class_between_whitespace() { + $block_content = '