-
Notifications
You must be signed in to change notification settings - Fork 0
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
Implement load handlers #50
Implement load handlers #50
Conversation
src/wp-includes/class-wp-scripts.php
Outdated
$output = <<<JS | ||
let wpLoadAfterScripts = ( handle ) => { | ||
let scripts = document.querySelectorAll(`[type="text/template"][data-wp-executes-after="\${handle}"]`); | ||
scripts.forEach( (script) => { script.setAttribute("type","text/javascript") }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kt-12 is this enough to get the browser to actually execute the script by just converting its type? I'm quite sure that during the discovery phase we has ascertained that this may need manual execution and that the browser would not automatically fire the JS tag just because its type was dynamically altered.
Can you confirm this please?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kt-12 upon further research, it seems to me that changing the type attribute alone will not execute the JS, and even inline injection/alteration would not. We're likely going to have to use appendChild()
or a similar method, where we clone the text/template tag, change the attribute, find the DOM element that exists currently (i.e the text/template tag in question) and append the new JS tag after it. We would probably want to then remove the text/template element.
A series of events may look like this:
- Iterate over all text/template tags as you currently do above
- Reference that DOM element
- Reference the full tag as text form, as a variable
- Change the type to text/javascript as you're doing above
- Use
appendChild()
to append the new script string after the DOM element referenced in point 2 - Consider deleting the DOM element referenced in point 2 above, but you'd need to make a call if this has implications and whether we should keep it.
src/wp-includes/class-wp-scripts.php
Outdated
$output = <<<JS | ||
let wpLoadAfterScripts = ( handle ) => { | ||
let scripts = document.querySelectorAll(`[type="text/template"][data-wp-executes-after="\${handle}"]`); | ||
scripts.forEach( (script) => { script.setAttribute("type","text/javascript") }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kt-12 upon further research, it seems to me that changing the type attribute alone will not execute the JS, and even inline injection/alteration would not. We're likely going to have to use appendChild()
or a similar method, where we clone the text/template tag, change the attribute, find the DOM element that exists currently (i.e the text/template tag in question) and append the new JS tag after it. We would probably want to then remove the text/template element.
A series of events may look like this:
- Iterate over all text/template tags as you currently do above
- Reference that DOM element
- Reference the full tag as text form, as a variable
- Change the type to text/javascript as you're doing above
- Use
appendChild()
to append the new script string after the DOM element referenced in point 2 - Consider deleting the DOM element referenced in point 2 above, but you'd need to make a call if this has implications and whether we should keep it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kt-12 minor observations, comments and small change requests noted.
src/wp-includes/class-wp-scripts.php
Outdated
* | ||
* @return bool True if script present. False if empty. | ||
*/ | ||
public function maybe_has_delayed_inline_script() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kt-12 this is a nitpick comment I guess, but I am wondering if maybe
is the correct wording here, as it seems to be like you are indefinitely checking of a deferred or async script has inline scripts? This is not a case of maybe
and seems like it's more a definite outcome?
If you agree, let's rename this to has_delayed_inline_script()
as that is more true to the logic here.
If I've misunderstood, please comment as such thank you :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are correct. I used maybe as there are certain cases where the final strategy of a script might change before we print them effecting it's inline scripts decision. For example a defer may change to blocking, but we never know it in print_scripts action.
But i do agree maybe
is not needed here, i'll remove that.
Co-authored-by: Simon Dowdles <72872375+10upsimon@users.noreply.github.com>
Co-authored-by: Simon Dowdles <72872375+10upsimon@users.noreply.github.com>
Co-authored-by: Simon Dowdles <72872375+10upsimon@users.noreply.github.com>
…com/10up/wordpress-develop into enhancement/implement_load_handlers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @kt-12, I quick review and left some feedback and questions.
src/wp-includes/class-wp-scripts.php
Outdated
'<script%1$s id=\'%2$s-js-after\' type=\'text/template\' 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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'<script%1$s id=\'%2$s-js-after\' type=\'text/template\' 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 | |
'<script%s id=\'%2$s-js-after\' type=\'text/template\' data-wp-executes-after=\'%s\'>\n%s\n</script>\n', | |
$this->type_attr, | |
esc_attr( $handle ), | |
$after_non_standalone_handle, |
Similar to other scripts, use \n
instead of PHP_EOL
and use %s
as it is sufficient for these changes as we don't need to add translators or change the order of the arguments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mukeshpanchal27 I was trying the same initially but \n don't work when the parent string is in single quotes. It is instead printed as string \n
. Numbered placeholder was added as there are multiple places i wanted the handle string and for numbered placeholder I need the enclosing string to be in single quotes.
@@ -771,6 +788,23 @@ public function add_data( $handle, $key, $value ) { | |||
return parent::add_data( $handle, $key, $value ); | |||
} | |||
|
|||
/** | |||
* Check all handles for any delayed inline scripts. | |||
* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Since
annotation is missing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mukeshpanchal27 We haven't fixed on the final @since
yet. We have a separate task for this.
src/wp-includes/script-loader.php
Outdated
}) | ||
} | ||
JS; | ||
printf( "<script id='wp-executes-after-js'>\n%s\n</script>\n", $output ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
$this->type_attr
is missing in script.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed, but $this->type_attr
is not available here so replicate the way function _print_scripts()
was handling the same scenario.
src/wp-includes/script-loader.php
Outdated
/** | ||
* Prints a loader script if there is text/template registered script. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per PHP Documentation Standards, Use proper format for function
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated. Usage of since
is still missing as this will be handled together for the entire functionality in a separate task. Thanks @mukeshpanchal27.
let wpLoadAfterScripts = ( handle ) => { | ||
let scripts = document.querySelectorAll(`[type="text/template"][data-wp-executes-after="\${handle}"]`); | ||
scripts.forEach( (script) => { | ||
script.setAttribute("type","text/javascript"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
script.setAttribute("type","text/javascript"); |
WP use $this->type_attr
for script type. Please correct me if i miss anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@mukeshpanchal27 this is the JS code for modifying type after a script is loaded on the DOM. So we can't use $this->type_attr
Co-authored-by: Mukesh Panchal <mukeshpanchal27@users.noreply.github.com>
Co-authored-by: Mukesh Panchal <mukeshpanchal27@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple small nits, but this seems ok to me. Pre-approving since nothing is blocking.
src/wp-includes/class-wp-scripts.php
Outdated
if ( in_array( $this->get_intended_strategy( $handle ), array( 'defer', 'async' ), true ) ) { | ||
// non standalone after scripts of async or defer are usually delayed. | ||
if ( $this->has_non_standalone_inline_script( $handle, 'after' ) ) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These could be combined into a single if
statement with &&
}) | ||
} | ||
JS; | ||
$type_attr = current_theme_supports( 'html5', 'script' ) ? '' : " type='text/javascript'"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could probably use $wp_scripts->type_attr
since it's the same functionality, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@joemcgill we can't use it here as, type_attr
is a private attribute.
src/wp-includes/script-loader.php
Outdated
$wp_scripts = wp_scripts(); | ||
if ( $wp_scripts->has_delayed_inline_script() ) { | ||
$output = <<<JS | ||
let wpLoadAfterScripts = ( handle ) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could probably be a regular function rather than an arrow function.
function wpLoadAfterScripts( handle ) {
// functionality
}
src/wp-includes/script-loader.php
Outdated
* associated with a handle to type/javascript and execute them. | ||
*/ | ||
function wp_print_template_loader_script() { | ||
$wp_scripts = wp_scripts(); | ||
if ( $wp_scripts->has_delayed_inline_script() ) { | ||
$output = <<<JS | ||
let wpLoadAfterScripts = ( handle ) => { | ||
function wpLoadAfterScripts() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You still need to accept a handle
param, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed.
Thanks @kt-12. I've already approved so this is good to merge whenever you're ready. |
Trac ticket:
This Pull Request is for code review only. Please keep all other discussion in the Trac ticket. Do not merge this Pull Request. See GitHub Pull Requests for Code Review in the Core Handbook for more details.