diff --git a/lib/experimental/add-registered-webfonts-to-theme-json.php b/lib/experimental/add-registered-webfonts-to-theme-json.php index a859b0c1edc036..14039aaa947524 100644 --- a/lib/experimental/add-registered-webfonts-to-theme-json.php +++ b/lib/experimental/add-registered-webfonts-to-theme-json.php @@ -1,10 +1,14 @@ $webfont ) { - if ( gutenberg_is_webfont_equal( $webfont, $webfont_to_find ) ) { + if ( gutenberg_is_webfont_equal( $webfont, $webfont_to_find, $is_camel_case ) ) { return $index; } } diff --git a/lib/experimental/class-wp-webfonts.php b/lib/experimental/class-wp-webfonts.php index d4a73c77cc2d2d..e1cb151075377b 100644 --- a/lib/experimental/class-wp-webfonts.php +++ b/lib/experimental/class-wp-webfonts.php @@ -145,13 +145,14 @@ public function register_webfont( array $webfont ) { /** * Enqueue a font-family that has been already registered. * - * @param string $font_family_name The font family name to be enqueued. + * @param string $font_family_name The font family name to be enqueued. + * @param array|null $font_face The font face to selectively enqueue. * @return bool True if successfully enqueued, else false. */ - public function enqueue_webfont( $font_family_name ) { + public function enqueue_webfont( $font_family_name, $font_face = null ) { $slug = $this->get_font_slug( $font_family_name ); - if ( isset( $this->enqueued_webfonts[ $slug ] ) ) { + if ( isset( $this->enqueued_webfonts[ $slug ] ) && ! isset( $this->registered_webfonts[ $slug ] ) ) { trigger_error( sprintf( /* translators: %s unique slug to identify the font family of the webfont */ @@ -170,11 +171,50 @@ public function enqueue_webfont( $font_family_name ) { return false; } - $this->enqueued_webfonts[ $slug ] = $this->registered_webfonts[ $slug ]; - unset( $this->registered_webfonts[ $slug ] ); + if ( ! $font_face ) { + $font_family_to_enqueue = $this->unregister_font_family( $font_family_name ); + $this->enqueued_webfonts[ $slug ] = $font_family_to_enqueue; + + return true; + } + + $font_face = gutenberg_webfont_to_kebab_case( $font_face ); + $font_face_to_enqueue = $this->unregister_font_face( $font_face ); + + if ( ! $font_face_to_enqueue ) { + trigger_error( + sprintf( + __( 'The "%1$s:%2$s:%3$s" font face is not registered.', 'gutenberg' ), + $font_face['font-family'], + $font_face['font-weight'], + $font_face['font-style'] + ) + ); + + return false; + } + + if ( ! isset( $this->enqueued_webfonts[ $slug ] ) ) { + $this->enqueued_webfonts[ $slug ] = array(); + } + + $this->enqueued_webfonts[ $slug ][] = $font_face_to_enqueue; + return true; } + /** + * Checks if a font family is registered. + * + * @param string $font_family_name The font family name to check in the registry. + * @return bool True if found, else false. + */ + public function is_font_family_registered( $font_family_name ) { + $slug = $this->get_font_slug( $font_family_name ); + + return isset( $this->registered_webfonts[ $slug ] ); + } + /** * Get the font slug. * @@ -199,6 +239,41 @@ public static function get_font_slug( $to_convert ) { return sanitize_title( $to_convert ); } + public function unregister_font_family( $font_family_name ) { + $slug = $this->get_font_slug( $font_family_name ); + + if ( ! isset( $this->registered_webfonts[ $slug ] ) ) { + return false; + } + + $font_family = $this->registered_webfonts[ $slug ]; + unset( $this->registered_webfonts[ $slug ] ); + + return $font_family; + } + + public function unregister_font_face( $font_face_to_unregister ) { + $font_family_slug = $this->get_font_slug( $font_face_to_unregister ); + + $font_family = $this->registered_webfonts[ $font_family_slug ]; + $index = gutenberg_find_webfont( $font_family, $font_face_to_unregister ); + + // Font face not found. + if ( false === $index ) { + return false; + } + + $font_face = $this->registered_webfonts[ $font_family_slug ][ $index ]; + unset( $this->registered_webfonts[ $font_family_slug ][ $index ] ); + + // No font faces left, let's remove the font family entry. + if ( 0 === count( $this->registered_webfonts[ $font_family_slug ] ) ) { + unset( $this->registered_webfonts[ $font_family_slug ] ); + } + + return $font_face; + } + /** * Validate a webfont. * diff --git a/lib/experimental/enqueue-webfonts-listed-in-theme-json.php b/lib/experimental/enqueue-webfonts-listed-in-theme-json.php new file mode 100644 index 00000000000000..e067ebe796164c --- /dev/null +++ b/lib/experimental/enqueue-webfonts-listed-in-theme-json.php @@ -0,0 +1,56 @@ +get_settings(); + + // Bail out early if there are no settings for webfonts. + if ( empty( $theme_settings['typography'] ) || empty( $theme_settings['typography']['fontFamilies'] ) ) { + return; + } + + // Look for fontFamilies. + foreach ( $theme_settings['typography']['fontFamilies'] as $font_families ) { + foreach ( $font_families as $font_family ) { + // Skip dynamically included font families. We only want to enqueue explicitly added fonts. + if ( gutenberg_is_externally_registered_webfont( $font_family ) ) { + continue; + } + + // If no font faces defined. + if ( ! isset( $font_family['fontFaces'] ) ) { + // And the font family is registered. + if ( ! wp_webfonts()->is_font_family_registered( $font_family['fontFamily'] ) ) { + continue; + } + + // Enqueue the entire family. + wp_webfonts()->enqueue_webfont( $font_family ); + continue; + } + + // Loop through all the font faces, enqueueing each one of them. + foreach ( $font_family['fontFaces'] as $font_face ) { + // Skip dynamically included font faces. We only want to enqueue the font faces listed in theme.json. + if ( gutenberg_is_externally_registered_webfont( $font_face ) ) { + continue; + } + + wp_webfonts()->enqueue_webfont( $font_family, $font_face ); + } + } + } +} + +add_filter( 'wp_loaded', 'gutenberg_enqueue_webfonts_listed_in_theme_json' ); + +// No need to run this -- opening the admin interface enqueues all the webfonts. +add_action( + 'admin_init', + function() { + remove_filter( 'wp_loaded', 'gutenberg_enqueue_webfonts_listed_in_theme_json' ); + } +); diff --git a/lib/load.php b/lib/load.php index 568a00a63e0f77..2a45026fca7a42 100644 --- a/lib/load.php +++ b/lib/load.php @@ -109,6 +109,7 @@ function gutenberg_is_experiment_enabled( $name ) { require __DIR__ . '/compat/wordpress-6.0/edit-form-blocks.php'; require __DIR__ . '/experimental/register-webfonts-from-theme-json.php'; require __DIR__ . '/experimental/add-registered-webfonts-to-theme-json.php'; +require __DIR__ . '/experimental/enqueue-webfonts-listed-in-theme-json.php'; require __DIR__ . '/experimental/class-wp-theme-json-resolver-gutenberg.php'; require __DIR__ . '/experimental/class-wp-webfonts.php'; require __DIR__ . '/experimental/class-wp-webfonts-provider.php';