[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

/wp-includes/block-supports/ -> background.php (source)

   1  <?php
   2  /**
   3   * Background block support flag.
   4   *
   5   * @package WordPress
   6   * @since 6.4.0
   7   */
   8  
   9  /**
  10   * Registers the style block attribute for block types that support it.
  11   *
  12   * @since 6.4.0
  13   * @access private
  14   *
  15   * @param WP_Block_Type $block_type Block Type.
  16   */
  17  function wp_register_background_support( $block_type ) {
  18      // Setup attributes and styles within that if needed.
  19      if ( ! $block_type->attributes ) {
  20          $block_type->attributes = array();
  21      }
  22  
  23      // Check for existing style attribute definition e.g. from block.json.
  24      if ( array_key_exists( 'style', $block_type->attributes ) ) {
  25          return;
  26      }
  27  
  28      $has_background_support = block_has_support( $block_type, array( 'background' ), false );
  29  
  30      if ( $has_background_support ) {
  31          $block_type->attributes['style'] = array(
  32              'type' => 'object',
  33          );
  34      }
  35  }
  36  
  37  /**
  38   * Renders the background styles to the block wrapper.
  39   * This block support uses the `render_block` hook to ensure that
  40   * it is also applied to non-server-rendered blocks.
  41   *
  42   * @since 6.4.0
  43   * @since 6.5.0 Added support for `backgroundPosition` and `backgroundRepeat` output.
  44   * @since 6.6.0 Removed requirement for `backgroundImage.source`. A file/url is the default.
  45   * @since 6.7.0 Added support for `backgroundAttachment` output.
  46   * @since 7.1.0 Added support for `background.gradient` output.
  47   * @since 7.2.0 Added support for `background.backgroundClip` output.
  48   *
  49   * @access private
  50   *
  51   * @param string $block_content Rendered block content.
  52   * @param array  $block         Block object.
  53   * @return string Filtered block content.
  54   *
  55   * @phpstan-param array{
  56   *     blockName: string,
  57   *     attrs: array{
  58   *         style?: array{
  59   *             background?: array<string, mixed>,
  60   *             ...<string, mixed>
  61   *         },
  62   *         ...<string, mixed>
  63   *     },
  64   *     ...
  65   * } $block
  66   */
  67  function wp_render_background_support( $block_content, $block ) {
  68      $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
  69      if ( ! $block_type ) {
  70          return $block_content;
  71      }
  72  
  73      $block_attributes                = ( isset( $block['attrs'] ) && is_array( $block['attrs'] ) ) ? $block['attrs'] : array();
  74      $has_background_image_support    = block_has_support( $block_type, array( 'background', 'backgroundImage' ), false );
  75      $has_background_gradient_support = block_has_support( $block_type, array( 'background', 'gradient' ), false );
  76      $has_background_clip_support     = block_has_support( $block_type, array( 'background', 'backgroundClip' ), false );
  77  
  78      if (
  79          ( ! $has_background_image_support && ! $has_background_gradient_support && ! $has_background_clip_support ) ||
  80          ! isset( $block_attributes['style']['background'] )
  81      ) {
  82          return $block_content;
  83      }
  84  
  85      // Check serialization skip for each feature individually.
  86      $skip_background_image    = ! $has_background_image_support || wp_should_skip_block_supports_serialization( $block_type, 'background', 'backgroundImage' );
  87      $skip_background_gradient = ! $has_background_gradient_support || wp_should_skip_block_supports_serialization( $block_type, 'background', 'gradient' );
  88      $skip_background_clip     = ! $has_background_clip_support || wp_should_skip_block_supports_serialization( $block_type, 'background', 'backgroundClip' );
  89  
  90      if ( $skip_background_image && $skip_background_gradient && $skip_background_clip ) {
  91          return $block_content;
  92      }
  93  
  94      $background_styles = array();
  95  
  96      if ( ! $skip_background_image ) {
  97          $background_styles['backgroundImage']      = $block_attributes['style']['background']['backgroundImage'] ?? null;
  98          $background_styles['backgroundSize']       = $block_attributes['style']['background']['backgroundSize'] ?? null;
  99          $background_styles['backgroundPosition']   = $block_attributes['style']['background']['backgroundPosition'] ?? null;
 100          $background_styles['backgroundRepeat']     = $block_attributes['style']['background']['backgroundRepeat'] ?? null;
 101          $background_styles['backgroundAttachment'] = $block_attributes['style']['background']['backgroundAttachment'] ?? null;
 102  
 103          if ( ! empty( $background_styles['backgroundImage'] ) ) {
 104              $background_styles['backgroundSize'] ??= 'cover';
 105  
 106              // If the background size is set to `contain` and no position is set, set the position to `center`.
 107              if ( 'contain' === $background_styles['backgroundSize'] && ! $background_styles['backgroundPosition'] ) {
 108                  $background_styles['backgroundPosition'] = '50% 50%';
 109              }
 110          }
 111      }
 112  
 113      if ( ! $skip_background_gradient ) {
 114          $background_styles['gradient'] = $block_attributes['style']['background']['gradient'] ?? null;
 115      }
 116  
 117      if ( ! $skip_background_clip ) {
 118          $background_styles['backgroundClip'] = $block_attributes['style']['background']['backgroundClip'] ?? null;
 119      }
 120  
 121      $styles = wp_style_engine_get_styles( array( 'background' => $background_styles ) );
 122  
 123      if ( ! empty( $styles['css'] ) ) {
 124          // Inject background styles to the first element, presuming it's the wrapper, if it exists.
 125          $tags = new WP_HTML_Tag_Processor( $block_content );
 126  
 127          if ( $tags->next_tag() ) {
 128              $existing_style = $tags->get_attribute( 'style' );
 129              if ( is_string( $existing_style ) && '' !== $existing_style ) {
 130                  $separator     = str_ends_with( $existing_style, ';' ) ? '' : ';';
 131                  $updated_style = "{$existing_style}{$separator}{$styles['css']}";
 132              } else {
 133                  $updated_style = $styles['css'];
 134              }
 135  
 136              $tags->set_attribute( 'style', $updated_style );
 137  
 138              /*
 139               * A background clipped to the text paints the glyphs rather than the
 140               * block's box, so there is no block background to announce. Read the
 141               * clip from the serialized styles so an unsupported or skipped value
 142               * left in the block's attributes cannot suppress the class.
 143               */
 144              $background_clip = $background_styles['backgroundClip'] ?? null;
 145              $has_background  = ! empty( $background_styles['backgroundImage'] ) || ! empty( $background_styles['gradient'] );
 146  
 147              if ( $has_background && 'text' !== $background_clip ) {
 148                  $tags->add_class( 'has-background' );
 149              }
 150          }
 151  
 152          return $tags->get_updated_html();
 153      }
 154  
 155      return $block_content;
 156  }
 157  
 158  // Register the block support.
 159  WP_Block_Supports::get_instance()->register(
 160      'background',
 161      array(
 162          'register_attribute' => 'wp_register_background_support',
 163      )
 164  );
 165  
 166  add_filter( 'render_block', 'wp_render_background_support', 10, 2 );


Generated : Wed Nov 4 08:20:38 2026 Cross-referenced by PHPXref