diff --git a/backport-changelog/7.0/10868.md b/backport-changelog/7.0/10868.md
index 9045022e44e641..5eab0bfe57231b 100644
--- a/backport-changelog/7.0/10868.md
+++ b/backport-changelog/7.0/10868.md
@@ -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
diff --git a/lib/compat/wordpress-6.9/rest-api.php b/lib/compat/wordpress-6.9/rest-api.php
index 994d3fb000b721..f206371fc14bd7 100644
--- a/lib/compat/wordpress-6.9/rest-api.php
+++ b/lib/compat/wordpress-6.9/rest-api.php
@@ -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;
diff --git a/lib/compat/wordpress-7.0/media.php b/lib/compat/wordpress-7.0/media.php
new file mode 100644
index 00000000000000..cbd5d70598e71b
--- /dev/null
+++ b/lib/compat/wordpress-7.0/media.php
@@ -0,0 +1,27 @@
+ __( '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' ),
diff --git a/lib/load.php b/lib/load.php
index 36da6f88e32f81..5b0674274a2063 100644
--- a/lib/load.php
+++ b/lib/load.php
@@ -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';
@@ -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' ) ) {
diff --git a/lib/experimental/media/class-gutenberg-rest-attachments-controller.php b/lib/media/class-gutenberg-rest-attachments-controller.php
similarity index 98%
rename from lib/experimental/media/class-gutenberg-rest-attachments-controller.php
rename to lib/media/class-gutenberg-rest-attachments-controller.php
index 3eb40bcf8dd16c..60b2930bec9b6e 100644
--- a/lib/experimental/media/class-gutenberg-rest-attachments-controller.php
+++ b/lib/media/class-gutenberg-rest-attachments-controller.php
@@ -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 {
/**
diff --git a/lib/experimental/media/docs/client-side-media-docs.md b/lib/media/docs/client-side-media-docs.md
similarity index 100%
rename from lib/experimental/media/docs/client-side-media-docs.md
rename to lib/media/docs/client-side-media-docs.md
diff --git a/lib/experimental/media/load.php b/lib/media/load.php
similarity index 91%
rename from lib/experimental/media/load.php
rename to lib/media/load.php
index 5e7b00173ca616..6d2cf05561d821 100644
--- a/lib/experimental/media/load.php
+++ b/lib/media/load.php
@@ -1,10 +1,25 @@
{
- if ( ! window.__experimentalMediaProcessing || ! id ) {
+ if ( ! window.__clientSideMediaProcessing || ! id ) {
return false;
}
return select( uploadStore ).isUploadingById( id );
diff --git a/packages/e2e-tests/plugins/disable-client-side-media-processing.php b/packages/e2e-tests/plugins/disable-client-side-media-processing.php
new file mode 100644
index 00000000000000..bb81e54f7cc1bc
--- /dev/null
+++ b/packages/e2e-tests/plugins/disable-client-side-media-processing.php
@@ -0,0 +1,10 @@
+
),
},
- window.__experimentalMediaProcessing && {
+ window.__clientSideMediaProcessing && {
name: 'media',
tabLabel: __( 'Media' ),
content: (
diff --git a/packages/editor/src/components/provider/use-upload-save-lock.js b/packages/editor/src/components/provider/use-upload-save-lock.js
index c4acc9cc315dfc..8c0473e061774f 100644
--- a/packages/editor/src/components/provider/use-upload-save-lock.js
+++ b/packages/editor/src/components/provider/use-upload-save-lock.js
@@ -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 {
@@ -39,7 +40,7 @@ export default function useUploadSaveLock() {
} = useDispatch( editorStore );
useEffect( () => {
- if ( ! isExperimentEnabled ) {
+ if ( ! isClientSideMediaProcessingEnabled ) {
return;
}
@@ -56,7 +57,7 @@ export default function useUploadSaveLock() {
unlockPostAutosaving( LOCK_NAME );
};
}, [
- isExperimentEnabled,
+ isClientSideMediaProcessingEnabled,
isUploading,
lockPostSaving,
unlockPostSaving,
diff --git a/packages/editor/src/utils/media-upload/index.js b/packages/editor/src/utils/media-upload/index.js
index 26fbbf3bf128c8..2a3d4ca46f440f 100644
--- a/packages/editor/src/utils/media-upload/index.js
+++ b/packages/editor/src/utils/media-upload/index.js
@@ -62,6 +62,9 @@ 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;
@@ -69,6 +72,9 @@ export default function mediaUpload( {
const postData = currentPostId ? { post: currentPostId } : {};
const clearSaveLock = () => {
+ if ( window.__clientSideMediaProcessing ) {
+ return; // Skip - handled by useUploadSaveLock in editor provider
+ }
unlockPostSaving( lockKey );
unlockPostAutosaving( lockKey );
imageIsUploading = false;
@@ -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 {
@@ -111,7 +117,7 @@ export default function mediaUpload( {
},
maxUploadFileSize,
onError: ( { message } ) => {
- if ( ! window.__experimentalMediaProcessing ) {
+ if ( ! window.__clientSideMediaProcessing ) {
clearSaveLock();
}
onError( message );
diff --git a/packages/media-utils/src/utils/upload-media.ts b/packages/media-utils/src/utils/upload-media.ts
index 3b49e317ffb9e4..278b5c4ababf7a 100644
--- a/packages/media-utils/src/utils/upload-media.ts
+++ b/packages/media-utils/src/utils/upload-media.ts
@@ -21,7 +21,7 @@ import { UploadError } from './upload-error';
declare global {
interface Window {
- __experimentalMediaProcessing?: boolean;
+ __clientSideMediaProcessing?: boolean;
}
}
@@ -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 );
}
@@ -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 ) } );
diff --git a/phpunit/bootstrap.php b/phpunit/bootstrap.php
index bdde8917ac192a..19667b25979b8e 100644
--- a/phpunit/bootstrap.php
+++ b/phpunit/bootstrap.php
@@ -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,
),
);
diff --git a/phpunit/experimental/media/class-gutenberg-rest-attachments-controller-test.php b/phpunit/media/class-gutenberg-rest-attachments-controller-test.php
similarity index 99%
rename from phpunit/experimental/media/class-gutenberg-rest-attachments-controller-test.php
rename to phpunit/media/class-gutenberg-rest-attachments-controller-test.php
index 6b4edf44454347..31f2b51c6eb350 100644
--- a/phpunit/experimental/media/class-gutenberg-rest-attachments-controller-test.php
+++ b/phpunit/media/class-gutenberg-rest-attachments-controller-test.php
@@ -1,4 +1,11 @@
assertStringContainsString( '
assertStringContainsString( '