Changeset 54274
- Timestamp:
- 09/21/2022 01:00:29 PM (2 years ago)
- Location:
- trunk
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/block-supports/layout.php
r53568 r54274 34 34 * 35 35 * @since 5.9.0 36 * @since 6.1.0 Added `$block_spacing` param, use style engine to enqueue styles. 36 37 * @access private 37 38 * 38 * @param string $selector CSS selector. 39 * @param array $layout Layout object. The one that is passed has already checked 40 * the existence of default block layout. 41 * @param boolean $has_block_gap_support Whether the theme has support for the block gap. 42 * @param string $gap_value The block gap value to apply. 43 * @param boolean $should_skip_gap_serialization Whether to skip applying the user-defined value set in the editor. 44 * @param string $fallback_gap_value The custom fallback value for block gap. 39 * @param string $selector CSS selector. 40 * @param array $layout Layout object. The one that is passed has already checked 41 * the existence of default block layout. 42 * @param boolean $has_block_gap_support Whether the theme has support for the block gap. 43 * @param string|string[]|null $gap_value Optional. The block gap value to apply. Default null. 44 * @param boolean $should_skip_gap_serialization Whether to skip applying the user-defined value set in the editor. 45 * @param string $fallback_gap_value The block gap value to apply. 46 * @param array|null $block_spacing Optional. Custom spacing set on the block. Default null. 45 47 * @return string CSS style. 46 48 */ 47 function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false, $gap_value = null, $should_skip_gap_serialization = false, $fallback_gap_value = '0.5em' ) {48 $layout_type = isset( $layout['type'] ) ? $layout['type'] : 'default';49 50 $style = ''; 49 function wp_get_layout_style( $selector, $layout, $has_block_gap_support = false, $gap_value = null, $should_skip_gap_serialization = false, $fallback_gap_value = '0.5em', $block_spacing = null ) { 50 $layout_type = isset( $layout['type'] ) ? $layout['type'] : 'default'; 51 $layout_styles = array(); 52 51 53 if ( 'default' === $layout_type ) { 52 $content_size = isset( $layout['contentSize'] ) ? $layout['contentSize'] : ''; 53 $wide_size = isset( $layout['wideSize'] ) ? $layout['wideSize'] : ''; 54 if ( $has_block_gap_support ) { 55 if ( is_array( $gap_value ) ) { 56 $gap_value = isset( $gap_value['top'] ) ? $gap_value['top'] : null; 57 } 58 if ( null !== $gap_value && ! $should_skip_gap_serialization ) { 59 array_push( 60 $layout_styles, 61 array( 62 'selector' => "$selector > *", 63 'declarations' => array( 64 'margin-block-start' => '0', 65 'margin-block-end' => '0', 66 ), 67 ), 68 array( 69 'selector' => "$selector$selector > * + *", 70 'declarations' => array( 71 'margin-block-start' => $gap_value, 72 'margin-block-end' => '0', 73 ), 74 ) 75 ); 76 } 77 } 78 } elseif ( 'constrained' === $layout_type ) { 79 $content_size = isset( $layout['contentSize'] ) ? $layout['contentSize'] : ''; 80 $wide_size = isset( $layout['wideSize'] ) ? $layout['wideSize'] : ''; 81 $justify_content = isset( $layout['justifyContent'] ) ? $layout['justifyContent'] : 'center'; 54 82 55 83 $all_max_width_value = $content_size ? $content_size : $wide_size; … … 60 88 $wide_max_width_value = safecss_filter_attr( explode( ';', $wide_max_width_value )[0] ); 61 89 90 $margin_left = 'left' === $justify_content ? '0 !important' : 'auto !important'; 91 $margin_right = 'right' === $justify_content ? '0 !important' : 'auto !important'; 92 62 93 if ( $content_size || $wide_size ) { 63 $style = "$selector > :where(:not(.alignleft):not(.alignright)) {"; 64 $style .= 'max-width: ' . esc_html( $all_max_width_value ) . ';'; 65 $style .= 'margin-left: auto !important;'; 66 $style .= 'margin-right: auto !important;'; 67 $style .= '}'; 68 69 $style .= "$selector > .alignwide { max-width: " . esc_html( $wide_max_width_value ) . ';}'; 70 $style .= "$selector .alignfull { max-width: none; }"; 71 } 72 73 $style .= "$selector > .alignleft { float: left; margin-inline-start: 0; margin-inline-end: 2em; }"; 74 $style .= "$selector > .alignright { float: right; margin-inline-start: 2em; margin-inline-end: 0; }"; 75 $style .= "$selector > .aligncenter { margin-left: auto !important; margin-right: auto !important; }"; 94 array_push( 95 $layout_styles, 96 array( 97 'selector' => "$selector > :where(:not(.alignleft):not(.alignright):not(.alignfull))", 98 'declarations' => array( 99 'max-width' => $all_max_width_value, 100 'margin-left' => $margin_left, 101 'margin-right' => $margin_right, 102 ), 103 ), 104 array( 105 'selector' => "$selector > .alignwide", 106 'declarations' => array( 'max-width' => $wide_max_width_value ), 107 ), 108 array( 109 'selector' => "$selector .alignfull", 110 'declarations' => array( 'max-width' => 'none' ), 111 ) 112 ); 113 114 if ( isset( $block_spacing ) ) { 115 $block_spacing_values = wp_style_engine_get_styles( 116 array( 117 'spacing' => $block_spacing, 118 ) 119 ); 120 121 /* 122 * Handle negative margins for alignfull children of blocks with custom padding set. 123 * They're added separately because padding might only be set on one side. 124 */ 125 if ( isset( $block_spacing_values['declarations']['padding-right'] ) ) { 126 $padding_right = $block_spacing_values['declarations']['padding-right']; 127 $layout_styles[] = array( 128 'selector' => "$selector > .alignfull", 129 'declarations' => array( 'margin-right' => "calc($padding_right * -1)" ), 130 ); 131 } 132 if ( isset( $block_spacing_values['declarations']['padding-left'] ) ) { 133 $padding_left = $block_spacing_values['declarations']['padding-left']; 134 $layout_styles[] = array( 135 'selector' => "$selector > .alignfull", 136 'declarations' => array( 'margin-left' => "calc($padding_left * -1)" ), 137 ); 138 } 139 } 140 } 141 142 if ( 'left' === $justify_content ) { 143 $layout_styles[] = array( 144 'selector' => "$selector > :where(:not(.alignleft):not(.alignright):not(.alignfull))", 145 'declarations' => array( 'margin-left' => '0 !important' ), 146 ); 147 } 148 149 if ( 'right' === $justify_content ) { 150 $layout_styles[] = array( 151 'selector' => "$selector > :where(:not(.alignleft):not(.alignright):not(.alignfull))", 152 'declarations' => array( 'margin-right' => '0 !important' ), 153 ); 154 } 155 76 156 if ( $has_block_gap_support ) { 77 157 if ( is_array( $gap_value ) ) { 78 158 $gap_value = isset( $gap_value['top'] ) ? $gap_value['top'] : null; 79 159 } 80 $gap_style = $gap_value && ! $should_skip_gap_serialization ? $gap_value : 'var( --wp--style--block-gap )'; 81 $style .= "$selector > * { margin-block-start: 0; margin-block-end: 0; }"; 82 $style .= "$selector > * + * { margin-block-start: $gap_style; margin-block-end: 0; }"; 160 if ( null !== $gap_value && ! $should_skip_gap_serialization ) { 161 // Get spacing CSS variable from preset value if provided. 162 if ( is_string( $gap_value ) && str_contains( $gap_value, 'var:preset|spacing|' ) ) { 163 $index_to_splice = strrpos( $gap_value, '|' ) + 1; 164 $slug = _wp_to_kebab_case( substr( $gap_value, $index_to_splice ) ); 165 $gap_value = "var(--wp--preset--spacing--$slug)"; 166 } 167 168 array_push( 169 $layout_styles, 170 array( 171 'selector' => "$selector > *", 172 'declarations' => array( 173 'margin-block-start' => '0', 174 'margin-block-end' => '0', 175 ), 176 ), 177 array( 178 'selector' => "$selector$selector > * + *", 179 'declarations' => array( 180 'margin-block-start' => $gap_value, 181 'margin-block-end' => '0', 182 ), 183 ) 184 ); 185 } 83 186 } 84 187 } elseif ( 'flex' === $layout_type ) { … … 91 194 ); 92 195 196 $vertical_alignment_options = array( 197 'top' => 'flex-start', 198 'center' => 'center', 199 'bottom' => 'flex-end', 200 ); 201 93 202 if ( 'horizontal' === $layout_orientation ) { 94 203 $justify_content_options += array( 'space-between' => 'space-between' ); 95 204 } 96 205 97 $flex_wrap_options = array( 'wrap', 'nowrap' ); 98 $flex_wrap = ! empty( $layout['flexWrap'] ) && in_array( $layout['flexWrap'], $flex_wrap_options, true ) ? 99 $layout['flexWrap'] : 100 'wrap'; 101 102 $style = "$selector {"; 103 $style .= 'display: flex;'; 104 if ( $has_block_gap_support ) { 105 if ( is_array( $gap_value ) ) { 106 $gap_row = isset( $gap_value['top'] ) ? $gap_value['top'] : $fallback_gap_value; 107 $gap_column = isset( $gap_value['left'] ) ? $gap_value['left'] : $fallback_gap_value; 108 $gap_value = $gap_row === $gap_column ? $gap_row : $gap_row . ' ' . $gap_column; 109 } 110 $gap_style = $gap_value && ! $should_skip_gap_serialization ? $gap_value : "var( --wp--style--block-gap, $fallback_gap_value )"; 111 $style .= "gap: $gap_style;"; 112 } else { 113 $style .= "gap: $fallback_gap_value;"; 114 } 115 116 $style .= "flex-wrap: $flex_wrap;"; 206 if ( ! empty( $layout['flexWrap'] ) && 'nowrap' === $layout['flexWrap'] ) { 207 $layout_styles[] = array( 208 'selector' => $selector, 209 'declarations' => array( 'flex-wrap' => 'nowrap' ), 210 ); 211 } 212 213 if ( $has_block_gap_support && isset( $gap_value ) ) { 214 $combined_gap_value = ''; 215 $gap_sides = is_array( $gap_value ) ? array( 'top', 'left' ) : array( 'top' ); 216 217 foreach ( $gap_sides as $gap_side ) { 218 $process_value = is_string( $gap_value ) ? $gap_value : _wp_array_get( $gap_value, array( $gap_side ), $fallback_gap_value ); 219 // Get spacing CSS variable from preset value if provided. 220 if ( is_string( $process_value ) && str_contains( $process_value, 'var:preset|spacing|' ) ) { 221 $index_to_splice = strrpos( $process_value, '|' ) + 1; 222 $slug = _wp_to_kebab_case( substr( $process_value, $index_to_splice ) ); 223 $process_value = "var(--wp--preset--spacing--$slug)"; 224 } 225 $combined_gap_value .= "$process_value "; 226 } 227 $gap_value = trim( $combined_gap_value ); 228 229 if ( null !== $gap_value && ! $should_skip_gap_serialization ) { 230 $layout_styles[] = array( 231 'selector' => $selector, 232 'declarations' => array( 'gap' => $gap_value ), 233 ); 234 } 235 } 236 117 237 if ( 'horizontal' === $layout_orientation ) { 118 $style .= 'align-items: center;'; 119 /** 238 /* 120 239 * Add this style only if is not empty for backwards compatibility, 121 240 * since we intend to convert blocks that had flex layout implemented … … 123 242 */ 124 243 if ( ! empty( $layout['justifyContent'] ) && array_key_exists( $layout['justifyContent'], $justify_content_options ) ) { 125 $style .= "justify-content: {$justify_content_options[ $layout['justifyContent'] ]};"; 244 $layout_styles[] = array( 245 'selector' => $selector, 246 'declarations' => array( 'justify-content' => $justify_content_options[ $layout['justifyContent'] ] ), 247 ); 248 } 249 250 if ( ! empty( $layout['verticalAlignment'] ) && array_key_exists( $layout['verticalAlignment'], $vertical_alignment_options ) ) { 251 $layout_styles[] = array( 252 'selector' => $selector, 253 'declarations' => array( 'align-items' => $vertical_alignment_options[ $layout['verticalAlignment'] ] ), 254 ); 126 255 } 127 256 } else { 128 $style .= 'flex-direction: column;'; 257 $layout_styles[] = array( 258 'selector' => $selector, 259 'declarations' => array( 'flex-direction' => 'column' ), 260 ); 129 261 if ( ! empty( $layout['justifyContent'] ) && array_key_exists( $layout['justifyContent'], $justify_content_options ) ) { 130 $style .= "align-items: {$justify_content_options[ $layout['justifyContent'] ]};"; 262 $layout_styles[] = array( 263 'selector' => $selector, 264 'declarations' => array( 'align-items' => $justify_content_options[ $layout['justifyContent'] ] ), 265 ); 131 266 } else { 132 $style .= 'align-items: flex-start;'; 133 } 134 } 135 $style .= '}'; 136 137 $style .= "$selector > * { margin: 0; }"; 138 } 139 140 return $style; 267 $layout_styles[] = array( 268 'selector' => $selector, 269 'declarations' => array( 'align-items' => 'flex-start' ), 270 ); 271 } 272 } 273 } 274 275 if ( ! empty( $layout_styles ) ) { 276 /* 277 * Add to the style engine store to enqueue and render layout styles. 278 * Return compiled layout styles to retain backwards compatibility. 279 * Since https://github.com/WordPress/gutenberg/pull/42452, 280 * wp_enqueue_block_support_styles is no longer called in this block supports file. 281 */ 282 return wp_style_engine_get_stylesheet_from_css_rules( 283 $layout_styles, 284 array( 285 'context' => 'block-supports', 286 'prettify' => false, 287 ) 288 ); 289 } 290 291 return ''; 141 292 } 142 293 … … 159 310 } 160 311 161 $block_gap = wp_get_global_settings( array( 'spacing', 'blockGap' ) ); 162 $default_layout = wp_get_global_settings( array( 'layout' ) ); 163 $has_block_gap_support = isset( $block_gap ) ? null !== $block_gap : false; 164 $default_block_layout = _wp_array_get( $block_type->supports, array( '__experimentalLayout', 'default' ), array() ); 165 $used_layout = isset( $block['attrs']['layout'] ) ? $block['attrs']['layout'] : $default_block_layout; 312 $block_gap = wp_get_global_settings( array( 'spacing', 'blockGap' ) ); 313 $global_layout_settings = wp_get_global_settings( array( 'layout' ) ); 314 $has_block_gap_support = isset( $block_gap ) ? null !== $block_gap : false; 315 $default_block_layout = _wp_array_get( $block_type->supports, array( '__experimentalLayout', 'default' ), array() ); 316 $used_layout = isset( $block['attrs']['layout'] ) ? $block['attrs']['layout'] : $default_block_layout; 317 166 318 if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] ) { 167 if ( ! $ default_layout) {319 if ( ! $global_layout_settings ) { 168 320 return $block_content; 169 321 } 170 $used_layout = $default_layout; 171 } 172 173 $class_names = array(); 174 $container_class = wp_unique_id( 'wp-container-' ); 175 $class_names[] = $container_class; 176 177 // The following section was added to reintroduce a small set of layout classnames that were 178 // removed in the 5.9 release (https://github.com/WordPress/gutenberg/issues/38719). It is 179 // not intended to provide an extended set of classes to match all block layout attributes 180 // here. 322 } 323 324 $class_names = array(); 325 $layout_definitions = _wp_array_get( $global_layout_settings, array( 'definitions' ), array() ); 326 $block_classname = wp_get_block_default_classname( $block['blockName'] ); 327 $container_class = wp_unique_id( 'wp-container-' ); 328 $layout_classname = ''; 329 330 // Set the correct layout type for blocks using legacy content width. 331 if ( isset( $used_layout['inherit'] ) && $used_layout['inherit'] || isset( $used_layout['contentSize'] ) && $used_layout['contentSize'] ) { 332 $used_layout['type'] = 'constrained'; 333 } 334 335 if ( 336 wp_get_global_settings( array( 'useRootPaddingAwareAlignments' ) ) && 337 isset( $used_layout['type'] ) && 338 'constrained' === $used_layout['type'] 339 ) { 340 $class_names[] = 'has-global-padding'; 341 } 342 343 /* 344 * The following section was added to reintroduce a small set of layout classnames that were 345 * removed in the 5.9 release (https://github.com/WordPress/gutenberg/issues/38719). It is 346 * not intended to provide an extended set of classes to match all block layout attributes 347 * here. 348 */ 181 349 if ( ! empty( $block['attrs']['layout']['orientation'] ) ) { 182 350 $class_names[] = 'is-' . sanitize_title( $block['attrs']['layout']['orientation'] ); … … 191 359 } 192 360 193 $gap_value = _wp_array_get( $block, array( 'attrs', 'style', 'spacing', 'blockGap' ) ); 194 // Skip if gap value contains unsupported characters. 195 // Regex for CSS value borrowed from `safecss_filter_attr`, and used here 196 // because we only want to match against the value, not the CSS attribute. 197 if ( is_array( $gap_value ) ) { 198 foreach ( $gap_value as $key => $value ) { 199 $gap_value[ $key ] = $value && preg_match( '%[\\\(&=}]|/\*%', $value ) ? null : $value; 200 } 361 // Get classname for layout type. 362 if ( isset( $used_layout['type'] ) ) { 363 $layout_classname = _wp_array_get( $layout_definitions, array( $used_layout['type'], 'className' ), '' ); 201 364 } else { 202 $gap_value = $gap_value && preg_match( '%[\\\(&=}]|/\*%', $gap_value ) ? null : $gap_value; 203 } 204 205 $fallback_gap_value = _wp_array_get( $block_type->supports, array( 'spacing', 'blockGap', '__experimentalDefault' ), '0.5em' ); 206 207 // If a block's block.json skips serialization for spacing or spacing.blockGap, 208 // don't apply the user-defined value to the styles. 209 $should_skip_gap_serialization = wp_should_skip_block_supports_serialization( $block_type, 'spacing', 'blockGap' ); 210 $style = wp_get_layout_style( ".$container_class", $used_layout, $has_block_gap_support, $gap_value, $should_skip_gap_serialization, $fallback_gap_value ); 211 // This assumes the hook only applies to blocks with a single wrapper. 212 // I think this is a reasonable limitation for that particular hook. 365 $layout_classname = _wp_array_get( $layout_definitions, array( 'default', 'className' ), '' ); 366 } 367 368 if ( $layout_classname && is_string( $layout_classname ) ) { 369 $class_names[] = sanitize_title( $layout_classname ); 370 } 371 372 /* 373 * Only generate Layout styles if the theme has not opted-out. 374 * Attribute-based Layout classnames are output in all cases. 375 */ 376 if ( ! current_theme_supports( 'disable-layout-styles' ) ) { 377 378 $gap_value = _wp_array_get( $block, array( 'attrs', 'style', 'spacing', 'blockGap' ) ); 379 /* 380 * Skip if gap value contains unsupported characters. 381 * Regex for CSS value borrowed from `safecss_filter_attr`, and used here 382 * to only match against the value, not the CSS attribute. 383 */ 384 if ( is_array( $gap_value ) ) { 385 foreach ( $gap_value as $key => $value ) { 386 $gap_value[ $key ] = $value && preg_match( '%[\\\(&=}]|/\*%', $value ) ? null : $value; 387 } 388 } else { 389 $gap_value = $gap_value && preg_match( '%[\\\(&=}]|/\*%', $gap_value ) ? null : $gap_value; 390 } 391 392 $fallback_gap_value = _wp_array_get( $block_type->supports, array( 'spacing', 'blockGap', '__experimentalDefault' ), '0.5em' ); 393 $block_spacing = _wp_array_get( $block, array( 'attrs', 'style', 'spacing' ), null ); 394 395 /* 396 * If a block's block.json skips serialization for spacing or spacing.blockGap, 397 * don't apply the user-defined value to the styles. 398 */ 399 $should_skip_gap_serialization = wp_should_skip_block_supports_serialization( $block_type, 'spacing', 'blockGap' ); 400 401 $style = wp_get_layout_style( 402 ".$block_classname.$container_class", 403 $used_layout, 404 $has_block_gap_support, 405 $gap_value, 406 $should_skip_gap_serialization, 407 $fallback_gap_value, 408 $block_spacing 409 ); 410 411 // Only add container class and enqueue block support styles if unique styles were generated. 412 if ( ! empty( $style ) ) { 413 $class_names[] = $container_class; 414 } 415 } 416 417 /* 418 * This assumes the hook only applies to blocks with a single wrapper. 419 * A limitation of this hook is that nested inner blocks wrappers are not yet supported. 420 */ 213 421 $content = preg_replace( 214 422 '/' . preg_quote( 'class="', '/' ) . '/', … … 217 425 1 218 426 ); 219 220 wp_enqueue_block_support_styles( $style );221 427 222 428 return $content; -
trunk/tests/phpunit/data/blocks/fixtures/core__column.server.html
r53157 r54274 1 1 2 <div class=" wp-container-1wp-block-column">2 <div class="is-layout-flow wp-block-column"> 3 3 4 4 <p>Column One, Paragraph One</p> -
trunk/tests/phpunit/data/blocks/fixtures/core__columns.server.html
r53157 r54274 1 1 2 <div class=" wp-container-1 wp-block-columns has-3-columns">2 <div class="is-layout-flex wp-container-1 wp-block-columns has-3-columns"> 3 3 4 <div class=" wp-container-1wp-block-column">4 <div class="is-layout-flow wp-block-column"> 5 5 6 6 <p>Column One, Paragraph One</p> … … 12 12 13 13 14 <div class=" wp-container-1wp-block-column">14 <div class="is-layout-flow wp-block-column"> 15 15 16 16 <p>Column Two, Paragraph One</p> -
trunk/tests/phpunit/data/blocks/fixtures/core__columns__deprecated.server.html
r53157 r54274 1 1 2 <div class=" wp-container-1 wp-block-columns has-3-columns">2 <div class="is-layout-flex wp-container-1 wp-block-columns has-3-columns"> 3 3 4 4 <p class="layout-column-1">Column One, Paragraph One</p> -
trunk/tests/phpunit/data/blocks/fixtures/core__gallery.server.html
r53261 r54274 1 1 2 <figure class=" wp-container-1wp-block-gallery-1 wp-block-gallery has-nested-images columns-default is-cropped columns-2">2 <figure class="is-layout-flex wp-block-gallery-1 wp-block-gallery has-nested-images columns-default is-cropped columns-2"> 3 3 4 4 <figure class="wp-block-image size-large"> -
trunk/tests/phpunit/data/blocks/fixtures/core__gallery__columns.server.html
r53261 r54274 1 1 2 <figure class=" wp-container-1wp-block-gallery-1 wp-block-gallery has-nested-images is-cropped columns-1" >2 <figure class="is-layout-flex wp-block-gallery-1 wp-block-gallery has-nested-images is-cropped columns-1" > 3 3 4 4 <figure class="wp-block-image size-large">
Note: See TracChangeset
for help on using the changeset viewer.