From e7747ce23e8e88a87cf09867027487bd236c0a43 Mon Sep 17 00:00:00 2001 From: Weston Ruter Date: Mon, 25 Sep 2023 21:05:21 +0000 Subject: [PATCH] Script Loader: Use `wp_get_script_tag()` and `wp_get_inline_script_tag()`/`wp_print_inline_script_tag()` helper functions to output scripts on the frontend and login screen. Using script tag helper functions allows plugins to employ the `wp_script_attributes` and `wp_inline_script_attributes` filters to inject the `nonce` attribute to apply Content Security Policy (e.g. Strict CSP). Use of helper functions also simplifies logic in `WP_Scripts`. * Update `wp_get_inline_script_tag()` to wrap inline script in CDATA blocks for XHTML-compatibility when not using HTML5. * Ensure the `type` attribute is printed first in `wp_get_inline_script_tag()` for back-compat. * Wrap existing ` ', '' ), '', ob_get_clean() ) ); } wp_die( $message ); @@ -2083,6 +2085,7 @@ final class WP_Customize_Manager { if ( ! $this->messenger_channel ) { return; } + ob_start(); ?> ', '' ), '', ob_get_clean() ) ); } /** @@ -2201,8 +2205,9 @@ final class WP_Customize_Manager { } } + ob_start(); ?> - ', '' ), '', ob_get_clean() ) ); } /** @@ -4976,8 +4982,9 @@ final class WP_Customize_Manager { } } + ob_start(); ?> - ', '' ), '', ob_get_clean() ) ); } /** diff --git a/wp-includes/class-wp-customize-nav-menus.php b/wp-includes/class-wp-customize-nav-menus.php index bbda8b51b3..20f88f8440 100644 --- a/wp-includes/class-wp-customize-nav-menus.php +++ b/wp-includes/class-wp-customize-nav-menus.php @@ -1559,7 +1559,7 @@ final class WP_Customize_Nav_Menus { $exports = array( 'navMenuInstanceArgs' => $this->preview_nav_menu_instance_args, ); - printf( '', wp_json_encode( $exports ) ); + wp_print_inline_script_tag( sprintf( 'var _wpCustomizePreviewNavMenusExports = %s;', wp_json_encode( $exports ) ) ); } /** diff --git a/wp-includes/class-wp-customize-widgets.php b/wp-includes/class-wp-customize-widgets.php index 93006ef916..c8a00c741f 100644 --- a/wp-includes/class-wp-customize-widgets.php +++ b/wp-includes/class-wp-customize-widgets.php @@ -1310,12 +1310,9 @@ final class WP_Customize_Widgets { foreach ( $settings['registeredWidgets'] as &$registered_widget ) { unset( $registered_widget['callback'] ); // May not be JSON-serializeable. } - - ?> - - type_attr = " type='text/javascript'"; - } - /** * Fires when the WP_Scripts instance is initialized. * @@ -245,20 +226,7 @@ class WP_Scripts extends WP_Dependencies { return $output; } - printf( "\n", $this->type_attr, esc_attr( $handle ) ); - - // CDATA is not needed for HTML 5. - if ( $this->type_attr ) { - echo "/* type_attr ) { - echo "/* ]]> */\n"; - } - - echo "\n"; + wp_print_inline_script_tag( $output, array( 'id' => "{$handle}-js-extra" ) ); return true; } @@ -335,7 +303,7 @@ class WP_Scripts extends WP_Dependencies { $translations = $this->print_translations( $handle, false ); if ( $translations ) { - $translations = sprintf( "\n%s\n\n", $this->type_attr, esc_attr( $handle ), $translations ); + $translations = wp_get_inline_script_tag( $translations, array( 'id' => "{$handle}-js-translations" ) ); } if ( $this->do_concat ) { @@ -403,21 +371,24 @@ class WP_Scripts extends WP_Dependencies { } /** This filter is documented in wp-includes/class-wp-scripts.php */ - $src = esc_url( apply_filters( 'script_loader_src', $src, $handle ) ); + $src = esc_url_raw( apply_filters( 'script_loader_src', $src, $handle ) ); if ( ! $src ) { return true; } - $tag = $translations . $cond_before . $before_script; - $tag .= sprintf( - "\n", - $this->type_attr, - $src, // Value is escaped above. - esc_attr( $handle ), - $strategy ? " {$strategy}" : '', - $intended_strategy ? " data-wp-strategy='{$intended_strategy}'" : '' + $attr = array( + 'src' => $src, + 'id' => "{$handle}-js", ); + if ( $strategy ) { + $attr[ $strategy ] = true; + } + if ( $intended_strategy ) { + $attr['data-wp-strategy'] = $intended_strategy; + } + $tag = $translations . $cond_before . $before_script; + $tag .= wp_get_script_tag( $attr ); $tag .= $after_script . $cond_after; /** @@ -720,7 +691,7 @@ class WP_Scripts extends WP_Dependencies { JS; if ( $display ) { - printf( "\n%s\n\n", $this->type_attr, esc_attr( $handle ), $output ); + wp_print_inline_script_tag( $output, array( 'id' => "{$handle}-js-translations" ) ); } return $output; diff --git a/wp-includes/comment-template.php b/wp-includes/comment-template.php index a80dc60e41..a1005d56e2 100644 --- a/wp-includes/comment-template.php +++ b/wp-includes/comment-template.php @@ -1366,7 +1366,7 @@ function wp_comment_form_unfiltered_html_nonce() { if ( current_user_can( 'unfiltered_html' ) ) { wp_nonce_field( 'unfiltered-html-comment_' . $post_id, '_wp_unfiltered_html_comment_disabled', false ); - echo "\n"; + wp_print_inline_script_tag( "(function(){if(window===window.parent){document.getElementById('_wp_unfiltered_html_comment_disabled').name='_wp_unfiltered_html_comment';}})();" ); } } diff --git a/wp-includes/customize/class-wp-customize-selective-refresh.php b/wp-includes/customize/class-wp-customize-selective-refresh.php index f75baff3e4..d20e8ab0a7 100644 --- a/wp-includes/customize/class-wp-customize-selective-refresh.php +++ b/wp-includes/customize/class-wp-customize-selective-refresh.php @@ -193,7 +193,7 @@ final class WP_Customize_Selective_Refresh { ); // Export data to JS. - printf( '', wp_json_encode( $exports ) ); + wp_print_inline_script_tag( sprintf( 'var _customizePartialRefreshExports = %s;', wp_json_encode( $exports ) ) ); } /** diff --git a/wp-includes/functions.php b/wp-includes/functions.php index ab49f8f405..a86d8eaa27 100644 --- a/wp-includes/functions.php +++ b/wp-includes/functions.php @@ -7655,6 +7655,7 @@ function wp_post_preview_js() { // Has to match the window name used in post_submit_meta_box(). $name = 'wp-preview-' . (int) $post->ID; + ob_start(); ?> ', '' ), '', ob_get_clean() ) ); } /** diff --git a/wp-includes/script-loader.php b/wp-includes/script-loader.php index 041c828bf2..dfc84c7b2f 100644 --- a/wp-includes/script-loader.php +++ b/wp-includes/script-loader.php @@ -2787,7 +2787,11 @@ function wp_sanitize_script_attributes( $attributes ) { */ function wp_get_script_tag( $attributes ) { if ( ! isset( $attributes['type'] ) && ! is_admin() && ! current_theme_supports( 'html5', 'script' ) ) { - $attributes['type'] = 'text/javascript'; + // Keep the type attribute as the first for legacy reasons (it has always been this way in core). + $attributes = array_merge( + array( 'type' => 'text/javascript' ), + $attributes + ); } /** * Filters attributes to be added to a script tag. @@ -2830,9 +2834,23 @@ function wp_print_script_tag( $attributes ) { * @return string String containing inline JavaScript code wrapped around `\n", wp_sanitize_script_attributes( $attributes ), $javascript ); } diff --git a/wp-includes/theme-templates.php b/wp-includes/theme-templates.php index 3604dc6dbe..8f0ee9a69f 100644 --- a/wp-includes/theme-templates.php +++ b/wp-includes/theme-templates.php @@ -160,8 +160,9 @@ function the_block_template_skip_link() { wp_enqueue_style( $handle ); /** - * Print the skip-link script. + * Enqueue the skip-link script. */ + ob_start(); ?> ', '' ), '', ob_get_clean() ); + $script_handle = 'wp-block-template-skip-link'; + wp_register_script( $script_handle, false ); + wp_add_inline_script( $script_handle, $skip_link_script ); + wp_enqueue_script( $script_handle ); } /** diff --git a/wp-includes/theme.php b/wp-includes/theme.php index 6be2ad700a..ba88a83fde 100644 --- a/wp-includes/theme.php +++ b/wp-includes/theme.php @@ -3783,9 +3783,9 @@ function wp_customize_support_script() { $admin_origin = parse_url( admin_url() ); $home_origin = parse_url( home_url() ); $cross_domain = ( strtolower( $admin_origin['host'] ) !== strtolower( $home_origin['host'] ) ); - $type_attr = current_theme_supports( 'html5', 'script' ) ? '' : ' type="text/javascript"'; + ob_start(); ?> - > + ', '' ), '', ob_get_clean() ) ); } /** diff --git a/wp-includes/version.php b/wp-includes/version.php index f92cfe3d11..e822d59489 100644 --- a/wp-includes/version.php +++ b/wp-includes/version.php @@ -16,7 +16,7 @@ * * @global string $wp_version */ -$wp_version = '6.4-alpha-56686'; +$wp_version = '6.4-alpha-56687'; /** * Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema. diff --git a/wp-includes/widgets/class-wp-widget-archives.php b/wp-includes/widgets/class-wp-widget-archives.php index f32aa9bbb0..21d3a7b672 100644 --- a/wp-includes/widgets/class-wp-widget-archives.php +++ b/wp-includes/widgets/class-wp-widget-archives.php @@ -100,8 +100,6 @@ class WP_Widget_Archives extends WP_Widget { $label = __( 'Select Post' ); break; } - - $type_attr = current_theme_supports( 'html5', 'script' ) ? '' : ' type="text/javascript"'; ?> @@ -109,8 +107,8 @@ class WP_Widget_Archives extends WP_Widget { -> -/* + ', '' ), '', ob_get_clean() ) ); } else { $format = current_theme_supports( 'html5', 'navigation-widgets' ) ? 'html5' : 'xhtml'; diff --git a/wp-includes/widgets/class-wp-widget-categories.php b/wp-includes/widgets/class-wp-widget-categories.php index 3c009709ba..e00ce7f960 100644 --- a/wp-includes/widgets/class-wp-widget-categories.php +++ b/wp-includes/widgets/class-wp-widget-categories.php @@ -92,11 +92,10 @@ class WP_Widget_Categories extends WP_Widget { echo ''; - $type_attr = current_theme_supports( 'html5', 'script' ) ? '' : ' type="text/javascript"'; + ob_start(); ?> -> -/* (function() { var dropdown = document.getElementById( "" ); function onCatChange() { @@ -106,10 +105,10 @@ class WP_Widget_Categories extends WP_Widget { } dropdown.onchange = onCatChange; })(); -/* ]]> */ ', '' ), '', ob_get_clean() ) ); } else { $format = current_theme_supports( 'html5', 'navigation-widgets' ) ? 'html5' : 'xhtml'; diff --git a/wp-login.php b/wp-login.php index 60877bdb70..80887f0420 100644 --- a/wp-login.php +++ b/wp-login.php @@ -101,9 +101,11 @@ function login_header( $title = 'Log In', $message = '', $wp_error = null ) { * but maybe better if it's not removable by plugins. */ if ( 'loggedout' === $wp_error->get_error_code() ) { + ob_start(); ?> ', '' ), '', ob_get_clean() ) ); } /** @@ -193,9 +195,10 @@ function login_header( $title = 'Log In', $message = '', $wp_error = null ) { ?> - + + - ', '' ), '', ob_get_clean() ) ); } /** @@ -441,11 +446,7 @@ function login_footer( $input_id = '' ) { * @since 3.0.0 */ function wp_shake_js() { - ?> - - - + ', '' ), '', ob_get_clean() ) ); } ?> @@ -1605,15 +1608,12 @@ switch ( $action ) { // Run `wpOnload()` if defined. $login_script .= "if ( typeof wpOnload === 'function' ) { wpOnload() }"; - ?> - - - ', '' ), '', ob_get_clean() ) ); } login_footer();