Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: minor
Type: added

Add functions for enqueueing fonts used in block and global style settings
2 changes: 1 addition & 1 deletion projects/packages/google-fonts-provider/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
"link-template": "https://github.com/Automattic/jetpack-google-fonts-provider/compare/v${old}...v${new}"
},
"branch-alias": {
"dev-master": "0.2.x-dev"
"dev-master": "0.3.x-dev"
},
"textdomain": "jetpack-google-fonts-provider"
}
Expand Down
2 changes: 1 addition & 1 deletion projects/packages/google-fonts-provider/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"private": true,
"name": "@automattic/jetpack-google-fonts-provider",
"version": "0.2.3-alpha",
"version": "0.3.0-alpha",
"description": "WordPress Webfonts provider for Google Fonts",
"homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/packages/google-fonts-provider/#readme",
"bugs": {
Expand Down
23 changes: 23 additions & 0 deletions projects/packages/google-fonts-provider/src/class-utils.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,27 @@ public static function font_source_resource_hint( $urls, $relation_type ) {

return $urls;
}

/**
* Check if a font family is registered (verifying that it can be enqueued).
*
* This function will not be needed if/when WP_Webfonts provides this functionality.
*
* @link https://github.com/WordPress/gutenberg/pull/39988
* @link https://github.com/WordPress/gutenberg/blob/e94fffae0684aa5a6dc370ce3eba262cb77071d9/lib/experimental/class-wp-webfonts.php#L217
*
* @param string $font_family_name Name of font family.
* @return boolean|void Whether the font family is registered, or void if WP_Webfonts is not available.
*/
public static function is_font_family_registered( $font_family_name ) {
if ( ! function_exists( 'wp_webfonts' ) || ! method_exists( 'WP_Webfonts', 'get_font_slug' ) ) {
return;
}

$wp_webfonts = wp_webfonts();

$slug = \WP_Webfonts::get_font_slug( $font_family_name );

return isset( $wp_webfonts->get_registered_webfonts()[ $slug ] );
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php
/**
* Google Fonts package Blocks fonts introspector class file.
*
* @package automattic/jetpack-google-fonts-provider
*/

namespace Automattic\Jetpack\Fonts\Introspectors;

use Automattic\Jetpack\Fonts\Utils;

/**
* Blocks fonts introspector.
*/
class Blocks {
/**
* Enqueue fonts used for block typography settings.
*
* @filter pre_render_block
*
* @param string|null $content The pre-rendered content. Default null.
* @param array $parsed_block The block being rendered.
*/
public static function enqueue_block_fonts( $content, $parsed_block ) {
if ( ! is_admin() && isset( $parsed_block['attrs']['fontFamily'] ) ) {

$block_font_family = $parsed_block['attrs']['fontFamily'];
$font_is_registered = Utils::is_font_family_registered( $block_font_family );

if ( $font_is_registered ) {
wp_enqueue_webfont( $block_font_family );
}
}

return $content;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php
/**
* Google Fonts package Global Styles fonts introspector class file.
*
* @package automattic/jetpack-google-fonts-provider
*/

namespace Automattic\Jetpack\Fonts\Introspectors;

use Automattic\Jetpack\Fonts\Utils;

/**
* Global Styles fonts introspector.
*/
class Global_Styles {
/**
* Enqueue fonts used in global styles settings.
*
* @return void
*/
public static function enqueue_global_styles_fonts() {
if ( is_admin() || ! function_exists( 'wp_enqueue_webfont' ) ) {
Copy link
Contributor

@jeyip jeyip Apr 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-blocking: This might be a silly question, but would you mind explaining the is_admin() condition here? I thought that we wanted to enqueue all fonts in the site editor? I'm assuming that it's already being done elsewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Answering now for posterity (sorry I missed this initially!): this is because the all the fonts are already enqueued in wp-admin views (at least in the editor) by Gutenberg, so there's no need to run this function in that context.

return;
}

$global_styles_fonts = self::collect_fonts_from_global_styles();

foreach ( $global_styles_fonts as $font ) {
$font_is_registered = Utils::is_font_family_registered( $font );

if ( $font_is_registered ) {
wp_enqueue_webfont( $font );
}
}
}

/**
* Collect fonts set in Global Styles settings.
*
* @return array Font faces from Global Styles settings.
*/
public static function collect_fonts_from_global_styles() {
if ( ! function_exists( 'gutenberg_get_global_styles' ) ) {
return array();
}

$global_styles = gutenberg_get_global_styles();

$found_webfonts = array();

// Look for fonts in block presets...
if ( isset( $global_styles['blocks'] ) ) {
foreach ( $global_styles['blocks'] as $setting ) {
$font_slug = self::extract_font_slug_from_setting( $setting );

if ( $font_slug ) {
$found_webfonts[] = $font_slug;
}
}
}

// Look for fonts in HTML element presets...
if ( isset( $global_styles['elements'] ) ) {
foreach ( $global_styles['elements'] as $setting ) {
$font_slug = self::extract_font_slug_from_setting( $setting );

if ( $font_slug ) {
$found_webfonts[] = $font_slug;
}
}
}

// Check if a global typography setting was defined.
$font_slug = self::extract_font_slug_from_setting( $global_styles );

if ( $font_slug ) {
$found_webfonts[] = $font_slug;
}

return $found_webfonts;
}

/**
* Extract the font family slug from a settings array.
*
* @param array $setting The settings object.
*
* @return string|null
*/
protected static function extract_font_slug_from_setting( $setting ) {
if ( ! isset( $setting['typography']['fontFamily'] ) ) {
return null;
}

$font_family = $setting['typography']['fontFamily'];

// Full string: var(--wp--preset--font-family--slug).
// We do not care about the origin of the font, only its slug.
preg_match( '/font-family--(?P<slug>.+)\)$/', $font_family, $matches );

if ( isset( $matches['slug'] ) ) {
return $matches['slug'];
}

// Full string: var:preset|font-family|slug
// We do not care about the origin of the font, only its slug.
preg_match( '/font-family\|(?P<slug>.+)$/', $font_family, $matches );

if ( isset( $matches['slug'] ) ) {
return $matches['slug'];
}

return $font_family;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<?php
/**
* Tests the Blocks fonts introspector.
*
* @package automattic/jetpack-google-fonts-provider
*/

use Automattic\Jetpack\Fonts\Introspectors\Blocks;
use Brain\Monkey;
use Brain\Monkey\Functions;
use PHPUnit\Framework\TestCase;

/**
* Blocks fonts introspector test suite.
*/
class Test_Blocks_Font_Introspector extends TestCase {
/**
* WP_Webfont instance.
*
* @var WP_Webfont
*/
protected $webfonts;

/**
* Test setup.
*
* @before
*/
public function set_up() {
Monkey\setUp();

$this->webfonts = \Mockery::mock( 'WP_Webfonts' );

Functions\stubs(
array(
'is_admin' => false,
'wp_webfonts' => $this->webfonts,
)
);
}

/**
* Test that a font family in block attributes is enqueued.
*/
public function test_enqueues_block_font_when_set() {
$content = 'foo';
$parsed_block = array(
'attrs' => array(
'fontFamily' => 'Roboto',
),
);

$this->webfonts
->shouldReceive( 'get_registered_webfonts' )
->andReturn( array( 'roboto' => array() ) );

Functions\expect( 'wp_enqueue_webfont' )
->once()
->with( 'Roboto' );

$this->assertEquals( $content, Blocks::enqueue_block_fonts( $content, $parsed_block ) );
}

/**
* Test that a block without font settings still returns the filtered content.
*/
public function test_does_not_enqueue_block_font_when_not_set() {
$content = 'foo';
$parsed_block = array();

Functions\expect( 'wp_enqueue_webfont' )
->never();

$this->assertEquals( $content, Blocks::enqueue_block_fonts( $content, $parsed_block ) );
}

/**
* Test teardown.
*
* @after
*/
public function tear_down() {
Monkey\tearDown();
}
}

// phpcs:disable

/**
* Use stub so that method_exists checks will pass.
*
* This will not be needed if/when WP_Webfonts provides a check for
* is_font_family_registered().
*
* @link https://github.com/WordPress/gutenberg/pull/39988
* @link https://github.com/WordPress/gutenberg/blob/e94fffae0684aa5a6dc370ce3eba262cb77071d9/lib/experimental/class-wp-webfonts.php#L217
*/
class WP_Webfonts {
public static function get_font_slug( $font ) {
return strtolower( $font );
}
}
Loading