css = $css;
}
/**
* Converts existing screen CSS to be asynchronously loaded.
*
* @param string $html The link tag for the enqueued style.
* @param string $handle The style's registered handle.
* @param string $href The stylesheet's source URL.
* @param string $media The stylesheet's media attribute.
*
* @return string
* @see style_loader_tag
*/
public function asynchronize_stylesheets(
$html,
$handle,
$href,
$media
) {
// If there is no critical CSS, do not alter the stylesheet loading.
if ( ! $this->css ) {
return $html;
}
$supported_loading_methods = array( 'async', 'deferred' );
/**
* Loading method for stylesheets.
*
* Filter the loading method for each stylesheet for the screen with following values:
* async - Stylesheets are loaded asynchronously.
* Styles are applied once the stylesheet is loaded completely without render blocking.
* deferred - Loading of stylesheets are deferred until the window load event.
* Styles from all the stylesheets are applied at once after the page load.
*
* Stylesheet loading behaviour is not altered for any other value such as false or 'default'.
* Stylesheet loading is instant and the process blocks the page rendering.
* Eg: add_filter( 'jetpack_boost_async_style', '__return_false' );
*
* @param string $handle The style's registered handle.
* @param string $media The stylesheet's media attribute.
*
* @see onload_flip_stylesheets for how stylesheets loading is deferred.
*
* @todo Retrieve settings from database, either via auto-configuration or UI option.
*/
$method = apply_filters( 'jetpack_boost_async_style', 'async', $handle, $media );
// If the loading method is not supported, do not alter the stylesheet loading.
if ( ! in_array( $method, $supported_loading_methods, true ) ) {
return $html;
}
// Update the stylesheet markup for supported loading methods using WordPress HTML API.
$processor = new \WP_HTML_Tag_Processor( $html );
if ( ! $processor->next_tag( 'link' ) ) {
return $html;
}
// Only process if this is a stylesheet link tag.
if ( 'stylesheet' !== $processor->get_attribute( 'rel' ) ) {
return $html;
}
// Set the new attributes based on the selected method.
$processor->set_attribute( 'media', 'not all' );
$processor->set_attribute( 'data-media', $media );
if ( 'async' === $method ) {
$processor->set_attribute( 'onload', "this.media=this.dataset.media; delete this.dataset.media; this.removeAttribute( 'onload' );" );
}
// Prepend the original HTML stylesheet tag within the noscript tag
// to support the rendering of the stylesheet when JavaScript is disabled.
return '' . $processor->get_updated_html();
}
/**
* Prints the critical CSS to the page.
*/
public function display_critical_css() {
$critical_css = $this->css;
if ( ! $critical_css ) {
return false;
}
echo '';
}
/**
* Neutralize any closing
* element without breaking out of it.
*
* This is NOT a general-purpose CSS sanitizer: it does exactly one thing,
* which is to stop the CSS from terminating the surrounding element.
*/
public static function neutralize_style_closing_tags( $css ) {
return str_ireplace( ' block to media="not all" to deactivate it.
*/
public function onload_flip_stylesheets() {
/*
Unminified version of footer script.
?>