Skip to content

Commit

Permalink
Enqueue webfonts listed in theme.json
Browse files Browse the repository at this point in the history
  • Loading branch information
zaguiini committed Apr 5, 2022
1 parent d9a25f6 commit 12d41f8
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 8 deletions.
16 changes: 13 additions & 3 deletions lib/experimental/add-registered-webfonts-to-theme-json.php
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
<?php

function gutenberg_is_webfont_equal( $a, $b ) {
$equality_attrs = array(
function gutenberg_is_webfont_equal( $a, $b, $is_camel_case = true ) {
$equality_attrs = $is_camel_case ? array(
'fontFamily',
'fontStyle',
'fontWeight',
) : array(
'font-family',
'font-style',
'font-weight',
);

foreach ( $equality_attrs as $attr ) {
Expand All @@ -17,8 +21,14 @@ function gutenberg_is_webfont_equal( $a, $b ) {
}

function gutenberg_find_webfont( $webfonts, $webfont_to_find ) {
if ( ! count( $webfonts ) ) {
return false;
}

$is_camel_case = isset( $webfonts[0]['fontFamily'] );

foreach ( $webfonts as $index => $webfont ) {
if ( gutenberg_is_webfont_equal( $webfont, $webfont_to_find ) ) {
if ( gutenberg_is_webfont_equal( $webfont, $webfont_to_find, $is_camel_case ) ) {
return $index;
}
}
Expand Down
85 changes: 80 additions & 5 deletions lib/experimental/class-wp-webfonts.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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.
*
Expand All @@ -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.
*
Expand Down
56 changes: 56 additions & 0 deletions lib/experimental/enqueue-webfonts-listed-in-theme-json.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

function gutenberg_is_externally_registered_webfont( $webfont ) {
return isset( $webfont['origin'] ) && 'gutenberg_wp_webfonts_api' === $webfont['origin'];
}

function gutenberg_enqueue_webfonts_listed_in_theme_json() {
$theme_settings = WP_Theme_JSON_Resolver_Gutenberg::get_theme_data()->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' );
}
);
1 change: 1 addition & 0 deletions lib/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down

0 comments on commit 12d41f8

Please sign in to comment.