From fa883aabab39611ff236053892a7a6606d341ad4 Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Tue, 8 Mar 2022 16:44:18 -0300 Subject: [PATCH 1/9] Filter out webfonts that are not being used by the front-end --- .../wordpress-6.0/class-wp-webfonts.php | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/lib/compat/wordpress-6.0/class-wp-webfonts.php b/lib/compat/wordpress-6.0/class-wp-webfonts.php index 9b5114b7452bb2..ab68e2d304248f 100644 --- a/lib/compat/wordpress-6.0/class-wp-webfonts.php +++ b/lib/compat/wordpress-6.0/class-wp-webfonts.php @@ -28,6 +28,15 @@ class WP_Webfonts { */ private static $providers = array(); + /** + * An array of fonts actually used in the front-end. + * + * @static + * @access private + * @var array + */ + private static $webfonts_used_in_front_end = array(); + /** * Stylesheet handle. * @@ -198,10 +207,34 @@ public function register_provider( $provider, $class ) { return true; } + /** + * Filter out webfonts that are not being used by the front-end. + * + * @return void + */ + private function filter_out_webfonts_unused_in_front_end() { + $all_registered_fonts = $this->get_fonts(); + $picked_webfonts = array(); + + self::$webfonts_used_in_front_end = apply_filters( 'gutenberg_webfonts_used_in_front_end', self::$webfonts_used_in_front_end ); + + foreach ( $all_registered_fonts as $id => $webfont ) { + $font_name = _wp_to_kebab_case( $webfont['font-family'] ); + + if ( isset( self::$webfonts_used_in_front_end[ $font_name ] ) ) { + $picked_webfonts[ $id ] = $webfont; + } + } + + self::$webfonts = $picked_webfonts; + } + /** * Generate and enqueue webfonts styles. */ public function generate_and_enqueue_styles() { + $this->filter_out_webfonts_unused_in_front_end(); + // Generate the styles. $styles = $this->generate_styles(); From 65364d88dda621c43a65b1fe323242818b864613 Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Tue, 8 Mar 2022 18:04:18 -0300 Subject: [PATCH 2/9] Include webfonts used in global styles in the set of all the webfonts used in the front-end --- .../wordpress-6.0/class-wp-webfonts.php | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/lib/compat/wordpress-6.0/class-wp-webfonts.php b/lib/compat/wordpress-6.0/class-wp-webfonts.php index ab68e2d304248f..7de4d89660a4d4 100644 --- a/lib/compat/wordpress-6.0/class-wp-webfonts.php +++ b/lib/compat/wordpress-6.0/class-wp-webfonts.php @@ -37,6 +37,15 @@ class WP_Webfonts { */ private static $webfonts_used_in_front_end = array(); + /** + * The name of option that caches the webfonts used in global styles. + * + * @static + * @access private + * @var string + */ + private static $webfonts_used_in_global_styles_cache_option = 'gutenberg_webfonts_used_in_global_styles'; + /** * Stylesheet handle. * @@ -60,12 +69,97 @@ public function init() { $this->stylesheet_handle = 'webfonts'; $hook = 'wp_enqueue_scripts'; } + + add_action( 'init', array( $this, 'collect_webfonts_used_in_global_styles' ) ); + add_action( $hook, array( $this, 'generate_and_enqueue_styles' ) ); // Enqueue webfonts in the block editor. add_action( 'admin_init', array( $this, 'generate_and_enqueue_editor_styles' ) ); } + /** + * Grab the webfonts used in global styles and include them + * in the set of all the webfonts used in the front-end. + */ + public function collect_webfonts_used_in_global_styles() { + $webfonts_used_in_global_styles = get_option( self::$webfonts_used_in_global_styles_cache_option ); + + if ( ! $webfonts_used_in_global_styles ) { + $webfonts_used_in_global_styles = $this->get_webfonts_used_in_global_styles(); + update_option( self::$webfonts_used_in_global_styles_cache_option, $webfonts_used_in_global_styles ); + } + + self::$webfonts_used_in_front_end = array_merge( self::$webfonts_used_in_front_end, $webfonts_used_in_global_styles ); + } + + /** + * Get globally used webfonts. + * + * @return array + */ + private function get_webfonts_used_in_global_styles() { + $global_styles = gutenberg_get_global_styles(); + $webfonts_used_in_global_styles = array(); + + if ( isset( $global_styles['blocks'] ) ) { + // Register used fonts from blocks. + foreach ( $global_styles['blocks'] as $setting ) { + $font_family_slug = $this->get_font_family_from_setting( $setting ); + + if ( $font_family_slug ) { + $webfonts_used_in_global_styles[ $font_family_slug ] = 1; + } + } + } + + if ( isset( $global_styles['elements'] ) ) { + // Register used fonts from elements. + foreach ( $global_styles['elements'] as $setting ) { + $font_family_slug = $this->get_font_family_from_setting( $setting ); + + if ( $font_family_slug ) { + $webfonts_used_in_global_styles[ $font_family_slug ] = 1; + } + } + } + + // Get global font. + $font_family_slug = $this->get_font_family_from_setting( $global_styles ); + + if ( $font_family_slug ) { + $webfonts_used_in_global_styles[ $font_family_slug ] = 1; + } + + return $webfonts_used_in_global_styles; + } + + /** + * Get font family from global setting. + * + * @param mixed $setting The global setting. + * @return string|false + */ + private function get_font_family_from_setting( $setting ) { + if ( isset( $setting['typography'] ) && isset( $setting['typography']['fontFamily'] ) ) { + $font_family = $setting['typography']['fontFamily']; + + preg_match( '/var\(--wp--(?:preset|custom)--font-family--([^\\\]+)\)/', $font_family, $matches ); + + if ( isset( $matches[1] ) ) { + return _wp_to_kebab_case( $matches[1] ); + } + + preg_match( '/var:(?:preset|custom)\|font-family\|(.+)/', $font_family, $matches ); + + if ( isset( $matches[1] ) ) { + return _wp_to_kebab_case( $matches[1] ); + } + } + + return false; + } + /** * Get the list of fonts. * From cf9f5a69771e4222e4d4e3989ff07fcba1ad7546 Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Tue, 8 Mar 2022 18:26:06 -0300 Subject: [PATCH 3/9] Update webfonts used in global styles cache after save --- lib/compat/wordpress-6.0/class-wp-webfonts.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/compat/wordpress-6.0/class-wp-webfonts.php b/lib/compat/wordpress-6.0/class-wp-webfonts.php index 7de4d89660a4d4..5dfed4180d72eb 100644 --- a/lib/compat/wordpress-6.0/class-wp-webfonts.php +++ b/lib/compat/wordpress-6.0/class-wp-webfonts.php @@ -71,6 +71,7 @@ public function init() { } add_action( 'init', array( $this, 'collect_webfonts_used_in_global_styles' ) ); + add_action( 'save_post_wp_global_styles', array( $this, 'update_webfonts_used_in_global_styles_cache' ) ); add_action( $hook, array( $this, 'generate_and_enqueue_styles' ) ); @@ -78,6 +79,16 @@ public function init() { add_action( 'admin_init', array( $this, 'generate_and_enqueue_editor_styles' ) ); } + /** + * Update webfonts used in global styles cache. + */ + public function update_webfonts_used_in_global_styles_cache() { + $webfonts_used_in_global_styles = $this->get_webfonts_used_in_global_styles(); + update_option( self::$webfonts_used_in_global_styles_cache_option, $webfonts_used_in_global_styles ); + + return $webfonts_used_in_global_styles; + } + /** * Grab the webfonts used in global styles and include them * in the set of all the webfonts used in the front-end. @@ -86,8 +97,7 @@ public function collect_webfonts_used_in_global_styles() { $webfonts_used_in_global_styles = get_option( self::$webfonts_used_in_global_styles_cache_option ); if ( ! $webfonts_used_in_global_styles ) { - $webfonts_used_in_global_styles = $this->get_webfonts_used_in_global_styles(); - update_option( self::$webfonts_used_in_global_styles_cache_option, $webfonts_used_in_global_styles ); + $webfonts_used_in_global_styles = $this->update_webfonts_used_in_global_styles_cache(); } self::$webfonts_used_in_front_end = array_merge( self::$webfonts_used_in_front_end, $webfonts_used_in_global_styles ); From 280c3f0aa438d9d5141ab158b02d5cbc28d448a7 Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Tue, 8 Mar 2022 18:32:09 -0300 Subject: [PATCH 4/9] Update webfonts used in global styles cache after theme switch --- lib/compat/wordpress-6.0/class-wp-webfonts.php | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/compat/wordpress-6.0/class-wp-webfonts.php b/lib/compat/wordpress-6.0/class-wp-webfonts.php index 5dfed4180d72eb..28820c893a5e9a 100644 --- a/lib/compat/wordpress-6.0/class-wp-webfonts.php +++ b/lib/compat/wordpress-6.0/class-wp-webfonts.php @@ -71,6 +71,7 @@ public function init() { } add_action( 'init', array( $this, 'collect_webfonts_used_in_global_styles' ) ); + add_action( 'switch_theme', array( $this, 'update_webfonts_used_in_global_styles_cache' ) ); add_action( 'save_post_wp_global_styles', array( $this, 'update_webfonts_used_in_global_styles_cache' ) ); add_action( $hook, array( $this, 'generate_and_enqueue_styles' ) ); From 6c410d0253b44e796bfcabb5a2789604a5e36a57 Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Tue, 8 Mar 2022 19:14:17 -0300 Subject: [PATCH 5/9] Include and cache webfonts used in the current template in the set of all the webfonts used in the front-end --- .../wordpress-6.0/class-wp-webfonts.php | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/lib/compat/wordpress-6.0/class-wp-webfonts.php b/lib/compat/wordpress-6.0/class-wp-webfonts.php index 28820c893a5e9a..dcb6dc2246fba5 100644 --- a/lib/compat/wordpress-6.0/class-wp-webfonts.php +++ b/lib/compat/wordpress-6.0/class-wp-webfonts.php @@ -37,6 +37,15 @@ class WP_Webfonts { */ private static $webfonts_used_in_front_end = array(); + /** + * The name of option that caches the webfonts used in the templates. + * + * @static + * @access private + * @var string + */ + private static $webfonts_used_in_templates_cache_option = 'gutenberg_webfonts_used_in_templates'; + /** * The name of option that caches the webfonts used in global styles. * @@ -70,6 +79,7 @@ public function init() { $hook = 'wp_enqueue_scripts'; } + add_action( 'init', array( $this, 'register_filter_for_current_template_webfonts_collector' ) ); add_action( 'init', array( $this, 'collect_webfonts_used_in_global_styles' ) ); add_action( 'switch_theme', array( $this, 'update_webfonts_used_in_global_styles_cache' ) ); add_action( 'save_post_wp_global_styles', array( $this, 'update_webfonts_used_in_global_styles_cache' ) ); @@ -80,6 +90,79 @@ public function init() { add_action( 'admin_init', array( $this, 'generate_and_enqueue_editor_styles' ) ); } + /** + * Hook into every possible template so we can collect the webfonts used in the template + * that has been loaded in the front-end. + */ + public function register_filter_for_current_template_webfonts_collector() { + $template_type_slugs = array_keys( get_default_block_template_types() ); + + foreach ( $template_type_slugs as $template_type_slug ) { + add_filter( + str_replace( '-', '', $template_type_slug ) . '_template', + array( $this, 'collect_webfonts_used_in_template' ), + 10, + 2 + ); + } + } + + /** + * Grab the webfonts used in the template and include them + * in the set of all the webfonts used in the front-end. + * + * @param string $template_path The current template path. + * @param string $template_slug The current template slug. + * + * @return void + */ + public function collect_webfonts_used_in_template( $template_path, $template_slug ) { + global $_wp_current_template_content; + + $webfonts_used_in_templates = get_option( self::$webfonts_used_in_templates_cache_option, array() ); + + if ( ! isset( $webfonts_used_in_templates[ $template_slug ] ) ) { + $webfonts_used_in_templates[ $template_slug ] = $this->get_fonts_from_template( $_wp_current_template_content ); + + update_option( self::$webfonts_used_in_templates_cache_option, $webfonts_used_in_templates ); + } + + $webfonts_used_in_template = $webfonts_used_in_templates[ $template_slug ]; + self::$webfonts_used_in_front_end = array_merge( self::$webfonts_used_in_front_end, $webfonts_used_in_template ); + } + + /** + * Get webfonts used in the template. + * + * @param string $template_content The template content. + * + * @return array + */ + private function get_fonts_from_template( $template_content ) { + $webfonts_used_in_template = array(); + + $template_blocks = parse_blocks( $template_content ); + $template_blocks = _flatten_blocks( $template_blocks ); + + foreach ( $template_blocks as $block ) { + if ( 'core/template-part' === $block['blockName'] ) { + $template_part = get_block_template( get_stylesheet() . '//' . $block['attrs']['slug'], 'wp_template_part' ); + $fonts_in_template_part = $this->get_fonts_from_template( $template_part->content ); + + $webfonts_used_in_template = array_merge( + $webfonts_used_in_template, + $fonts_in_template_part + ); + } + + if ( isset( $block['attrs']['fontFamily'] ) ) { + $used_webfonts[ $block['attrs']['fontFamily'] ] = 1; + } + } + + return $webfonts_used_in_template; + } + /** * Update webfonts used in global styles cache. */ From 78dffcba0d6c0b1f8924e638fb8e03e976c1398d Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Tue, 8 Mar 2022 19:19:44 -0300 Subject: [PATCH 6/9] Invalidate webfonts used in templates cache after template or template part update --- lib/compat/wordpress-6.0/class-wp-webfonts.php | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/lib/compat/wordpress-6.0/class-wp-webfonts.php b/lib/compat/wordpress-6.0/class-wp-webfonts.php index dcb6dc2246fba5..99f153b13915da 100644 --- a/lib/compat/wordpress-6.0/class-wp-webfonts.php +++ b/lib/compat/wordpress-6.0/class-wp-webfonts.php @@ -82,6 +82,9 @@ public function init() { add_action( 'init', array( $this, 'register_filter_for_current_template_webfonts_collector' ) ); add_action( 'init', array( $this, 'collect_webfonts_used_in_global_styles' ) ); add_action( 'switch_theme', array( $this, 'update_webfonts_used_in_global_styles_cache' ) ); + + add_action( 'save_post_wp_template', array( $this, 'invalidate_webfonts_used_in_templates_cache' ) ); + add_action( 'save_post_wp_template_part', array( $this, 'invalidate_webfonts_used_in_templates_cache' ) ); add_action( 'save_post_wp_global_styles', array( $this, 'update_webfonts_used_in_global_styles_cache' ) ); add_action( $hook, array( $this, 'generate_and_enqueue_styles' ) ); @@ -90,6 +93,17 @@ public function init() { add_action( 'admin_init', array( $this, 'generate_and_enqueue_editor_styles' ) ); } + /** + * Invalidate webfonts used in templates cache. + * We need to do that because there's no indication on which templates uses which template parts, + * so we're throwing everything away and lazily reconstructing the cache whenever a template gets loaded. + * + * @return void + */ + public function invalidate_webfonts_used_in_templates_cache() { + delete_option( self::$webfonts_used_in_templates_cache_option ); + } + /** * Hook into every possible template so we can collect the webfonts used in the template * that has been loaded in the front-end. From 3b62835a55be70a49ea0d942f977044258f19502 Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Tue, 8 Mar 2022 19:20:57 -0300 Subject: [PATCH 7/9] Invalidate webfonts used in templates cache on theme switch --- lib/compat/wordpress-6.0/class-wp-webfonts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/compat/wordpress-6.0/class-wp-webfonts.php b/lib/compat/wordpress-6.0/class-wp-webfonts.php index 99f153b13915da..bbf35e78bc69db 100644 --- a/lib/compat/wordpress-6.0/class-wp-webfonts.php +++ b/lib/compat/wordpress-6.0/class-wp-webfonts.php @@ -82,7 +82,7 @@ public function init() { add_action( 'init', array( $this, 'register_filter_for_current_template_webfonts_collector' ) ); add_action( 'init', array( $this, 'collect_webfonts_used_in_global_styles' ) ); add_action( 'switch_theme', array( $this, 'update_webfonts_used_in_global_styles_cache' ) ); - + add_action( 'switch_theme', array( $this, 'invalidate_webfonts_used_in_templates_cache' ) ); add_action( 'save_post_wp_template', array( $this, 'invalidate_webfonts_used_in_templates_cache' ) ); add_action( 'save_post_wp_template_part', array( $this, 'invalidate_webfonts_used_in_templates_cache' ) ); add_action( 'save_post_wp_global_styles', array( $this, 'update_webfonts_used_in_global_styles_cache' ) ); From f0453829ed58973bd3cd38a85803403658deed11 Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Tue, 8 Mar 2022 19:51:10 -0300 Subject: [PATCH 8/9] Collect webfonts used in the post/page content --- .../wordpress-6.0/class-wp-webfonts.php | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/lib/compat/wordpress-6.0/class-wp-webfonts.php b/lib/compat/wordpress-6.0/class-wp-webfonts.php index bbf35e78bc69db..17a626b311c7bb 100644 --- a/lib/compat/wordpress-6.0/class-wp-webfonts.php +++ b/lib/compat/wordpress-6.0/class-wp-webfonts.php @@ -37,6 +37,15 @@ class WP_Webfonts { */ private static $webfonts_used_in_front_end = array(); + /** + * The key of the post meta attribute that caches the webfonts used in the post content. + * + * @static + * @access private + * @var string + */ + private static $webfonts_used_in_content_meta_key = 'gutenberg_webfonts_used_in_content'; + /** * The name of option that caches the webfonts used in the templates. * @@ -81,6 +90,7 @@ public function init() { add_action( 'init', array( $this, 'register_filter_for_current_template_webfonts_collector' ) ); add_action( 'init', array( $this, 'collect_webfonts_used_in_global_styles' ) ); + add_filter( 'the_content', array( $this, 'collect_webfonts_used_in_content' ) ); add_action( 'switch_theme', array( $this, 'update_webfonts_used_in_global_styles_cache' ) ); add_action( 'switch_theme', array( $this, 'invalidate_webfonts_used_in_templates_cache' ) ); add_action( 'save_post_wp_template', array( $this, 'invalidate_webfonts_used_in_templates_cache' ) ); @@ -93,6 +103,30 @@ public function init() { add_action( 'admin_init', array( $this, 'generate_and_enqueue_editor_styles' ) ); } + /** + * Grab the webfonts used in the content and include them + * in the set of all the webfonts used in the front-end. + * + * @param string $content The post content. + * + * @return string + */ + public function collect_webfonts_used_in_content( $content ) { + global $post; + + preg_match_all( '/class\=\".*has-(?P.+)-font-family/', $content, $matches ); + + if ( isset( $matches['slug'] ) ) { + foreach ( $matches['slug'] as $font_family_slug ) { + $webfonts_used_in_post_cache[ $font_family_slug ] = 1; + } + } + + self::$webfonts_used_in_front_end = array_merge( self::$webfonts_used_in_front_end, $webfonts_used_in_post_cache ); + + return $content; + } + /** * Invalidate webfonts used in templates cache. * We need to do that because there's no indication on which templates uses which template parts, From 62d677bd135d62a444f93222eec3ac736d251408 Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Tue, 8 Mar 2022 20:01:46 -0300 Subject: [PATCH 9/9] Regenerate used webfonts meta for post and page on save --- .../wordpress-6.0/class-wp-webfonts.php | 34 ++++++++++++++++--- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/lib/compat/wordpress-6.0/class-wp-webfonts.php b/lib/compat/wordpress-6.0/class-wp-webfonts.php index 17a626b311c7bb..0c2f8f0c0a58c6 100644 --- a/lib/compat/wordpress-6.0/class-wp-webfonts.php +++ b/lib/compat/wordpress-6.0/class-wp-webfonts.php @@ -93,6 +93,8 @@ public function init() { add_filter( 'the_content', array( $this, 'collect_webfonts_used_in_content' ) ); add_action( 'switch_theme', array( $this, 'update_webfonts_used_in_global_styles_cache' ) ); add_action( 'switch_theme', array( $this, 'invalidate_webfonts_used_in_templates_cache' ) ); + add_action( 'save_post_post', array( $this, 'update_webfonts_used_in_content_cache' ), 10, 2 ); + add_action( 'save_post_page', array( $this, 'update_webfonts_used_in_content_cache' ), 10, 2 ); add_action( 'save_post_wp_template', array( $this, 'invalidate_webfonts_used_in_templates_cache' ) ); add_action( 'save_post_wp_template_part', array( $this, 'invalidate_webfonts_used_in_templates_cache' ) ); add_action( 'save_post_wp_global_styles', array( $this, 'update_webfonts_used_in_global_styles_cache' ) ); @@ -103,6 +105,30 @@ public function init() { add_action( 'admin_init', array( $this, 'generate_and_enqueue_editor_styles' ) ); } + /** + * Update webfonts used in the content cache. + * + * @param integer $post_id The post ID. + * @param WP_Post $post The post. + * + * @return array + */ + public function update_webfonts_used_in_content_cache( $post_id, $post ) { + $webfonts_used_in_post_cache = array(); + + preg_match_all( '/class\=\".*has-(?P.+)-font-family/', $post->post_content, $matches ); + + if ( isset( $matches['slug'] ) ) { + foreach ( $matches['slug'] as $font_family_slug ) { + $webfonts_used_in_post_cache[ $font_family_slug ] = 1; + } + } + + update_post_meta( $post->ID, self::$webfonts_used_in_content_meta_key, $webfonts_used_in_post_cache ); + + return $webfonts_used_in_post_cache; + } + /** * Grab the webfonts used in the content and include them * in the set of all the webfonts used in the front-end. @@ -114,12 +140,10 @@ public function init() { public function collect_webfonts_used_in_content( $content ) { global $post; - preg_match_all( '/class\=\".*has-(?P.+)-font-family/', $content, $matches ); + $webfonts_used_in_post_cache = get_post_meta( $post->ID, self::$webfonts_used_in_content_meta_key, true ); - if ( isset( $matches['slug'] ) ) { - foreach ( $matches['slug'] as $font_family_slug ) { - $webfonts_used_in_post_cache[ $font_family_slug ] = 1; - } + if ( ! $webfonts_used_in_post_cache ) { + $webfonts_used_in_post_cache = $this->update_webfonts_used_in_content_cache( $post->ID, $post ); } self::$webfonts_used_in_front_end = array_merge( self::$webfonts_used_in_front_end, $webfonts_used_in_post_cache );