Make WordPress Core


Ignore:
Timestamp:
09/25/2023 09:03:19 PM (15 months ago)
Author:
westonruter
Message:

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 <script> tags in output buffering to retain IDE supports.
  • In wp_get_inline_script_tag(), append the newline to $javascript before it is passed into the wp_inline_script_attributes filter so that the CSP hash can be computed properly.
  • In the_block_template_skip_link(), opt to enqueue the inline script rather than print it.
  • Add ext-php to composer.json under suggest as previously it was an undeclared dependency for running PHPUnit tests.
  • Update tests to rely on DOMDocument to compare script markup, normalizing unsemantic differences.

Props westonruter, spacedmonkey, flixos90, 10upsimon, dmsnell, mukesh27, joemcgill, swissspidy, azaozz.
Fixes #58664.
See #39941.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/class-wp-scripts.php

    r56273 r56687  
    124124
    125125    /**
    126      * Holds a string which contains the type attribute for script tag.
    127      *
    128      * If the active theme does not declare HTML5 support for 'script',
    129      * then it initializes as `type='text/javascript'`.
    130      *
    131      * @since 5.3.0
    132      * @var string
    133      */
    134     private $type_attr = '';
    135 
    136     /**
    137126     * Holds a mapping of dependents (as handles) for a given script handle.
    138127     * Used to optimize recursive dependency tree checks.
     
    168157     */
    169158    public function init() {
    170         if (
    171             function_exists( 'is_admin' ) && ! is_admin()
    172         &&
    173             function_exists( 'current_theme_supports' ) && ! current_theme_supports( 'html5', 'script' )
    174         ) {
    175             $this->type_attr = " type='text/javascript'";
    176         }
    177 
    178159        /**
    179160         * Fires when the WP_Scripts instance is initialized.
     
    246227        }
    247228
    248         printf( "<script%s id='%s-js-extra'>\n", $this->type_attr, esc_attr( $handle ) );
    249 
    250         // CDATA is not needed for HTML 5.
    251         if ( $this->type_attr ) {
    252             echo "/* <![CDATA[ */\n";
    253         }
    254 
    255         echo "$output\n";
    256 
    257         if ( $this->type_attr ) {
    258             echo "/* ]]> */\n";
    259         }
    260 
    261         echo "</script>\n";
     229        wp_print_inline_script_tag( $output, array( 'id' => "{$handle}-js-extra" ) );
    262230
    263231        return true;
     
    336304        $translations = $this->print_translations( $handle, false );
    337305        if ( $translations ) {
    338             $translations = sprintf( "<script%s id='%s-js-translations'>\n%s\n</script>\n", $this->type_attr, esc_attr( $handle ), $translations );
     306            $translations = wp_get_inline_script_tag( $translations, array( 'id' => "{$handle}-js-translations" ) );
    339307        }
    340308
     
    404372
    405373        /** This filter is documented in wp-includes/class-wp-scripts.php */
    406         $src = esc_url( apply_filters( 'script_loader_src', $src, $handle ) );
     374        $src = esc_url_raw( apply_filters( 'script_loader_src', $src, $handle ) );
    407375
    408376        if ( ! $src ) {
     
    410378        }
    411379
     380        $attr = array(
     381            'src' => $src,
     382            'id'  => "{$handle}-js",
     383        );
     384        if ( $strategy ) {
     385            $attr[ $strategy ] = true;
     386        }
     387        if ( $intended_strategy ) {
     388            $attr['data-wp-strategy'] = $intended_strategy;
     389        }
    412390        $tag  = $translations . $cond_before . $before_script;
    413         $tag .= sprintf(
    414             "<script%s src='%s' id='%s-js'%s%s></script>\n",
    415             $this->type_attr,
    416             $src, // Value is escaped above.
    417             esc_attr( $handle ),
    418             $strategy ? " {$strategy}" : '',
    419             $intended_strategy ? " data-wp-strategy='{$intended_strategy}'" : ''
    420         );
     391        $tag .= wp_get_script_tag( $attr );
    421392        $tag .= $after_script . $cond_after;
    422393
     
    721692
    722693        if ( $display ) {
    723             printf( "<script%s id='%s-js-translations'>\n%s\n</script>\n", $this->type_attr, esc_attr( $handle ), $output );
     694            wp_print_inline_script_tag( $output, array( 'id' => "{$handle}-js-translations" ) );
    724695        }
    725696
Note: See TracChangeset for help on using the changeset viewer.