Modern Image Formats: let the browser encode client side uploads, and reflect it on the settings screen - #2663
Conversation
When the block editor processes uploads client side (WordPress 7.1), the browser encodes the sub-sizes in the format reported by the image_output_format REST field. That field is computed from the image_editor_output_format filter, which the plugin only mapped to AVIF when the server's own image editor could encode AVIF, so a browser that could produce AVIF was silently told to produce WebP instead. Track the REST requests of the client side flow (attachment creation with generate_sub_sizes disabled, sideload and finalize) and, within them, keep the selected format in the mime transforms and map the source type to it regardless of server support. Fallback output still works because the server generates the original format sizes when the upload is finalized.
With WordPress 7.1 the browser can encode AVIF and WebP for editor uploads, so a format is no longer unavailable just because the server cannot encode it. Keep both formats selectable when client side media processing is enabled for the site, explain that the browser handles editor uploads while other upload paths fall back, and let a runtime feature check in the browser restore the server-only notices when the browser cannot process media itself.
The picture element wrapper assumed the inner img is in the original upload format, which holds when the server generates the sub-sizes and adds the modern format as an additional source. With client side media processing the browser generates the sub-sizes in the modern format and the server adds the original format afterwards, so the fallback img pointed at AVIF files. Point the src and srcset of the fallback img at the original format sources whenever the image is in a modern format.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## trunk #2663 +/- ##
==========================================
+ Coverage 70.50% 70.87% +0.36%
==========================================
Files 91 91
Lines 7870 7931 +61
==========================================
+ Hits 5549 5621 +72
+ Misses 2321 2310 -11
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
|
This is a first pass at leveraging client side media for modern image support. The big caveat with 7.1 is the feature client side media is only available in the editor. For 7.2 I hope to land this in the media library as well, so maybe its worth waiting for 7.2 to try to land this feature? |
Move the WP_REST_Request generic into a phpstan-param tag so the FunctionComment sniff no longer misreads the type hint, and realign the array double arrows and assignments phpcbf flagged in the tests. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CgmXFEKZyEoskNXDtv6fJy
With the WordPress 7.1 stubs, PHPStan knows the finalize endpoint always exists and reports the method_exists() guard as dead code. Check the WordPress version instead, since the runtime check is still needed on the WordPress 6.9 test matrix entry. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CgmXFEKZyEoskNXDtv6fJy
| <?php | ||
| webp_uploads_render_modern_image_support_unavailable_notice( true ); | ||
| ?> | ||
| <script> |
There was a problem hiding this comment.
We should not be printing script tags manually as this violates CSP compat.
This should instead be:
wp_print_inline_script_tag(
<<<'JS'
/* ... */
JS
);There was a problem hiding this comment.
Thanks!
I also wonder looking at this whether we could leverage the existing checks somehow (even though they don't typically run here) instead of duplicating them.
There was a problem hiding this comment.
Switched to wp_print_inline_script_tag() in 8fbb1da.
Claude checked whether the core detection could be reused here:
wp.uploadMedia.isClientSideMediaSupported()is available on this screen, but it bails on the missingSharedArrayBufferbecause the settings page is not cross-origin isolated, so it would report unsupported in every browser. Until the package can skip that check, the mirrored detection seems the practical option.
Printing a script tag by hand bypasses the CSP nonce and other attributes that wp_print_inline_script_tag() applies, as raised in review. Match the pattern used by the Speculative Loading settings. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CgmXFEKZyEoskNXDtv6fJy
This picks up the verification list from #2662. Short version: the plugin was telling the browser to produce WebP whenever the server could not encode AVIF, and the picture element assumed the server had made the sub-sizes. Both are addressed here, and I ran through each of the scenarios from the issue on WP 7.1 in the editor. There are Playground links below for anyone who wants to try it without a local setup.
Claude wrote the code and this write up, findings and all:
AI Use
Code and description both written with 🤖 Claude Code. I will review and test.
🤖 Generated with Claude Code