PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.3-a.7
Jetpack – WP Security, Backup, Speed, & Growth v16.3-a.7
16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 All 506 releases
← All changes | modules/google-fonts/current/class-jetpack-google-font-face.php +90 -28 12.9.5 → 16.3-a.7 View file →
@@ -8,8 +8,10 @@
8 8 /**
9 9 * Jetpack Google Font Face disables Font Face hooks in Core that prints **ALL** font faces.
10 10 * Instead, it collects fonts that are used in global styles or block-level settings and
11 11 * print those fonts in use.
12 + *
13 + * @phan-constructor-used-for-side-effects
12 14 */
13 15 class Jetpack_Google_Font_Face {
14 16 /**
15 17 * The fonts that are used in global styles or block-level settings.
@@ -23,12 +25,17 @@
23 25 */
24 26 public function __construct() {
25 27 // Turns off hooks to print fonts
26 28 add_action( 'wp_loaded', array( $this, 'wp_loaded' ) );
27 - add_action( 'admin_init', array( $this, 'admin_init' ), 10 );
29 + add_action( 'current_screen', array( $this, 'current_screen' ), 10 );
28 30
29 31 // Collect and print fonts in use
30 - add_action( 'wp_head', array( $this, 'print_font_faces' ), 50 );
32 + if ( wp_is_block_theme() ) {
33 + add_action( 'wp_head', array( $this, 'print_font_faces' ), 50 );
34 + } else {
35 + // In classic themes wp_head runs before the blocks are processed to collect the block fonts.
36 + add_action( 'wp_footer', array( $this, 'print_font_faces' ), 50 );
37 + }
31 38 add_filter( 'pre_render_block', array( $this, 'collect_block_fonts' ), 10, 2 );
32 39 }
33 40
34 41 /**
@@ -36,16 +43,22 @@
36 43 */
37 44 public function wp_loaded() {
38 45 remove_action( 'wp_head', 'wp_print_fonts', 50 );
39 46 remove_action( 'wp_head', 'wp_print_font_faces', 50 );
47 + // Gutenberg 22.4+ overrides Core's font printing with its own function
48 + // for classic theme support. Remove it so we can print only fonts in use.
49 + remove_action( 'wp_head', 'gutenberg_print_font_faces', 50 );
40 50 }
41 51
42 52 /**
43 - * Turn off hooks to print fonts on wp-admin
53 + * Turn off hooks to print fonts on wp-admin, except for GB editor pages.
44 54 */
45 - public function admin_init() {
55 + public function current_screen() {
46 56 remove_action( 'admin_print_styles', 'wp_print_fonts', 50 );
47 - remove_action( 'admin_print_styles', 'wp_print_font_faces', 50 );
57 +
58 + if ( ! $this->is_block_editor() ) {
59 + remove_action( 'admin_print_styles', 'wp_print_font_faces', 50 );
60 + }
48 61 }
49 62
50 63 /**
51 64 * Print fonts that are used in global styles or block-level settings.
@@ -50,16 +63,25 @@
50 63 /**
51 64 * Print fonts that are used in global styles or block-level settings.
52 65 */
53 66 public function print_font_faces() {
54 - $fonts = $this->get_fonts();
55 - $fonts_to_print = array();
67 + $fonts = WP_Font_Face_Resolver::get_fonts_from_theme_json();
68 + $font_slug_aliases = $this->get_font_slug_aliases();
69 + $fonts_to_print = array();
56 70
57 71 $this->collect_global_styles_fonts();
58 - $this->fonts_in_use = array_values( array_unique( $this->fonts_in_use, SORT_STRING ) );
59 - foreach ( $fonts as $font_family => $font_faces ) {
60 - if ( in_array( _wp_to_kebab_case( $font_family ), $this->fonts_in_use, true ) ) {
61 - $fonts_to_print[ $font_family ] = $font_faces;
72 + $fonts_in_use = array_values( array_unique( $this->fonts_in_use, SORT_STRING ) );
73 + $fonts_in_use = array_map(
74 + function ( $font_slug ) use ( $font_slug_aliases ) {
75 + return $font_slug_aliases[ $font_slug ] ?? $font_slug;
76 + },
77 + $fonts_in_use
78 + );
79 +
80 + foreach ( $fonts as $font_faces ) {
81 + $font_family = $font_faces[0]['font-family'] ?? '';
82 + if ( in_array( $this->format_font( $font_family ), $fonts_in_use, true ) ) {
83 + $fonts_to_print[] = $font_faces;
62 84 }
63 85 }
64 86
65 87 if ( ! empty( $fonts_to_print ) ) {
@@ -121,32 +143,50 @@
121 143 *
122 144 * @param string $font_slug The font slug.
123 145 */
124 146 public function add_font( $font_slug ) {
125 - $this->fonts_in_use[] = _wp_to_kebab_case( $font_slug );
147 + if ( is_string( $font_slug ) ) {
148 + $this->fonts_in_use[] = $this->format_font( $font_slug );
149 + }
126 150 }
127 151
128 152 /**
129 - * Get all font definitions from theme json.
153 + * Format the given font slug.
154 + *
155 + * @example "ABeeZee" formats to "abeezee"
156 + * @example "ADLaM Display" formats to "adlam-display"
157 + * @param string $font_slug The font slug.
158 + * @return string The formatted font slug.
130 159 */
131 - public function get_fonts() {
132 - $fonts = WP_Font_Face_Resolver::get_fonts_from_theme_json();
160 + public function format_font( $font_slug ) {
161 + return _wp_to_kebab_case( strtolower( $font_slug ) );
162 + }
133 163
134 - // The font definition might define an alias slug name, so we have to add the map from the slug name to font faces.
135 - // See https://github.com/WordPress/twentytwentyfour/blob/df92472089ede6fae5924c124a93c843b84e8cbd/theme.json#L215.
164 + /**
165 + * Get the font slug aliases that maps the font slug to the font family if they are different.
166 + *
167 + * The font definition may define an alias slug name, so we have to add the map from the slug name to the font family.
168 + * See https://github.com/WordPress/twentytwentyfour/blob/df92472089ede6fae5924c124a93c843b84e8cbd/theme.json#L215.
169 + */
170 + public function get_font_slug_aliases() {
171 + $font_slug_aliases = array();
172 +
136 173 $theme_json = WP_Theme_JSON_Resolver::get_theme_data();
137 174 $raw_data = $theme_json->get_data();
138 175 if ( ! empty( $raw_data['settings']['typography']['fontFamilies'] ) ) {
139 176 foreach ( $raw_data['settings']['typography']['fontFamilies'] as $font ) {
140 - $font_family_name = $this->get_font_family_name( $font );
141 - $font_slug = isset( $font['slug'] ) ? $font['slug'] : '';
142 - if ( $font_slug && ! array_key_exists( $font_slug, $fonts ) && array_key_exists( $font_family_name, $fonts ) ) {
143 - $fonts[ $font_slug ] = $fonts[ $font_family_name ];
177 + if ( ! isset( $font['fontFamily'] ) ) {
178 + continue;
144 179 }
180 + $font_family_name = $this->format_font( $this->get_font_family_name( $font ) );
181 + $font_slug = $font['slug'] ?? '';
182 + if ( $font_slug && $font_slug !== $font_family_name && ! array_key_exists( $font_slug, $font_slug_aliases ) ) {
183 + $font_slug_aliases[ $font_slug ] = $font_family_name;
184 + }
145 185 }
146 186 }
147 187
148 - return $fonts;
188 + return $font_slug_aliases;
149 189 }
150 190
151 191 /**
152 192 * Get the font family name from a font.
@@ -152,9 +192,9 @@
152 192 * Get the font family name from a font.
153 193 *
154 194 * @param array $font The font definition object.
155 195 */
156 - public function get_font_family_name( $font ) {
196 + public static function get_font_family_name( $font ) {
157 197 $font_family = $font['fontFamily'];
158 198 if ( str_contains( $font_family, ',' ) ) {
159 199 $font_family = explode( ',', $font_family )[0];
160 200 }
@@ -175,12 +215,18 @@
175 215 }
176 216
177 217 $font_family = $setting['typography']['fontFamily'];
178 218
179 - // Full string: var(--wp--preset--font-family--slug).
180 - // We do not care about the origin of the font, only its slug.
181 - preg_match( '/font-family--(?P<slug>.+)\)$/', $font_family, $matches );
219 + // The font family may be a reference to a path to the value stored at that location,
220 + // e.g.: { "ref": "styles.elements.heading.typography.fontFamily" }.
221 + // Ignore it as we also get the value stored at that location from the setting.
222 + if ( ! is_string( $font_family ) ) {
223 + return null;
224 + }
182 225
226 + // A preset reference can include a var() fallback and a trailing font stack.
227 + preg_match( '/^\s*var\(\s*--wp--preset--font-family--(?P<slug>[^\s,()]+)\s*[,)]/', $font_family, $matches );
228 +
183 229 if ( isset( $matches['slug'] ) ) {
184 230 return $matches['slug'];
185 231 }
186 232
@@ -185,13 +231,29 @@
185 231 }
186 232
187 233 // Full string: var:preset|font-family|slug
188 234 // We do not care about the origin of the font, only its slug.
189 - preg_match( '/font-family\|(?P<slug>.+)$/', $font_family, $matches );
235 + preg_match( '/^\s*var:preset\|font-family\|(?P<slug>[^\s,]+)/', $font_family, $matches );
190 236
191 237 if ( isset( $matches['slug'] ) ) {
192 238 return $matches['slug'];
193 239 }
194 240
195 - return $font_family;
241 + return self::get_font_family_name( $setting['typography'] );
242 + }
243 +
244 + /**
245 + * Check if the current screen is the block editor.
246 + *
247 + * @return bool
248 + */
249 + public function is_block_editor() {
250 + if ( function_exists( 'get_current_screen' ) ) {
251 + $current_screen = get_current_screen();
252 + if ( ! empty( $current_screen ) && method_exists( $current_screen, 'is_block_editor' ) && $current_screen->is_block_editor() ) {
253 + return true;
254 + }
255 + }
256 +
257 + return false;
196 258 }
197 259 }