From 9ea1125557ec2a66827d48e94e7d36e1acea29fc Mon Sep 17 00:00:00 2001 From: adamsilverstein Date: Thu, 16 Jul 2026 09:24:36 -0700 Subject: [PATCH 1/2] Media: Set HEIC upload support flag for canvas-based conversion. The block editor's HEIC canvas fallback is gated on window.__heicUploadSupport, which core never set. Without it, browsers that cannot use the full WebAssembly pipeline (such as Safari, which lacks Document-Isolation-Policy support) get no client-side HEIC conversion at all, even though they can decode HEIC natively via createImageBitmap(). Set the flag in wp_set_client_side_media_processing_flag() alongside the existing client-side media processing flags so Safari users get HEIC uploads converted to JPEG in the browser. --- src/wp-includes/media.php | 8 ++ .../wpSetClientSideMediaProcessingFlag.php | 123 ++++++++++++++++++ 2 files changed, 131 insertions(+) create mode 100644 tests/phpunit/tests/media/wpSetClientSideMediaProcessingFlag.php diff --git a/src/wp-includes/media.php b/src/wp-includes/media.php index e5b4276e46af5..da64b70e6b2d9 100644 --- a/src/wp-includes/media.php +++ b/src/wp-includes/media.php @@ -6603,6 +6603,14 @@ function wp_set_client_side_media_processing_flag(): void { wp_add_inline_script( 'wp-block-editor', 'window.__clientSideMediaProcessing = true;', 'before' ); + /* + * Indicates that HEIC canvas-based upload support is available. Unlike the + * full WebAssembly pipeline, this fallback does not require cross-origin + * isolation, so browsers such as Safari can use createImageBitmap() to + * decode HEIC images and convert them to JPEG before uploading. + */ + wp_add_inline_script( 'wp-block-editor', 'window.__heicUploadSupport = true;', 'before' ); + $chromium_version = wp_get_chromium_major_version(); if ( null !== $chromium_version && $chromium_version >= 137 ) { diff --git a/tests/phpunit/tests/media/wpSetClientSideMediaProcessingFlag.php b/tests/phpunit/tests/media/wpSetClientSideMediaProcessingFlag.php new file mode 100644 index 0000000000000..0dd1b496f1dae --- /dev/null +++ b/tests/phpunit/tests/media/wpSetClientSideMediaProcessingFlag.php @@ -0,0 +1,123 @@ +original_user_agent = $_SERVER['HTTP_USER_AGENT'] ?? null; + $this->original_http_host = $_SERVER['HTTP_HOST'] ?? null; + $this->original_https = $_SERVER['HTTPS'] ?? null; + + // Ensure client-side media processing is considered enabled. + $_SERVER['HTTP_HOST'] = 'localhost'; + + $GLOBALS['wp_scripts'] = new WP_Scripts(); + } + + public function tear_down() { + if ( null === $this->original_user_agent ) { + unset( $_SERVER['HTTP_USER_AGENT'] ); + } else { + $_SERVER['HTTP_USER_AGENT'] = $this->original_user_agent; + } + + if ( null === $this->original_http_host ) { + unset( $_SERVER['HTTP_HOST'] ); + } else { + $_SERVER['HTTP_HOST'] = $this->original_http_host; + } + + if ( null === $this->original_https ) { + unset( $_SERVER['HTTPS'] ); + } else { + $_SERVER['HTTPS'] = $this->original_https; + } + + unset( $GLOBALS['wp_scripts'] ); + + parent::tear_down(); + } + + /** + * Returns the inline scripts added before the 'wp-block-editor' script. + * + * @return string Concatenated inline scripts, or an empty string if none. + */ + private function get_block_editor_before_scripts(): string { + $before = wp_scripts()->get_data( 'wp-block-editor', 'before' ); + + if ( ! is_array( $before ) ) { + return ''; + } + + return implode( "\n", array_filter( $before ) ); + } + + /** + * @ticket 64906 + */ + public function test_sets_heic_upload_support_flag_for_non_chromium_browsers() { + // Safari 26 on macOS. + $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Safari/605.1.15'; + + wp_set_client_side_media_processing_flag(); + + $before = $this->get_block_editor_before_scripts(); + + $this->assertStringContainsString( 'window.__clientSideMediaProcessing = true;', $before, 'The client-side media processing flag should be set.' ); + $this->assertStringContainsString( 'window.__heicUploadSupport = true;', $before, 'The HEIC upload support flag should be set for non-Chromium browsers.' ); + $this->assertStringNotContainsString( 'window.__documentIsolationPolicy', $before, 'The Document-Isolation-Policy flag should not be set for non-Chromium browsers.' ); + } + + /** + * @ticket 64906 + */ + public function test_sets_heic_upload_support_flag_for_chromium_browsers() { + $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36'; + + wp_set_client_side_media_processing_flag(); + + $before = $this->get_block_editor_before_scripts(); + + $this->assertStringContainsString( 'window.__clientSideMediaProcessing = true;', $before, 'The client-side media processing flag should be set.' ); + $this->assertStringContainsString( 'window.__heicUploadSupport = true;', $before, 'The HEIC upload support flag should be set for Chromium browsers.' ); + $this->assertStringContainsString( 'window.__documentIsolationPolicy = true;', $before, 'The Document-Isolation-Policy flag should be set for Chromium 137+.' ); + } + + /** + * @ticket 64906 + */ + public function test_does_not_set_flags_when_client_side_media_processing_is_disabled() { + $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Safari/605.1.15'; + + add_filter( 'wp_client_side_media_processing_enabled', '__return_false' ); + + wp_set_client_side_media_processing_flag(); + + $before = $this->get_block_editor_before_scripts(); + + $this->assertStringNotContainsString( 'window.__clientSideMediaProcessing', $before, 'The client-side media processing flag should not be set when the feature is disabled.' ); + $this->assertStringNotContainsString( 'window.__heicUploadSupport', $before, 'The HEIC upload support flag should not be set when the feature is disabled.' ); + } +} From 8e481d08d155dda954cd91d8101b6479b9a70efa Mon Sep 17 00:00:00 2001 From: adamsilverstein Date: Thu, 16 Jul 2026 09:32:16 -0700 Subject: [PATCH 2/2] Update ticket annotations to point to Trac ticket 65648 --- .../tests/media/wpSetClientSideMediaProcessingFlag.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/phpunit/tests/media/wpSetClientSideMediaProcessingFlag.php b/tests/phpunit/tests/media/wpSetClientSideMediaProcessingFlag.php index 0dd1b496f1dae..759a5b1d7a2e0 100644 --- a/tests/phpunit/tests/media/wpSetClientSideMediaProcessingFlag.php +++ b/tests/phpunit/tests/media/wpSetClientSideMediaProcessingFlag.php @@ -75,7 +75,7 @@ private function get_block_editor_before_scripts(): string { } /** - * @ticket 64906 + * @ticket 65648 */ public function test_sets_heic_upload_support_flag_for_non_chromium_browsers() { // Safari 26 on macOS. @@ -91,7 +91,7 @@ public function test_sets_heic_upload_support_flag_for_non_chromium_browsers() { } /** - * @ticket 64906 + * @ticket 65648 */ public function test_sets_heic_upload_support_flag_for_chromium_browsers() { $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36'; @@ -106,7 +106,7 @@ public function test_sets_heic_upload_support_flag_for_chromium_browsers() { } /** - * @ticket 64906 + * @ticket 65648 */ public function test_does_not_set_flags_when_client_side_media_processing_is_disabled() { $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/26.0 Safari/605.1.15';