Skip to content

Commit 2c76736

Browse files
Merge pull request #1795 from WordPress/add/ancestor-block-context
Accurate sizes: Add ancestor block context
2 parents 0abf83e + 7757e50 commit 2c76736

File tree

3 files changed

+64
-31
lines changed

3 files changed

+64
-31
lines changed

.wp-env.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"core": null,
2+
"core": "WordPress/WordPress#master",
33
"plugins": [
44
"./plugins/optimization-detective",
55
"./plugins/auto-sizes",

plugins/auto-sizes/hooks.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,4 @@ function auto_sizes_render_generator(): void {
4141
add_filter( 'render_block_core/image', 'auto_sizes_filter_image_tag', 10, 3 );
4242
add_filter( 'render_block_core/cover', 'auto_sizes_filter_image_tag', 10, 3 );
4343
add_filter( 'get_block_type_uses_context', 'auto_sizes_filter_uses_context', 10, 2 );
44-
add_filter( 'render_block_context', 'auto_sizes_filter_render_block_context', 10, 2 );
44+
add_filter( 'render_block_context', 'auto_sizes_filter_render_block_context', 10, 3 );

plugins/auto-sizes/includes/improve-calculate-sizes.php

Lines changed: 62 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,19 @@
66
* @since 1.4.0
77
*/
88

9+
/*
10+
* Map alignment values to a weighting value so they can be compared.
11+
* Note that 'left' and 'right' alignments are only constrained by max alignment.
12+
*/
13+
const AUTO_SIZES_CONSTRAINTS = array(
14+
'full' => 0,
15+
'wide' => 1,
16+
'left' => 2,
17+
'right' => 2,
18+
'default' => 3,
19+
'center' => 3,
20+
);
21+
922
/**
1023
* Primes attachment into the cache with a single database query.
1124
*
@@ -172,18 +185,8 @@ function auto_sizes_calculate_better_sizes( int $id, $size, string $align, int $
172185
// Normalize default alignment values.
173186
$align = '' !== $align ? $align : 'default';
174187

175-
/*
176-
* Map alignment values to a weighting value so they can be compared.
177-
* Note that 'left' and 'right' alignments are only constrained by max alignment.
178-
*/
179-
$constraints = array(
180-
'full' => 0,
181-
'wide' => 1,
182-
'left' => 2,
183-
'right' => 2,
184-
'default' => 3,
185-
'center' => 3,
186-
);
188+
// Use the defined constant for constraints.
189+
$constraints = AUTO_SIZES_CONSTRAINTS;
187190

188191
$alignment = $constraints[ $align ] > $constraints[ $max_alignment ] ? $align : $max_alignment;
189192

@@ -255,15 +258,18 @@ function auto_sizes_get_layout_width( string $alignment ): string {
255258
* @return string[] The filtered context keys used by the block type.
256259
*/
257260
function auto_sizes_filter_uses_context( array $uses_context, WP_Block_Type $block_type ): array {
258-
// The list of blocks that can consume outer layout context.
259-
$consumer_blocks = array(
260-
'core/cover',
261-
'core/image',
261+
// Define block-specific context usage.
262+
$block_specific_context = array(
263+
'core/cover' => array( 'max_alignment', 'container_relative_width' ),
264+
'core/image' => array( 'max_alignment', 'container_relative_width' ),
265+
'core/group' => array( 'max_alignment' ),
266+
'core/columns' => array( 'max_alignment', 'container_relative_width' ),
267+
'core/column' => array( 'max_alignment', 'column_count' ),
262268
);
263269

264-
if ( in_array( $block_type->name, $consumer_blocks, true ) ) {
265-
// Use array_values to reset the array keys after merging.
266-
return array_values( array_unique( array_merge( $uses_context, array( 'max_alignment' ) ) ) );
270+
if ( isset( $block_specific_context[ $block_type->name ] ) ) {
271+
// Use array_values to reset array keys after merging.
272+
return array_values( array_unique( array_merge( $uses_context, $block_specific_context[ $block_type->name ] ) ) );
267273
}
268274
return $uses_context;
269275
}
@@ -273,11 +279,12 @@ function auto_sizes_filter_uses_context( array $uses_context, WP_Block_Type $blo
273279
*
274280
* @since 1.4.0
275281
*
276-
* @param array<string, mixed> $context Current block context.
277-
* @param array<string, mixed> $block The block being rendered.
282+
* @param array<string, mixed> $context Current block context.
283+
* @param array<string, mixed> $block The block being rendered.
284+
* @param WP_Block|null $parent_block If this is a nested block, a reference to the parent block.
278285
* @return array<string, mixed> Modified block context.
279286
*/
280-
function auto_sizes_filter_render_block_context( array $context, array $block ): array {
287+
function auto_sizes_filter_render_block_context( array $context, array $block, ?WP_Block $parent_block ): array {
281288
// When no max alignment is set, the maximum is assumed to be 'full'.
282289
$context['max_alignment'] = $context['max_alignment'] ?? 'full';
283290

@@ -288,15 +295,41 @@ function auto_sizes_filter_render_block_context( array $context, array $block ):
288295
);
289296

290297
if ( in_array( $block['blockName'], $provider_blocks, true ) ) {
291-
$alignment = $block['attrs']['align'] ?? '';
298+
// Normalize default alignment values.
299+
$alignment = isset( $block['attrs']['align'] ) && '' !== $block['attrs']['align'] ? $block['attrs']['align'] : 'default';
300+
// Use the defined constant for constraints.
301+
$constraints = AUTO_SIZES_CONSTRAINTS;
292302

293-
// If the container block doesn't have alignment, it's assumed to be 'default'.
294-
if ( '' === $alignment ) {
295-
$context['max_alignment'] = 'default';
296-
} elseif ( 'wide' === $alignment ) {
297-
$context['max_alignment'] = 'wide';
298-
}
303+
$context['max_alignment'] = $constraints[ $context['max_alignment'] ] > $constraints[ $alignment ] ? $context['max_alignment'] : $alignment;
304+
}
305+
306+
if ( 'core/columns' === $block['blockName'] ) {
307+
// This is a special context key just to pass to the child 'core/column' block.
308+
$context['column_count'] = count( $block['innerBlocks'] );
299309
}
300310

311+
if ( 'core/column' === $block['blockName'] ) {
312+
$found_image_block = wp_get_first_block( $block['innerBlocks'], 'core/image' );
313+
$found_cover_block = wp_get_first_block( $block['innerBlocks'], 'core/cover' );
314+
if ( count( $found_image_block ) > 0 || count( $found_cover_block ) > 0 ) {
315+
// Get column width, if explicitly set.
316+
if ( isset( $block['attrs']['width'] ) && '' !== $block['attrs']['width'] ) {
317+
$current_width = floatval( rtrim( $block['attrs']['width'], '%' ) ) / 100;
318+
} elseif ( isset( $parent_block->context['column_count'] ) && $parent_block->context['column_count'] ) {
319+
// Default to equally divided width if not explicitly set.
320+
$current_width = 1.0 / $parent_block->context['column_count'];
321+
} else {
322+
// Full width fallback.
323+
$current_width = 1.0;
324+
}
325+
326+
// Multiply with parent's width if available.
327+
if ( isset( $parent_block->context['container_relative_width'] ) ) {
328+
$context['container_relative_width'] = $parent_block->context['container_relative_width'] * $current_width;
329+
} else {
330+
$context['container_relative_width'] = $current_width;
331+
}
332+
}
333+
}
301334
return $context;
302335
}

0 commit comments

Comments
 (0)