Make WordPress Core

Ticket #39941: 39941.3.diff

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

    diff --git a/src/wp-includes/functions.php b/src/wp-includes/functions.php
    index 75a2463b0d..b6dd0d6518 100644
    a b function retrieve_password( $user_login = null ) { 
    80358035
    80368036        return true;
    80378037}
     8038
     8039/**
     8040 * Sanitizes an attributes array into an attributes string to be placed inside a `<script>` tag.
     8041 *
     8042 * Automatically injects type attribute if needed.
     8043 * Used by {@see wp_get_script_tag()} and {@see wp_get_inline_script_tag()}.
     8044 *
     8045 * @since 5.7.0
     8046 *
     8047 * @param array $attributes Key-value pairs representing `<script>` tag attributes.
     8048 * @return string String made of sanitized `<script>` tag attributes.
     8049 */
     8050function wp_sanitize_script_attributes( $attributes ) {
     8051        $html5_script_support = ! is_admin() && ! current_theme_supports( 'html5', 'script' );
     8052        $attributes_string    = '';
     8053
     8054        // If HTML5 script tag is supported, only the attribute name is added
     8055        // to $attributes_string for entries with a boolean value, and that are true.
     8056        foreach ( $attributes as $attribute_name => $attribute_value ) {
     8057                if ( is_bool( $attribute_value ) ) {
     8058                        if ( $attribute_value ) {
     8059                                $attributes_string .= $html5_script_support ? sprintf( ' %1$s="%2$s"', $attribute_name, esc_attr( $attribute_name ) ) : ' ' . $attribute_name;
     8060                        }
     8061                } else {
     8062                        $attributes_string .= sprintf( ' %1$s="%2$s"', $attribute_name, esc_attr( $attribute_value ) );
     8063                }
     8064        }
     8065
     8066        return $attributes_string;
     8067}
     8068
     8069/**
     8070 * Formats `<script>` loader tags.
     8071 *
     8072 * It is possible to inject attributes in the `<script>` tag via the {@see 'wp_script_attributes'} filter.
     8073 * Automatically injects type attribute if needed.
     8074 *
     8075 * @since 5.7.0
     8076 *
     8077 * @param array $attributes Key-value pairs representing `<script>` tag attributes.
     8078 * @return string String containing `<script>` opening and closing tags.
     8079 */
     8080function wp_get_script_tag( $attributes ) {
     8081        if ( ! isset( $attributes['type'] ) && ! is_admin() && ! current_theme_supports( 'html5', 'script' ) ) {
     8082                $attributes['type'] = 'text/javascript';
     8083        }
     8084        /**
     8085         * Filters attributes to be added to a script tag.
     8086         *
     8087         * @since 5.7.0
     8088         *
     8089         * @param array $attributes Key-value pairs representing `<script>` tag attributes.
     8090         *                          Only the attribute name is added to the `<script>` tag for
     8091         *                          entries with a boolean value, and that are true.
     8092         */
     8093        $attributes = apply_filters( 'wp_script_attributes', $attributes );
     8094
     8095        return sprintf( "<script%s></script>\n", wp_sanitize_script_attributes( $attributes ) );
     8096}
     8097
     8098/**
     8099 * Prints formatted `<script>` loader tag.
     8100 *
     8101 * It is possible to inject attributes in the `<script>` tag via the  {@see 'wp_script_attributes'}  filter.
     8102 * Automatically injects type attribute if needed.
     8103 *
     8104 * @since 5.7.0
     8105 *
     8106 * @param array $attributes Key-value pairs representing `<script>` tag attributes.
     8107 */
     8108function wp_print_script_tag( $attributes ) {
     8109        echo wp_get_script_tag( $attributes );
     8110}
     8111
     8112/**
     8113 * Wraps inline JavaScript in `<script>` tag.
     8114 *
     8115 * It is possible to inject attributes in the `<script>` tag via the  {@see 'wp_script_attributes'}  filter.
     8116 * Automatically injects type attribute if needed.
     8117 *
     8118 * @since 5.7.0
     8119 *
     8120 * @param string $javascript Inline JavaScript code.
     8121 * @param array  $attributes  Optional. Key-value pairs representing `<script>` tag attributes.
     8122 * @return string String containing inline JavaScript code wrapped around `<script>` tag.
     8123 */
     8124function wp_get_inline_script_tag( $javascript, $attributes = array() ) {
     8125        if ( ! isset( $attributes['type'] ) && ! is_admin() && ! current_theme_supports( 'html5', 'script' ) ) {
     8126                $attributes['type'] = 'text/javascript';
     8127        }
     8128        /**
     8129         * Filters attributes to be added to a script tag.
     8130         *
     8131         * @since 5.7.0
     8132         *
     8133         * @param array $attributes Key-value pairs representing `<script>` tag attributes.
     8134         *                          Only the attribute name is added to the `<script>` tag for
     8135         *                          entries with a boolean value, and that are true.
     8136         */
     8137        $attributes = apply_filters( 'wp_script_attributes', $attributes );
     8138
     8139        $javascript = "\n" . trim( $javascript, "\n\r " ) . "\n";
     8140
     8141        return sprintf( "<script%s>%s</script>\n", wp_sanitize_script_attributes( $attributes ), $javascript );
     8142}
     8143
     8144/**
     8145 * Prints inline JavaScript wrapped in `<script>` tag.
     8146 *
     8147 * It is possible to inject attributes in the `<script>` tag via the  {@see 'wp_script_attributes'}  filter.
     8148 * Automatically injects type attribute if needed.
     8149 *
     8150 * @since 5.7.0
     8151 *
     8152 * @param string $javascript Inline JavaScript code.
     8153 * @param array  $attributes Optional. Key-value pairs representing `<script>` tag attributes.
     8154 */
     8155function wp_print_inline_script_tag( $javascript, $attributes = array() ) {
     8156        echo wp_get_inline_script_tag( $javascript, $attributes );
     8157}
     8158 No newline at end of file
  • new file tests/phpunit/tests/functions/wpInlineScriptTag.php

    diff --git a/tests/phpunit/tests/functions/wpInlineScriptTag.php b/tests/phpunit/tests/functions/wpInlineScriptTag.php
    new file mode 100644
    index 0000000000..d4ece1caa9
    - +  
     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        public 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        public 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        public 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        public 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 a/tests/phpunit/tests/functions/wpSanitizeScriptAttributes.php b/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 a/tests/phpunit/tests/functions/wpScriptTag.php b/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}