From ba472085a05c837e42ab38f16aa06d90c3759994 Mon Sep 17 00:00:00 2001 From: Peter Wilson Date: Sun, 20 Oct 2024 23:23:11 +0000 Subject: [PATCH] Editor: Load all style variation fonts within the editors. Loads the font family files from style variations defined within a theme for user in the site and post editors. This is to ensure the fonts are shown while editing without the need for a reload after switching styles. Props ironprogrammer, mmaattiiaass. Fixes #62231. git-svn-id: https://develop.svn.wordpress.org/trunk@59260 602fd350-edb4-49c9-b593-d223f7449a82 --- src/wp-admin/includes/admin-filters.php | 1 + src/wp-includes/block-editor.php | 1 + src/wp-includes/fonts.php | 16 ++++ .../fonts/class-wp-font-face-resolver.php | 32 +++++++ .../font-face/wp-font-face-tests-dataset.php | 91 +++++++++++++++++++ .../getFontsFromStyleVariations.php | 71 +++++++++++++++ .../wpPrintFontFacesFromStyleVariations.php | 54 +++++++++++ 7 files changed, 266 insertions(+) create mode 100644 tests/phpunit/tests/fonts/font-face/wpFontFaceResolver/getFontsFromStyleVariations.php create mode 100644 tests/phpunit/tests/fonts/font-face/wpPrintFontFacesFromStyleVariations.php diff --git a/src/wp-admin/includes/admin-filters.php b/src/wp-admin/includes/admin-filters.php index b5adb946cf0d3..587fbc25e9e3c 100644 --- a/src/wp-admin/includes/admin-filters.php +++ b/src/wp-admin/includes/admin-filters.php @@ -172,3 +172,4 @@ // Font management. add_action( 'admin_print_styles', 'wp_print_font_faces', 50 ); +add_action( 'admin_print_styles', 'wp_print_font_faces_from_style_variations', 50 ); diff --git a/src/wp-includes/block-editor.php b/src/wp-includes/block-editor.php index be8a8f901fe5c..bdca0d2c08528 100644 --- a/src/wp-includes/block-editor.php +++ b/src/wp-includes/block-editor.php @@ -366,6 +366,7 @@ function _wp_get_iframed_editor_assets() { ob_start(); wp_print_styles(); wp_print_font_faces(); + wp_print_font_faces_from_style_variations(); $styles = ob_get_clean(); if ( $has_emoji_styles ) { diff --git a/src/wp-includes/fonts.php b/src/wp-includes/fonts.php index 4e286b71dc7f2..17db0396089f8 100644 --- a/src/wp-includes/fonts.php +++ b/src/wp-includes/fonts.php @@ -54,6 +54,22 @@ function wp_print_font_faces( $fonts = array() ) { $wp_font_face->generate_and_print( $fonts ); } +/** + * Generates and prints font-face styles defined the the theme style variations. + * + * @since 6.7.0 + * + */ +function wp_print_font_faces_from_style_variations() { + $fonts = WP_Font_Face_Resolver::get_fonts_from_style_variations(); + + if ( empty( $fonts ) ) { + return; + } + + wp_print_font_faces( $fonts ); +} + /** * Registers a new font collection in the font library. * diff --git a/src/wp-includes/fonts/class-wp-font-face-resolver.php b/src/wp-includes/fonts/class-wp-font-face-resolver.php index 12245af556b58..153008b53aec0 100644 --- a/src/wp-includes/fonts/class-wp-font-face-resolver.php +++ b/src/wp-includes/fonts/class-wp-font-face-resolver.php @@ -36,6 +36,38 @@ public static function get_fonts_from_theme_json() { return static::parse_settings( $settings ); } + /** + * Gets fonts defined in style variations. + * + * @since 6.7.0 + * + * @return array Returns an array of font-families. + */ + public static function get_fonts_from_style_variations() { + $variations = WP_Theme_JSON_Resolver::get_style_variations(); + $fonts = array(); + + if ( empty( $variations ) ) { + return $fonts; + } + + foreach ( $variations as $variation ) { + if ( ! empty( $variation['settings']['typography']['fontFamilies']['theme'] ) ) { + $fonts = array_merge( $fonts, $variation['settings']['typography']['fontFamilies']['theme'] ); + } + } + + $settings = array( + 'typography' => array( + 'fontFamilies' => array( + 'theme' => $fonts, + ), + ), + ); + + return static::parse_settings( $settings ); + } + /** * Parse theme.json settings to extract font definitions with variations grouped by font-family. * diff --git a/tests/phpunit/tests/fonts/font-face/wp-font-face-tests-dataset.php b/tests/phpunit/tests/fonts/font-face/wp-font-face-tests-dataset.php index 1432c8589f5cc..d410acb7c4124 100644 --- a/tests/phpunit/tests/fonts/font-face/wp-font-face-tests-dataset.php +++ b/tests/phpunit/tests/fonts/font-face/wp-font-face-tests-dataset.php @@ -403,4 +403,95 @@ public static function get_custom_font_families( $key = '' ) { return $data; } + + public static function get_custom_style_variations( $key = '' ) { + static $data = null; + + $path = get_stylesheet_directory() . '/assets/fonts/'; + $uri = get_stylesheet_directory_uri() . '/assets/fonts/'; + $expected_font_families = array( + array( + array( + 'src' => array( + "{$path}dm-sans/DMSans-Regular.woff2", + ), + 'font-family' => 'DM Sans', + 'font-stretch' => 'normal', + 'font-style' => 'normal', + 'font-weight' => '400', + ), + array( + 'src' => array( + "{$path}dm-sans/DMSans-Bold.woff2", + ), + 'font-family' => 'DM Sans', + 'font-stretch' => 'normal', + 'font-style' => 'normal', + 'font-weight' => '700', + ), + ), + array( + array( + 'src' => array( + "{$path}open-sans/OpenSans-VariableFont_wdth,wght.ttf", + ), + 'font-family' => 'Open Sans', + 'font-stretch' => 'normal', + 'font-style' => 'normal', + 'font-weight' => '400', + ), + array( + 'src' => array( + "{$path}open-sans/OpenSans-Italic-VariableFont_wdth,wght.ttf", + ), + 'font-family' => 'Open Sans', + 'font-stretch' => 'normal', + 'font-style' => 'italic', + 'font-weight' => '400', + ), + ), + array( + array( + 'src' => array( + "{$path}dm-sans/DMSans-Medium.woff2", + ), + 'font-family' => 'DM Sans', + 'font-stretch' => 'normal', + 'font-style' => 'normal', + 'font-weight' => '500', + ), + array( + 'src' => array( + "{$path}dm-sans/DMSans-Medium-Italic.woff2", + ), + 'font-family' => 'DM Sans', + 'font-stretch' => 'normal', + 'font-style' => 'italic', + 'font-weight' => '500', + ), + ), + ); + + $expected_styles = << $expected_font_families, + 'expected_styles' => $expected_styles, + ); + } + + if ( isset( $data[ $key ] ) ) { + return $data[ $key ]; + } + + return $data; + } } diff --git a/tests/phpunit/tests/fonts/font-face/wpFontFaceResolver/getFontsFromStyleVariations.php b/tests/phpunit/tests/fonts/font-face/wpFontFaceResolver/getFontsFromStyleVariations.php new file mode 100644 index 0000000000000..0087dac087292 --- /dev/null +++ b/tests/phpunit/tests/fonts/font-face/wpFontFaceResolver/getFontsFromStyleVariations.php @@ -0,0 +1,71 @@ +assertIsArray( $fonts, 'Should return an array data type' ); + $this->assertEmpty( $fonts, 'Should return an empty array' ); + } + + /** + * Ensure that all variations are loaded from a theme. + * + * @ticket 62231 + */ + public function test_should_return_all_fonts_from_all_style_variations() { + switch_theme( static::FONTS_THEME ); + + $actual = WP_Font_Face_Resolver::get_fonts_from_style_variations(); + $expected = self::get_custom_style_variations( 'expected' ); + + $this->assertSame( $expected, $actual, 'All the fonts from the theme variations should be returned.' ); + } + + /** + * Ensure that file:./ is replaced in the src list. + * + * @ticket 62231 + */ + public function test_should_replace_src_file_placeholder() { + switch_theme( static::FONTS_THEME ); + + $fonts = WP_Font_Face_Resolver::get_fonts_from_style_variations(); + + // Check that the there is no theme relative url in the src list. + foreach ( $fonts as $family ) { + foreach ( $family as $font ) { + foreach ( $font['src'] as $src ) { + $src_basename = basename( $src ); + $this->assertStringNotContainsString( 'file:./', $src, "Font $src_basename should not contain the 'file:./' placeholder" ); + } + } + } + } +} diff --git a/tests/phpunit/tests/fonts/font-face/wpPrintFontFacesFromStyleVariations.php b/tests/phpunit/tests/fonts/font-face/wpPrintFontFacesFromStyleVariations.php new file mode 100644 index 0000000000000..a59ba882a4e86 --- /dev/null +++ b/tests/phpunit/tests/fonts/font-face/wpPrintFontFacesFromStyleVariations.php @@ -0,0 +1,54 @@ +expectOutputString( '' ); + wp_print_font_faces_from_style_variations(); + } + + /** + * Ensure that all fonts are printed from the theme style variations. + * + * @ticket 62231 + */ + public function test_should_print_fonts_in_style_variations() { + switch_theme( static::FONTS_THEME ); + + $expected = $this->get_custom_style_variations( 'expected_styles' ); + $expected_output = $this->get_expected_styles_output( $expected ); + + $this->expectOutputString( $expected_output ); + wp_print_font_faces_from_style_variations(); + } + + private function get_expected_styles_output( $styles ) { + $style_element = "\n"; + return sprintf( $style_element, $styles ); + } +}