<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[60920] trunk: Script Loader: Use original stylesheet URL for `sourceURL` when inlined.</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { white-space: pre-line; overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/60920">60920</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/60920","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>westonruter</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2025-10-10 04:17:22 +0000 (Fri, 10 Oct 2025)</dd>
</dl>

<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Script Loader: Use original stylesheet URL for `sourceURL` when inlined.

For inline styles which had been inlined from registered external stylesheets via `wp_maybe_inline_styles()`, this defers to using the original stylesheet URL for the `sourceURL` as opposed to fabricating one from the stylesheet handle. This makes the `sourceURL` much more useful for debugging, as it indicates where the stylesheet is located. This allows a developer to make a change to the CSS more easily.

Developed in https://github.com/WordPress/wordpress-develop/pull/10177.

Follow-up to <a href="https://core.trac.wordpress.org/changeset/50836">[50836]</a>.

Props westonruter, mukesh27, gziolo.
See <a href="https://core.trac.wordpress.org/ticket/50328">#50328</a>, <a href="https://core.trac.wordpress.org/ticket/52620">#52620</a>.
Fixes <a href="https://core.trac.wordpress.org/ticket/63887">#63887</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesclasswpstylesphp">trunk/src/wp-includes/class-wp-styles.php</a></li>
<li><a href="#trunksrcwpincludesscriptloaderphp">trunk/src/wp-includes/script-loader.php</a></li>
<li><a href="#trunktestsphpunittestsdependenciesstylesphp">trunk/tests/phpunit/tests/dependencies/styles.php</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesclasswpstylesphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/class-wp-styles.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/class-wp-styles.php 2025-10-09 23:36:10 UTC (rev 60919)
+++ trunk/src/wp-includes/class-wp-styles.php   2025-10-10 04:17:22 UTC (rev 60920)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -333,14 +333,27 @@
</span><span class="cx" style="display: block; padding: 0 10px">        public function print_inline_style( $handle, $display = true ) {
</span><span class="cx" style="display: block; padding: 0 10px">                $output = $this->get_data( $handle, 'after' );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                if ( empty( $output ) ) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( empty( $output ) || ! is_array( $output ) ) {
</ins><span class="cx" style="display: block; padding: 0 10px">                         return false;
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                if ( ! $this->do_concat ) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+                       // Obtain the original `src` for a stylesheet possibly inlined by wp_maybe_inline_styles().
+                       $inlined_src = $this->get_data( $handle, 'inlined_src' );
+
+                       // If there's only one `after` inline style, and that inline style had been inlined, then use the $inlined_src
+                       // as the sourceURL. Otherwise, if there is more than one inline `after` style associated with the handle,
+                       // then resort to using the handle to construct the sourceURL since there isn't a single source.
+                       if ( count( $output ) === 1 && is_string( $inlined_src ) && strlen( $inlined_src ) > 0 ) {
+                               $source_url = esc_url_raw( $inlined_src );
+                       } else {
+                               $source_url = rawurlencode( "{$handle}-inline-css" );
+                       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">                         $output[] = sprintf(
</span><span class="cx" style="display: block; padding: 0 10px">                                '/*# sourceURL=%s */',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                rawurlencode( "{$handle}-inline-css" )
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         $source_url
</ins><span class="cx" style="display: block; padding: 0 10px">                         );
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span></span></pre></div>
<a id="trunksrcwpincludesscriptloaderphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/script-loader.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/script-loader.php   2025-10-09 23:36:10 UTC (rev 60919)
+++ trunk/src/wp-includes/script-loader.php     2025-10-10 04:17:22 UTC (rev 60920)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3116,6 +3116,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">                         */
</span><span class="cx" style="display: block; padding: 0 10px">                        $style['css'] = _wp_normalize_relative_css_links( $style['css'], $style['src'] );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        // Keep track of the original `src` for the style that was inlined so that the `sourceURL` comment can be added.
+                       $wp_styles->add_data( $style['handle'], 'inlined_src', $style['src'] );
+
</ins><span class="cx" style="display: block; padding: 0 10px">                         // Set `src` to `false` and add styles inline.
</span><span class="cx" style="display: block; padding: 0 10px">                        $wp_styles->registered[ $style['handle'] ]->src = false;
</span><span class="cx" style="display: block; padding: 0 10px">                        if ( empty( $wp_styles->registered[ $style['handle'] ]->extra['after'] ) ) {
</span></span></pre></div>
<a id="trunktestsphpunittestsdependenciesstylesphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/tests/phpunit/tests/dependencies/styles.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/tests/phpunit/tests/dependencies/styles.php 2025-10-09 23:36:10 UTC (rev 60919)
+++ trunk/tests/phpunit/tests/dependencies/styles.php   2025-10-10 04:17:22 UTC (rev 60920)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -524,24 +524,120 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * @ticket 58394
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @ticket 63887
</ins><span class="cx" style="display: block; padding: 0 10px">          *
</span><span class="cx" style="display: block; padding: 0 10px">         * @covers ::wp_maybe_inline_styles
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * @covers ::wp_add_inline_style
+        * @covers ::wp_print_styles
+        * @covers WP_Styles::do_items
+        * @covers WP_Styles::do_item
+        * @covers WP_Styles::print_inline_style
+        *
+        * @dataProvider data_provider_test_wp_maybe_inline_styles
</ins><span class="cx" style="display: block; padding: 0 10px">          */
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-        public function test_wp_maybe_inline_styles() {
-               wp_register_style( 'test-handle', '/' . WPINC . '/css/classic-themes.css' );
-               wp_style_add_data( 'test-handle', 'path', ABSPATH . WPINC . '/css/classic-themes.css' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function test_wp_maybe_inline_styles( ?string $additional_inline_style, ?int $styles_inline_size_limit ) {
+               $rel_path = 'css/classic-themes.css';
+               $src_url  = includes_url( $rel_path );
+               $src_path = ABSPATH . WPINC . '/' . $rel_path;
+               $css      = file_get_contents( $src_path );
+               $handle   = 'test-handle';
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                wp_enqueue_style( 'test-handle' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( isset( $styles_inline_size_limit ) ) {
+                       add_filter(
+                               'styles_inline_size_limit',
+                               static function () use ( $styles_inline_size_limit ): int {
+                                       return $styles_inline_size_limit;
+                               }
+                       );
+               }
+               wp_register_style( $handle, $src_url, array(), null );
+               wp_style_add_data( $handle, 'path', $src_path );
+               if ( isset( $additional_inline_style ) ) {
+                       wp_add_inline_style( $handle, $additional_inline_style );
+               }
+               wp_enqueue_style( $handle );
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                wp_maybe_inline_styles();
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->assertFalse( $GLOBALS['wp_styles']->registered['test-handle']->src, 'Source of style should be reset to false' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $expected_after = array();
+               if ( ! isset( $styles_inline_size_limit ) || strlen( $css ) <= $styles_inline_size_limit ) {
+                       $expected_after[] = $css;
+                       $this->assertFalse( wp_styles()->registered[ $handle ]->src, 'Source of style should be reset to false' );
+                       $this->assertArrayHasKey( 'inlined_src', wp_styles()->registered[ $handle ]->extra );
+                       $this->assertSame( $src_url, wp_styles()->registered[ $handle ]->extra['inlined_src'] );
+               } else {
+                       $this->assertArrayNotHasKey( 'inlined_src', wp_styles()->registered[ $handle ]->extra );
+               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $css = file_get_contents( ABSPATH . WPINC . '/css/classic-themes.css' );
-               $this->assertSameSets( $GLOBALS['wp_styles']->registered['test-handle']->extra['after'], array( $css ), 'Source of style should set to after property' );
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if ( isset( $additional_inline_style ) ) {
+                       $expected_after[] = $additional_inline_style;
+               }
+
+               $after = wp_styles()->get_data( $handle, 'after' );
+               if ( false === $after ) {
+                       $after = array();
+               }
+               $this->assertSameSets( $after, $expected_after, 'Source of style should set to after property' );
+
+               $printed_styles = get_echo( 'wp_print_styles', array( $handle ) );
+               $processor      = new WP_HTML_Tag_Processor( $printed_styles );
+
+               if ( isset( $styles_inline_size_limit ) && strlen( $css ) > $styles_inline_size_limit ) {
+                       $this->assertTrue( $processor->next_tag() );
+                       $this->assertSame( 'LINK', $processor->get_tag() );
+                       $this->assertSame( 'stylesheet', $processor->get_attribute( 'rel' ) );
+                       $this->assertSame( $src_url, $processor->get_attribute( 'href' ) );
+               }
+
+               if ( count( $expected_after ) > 0 ) {
+                       $this->assertTrue( $processor->next_tag() );
+                       $this->assertSame( 'STYLE', $processor->get_tag() );
+                       $this->assertSame( $handle . '-inline-css', $processor->get_attribute( 'id' ) );
+                       $this->assertSame( 'text/css', $processor->get_attribute( 'type' ) );
+
+                       $expected_inline_styles = $expected_after;
+                       if ( isset( $additional_inline_style ) ) {
+                               $source_url = $handle . '-inline-css';
+                       } else {
+                               $source_url = $src_url;
+                       }
+                       $expected_inline_styles[] = "/*# sourceURL=$source_url */";
+
+                       $expected_text = "\n" . implode( "\n", $expected_inline_styles ) . "\n";
+                       $this->assertSame( $expected_text, $processor->get_modifiable_text() );
+               }
+
+               $this->assertFalse( $processor->next_tag() );
</ins><span class="cx" style="display: block; padding: 0 10px">         }
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         * Data provider for test_wp_maybe_inline_styles.
+        *
+        * @see self::test_wp_maybe_inline_styles()
+        * @return array<string, array{additional_inline_style: string|null, styles_inline_size_limit: int|null}>
+        */
+       public static function data_provider_test_wp_maybe_inline_styles(): array {
+               return array(
+                       'regular_limit_without_additional_inline_styles' => array(
+                               'additional_inline_style'  => null,
+                               'styles_inline_size_limit' => null,
+                       ),
+                       'regular_limit_with_additional_inline_style' => array(
+                               'additional_inline_style'  => '/* additional inline style */',
+                               'styles_inline_size_limit' => null,
+                       ),
+                       'zero_limit_without_additional_inline_style' => array(
+                               'additional_inline_style'  => null,
+                               'styles_inline_size_limit' => 0,
+                       ),
+                       'zero_limit_with_additional_inline_style'    => array(
+                               'additional_inline_style'  => '/* additional inline style */',
+                               'styles_inline_size_limit' => 0,
+                       ),
+               );
+       }
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * @ticket 58394
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @covers ::wp_maybe_inline_styles
</span></span></pre>
</div>
</div>

</body>
</html>