From 79df64ba7cc53e7a338d9395c977574642277c0d Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Thu, 16 Apr 2026 10:10:22 +0530 Subject: [PATCH 01/13] Update BASE_TAG default version to 6.8.0 --- .github/workflows/reusable-performance-test-v2.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-performance-test-v2.yml b/.github/workflows/reusable-performance-test-v2.yml index f572060e26d63..58a794b39572b 100644 --- a/.github/workflows/reusable-performance-test-v2.yml +++ b/.github/workflows/reusable-performance-test-v2.yml @@ -19,7 +19,7 @@ on: description: 'The version being used for baseline measurements.' required: false type: 'string' - default: '6.7.0' + default: '6.8.0' TARGET_SHA: description: 'SHA hash of the target commit used for "before" measurements.' required: true From 98aa9398f993c8c4f0d1b6d11756795cc719f1ae Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Thu, 30 Apr 2026 15:56:53 +0530 Subject: [PATCH 02/13] Return early if no custom CSS class is provided Add early return for empty custom CSS class string --- src/wp-includes/block-supports/custom-css.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/wp-includes/block-supports/custom-css.php b/src/wp-includes/block-supports/custom-css.php index b931acf47bc02..114a0c598acda 100644 --- a/src/wp-includes/block-supports/custom-css.php +++ b/src/wp-includes/block-supports/custom-css.php @@ -79,6 +79,12 @@ function wp_enqueue_block_custom_css() { */ function wp_render_custom_css_class_name( $block_content, $block ) { $class_string = $block['attrs']['className'] ?? ''; + + /* If there is no class string, there is no custom CSS class to add, so return early. */ + if ( '' === $class_string ) { + return $block_content; + } + preg_match( '/\bwp-custom-css-\S+\b/', $class_string, $matches ); if ( empty( $matches ) ) { From 391f5b71bf7dd900375fcda41e301605f98ec13b Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Thu, 30 Apr 2026 16:00:39 +0530 Subject: [PATCH 03/13] Update default BASE_TAG version to 6.7.0 --- .github/workflows/reusable-performance-test-v2.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/reusable-performance-test-v2.yml b/.github/workflows/reusable-performance-test-v2.yml index 472c26d96df36..691e79c39508a 100644 --- a/.github/workflows/reusable-performance-test-v2.yml +++ b/.github/workflows/reusable-performance-test-v2.yml @@ -19,7 +19,7 @@ on: description: 'The version being used for baseline measurements.' required: false type: 'string' - default: '6.8.0' + default: '6.7.0' TARGET_SHA: description: 'SHA hash of the target commit used for "before" measurements.' required: true From a331593050ecf081b5e14a7710a3393253469b6c Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Fri, 1 May 2026 11:40:09 +0530 Subject: [PATCH 04/13] Refactor custom CSS support validation logic Add check for empty custom CSS before block support validation. --- src/wp-includes/block-supports/custom-css.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/block-supports/custom-css.php b/src/wp-includes/block-supports/custom-css.php index 114a0c598acda..95fbbc07ecf6f 100644 --- a/src/wp-includes/block-supports/custom-css.php +++ b/src/wp-includes/block-supports/custom-css.php @@ -14,15 +14,16 @@ * @return array The same parsed block with custom CSS class name added if appropriate. */ function wp_render_custom_css_support_styles( $parsed_block ) { - $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $parsed_block['blockName'] ); + // Check if the custom CSS attribute even exists. + $custom_css = $parsed_block['attrs']['style']['css'] ?? ''; - if ( ! block_has_support( $block_type, 'customCSS', true ) ) { + if ( empty( trim( $custom_css ) ) ) { return $parsed_block; } - $custom_css = trim( $parsed_block['attrs']['style']['css'] ?? '' ); + $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $parsed_block['blockName'] ); - if ( empty( $custom_css ) ) { + if ( ! block_has_support( $block_type, 'customCSS', true ) ) { return $parsed_block; } From 439b39ff8c8b4e9769f77074b1fc4596414ee229 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Wed, 6 May 2026 09:45:25 +0530 Subject: [PATCH 05/13] Apply suggestions from code review Co-authored-by: Weston Ruter --- src/wp-includes/block-supports/custom-css.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/wp-includes/block-supports/custom-css.php b/src/wp-includes/block-supports/custom-css.php index f968f482687a3..bf0e048453772 100644 --- a/src/wp-includes/block-supports/custom-css.php +++ b/src/wp-includes/block-supports/custom-css.php @@ -14,10 +14,9 @@ * @return array The same parsed block with custom CSS class name added if appropriate. */ function wp_render_custom_css_support_styles( $parsed_block ) { - // Check if the custom CSS attribute even exists. - $custom_css = $parsed_block['attrs']['style']['css'] ?? ''; + $custom_css = trim( $parsed_block['attrs']['style']['css'] ?? '' ); - if ( empty( trim( $custom_css ) ) ) { + if ( empty( $custom_css ) ) { return $parsed_block; } @@ -81,7 +80,6 @@ function wp_enqueue_block_custom_css() { function wp_render_custom_css_class_name( $block_content, $block ) { $class_string = $block['attrs']['className'] ?? ''; - /* If there is no class string, there is no custom CSS class to add, so return early. */ if ( '' === $class_string ) { return $block_content; } From a291f8389169ee409da786a8d1a038c750e96bd2 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 9 May 2026 23:22:25 -0700 Subject: [PATCH 06/13] Guard against malformed attrs from parsed block --- src/wp-includes/block-supports/custom-css.php | 21 +++++++++++++++---- src/wp-includes/blocks.php | 6 +++--- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/wp-includes/block-supports/custom-css.php b/src/wp-includes/block-supports/custom-css.php index bf0e048453772..54ad85411f339 100644 --- a/src/wp-includes/block-supports/custom-css.php +++ b/src/wp-includes/block-supports/custom-css.php @@ -12,16 +12,29 @@ * * @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, + * ... + * }, + * ... + * }, + * innerBlocks: array>, + * innerHTML: string, + * innerContent: array, + * } $parsed_block */ function wp_render_custom_css_support_styles( $parsed_block ) { - $custom_css = trim( $parsed_block['attrs']['style']['css'] ?? '' ); - - if ( empty( $custom_css ) ) { + $custom_css = $parsed_block['attrs']['style']['css'] ?? null; + if ( ! is_string( $custom_css ) || '' === trim( $custom_css ) ) { return $parsed_block; } $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $parsed_block['blockName'] ); - if ( ! block_has_support( $block_type, 'customCSS', true ) ) { return $parsed_block; } diff --git a/src/wp-includes/blocks.php b/src/wp-includes/blocks.php index cc1ac60667773..6a6418d966457 100644 --- a/src/wp-includes/blocks.php +++ b/src/wp-includes/blocks.php @@ -2604,9 +2604,9 @@ function unregister_block_style( $block_name, $block_style_name ) { * @since 5.8.0 * @since 6.4.0 The `$feature` parameter now supports a string. * - * @param WP_Block_Type $block_type Block type to check for support. - * @param string|array $feature Feature slug, or path to a specific feature to check support for. - * @param mixed $default_value Optional. Fallback value for feature support. Default false. + * @param WP_Block_Type|null $block_type Block type to check for support. + * @param string|array $feature Feature slug, or path to a specific feature to check support for. + * @param mixed $default_value Optional. Fallback value for feature support. Default false. * @return bool Whether the feature is supported. */ function block_has_support( $block_type, $feature, $default_value = false ) { From d637df3eb974525d73edba2d544abcbb393e26d6 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 9 May 2026 23:36:04 -0700 Subject: [PATCH 07/13] Guard against non-string className in attrs --- src/wp-includes/block-supports/custom-css.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/wp-includes/block-supports/custom-css.php b/src/wp-includes/block-supports/custom-css.php index 54ad85411f339..3f0c4534d2b68 100644 --- a/src/wp-includes/block-supports/custom-css.php +++ b/src/wp-includes/block-supports/custom-css.php @@ -45,9 +45,10 @@ function wp_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 ); From fba41c37a2c906d3f5092f9d7437c4fa07ad25ff Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 9 May 2026 23:48:02 -0700 Subject: [PATCH 08/13] Harden types for wp_render_custom_css_class_name() --- src/wp-includes/block-supports/custom-css.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/block-supports/custom-css.php b/src/wp-includes/block-supports/custom-css.php index 3f0c4534d2b68..90fac3f5efc46 100644 --- a/src/wp-includes/block-supports/custom-css.php +++ b/src/wp-includes/block-supports/custom-css.php @@ -90,11 +90,19 @@ function wp_enqueue_block_custom_css() { * @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 wp_render_custom_css_class_name( $block_content, $block ) { - $class_string = $block['attrs']['className'] ?? ''; + $class_string = $block['attrs']['className'] ?? null; - if ( '' === $class_string ) { + if ( ! is_string( $class_string ) || '' === $class_string ) { return $block_content; } From 62781aec7a72c4edd5c95e6a8a92c08f06ab752a Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Sat, 9 May 2026 23:50:29 -0700 Subject: [PATCH 09/13] Omit irrelevant types from phpdoc for wp_render_custom_css_support_styles() --- src/wp-includes/block-supports/custom-css.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/wp-includes/block-supports/custom-css.php b/src/wp-includes/block-supports/custom-css.php index 90fac3f5efc46..e80fe0c47cdab 100644 --- a/src/wp-includes/block-supports/custom-css.php +++ b/src/wp-includes/block-supports/custom-css.php @@ -23,9 +23,7 @@ * }, * ... * }, - * innerBlocks: array>, - * innerHTML: string, - * innerContent: array, + * ... * } $parsed_block */ function wp_render_custom_css_support_styles( $parsed_block ) { From 2fc9025bb11047c2bf2be177a44ac4cbab961cc3 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 12 May 2026 15:21:15 -0700 Subject: [PATCH 10/13] Use phpdoc tag for function reference --- src/wp-includes/block-supports/custom-css.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/block-supports/custom-css.php b/src/wp-includes/block-supports/custom-css.php index e80fe0c47cdab..0edea85dda6d1 100644 --- a/src/wp-includes/block-supports/custom-css.php +++ b/src/wp-includes/block-supports/custom-css.php @@ -80,7 +80,7 @@ function wp_enqueue_block_custom_css() { /** * Applies the custom CSS class name to the block's rendered HTML. * - * The class name is generated in `wp_render_custom_css_support_styles` + * The class name is generated in {@see wp_render_custom_css_support_styles()} * and stored in block attributes. This filter adds it to the actual markup. * * @since 7.0.0 From 5eb8c72a39074f4bf48e300a9d6d5cb4afb1dee2 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 12 May 2026 15:31:41 -0700 Subject: [PATCH 11/13] Block Supports: Short-circuit custom CSS class rendering with a cheap substring check. Add a str_contains() fast path before the preg_match() in wp_render_custom_css_class_name() so blocks with a className but no wp-custom-css-* class avoid the regex on the render_block filter, and fold the match check into the guard condition. Co-Authored-By: Claude Opus 4.7 (1M context) --- src/wp-includes/block-supports/custom-css.php | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/src/wp-includes/block-supports/custom-css.php b/src/wp-includes/block-supports/custom-css.php index 0edea85dda6d1..8ab5cc3da05b0 100644 --- a/src/wp-includes/block-supports/custom-css.php +++ b/src/wp-includes/block-supports/custom-css.php @@ -100,13 +100,11 @@ function wp_enqueue_block_custom_css() { function wp_render_custom_css_class_name( $block_content, $block ) { $class_string = $block['attrs']['className'] ?? null; - if ( ! is_string( $class_string ) || '' === $class_string ) { - return $block_content; - } - - preg_match( '/\bwp-custom-css-\S+\b/', $class_string, $matches ); - - if ( empty( $matches ) ) { + if ( + ! is_string( $class_string ) || + ! str_contains( $class_string, 'wp-custom-css-' ) || + ! preg_match( '/\bwp-custom-css-\S+\b/', $class_string, $matches ) + ) { return $block_content; } From bd93fe807cb9485cf0a8229ade4fb763f3bee551 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 12 May 2026 15:36:03 -0700 Subject: [PATCH 12/13] Ensure wp-custom-css-* class is not the suffix of another class after a hyphen --- src/wp-includes/block-supports/custom-css.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/block-supports/custom-css.php b/src/wp-includes/block-supports/custom-css.php index 8ab5cc3da05b0..5143e6d885aac 100644 --- a/src/wp-includes/block-supports/custom-css.php +++ b/src/wp-includes/block-supports/custom-css.php @@ -103,7 +103,7 @@ function wp_render_custom_css_class_name( $block_content, $block ) { if ( ! is_string( $class_string ) || ! str_contains( $class_string, 'wp-custom-css-' ) || - ! preg_match( '/\bwp-custom-css-\S+\b/', $class_string, $matches ) + ! preg_match( '/(?:^|\s)(wp-custom-css-\S+)\b/', $class_string, $matches ) ) { return $block_content; } @@ -112,7 +112,7 @@ function wp_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( $matches[1] ); } return $tags->get_updated_html(); From a89feac76e92eab76630888707a92b22ac9b78bf Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Tue, 12 May 2026 15:55:33 -0700 Subject: [PATCH 13/13] Leverage HTML Tag Processor to parse out wp-custom-css-* class name --- src/wp-includes/block-supports/custom-css.php | 25 +++++++++++++------ .../html-api/class-wp-html-tag-processor.php | 2 ++ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/wp-includes/block-supports/custom-css.php b/src/wp-includes/block-supports/custom-css.php index 5143e6d885aac..c46bc94412f5c 100644 --- a/src/wp-includes/block-supports/custom-css.php +++ b/src/wp-includes/block-supports/custom-css.php @@ -98,13 +98,24 @@ function wp_enqueue_block_custom_css() { * } $block */ function wp_render_custom_css_class_name( $block_content, $block ) { - $class_string = $block['attrs']['className'] ?? null; + $class_name_attr = $block['attrs']['className'] ?? null; - if ( - ! is_string( $class_string ) || - ! str_contains( $class_string, 'wp-custom-css-' ) || - ! preg_match( '/(?:^|\s)(wp-custom-css-\S+)\b/', $class_string, $matches ) - ) { + if ( ! is_string( $class_name_attr ) || ! str_contains( $class_name_attr, 'wp-custom-css-' ) ) { + return $block_content; + } + + // Parse out the 'wp-custom-css-*' class name added by wp_render_custom_css_support_styles(). + $tag = new WP_HTML_Tag_Processor( '
' ); + $tag->next_tag(); // Advance to the DIV. + $tag->set_attribute( 'class', $class_name_attr ); + $custom_class_name = null; + foreach ( $tag->class_list() as $class_name ) { + if ( str_starts_with( $class_name, 'wp-custom-css-' ) ) { + $custom_class_name = $class_name; + break; + } + } + if ( null === $custom_class_name ) { return $block_content; } @@ -112,7 +123,7 @@ function wp_render_custom_css_class_name( $block_content, $block ) { if ( $tags->next_tag() ) { $tags->add_class( 'has-custom-css' ); - $tags->add_class( $matches[1] ); + $tags->add_class( $custom_class_name ); } return $tags->get_updated_html(); diff --git a/src/wp-includes/html-api/class-wp-html-tag-processor.php b/src/wp-includes/html-api/class-wp-html-tag-processor.php index 8397ecf520fa2..4015b352c153c 100644 --- a/src/wp-includes/html-api/class-wp-html-tag-processor.php +++ b/src/wp-includes/html-api/class-wp-html-tag-processor.php @@ -1175,6 +1175,8 @@ public function paused_at_incomplete_token(): bool { * // Outputs: "free lang-en " * * @since 6.4.0 + * + * @return Generator */ public function class_list() { if ( self::STATE_MATCHED_TAG !== $this->parser_state ) {