Make WordPress Core

Opened 3 months ago

Closed 4 weeks ago

#63887 closed enhancement (fixed)

Add sourceURL to inline scripts and styles

Reported by: jonsurrell's profile jonsurrell Owned by: jonsurrell's profile jonsurrell
Milestone: 6.9 Priority: normal
Severity: normal Version:
Component: Script Loader Keywords: has-patch has-unit-tests
Focuses: javascript, css Cc:

Description

Script and style tags can add a sourceURL comment to name them for developer tools. This is similar to sourceMappingURL that are often used with JavaScript compilers. They are described in this specification.

Messages and styles that come from inline scripts and styles are often difficult to understand and debug because they typically point to part of the current URL, like (index):1530 or ?p=1535:1530. These point to a line number in the page HTML and are confusing and inconsistent across pages.

Inline scripts and styles can provide a sourceURL to provide a consistent name and simplify debugging, for example //# sourceURL=example-js-after. It seems to be supported in Chrome, Firefox, and Edge at this time. Safari does not appear to support it.

Some examples from developer tools in Chrome:

Inline styles before

body { (index):475
    background: red !important;
}

After

body { example-inline-css:2
    background: red !important;
}

Inline scripts before

Uncaught Error: Oh no!
    at (index):1401:7

After

example-js-after:2 Uncaught Error: Oh no!
    at example-js-after:2:7

Attachments (1)

customizer-widget-browser-error.png (124.8 KB) - added by wildworks 2 months ago.
Browser console error in the Customizer

Download all attachments as: .zip

Change History (57)

This ticket was mentioned in PR #9628 on WordPress/wordpress-develop by @jonsurrell.


3 months ago
#1

  • Keywords has-patch added

Trac ticket: https://core.trac.wordpress.org/ticket/63887

Script and style tags can add a sourceURL comment to name them for developer tools. This is similar to sourceMappingURL that are often used with JavaScript compilers. They are described in this specification.

Messages and styles that come from inline scripts and styles are often difficult to understand and debug because they typically point to part of the current URL, like (index):1530 or ?p=1535:1530. These point to a line number in the page HTML and are confusing and inconsistent across pages.

Inline scripts and styles can provide a sourceURL to provide a consistent name and simplify debugging, for example //# sourceURL=example-js-after. It seems to be supported in Chrome, Firefox, and Edge at this time. Safari does not appear to support it.

Some examples from developer tools in Chrome:

Inline styles before

body { (index):475
    background: red !important;
}

After

body { example-inline-css:2
    background: red !important;
}

---

Inline scripts before

Uncaught Error: Oh no!
    at (index):1401:7

After

example-js-after:2 Uncaught Error: Oh no!
    at example-js-after:2:7

@jonsurrell commented on PR #9628:


2 months ago
#2

Inline scripts and styles include a sourceURL that matches the ID attributes used in their tags, for example:

  • scripthandle-js-before
  • scripthandle-js-after
  • stylehandle-inline-css

wp_localize_script() is not handled in the first version of this PR. If desired, that can likely be added.

@alshakero brought this to my attention. I know @jsnajdr, @sgomes, and @youknowriad also expressed interest.

#3 @jonsurrell
2 months ago

  • Keywords has-unit-tests added

@jonsurrell commented on PR #9628:


2 months ago
#4

Shall I see about handling wp_localize_script() as well?

@jonsurrell commented on PR #9628:


2 months ago
#5

I pushed a change to add sourceURL to scripts produced by wp_localize_script() as well.

#6 @jonsurrell
2 months ago

  • Milestone changed from Awaiting Review to 6.9
  • Owner set to jonsurrell
  • Status changed from new to accepted

@westonruter commented on PR #9628:


2 months ago
#7

I saw this feature recently too and thought it would be perfect for core, so thanks for adding this!

Me too! I had this on my list to follow up on. Specifically via: https://x.com/csswizardry/status/1954863359695720623

@westonruter commented on PR #9628:


2 months ago
#8

What about prefixing the sourceURL with inline: as suggested in that tweet?

@jonsurrell commented on PR #9628:


2 months ago
#9

What about prefixing the sourceURL with inline:

I don't feel strongly, but after reflecting I'm inclined to add it. I don't believe there are _technical_ reasons to use a specific name or format, this should be what's easiest for people to identify. I do think there's value in using the same name as the ID of the script or style element, but that would be fine with or without the inline: prefix.

Right now the source URLs look like this:

  • handle-js-before
  • handle-js-after
  • handle-js-extra
  • handle-inline-css

With the prefix and no other changes they'd be:

  • inline:handle-js-before
  • inline:handle-js-after
  • inline:handle-js-extra
  • inline:handle-inline-css

It seems slightly redundant in the style case inline:handle-inline-css, but in general this adds nice clarity about the provenance.

#10 @jonsurrell
2 months ago

  • Resolution set to fixed
  • Status changed from accepted to closed

In 60685:

Script Loader: Add sourceURL to inline scripts and styles.

Improve the source locations referenced by developer tooling in supporting browsers. Inline source locations are named like inline:handle-js-after and appear in the developer tools "sources" panel.

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

Props jonsurrell, swissspidy, alshakero, westonruter.
Fixes #63887.

@jonsurrell commented on PR #9628:


2 months ago
#11

Thanks, it sounds like we now have a technical reason to avoid the inline: prefix 🙂 I'll do some investigation and prepare a change to remove it.

From the linked tweet:

inline: breaks LoAF attribution so a pattern like //# sourceURL=foo.inline.js is probably better.

Referring to Long Animation Frames API.

This ticket was mentioned in PR #9655 on WordPress/wordpress-develop by @jonsurrell.


2 months ago
#12

Follow-up to https://github.com/WordPress/wordpress-develop/pull/9628 where it was noted:

inline: breaks LoAF attribution so a pattern like //# sourceURL=foo.inline.js is probably better.

Referring to Long Animation Frames API.

Trac ticket: https://core.trac.wordpress.org/ticket/63887

#14 @jonsurrell
2 months ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

#15 @jonsurrell
2 months ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In 60686:

Script Loader: Remove "inline:" prefix from sourceURL.

The prefix may negatively impact some APIs such as the Long Animation Frames API.

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

Follow-up to [60685].

Props jonsurrell, swissspidy.
Fixes #63887.

#16 @wildworks
2 months ago

I think the changeset [60685] has caused an error in the customizer. Please follow the steps below:

  • Set SCRIPT_DEBUG to false (Important)
  • Activate TT1 theme
  • Access Appearance > Customize > Widgets

I don't know the exact reason, but it might be because the behavior of load-scripts.php changes depending on the value of SCRIPT_DEBUG. Also, I'm not sure if the source URL is necessary when SCRIPT_DEBUG is false.

Related Gutenberg discussion: https://github.com/WordPress/gutenberg/pull/71374

Version 1, edited 2 months ago by wildworks (previous) (next) (diff)

This ticket was mentioned in Slack in #core-editor by wildworks. View the logs.


2 months ago

@wildworks
2 months ago

Browser console error in the Customizer

This ticket was mentioned in PR #9671 on WordPress/wordpress-develop by @jonsurrell.


2 months ago
#18

Adding sourceURL seems to cause some issues with the customizer when SCRIPT_DEBUG is set to false.

Revert the changes to fix customizer issues.

Revert [60685]
Revert [60686]

Trac ticket: https://core.trac.wordpress.org/ticket/63887

#19 @jonsurrell
2 months ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

I'm able to reproduce the issue with SCRIPT_DEBUG = false. Reverting [60686] and [60685] seems to fix the issue.

Reverting in PR 9671 for now.

#20 @jonsurrell
2 months ago

In 60690:

Script Loader: Revert sourceURL addition.

It was discovered that these changes cause some issues in the customizer when SCRIPT_DEBUG is false.

Reverts [60685] and [60686].

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

Props jonsurrell, wildworks, tyxla.
See #63887.

@jonsurrell commented on PR #9671:


2 months ago
#21

Merged in [60690].

This ticket was mentioned in PR #9672 on WordPress/wordpress-develop by @jonsurrell.


2 months ago
#22

Re-apply the patch to add sourceURL comments to inline scripts and styles.

Trac ticket: https://core.trac.wordpress.org/ticket/63887

#23 @westonruter
2 months ago

I recall this issue coming up in the past in relation to inline // comments being used in some inline scripts, where some naïve minification/concatenation logic would remove newlines, causing the comment to comment-out the initial line of the subsequently-concatenated script. If all of the scripts were adding the sourceURL comment with multi-line comments like was done for CSS, then this should fix the issue. Alternatively, a newline could be printed at the end of the inline comment, which should fix the issue with load-scripts.php.

So instead of:

<?php
$output .= sprintf(
    "\n//# sourceURL=%s",
    rawurlencode( "{$handle}-js-extra" )
);

Do:

<?php
$output .= sprintf(
    "\n/*# sourceURL=%s */",
    rawurlencode( "{$handle}-js-extra" )
);

Or:

<?php
$output .= sprintf(
    "\n//# sourceURL=%s\n",
    rawurlencode( "{$handle}-js-extra" )
);

#24 follow-up: @johnbillion
2 months ago

Weird that none of the e2e tests caught this. The suite runs one with SCRIPT_DEBUG and once without. eg. https://github.com/WordPress/wordpress-develop/actions/runs/17324288405/job/49184432082

#25 @TobiasBg
2 months ago

I know of sites that use such a naïve minification/concatenation logic on the frontend as well, so switching from single-line // ... to multi-line /* ... */ comments would definitely be good.

#26 in reply to: ↑ 24 @westonruter
2 months ago

Replying to johnbillion:

Weird that none of the e2e tests caught this. The suite runs one with SCRIPT_DEBUG and once without. eg. https://github.com/WordPress/wordpress-develop/actions/runs/17324288405/job/49184432082

Since the issue occurred in the Customizer per @wildworks, I think the issue is that there aren't any E2E tests for the Customizer (yet). This is noted in #52895 (from 4 years ago) as something needing to be done.

Replying to jonsurrell:

I suspect this would fix the issue, but I need to confirm this works in browsers with the other comment format. I believe the spec only mentions the // form.

If it works, this is likely safer in general. However, it doesn't make sense to add several of these comments in a concatenated script.

I think we should disable this behavior if scripts are being concatenated, or possibly only enable with SCRIPT_DEBUG = true.

I enabled script concatenation by updating my wp-config.php in the wordpress-develop repo to have:

<?php
define( 'SCRIPT_DEBUG', false );
define( 'CONCATENATE_SCRIPTS', true );

This results in the following inline script being printed:

<script>
/* <![CDATA[ */
var heartbeatSettings = {"nonce":"7afd0d4e07","screenId":"customize"};
//# sourceURL=heartbeat-js-extravar _wpUtilSettings = {"ajax":{"url":"/wp-admin/admin-ajax.php"}};
//# sourceURL=wp-util-js-extravar _wpCustomizeControlsL10n = {"activate":"Activate & Publish","save":"Save & Publish","publish":"Publish","published":"Published","saveDraft":"Save Draft","draftSaved":"Draft Saved","updating":"Updating","schedule":"Schedule","scheduled":"Scheduled","invalid":"Invalid","saveBeforeShare":"Please save your changes in order to share the preview.","futureDateError":"You must supply a future date to schedule.","saveAlert":"The changes you made will be lost if you navigate away from this page.","saved":"Saved","cancel":"Cancel","close":"Close","action":"Action","discardChanges":"Discard changes","cheatin":"An error occurred. Please try again later.","notAllowedHeading":"You need a higher level of permission.","notAllowed":"Sorry, you are not allowed to customize this site.","previewIframeTitle":"Site Preview","loginIframeTitle":"Session expired","collapseSidebar":"Hide Controls","expandSidebar":"Show Controls","untitledBlogName":"(Untitled)","unknownRequestFail":"Looks like something\u2019s gone wrong. Wait a couple seconds, and then try again.","themeDownloading":"Downloading your new theme\u2026","themePreviewWait":"Setting up your live preview. This may take a bit.","revertingChanges":"Reverting unpublished changes\u2026","trashConfirm":"Are you sure you want to discard your unpublished changes?","takenOverMessage":"%s has taken over and is currently customizing.","autosaveNotice":"There is a more recent autosave of your changes than the one you are previewing. \u003Ca href=\"%s\"\u003ERestore the autosave\u003C/a\u003E","videoHeaderNotice":"This theme does not support video headers on this page. Navigate to the front page or another page that supports video headers.","allowedFiles":"Allowed Files","customCssError":{"singular":"There is %d error which must be fixed before you can save.","plural":"There are %d errors which must be fixed before you can save."},"pageOnFrontError":"Homepage and posts page must be different.","saveBlockedError":{"singular":"Unable to save due to %s invalid setting.","plural":"Unable to save due to %s invalid settings."},"scheduleDescription":"Schedule your customization changes to publish (\"go live\") at a future date.","themePreviewUnavailable":"Sorry, you cannot preview new themes when you have changes scheduled or saved as a draft. Please publish your changes, or wait until they publish to preview new themes.","themeInstallUnavailable":"You will not be able to install new themes from here yet since your install requires SFTP credentials. For now, please \u003Ca href=\"http://localhost:8000/wp-admin/theme-install.php\"\u003Eadd themes in the admin\u003C/a\u003E.","publishSettings":"Publish Settings","invalidDate":"Invalid date.","invalidValue":"Invalid value.","blockThemeNotification":"Hurray! Your theme supports site editing with blocks. \u003Ca href=\"https://wordpress.org/documentation/article/site-editor/\"\u003ETell me more\u003C/a\u003E. \u003Cbutton type=\"button\" data-action=\"http://localhost:8000/wp-admin/site-editor.php\" class=\"button switch-to-editor\"\u003EUse Site Editor\u003C/button\u003E"};
//# sourceURL=customize-controls-js-extravar _wpCustomizeNavMenusSettings = {"allMenus":[{"term_id":3,"name":"Primary","slug":"primary","term_group":0,"term_taxonomy_id":3,"taxonomy":"nav_menu","description":"","parent":0,"count":1,"filter":"raw"}],"itemTypes":[{"title":"Posts","type_label":"Post","type":"post_type","object":"post"},{"title":"Pages","type_label":"Page","type":"post_type","object":"page"},{"title":"Categories","type_label":"Category","type":"taxonomy","object":"category"},{"title":"Tags","type_label":"Tag","type":"taxonomy","object":"post_tag"},{"title":"Formats","type_label":"Format","type":"taxonomy","object":"post_format"}],"l10n":{"untitled":"(no label)","unnamed":"(unnamed)","custom_label":"Custom Link","page_label":"Page","menuLocation":"(Currently set to: %s)","locationsTitle":"Menu Locations","locationsDescription":"Your theme can display menus in 0 locations.","menuNameLabel":"Menu Name","newMenuNameDescription":"If your theme has multiple menus, giving them clear names will help you manage them.","itemAdded":"Menu item added","itemDeleted":"Menu item deleted","menuAdded":"Menu created","menuDeleted":"Menu deleted","movedUp":"Menu item moved up","movedDown":"Menu item moved down","movedLeft":"Menu item moved out of submenu","movedRight":"Menu item is now a sub-item","customizingMenus":"Customizing &#9656; Menus","invalidTitleTpl":"%s (Invalid)","pendingTitleTpl":"%s (Pending)","itemsFound":"Number of items found: %d","itemsFoundMore":"Additional items found: %d","itemsLoadingMore":"Loading more results... please wait.","reorderModeOn":"Reorder mode enabled","reorderModeOff":"Reorder mode closed","reorderLabelOn":"Reorder menu items","reorderLabelOff":"Close reorder mode"},"settingTransport":"postMessage","phpIntMax":9223372036854775807,"defaultSettingValues":{"nav_menu":{"name":"","description":"","parent":0,"auto_add":false},"nav_menu_item":{"object_id":0,"object":"","menu_item_parent":0,"position":0,"type":"custom","title":"","url":"","target":"","attr_title":"","description":"","classes":"","xfn":"","status":"publish","original_title":"","nav_menu_term_id":0,"_invalid":false}},"locationSlugMappedToName":[]};
//# sourceURL=customize-nav-menus-js-extravar _wpMediaModelsL10n = {"settings":{"ajaxurl":"/wp-admin/admin-ajax.php","post":{"id":0}}};
//# sourceURL=media-models-js-extravar pluploadL10n = {"queue_limit_exceeded":"You have attempted to queue too many files.","file_exceeds_size_limit":"%s exceeds the maximum upload size for this site.","zero_byte_file":"This file is empty. Please try another.","invalid_filetype":"This file cannot be processed by the web server.","not_an_image":"This file is not an image. Please try another.","image_memory_exceeded":"Memory exceeded. Please try another smaller file.","image_dimensions_exceeded":"This is larger than the maximum size. Please try another.","default_error":"An error occurred in the upload. Please try again later.","missing_upload_url":"There was a configuration error. Please contact the server administrator.","upload_limit_exceeded":"You may only upload 1 file.","http_error":"Unexpected response from the server. The file may have been uploaded successfully. Check in the Media Library or reload the page.","http_error_image":"The server cannot process the image. This can happen if the server is busy or does not have enough resources to complete the task. Uploading a smaller image may help. Suggested maximum size is 2560 pixels.","upload_failed":"Upload failed.","big_upload_failed":"Please try uploading this file with the %1$sbrowser uploader%2$s.","big_upload_queued":"%s exceeds the maximum upload size for the multi-file uploader when used in your browser.","io_error":"IO error.","security_error":"Security error.","file_cancelled":"File canceled.","upload_stopped":"Upload stopped.","dismiss":"Dismiss","crunching":"Crunching\u2026","deleted":"moved to the Trash.","error_uploading":"\u201c%s\u201d has failed to upload.","unsupported_image":"This image cannot be displayed in a web browser. For best results convert it to JPEG before uploading.","noneditable_image":"The web server cannot generate responsive image sizes for this image. Convert it to JPEG or PNG before uploading.","file_url_copied":"The file URL has been copied to your clipboard"};
var _wpPluploadSettings = {"defaults":{"file_data_name":"async-upload","url":"/wp-admin/async-upload.php","filters":{"max_file_size":"1073741824b","mime_types":[{"extensions":"jpg,jpeg,jpe,gif,png,bmp,tiff,tif,webp,avif,ico,heic,heif,heics,heifs,asf,asx,wmv,wmx,wm,avi,divx,flv,mov,qt,mpeg,mpg,mpe,mp4,m4v,ogv,webm,mkv,3gp,3gpp,3g2,3gp2,txt,asc,c,cc,h,srt,csv,tsv,ics,rtx,css,htm,html,vtt,dfxp,mp3,m4a,m4b,aac,ra,ram,wav,x-wav,ogg,oga,flac,mid,midi,wma,wax,mka,rtf,js,pdf,class,tar,zip,gz,gzip,rar,7z,psd,xcf,doc,pot,pps,ppt,wri,xla,xls,xlt,xlw,mdb,mpp,docx,docm,dotx,dotm,xlsx,xlsm,xlsb,xltx,xltm,xlam,pptx,pptm,ppsx,ppsm,potx,potm,ppam,sldx,sldm,onetoc,onetoc2,onetmp,onepkg,oxps,xps,odt,odp,ods,odg,odc,odb,odf,wp,wpd,key,numbers,pages"}]},"multipart_params":{"action":"upload-attachment","_wpnonce":"23c9ecbaaa"}},"browser":{"mobile":false,"supported":true},"limitExceeded":false};
//# sourceURL=wp-plupload-js-extra/* ]]> */
</script>

Note how the inline source comments cause the subsequent concatenated script to be commented-out.

While this would be fixed by using multi-line comment syntax as noted above, having these comments present when CONCATENATE_SCRIPTS is enabled doesn't make sense. So it would make sense to potentially omit them when CONCATENATE_SCRIPTS is enabled. But at the same time, #57548 proposes the elimination of script concatenation altogether. Doing this would eliminate some key technical debt which doesn't seem to be of any current value, and to the contrary: there are clearly problems introduced by this script concatenation.

#27 @jonsurrell
2 months ago

I tried some different forms. The only major that seems to support multiline is Firefox:

Chrome 139 Firefox 142 Edge 139 Safari 18.6
//# … ✅ OK ✅ OK ✅ OK 🚫 NO
/*# … */ 🚫 NO ✅ OK 🚫 NO 🚫 NO
/**# … */ 🚫 NO ✅ OK 🚫 NO 🚫 NO

#28 @jonsurrell
2 months ago

I did some testing with CSS concat as well. The same issue is not a concern because CSS does not have line-based comments so they always terminate.

However, separate inline styles can still be concatenated with multiple sourceURL so it seems best to disable there as well.

An approach to disable the comments when concatenating scripts/styles seems to fix the issues and removes the problem of multiple sourceURL comments in a single inline script/style.

Some descriptive sourceURL comment could be added to concatenated scripts, but with efforts like #57548 it doesn't seem worth investing more effort to better support concatenation.

#29 @jonsurrell
2 months ago

SourceURL support can be tested with snippets like the following on the browser console:

eval('console.log(1);//# sourceURL=ok')
// 1    ok:1
eval('console.log(1);/*# sourceURL=ok */')
// 1    VM1234:1

@Mamaduka commented on PR #9671:


2 months ago
#30

Thanks for fixing this, @sirreal!

#31 @TobiasBg
2 months ago

Yes, Chrome/Chromium does not support multiline comments :-(
https://source.chromium.org/chromium/chromium/src/+/main:v8/src/inspector/search-util.cc;l=160;bpv=1;bpt=1?q=findSourceURL&ss=chromium%2Fchromium%2Fsrc
(The multiline parameter is set to false when viewing the call hierarchy.)

(Link to Chromium source found via https://developer.chrome.com/blog/sourcemappingurl-and-sourceurl-syntax-changed .)

@westonruter commented on PR #9672:


2 months ago
#32

This is working well for me. I tried adding this:

wp_add_inline_script( 'customize-controls', 'bad()' );

And I got as expected:

https://github.com/user-attachments/assets/6120b2da-5c59-493c-8876-10641eadb681

When I enabled concatenation, I get the same error without the source, as expected:

https://github.com/user-attachments/assets/59bf3769-dbc8-42b2-8c4b-40e3a168ca28

And there are no other errors as seen previously.

@peterwilsoncc commented on PR #9672:


2 months ago
#33

In _print_scripts() is it worth adding a unique ID to each concatenated element to give some indication of the source:

if ( $concat ) {
        if ( ! empty( $wp_scripts->print_code ) ) {
                $inline_tag_id = wp_unique_prefixed_id( 'wp-concatenated-inline-javascript-' );
                echo "\n<script{$type_attr} id=\"{$inline_tag_id}\">\n";
                echo "/* <![CDATA[ */\n"; // Not needed in HTML 5.
                echo $wp_scripts->print_code;
                echo "/* ]]> */\n";
                echo "//# sourceURL={$inline_tag_id}\n";
                echo "</script>\n";
        }

@westonruter commented on PR #9672:


2 months ago
#34

In _print_scripts() is it worth adding a unique ID to each concatenated element to give some indication of the source:

I think we should rather eliminate script/style concatenation per Core-57548.

@jonsurrell commented on PR #9672:


2 months ago
#35

In _print_scripts() is it worth adding a unique ID to each concatenated element

That would be consistent with the rest of this change, it seems good 👍

I think we should rather eliminate script/style concatenation per Core-57548.

Whatever is done here for sourceURL can be implemented separately from whatever concatenation changes happen. The comments can always be removed later if concatenation is disabled.

#36 @jonsurrell
2 months ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In 60719:

Script Loader: Add sourceURL to inline scripts and styles.

Improve the source locations referenced by developer tooling in supporting browsers. Inline source locations are named like inline:handle-js-after and appear in the developer tools "sources" panel.

This is the second attempt to add sourceURL comments. The first attempt in [60685] was reverted due to an issue with script concatenation that has been addressed.

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

Follow-up to [60685], [60690].

Props jonsurrell, westonruter, wildworks, peterwilsoncc, johnbillion, tobiasbg.
Fixes #63887.

#37 follow-up: @TobiasBg
2 months ago

@jonsurrell: The comment "The line-based sourceURL comments may a concatenated script and do not make sense when multiple are joined together." is missing the word "break", no?

This ticket was mentioned in PR #9794 on WordPress/wordpress-develop by @jonsurrell.


2 months ago
#38

@tobiasbg noticed a typo in a code comment from [60719].

Trac ticket: https://core.trac.wordpress.org/ticket/63887

#39 in reply to: ↑ 37 @jonsurrell
2 months ago

Replying to TobiasBg:

The comment "The line-based sourceURL comments may a concatenated script and do not make sense when multiple are joined together." is missing the word "break", no?

Good spot. PR 9794 fixes and improves the comment.

#40 @jonsurrell
2 months ago

In 60722:

Script Loader: Fix typo in code comment about sourceURL.

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

Follow-up to [60719].

Props jonsurrell, tobiasbg.
See #63887.

@jonsurrell commented on PR #9794:


2 months ago
#41

Merged in [60722].

This ticket was mentioned in PR #9955 on WordPress/wordpress-develop by @westonruter.


7 weeks ago
#42

I realized in https://github.com/WordPress/wordpress-develop/pull/9531/files#r2361414013 that that the emoji loader script wasn't geting the sourceURL comment. I then realized that there were more than a dozen other such instances of scripts constructed via wp_get_inline_script_tag() and wp_print_inline_script_tag() in wp-includes which lacked these comments.

Note that there are quite a few scripts constructed in wp-admin which are _not_ yet using wp_get_inline_script_tag() and wp_print_inline_script_tag(). See #59446.

There are also instances of inline scripts being printed in themes which this PR does not address. I've suggested that these be handled as part of #63806.

Trac ticket: https://core.trac.wordpress.org/ticket/63887

#43 @westonruter
7 weeks ago

  • Resolution fixed deleted
  • Status changed from closed to reopened

@jonsurrell I have another follow-up for you in https://github.com/WordPress/wordpress-develop/pull/9955

Namely, what hasn't been accounted for yet are scripts being constructed with wp_get_inline_script_tag() or wp_print_inline_script_tag(), or scripts still being manually printed with <script> tags for that matter. My PR tackles that for scripts in wp-includes, but not wp-admin or in bundled themes. For themes, I think this can be done as part of #63806.

Something else which comes to mind is that the current implementation for inline styles isn't ideal for wp_maybe_inline_styles(), because the sourceURL isn't pointing to the available actual URL for the stylesheet, and instead it is using the handle. For example, with #63007 I want to allow the block theme stylesheets to be able to be inlined. This can be done simply with:

<?php
wp_style_add_data(
        'twentytwentyfive-style',
        'path',
        get_parent_theme_file_path( 'style.css' )
);

However, this results in the following inline style being printed to the page:

<style id='twentytwentyfive-style-inline-css'>
*SNIP*

/*# sourceURL=twentytwentyfive-style-inline-css */
</style>

The sourceURL comment here is not ideal. It should rather use the stylesheet's actual URL which it already knows:

/*# sourceURL=http://localhost:8000/wp-content/themes/twentytwentyfive/style.css */

This would be particularly helpful for theme developers wanting to modify CSS as it would show them directly where the file is located for modification.

However, I realize this won't necessarily always be feasible to include since there could be inline styles added in addition to the maybe-inlined styles. Since those inline styles all end up getting concatenated together into one STYLE, it wouldn't be correct in that case to use the URL. (But otherwise, it would be helpful to append a comment with the URL for the maybe-inlined CSS.)

One way to deal with this would be to honor whatever sourceURL is provided already in the inlined CSS/JS. For example:

  • src/wp-includes/script-loader.php

    diff --git a/src/wp-includes/script-loader.php b/src/wp-includes/script-loader.php
    index fc4165009e..39ff3bf8f2 100644
    a b function wp_maybe_inline_styles() { 
    31163116                         */
    31173117                        $style['css'] = _wp_normalize_relative_css_links( $style['css'], $style['src'] );
    31183118
     3119                        $style['css'] .= sprintf( "\n/*# sourceURL=%s */\n", $style['src'] );
     3120
    31193121                        // Set `src` to `false` and add styles inline.
    31203122                        $wp_styles->registered[ $style['handle'] ]->src = false;
    31213123                        if ( empty( $wp_styles->registered[ $style['handle'] ]->extra['after'] ) ) {

With this in place, WP_Styles::print_inline_style() should be updated to check if the CSS being printed already contains a sourceURL comment at the end, and if so, avoid generating one. If more than one inline style is being printed, then it should go ahead and append a handle-generated sourceURL comment. Alternatively, we could just discontinue concatenating all inline scripts and styles into one tag, but this would probably break existing.

#44 @westonruter
7 weeks ago

Also, in the case of adding actually stylesheet URLs as sourceURL comments, we should make sure that any */ in the URL gets URL-encoded so that the comment doesn't get prematurely closed.

@westonruter commented on PR #9955:


6 weeks ago
#45

Note how the function now shows up in the coverage report:

https://github.com/user-attachments/assets/e450e925-1d9a-46dc-82a4-35b36e18ffb4

#46 @westonruter
5 weeks ago

In 60899:

Emoji: Convert the emoji loader from an inline blocking script to a (deferred) script module.

This modernizes the emoji loader script by converting it from a blocking inline script with an IIFE to a script module. Using a script module improves the performance of the FCP and LCP metrics since it does not block the HTML parser. Since script modules are deferred and run immediately before DOMContentLoaded, the logic to wait until that event is also now removed. Additionally, since the script is loaded as a module, it has been modernized to use const, let, and arrow functions. The sourceURL comment is also added. See #63887.

The emoji settings are now passed via a separate script tag with a type of application/json, following the new "pull" paradigm introduced for exporting data from PHP to script modules. See #58873. The JSON data is also now encoded in a more resilient way according to #63851. When the wp-emoji-loader.js script module executes, it continues to populate the window._wpemojiSettings global for backwards-compatibility for any extensions that may be using it.

A new uglify:emoji-loader grunt task is added which ensures wp-includes/js/wp-emoji-loader.js is processed as a module and that top-level symbols are minified.

Follow-up to [60681].

Props westonruter, jonsurrell, adamsilverstein, peterwilsoncc.
See #63851, #63887.
Fixes #63842.

@jonsurrell commented on PR #9955:


5 weeks ago
#47

Have you or are you planning to create a PR for the case that comes from Gutenberg?

@westonruter commented on PR #9955:


5 weeks ago
#48

Have you or are you planning to create a PR for the case that comes from Gutenberg?

@sirreal Thanks for the reminder: https://github.com/WordPress/gutenberg/pull/72118

#49 @westonruter
5 weeks ago

In 60909:

Script Loader: Add sourceURL comments to inline SCRIPT tags manually constructed in wp-includes.

This applies to tags constructed without wp_get_inline_script_tag()/wp_print_inline_script_tag().

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

Props westonruter, jonsurrell.
See #63887.

@westonruter commented on PR #9955:


5 weeks ago
#50

Committed in r60909 (8c2ec298ad82d32f6bd66fae5ec567d287bd6bbf)

This ticket was mentioned in PR #10177 on WordPress/wordpress-develop by @westonruter.


5 weeks ago
#51

This addresses the last feedback I had for sourceURL. For inline styles which had been inlined from registered external stylesheets via wp_maybe_inline_styles(), this will defer 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 would then allow a dev to make a change to the CSS more easily.

  • .html

    old new  
    4242        line-height: inherit;
    4343        text-decoration: inherit;
    4444      }
    45       /*# sourceURL=wp-block-site-title-inline-css */
     45      /*# sourceURL=http://localhost:8000/wp-includes/blocks/site-title/style.css */
    4646    </style>
    4747    <style id="wp-block-page-list-inline-css">
    4848      .wp-block-navigation .wp-block-page-list {
     
    6060      .wp-block-page-list {
    6161        box-sizing: border-box;
    6262      }
    63       /*# sourceURL=wp-block-page-list-inline-css */
     63      /*# sourceURL=http://localhost:8000/wp-includes/blocks/page-list/style.css */
    6464    </style>
    6565    <link
    6666      rel="stylesheet"
     
    7676      :where(.wp-block-group.wp-block-group-is-layout-constrained) {
    7777        position: relative;
    7878      }
    79       /*# sourceURL=wp-block-group-inline-css */
     79      /*# sourceURL=http://localhost:8000/wp-includes/blocks/group/style.css */
    8080    </style>
    8181    <style id="wp-block-post-featured-image-inline-css">
    8282      .wp-block-post-featured-image {
     
    159159      .wp-block-post-featured-image:where(.alignleft, .alignright) {
    160160        width: 100%;
    161161      }
    162       /*# sourceURL=wp-block-post-featured-image-inline-css */
     162      /*# sourceURL=http://localhost:8000/wp-includes/blocks/post-featured-image/style.css */
    163163    </style>
    164164    <style id="wp-block-post-title-inline-css">
    165165      .wp-block-post-title {
     
    176176        line-height: inherit;
    177177        text-decoration: inherit;
    178178      }
    179       /*# sourceURL=wp-block-post-title-inline-css */
     179      /*# sourceURL=http://localhost:8000/wp-includes/blocks/post-title/style.css */
    180180    </style>
    181181    <style id="wp-block-paragraph-inline-css">
    182182      .is-small-text {
     
    226226      p.has-text-align-right[style*="writing-mode:vertical-rl"] {
    227227        rotate: 180deg;
    228228      }
    229       /*# sourceURL=wp-block-paragraph-inline-css */
     229      /*# sourceURL=http://localhost:8000/wp-includes/blocks/paragraph/style.css */
    230230    </style>
    231231    <style id="wp-block-quote-inline-css">
    232232      .wp-block-quote {
     
    254254      .wp-block-quote > cite {
    255255        display: block;
    256256      }
    257       /*# sourceURL=wp-block-quote-inline-css */
     257      /*# sourceURL=http://localhost:8000/wp-includes/blocks/quote/style.css */
    258258    </style>
    259259    <style id="wp-block-post-content-inline-css">
    260260      .wp-block-post-content {
    261261        display: flow-root;
    262262      }
    263       /*# sourceURL=wp-block-post-content-inline-css */
     263      /*# sourceURL=http://localhost:8000/wp-includes/blocks/post-content/style.css */
    264264    </style>
    265265    <style id="wp-block-site-logo-inline-css">
    266266      .wp-block-site-logo {
     
    292292      :root :where(.wp-block-site-logo.is-style-rounded) {
    293293        border-radius: 9999px;
    294294      }
    295       /*# sourceURL=wp-block-site-logo-inline-css */
     295      /*# sourceURL=http://localhost:8000/wp-includes/blocks/site-logo/style.css */
    296296    </style>
    297297    <style id="wp-block-site-tagline-inline-css">
    298298      .wp-block-site-tagline {
    299299        box-sizing: border-box;
    300300      }
    301       /*# sourceURL=wp-block-site-tagline-inline-css */
     301      /*# sourceURL=http://localhost:8000/wp-includes/blocks/site-tagline/style.css */
    302302    </style>
    303303    <style id="wp-block-spacer-inline-css">
    304304      .wp-block-spacer {
    305305        clear: both;
    306306      }
    307       /*# sourceURL=wp-block-spacer-inline-css */
     307      /*# sourceURL=http://localhost:8000/wp-includes/blocks/spacer/style.css */
    308308    </style>
    309309    <style id="wp-block-columns-inline-css">
    310310      .wp-block-columns {
     
    385385      .wp-block-column.is-vertically-aligned-top {
    386386        width: 100%;
    387387      }
    388       /*# sourceURL=wp-block-columns-inline-css */
     388      /*# sourceURL=http://localhost:8000/wp-includes/blocks/columns/style.css */
    389389    </style>
    390390    <style id="wp-block-navigation-link-inline-css">
    391391      .wp-block-navigation .wp-block-navigation-item__label {
     
    408408        margin-left: 8px;
    409409        text-transform: uppercase;
    410410      }
    411       /*# sourceURL=wp-block-navigation-link-inline-css */
     411      /*# sourceURL=http://localhost:8000/wp-includes/blocks/navigation-link/style.css */
    412412    </style>
    413413    <style id="wp-emoji-styles-inline-css">
    414414      img.wp-smiley,
     
    623623          --wp-admin--admin-bar--position-offset: 0px;
    624624        }
    625625      }
    626       /*# sourceURL=wp-block-library-inline-css */
     626      /*# sourceURL=/wp-includes/css/dist/block-library/common.css */
    627627    </style>
    628628    <style id="global-styles-inline-css">
    629629      :root {
     
    15181518        display: block;
    15191519      }
    15201520
    1521       /*# sourceURL=twentytwentyfive-style-inline-css */
     1521      /*# sourceURL=http://localhost:8000/wp-content/themes/twentytwentyfive/style.css */
    15221522    </style>
    15231523    <link rel="https://api.w.org/" href="http://localhost:8000/wp-json/" />
    15241524    <link

Trac ticket: https://core.trac.wordpress.org/ticket/63887

#52 @westonruter
5 weeks ago

Note that after this is closed, there is #63806 remaining for applying similar changes to the core themes.

#53 @westonruter
5 weeks ago

In 60913:

Bundled Themes: Use wp_print_inline_script_tag() when available and include sourceURL for JS.

Instead of manually constructing the markup for SCRIPT tags, leverage wp_print_inline_script_tag() when available to do the construction while also ensuring filters may inject additional attributes on the SCRIPT tags, such as nonce for CSP. When the function is not available (prior to WP 5.7), fall back to the manual markup construction.

This also adds the sourceURL comments to the inline scripts to facilitate debugging, per #63887.

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

Follow-up to [60909], [60899].

Props debarghyabanerjee, westonruter, hbhalodia, peterwilsoncc, sabernhardt, poena.
See #63887, #59446.
Fixes #63806.

@westonruter commented on PR #10177:


5 weeks ago
#54

This is a follow-up to r50836 (https://github.com/WordPress/wordpress-develop/commit/d5f900c3dffe53cd399d583c3d1c600fdceee0d1) which introduced wp_maybe_inline_styles() for Core-50328/Core-52620.

@gziolo commented on PR #10177:


5 weeks ago
#55

These changes look good to me.

#56 @westonruter
4 weeks ago

  • Resolution set to fixed
  • Status changed from reopened to closed

In 60920:

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 [50836].

Props westonruter, mukesh27, gziolo.
See #50328, #52620.
Fixes #63887.

Note: See TracTickets for help on using tickets.