Make WordPress Core


Ignore:
Timestamp:
05/19/2026 09:05:27 AM (3 months ago)
Author:
ellatrix
Message:

Block Supports: Improve performance and hardening of block-level custom CSS rendering.

Short-circuits the custom CSS support filter before the more expensive lookups so blocks without custom CSS return faster.

Replaces the regex class name parsing in wp_render_custom_css_class_name() with a cheap str_contains() guard followed by an HTML spec-compliant strtok() walk over the className tokens. This avoids the regex engine for the common case where no wp-custom-css- class is present, and correctly handles tab/form-feed/CR/LF separators as well as classes such as my-wp-custom-css-* that merely contain the prefix as a substring after a hyphen.

Also hardens both functions against malformed parsed blocks (non-string className, missing keys), tightens @phpstan-param array shapes, and corrects the block_has_support() @param to allow WP_Block_Type|null. Lastly, a @return Generator<int, non-empty-string> phpdoc tag is added to WP_HTML_Tag_Processor::class_list().

Developed in https://github.com/WordPress/wordpress-develop/pull/11686 and https://github.com/WordPress/gutenberg/pull/78217

Follow-up to r61678.

Reviewed by ellatrix.
Merges [62359] to the 7.0 branch.
Props mukesh27, westonruter, ramonopoly, jonsurrell.
See #64544, #64238.

Location:
branches/7.0
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • branches/7.0

  • branches/7.0/src/wp-includes/block-supports/custom-css.php

    r62300 r62376  
    1313 * @param array $parsed_block The parsed block.
    1414 * @return array The same parsed block with custom CSS class name added if appropriate.
     15 *
     16 * @phpstan-param array{
     17 *     blockName: string|null,
     18 *     attrs: array{
     19 *         className?: string,
     20 *         style?: array{
     21 *             css?: string,
     22 *             ...
     23 *         },
     24 *         ...
     25 *     },
     26 *     ...
     27 * } $parsed_block
    1528 */
    1629function wp_render_custom_css_support_styles( $parsed_block ) {
     30        $custom_css = $parsed_block['attrs']['style']['css'] ?? null;
     31        if ( ! is_string( $custom_css ) || '' === trim( $custom_css ) ) {
     32                return $parsed_block;
     33        }
     34
    1735        $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $parsed_block['blockName'] );
    18 
    1936        if ( ! block_has_support( $block_type, 'customCSS', true ) ) {
    20                 return $parsed_block;
    21         }
    22 
    23         $custom_css = trim( $parsed_block['attrs']['style']['css'] ?? '' );
    24 
    25         if ( empty( $custom_css ) ) {
    2637                return $parsed_block;
    2738        }
     
    3344
    3445        // Generate a unique class name for this block instance.
    35         $class_name         = wp_unique_id_from_values( $parsed_block, 'wp-custom-css-' );
    36         $updated_class_name = isset( $parsed_block['attrs']['className'] )
    37                 ? $parsed_block['attrs']['className'] . " $class_name"
     46        $class_name          = wp_unique_id_from_values( $parsed_block, 'wp-custom-css-' );
     47        $existing_class_name = $parsed_block['attrs']['className'] ?? null;
     48        $updated_class_name  = is_string( $existing_class_name )
     49                ? "$existing_class_name $class_name"
    3850                : $class_name;
    3951
     
    6981 * Applies the custom CSS class name to the block's rendered HTML.
    7082 *
    71  * The class name is generated in `wp_render_custom_css_support_styles`
     83 * The class name is generated in {@see wp_render_custom_css_support_styles()}
    7284 * and stored in block attributes. This filter adds it to the actual markup.
    7385 *
     
    7789 * @param array  $block         Block object.
    7890 * @return string               Filtered block content.
     91 *
     92 * @phpstan-param array{
     93 *     attrs: array{
     94 *         className?: string,
     95 *         ...
     96 *     },
     97 *     ...
     98 * } $block
    7999 */
    80100function wp_render_custom_css_class_name( $block_content, $block ) {
    81         $class_string = $block['attrs']['className'] ?? '';
    82         preg_match( '/\bwp-custom-css-\S+\b/', $class_string, $matches );
    83 
    84         if ( empty( $matches ) ) {
     101        $class_name_attr = $block['attrs']['className'] ?? null;
     102
     103        if ( ! is_string( $class_name_attr ) || ! str_contains( $class_name_attr, 'wp-custom-css-' ) ) {
     104                return $block_content;
     105        }
     106
     107        // Parse out the 'wp-custom-css-*' class name added by wp_render_custom_css_support_styles().
     108        $custom_class_name = null;
     109        $token_delimiter   = " \t\f\r\n";
     110        $class_token       = strtok( $class_name_attr, $token_delimiter );
     111        while ( false !== $class_token ) {
     112                if ( str_starts_with( $class_token, 'wp-custom-css-' ) ) {
     113                        $custom_class_name = $class_token;
     114                        break;
     115                }
     116                $class_token = strtok( $token_delimiter );
     117        }
     118        if ( null === $custom_class_name ) {
    85119                return $block_content;
    86120        }
     
    90124        if ( $tags->next_tag() ) {
    91125                $tags->add_class( 'has-custom-css' );
    92                 $tags->add_class( $matches[0] );
     126                $tags->add_class( $custom_class_name );
    93127        }
    94128
Note: See TracChangeset for help on using the changeset viewer.