Skip to content

Commit

Permalink
Backport Core changeset 56500
Browse files Browse the repository at this point in the history
  • Loading branch information
hellofromtonya committed Sep 6, 2023
1 parent 56a48fb commit 2c3c729
Show file tree
Hide file tree
Showing 9 changed files with 194 additions and 190 deletions.
82 changes: 82 additions & 0 deletions lib/compat/wordpress-6.4/fonts.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php
/**
* Fonts functions.
*
* @package WordPress
* @subpackage Fonts
* @since 6.4.0
*
* @core-merge: this file is located in `wp-includes/fonts.php`. It will contain Font Face and Font Library functions.
*/

if ( ! function_exists( 'wp_print_font_faces' ) ) {
// @core-merge: will merge into Core's `wp-includes/default-filters.php` file.
add_action( 'wp_head', 'wp_print_font_faces', 50 );
// @core-merge: will merge into Core's `wp-admin/includes/admin-filters.php.` file.
add_action( 'admin_print_styles', 'wp_print_font_faces', 50 );

/**
* Generates and prints font-face styles for given fonts or theme.json fonts.
*
* @since 6.4.0
*
* @param array[][] $fonts {
* Optional. The font-families and their font variations. Default empty array.
*
* @type string $font-family => array[] $variations {
* Optional. An associated array of font variations for this font-family.
* Each variation has the following structure.
*
* @type array $font_variation {
* @type string $font-family The font-family property.
* @type string|string[] $src The URL(s) to each resource containing the font data.
* @type string $font_style Optional. The font-style property. Default 'normal'.
* @type string $font-weight Optional. The font-weight property. Default '400'.
* @type string $font-display Optional. The font-display property. Default 'fallback'.
* @type string $ascent-override Optional. The ascent-override property.
* @type string $descent-override Optional. The descent-override property.
* @type string $font-stretch Optional. The font-stretch property.
* @type string $font-variant Optional. The font-variant property.
* @type string $font-feature-settings Optional. The font-feature-settings property.
* @type string $font-variation-settings Optional. The font-variation-settings property.
* @type string $line-gap-override Optional. The line-gap-override property.
* @type string $size-adjust Optional. The size-adjust property.
* @type string $unicode-range Optional. The unicode-range property.
* }
* }
* }
*/
function wp_print_font_faces( $fonts = array() ) {
static $wp_font_face = null;

if ( empty( $fonts ) ) {
$fonts = WP_Font_Face_Resolver::get_fonts_from_theme_json();
}

if ( empty( $fonts ) ) {
return;
}

if ( null === $wp_font_face ) {
$wp_font_face = new WP_Font_Face();
}

$wp_font_face->generate_and_print( $fonts );
}

// @core-merge: do not merge this code into Core.
add_filter(
'block_editor_settings_all',
static function( $settings ) {
ob_start();
// @core-merge: add only this line into Core's `_wp_get_iframed_editor_assets()` function after `wp_print_styles()`.
wp_print_font_faces();
$styles = ob_get_clean();

// Add the font-face styles to iframed editor assets.
$settings['__unstableResolvedAssets']['styles'] .= $styles;
return $settings;
},
11
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ class WP_Font_Face_Resolver {
* @return array Returns the font-families, each with their font-face variations.
*/
public static function get_fonts_from_theme_json() {
// @core-merge: replace with wp_get_global_settings().
$settings = gutenberg_get_global_settings();

// Bail out early if there are no font settings.
if ( empty( $settings['typography'] ) || empty( $settings['typography']['fontFamilies'] ) ) {
if ( empty( $settings['typography']['fontFamilies'] ) ) {
return array();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,23 +82,6 @@ class WP_Font_Face {
* @since 6.4.0
*/
public function __construct() {
/**
* Filters the font-face property defaults.
*
* @since 6.4.0
*
* @param array $defaults {
* An array of required font-face properties and defaults.
*
* @type string $provider The provider ID. Default 'local'.
* @type string $font-family The font-family property. Default empty string.
* @type string $font-style The font-style property. Default 'normal'.
* @type string $font-weight The font-weight property. Default '400'.
* @type string $font-display The font-display property. Default 'fallback'.
* }
*/
$this->font_face_property_defaults = apply_filters( 'wp_font_face_property_defaults', $this->font_face_property_defaults );

if (
function_exists( 'is_admin' ) && ! is_admin()
&&
Expand All @@ -113,7 +96,9 @@ function_exists( 'current_theme_supports' ) && ! current_theme_supports( 'html5'
*
* @since 6.4.0
*
* @param array $fonts The fonts to generate and print @font-face styles.
* @param array[][] $fonts Optional. The font-families and their font variations.
* See {@see wp_print_font_faces()} for the supported fields.
* Default empty array.
*/
public function generate_and_print( array $fonts ) {
$fonts = $this->validate_fonts( $fonts );
Expand All @@ -123,10 +108,21 @@ public function generate_and_print( array $fonts ) {
return;
}

printf(
$this->get_style_element(),
$this->get_css( $fonts )
);
$css = $this->get_css( $fonts );

/*
* The font-face CSS is contained within <style> tags and can only be interpreted
* as CSS in the browser. Using wp_strip_all_tags() is sufficient escaping
* to avoid malicious attempts to close </style> and open a <script>.
*/
$css = wp_strip_all_tags( $css );

// Bail out if there is no CSS to print.
if ( empty( $css ) ) {
return;
}

printf( $this->get_style_element(), $css );
}

/**
Expand All @@ -142,7 +138,7 @@ private function validate_fonts( array $fonts ) {

foreach ( $fonts as $font_faces ) {
foreach ( $font_faces as $font_face ) {
$font_face = $this->validate_font_face_properties( $font_face );
$font_face = $this->validate_font_face_declarations( $font_face );
// Skip if failed validation.
if ( false === $font_face ) {
continue;
Expand All @@ -156,41 +152,59 @@ private function validate_fonts( array $fonts ) {
}

/**
* Validates each font-face property.
* Validates each font-face declaration (property and value pairing).
*
* @since 6.4.0
*
* @param array $font_face Font face properties to validate.
* @return false|array Validated font-face on success. Else, false.
* @param array $font_face Font face property and value pairings to validate.
* @return array|false Validated font-face on success, or false on failure.
*/
private function validate_font_face_properties( array $font_face ) {
private function validate_font_face_declarations( array $font_face ) {
$font_face = wp_parse_args( $font_face, $this->font_face_property_defaults );

// Check the font-family.
if ( empty( $font_face['font-family'] ) || ! is_string( $font_face['font-family'] ) ) {
trigger_error( 'Font font-family must be a non-empty string.' );
// @todo replace with `wp_trigger_error()`.
_doing_it_wrong(
__METHOD__,
__( 'Font font-family must be a non-empty string.' ),
'6.4.0'
);
return false;
}

// Make sure that local fonts have 'src' defined.
if ( empty( $font_face['src'] ) || ( ! is_string( $font_face['src'] ) && ! is_array( $font_face['src'] ) ) ) {
trigger_error( 'Font src must be a non-empty string or an array of strings.' );
// @todo replace with `wp_trigger_error()`.
_doing_it_wrong(
__METHOD__,
__( 'Font src must be a non-empty string or an array of strings.' ),
'6.4.0'
);
return false;
}

// Validate the 'src' property.
if ( ! empty( $font_face['src'] ) ) {
foreach ( (array) $font_face['src'] as $src ) {
if ( empty( $src ) || ! is_string( $src ) ) {
trigger_error( 'Each font src must be a non-empty string.' );
return false;
}
foreach ( (array) $font_face['src'] as $src ) {
if ( empty( $src ) || ! is_string( $src ) ) {
// @todo replace with `wp_trigger_error()`.
_doing_it_wrong(
__METHOD__,
__( 'Each font src must be a non-empty string.' ),
'6.4.0'
);
return false;
}
}

// Check the font-weight.
if ( ! is_string( $font_face['font-weight'] ) && ! is_int( $font_face['font-weight'] ) ) {
trigger_error( 'Font font-weight must be a properly formatted string or integer.' );
// @todo replace with `wp_trigger_error()`.
_doing_it_wrong(
__METHOD__,
__( 'Font font-weight must be a properly formatted string or integer.' ),
'6.4.0'
);
return false;
}

Expand All @@ -200,17 +214,17 @@ private function validate_font_face_properties( array $font_face ) {
}

// Remove invalid properties.
foreach ( $font_face as $prop => $value ) {
if ( ! in_array( $prop, $this->valid_font_face_properties, true ) ) {
unset( $font_face[ $prop ] );
foreach ( $font_face as $property => $value ) {
if ( ! in_array( $property, $this->valid_font_face_properties, true ) ) {
unset( $font_face[ $property ] );
}
}

return $font_face;
}

/**
* Gets the `<style>` element for wrapping the `@font-face` CSS.
* Gets the style element for wrapping the `@font-face` CSS.
*
* @since 6.4.0
*
Expand Down Expand Up @@ -348,8 +362,10 @@ private function order_src( array $font_face ) {
private function build_font_face_css( array $font_face ) {
$css = '';

// Wrap font-family in quotes if it contains spaces
// and is not already wrapped in quotes.
/*
* Wrap font-family in quotes if it contains spaces
* and is not already wrapped in quotes.
*/
if (
str_contains( $font_face['font-family'], ' ' ) &&
! str_contains( $font_face['font-family'], '"' ) &&
Expand Down
62 changes: 0 additions & 62 deletions lib/compat/wordpress-6.4/fonts/fonts.php

This file was deleted.

10 changes: 6 additions & 4 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,9 @@ function gutenberg_is_experiment_enabled( $name ) {

// Load the Font Face.
if ( ! class_exists( 'WP_Font_Face' ) ) {
require __DIR__ . '/compat/wordpress-6.4/fonts/font-face/class-wp-font-face.php';
require __DIR__ . '/compat/wordpress-6.4/fonts/font-face/class-wp-font-face-resolver.php';
require __DIR__ . '/compat/wordpress-6.4/fonts/fonts.php';
require __DIR__ . '/compat/wordpress-6.4/fonts/class-wp-font-face.php';
require __DIR__ . '/compat/wordpress-6.4/fonts/class-wp-font-face-resolver.php';
require __DIR__ . '/compat/wordpress-6.4/fonts.php';
}

// Load the BC Layer to avoid fatal errors of extenders using the Fonts API.
Expand All @@ -170,6 +170,8 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/experimental/fonts/font-face/bc-layer/class-wp-webfonts.php';
require __DIR__ . '/experimental/fonts/font-face/bc-layer/class-wp-web-fonts.php';
} elseif ( ! class_exists( 'WP_Fonts' ) ) {
// @core-merge: do not merge these files into WordPress Core.

// Turns off Font Face hooks in Core.
// @since 6.4.0.
remove_action( 'wp_head', 'wp_print_font_faces', 50 );
Expand All @@ -183,7 +185,7 @@ function gutenberg_is_experiment_enabled( $name ) {
require __DIR__ . '/experimental/fonts-api/class-wp-fonts-resolver.php';
require __DIR__ . '/experimental/fonts-api/fonts-api.php';

// BC Layer files, which will not be backported to WP Core.
// BC Layer files.
require __DIR__ . '/experimental/fonts-api/bc-layer/class-gutenberg-fonts-api-bc-layer.php';
require __DIR__ . '/experimental/fonts-api/bc-layer/webfonts-deprecations.php';
require __DIR__ . '/experimental/fonts-api/bc-layer/class-wp-webfonts-utils.php';
Expand Down
Loading

0 comments on commit 2c3c729

Please sign in to comment.