[ Index ]

PHP Cross Reference of WordPress Trunk (Updated Daily)

Search

title

Body

[close]

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

   1  <?php
   2  /**
   3   * Elements styles block support.
   4   *
   5   * @package WordPress
   6   * @since 5.8.0
   7   */
   8  
   9  /**
  10   * Gets the elements class names.
  11   *
  12   * @since 6.0.0
  13   * @access private
  14   *
  15   * @param array $block Block object.
  16   * @return string The unique class name.
  17   */
  18  function wp_get_elements_class_name( $block ) {
  19      return 'wp-elements-' . md5( serialize( $block ) );
  20  }
  21  
  22  /**
  23   * Updates the block content with elements class names.
  24   *
  25   * @since 5.8.0
  26   * @since 6.4.0 Added support for button and heading element styling.
  27   * @access private
  28   *
  29   * @param string $block_content Rendered block content.
  30   * @param array  $block         Block object.
  31   * @return string Filtered block content.
  32   */
  33  function wp_render_elements_support( $block_content, $block ) {
  34      if ( ! $block_content || ! isset( $block['attrs']['style']['elements'] ) ) {
  35          return $block_content;
  36      }
  37  
  38      $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
  39      if ( ! $block_type ) {
  40          return $block_content;
  41      }
  42  
  43      $element_color_properties = array(
  44          'button'  => array(
  45              'skip'  => wp_should_skip_block_supports_serialization( $block_type, 'color', 'button' ),
  46              'paths' => array(
  47                  array( 'button', 'color', 'text' ),
  48                  array( 'button', 'color', 'background' ),
  49                  array( 'button', 'color', 'gradient' ),
  50              ),
  51          ),
  52          'link'    => array(
  53              'skip'  => wp_should_skip_block_supports_serialization( $block_type, 'color', 'link' ),
  54              'paths' => array(
  55                  array( 'link', 'color', 'text' ),
  56                  array( 'link', ':hover', 'color', 'text' ),
  57              ),
  58          ),
  59          'heading' => array(
  60              'skip'  => wp_should_skip_block_supports_serialization( $block_type, 'color', 'heading' ),
  61              'paths' => array(
  62                  array( 'heading', 'color', 'text' ),
  63                  array( 'heading', 'color', 'background' ),
  64                  array( 'heading', 'color', 'gradient' ),
  65                  array( 'h1', 'color', 'text' ),
  66                  array( 'h1', 'color', 'background' ),
  67                  array( 'h1', 'color', 'gradient' ),
  68                  array( 'h2', 'color', 'text' ),
  69                  array( 'h2', 'color', 'background' ),
  70                  array( 'h2', 'color', 'gradient' ),
  71                  array( 'h3', 'color', 'text' ),
  72                  array( 'h3', 'color', 'background' ),
  73                  array( 'h3', 'color', 'gradient' ),
  74                  array( 'h4', 'color', 'text' ),
  75                  array( 'h4', 'color', 'background' ),
  76                  array( 'h4', 'color', 'gradient' ),
  77                  array( 'h5', 'color', 'text' ),
  78                  array( 'h5', 'color', 'background' ),
  79                  array( 'h5', 'color', 'gradient' ),
  80                  array( 'h6', 'color', 'text' ),
  81                  array( 'h6', 'color', 'background' ),
  82                  array( 'h6', 'color', 'gradient' ),
  83              ),
  84          ),
  85      );
  86  
  87      $skip_all_element_color_serialization = $element_color_properties['button']['skip'] &&
  88          $element_color_properties['link']['skip'] &&
  89          $element_color_properties['heading']['skip'];
  90  
  91      if ( $skip_all_element_color_serialization ) {
  92          return $block_content;
  93      }
  94  
  95      $elements_style_attributes = $block['attrs']['style']['elements'];
  96  
  97      foreach ( $element_color_properties as $element_config ) {
  98          if ( $element_config['skip'] ) {
  99              continue;
 100          }
 101  
 102          foreach ( $element_config['paths'] as $path ) {
 103              if ( null !== _wp_array_get( $elements_style_attributes, $path, null ) ) {
 104                  /*
 105                   * It only takes a single custom attribute to require that the custom
 106                   * class name be added to the block, so once one is found there's no
 107                   * need to continue looking for others.
 108                   *
 109                   * As is done with the layout hook, this code assumes that the block
 110                   * contains a single wrapper and that it's the first element in the
 111                   * rendered output. That first element, if it exists, gets the class.
 112                   */
 113                  $tags = new WP_HTML_Tag_Processor( $block_content );
 114                  if ( $tags->next_tag() ) {
 115                      $tags->add_class( wp_get_elements_class_name( $block ) );
 116                  }
 117  
 118                  return $tags->get_updated_html();
 119              }
 120          }
 121      }
 122  
 123      // If no custom attributes were found then there's nothing to modify.
 124      return $block_content;
 125  }
 126  
 127  /**
 128   * Renders the elements stylesheet.
 129   *
 130   * In the case of nested blocks we want the parent element styles to be rendered before their descendants.
 131   * This solves the issue of an element (e.g.: link color) being styled in both the parent and a descendant:
 132   * we want the descendant style to take priority, and this is done by loading it after, in DOM order.
 133   *
 134   * @since 6.0.0
 135   * @since 6.1.0 Implemented the style engine to generate CSS and classnames.
 136   * @access private
 137   *
 138   * @param string|null $pre_render The pre-rendered content. Default null.
 139   * @param array       $block      The block being rendered.
 140   * @return null
 141   */
 142  function wp_render_elements_support_styles( $pre_render, $block ) {
 143      $block_type           = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
 144      $element_block_styles = isset( $block['attrs']['style']['elements'] ) ? $block['attrs']['style']['elements'] : null;
 145  
 146      if ( ! $element_block_styles ) {
 147          return null;
 148      }
 149  
 150      $skip_link_color_serialization         = wp_should_skip_block_supports_serialization( $block_type, 'color', 'link' );
 151      $skip_heading_color_serialization      = wp_should_skip_block_supports_serialization( $block_type, 'color', 'heading' );
 152      $skip_button_color_serialization       = wp_should_skip_block_supports_serialization( $block_type, 'color', 'button' );
 153      $skips_all_element_color_serialization = $skip_link_color_serialization &&
 154          $skip_heading_color_serialization &&
 155          $skip_button_color_serialization;
 156  
 157      if ( $skips_all_element_color_serialization ) {
 158          return null;
 159      }
 160  
 161      $class_name = wp_get_elements_class_name( $block );
 162  
 163      $element_types = array(
 164          'button'  => array(
 165              'selector' => ".$class_name .wp-element-button, .$class_name .wp-block-button__link",
 166              'skip'     => $skip_button_color_serialization,
 167          ),
 168          'link'    => array(
 169              'selector'       => ".$class_name a:where(:not(.wp-element-button))",
 170              'hover_selector' => ".$class_name a:where(:not(.wp-element-button)):hover",
 171              'skip'           => $skip_link_color_serialization,
 172          ),
 173          'heading' => array(
 174              'selector' => ".$class_name h1, .$class_name h2, .$class_name h3, .$class_name h4, .$class_name h5, .$class_name h6",
 175              'skip'     => $skip_heading_color_serialization,
 176              'elements' => array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ),
 177          ),
 178      );
 179  
 180      foreach ( $element_types as $element_type => $element_config ) {
 181          if ( $element_config['skip'] ) {
 182              continue;
 183          }
 184  
 185          $element_style_object = isset( $element_block_styles[ $element_type ] ) ? $element_block_styles[ $element_type ] : null;
 186  
 187          // Process primary element type styles.
 188          if ( $element_style_object ) {
 189              wp_style_engine_get_styles(
 190                  $element_style_object,
 191                  array(
 192                      'selector' => $element_config['selector'],
 193                      'context'  => 'block-supports',
 194                  )
 195              );
 196  
 197              if ( isset( $element_style_object[':hover'] ) ) {
 198                  wp_style_engine_get_styles(
 199                      $element_style_object[':hover'],
 200                      array(
 201                          'selector' => $element_config['hover_selector'],
 202                          'context'  => 'block-supports',
 203                      )
 204                  );
 205              }
 206          }
 207  
 208          // Process related elements e.g. h1-h6 for headings.
 209          if ( isset( $element_config['elements'] ) ) {
 210              foreach ( $element_config['elements'] as $element ) {
 211                  $element_style_object = isset( $element_block_styles[ $element ] )
 212                      ? $element_block_styles[ $element ]
 213                      : null;
 214  
 215                  if ( $element_style_object ) {
 216                      wp_style_engine_get_styles(
 217                          $element_style_object,
 218                          array(
 219                              'selector' => ".$class_name $element",
 220                              'context'  => 'block-supports',
 221                          )
 222                      );
 223                  }
 224              }
 225          }
 226      }
 227  
 228      return null;
 229  }
 230  
 231  add_filter( 'render_block', 'wp_render_elements_support', 10, 2 );
 232  add_filter( 'pre_render_block', 'wp_render_elements_support_styles', 10, 2 );


Generated : Fri Apr 26 08:20:02 2024 Cross-referenced by PHPXref