From 24452a6642a8473bef1da2ed7c435683f3c4eb8f Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 27 Mar 2023 13:25:15 +0200 Subject: [PATCH 01/13] Abort/reset script concatenation if the handle in question is of a defer or async loading strategy. --- src/wp-includes/class-wp-scripts.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-scripts.php b/src/wp-includes/class-wp-scripts.php index d062eb3bfdf20..06f2e96edba48 100644 --- a/src/wp-includes/class-wp-scripts.php +++ b/src/wp-includes/class-wp-scripts.php @@ -333,7 +333,12 @@ public function do_item( $handle, $group = false ) { */ $srce = apply_filters( 'script_loader_src', $src, $handle ); - if ( $this->in_default_dir( $srce ) && ( $before_handle || $after_handle || $translations_stop_concat ) ) { + // Get the most eligible loading strategy for said script handle. + // Used as a conditional tp prevent script concatenation. + $strategy = $this->get_eligible_loading_strategy( $handle ); + $is_deferred_or_async_handle = '' !== $strategy; + + if ( $this->in_default_dir( $srce ) && ( $before_handle || $after_handle || $translations_stop_concat || $is_deferred_or_async_handle ) ) { $this->do_concat = false; // Have to print the so-far concatenated scripts right away to maintain the right order. From 08f200f4d4e0f91e93778411a2ee88f3e11af5c1 Mon Sep 17 00:00:00 2001 From: Simon Date: Mon, 27 Mar 2023 13:37:22 +0200 Subject: [PATCH 02/13] Fixed comment typo --- src/wp-includes/class-wp-scripts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-scripts.php b/src/wp-includes/class-wp-scripts.php index 06f2e96edba48..d963d1fa33c96 100644 --- a/src/wp-includes/class-wp-scripts.php +++ b/src/wp-includes/class-wp-scripts.php @@ -334,7 +334,7 @@ public function do_item( $handle, $group = false ) { $srce = apply_filters( 'script_loader_src', $src, $handle ); // Get the most eligible loading strategy for said script handle. - // Used as a conditional tp prevent script concatenation. + // Used as a conditional to prevent script concatenation. $strategy = $this->get_eligible_loading_strategy( $handle ); $is_deferred_or_async_handle = '' !== $strategy; From ae38432890e8edfa0e80cf75e2fedae650408f1a Mon Sep 17 00:00:00 2001 From: Karthik Thayyil Date: Tue, 28 Mar 2023 17:00:52 +0100 Subject: [PATCH 03/13] strategy already available --- src/wp-includes/class-wp-scripts.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/wp-includes/class-wp-scripts.php b/src/wp-includes/class-wp-scripts.php index d8a92c593800e..df712b37231ca 100644 --- a/src/wp-includes/class-wp-scripts.php +++ b/src/wp-includes/class-wp-scripts.php @@ -358,10 +358,8 @@ public function do_item( $handle, $group = false ) { */ $srce = apply_filters( 'script_loader_src', $src, $handle ); - // Get the most eligible loading strategy for said script handle. // Used as a conditional to prevent script concatenation. - $strategy = $this->get_eligible_loading_strategy( $handle ); - $is_deferred_or_async_handle = '' !== $strategy; + $is_deferred_or_async_handle = in_array( $strategy, array( 'defer', 'async' ), true ); if ( $this->in_default_dir( $srce ) && ( $before_handle || $after_handle || $translations_stop_concat || $is_deferred_or_async_handle ) ) { $this->do_concat = false; From 54c74bea02e188b6a34c424f04e13bb1cab81b79 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 28 Mar 2023 22:39:09 +0200 Subject: [PATCH 04/13] Add more specific defer and async strategy checks for concatenation exiting --- src/wp-includes/class-wp-scripts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-scripts.php b/src/wp-includes/class-wp-scripts.php index d963d1fa33c96..3e0f906276298 100644 --- a/src/wp-includes/class-wp-scripts.php +++ b/src/wp-includes/class-wp-scripts.php @@ -336,7 +336,7 @@ public function do_item( $handle, $group = false ) { // Get the most eligible loading strategy for said script handle. // Used as a conditional to prevent script concatenation. $strategy = $this->get_eligible_loading_strategy( $handle ); - $is_deferred_or_async_handle = '' !== $strategy; + $is_deferred_or_async_handle = in_array( $strategy, array( 'defer', 'async' ), true ); if ( $this->in_default_dir( $srce ) && ( $before_handle || $after_handle || $translations_stop_concat || $is_deferred_or_async_handle ) ) { $this->do_concat = false; From 31e4507b2562f874fbe579c4a93d5510fbc174f3 Mon Sep 17 00:00:00 2001 From: Karthik Thayyil Date: Wed, 29 Mar 2023 02:57:35 +0100 Subject: [PATCH 05/13] test defer script with concat --- tests/phpunit/tests/dependencies/scripts.php | 26 ++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/tests/phpunit/tests/dependencies/scripts.php b/tests/phpunit/tests/dependencies/scripts.php index b2f221a616bc4..f136bbbe1fd68 100644 --- a/tests/phpunit/tests/dependencies/scripts.php +++ b/tests/phpunit/tests/dependencies/scripts.php @@ -586,6 +586,32 @@ public function test_get_normalized_script_args() { $this->assertSame( $expected_args, $wp_scripts->get_data( 'footer-old', 'script_args' ) ); } + /** + * Test script concatenation with deferred main script. + * + * @ticket 12009 + */ + public function test_concatenate_with_defer_strategy() { + global $wp_scripts; + + $wp_scripts->do_concat = true; + $wp_scripts->default_dirs = array( '/directory/' ); + + wp_register_script( 'one-concat-dep', '/directory/script.js' ); + wp_register_script( 'two-concat-dep', '/directory/script.js' ); + wp_register_script( 'three-concat-dep', '/directory/script.js' ); + wp_enqueue_script( 'main-defer-script', '/main-script.js', array( 'one-concat-dep', 'two-concat-dep', 'three-concat-dep' ), null, array( 'strategy' => 'defer' ) ); + + wp_print_scripts(); + $print_scripts = get_echo( '_print_scripts' ); + + $ver = get_bloginfo( 'version' ); + $expected = "\n"; + $expected .= "\n"; + + $this->assertSame( $expected, $print_scripts ); + } + /** * @ticket 42804 */ From 2031affb729d8198f9ab5a8419f8d185bc6b3f3f Mon Sep 17 00:00:00 2001 From: Karthik Thayyil Date: Wed, 29 Mar 2023 03:05:02 +0100 Subject: [PATCH 06/13] concat with async --- tests/phpunit/tests/dependencies/scripts.php | 30 ++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/dependencies/scripts.php b/tests/phpunit/tests/dependencies/scripts.php index f136bbbe1fd68..eeb3c90829fd0 100644 --- a/tests/phpunit/tests/dependencies/scripts.php +++ b/tests/phpunit/tests/dependencies/scripts.php @@ -605,13 +605,39 @@ public function test_concatenate_with_defer_strategy() { wp_print_scripts(); $print_scripts = get_echo( '_print_scripts' ); - $ver = get_bloginfo( 'version' ); - $expected = "\n"; + $ver = get_bloginfo( 'version' ); + $expected = "\n"; $expected .= "\n"; $this->assertSame( $expected, $print_scripts ); } + /** + * Test script concatenation with `async` main script. + * + * @ticket 12009 + */ + public function test_concatenate_with_async_strategy() { + global $wp_scripts; + + $wp_scripts->do_concat = true; + $wp_scripts->default_dirs = array( '/directory/' ); + + wp_enqueue_script( 'one-concat-dep-1', '/directory/script.js' ); + wp_enqueue_script( 'two-concat-dep-1', '/directory/script.js' ); + wp_enqueue_script( 'three-concat-dep-1', '/directory/script.js' ); + wp_enqueue_script( 'main-defer-script-1', '/main-script.js', array(), null, array( 'strategy' => 'async' ) ); + + wp_print_scripts(); + $print_scripts = get_echo( '_print_scripts' ); + + $ver = get_bloginfo( 'version' ); + $expected = "\n"; + $expected .= "\n"; + + $this->assertSame( $expected, $print_scripts ); + } + /** * @ticket 42804 */ From 6beabcea7144b0b399c4daf239262adb91f1d750 Mon Sep 17 00:00:00 2001 From: Karthik Thayyil Date: Wed, 29 Mar 2023 10:18:43 +0100 Subject: [PATCH 07/13] blocking before and after defer --- tests/phpunit/tests/dependencies/scripts.php | 51 +++++++++++++++++++- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/dependencies/scripts.php b/tests/phpunit/tests/dependencies/scripts.php index eeb3c90829fd0..1b51569a9ff32 100644 --- a/tests/phpunit/tests/dependencies/scripts.php +++ b/tests/phpunit/tests/dependencies/scripts.php @@ -592,7 +592,10 @@ public function test_get_normalized_script_args() { * @ticket 12009 */ public function test_concatenate_with_defer_strategy() { - global $wp_scripts; + global $wp_scripts, $concatenate_scripts; + + $old_value = $concatenate_scripts; + $concatenate_scripts = true; $wp_scripts->do_concat = true; $wp_scripts->default_dirs = array( '/directory/' ); @@ -605,6 +608,9 @@ public function test_concatenate_with_defer_strategy() { wp_print_scripts(); $print_scripts = get_echo( '_print_scripts' ); + // reset global before asserting. + $concatenate_scripts = $old_value; + $ver = get_bloginfo( 'version' ); $expected = "\n"; $expected .= "\n"; @@ -618,7 +624,10 @@ public function test_concatenate_with_defer_strategy() { * @ticket 12009 */ public function test_concatenate_with_async_strategy() { - global $wp_scripts; + global $wp_scripts, $concatenate_scripts; + + $old_value = $concatenate_scripts; + $concatenate_scripts = true; $wp_scripts->do_concat = true; $wp_scripts->default_dirs = array( '/directory/' ); @@ -631,6 +640,9 @@ public function test_concatenate_with_async_strategy() { wp_print_scripts(); $print_scripts = get_echo( '_print_scripts' ); + // reset global before asserting. + $concatenate_scripts = $old_value; + $ver = get_bloginfo( 'version' ); $expected = "\n"; $expected .= "\n"; @@ -638,6 +650,41 @@ public function test_concatenate_with_async_strategy() { $this->assertSame( $expected, $print_scripts ); } + /** + * Test script concatenation with blocking scripts before and after a `defer` script. + * + * @ticket 12009 + */ + public function test_concatenate_with_blocking_script_before_and_after_script_with_defer_strategy() { + global $wp_scripts, $concatenate_scripts; + + $old_value = $concatenate_scripts; + $concatenate_scripts = true; + + $wp_scripts->do_concat = true; + $wp_scripts->default_dirs = array( '/directory/' ); + + wp_enqueue_script( 'one-concat-dep-2', '/directory/script.js' ); + wp_enqueue_script( 'two-concat-dep-2', '/directory/script.js' ); + wp_enqueue_script( 'three-concat-dep-2', '/directory/script.js' ); + wp_enqueue_script( 'deferred-script-2', '/main-script.js', array(), null, array( 'strategy' => 'defer' ) ); + wp_enqueue_script( 'four-concat-dep-2', '/directory/script.js' ); + wp_enqueue_script( 'five-concat-dep-2', '/directory/script.js' ); + wp_enqueue_script( 'six-concat-dep-2', '/directory/script.js' ); + + wp_print_scripts(); + $print_scripts = get_echo( '_print_scripts' ); + + // reset global before asserting. + $concatenate_scripts = $old_value; + + $ver = get_bloginfo( 'version' ); + $expected = "\n"; + $expected .= "\n"; + + $this->assertSame( $expected, $print_scripts ); + } + /** * @ticket 42804 */ From ffe725c33fedbc7b181ad857d3592388cf10db74 Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 30 Mar 2023 16:14:35 +0200 Subject: [PATCH 08/13] Remove two trailing spaces in printed output that were failing test instances. --- src/wp-includes/script-loader.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php index 11b57280c5f58..7728debd443aa 100644 --- a/src/wp-includes/script-loader.php +++ b/src/wp-includes/script-loader.php @@ -1853,8 +1853,8 @@ function wp_print_template_loader_script() { $output = << { let scripts = document.querySelectorAll(`[type="text/template"][data-wp-executes-after="\${handle}"]`); - scripts.forEach( (script) => { - script.setAttribute("type","text/javascript"); + scripts.forEach( (script) => { + script.setAttribute("type","text/javascript"); eval(script.innerHTML); }) } From c6564954de2262272802f3f11822bcf48c3d819d Mon Sep 17 00:00:00 2001 From: Simon Date: Thu, 30 Mar 2023 16:15:12 +0200 Subject: [PATCH 09/13] Replaced hard coded references to default script directory string to instead reference new protected property. --- tests/phpunit/tests/dependencies/scripts.php | 99 ++++++++++---------- 1 file changed, 51 insertions(+), 48 deletions(-) diff --git a/tests/phpunit/tests/dependencies/scripts.php b/tests/phpunit/tests/dependencies/scripts.php index 1b51569a9ff32..f050b19d4c677 100644 --- a/tests/phpunit/tests/dependencies/scripts.php +++ b/tests/phpunit/tests/dependencies/scripts.php @@ -14,6 +14,9 @@ class Tests_Dependencies_Scripts extends WP_UnitTestCase { protected $wp_scripts_print_translations_output; + // Stores a string reference to a default scripts directory name, utilised by certain tests. + protected $default_scripts_dir = '/directory/'; + public function set_up() { parent::set_up(); $this->old_wp_scripts = isset( $GLOBALS['wp_scripts'] ) ? $GLOBALS['wp_scripts'] : null; @@ -79,8 +82,8 @@ public function test_non_standalone_and_standalone_after_script_combined() { \n"; - $expected .= "\n"; + $expected .= "\n"; $expected .= "\n"; - $expected .= "\n"; - $expected .= "\n"; + $expected .= "\n"; + $expected .= "\n"; $this->assertSame( $expected, get_echo( 'wp_print_scripts' ) ); } @@ -1177,19 +1180,19 @@ public function test_wp_add_inline_script_before_with_concat2() { global $wp_scripts; $wp_scripts->do_concat = true; - $wp_scripts->default_dirs = array( '/directory/' ); + $wp_scripts->default_dirs = array( $this->default_scripts_dir ); - wp_enqueue_script( 'one', '/directory/one.js' ); - wp_enqueue_script( 'two', '/directory/two.js' ); - wp_enqueue_script( 'three', '/directory/three.js' ); + wp_enqueue_script( 'one', $this->default_scripts_dir . 'one.js' ); + wp_enqueue_script( 'two', $this->default_scripts_dir . 'two.js' ); + wp_enqueue_script( 'three', $this->default_scripts_dir . 'three.js' ); wp_add_inline_script( 'one', 'console.log("before one");', 'before' ); $ver = get_bloginfo( 'version' ); $expected = "\n"; - $expected .= "\n"; - $expected .= "\n"; - $expected .= "\n"; + $expected .= "\n"; + $expected .= "\n"; + $expected .= "\n"; $this->assertSame( $expected, get_echo( 'wp_print_scripts' ) ); } @@ -1201,23 +1204,23 @@ public function test_wp_add_inline_script_after_with_concat() { global $wp_scripts; $wp_scripts->do_concat = true; - $wp_scripts->default_dirs = array( '/directory/' ); + $wp_scripts->default_dirs = array( $this->default_scripts_dir ); - wp_enqueue_script( 'one', '/directory/one.js' ); - wp_enqueue_script( 'two', '/directory/two.js' ); - wp_enqueue_script( 'three', '/directory/three.js' ); - wp_enqueue_script( 'four', '/directory/four.js' ); + wp_enqueue_script( 'one', $this->default_scripts_dir . 'one.js' ); + wp_enqueue_script( 'two', $this->default_scripts_dir . 'two.js' ); + wp_enqueue_script( 'three', $this->default_scripts_dir . 'three.js' ); + wp_enqueue_script( 'four', $this->default_scripts_dir . 'four.js' ); wp_add_inline_script( 'two', 'console.log("after two");' ); wp_add_inline_script( 'three', 'console.log("after three");' ); $ver = get_bloginfo( 'version' ); $expected = "\n"; - $expected .= "\n"; + $expected .= "\n"; $expected .= "\n"; - $expected .= "\n"; + $expected .= "\n"; $expected .= "\n"; - $expected .= "\n"; + $expected .= "\n"; $this->assertSame( $expected, get_echo( 'wp_print_scripts' ) ); } From 23630b971dfd8497aa8ff3a027ec639003a21e7f Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Thu, 30 Mar 2023 11:47:07 -0500 Subject: [PATCH 10/13] Fix spacing for PHPCS --- tests/phpunit/tests/dependencies/scripts.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/phpunit/tests/dependencies/scripts.php b/tests/phpunit/tests/dependencies/scripts.php index f050b19d4c677..509adc0834f7b 100644 --- a/tests/phpunit/tests/dependencies/scripts.php +++ b/tests/phpunit/tests/dependencies/scripts.php @@ -597,7 +597,7 @@ public function test_get_normalized_script_args() { public function test_concatenate_with_defer_strategy() { global $wp_scripts, $concatenate_scripts; - $old_value = $concatenate_scripts; + $old_value = $concatenate_scripts; $concatenate_scripts = true; $wp_scripts->do_concat = true; @@ -629,7 +629,7 @@ public function test_concatenate_with_defer_strategy() { public function test_concatenate_with_async_strategy() { global $wp_scripts, $concatenate_scripts; - $old_value = $concatenate_scripts; + $old_value = $concatenate_scripts; $concatenate_scripts = true; $wp_scripts->do_concat = true; @@ -661,7 +661,7 @@ public function test_concatenate_with_async_strategy() { public function test_concatenate_with_blocking_script_before_and_after_script_with_defer_strategy() { global $wp_scripts, $concatenate_scripts; - $old_value = $concatenate_scripts; + $old_value = $concatenate_scripts; $concatenate_scripts = true; $wp_scripts->do_concat = true; From 2087305f76755d500f779dffcebd831cc31724f2 Mon Sep 17 00:00:00 2001 From: Joe McGill Date: Thu, 30 Mar 2023 11:48:30 -0500 Subject: [PATCH 11/13] Update script handle name to match async strategy in tests --- tests/phpunit/tests/dependencies/scripts.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/phpunit/tests/dependencies/scripts.php b/tests/phpunit/tests/dependencies/scripts.php index 509adc0834f7b..82cea96ff5e81 100644 --- a/tests/phpunit/tests/dependencies/scripts.php +++ b/tests/phpunit/tests/dependencies/scripts.php @@ -638,7 +638,7 @@ public function test_concatenate_with_async_strategy() { wp_enqueue_script( 'one-concat-dep-1', $this->default_scripts_dir . 'script.js' ); wp_enqueue_script( 'two-concat-dep-1', $this->default_scripts_dir . 'script.js' ); wp_enqueue_script( 'three-concat-dep-1', $this->default_scripts_dir . 'script.js' ); - wp_enqueue_script( 'main-defer-script-1', '/main-script.js', array(), null, array( 'strategy' => 'async' ) ); + wp_enqueue_script( 'main-async-script-1', '/main-script.js', array(), null, array( 'strategy' => 'async' ) ); wp_print_scripts(); $print_scripts = get_echo( '_print_scripts' ); @@ -648,7 +648,7 @@ public function test_concatenate_with_async_strategy() { $ver = get_bloginfo( 'version' ); $expected = "\n"; - $expected .= "\n"; + $expected .= "\n"; $this->assertSame( $expected, $print_scripts ); } From 4b161625468c5ceb9b35dfb2185e7a20a6fbaba2 Mon Sep 17 00:00:00 2001 From: Karthik Thayyil Date: Fri, 31 Mar 2023 13:36:29 +0100 Subject: [PATCH 12/13] remove extra variable --- src/wp-includes/class-wp-scripts.php | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/wp-includes/class-wp-scripts.php b/src/wp-includes/class-wp-scripts.php index ca50bfe2b115e..d395a7d2814dd 100644 --- a/src/wp-includes/class-wp-scripts.php +++ b/src/wp-includes/class-wp-scripts.php @@ -329,8 +329,6 @@ public function do_item( $handle, $group = false ) { PHP_EOL ); $this->type_attr = $initial_type_attr; - - $this->has_load_later_inline = true; } } From 0c7d18e15edd3f829f5a0819b1ddd3c4d78cb74b Mon Sep 17 00:00:00 2001 From: Karthik Thayyil Date: Fri, 31 Mar 2023 13:38:19 +0100 Subject: [PATCH 13/13] remove hardcoded type --- src/wp-includes/class-wp-scripts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wp-includes/class-wp-scripts.php b/src/wp-includes/class-wp-scripts.php index d395a7d2814dd..c57570ea9ad03 100644 --- a/src/wp-includes/class-wp-scripts.php +++ b/src/wp-includes/class-wp-scripts.php @@ -517,7 +517,7 @@ public function print_inline_script( $handle, $position = 'after', $display = tr $initial_type_attr = $this->type_attr; $this->type_attr = " type='text/template'"; printf( - '%5$s%4$s%5$s%5$s', + '%5$s%4$s%5$s%5$s', $this->type_attr, esc_attr( $handle ), esc_attr( $position ),