Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
21f9316
Media: Move client-side media processing files from experimental to s…
adamsilverstein Jan 31, 2026
360ef2c
Media: Remove client-side media processing from experiments page
adamsilverstein Jan 31, 2026
a184f96
Media: Always load client-side media processing module
adamsilverstein Jan 31, 2026
821bd62
Media: Add filter to control client-side media processing
adamsilverstein Jan 31, 2026
8f3f610
Media: Add filter check and update documentation in media module
adamsilverstein Jan 31, 2026
5d2bcb2
Media: Update REST API compat to use filter instead of experiment check
adamsilverstein Jan 31, 2026
af3e87e
Media: Rename window global to __clientSideMediaProcessing
adamsilverstein Jan 31, 2026
0fca462
Media: Update tests for graduated client-side media processing
adamsilverstein Jan 31, 2026
e0e27e9
Media: Add helper function for client-side media processing check
adamsilverstein Jan 31, 2026
00290be
E2E Tests: Increase timeout for image upload assertions
adamsilverstein Feb 5, 2026
4b1bd58
E2E Tests: Update assertions for client-side media processing
adamsilverstein Feb 5, 2026
bb6ce73
Media: Fix E2E tests for client-side media processing
adamsilverstein Feb 5, 2026
a78d07c
Media: Wait for Publish button to be enabled before publishing
adamsilverstein Feb 5, 2026
afe3c77
Rename remaining experimental media processing global
adamsilverstein Feb 15, 2026
c91e362
Update E2E tests for graduated media processing
adamsilverstein Feb 15, 2026
ccfb923
Fix prettier formatting in cross-origin isolation E2E test
adamsilverstein Feb 15, 2026
f0f3ac6
Fix E2E tests for client-side media processing in site editor
adamsilverstein Feb 15, 2026
1b77abe
E2E Tests: Disable client-side media processing for site editor uploa…
adamsilverstein Feb 15, 2026
ce3f49e
Trigger CI re-run
adamsilverstein Feb 16, 2026
7d681ef
Move media processing function to compat dir
adamsilverstein Feb 16, 2026
df5f314
Add PR 75112 to backport changelog
adamsilverstein Feb 18, 2026
d32b712
Remove debug logging functions
adamsilverstein Feb 18, 2026
c187ab7
Rename isExperimentEnabled to isClientSideMediaProcessingEnabled
adamsilverstein Feb 18, 2026
b97cdce
Move __clientSideMediaProcessing global out of experimental
adamsilverstein Feb 18, 2026
cf9be0b
Update new trunk references from experimental to graduated
adamsilverstein Feb 18, 2026
9873558
Disable client-side media processing in meta box test
adamsilverstein Feb 19, 2026
275ddc2
Disable client-side media processing in template E2E tests
adamsilverstein Feb 19, 2026
e0ce3c5
Fix wp_add_inline_script called too early
adamsilverstein Feb 19, 2026
62da54e
Defer COEP filter check and disable media processing in pattern tests
adamsilverstein Feb 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions backport-changelog/7.0/10868.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
https://github.com/WordPress/wordpress-develop/pull/10868

* https://github.com/WordPress/gutenberg/pull/74909
* https://github.com/WordPress/gutenberg/pull/75112
2 changes: 1 addition & 1 deletion lib/compat/wordpress-6.9/rest-api.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ function gutenberg_rest_theme_export_link_rel( $response, $theme ) {
* @return array Modified array of arguments.
*/
function gutenberg_override_attachments_rest_controller( $args, $post_type ) {
if ( 'attachment' === $post_type && ! gutenberg_is_experiment_enabled( 'gutenberg-media-processing' ) ) {
if ( 'attachment' === $post_type && ! gutenberg_is_client_side_media_processing_enabled() ) {
$args['rest_controller_class'] = 'Gutenberg_REST_Attachments_Controller_6_9';
}
return $args;
Expand Down
27 changes: 27 additions & 0 deletions lib/compat/wordpress-7.0/media.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php
/**
* Client-side media processing functions.
*
* @package gutenberg
*/

/**
* Checks whether client-side media processing is enabled.
*
* Client-side media processing uses the browser's capabilities to handle
* tasks like image resizing and compression before uploading to the server.
*
* @since 20.8.0
*
* @return bool Whether client-side media processing is enabled.
*/
function gutenberg_is_client_side_media_processing_enabled() {
/**
* Filters whether client-side media processing is enabled.
*
* @since 20.8.0
*
* @param bool $enabled Whether client-side media processing is enabled. Default true.
*/
return apply_filters( 'wp_client_side_media_processing_enabled', true );
}
3 changes: 0 additions & 3 deletions lib/experimental/editor-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,6 @@ function gutenberg_enable_experiments() {
if ( $gutenberg_experiments && array_key_exists( 'gutenberg-dataviews-media-modal', $gutenberg_experiments ) ) {
wp_add_inline_script( 'wp-block-editor', 'window.__experimentalDataViewsMediaModal = true', 'before' );
}
if ( $gutenberg_experiments && array_key_exists( 'gutenberg-media-processing', $gutenberg_experiments ) ) {
wp_add_inline_script( 'wp-block-editor', 'window.__experimentalMediaProcessing = true', 'before' );
}
if ( $gutenberg_experiments && array_key_exists( 'gutenberg-content-only-inspector-fields', $gutenberg_experiments ) ) {
wp_add_inline_script( 'wp-block-editor', 'window.__experimentalContentOnlyInspectorFields = true', 'before' );
}
Expand Down
12 changes: 0 additions & 12 deletions lib/experiments-page.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,18 +113,6 @@ function gutenberg_initialize_experiments_settings() {
)
);

add_settings_field(
'gutenberg-media-processing',
__( 'Client-side media processing', 'gutenberg' ),
'gutenberg_display_experiment_field',
'gutenberg-experiments',
'gutenberg_experiments_section',
array(
'label' => __( 'Enables client-side media processing to leverage the browser\'s capabilities to handle tasks like image resizing and compression.', 'gutenberg' ),
'id' => 'gutenberg-media-processing',
)
);

add_settings_field(
'gutenberg-color-randomizer',
__( 'Color randomizer', 'gutenberg' ),
Expand Down
5 changes: 2 additions & 3 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/compat/wordpress-7.0/auto-register.php';
require __DIR__ . '/compat/wordpress-7.0/blocks.php';
require __DIR__ . '/compat/wordpress-7.0/kses.php';
require __DIR__ . '/compat/wordpress-7.0/media.php';

// Experimental features.
require __DIR__ . '/experimental/block-editor-settings-mobile.php';
Expand Down Expand Up @@ -189,9 +190,7 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/block-supports/custom-css.php';

// Client-side media processing.
if ( gutenberg_is_experiment_enabled( 'gutenberg-media-processing' ) ) {
require_once __DIR__ . '/experimental/media/load.php';
}
require_once __DIR__ . '/media/load.php';

// Interactivity API full-page client-side navigation.
if ( gutenberg_is_experiment_enabled( 'gutenberg-full-page-client-side-navigation' ) ) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@
/**
* Class Gutenberg_REST_Attachments_Controller.
*
* @package MediaExperiments
* @package gutenberg
*/

/**
* Class Gutenberg_REST_Attachments_Controller.
* REST API controller for media attachments.
*
* Extends the core attachments controller to add client-side media processing
* functionality including sideload support and sub-size generation control.
*/
class Gutenberg_REST_Attachments_Controller extends WP_REST_Attachments_Controller {
/**
Expand Down
27 changes: 24 additions & 3 deletions lib/experimental/media/load.php → lib/media/load.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
<?php
/**
* Adds media-related experimental functionality.
* Adds media-related functionality for client-side media processing.
*
* @package gutenberg
*/

if ( ! gutenberg_is_client_side_media_processing_enabled() ) {
return;
}

/**
* Sets a global JS variable to indicate that client-side media processing is enabled.
*/
function gutenberg_set_client_side_media_processing_flag() {
if ( ! gutenberg_is_client_side_media_processing_enabled() ) {
return;
}
wp_add_inline_script( 'wp-block-editor', 'window.__clientSideMediaProcessing = true', 'before' );
}
add_action( 'admin_init', 'gutenberg_set_client_side_media_processing_flag' );

/**
* Returns a list of all available image sizes.
*
Expand Down Expand Up @@ -195,9 +210,9 @@ function gutenberg_rest_get_attachment_filesize( array $post ): ?int {
* @return string Filtered rewrite rules.
*/
function gutenberg_filter_mod_rewrite_rules( string $rules ): string {
$rules .= "\n# BEGIN Gutenberg client-side media processing experiment\n" .
$rules .= "\n# BEGIN Gutenberg client-side media processing\n" .
"AddType application/wasm wasm\n" .
"# END Gutenberg client-side media processing experiment\n";
"# END Gutenberg client-side media processing\n";

return $rules;
}
Expand All @@ -213,6 +228,12 @@ function gutenberg_filter_mod_rewrite_rules( string $rules ): string {
* @link https://web.dev/coop-coep/
*/
function gutenberg_set_up_cross_origin_isolation() {
// Re-check the filter at action time, since other plugins (loaded after Gutenberg)
// may have added a filter to disable client-side media processing.
if ( ! gutenberg_is_client_side_media_processing_enabled() ) {
return;
}

$screen = get_current_screen();

if ( ! $screen ) {
Expand Down
6 changes: 3 additions & 3 deletions packages/block-editor/src/components/provider/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ let isClientSideMediaEnabledCache = null;
* Checks if client-side media processing should be enabled.
*
* Returns true only if:
* 1. The experimental media processing flag is enabled
* 1. The client-side media processing flag is enabled
* 2. The browser supports WebAssembly, SharedArrayBuffer, cross-origin isolation, and CSP allows blob workers
*
* The result is cached for the session to ensure stability during React renders.
Expand All @@ -54,8 +54,8 @@ function shouldEnableClientSideMediaProcessing() {
return isClientSideMediaEnabledCache;
}

// Check if experimental flag is enabled first.
if ( ! window.__experimentalMediaProcessing ) {
// Check if the client-side media processing flag is enabled first.
if ( ! window.__clientSideMediaProcessing ) {
isClientSideMediaEnabledCache = false;
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/block-library/src/image/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ export function ImageEdit( {

const isSideloading = useSelect(
( select ) => {
if ( ! window.__experimentalMediaProcessing || ! id ) {
if ( ! window.__clientSideMediaProcessing || ! id ) {
return false;
}
return select( uploadStore ).isUploadingById( id );
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php
/**
* Plugin Name: Gutenberg Test Plugin: Disable Client-Side Media Processing
* Plugin URI: https://github.com/WordPress/gutenberg
* Author: Gutenberg Team
*
* @package gutenberg-test-disable-client-side-media-processing
*/

add_filter( 'wp_client_side_media_processing_enabled', '__return_false' );
2 changes: 1 addition & 1 deletion packages/edit-post/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export function initializeEditor(
isPublishSidebarEnabled: true,
} );

if ( window.__experimentalMediaProcessing ) {
if ( window.__clientSideMediaProcessing ) {
dispatch( preferencesStore ).setDefaults( 'core/media', {
requireApproval: true,
optimizeOnUpload: true,
Expand Down
2 changes: 1 addition & 1 deletion packages/edit-site/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export function initializeEditor( id, settings ) {
enableChoosePatternModal: true,
} );

if ( window.__experimentalMediaProcessing ) {
if ( window.__clientSideMediaProcessing ) {
dispatch( preferencesStore ).setDefaults( 'core/media', {
requireApproval: true,
optimizeOnUpload: true,
Expand Down
2 changes: 1 addition & 1 deletion packages/editor/src/components/preferences-modal/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ function PreferencesModalContents( { extraSections = {} } ) {
</>
),
},
window.__experimentalMediaProcessing && {
window.__clientSideMediaProcessing && {
name: 'media',
tabLabel: __( 'Media' ),
content: (
Expand Down
13 changes: 7 additions & 6 deletions packages/editor/src/components/provider/use-upload-save-lock.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,20 @@ const LOCK_NAME = 'upload-in-progress';
* A hook that locks post saving and autosaving while media uploads are in progress.
* This prevents users from publishing or saving while files are still uploading.
*
* Only active when the experimental media processing feature is enabled.
* Only active when client-side media processing is enabled.
*/
export default function useUploadSaveLock() {
const isExperimentEnabled = window.__experimentalMediaProcessing;
const isClientSideMediaProcessingEnabled =
window.__clientSideMediaProcessing;

const isUploading = useSelect(
( select ) => {
if ( ! isExperimentEnabled ) {
if ( ! isClientSideMediaProcessingEnabled ) {
return false;
}
return select( uploadStore ).isUploading();
},
[ isExperimentEnabled ]
[ isClientSideMediaProcessingEnabled ]
);

const {
Expand All @@ -39,7 +40,7 @@ export default function useUploadSaveLock() {
} = useDispatch( editorStore );

useEffect( () => {
if ( ! isExperimentEnabled ) {
if ( ! isClientSideMediaProcessingEnabled ) {
return;
}

Expand All @@ -56,7 +57,7 @@ export default function useUploadSaveLock() {
unlockPostAutosaving( LOCK_NAME );
};
}, [
isExperimentEnabled,
isClientSideMediaProcessingEnabled,
isUploading,
lockPostSaving,
unlockPostSaving,
Expand Down
10 changes: 8 additions & 2 deletions packages/editor/src/utils/media-upload/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,19 @@ export default function mediaUpload( {
? currentPost.id
: currentPost?.wp_id;
const setSaveLock = () => {
if ( window.__clientSideMediaProcessing ) {
return; // Skip - handled by useUploadSaveLock in editor provider
}
lockPostSaving( lockKey );
lockPostAutosaving( lockKey );
imageIsUploading = true;
};

const postData = currentPostId ? { post: currentPostId } : {};
const clearSaveLock = () => {
if ( window.__clientSideMediaProcessing ) {
return; // Skip - handled by useUploadSaveLock in editor provider
}
unlockPostSaving( lockKey );
unlockPostAutosaving( lockKey );
imageIsUploading = false;
Expand All @@ -80,7 +86,7 @@ export default function mediaUpload( {
onFileChange: ( file ) => {
// When client-side media processing is enabled, save locking
// is handled by useUploadSaveLock in the editor provider.
if ( ! window.__experimentalMediaProcessing ) {
if ( ! window.__clientSideMediaProcessing ) {
if ( ! imageIsUploading ) {
setSaveLock();
} else {
Expand Down Expand Up @@ -111,7 +117,7 @@ export default function mediaUpload( {
},
maxUploadFileSize,
onError: ( { message } ) => {
if ( ! window.__experimentalMediaProcessing ) {
if ( ! window.__clientSideMediaProcessing ) {
clearSaveLock();
}
onError( message );
Expand Down
6 changes: 3 additions & 3 deletions packages/media-utils/src/utils/upload-media.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { UploadError } from './upload-error';

declare global {
interface Window {
__experimentalMediaProcessing?: boolean;
__clientSideMediaProcessing?: boolean;
}
}

Expand Down Expand Up @@ -82,7 +82,7 @@ export function uploadMedia( {
const filesSet: Array< Partial< Attachment > | null > = [];
const setAndUpdateFiles = ( index: number, value: Attachment | null ) => {
// For client-side media processing, this is handled by the upload-media package.
if ( ! window.__experimentalMediaProcessing ) {
if ( ! window.__clientSideMediaProcessing ) {
if ( filesSet[ index ]?.url ) {
revokeBlobURL( filesSet[ index ].url );
}
Expand Down Expand Up @@ -123,7 +123,7 @@ export function uploadMedia( {
validFiles.push( mediaFile );

// For client-side media processing, this is handled by the upload-media package.
if ( ! window.__experimentalMediaProcessing ) {
if ( ! window.__clientSideMediaProcessing ) {
// Set temporary URL to create placeholder media file, this is replaced
// with final file from media gallery when upload is `done` below.
filesSet.push( { url: createBlobURL( mediaFile ) } );
Expand Down
1 change: 0 additions & 1 deletion phpunit/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ function fail_if_died( $message ) {
'gutenberg-full-site-editing' => 1,
'gutenberg-form-blocks' => 1,
'gutenberg-block-experiments' => 1,
'gutenberg-media-processing' => 1,
),
);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
<?php
/**
* Tests for Gutenberg_REST_Attachments_Controller.
*
* Tests the REST API controller for media attachments which provides
* client-side media processing functionality including sideload support
* and sub-size generation control.
*/

/**
* @coversDefaultClass \Gutenberg_REST_Attachments_Controller
Expand Down
Loading
Loading