get_all_settings(); if ( empty( $settings['font_display_sitewide'] ) ) { return; } add_action( 'template_redirect', array( $this, 'start_buffer' ), 2 ); // Also preload custom list when sitewide fonts optimization is on. if ( ! empty( $settings['font_preload_list'] ) ) { add_filter( 'wp_preload_resources', array( $this, 'preload_custom' ) ); } } public function start_buffer() { if ( ! \QWSpeedCache\Plugin::should_optimize() || is_admin() || is_embed() || ( defined( 'REST_REQUEST' ) && REST_REQUEST ) ) { return; } \QWSpeedCache\Support\OutputBuffer::start( array( $this, 'filter_html' ) ); } /** * @param string $html HTML. * @return string */ public function filter_html( $html ) { $settings = \QWSpeedCache\Plugin::instance()->get_all_settings(); $display = isset( $settings['font_display'] ) ? $settings['font_display'] : 'swap'; return self::inject_into_html( $html, $display ); } /** * Inject font-display into @font-face blocks missing it (pure). * * @param string $css CSS. * @param string $display Value. * @return string */ public static function inject_into_css( $css, $display = 'swap' ) { $display = self::sanitize_display( $display ); $css = (string) $css; if ( '' === $css ) { return $css; } $out = preg_replace_callback( '/@font-face\s*\{([^{}]*)\}/i', static function ( $m ) use ( $display ) { $body = $m[1]; if ( false !== stripos( $body, 'font-display' ) ) { return $m[0]; } $body = rtrim( $body, "; \t\n\r" ) . ';font-display:' . $display . ';'; return '@font-face{' . $body . '}'; }, $css ); return is_string( $out ) ? $out : $css; } /** * Process inline '; }, $html ); return is_string( $out ) ? $out : $html; } /** * @param string $display Raw. * @return string */ public static function sanitize_display( $display ) { $display = function_exists( 'sanitize_key' ) ? sanitize_key( (string) $display ) : strtolower( preg_replace( '/[^a-z]/', '', (string) $display ) ); $allowed = array( 'auto', 'block', 'swap', 'fallback', 'optional' ); return in_array( $display, $allowed, true ) ? $display : 'swap'; } /** * Register custom font preloads with the WordPress resource API. * * @param array $preloads Existing preload resources. * @return array */ public function preload_custom( $preloads ) { if ( ! \QWSpeedCache\Plugin::should_optimize() ) { return $preloads; } $settings = \QWSpeedCache\Plugin::instance()->get_all_settings(); $lines = array_filter( array_map( 'trim', explode( "\n", (string) ( $settings['font_preload_list'] ?? '' ) ) ) ); foreach ( $lines as $url ) { if ( '' === $url || 0 === strpos( $url, '#' ) ) { continue; } $url = esc_url_raw( $url, array( 'http', 'https' ) ); if ( ! $url ) { continue; } $type = 'font/woff2'; if ( preg_match( '/\.woff(?:\?|$)/i', $url ) ) { $type = 'font/woff'; } $preloads[] = array( 'href' => $url, 'as' => 'font', 'type' => $type, 'crossorigin' => 'anonymous', ); } return $preloads; } }