From cbc8775f7ec8e3faf8779120ce51c8cb6ed0478f Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 27 Aug 2025 08:52:14 +0200 Subject: [PATCH 1/9] Add sourceURL to inline script and style tags --- src/wp-includes/class-wp-scripts.php | 5 +++++ src/wp-includes/class-wp-styles.php | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/wp-includes/class-wp-scripts.php b/src/wp-includes/class-wp-scripts.php index b1e4c76c73d43..0afa25ff56154 100644 --- a/src/wp-includes/class-wp-scripts.php +++ b/src/wp-includes/class-wp-scripts.php @@ -521,6 +521,11 @@ public function get_inline_script_data( $handle, $position = 'after' ) { return ''; } + $data[] = sprintf( + '//# sourceURL=%s', + rawurlencode( "{$handle}-js-{$position}" ) + ); + return trim( implode( "\n", $data ), "\n" ); } diff --git a/src/wp-includes/class-wp-styles.php b/src/wp-includes/class-wp-styles.php index e64378be5fc8d..0ddedcc58d6fb 100644 --- a/src/wp-includes/class-wp-styles.php +++ b/src/wp-includes/class-wp-styles.php @@ -337,6 +337,11 @@ public function print_inline_style( $handle, $display = true ) { return false; } + $output[] = sprintf( + '/*# sourceURL=%s */', + rawurlencode( "{$handle}-inline-css" ) + ); + $output = implode( "\n", $output ); if ( ! $display ) { From 58944ba43a45de2bf7a05422438725a60086a921 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 27 Aug 2025 09:31:55 +0200 Subject: [PATCH 2/9] Update styles tests --- tests/phpunit/tests/dependencies/styles.php | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tests/phpunit/tests/dependencies/styles.php b/tests/phpunit/tests/dependencies/styles.php index 9cb6283c488d5..4b5d6d70d04df 100644 --- a/tests/phpunit/tests/dependencies/styles.php +++ b/tests/phpunit/tests/dependencies/styles.php @@ -150,6 +150,7 @@ public function test_inline_styles() { $expected = "\n"; $expected .= "\n"; wp_enqueue_style( 'handle', 'http://example.com', array(), 1 ); @@ -179,6 +180,7 @@ public function test_inline_styles_concat() { $expected = "\n"; $expected .= "\n"; wp_enqueue_style( 'handle', 'http://example.com', array(), 1 ); @@ -274,6 +276,7 @@ public function test_multiple_inline_styles() { $expected .= "\n"; wp_enqueue_style( 'handle', 'http://example.com', array(), 1 ); @@ -292,18 +295,20 @@ public function test_multiple_inline_styles() { */ public function test_plugin_doing_inline_styles_wrong() { - $style = "'; + $style_tag_open = ''; + $style = ".thing {\n"; + $style .= "\tbackground: red;\n"; + $style .= '}'; $expected = "\n"; + $expected .= "\n"; wp_enqueue_style( 'handle', 'http://example.com', array(), 1 ); - wp_add_inline_style( 'handle', $style ); + wp_add_inline_style( 'handle', "" ); $this->assertSame( $expected, get_echo( 'wp_print_styles' ) ); } @@ -332,6 +337,7 @@ public function test_conditional_inline_styles_are_also_conditional() { @@ -363,6 +369,7 @@ public function test_wp_add_inline_style_for_handle_without_source() { $expected .= "\n"; $expected .= "\n"; wp_register_style( 'handle-one', 'http://example.com', array(), 1 ); From 384b58490e751cb03942e0c003d501bfd7b70ea7 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 27 Aug 2025 10:00:02 +0200 Subject: [PATCH 3/9] Update scripts tests --- tests/phpunit/tests/dependencies/scripts.php | 137 +++++++++++++------ 1 file changed, 96 insertions(+), 41 deletions(-) diff --git a/tests/phpunit/tests/dependencies/scripts.php b/tests/phpunit/tests/dependencies/scripts.php index 2cd51aad6ab70..3b4b27ad989e8 100644 --- a/tests/phpunit/tests/dependencies/scripts.php +++ b/tests/phpunit/tests/dependencies/scripts.php @@ -116,11 +116,11 @@ public function data_provider_delayed_strategies() { */ public function test_after_inline_script_with_delayed_main_script( $strategy ) { wp_enqueue_script( 'ms-isa-1', 'http://example.org/ms-isa-1.js', array(), null, compact( 'strategy' ) ); - wp_add_inline_script( 'ms-isa-1', 'console.log("after one");', 'after' ); + wp_add_inline_script( 'ms-isa-1', 'console.log(\'after one\');', 'after' ); $output = get_echo( 'wp_print_scripts' ); $expected = "\n"; $expected .= wp_get_inline_script_tag( - 'console.log("after one");', + "console.log('after one');\n//# sourceURL=ms-isa-1-js-after", array( 'id' => 'ms-isa-1-js-after', ) @@ -143,12 +143,12 @@ public function test_after_inline_script_with_delayed_main_script( $strategy ) { */ public function test_after_inline_script_with_blocking_main_script() { wp_enqueue_script( 'ms-insa-3', 'http://example.org/ms-insa-3.js', array(), null ); - wp_add_inline_script( 'ms-insa-3', 'console.log("after one");', 'after' ); + wp_add_inline_script( 'ms-insa-3', 'console.log(\'after one\');', 'after' ); $output = get_echo( 'wp_print_scripts' ); $expected = "\n"; $expected .= wp_get_inline_script_tag( - 'console.log("after one");', + "console.log('after one');\n//# sourceURL=ms-insa-3-js-after", array( 'id' => 'ms-insa-3-js-after', ) @@ -174,15 +174,15 @@ public function test_after_inline_script_with_blocking_main_script() { */ public function test_before_inline_scripts_with_delayed_main_script( $strategy ) { wp_enqueue_script( 'ds-i1-1', 'http://example.org/ds-i1-1.js', array(), null, compact( 'strategy' ) ); - wp_add_inline_script( 'ds-i1-1', 'console.log("before first");', 'before' ); + wp_add_inline_script( 'ds-i1-1', 'console.log(\'before first\');', 'before' ); wp_enqueue_script( 'ds-i1-2', 'http://example.org/ds-i1-2.js', array(), null, compact( 'strategy' ) ); wp_enqueue_script( 'ds-i1-3', 'http://example.org/ds-i1-3.js', array(), null, compact( 'strategy' ) ); 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' ) ); - wp_add_inline_script( 'ms-i1-1', 'console.log("before last");', 'before' ); + wp_add_inline_script( 'ms-i1-1', 'console.log(\'before last\');', 'before' ); $output = get_echo( 'wp_print_scripts' ); $expected = wp_get_inline_script_tag( - 'console.log("before first");', + "console.log('before first');\n//# sourceURL=ds-i1-1-js-before", array( 'id' => 'ds-i1-1-js-before', ) @@ -191,7 +191,7 @@ public function test_before_inline_scripts_with_delayed_main_script( $strategy ) $expected .= "\n"; $expected .= "\n"; $expected .= wp_get_inline_script_tag( - 'console.log("before last");', + "console.log('before last');\n//# sourceURL=ms-i1-1-js-before", array( 'id' => 'ms-i1-1-js-before', 'type' => 'text/javascript', @@ -513,23 +513,27 @@ public function data_provider_to_test_various_strategy_dependency_chains() { HTML @@ -558,34 +562,40 @@ public function data_provider_to_test_various_strategy_dependency_chains() { HTML @@ -606,23 +616,27 @@ public function data_provider_to_test_various_strategy_dependency_chains() { HTML @@ -643,23 +657,27 @@ public function data_provider_to_test_various_strategy_dependency_chains() { HTML @@ -683,22 +701,26 @@ public function data_provider_to_test_various_strategy_dependency_chains() { HTML @@ -725,34 +747,40 @@ public function data_provider_to_test_various_strategy_dependency_chains() { HTML @@ -778,22 +806,26 @@ public function data_provider_to_test_various_strategy_dependency_chains() { HTML @@ -817,34 +849,40 @@ public function data_provider_to_test_various_strategy_dependency_chains() { HTML @@ -868,34 +906,40 @@ public function data_provider_to_test_various_strategy_dependency_chains() { HTML @@ -916,23 +960,27 @@ public function data_provider_to_test_various_strategy_dependency_chains() { HTML @@ -949,6 +997,7 @@ public function data_provider_to_test_various_strategy_dependency_chains() { @@ -967,6 +1016,7 @@ public function data_provider_to_test_various_strategy_dependency_chains() { HTML @@ -1014,12 +1064,14 @@ public function data_provider_to_test_various_strategy_dependency_chains() { HTML @@ -1880,6 +1932,7 @@ public function test_wp_add_inline_script_before() { HTML; @@ -1900,6 +1953,7 @@ public function test_wp_add_inline_script_after() { HTML; @@ -1915,9 +1969,9 @@ public function test_wp_add_inline_script_before_and_after() { wp_add_inline_script( 'test-example', 'console.log("before");', 'before' ); wp_add_inline_script( 'test-example', 'console.log("after");' ); - $expected = "\n"; + $expected = "\n"; $expected .= "\n"; - $expected .= "\n"; + $expected .= "\n"; $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } @@ -1930,7 +1984,7 @@ public function test_wp_add_inline_script_before_for_handle_without_source() { wp_enqueue_script( 'test-example' ); wp_add_inline_script( 'test-example', 'console.log("before");', 'before' ); - $expected = "\n"; + $expected = "\n"; $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } @@ -1943,7 +1997,7 @@ public function test_wp_add_inline_script_after_for_handle_without_source() { wp_enqueue_script( 'test-example' ); wp_add_inline_script( 'test-example', 'console.log("after");' ); - $expected = "\n"; + $expected = "\n"; $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } @@ -1957,8 +2011,8 @@ public function test_wp_add_inline_script_before_and_after_for_handle_without_so wp_add_inline_script( 'test-example', 'console.log("before");', 'before' ); wp_add_inline_script( 'test-example', 'console.log("after");' ); - $expected = "\n"; - $expected .= "\n"; + $expected = "\n"; + $expected .= "\n"; $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } @@ -1973,9 +2027,9 @@ public function test_wp_add_inline_script_multiple() { wp_add_inline_script( 'test-example', 'console.log("after");' ); wp_add_inline_script( 'test-example', 'console.log("after");' ); - $expected = "\n"; + $expected = "\n"; $expected .= "\n"; - $expected .= "\n"; + $expected .= "\n"; $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } @@ -1990,9 +2044,9 @@ public function test_wp_add_inline_script_localized_data_is_added_first() { wp_add_inline_script( 'test-example', 'console.log("after");' ); $expected = "\n"; - $expected .= "\n"; + $expected .= "\n"; $expected .= "\n"; - $expected .= "\n"; + $expected .= "\n"; $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); } @@ -2013,9 +2067,9 @@ public function test_wp_add_inline_script_before_with_concat() { wp_add_inline_script( 'one', 'console.log("before one");', 'before' ); wp_add_inline_script( 'two', 'console.log("before two");', 'before' ); - $expected = "\n"; + $expected = "\n"; $expected .= "\n"; - $expected .= "\n"; + $expected .= "\n"; $expected .= "\n"; $expected .= "\n"; @@ -2037,7 +2091,7 @@ public function test_wp_add_inline_script_before_with_concat2() { wp_add_inline_script( 'one', 'console.log("before one");', 'before' ); - $expected = "\n"; + $expected = "\n"; $expected .= "\n"; $expected .= "\n"; $expected .= "\n"; @@ -2064,9 +2118,9 @@ public function test_wp_add_inline_script_after_with_concat() { $expected = "\n"; $expected .= "\n"; - $expected .= "\n"; + $expected .= "\n"; $expected .= "\n"; - $expected .= "\n"; + $expected .= "\n"; $expected .= "\n"; $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); @@ -2087,9 +2141,9 @@ public function test_wp_add_inline_script_after_and_before_with_concat_and_condi $expected_localized = str_replace( "'", '"', $expected_localized ); $expected = "\n"; $expected = str_replace( "'", '"', $expected ); @@ -2117,7 +2171,7 @@ public function test_wp_add_inline_script_after_with_concat_and_core_dependency( $expected = "\n"; $expected .= "\n"; - $expected .= "\n"; + $expected .= "\n"; wp_enqueue_script( 'test-example', 'http://example.com', array( 'jquery' ), null ); wp_add_inline_script( 'test-example', 'console.log("after");' ); @@ -2142,7 +2196,7 @@ public function test_wp_add_inline_script_after_with_concat_and_conditional_and_ $expected = "\n"; $expected .= "\n"; wp_enqueue_script( 'test-example', 'http://example.com', array( 'jquery' ), null ); @@ -2168,7 +2222,7 @@ public function test_wp_add_inline_script_before_with_concat_and_core_dependency $wp_scripts->do_concat = true; $expected = "\n"; - $expected .= "\n"; + $expected .= "\n"; $expected .= "\n"; wp_enqueue_script( 'test-example', 'http://example.com', array( 'jquery' ), null ); @@ -2193,18 +2247,18 @@ public function test_wp_add_inline_script_before_after_concat_with_core_dependen $wp_scripts->do_concat = true; $expected = "\n"; - $expected .= "\n"; + $expected .= "\n"; $expected .= "\n"; $expected .= "\n"; $expected .= "\n"; $expected .= "\n"; $expected .= "\n"; - $expected .= "\n"; - + $expected .= "\n"; wp_enqueue_script( 'test-example', 'http://example.com', array( 'jquery' ), null ); wp_add_inline_script( 'test-example', 'console.log("before");', 'before' ); wp_enqueue_script( 'test-example2', 'http://example2.com', array( 'wp-a11y' ), null ); @@ -2248,6 +2302,7 @@ public function test_wp_add_inline_script_customize_dependency() { $expected_tail .= "\n"; @@ -2283,7 +2338,7 @@ public function test_wp_add_inline_script_after_for_core_scripts_with_concat_is_ wp_enqueue_script( 'four', '/wp-includes/js/script4.js' ); $expected = "\n"; - $expected .= "\n"; + $expected .= "\n"; $expected .= "\n"; $expected .= "\n"; $expected .= "\n"; @@ -2307,7 +2362,7 @@ public function test_wp_add_inline_script_before_third_core_script_prints_two_co wp_enqueue_script( 'four', '/wp-includes/js/script4.js' ); $expected = "\n"; - $expected .= "\n"; + $expected .= "\n"; $expected .= "\n"; $expected .= "\n"; @@ -2327,8 +2382,8 @@ public function data_provider_to_test_get_inline_script() { '/*before foo 1*/', ), 'delayed' => false, - 'expected_data' => '/*before foo 1*/', - 'expected_tag' => "\n", + 'expected_data' => "/*before foo 1*/\n//# sourceURL=foo-js-before", + 'expected_tag' => "\n", ), 'after-blocking' => array( 'position' => 'after', @@ -2337,8 +2392,8 @@ public function data_provider_to_test_get_inline_script() { '/*after foo 2*/', ), 'delayed' => false, - 'expected_data' => "/*after foo 1*/\n/*after foo 2*/", - 'expected_tag' => "\n", + 'expected_data' => "/*after foo 1*/\n/*after foo 2*/\n//# sourceURL=foo-js-after", + 'expected_tag' => "\n", ), 'before-delayed' => array( 'position' => 'before', @@ -2346,8 +2401,8 @@ public function data_provider_to_test_get_inline_script() { '/*before foo 1*/', ), 'delayed' => true, - 'expected_data' => '/*before foo 1*/', - 'expected_tag' => "\n", + 'expected_data' => "/*before foo 1*/\n//# sourceURL=foo-js-before", + 'expected_tag' => "\n", ), 'after-delayed' => array( 'position' => 'after', @@ -2356,8 +2411,8 @@ public function data_provider_to_test_get_inline_script() { '/*after foo 2*/', ), 'delayed' => true, - 'expected_data' => "/*after foo 1*/\n/*after foo 2*/", - 'expected_tag' => "\n", + 'expected_data' => "/*after foo 1*/\n/*after foo 2*/\n//# sourceURL=foo-js-after", + 'expected_tag' => "\n", ), ); } From 2ebad5e027dc209ac62baec1b5a775efe40c11fe Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 27 Aug 2025 10:59:31 +0200 Subject: [PATCH 4/9] Add encoding/escaping tests --- tests/phpunit/tests/dependencies/scripts.php | 22 ++++++++++++++++++++ tests/phpunit/tests/dependencies/styles.php | 20 ++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/tests/phpunit/tests/dependencies/scripts.php b/tests/phpunit/tests/dependencies/scripts.php index 3b4b27ad989e8..e0265cd92f024 100644 --- a/tests/phpunit/tests/dependencies/scripts.php +++ b/tests/phpunit/tests/dependencies/scripts.php @@ -3623,4 +3623,26 @@ private function _scripts_from_package_json() { $provider = array(); return $data['dependencies']; } + + /** + * @ticket 63887 + */ + public function test_source_url_encoding() { + $this->add_html5_script_theme_support(); + + $handle = '# test/ #'; + wp_enqueue_script( $handle, '/example.js', array(), '0.0' ); + wp_add_inline_script( $handle, '"ok";' ); + + $expected = << + + +HTML; + + $this->assertEqualHTML( $expected, get_echo( 'wp_print_scripts' ) ); + } } diff --git a/tests/phpunit/tests/dependencies/styles.php b/tests/phpunit/tests/dependencies/styles.php index 4b5d6d70d04df..6600c32cc54c4 100644 --- a/tests/phpunit/tests/dependencies/styles.php +++ b/tests/phpunit/tests/dependencies/styles.php @@ -639,4 +639,24 @@ public function test_wp_maybe_inline_styles_no_path() { $this->assertSame( $GLOBALS['wp_styles']->registered['test-handle']->src, $url ); } + + /** + * @ticket 63887 + */ + public function test_source_url_encoding() { + $handle = '# test/ #'; + wp_enqueue_style( $handle, '/example.css', array(), '0.0' ); + wp_add_inline_style( $handle, 'custom-el { content: "ok"; }' ); + + $expected = << + + +HTML; + + $this->assertEqualHTML( $expected, get_echo( 'wp_print_styles' ) ); + } } From c2ab8bac7af1ad27ad387b942508bb99965414d9 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 27 Aug 2025 11:16:20 +0200 Subject: [PATCH 5/9] Fix editor test --- tests/phpunit/tests/blocks/editor.php | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/phpunit/tests/blocks/editor.php b/tests/phpunit/tests/blocks/editor.php index 97d18d89529e3..2ba757921038d 100644 --- a/tests/phpunit/tests/blocks/editor.php +++ b/tests/phpunit/tests/blocks/editor.php @@ -762,6 +762,7 @@ public function test_ensure_preload_data_script_tag_closes() { HTML; From b0c8484a9de1fd3deea03f55550c04b2ef5b71e1 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Wed, 27 Aug 2025 11:57:39 +0200 Subject: [PATCH 6/9] Remove unused var --- tests/phpunit/tests/dependencies/styles.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/phpunit/tests/dependencies/styles.php b/tests/phpunit/tests/dependencies/styles.php index 6600c32cc54c4..e077e3b320006 100644 --- a/tests/phpunit/tests/dependencies/styles.php +++ b/tests/phpunit/tests/dependencies/styles.php @@ -295,10 +295,9 @@ public function test_multiple_inline_styles() { */ public function test_plugin_doing_inline_styles_wrong() { - $style_tag_open = ''; - $style = ".thing {\n"; - $style .= "\tbackground: red;\n"; - $style .= '}'; + $style = ".thing {\n"; + $style .= "\tbackground: red;\n"; + $style .= '}'; $expected = "\n"; $expected .= "\n"; wp_enqueue_style( 'handle', 'http://example.com', array(), 1 ); @@ -180,7 +180,7 @@ public function test_inline_styles_concat() { $expected = "\n"; $expected .= "\n"; wp_enqueue_style( 'handle', 'http://example.com', array(), 1 ); @@ -276,7 +276,7 @@ public function test_multiple_inline_styles() { $expected .= "\n"; wp_enqueue_style( 'handle', 'http://example.com', array(), 1 ); @@ -302,7 +302,7 @@ public function test_plugin_doing_inline_styles_wrong() { $expected = "\n"; $expected .= "\n"; wp_enqueue_style( 'handle', 'http://example.com', array(), 1 ); @@ -336,7 +336,7 @@ public function test_conditional_inline_styles_are_also_conditional() { @@ -368,7 +368,7 @@ public function test_wp_add_inline_style_for_handle_without_source() { $expected .= "\n"; $expected .= "\n"; wp_register_style( 'handle-one', 'http://example.com', array(), 1 ); @@ -651,7 +651,7 @@ public function test_source_url_encoding() { HTML; diff --git a/tests/phpunit/tests/dependencies/wpLocalizeScript.php b/tests/phpunit/tests/dependencies/wpLocalizeScript.php index 7ec8604d40b87..a6477ee8f4f9b 100644 --- a/tests/phpunit/tests/dependencies/wpLocalizeScript.php +++ b/tests/phpunit/tests/dependencies/wpLocalizeScript.php @@ -56,7 +56,7 @@ public function test_wp_localize_script_outputs_safe_json() { $output = get_echo( 'wp_print_scripts' ); - $expected = "\n"; + $expected = "\n"; $expected .= "\n"; $this->assertEqualHTML( $expected, $output );