[ Index ] |
PHP Cross Reference of WordPress Trunk (Updated Daily) |
[Summary view] [Print] [Text view]
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 * Determines whether an elements class name should be added to the block. 24 * 25 * @since 6.6.0 26 * @access private 27 * 28 * @param array $block Block object. 29 * @param array $options Per element type options e.g. whether to skip serialization. 30 * @return boolean Whether the block needs an elements class name. 31 */ 32 function wp_should_add_elements_class_name( $block, $options ) { 33 if ( ! isset( $block['attrs']['style']['elements'] ) ) { 34 return false; 35 } 36 37 $element_color_properties = array( 38 'button' => array( 39 'skip' => isset( $options['button']['skip'] ) ? $options['button']['skip'] : false, 40 'paths' => array( 41 array( 'button', 'color', 'text' ), 42 array( 'button', 'color', 'background' ), 43 array( 'button', 'color', 'gradient' ), 44 ), 45 ), 46 'link' => array( 47 'skip' => isset( $options['link']['skip'] ) ? $options['link']['skip'] : false, 48 'paths' => array( 49 array( 'link', 'color', 'text' ), 50 array( 'link', ':hover', 'color', 'text' ), 51 ), 52 ), 53 'heading' => array( 54 'skip' => isset( $options['heading']['skip'] ) ? $options['heading']['skip'] : false, 55 'paths' => array( 56 array( 'heading', 'color', 'text' ), 57 array( 'heading', 'color', 'background' ), 58 array( 'heading', 'color', 'gradient' ), 59 array( 'h1', 'color', 'text' ), 60 array( 'h1', 'color', 'background' ), 61 array( 'h1', 'color', 'gradient' ), 62 array( 'h2', 'color', 'text' ), 63 array( 'h2', 'color', 'background' ), 64 array( 'h2', 'color', 'gradient' ), 65 array( 'h3', 'color', 'text' ), 66 array( 'h3', 'color', 'background' ), 67 array( 'h3', 'color', 'gradient' ), 68 array( 'h4', 'color', 'text' ), 69 array( 'h4', 'color', 'background' ), 70 array( 'h4', 'color', 'gradient' ), 71 array( 'h5', 'color', 'text' ), 72 array( 'h5', 'color', 'background' ), 73 array( 'h5', 'color', 'gradient' ), 74 array( 'h6', 'color', 'text' ), 75 array( 'h6', 'color', 'background' ), 76 array( 'h6', 'color', 'gradient' ), 77 ), 78 ), 79 ); 80 81 $elements_style_attributes = $block['attrs']['style']['elements']; 82 83 foreach ( $element_color_properties as $element_config ) { 84 if ( $element_config['skip'] ) { 85 continue; 86 } 87 88 foreach ( $element_config['paths'] as $path ) { 89 if ( null !== _wp_array_get( $elements_style_attributes, $path, null ) ) { 90 return true; 91 } 92 } 93 } 94 95 return false; 96 } 97 98 /** 99 * Render the elements stylesheet and adds elements class name to block as required. 100 * 101 * In the case of nested blocks we want the parent element styles to be rendered before their descendants. 102 * This solves the issue of an element (e.g.: link color) being styled in both the parent and a descendant: 103 * we want the descendant style to take priority, and this is done by loading it after, in DOM order. 104 * 105 * @since 6.0.0 106 * @since 6.1.0 Implemented the style engine to generate CSS and classnames. 107 * @since 6.6.0 Element block support class and styles are generated via the `render_block_data` filter instead of `pre_render_block`. 108 * @access private 109 * 110 * @param array $parsed_block The parsed block. 111 * @return array The same parsed block with elements classname added if appropriate. 112 */ 113 function wp_render_elements_support_styles( $parsed_block ) { 114 /* 115 * The generation of element styles and classname were moved to the 116 * `render_block_data` filter in 6.6.0 to avoid filtered attributes 117 * breaking the application of the elements CSS class. 118 * 119 * @see https://github.com/WordPress/gutenberg/pull/59535 120 * 121 * The change in filter means, the argument types for this function 122 * have changed and require deprecating. 123 */ 124 if ( is_string( $parsed_block ) ) { 125 _deprecated_argument( 126 __FUNCTION__, 127 '6.6.0', 128 __( 'Use as a `pre_render_block` filter is deprecated. Use with `render_block_data` instead.' ) 129 ); 130 } 131 132 $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $parsed_block['blockName'] ); 133 $element_block_styles = isset( $parsed_block['attrs']['style']['elements'] ) ? $parsed_block['attrs']['style']['elements'] : null; 134 135 if ( ! $element_block_styles ) { 136 return $parsed_block; 137 } 138 139 $skip_link_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'link' ); 140 $skip_heading_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'heading' ); 141 $skip_button_color_serialization = wp_should_skip_block_supports_serialization( $block_type, 'color', 'button' ); 142 $skips_all_element_color_serialization = $skip_link_color_serialization && 143 $skip_heading_color_serialization && 144 $skip_button_color_serialization; 145 146 if ( $skips_all_element_color_serialization ) { 147 return $parsed_block; 148 } 149 150 $options = array( 151 'button' => array( 'skip' => $skip_button_color_serialization ), 152 'link' => array( 'skip' => $skip_link_color_serialization ), 153 'heading' => array( 'skip' => $skip_heading_color_serialization ), 154 ); 155 156 if ( ! wp_should_add_elements_class_name( $parsed_block, $options ) ) { 157 return $parsed_block; 158 } 159 160 $class_name = wp_get_elements_class_name( $parsed_block ); 161 $updated_class_name = isset( $parsed_block['attrs']['className'] ) ? $parsed_block['attrs']['className'] . " $class_name" : $class_name; 162 163 _wp_array_set( $parsed_block, array( 'attrs', 'className' ), $updated_class_name ); 164 165 // Generate element styles based on selector and store in style engine for enqueuing. 166 $element_types = array( 167 'button' => array( 168 'selector' => ".$class_name .wp-element-button, .$class_name .wp-block-button__link", 169 'skip' => $skip_button_color_serialization, 170 ), 171 'link' => array( 172 'selector' => ".$class_name a:where(:not(.wp-element-button))", 173 'hover_selector' => ".$class_name a:where(:not(.wp-element-button)):hover", 174 'skip' => $skip_link_color_serialization, 175 ), 176 'heading' => array( 177 'selector' => ".$class_name h1, .$class_name h2, .$class_name h3, .$class_name h4, .$class_name h5, .$class_name h6", 178 'skip' => $skip_heading_color_serialization, 179 'elements' => array( 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' ), 180 ), 181 ); 182 183 foreach ( $element_types as $element_type => $element_config ) { 184 if ( $element_config['skip'] ) { 185 continue; 186 } 187 188 $element_style_object = isset( $element_block_styles[ $element_type ] ) ? $element_block_styles[ $element_type ] : null; 189 190 // Process primary element type styles. 191 if ( $element_style_object ) { 192 wp_style_engine_get_styles( 193 $element_style_object, 194 array( 195 'selector' => $element_config['selector'], 196 'context' => 'block-supports', 197 ) 198 ); 199 200 if ( isset( $element_style_object[':hover'] ) ) { 201 wp_style_engine_get_styles( 202 $element_style_object[':hover'], 203 array( 204 'selector' => $element_config['hover_selector'], 205 'context' => 'block-supports', 206 ) 207 ); 208 } 209 } 210 211 // Process related elements e.g. h1-h6 for headings. 212 if ( isset( $element_config['elements'] ) ) { 213 foreach ( $element_config['elements'] as $element ) { 214 $element_style_object = isset( $element_block_styles[ $element ] ) 215 ? $element_block_styles[ $element ] 216 : null; 217 218 if ( $element_style_object ) { 219 wp_style_engine_get_styles( 220 $element_style_object, 221 array( 222 'selector' => ".$class_name $element", 223 'context' => 'block-supports', 224 ) 225 ); 226 } 227 } 228 } 229 } 230 231 return $parsed_block; 232 } 233 234 /** 235 * Ensure the elements block support class name generated, and added to 236 * block attributes, in the `render_block_data` filter gets applied to the 237 * block's markup. 238 * 239 * @see wp_render_elements_support_styles 240 * @since 6.6.0 241 * 242 * @param string $block_content Rendered block content. 243 * @param array $block Block object. 244 * @return string Filtered block content. 245 */ 246 function wp_render_elements_class_name( $block_content, $block ) { 247 $class_string = $block['attrs']['className'] ?? ''; 248 preg_match( '/\bwp-elements-\S+\b/', $class_string, $matches ); 249 250 if ( empty( $matches ) ) { 251 return $block_content; 252 } 253 254 $tags = new WP_HTML_Tag_Processor( $block_content ); 255 256 if ( $tags->next_tag() ) { 257 $tags->add_class( $matches[0] ); 258 } 259 260 return $tags->get_updated_html(); 261 } 262 263 add_filter( 'render_block', 'wp_render_elements_class_name', 10, 2 ); 264 add_filter( 'render_block_data', 'wp_render_elements_support_styles', 10, 1 );
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated : Thu Nov 21 08:20:01 2024 | Cross-referenced by PHPXref |