Make WordPress Core

Ticket #39941: 39941.2.diff

File 39941.2.diff, 13.4 KB (added by adamsilverstein, 5 years ago)
  • src/wp-includes/functions.php

    diff --git src/wp-includes/functions.php src/wp-includes/functions.php
    index 536f195b14..a6c63681f8 100644
    function is_php_version_compatible( $required ) { 
    77817781function wp_fuzzy_number_match( $expected, $actual, $precision = 1 ) {
    77827782        return abs( (float) $expected - (float) $actual ) <= $precision;
    77837783}
     7784
     7785/**
     7786 * Sanitizes an attributes array into an attributes string to be placed inside a `<script>` tag.
     7787 *
     7788 * Automatically injects type attribute if needed.
     7789 * Used by {@see wp_get_script_tag()} and {@see wp_get_inline_script_tag()}.
     7790 *
     7791 * @since 5.6.0
     7792 *
     7793 * @param array $attributes Key-value pairs representing `<script>` tag attributes.
     7794 * @return string String made of sanitized `<script>` tag attributes.
     7795 */
     7796function wp_sanitize_script_attributes( $attributes ) {
     7797        $html5_script_support = ! is_admin() && ! current_theme_supports( 'html5', 'script' );
     7798        $attributes_string    = '';
     7799
     7800        // If HTML5 scirpt tag is supported, only the attribute name is added
     7801        // to $attributes_string for entries with a boolean value, and that are true.
     7802        foreach ( $attributes as $attribute_name => $attribute_value ) {
     7803                if ( is_bool( $attribute_value ) ) {
     7804                        if ( $attribute_value ) {
     7805                                $attributes_string .= $html5_script_support ? sprintf( ' %1$s="%2$s"', $attribute_name, esc_attr( $attribute_name ) ) : ' ' . $attribute_name;
     7806                        }
     7807                } else {
     7808                        $attributes_string .= sprintf( ' %1$s="%2$s"', $attribute_name, esc_attr( $attribute_value ) );
     7809                }
     7810        }
     7811
     7812        return $attributes_string;
     7813}
     7814
     7815/**
     7816 * Formats `<script>` loader tags.
     7817 *
     7818 * It is possible to inject attributes in the `<script>` tag via the {@see 'wp_script_attributes'} filter.
     7819 * Automatically injects type attribute if needed.
     7820 *
     7821 * @since 5.6.0
     7822 *
     7823 * @param array $attributes Key-value pairs representing `<script>` tag attributes.
     7824 * @return string String containing `<script>` opening and closing tags.
     7825 */
     7826function wp_get_script_tag( $attributes ) {
     7827        if ( ! isset( $attributes['type'] ) && ! is_admin() && ! current_theme_supports( 'html5', 'script' ) ) {
     7828                $attributes['type'] = 'text/javascript';
     7829        }
     7830        /**
     7831         * Filters attributes to be added to a script tag.
     7832         *
     7833         * @since 5.6.0
     7834         *
     7835         * @param array $attributes Key-value pairs representing `<script>` tag attributes.
     7836         *                          Only the attribute name is added to the `<script>` tag for
     7837         *                          entries with a boolean value, and that are true.
     7838         */
     7839        $attributes = apply_filters( 'wp_script_attributes', $attributes );
     7840
     7841        return sprintf( "<script%s></script>\n", wp_sanitize_script_attributes( $attributes ) );
     7842}
     7843
     7844/**
     7845 * Prints formatted `<script>` loader tag.
     7846 *
     7847 * It is possible to inject attributes in the `<script>` tag via the  {@see 'wp_script_attributes'}  filter.
     7848 * Automatically injects type attribute if needed.
     7849 *
     7850 * @since 5.6.0
     7851 *
     7852 * @param array $attributes Key-value pairs representing `<script>` tag attributes.
     7853 */
     7854function wp_print_script_tag( $attributes ) {
     7855        echo wp_get_script_tag( $attributes );
     7856}
     7857
     7858/**
     7859 * Wraps inline JavaScript in `<script>` tag.
     7860 *
     7861 * It is possible to inject attributes in the `<script>` tag via the  {@see 'wp_script_attributes'}  filter.
     7862 * Automatically injects type attribute if needed.
     7863 *
     7864 * @since 5.6.0
     7865 *
     7866 * @param string $javascript Inline JavaScript code.
     7867 * @param array  $attributes Optional. Key-value pairs representing `<script>` tag attributes.
     7868 * @return string String containing inline JavaScript code wrapped around `<script>` tag.
     7869 */
     7870function wp_get_inline_script_tag( $javascript, $attributes = array() ) {
     7871        if ( ! isset( $attributes['type'] ) && ! is_admin() && ! current_theme_supports( 'html5', 'script' ) ) {
     7872                $attributes['type'] = 'text/javascript';
     7873        }
     7874        /**
     7875         * Filters attributes to be added to a script tag.
     7876         *
     7877         * @since 5.6.0
     7878         *
     7879         * @param array $attributes Key-value pairs representing `<script>` tag attributes.
     7880         *                          Only the attribute name is added to the `<script>` tag for
     7881         *                          entries with a boolean value, and that are true.
     7882         */
     7883        $attributes = apply_filters( 'wp_script_attributes', $attributes );
     7884
     7885        $javascript = "\n" . trim( $javascript, "\n\r " ) . "\n";
     7886
     7887        return sprintf( "<script%s>%s</script>\n", wp_sanitize_script_attributes( $attributes ), $javascript );
     7888}
     7889
     7890/**
     7891 * Prints inline JavaScript wrapped in `<script>` tag.
     7892 *
     7893 * It is possible to inject attributes in the `<script>` tag via the  {@see 'wp_script_attributes'}  filter.
     7894 * Automatically injects type attribute if needed.
     7895 *
     7896 * @since 5.6.0
     7897 *
     7898 * @param string $javascript Inline JavaScript code.
     7899 * @param array  $attributes Optional. Key-value pairs representing `<script>` tag attributes.
     7900 */
     7901function wp_print_inline_script_tag( $javascript, $attributes = array() ) {
     7902        echo wp_get_inline_script_tag( $javascript, $attributes );
     7903}
  • new file tests/phpunit/tests/functions/wpInlineScriptTag.php

    diff --git tests/phpunit/tests/functions/wpInlineScriptTag.php tests/phpunit/tests/functions/wpInlineScriptTag.php
    new file mode 100644
    index 0000000000..3cfd9d1af0
    - +  
     1<?php
     2
     3/**
     4 * Test wp_get_inline_script_tag() and wp_print_inline_script_tag().
     5 *
     6 * @group functions.php
     7 */
     8class Tests_Functions_wpInlineScriptTag extends WP_UnitTestCase {
     9
     10        private $event_handler = <<<'JS'
     11document.addEventListener( 'DOMContentLoaded', function () {
     12        document.getElementById( 'elementID' )
     13                        .addEventListener( 'click', function( event ) {
     14                                event.preventDefault();
     15                        });
     16});
     17JS;
     18
     19        function get_inline_script_tag_type_set() {
     20                add_theme_support( 'html5', array( 'script' ) );
     21
     22                $this->assertSame(
     23                        '<script type="application/javascript" nomodule>' . "\n{$this->event_handler}\n</script>\n",
     24                        wp_get_inline_script_tag(
     25                                $this->event_handler,
     26                                array(
     27                                        'type'     => 'application/javascript',
     28                                        'async'    => false,
     29                                        'nomodule' => true,
     30                                )
     31                        )
     32                );
     33
     34                remove_theme_support( 'html5' );
     35
     36                $this->assertSame(
     37                        '<script type="application/javascript" nomodule>' . "\n{$this->event_handler}\n</script>\n",
     38                        wp_get_inline_script_tag(
     39                                $this->event_handler,
     40                                array(
     41                                        'type'     => 'application/javascript',
     42                                        'async'    => false,
     43                                        'nomodule' => true,
     44                                )
     45                        )
     46                );
     47        }
     48
     49        function test_get_inline_script_tag_type_not_set() {
     50                add_theme_support( 'html5', array( 'script' ) );
     51
     52                $this->assertSame(
     53                        "<script nomodule>\n{$this->event_handler}\n</script>\n",
     54                        wp_get_inline_script_tag(
     55                                $this->event_handler,
     56                                array(
     57                                        'async'    => false,
     58                                        'nomodule' => true,
     59                                )
     60                        )
     61                );
     62
     63                remove_theme_support( 'html5' );
     64        }
     65
     66        function test_get_inline_script_tag_unescaped_src() {
     67                add_theme_support( 'html5', array( 'script' ) );
     68
     69                $this->assertSame(
     70                        "<script>\n{$this->event_handler}\n</script>\n",
     71                        wp_get_inline_script_tag( $this->event_handler )
     72                );
     73
     74                remove_theme_support( 'html5' );
     75        }
     76
     77        function test_print_script_tag_prints_get_inline_script_tag() {
     78                add_filter(
     79                        'wp_script_attributes',
     80                        function ( $attributes ) {
     81                                if ( isset( $attributes['id'] ) && 'utils-js-extra' === $attributes['id'] ) {
     82                                        $attributes['async'] = true;
     83                                }
     84                                return $attributes;
     85                        }
     86                );
     87
     88                add_theme_support( 'html5', array( 'script' ) );
     89
     90                $attributes = array(
     91                        'id'       => 'utils-js-before',
     92                        'nomodule' => true,
     93                );
     94
     95                $this->assertSame(
     96                        wp_get_inline_script_tag( $this->event_handler, $attributes ),
     97                        get_echo(
     98                                'wp_print_inline_script_tag',
     99                                array(
     100                                        $this->event_handler,
     101                                        $attributes,
     102                                )
     103                        )
     104                );
     105
     106                remove_theme_support( 'html5' );
     107
     108                $this->assertSame(
     109                        wp_get_inline_script_tag( $this->event_handler, $attributes ),
     110                        get_echo(
     111                                'wp_print_inline_script_tag',
     112                                array(
     113                                        $this->event_handler,
     114                                        $attributes,
     115                                )
     116                        )
     117                );
     118        }
     119}
  • new file tests/phpunit/tests/functions/wpSanitizeScriptAttributes.php

    diff --git tests/phpunit/tests/functions/wpSanitizeScriptAttributes.php tests/phpunit/tests/functions/wpSanitizeScriptAttributes.php
    new file mode 100644
    index 0000000000..dd060ebd5d
    - +  
     1<?php
     2
     3/**
     4 * Test wp_sanitize_script_attributes().
     5 *
     6 * @group functions.php
     7 */
     8class Tests_Functions_wpSanitizeScriptAttributes extends WP_UnitTestCase {
     9
     10        function test_sanitize_script_attributes_type_set() {
     11                add_theme_support( 'html5', array( 'script' ) );
     12
     13                $this->assertSame(
     14                        ' type="application/javascript" src="https://DOMAIN.TLD/PATH/FILE.js" nomodule',
     15                        wp_sanitize_script_attributes(
     16                                array(
     17                                        'type'     => 'application/javascript',
     18                                        'src'      => 'https://DOMAIN.TLD/PATH/FILE.js',
     19                                        'async'    => false,
     20                                        'nomodule' => true,
     21                                )
     22                        )
     23                );
     24
     25                remove_theme_support( 'html5' );
     26
     27                $this->assertSame(
     28                        ' src="https://DOMAIN.TLD/PATH/FILE.js" type="application/javascript" nomodule="nomodule"',
     29                        wp_sanitize_script_attributes(
     30                                array(
     31                                        'src'      => 'https://DOMAIN.TLD/PATH/FILE.js',
     32                                        'type'     => 'application/javascript',
     33                                        'async'    => false,
     34                                        'nomodule' => true,
     35                                )
     36                        )
     37                );
     38        }
     39
     40        function test_sanitize_script_attributes_type_not_set() {
     41                add_theme_support( 'html5', array( 'script' ) );
     42
     43                $this->assertSame(
     44                        ' src="https://DOMAIN.TLD/PATH/FILE.js" nomodule',
     45                        wp_sanitize_script_attributes(
     46                                array(
     47                                        'src'      => 'https://DOMAIN.TLD/PATH/FILE.js',
     48                                        'async'    => false,
     49                                        'nomodule' => true,
     50                                )
     51                        )
     52                );
     53
     54                remove_theme_support( 'html5' );
     55
     56                $this->assertSame(
     57                        ' src="https://DOMAIN.TLD/PATH/FILE.js" nomodule="nomodule"',
     58                        wp_sanitize_script_attributes(
     59                                array(
     60                                        'src'      => 'https://DOMAIN.TLD/PATH/FILE.js',
     61                                        'async'    => false,
     62                                        'nomodule' => true,
     63                                )
     64                        )
     65                );
     66        }
     67
     68
     69        function test_sanitize_script_attributes_no_attributes() {
     70                add_theme_support( 'html5', array( 'script' ) );
     71
     72                $this->assertSame(
     73                        '',
     74                        wp_sanitize_script_attributes( array() )
     75                );
     76
     77                remove_theme_support( 'html5' );
     78        }
     79
     80        function test_sanitize_script_attributes_relative_src() {
     81                add_theme_support( 'html5', array( 'script' ) );
     82
     83                $this->assertSame(
     84                        ' src="PATH/FILE.js" nomodule',
     85                        wp_sanitize_script_attributes(
     86                                array(
     87                                        'src'      => 'PATH/FILE.js',
     88                                        'async'    => false,
     89                                        'nomodule' => true,
     90                                )
     91                        )
     92                );
     93
     94                remove_theme_support( 'html5' );
     95        }
     96
     97
     98        function test_sanitize_script_attributes_only_false_boolean_attributes() {
     99                add_theme_support( 'html5', array( 'script' ) );
     100
     101                $this->assertSame(
     102                        '',
     103                        wp_sanitize_script_attributes(
     104                                array(
     105                                        'async'    => false,
     106                                        'nomodule' => false,
     107                                )
     108                        )
     109                );
     110
     111                remove_theme_support( 'html5' );
     112        }
     113
     114        function test_sanitize_script_attributes_only_true_boolean_attributes() {
     115                add_theme_support( 'html5', array( 'script' ) );
     116
     117                $this->assertSame(
     118                        ' async nomodule',
     119                        wp_sanitize_script_attributes(
     120                                array(
     121                                        'async'    => true,
     122                                        'nomodule' => true,
     123                                )
     124                        )
     125                );
     126
     127                remove_theme_support( 'html5' );
     128        }
     129
     130}
  • new file tests/phpunit/tests/functions/wpScriptTag.php

    diff --git tests/phpunit/tests/functions/wpScriptTag.php tests/phpunit/tests/functions/wpScriptTag.php
    new file mode 100644
    index 0000000000..3c451f5359
    - +  
     1<?php
     2
     3/**
     4 * Test wp_get_script_tag() and wp_print_script_tag().
     5 *
     6 * @group functions.php
     7 */
     8class Tests_Functions_wpScriptTag extends WP_UnitTestCase {
     9
     10        function get_script_tag_type_set() {
     11                add_theme_support( 'html5', array( 'script' ) );
     12
     13                $this->assertSame(
     14                        '<script src="https://localhost/PATH/FILE.js" type="application/javascript" nomodule></script>' . "\n",
     15                        wp_get_script_tag(
     16                                array(
     17                                        'type'     => 'application/javascript',
     18                                        'src'      => 'https://localhost/PATH/FILE.js',
     19                                        'async'    => false,
     20                                        'nomodule' => true,
     21                                )
     22                        )
     23                );
     24
     25                remove_theme_support( 'html5' );
     26
     27                $this->assertSame(
     28                        '<script src="https://localhost/PATH/FILE.js" type="application/javascript" nomodule></script>' . "\n",
     29                        wp_get_script_tag(
     30                                array(
     31                                        'src'      => 'https://localhost/PATH/FILE.js',
     32                                        'type'     => 'application/javascript',
     33                                        'async'    => false,
     34                                        'nomodule' => true,
     35                                )
     36                        )
     37                );
     38        }
     39
     40        function test_get_script_tag_type_not_set() {
     41                add_theme_support( 'html5', array( 'script' ) );
     42
     43                $this->assertSame(
     44                        '<script src="https://localhost/PATH/FILE.js" nomodule></script>' . "\n",
     45                        wp_get_script_tag(
     46                                array(
     47                                        'src'      => 'https://localhost/PATH/FILE.js',
     48                                        'async'    => false,
     49                                        'nomodule' => true,
     50                                )
     51                        )
     52                );
     53
     54                remove_theme_support( 'html5' );
     55        }
     56
     57        function test_print_script_tag_prints_get_script_tag() {
     58                add_filter(
     59                        'wp_script_attributes',
     60                        function ( $attributes ) {
     61                                if ( isset( $attributes['id'] ) && 'utils-js-extra' === $attributes['id'] ) {
     62                                        $attributes['async'] = true;
     63                                }
     64                                return $attributes;
     65                        }
     66                );
     67
     68                add_theme_support( 'html5', array( 'script' ) );
     69
     70                $attributes = array(
     71                        'src'      => 'https://localhost/PATH/FILE.js',
     72                        'id'       => 'utils-js-extra',
     73                        'nomodule' => true,
     74                );
     75
     76                $this->assertSame(
     77                        wp_get_script_tag( $attributes ),
     78                        get_echo(
     79                                'wp_print_script_tag',
     80                                array( $attributes )
     81                        )
     82                );
     83
     84                remove_theme_support( 'html5' );
     85
     86                $this->assertSame(
     87                        wp_get_script_tag( $attributes ),
     88                        get_echo(
     89                                'wp_print_script_tag',
     90                                array( $attributes )
     91                        )
     92                );
     93        }
     94}