PluginProbe
Gutenberg / 24.0.0
Gutenberg v24.0.0
24.0.0 23.9.1 23.9.0 23.8.0 23.7.2 23.7.1 23.7.0 23.6.1 23.6.2 23.6.0 23.5.3 23.5.2 23.5.1 23.5.0 23.4.0 23.3.2 23.3.1 23.3.0 23.2.0 23.2.1 23.2.2 23.1.1 23.1.0 23.0.1 12.6.0 All 403 releases
← All changes | lib/media/load.php +51 -13 23.6.0 → 24.0.0 View file →
@@ -462,12 +462,60 @@
462 462 return $processor->get_updated_html();
463 463 }
464 464
465 465 /**
466 + * Updates `crossorigin` attributes in the printed media templates.
467 + *
468 + * Adds `crossorigin="anonymous"` to AUDIO and VIDEO tags inside the
469 + * Backbone `<script type="text/html">` templates so the media modal can
470 + * play cross-origin audio and video under cross-origin isolation. Tags
471 + * that already have the attribute are left untouched so the output does
472 + * not gain duplicates on WordPress versions where Core adds it itself.
473 + *
474 + * IMG is intentionally excluded: under
475 + * `Document-Isolation-Policy: isolate-and-credentialless` the browser
476 + * already loads cross-origin images in credentialless mode, so forcing
477 + * `crossorigin="anonymous"` triggers a CORS request that breaks previews
478 + * of images served without CORS headers, such as media offloaded to a
479 + * CDN. See https://core.trac.wordpress.org/ticket/65673.
480 + *
481 + * @param string $html The printed media templates.
482 + *
483 + * @return string Modified media templates.
484 + */
485 +function gutenberg_update_media_template_crossorigin_attributes( string $html ): string {
486 + /*
487 + * The media templates are inside <script type="text/html"> tags,
488 + * whose content is treated as raw text by the HTML Tag Processor.
489 + * Extract each script block's content, process it separately,
490 + * then reassemble the full output.
491 + */
492 + $script_processor = new WP_HTML_Tag_Processor( $html );
493 + while ( $script_processor->next_tag( 'SCRIPT' ) ) {
494 + if ( 'text/html' !== $script_processor->get_attribute( 'type' ) ) {
495 + continue;
496 + }
497 + $template_processor = new WP_HTML_Tag_Processor( $script_processor->get_modifiable_text() );
498 + while ( $template_processor->next_tag() ) {
499 + if (
500 + in_array( $template_processor->get_tag(), array( 'AUDIO', 'VIDEO' ), true )
501 + && ! is_string( $template_processor->get_attribute( 'crossorigin' ) )
502 + ) {
503 + $template_processor->set_attribute( 'crossorigin', 'anonymous' );
504 + }
505 + }
506 + $script_processor->set_modifiable_text( $template_processor->get_updated_html() );
507 + }
508 +
509 + return $script_processor->get_updated_html();
510 +}
511 +
512 +/**
466 513 * Overrides templates from wp_print_media_templates with custom ones.
467 514 *
468 - * Adds `crossorigin` attribute to all tags that
469 - * could have assets loaded from a different domain.
515 + * Updates the `crossorigin` attributes on media tags so cross-origin
516 + * audio and video can be processed under cross-origin isolation without
517 + * breaking previews of images served without CORS headers.
470 518 */
471 519 function gutenberg_override_media_templates(): void {
472 520 remove_action( 'admin_footer', 'wp_print_media_templates' );
473 521 add_action(
@@ -476,19 +524,9 @@
476 524 ob_start();
477 525 wp_print_media_templates();
478 526 $html = (string) ob_get_clean();
479 527
480 - $tags = array(
481 - 'audio',
482 - 'img',
483 - 'video',
484 - );
485 -
486 - foreach ( $tags as $tag ) {
487 - $html = (string) str_replace( "<$tag", "<$tag crossorigin=\"anonymous\"", $html );
488 - }
489 -
490 - echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
528 + echo gutenberg_update_media_template_crossorigin_attributes( $html ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
491 529 }
492 530 );
493 531 }
494 532