Skip to content

Commit

Permalink
Editor: Load all style variation fonts within the editors.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
peterwilsoncc committed Oct 20, 2024
1 parent 281a68f commit ba47208
Show file tree
Hide file tree
Showing 7 changed files with 266 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/wp-admin/includes/admin-filters.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 );
1 change: 1 addition & 0 deletions src/wp-includes/block-editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) {
Expand Down
16 changes: 16 additions & 0 deletions src/wp-includes/fonts.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
32 changes: 32 additions & 0 deletions src/wp-includes/fonts/class-wp-font-face-resolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand Down
91 changes: 91 additions & 0 deletions tests/phpunit/tests/fonts/font-face/wp-font-face-tests-dataset.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 = <<<CSS
@font-face{font-family:"DM Sans";font-style:normal;font-weight:400;font-display:fallback;src:url('{$uri}dm-sans/DMSans-Regular.woff2') format('woff2');font-stretch:normal;}
@font-face{font-family:"DM Sans";font-style:normal;font-weight:700;font-display:fallback;src:url('{$uri}dm-sans/DMSans-Bold.woff2') format('woff2');font-stretch:normal;}
@font-face{font-family:"Open Sans";font-style:normal;font-weight:400;font-display:fallback;src:url('{$uri}open-sans/OpenSans-VariableFont_wdth,wght.ttf') format('truetype');font-stretch:normal;}
@font-face{font-family:"Open Sans";font-style:italic;font-weight:400;font-display:fallback;src:url('{$uri}open-sans/OpenSans-Italic-VariableFont_wdth,wght.ttf') format('truetype');font-stretch:normal;}
@font-face{font-family:"DM Sans";font-style:normal;font-weight:500;font-display:fallback;src:url('{$uri}dm-sans/DMSans-Medium.woff2') format('woff2');font-stretch:normal;}
@font-face{font-family:"DM Sans";font-style:italic;font-weight:500;font-display:fallback;src:url('{$uri}dm-sans/DMSans-Medium-Italic.woff2') format('woff2');font-stretch:normal;}
CSS;

if ( null === $data ) {
$data = array(
'expected' => $expected_font_families,
'expected_styles' => $expected_styles,
);
}

if ( isset( $data[ $key ] ) ) {
return $data[ $key ];
}

return $data;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
/**
* Test case for WP_Font_Face_Resolver::get_fonts_from_style_variations().
*
* @package WordPress
* @subpackage Fonts
*
* @since 6.7.0
*
* @group fonts
* @group fontface
*
* @covers WP_Font_Face_Resolver::get_fonts_from_style_variations
*/
class Tests_Fonts_WPFontFaceResolver_GetFontsFromStyleVariations extends WP_Font_Face_UnitTestCase {
const FONTS_THEME = 'fonts-block-theme';

public static function set_up_before_class() {
self::$requires_switch_theme_fixtures = true;

parent::set_up_before_class();
}

/**
* Ensure that an empty array is returned when the theme has no style variations.
*
* @ticket 62231
*/
public function test_should_return_empty_array_when_theme_has_no_style_variations() {
switch_theme( 'block-theme' );

$fonts = WP_Font_Face_Resolver::get_fonts_from_style_variations();
$this->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" );
}
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<?php
/**
* Test case for wp_print_font_faces_from_style_variations().
*
* @package WordPress
* @subpackage Fonts
*
* @since 6.7.0
*
* @group fonts
* @group fontface
*
* @covers wp_print_font_faces_from_style_variations
*/
class Tests_Fonts_WpPrintFontFacesFromStyleVariations extends WP_Font_Face_UnitTestCase {
const FONTS_THEME = 'fonts-block-theme';

public static function set_up_before_class() {
parent::set_up_before_class();
self::$requires_switch_theme_fixtures = true;
}

/**
* Ensure that no fonts are printed when the theme has no fonts.
*
* @ticket 62231
*/
public function test_should_not_print_when_no_fonts() {
switch_theme( 'block-theme' );

$this->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 = "<style class='wp-fonts-local' type='text/css'>\n%s\n</style>\n";
return sprintf( $style_element, $styles );
}
}

0 comments on commit ba47208

Please sign in to comment.