From 2e6622c3c7f93758e6f6ab69b883260a7de76a4d Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Thu, 12 Aug 2021 13:07:20 -0700 Subject: [PATCH 1/6] [not verified] --- projects/plugins/jetpack/extensions/editor.js | 1 + .../dynamically-load-google-font-files.js | 114 ++++++++++++++++++ .../global-styles/global-styles.php | 81 +++++++++++++ .../extended-blocks/global-styles/index.js | 1 + 4 files changed, 197 insertions(+) create mode 100644 projects/plugins/jetpack/extensions/extended-blocks/global-styles/dynamically-load-google-font-files.js create mode 100644 projects/plugins/jetpack/extensions/extended-blocks/global-styles/global-styles.php create mode 100644 projects/plugins/jetpack/extensions/extended-blocks/global-styles/index.js diff --git a/projects/plugins/jetpack/extensions/editor.js b/projects/plugins/jetpack/extensions/editor.js index f1ad01d6a2d59..88bbde2024e6e 100644 --- a/projects/plugins/jetpack/extensions/editor.js +++ b/projects/plugins/jetpack/extensions/editor.js @@ -10,6 +10,7 @@ import './extended-blocks/core-embed'; import './extended-blocks/paid-blocks'; import './shared/styles/slideshow-fix.scss'; import './shared/styles/external-link-fix.scss'; +import './extended-blocks/global-styles'; // Register media source store to the centralized data registry. import './store/media-source'; diff --git a/projects/plugins/jetpack/extensions/extended-blocks/global-styles/dynamically-load-google-font-files.js b/projects/plugins/jetpack/extensions/extended-blocks/global-styles/dynamically-load-google-font-files.js new file mode 100644 index 0000000000000..ac27442568d91 --- /dev/null +++ b/projects/plugins/jetpack/extensions/extended-blocks/global-styles/dynamically-load-google-font-files.js @@ -0,0 +1,114 @@ +/* eslint-disable no-undef */ + +const VALID_GOOGLE_FONTS = [ + 'Bodoni Moda', + 'Cabin', + 'Chivo', + 'Courier Prime', + 'EB Garamond', + 'Fira Sans', + 'Josefin Sans', + 'Libre Baskerville', + 'Libre Franklin', + 'Lora', + 'Merriweather', + 'Montserrat', + 'Nunito', + 'Open Sans', + 'Overpass', + 'Playfair Display', + 'Poppins', + 'Raleway', + 'Roboto', + 'Roboto Slab', + 'Rubik', + 'Source Sans Pro', + 'Source Serif Pro', + 'Space Mono', + 'Work Sans', +]; + +// TODO: Stylesheets not being added properly to editor +function addGoogleFontStylesheet( url ) { + // Generate stylesheet link tag + const link = document.createElement( 'link' ); + link.rel = 'stylesheet'; + link.href = url; + + // Add google font import stylesheet to Gutenberg canvas + const iframe = document.querySelector( 'iframe[name="editor-canvas"]' ); + iframe.contentWindow.document.getElementsByTagName( 'head' )[ 0 ].appendChild( link ); +} + +const isEditorReadyWithBlocks = async () => { + return new Promise( ( resolve, reject ) => { + if ( wp && wp.data && wp.data.select && wp.data.subscribe ) { + const unsubscribe = wp.data.subscribe( () => { + const isCleanNewPost = wp.data.select( 'core/editor' ).isCleanNewPost(); + + if ( isCleanNewPost ) { + unsubscribe(); + resolve( false ); + } + + const blocks = wp.data.select( 'core/editor' ).getBlocks(); + + if ( blocks.length > 0 ) { + unsubscribe(); + resolve( true ); + } + } ); + } else { + reject( false ); + } + } ); +}; + +// When a google font is selected in the global styles site editor sidebar, its +// font face declarations and font files will be dynamically imported +( function () { + $( document ).ready( async function () { + await isEditorReadyWithBlocks(); + + // Prevents re-fetching google fonts that have already been requested + // during the session + const cache = []; + + // Monitor wp-data for updates to the global styles and selected fontFamily + wp.data.subscribe( function () { + const settings = wp.data.select( 'core/edit-site' ).getSettings(); + let globalStylesCSSDeclarations = ''; + if ( settings.styles ) { + globalStylesCSSDeclarations = settings.styles.reduce( function ( acc, style ) { + return style.isGlobalStyles && ! style.__experimentalNoWrapper ? style.css : acc; + }, '' ); + } + + if ( globalStylesCSSDeclarations ) { + // Retrieve information about selected font family from serialized data + const fontFamilySlug = globalStylesCSSDeclarations.match( + /font-family: var\(--wp--preset--font-family--(.*?)(?=\);)/ + ); + const fontFamilyName = + fontFamilySlug && + fontFamilySlug[ 1 ] + .split( '-' ) + .map( function ( word ) { + return word[ 0 ].toUpperCase() + word.substring( 1 ); + } ) + .join( ' ' ); + + // Fetch google font files for selected font + if ( VALID_GOOGLE_FONTS.includes( fontFamilyName ) ) { + if ( ! cache.includes( fontFamilyName ) ) { + cache.push( fontFamilyName ); + const encodedFontName = fontFamilyName.replace( ' ', '+' ); + addGoogleFontStylesheet( + `https://fonts.googleapis.com/css?family=${ encodedFontName }:regular,bold,italic,bolditalic|` + ); + } + } + } + } ); + } ); +} )( jQuery ); diff --git a/projects/plugins/jetpack/extensions/extended-blocks/global-styles/global-styles.php b/projects/plugins/jetpack/extensions/extended-blocks/global-styles/global-styles.php new file mode 100644 index 0000000000000..dbd15353c5a90 --- /dev/null +++ b/projects/plugins/jetpack/extensions/extended-blocks/global-styles/global-styles.php @@ -0,0 +1,81 @@ +id ) && + WP_Theme_JSON_Resolver_Gutenberg::theme_has_support() && + gutenberg_supports_block_templates(); + + if ( $should_use_site_editor_context ) { + // Add google fonts as selectable options to the global styles font family picker. + $google_font_options = array_map( + function ( $font_name ) { + return array( + 'fontFamily' => $font_name, + 'slug' => str_replace( ' ', '-', strtolower( $font_name ) ), + 'name' => $font_name, + ); + }, + valid_google_fonts() + ); + + if ( isset( $settings['__experimentalGlobalStylesBaseStyles']['settings']['typography']['fontFamilies'] ) ) { + $settings['__experimentalGlobalStylesBaseStyles']['settings']['typography']['fontFamilies']['theme'] = array_merge( + $settings['__experimentalGlobalStylesBaseStyles']['settings']['typography']['fontFamilies']['theme'], + $google_font_options + ); + } + } + + return $settings; +} + +if ( function_exists( 'get_block_editor_settings' ) ) { + add_filter( 'block_editor_settings_all', 'gutenberg_wpcom_add_google_fonts_to_site_editor', PHP_INT_MAX ); +} else { + add_filter( 'block_editor_settings', 'gutenberg_wpcom_add_google_fonts_to_site_editor', PHP_INT_MAX ); +} diff --git a/projects/plugins/jetpack/extensions/extended-blocks/global-styles/index.js b/projects/plugins/jetpack/extensions/extended-blocks/global-styles/index.js new file mode 100644 index 0000000000000..45069d7c6f251 --- /dev/null +++ b/projects/plugins/jetpack/extensions/extended-blocks/global-styles/index.js @@ -0,0 +1 @@ +import './dynamically-load-google-font-files'; From c7574ce8870284df03bc6bf1b879d6df4eff1e7f Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Thu, 12 Aug 2021 16:09:35 -0700 Subject: [PATCH 2/6] Remove jQuery dependency --- .../dynamically-load-google-font-files.js | 76 +++++++++---------- 1 file changed, 37 insertions(+), 39 deletions(-) diff --git a/projects/plugins/jetpack/extensions/extended-blocks/global-styles/dynamically-load-google-font-files.js b/projects/plugins/jetpack/extensions/extended-blocks/global-styles/dynamically-load-google-font-files.js index ac27442568d91..e7be86bcc09c3 100644 --- a/projects/plugins/jetpack/extensions/extended-blocks/global-styles/dynamically-load-google-font-files.js +++ b/projects/plugins/jetpack/extensions/extended-blocks/global-styles/dynamically-load-google-font-files.js @@ -66,49 +66,47 @@ const isEditorReadyWithBlocks = async () => { // When a google font is selected in the global styles site editor sidebar, its // font face declarations and font files will be dynamically imported -( function () { - $( document ).ready( async function () { - await isEditorReadyWithBlocks(); +( async function () { + await isEditorReadyWithBlocks(); - // Prevents re-fetching google fonts that have already been requested - // during the session - const cache = []; + // Prevents re-fetching google fonts that have already been requested + // during the session + const cache = []; - // Monitor wp-data for updates to the global styles and selected fontFamily - wp.data.subscribe( function () { - const settings = wp.data.select( 'core/edit-site' ).getSettings(); - let globalStylesCSSDeclarations = ''; - if ( settings.styles ) { - globalStylesCSSDeclarations = settings.styles.reduce( function ( acc, style ) { - return style.isGlobalStyles && ! style.__experimentalNoWrapper ? style.css : acc; - }, '' ); - } + // Monitor wp-data for updates to the global styles and selected fontFamily + wp.data.subscribe( function () { + const settings = wp.data.select( 'core/edit-site' ).getSettings(); + let globalStylesCSSDeclarations = ''; + if ( settings.styles ) { + globalStylesCSSDeclarations = settings.styles.reduce( function ( acc, style ) { + return style.isGlobalStyles && ! style.__experimentalNoWrapper ? style.css : acc; + }, '' ); + } - if ( globalStylesCSSDeclarations ) { - // Retrieve information about selected font family from serialized data - const fontFamilySlug = globalStylesCSSDeclarations.match( - /font-family: var\(--wp--preset--font-family--(.*?)(?=\);)/ - ); - const fontFamilyName = - fontFamilySlug && - fontFamilySlug[ 1 ] - .split( '-' ) - .map( function ( word ) { - return word[ 0 ].toUpperCase() + word.substring( 1 ); - } ) - .join( ' ' ); + if ( globalStylesCSSDeclarations ) { + // Retrieve information about selected font family from serialized data + const fontFamilySlug = globalStylesCSSDeclarations.match( + /font-family: var\(--wp--preset--font-family--(.*?)(?=\);)/ + ); + const fontFamilyName = + fontFamilySlug && + fontFamilySlug[ 1 ] + .split( '-' ) + .map( function ( word ) { + return word[ 0 ].toUpperCase() + word.substring( 1 ); + } ) + .join( ' ' ); - // Fetch google font files for selected font - if ( VALID_GOOGLE_FONTS.includes( fontFamilyName ) ) { - if ( ! cache.includes( fontFamilyName ) ) { - cache.push( fontFamilyName ); - const encodedFontName = fontFamilyName.replace( ' ', '+' ); - addGoogleFontStylesheet( - `https://fonts.googleapis.com/css?family=${ encodedFontName }:regular,bold,italic,bolditalic|` - ); - } + // Fetch google font files for selected font + if ( VALID_GOOGLE_FONTS.includes( fontFamilyName ) ) { + if ( ! cache.includes( fontFamilyName ) ) { + cache.push( fontFamilyName ); + const encodedFontName = fontFamilyName.replace( ' ', '+' ); + addGoogleFontStylesheet( + `https://fonts.googleapis.com/css?family=${ encodedFontName }:regular,bold,italic,bolditalic|` + ); } } - } ); + } } ); -} )( jQuery ); +} )(); From 18bf08f3ac0dc6f371307abff86fb2c7ab5d3108 Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Thu, 12 Aug 2021 16:12:10 -0700 Subject: [PATCH 3/6] Add changelog --- .../changelog/add-google-fonts-support-gutenberg-extension | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 projects/plugins/jetpack/changelog/add-google-fonts-support-gutenberg-extension diff --git a/projects/plugins/jetpack/changelog/add-google-fonts-support-gutenberg-extension b/projects/plugins/jetpack/changelog/add-google-fonts-support-gutenberg-extension new file mode 100644 index 0000000000000..39acda215b3d9 --- /dev/null +++ b/projects/plugins/jetpack/changelog/add-google-fonts-support-gutenberg-extension @@ -0,0 +1,4 @@ +Significance: minor +Type: enhancement + +Implement support for google fonts in the site editor's global styles feature From 62eb61eafbc11414c350a3fedd82c8f4a58d82ce Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Fri, 13 Aug 2021 11:58:41 -0700 Subject: [PATCH 4/6] Update documentation --- .../add-google-fonts-support-gutenberg-extension | 2 +- .../dynamically-load-google-font-files.js | 1 - .../extended-blocks/global-styles/global-styles.php | 10 +++++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/projects/plugins/jetpack/changelog/add-google-fonts-support-gutenberg-extension b/projects/plugins/jetpack/changelog/add-google-fonts-support-gutenberg-extension index 39acda215b3d9..774f5f21538cc 100644 --- a/projects/plugins/jetpack/changelog/add-google-fonts-support-gutenberg-extension +++ b/projects/plugins/jetpack/changelog/add-google-fonts-support-gutenberg-extension @@ -1,4 +1,4 @@ Significance: minor Type: enhancement -Implement support for google fonts in the site editor's global styles feature +Gutenberg Extensions: add support for google fonts in the site editor's global styles feature diff --git a/projects/plugins/jetpack/extensions/extended-blocks/global-styles/dynamically-load-google-font-files.js b/projects/plugins/jetpack/extensions/extended-blocks/global-styles/dynamically-load-google-font-files.js index e7be86bcc09c3..d7af4cf8d4d61 100644 --- a/projects/plugins/jetpack/extensions/extended-blocks/global-styles/dynamically-load-google-font-files.js +++ b/projects/plugins/jetpack/extensions/extended-blocks/global-styles/dynamically-load-google-font-files.js @@ -28,7 +28,6 @@ const VALID_GOOGLE_FONTS = [ 'Work Sans', ]; -// TODO: Stylesheets not being added properly to editor function addGoogleFontStylesheet( url ) { // Generate stylesheet link tag const link = document.createElement( 'link' ); diff --git a/projects/plugins/jetpack/extensions/extended-blocks/global-styles/global-styles.php b/projects/plugins/jetpack/extensions/extended-blocks/global-styles/global-styles.php index dbd15353c5a90..3fd2561156f6d 100644 --- a/projects/plugins/jetpack/extensions/extended-blocks/global-styles/global-styles.php +++ b/projects/plugins/jetpack/extensions/extended-blocks/global-styles/global-styles.php @@ -1,4 +1,9 @@ Date: Fri, 13 Aug 2021 15:31:49 -0700 Subject: [PATCH 5/6] Support google fonts in frontend --- .../global-styles/global-styles.php | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/projects/plugins/jetpack/extensions/extended-blocks/global-styles/global-styles.php b/projects/plugins/jetpack/extensions/extended-blocks/global-styles/global-styles.php index 3fd2561156f6d..b3fd35810b600 100644 --- a/projects/plugins/jetpack/extensions/extended-blocks/global-styles/global-styles.php +++ b/projects/plugins/jetpack/extensions/extended-blocks/global-styles/global-styles.php @@ -87,3 +87,65 @@ function ( $font_name ) { } else { add_filter( 'block_editor_settings', 'gutenberg_wpcom_add_google_fonts_to_site_editor', PHP_INT_MAX ); } + +/** + * Add a server-side action that applies google fonts selected in the global styles site + * edtor sidebar to frontend styles. + * + * This function can be updated or removed when core Gutenberg provides more specific hooks + * for global styles. + * + * @see https://github.com/WordPress/gutenberg/issues/27504 + * + * @return void + */ +function gutenberg_wpcom_google_fonts_enqueue_assets() { + $global_styles_user_data = WP_Theme_JSON_Resolver_Gutenberg::get_user_data()->get_raw_data(); + + if ( isset( $global_styles_user_data['styles'] ) && isset( $global_styles_user_data['styles']['typography'] ) ) { + // 1. Determine if a google font was selected for site editor global styles + $user_selected_font_family = $global_styles_user_data['styles']['typography']['fontFamily']; + foreach ( valid_google_fonts() as $font_name ) { + $font_slug = str_replace( ' ', '-', strtolower( $font_name ) ); + if ( strpos( $user_selected_font_family, $font_slug ) ) { + $google_font_name = $font_name; + $google_font_slug = $font_slug; + break; + } + } + + if ( $google_font_name && $google_font_slug ) { + // 2. Generate formatted style declarations for the selected google font + $google_font_settings_theme_json = new WP_Theme_JSON_Gutenberg( + array( + 'version' => 1, + 'settings' => array( + 'typography' => array( + 'fontFamilies' => array( + 'theme' => array( + 'name' => $google_font_name, + 'slug' => $google_font_slug, + 'fontFamily' => $google_font_name, + ), + ), + ), + ), + ) + ); + $css_variable_declaration = $google_font_settings_theme_json->get_stylesheet( 'css_variables' ); + + // 3. Inject the google font style declarations into the global styles embedded stylesheet + if ( isset( wp_styles()->registered['global-styles'] ) && $css_variable_declaration ) { + $import_statement = "@import url('https://fonts.googleapis.com/css?family=" + . str_replace( ' ', '+', $google_font_name ) + . ':regular,bold,italic,bolditalic|' . "');"; + + wp_styles()->registered['global-styles']->extra['after'][0] = $import_statement + . "\n" . $css_variable_declaration + . "\n" . wp_styles()->registered['global-styles']->extra['after'][0]; + } + } + } +} + +add_action( 'wp_enqueue_scripts', 'gutenberg_wpcom_google_fonts_enqueue_assets' ); From ac59e16847a95edc85b7045ba5d34341e8ed8556 Mon Sep 17 00:00:00 2001 From: Jeremy Yip Date: Fri, 13 Aug 2021 17:14:35 -0700 Subject: [PATCH 6/6] Refactor conditional guards --- .../global-styles/global-styles.php | 94 +++++++++++-------- 1 file changed, 54 insertions(+), 40 deletions(-) diff --git a/projects/plugins/jetpack/extensions/extended-blocks/global-styles/global-styles.php b/projects/plugins/jetpack/extensions/extended-blocks/global-styles/global-styles.php index b3fd35810b600..f585fc8cd93f6 100644 --- a/projects/plugins/jetpack/extensions/extended-blocks/global-styles/global-styles.php +++ b/projects/plugins/jetpack/extensions/extended-blocks/global-styles/global-styles.php @@ -71,12 +71,19 @@ function ( $font_name ) { valid_google_fonts() ); - if ( isset( $settings['__experimentalGlobalStylesBaseStyles']['settings']['typography']['fontFamilies'] ) ) { - $settings['__experimentalGlobalStylesBaseStyles']['settings']['typography']['fontFamilies']['theme'] = array_merge( - $settings['__experimentalGlobalStylesBaseStyles']['settings']['typography']['fontFamilies']['theme'], - $google_font_options - ); + if ( + ! isset( $settings['__experimentalGlobalStylesBaseStyles'] ) || + ! isset( $settings['__experimentalGlobalStylesBaseStyles']['settings'] ) || + ! isset( $settings['__experimentalGlobalStylesBaseStyles']['settings']['typography'] ) || + ! isset( $settings['__experimentalGlobalStylesBaseStyles']['settings']['typography']['fontFamilies'] ) + ) { + return; } + + $settings['__experimentalGlobalStylesBaseStyles']['settings']['typography']['fontFamilies']['theme'] = array_merge( + $settings['__experimentalGlobalStylesBaseStyles']['settings']['typography']['fontFamilies']['theme'], + $google_font_options + ); } return $settings; @@ -102,48 +109,55 @@ function ( $font_name ) { function gutenberg_wpcom_google_fonts_enqueue_assets() { $global_styles_user_data = WP_Theme_JSON_Resolver_Gutenberg::get_user_data()->get_raw_data(); - if ( isset( $global_styles_user_data['styles'] ) && isset( $global_styles_user_data['styles']['typography'] ) ) { - // 1. Determine if a google font was selected for site editor global styles - $user_selected_font_family = $global_styles_user_data['styles']['typography']['fontFamily']; - foreach ( valid_google_fonts() as $font_name ) { - $font_slug = str_replace( ' ', '-', strtolower( $font_name ) ); - if ( strpos( $user_selected_font_family, $font_slug ) ) { - $google_font_name = $font_name; - $google_font_slug = $font_slug; - break; - } + if ( + ! isset( $global_styles_user_data ) || + ! isset( $global_styles_user_data['styles'] ) || + ! isset( $global_styles_user_data['styles']['typography'] ) || + ! isset( $global_styles_user_data['styles']['typography']['fontFamily'] ) + ) { + return; + } + + // 1. Determine if a google font was selected for site editor global styles + $user_selected_font_family = $global_styles_user_data['styles']['typography']['fontFamily']; + foreach ( valid_google_fonts() as $font_name ) { + $font_slug = str_replace( ' ', '-', strtolower( $font_name ) ); + if ( strpos( $user_selected_font_family, $font_slug ) ) { + $google_font_name = $font_name; + $google_font_slug = $font_slug; + break; } + } - if ( $google_font_name && $google_font_slug ) { - // 2. Generate formatted style declarations for the selected google font - $google_font_settings_theme_json = new WP_Theme_JSON_Gutenberg( - array( - 'version' => 1, - 'settings' => array( - 'typography' => array( - 'fontFamilies' => array( - 'theme' => array( - 'name' => $google_font_name, - 'slug' => $google_font_slug, - 'fontFamily' => $google_font_name, - ), + if ( $google_font_name && $google_font_slug ) { + // 2. Generate formatted style declarations for the selected google font + $google_font_settings_theme_json = new WP_Theme_JSON_Gutenberg( + array( + 'version' => 1, + 'settings' => array( + 'typography' => array( + 'fontFamilies' => array( + 'theme' => array( + 'name' => $google_font_name, + 'slug' => $google_font_slug, + 'fontFamily' => $google_font_name, ), ), ), - ) - ); - $css_variable_declaration = $google_font_settings_theme_json->get_stylesheet( 'css_variables' ); + ), + ) + ); + $css_variable_declaration = $google_font_settings_theme_json->get_stylesheet( 'css_variables' ); - // 3. Inject the google font style declarations into the global styles embedded stylesheet - if ( isset( wp_styles()->registered['global-styles'] ) && $css_variable_declaration ) { - $import_statement = "@import url('https://fonts.googleapis.com/css?family=" - . str_replace( ' ', '+', $google_font_name ) - . ':regular,bold,italic,bolditalic|' . "');"; + // 3. Inject the google font style declarations into the global styles embedded stylesheet + if ( isset( wp_styles()->registered['global-styles'] ) && $css_variable_declaration ) { + $import_statement = "@import url('https://fonts.googleapis.com/css?family=" + . str_replace( ' ', '+', $google_font_name ) + . ':regular,bold,italic,bolditalic|' . "');"; - wp_styles()->registered['global-styles']->extra['after'][0] = $import_statement - . "\n" . $css_variable_declaration - . "\n" . wp_styles()->registered['global-styles']->extra['after'][0]; - } + wp_styles()->registered['global-styles']->extra['after'][0] = $import_statement + . "\n" . $css_variable_declaration + . "\n" . wp_styles()->registered['global-styles']->extra['after'][0]; } } }