-
Notifications
You must be signed in to change notification settings - Fork 140
Add picture element support
#73
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
86 commits
Select commit
Hold shift + click to select a range
0d3484c
Begin work on picture element support.
adamsilverstein f29a491
Improve picture construction
adamsilverstein 81dfa5e
Cleanup, docs
adamsilverstein bca723c
Doc block improvements, cleanup
adamsilverstein 5d7b562
Move module into images folder
adamsilverstein f4abeed
clarify default is for testing
adamsilverstein 89cf629
Use original image for fallback
adamsilverstein d4b710d
PHPCS cleanup
adamsilverstein 8b32473
Add some demo picture elements to test approach
adamsilverstein 1ebc2ec
start updating picture element support for new structure
adamsilverstein 74b66c8
fixes for phpstan
adamsilverstein c0bf335
Use picture element by default if the theme declares support for it
adamsilverstein b9624a0
correct typo in function name
adamsilverstein d41a7f3
fixes for linter
adamsilverstein 86602fb
cleanup
adamsilverstein a46ad9d
Merge branch 'trunk' into add/picture-support
adamsilverstein 3ff5d6f
Merge branch 'trunk' into add/picture-support
adamsilverstein 03f710f
Correct logic in webp_uploads_picture_element_enabled
adamsilverstein 0360efe
Always hook picture support, bail early if disabled
adamsilverstein 8c21fa2
Add initial picture element test
adamsilverstein cd6f975
Add additional test cases for picture element
adamsilverstein 3a93d76
skip picture element test if server lacks webp support
adamsilverstein 48573af
rename filter
adamsilverstein ba366a9
Merge branch 'trunk' into add/picture-support
adamsilverstein 7eeb3b8
Merge branch 'trunk' into add/picture-support
adamsilverstein d49e704
Update plugins/webp-uploads/helper.php
adamsilverstein 9bd5be8
only add filter if feature enabled
adamsilverstein 25355a8
Update plugins/webp-uploads/picture-element.php
adamsilverstein 43f8533
Update plugins/webp-uploads/picture-element.php
adamsilverstein 21a3ad3
Update plugins/webp-uploads/picture-element.php
adamsilverstein 4b657a6
Update plugins/webp-uploads/picture-element.php
adamsilverstein cf8a7a8
Update plugins/webp-uploads/picture-element.php
adamsilverstein 7d884ec
Update plugins/webp-uploads/picture-element.php
adamsilverstein a934b0c
Update plugins/webp-uploads/picture-element.php
adamsilverstein 2d0b40b
Update plugins/webp-uploads/picture-element.php
adamsilverstein 14fd90f
Update plugins/webp-uploads/settings.php
adamsilverstein 42a4713
Move PHPCS shared ruleset to tools dir
thelovekesh c99c92e
Move PHPStan stubs and constants to tools dir
thelovekesh d8f3969
Move webpack utils to tools dir
thelovekesh c5765a6
Update PHPCS shared ruleset path
thelovekesh ae319e5
Update utils path
thelovekesh dd13dcc
Update stub and constant files path
thelovekesh 4e16457
Clean stale header
adamsilverstein de05e79
Merge branch 'trunk' into add/picture-support
adamsilverstein 6a9d7e5
Update plugins/webp-uploads/picture-element.php
adamsilverstein 1b10b5a
Update tests/plugins/webp-uploads/picture-element-tests.php
adamsilverstein ddaa425
fix for phpcs
adamsilverstein fab30c8
Update plugins/webp-uploads/picture-element.php
adamsilverstein 6b38a3b
Merge branch 'trunk' into add/picture-support
adamsilverstein 2cb0d68
Merge branch 'trunk' into add/picture-support
adamsilverstein 05fe45f
Align equals
adamsilverstein 132c784
Update plugins/webp-uploads/picture-element.php
adamsilverstein c0e0b25
Update plugins/webp-uploads/picture-element.php
adamsilverstein ac26be0
Ensure sizes and srcset available before trying to wrap in picture el…
adamsilverstein e0a382d
Improve tests
adamsilverstein 0214583
whitespace
adamsilverstein 0b7043e
Merge branch 'trunk' into add/picture-support
adamsilverstein 06e4bf2
Update plugins/webp-uploads/hooks.php
adamsilverstein 47304d4
Fix typo webp_uploads_wepb_fallback->webp_uploads_webp_fallback
adamsilverstein 45e8c4a
Update tests/plugins/webp-uploads/picture-element-tests.php
adamsilverstein e49cc20
Update tests/plugins/webp-uploads/picture-element-tests.php
adamsilverstein 78f28f5
Update tests/plugins/webp-uploads/picture-element-tests.php
adamsilverstein 82c6f80
Update tests/plugins/webp-uploads/picture-element-tests.php
adamsilverstein 4818932
Update plugins/webp-uploads/settings.php
adamsilverstein eccd446
Update plugins/webp-uploads/picture-element.php
adamsilverstein 5d60dd6
Update plugins/webp-uploads/settings.php
adamsilverstein e473b92
Update tests/plugins/webp-uploads/picture-element-tests.php
adamsilverstein 5b687bc
“Picture Element” -> “`<picture>` Element”
adamsilverstein f4042fe
Rename picture test file
adamsilverstein 49a9d4b
Merge branch 'trunk' into add/picture-support + linting
adamsilverstein 5f820d4
Add avif to enabled_mime_types for picture element
adamsilverstein f2b6ea5
Update plugins/webp-uploads/helper.php
adamsilverstein 27be1c7
Update plugins/webp-uploads/settings.php
adamsilverstein 7a07e91
Update plugins/webp-uploads/picture-element.php
adamsilverstein e0b584c
Update plugins/webp-uploads/picture-element.php
adamsilverstein d2af184
webp_uploads_picture_element_enabled -> webp_uploads_is_picture_eleme…
adamsilverstein ac46157
Add settings field back after merge
adamsilverstein 0aa496e
settings cleanup
adamsilverstein 2e68884
Update settings link to point to the entire settings section
westonruter e88caca
Update plugins/webp-uploads/settings.php
adamsilverstein 2d57e43
Update plugins/webp-uploads/picture-element.php
adamsilverstein 6d024de
Update plugins/webp-uploads/settings.php
adamsilverstein 7d5f911
Update plugins/webp-uploads/settings.php
adamsilverstein 86a03f2
fixup! Update settings link to point to the entire settings section
westonruter 70400c8
Update plugins/webp-uploads/settings.php
adamsilverstein 38edfdb
Improve doc block
adamsilverstein File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,154 @@ | ||
| <?php | ||
| /** | ||
| * Add `picture` element support | ||
| * | ||
| * @package webp-uploads | ||
| * | ||
| * @since n.e.x.t | ||
| */ | ||
|
|
||
| /** | ||
| * Potentially wrap an image tag in a picture element. | ||
| * | ||
| * @since n.e.x.t | ||
| * | ||
| * @param string $image The image tag. | ||
| * @param string $context The context for the image tag. | ||
| * @param int $attachment_id The attachment id. | ||
| * | ||
| * @return string The new image tag. | ||
| */ | ||
| function webp_uploads_wrap_image_in_picture( string $image, string $context, int $attachment_id ): string { | ||
| if ( 'the_content' !== $context ) { | ||
| return $image; | ||
| } | ||
| $image_meta = wp_get_attachment_metadata( $attachment_id ); | ||
| $original_file_mime_type = get_post_mime_type( $attachment_id ); | ||
| if ( false === $original_file_mime_type || ! isset( $image_meta['sizes'] ) ) { | ||
| return $image; | ||
| } | ||
|
|
||
| // Collect all the sub size image mime types. | ||
| $mime_type_data = array(); | ||
| foreach ( $image_meta['sizes'] as $size ) { | ||
| if ( isset( $size['sources'] ) && isset( $size['width'] ) && isset( $size['height'] ) ) { | ||
| foreach ( $size['sources'] as $mime_type => $data ) { | ||
| $mime_type_data[ $mime_type ] = $mime_type_data[ $mime_type ] ?? array(); | ||
| $mime_type_data[ $mime_type ]['w'][ $size['width'] ] = $data; | ||
| $mime_type_data[ $mime_type ]['h'][ $size['height'] ] = $data; | ||
| } | ||
| } | ||
| } | ||
| $sub_size_mime_types = array_keys( $mime_type_data ); | ||
|
|
||
| /** | ||
| * Filter the image mime types that can be used for the <picture> element. | ||
| * | ||
| * Default is: ['image/avif', 'image/webp', 'image/jpeg']. Returning an empty array will skip using the `picture` element. | ||
| * | ||
| * The mime types will output in the picture element in the order they are provided. | ||
| * The original image will be used as the fallback image for browsers that don't support the picture element. | ||
| * | ||
| * @since n.e.x.t | ||
| * @param string[] $mime_types Mime types than can be used. | ||
| * @param int $attachment_id The id of the image being evaluated. | ||
| */ | ||
| $enabled_mime_types = (array) apply_filters( | ||
| 'webp_uploads_picture_element_mime_types', | ||
| array( | ||
| 'image/avif', | ||
| 'image/webp', | ||
| 'image/jpeg', | ||
| ), | ||
| $attachment_id | ||
| ); | ||
|
|
||
| $mime_types = array_intersect( $enabled_mime_types, $sub_size_mime_types ); | ||
|
|
||
| // No eligible mime types. | ||
| if ( count( $mime_types ) === 0 ) { | ||
| return $image; | ||
| } | ||
|
|
||
| // If the original mime types is the only one available, no picture element is needed. | ||
| if ( 1 === count( $mime_types ) && current( $mime_types ) === $original_file_mime_type ) { | ||
| return $image; | ||
| } | ||
|
|
||
| // Add each mime type to the picture's sources. | ||
| $picture_sources = ''; | ||
|
|
||
| // Extract sizes using regex to parse image tag, then use to retrieve tag. | ||
| $width = 0; | ||
| $height = 0; | ||
| $processor = new WP_HTML_Tag_Processor( $image ); | ||
| if ( $processor->next_tag( array( 'tag_name' => 'IMG' ) ) ) { | ||
| $width = (int) $processor->get_attribute( 'width' ); | ||
| $height = (int) $processor->get_attribute( 'height' ); | ||
| } | ||
| $size_to_use = ( $width > 0 && $height > 0 ) ? array( $width, $height ) : 'full'; | ||
|
|
||
| $image_src = wp_get_attachment_image_src( $attachment_id, $size_to_use ); | ||
| if ( false === $image_src ) { | ||
| return $image; | ||
| } | ||
| list( $src, $width, $height ) = $image_src; | ||
| $size_array = array( absint( $width ), absint( $height ) ); | ||
|
|
||
| foreach ( $mime_types as $image_mime_type ) { | ||
| $sizes = wp_calculate_image_sizes( $size_array, $src, $image_meta, $attachment_id ); | ||
| if ( false === $sizes ) { | ||
| continue; | ||
| } | ||
|
|
||
| // Filter core's wp_get_attachment_image_srcset to return the sources for the current mime type. | ||
| $filter = static function ( $sources ) use ( $mime_type_data, $image_mime_type ): array { | ||
| $filtered_sources = array(); | ||
| foreach ( $sources as $source ) { | ||
| // Swap the URL for the current mime type. | ||
| if ( isset( $mime_type_data[ $image_mime_type ][ $source['descriptor'] ][ $source['value'] ] ) ) { | ||
| $filename = $mime_type_data[ $image_mime_type ][ $source['descriptor'] ][ $source['value'] ]['file']; | ||
| $filtered_sources[] = array( | ||
| 'url' => dirname( $source['url'] ) . '/' . $filename, | ||
| 'descriptor' => $source['descriptor'], | ||
| 'value' => $source['value'], | ||
| ); | ||
| } | ||
| } | ||
| return $filtered_sources; | ||
| }; | ||
| add_filter( 'wp_calculate_image_srcset', $filter ); | ||
| $image_srcset = wp_get_attachment_image_srcset( $attachment_id, $size_array, $image_meta ); | ||
| remove_filter( 'wp_calculate_image_srcset', $filter ); | ||
| if ( false === $image_srcset ) { | ||
| continue; | ||
| } | ||
| $picture_sources .= sprintf( | ||
| '<source type="%s" srcset="%s" sizes="%s">', | ||
| esc_attr( $image_mime_type ), | ||
| esc_attr( $image_srcset ), | ||
| esc_attr( $sizes ) | ||
| ); | ||
| } | ||
|
|
||
| // Fall back to the original image without a srcset. | ||
| $original_sizes = array( $image_src[1], $image_src[2] ); | ||
| $original_image = wp_get_original_image_url( $attachment_id ); | ||
| // Fail gracefully if the original image is not found. | ||
| if ( false === $original_image ) { | ||
| return $image; | ||
| } | ||
| $filter = static function (): bool { | ||
| return false; | ||
| }; | ||
| add_filter( 'wp_calculate_image_srcset_meta', $filter ); | ||
| $original_image_without_srcset = wp_get_attachment_image( $attachment_id, $original_sizes, false, array( 'src' => $original_image ) ); | ||
| remove_filter( 'wp_calculate_image_srcset_meta', $filter ); | ||
|
|
||
| return sprintf( | ||
| '<picture class="%s">%s%s</picture>', | ||
| esc_attr( 'wp-picture-' . $attachment_id ), | ||
| $picture_sources, | ||
| $original_image_without_srcset | ||
| ); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.