Make WordPress Core

Changeset 57720


Ignore:
Timestamp:
02/27/2024 12:04:55 PM (2 months ago)
Author:
youknowriad
Message:

Font face resolver: print font faces from font families defined in all theme.json origins.

This commit updates the theme.json style generation to allow a font family name to be repeated across theme.json origins (default, theme, custom).

Props mmaattiiaass, hellofromtonya, arthur791004, ironprogrammer.
Fixes #60605.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/fonts.php

    r57686 r57720  
    1414 *
    1515 * @param array[][] $fonts {
    16  *     Optional. The font-families and their font variations. Default empty array.
    17  *
    18  *     @type string $font-family => array[] $variations {
    19  *         Optional. An associated array of font variations for this font-family.
    20  *         Each variation has the following structure.
    21  *
    22  *         @type array $font_variation {
     16 *     Optional. The font-families and their font faces. Default empty array.
     17 *
     18 *     @type array {
     19 *         An indexed or associative (keyed by font-family) array of font variations for this font-family.
     20 *         Each font face has the following structure.
     21 *
     22 *         @type array {
    2323 *             @type string          $font-family             The font-family property.
    2424 *             @type string|string[] $src                     The URL(s) to each resource containing the font data.
  • trunk/src/wp-includes/fonts/class-wp-font-face-resolver.php

    r56688 r57720  
    6868                }
    6969
    70                 // Prepare the fonts array structure for this font-family.
    71                 if ( ! array_key_exists( $font_family_name, $fonts ) ) {
    72                     $fonts[ $font_family_name ] = array();
    73                 }
    74 
    75                 $fonts[ $font_family_name ] = static::convert_font_face_properties( $definition['fontFace'], $font_family_name );
     70                $fonts[] = static::convert_font_face_properties( $definition['fontFace'], $font_family_name );
    7671            }
    7772        }
  • trunk/tests/phpunit/tests/fonts/font-face/wp-font-face-tests-dataset.php

    r56500 r57720  
    9393            ),
    9494            'multiple woff2 format fonts'    => array(
    95                 'fonts'    => array(
     95                'fonts'                  => array(
    9696                    'DM Sans'       =>
    9797                        array(
     
    185185                        ),
    186186                ),
    187                 'expected' => <<<CSS
     187                'expected'               => <<<CSS
    188188@font-face{font-family:"DM Sans";font-style:normal;font-weight:400;font-display:fallback;src:url('https://example.org/assets/fonts/dm-sans/DMSans-Regular.woff2') format('woff2');font-stretch:normal;}
    189189@font-face{font-family:"DM Sans";font-style:italic;font-weight:400;font-display:fallback;src:url('https://example.org/assets/fonts/dm-sans/DMSans-Regular-Italic.woff2') format('woff2');font-stretch:normal;}
     
    196196CSS
    197197            ,
     198                'indexed array as input' => array(
     199                    'fonts'    => array(
     200                        array(
     201                            array(
     202                                'font-family'  => 'Piazzolla',
     203                                'src'          => array( 'https://example.org/fonts/piazzolla400.ttf' ),
     204                                'font-style'   => 'normal',
     205                                'font-weight'  => '400',
     206                                'font-stretch' => 'normal',
     207                            ),
     208                            array(
     209                                'font-family'  => 'Piazzolla',
     210                                'src'          => array( 'https://example.org/fonts/piazzolla500.ttf' ),
     211                                'font-style'   => 'normal',
     212                                'font-weight'  => '400',
     213                                'font-stretch' => 'normal',
     214                            ),
     215                        ),
     216                        array(
     217                            array(
     218                                'font-family'  => 'Lobster',
     219                                'src'          => array( 'https://example.org/fonts/lobster400.ttf' ),
     220                                'font-style'   => 'normal',
     221                                'font-weight'  => '400',
     222                                'font-stretch' => 'normal',
     223                            ),
     224                            array(
     225                                'font-family'  => 'Lobster',
     226                                'src'          => array( 'https://example.org/fonts/lobster500.ttf' ),
     227                                'font-style'   => 'normal',
     228                                'font-weight'  => '500',
     229                                'font-stretch' => 'normal',
     230                            ),
     231                        ),
     232                    ),
     233                    'expected' => <<<CSS
     234@font-face{font-family:Piazzolla;font-style:normal;font-weight:400;font-display:fallback;src:url('https://example.org/fonts/piazzolla400.ttf') format('truetype');font-stretch:normal;}
     235@font-face{font-family:Piazzolla;font-style:normal;font-weight:400;font-display:fallback;src:url('https://example.org/fonts/piazzolla500.ttf') format('truetype');font-stretch:normal;}
     236@font-face{font-family:Lobster;font-style:normal;font-weight:400;font-display:fallback;src:url('https://example.org/fonts/lobster400.ttf') format('truetype');font-stretch:normal;}
     237@font-face{font-family:Lobster;font-style:normal;font-weight:500;font-display:fallback;src:url('https://example.org/fonts/lobster500.ttf') format('truetype');font-stretch:normal;}
     238CSS
     239                    ,
     240                ),
    198241            ),
    199242        );
     
    207250            $data = array(
    208251                'fonts'            => array(
    209                     'DM Sans'          => array(
     252                    array(
    210253                        array(
    211254                            'src'          => array( $uri . 'dm-sans/DMSans-Regular.woff2' ),
     
    237280                        ),
    238281                    ),
    239                     'Source Serif Pro' => array(
     282                    array(
    240283                        array(
    241284                            'src'          => array( $uri . 'source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2' ),
     
    272315        return $data;
    273316    }
     317
     318    public static function get_custom_font_families( $key = '' ) {
     319        static $data = null;
     320
     321        $custom_theme_json_fonts = array(
     322            array(
     323                'fontFamily' => 'Piazzolla, serif',
     324                'name'       => 'Piazzolla',
     325                'slug'       => 'piazzolla',
     326                'fontFace'   => array(
     327                    array(
     328                        'fontFamily' => 'Piazzolla',
     329                        'src'        => array( 'https://example.org/fonts/piazzolla400.ttf' ),
     330                        'fontStyle'  => 'normal',
     331                        'fontWeight' => '400',
     332                    ),
     333                    array(
     334                        'fontFamily' => 'Piazzolla',
     335                        'src'        => array( 'https://example.org/fonts/piazzolla500.ttf' ),
     336                        'fontStyle'  => 'normal',
     337                        'fontWeight' => '400',
     338                    ),
     339                ),
     340            ),
     341            array(
     342                'fontFamily' => 'Lobster, sans-serif',
     343                'name'       => 'Lobster',
     344                'slug'       => 'lobster',
     345                'fontFace'   => array(
     346                    array(
     347                        'fontFamily' => 'Lobster',
     348                        'src'        => array( 'https://example.org/fonts/lobster400.ttf' ),
     349                        'fontStyle'  => 'normal',
     350                        'fontWeight' => '400',
     351                    ),
     352                    array(
     353                        'fontFamily' => 'Lobster',
     354                        'src'        => array( 'https://example.org/fonts/lobster500.ttf' ),
     355                        'fontStyle'  => 'normal',
     356                        'fontWeight' => '500',
     357                    ),
     358                ),
     359            ),
     360        );
     361
     362        $expected_font_faces = array(
     363            array(
     364                array(
     365                    'src'         => array( 'https://example.org/fonts/piazzolla400.ttf' ),
     366                    'font-family' => 'Piazzolla',
     367                    'font-style'  => 'normal',
     368                    'font-weight' => '400',
     369                ),
     370                array(
     371                    'src'         => array( 'https://example.org/fonts/piazzolla500.ttf' ),
     372                    'font-family' => 'Piazzolla',
     373                    'font-style'  => 'normal',
     374                    'font-weight' => '400',
     375                ),
     376            ),
     377            array(
     378                array(
     379                    'src'         => array( 'https://example.org/fonts/lobster400.ttf' ),
     380                    'font-family' => 'Lobster',
     381                    'font-style'  => 'normal',
     382                    'font-weight' => '400',
     383                ),
     384                array(
     385                    'src'         => array( 'https://example.org/fonts/lobster500.ttf' ),
     386                    'font-family' => 'Lobster',
     387                    'font-style'  => 'normal',
     388                    'font-weight' => '500',
     389                ),
     390            ),
     391        );
     392
     393        if ( null === $data ) {
     394            $data = array(
     395                'input'    => $custom_theme_json_fonts,
     396                'expected' => $expected_font_faces,
     397            );
     398        }
     399
     400        if ( isset( $data[ $key ] ) ) {
     401            return $data[ $key ];
     402        }
     403
     404        return $data;
     405    }
    274406}
  • trunk/tests/phpunit/tests/fonts/font-face/wpFontFaceResolver/getFontsFromThemeJson.php

    r56688 r57720  
    3939
    4040    /**
     41     * @ticket 60605
     42     */
     43    public function test_should_return_all_fonts_from_all_theme_origins() {
     44        switch_theme( static::FONTS_THEME );
     45
     46        $add_custom_fonts = static function ( $theme_json_data ) {
     47            $data = $theme_json_data->get_data();
     48            // Add font families to the custom origin of theme json.
     49            $data['settings']['typography']['fontFamilies']['custom'] = self::get_custom_font_families( 'input' );
     50            return new WP_Theme_JSON_Data( $data );
     51        };
     52
     53        add_filter( 'wp_theme_json_data_theme', $add_custom_fonts );
     54        $actual = WP_Font_Face_Resolver::get_fonts_from_theme_json();
     55        remove_filter( 'wp_theme_json_data_theme', $add_custom_fonts );
     56
     57        $expected = array_merge(
     58            $this->get_expected_fonts_for_fonts_block_theme( 'fonts' ),
     59            $this->get_custom_font_families( 'expected' )
     60        );
     61
     62        $this->assertSame( $expected, $actual, 'Both the fonts from the theme and the custom origin should be returned.' );
     63    }
     64
     65    /**
    4166     * @dataProvider data_should_replace_src_file_placeholder
    4267     *
    4368     * @param string $font_name  Font's name.
    44      * @param string $font_index Font's index in the $fonts array.
     69     * @param string $font_weight Font's weight.
     70     * @param string $font_style  Font's style.
    4571     * @param string $expected   Expected src.
    4672     */
    47     public function test_should_replace_src_file_placeholder( $font_name, $font_index, $expected ) {
     73    public function test_should_replace_src_file_placeholder( $font_name, $font_weight, $font_style, $expected ) {
    4874        switch_theme( static::FONTS_THEME );
    4975
    5076        $fonts = WP_Font_Face_Resolver::get_fonts_from_theme_json();
    51 
    52         $actual   = $fonts[ $font_name ][ $font_index ]['src'][0];
     77        $fonts = array_merge( array(), ...array_map( 'array_values', $fonts ) );
     78
     79        $font = array_filter(
     80            $fonts,
     81            static function ( $font ) use ( $font_name, $font_weight, $font_style ) {
     82                return $font['font-family'] === $font_name
     83                && $font['font-weight'] === $font_weight
     84                && $font['font-style'] === $font_style;
     85            }
     86        );
     87
     88        $font = reset( $font );
     89
    5390        $expected = get_stylesheet_directory_uri() . $expected;
     91        $actual   = $font['src'][0];
    5492
    5593        $this->assertStringNotContainsString( 'file:./', $actual, 'Font src should not contain the "file:./" placeholder' );
     
    66104            // Theme's theme.json.
    67105            'DM Sans: 400 normal'              => array(
    68                 'font_name'  => 'DM Sans',
    69                 'font_index' => 0,
    70                 'expected'   => '/assets/fonts/dm-sans/DMSans-Regular.woff2',
     106                'font_name'   => 'DM Sans',
     107                'font_weight' => '400',
     108                'font_style'  => 'normal',
     109                'expected'    => '/assets/fonts/dm-sans/DMSans-Regular.woff2',
    71110            ),
    72111            'DM Sans: 400 italic'              => array(
    73                 'font_name'  => 'DM Sans',
    74                 'font_index' => 1,
    75                 'expected'   => '/assets/fonts/dm-sans/DMSans-Regular-Italic.woff2',
     112                'font_name'   => 'DM Sans',
     113                'font_weight' => '400',
     114                'font_style'  => 'italic',
     115                'expected'    => '/assets/fonts/dm-sans/DMSans-Regular-Italic.woff2',
    76116            ),
    77117            'DM Sans: 700 normal'              => array(
    78                 'font_name'  => 'DM Sans',
    79                 'font_index' => 2,
    80                 'expected'   => '/assets/fonts/dm-sans/DMSans-Bold.woff2',
     118                'font_name'   => 'DM Sans',
     119                'font_weight' => '700',
     120                'font_style'  => 'normal',
     121                'expected'    => '/assets/fonts/dm-sans/DMSans-Bold.woff2',
    81122            ),
    82123            'DM Sans: 700 italic'              => array(
    83                 'font_name'  => 'DM Sans',
    84                 'font_index' => 3,
    85                 'expected'   => '/assets/fonts/dm-sans/DMSans-Bold-Italic.woff2',
     124                'font_name'   => 'DM Sans',
     125                'font_weight' => '700',
     126                'font_style'  => 'italic',
     127                'expected'    => '/assets/fonts/dm-sans/DMSans-Bold-Italic.woff2',
    86128            ),
    87129            'Source Serif Pro: 200-900 normal' => array(
    88                 'font_name'  => 'Source Serif Pro',
    89                 'font_index' => 0,
    90                 'expected'   => '/assets/fonts/source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2',
     130                'font_name'   => 'Source Serif Pro',
     131                'font_weight' => '200 900',
     132                'font_style'  => 'normal',
     133                'expected'    => '/assets/fonts/source-serif-pro/SourceSerif4Variable-Roman.ttf.woff2',
    91134            ),
    92135            'Source Serif Pro: 200-900 italic' => array(
    93                 'font_name'  => 'Source Serif Pro',
    94                 'font_index' => 1,
    95                 'expected'   => '/assets/fonts/source-serif-pro/SourceSerif4Variable-Italic.ttf.woff2',
     136                'font_name'   => 'Source Serif Pro',
     137                'font_weight' => '200 900',
     138                'font_style'  => 'italic',
     139                'expected'    => '/assets/fonts/source-serif-pro/SourceSerif4Variable-Italic.ttf.woff2',
    96140            ),
    97141        );
     
    119163        remove_filter( 'wp_theme_json_data_theme', $replace_fonts );
    120164
    121         $this->assertArrayHasKey( $expected_name, $fonts );
     165        // flatten the array to make it easier to test.
     166        $fonts = array_merge( array(), ...array_map( 'array_values', $fonts ) );
     167
     168        $fonts_found = array_filter(
     169            $fonts,
     170            function ( $font ) use ( $expected_name ) {
     171                return $font['font-family'] === $expected_name;
     172            }
     173        );
     174
     175        $this->assertNotEmpty( $fonts_found, 'Expected font-family name not found in the array' );
    122176    }
    123177
Note: See TracChangeset for help on using the changeset viewer.