diff --git a/src/wp-includes/class-wp-scripts.php b/src/wp-includes/class-wp-scripts.php index 0c85201bad..08aba0aa5d 100644 --- a/src/wp-includes/class-wp-scripts.php +++ b/src/wp-includes/class-wp-scripts.php @@ -914,7 +914,10 @@ JS; return ''; } - // If the intended strategy is 'defer', limit the initial list of eligibles. + /* + * If the intended strategy is 'defer', limit the initial list of eligible + * strategies, since 'async' can fallback to 'defer', but not vice-versa. + */ $initial = ( 'defer' === $intended ) ? array( 'defer' ) : null; $eligible = $this->filter_eligible_strategies( $handle, $initial ); diff --git a/tests/phpunit/tests/dependencies/scripts.php b/tests/phpunit/tests/dependencies/scripts.php index b3ff0ad123..ca88433713 100644 --- a/tests/phpunit/tests/dependencies/scripts.php +++ b/tests/phpunit/tests/dependencies/scripts.php @@ -2943,7 +2943,24 @@ HTML $actual = get_echo( 'wp_print_scripts', array( array( 'wp-tinymce' ) ) ); - $this->assertStringNotContainsString( 'async', $actual ); + $this->assertStringNotContainsString( 'async', $actual, 'TinyMCE should not have an async attribute.' ); + $this->assertStringNotContainsString( 'defer', $actual, 'TinyMCE should not have a defer attribute.' ); + } + + /** + * Make sure scripts with a loading strategy that are printed + * without being enqueued are handled properly. + * + * @ticket 58648 + * + * @dataProvider data_provider_delayed_strategies + */ + public function test_printing_non_enqueued_scripts( $strategy ) { + wp_register_script( 'test-script', 'test-script.js', array(), false, array( 'strategy' => $strategy ) ); + + $actual = get_echo( 'wp_print_scripts', array( array( 'test-script' ) ) ); + + $this->assertStringContainsString( $strategy, $actual ); } /**