WordPress.org

Make WordPress Core

Ticket #22249: 22249.4.diff

File 22249.4.diff, 13.6 KB (added by ericlewis, 5 years ago)
  • src/wp-includes/class.wp-scripts.php

     
    108108        }
    109109
    110110        /**
     111         * Get the expanded source URL for a script.
     112         *
     113         * @since 4.5.0
     114         *
     115         * @param  string $handle The script's handle.
     116         * @return string The URL.
     117         */
     118        public function get_script_src( $handle ) {
     119                $obj = $this->registered[$handle];
     120                $src = $obj->src;
     121                if ( null === $obj->ver ) {
     122                        $ver = '';
     123                } else {
     124                        $ver = $obj->ver ? $obj->ver : $this->default_version;
     125                }
     126
     127                // Add any extra arguments to the version string.
     128                if ( isset($this->args[$handle]) )
     129                        $ver = $ver ? $ver . '&' . $this->args[$handle] : $this->args[$handle];
     130
     131                if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $this->content_url && 0 === strpos( $src, $this->content_url ) ) ) {
     132                        $src = $this->base_url . $src;
     133                }
     134
     135                if ( ! empty( $ver ) )
     136                        $src = add_query_arg( 'ver', $ver, $src );
     137
     138                /** This filter is documented in wp-includes/class.wp-scripts.php */
     139                return esc_url( apply_filters( 'script_loader_src', $src, $handle ) );
     140        }
     141
     142        /**
    111143         * @param string   $handle Name of the item. Should be unique.
    112144         * @param int|bool $group
    113145         * @return bool True on success, false if not set.
     
    182214                        return true;
    183215                }
    184216
    185                 if ( ! preg_match( '|^(https?:)?//|', $src ) && ! ( $this->content_url && 0 === strpos( $src, $this->content_url ) ) ) {
    186                         $src = $this->base_url . $src;
     217                $_attributes = $this->get_script_attributes( $handle );
     218                $src = $_attributes['src'];
     219                if ( ! $src ) {
     220                        return true;
    187221                }
    188222
    189                 if ( ! empty( $ver ) )
    190                         $src = add_query_arg( 'ver', $ver, $src );
     223                $attributes = $this->get_script_attribute_html( $handle );
     224                $tag = "{$cond_before}<script$attributes></script>\n{$cond_after}";
    191225
    192                 /** This filter is documented in wp-includes/class.wp-scripts.php */
    193                 $src = esc_url( apply_filters( 'script_loader_src', $src, $handle ) );
    194 
    195                 if ( ! $src )
    196                         return true;
    197 
    198                 $tag = "{$cond_before}<script type='text/javascript' src='$src'></script>\n{$cond_after}";
    199 
    200226                /**
    201227                 * Filter the HTML script tag of an enqueued script.
    202228                 *
     
    218244        }
    219245
    220246        /**
     247         * Get the HTML element attributes for a script.
     248         *
     249         * @since 4.5.0
     250         *
     251         * @param string $handle Script registered handle.
     252         * @return array Attribues.
     253         */
     254        public function get_script_attributes( $handle ) {
     255                $src = $this->get_script_src( $handle );
     256
     257                $default_attributes = array(
     258                        'type' => 'text/javascript',
     259                        'src'  => $src
     260                );
     261
     262                if ( isset( $this->registered[ $handle ]->args['attributes'] ) ) {
     263                        $extra_attributes = $this->registered[ $handle ]->args['attributes'];
     264                        $attributes = wp_parse_args( $extra_attributes, $default_attributes );
     265                } else {
     266                        $attributes = $default_attributes;
     267                }
     268
     269                /**
     270                 * Filter the HTML element attributes for a script.
     271                 *
     272                 * @since 4.5.0
     273                 *
     274                 * @param array  $attributes Array of script element attributes.
     275                 * @param string $handle     Script handle.
     276                 */
     277                $attributes = apply_filters( 'script_attributes', $attributes, $handle );
     278                // Ensure source is set.
     279                $attributes['src'] = isset( $attributes['src'] ) ? $attributes['src'] : $src;
     280                return $attributes;
     281        }
     282
     283
     284        /**
     285         * Get the concatenated HTML element attributes for a script.
     286         *
     287         * @since 4.5.0
     288         *
     289         * @param  string $handle The script handle.
     290         * @return string Concatenated attributes.
     291         */
     292        public function get_script_attribute_html( $handle ) {
     293                $attributes = $this->get_script_attributes( $handle );
     294                $concat_attributes = '';
     295                foreach ( $attributes as $attribute => $attribute_value ) {
     296                        $concat_attributes .=  sprintf( " %s='%s'", esc_attr( $attribute ), esc_attr( $attribute_value )  );
     297                }
     298
     299                return $concat_attributes;
     300        }
     301
     302        /**
    221303         * Localizes a script, only if the script has already been added
    222304         *
    223305         * @param string $handle
  • src/wp-includes/functions.wp-scripts.php

     
    9595 *
    9696 * @since 2.6.0
    9797 * @since 4.3.0 A return value was added.
     98 * @since 4.5.0 The sixth argument was added.
    9899 *
    99100 * @param string      $handle    Name of the script. Should be unique.
    100101 * @param string      $src       Path to the script from the WordPress root directory. Example: '/js/myscript.js'.
     
    106107 *                               If set to null, no version is added. Default 'false'. Accepts 'false', 'null', or 'string'.
    107108 * @param bool        $in_footer Optional. Whether to enqueue the script before </head> or before </body>.
    108109 *                               Default 'false'. Accepts 'false' or 'true'.
     110 * @param array       $args {
     111 *     Optional script arguments.
     112 *
     113 *     @type array $attributes Array of script element attributes.
     114 *                             Default: array( 'type' => 'text/javascript' )
     115 * }
    109116 * @return bool Whether the script has been registered. True on success, false on failure.
    110117 */
    111 function wp_register_script( $handle, $src, $deps = array(), $ver = false, $in_footer = false ) {
     118function wp_register_script( $handle, $src, $deps = array(), $ver = false, $in_footer = false, $attributes = array() ) {
    112119        $wp_scripts = wp_scripts();
    113120        _wp_scripts_maybe_doing_it_wrong( __FUNCTION__ );
    114121
    115         $registered = $wp_scripts->add( $handle, $src, $deps, $ver );
     122        $attributes = wp_parse_args( $attributes, array( 'type' => 'text/javascript' ) );
     123
     124        $registered = $wp_scripts->add( $handle, $src, $deps, $ver, array( 'attributes' => $attributes ) );
    116125        if ( $in_footer ) {
    117126                $wp_scripts->add_data( $handle, 'group', 1 );
    118127        }
     
    211220 * @see WP_Dependencies::enqueue()
    212221 *
    213222 * @since 2.6.0
     223 * @since 4.5.0 The sixth argument was added.
    214224 *
    215225 * @param string      $handle    Name of the script.
    216226 * @param string|bool $src       Path to the script from the root directory of WordPress. Example: '/js/myscript.js'.
     
    220230 *                               and so should be included if a version number is available and makes sense for the script.
    221231 * @param bool        $in_footer Optional. Whether to enqueue the script before </head> or before </body>.
    222232 *                               Default 'false'. Accepts 'false' or 'true'.
     233 * @param array       $args {
     234 *     Optional script arguments.
     235 *
     236 *     @type array $attributes Array of script element attributes.
     237 *                             Default: array( 'type' => 'text/javascript' )
     238 * }
    223239 */
    224 function wp_enqueue_script( $handle, $src = false, $deps = array(), $ver = false, $in_footer = false ) {
     240function wp_enqueue_script( $handle, $src = false, $deps = array(), $ver = false, $in_footer = false, $attributes = array() ) {
    225241        $wp_scripts = wp_scripts();
    226242
    227243        _wp_scripts_maybe_doing_it_wrong( __FUNCTION__ );
    228244
     245        $attributes = wp_parse_args( $attributes, array( 'type' => 'text/javascript' ) );
    229246
    230247        if ( $src || $in_footer ) {
    231248                $_handle = explode( '?', $handle );
    232249
    233250                if ( $src ) {
    234                         $wp_scripts->add( $_handle[0], $src, $deps, $ver );
     251                        $wp_scripts->add( $_handle[0], $src, $deps, $ver, array( 'attributes' => $attributes ) );
    235252                }
    236253
    237254                if ( $in_footer ) {
  • tests/phpunit/tests/dependencies/getScriptAttributeHtml.php

     
     1<?php
     2/**
     3 * @group dependencies
     4 * @group scripts
     5 */
     6class Tests_Dependencies_GetScriptAttributeHtml 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_attribute_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_attribute_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_attribute_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_attribute_html( 'cool-script' );
     43                $expected = " type='text/javascript' src='/cool-script.js?ver=1' async='async'";
     44                $this->assertEquals( $expected, $actual );
     45        }
     46
     47}
  • tests/phpunit/tests/dependencies/getScriptAttributes.php

     
     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}
  • tests/phpunit/tests/dependencies/getScriptSrc.php

     
     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

     
    266266                $this->assertEquals( $expected_header, $header );
    267267                $this->assertEquals( $expected_footer, $footer );
    268268        }
     269
     270        /**
     271         * @ticket 22249
     272         */
     273        function test_wp_register_script_should_allow_arbitrary_element_attributes() {
     274                wp_register_script( 'cool-script', '/cool-script.js', array(), '1', false, array( 'async' => 'async' ) );
     275
     276                wp_enqueue_script( 'cool-script' );
     277
     278                $header = get_echo( 'wp_print_head_scripts' );
     279                $expected_header  = "<script type='text/javascript' src='/cool-script.js?ver=1' async='async'></script>\n";
     280
     281                $this->assertEquals( $expected_header, $header );
     282        }
     283
     284        /**
     285         * @ticket 22249
     286         */
     287        function test_wp_enqueue_script_should_allow_arbitrary_element_attributes() {
     288                wp_enqueue_script( 'cool-script', '/cool-script.js', array(), '1', false, array( 'async' => 'async' ) );
     289
     290                $header = get_echo( 'wp_print_head_scripts' );
     291                $expected_header  = "<script type='text/javascript' src='/cool-script.js?ver=1' async='async'></script>\n";
     292
     293                $this->assertEquals( $expected_header, $header );
     294        }
     295
    269296}