From 501c65e276a748821f23c8627134c04aad39522b Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Thu, 12 Dec 2024 16:18:59 -0600 Subject: [PATCH 1/4] Initial concept for supporting relative alingment widths --- .../includes/improve-calculate-sizes.php | 84 ++++++++++--------- 1 file changed, 46 insertions(+), 38 deletions(-) diff --git a/plugins/auto-sizes/includes/improve-calculate-sizes.php b/plugins/auto-sizes/includes/improve-calculate-sizes.php index 40b50a0e46..0a92c76c75 100644 --- a/plugins/auto-sizes/includes/improve-calculate-sizes.php +++ b/plugins/auto-sizes/includes/improve-calculate-sizes.php @@ -194,13 +194,21 @@ function auto_sizes_calculate_better_sizes( int $id, $size, string $align, int $ case 'left': case 'right': - $layout_width = sprintf( '%1$spx', $image_width ); - break; - case 'center': default: - $alignment = auto_sizes_get_layout_width( 'default' ); - $layout_width = sprintf( '%1$spx', min( (int) $alignment, $image_width ) ); + $layout_alignment = in_array( $alignment, array( 'left', 'right' ), true ) ? 'wide' : 'default'; + $layout_width = auto_sizes_get_layout_width( $layout_alignment ); + + /* + * If the layout width is in pixels, we can compare against the image width + * on the server. Otherwise, we need to rely on CSS functions. + */ + if ( str_ends_with( $layout_width, 'px' ) ) { + $layout_width = sprintf( '%1$spx', min( (int) $layout_width, $image_width ) ); + } else { + $layout_width = sprintf( 'min(%1$s, %2$spx)', $layout_width, $image_width ); + } + break; } @@ -212,14 +220,14 @@ function auto_sizes_calculate_better_sizes( int $id, $size, string $align, int $ return $layout_width; } -/** - * Retrieves the layout width for an alignment defined in theme.json. - * - * @since n.e.x.t - * - * @param string $alignment The alignment value. - * @return string The alignment width based. - */ + /** + * Retrieves the layout width for an alignment defined in theme.json. + * + * @since n.e.x.t + * + * @param string $alignment The alignment value. + * @return string The alignment width based. + */ function auto_sizes_get_layout_width( string $alignment ): string { $layout = auto_sizes_get_layout_settings(); @@ -232,15 +240,15 @@ function auto_sizes_get_layout_width( string $alignment ): string { return $layout_widths[ $alignment ] ?? ''; } -/** - * Filters the context keys that a block type uses. - * - * @since n.e.x.t - * - * @param string[] $uses_context Array of registered uses context for a block type. - * @param WP_Block_Type $block_type The full block type object. - * @return string[] The filtered context keys used by the block type. - */ + /** + * Filters the context keys that a block type uses. + * + * @since n.e.x.t + * + * @param string[] $uses_context Array of registered uses context for a block type. + * @param WP_Block_Type $block_type The full block type object. + * @return string[] The filtered context keys used by the block type. + */ function auto_sizes_filter_uses_context( array $uses_context, WP_Block_Type $block_type ): array { // The list of blocks that can consume outer layout context. $consumer_blocks = array( @@ -255,15 +263,15 @@ function auto_sizes_filter_uses_context( array $uses_context, WP_Block_Type $blo return $uses_context; } -/** - * Modifies the block context during rendering to blocks. - * - * @since n.e.x.t - * - * @param array $context Current block context. - * @param array $block The block being rendered. - * @return array Modified block context. - */ + /** + * Modifies the block context during rendering to blocks. + * + * @since n.e.x.t + * + * @param array $context Current block context. + * @param array $block The block being rendered. + * @return array Modified block context. + */ function auto_sizes_filter_render_block_context( array $context, array $block ): array { // When no max alignment is set, the maximum is assumed to be 'full'. $context['max_alignment'] = $context['max_alignment'] ?? 'full'; @@ -288,13 +296,13 @@ function auto_sizes_filter_render_block_context( array $context, array $block ): return $context; } -/** - * Retrieves the layout settings defined in theme.json. - * - * @since n.e.x.t - * - * @return array Associative array of layout settings. - */ + /** + * Retrieves the layout settings defined in theme.json. + * + * @since n.e.x.t + * + * @return array Associative array of layout settings. + */ function auto_sizes_get_layout_settings(): array { static $layout = array(); if ( count( $layout ) === 0 ) { From e69b2afc17f2903ea3da409440808da591020747 Mon Sep 17 00:00:00 2001 From: Mukesh Panchal Date: Fri, 13 Dec 2024 10:24:41 +0530 Subject: [PATCH 2/4] Revert unwanted doc indention changes --- .../includes/improve-calculate-sizes.php | 66 +++++++++---------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/plugins/auto-sizes/includes/improve-calculate-sizes.php b/plugins/auto-sizes/includes/improve-calculate-sizes.php index 0a92c76c75..b7c36be17d 100644 --- a/plugins/auto-sizes/includes/improve-calculate-sizes.php +++ b/plugins/auto-sizes/includes/improve-calculate-sizes.php @@ -220,14 +220,14 @@ function auto_sizes_calculate_better_sizes( int $id, $size, string $align, int $ return $layout_width; } - /** - * Retrieves the layout width for an alignment defined in theme.json. - * - * @since n.e.x.t - * - * @param string $alignment The alignment value. - * @return string The alignment width based. - */ +/** + * Retrieves the layout width for an alignment defined in theme.json. + * + * @since n.e.x.t + * + * @param string $alignment The alignment value. + * @return string The alignment width based. + */ function auto_sizes_get_layout_width( string $alignment ): string { $layout = auto_sizes_get_layout_settings(); @@ -240,15 +240,15 @@ function auto_sizes_get_layout_width( string $alignment ): string { return $layout_widths[ $alignment ] ?? ''; } - /** - * Filters the context keys that a block type uses. - * - * @since n.e.x.t - * - * @param string[] $uses_context Array of registered uses context for a block type. - * @param WP_Block_Type $block_type The full block type object. - * @return string[] The filtered context keys used by the block type. - */ +/** + * Filters the context keys that a block type uses. + * + * @since n.e.x.t + * + * @param string[] $uses_context Array of registered uses context for a block type. + * @param WP_Block_Type $block_type The full block type object. + * @return string[] The filtered context keys used by the block type. + */ function auto_sizes_filter_uses_context( array $uses_context, WP_Block_Type $block_type ): array { // The list of blocks that can consume outer layout context. $consumer_blocks = array( @@ -263,15 +263,15 @@ function auto_sizes_filter_uses_context( array $uses_context, WP_Block_Type $blo return $uses_context; } - /** - * Modifies the block context during rendering to blocks. - * - * @since n.e.x.t - * - * @param array $context Current block context. - * @param array $block The block being rendered. - * @return array Modified block context. - */ +/** + * Modifies the block context during rendering to blocks. + * + * @since n.e.x.t + * + * @param array $context Current block context. + * @param array $block The block being rendered. + * @return array Modified block context. + */ function auto_sizes_filter_render_block_context( array $context, array $block ): array { // When no max alignment is set, the maximum is assumed to be 'full'. $context['max_alignment'] = $context['max_alignment'] ?? 'full'; @@ -296,13 +296,13 @@ function auto_sizes_filter_render_block_context( array $context, array $block ): return $context; } - /** - * Retrieves the layout settings defined in theme.json. - * - * @since n.e.x.t - * - * @return array Associative array of layout settings. - */ +/** + * Retrieves the layout settings defined in theme.json. + * + * @since n.e.x.t + * + * @return array Associative array of layout settings. + */ function auto_sizes_get_layout_settings(): array { static $layout = array(); if ( count( $layout ) === 0 ) { From 7dd60d5532fcb34d06ecb0ac27cdf1bd29502d13 Mon Sep 17 00:00:00 2001 From: Joe McGill <801097+joemcgill@users.noreply.github.com> Date: Fri, 13 Dec 2024 10:01:28 -0600 Subject: [PATCH 3/4] Chance typing for `sprintf()` placeholder Co-authored-by: Weston Ruter --- plugins/auto-sizes/includes/improve-calculate-sizes.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/auto-sizes/includes/improve-calculate-sizes.php b/plugins/auto-sizes/includes/improve-calculate-sizes.php index b7c36be17d..a354e08f13 100644 --- a/plugins/auto-sizes/includes/improve-calculate-sizes.php +++ b/plugins/auto-sizes/includes/improve-calculate-sizes.php @@ -204,7 +204,7 @@ function auto_sizes_calculate_better_sizes( int $id, $size, string $align, int $ * on the server. Otherwise, we need to rely on CSS functions. */ if ( str_ends_with( $layout_width, 'px' ) ) { - $layout_width = sprintf( '%1$spx', min( (int) $layout_width, $image_width ) ); + $layout_width = sprintf( '%dpx', min( (int) $layout_width, $image_width ) ); } else { $layout_width = sprintf( 'min(%1$s, %2$spx)', $layout_width, $image_width ); } From 35988a41382022cdccd22433f1d6f1cdb5f70f5b Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Fri, 13 Dec 2024 10:53:41 -0600 Subject: [PATCH 4/4] Add tests for relative alignment --- .../includes/improve-calculate-sizes.php | 6 +- .../tests/test-improve-calculate-sizes.php | 122 ++++++++++++++++++ 2 files changed, 123 insertions(+), 5 deletions(-) diff --git a/plugins/auto-sizes/includes/improve-calculate-sizes.php b/plugins/auto-sizes/includes/improve-calculate-sizes.php index a354e08f13..1e0c5113fd 100644 --- a/plugins/auto-sizes/includes/improve-calculate-sizes.php +++ b/plugins/auto-sizes/includes/improve-calculate-sizes.php @@ -304,9 +304,5 @@ function auto_sizes_filter_render_block_context( array $context, array $block ): * @return array Associative array of layout settings. */ function auto_sizes_get_layout_settings(): array { - static $layout = array(); - if ( count( $layout ) === 0 ) { - $layout = wp_get_global_settings( array( 'layout' ) ); - } - return $layout; + return wp_get_global_settings( array( 'layout' ) ); } diff --git a/plugins/auto-sizes/tests/test-improve-calculate-sizes.php b/plugins/auto-sizes/tests/test-improve-calculate-sizes.php index 1ef56fd2c6..484fb3f954 100644 --- a/plugins/auto-sizes/tests/test-improve-calculate-sizes.php +++ b/plugins/auto-sizes/tests/test-improve-calculate-sizes.php @@ -34,6 +34,9 @@ public function set_up(): void { // Disable lazy loading attribute. add_filter( 'wp_img_tag_add_loading_attr', '__return_false' ); + + // Run each test with fresh WP_Theme_JSON data so we can filter layout values. + wp_clean_theme_json_cache(); } /** @@ -514,6 +517,125 @@ public function data_ancestor_and_image_block_alignment(): array { ); } + /** + * Test sizes attributes when alignments use relative units. + * + * @dataProvider data_image_blocks_with_relative_alignment + * + * @param string $ancestor_alignment Ancestor alignment. + * @param string $image_alignment Image alignment. + * @param string $expected Expected output. + */ + public function test_sizes_with_relative_layout_sizes( string $ancestor_alignment, string $image_alignment, string $expected ): void { + add_filter( 'wp_theme_json_data_user', array( $this, 'filter_theme_json_layout_sizes' ) ); + + $block_content = $this->get_group_block_markup( + $this->get_image_block_markup( self::$image_id, 'large', $image_alignment ), + array( + 'align' => $ancestor_alignment, + ) + ); + + $result = apply_filters( 'the_content', $block_content ); + + $this->assertStringContainsString( $expected, $result ); + } + + /** + * Data provider. + * + * @return array> The ancestor and image alignments. + */ + public function data_image_blocks_with_relative_alignment(): array { + return array( + // Parent default alignment. + 'Return contentSize 50vw, parent block default alignment, image block default alignment' => array( + '', + '', + 'sizes="(max-width: min(50vw, 1024px)) 100vw, min(50vw, 1024px)" ', + ), + 'Return contentSize 50vw, parent block default alignment, image block wide alignment' => array( + '', + 'wide', + 'sizes="(max-width: min(50vw, 1024px)) 100vw, min(50vw, 1024px)" ', + ), + 'Return contentSize 50vw, parent block default alignment, image block full alignment' => array( + '', + 'full', + 'sizes="(max-width: min(50vw, 1024px)) 100vw, min(50vw, 1024px)" ', + ), + 'Return contentSize 50vw, parent block default alignment, image block left alignment' => array( + '', + 'left', + 'sizes="(max-width: min(50vw, 1024px)) 100vw, min(50vw, 1024px)" ', + ), + 'Return contentSize 50vw, parent block default alignment, image block center alignment' => array( + '', + 'center', + 'sizes="(max-width: min(50vw, 1024px)) 100vw, min(50vw, 1024px)" ', + ), + 'Return contentSize 50vw, parent block default alignment, image block right alignment' => array( + '', + 'right', + 'sizes="(max-width: min(50vw, 1024px)) 100vw, min(50vw, 1024px)" ', + ), + + // Parent wide alignment. + 'Return contentSize 50vw, parent block wide alignment, image block default alignment' => array( + 'wide', + '', + 'sizes="(max-width: min(50vw, 1024px)) 100vw, min(50vw, 1024px)" ', + ), + 'Return wideSize 75vw, parent block wide alignment, image block wide alignment' => array( + 'wide', + 'wide', + 'sizes="(max-width: 75vw) 100vw, 75vw" ', + ), + 'Return wideSize 75vw, parent block wide alignment, image block full alignment' => array( + 'wide', + 'full', + 'sizes="(max-width: 75vw) 100vw, 75vw" ', + ), + 'Return image size 1024px, parent block wide alignment, image block left alignment' => array( + 'wide', + 'left', + 'sizes="(max-width: min(75vw, 1024px)) 100vw, min(75vw, 1024px)" ', + ), + 'Return image size 620px, parent block wide alignment, image block center alignment' => array( + 'wide', + 'center', + 'sizes="(max-width: min(50vw, 1024px)) 100vw, min(50vw, 1024px)" ', + ), + 'Return image size 1024px, parent block wide alignment, image block right alignment' => array( + 'wide', + 'right', + 'sizes="(max-width: min(75vw, 1024px)) 100vw, min(75vw, 1024px)" ', + ), + ); + } + + /** + * Filter the theme.json data to include relative layout sizes. + * + * @param WP_Theme_JSON_Data $theme_json Theme JSON object. + * @return WP_Theme_JSON_Data Updated theme JSON object. + */ + public function filter_theme_json_layout_sizes( WP_Theme_JSON_Data $theme_json ): WP_Theme_JSON_Data { + $data = array( + 'version' => 2, + 'settings' => array( + 'layout' => array( + 'contentSize' => '50vw', + 'wideSize' => '75vw', + ), + ), + ); + + $theme_json = $theme_json->update_with( $data ); + + return $theme_json; + } + /** * Helper to generate image block markup. *