Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DRAFT: PR for enhancing WP_Scripts with a loading strategy #54

Closed
Closed
Show file tree
Hide file tree
Changes from 245 commits
Commits
Show all changes
307 commits
Select commit Hold shift + click to select a range
5795b4c
restore default values
kt-12 Feb 26, 2023
0ebfaa5
phpcs fixes
kt-12 Feb 26, 2023
f6b0483
Update text
kt-12 Feb 26, 2023
7b36d21
Readability
kt-12 Feb 26, 2023
f71319c
consistent with other docblock descriptions
kt-12 Feb 26, 2023
624e797
casting the result
kt-12 Feb 26, 2023
b7334b7
wordpress coding standards
kt-12 Feb 26, 2023
2cb01be
Merge branch 'enhancement/get_eligible_loading_strategy-ML2-12' of ht…
kt-12 Feb 26, 2023
5305f1c
restore test case
kt-12 Feb 27, 2023
073684a
add temporary ticket id
kt-12 Feb 27, 2023
5e343b8
fix test bug
kt-12 Feb 27, 2023
b56c0e1
restore test case
kt-12 Feb 27, 2023
9caf8bb
Merge branch 'enhancement/get_eligible_loading_strategy-ML2-12' into …
kt-12 Feb 27, 2023
b70ee6c
temporary ticket added for testing
kt-12 Feb 27, 2023
dbf6da9
Merge branch 'enhancement/get_eligible_loading_strategy-ML2-12' into …
kt-12 Feb 27, 2023
2deadcf
remove extra line
kt-12 Feb 27, 2023
fcaa62e
remove after dependency function
kt-12 Feb 27, 2023
150ba8b
Merge branch 'enhancement/get_eligible_loading_strategy-ML2-12' into …
kt-12 Feb 27, 2023
d578e50
fix doc block text
kt-12 Feb 27, 2023
5262bf7
Correct grammar
kt-12 Feb 27, 2023
2970f1a
Fix doc block string.
kt-12 Feb 27, 2023
28af60d
change variable name
kt-12 Feb 27, 2023
f746dfd
doc block changes, better word
kt-12 Feb 27, 2023
00a50d1
Merge branch 'enhancement/get_eligible_loading_strategy-ML2-12' into …
kt-12 Feb 27, 2023
d4bbaff
spacing issue.
kt-12 Feb 27, 2023
01e1d4f
update placeholder with numbered placeholder
kt-12 Feb 28, 2023
a367951
Change ticket id to trac id
kt-12 Feb 28, 2023
51e3e41
Switching from numbered to normal substitution
kt-12 Feb 28, 2023
62cbf60
Breaking test into multiple test functions
kt-12 Feb 28, 2023
0f80794
breaking test to dataprovider
kt-12 Feb 28, 2023
f20cfea
add async and defer check in dependent check
kt-12 Feb 28, 2023
e406a13
Merge branch 'enhancement/get_eligible_loading_strategy-ML2-12' into …
kt-12 Feb 28, 2023
b961108
defer with async dependent
kt-12 Feb 28, 2023
70fb6c6
Add failure messages
kt-12 Feb 28, 2023
2b3d11c
Merge pull request #38 from 10up/enhancement/do_item-ML2-14
kt-12 Feb 28, 2023
16c4634
Merge pull request #35 from 10up/enhancement/get_eligible_loading_str…
kt-12 Mar 1, 2023
a10cb5c
phpcs-fixes
kt-12 Mar 2, 2023
dfbecd8
add parameter
kt-12 Mar 6, 2023
4fa3d7b
butification
kt-12 Mar 6, 2023
043c244
Handling inline before
kt-12 Mar 6, 2023
53a54e6
TODO Note for on Load logic for after
kt-12 Mar 6, 2023
d90ed89
Before Logic.
kt-12 Mar 9, 2023
514876f
test cases
kt-12 Mar 9, 2023
2c31104
bug fix
kt-12 Mar 9, 2023
4e1aaaf
Add non standalone test cases.
kt-12 Mar 9, 2023
df906be
stand alone test case
kt-12 Mar 10, 2023
6be6f16
passing standalone
kt-12 Mar 10, 2023
7564a68
doc block update
kt-12 Mar 10, 2023
484789f
Merge branch 'enhancement/wp-add-inline-script-standalone' into enhan…
kt-12 Mar 10, 2023
3ad953f
keep a track of standalone and non-standalone
kt-12 Mar 10, 2023
dcd2a32
standalone and non-standalone
kt-12 Mar 10, 2023
8d33fac
phpcs fixes
kt-12 Mar 10, 2023
e4b461d
set defaults
kt-12 Mar 10, 2023
8421a1c
update print_inline_script for stand alone
kt-12 Mar 10, 2023
371e42f
fix issue with standalone appending
kt-12 Mar 10, 2023
c517bc1
bug fix incorrect strategy check
kt-12 Mar 10, 2023
04aabf5
numbered attributes
kt-12 Mar 10, 2023
e366d5d
onload script
kt-12 Mar 10, 2023
0fafd88
fix bug
kt-12 Mar 10, 2023
386022e
sprintf issue with \n
kt-12 Mar 11, 2023
fe7acc0
phpcs fixes
kt-12 Mar 11, 2023
394405f
print template loader script
kt-12 Mar 11, 2023
cc5dace
\n to EOL
kt-12 Mar 11, 2023
b558f34
Loading the script before other script
kt-12 Mar 13, 2023
f04a246
temp commit
kt-12 Mar 14, 2023
b5f4df4
check if any delayed inline scripts
kt-12 Mar 15, 2023
2eb8aed
Update src/wp-includes/class-wp-scripts.php
kt-12 Mar 15, 2023
e0e560e
non-stanadalone after script test cases
kt-12 Mar 15, 2023
c856372
test standalone and non-standalone script combined
kt-12 Mar 15, 2023
ff25567
phpcs fix
kt-12 Mar 15, 2023
b2d6ec1
for consistency
kt-12 Mar 15, 2023
d9a0f39
Merge add_text_template to implement_load_handlers
kt-12 Mar 15, 2023
d110556
add new line
kt-12 Mar 16, 2023
b6b7022
backward compatibility
kt-12 Mar 16, 2023
9e8c378
update test utility and scripts.
kt-12 Mar 16, 2023
ffc40c1
php cs fixes
kt-12 Mar 16, 2023
8af918c
fix csfix issue
kt-12 Mar 16, 2023
d952da5
Update test message.
kt-12 Mar 21, 2023
b71b557
Update test comment
kt-12 Mar 21, 2023
479d656
Update test error message
kt-12 Mar 21, 2023
968d5b7
change function names
kt-12 Mar 21, 2023
ad9d9c3
Merge branch 'enhancement/implement_load_handlers' of https://github.…
kt-12 Mar 21, 2023
d522c46
Update doc header.
kt-12 Mar 22, 2023
ce5fc87
Update comment text
kt-12 Mar 22, 2023
0a0b253
comment text grammar.
kt-12 Mar 22, 2023
a24665a
update doc block
kt-12 Mar 22, 2023
f29c144
comment grammar fixes
kt-12 Mar 22, 2023
0988655
comment grammar fixes
kt-12 Mar 22, 2023
d66907e
comment grammar
kt-12 Mar 22, 2023
b7bff57
doc block grammar
kt-12 Mar 22, 2023
013cb1e
comment grammar
kt-12 Mar 22, 2023
db02925
update doc block for grammar
kt-12 Mar 22, 2023
42bc576
updated grammar
kt-12 Mar 22, 2023
07179c8
update comment text
kt-12 Mar 22, 2023
169fc28
Update comment
kt-12 Mar 22, 2023
ad9cafb
Update comment
kt-12 Mar 22, 2023
5cda63d
Update comment
kt-12 Mar 22, 2023
a587e5e
Update doc block.
kt-12 Mar 22, 2023
b861844
Update doc block
kt-12 Mar 22, 2023
70122ff
Update comment
kt-12 Mar 22, 2023
c81fdf2
Update comment
kt-12 Mar 22, 2023
2dce5f4
Update comment
kt-12 Mar 22, 2023
2571691
Update comment
kt-12 Mar 22, 2023
b7ac63f
grammar fix
kt-12 Mar 22, 2023
326555d
use unregister column
kt-12 Mar 22, 2023
8d5729c
Merge branch 'enhancement/update-wp-add-inline-script-standalone' int…
kt-12 Mar 22, 2023
6187dd1
Merge branch 'enhancement/add_text_template' into enhancement/impleme…
kt-12 Mar 22, 2023
1321d6f
avoid removal of jquery libraries
kt-12 Mar 23, 2023
66ab60c
Dataprovider doc block.
kt-12 Mar 23, 2023
bbdad37
doc block change
kt-12 Mar 23, 2023
24452a6
Abort/reset script concatenation if the handle in question is of a de…
10upsimon Mar 27, 2023
08f200f
Fixed comment typo
10upsimon Mar 27, 2023
966be0c
Update src/wp-includes/class-wp-scripts.php
kt-12 Mar 28, 2023
f9355cd
Merge branch 'enhancement/implement_load_handlers' into add/issue-48-…
kt-12 Mar 28, 2023
ae38432
strategy already available
kt-12 Mar 28, 2023
54c74be
Add more specific defer and async strategy checks for concatenation e…
10upsimon Mar 28, 2023
31e4507
test defer script with concat
kt-12 Mar 29, 2023
2031aff
concat with async
kt-12 Mar 29, 2023
6beabce
blocking before and after defer
kt-12 Mar 29, 2023
a8dba9f
Merge origin into local
10upsimon Mar 29, 2023
6d75add
Merge branch 'add/issue-48-abort-script-strategy-logic-when-concat-sc…
10upsimon Mar 29, 2023
ffe725c
Remove two trailing spaces in printed output that were failing test i…
10upsimon Mar 30, 2023
c656495
Replaced hard coded references to default script directory string to …
10upsimon Mar 30, 2023
23630b9
Fix spacing for PHPCS
joemcgill Mar 30, 2023
2087305
Update script handle name to match async strategy in tests
joemcgill Mar 30, 2023
dcbf0af
Update doc text
kt-12 Mar 31, 2023
01c890e
bug: multiple type in a single script.
kt-12 Mar 31, 2023
9aaca52
print_display
kt-12 Mar 31, 2023
8e08454
Merge branch 'enhancement/add_text_template' into enhancement/impleme…
kt-12 Mar 31, 2023
b3f7225
fix type_attr no there issue
kt-12 Mar 31, 2023
4df5288
adding description
kt-12 Mar 31, 2023
264853c
broke standalone script test to multiple function
kt-12 Mar 31, 2023
556ae91
non-standalone after script test broken
kt-12 Mar 31, 2023
d4be88d
before standalone test broken
kt-12 Mar 31, 2023
180a6ae
non standalone with before and defer
kt-12 Mar 31, 2023
fdf0bd3
Merge branch 'enhancement/implement_load_handlers' into add/issue-48-…
kt-12 Mar 31, 2023
4b16162
remove extra variable
kt-12 Mar 31, 2023
0c7d18e
remove hardcoded type
kt-12 Mar 31, 2023
4d0140d
used function instead of arrow function.
kt-12 Mar 31, 2023
a5b83a4
single condition
kt-12 Mar 31, 2023
0269128
put back handle
kt-12 Mar 31, 2023
db29ae2
Merge pull request #47 from 10up/enhancement/update-wp-add-inline-scr…
kt-12 Apr 1, 2023
28ba27c
Merge pull request #46 from 10up/enhancement/wp-add-inline-script-sta…
10upsimon Apr 3, 2023
4cc2502
Merge pull request #50 from 10up/enhancement/implement_load_handlers
10upsimon Apr 3, 2023
0007785
Merge pull request #49 from 10up/enhancement/add_text_template
10upsimon Apr 3, 2023
59ee419
Merge branch 'enhancement/wp-script-api-strategy-base' of github.com:…
10upsimon Apr 3, 2023
6125283
Merge branch 'trunk' of github.com:10up/wordpress-develop into trunk
10upsimon Apr 3, 2023
71811ab
Merge branch 'trunk' into enhancement/wp-script-api-strategy-base
10upsimon Apr 3, 2023
f61d867
Merge branch 'enhancement/implement_load_handlers' into add/issue-48-…
kt-12 Apr 3, 2023
90e6105
Merge pull request #51 from 10up/add/issue-48-abort-script-strategy-l…
kt-12 Apr 3, 2023
88fe91d
Merge branch 'enhancement/wp-script-api-strategy-base' of github.com:…
10upsimon Apr 3, 2023
82d5ea8
Merge pull request #53 from 10up/trunk
10upsimon Apr 3, 2023
569fd3e
Merge branch 'trunk' of github.com:10up/wordpress-develop into trunk
10upsimon Apr 3, 2023
9eb6336
Merge branch 'trunk' into enhancement/wp-script-api-strategy-base
10upsimon Apr 3, 2023
76b3705
Merge branch 'feature/enhance-wp-scripts-api-with-a-loading-strategy'…
joemcgill Apr 3, 2023
1b7ac23
Merge branch 'trunk' into feature/enhance-wp-scripts-api-with-a-loadi…
joemcgill Apr 3, 2023
5114138
Merge branch 'feature/enhance-wp-scripts-api-with-a-loading-strategy'…
joemcgill Apr 3, 2023
204ff24
Merge pull request #52 from 10up/enhancement/wp-script-api-strategy-base
10upsimon Apr 3, 2023
2e8cbfa
moving down the code by few lines
kt-12 Apr 12, 2023
70aed2d
adding a new line - clean code
kt-12 Apr 12, 2023
146499d
add some useful information in comment
kt-12 Apr 12, 2023
0be95f2
code readability
kt-12 Apr 12, 2023
24003f0
optional in doc type
kt-12 Apr 12, 2023
a3baa8d
Update comment text.
kt-12 Apr 12, 2023
4945a14
default true
kt-12 Apr 12, 2023
f062f0b
standalone optional
kt-12 Apr 12, 2023
239ee0b
Merge branch 'feature/enhance-wp-scripts-api-with-a-loading-strategy'…
kt-12 Apr 12, 2023
626e2bf
default false
kt-12 Apr 12, 2023
c3f5898
typo
kt-12 Apr 12, 2023
fefe6ee
add line
kt-12 Apr 12, 2023
1052b59
add a line for clean code
kt-12 Apr 12, 2023
1d7b9bd
add a line
kt-12 Apr 12, 2023
b10982d
fixing comment
kt-12 Apr 12, 2023
30747d1
add a line for clean code
kt-12 Apr 12, 2023
0b393b7
comment language fix.
kt-12 Apr 12, 2023
4df050c
$handle is not optional
kt-12 Apr 12, 2023
e4c5128
update comment.
kt-12 Apr 12, 2023
ae5797b
improve doc block comment
kt-12 Apr 12, 2023
90764c8
clean code add a line
kt-12 Apr 12, 2023
08ed2d3
add a line
kt-12 Apr 12, 2023
97846ba
doc type text update.
kt-12 Apr 12, 2023
03cb904
add a line for clean code.
kt-12 Apr 12, 2023
a569440
update doc block.
kt-12 Apr 12, 2023
5be4ecf
add a line for clean code.
kt-12 Apr 12, 2023
5bc5864
add a new line.
kt-12 Apr 12, 2023
37eeff9
Update doc block comments
kt-12 Apr 12, 2023
9f91ccb
change function name
kt-12 Apr 12, 2023
09c4abb
Merge branch 'feature/enhance-wp-scripts-api-with-a-loading-strategy'…
kt-12 Apr 12, 2023
4e59471
is_valid_script
kt-12 Apr 13, 2023
a75c67d
fix grammar
kt-12 Apr 13, 2023
bfc27f9
bug fix get_intended_strategy
kt-12 Apr 14, 2023
06514c4
return false if invalid strategy used.
kt-12 Apr 14, 2023
59d2503
invalid script strategy test
kt-12 Apr 14, 2023
fb93f94
script strategy doing it wrong.
kt-12 Apr 14, 2023
9804459
in_array with helper function
kt-12 Apr 14, 2023
83b2b27
Merge branch 'feature/enhance-wp-scripts-api-with-a-loading-strategy'…
10upsimon Apr 14, 2023
286d589
update doc block
kt-12 Apr 14, 2023
15dfe0f
typo fix
kt-12 Apr 14, 2023
909714e
code cleanup
kt-12 Apr 14, 2023
4534440
fix grammar.
kt-12 Apr 14, 2023
f5d4b55
fix grammar
kt-12 Apr 14, 2023
4be6d42
update comment
kt-12 Apr 14, 2023
3385b26
inline type template
kt-12 Apr 20, 2023
3b46fe9
hardcode type
kt-12 Apr 20, 2023
b1d57ea
function name change
kt-12 Apr 20, 2023
5508cf0
placeholder
kt-12 Apr 20, 2023
996e018
fix issue
kt-12 Apr 20, 2023
654d1e7
Merge branch 'feature/enhance-wp-scripts-api-with-a-loading-strategy'…
kt-12 Apr 20, 2023
a80156f
Change docblock description for is_non_blocking_strategy method
10upsimon Apr 21, 2023
b92f5be
Merge pull request #57 from 10up/enhancement/create-helper-for-delaye…
10upsimon Apr 21, 2023
8549c52
Updated description and param decription within docblock of is_valid_…
10upsimon Apr 21, 2023
281aadc
Merge pull request #56 from 10up/enhancement/add_valid_strategy_function
10upsimon Apr 21, 2023
69f20dd
Merge branch 'feature/enhance-wp-scripts-api-with-a-loading-strategy'…
10upsimon Apr 24, 2023
bd4c18c
Handle malicious attempts more robustly
10upsimon Apr 25, 2023
156555d
Return empty string if no strategy set as part of get_intended_strate…
10upsimon Apr 25, 2023
e0c60d4
Renamed wp_print_template_loader_script function to wp_print_delayed_…
10upsimon Apr 25, 2023
07ae509
Change let to const within wpLoadAfterScripts as scripts assignment i…
10upsimon Apr 25, 2023
35bc9c7
Replace usage of innerHTML with textContent within wp_print_delayed_i…
10upsimon Apr 25, 2023
2b6155a
Replaced usage of printf with wp_print_inline_script_tag within wp_pr…
10upsimon Apr 25, 2023
3ad9b74
Updated docblock for wp_register_script to indicate change from to
10upsimon Apr 25, 2023
8116c22
Updated docblock for wp_enqueue_script to indicate change from to
10upsimon Apr 25, 2023
6bccf2e
Additon of @since 6.3.0 to docblock for changes to add_inline_script …
10upsimon Apr 25, 2023
213d83d
Added @since 6.3.0 for newly added has_delayed_inline_script function
10upsimon Apr 25, 2023
dc9f902
Added @since 6.3.0 for newly added add_data function
10upsimon Apr 25, 2023
fd16848
Added @since 6.3.0 for newly added get_normalized_script_args function
10upsimon Apr 25, 2023
1a77dd4
Added @since 6.3.0 for newly added get_dependents function
10upsimon Apr 25, 2023
d0e740e
Added @since 6.3.0 for newly added is_valid_strategy function
10upsimon Apr 25, 2023
6801291
Added @since 6.3.0 for newly added get_intended_strategy function
10upsimon Apr 25, 2023
dbca402
Added @since 6.3.0 for newly added is_non_blocking_strategy function
10upsimon Apr 25, 2023
17516c7
Added @since 6.3.0 for newly added has_non_standalone_inline_script f…
10upsimon Apr 25, 2023
9813ba8
Added @since 6.3.0 for newly added has_only_deferrable_dependents fun…
10upsimon Apr 25, 2023
0c90511
Added @since 6.3.0 for newly added get_eligible_loading_strategy func…
10upsimon Apr 25, 2023
25db6e8
Added @since 6.3.0 for newly added wp_print_delayed_inline_script_loa…
10upsimon Apr 25, 2023
b61fe3d
Remove space prior to command in argument list, causing linting error
10upsimon Apr 25, 2023
343e5ed
Update unit test logic for test_non_standalone_and_standalone_after_s…
10upsimon Apr 25, 2023
79ef56d
Update unit test logic for test_non_standalone_and_standalone_after_s…
10upsimon Apr 25, 2023
f75a8d2
Replace double quotes with '"' for certain inline script conditi…
10upsimon Apr 25, 2023
2770ba9
Updates to test suite logic to account for new double quotes and esca…
10upsimon Apr 25, 2023
9d0e68c
Updates to test_non_standalone_after_inline_script_with_defer_main_sc…
10upsimon Apr 26, 2023
3044aa3
Added private var to store a handles dependents against, in order to…
10upsimon Apr 26, 2023
3ca847e
Cleaner output handling within print_inline_script when display condi…
10upsimon Apr 26, 2023
edd3d52
Cleanup/optimzation of code within do_item function for inline script…
10upsimon Apr 26, 2023
59324a8
Docblock wording change
10upsimon Apr 26, 2023
6ab9511
Update applicable core calls to wp_register_script() to reflect new f…
10upsimon Apr 26, 2023
5a94bfa
Fix formatting issue causing PHPCS failure
10upsimon Apr 26, 2023
0e120b7
Rewrite function body for wpLoadAfterScripts to be ES5 and not requir…
10upsimon Apr 27, 2023
da5668f
Updated function body for wpLoadAfterScripts to reflect updated funct…
10upsimon Apr 27, 2023
9c3ded2
Update js formatting within wpLoadAfterScripts function
10upsimon Apr 27, 2023
3d9d0d8
Update js formatting within wpLoadAfterScripts function used in test …
10upsimon Apr 27, 2023
430e5b2
Updated formatting of wpLoadAfterScripts js function to satisfy WP co…
10upsimon Apr 27, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
278 changes: 266 additions & 12 deletions src/wp-includes/class-wp-scripts.php
Original file line number Diff line number Diff line change
Expand Up @@ -295,14 +295,43 @@ public function do_item( $handle, $group = false ) {
}

$before_handle = $this->print_inline_script( $handle, 'before', false );
$after_handle = $this->print_inline_script( $handle, 'after', false );

if ( $before_handle ) {
$before_handle = sprintf( "<script%s id='%s-js-before'>\n%s\n</script>\n", $this->type_attr, esc_attr( $handle ), $before_handle );
}

if ( $after_handle ) {
$after_handle = sprintf( "<script%s id='%s-js-after'>\n%s\n</script>\n", $this->type_attr, esc_attr( $handle ), $after_handle );
$strategy = $this->get_eligible_loading_strategy( $handle );

$after_handle = '';

// Eligible loading strategies will only be 'async', 'defer', or ''.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about blocking?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@westonruter this is not where we define a strategy, but where we get the value back from get_eligible_loading_strategy(). If the intended strategy (i.e the one supplied in $args) was 'blocking' that still gets returned as '' and we treat that as blocking.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if the intended strategy was set as '' in $args, that too is treated as the default strategy, which is blocking.

if ( '' === $strategy ) {
kt-12 marked this conversation as resolved.
Show resolved Hide resolved
$after_handle = $this->print_inline_script( $handle, 'after', false );

if ( $after_handle ) {
$after_handle = sprintf( "<script%s id='%s-js-after'>\n%s\n</script>\n", $this->type_attr, esc_attr( $handle ), $after_handle );
joemcgill marked this conversation as resolved.
Show resolved Hide resolved
}
} else {
$after_standalone_handle = $this->print_inline_script( $handle, 'after-standalone', false );

if ( $after_standalone_handle ) {
$after_handle .= sprintf( "<script%s id='%s-js-after'>\n%s\n</script>\n", $this->type_attr, esc_attr( $handle ), $after_standalone_handle );
}

$after_non_standalone_handle = $this->print_inline_script( $handle, 'after-non-standalone', false );

if ( $after_non_standalone_handle ) {
$initial_type_attr = $this->type_attr;
$this->type_attr = " type='text/template'";
$after_handle .= sprintf(
'<script%1$s id=\'%2$s-js-after\' data-wp-executes-after=\'%2$s\'>%4$s%3$s%4$s</script>%4$s',
$this->type_attr,
esc_attr( $handle ),
$after_non_standalone_handle,
PHP_EOL
);
$this->type_attr = $initial_type_attr;
joemcgill marked this conversation as resolved.
Show resolved Hide resolved
}
}

if ( $before_handle || $after_handle ) {
Expand Down Expand Up @@ -333,7 +362,13 @@ 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 ) ) {
// Used as a conditional to prevent script concatenation.
$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;

// Have to print the so-far concatenated scripts right away to maintain the right order.
Expand Down Expand Up @@ -390,8 +425,20 @@ public function do_item( $handle, $group = false ) {
return true;
}

if ( '' !== $strategy ) {
$strategy = ' ' . $strategy;
if ( ! empty( $after_non_standalone_handle ) ) {
$strategy .= sprintf( " onload='wpLoadAfterScripts(\"%s\")'", esc_attr( $handle ) );
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be more robust to guard against malicious script handles:

Suggested change
$strategy .= sprintf( " onload='wpLoadAfterScripts(\"%s\")'", esc_attr( $handle ) );
$strategy .= sprintf( " onload='wpLoadAfterScripts(%s)'", esc_attr( wp_json_encode( $handle ) ) );

}
}
$tag = $translations . $cond_before . $before_handle;
$tag .= sprintf( "<script%s src='%s' id='%s-js'></script>\n", $this->type_attr, $src, esc_attr( $handle ) );
$tag .= sprintf(
"<script%s src='%s' id='%s-js'%s></script>\n",
$this->type_attr,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto, can we really trust $this->type_attr?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adamsilverstein yes, this is not an addition by us, this is a private var in the WP_Scripts class, and is actually only ever assigned a value in the init() method of said class, where it is given a value of type='text/javascript' if the current theme supports html5 and script.

Please see here.

esc_url( $src ),
esc_attr( $handle ),
$strategy
);
$tag .= $after_handle . $cond_after;

/**
Expand Down Expand Up @@ -419,14 +466,15 @@ public function do_item( $handle, $group = false ) {
*
* @since 4.5.0
*
* @param string $handle Name of the script to add the inline script to.
* Must be lowercase.
* @param string $data String containing the JavaScript to be added.
* @param string $position Optional. Whether to add the inline script
* before the handle or after. Default 'after'.
* @param string $handle Name of the script to add the inline script to.
* Must be lowercase.
* @param string $data String containing the JavaScript to be added.
* @param string $position Optional. Whether to add the inline script
* before the handle or after. Default 'after'.
* @param bool $standalone Optional. Inline script opted to be standalone or not. Default false.
* @return bool True on success, false on failure.
*/
public function add_inline_script( $handle, $data, $position = 'after' ) {
public function add_inline_script( $handle, $data, $position = 'after', $standalone = false ) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same question here - should we consider updating all usages in core?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adamsilverstein I think this would be okay to do, my only comment would be that should any of the main scripts that the inline scripts attached to ever be updated to have a deferred loading strategy (even by association with another script), we'd need to be very certain that these $standalone declarations do not affect the inline scripts, although I am quite sure that should not be the case.

if ( ! $data ) {
return false;
}
Expand All @@ -438,6 +486,12 @@ public function add_inline_script( $handle, $data, $position = 'after' ) {
$script = (array) $this->get_data( $handle, $position );
$script[] = $data;

// Maintain a list of standalone and non-standalone before/after scripts.
$standalone_key = $standalone ? $position . '-standalone' : $position . '-non-standalone';
$standalone_script = (array) $this->get_data( $handle, $standalone_key );
$standalone_script[] = $data;
$this->add_data( $handle, $standalone_key, $standalone_script );

return $this->add_data( $handle, $position, $script );
}

Expand All @@ -464,7 +518,21 @@ public function print_inline_script( $handle, $position = 'after', $display = tr
$output = trim( implode( "\n", $output ), "\n" );

if ( $display ) {
printf( "<script%s id='%s-js-%s'>\n%s\n</script>\n", $this->type_attr, esc_attr( $handle ), esc_attr( $position ), $output );
if ( 'after-non-standalone' === $position ) {
10upsimon marked this conversation as resolved.
Show resolved Hide resolved
$initial_type_attr = $this->type_attr;
$this->type_attr = " type='text/template'";
printf(
'<script%1$s id=\'%2$s-js-after\' data-wp-executes-after=\'%2$s\'>%5$s%4$s%5$s</script>%5$s',
$this->type_attr,
esc_attr( $handle ),
esc_attr( $position ),
$output,
PHP_EOL
);
$this->type_attr = $initial_type_attr;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See previous comment about swapping $this->type_attr and use of PHP_EOL.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

} else {
printf( "<script%s id='%s-js-%s'>\n%s\n</script>\n", $this->type_attr, esc_attr( $handle ), esc_attr( $position ), $output );
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Numbered placeholders and readability:

Suggested change
printf( "<script%s id='%s-js-%s'>\n%s\n</script>\n", $this->type_attr, esc_attr( $handle ), esc_attr( $position ), $output );
printf(
"<script%1$s id='%2$s-js-%3$s'>\n%4$s\n</script>\n",
$this->type_attr,
esc_attr( $handle ),
esc_attr( $position ),
$output
);

Copy link

@kt-12 kt-12 Apr 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
}

return $output;
Expand Down Expand Up @@ -714,6 +782,192 @@ public function in_default_dir( $src ) {
return false;
}

/**
* This overrides the add_data method from WP_Dependencies, to support normalizing of $args.
*
* @param string $handle Name of the item. Should be unique.
* @param string $key The data key.
* @param mixed $value The data value.
* @return bool True on success, false on failure.
*/
public function add_data( $handle, $key, $value ) {
if ( 'script_args' === $key ) {
$args = $this->get_normalized_script_args( $handle, $value );
if ( $args['in_footer'] ) {
parent::add_data( $handle, 'group', 1 );
}
return parent::add_data( $handle, $key, $args );
}
return parent::add_data( $handle, $key, $value );
}

/**
* Checks all handles for any delayed inline scripts.
*
* @return bool True if the inline script present, otherwise false.
*/
public function has_delayed_inline_script() {
foreach ( $this->registered as $handle => $script ) {
// Non standalone scripts in the after position, of type async or defer, are usually delayed.
if ( in_array( $this->get_intended_strategy( $handle ), array( 'defer', 'async' ), true ) &&
$this->has_non_standalone_inline_script( $handle, 'after' )
) {
return true;
}
}
return false;
}

/**
* Normalize the data inside the $args parameter and support backward compatibility.
*
* @param string $handle Name of the script.
* @param array $args {
* Optional. Additional script arguments. Default empty array.
*
* @type boolean $in_footer Optional. Default false.
* @type string $strategy Optional. Values blocking|defer|async. Default 'blocking'.
* }
* @return array Normalized $args array.
*/
private function get_normalized_script_args( $handle, $args = array() ) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent! noting this will need a _ prefix for core (convention for private functions)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adamsilverstein I think we need to seek clarity around this, as when searching the contents of wp-includes there are far more instances of private function declarations without the _ preceding the function name than there are with the _, by a large amount.

I also can not find anything about this in the official coding standards, see link here.

I'm happy to add it, as it changes little aside from having to update one or two references to the function, but I do feel that this is an area of preference as opposed to standard.

If I am wrong, please let me know :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is a private class method, the prefix is unnecessary. In wp-includes at the moment, only 15 of the 114 private methods start with an underscore. The underscore prefix is more commonly used for global functions.

$default_args = array(
'in_footer' => false,
'strategy' => 'blocking',
);

// Handle backward compatibility for $in_footer.
if ( true === $args ) {
$args = array( 'in_footer' => true );
}

return wp_parse_args( $args, $default_args );
}

/**
* Get all dependents of a script.
*
* @param string $handle The script handle.
* @return array Array of script handles.
*/
private function get_dependents( $handle ) {
$dependents = array();

// Iterate over all registered scripts, finding dependents of the script passed to this method.
foreach ( $this->registered as $registered_handle => $args ) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this loop execution time will grow as the number of registered handles grows. Probably fine, but I do have a concern that on large sites with many scripts it could become a bit heavy. a potential optimization here would be building a map of handle->array(dependents) the first time it is called, then use the map for subsequent calls.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@adamsilverstein I've amended this in a recent commit to make sue of a private var to maintain the mapping, and use this for a given handle should it exist.

if ( in_array( $handle, $args->deps, true ) ) {
$dependents[] = $registered_handle;
}
}

return $dependents;
}

/**
* Get the strategy assigned during script registration.
*
* @param string $handle The script handle.
* @return string|bool Strategy set during script registration. False if none was set.
*/
private function get_intended_strategy( $handle ) {
$script_args = $this->get_data( $handle, 'script_args' );

return isset( $script_args['strategy'] ) ? $script_args['strategy'] : false;
joemcgill marked this conversation as resolved.
Show resolved Hide resolved
}

/**
* Check if a script has a non standalone inline script associated with it.
*
* @param string $handle The script handle.
* @param string $position Position of the inline script.
*
* @return bool True if script present. False if empty.
*/
private function has_non_standalone_inline_script( $handle, $position ) {
$non_standalone_script_key = $position . '-non-standalone';
$non_standalone_script = $this->get_data( $handle, $non_standalone_script_key );

return ! empty( $non_standalone_script );
}

/**
* Check if all of a scripts dependents are deferrable, which is required to maintain execution order.
*
* @param string $handle The script handle.
* @param array $checked Optional. An array of already checked script handles, used to avoid recursive loops.
* @return bool True if all dependents are deferrable, false otherwise.
*/
private function has_only_deferrable_dependents( $handle, $checked = array() ) {
// If this node was already checked, this script can be deferred and the branch ends.
if ( in_array( $handle, $checked, true ) ) {
return true;
}

$checked[] = $handle;
$dependents = $this->get_dependents( $handle );

// If there are no dependents remaining to consider, the script can be deferred.
if ( empty( $dependents ) ) {
return true;
}

// Consider each dependent and check if it is deferrable.
foreach ( $dependents as $dependent ) {
// If the dependent script is not using the defer or async strategy, no script in the chain is deferrable.
if ( ! in_array( $this->get_intended_strategy( $dependent ), array( 'defer', 'async' ), true ) ) {
joemcgill marked this conversation as resolved.
Show resolved Hide resolved
return false;
}

// If the dependent script has a non-standalone inline script in the 'before' position associated with it, do not defer.
if ( $this->has_non_standalone_inline_script( $dependent, 'before' ) ) {
return false;
}

// Recursively check all dependents.
if ( ! $this->has_only_deferrable_dependents( $dependent, $checked ) ) {
return false;
}
}

return true;
}

/**
* Get the best eligible loading strategy for a script.
*
* @param string $handle The registered handle of the script.
* @return string $strategy return the final strategy.
*/
private function get_eligible_loading_strategy( $handle ) {
if ( ! isset( $this->registered[ $handle ] ) ) {
return '';
}

$intended_strategy = $this->get_intended_strategy( $handle );

/*
* Handle known blocking strategy scenarios.
*
* blocking if script args not set.
* blocking if explicitly set.
*/
if ( ! $intended_strategy || 'blocking' === $intended_strategy ) {
return '';
}

// Handling async strategy scenarios.
if ( 'async' === $intended_strategy && empty( $this->registered[ $handle ]->deps ) && empty( $this->get_dependents( $handle ) ) ) {
return 'async';
}

// Handling defer strategy scenarios.
if ( $this->has_only_deferrable_dependents( $handle ) ) {
return 'defer';
}

return '';
}

/**
* Resets class properties.
*
Expand Down
1 change: 1 addition & 0 deletions src/wp-includes/default-filters.php
Original file line number Diff line number Diff line change
Expand Up @@ -568,6 +568,7 @@
add_action( 'enqueue_block_editor_assets', 'wp_enqueue_editor_format_library_assets' );
add_action( 'enqueue_block_editor_assets', 'wp_enqueue_global_styles_css_custom_properties' );
add_filter( 'wp_print_scripts', 'wp_just_in_time_script_localization' );
add_action( 'wp_print_scripts', 'wp_print_template_loader_script' );
add_filter( 'print_scripts_array', 'wp_prototype_before_jquery' );
add_filter( 'customize_controls_print_styles', 'wp_resource_hints', 1 );
add_action( 'admin_head', 'wp_check_widget_editor_deps' );
Expand Down
Loading