From 86ece5fc7d637d2fd881fa2cdb457f0f60f1da68 Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Wed, 9 Mar 2022 19:20:07 -0300 Subject: [PATCH 01/14] Separate between registered and enqueued webfonts --- ...class-wp-theme-json-resolver-gutenberg.php | 4 +- .../wordpress-6.0/class-wp-webfonts.php | 95 +++++++++++++++---- .../register-webfonts-from-theme-json.php | 8 +- lib/compat/wordpress-6.0/webfonts.php | 15 +-- 4 files changed, 92 insertions(+), 30 deletions(-) diff --git a/lib/compat/wordpress-6.0/class-wp-theme-json-resolver-gutenberg.php b/lib/compat/wordpress-6.0/class-wp-theme-json-resolver-gutenberg.php index a79c510141be32..6a2c4445086d42 100644 --- a/lib/compat/wordpress-6.0/class-wp-theme-json-resolver-gutenberg.php +++ b/lib/compat/wordpress-6.0/class-wp-theme-json-resolver-gutenberg.php @@ -35,14 +35,14 @@ public static function get_theme_data( $deprecated = array() ) { if ( null === static::$theme ) { $theme_json_data = static::read_json_file( static::get_file_path_from_theme( 'theme.json' ) ); $theme_json_data = static::translate( $theme_json_data, wp_get_theme()->get( 'TextDomain' ) ); - $theme_json_data = gutenberg_add_registered_webfonts_to_theme_json( $theme_json_data ); + $theme_json_data = gutenberg_add_webfonts_to_theme_json( $theme_json_data ); static::$theme = new WP_Theme_JSON_Gutenberg( $theme_json_data ); if ( wp_get_theme()->parent() ) { // Get parent theme.json. $parent_theme_json_data = static::read_json_file( static::get_file_path_from_theme( 'theme.json', true ) ); $parent_theme_json_data = static::translate( $parent_theme_json_data, wp_get_theme()->parent()->get( 'TextDomain' ) ); - $parent_theme_json_data = gutenberg_add_registered_webfonts_to_theme_json( $parent_theme_json_data ); + $parent_theme_json_data = gutenberg_add_webfonts_to_theme_json( $parent_theme_json_data ); $parent_theme = new WP_Theme_JSON_Gutenberg( $parent_theme_json_data ); // Merge the child theme.json into the parent theme.json. diff --git a/lib/compat/wordpress-6.0/class-wp-webfonts.php b/lib/compat/wordpress-6.0/class-wp-webfonts.php index dce9830c1d32b9..9428100edc0d0f 100644 --- a/lib/compat/wordpress-6.0/class-wp-webfonts.php +++ b/lib/compat/wordpress-6.0/class-wp-webfonts.php @@ -16,7 +16,16 @@ class WP_Webfonts { * @access private * @var array */ - private $webfonts = array(); + private static $registered_webfonts = array(); + + /** + * An array of enqueued webfonts. + * + * @static + * @access private + * @var array + */ + private static $enqueued_webfonts = array(); /** * An array of registered providers. @@ -56,12 +65,21 @@ public function init() { } /** - * Get the list of fonts. + * Get the list of registered fonts. * * @return array */ - public function get_fonts() { - return $this->webfonts; + public function get_registered_fonts() { + return self::$registered_webfonts; + } + + /** + * Get the list of enqueued fonts. + * + * @return array + */ + public function get_enqueued_fonts() { + return self::$enqueued_webfonts; } /** @@ -76,24 +94,55 @@ public function get_providers() { /** * Register a webfont. * - * @param array $font The font arguments. + * @param string $id The unique identifier for the webfont. + * @param array $font The font arguments. */ - public function register_font( $font ) { + public function register_font( $id, $font ) { + if ( ! $id ) { + trigger_error( __( 'An ID is necessary when registering a webfont.', 'gutenberg' ) ); + return false; + } + + if ( isset( $this->registered_webfonts[ $id ] ) ) { + return; + } + $font = $this->validate_font( $font ); if ( $font ) { - $id = $this->get_font_id( $font ); - $this->webfonts[ $id ] = $font; + self::$registered_webfonts[ $id ] = $font; } } /** - * Get the font ID. + * Enqueue a webfont. * - * @param array $font The font arguments. - * @return string + * @param string $id The unique identifier for the webfont. + * @param array|null $font The font arguments. */ - public function get_font_id( $font ) { - return sanitize_title( "{$font['font-family']}-{$font['font-weight']}-{$font['font-style']}-{$font['provider']}" ); + public function enqueue_font( $id, $font = null ) { + if ( ! $id ) { + trigger_error( __( 'An ID is necessary when enqueueing a webfont.', 'gutenberg' ) ); + return false; + } + + if ( isset( $this->enqueued_webfonts[ $id ] ) ) { + return; + } + + if ( $font ) { + $font = $this->validate_font( $font ); + self::$enqueued_webfonts[ $id ] = $font; + + if ( isset( self::$registered_webfonts[ $id ] ) ) { + unset( self::$registered_webfonts[ $id ] ); + } + } elseif ( isset( self::$registered_webfonts[ $id ] ) ) { + self::$enqueued_webfonts[ $id ] = self::$registered_webfonts[ $id ]; + + unset( self::$registered_webfonts[ $id ] ); + } else { + trigger_error( __( 'The given webfont ID is not registered, therefore the webfont cannot be enqueued.', 'gutenberg' ) ); + } } /** @@ -201,7 +250,7 @@ public function register_provider( $provider, $class ) { */ public function generate_and_enqueue_styles() { // Generate the styles. - $styles = $this->generate_styles(); + $styles = $this->generate_styles( $this->get_enqueued_fonts() ); // Bail out if there are no styles to enqueue. if ( '' === $styles ) { @@ -216,12 +265,21 @@ public function generate_and_enqueue_styles() { wp_add_inline_style( $this->stylesheet_handle, $styles ); } + /** + * Returns a list of registered and enqueued webfonts. + * We need this so all webfonts show up in the editor, + * regardless of their state. + */ + public function get_all_webfonts() { + return array_merge( $this->get_registered_fonts(), $this->get_enqueued_fonts() ); + } + /** * Generate and enqueue editor styles. */ public function generate_and_enqueue_editor_styles() { // Generate the styles. - $styles = $this->generate_styles(); + $styles = $this->generate_styles( $this->get_all_webfonts() ); // Bail out if there are no styles to enqueue. if ( '' === $styles ) { @@ -236,16 +294,17 @@ public function generate_and_enqueue_editor_styles() { * * @since 6.0.0 * + * @param array $webfonts The fonts that are going to the output. + * * @return string $styles Generated styles. */ - public function generate_styles() { + public function generate_styles( $webfonts ) { $styles = ''; $providers = $this->get_providers(); // Group webfonts by provider. $webfonts_by_provider = array(); - $registered_webfonts = $this->get_fonts(); - foreach ( $registered_webfonts as $id => $webfont ) { + foreach ( $webfonts as $id => $webfont ) { $provider = $webfont['provider']; if ( ! isset( $providers[ $provider ] ) ) { /* translators: %s is the provider name. */ diff --git a/lib/compat/wordpress-6.0/register-webfonts-from-theme-json.php b/lib/compat/wordpress-6.0/register-webfonts-from-theme-json.php index f18c301764c710..17b925f7f99083 100644 --- a/lib/compat/wordpress-6.0/register-webfonts-from-theme-json.php +++ b/lib/compat/wordpress-6.0/register-webfonts-from-theme-json.php @@ -69,8 +69,8 @@ function gutenberg_register_webfonts_from_theme_json() { * * @return array The global styles with missing fonts data. */ -function gutenberg_add_registered_webfonts_to_theme_json( $data ) { - $font_families_registered = wp_webfonts()->get_fonts(); +function gutenberg_add_webfonts_to_theme_json( $data ) { + $webfonts = wp_webfonts()->get_all_webfonts(); $font_families_from_theme = array(); if ( ! empty( $data['settings'] ) && ! empty( $data['settings']['typography'] ) && ! empty( $data['settings']['typography']['fontFamilies'] ) ) { $font_families_from_theme = $data['settings']['typography']['fontFamilies']; @@ -101,7 +101,7 @@ function gutenberg_add_registered_webfonts_to_theme_json( $data ) { // Diff the arrays to find the missing fonts. $to_add = array_diff( - $get_families( $font_families_registered ), + $get_families( $webfonts ), $get_families( $font_families_from_theme ) ); @@ -125,7 +125,7 @@ function gutenberg_add_registered_webfonts_to_theme_json( $data ) { // Add missing fonts. foreach ( $to_add as $family ) { $font_face = array(); - foreach ( $font_families_registered as $font_family ) { + foreach ( $webfonts as $font_family ) { if ( $family !== $font_family['font-family'] ) { continue; } diff --git a/lib/compat/wordpress-6.0/webfonts.php b/lib/compat/wordpress-6.0/webfonts.php index f3665766f06f36..a0dcb90cb470f8 100644 --- a/lib/compat/wordpress-6.0/webfonts.php +++ b/lib/compat/wordpress-6.0/webfonts.php @@ -37,6 +37,7 @@ function wp_webfonts() { * wp_register_webfonts( * array( * array( + * 'id' => 'source-serif-200-900-normal', * 'provider' => 'local', * 'font_family' => 'Source Serif Pro', * 'font_weight' => '200 900', @@ -44,6 +45,7 @@ function wp_webfonts() { * 'src' => get_theme_file_uri( 'assets/fonts/source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2' ), * ), * array( + * 'id' => 'source-serif-200-900-italic', * 'provider' => 'local', * 'font_family' => 'Source Serif Pro', * 'font_weight' => '200 900', @@ -64,9 +66,9 @@ function wp_webfonts() { * See {@see WP_Webfonts_Registry::register()} for a list of * supported arguments for each webfont. */ -function wp_register_webfonts( array $webfonts = array() ) { +function wp_register_webfonts( $webfonts = array() ) { foreach ( $webfonts as $webfont ) { - wp_register_webfont( $webfont ); + wp_register_webfont( $webfont['id'], $webfont ); } } @@ -90,11 +92,12 @@ function wp_register_webfonts( array $webfonts = array() ) { * * @since 6.0.0 * - * @param array $webfont Webfont to be registered. - * See {@see WP_Webfonts_Registry::register()} for a list of supported arguments. + * @param string $id The webfont id. + * @param array $webfont Webfont to be registered. + * See {@see WP_Webfonts_Registry::register()} for a list of supported arguments. */ -function wp_register_webfont( array $webfont ) { - wp_webfonts()->register_font( $webfont ); +function wp_register_webfont( $id, $webfont ) { + wp_webfonts()->register_font( $id, $webfont ); } /** From b084fd0be2239f96a814c349f86cfadad25261a2 Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Wed, 9 Mar 2022 19:20:56 -0300 Subject: [PATCH 02/14] Expose webfont enqueueing method --- lib/compat/wordpress-6.0/webfonts.php | 32 +++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/lib/compat/wordpress-6.0/webfonts.php b/lib/compat/wordpress-6.0/webfonts.php index a0dcb90cb470f8..3138360f546ef9 100644 --- a/lib/compat/wordpress-6.0/webfonts.php +++ b/lib/compat/wordpress-6.0/webfonts.php @@ -80,6 +80,7 @@ function wp_register_webfonts( $webfonts = array() ) { * If the font file is contained within the theme: * ``` * wp_register_webfont( + * 'source-serif-pro-normal', * array( * 'provider' => 'local', * 'font_family' => 'Source Serif Pro', @@ -100,6 +101,37 @@ function wp_register_webfont( $id, $webfont ) { wp_webfonts()->register_font( $id, $webfont ); } +/** + * Enqueue a single webfont. + * + * Register the webfont if $webfont is provided and enqueues. + * + * Example of how to register Source Serif Pro font with font-weight range of 200-900: + * + * If the font file is contained within the theme: + * ``` + * wp_enqueue_webfont( + * 'source-serif-pro-normal', + * array( + * 'provider' => 'local', + * 'font_family' => 'Source Serif Pro', + * 'font_weight' => '200 900', + * 'font_style' => 'normal', + * 'src' => get_theme_file_uri( 'assets/fonts/source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2' ), + * ) + * ); + * ``` + * + * @since 6.0.0 + * + * @param string $id The webfont id. + * @param array|null $webfont Webfont to be enqueued. Can be omitted if the font was registered beforehand. + * See {@see WP_Webfonts_Registry::register()} for a list of supported arguments. + */ +function wp_enqueue_webfont( $id, $webfont = null ) { + wp_webfonts()->enqueue_font( $id, $webfont ); +} + /** * Registers a custom font service provider. * From a9bf4b6ec62ec6aa89fdec79e0d24dffec1f4104 Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Wed, 9 Mar 2022 19:22:06 -0300 Subject: [PATCH 03/14] Register fonts from theme.json instead of directly enqueueing them --- .../register-webfonts-from-theme-json.php | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/compat/wordpress-6.0/register-webfonts-from-theme-json.php b/lib/compat/wordpress-6.0/register-webfonts-from-theme-json.php index 17b925f7f99083..6547c62c2f8981 100644 --- a/lib/compat/wordpress-6.0/register-webfonts-from-theme-json.php +++ b/lib/compat/wordpress-6.0/register-webfonts-from-theme-json.php @@ -5,6 +5,16 @@ * @package gutenberg */ +/** + * Generates a font id based on the provided font object. + * + * @param array $font The font object. + * @return string + */ +function gutenberg_generate_font_id( $font ) { + return sanitize_title( "{$font['font-family']}-{$font['font-weight']}-{$font['font-style']}-{$font['provider']}" ); +} + /** * Register webfonts defined in theme.json. */ @@ -58,7 +68,8 @@ function gutenberg_register_webfonts_from_theme_json() { } } foreach ( $webfonts as $webfont ) { - wp_webfonts()->register_font( $webfont ); + $id = isset( $webfont['id'] ) ? $webfont['id'] : gutenberg_generate_font_id( $webfont ); + wp_register_webfont( $id, $webfont ); } } From 91dbebaddf7ae55d9eacd0164fdc3e039d7229fd Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Thu, 10 Mar 2022 16:03:11 -0300 Subject: [PATCH 04/14] Expose bulk webfont enqueueing method --- lib/compat/wordpress-6.0/webfonts.php | 51 +++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/lib/compat/wordpress-6.0/webfonts.php b/lib/compat/wordpress-6.0/webfonts.php index 3138360f546ef9..09e0a88ada6f24 100644 --- a/lib/compat/wordpress-6.0/webfonts.php +++ b/lib/compat/wordpress-6.0/webfonts.php @@ -101,6 +101,57 @@ function wp_register_webfont( $id, $webfont ) { wp_webfonts()->register_font( $id, $webfont ); } +/** + * Enqueues a collection of webfonts. + * + * Example of how to enqueue Source Serif Pro font with font-weight range of 200-900 + * and font-style of normal and italic: + * + * + * wp_enqueue_webfonts( + * array( + * 'some-already-registered-font', // This requires the font to be registered beforehand. + * array( + * 'id' => 'source-serif-200-900-normal', + * 'provider' => 'local', + * 'font_family' => 'Source Serif Pro', + * 'font_weight' => '200 900', + * 'font_style' => 'normal', + * 'src' => get_theme_file_uri( 'assets/fonts/source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2' ), + * ), + * array( + * 'id' => 'source-serif-200-900-italic', + * 'provider' => 'local', + * 'font_family' => 'Source Serif Pro', + * 'font_weight' => '200 900', + * 'font_style' => 'italic', + * 'src' => get_theme_file_uri( 'assets/fonts/source-serif-pro/SourceSerif4Variable-Italic.ttf.woff2' ), + * ), + * ) + * ); + * + * + * Webfonts should be enqueued in the `after_setup_theme` hook. + * + * @since 6.0.0 + * + * @param array $webfonts Webfonts to be enqueued. + * This contains an array of webfonts to be enqueued. + * Each webfont is an array. + * See {@see WP_Webfonts_Registry::register()} for a list of + * supported arguments for each webfont. + */ +function wp_enqueue_webfonts( $webfonts = array() ) { + foreach ( $webfonts as $webfont ) { + if ( is_string( $webfont ) ) { + wp_enqueue_webfont( $webfont ); + continue; + } + + wp_enqueue_webfont( $webfont['id'], $webfont ); + } +} + /** * Enqueue a single webfont. * From ab3607244812792c14742106d5221426b7066b43 Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Thu, 10 Mar 2022 16:08:57 -0300 Subject: [PATCH 05/14] Remove misleading comment regarding arguments list --- lib/compat/wordpress-6.0/webfonts.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/lib/compat/wordpress-6.0/webfonts.php b/lib/compat/wordpress-6.0/webfonts.php index 09e0a88ada6f24..35bcd28ea44e00 100644 --- a/lib/compat/wordpress-6.0/webfonts.php +++ b/lib/compat/wordpress-6.0/webfonts.php @@ -63,8 +63,6 @@ function wp_webfonts() { * @param array $webfonts Webfonts to be registered. * This contains an array of webfonts to be registered. * Each webfont is an array. - * See {@see WP_Webfonts_Registry::register()} for a list of - * supported arguments for each webfont. */ function wp_register_webfonts( $webfonts = array() ) { foreach ( $webfonts as $webfont ) { @@ -95,7 +93,6 @@ function wp_register_webfonts( $webfonts = array() ) { * * @param string $id The webfont id. * @param array $webfont Webfont to be registered. - * See {@see WP_Webfonts_Registry::register()} for a list of supported arguments. */ function wp_register_webfont( $id, $webfont ) { wp_webfonts()->register_font( $id, $webfont ); @@ -138,8 +135,6 @@ function wp_register_webfont( $id, $webfont ) { * @param array $webfonts Webfonts to be enqueued. * This contains an array of webfonts to be enqueued. * Each webfont is an array. - * See {@see WP_Webfonts_Registry::register()} for a list of - * supported arguments for each webfont. */ function wp_enqueue_webfonts( $webfonts = array() ) { foreach ( $webfonts as $webfont ) { @@ -177,7 +172,6 @@ function wp_enqueue_webfonts( $webfonts = array() ) { * * @param string $id The webfont id. * @param array|null $webfont Webfont to be enqueued. Can be omitted if the font was registered beforehand. - * See {@see WP_Webfonts_Registry::register()} for a list of supported arguments. */ function wp_enqueue_webfont( $id, $webfont = null ) { wp_webfonts()->enqueue_font( $id, $webfont ); From 53ab9d117833e733fee1e7e49e7353de35b48701 Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Fri, 11 Mar 2022 14:19:09 -0300 Subject: [PATCH 06/14] Enhance wp_register_webfonts and wp_register_webfont tests --- phpunit/class-wp-webfonts-test.php | 77 +++++++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 6 deletions(-) diff --git a/phpunit/class-wp-webfonts-test.php b/phpunit/class-wp-webfonts-test.php index 382c1b1583e0db..e361044832aa1e 100644 --- a/phpunit/class-wp-webfonts-test.php +++ b/phpunit/class-wp-webfonts-test.php @@ -26,14 +26,17 @@ function tearDown() { } /** + * Test wp_register_webfonts() bulk register webfonts. + * * @covers wp_register_webfonts * @covers WP_Webfonts::register_font - * @covers WP_Webfonts::get_fonts - * @covers WP_Webfonts::get_font_id + * @covers WP_Webfonts::get_registered_fonts + * @covers WP_Webfonts::get_enqueued_fonts */ - public function test_get_fonts() { + public function test_wp_register_webfonts() { $fonts = array( array( + 'id' => 'source-serif-pro-200-900-normal-local', 'provider' => 'local', 'font-family' => 'Source Serif Pro', 'font-style' => 'normal', @@ -43,6 +46,7 @@ public function test_get_fonts() { 'font-display' => 'fallback', ), array( + 'id' => 'source-serif-pro-200-900-italic-local', 'provider' => 'local', 'font-family' => 'Source Serif Pro', 'font-style' => 'italic', @@ -54,12 +58,73 @@ public function test_get_fonts() { ); $expected = array( - 'source-serif-pro-200-900-normal-local' => $fonts[0], - 'source-serif-pro-200-900-italic-local' => $fonts[1], + $fonts[0]['id'] => array_filter( $fonts[0], fn( $key ) => 'id' !== $key, ARRAY_FILTER_USE_KEY ), + $fonts[1]['id'] => array_filter( $fonts[1], fn( $key ) => 'id' !== $key, ARRAY_FILTER_USE_KEY ), ); wp_register_webfonts( $fonts ); - $this->assertEquals( $expected, wp_webfonts()->get_fonts() ); + $this->assertEquals( $expected, wp_webfonts()->get_registered_fonts() ); + $this->assertEquals( array(), wp_webfonts()->get_enqueued_fonts() ); + } + + /** + * Test wp_register_webfont() register a single webfont. + * + * @covers wp_register_webfont + * @covers WP_Webfonts::register_font + * @covers WP_Webfonts::get_registered_fonts + * @covers WP_Webfonts::get_enqueued_fonts + */ + public function test_wp_register_webfont() { + $id = 'source-serif-pro-200-900-normal-local'; + + $font = array( + 'provider' => 'local', + 'font-family' => 'Source Serif Pro', + 'font-style' => 'normal', + 'font-weight' => '200 900', + 'font-stretch' => 'normal', + 'src' => 'https://example.com/assets/fonts/source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2', + 'font-display' => 'fallback', + ); + + $expected = array( + $id => $font, + ); + + wp_register_webfont( $id, $font ); + $this->assertEquals( $expected, wp_webfonts()->get_registered_fonts() ); + $this->assertEquals( array(), wp_webfonts()->get_enqueued_fonts() ); + } + + /** + * Test wp_register_webfont() does not enqueue the webfont on registration. + * + * @covers wp_register_webfont + * @covers WP_Webfonts::register_font + * @covers WP_Webfonts::get_registered_fonts + * @covers WP_Webfonts::get_enqueued_fonts + */ + public function test_wp_register_webfont_does_not_enqueue_on_registration() { + $id = 'source-serif-pro-200-900-normal-local'; + + $font = array( + 'provider' => 'local', + 'font-family' => 'Source Serif Pro', + 'font-style' => 'normal', + 'font-weight' => '200 900', + 'font-stretch' => 'normal', + 'src' => 'https://example.com/assets/fonts/source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2', + 'font-display' => 'fallback', + ); + + $expected = array( + $id => $font, + ); + + wp_register_webfont( $id, $font ); + $this->assertEquals( $expected, wp_webfonts()->get_registered_fonts() ); + $this->assertEquals( array(), wp_webfonts()->get_enqueued_fonts() ); } /** From 0888132d55beb52fca1af85daa3e8aeb0ec17906 Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Fri, 11 Mar 2022 14:19:33 -0300 Subject: [PATCH 07/14] Add wp_enqueue_webfonts and wp_enqueue_webfont tests --- phpunit/class-wp-webfonts-test.php | 121 +++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) diff --git a/phpunit/class-wp-webfonts-test.php b/phpunit/class-wp-webfonts-test.php index e361044832aa1e..83cc32cb2d9cf9 100644 --- a/phpunit/class-wp-webfonts-test.php +++ b/phpunit/class-wp-webfonts-test.php @@ -127,6 +127,127 @@ public function test_wp_register_webfont_does_not_enqueue_on_registration() { $this->assertEquals( array(), wp_webfonts()->get_enqueued_fonts() ); } + /** + * Test wp_enqueue_webfonts() bulk enqueue webfonts. + * + * @covers wp_enqueue_webfonts + * @covers WP_Webfonts::enqueue_font + * @covers WP_Webfonts::get_enqueued_fonts + * @covers WP_Webfonts::get_registered_fonts + */ + public function test_wp_enqueue_webfonts() { + $fonts = array( + array( + 'id' => 'source-serif-pro-200-900-normal-local', + 'provider' => 'local', + 'font-family' => 'Source Serif Pro', + 'font-style' => 'normal', + 'font-weight' => '200 900', + 'font-stretch' => 'normal', + 'src' => 'https://example.com/assets/fonts/source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2', + 'font-display' => 'fallback', + ), + array( + 'id' => 'source-serif-pro-200-900-italic-local', + 'provider' => 'local', + 'font-family' => 'Source Serif Pro', + 'font-style' => 'italic', + 'font-weight' => '200 900', + 'font-stretch' => 'normal', + 'src' => 'https://example.com/assets/fonts/source-serif-pro/SourceSerif4Variable-Italic.ttf.woff2', + 'font-display' => 'fallback', + ), + ); + + $expected = array( + $fonts[0]['id'] => array_filter( $fonts[0], fn( $key ) => 'id' !== $key, ARRAY_FILTER_USE_KEY ), + $fonts[1]['id'] => array_filter( $fonts[1], fn( $key ) => 'id' !== $key, ARRAY_FILTER_USE_KEY ), + ); + + wp_enqueue_webfonts( $fonts ); + $this->assertEquals( $expected, wp_webfonts()->get_enqueued_fonts() ); + $this->assertEquals( array(), wp_webfonts()->get_registered_fonts() ); + } + + /** + * Test wp_enqueue_font() enqueues a registered webfont. + * + * @covers wp_enqueue_webfont + * @covers WP_Webfonts::enqueued_font + * @covers WP_Webfonts::get_enqueued_fonts + * @covers WP_Webfonts::get_registered_fonts + */ + public function test_wp_enqueue_webfont_enqueues_registered_webfont() { + $id = 'source-serif-pro-200-900-normal-local'; + + $font = array( + 'provider' => 'local', + 'font-family' => 'Source Serif Pro', + 'font-style' => 'normal', + 'font-weight' => '200 900', + 'font-stretch' => 'normal', + 'src' => 'https://example.com/assets/fonts/source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2', + 'font-display' => 'fallback', + ); + + $expected = array( + $id => $font, + ); + + wp_register_webfont( $id, $font ); + wp_enqueue_webfont( $id ); + + $this->assertEquals( array(), wp_webfonts()->get_registered_fonts() ); + $this->assertEquals( $expected, wp_webfonts()->get_enqueued_fonts() ); + } + + /** + * Test wp_enqueue_font() register and enqueues a webfont if given as an argument. + * + * @covers wp_enqueue_webfont + * @covers WP_Webfonts::enqueued_font + * @covers WP_Webfonts::get_enqueued_fonts + */ + public function test_wp_enqueue_webfont_register_and_enqueues_if_webfont_given_as_argument() { + $id = 'source-serif-pro-200-900-normal-local'; + + $font = array( + 'provider' => 'local', + 'font-family' => 'Source Serif Pro', + 'font-style' => 'normal', + 'font-weight' => '200 900', + 'font-stretch' => 'normal', + 'src' => 'https://example.com/assets/fonts/source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2', + 'font-display' => 'fallback', + ); + + $expected = array( + $id => $font, + ); + + wp_enqueue_webfont( $id, $font ); + + $this->assertEquals( array(), wp_webfonts()->get_registered_fonts() ); + $this->assertEquals( $expected, wp_webfonts()->get_enqueued_fonts() ); + } + + /** + * Test wp_enqueue_font() does not enqueue a webfont that was not registered. + * + * @covers wp_enqueue_webfont + * @covers WP_Webfonts::enqueued_font + * @covers WP_Webfonts::get_enqueued_fonts + * @covers WP_Webfonts::get_registered_fonts + */ + public function test_wp_enqueue_webfont_does_not_enqueue_unregistered_webfont() { + $id = 'source-serif-pro-200-900-normal-local'; + + wp_enqueue_webfont( $id ); + + $this->assertEquals( array(), wp_webfonts()->get_registered_fonts() ); + $this->assertEquals( array(), wp_webfonts()->get_enqueued_fonts() ); + } + /** * @covers wp_register_webfont * @covers WP_Webfonts::register_provider From 6a0cf04c1885543676f22dcbfb7eb18c7da34220 Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Fri, 11 Mar 2022 15:18:39 -0300 Subject: [PATCH 08/14] Make sure wp-block-library is enqueued before adding inline styles to it --- 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 9428100edc0d0f..69bf17083cc2d2 100644 --- a/lib/compat/wordpress-6.0/class-wp-webfonts.php +++ b/lib/compat/wordpress-6.0/class-wp-webfonts.php @@ -286,6 +286,7 @@ public function generate_and_enqueue_editor_styles() { return; } + wp_enqueue_style( 'wp-block-library' ); wp_add_inline_style( 'wp-block-library', $styles ); } From 59ef049a6aa7743ed3b4a9396182be6d19c2a641 Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Mon, 14 Mar 2022 14:28:31 -0700 Subject: [PATCH 09/14] Remove static variable declaration for registered and enqueued webfonts --- lib/compat/wordpress-6.0/class-wp-webfonts.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/compat/wordpress-6.0/class-wp-webfonts.php b/lib/compat/wordpress-6.0/class-wp-webfonts.php index 69bf17083cc2d2..dd5305f6bc8c63 100644 --- a/lib/compat/wordpress-6.0/class-wp-webfonts.php +++ b/lib/compat/wordpress-6.0/class-wp-webfonts.php @@ -16,16 +16,15 @@ class WP_Webfonts { * @access private * @var array */ - private static $registered_webfonts = array(); + private $registered_webfonts = array(); /** * An array of enqueued webfonts. * - * @static * @access private * @var array */ - private static $enqueued_webfonts = array(); + private $enqueued_webfonts = array(); /** * An array of registered providers. From e0a573d53936f4a82d44b5cd960ab569737ddd9e Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Mon, 14 Mar 2022 14:29:35 -0700 Subject: [PATCH 10/14] Reference the registered_webfonts as an instance variable --- lib/compat/wordpress-6.0/class-wp-webfonts.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/compat/wordpress-6.0/class-wp-webfonts.php b/lib/compat/wordpress-6.0/class-wp-webfonts.php index dd5305f6bc8c63..19b91699cb8789 100644 --- a/lib/compat/wordpress-6.0/class-wp-webfonts.php +++ b/lib/compat/wordpress-6.0/class-wp-webfonts.php @@ -69,7 +69,7 @@ public function init() { * @return array */ public function get_registered_fonts() { - return self::$registered_webfonts; + return $this->registered_webfonts; } /** @@ -108,7 +108,7 @@ public function register_font( $id, $font ) { $font = $this->validate_font( $font ); if ( $font ) { - self::$registered_webfonts[ $id ] = $font; + $this->registered_webfonts[ $id ] = $font; } } @@ -132,13 +132,13 @@ public function enqueue_font( $id, $font = null ) { $font = $this->validate_font( $font ); self::$enqueued_webfonts[ $id ] = $font; - if ( isset( self::$registered_webfonts[ $id ] ) ) { - unset( self::$registered_webfonts[ $id ] ); + if ( isset( $this->registered_webfonts[ $id ] ) ) { + unset( $this->registered_webfonts[ $id ] ); } - } elseif ( isset( self::$registered_webfonts[ $id ] ) ) { - self::$enqueued_webfonts[ $id ] = self::$registered_webfonts[ $id ]; + } elseif ( isset( $this->registered_webfonts[ $id ] ) ) { + self::$enqueued_webfonts[ $id ] = $this->registered_webfonts[ $id ]; - unset( self::$registered_webfonts[ $id ] ); + unset( $this->registered_webfonts[ $id ] ); } else { trigger_error( __( 'The given webfont ID is not registered, therefore the webfont cannot be enqueued.', 'gutenberg' ) ); } From 391b0b08f79cce32bba6f1f2230a36ea90b2a80f Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Mon, 14 Mar 2022 14:30:22 -0700 Subject: [PATCH 11/14] Reference the enqueued_webfonts as an instance variable --- lib/compat/wordpress-6.0/class-wp-webfonts.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/compat/wordpress-6.0/class-wp-webfonts.php b/lib/compat/wordpress-6.0/class-wp-webfonts.php index 19b91699cb8789..c0e137699a73fc 100644 --- a/lib/compat/wordpress-6.0/class-wp-webfonts.php +++ b/lib/compat/wordpress-6.0/class-wp-webfonts.php @@ -78,7 +78,7 @@ public function get_registered_fonts() { * @return array */ public function get_enqueued_fonts() { - return self::$enqueued_webfonts; + return $this->enqueued_webfonts; } /** @@ -130,13 +130,13 @@ public function enqueue_font( $id, $font = null ) { if ( $font ) { $font = $this->validate_font( $font ); - self::$enqueued_webfonts[ $id ] = $font; + $this->enqueued_webfonts[ $id ] = $font; if ( isset( $this->registered_webfonts[ $id ] ) ) { unset( $this->registered_webfonts[ $id ] ); } } elseif ( isset( $this->registered_webfonts[ $id ] ) ) { - self::$enqueued_webfonts[ $id ] = $this->registered_webfonts[ $id ]; + $this->enqueued_webfonts[ $id ] = $this->registered_webfonts[ $id ]; unset( $this->registered_webfonts[ $id ] ); } else { From 2df17bfa6523137eefd0e9ef15b92ef356aebcbf Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Tue, 15 Mar 2022 14:43:14 -0300 Subject: [PATCH 12/14] Add test for generate_and_enqueue_styles --- phpunit/class-wp-webfonts-test.php | 46 ++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/phpunit/class-wp-webfonts-test.php b/phpunit/class-wp-webfonts-test.php index 83cc32cb2d9cf9..484217c54b03c5 100644 --- a/phpunit/class-wp-webfonts-test.php +++ b/phpunit/class-wp-webfonts-test.php @@ -308,24 +308,46 @@ public function test_validate_font() { } /** + * Test generate_and_enqueue_styles outputs only enqueued webfonts. + * * @covers WP_Webfonts::generate_styles */ public function test_generate_styles() { - $font = array( - 'provider' => 'local', - 'font-family' => 'Source Serif Pro', - 'font-style' => 'normal', - 'font-weight' => '200 900', - 'font-stretch' => 'normal', - 'src' => 'https://example.com/assets/fonts/source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2', - 'font-display' => 'fallback', + wp_register_webfont( + 'source-serif-pro-200-900-italic-local', + array( + 'provider' => 'local', + 'font-family' => 'Source Serif Pro', + 'font-style' => 'italic', + 'font-weight' => '200 900', + 'font-stretch' => 'normal', + 'src' => 'https://example.com/assets/fonts/source-serif-pro/SourceSerif4Variable-Italic.ttf.woff2', + 'font-display' => 'fallback', + ) + ); + + wp_enqueue_webfont( + 'source-serif-pro-200-900-normal-local', // This is different from the webfont registered above. + array( + 'provider' => 'local', + 'font-family' => 'Source Serif Pro', + 'font-style' => 'normal', + 'font-weight' => '200 900', + 'font-stretch' => 'normal', + 'src' => 'https://example.com/assets/fonts/source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2', + 'font-display' => 'fallback', + ) ); - wp_register_webfont( $font ); + wp_webfonts()->generate_and_enqueue_styles(); - $this->assertEquals( - '@font-face{font-family:"Source Serif Pro";font-style:normal;font-weight:200 900;font-display:fallback;font-stretch:normal;src:local("Source Serif Pro"), url(\'https://example.com/assets/fonts/source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2\') format(\'woff2\');}', - wp_webfonts()->generate_styles() + $expected = <<assertContains( + $expected, + get_echo( 'wp_print_styles' ) ); } } From 7a12067fbdfa9b7123a1364bb747420863d152b4 Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Mon, 14 Mar 2022 15:42:40 -0700 Subject: [PATCH 13/14] Add test for generate_and_enqueue_editor_styles --- phpunit/class-wp-webfonts-test.php | 45 ++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/phpunit/class-wp-webfonts-test.php b/phpunit/class-wp-webfonts-test.php index 484217c54b03c5..569f2bd3ea20ec 100644 --- a/phpunit/class-wp-webfonts-test.php +++ b/phpunit/class-wp-webfonts-test.php @@ -343,6 +343,51 @@ public function test_generate_styles() { $expected = <<assertContains( + $expected, + get_echo( 'wp_print_styles' ) + ); + } + + /** + * Test generate_and_enqueue_editor_styles outputs registered and enqueued webfonts. + * Both are necessary so the editor correctly loads webfonts picked while in the editor. + * + * @covers WP_Webfonts::generate_and_enqueue_editor_styles + */ + public function test_generate_and_enqueue_editor_styles() { + wp_register_webfont( + 'source-serif-pro-200-900-italic-local', + array( + 'provider' => 'local', + 'font-family' => 'Source Serif Pro', + 'font-style' => 'italic', + 'font-weight' => '200 900', + 'font-stretch' => 'normal', + 'src' => 'https://example.com/assets/fonts/source-serif-pro/SourceSerif4Variable-Italic.ttf.woff2', + 'font-display' => 'fallback', + ) + ); + + wp_enqueue_webfont( + 'source-serif-pro-200-900-normal-local', // This is different from the webfont registered above. + array( + 'provider' => 'local', + 'font-family' => 'Source Serif Pro', + 'font-style' => 'normal', + 'font-weight' => '200 900', + 'font-stretch' => 'normal', + 'src' => 'https://example.com/assets/fonts/source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2', + 'font-display' => 'fallback', + ) + ); + + wp_webfonts()->generate_and_enqueue_editor_styles(); + + $expected = <<assertContains( From 5ab6da7f18c468a9e697bedf57335f32251f3123 Mon Sep 17 00:00:00 2001 From: Luis Felipe Zaguini Date: Wed, 16 Mar 2022 19:53:17 -0300 Subject: [PATCH 14/14] Move src attribute processing to the local provider --- .../class-wp-webfonts-provider-local.php | 6 +++--- .../register-webfonts-from-theme-json.php | 13 ------------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/lib/compat/wordpress-6.0/class-wp-webfonts-provider-local.php b/lib/compat/wordpress-6.0/class-wp-webfonts-provider-local.php index 6d1da877ae6d48..4a48332ba9d869 100644 --- a/lib/compat/wordpress-6.0/class-wp-webfonts-provider-local.php +++ b/lib/compat/wordpress-6.0/class-wp-webfonts-provider-local.php @@ -227,9 +227,9 @@ private function compile_src( $font_family, array $value ) { $src = "local($font_family)"; foreach ( $value as $item ) { - - if ( 0 === strpos( $item['url'], get_site_url() ) ) { - $item['url'] = wp_make_link_relative( $item['url'] ); + if ( 0 === strpos( $item['url'], 'file:./' ) ) { + $absolute_path_to_url = get_stylesheet_directory_uri() . '/' . str_replace( 'file:./', '', $item['url'] ); + $item['url'] = wp_make_link_relative( $absolute_path_to_url ); } $src .= ( 'data' === $item['format'] ) diff --git a/lib/compat/wordpress-6.0/register-webfonts-from-theme-json.php b/lib/compat/wordpress-6.0/register-webfonts-from-theme-json.php index 6547c62c2f8981..a11f34c4ea9207 100644 --- a/lib/compat/wordpress-6.0/register-webfonts-from-theme-json.php +++ b/lib/compat/wordpress-6.0/register-webfonts-from-theme-json.php @@ -41,19 +41,6 @@ function gutenberg_register_webfonts_from_theme_json() { $font_family['fontFace'] = (array) $font_family['fontFace']; foreach ( $font_family['fontFace'] as $font_face ) { - // Check if webfonts have a "src" param, and if they do account for the use of "file:./". - if ( ! empty( $font_face['src'] ) ) { - $font_face['src'] = (array) $font_face['src']; - - foreach ( $font_face['src'] as $src_key => $url ) { - // Tweak the URL to be relative to the theme root. - if ( 0 !== strpos( $url, 'file:./' ) ) { - continue; - } - $font_face['src'][ $src_key ] = get_theme_file_uri( str_replace( 'file:./', '', $url ) ); - } - } - // Convert keys to kebab-case. foreach ( $font_face as $property => $value ) { $kebab_case = _wp_to_kebab_case( $property );