WordPress.org

Make WordPress Core

Ticket #22249: 22249.7.diff

File 22249.7.diff, 16.3 KB (added by joe_bopper, 4 years ago)
  • src/wp-includes/class.wp-scripts.php

    diff --git src/wp-includes/class.wp-scripts.php src/wp-includes/class.wp-scripts.php
    index 144bfce..a3d0ad5 100644
    class WP_Scripts extends WP_Dependencies { 
    163163        }
    164164
    165165        /**
     166         * Get the expanded source URL for a script.
     167         *
     168         * @since 4.6.0
     169         *
     170         * @param  string $handle The script's handle.
     171         * @return string The URL.
     172         */
     173        public function get_script_src( $handle ) {
     174                $obj = $this->registered[ $handle ];
     175                $src = $obj->src;
     176                if ( null === $obj->ver ) {
     177                        $ver = '';
     178                } else {
     179                        $ver = $obj->ver ? $obj->ver : $this->default_version;
     180                }
     181
     182                // Add any extra arguments to the version string.
     183                if ( isset($this->args[ $handle ]) )
     184                        $ver = $ver ? $ver . '&' . $this->args[ $handle ] : $this->args[ $handle ];
     185
     186                if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $this->content_url && 0 === strpos( $src, $this->content_url ) ) ) {
     187                        $src = $this->base_url . $src;
     188                }
     189
     190                if ( ! empty( $ver ) )
     191                        $src = add_query_arg( 'ver', $ver, $src );
     192
     193                /** This filter is documented in wp-includes/class.wp-scripts.php */
     194                return apply_filters( 'script_loader_src', $src, $handle );
     195        }
     196
     197                /**
    166198         * Prints scripts.
    167199         *
    168200         * Prints the scripts passed to it or the print queue. Also prints all necessary dependencies.
    class WP_Scripts extends WP_Dependencies { 
    329361                        return true;
    330362                }
    331363
    332                 if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $this->content_url && 0 === strpos( $src, $this->content_url ) ) ) {
    333                         $src = $this->base_url . $src;
    334                 }
    335 
    336                 if ( ! empty( $ver ) )
    337                         $src = add_query_arg( 'ver', $ver, $src );
    338 
    339                 /** This filter is documented in wp-includes/class.wp-scripts.php */
    340                 $src = esc_url( apply_filters( 'script_loader_src', $src, $handle ) );
     364                $src = $this->get_script_src( $handle );
    341365
    342                 if ( ! $src )
     366                if ( ! $src ) {
    343367                        return true;
    344 
    345                 $tag = "{$cond_before}{$before_handle}<script type='text/javascript' src='$src'></script>\n{$after_handle}{$cond_after}";
     368                }
     369                $attributes = $this->get_script_attributes_html( $handle );
     370                $tag = "{$cond_before}{$before_handle}<script$attributes></script>\n{$after_handle}{$cond_after}";
    346371
    347372                /**
    348373                 * Filter the HTML script tag of an enqueued script.
    class WP_Scripts extends WP_Dependencies { 
    421446        }
    422447
    423448        /**
     449         * Get the HTML element attributes for a script.
     450         *
     451         * Does not include the `src` attribute.
     452         *
     453         * @since 4.6.0
     454         *
     455         * @param string $handle Script registered handle.
     456         * @return array Attribues.
     457         */
     458        public function get_script_attributes( $handle ) {
     459                $default_attributes = array(
     460                        'type' => 'text/javascript',
     461                        'src' => $this->get_script_src( $handle ),
     462                );
     463
     464                if ( isset( $this->registered[ $handle ]->args['attributes'] ) ) {
     465                        $extra_attributes = $this->registered[ $handle ]->args['attributes'];
     466                        $attributes = wp_parse_args( $extra_attributes, $default_attributes );
     467                } else {
     468                        $attributes = $default_attributes;
     469                }
     470
     471                /**
     472                 * Filter the HTML element attributes for a script.
     473                 *
     474                 * @since 4.6.0
     475                 *
     476                 * @param array  $attributes Array of script element attributes.
     477                 * @param string $handle     Script handle.
     478                 */
     479                $attributes = apply_filters( 'script_additional_attributes', $attributes, $handle );
     480                return $attributes;
     481        }
     482
     483
     484        /**
     485         * Get the concatenated HTML element attributes for a script.
     486         *
     487         * @since 4.6.0
     488         *
     489         * @param  string $handle The script handle.
     490         * @return string Concatenated attributes.
     491         */
     492        public function get_script_attributes_html( $handle ) {
     493                $attributes = $this->get_script_attributes( $handle );
     494                $html = '';
     495                foreach ( $attributes as $attribute => $attribute_value ) {
     496                        if ( 'src' === $attribute ) {
     497                                $escaped_attribute_value = esc_url_raw( $attribute_value );
     498                        } else {
     499                                $escaped_attribute_value = esc_attr( $attribute_value );
     500                        }
     501                        $html .=  sprintf( " %s='%s'", esc_attr_name( $attribute ), $escaped_attribute_value );
     502                }
     503                return $html;
     504        }
     505
     506        /**
    424507         * Localizes a script, only if the script has already been added.
    425508         *
    426509         * @since 2.1.0
  • src/wp-includes/class.wp-styles.php

    diff --git src/wp-includes/class.wp-styles.php src/wp-includes/class.wp-styles.php
    index a175058..b0d9a68 100644
    class WP_Styles extends WP_Dependencies { 
    128128        }
    129129
    130130        /**
     131         * Get the HTML element attributes for a stylesheet.
     132         *
     133         * Does not include the `href` attribute.
     134         *
     135         * @since 4.6.0
     136         *
     137         * @param  string $handle The stylesheet handle.
     138         * @return array Attribues.
     139         */
     140        public function get_style_additional_attributes( $handle ) {
     141                $obj = $this->registered[ $handle ];
     142                if ( null === $obj->ver ) {
     143                        $ver = '';
     144                } else {
     145                        $ver = $obj->ver ? $obj->ver : $this->default_version;
     146                }
     147
     148                $attributes = array(
     149                        'rel' => isset($obj->extra['alt']) && $obj->extra['alt'] ? 'alternate stylesheet' : 'stylesheet',
     150                        'id' => $handle . '-css',
     151                        'title' => isset($obj->extra['title']) ? $obj->extra['title'] : '',
     152                        'type' => 'text/css',
     153                        'media' => isset( $obj->args ) ? $obj->args : 'all'
     154                );
     155                return $attributes;
     156        }
     157
     158        /**
    131159         * Processes a style dependency.
    132160         *
    133161         * @since 2.6.0
    class WP_Styles extends WP_Dependencies { 
    200228                 * @param string $href   The stylesheet's source URL.
    201229                 * @param string $media  The stylesheet's media attribute.
    202230                 */
    203                 $tag = apply_filters( 'style_loader_tag', "<link rel='$rel' id='$handle-css' $title href='$href' type='text/css' media='$media' />\n", $handle, $href, $media);
     231                $tag = apply_filters( 'style_loader_tag', "<link href='$href'" . $this->get_style_attribute_html( $handle ) . " />\n", $handle, $href, $media);
    204232                if ( 'rtl' === $this->text_direction && isset($obj->extra['rtl']) && $obj->extra['rtl'] ) {
    205233                        if ( is_bool( $obj->extra['rtl'] ) || 'replace' === $obj->extra['rtl'] ) {
    206234                                $suffix = isset( $obj->extra['suffix'] ) ? $obj->extra['suffix'] : '';
    class WP_Styles extends WP_Dependencies { 
    243271        }
    244272
    245273        /**
     274         * Get the concatenated HTML element attributes for a stylesheet
     275         *
     276         * @since 4.6.0
     277         *
     278         * @param  string $handle The stylesheet handle.
     279         * @return string Concatenated attributes.
     280         */
     281        public function get_style_attribute_html( $handle ) {
     282                $attributes = $this->get_style_additional_attributes( $handle );
     283                $html = '';
     284                foreach ( $attributes as $attribute => $attribute_value ) {
     285                        $html .=  sprintf( " %s='%s'", esc_attr_name( $attribute ), esc_attr( $attribute_value ) );
     286                }
     287                return $html;
     288        }
     289
     290        /**
    246291         * Adds extra CSS styles to a registered stylesheet.
    247292         *
    248293         * @since 3.3.0
  • src/wp-includes/functions.wp-scripts.php

    diff --git src/wp-includes/functions.wp-scripts.php src/wp-includes/functions.wp-scripts.php
    index 0e06218..e9a27ca 100644
    function wp_add_inline_script( $handle, $data, $position = 'after' ) { 
    129129 *
    130130 * @since 2.1.0
    131131 * @since 4.3.0 A return value was added.
     132 * @since 4.6.0 Introduced the `$attributes` parameter.
    132133 *
    133134 * @param string           $handle    Name of the script. Should be unique.
    134135 * @param string           $src       Full URL of the script, or path of the script relative to the WordPress root directory.
    function wp_add_inline_script( $handle, $data, $position = 'after' ) { 
    139140 *                                    If set to null, no version is added.
    140141 * @param bool             $in_footer Optional. Whether to enqueue the script before </body> instead of in the <head>.
    141142 *                                    Default 'false'.
     143 * @param array            $args {
     144 *     Optional script arguments.
     145 *
     146 *     @type array $attributes Array of script element attributes.
     147 *                             Default: array( 'type' => 'text/javascript' )
     148 * }
    142149 * @return bool Whether the script has been registered. True on success, false on failure.
    143150 */
    144 function wp_register_script( $handle, $src, $deps = array(), $ver = false, $in_footer = false ) {
     151function wp_register_script( $handle, $src, $deps = array(), $ver = false, $in_footer = false, $attributes = array() ) {
    145152        $wp_scripts = wp_scripts();
    146153        _wp_scripts_maybe_doing_it_wrong( __FUNCTION__ );
    147154
    148         $registered = $wp_scripts->add( $handle, $src, $deps, $ver );
     155        $attributes = wp_parse_args( $attributes, array( 'type' => 'text/javascript' ) );
     156
     157        $registered = $wp_scripts->add( $handle, $src, $deps, $ver, array( 'attributes' => $attributes ) );
    149158        if ( $in_footer ) {
    150159                $wp_scripts->add_data( $handle, 'group', 1 );
    151160        }
    function wp_deregister_script( $handle ) { 
    244253 * @see WP_Dependencies::enqueue()
    245254 *
    246255 * @since 2.1.0
     256 * @since 4.6.0 Introduced the `$attributes` parameter.
    247257 *
    248258 * @param string           $handle    Name of the script. Should be unique.
    249259 * @param string           $src       Full URL of the script, or path of the script relative to the WordPress root directory.
    function wp_deregister_script( $handle ) { 
    254264 *                                    If set to null, no version is added.
    255265 * @param bool             $in_footer Optional. Whether to enqueue the script before </body> instead of in the <head>.
    256266 *                                    Default 'false'.
     267 * @param array            $args {
     268 *     Optional script arguments.
     269 *
     270 *     @type array $attributes Array of script element attributes.
     271 *                             Default: array( 'type' => 'text/javascript' )
     272 * }
    257273 */
    258 function wp_enqueue_script( $handle, $src = false, $deps = array(), $ver = false, $in_footer = false ) {
     274function wp_enqueue_script( $handle, $src = false, $deps = array(), $ver = false, $in_footer = false, $attributes = array() ) {
    259275        $wp_scripts = wp_scripts();
    260276
    261277        _wp_scripts_maybe_doing_it_wrong( __FUNCTION__ );
    262278
     279        $attributes = wp_parse_args( $attributes, array( 'type' => 'text/javascript' ) );
    263280
    264281        if ( $src || $in_footer ) {
    265282                $_handle = explode( '?', $handle );
    266283
    267284                if ( $src ) {
    268                         $wp_scripts->add( $_handle[0], $src, $deps, $ver );
     285                        $wp_scripts->add( $_handle[0], $src, $deps, $ver, array( 'attributes' => $attributes ) );
    269286                }
    270287
    271288                if ( $in_footer ) {
  • new file tests/phpunit/tests/dependencies/getScriptAttributes.php

    diff --git tests/phpunit/tests/dependencies/getScriptAttributes.php tests/phpunit/tests/dependencies/getScriptAttributes.php
    new file mode 100644
    index 0000000..24f84b7
    - +  
     1<?php
     2/**
     3 * @group dependencies
     4 * @group scripts
     5 */
     6class Tests_Dependencies_GetScriptAttributes extends WP_UnitTestCase {
     7        var $old_wp_scripts;
     8
     9        function setUp() {
     10                parent::setUp();
     11                $this->old_wp_scripts = isset( $GLOBALS['wp_scripts'] ) ? $GLOBALS['wp_scripts'] : null;
     12                remove_action( 'wp_default_scripts', 'wp_default_scripts' );
     13                $GLOBALS['wp_scripts'] = new WP_Scripts();
     14                $GLOBALS['wp_scripts']->default_version = get_bloginfo( 'version' );
     15        }
     16
     17        function tearDown() {
     18                $GLOBALS['wp_scripts'] = $this->old_wp_scripts;
     19                add_action( 'wp_default_scripts', 'wp_default_scripts' );
     20                parent::tearDown();
     21        }
     22
     23        /**
     24         * @ticket 22249
     25         */
     26        function test_get_script_attributes_with_defaults() {
     27                global $wp_scripts;
     28                wp_register_script( 'cool-script', '/cool-script.js', array(), '1' );
     29
     30                $expected_attributes = array(
     31                        'type' => 'text/javascript',
     32                        'src' => '/cool-script.js?ver=1',
     33                );
     34                $actual_attributes = $wp_scripts->get_script_attributes( 'cool-script' );
     35                $this->assertEquals( $expected_attributes, $actual_attributes );
     36        }
     37
     38        /**
     39         * @ticket 22249
     40         */
     41        function test_get_script_attributes_with_arbitrary_attributes_added() {
     42                global $wp_scripts;
     43                wp_register_script( 'cool-script', '/cool-script.js', array(), '1', false, array( 'async' => 'async' ) );
     44
     45                $expected_attributes = array(
     46                        'type' => 'text/javascript',
     47                        'src' => '/cool-script.js?ver=1',
     48                        'async' => 'async',
     49                );
     50                $actual_attributes = $wp_scripts->get_script_attributes( 'cool-script' );
     51                $this->assertEquals( $expected_attributes, $actual_attributes );
     52        }
     53
     54}
  • new file tests/phpunit/tests/dependencies/getScriptAttributesHtml.php

    diff --git tests/phpunit/tests/dependencies/getScriptAttributesHtml.php tests/phpunit/tests/dependencies/getScriptAttributesHtml.php
    new file mode 100644
    index 0000000..5a2a766
    - +  
     1<?php
     2/**
     3 * @group dependencies
     4 * @group scripts
     5 */
     6class Tests_Dependencies_GetScriptAttributesHtml extends WP_UnitTestCase {
     7        var $old_wp_scripts;
     8
     9        function setUp() {
     10                parent::setUp();
     11                $this->old_wp_scripts = isset( $GLOBALS['wp_scripts'] ) ? $GLOBALS['wp_scripts'] : null;
     12                remove_action( 'wp_default_scripts', 'wp_default_scripts' );
     13                $GLOBALS['wp_scripts'] = new WP_Scripts();
     14                $GLOBALS['wp_scripts']->default_version = get_bloginfo( 'version' );
     15        }
     16
     17        function tearDown() {
     18                $GLOBALS['wp_scripts'] = $this->old_wp_scripts;
     19                add_action( 'wp_default_scripts', 'wp_default_scripts' );
     20                parent::tearDown();
     21        }
     22
     23        /**
     24         * @ticket 22249
     25         */
     26        function test_get_script_attributes_html_with_defaults() {
     27                global $wp_scripts;
     28                wp_register_script( 'cool-script', '/cool-script.js', array(), '1' );
     29
     30                $actual = $wp_scripts->get_script_attributes_html( 'cool-script' );
     31                $expected = " type='text/javascript' src='/cool-script.js?ver=1'";
     32                $this->assertEquals( $expected, $actual );
     33        }
     34
     35        /**
     36         * @ticket 22249
     37         */
     38        function test_get_script_attributes_html_with_arbitrary_attributes_added() {
     39                global $wp_scripts;
     40                wp_register_script( 'cool-script', '/cool-script.js', array(), '1', false, array( 'async' => 'async' ) );
     41
     42                $actual = $wp_scripts->get_script_attributes_html( 'cool-script' );
     43                $expected = " type='text/javascript' src='/cool-script.js?ver=1' async='async'";
     44                $this->assertEquals( $expected, $actual );
     45        }
     46
     47}
  • new file tests/phpunit/tests/dependencies/getScriptSrc.php

    diff --git tests/phpunit/tests/dependencies/getScriptSrc.php tests/phpunit/tests/dependencies/getScriptSrc.php
    new file mode 100644
    index 0000000..64d7007
    - +  
     1<?php
     2/**
     3 * @group dependencies
     4 * @group scripts
     5 */
     6class Tests_Dependencies_GetScriptSrc extends WP_UnitTestCase {
     7        var $old_wp_scripts;
     8
     9        function setUp() {
     10                parent::setUp();
     11                $this->old_wp_scripts = isset( $GLOBALS['wp_scripts'] ) ? $GLOBALS['wp_scripts'] : null;
     12                remove_action( 'wp_default_scripts', 'wp_default_scripts' );
     13                $GLOBALS['wp_scripts'] = new WP_Scripts();
     14                $GLOBALS['wp_scripts']->default_version = get_bloginfo( 'version' );
     15        }
     16
     17        function tearDown() {
     18                $GLOBALS['wp_scripts'] = $this->old_wp_scripts;
     19                add_action( 'wp_default_scripts', 'wp_default_scripts' );
     20                parent::tearDown();
     21        }
     22
     23        /**
     24         * @ticket 22249
     25         */
     26        function test_get_script_src_for_script_with_relative_url() {
     27                global $wp_scripts;
     28                wp_register_script( 'cool-script', '/cool-script.js', array(), '1' );
     29
     30                $actual = $wp_scripts->get_script_src( 'cool-script' );
     31                $this->assertEquals( '/cool-script.js?ver=1', $actual );
     32        }
     33
     34        /**
     35         * @ticket 22249
     36         */
     37        function test_get_script_src_for_script_with_full_url() {
     38                global $wp_scripts;
     39                wp_register_script( 'd3', 'https://d3js.org/d3.v3.min.js', array(), '1' );
     40
     41                $actual = $wp_scripts->get_script_src( 'd3' );
     42                $this->assertEquals( 'https://d3js.org/d3.v3.min.js?ver=1', $actual );
     43        }
     44
     45}
  • tests/phpunit/tests/dependencies/scripts.php

    diff --git tests/phpunit/tests/dependencies/scripts.php tests/phpunit/tests/dependencies/scripts.php
    index efe5a7b..01c56ab 100644
    class Tests_Dependencies_Scripts extends WP_UnitTestCase { 
    724724
    725725                $this->assertEquals( $expected, get_echo( 'wp_print_scripts' ) );
    726726        }
     727
     728        /**
     729         * @ticket 22249
     730         */
     731        function test_wp_register_script_should_allow_arbitrary_element_attributes() {
     732                wp_register_script( 'cool-script', '/cool-script.js', array(), '1', false, array( 'async' => 'async' ) );
     733
     734                wp_enqueue_script( 'cool-script' );
     735
     736                $header = get_echo( 'wp_print_head_scripts' );
     737                $expected_header  = "<script type='text/javascript' src='/cool-script.js?ver=1' async='async'></script>\n";
     738
     739                $this->assertEquals( $expected_header, $header );
     740        }
     741
     742        /**
     743         * @ticket 22249
     744         */
     745        function test_wp_enqueue_script_should_allow_arbitrary_element_attributes() {
     746                wp_enqueue_script( 'cool-script', '/cool-script.js', array(), '1', false, array( 'async' => 'async' ) );
     747
     748                $header = get_echo( 'wp_print_head_scripts' );
     749                $expected_header  = "<script type='text/javascript' src='/cool-script.js?ver=1' async='async'></script>\n";
     750
     751                $this->assertEquals( $expected_header, $header );
     752        }
     753
    727754}