PluginProbe
Gutenberg / trunk
Gutenberg vtrunk
24.1.0 24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 All 404 releases
← All changes | lib/block-supports/layout.php +62 -33 23.8.0 → trunk View file →
@@ -320,11 +320,11 @@
320 320
321 321 /**
322 322 * Returns child layout styles for a block affected by its parent's layout.
323 323 *
324 - * @param string $selector CSS selector.
325 - * @param array $child_layout Child layout values.
326 - * @param array $parent_layout Parent layout values.
324 + * @param string $selector CSS selector.
325 + * @param array $child_layout Child layout values.
326 + * @param array $parent_layout Parent layout values.
327 327 * @param array|null $viewport_overrides Optional. Child viewport layout overrides to emit.
328 328 * @return array Child layout style rules.
329 329 */
330 330 function gutenberg_get_child_layout_style_rules( $selector, $child_layout, $parent_layout = array(), $viewport_overrides = null ) {
@@ -379,10 +379,19 @@
379 379 $child_layout_declarations['flex-grow'] = '1';
380 380 }
381 381 }
382 382
383 - $column_start = $child_layout['columnStart'] ?? null;
384 - $column_span = $child_layout['columnSpan'] ?? null;
383 + /*
384 + * Grid line numbers and spans are whole numbers. The editor stores them as numbers, but
385 + * content saved by WordPress 6.3 to 6.6 stored them as numeric strings, and that
386 + * migration only runs when a block is parsed in JavaScript, so the front end still sees
387 + * strings. Accept any numeric value and cast it, and treat anything else as absent
388 + * because it can't render as valid CSS.
389 + */
390 + $column_start_attr = $child_layout['columnStart'] ?? null;
391 + $column_start = is_numeric( $column_start_attr ) ? (int) $column_start_attr : null;
392 + $column_span_attr = $child_layout['columnSpan'] ?? null;
393 + $column_span = is_numeric( $column_span_attr ) ? (int) $column_span_attr : null;
385 394 if ( null === $viewport_overrides || $has_viewport_property_override( 'columnStart' ) || $has_viewport_property_override( 'columnSpan' ) ) {
386 395 if ( $column_start && $column_span ) {
387 396 $child_layout_declarations['grid-column'] = "$column_start / span $column_span";
388 397 } elseif ( $column_start ) {
@@ -391,10 +400,12 @@
391 400 $child_layout_declarations['grid-column'] = "span $column_span";
392 401 }
393 402 }
394 403
395 - $row_start = $child_layout['rowStart'] ?? null;
396 - $row_span = $child_layout['rowSpan'] ?? null;
404 + $row_start_attr = $child_layout['rowStart'] ?? null;
405 + $row_start = is_numeric( $row_start_attr ) ? (int) $row_start_attr : null;
406 + $row_span_attr = $child_layout['rowSpan'] ?? null;
407 + $row_span = is_numeric( $row_span_attr ) ? (int) $row_span_attr : null;
397 408 if ( null === $viewport_overrides || $has_viewport_property_override( 'rowStart' ) || $has_viewport_property_override( 'rowSpan' ) ) {
398 409 if ( $row_start && $row_span ) {
399 410 $child_layout_declarations['grid-row'] = "$row_start / span $row_span";
400 411 } elseif ( $row_start ) {
@@ -778,8 +789,19 @@
778 789 $flex_vertical_alignment = $layout_for_styles['verticalAlignment'] ?? null;
779 790
780 791 if ( 'horizontal' === $layout_orientation ) {
781 792 /*
793 + * `row` is the flex default, so the base layout never declares it. A viewport
794 + * override that switches a vertical base layout to horizontal has to declare
795 + * it explicitly, otherwise the base `flex-direction: column` keeps applying.
796 + */
797 + if ( null !== $viewport_overrides && $has_viewport_property_override( 'orientation' ) ) {
798 + $layout_styles[] = array(
799 + 'selector' => $selector,
800 + 'declarations' => array( 'flex-direction' => 'row' ),
801 + );
802 + }
803 + /*
782 804 * Add this style only if is not empty for backwards compatibility,
783 805 * since we intend to convert blocks that had flex layout implemented
784 806 * by custom css.
785 807 */
@@ -822,9 +844,18 @@
822 844 }
823 845 }
824 846 } elseif ( 'grid' === $layout_type ) {
825 847 /*
826 - * If the gap value is an array, we use the "left" value because it represents the vertical gap, which
848 + * Column and row counts are whole numbers, for the same reason as the grid line
849 + * numbers in gutenberg_get_child_layout_style_rules().
850 + */
851 + $column_count_attr = $layout_for_styles['columnCount'] ?? null;
852 + $column_count = is_numeric( $column_count_attr ) ? (int) $column_count_attr : null;
853 + $row_count_attr = $layout_for_styles['rowCount'] ?? null;
854 + $row_count = is_numeric( $row_count_attr ) ? (int) $row_count_attr : null;
855 +
856 + /*
857 + * If the gap value is an array, we use the "left" value because it represents the horizontal gap, which
827 858 * is the relevant one for computation of responsive grid columns.
828 859 */
829 860 if ( is_array( $fallback_gap_value ) ) {
830 861 $responsive_gap_value = $fallback_gap_value['left'] ?? reset( $fallback_gap_value );
@@ -851,12 +882,14 @@
851 882 $index_to_splice = strrpos( $process_value, '|' ) + 1;
852 883 $slug = _wp_to_kebab_case( substr( $process_value, $index_to_splice ) );
853 884 $process_value = "var(--wp--preset--spacing--$slug)";
854 885 }
886 + if ( ! is_array( $gap_value ) || 'left' === $gap_side ) {
887 + $responsive_gap_value = $process_value;
888 + }
855 889 $combined_gap_value .= "$process_value ";
856 890 }
857 - $gap_value = trim( $combined_gap_value );
858 - $responsive_gap_value = $gap_value;
891 + $gap_value = trim( $combined_gap_value );
859 892 }
860 893
861 894 // Ensure 0 values have a unit so they work in calc().
862 895 if ( '0' === $responsive_gap_value || 0 === $responsive_gap_value ) {
@@ -866,14 +899,14 @@
866 899 /* Styles should be output either if there are no viewport overrides (this is the default case), or if the user has set a new viewport-specific
867 900 * value for any of the grid properties.
868 901 */
869 902 $should_output_grid_columns = null === $viewport_overrides || $has_viewport_property_override( 'minimumColumnWidth' ) || $has_viewport_property_override( 'columnCount' ) || $has_viewport_property_override( 'autoFit' );
870 - $uses_gap_in_grid_columns = ! empty( $layout_for_styles['columnCount'] ) && ! empty( $layout_for_styles['minimumColumnWidth'] );
903 + $uses_gap_in_grid_columns = ! empty( $column_count ) && ! empty( $layout_for_styles['minimumColumnWidth'] );
871 904 if ( $has_block_gap_override && $uses_gap_in_grid_columns ) {
872 905 $should_output_grid_columns = true;
873 906 }
874 907
875 - $should_output_grid_rows = ( null === $viewport_overrides || $has_viewport_property_override( 'rowCount' ) ) && ! empty( $layout_for_styles['columnCount'] ) && ! empty( $layout_for_styles['rowCount'] );
908 + $should_output_grid_rows = ( null === $viewport_overrides || $has_viewport_property_override( 'rowCount' ) ) && ! empty( $column_count ) && ! empty( $row_count );
876 909 $grid_declarations = array();
877 910
878 911 /* When enabled, columns stretch to fill the available space using
879 912 * `auto-fit`; otherwise empty tracks are preserved with `auto-fill`.
@@ -879,13 +912,13 @@
879 912 * `auto-fit`; otherwise empty tracks are preserved with `auto-fill`.
880 913 */
881 914 $auto_placement = ! empty( $layout_for_styles['autoFit'] ) ? 'auto-fit' : 'auto-fill';
882 915
883 - if ( $should_output_grid_columns && ! empty( $layout_for_styles['columnCount'] ) && ! empty( $layout_for_styles['minimumColumnWidth'] ) ) {
884 - $max_value = 'max(min(' . $layout_for_styles['minimumColumnWidth'] . ', 100%), (100% - (' . $responsive_gap_value . ' * (' . $layout_for_styles['columnCount'] . ' - 1))) /' . $layout_for_styles['columnCount'] . ')';
916 + if ( $should_output_grid_columns && ! empty( $column_count ) && ! empty( $layout_for_styles['minimumColumnWidth'] ) ) {
917 + $max_value = 'max(min(' . $layout_for_styles['minimumColumnWidth'] . ', 100%), (100% - (' . $responsive_gap_value . ' * (' . $column_count . ' - 1))) /' . $column_count . ')';
885 918 $grid_declarations['grid-template-columns'] = 'repeat(' . $auto_placement . ', minmax(' . $max_value . ', 1fr))';
886 - } elseif ( $should_output_grid_columns && ! empty( $layout_for_styles['columnCount'] ) ) {
887 - $grid_declarations['grid-template-columns'] = 'repeat(' . $layout_for_styles['columnCount'] . ', minmax(0, 1fr))';
919 + } elseif ( $should_output_grid_columns && ! empty( $column_count ) ) {
920 + $grid_declarations['grid-template-columns'] = 'repeat(' . $column_count . ', minmax(0, 1fr))';
888 921 } elseif ( $should_output_grid_columns ) {
889 922 $minimum_column_width = ! empty( $layout_for_styles['minimumColumnWidth'] ) ? $layout_for_styles['minimumColumnWidth'] : '12rem';
890 923 $grid_declarations['grid-template-columns'] = 'repeat(' . $auto_placement . ', minmax(min(' . $minimum_column_width . ', 100%), 1fr))';
891 924 }
@@ -891,9 +924,9 @@
891 924 }
892 925
893 926 if ( ! empty( $grid_declarations ) ) {
894 927 $base_has_container_type = empty( $base_layout['columnCount'] ) || ( ! empty( $base_layout['columnCount'] ) && ! empty( $base_layout['minimumColumnWidth'] ) );
895 - if ( empty( $layout_for_styles['columnCount'] ) || ! empty( $layout_for_styles['minimumColumnWidth'] ) ) {
928 + if ( empty( $column_count ) || ! empty( $layout_for_styles['minimumColumnWidth'] ) ) {
896 929 if ( null === $viewport_overrides || ! $base_has_container_type ) {
897 930 $grid_declarations['container-type'] = 'inline-size';
898 931 }
899 932 }
@@ -905,9 +938,9 @@
905 938
906 939 if ( $should_output_grid_rows ) {
907 940 $layout_styles[] = array(
908 941 'selector' => $selector,
909 - 'declarations' => array( 'grid-template-rows' => 'repeat(' . $layout_for_styles['rowCount'] . ', minmax(1rem, auto))' ),
942 + 'declarations' => array( 'grid-template-rows' => 'repeat(' . $row_count . ', minmax(1rem, auto))' ),
910 943 );
911 944 }
912 945
913 946 if ( $has_block_gap_support && $should_output_block_gap && null !== $gap_value && ! $should_skip_gap_serialization ) {
@@ -951,10 +984,10 @@
951 984 * and increments on each call. The returned value is not universally unique,
952 985 * but it is unique across the life of the PHP process and it's stable per
953 986 * prefix.
954 987 *
955 - * @param string $prefix Prefix for the returned ID.
956 - * @return string Incremental ID per prefix.
988 + * @param string $prefix Prefix for the returned ID.
989 + * @return string Incremental ID per prefix.
957 990 */
958 991 function gutenberg_incremental_id_per_prefix( $prefix = '' ) {
959 992 static $id_counters = array();
960 993 if ( ! array_key_exists( $prefix, $id_counters ) ) {
@@ -983,15 +1016,13 @@
983 1016
984 1017 /**
985 1018 * Renders the layout config to the block wrapper.
986 1019 *
987 - * @param string $block_content Rendered block content.
988 - * @param array $block Block object.
989 - * @return string Filtered block content.
1020 + * @param string $block_content Rendered block content.
1021 + * @param array $block Block object.
1022 + * @return string Filtered block content.
990 1023 */
991 1024 function gutenberg_render_layout_support_flag( $block_content, $block ) {
992 - static $global_styles = null;
993 -
994 1025 $block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
995 1026 $block_supports_layout = block_has_support( $block_type, array( 'layout' ), false ) || block_has_support( $block_type, array( '__experimentalLayout' ), false );
996 1027 $style_attr = gutenberg_resolve_style_state_aliases(
997 1028 $block['attrs']['style'] ?? array(),
@@ -1206,12 +1237,10 @@
1206 1237 $has_block_gap_support = isset( $block_gap );
1207 1238
1208 1239 // Get default blockGap value from global styles for use in layouts like grid.
1209 1240 // Check style variation first, then block-specific styles, then fall back to root styles.
1210 - $block_name = $block['blockName'] ?? '';
1211 - if ( null === $global_styles ) {
1212 - $global_styles = gutenberg_get_global_styles();
1213 - }
1241 + $block_name = $block['blockName'] ?? '';
1242 + $global_styles = gutenberg_get_global_styles();
1214 1243
1215 1244 // Check if the block has an active style variation with a blockGap value.
1216 1245 // Only check the registry if the className contains a variation class to avoid unnecessary lookups.
1217 1246 $variation_block_gap_value = null;
@@ -1506,11 +1535,11 @@
1506 1535 * For themes without theme.json file, make sure
1507 1536 * to restore the inner div for the group block
1508 1537 * to avoid breaking styles relying on that div.
1509 1538 *
1510 - * @param string $block_content Rendered block content.
1511 - * @param array $block Block object.
1512 - * @return string Filtered block content.
1539 + * @param string $block_content Rendered block content.
1540 + * @param array $block Block object.
1541 + * @return string Filtered block content.
1513 1542 */
1514 1543 function gutenberg_restore_group_inner_container( $block_content, $block ) {
1515 1544 $tag_name_attr = $block['attrs']['tagName'] ?? null;
1516 1545 $tag_name = is_string( $tag_name_attr ) ? $tag_name_attr : 'div';
@@ -1580,9 +1609,9 @@
1580 1609 * to restore the outer div for the aligned image block
1581 1610 * to avoid breaking styles relying on that div.
1582 1611 *
1583 1612 * @param string $block_content Rendered block content.
1584 - * @param array $block Block object.
1613 + * @param array $block Block object.
1585 1614 * @return string Filtered block content.
1586 1615 */
1587 1616 function gutenberg_restore_image_outer_container( $block_content, $block ) {
1588 1617 if ( wp_theme_has_theme_json() ) {