Changeset 56033
- Timestamp:
- 06/26/2023 01:40:31 PM (16 months ago)
- Location:
- trunk
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/.jshintrc
r46587 r56033 20 20 "_": false, 21 21 "Backbone": false, 22 "console": false, 22 23 "jQuery": false, 23 24 "JSON": false, … … 25 26 "export": false, 26 27 "module": false, 27 "require": false 28 "require": false, 29 "Set": false 28 30 } 29 31 } -
trunk/phpcs.xml.dist
r54703 r56033 69 69 <!-- From DOMDocument. --> 70 70 <element value="childNodes"/> 71 <element value="firstChild"/> 71 72 <element value="formatOutput"/> 73 <element value="lastChild"/> 72 74 <element value="nodeName"/> 73 75 <element value="nodeType"/> -
trunk/src/wp-includes/class-wp-scripts.php
r55703 r56033 135 135 136 136 /** 137 * Holds a mapping of dependents (as handles) for a given script handle. 138 * Used to optimize recursive dependency tree checks. 139 * 140 * @since 6.3.0 141 * @var array 142 */ 143 private $dependents_map = array(); 144 145 /** 146 * Holds a reference to the delayed (non-blocking) script loading strategies. 147 * Used by methods that validate loading strategies. 148 * 149 * @since 6.3.0 150 * @var string[] 151 */ 152 private $delayed_strategies = array( 'defer', 'async' ); 153 154 /** 137 155 * Constructor. 138 156 * … … 285 303 } 286 304 287 $src = $obj->src; 288 $cond_before = ''; 289 $cond_after = ''; 290 $conditional = isset( $obj->extra['conditional'] ) ? $obj->extra['conditional'] : ''; 305 $src = $obj->src; 306 $strategy = $this->get_eligible_loading_strategy( $handle ); 307 $intended_strategy = (string) $this->get_data( $handle, 'strategy' ); 308 $cond_before = ''; 309 $cond_after = ''; 310 $conditional = isset( $obj->extra['conditional'] ) ? $obj->extra['conditional'] : ''; 311 312 if ( ! $this->is_delayed_strategy( $intended_strategy ) ) { 313 $intended_strategy = ''; 314 } 291 315 292 316 if ( $conditional ) { … … 295 319 } 296 320 297 $before_handle = $this->print_inline_script( $handle, 'before', false ); 298 $after_handle = $this->print_inline_script( $handle, 'after', false ); 299 300 if ( $before_handle ) { 301 $before_handle = sprintf( "<script%s id='%s-js-before'>\n%s\n</script>\n", $this->type_attr, esc_attr( $handle ), $before_handle ); 302 } 303 304 if ( $after_handle ) { 305 $after_handle = sprintf( "<script%s id='%s-js-after'>\n%s\n</script>\n", $this->type_attr, esc_attr( $handle ), $after_handle ); 306 } 307 308 if ( $before_handle || $after_handle ) { 309 $inline_script_tag = $cond_before . $before_handle . $after_handle . $cond_after; 321 $before_script = $this->get_inline_script_tag( $handle, 'before' ); 322 $after_script = $this->get_inline_script_tag( $handle, 'after' ); 323 324 if ( $before_script || $after_script ) { 325 $inline_script_tag = $cond_before . $before_script . $after_script . $cond_after; 310 326 } else { 311 327 $inline_script_tag = ''; … … 334 350 $srce = apply_filters( 'script_loader_src', $src, $handle ); 335 351 336 if ( $this->in_default_dir( $srce ) && ( $before_handle || $after_handle || $translations_stop_concat ) ) { 352 if ( 353 $this->in_default_dir( $srce ) 354 && ( $before_script || $after_script || $translations_stop_concat || $this->is_delayed_strategy( $strategy ) ) 355 ) { 337 356 $this->do_concat = false; 338 357 … … 391 410 } 392 411 393 $tag = $translations . $cond_before . $before_handle; 394 $tag .= sprintf( "<script%s src='%s' id='%s-js'></script>\n", $this->type_attr, $src, esc_attr( $handle ) ); 395 $tag .= $after_handle . $cond_after; 412 $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 ); 421 $tag .= $after_script . $cond_after; 396 422 397 423 /** … … 446 472 * 447 473 * @since 4.5.0 448 * 449 * @param string $handle Name of the script to add the inline script to. 474 * @deprecated 6.3.0 Use methods get_inline_script_tag() or get_inline_script_data() instead. 475 * 476 * @param string $handle Name of the script to print inline scripts for. 450 477 * Must be lowercase. 451 478 * @param string $position Optional. Whether to add the inline script 452 479 * before the handle or after. Default 'after'. 453 * @param bool $display Optional. Whether to print the script 454 * instead of just returning it. Default true.455 * @return string|false Script on success, false otherwise.480 * @param bool $display Optional. Whether to print the script tag 481 * instead of just returning the script data. Default true. 482 * @return string|false Script data on success, false otherwise. 456 483 */ 457 484 public function print_inline_script( $handle, $position = 'after', $display = true ) { 458 $output = $this->get_data( $handle, $position ); 459 485 _deprecated_function( __METHOD__, '6.3.0', 'WP_Scripts::get_inline_script_data() or WP_Scripts::get_inline_script_tag()' ); 486 487 $output = $this->get_inline_script_data( $handle, $position ); 460 488 if ( empty( $output ) ) { 461 489 return false; 462 490 } 463 491 464 $output = trim( implode( "\n", $output ), "\n" );465 466 492 if ( $display ) { 467 printf( "<script%s id='%s-js-%s'>\n%s\n</script>\n", $this->type_attr, esc_attr( $handle ), esc_attr( $position ), $output ); 468 } 469 493 echo $this->get_inline_script_tag( $handle, $position ); 494 } 470 495 return $output; 496 } 497 498 /** 499 * Gets data for inline scripts registered for a specific handle. 500 * 501 * @since 6.3.0 502 * 503 * @param string $handle Name of the script to get data for. 504 * Must be lowercase. 505 * @param string $position Optional. Whether to add the inline script 506 * before the handle or after. Default 'after'. 507 * @return string Inline script, which may be empty string. 508 */ 509 public function get_inline_script_data( $handle, $position = 'after' ) { 510 $data = $this->get_data( $handle, $position ); 511 if ( empty( $data ) || ! is_array( $data ) ) { 512 return ''; 513 } 514 515 return trim( implode( "\n", $data ), "\n" ); 516 } 517 518 /** 519 * Gets unaliased dependencies. 520 * 521 * An alias is a dependency whose src is false. It is used as a way to bundle multiple dependencies in a single 522 * handle. This in effect flattens an alias dependency tree. 523 * 524 * @since 6.3.0 525 * 526 * @param string[] $deps Dependency handles. 527 * @return string[] Unaliased handles. 528 */ 529 private function get_unaliased_deps( array $deps ) { 530 $flattened = array(); 531 foreach ( $deps as $dep ) { 532 if ( ! isset( $this->registered[ $dep ] ) ) { 533 continue; 534 } 535 536 if ( $this->registered[ $dep ]->src ) { 537 $flattened[] = $dep; 538 } elseif ( $this->registered[ $dep ]->deps ) { 539 array_push( $flattened, ...$this->get_unaliased_deps( $this->registered[ $dep ]->deps ) ); 540 } 541 } 542 return $flattened; 543 } 544 545 /** 546 * Gets tags for inline scripts registered for a specific handle. 547 * 548 * @since 6.3.0 549 * 550 * @param string $handle Name of the script to get associated inline script tag for. 551 * Must be lowercase. 552 * @param string $position Optional. Whether to get tag for inline 553 * scripts in the before or after position. Default 'after'. 554 * @return string Inline script, which may be empty string. 555 */ 556 public function get_inline_script_tag( $handle, $position = 'after' ) { 557 $js = $this->get_inline_script_data( $handle, $position ); 558 if ( empty( $js ) ) { 559 return ''; 560 } 561 562 $id = "{$handle}-js-{$position}"; 563 564 return wp_get_inline_script_tag( $js, compact( 'id' ) ); 471 565 } 472 566 … … 716 810 717 811 /** 812 * This overrides the add_data method from WP_Dependencies, to support normalizing of $args. 813 * 814 * @since 6.3.0 815 * 816 * @param string $handle Name of the item. Should be unique. 817 * @param string $key The data key. 818 * @param mixed $value The data value. 819 * @return bool True on success, false on failure. 820 */ 821 public function add_data( $handle, $key, $value ) { 822 if ( ! isset( $this->registered[ $handle ] ) ) { 823 return false; 824 } 825 826 if ( 'strategy' === $key ) { 827 if ( ! empty( $value ) && ! $this->is_delayed_strategy( $value ) ) { 828 _doing_it_wrong( 829 __METHOD__, 830 sprintf( 831 /* translators: 1: $strategy, 2: $handle */ 832 __( 'Invalid strategy `%1$s` defined for `%2$s` during script registration.' ), 833 $value, 834 $handle 835 ), 836 '6.3.0' 837 ); 838 return false; 839 } elseif ( ! $this->registered[ $handle ]->src && $this->is_delayed_strategy( $value ) ) { 840 _doing_it_wrong( 841 __METHOD__, 842 sprintf( 843 /* translators: 1: $strategy, 2: $handle */ 844 __( 'Cannot supply a strategy `%1$s` for script `%2$s` because it is an alias (it lacks a `src` value).' ), 845 $value, 846 $handle 847 ), 848 '6.3.0' 849 ); 850 return false; 851 } 852 } 853 return parent::add_data( $handle, $key, $value ); 854 } 855 856 /** 857 * Gets all dependents of a script. 858 * 859 * @since 6.3.0 860 * 861 * @param string $handle The script handle. 862 * @return string[] Script handles. 863 */ 864 private function get_dependents( $handle ) { 865 // Check if dependents map for the handle in question is present. If so, use it. 866 if ( isset( $this->dependents_map[ $handle ] ) ) { 867 return $this->dependents_map[ $handle ]; 868 } 869 870 $dependents = array(); 871 872 // Iterate over all registered scripts, finding dependents of the script passed to this method. 873 foreach ( $this->registered as $registered_handle => $args ) { 874 if ( in_array( $handle, $args->deps, true ) ) { 875 $dependents[] = $registered_handle; 876 } 877 } 878 879 // Add the handles dependents to the map to ease future lookups. 880 $this->dependents_map[ $handle ] = $dependents; 881 882 return $dependents; 883 } 884 885 /** 886 * Checks if the strategy passed is a valid delayed (non-blocking) strategy. 887 * 888 * @since 6.3.0 889 * 890 * @param string $strategy The strategy to check. 891 * @return bool True if $strategy is one of the delayed strategies, otherwise false. 892 */ 893 private function is_delayed_strategy( $strategy ) { 894 return in_array( 895 $strategy, 896 $this->delayed_strategies, 897 true 898 ); 899 } 900 901 /** 902 * Gets the best eligible loading strategy for a script. 903 * 904 * @since 6.3.0 905 * 906 * @param string $handle The script handle. 907 * @return string The best eligible loading strategy. 908 */ 909 private function get_eligible_loading_strategy( $handle ) { 910 $eligible = $this->filter_eligible_strategies( $handle ); 911 912 // Bail early once we know the eligible strategy is blocking. 913 if ( empty( $eligible ) ) { 914 return ''; 915 } 916 917 return in_array( 'async', $eligible, true ) ? 'async' : 'defer'; 918 } 919 920 /** 921 * Filter the list of eligible loading strategies for a script. 922 * 923 * @since 6.3.0 924 * 925 * @param string $handle The script handle. 926 * @param string[]|null $eligible Optional. The list of strategies to filter. Default null. 927 * @param array<string, true> $checked Optional. An array of already checked script handles, used to avoid recursive loops. 928 * @return string[] A list of eligible loading strategies that could be used. 929 */ 930 private function filter_eligible_strategies( $handle, $eligible = null, $checked = array() ) { 931 // If no strategies are being passed, all strategies are eligible. 932 if ( null === $eligible ) { 933 $eligible = $this->delayed_strategies; 934 } 935 936 // If this handle was already checked, return early. 937 if ( isset( $checked[ $handle ] ) ) { 938 return $eligible; 939 } 940 941 // Mark this handle as checked. 942 $checked[ $handle ] = true; 943 944 // If this handle isn't registered, don't filter anything and return. 945 if ( ! isset( $this->registered[ $handle ] ) ) { 946 return $eligible; 947 } 948 949 // If the handle is not enqueued, don't filter anything and return. 950 if ( ! $this->query( $handle, 'enqueued' ) ) { 951 return $eligible; 952 } 953 954 $is_alias = (bool) ! $this->registered[ $handle ]->src; 955 $intended_strategy = $this->get_data( $handle, 'strategy' ); 956 957 // For non-alias handles, an empty intended strategy filters all strategies. 958 if ( ! $is_alias && empty( $intended_strategy ) ) { 959 return array(); 960 } 961 962 // Handles with inline scripts attached in the 'after' position cannot be delayed. 963 if ( $this->has_inline_script( $handle, 'after' ) ) { 964 return array(); 965 } 966 967 // If the intended strategy is 'defer', filter out 'async'. 968 if ( 'defer' === $intended_strategy ) { 969 $eligible = array( 'defer' ); 970 } 971 972 $dependents = $this->get_dependents( $handle ); 973 974 // Recursively filter eligible strategies for dependents. 975 foreach ( $dependents as $dependent ) { 976 // Bail early once we know the eligible strategy is blocking. 977 if ( empty( $eligible ) ) { 978 return array(); 979 } 980 981 $eligible = $this->filter_eligible_strategies( $dependent, $eligible, $checked ); 982 } 983 984 return $eligible; 985 } 986 987 /** 988 * Gets data for inline scripts registered for a specific handle. 989 * 990 * @since 6.3.0 991 * 992 * @param string $handle Name of the script to get data for. Must be lowercase. 993 * @param string $position The position of the inline script. 994 * @return bool Whether the handle has an inline script (either before or after). 995 */ 996 private function has_inline_script( $handle, $position = null ) { 997 if ( $position && in_array( $position, array( 'before', 'after' ), true ) ) { 998 return (bool) $this->get_data( $handle, $position ); 999 } 1000 1001 return (bool) ( $this->get_data( $handle, 'before' ) || $this->get_data( $handle, 'after' ) ); 1002 } 1003 1004 /** 718 1005 * Resets class properties. 719 1006 * -
trunk/src/wp-includes/functions.wp-scripts.php
r55732 r56033 158 158 * @since 2.1.0 159 159 * @since 4.3.0 A return value was added. 160 * @since 6.3.0 The $in_footer parameter of type boolean was overloaded to be an $args parameter of type array. 160 161 * 161 162 * @param string $handle Name of the script. Should be unique. … … 167 168 * number is automatically added equal to current installed WordPress version. 168 169 * If set to null, no version is added. 169 * @param bool $in_footer Optional. Whether to enqueue the script before `</body>` instead of in the `<head>`. 170 * Default 'false'. 170 * @param array|bool $args { 171 * Optional. An array of additional script loading strategies. Default empty array. 172 * Otherwise, it may be a boolean in which case it determines whether the script is printed in the footer. Default false. 173 * 174 * @type string $strategy Optional. If provided, may be either 'defer' or 'async'. 175 * @type bool $in_footer Optional. Whether to print the script in the footer. Default 'false'. 176 * } 171 177 * @return bool Whether the script has been registered. True on success, false on failure. 172 178 */ 173 function wp_register_script( $handle, $src, $deps = array(), $ver = false, $in_footer = false ) { 179 function wp_register_script( $handle, $src, $deps = array(), $ver = false, $args = array() ) { 180 if ( ! is_array( $args ) ) { 181 $args = array( 182 'in_footer' => (bool) $args, 183 ); 184 } 174 185 _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle ); 175 186 … … 177 188 178 189 $registered = $wp_scripts->add( $handle, $src, $deps, $ver ); 179 if ( $in_footer) {190 if ( ! empty( $args['in_footer'] ) ) { 180 191 $wp_scripts->add_data( $handle, 'group', 1 ); 181 192 } 182 193 if ( ! empty( $args['strategy'] ) ) { 194 $wp_scripts->add_data( $handle, 'strategy', $args['strategy'] ); 195 } 183 196 return $registered; 184 197 } … … 332 345 * 333 346 * @since 2.1.0 347 * @since 6.3.0 The $in_footer parameter of type boolean was overloaded to be an $args parameter of type array. 334 348 * 335 349 * @param string $handle Name of the script. Should be unique. … … 341 355 * number is automatically added equal to current installed WordPress version. 342 356 * If set to null, no version is added. 343 * @param bool $in_footer Optional. Whether to enqueue the script before `</body>` instead of in the `<head>`. 344 * Default 'false'. 345 */ 346 function wp_enqueue_script( $handle, $src = '', $deps = array(), $ver = false, $in_footer = false ) { 357 * @param array|bool $args { 358 * Optional. An array of additional script loading strategies. Default empty array. 359 * Otherwise, it may be a boolean in which case it determines whether the script is printed in the footer. Default false. 360 * 361 * @type string $strategy Optional. If provided, may be either 'defer' or 'async'. 362 * @type bool $in_footer Optional. Whether to print the script in the footer. Default 'false'. 363 * } 364 */ 365 function wp_enqueue_script( $handle, $src = '', $deps = array(), $ver = false, $args = array() ) { 347 366 _wp_scripts_maybe_doing_it_wrong( __FUNCTION__, $handle ); 348 367 349 368 $wp_scripts = wp_scripts(); 350 369 351 if ( $src || $in_footer) {370 if ( $src || ! empty( $args ) ) { 352 371 $_handle = explode( '?', $handle ); 372 if ( ! is_array( $args ) ) { 373 $args = array( 374 'in_footer' => (bool) $args, 375 ); 376 } 353 377 354 378 if ( $src ) { 355 379 $wp_scripts->add( $_handle[0], $src, $deps, $ver ); 356 380 } 357 358 if ( $in_footer ) { 381 if ( ! empty( $args['in_footer'] ) ) { 359 382 $wp_scripts->add_data( $_handle[0], 'group', 1 ); 383 } 384 if ( ! empty( $args['strategy'] ) ) { 385 $wp_scripts->add_data( $_handle[0], 'strategy', $args['strategy'] ); 360 386 } 361 387 } -
trunk/tests/phpunit/tests/dependencies/scripts.php
r55822 r56033 11 11 */ 12 12 class Tests_Dependencies_Scripts extends WP_UnitTestCase { 13 14 /** 15 * @var WP_Scripts 16 */ 13 17 protected $old_wp_scripts; 14 18 19 /** 20 * @var WP_Styles 21 */ 22 protected $old_wp_styles; 23 15 24 protected $wp_scripts_print_translations_output; 25 26 /** 27 * Stores a string reference to a default scripts directory name, utilised by certain tests. 28 * 29 * @var string 30 */ 31 protected $default_scripts_dir = '/directory/'; 16 32 17 33 public function set_up() { 18 34 parent::set_up(); 19 35 $this->old_wp_scripts = isset( $GLOBALS['wp_scripts'] ) ? $GLOBALS['wp_scripts'] : null; 36 $this->old_wp_styles = isset( $GLOBALS['wp_styles'] ) ? $GLOBALS['wp_styles'] : null; 20 37 remove_action( 'wp_default_scripts', 'wp_default_scripts' ); 21 38 remove_action( 'wp_default_scripts', 'wp_default_packages' ); 22 39 $GLOBALS['wp_scripts'] = new WP_Scripts(); 23 40 $GLOBALS['wp_scripts']->default_version = get_bloginfo( 'version' ); 41 $GLOBALS['wp_styles'] = new WP_Styles(); 24 42 25 43 $this->wp_scripts_print_translations_output = <<<JS … … 37 55 public function tear_down() { 38 56 $GLOBALS['wp_scripts'] = $this->old_wp_scripts; 57 $GLOBALS['wp_styles'] = $this->old_wp_styles; 39 58 add_action( 'wp_default_scripts', 'wp_default_scripts' ); 40 59 parent::tear_down(); … … 47 66 */ 48 67 public function test_wp_enqueue_script() { 68 global $wp_version; 69 49 70 wp_enqueue_script( 'no-deps-no-version', 'example.com', array() ); 50 71 wp_enqueue_script( 'empty-deps-no-version', 'example.com' ); … … 52 73 wp_enqueue_script( 'empty-deps-null-version', 'example.com', array(), null ); 53 74 54 $ver = get_bloginfo( 'version' ); 55 $expected = "<script type='text/javascript' src='http://example.com?ver=$ver' id='no-deps-no-version-js'></script>\n"; 56 $expected .= "<script type='text/javascript' src='http://example.com?ver=$ver' id='empty-deps-no-version-js'></script>\n"; 75 $expected = "<script type='text/javascript' src='http://example.com?ver={$wp_version}' id='no-deps-no-version-js'></script>\n"; 76 $expected .= "<script type='text/javascript' src='http://example.com?ver={$wp_version}' id='empty-deps-no-version-js'></script>\n"; 57 77 $expected .= "<script type='text/javascript' src='http://example.com?ver=1.2' id='empty-deps-version-js'></script>\n"; 58 78 $expected .= "<script type='text/javascript' src='http://example.com' id='empty-deps-null-version-js'></script>\n"; … … 65 85 66 86 /** 87 * Gets delayed strategies as a data provider. 88 * 89 * @return array[] Delayed strategies. 90 */ 91 public function data_provider_delayed_strategies() { 92 return array( 93 'defer' => array( 'defer' ), 94 'async' => array( 'async' ), 95 ); 96 } 97 98 /** 99 * Tests that inline scripts in the `after` position, attached to delayed main scripts, remain unaffected. 100 * 101 * If the main script with delayed loading strategy has an `after` inline script, 102 * the inline script should not be affected. 103 * 104 * @ticket 12009 105 * 106 * @covers WP_Scripts::do_item 107 * @covers WP_Scripts::get_inline_script_tag 108 * @covers ::wp_add_inline_script 109 * @covers ::wp_enqueue_script 110 * 111 * @dataProvider data_provider_delayed_strategies 112 * 113 * @param string $strategy Strategy. 114 */ 115 public function test_after_inline_script_with_delayed_main_script( $strategy ) { 116 wp_enqueue_script( 'ms-isa-1', 'http://example.org/ms-isa-1.js', array(), null, compact( 'strategy' ) ); 117 wp_add_inline_script( 'ms-isa-1', 'console.log("after one");', 'after' ); 118 $output = get_echo( 'wp_print_scripts' ); 119 $expected = "<script type='text/javascript' src='http://example.org/ms-isa-1.js' id='ms-isa-1-js' data-wp-strategy='{$strategy}'></script>\n"; 120 $expected .= wp_get_inline_script_tag( 121 "console.log(\"after one\");\n", 122 array( 123 'id' => 'ms-isa-1-js-after', 124 ) 125 ); 126 $this->assertSame( $expected, $output, 'Inline scripts in the "after" position, that are attached to a deferred main script, are failing to print/execute.' ); 127 } 128 129 /** 130 * Tests that inline scripts in the `after` position, attached to a blocking main script, are rendered as javascript. 131 * 132 * If a main script with a `blocking` strategy has an `after` inline script, 133 * the inline script should be rendered as type='text/javascript'. 134 * 135 * @ticket 12009 136 * 137 * @covers WP_Scripts::do_item 138 * @covers WP_Scripts::get_inline_script_tag 139 * @covers ::wp_add_inline_script 140 * @covers ::wp_enqueue_script 141 */ 142 public function test_after_inline_script_with_blocking_main_script() { 143 wp_enqueue_script( 'ms-insa-3', 'http://example.org/ms-insa-3.js', array(), null ); 144 wp_add_inline_script( 'ms-insa-3', 'console.log("after one");', 'after' ); 145 $output = get_echo( 'wp_print_scripts' ); 146 147 $expected = "<script type='text/javascript' src='http://example.org/ms-insa-3.js' id='ms-insa-3-js'></script>\n"; 148 $expected .= wp_get_inline_script_tag( 149 "console.log(\"after one\");\n", 150 array( 151 'id' => 'ms-insa-3-js-after', 152 ) 153 ); 154 155 $this->assertSame( $expected, $output, 'Inline scripts in the "after" position, that are attached to a blocking main script, are failing to print/execute.' ); 156 } 157 158 /** 159 * Tests that inline scripts in the `before` position, attached to a delayed inline main script, results in all 160 * dependents being delayed. 161 * 162 * @ticket 12009 163 * 164 * @covers WP_Scripts::do_item 165 * @covers WP_Scripts::get_inline_script_tag 166 * @covers ::wp_add_inline_script 167 * @covers ::wp_enqueue_script 168 * 169 * @dataProvider data_provider_delayed_strategies 170 * 171 * @param string $strategy 172 */ 173 public function test_before_inline_scripts_with_delayed_main_script( $strategy ) { 174 wp_enqueue_script( 'ds-i1-1', 'http://example.org/ds-i1-1.js', array(), null, compact( 'strategy' ) ); 175 wp_add_inline_script( 'ds-i1-1', 'console.log("before first");', 'before' ); 176 wp_enqueue_script( 'ds-i1-2', 'http://example.org/ds-i1-2.js', array(), null, compact( 'strategy' ) ); 177 wp_enqueue_script( 'ds-i1-3', 'http://example.org/ds-i1-3.js', array(), null, compact( 'strategy' ) ); 178 wp_enqueue_script( 'ms-i1-1', 'http://example.org/ms-i1-1.js', array( 'ds-i1-1', 'ds-i1-2', 'ds-i1-3' ), null, compact( 'strategy' ) ); 179 wp_add_inline_script( 'ms-i1-1', 'console.log("before last");', 'before' ); 180 $output = get_echo( 'wp_print_scripts' ); 181 182 $expected = wp_get_inline_script_tag( 183 "console.log(\"before first\");\n", 184 array( 185 'id' => 'ds-i1-1-js-before', 186 ) 187 ); 188 $expected .= "<script type='text/javascript' src='http://example.org/ds-i1-1.js' id='ds-i1-1-js' $strategy data-wp-strategy='{$strategy}'></script>\n"; 189 $expected .= "<script type='text/javascript' src='http://example.org/ds-i1-2.js' id='ds-i1-2-js' $strategy data-wp-strategy='{$strategy}'></script>\n"; 190 $expected .= "<script type='text/javascript' src='http://example.org/ds-i1-3.js' id='ds-i1-3-js' $strategy data-wp-strategy='{$strategy}'></script>\n"; 191 $expected .= wp_get_inline_script_tag( 192 "console.log(\"before last\");\n", 193 array( 194 'id' => 'ms-i1-1-js-before', 195 'type' => 'text/javascript', 196 ) 197 ); 198 $expected .= "<script type='text/javascript' src='http://example.org/ms-i1-1.js' id='ms-i1-1-js' {$strategy} data-wp-strategy='{$strategy}'></script>\n"; 199 200 $this->assertSame( $expected, $output, 'Inline scripts in the "before" position, that are attached to a deferred main script, are failing to print/execute.' ); 201 } 202 203 /** 204 * Tests that scripts registered with an async strategy print with the async attribute. 205 * 206 * @ticket 12009 207 * 208 * @covers WP_Scripts::do_item 209 * @covers WP_Scripts::get_eligible_loading_strategy 210 * @covers WP_Scripts::filter_eligible_strategies 211 * @covers ::wp_enqueue_script 212 */ 213 public function test_loading_strategy_with_valid_async_registration() { 214 // No dependents, No dependencies then async. 215 wp_enqueue_script( 'main-script-a1', '/main-script-a1.js', array(), null, array( 'strategy' => 'async' ) ); 216 $output = get_echo( 'wp_print_scripts' ); 217 $expected = "<script type='text/javascript' src='/main-script-a1.js' id='main-script-a1-js' async data-wp-strategy='async'></script>\n"; 218 $this->assertSame( $expected, $output, 'Scripts enqueued with an async loading strategy are failing to have the async attribute applied to the script handle when being printed.' ); 219 } 220 221 /** 222 * Tests that dependents of a blocking dependency script are free to contain any strategy. 223 * 224 * @ticket 12009 225 * 226 * @covers WP_Scripts::do_item 227 * @covers WP_Scripts::get_eligible_loading_strategy 228 * @covers WP_Scripts::filter_eligible_strategies 229 * @covers ::wp_enqueue_script 230 * 231 * @dataProvider data_provider_delayed_strategies 232 * 233 * @param string $strategy Strategy. 234 */ 235 public function test_delayed_dependent_with_blocking_dependency( $strategy ) { 236 wp_enqueue_script( 'dependency-script-a2', '/dependency-script-a2.js', array(), null ); 237 wp_enqueue_script( 'main-script-a2', '/main-script-a2.js', array( 'dependency-script-a2' ), null, compact( 'strategy' ) ); 238 $output = get_echo( 'wp_print_scripts' ); 239 $expected = "<script type='text/javascript' src='/main-script-a2.js' id='main-script-a2-js' {$strategy} data-wp-strategy='{$strategy}'></script>"; 240 $this->assertStringContainsString( $expected, $output, 'Dependents of a blocking dependency are free to have any strategy.' ); 241 } 242 243 /** 244 * Tests that blocking dependents force delayed dependencies to become blocking. 245 * 246 * @ticket 12009 247 * 248 * @covers WP_Scripts::do_item 249 * @covers WP_Scripts::get_eligible_loading_strategy 250 * @covers WP_Scripts::filter_eligible_strategies 251 * @covers ::wp_enqueue_script 252 * 253 * @dataProvider data_provider_delayed_strategies 254 * @param string $strategy Strategy. 255 */ 256 public function test_blocking_dependent_with_delayed_dependency( $strategy ) { 257 wp_enqueue_script( 'main-script-a3', '/main-script-a3.js', array(), null, compact( 'strategy' ) ); 258 wp_enqueue_script( 'dependent-script-a3', '/dependent-script-a3.js', array( 'main-script-a3' ), null ); 259 $output = get_echo( 'wp_print_scripts' ); 260 $expected = "<script type='text/javascript' src='/main-script-a3.js' id='main-script-a3-js' data-wp-strategy='{$strategy}'></script>"; 261 $this->assertStringContainsString( $expected, $output, 'Blocking dependents must force delayed dependencies to become blocking.' ); 262 } 263 264 /** 265 * Tests that only enqueued dependents effect the eligible loading strategy. 266 * 267 * @ticket 12009 268 * 269 * @covers WP_Scripts::do_item 270 * @covers WP_Scripts::get_eligible_loading_strategy 271 * @covers WP_Scripts::filter_eligible_strategies 272 * @covers ::wp_enqueue_script 273 * 274 * @dataProvider data_provider_delayed_strategies 275 * @param string $strategy Strategy. 276 */ 277 public function test_delayed_dependent_with_blocking_dependency_not_enqueued( $strategy ) { 278 wp_enqueue_script( 'main-script-a4', '/main-script-a4.js', array(), null, compact( 'strategy' ) ); 279 // This dependent is registered but not enqueued, so it should not factor into the eligible loading strategy. 280 wp_register_script( 'dependent-script-a4', '/dependent-script-a4.js', array( 'main-script-a4' ), null ); 281 $output = get_echo( 'wp_print_scripts' ); 282 $expected = "<script type='text/javascript' src='/main-script-a4.js' id='main-script-a4-js' {$strategy} data-wp-strategy='{$strategy}'></script>"; 283 $this->assertStringContainsString( $expected, $output, 'Only enqueued dependents should affect the eligible strategy.' ); 284 } 285 286 /** 287 * Data provider for test_filter_eligible_strategies. 288 * 289 * @return array 290 */ 291 public function get_data_to_filter_eligible_strategies() { 292 return array( 293 'no_dependents' => array( 294 'set_up' => static function () { 295 wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), null, array( 'strategy' => 'defer' ) ); 296 return 'foo'; 297 }, 298 'expected' => array( 'defer' ), 299 ), 300 'one_delayed_dependent' => array( 301 'set_up' => static function () { 302 wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), null, array( 'strategy' => 'defer' ) ); 303 wp_enqueue_script( 'bar', 'https://example.com/bar.js', array( 'foo' ), null, array( 'strategy' => 'defer' ) ); 304 return 'foo'; 305 }, 306 'expected' => array( 'defer' ), 307 ), 308 'one_blocking_dependent' => array( 309 'set_up' => static function () { 310 wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), null, array( 'strategy' => 'defer' ) ); 311 wp_enqueue_script( 'bar', 'https://example.com/bar.js', array( 'foo' ), null ); 312 return 'foo'; 313 }, 314 'expected' => array(), 315 ), 316 'one_blocking_dependent_not_enqueued' => array( 317 'set_up' => static function () { 318 wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), null, array( 'strategy' => 'defer' ) ); 319 wp_register_script( 'bar', 'https://example.com/bar.js', array( 'foo' ), null ); 320 return 'foo'; 321 }, 322 'expected' => array( 'defer' ), // Because bar was not enqueued, only foo was. 323 ), 324 'two_delayed_dependents' => array( 325 'set_up' => static function () { 326 wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), null, array( 'strategy' => 'defer' ) ); 327 wp_enqueue_script( 'bar', 'https://example.com/bar.js', array( 'foo' ), null, array( 'strategy' => 'defer' ) ); 328 wp_enqueue_script( 'baz', 'https://example.com/baz.js', array( 'foo' ), null, array( 'strategy' => 'defer' ) ); 329 return 'foo'; 330 }, 331 'expected' => array( 'defer' ), 332 ), 333 'recursion_not_delayed' => array( 334 'set_up' => static function () { 335 wp_enqueue_script( 'foo', 'https://example.com/foo.js', array( 'foo' ), null ); 336 return 'foo'; 337 }, 338 'expected' => array(), 339 ), 340 'recursion_yes_delayed' => array( 341 'set_up' => static function () { 342 wp_enqueue_script( 'foo', 'https://example.com/foo.js', array( 'foo' ), null, array( 'strategy' => 'defer' ) ); 343 return 'foo'; 344 }, 345 'expected' => array( 'defer' ), 346 ), 347 'recursion_triple_level' => array( 348 'set_up' => static function () { 349 wp_enqueue_script( 'foo', 'https://example.com/foo.js', array( 'baz' ), null, array( 'strategy' => 'defer' ) ); 350 wp_enqueue_script( 'bar', 'https://example.com/bar.js', array( 'foo' ), null, array( 'strategy' => 'defer' ) ); 351 wp_enqueue_script( 'baz', 'https://example.com/bar.js', array( 'bar' ), null, array( 'strategy' => 'defer' ) ); 352 return 'foo'; 353 }, 354 'expected' => array( 'defer' ), 355 ), 356 'async_only_with_async_dependency' => array( 357 'set_up' => static function () { 358 wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), null, array( 'strategy' => 'async' ) ); 359 wp_enqueue_script( 'bar', 'https://example.com/bar.js', array( 'foo' ), null, array( 'strategy' => 'async' ) ); 360 return 'foo'; 361 }, 362 'expected' => array( 'defer', 'async' ), 363 ), 364 'async_only_with_defer_dependency' => array( 365 'set_up' => static function () { 366 wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), null, array( 'strategy' => 'async' ) ); 367 wp_enqueue_script( 'bar', 'https://example.com/bar.js', array( 'foo' ), null, array( 'strategy' => 'defer' ) ); 368 return 'foo'; 369 }, 370 'expected' => array( 'defer' ), 371 ), 372 'async_only_with_blocking_dependency' => array( 373 'set_up' => static function () { 374 wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), null, array( 'strategy' => 'async' ) ); 375 wp_enqueue_script( 'bar', 'https://example.com/bar.js', array( 'foo' ), null ); 376 return 'foo'; 377 }, 378 'expected' => array(), 379 ), 380 'defer_with_inline_after_script' => array( 381 'set_up' => static function () { 382 wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), null, array( 'strategy' => 'defer' ) ); 383 wp_add_inline_script( 'foo', 'console.log("foo")', 'after' ); 384 return 'foo'; 385 }, 386 'expected' => array(), 387 ), 388 'defer_with_inline_before_script' => array( 389 'set_up' => static function () { 390 wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), null, array( 'strategy' => 'defer' ) ); 391 wp_add_inline_script( 'foo', 'console.log("foo")', 'before' ); 392 return 'foo'; 393 }, 394 'expected' => array( 'defer' ), 395 ), 396 'async_with_inline_after_script' => array( 397 'set_up' => static function () { 398 wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), null, array( 'strategy' => 'async' ) ); 399 wp_add_inline_script( 'foo', 'console.log("foo")', 'after' ); 400 return 'foo'; 401 }, 402 'expected' => array(), 403 ), 404 'async_with_inline_before_script' => array( 405 'set_up' => static function () { 406 wp_enqueue_script( 'foo', 'https://example.com/foo.js', array(), null, array( 'strategy' => 'async' ) ); 407 wp_add_inline_script( 'foo', 'console.log("foo")', 'before' ); 408 return 'foo'; 409 }, 410 'expected' => array( 'defer', 'async' ), 411 ), 412 ); 413 } 414 415 /** 416 * Tests that the filter_eligible_strategies method works as expected and returns the correct value. 417 * 418 * @ticket 12009 419 * 420 * @covers WP_Scripts::filter_eligible_strategies 421 * 422 * @dataProvider get_data_to_filter_eligible_strategies 423 * 424 * @param callable $set_up Set up. 425 * @param bool $async_only Async only. 426 * @param bool $expected Expected return value. 427 */ 428 public function test_filter_eligible_strategies( $set_up, $expected ) { 429 $handle = $set_up(); 430 431 $wp_scripts_reflection = new ReflectionClass( WP_Scripts::class ); 432 $filter_eligible_strategies = $wp_scripts_reflection->getMethod( 'filter_eligible_strategies' ); 433 $filter_eligible_strategies->setAccessible( true ); 434 $this->assertSame( $expected, $filter_eligible_strategies->invokeArgs( wp_scripts(), array( $handle ) ), 'Expected return value of WP_Scripts::filter_eligible_strategies to match.' ); 435 } 436 437 /** 438 * Register test script. 439 * 440 * @param string $handle Dependency handle to enqueue. 441 * @param string $strategy Strategy to use for dependency. 442 * @param string[] $deps Dependencies for the script. 443 * @param bool $in_footer Whether to print the script in the footer. 444 */ 445 protected function register_test_script( $handle, $strategy, $deps = array(), $in_footer = false ) { 446 wp_register_script( 447 $handle, 448 add_query_arg( 449 array( 450 'script_event_log' => "$handle: script", 451 ), 452 'https://example.com/external.js' 453 ), 454 $deps, 455 null 456 ); 457 if ( 'blocking' !== $strategy ) { 458 wp_script_add_data( $handle, 'strategy', $strategy ); 459 } 460 } 461 462 /** 463 * Enqueue test script. 464 * 465 * @param string $handle Dependency handle to enqueue. 466 * @param string $strategy Strategy to use for dependency. 467 * @param string[] $deps Dependencies for the script. 468 * @param bool $in_footer Whether to print the script in the footer. 469 */ 470 protected function enqueue_test_script( $handle, $strategy, $deps = array(), $in_footer = false ) { 471 $this->register_test_script( $handle, $strategy, $deps, $in_footer ); 472 wp_enqueue_script( $handle ); 473 } 474 475 /** 476 * Adds test inline script. 477 * 478 * @param string $handle Dependency handle to enqueue. 479 * @param string $position Position. 480 */ 481 protected function add_test_inline_script( $handle, $position ) { 482 wp_add_inline_script( $handle, sprintf( 'scriptEventLog.push( %s )', wp_json_encode( "{$handle}: {$position} inline" ) ), $position ); 483 } 484 485 /** 486 * Data provider to test various strategy dependency chains. 487 * 488 * @return array[] 489 */ 490 public function data_provider_to_test_various_strategy_dependency_chains() { 491 return array( 492 'async-dependent-with-one-blocking-dependency' => array( 493 'set_up' => function () { 494 $handle1 = 'blocking-not-async-without-dependency'; 495 $handle2 = 'async-with-blocking-dependency'; 496 $this->enqueue_test_script( $handle1, 'blocking', array() ); 497 $this->enqueue_test_script( $handle2, 'async', array( $handle1 ) ); 498 foreach ( array( $handle1, $handle2 ) as $handle ) { 499 $this->add_test_inline_script( $handle, 'before' ); 500 $this->add_test_inline_script( $handle, 'after' ); 501 } 502 }, 503 'expected_markup' => <<<HTML 504 <script id="blocking-not-async-without-dependency-js-before" type="text/javascript"> 505 scriptEventLog.push( "blocking-not-async-without-dependency: before inline" ) 506 </script> 507 <script type='text/javascript' src='https://example.com/external.js?script_event_log=blocking-not-async-without-dependency:%20script' id='blocking-not-async-without-dependency-js'></script> 508 <script id="blocking-not-async-without-dependency-js-after" type="text/javascript"> 509 scriptEventLog.push( "blocking-not-async-without-dependency: after inline" ) 510 </script> 511 <script id="async-with-blocking-dependency-js-before" type="text/javascript"> 512 scriptEventLog.push( "async-with-blocking-dependency: before inline" ) 513 </script> 514 <script type='text/javascript' src='https://example.com/external.js?script_event_log=async-with-blocking-dependency:%20script' id='async-with-blocking-dependency-js' data-wp-strategy='async'></script> 515 <script id="async-with-blocking-dependency-js-after" type="text/javascript"> 516 scriptEventLog.push( "async-with-blocking-dependency: after inline" ) 517 </script> 518 HTML 519 , 520 /* 521 * Note: The above comma must be on its own line in PHP<7.3 and not after the `HTML` identifier 522 * terminating the heredoc. Otherwise, a syntax error is raised with the line number being wildly wrong: 523 * 524 * PHP Parse error: syntax error, unexpected '' (T_ENCAPSED_AND_WHITESPACE), expecting '-' or identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING) 525 */ 526 ), 527 'async-with-async-dependencies' => array( 528 'set_up' => function () { 529 $handle1 = 'async-no-dependency'; 530 $handle2 = 'async-one-async-dependency'; 531 $handle3 = 'async-two-async-dependencies'; 532 $this->enqueue_test_script( $handle1, 'async', array() ); 533 $this->enqueue_test_script( $handle2, 'async', array( $handle1 ) ); 534 $this->enqueue_test_script( $handle3, 'async', array( $handle1, $handle2 ) ); 535 foreach ( array( $handle1, $handle2, $handle3 ) as $handle ) { 536 $this->add_test_inline_script( $handle, 'before' ); 537 $this->add_test_inline_script( $handle, 'after' ); 538 } 539 }, 540 'expected_markup' => <<<HTML 541 <script id="async-no-dependency-js-before" type="text/javascript"> 542 scriptEventLog.push( "async-no-dependency: before inline" ) 543 </script> 544 <script type='text/javascript' src='https://example.com/external.js?script_event_log=async-no-dependency:%20script' id='async-no-dependency-js' data-wp-strategy='async'></script> 545 <script id="async-no-dependency-js-after" type="text/javascript"> 546 scriptEventLog.push( "async-no-dependency: after inline" ) 547 </script> 548 <script id="async-one-async-dependency-js-before" type="text/javascript"> 549 scriptEventLog.push( "async-one-async-dependency: before inline" ) 550 </script> 551 <script type='text/javascript' src='https://example.com/external.js?script_event_log=async-one-async-dependency:%20script' id='async-one-async-dependency-js' data-wp-strategy='async'></script> 552 <script id="async-one-async-dependency-js-after" type="text/javascript"> 553 scriptEventLog.push( "async-one-async-dependency: after inline" ) 554 </script> 555 <script id="async-two-async-dependencies-js-before" type="text/javascript"> 556 scriptEventLog.push( "async-two-async-dependencies: before inline" ) 557 </script> 558 <script type='text/javascript' src='https://example.com/external.js?script_event_log=async-two-async-dependencies:%20script' id='async-two-async-dependencies-js' data-wp-strategy='async'></script> 559 <script id="async-two-async-dependencies-js-after" type="text/javascript"> 560 scriptEventLog.push( "async-two-async-dependencies: after inline" ) 561 </script> 562 HTML 563 , 564 ), 565 'async-with-blocking-dependency' => array( 566 'set_up' => function () { 567 $handle1 = 'async-with-blocking-dependent'; 568 $handle2 = 'blocking-dependent-of-async'; 569 $this->enqueue_test_script( $handle1, 'async', array() ); 570 $this->enqueue_test_script( $handle2, 'blocking', array( $handle1 ) ); 571 foreach ( array( $handle1, $handle2 ) as $handle ) { 572 $this->add_test_inline_script( $handle, 'before' ); 573 $this->add_test_inline_script( $handle, 'after' ); 574 } 575 }, 576 'expected_markup' => <<<HTML 577 <script id="async-with-blocking-dependent-js-before" type="text/javascript"> 578 scriptEventLog.push( "async-with-blocking-dependent: before inline" ) 579 </script> 580 <script type='text/javascript' src='https://example.com/external.js?script_event_log=async-with-blocking-dependent:%20script' id='async-with-blocking-dependent-js' data-wp-strategy='async'></script> 581 <script id="async-with-blocking-dependent-js-after" type="text/javascript"> 582 scriptEventLog.push( "async-with-blocking-dependent: after inline" ) 583 </script> 584 <script id="blocking-dependent-of-async-js-before" type="text/javascript"> 585 scriptEventLog.push( "blocking-dependent-of-async: before inline" ) 586 </script> 587 <script type='text/javascript' src='https://example.com/external.js?script_event_log=blocking-dependent-of-async:%20script' id='blocking-dependent-of-async-js'></script> 588 <script id="blocking-dependent-of-async-js-after" type="text/javascript"> 589 scriptEventLog.push( "blocking-dependent-of-async: after inline" ) 590 </script> 591 HTML 592 , 593 ), 594 'defer-with-async-dependency' => array( 595 'set_up' => function () { 596 $handle1 = 'async-with-defer-dependent'; 597 $handle2 = 'defer-dependent-of-async'; 598 $this->enqueue_test_script( $handle1, 'async', array() ); 599 $this->enqueue_test_script( $handle2, 'defer', array( $handle1 ) ); 600 foreach ( array( $handle1, $handle2 ) as $handle ) { 601 $this->add_test_inline_script( $handle, 'before' ); 602 $this->add_test_inline_script( $handle, 'after' ); 603 } 604 }, 605 'expected_markup' => <<<HTML 606 <script id="async-with-defer-dependent-js-before" type="text/javascript"> 607 scriptEventLog.push( "async-with-defer-dependent: before inline" ) 608 </script> 609 <script type='text/javascript' src='https://example.com/external.js?script_event_log=async-with-defer-dependent:%20script' id='async-with-defer-dependent-js' data-wp-strategy='async'></script> 610 <script id="async-with-defer-dependent-js-after" type="text/javascript"> 611 scriptEventLog.push( "async-with-defer-dependent: after inline" ) 612 </script> 613 <script id="defer-dependent-of-async-js-before" type="text/javascript"> 614 scriptEventLog.push( "defer-dependent-of-async: before inline" ) 615 </script> 616 <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependent-of-async:%20script' id='defer-dependent-of-async-js' data-wp-strategy='defer'></script> 617 <script id="defer-dependent-of-async-js-after" type="text/javascript"> 618 scriptEventLog.push( "defer-dependent-of-async: after inline" ) 619 </script> 620 HTML 621 , 622 ), 623 'blocking-bundle-of-none-with-inline-scripts-and-defer-dependent' => array( 624 'set_up' => function () { 625 $handle1 = 'blocking-bundle-of-none'; 626 $handle2 = 'defer-dependent-of-blocking-bundle-of-none'; 627 628 wp_register_script( $handle1, false, array(), null ); 629 $this->add_test_inline_script( $handle1, 'before' ); 630 $this->add_test_inline_script( $handle1, 'after' ); 631 632 // Note: the before script for this will be blocking because the dependency is blocking. 633 $this->enqueue_test_script( $handle2, 'defer', array( $handle1 ) ); 634 $this->add_test_inline_script( $handle2, 'before' ); 635 $this->add_test_inline_script( $handle2, 'after' ); 636 }, 637 'expected_markup' => <<<HTML 638 <script id="blocking-bundle-of-none-js-before" type="text/javascript"> 639 scriptEventLog.push( "blocking-bundle-of-none: before inline" ) 640 </script> 641 <script id="blocking-bundle-of-none-js-after" type="text/javascript"> 642 scriptEventLog.push( "blocking-bundle-of-none: after inline" ) 643 </script> 644 <script id="defer-dependent-of-blocking-bundle-of-none-js-before" type="text/javascript"> 645 scriptEventLog.push( "defer-dependent-of-blocking-bundle-of-none: before inline" ) 646 </script> 647 <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependent-of-blocking-bundle-of-none:%20script' id='defer-dependent-of-blocking-bundle-of-none-js' data-wp-strategy='defer'></script> 648 <script id="defer-dependent-of-blocking-bundle-of-none-js-after" type="text/javascript"> 649 scriptEventLog.push( "defer-dependent-of-blocking-bundle-of-none: after inline" ) 650 </script> 651 HTML 652 , 653 ), 654 'blocking-bundle-of-two-with-defer-dependent' => array( 655 'set_up' => function () { 656 $handle1 = 'blocking-bundle-of-two'; 657 $handle2 = 'blocking-bundle-member-one'; 658 $handle3 = 'blocking-bundle-member-two'; 659 $handle4 = 'defer-dependent-of-blocking-bundle-of-two'; 660 661 wp_register_script( $handle1, false, array( $handle2, $handle3 ), null ); 662 $this->enqueue_test_script( $handle2, 'blocking' ); 663 $this->enqueue_test_script( $handle3, 'blocking' ); 664 $this->enqueue_test_script( $handle4, 'defer', array( $handle1 ) ); 665 666 foreach ( array( $handle2, $handle3, $handle4 ) as $handle ) { 667 $this->add_test_inline_script( $handle, 'before' ); 668 $this->add_test_inline_script( $handle, 'after' ); 669 } 670 }, 671 'expected_markup' => <<<HTML 672 <script id="blocking-bundle-member-one-js-before" type="text/javascript"> 673 scriptEventLog.push( "blocking-bundle-member-one: before inline" ) 674 </script> 675 <script type='text/javascript' src='https://example.com/external.js?script_event_log=blocking-bundle-member-one:%20script' id='blocking-bundle-member-one-js'></script> 676 <script id="blocking-bundle-member-one-js-after" type="text/javascript"> 677 scriptEventLog.push( "blocking-bundle-member-one: after inline" ) 678 </script> 679 <script id="blocking-bundle-member-two-js-before" type="text/javascript"> 680 scriptEventLog.push( "blocking-bundle-member-two: before inline" ) 681 </script> 682 <script type='text/javascript' src='https://example.com/external.js?script_event_log=blocking-bundle-member-two:%20script' id='blocking-bundle-member-two-js'></script> 683 <script id="blocking-bundle-member-two-js-after" type="text/javascript"> 684 scriptEventLog.push( "blocking-bundle-member-two: after inline" ) 685 </script> 686 <script id="defer-dependent-of-blocking-bundle-of-two-js-before" type="text/javascript"> 687 scriptEventLog.push( "defer-dependent-of-blocking-bundle-of-two: before inline" ) 688 </script> 689 <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependent-of-blocking-bundle-of-two:%20script' id='defer-dependent-of-blocking-bundle-of-two-js' data-wp-strategy='defer'></script> 690 <script id="defer-dependent-of-blocking-bundle-of-two-js-after" type="text/javascript"> 691 scriptEventLog.push( "defer-dependent-of-blocking-bundle-of-two: after inline" ) 692 </script> 693 HTML 694 , 695 ), 696 'defer-bundle-of-none-with-inline-scripts-and-defer-dependents' => array( 697 'set_up' => function () { 698 $handle1 = 'defer-bundle-of-none'; 699 $handle2 = 'defer-dependent-of-defer-bundle-of-none'; 700 701 // The eligible loading strategy for this will be forced to be blocking when rendered since $src = false. 702 wp_register_script( $handle1, false, array(), null ); 703 wp_scripts()->registered[ $handle1 ]->extra['strategy'] = 'defer'; // Bypass wp_script_add_data() which should no-op with _doing_it_wrong() because of $src=false. 704 $this->add_test_inline_script( $handle1, 'before' ); 705 $this->add_test_inline_script( $handle1, 'after' ); 706 707 // Note: the before script for this will be blocking because the dependency is blocking. 708 $this->enqueue_test_script( $handle2, 'defer', array( $handle1 ) ); 709 $this->add_test_inline_script( $handle2, 'before' ); 710 $this->add_test_inline_script( $handle2, 'after' ); 711 }, 712 'expected_markup' => <<<HTML 713 <script id="defer-bundle-of-none-js-before" type="text/javascript"> 714 scriptEventLog.push( "defer-bundle-of-none: before inline" ) 715 </script> 716 <script id="defer-bundle-of-none-js-after" type="text/javascript"> 717 scriptEventLog.push( "defer-bundle-of-none: after inline" ) 718 </script> 719 <script id="defer-dependent-of-defer-bundle-of-none-js-before" type="text/javascript"> 720 scriptEventLog.push( "defer-dependent-of-defer-bundle-of-none: before inline" ) 721 </script> 722 <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependent-of-defer-bundle-of-none:%20script' id='defer-dependent-of-defer-bundle-of-none-js' data-wp-strategy='defer'></script> 723 <script id="defer-dependent-of-defer-bundle-of-none-js-after" type="text/javascript"> 724 scriptEventLog.push( "defer-dependent-of-defer-bundle-of-none: after inline" ) 725 </script> 726 HTML 727 , 728 ), 729 'defer-dependent-with-blocking-and-defer-dependencies' => array( 730 'set_up' => function () { 731 $handle1 = 'blocking-dependency-with-defer-following-dependency'; 732 $handle2 = 'defer-dependency-with-blocking-preceding-dependency'; 733 $handle3 = 'defer-dependent-of-blocking-and-defer-dependencies'; 734 $this->enqueue_test_script( $handle1, 'blocking', array() ); 735 $this->enqueue_test_script( $handle2, 'defer', array() ); 736 $this->enqueue_test_script( $handle3, 'defer', array( $handle1, $handle2 ) ); 737 738 foreach ( array( $handle1, $handle2, $handle3 ) as $dep ) { 739 $this->add_test_inline_script( $dep, 'before' ); 740 $this->add_test_inline_script( $dep, 'after' ); 741 } 742 }, 743 'expected_markup' => <<<HTML 744 <script id="blocking-dependency-with-defer-following-dependency-js-before" type="text/javascript"> 745 scriptEventLog.push( "blocking-dependency-with-defer-following-dependency: before inline" ) 746 </script> 747 <script type='text/javascript' src='https://example.com/external.js?script_event_log=blocking-dependency-with-defer-following-dependency:%20script' id='blocking-dependency-with-defer-following-dependency-js'></script> 748 <script id="blocking-dependency-with-defer-following-dependency-js-after" type="text/javascript"> 749 scriptEventLog.push( "blocking-dependency-with-defer-following-dependency: after inline" ) 750 </script> 751 <script id="defer-dependency-with-blocking-preceding-dependency-js-before" type="text/javascript"> 752 scriptEventLog.push( "defer-dependency-with-blocking-preceding-dependency: before inline" ) 753 </script> 754 <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependency-with-blocking-preceding-dependency:%20script' id='defer-dependency-with-blocking-preceding-dependency-js' data-wp-strategy='defer'></script> 755 <script id="defer-dependency-with-blocking-preceding-dependency-js-after" type="text/javascript"> 756 scriptEventLog.push( "defer-dependency-with-blocking-preceding-dependency: after inline" ) 757 </script> 758 <script id="defer-dependent-of-blocking-and-defer-dependencies-js-before" type="text/javascript"> 759 scriptEventLog.push( "defer-dependent-of-blocking-and-defer-dependencies: before inline" ) 760 </script> 761 <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependent-of-blocking-and-defer-dependencies:%20script' id='defer-dependent-of-blocking-and-defer-dependencies-js' data-wp-strategy='defer'></script> 762 <script id="defer-dependent-of-blocking-and-defer-dependencies-js-after" type="text/javascript"> 763 scriptEventLog.push( "defer-dependent-of-blocking-and-defer-dependencies: after inline" ) 764 </script> 765 HTML 766 , 767 ), 768 'defer-dependent-with-defer-and-blocking-dependencies' => array( 769 'set_up' => function () { 770 $handle1 = 'defer-dependency-with-blocking-following-dependency'; 771 $handle2 = 'blocking-dependency-with-defer-preceding-dependency'; 772 $handle3 = 'defer-dependent-of-defer-and-blocking-dependencies'; 773 $this->enqueue_test_script( $handle1, 'defer', array() ); 774 $this->enqueue_test_script( $handle2, 'blocking', array() ); 775 $this->enqueue_test_script( $handle3, 'defer', array( $handle1, $handle2 ) ); 776 777 foreach ( array( $handle1, $handle2, $handle3 ) as $dep ) { 778 $this->add_test_inline_script( $dep, 'before' ); 779 $this->add_test_inline_script( $dep, 'after' ); 780 } 781 }, 782 'expected_markup' => <<<HTML 783 <script id="defer-dependency-with-blocking-following-dependency-js-before" type="text/javascript"> 784 scriptEventLog.push( "defer-dependency-with-blocking-following-dependency: before inline" ) 785 </script> 786 <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependency-with-blocking-following-dependency:%20script' id='defer-dependency-with-blocking-following-dependency-js' data-wp-strategy='defer'></script> 787 <script id="defer-dependency-with-blocking-following-dependency-js-after" type="text/javascript"> 788 scriptEventLog.push( "defer-dependency-with-blocking-following-dependency: after inline" ) 789 </script> 790 <script id="blocking-dependency-with-defer-preceding-dependency-js-before" type="text/javascript"> 791 scriptEventLog.push( "blocking-dependency-with-defer-preceding-dependency: before inline" ) 792 </script> 793 <script type='text/javascript' src='https://example.com/external.js?script_event_log=blocking-dependency-with-defer-preceding-dependency:%20script' id='blocking-dependency-with-defer-preceding-dependency-js'></script> 794 <script id="blocking-dependency-with-defer-preceding-dependency-js-after" type="text/javascript"> 795 scriptEventLog.push( "blocking-dependency-with-defer-preceding-dependency: after inline" ) 796 </script> 797 <script id="defer-dependent-of-defer-and-blocking-dependencies-js-before" type="text/javascript"> 798 scriptEventLog.push( "defer-dependent-of-defer-and-blocking-dependencies: before inline" ) 799 </script> 800 <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependent-of-defer-and-blocking-dependencies:%20script' id='defer-dependent-of-defer-and-blocking-dependencies-js' data-wp-strategy='defer'></script> 801 <script id="defer-dependent-of-defer-and-blocking-dependencies-js-after" type="text/javascript"> 802 scriptEventLog.push( "defer-dependent-of-defer-and-blocking-dependencies: after inline" ) 803 </script> 804 HTML 805 , 806 ), 807 'async-with-defer-dependency' => array( 808 'set_up' => function () { 809 $handle1 = 'defer-with-async-dependent'; 810 $handle2 = 'async-dependent-of-defer'; 811 $this->enqueue_test_script( $handle1, 'defer', array() ); 812 $this->enqueue_test_script( $handle2, 'async', array( $handle1 ) ); 813 foreach ( array( $handle1, $handle2 ) as $handle ) { 814 $this->add_test_inline_script( $handle, 'before' ); 815 $this->add_test_inline_script( $handle, 'after' ); 816 } 817 }, 818 'expected_markup' => <<<HTML 819 <script id="defer-with-async-dependent-js-before" type="text/javascript"> 820 scriptEventLog.push( "defer-with-async-dependent: before inline" ) 821 </script> 822 <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-with-async-dependent:%20script' id='defer-with-async-dependent-js' data-wp-strategy='defer'></script> 823 <script id="defer-with-async-dependent-js-after" type="text/javascript"> 824 scriptEventLog.push( "defer-with-async-dependent: after inline" ) 825 </script> 826 <script id="async-dependent-of-defer-js-before" type="text/javascript"> 827 scriptEventLog.push( "async-dependent-of-defer: before inline" ) 828 </script> 829 <script type='text/javascript' src='https://example.com/external.js?script_event_log=async-dependent-of-defer:%20script' id='async-dependent-of-defer-js' data-wp-strategy='async'></script> 830 <script id="async-dependent-of-defer-js-after" type="text/javascript"> 831 scriptEventLog.push( "async-dependent-of-defer: after inline" ) 832 </script> 833 HTML 834 , 835 ), 836 'defer-with-before-inline-script' => array( 837 'set_up' => function () { 838 // Note this should NOT result in no delayed-inline-script-loader script being added. 839 $handle = 'defer-with-before-inline'; 840 $this->enqueue_test_script( $handle, 'defer', array() ); 841 $this->add_test_inline_script( $handle, 'before' ); 842 }, 843 'expected_markup' => <<<HTML 844 <script id="defer-with-before-inline-js-before" type="text/javascript"> 845 scriptEventLog.push( "defer-with-before-inline: before inline" ) 846 </script> 847 <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-with-before-inline:%20script' id='defer-with-before-inline-js' defer data-wp-strategy='defer'></script> 848 HTML 849 , 850 ), 851 'defer-with-after-inline-script' => array( 852 'set_up' => function () { 853 // Note this SHOULD result in delayed-inline-script-loader script being added. 854 $handle = 'defer-with-after-inline'; 855 $this->enqueue_test_script( $handle, 'defer', array() ); 856 $this->add_test_inline_script( $handle, 'after' ); 857 }, 858 'expected_markup' => <<<HTML 859 <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-with-after-inline:%20script' id='defer-with-after-inline-js' data-wp-strategy='defer'></script> 860 <script id="defer-with-after-inline-js-after" type="text/javascript"> 861 scriptEventLog.push( "defer-with-after-inline: after inline" ) 862 </script> 863 HTML 864 , 865 ), 866 'jquery-deferred' => array( 867 'set_up' => function () { 868 $wp_scripts = wp_scripts(); 869 wp_default_scripts( $wp_scripts ); 870 foreach ( $wp_scripts->registered['jquery']->deps as $jquery_dep ) { 871 $wp_scripts->registered[ $jquery_dep ]->add_data( 'strategy', 'defer' ); 872 $wp_scripts->registered[ $jquery_dep ]->ver = null; // Just to avoid markup changes in the test when jQuery is upgraded. 873 } 874 wp_enqueue_script( 'theme-functions', 'https://example.com/theme-functions.js', array( 'jquery' ), null, array( 'strategy' => 'defer' ) ); 875 }, 876 'expected_markup' => <<<HTML 877 <script type='text/javascript' src='http://example.org/wp-includes/js/jquery/jquery.js' id='jquery-core-js' defer data-wp-strategy='defer'></script> 878 <script type='text/javascript' src='http://example.org/wp-includes/js/jquery/jquery-migrate.js' id='jquery-migrate-js' defer data-wp-strategy='defer'></script> 879 <script type='text/javascript' src='https://example.com/theme-functions.js' id='theme-functions-js' defer data-wp-strategy='defer'></script> 880 HTML 881 , 882 ), 883 'nested-aliases' => array( 884 'set_up' => function () { 885 $outer_alias_handle = 'outer-bundle-of-two'; 886 $inner_alias_handle = 'inner-bundle-of-two'; 887 888 // The outer alias contains a blocking member, as well as a nested alias that contains defer scripts. 889 wp_register_script( $outer_alias_handle, false, array( $inner_alias_handle, 'outer-bundle-leaf-member' ), null ); 890 $this->register_test_script( 'outer-bundle-leaf-member', 'blocking', array() ); 891 892 // Inner alias only contains delay scripts. 893 wp_register_script( $inner_alias_handle, false, array( 'inner-bundle-member-one', 'inner-bundle-member-two' ), null ); 894 $this->register_test_script( 'inner-bundle-member-one', 'defer', array() ); 895 $this->register_test_script( 'inner-bundle-member-two', 'defer', array() ); 896 897 $this->enqueue_test_script( 'defer-dependent-of-nested-aliases', 'defer', array( $outer_alias_handle ) ); 898 $this->add_test_inline_script( 'defer-dependent-of-nested-aliases', 'before' ); 899 $this->add_test_inline_script( 'defer-dependent-of-nested-aliases', 'after' ); 900 }, 901 'expected_markup' => <<<HTML 902 <script type='text/javascript' src='https://example.com/external.js?script_event_log=inner-bundle-member-one:%20script' id='inner-bundle-member-one-js' data-wp-strategy='defer'></script> 903 <script type='text/javascript' src='https://example.com/external.js?script_event_log=inner-bundle-member-two:%20script' id='inner-bundle-member-two-js' data-wp-strategy='defer'></script> 904 <script type='text/javascript' src='https://example.com/external.js?script_event_log=outer-bundle-leaf-member:%20script' id='outer-bundle-leaf-member-js'></script> 905 <script id="defer-dependent-of-nested-aliases-js-before" type="text/javascript"> 906 scriptEventLog.push( "defer-dependent-of-nested-aliases: before inline" ) 907 </script> 908 <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependent-of-nested-aliases:%20script' id='defer-dependent-of-nested-aliases-js' data-wp-strategy='defer'></script> 909 <script id="defer-dependent-of-nested-aliases-js-after" type="text/javascript"> 910 scriptEventLog.push( "defer-dependent-of-nested-aliases: after inline" ) 911 </script> 912 HTML 913 , 914 ), 915 916 'async-alias-members-with-defer-dependency' => array( 917 'set_up' => function () { 918 $alias_handle = 'async-alias'; 919 $async_handle1 = 'async1'; 920 $async_handle2 = 'async2'; 921 922 wp_register_script( $alias_handle, false, array( $async_handle1, $async_handle2 ), null ); 923 $this->register_test_script( $async_handle1, 'async', array() ); 924 $this->register_test_script( $async_handle2, 'async', array() ); 925 926 $this->enqueue_test_script( 'defer-dependent-of-async-aliases', 'defer', array( $alias_handle ) ); 927 }, 928 'expected_markup' => <<<HTML 929 <script type='text/javascript' src='https://example.com/external.js?script_event_log=async1:%20script' id='async1-js' defer data-wp-strategy='async'></script> 930 <script type='text/javascript' src='https://example.com/external.js?script_event_log=async2:%20script' id='async2-js' defer data-wp-strategy='async'></script> 931 <script type='text/javascript' src='https://example.com/external.js?script_event_log=defer-dependent-of-async-aliases:%20script' id='defer-dependent-of-async-aliases-js' defer data-wp-strategy='defer'></script> 932 HTML 933 , 934 ), 935 ); 936 } 937 938 /** 939 * Tests that various loading strategy dependency chains function as expected. 940 * 941 * @covers ::wp_enqueue_script() 942 * @covers ::wp_add_inline_script() 943 * @covers ::wp_print_scripts() 944 * @covers WP_Scripts::get_inline_script_tag 945 * 946 * @dataProvider data_provider_to_test_various_strategy_dependency_chains 947 * 948 * @param callable $set_up Set up. 949 * @param string $expected_markup Expected markup. 950 */ 951 public function test_various_strategy_dependency_chains( $set_up, $expected_markup ) { 952 $set_up(); 953 $actual_markup = get_echo( 'wp_print_scripts' ); 954 $this->assertEqualMarkup( trim( $expected_markup ), trim( $actual_markup ), "Actual markup:\n{$actual_markup}" ); 955 } 956 957 /** 958 * Tests that defer is the final strategy when registering a script using defer, that has no dependents/dependencies. 959 * 960 * @ticket 12009 961 * 962 * @covers WP_Scripts::do_item 963 * @covers WP_Scripts::get_eligible_loading_strategy 964 * @covers ::wp_enqueue_script 965 */ 966 public function test_loading_strategy_with_defer_having_no_dependents_nor_dependencies() { 967 wp_enqueue_script( 'main-script-d1', 'http://example.com/main-script-d1.js', array(), null, array( 'strategy' => 'defer' ) ); 968 $output = get_echo( 'wp_print_scripts' ); 969 $expected = "<script type='text/javascript' src='http://example.com/main-script-d1.js' id='main-script-d1-js' defer data-wp-strategy='defer'></script>\n"; 970 $this->assertStringContainsString( $expected, $output, 'Expected defer, as there is no dependent or dependency' ); 971 } 972 973 /** 974 * Tests that a script registered with defer remains deferred when all dependencies are either deferred or blocking. 975 * 976 * @ticket 12009 977 * 978 * @covers WP_Scripts::do_item 979 * @covers WP_Scripts::get_eligible_loading_strategy 980 * @covers ::wp_enqueue_script 981 */ 982 public function test_loading_strategy_with_defer_dependent_and_varied_dependencies() { 983 wp_enqueue_script( 'dependency-script-d2-1', 'http://example.com/dependency-script-d2-1.js', array(), null, array( 'strategy' => 'defer' ) ); 984 wp_enqueue_script( 'dependency-script-d2-2', 'http://example.com/dependency-script-d2-2.js', array(), null ); 985 wp_enqueue_script( 'dependency-script-d2-3', 'http://example.com/dependency-script-d2-3.js', array( 'dependency-script-d2-2' ), null, array( 'strategy' => 'defer' ) ); 986 wp_enqueue_script( 'main-script-d2', 'http://example.com/main-script-d2.js', array( 'dependency-script-d2-1', 'dependency-script-d2-3' ), null, array( 'strategy' => 'defer' ) ); 987 $output = get_echo( 'wp_print_scripts' ); 988 $expected = "<script type='text/javascript' src='http://example.com/main-script-d2.js' id='main-script-d2-js' defer data-wp-strategy='defer'></script>\n"; 989 $this->assertStringContainsString( $expected, $output, 'Expected defer, as all dependencies are either deferred or blocking' ); 990 } 991 992 /** 993 * Tests that scripts registered with defer remain deferred when all dependents are also deferred. 994 * 995 * @ticket 12009 996 * 997 * @covers WP_Scripts::do_item 998 * @covers WP_Scripts::get_eligible_loading_strategy 999 * @covers ::wp_enqueue_script 1000 */ 1001 public function test_loading_strategy_with_all_defer_dependencies() { 1002 wp_enqueue_script( 'main-script-d3', 'http://example.com/main-script-d3.js', array(), null, array( 'strategy' => 'defer' ) ); 1003 wp_enqueue_script( 'dependent-script-d3-1', 'http://example.com/dependent-script-d3-1.js', array( 'main-script-d3' ), null, array( 'strategy' => 'defer' ) ); 1004 wp_enqueue_script( 'dependent-script-d3-2', 'http://example.com/dependent-script-d3-2.js', array( 'dependent-script-d3-1' ), null, array( 'strategy' => 'defer' ) ); 1005 wp_enqueue_script( 'dependent-script-d3-3', 'http://example.com/dependent-script-d3-3.js', array( 'dependent-script-d3-2' ), null, array( 'strategy' => 'defer' ) ); 1006 $output = get_echo( 'wp_print_scripts' ); 1007 $expected = "<script type='text/javascript' src='http://example.com/main-script-d3.js' id='main-script-d3-js' defer data-wp-strategy='defer'></script>\n"; 1008 $this->assertStringContainsString( $expected, $output, 'Expected defer, as all dependents have defer loading strategy' ); 1009 } 1010 1011 /** 1012 * Tests that dependents that are async but attached to a deferred main script, print with defer as opposed to async. 1013 * 1014 * @ticket 12009 1015 * 1016 * @covers WP_Scripts::do_item 1017 * @covers WP_Scripts::get_eligible_loading_strategy 1018 * @covers ::wp_enqueue_script 1019 */ 1020 public function test_defer_with_async_dependent() { 1021 // case with one async dependent. 1022 wp_enqueue_script( 'main-script-d4', '/main-script-d4.js', array(), null, array( 'strategy' => 'defer' ) ); 1023 wp_enqueue_script( 'dependent-script-d4-1', '/dependent-script-d4-1.js', array( 'main-script-d4' ), null, array( 'strategy' => 'defer' ) ); 1024 wp_enqueue_script( 'dependent-script-d4-2', '/dependent-script-d4-2.js', array( 'dependent-script-d4-1' ), null, array( 'strategy' => 'async' ) ); 1025 wp_enqueue_script( 'dependent-script-d4-3', '/dependent-script-d4-3.js', array( 'dependent-script-d4-2' ), null, array( 'strategy' => 'defer' ) ); 1026 $output = get_echo( 'wp_print_scripts' ); 1027 $expected = "<script type='text/javascript' src='/main-script-d4.js' id='main-script-d4-js' defer data-wp-strategy='defer'></script>\n"; 1028 $expected .= "<script type='text/javascript' src='/dependent-script-d4-1.js' id='dependent-script-d4-1-js' defer data-wp-strategy='defer'></script>\n"; 1029 $expected .= "<script type='text/javascript' src='/dependent-script-d4-2.js' id='dependent-script-d4-2-js' defer data-wp-strategy='async'></script>\n"; 1030 $expected .= "<script type='text/javascript' src='/dependent-script-d4-3.js' id='dependent-script-d4-3-js' defer data-wp-strategy='defer'></script>\n"; 1031 1032 $this->assertSame( $expected, $output, 'Scripts registered as defer but that have dependents that are async are expected to have said dependents deferred.' ); 1033 } 1034 1035 /** 1036 * Tests that scripts registered as defer become blocking when their dependents chain are all blocking. 1037 * 1038 * @ticket 12009 1039 * 1040 * @covers WP_Scripts::do_item 1041 * @covers WP_Scripts::get_eligible_loading_strategy 1042 * @covers WP_Scripts::filter_eligible_strategies 1043 * @covers ::wp_enqueue_script 1044 */ 1045 public function test_loading_strategy_with_invalid_defer_registration() { 1046 // Main script is defer and all dependent are not defer. Then main script will have blocking(or no) strategy. 1047 wp_enqueue_script( 'main-script-d4', '/main-script-d4.js', array(), null, array( 'strategy' => 'defer' ) ); 1048 wp_enqueue_script( 'dependent-script-d4-1', '/dependent-script-d4-1.js', array( 'main-script-d4' ), null, array( 'strategy' => 'defer' ) ); 1049 wp_enqueue_script( 'dependent-script-d4-2', '/dependent-script-d4-2.js', array( 'dependent-script-d4-1' ), null ); 1050 wp_enqueue_script( 'dependent-script-d4-3', '/dependent-script-d4-3.js', array( 'dependent-script-d4-2' ), null, array( 'strategy' => 'defer' ) ); 1051 $output = get_echo( 'wp_print_scripts' ); 1052 $expected = "<script type='text/javascript' src='/main-script-d4.js' id='main-script-d4-js' data-wp-strategy='defer'></script>\n"; 1053 $this->assertStringContainsString( $expected, $output, 'Scripts registered as defer but that have all dependents with no strategy, should become blocking (no strategy).' ); 1054 } 1055 1056 /** 1057 * Tests that scripts registered as default/blocking remain as such when they have no dependencies. 1058 * 1059 * @ticket 12009 1060 * 1061 * @covers WP_Scripts::do_item 1062 * @covers WP_Scripts::get_eligible_loading_strategy 1063 * @covers WP_Scripts::filter_eligible_strategies 1064 * @covers ::wp_enqueue_script 1065 */ 1066 public function test_loading_strategy_with_valid_blocking_registration() { 1067 wp_enqueue_script( 'main-script-b1', '/main-script-b1.js', array(), null ); 1068 $output = get_echo( 'wp_print_scripts' ); 1069 $expected = "<script type='text/javascript' src='/main-script-b1.js' id='main-script-b1-js'></script>\n"; 1070 $this->assertSame( $expected, $output, 'Scripts registered with a "blocking" strategy, and who have no dependencies, should have no loading strategy attributes printed.' ); 1071 1072 // strategy args not set. 1073 wp_enqueue_script( 'main-script-b2', '/main-script-b2.js', array(), null, array() ); 1074 $output = get_echo( 'wp_print_scripts' ); 1075 $expected = "<script type='text/javascript' src='/main-script-b2.js' id='main-script-b2-js'></script>\n"; 1076 $this->assertSame( $expected, $output, 'Scripts registered with no strategy assigned, and who have no dependencies, should have no loading strategy attributes printed.' ); 1077 } 1078 1079 /** 1080 * Tests that scripts registered for the head do indeed end up there. 1081 * 1082 * @ticket 12009 1083 * 1084 * @covers WP_Scripts::do_item 1085 * @covers ::wp_enqueue_script 1086 * @covers ::wp_register_script 1087 */ 1088 public function test_scripts_targeting_head() { 1089 wp_register_script( 'header-old', '/header-old.js', array(), null, false ); 1090 wp_register_script( 'header-new', '/header-new.js', array( 'header-old' ), null, array( 'in_footer' => false ) ); 1091 wp_enqueue_script( 'enqueue-header-old', '/enqueue-header-old.js', array( 'header-new' ), null, false ); 1092 wp_enqueue_script( 'enqueue-header-new', '/enqueue-header-new.js', array( 'enqueue-header-old' ), null, array( 'in_footer' => false ) ); 1093 1094 $actual_header = get_echo( 'wp_print_head_scripts' ); 1095 $actual_footer = get_echo( 'wp_print_scripts' ); 1096 1097 $expected_header = "<script type='text/javascript' src='/header-old.js' id='header-old-js'></script>\n"; 1098 $expected_header .= "<script type='text/javascript' src='/header-new.js' id='header-new-js'></script>\n"; 1099 $expected_header .= "<script type='text/javascript' src='/enqueue-header-old.js' id='enqueue-header-old-js'></script>\n"; 1100 $expected_header .= "<script type='text/javascript' src='/enqueue-header-new.js' id='enqueue-header-new-js'></script>\n"; 1101 1102 $this->assertSame( $expected_header, $actual_header, 'Scripts registered/enqueued using the older $in_footer parameter or the newer $args parameter should have the same outcome.' ); 1103 $this->assertEmpty( $actual_footer, 'Expected footer to be empty since all scripts were for head.' ); 1104 } 1105 1106 /** 1107 * Test that scripts registered for the footer do indeed end up there. 1108 * 1109 * @ticket 12009 1110 * 1111 * @covers WP_Scripts::do_item 1112 * @covers ::wp_enqueue_script 1113 * @covers ::wp_register_script 1114 */ 1115 public function test_scripts_targeting_footer() { 1116 wp_register_script( 'footer-old', '/footer-old.js', array(), null, true ); 1117 wp_register_script( 'footer-new', '/footer-new.js', array( 'footer-old' ), null, array( 'in_footer' => true ) ); 1118 wp_enqueue_script( 'enqueue-footer-old', '/enqueue-footer-old.js', array( 'footer-new' ), null, true ); 1119 wp_enqueue_script( 'enqueue-footer-new', '/enqueue-footer-new.js', array( 'enqueue-footer-old' ), null, array( 'in_footer' => true ) ); 1120 1121 $actual_header = get_echo( 'wp_print_head_scripts' ); 1122 $actual_footer = get_echo( 'wp_print_scripts' ); 1123 1124 $expected_footer = "<script type='text/javascript' src='/footer-old.js' id='footer-old-js'></script>\n"; 1125 $expected_footer .= "<script type='text/javascript' src='/footer-new.js' id='footer-new-js'></script>\n"; 1126 $expected_footer .= "<script type='text/javascript' src='/enqueue-footer-old.js' id='enqueue-footer-old-js'></script>\n"; 1127 $expected_footer .= "<script type='text/javascript' src='/enqueue-footer-new.js' id='enqueue-footer-new-js'></script>\n"; 1128 1129 $this->assertEmpty( $actual_header, 'Expected header to be empty since all scripts targeted footer.' ); 1130 $this->assertSame( $expected_footer, $actual_footer, 'Scripts registered/enqueued using the older $in_footer parameter or the newer $args parameter should have the same outcome.' ); 1131 } 1132 1133 /** 1134 * Data provider for test_setting_in_footer_and_strategy. 1135 * 1136 * @return array[] 1137 */ 1138 public function get_data_for_test_setting_in_footer_and_strategy() { 1139 return array( 1140 // Passing in_footer and strategy via args array. 1141 'async_footer_in_args_array' => array( 1142 'set_up' => static function ( $handle ) { 1143 $args = array( 1144 'in_footer' => true, 1145 'strategy' => 'async', 1146 ); 1147 wp_enqueue_script( $handle, '/footer-async.js', array(), null, $args ); 1148 }, 1149 'group' => 1, 1150 'strategy' => 'async', 1151 ), 1152 1153 // Passing in_footer=true but no strategy. 1154 'blocking_footer_in_args_array' => array( 1155 'set_up' => static function ( $handle ) { 1156 wp_register_script( $handle, '/defaults.js', array(), null, array( 'in_footer' => true ) ); 1157 }, 1158 'group' => 1, 1159 'strategy' => false, 1160 ), 1161 1162 // Passing async strategy in script args array. 1163 'async_in_args_array' => array( 1164 'set_up' => static function ( $handle ) { 1165 wp_register_script( $handle, '/defaults.js', array(), null, array( 'strategy' => 'async' ) ); 1166 }, 1167 'group' => false, 1168 'strategy' => 'async', 1169 ), 1170 1171 // Passing empty array as 5th arg. 1172 'empty_args_array' => array( 1173 'set_up' => static function ( $handle ) { 1174 wp_register_script( $handle, '/defaults.js', array(), null, array() ); 1175 }, 1176 'group' => false, 1177 'strategy' => false, 1178 ), 1179 1180 // Passing no value as 5th arg. 1181 'undefined_args_param' => array( 1182 'set_up' => static function ( $handle ) { 1183 wp_register_script( $handle, '/defaults.js', array(), null ); 1184 }, 1185 'group' => false, 1186 'strategy' => false, 1187 ), 1188 1189 // Test backward compatibility, passing $in_footer=true as 5th arg. 1190 'passing_bool_as_args_param' => array( 1191 'set_up' => static function ( $handle ) { 1192 wp_enqueue_script( $handle, '/footer-async.js', array(), null, true ); 1193 }, 1194 'group' => 1, 1195 'strategy' => false, 1196 ), 1197 1198 // Test backward compatibility, passing $in_footer=true as 5th arg and setting strategy via wp_script_add_data(). 1199 'bool_as_args_and_add_data' => array( 1200 'set_up' => static function ( $handle ) { 1201 wp_register_script( $handle, '/footer-async.js', array(), null, true ); 1202 wp_script_add_data( $handle, 'strategy', 'defer' ); 1203 }, 1204 'group' => 1, 1205 'strategy' => 'defer', 1206 ), 1207 ); 1208 } 1209 1210 /** 1211 * Tests that scripts print in the correct group (head/footer) when using in_footer and assigning a strategy. 1212 * 1213 * @ticket 12009 1214 * 1215 * @covers ::wp_register_script 1216 * @covers ::wp_enqueue_script 1217 * @covers ::wp_script_add_data 1218 * 1219 * @dataProvider get_data_for_test_setting_in_footer_and_strategy 1220 * 1221 * @param callable $set_up Set up. 1222 * @param int|false $expected_group Expected group. 1223 * @param string|false $expected_strategy Expected strategy. 1224 */ 1225 public function test_setting_in_footer_and_strategy( $set_up, $expected_group, $expected_strategy ) { 1226 $handle = 'foo'; 1227 $set_up( $handle ); 1228 $this->assertSame( $expected_group, wp_scripts()->get_data( $handle, 'group' ) ); 1229 $this->assertSame( $expected_strategy, wp_scripts()->get_data( $handle, 'strategy' ) ); 1230 } 1231 1232 /** 1233 * Tests that scripts print with no strategy when an incorrect strategy is passed during wp_register_script. 1234 * 1235 * For an invalid strategy defined during script registration, default to a blocking strategy. 1236 * 1237 * @ticket 12009 1238 * 1239 * @covers WP_Scripts::add_data 1240 * @covers ::wp_register_script 1241 * @covers ::wp_enqueue_script 1242 * 1243 * @expectedIncorrectUsage WP_Scripts::add_data 1244 */ 1245 public function test_script_strategy_doing_it_wrong_via_register() { 1246 wp_register_script( 'invalid-strategy', '/defaults.js', array(), null, array( 'strategy' => 'random-strategy' ) ); 1247 wp_enqueue_script( 'invalid-strategy' ); 1248 1249 $this->assertSame( 1250 "<script type='text/javascript' src='/defaults.js' id='invalid-strategy-js'></script>\n", 1251 get_echo( 'wp_print_scripts' ) 1252 ); 1253 } 1254 1255 /** 1256 * Tests that scripts print with no strategy when an incorrect strategy is passed via wp_script_add_data(). 1257 * 1258 * For an invalid strategy defined during script registration, default to a blocking strategy. 1259 * 1260 * @ticket 12009 1261 * 1262 * @covers WP_Scripts::add_data 1263 * @covers ::wp_script_add_data 1264 * @covers ::wp_register_script 1265 * @covers ::wp_enqueue_script 1266 * 1267 * @expectedIncorrectUsage WP_Scripts::add_data 1268 */ 1269 public function test_script_strategy_doing_it_wrong_via_add_data() { 1270 wp_register_script( 'invalid-strategy', '/defaults.js', array(), null ); 1271 wp_script_add_data( 'invalid-strategy', 'strategy', 'random-strategy' ); 1272 wp_enqueue_script( 'invalid-strategy' ); 1273 1274 $this->assertSame( 1275 "<script type='text/javascript' src='/defaults.js' id='invalid-strategy-js'></script>\n", 1276 get_echo( 'wp_print_scripts' ) 1277 ); 1278 } 1279 1280 /** 1281 * Tests that scripts print with no strategy when an incorrect strategy is passed during wp_enqueue_script. 1282 * 1283 * For an invalid strategy defined during script registration, default to a blocking strategy. 1284 * 1285 * @ticket 12009 1286 * 1287 * @covers WP_Scripts::add_data 1288 * @covers ::wp_enqueue_script 1289 * 1290 * @expectedIncorrectUsage WP_Scripts::add_data 1291 */ 1292 public function test_script_strategy_doing_it_wrong_via_enqueue() { 1293 wp_enqueue_script( 'invalid-strategy', '/defaults.js', array(), null, array( 'strategy' => 'random-strategy' ) ); 1294 1295 $this->assertSame( 1296 "<script type='text/javascript' src='/defaults.js' id='invalid-strategy-js'></script>\n", 1297 get_echo( 'wp_print_scripts' ) 1298 ); 1299 } 1300 1301 /** 1302 * Tests that scripts registered with a deferred strategy are not included in the script concat loading query. 1303 * 1304 * @ticket 12009 1305 * 1306 * @covers WP_Scripts::do_item 1307 * @covers ::wp_enqueue_script 1308 * @covers ::wp_register_script 1309 */ 1310 public function test_concatenate_with_defer_strategy() { 1311 global $wp_scripts, $concatenate_scripts, $wp_version; 1312 1313 $old_value = $concatenate_scripts; 1314 $concatenate_scripts = true; 1315 1316 $wp_scripts->do_concat = true; 1317 $wp_scripts->default_dirs = array( $this->default_scripts_dir ); 1318 1319 wp_register_script( 'one-concat-dep', $this->default_scripts_dir . 'script.js' ); 1320 wp_register_script( 'two-concat-dep', $this->default_scripts_dir . 'script.js' ); 1321 wp_register_script( 'three-concat-dep', $this->default_scripts_dir . 'script.js' ); 1322 wp_enqueue_script( 'main-defer-script', '/main-script.js', array( 'one-concat-dep', 'two-concat-dep', 'three-concat-dep' ), null, array( 'strategy' => 'defer' ) ); 1323 1324 wp_print_scripts(); 1325 $print_scripts = get_echo( '_print_scripts' ); 1326 1327 // Reset global before asserting. 1328 $concatenate_scripts = $old_value; 1329 1330 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=one-concat-dep,two-concat-dep,three-concat-dep&ver={$wp_version}'></script>\n"; 1331 $expected .= "<script type='text/javascript' src='/main-script.js' id='main-defer-script-js' defer data-wp-strategy='defer'></script>\n"; 1332 1333 $this->assertSame( $expected, $print_scripts, 'Scripts are being incorrectly concatenated when a main script is registered with a "defer" loading strategy. Deferred scripts should not be part of the script concat loading query.' ); 1334 } 1335 1336 /** 1337 * Test script concatenation with `async` main script. 1338 * 1339 * @ticket 12009 1340 * 1341 * @covers WP_Scripts::do_item 1342 * @covers ::wp_enqueue_script 1343 * @covers ::wp_register_script 1344 */ 1345 public function test_concatenate_with_async_strategy() { 1346 global $wp_scripts, $concatenate_scripts, $wp_version; 1347 1348 $old_value = $concatenate_scripts; 1349 $concatenate_scripts = true; 1350 1351 $wp_scripts->do_concat = true; 1352 $wp_scripts->default_dirs = array( $this->default_scripts_dir ); 1353 1354 wp_enqueue_script( 'one-concat-dep-1', $this->default_scripts_dir . 'script.js' ); 1355 wp_enqueue_script( 'two-concat-dep-1', $this->default_scripts_dir . 'script.js' ); 1356 wp_enqueue_script( 'three-concat-dep-1', $this->default_scripts_dir . 'script.js' ); 1357 wp_enqueue_script( 'main-async-script-1', '/main-script.js', array(), null, array( 'strategy' => 'async' ) ); 1358 1359 wp_print_scripts(); 1360 $print_scripts = get_echo( '_print_scripts' ); 1361 1362 // Reset global before asserting. 1363 $concatenate_scripts = $old_value; 1364 1365 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=one-concat-dep-1,two-concat-dep-1,three-concat-dep-1&ver={$wp_version}'></script>\n"; 1366 $expected .= "<script type='text/javascript' src='/main-script.js' id='main-async-script-1-js' async data-wp-strategy='async'></script>\n"; 1367 1368 $this->assertSame( $expected, $print_scripts, 'Scripts are being incorrectly concatenated when a main script is registered with an "async" loading strategy. Async scripts should not be part of the script concat loading query.' ); 1369 } 1370 1371 /** 1372 * Tests that script concatenation remains correct when a main script is registered as deferred after other blocking 1373 * scripts are registered. 1374 * 1375 * @ticket 12009 1376 * 1377 * @covers WP_Scripts::do_item 1378 * @covers ::wp_enqueue_script 1379 * @covers ::wp_register_script 1380 */ 1381 public function test_concatenate_with_blocking_script_before_and_after_script_with_defer_strategy() { 1382 global $wp_scripts, $concatenate_scripts, $wp_version; 1383 1384 $old_value = $concatenate_scripts; 1385 $concatenate_scripts = true; 1386 1387 $wp_scripts->do_concat = true; 1388 $wp_scripts->default_dirs = array( $this->default_scripts_dir ); 1389 1390 wp_enqueue_script( 'one-concat-dep-2', $this->default_scripts_dir . 'script.js' ); 1391 wp_enqueue_script( 'two-concat-dep-2', $this->default_scripts_dir . 'script.js' ); 1392 wp_enqueue_script( 'three-concat-dep-2', $this->default_scripts_dir . 'script.js' ); 1393 wp_enqueue_script( 'deferred-script-2', '/main-script.js', array(), null, array( 'strategy' => 'defer' ) ); 1394 wp_enqueue_script( 'four-concat-dep-2', $this->default_scripts_dir . 'script.js' ); 1395 wp_enqueue_script( 'five-concat-dep-2', $this->default_scripts_dir . 'script.js' ); 1396 wp_enqueue_script( 'six-concat-dep-2', $this->default_scripts_dir . 'script.js' ); 1397 1398 wp_print_scripts(); 1399 $print_scripts = get_echo( '_print_scripts' ); 1400 1401 // Reset global before asserting. 1402 $concatenate_scripts = $old_value; 1403 1404 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=one-concat-dep-2,two-concat-dep-2,three-concat-dep-2,four-concat-dep-2,five-concat-dep-2,six-concat-dep-2&ver={$wp_version}'></script>\n"; 1405 $expected .= "<script type='text/javascript' src='/main-script.js' id='deferred-script-2-js' defer data-wp-strategy='defer'></script>\n"; 1406 1407 $this->assertSame( $expected, $print_scripts, 'Scripts are being incorrectly concatenated when a main script is registered as deferred after other blocking scripts are registered. Deferred scripts should not be part of the script concat loader query string. ' ); 1408 } 1409 1410 /** 67 1411 * @ticket 42804 68 1412 */ 69 1413 public function test_wp_enqueue_script_with_html5_support_does_not_contain_type_attribute() { 1414 global $wp_version; 70 1415 add_theme_support( 'html5', array( 'script' ) ); 71 1416 … … 75 1420 wp_enqueue_script( 'empty-deps-no-version', 'example.com' ); 76 1421 77 $ver = get_bloginfo( 'version' ); 78 $expected = "<script src='http://example.com?ver=$ver' id='empty-deps-no-version-js'></script>\n"; 1422 $expected = "<script src='http://example.com?ver={$wp_version}' id='empty-deps-no-version-js'></script>\n"; 79 1423 80 1424 $this->assertSame( $expected, get_echo( 'wp_print_scripts' ) ); … … 84 1428 * Test the different protocol references in wp_enqueue_script 85 1429 * 1430 * @ticket 16560 1431 * 86 1432 * @global WP_Scripts $wp_scripts 87 * @ticket 1656088 1433 */ 89 1434 public function test_protocols() { 90 1435 // Init. 91 global $wp_scripts ;1436 global $wp_scripts, $wp_version; 92 1437 $base_url_backup = $wp_scripts->base_url; 93 1438 $wp_scripts->base_url = 'http://example.com/wordpress'; 94 1439 $expected = ''; 95 $ver = get_bloginfo( 'version' );96 1440 97 1441 // Try with an HTTP reference. 98 1442 wp_enqueue_script( 'jquery-http', 'http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js' ); 99 $expected .= "<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js?ver= $ver' id='jquery-http-js'></script>\n";1443 $expected .= "<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js?ver={$wp_version}' id='jquery-http-js'></script>\n"; 100 1444 101 1445 // Try with an HTTPS reference. 102 1446 wp_enqueue_script( 'jquery-https', 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js' ); 103 $expected .= "<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js?ver= $ver' id='jquery-https-js'></script>\n";1447 $expected .= "<script type='text/javascript' src='https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js?ver={$wp_version}' id='jquery-https-js'></script>\n"; 104 1448 105 1449 // Try with an automatic protocol reference (//). 106 1450 wp_enqueue_script( 'jquery-doubleslash', '//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js' ); 107 $expected .= "<script type='text/javascript' src='//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js?ver= $ver' id='jquery-doubleslash-js'></script>\n";1451 $expected .= "<script type='text/javascript' src='//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js?ver={$wp_version}' id='jquery-doubleslash-js'></script>\n"; 108 1452 109 1453 // Try with a local resource and an automatic protocol reference (//). 110 1454 $url = '//my_plugin/script.js'; 111 1455 wp_enqueue_script( 'plugin-script', $url ); 112 $expected .= "<script type='text/javascript' src='$url?ver= $ver' id='plugin-script-js'></script>\n";1456 $expected .= "<script type='text/javascript' src='$url?ver={$wp_version}' id='plugin-script-js'></script>\n"; 113 1457 114 1458 // Try with a bad protocol. 115 1459 wp_enqueue_script( 'jquery-ftp', 'ftp://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js' ); 116 $expected .= "<script type='text/javascript' src='{$wp_scripts->base_url}ftp://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js?ver= $ver' id='jquery-ftp-js'></script>\n";1460 $expected .= "<script type='text/javascript' src='{$wp_scripts->base_url}ftp://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js?ver={$wp_version}' id='jquery-ftp-js'></script>\n"; 117 1461 118 1462 // Go! … … 130 1474 */ 131 1475 public function test_script_concatenation() { 132 global $wp_scripts ;1476 global $wp_scripts, $wp_version; 133 1477 134 1478 $wp_scripts->do_concat = true; 135 $wp_scripts->default_dirs = array( '/directory/');136 137 wp_enqueue_script( 'one', '/directory/script.js' );138 wp_enqueue_script( 'two', '/directory/script.js' );139 wp_enqueue_script( 'three', '/directory/script.js' );1479 $wp_scripts->default_dirs = array( $this->default_scripts_dir ); 1480 1481 wp_enqueue_script( 'one', $this->default_scripts_dir . 'script.js' ); 1482 wp_enqueue_script( 'two', $this->default_scripts_dir . 'script.js' ); 1483 wp_enqueue_script( 'three', $this->default_scripts_dir . 'script.js' ); 140 1484 141 1485 wp_print_scripts(); 142 1486 $print_scripts = get_echo( '_print_scripts' ); 143 1487 144 $ver = get_bloginfo( 'version' ); 145 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=one,two,three&ver={$ver}'></script>\n"; 1488 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=one,two,three&ver={$wp_version}'></script>\n"; 146 1489 147 1490 $this->assertSame( $expected, $print_scripts ); … … 206 1549 207 1550 /** 208 * Testing `wp_script_add_data` with an anvalid key.1551 * Testing `wp_script_add_data` with an invalid key. 209 1552 * 210 1553 * @ticket 16024 … … 334 1677 $expected_footer = "<script type='text/javascript' src='/parent.js' id='parent-js'></script>\n"; 335 1678 336 $this->assertSame( $expected_header, $header );337 $this->assertSame( $expected_footer, $footer );1679 $this->assertSame( $expected_header, $header, 'Expected same header markup.' ); 1680 $this->assertSame( $expected_footer, $footer, 'Expected same footer markup.' ); 338 1681 } 339 1682 … … 355 1698 $expected_footer .= "<script type='text/javascript' src='/parent.js' id='parent-js'></script>\n"; 356 1699 357 $this->assertSame( $expected_header, $header );358 $this->assertSame( $expected_footer, $footer );1700 $this->assertSame( $expected_header, $header, 'Expected same header markup.' ); 1701 $this->assertSame( $expected_footer, $footer, 'Expected same footer markup.' ); 359 1702 } 360 1703 … … 386 1729 $expected_footer .= "<script type='text/javascript' src='/parent-footer.js' id='parent-footer-js'></script>\n"; 387 1730 388 $this->assertSame( $expected_header, $header );389 $this->assertSame( $expected_footer, $footer );1731 $this->assertSame( $expected_header, $header, 'Expected same header markup.' ); 1732 $this->assertSame( $expected_footer, $footer, 'Expected same footer markup.' ); 390 1733 } 391 1734 … … 417 1760 $expected .= "<script type='text/javascript' src='http://example.com' id='test-example-js'></script>\n"; 418 1761 419 $this->assert Same( $expected, get_echo( 'wp_print_scripts' ) );1762 $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); 420 1763 } 421 1764 … … 430 1773 $expected .= "<script type='text/javascript' id='test-example-js-after'>\nconsole.log(\"after\");\n</script>\n"; 431 1774 432 $this->assert Same( $expected, get_echo( 'wp_print_scripts' ) );1775 $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); 433 1776 } 434 1777 … … 445 1788 $expected .= "<script type='text/javascript' id='test-example-js-after'>\nconsole.log(\"after\");\n</script>\n"; 446 1789 447 $this->assert Same( $expected, get_echo( 'wp_print_scripts' ) );1790 $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); 448 1791 } 449 1792 … … 458 1801 $expected = "<script type='text/javascript' id='test-example-js-before'>\nconsole.log(\"before\");\n</script>\n"; 459 1802 460 $this->assert Same( $expected, get_echo( 'wp_print_scripts' ) );1803 $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); 461 1804 } 462 1805 … … 471 1814 $expected = "<script type='text/javascript' id='test-example-js-after'>\nconsole.log(\"after\");\n</script>\n"; 472 1815 473 $this->assert Same( $expected, get_echo( 'wp_print_scripts' ) );1816 $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); 474 1817 } 475 1818 … … 486 1829 $expected .= "<script type='text/javascript' id='test-example-js-after'>\nconsole.log(\"after\");\n</script>\n"; 487 1830 488 $this->assert Same( $expected, get_echo( 'wp_print_scripts' ) );1831 $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); 489 1832 } 490 1833 … … 503 1846 $expected .= "<script type='text/javascript' id='test-example-js-after'>\nconsole.log(\"after\");\nconsole.log(\"after\");\n</script>\n"; 504 1847 505 $this->assert Same( $expected, get_echo( 'wp_print_scripts' ) );1848 $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); 506 1849 } 507 1850 … … 520 1863 $expected .= "<script type='text/javascript' id='test-example-js-after'>\nconsole.log(\"after\");\n</script>\n"; 521 1864 522 $this->assert Same( $expected, get_echo( 'wp_print_scripts' ) );1865 $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); 523 1866 } 524 1867 … … 527 1870 */ 528 1871 public function test_wp_add_inline_script_before_with_concat() { 529 global $wp_scripts ;1872 global $wp_scripts, $wp_version; 530 1873 531 1874 $wp_scripts->do_concat = true; 532 $wp_scripts->default_dirs = array( '/directory/');533 534 wp_enqueue_script( 'one', '/directory/one.js' );535 wp_enqueue_script( 'two', '/directory/two.js' );536 wp_enqueue_script( 'three', '/directory/three.js' );1875 $wp_scripts->default_dirs = array( $this->default_scripts_dir ); 1876 1877 wp_enqueue_script( 'one', $this->default_scripts_dir . 'one.js' ); 1878 wp_enqueue_script( 'two', $this->default_scripts_dir . 'two.js' ); 1879 wp_enqueue_script( 'three', $this->default_scripts_dir . 'three.js' ); 537 1880 538 1881 wp_add_inline_script( 'one', 'console.log("before one");', 'before' ); 539 1882 wp_add_inline_script( 'two', 'console.log("before two");', 'before' ); 540 1883 541 $ver = get_bloginfo( 'version' );542 1884 $expected = "<script type='text/javascript' id='one-js-before'>\nconsole.log(\"before one\");\n</script>\n"; 543 $expected .= "<script type='text/javascript' src=' /directory/one.js?ver={$ver}' id='one-js'></script>\n";1885 $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}one.js?ver={$wp_version}' id='one-js'></script>\n"; 544 1886 $expected .= "<script type='text/javascript' id='two-js-before'>\nconsole.log(\"before two\");\n</script>\n"; 545 $expected .= "<script type='text/javascript' src=' /directory/two.js?ver={$ver}' id='two-js'></script>\n";546 $expected .= "<script type='text/javascript' src=' /directory/three.js?ver={$ver}' id='three-js'></script>\n";547 548 $this->assert Same( $expected, get_echo( 'wp_print_scripts' ) );1887 $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}two.js?ver={$wp_version}' id='two-js'></script>\n"; 1888 $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}three.js?ver={$wp_version}' id='three-js'></script>\n"; 1889 1890 $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); 549 1891 } 550 1892 … … 553 1895 */ 554 1896 public function test_wp_add_inline_script_before_with_concat2() { 555 global $wp_scripts ;1897 global $wp_scripts, $wp_version; 556 1898 557 1899 $wp_scripts->do_concat = true; 558 $wp_scripts->default_dirs = array( '/directory/');559 560 wp_enqueue_script( 'one', '/directory/one.js' );561 wp_enqueue_script( 'two', '/directory/two.js' );562 wp_enqueue_script( 'three', '/directory/three.js' );1900 $wp_scripts->default_dirs = array( $this->default_scripts_dir ); 1901 1902 wp_enqueue_script( 'one', $this->default_scripts_dir . 'one.js' ); 1903 wp_enqueue_script( 'two', $this->default_scripts_dir . 'two.js' ); 1904 wp_enqueue_script( 'three', $this->default_scripts_dir . 'three.js' ); 563 1905 564 1906 wp_add_inline_script( 'one', 'console.log("before one");', 'before' ); 565 1907 566 $ver = get_bloginfo( 'version' );567 1908 $expected = "<script type='text/javascript' id='one-js-before'>\nconsole.log(\"before one\");\n</script>\n"; 568 $expected .= "<script type='text/javascript' src=' /directory/one.js?ver={$ver}' id='one-js'></script>\n";569 $expected .= "<script type='text/javascript' src=' /directory/two.js?ver={$ver}' id='two-js'></script>\n";570 $expected .= "<script type='text/javascript' src=' /directory/three.js?ver={$ver}' id='three-js'></script>\n";571 572 $this->assert Same( $expected, get_echo( 'wp_print_scripts' ) );1909 $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}one.js?ver={$wp_version}' id='one-js'></script>\n"; 1910 $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}two.js?ver={$wp_version}' id='two-js'></script>\n"; 1911 $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}three.js?ver={$wp_version}' id='three-js'></script>\n"; 1912 1913 $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); 573 1914 } 574 1915 … … 577 1918 */ 578 1919 public function test_wp_add_inline_script_after_with_concat() { 579 global $wp_scripts ;1920 global $wp_scripts, $wp_version; 580 1921 581 1922 $wp_scripts->do_concat = true; 582 $wp_scripts->default_dirs = array( '/directory/');583 584 wp_enqueue_script( 'one', '/directory/one.js' );585 wp_enqueue_script( 'two', '/directory/two.js' );586 wp_enqueue_script( 'three', '/directory/three.js' );587 wp_enqueue_script( 'four', '/directory/four.js' );1923 $wp_scripts->default_dirs = array( $this->default_scripts_dir ); 1924 1925 wp_enqueue_script( 'one', $this->default_scripts_dir . 'one.js' ); 1926 wp_enqueue_script( 'two', $this->default_scripts_dir . 'two.js' ); 1927 wp_enqueue_script( 'three', $this->default_scripts_dir . 'three.js' ); 1928 wp_enqueue_script( 'four', $this->default_scripts_dir . 'four.js' ); 588 1929 589 1930 wp_add_inline_script( 'two', 'console.log("after two");' ); 590 1931 wp_add_inline_script( 'three', 'console.log("after three");' ); 591 1932 592 $ver = get_bloginfo( 'version' ); 593 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=one&ver={$ver}'></script>\n"; 594 $expected .= "<script type='text/javascript' src='/directory/two.js?ver={$ver}' id='two-js'></script>\n"; 1933 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=one&ver={$wp_version}'></script>\n"; 1934 $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}two.js?ver={$wp_version}' id='two-js'></script>\n"; 595 1935 $expected .= "<script type='text/javascript' id='two-js-after'>\nconsole.log(\"after two\");\n</script>\n"; 596 $expected .= "<script type='text/javascript' src=' /directory/three.js?ver={$ver}' id='three-js'></script>\n";1936 $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}three.js?ver={$wp_version}' id='three-js'></script>\n"; 597 1937 $expected .= "<script type='text/javascript' id='three-js-after'>\nconsole.log(\"after three\");\n</script>\n"; 598 $expected .= "<script type='text/javascript' src=' /directory/four.js?ver={$ver}' id='four-js'></script>\n";599 600 $this->assert Same( $expected, get_echo( 'wp_print_scripts' ) );1938 $expected .= "<script type='text/javascript' src='{$this->default_scripts_dir}four.js?ver={$wp_version}' id='four-js'></script>\n"; 1939 1940 $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); 601 1941 } 602 1942 … … 627 1967 628 1968 $this->assertSame( $expected_localized, get_echo( 'wp_print_scripts' ) ); 629 $this->assert Same( $expected, $wp_scripts->print_html );1969 $this->assertEqualMarkup( $expected, $wp_scripts->print_html ); 630 1970 $this->assertTrue( $wp_scripts->do_concat ); 631 1971 } … … 635 1975 */ 636 1976 public function test_wp_add_inline_script_after_with_concat_and_core_dependency() { 637 global $wp_scripts ;1977 global $wp_scripts, $wp_version; 638 1978 639 1979 wp_default_scripts( $wp_scripts ); … … 642 1982 $wp_scripts->do_concat = true; 643 1983 644 $ver = get_bloginfo( 'version' ); 645 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=jquery-core,jquery-migrate&ver={$ver}'></script>\n"; 1984 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=jquery-core,jquery-migrate&ver={$wp_version}'></script>\n"; 646 1985 $expected .= "<script type='text/javascript' src='http://example.com' id='test-example-js'></script>\n"; 647 1986 $expected .= "<script type='text/javascript' id='test-example-js-after'>\nconsole.log(\"after\");\n</script>\n"; … … 653 1992 $print_scripts = get_echo( '_print_scripts' ); 654 1993 655 $this->assert Same( $expected, $print_scripts );1994 $this->assertEqualMarkup( $expected, $print_scripts ); 656 1995 } 657 1996 … … 660 1999 */ 661 2000 public function test_wp_add_inline_script_after_with_concat_and_conditional_and_core_dependency() { 662 global $wp_scripts ;2001 global $wp_scripts, $wp_version; 663 2002 664 2003 wp_default_scripts( $wp_scripts ); … … 667 2006 $wp_scripts->do_concat = true; 668 2007 669 $ver = get_bloginfo( 'version' ); 670 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=jquery-core,jquery-migrate&ver={$ver}'></script>\n"; 2008 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=jquery-core,jquery-migrate&ver={$wp_version}'></script>\n"; 671 2009 $expected .= "<!--[if gte IE 9]>\n"; 672 2010 $expected .= "<script type='text/javascript' src='http://example.com' id='test-example-js'></script>\n"; … … 681 2019 $print_scripts = get_echo( '_print_scripts' ); 682 2020 683 $this->assert Same( $expected, $print_scripts );2021 $this->assertEqualMarkup( $expected, $print_scripts ); 684 2022 } 685 2023 … … 688 2026 */ 689 2027 public function test_wp_add_inline_script_before_with_concat_and_core_dependency() { 690 global $wp_scripts ;2028 global $wp_scripts, $wp_version; 691 2029 692 2030 wp_default_scripts( $wp_scripts ); … … 696 2034 $wp_scripts->do_concat = true; 697 2035 698 $ver = get_bloginfo( 'version' ); 699 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=jquery-core,jquery-migrate&ver={$ver}'></script>\n"; 2036 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=jquery-core,jquery-migrate&ver={$wp_version}'></script>\n"; 700 2037 $expected .= "<script type='text/javascript' id='test-example-js-before'>\nconsole.log(\"before\");\n</script>\n"; 701 2038 $expected .= "<script type='text/javascript' src='http://example.com' id='test-example-js'></script>\n"; … … 707 2044 $print_scripts = get_echo( '_print_scripts' ); 708 2045 709 $this->assert Same( $expected, $print_scripts );2046 $this->assertEqualMarkup( $expected, $print_scripts ); 710 2047 } 711 2048 … … 714 2051 */ 715 2052 public function test_wp_add_inline_script_before_after_concat_with_core_dependency() { 716 global $wp_scripts ;2053 global $wp_scripts, $wp_version; 717 2054 718 2055 wp_default_scripts( $wp_scripts ); … … 722 2059 $wp_scripts->do_concat = true; 723 2060 724 $ver = get_bloginfo( 'version' ); 725 $suffix = wp_scripts_get_suffix(); 726 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=jquery-core,jquery-migrate,wp-polyfill-inert,regenerator-runtime,wp-polyfill,wp-dom-ready,wp-hooks&ver={$ver}'></script>\n"; 2061 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=jquery-core,jquery-migrate,wp-polyfill-inert,regenerator-runtime,wp-polyfill,wp-dom-ready,wp-hooks&ver={$wp_version}'></script>\n"; 727 2062 $expected .= "<script type='text/javascript' id='test-example-js-before'>\nconsole.log(\"before\");\n</script>\n"; 728 2063 $expected .= "<script type='text/javascript' src='http://example.com' id='test-example-js'></script>\n"; … … 759 2094 ); 760 2095 761 $this->assert SameIgnoreEOL( $expected, $print_scripts );2096 $this->assertEqualMarkup( $expected, $print_scripts ); 762 2097 } 763 2098 … … 791 2126 792 2127 $tail = substr( $print_scripts, strrpos( $print_scripts, "<script type='text/javascript' src='/customize-dependency.js' id='customize-dependency-js'>" ) ); 793 $this->assert Same( $expected_tail, $tail );2128 $this->assertEqualMarkup( $expected_tail, $tail ); 794 2129 } 795 2130 … … 798 2133 */ 799 2134 public function test_wp_add_inline_script_after_for_core_scripts_with_concat_is_limited_and_falls_back_to_no_concat() { 800 global $wp_scripts ;2135 global $wp_scripts, $wp_version; 801 2136 802 2137 $wp_scripts->do_concat = true; … … 809 2144 wp_enqueue_script( 'four', '/wp-includes/js/script4.js' ); 810 2145 811 $ver = get_bloginfo( 'version' ); 812 $expected = "<script type='text/javascript' src='/wp-includes/js/script.js?ver={$ver}' id='one-js'></script>\n"; 2146 $expected = "<script type='text/javascript' src='/wp-includes/js/script.js?ver={$wp_version}' id='one-js'></script>\n"; 813 2147 $expected .= "<script type='text/javascript' id='one-js-after'>\nconsole.log(\"after one\");\n</script>\n"; 814 $expected .= "<script type='text/javascript' src='/wp-includes/js/script2.js?ver={$ ver}' id='two-js'></script>\n";815 $expected .= "<script type='text/javascript' src='/wp-includes/js/script3.js?ver={$ ver}' id='three-js'></script>\n";816 $expected .= "<script type='text/javascript' src='/wp-includes/js/script4.js?ver={$ ver}' id='four-js'></script>\n";817 818 $this->assert Same( $expected, get_echo( 'wp_print_scripts' ) );2148 $expected .= "<script type='text/javascript' src='/wp-includes/js/script2.js?ver={$wp_version}' id='two-js'></script>\n"; 2149 $expected .= "<script type='text/javascript' src='/wp-includes/js/script3.js?ver={$wp_version}' id='three-js'></script>\n"; 2150 $expected .= "<script type='text/javascript' src='/wp-includes/js/script4.js?ver={$wp_version}' id='four-js'></script>\n"; 2151 2152 $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); 819 2153 } 820 2154 … … 823 2157 */ 824 2158 public function test_wp_add_inline_script_before_third_core_script_prints_two_concat_scripts() { 825 global $wp_scripts ;2159 global $wp_scripts, $wp_version; 826 2160 827 2161 $wp_scripts->do_concat = true; … … 834 2168 wp_enqueue_script( 'four', '/wp-includes/js/script4.js' ); 835 2169 836 $ver = get_bloginfo( 'version' ); 837 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=one,two&ver={$ver}'></script>\n"; 2170 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=one,two&ver={$wp_version}'></script>\n"; 838 2171 $expected .= "<script type='text/javascript' id='three-js-before'>\nconsole.log(\"before three\");\n</script>\n"; 839 $expected .= "<script type='text/javascript' src='/wp-includes/js/script3.js?ver={$ver}' id='three-js'></script>\n"; 840 $expected .= "<script type='text/javascript' src='/wp-includes/js/script4.js?ver={$ver}' id='four-js'></script>\n"; 841 842 $this->assertSame( $expected, get_echo( 'wp_print_scripts' ) ); 2172 $expected .= "<script type='text/javascript' src='/wp-includes/js/script3.js?ver={$wp_version}' id='three-js'></script>\n"; 2173 $expected .= "<script type='text/javascript' src='/wp-includes/js/script4.js?ver={$wp_version}' id='four-js'></script>\n"; 2174 2175 $this->assertEqualMarkup( $expected, get_echo( 'wp_print_scripts' ) ); 2176 } 2177 2178 /** 2179 * Data provider to test get_inline_script_data and get_inline_script_tag. 2180 * 2181 * @return array[] 2182 */ 2183 public function data_provider_to_test_get_inline_script() { 2184 return array( 2185 'before-blocking' => array( 2186 'position' => 'before', 2187 'inline_scripts' => array( 2188 '/*before foo 1*/', 2189 ), 2190 'delayed' => false, 2191 'expected_data' => '/*before foo 1*/', 2192 'expected_tag' => "<script id='foo-js-before' type='text/javascript'>\n/*before foo 1*/\n</script>\n", 2193 ), 2194 'after-blocking' => array( 2195 'position' => 'after', 2196 'inline_scripts' => array( 2197 '/*after foo 1*/', 2198 '/*after foo 2*/', 2199 ), 2200 'delayed' => false, 2201 'expected_data' => "/*after foo 1*/\n/*after foo 2*/", 2202 'expected_tag' => "<script id='foo-js-after' type='text/javascript'>\n/*after foo 1*/\n/*after foo 2*/\n</script>\n", 2203 ), 2204 'before-delayed' => array( 2205 'position' => 'before', 2206 'inline_scripts' => array( 2207 '/*before foo 1*/', 2208 ), 2209 'delayed' => true, 2210 'expected_data' => '/*before foo 1*/', 2211 'expected_tag' => "<script id='foo-js-before' type='text/javascript'>\n/*before foo 1*/\n</script>\n", 2212 ), 2213 'after-delayed' => array( 2214 'position' => 'after', 2215 'inline_scripts' => array( 2216 '/*after foo 1*/', 2217 '/*after foo 2*/', 2218 ), 2219 'delayed' => true, 2220 'expected_data' => "/*after foo 1*/\n/*after foo 2*/", 2221 'expected_tag' => "<script id='foo-js-after' type='text/javascript'>\n/*after foo 1*/\n/*after foo 2*/\n</script>\n", 2222 ), 2223 ); 2224 } 2225 2226 /** 2227 * Test getting inline scripts. 2228 * 2229 * @covers WP_Scripts::get_inline_script_data 2230 * @covers WP_Scripts::get_inline_script_tag 2231 * @covers WP_Scripts::print_inline_script 2232 * 2233 * @expectedDeprecated WP_Scripts::print_inline_script 2234 * 2235 * @dataProvider data_provider_to_test_get_inline_script 2236 * 2237 * @param string $position Position. 2238 * @param string[] $inline_scripts Inline scripts. 2239 * @param bool $delayed Delayed. 2240 * @param string $expected_data Expected data. 2241 * @param string $expected_tag Expected tag. 2242 */ 2243 public function test_get_inline_script( $position, $inline_scripts, $delayed, $expected_data, $expected_tag ) { 2244 global $wp_scripts; 2245 2246 $deps = array(); 2247 if ( $delayed ) { 2248 $wp_scripts->add( 'dep', 'https://example.com/dependency.js', array(), false ); // TODO: Cannot pass strategy to $args e.g. array( 'strategy' => 'defer' ) 2249 $wp_scripts->add_data( 'dep', 'strategy', 'defer' ); 2250 $deps[] = 'dep'; 2251 } 2252 2253 $handle = 'foo'; 2254 $wp_scripts->add( $handle, 'https://example.com/foo.js', $deps ); 2255 if ( $delayed ) { 2256 $wp_scripts->add_data( $handle, 'strategy', 'defer' ); 2257 } 2258 2259 $this->assertSame( '', $wp_scripts->get_inline_script_data( $handle, $position ) ); 2260 $this->assertSame( '', $wp_scripts->get_inline_script_tag( $handle, $position ) ); 2261 $this->assertFalse( $wp_scripts->print_inline_script( $handle, $position, false ) ); 2262 ob_start(); 2263 $output = $wp_scripts->print_inline_script( $handle, $position, true ); 2264 $this->assertSame( '', ob_get_clean() ); 2265 $this->assertFalse( $output ); 2266 2267 foreach ( $inline_scripts as $inline_script ) { 2268 $wp_scripts->add_inline_script( $handle, $inline_script, $position ); 2269 } 2270 2271 $this->assertSame( $expected_data, $wp_scripts->get_inline_script_data( $handle, $position ) ); 2272 $this->assertSame( $expected_data, $wp_scripts->print_inline_script( $handle, $position, false ) ); 2273 $this->assertEqualMarkup( 2274 $expected_tag, 2275 $wp_scripts->get_inline_script_tag( $handle, $position ) 2276 ); 2277 ob_start(); 2278 $output = $wp_scripts->print_inline_script( $handle, $position, true ); 2279 $this->assertEqualMarkup( $expected_tag, ob_get_clean() ); 2280 $this->assertEquals( $expected_data, $output ); 843 2281 } 844 2282 … … 1044 2482 * 1045 2483 * @ticket 41871 2484 * 1046 2485 * @covers ::wp_enqueue_code_editor 1047 2486 */ … … 1131 2570 * 1132 2571 * @ticket 41871 2572 * 1133 2573 * @covers ::wp_enqueue_code_editor 1134 2574 */ … … 1214 2654 * 1215 2655 * @ticket 41871 2656 * 1216 2657 * @covers ::wp_enqueue_code_editor 1217 2658 */ … … 1311 2752 * 1312 2753 * @ticket 41871 2754 * 1313 2755 * @covers ::wp_enqueue_code_editor 1314 2756 */ … … 1403 2845 /** 1404 2846 * @ticket 52534 2847 * 1405 2848 * @covers ::wp_localize_script 1406 2849 * … … 1457 2900 /** 1458 2901 * @ticket 55628 2902 * 1459 2903 * @covers ::wp_set_script_translations 1460 2904 */ 1461 2905 public function test_wp_external_wp_i18n_print_order() { 1462 global $wp_scripts ;2906 global $wp_scripts, $wp_version; 1463 2907 1464 2908 $wp_scripts->do_concat = true; … … 1481 2925 1482 2926 // The non-default script should end concatenation and maintain order. 1483 $ver = get_bloginfo( 'version' ); 1484 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=jquery-core&ver={$ver}'></script>\n"; 2927 $expected = "<script type='text/javascript' src='/wp-admin/load-scripts.php?c=0&load%5Bchunk_0%5D=jquery-core&ver={$wp_version}'></script>\n"; 1485 2928 $expected .= "<script type='text/javascript' src='/plugins/wp-i18n.js' id='wp-i18n-js'></script>\n"; 1486 2929 $expected .= "<script type='text/javascript' src='/default/common.js' id='common-js'></script>\n"; … … 1488 2931 $this->assertSame( $expected, $print_scripts ); 1489 2932 } 2933 2934 /** 2935 * Parse an HTML markup fragment. 2936 * 2937 * @param string $markup Markup. 2938 * @return DOMElement Body element wrapping supplied markup fragment. 2939 */ 2940 protected function parse_markup_fragment( $markup ) { 2941 $dom = new DOMDocument(); 2942 $dom->loadHTML( 2943 "<!DOCTYPE html><html><head><meta charset=utf8></head><body>{$markup}</body></html>" 2944 ); 2945 2946 /** @var DOMElement $body */ 2947 $body = $dom->getElementsByTagName( 'body' )->item( 0 ); 2948 2949 // Trim whitespace nodes added before/after which can be added when parsing. 2950 foreach ( array( $body->firstChild, $body->lastChild ) as $node ) { 2951 if ( $node instanceof DOMText && '' === trim( $node->data ) ) { 2952 $body->removeChild( $node ); 2953 } 2954 } 2955 2956 return $body; 2957 } 2958 2959 /** 2960 * Assert markup is equal. 2961 * 2962 * @param string $expected Expected markup. 2963 * @param string $actual Actual markup. 2964 * @param string $message Message. 2965 */ 2966 protected function assertEqualMarkup( $expected, $actual, $message = '' ) { 2967 $this->assertEquals( 2968 $this->parse_markup_fragment( $expected ), 2969 $this->parse_markup_fragment( $actual ), 2970 $message 2971 ); 2972 } 1490 2973 }
Note: See TracChangeset
for help on using the changeset viewer.