Media: Make client-side supported MIME types configurable#76549
Media: Make client-side supported MIME types configurable#76549adamsilverstein wants to merge 8 commits into
Conversation
The CLIENT_SIDE_SUPPORTED_MIME_TYPES constant is hardcoded, preventing plugins from adding support for additional image formats via client-side processing. This adds a clientSideSupportedMimeTypes setting that flows from a PHP filter through the REST API and settings pipeline, falling back to the existing constant when not set. This follows the same pattern used by imageOutputFormats.
|
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. |
Cover the new configurable MIME types setting in the REST index: verify it is absent for unprivileged users, present with correct defaults for admins, and filterable via the client_side_supported_mime_types hook.
|
Size Change: +67 B (0%) Total Size: 8.75 MB
ℹ️ View Unchanged
|
Verify that prepareItem respects a custom MIME types list from settings, can add normally-unsupported types to client-side processing, and falls back to the default constant when the setting is not provided.
Plugins that convert files client-side before upload need to swap the main attached file afterward (e.g. uploading a JPEG for processing then replacing it with the original HEIC). The new replace_file boolean parameter updates the attached file, MIME type, and metadata, and deletes the old file from disk.
The preload root fields must exactly match the fields requested in entities.js. Without this, the site editor makes an extra fetch for the root endpoint because the preloaded URL doesn't match the requested URL.
Resolves PHPCS warning about double arrow alignment in the sideload item endpoint args array.
|
Flaky tests detected in 7b03bc8. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/23204523654
|
Add a `client_side_supported_mime_types` filter and REST API index field so plugins can customize which image formats are processed client-side via WebAssembly-based vips. The default list includes JPEG, PNG, GIF, WebP, and AVIF. Also updates the preload paths in the post editor and site editor to include the new field, ensuring the preloaded URL matches the JavaScript request. Props adamsilverstein. See WordPress/gutenberg#76549.
Links Gutenberg PR #76549 to the corresponding wordpress-develop backport PR.
|
Core backport PR: WordPress/wordpress-develop#11277 |
|
@andrewserong working on making client-side media more extensible here so it is possible add support for HEIC and other newer formats like UltraHDR in the experiments plugin. This will let us make them available and testable more quickly and also open up the system so other plugins could add support for additional types. With this PR and https://github.com/adamsilverstein/client-side-media-experiments/ HEIC uploads work without server support (which is not the case currently). |
|
If this is for 7.1, is it worth holding off for now, until after 7.0 / after the RC period? Just to make sure backports can happen cleanly. Something I'm wondering about the API for this is whether we even need the PHP side? If there's a block editor setting, then plugins can already filter block editor settings, so that could simplify things. But the main question I had is: what does it mean for plugins to change the list of image types that can be converted with client-side media processing? I thought the code for converting files happens within Gutenberg / the existing JS logic, so how does a plugin extend this behaviour? (I.e. I'd assumed that hard-coding the list would be fine, because the client-side media processing is responsible for itself). I see in the linked plugin that the IMO I'd be pretty wary about supporting this as an extensibility API as it seems quite brittle. I guess another way of putting my comment here is: how valuable is it to support filtering the mime types if a plugin has to go to such lengths to add support for the mime types they're adding? It seems a bit tangled to me. But that's just my first impression! |
|
Since I have solved HEIC extensibility with a different approach, I'm going to close this. |
|
Sounds good, thanks for the update 👍 |
The feature shipping target moved from 7.0 to 7.1 (per #76756). Bring the architecture explanation and how-to guide up to date with the post-7.0-cycle state of the code: - Reposition introductions around 7.1 with 7.0 as the groundwork cycle. - HEIC/HEIF: document the canvas-based fallback path (createImageBitmap, HTMLImageElement+OffscreenCanvas, HEIC container parsing + WebCodecs VideoDecoder), JPEG companion file, and isHeicCanvasSupported() gate. - AVIF: note the wp_prevent_unsupported_mime_type_uploads bypass when generate_sub_sizes=false (#76371). - Batch thumbnail generation via image.copyMemory() / thumbnailImage() (#76979). - Sub-size deduplication via image_size: string|string[] on the sideload route (#77036). - Single VIPS instance via promise caching (#76780). - Build-output trimming: remove vips-jxl.wasm (#76639), skip non-min worker (#76615), skip WASM-inlined sourcemaps (#75993). - COI: <img> excluded from cross-origin attribute injection (#76618). - Loosened feature-detection thresholds: 2 cores, 3g (#76616). - Post-saving lock fix: Save Draft now respects the lock (#76973). - convert_format declared as boolean on sideload route (#77565). - Fix incorrect REST index settings list (only image_sizes and image_size_threshold are exposed). - Remove references to client_side_supported_mime_types filter (PR #76549 was closed unmerged); state the supported MIME set is fixed at CLIENT_SIDE_SUPPORTED_MIME_TYPES. Refs #75111.
The feature ships in 7.1 instead of 7.0 (per #76756). Reframe the post as a 7.1 announcement with a dedicated 'What's new in 7.1' section listing HEIC support, end-to-end AVIF uploads, batch thumbnail generation, sub-size deduplication, single VIPS instance, save lock fix, loosened device requirements, <img> COI exclusion, smaller build output, and the convert_format boolean coercion fix. Each item is linked to its merged PR. Move the original 7.0 cycle deliverables under 'What changed during 7.0' so the historical context stays available for the announcement audience. Update technical overview to use the actual function name (gutenberg_is_client_side_media_processing_enabled), reflect that DIP replaces COEP/COOP, and remove the inaccurate note that the imageQuality hook isn't wired up. Drop the make-believe client_side_supported_mime_types filter; PR #76549 was closed unmerged. State that the supported MIME set is fixed at CLIENT_SIDE_SUPPORTED_MIME_TYPES. Update browser compatibility table to reflect the DIP-based gating (Chromium 137+, no Firefox/Safari) and add a feature detection thresholds section.
Summary
The
CLIENT_SIDE_SUPPORTED_MIME_TYPESconstant in theupload-mediapackage is hardcoded, preventing plugins from adding support for additional image formats via client-side processing.This adds a
clientSideSupportedMimeTypessetting that flows from a PHP filter (client_side_supported_mime_types) through the REST API and settings pipeline to theprepareItemfunction, falling back to the existing hardcoded constant when not provided.This follows the same pattern used by
imageOutputFormats:lib/media/load.php)core-data/entities.js)Settingstype (upload-media/store/types.ts)prepareItem()with fallback (upload-media/store/private-actions.ts)use-media-upload-settings.js,use-block-editor-settings.js)Use case
This is needed to to add client-side conversion for HEIC→JPEG via a JavaScript library and need to tell the upload pipeline that those MIME types should be processed client-side rather than sent to the server. Without this filter, such files bypass client-side processing entirely and get rejected by the server (unless supported there).
Test plan
Expected: HEIC is processed on the client, sub-sized jpegs are uploaded using the sideload endpoint along with the original heic file.