diff --git a/inc/Engine/Common/Head/ElementTrait.php b/inc/Engine/Common/Head/ElementTrait.php new file mode 100644 index 0000000000..9511a1250c --- /dev/null +++ b/inc/Engine/Common/Head/ElementTrait.php @@ -0,0 +1,139 @@ +link( $args ); + } + + /** + * Preconnect link. + * + * @param array $args Element args. + * @return array|string[] + */ + protected function preconnect_link( array $args = [] ) { + $args['rel'] = 'preconnect'; + return $this->link( $args ); + } + + /** + * Dns_prefetch link. + * + * @param array $args Element args. + * @return array|string[] + */ + protected function dns_prefetch_link( array $args = [] ) { + $args['rel'] = 'dns-prefetch'; + return $this->link( $args ); + } + + /** + * Prefetch link. + * + * @param array $args Element args. + * @return array|string[] + */ + protected function prefetch_link( array $args = [] ) { + $args['rel'] = 'prefetch'; + return $this->link( $args ); + } + + /** + * Prerender link. + * + * @param array $args Element args. + * @return array|string[] + */ + protected function prerender_link( array $args = [] ) { + $args['rel'] = 'prerender'; + return $this->link( $args ); + } + + /** + * Stylesheet link. + * + * @param array $args Element args. + * @return array|string[] + */ + protected function stylesheet_link( array $args = [] ) { + $args['rel'] = 'stylesheet'; + return $this->link( $args ); + } + + /** + * Style tag. + * + * @param string $css CSS content. + * @param array $args Element args. + * @return array|string[] + */ + protected function style_tag( string $css = '', array $args = [] ) { + $element = [ + 'open_tag' => ' $css, + ] + ); + $element['close_tag'] = ''; + + return $element; + } + + /** + * Noscript tag. + * + * @param string $content Element contents. + * @param array $args Element args. + * @return array|string[] + */ + protected function noscript_tag( string $content = '', array $args = [] ) { + $element = [ + 'open_tag' => ' $content, + ] + ); + $element['close_tag'] = ''; + + return $element; + } + + /** + * Generic link tag. + * + * @param array $args Element args. + * @return array|string[] + */ + private function link( array $args = [] ) { + $element = [ + 'open_tag' => ' '', + ] + ); + + return $element; + } +} diff --git a/inc/Engine/Common/Head/ServiceProvider.php b/inc/Engine/Common/Head/ServiceProvider.php new file mode 100644 index 0000000000..885943fe7f --- /dev/null +++ b/inc/Engine/Common/Head/ServiceProvider.php @@ -0,0 +1,39 @@ +provides, true ); + } + + /** + * Registers items with the container + * + * @return void + */ + public function register(): void { + $this->getContainer()->addShared( 'common_head_subscriber', Subscriber::class ); + } +} diff --git a/inc/Engine/Common/Head/Subscriber.php b/inc/Engine/Common/Head/Subscriber.php new file mode 100644 index 0000000000..0c0148adea --- /dev/null +++ b/inc/Engine/Common/Head/Subscriber.php @@ -0,0 +1,168 @@ + 'method_name') + * * array('hook_name' => array('method_name', $priority)) + * * array('hook_name' => array('method_name', $priority, $accepted_args)) + * * array('hook_name' => array(array('method_name_1', $priority_1, $accepted_args_1)), array('method_name_2', $priority_2, $accepted_args_2))) + * + * @return array + */ + public static function get_subscribed_events() { + return [ + 'rocket_buffer' => [ 'insert_rocket_head', 100000 ], + 'rocket_head' => 'print_head_elements', + ]; + } + + /** + * Print all head elements. + * + * @param string $content Head elements HTML. + * @return string + */ + public function print_head_elements( $content ) { + /** + * Filter Head elements array. + * + * @param array $head_items Elements to be added to head after closing of title tag. + * + * Priority 10: preconnect + * Priority 30: preload + * Priority 50: styles + * @returns array + */ + $items = wpm_apply_filters_typed( 'array', 'rocket_head_items', [] ); + if ( empty( $items ) ) { + return $content; + } + + $this->head_items = []; + // Combine elements. + $elements = ''; + foreach ( $items as $item ) { + // Make sure that we don't have duplication based on `href` inside each `rel`. + if ( $this->is_duplicate( $item ) ) { + continue; + } + $elements .= "\n" . $this->prepare_element( $item ); + } + + return $content . $elements; + } + + /** + * Check if the item is duplicate. + * + * @param array $item Item to check. + * @return bool + */ + private function is_duplicate( $item ) { + if ( empty( $item['rel'] ) || empty( $item['href'] ) ) { + return false; + } + + if ( ! isset( $this->head_items[ $item['rel'] ] ) ) { + $this->head_items[ $item['rel'] ] = []; + } + + if ( ! isset( $this->head_items[ $item['rel'] ][ $item['href'] ] ) ) { + $this->head_items[ $item['rel'] ][ $item['href'] ] = true; + return false; + } + + return true; + } + + /** + * Prepare element HTML from the item array. + * + * @param array $element Item element. + * @return string + */ + private function prepare_element( $element ) { + $open_tag = ''; + if ( ! empty( $element['open_tag'] ) ) { + $open_tag = $element['open_tag']; + unset( $element['open_tag'] ); + } + + $close_tag = ''; + if ( ! empty( $element['close_tag'] ) ) { + $close_tag = $element['close_tag']; + unset( $element['close_tag'] ); + } + + $inner_content = ''; + if ( ! empty( $element['inner_content'] ) ) { + $inner_content = $element['inner_content']; + unset( $element['inner_content'] ); + } + + $attributes = []; + + ksort( $element, SORT_NATURAL ); + + foreach ( $element as $key => $value ) { + if ( is_int( $key ) ) { + $attributes[] = $value; + continue; + } + $attributes[] = $key . '="' . esc_attr( $value ) . '"'; + } + + $attributes_html = ! empty( $attributes ) ? ' ' . implode( ' ', $attributes ) : ''; + + return $open_tag . $attributes_html . '>' . $inner_content . $close_tag; + } + + /** + * Insert rocket_head into the buffer HTML + * + * @param string $html Buffer HTML. + * @return string + */ + public function insert_rocket_head( $html ) { + if ( empty( $html ) ) { + return $html; + } + + $filtered_buffer = preg_replace( + '##iU', + '' . wpm_apply_filters_typed( 'string', 'rocket_head', '' ), + $html, + 1 + ); + + if ( empty( $filtered_buffer ) ) { + return $html; + } + + return $filtered_buffer; + } +} diff --git a/inc/Engine/CriticalPath/CriticalCSSSubscriber.php b/inc/Engine/CriticalPath/CriticalCSSSubscriber.php index 8d663f8e99..38421de43b 100644 --- a/inc/Engine/CriticalPath/CriticalCSSSubscriber.php +++ b/inc/Engine/CriticalPath/CriticalCSSSubscriber.php @@ -4,6 +4,7 @@ use WP_Rocket\Admin\Options; use WP_Rocket\Admin\Options_Data; +use WP_Rocket\Engine\Common\Head\ElementTrait; use WP_Rocket\Engine\License\API\User; use WP_Rocket\Engine\Optimization\RegexTrait; use WP_Rocket\Event_Management\Subscriber_Interface; @@ -18,6 +19,7 @@ class CriticalCSSSubscriber implements Subscriber_Interface { use RegexTrait; use CommentTrait; + use ElementTrait; /** * Instance of Critical CSS. @@ -61,6 +63,13 @@ class CriticalCSSSubscriber implements Subscriber_Interface { */ protected $user; + /** + * Critical CSS contents. + * + * @var string + */ + private $critical_css_content = ''; + /** * Creates an instance of the Critical CSS Subscriber. * @@ -113,12 +122,13 @@ public static function get_subscribed_events() { [ 'async_css', 32 ], ], + 'rocket_head_items' => [ 'insert_css_in_head', 50 ], 'switch_theme' => 'maybe_regenerate_cpcss', 'rocket_excluded_inline_js_content' => 'exclude_inline_js', 'before_delete_post' => 'delete_cpcss', - 'rocket_before_rollback' => [ 'stop_critical_css_generation', 9 ], - 'wp_rocket_upgrade' => [ 'stop_critical_css_generation', 9 ], - 'admin_post_switch_to_rucss' => 'switch_to_rucss', + 'rocket_before_rollback' => [ 'stop_critical_css_generation', 9 ], + 'wp_rocket_upgrade' => [ 'stop_critical_css_generation', 9 ], + 'admin_post_switch_to_rucss' => 'switch_to_rucss', ]; // phpcs:enable WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned } @@ -595,20 +605,43 @@ public function insert_critical_css_buffer( $buffer ) { return $buffer; } - $critical_css_content = str_replace( '\\', '\\\\', $critical_css_content ); - - $buffer = preg_replace( - '##iU', - '', - $buffer, - 1 - ); + $this->critical_css_content = str_replace( '\\', '\\\\', $critical_css_content ); $buffer = preg_replace( '##iU', $this->return_remove_cpcss_script() . '', $buffer, 1 ); return $this->add_meta_comment( 'async_css', $buffer ); } + /** + * Insert critical CSS into head. + * + * @param array $items Head elements. + * @return mixed + */ + public function insert_css_in_head( $items ) { + $css = $this->get_critical_css_content(); + if ( empty( $css ) ) { + return $items; + } + + $items[] = $this->style_tag( + $css, + [ + 'id' => 'rocket-critical-css', + ] + ); + return $items; + } + + /** + * Get critical CSS content, getter method for critical_css_content property. + * + * @return string + */ + public function get_critical_css_content() { + return $this->should_async_css() ? $this->critical_css_content : ''; + } + /** * Returns JS script to remove the critical css style from frontend. * diff --git a/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php b/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php index 271f94e6f7..7de1e16b5b 100644 --- a/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php +++ b/inc/Engine/Optimization/GoogleFonts/AbstractGFOptimization.php @@ -3,6 +3,7 @@ namespace WP_Rocket\Engine\Optimization\GoogleFonts; +use WP_Rocket\Engine\Common\Head\ElementTrait; use WP_Rocket\Engine\Media\Fonts\FontsTrait; /** @@ -12,6 +13,7 @@ */ abstract class AbstractGFOptimization { use FontsTrait; + use ElementTrait; /** * Allowed display values. @@ -106,32 +108,85 @@ protected function get_font_display_value(): string { } /** - * Returns the optimized markup for Google Fonts + * Check if preload google fonts is enabled or not using filter. * - * @since 3.9.1 + * @return bool + */ + protected function is_preload_enabled() { + return ! wpm_apply_filters_typed( 'boolean', 'rocket_disable_google_fonts_preload', false ); + } + + /** + * Prepare preload fonts to the head items. * - * @param string $url Google Fonts URL. + * @param array $fonts Fonts list. + * @param array $items Head items. + * @return array + */ + protected function prepare_preload_fonts_to_head( array $fonts, array $items ): array { + foreach ( $fonts as $font_url ) { + $items[] = $this->preload_link( + [ + 'href' => $font_url, + 'as' => 'style', + ] + ); + } + + return $items; + } + + /** + * Prepare stylesheets to the head. * - * @return string + * @param array $fonts Fonts list. + * @param array $items Head items. + * @return array */ - protected function get_optimized_markup( string $url ): string { - /** - * Filters whether to disable Google Fonts preloading. - * - * @since 3.18 - * - * @param bool $disable_google_fonts_preload Whether to disable Google Fonts preloading. Default false. - */ - if ( wpm_apply_filters_typed( 'boolean', 'rocket_disable_google_fonts_preload', false ) ) { - return sprintf( - '', // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet - $url + protected function prepare_stylesheet_fonts_to_head( array $fonts, array $items ): array { + $preload_enabled = $this->is_preload_enabled(); + + foreach ( $fonts as $font_url ) { + $item = $this->stylesheet_link( + [ + 'href' => $font_url, + ] + ); + + if ( ! $preload_enabled ) { + $items[] = $item; + continue; + } + + $item['media'] = 'print'; + $item['onload'] = "this.media='all'"; + $items[] = $item; + + $items[] = $this->noscript_tag( + sprintf( '', $font_url ) // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet ); } - return sprintf( - '', // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedStylesheet - $url - ); + return $items; + } + + /** + * Insert font stylesheets into head. + * + * @param array $items Head elements. + * @return mixed + */ + public function insert_font_stylesheet_into_head( $items ) { + return $items; + } + + /** + * Insert font preloads into head. + * + * @param array $items Head elements. + * @return mixed + */ + public function insert_font_preload_into_head( $items ) { + return $items; } } diff --git a/inc/Engine/Optimization/GoogleFonts/Combine.php b/inc/Engine/Optimization/GoogleFonts/Combine.php index 9308f811ef..cd897894cb 100644 --- a/inc/Engine/Optimization/GoogleFonts/Combine.php +++ b/inc/Engine/Optimization/GoogleFonts/Combine.php @@ -32,6 +32,13 @@ class Combine extends AbstractGFOptimization { */ protected $subsets = ''; + /** + * Font urls. + * + * @var array + */ + protected $font_urls = []; + /** * Combines multiple Google Fonts links into one * @@ -42,6 +49,7 @@ class Combine extends AbstractGFOptimization { * @return string */ public function optimize( $html ): string { + $this->font_urls = []; Logger::info( 'GOOGLE FONTS COMBINE PROCESS STARTED.', [ 'GF combine process' ] ); $html_nocomments = $this->hide_comments( $html ); @@ -64,7 +72,7 @@ public function optimize( $html ): string { function ( $font ) use ( $exclusions ) { return ! $this->is_excluded( $font[0], $exclusions ); } - ); + ); $num_fonts = count( $filtered_fonts ); @@ -84,7 +92,7 @@ function ( $font ) use ( $exclusions ) { return $html; } - $html = preg_replace( '@<\/title>@i', '$0' . $this->get_optimized_markup( $this->get_combined_url() ), $html, 1 ); + $this->font_urls[] = $this->get_combined_url(); foreach ( $filtered_fonts as $font ) { $html = str_replace( $font[0], '', $html ); @@ -152,4 +160,47 @@ private function get_combined_url(): string { return esc_url( "https://fonts.googleapis.com/css?family={$this->fonts}{$this->subsets}&display={$display}" ); } + + /** + * Get font urls, getter method for font_urls property. + * + * @return array + */ + public function get_font_urls(): array { + return $this->font_urls; + } + + /** + * Insert font stylesheets into head. + * + * @param array $items Head elements. + * @return mixed + */ + public function insert_font_stylesheet_into_head( $items ) { + $font_urls = $this->get_font_urls(); + if ( empty( $font_urls ) ) { + return $items; + } + + return $this->prepare_stylesheet_fonts_to_head( $font_urls, $items ); + } + + /** + * Insert font preloads into head. + * + * @param array $items Head elements. + * @return mixed + */ + public function insert_font_preload_into_head( $items ) { + $font_urls = $this->get_font_urls(); + if ( empty( $font_urls ) ) { + return $items; + } + + if ( ! $this->is_preload_enabled() ) { + return $items; + } + + return $this->prepare_preload_fonts_to_head( $font_urls, $items ); + } } diff --git a/inc/Engine/Optimization/GoogleFonts/CombineV2.php b/inc/Engine/Optimization/GoogleFonts/CombineV2.php index b3878f064a..c92ccffa3c 100644 --- a/inc/Engine/Optimization/GoogleFonts/CombineV2.php +++ b/inc/Engine/Optimization/GoogleFonts/CombineV2.php @@ -14,6 +14,13 @@ class CombineV2 extends AbstractGFOptimization { use RegexTrait; + /** + * Font urls. + * + * @var array + */ + protected $font_urls = []; + /** * Combines multiple Google Fonts (API v2) links into one * @@ -24,6 +31,7 @@ class CombineV2 extends AbstractGFOptimization { * @return string */ public function optimize( $html ): string { + $this->font_urls = []; Logger::info( 'GOOGLE FONTS COMBINE-V2 PROCESS STARTED.', [ 'GF combine process' ] ); $processed_tags = []; @@ -73,9 +81,9 @@ function ( $tag ) use ( $exclusions ) { return $html; } - $families = array_unique( $families ); - $combined_tag = $this->get_optimized_markup( $this->get_combined_url( $families ) ); - $html = preg_replace( '@<\/title>@i', '$0' . $combined_tag, $html, 1 ); + $families = array_unique( $families ); + $combined_url = $this->get_combined_url( $families ); + $this->font_urls[] = $combined_url; foreach ( $processed_tags as $font ) { $html = str_replace( $font[0], '', $html ); @@ -85,7 +93,7 @@ function ( $tag ) use ( $exclusions ) { 'V2 Google Fonts successfully combined.', [ 'GF combine process', - 'url' => $combined_tag, + 'url' => $combined_url, ] ); @@ -161,4 +169,47 @@ private function get_concatenated_families( array $families ): string { return rtrim( $families_string, '&?' ); } + + /** + * Get font urls, getter method for font_urls property. + * + * @return array + */ + public function get_font_urls(): array { + return $this->font_urls; + } + + /** + * Insert font stylesheets into head. + * + * @param array $items Head elements. + * @return mixed + */ + public function insert_font_stylesheet_into_head( $items ) { + $font_urls = $this->get_font_urls(); + if ( empty( $font_urls ) ) { + return $items; + } + + return $this->prepare_stylesheet_fonts_to_head( $font_urls, $items ); + } + + /** + * Insert font preloads into head. + * + * @param array $items Head elements. + * @return mixed + */ + public function insert_font_preload_into_head( $items ) { + $font_urls = $this->get_font_urls(); + if ( empty( $font_urls ) ) { + return $items; + } + + if ( ! $this->is_preload_enabled() ) { + return $items; + } + + return $this->prepare_preload_fonts_to_head( $font_urls, $items ); + } } diff --git a/inc/Engine/Optimization/GoogleFonts/Subscriber.php b/inc/Engine/Optimization/GoogleFonts/Subscriber.php index 19232d36e8..28088738ca 100644 --- a/inc/Engine/Optimization/GoogleFonts/Subscriber.php +++ b/inc/Engine/Optimization/GoogleFonts/Subscriber.php @@ -55,6 +55,10 @@ public static function get_subscribed_events() { return [ 'wp_resource_hints' => [ 'preconnect', 10, 2 ], 'rocket_buffer' => [ 'process', 17 ], + 'rocket_head_items' => [ + [ 'insert_fonts_preload', 30 ], + [ 'insert_fonts_stylesheets', 50 ], + ], ]; } @@ -126,4 +130,32 @@ protected function is_allowed() { return ! is_user_logged_in() || (bool) $this->options->get( 'cache_logged_user', 0 ); } + + /** + * Insert fonts link stylesheets into head elements for v1 and v2. + * + * @param array $items Head elements. + * @return mixed + */ + public function insert_fonts_stylesheets( array $items ) { + if ( ! $this->is_allowed() ) { + return $items; + } + $items = $this->combine_v2->insert_font_stylesheet_into_head( $items ); + return $this->combine->insert_font_stylesheet_into_head( $items ); + } + + /** + * Insert fonts preloads into head elements for v1 and v2. + * + * @param array $items Head elements. + * @return mixed + */ + public function insert_fonts_preload( $items ) { + if ( ! $this->is_allowed() ) { + return $items; + } + $items = $this->combine_v2->insert_font_preload_into_head( $items ); + return $this->combine->insert_font_preload_into_head( $items ); + } } diff --git a/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php b/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php index 6c19692474..1ae6609644 100644 --- a/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php +++ b/inc/Engine/Optimization/RUCSS/Controller/UsedCSS.php @@ -5,6 +5,7 @@ use WP_Rocket\Admin\Options_Data; use WP_Rocket\Engine\Common\Context\ContextInterface; +use WP_Rocket\Engine\Common\Head\ElementTrait; use WP_Rocket\Engine\Optimization\CSSTrait; use WP_Rocket\Engine\Optimization\DynamicLists\DefaultLists\DataManager; use WP_Rocket\Engine\Optimization\RegexTrait; @@ -16,6 +17,7 @@ class UsedCSS { use RegexTrait; use CSSTrait; use CommentTrait; + use ElementTrait; /** * UsedCss Query instance. @@ -80,6 +82,20 @@ class UsedCSS { */ private $manager; + /** + * Used CSS contents. + * + * @var string + */ + private $used_css_content = ''; + + /** + * Preloaded font urls. + * + * @var array + */ + private $preloaded_fonts = []; + /** * Instantiate the class. * @@ -158,9 +174,10 @@ public function treeshake( string $html ): string { return $html; } + $this->used_css_content = $used_css_content; + $html = $this->remove_used_css_from_html( $clean_html, $html ); - $html = $this->add_used_css_to_html( $html, $used_css_content ); - $html = $this->add_used_fonts_preload( $html, $used_css_content ); + $this->add_used_fonts_preload( $used_css_content ); $html = $this->remove_google_font_preconnect( $html ); if ( ! empty( $used_css->id ) ) { @@ -354,26 +371,48 @@ private function remove_internal_styles_from_html( string $clean_html, string $h } /** - * Alter HTML string and add the used CSS style in tag, + * Add the used CSS style in tag, * - * @param string $html HTML content. - * @param string $used_css Used CSS content. + * @param array $items Head items. * - * @return string HTML content. + * @return array Filtered head items. */ - private function add_used_css_to_html( string $html, string $used_css ): string { - $replace = preg_replace( - '##iU', - '' . $this->get_used_css_markup( $used_css ), - $html, - 1 + public function add_used_css_to_html( array $items ): array { + $used_css = $this->get_used_css_content(); + if ( empty( $used_css ) ) { + return $items; + } + + $items[] = $this->style_tag( + $this->get_used_css_markup( $used_css ), + [ + 'id' => 'wpr-usedcss', + ] ); + return $items; + } - if ( null === $replace ) { - return $html; + /** + * Insert preload fonts into page head. + * + * @param array $items Head elements. + * @return mixed + */ + public function insert_preload_fonts( $items ) { + if ( empty( $this->preloaded_fonts ) ) { + return $items; + } + foreach ( $this->preloaded_fonts as $font ) { + $items[] = $this->preload_link( + [ + 'href' => esc_url( $font ), + 'as' => 'font', + 1 => 'crossorigin', + ] + ); } - return $replace; + return $items; } /** @@ -394,12 +433,7 @@ private function get_used_css_markup( string $used_css ): string { $used_css = apply_filters( 'rocket_usedcss_content', $used_css ); $used_css = str_replace( '\\', '\\\\', $used_css );// Guard the backslashes before passing the content to preg_replace. - $used_css = $this->handle_charsets( $used_css, false ); - - return sprintf( - '', - $used_css - ); + return $this->handle_charsets( $used_css, false ); } /** @@ -445,12 +479,11 @@ public function get_not_completed_count() { /** * Add preload links for the fonts in the used CSS * - * @param string $html HTML content. * @param string $used_css Used CSS content. * - * @return string + * @return void */ - private function add_used_fonts_preload( string $html, string $used_css ): string { + private function add_used_fonts_preload( string $used_css ): void { /** * Filters the fonts preload from the used CSS * @@ -459,15 +492,15 @@ private function add_used_fonts_preload( string $html, string $used_css ): strin * @param bool $enable True to enable, false to disable. */ if ( ! apply_filters( 'rocket_enable_rucss_fonts_preload', true ) ) { - return $html; + return; } if ( ! preg_match_all( '/@font-face\s*{\s*(?[^}]+)}/is', $used_css, $font_faces, PREG_SET_ORDER ) ) { - return $html; + return; } if ( empty( $font_faces ) ) { - return $html; + return; } /** @@ -526,23 +559,10 @@ function ( $item ) { } if ( empty( $urls ) ) { - return $html; - } - - $urls = array_unique( $urls ); - - $replace = preg_replace( - '##iU', - '' . $this->preload_links( $urls ), - $html, - 1 - ); - - if ( null === $replace ) { - return $html; + return; } - return $replace; + $this->preloaded_fonts = array_unique( $urls ); } /** @@ -610,23 +630,6 @@ private function extract_first_font( string $font_face ): string { return ''; } - /** - * Converts an array of URLs to preload link tags - * - * @param array $urls An array of URLs. - * - * @return string - */ - private function preload_links( array $urls ): string { - $links = ''; - - foreach ( $urls as $url ) { - $links .= ''; - } - - return $links; - } - /** * Set Rucss inline attr exclusions * @@ -695,4 +698,13 @@ static function ( $item ) { public function has_one_completed_row_at_least() { return $this->used_css_query->get_completed_count() > 0; } + + /** + * Get generated used CSS, getter method for used_css_content property. + * + * @return string + */ + public function get_used_css_content() { + return $this->used_css_content; + } } diff --git a/inc/Engine/Optimization/RUCSS/Frontend/Subscriber.php b/inc/Engine/Optimization/RUCSS/Frontend/Subscriber.php index 751b2f153b..3fd12d786d 100644 --- a/inc/Engine/Optimization/RUCSS/Frontend/Subscriber.php +++ b/inc/Engine/Optimization/RUCSS/Frontend/Subscriber.php @@ -46,6 +46,10 @@ public static function get_subscribed_events(): array { 'rocket_disable_preload_fonts' => 'maybe_disable_preload_fonts', 'rocket_first_install_options' => 'on_install', 'wp_rocket_upgrade' => [ 'on_update', 10, 2 ], + 'rocket_head_items' => [ + [ 'insert_preload_fonts', 30 ], + [ 'insert_css_in_head', 50 ], + ], ]; } @@ -113,4 +117,24 @@ public function on_install( $options ) { return $options; } + + /** + * Insert used CSS into head. + * + * @param array $items Head elements. + * @return mixed + */ + public function insert_css_in_head( $items ) { + return $this->used_css->add_used_css_to_html( $items ); + } + + /** + * Insert font preloads into head. + * + * @param array $items Head elements. + * @return mixed + */ + public function insert_preload_fonts( $items ) { + return $this->used_css->insert_preload_fonts( $items ); + } } diff --git a/inc/Engine/Preload/Fonts.php b/inc/Engine/Preload/Fonts.php index ae190ab932..c3c2f0d272 100644 --- a/inc/Engine/Preload/Fonts.php +++ b/inc/Engine/Preload/Fonts.php @@ -4,6 +4,7 @@ use WP_Rocket\Admin\Options_Data; use WP_Rocket\Engine\CDN\CDN; +use WP_Rocket\Engine\Common\Head\ElementTrait; use WP_Rocket\Engine\Support\CommentTrait; use WP_Rocket\Event_Management\Subscriber_Interface; @@ -14,6 +15,7 @@ */ class Fonts implements Subscriber_Interface { use CommentTrait; + use ElementTrait; /** * WP Rocket Options instance. @@ -49,6 +51,13 @@ class Fonts implements Subscriber_Interface { 'woff2', ]; + /** + * Loaded fonts + * + * @var array + */ + private $fonts = []; + /** * Return an array of events that this subscriber wants to listen to. * @@ -71,7 +80,8 @@ public function __construct( Options_Data $options, CDN $cdn ) { */ public static function get_subscribed_events() { return [ - 'rocket_buffer' => [ 'preload_fonts', 20 ], + 'rocket_head_items' => [ 'insert_preloaded_fonts_into_head', 30 ], + 'rocket_buffer' => [ 'preload_fonts', 20 ], ]; } @@ -84,6 +94,7 @@ public static function get_subscribed_events() { * @since 3.6 */ public function preload_fonts( $html ): string { + $this->fonts = []; if ( ! $this->is_allowed() ) { return $html; } @@ -107,24 +118,35 @@ public function preload_fonts( $html ): string { $base_url = get_rocket_parse_url( home_url() ); $base_url = "{$base_url['scheme']}://{$base_url['host']}"; - $preloads = ''; - foreach ( array_unique( $fonts ) as $font ) { - $preloads .= sprintf( - "\n", - esc_url( $this->cdn->rewrite_url( $base_url . $font ) ) - ); + $this->fonts[] = esc_url( $this->cdn->rewrite_url( $base_url . $font ) ); } - $result = preg_replace( '##', $preloads, $html, 1 ); + return $this->add_meta_comment( 'preload_fonts', $html ); + } - if ( null === $result ) { - return $html; + /** + * Add preload links into head. + * + * @param array $items Head elements. + * @return array + */ + public function insert_preloaded_fonts_into_head( $items ): array { + $fonts = $this->get_fonts(); + if ( empty( $fonts ) ) { + return $items; } - $result = $this->add_meta_comment( 'preload_fonts', $result ); - - return $result; + foreach ( $fonts as $font ) { + $items[] = $this->preload_link( + [ + 'href' => $font, + 'as' => 'font', + 1 => 'crossorigin', + ] + ); + } + return $items; } /** @@ -172,4 +194,13 @@ private function is_allowed(): bool { */ return ! apply_filters( 'rocket_disable_preload_fonts', false ); } + + /** + * Get fonts to preload, getter method for fonts property. + * + * @return array + */ + public function get_fonts(): array { + return $this->is_allowed() ? $this->fonts : []; + } } diff --git a/inc/Plugin.php b/inc/Plugin.php index 7c7ec851a2..972f29b0ac 100644 --- a/inc/Plugin.php +++ b/inc/Plugin.php @@ -8,6 +8,7 @@ use WP_Rocket\Admin\{Options, Options_Data}; use WP_Rocket\Engine\Admin\API\ServiceProvider as APIServiceProvider; use WP_Rocket\Engine\Common\ExtractCSS\ServiceProvider as CommonExtractCSSServiceProvider; +use WP_Rocket\Engine\Common\Head\ServiceProvider as CommonHeadServiceProvider; use WP_Rocket\Engine\Common\JobManager\ServiceProvider as JobManagerServiceProvider; use WP_Rocket\Engine\Media\Lazyload\CSS\ServiceProvider as LazyloadCSSServiceProvider; use WP_Rocket\Engine\Media\Lazyload\CSS\Admin\ServiceProvider as AdminLazyloadCSSServiceProvider; @@ -283,6 +284,7 @@ private function init_common_subscribers() { $this->container->addServiceProvider( new ThemesServiceProvider() ); $this->container->addServiceProvider( new APIServiceProvider() ); $this->container->addServiceProvider( new CommonExtractCSSServiceProvider() ); + $this->container->addServiceProvider( new CommonHeadServiceProvider() ); $this->container->addServiceProvider( new LazyloadCSSServiceProvider() ); $this->container->addServiceProvider( new DebugServiceProvider() ); $this->container->addServiceProvider( new ATFServiceProvider() ); @@ -300,6 +302,7 @@ private function init_common_subscribers() { 'critical_css_subscriber', 'sucuri_subscriber', 'common_extractcss_subscriber', + 'common_head_subscriber', 'expired_cache_purge_subscriber', 'fonts_preload_subscriber', 'heartbeat_subscriber', diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 6e027d3e20..698bf1ae43 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1541,7 +1541,17 @@ parameters: path: tests/Integration/inc/Engine/Optimization/GoogleFonts/Admin/Subscriber/enableGoogleFonts.php - - message: "#^Usage of apply_filters\\(\\) is discouraged\\. Use wpm_apply_filters_typed\\(\\) instead\\.$#" + message: "#^Property WP_Rocket\\\\Tests\\\\Integration\\\\inc\\\\Engine\\\\Optimization\\\\GoogleFonts\\\\Test_Optimize\\:\\:\\$disable_preload is never written, only read\\.$#" + count: 1 + path: tests/Integration/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php + + - + message: "#^Property WP_Rocket\\\\Tests\\\\Integration\\\\inc\\\\Engine\\\\Optimization\\\\GoogleFonts\\\\Test_Optimize\\:\\:\\$display is never written, only read\\.$#" + count: 1 + path: tests/Integration/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" count: 1 path: tests/Integration/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php @@ -1661,7 +1671,7 @@ parameters: path: tests/Integration/inc/Engine/Optimization/RUCSS/Frontend/Subscriber/onUpdate.php - - message: "#^Usage of apply_filters\\(\\) is discouraged\\. Use wpm_apply_filters_typed\\(\\) instead\\.$#" + message: "#^Unreachable statement \\- code above always terminates\\.$#" count: 1 path: tests/Integration/inc/Engine/Optimization/RUCSS/Frontend/Subscriber/treeshake.php @@ -1671,7 +1681,7 @@ parameters: path: tests/Integration/inc/Engine/Preload/Cron/Subscriber/processPendingUrls.php - - message: "#^Usage of apply_filters\\(\\) is discouraged\\. Use wpm_apply_filters_typed\\(\\) instead\\.$#" + message: "#^Unreachable statement \\- code above always terminates\\.$#" count: 1 path: tests/Integration/inc/Engine/Preload/Fonts/preloadFonts.php diff --git a/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php b/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php index c78bf59210..1b465f88a3 100644 --- a/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php +++ b/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/Combine/optimize.php @@ -16,13 +16,22 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' + - Sample Page + Sample Page + + + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A100%2C300%2C300italic%2C400%2C600%2C700%7CRoboto%3A100italic%2C300italic%2C400%2C500%2C600%2C700%7CUnica%20One%3A400%2C600%2C700%7CJosefin%20Sans%3Aregular%2C300%7CJosefin%20Sans%3A300&display=swap', + ], + ], ], 'testShouldUseFilteredDisplayValue' => [ 'config' => [ @@ -39,13 +48,21 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' - Sample Page + Sample Page + + + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A100%2C300%2C300italic%2C400%2C600%2C700%7CRoboto%3A100italic%2C300italic%2C400%2C500%2C600%2C700%7CUnica%20One%3A400%2C600%2C700%7CJosefin%20Sans%3Aregular%2C300%7CJosefin%20Sans%3A300&display=optional', + ] + ], ], 'testShouldCombineGoogleFontsWithSubsets' => [ 'config' => [ @@ -62,13 +79,21 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' - Sample Page + Sample Page + + + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Lato%3A100%2C300%2C400%2C600%2C700%2C900%7COpen%20Sans%3A700%2C300%2C600%2C400%7CRaleway%3A900%7CPlayfair%20Display%7COpen%20Sans%7CJockey%20One%3A400%7CAbril%20Fatface%3Aregular&subset=latin&display=swap', + ], + ], ], 'testShouldCombineGoogleFontsWithoutSubsetsAndNoEnding|' => [ 'config' => [ @@ -85,13 +110,21 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' - Sample Page + Sample Page + + + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A100%2C300%2C300italic%2C400%2C600%2C700%7CRoboto%3A100italic%2C300italic%2C400%2C500%2C600%2C700%7CUnica%20One%3A400%2C600%2C700%7CJosefin%20Sans%3Aregular%2C300%7CJosefin%20Sans%3A300&display=swap', + ], + ], ], 'testShouldCombineGoogleFontsWithoutSubsetsWhenMalformedURL' => [ 'config' => [ @@ -108,13 +141,21 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' - Sample Page + Sample Page + + + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3Aregular%2C300%7CLato%3Aregular%2C300&display=swap', + ], + ], ], 'testShouldCombineGoogleFontsWithSubsetsWhenMalformedURL' => [ 'config' => [ @@ -131,15 +172,22 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' Sample Page - + + + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3Aregular%2C300%7CLato%3Aregular%2C300&display=swap' + ], + ], ], 'testShouldOptimizeSingleGoogleFontsWhenNoParam' => [ 'config' => [ @@ -155,14 +203,21 @@ ', // Expected: Combined HTML. - 'expected' => ' + 'expected' => [ + 'html' => ' - Sample Page - + Sample Page + + + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A300&display=swap', + ], + ], ], 'testShouldOptimizeSingleGoogleFontsWhenParam' => [ 'config' => [ @@ -177,14 +232,21 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' - Sample Page - + Sample Page + + + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A300&display=swap', + ], + ], ], 'testShouldOptimizeSingleGoogleFontsWhenInvalidParam' => [ 'config' => [ @@ -199,14 +261,21 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' - Sample Page - + Sample Page + + + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A300&display=swap', + ], + ], ], 'testShouldOptimizeSingleGoogleFontsWhenEncodedParam' => [ 'config' => [ @@ -221,14 +290,21 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' - Sample Page - + Sample Page + + + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A100%2C300%2C300italic%2C400%2C600%2C700%7CRoboto%3A100italic%2C300italic%2C400%2C500%2C600%2C700%7CUnica%20One%3A400%2C600%2C700&display=swap', + ], + ], ], 'testShouldCombineGoogleFontsWhenMultipleTitleTags' => [ 'config' => [ @@ -246,14 +322,22 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' - Sample Page + Sample Page + + + Sample Title 2 ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A100%2C300%2C300italic%2C400%2C600%2C700%7CRoboto%3A100italic%2C300italic%2C400%2C500%2C600%2C700%7CUnica%20One%3A400%2C600%2C700%7CJosefin%20Sans%3Aregular%2C300%7CJosefin%20Sans%3A300&display=swap', + ], + ], ], 'testShouldCombineGoogleFontsWhenTitleTagInsideBody' => [ 'config' => [ @@ -271,14 +355,22 @@ Sample Title 2 ', - 'expected' => ' + 'expected' => [ + 'html' => ' - Sample Page + Sample Page + + + Sample Title 2 ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A100%2C300%2C300italic%2C400%2C600%2C700%7CRoboto%3A100italic%2C300italic%2C400%2C500%2C600%2C700%7CUnica%20One%3A400%2C600%2C700%7CJosefin%20Sans%3Aregular%2C300%7CJosefin%20Sans%3A300&display=swap', + ], + ], ], 'testShouldCombineGoogleFontsWhenTitleTagInsideSvgTag' => [ 'config' => [ @@ -297,15 +389,23 @@
logo-cacahuete","toggleOpenedIcon":"","closeIcon":"","backIcon":"","dropdownIcon":"","useBreadcrumb":true,"breadcrumbIcon":"","toggleText":"MENU","toggleLoader":true,"backText":"RETOUR","itemIconVisible":"true","itemBadgeVisible":"true","itemDescVisible":"false","loaderColor":"#FCC800","subTrigger":"item"}\'>
', - 'expected' => ' + 'expected' => [ + 'html' => ' - Sample Page + Sample Page + + +
logo-cacahuete","toggleOpenedIcon":"","closeIcon":"","backIcon":"","dropdownIcon":"","useBreadcrumb":true,"breadcrumbIcon":"","toggleText":"MENU","toggleLoader":true,"backText":"RETOUR","itemIconVisible":"true","itemBadgeVisible":"true","itemDescVisible":"false","loaderColor":"#FCC800","subTrigger":"item"}\'>
', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A100%2C300%2C300italic%2C400%2C600%2C700%7CRoboto%3A100italic%2C300italic%2C400%2C500%2C600%2C700%7CUnica%20One%3A400%2C600%2C700%7CJosefin%20Sans%3Aregular%2C300%7CJosefin%20Sans%3A300&display=swap', + ], + ], ], 'testShouldOptimizeSingleGoogleFontsNoPreload' => [ 'config' => [ @@ -321,13 +421,19 @@ ', // Expected: Combined HTML. - 'expected' => ' + 'expected' => [ + 'html' => ' - Sample Page + Sample Page + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Josefin%20Sans%3A300&display=swap', + ], + ], ], 'shouldExcludeFontFromCombine' => [ 'config' => [ @@ -350,15 +456,16 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' Sample Page - - + + @@ -367,5 +474,9 @@ ', + 'fonts' => [ + 'https://fonts.googleapis.com/css?family=Roboto%7CMontSerra%7CComfortaa&display=optional', + ], + ], ] ]; diff --git a/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV1V2/optimize.php b/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV1V2/optimize.php index 88120d742f..6683d8ae82 100644 --- a/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV1V2/optimize.php +++ b/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV1V2/optimize.php @@ -25,8 +25,13 @@ Sample Page - - + + + + + + + @@ -56,8 +61,13 @@ Sample Page - - + + + + + + + @@ -89,8 +99,13 @@ Sample Page - - + + + + + + + @@ -122,8 +137,13 @@ Sample Page - - + + + + + + + @@ -155,8 +175,13 @@ Sample Page - - + + + + + + + diff --git a/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV2/optimize.php b/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV2/optimize.php index 7c827ede94..3ceef7fa5d 100644 --- a/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV2/optimize.php +++ b/tests/Fixtures/inc/Engine/Optimization/GoogleFonts/CombineV2/optimize.php @@ -42,17 +42,22 @@ ', - 'expected' => - ' + 'expected' => [ + 'html' => ' - Sample Page - - + Sample Page + + + - ' + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@450&display=swap', + ], + ], ], 'shouldNotCombineMultipleTagsWithTextParam' => [ 'config' => [ @@ -69,17 +74,23 @@ ', - 'expected' => - ' + 'expected' => [ + 'html' => ' Sample Page - + + + - ' + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@450&display=swap', + ], + ], ], 'shouldCombineMultipleTags' => [ 'config' => [ @@ -97,16 +108,23 @@ ', - 'expected' => - ' + 'expected' => [ + 'html' => ' Sample Page - + + + - ' + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@450&family=Comfortaa&display=swap', + ], + ], + ], 'shouldCombineMultipleTagsWithMultipleFamiliesInTag' => [ 'config' => [ @@ -125,17 +143,24 @@ ', - 'expected' => - ' + 'expected' => [ + 'html' => ' Sample Page - + + + - ' + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css2?family=Goldman:wght@700&family=Roboto:ital,wght@0,100;0,400;0,500;1,500;1,900&family=Comfortaa&display=swap', + ], + ], + ], 'shouldReplaceAnotherFontDisplayValueWithSwap' => [ 'config' => [ @@ -154,17 +179,24 @@ ', - 'expected' => - ' + 'expected' => [ + 'html' => ' Sample Page - + + + - ' + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css2?family=Goldman:wght@700&family=Roboto:ital,wght@0,100;0,400;0,500;1,500;1,900&family=Comfortaa&display=swap', + ], + ], + ], 'shouldReplaceDisplayValueWithFilteredValue' => [ 'config' => [ @@ -183,18 +215,23 @@ ', - 'expected' => - ' + 'expected' => [ + 'html' => ' Sample Page - + + + - ' - , + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css2?family=Goldman:wght@700&family=Roboto:ital,wght@0,100;0,400;0,500;1,500;1,900&family=Comfortaa&display=optional', + ] + ], ], 'shouldCombineMultipleTagsNoPreload' => [ 'config' => [ @@ -212,16 +249,20 @@ ', - 'expected' => - ' + 'expected' => [ + 'html' => ' Sample Page - + - ' + ', + 'fonts' => [ + 'https://fonts.googleapis.com/css2?family=Crimson+Pro:wght@450&family=Comfortaa&display=swap', + ], + ], ], 'shouldExcludeFontFromCombine' => [ 'config' => [ @@ -244,15 +285,16 @@ ', - 'expected' => ' + 'expected' => [ + 'html' => ' Sample Page - - + + @@ -261,5 +303,9 @@ ', + 'fonts' => [ + 'https://fonts.googleapis.com/css2?family=Goldman:wght@700&family=Roboto:ital,wght@0,100;0,400;0,500;1,500;1,900&family=MontSerra:ital,wght@0,100;0,400;0,500;1,500;1,900&family=Comfortaa&display=optional', + ], + ], ] ]; diff --git a/tests/Fixtures/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php b/tests/Fixtures/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php index 95f7bc4b93..5b4e2bf62a 100644 --- a/tests/Fixtures/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php +++ b/tests/Fixtures/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/treeshake.php @@ -88,7 +88,10 @@ ], 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original.php'), ], - 'expected' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtered.php'), + 'expected' => [ + 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtered.php'), + 'used_css' => 'h1{color:red;}', + ], ], 'expectedFilteredHTMlWhenNoPreconnectGoogleAPI' => [ 'config' => [ @@ -112,7 +115,10 @@ ], 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/google_fonts.php'), ], - 'expected' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtered.php'), + 'expected' => [ + 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtered.php'), + 'used_css' => 'h1{color:red;}', + ], ], 'expectedFilteredHTMlWhenNoEmptyUsedCSSExcludeAttr' => [ 'config' => [ @@ -142,7 +148,10 @@ ], 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original_exclude_attr.php'), ], - 'expected' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtered_exclude_attr.php'), + 'expected' => [ + 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtered_exclude_attr.php'), + 'used_css' => 'h1{color:red;}', + ], ], 'expectedFilteredHTMlWhenNoEmptyUsedCSSExcludeContent' => [ 'config' => [ @@ -172,7 +181,10 @@ ], 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/original_exclude_content.php'), ], - 'expected' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtered_exclude_content.php'), + 'expected' => [ + 'html' => file_get_contents(WP_ROCKET_TESTS_FIXTURES_DIR . '/inc/Engine/Optimization/RUCSS/Controller/UsedCSS/HTML/filtered_exclude_content.php'), + 'used_css' => 'h1{color:red;}', + ], ], 'expectSameHtmlWhenNoTitleTag' => [ 'config' => [ diff --git a/tests/Fixtures/inc/Engine/Optimization/RUCSS/Frontend/Subscriber/HTML/outputFontExcluded.html b/tests/Fixtures/inc/Engine/Optimization/RUCSS/Frontend/Subscriber/HTML/outputFontExcluded.html index 00514687c0..cb768fe8e7 100644 --- a/tests/Fixtures/inc/Engine/Optimization/RUCSS/Frontend/Subscriber/HTML/outputFontExcluded.html +++ b/tests/Fixtures/inc/Engine/Optimization/RUCSS/Frontend/Subscriber/HTML/outputFontExcluded.html @@ -2,7 +2,7 @@ - Title