diff --git a/README.md b/README.md index bffa4bf..e833d57 100644 --- a/README.md +++ b/README.md @@ -1357,7 +1357,7 @@ function add_custom_block_metadata( $sourced_block, $block_name, $post_id, $bloc Direct block HTML can be accessed through `$block['innerHTML']`. This may be useful if manual HTML parsing is necessary to gather data from a block. -For another example of how this filter can be used to extend block data, we have implemented a default image block filter in [`src/parser/block-additions/core-image.php`][repo-core-image-block-addition]. This filter is automatically called on `core/image` blocks to add `width` and `height` to image attributes. +For another example of how this filter can be used to extend block data, we have implemented a default image block filter in [`src/parser/block-additions/core-image.php`][repo-core-image-block-addition]. This filter is automatically called on `core/image` blocks to add `width` and `height` to image attributes. When an image has been resized in the editor (e.g. via the drag handles), the editor-selected dimensions are also exposed as `resize-width` and `resize-height`, while `width` and `height` continue to reflect the attachment's full-size dimensions. --- diff --git a/src/parser/block-additions/core-image.php b/src/parser/block-additions/core-image.php index f444248..1e68ce5 100644 --- a/src/parser/block-additions/core-image.php +++ b/src/parser/block-additions/core-image.php @@ -66,6 +66,18 @@ public static function add_image_metadata( $sourced_block, $block_name ) { private static function get_size_metadata( $attributes, $attachment_metadata ) { $size_metadata = []; + // Preserve any editor-provided dimensions (e.g. from drag-to-resize) as + // separate resize-width/resize-height attributes. The width/height + // attributes below are overwritten with the attachment's metadata, which + // would otherwise discard the resized dimensions selected in the editor. + if ( isset( $attributes['width'] ) ) { + $size_metadata['resize-width'] = $attributes['width']; + } + + if ( isset( $attributes['height'] ) ) { + $size_metadata['resize-height'] = $attributes['height']; + } + if ( isset( $attachment_metadata['width'] ) ) { $size_metadata['width'] = $attachment_metadata['width']; } diff --git a/tests/parser/blocks/test-image-block.php b/tests/parser/blocks/test-image-block.php index eb94cab..420e571 100644 --- a/tests/parser/blocks/test-image-block.php +++ b/tests/parser/blocks/test-image-block.php @@ -42,6 +42,65 @@ public function test_parse_core_image_has_size_attributes() { $content_parser = new ContentParser(); $blocks = $content_parser->parse( $html ); $this->assertArrayHasKey( 'blocks', $blocks, sprintf( 'Unexpected parser output: %s', wp_json_encode( $blocks ) ) ); - $this->assertArraySubset( $expected_blocks, $expected_blocks, true ); + $this->assertArraySubset( $expected_blocks, $blocks['blocks'], true ); + } + + public function test_parse_core_image_resized_keeps_metadata_and_resize_attributes() { + global $wp_version; + + // A drag-to-resize in the editor stores width/height in the block + // attributes. The type of these attributes changed in WordPress 6.3 + // from numbers (e.g. 300) to unit strings (e.g. "300px"). + // Test each shape against the version that produces it. + if ( version_compare( $wp_version, '6.3', '<' ) ) { + $this->assert_resize_attributes_preserved( 300, 169 ); + } else { + $this->assert_resize_attributes_preserved( '300px', '169px' ); + } + } + + /** + * Assert that a resized core/image keeps its full-size metadata dimensions + * as width/height while exposing the editor resize dimensions separately. + * + * @param int|string $resize_width Editor-selected width stored in the block attributes. + * @param int|string $resize_height Editor-selected height stored in the block attributes. + */ + private function assert_resize_attributes_preserved( $resize_width, $resize_height ) { + $attachment_id = $this->factory()->attachment->create_upload_object( WPCOMVIP__BLOCK_DATA_API__TEST_DATA . '/blue.png' ); + $attachment_url = wp_get_attachment_url( $attachment_id ); + + $image_attributes = [ + 'id' => $attachment_id, + 'width' => $resize_width, + 'height' => $resize_height, + ]; + + $html = ' + +
+ +
+ + '; + + $expected_blocks = [ + [ + 'name' => 'core/image', + 'attributes' => [ + // Full-size dimensions from the attachment metadata are preserved. + 'width' => 800, + 'height' => 450, + // Editor-selected resize dimensions are exposed separately. + 'resize-width' => $resize_width, + 'resize-height' => $resize_height, + ], + ], + ]; + + $content_parser = new ContentParser(); + $blocks = $content_parser->parse( $html ); + $this->assertArrayHasKey( 'blocks', $blocks, sprintf( 'Unexpected parser output: %s', wp_json_encode( $blocks ) ) ); + $this->assertArraySubset( $expected_blocks, $blocks['blocks'], true ); } }