/** * Custom icons for this theme. * * @package WordPress * @subpackage Twenty_Twenty * @since Twenty Twenty 1.0 */ if ( ! class_exists( 'TwentyTwenty_SVG_Icons' ) ) { /** * SVG ICONS CLASS * Retrieve the SVG code for the specified icon. Based on a solution in Twenty Nineteen. * * @since Twenty Twenty 1.0 */ class TwentyTwenty_SVG_Icons { /** * GET SVG CODE * Get the SVG code for the specified icon * * @since Twenty Twenty 1.0 * * @param string $icon Icon name. * @param string $group Icon group. * @param string $color Color. */ public static function get_svg( $icon, $group = 'ui', $color = '#1A1A1B' ) { if ( 'ui' === $group ) { $arr = self::$ui_icons; } elseif ( 'social' === $group ) { $arr = self::$social_icons; } else { $arr = array(); } /** * Filters Twenty Twenty's array of icons. * * The dynamic portion of the hook name, `$group`, refers to * the name of the group of icons, either "ui" or "social". * * @since Twenty Twenty 1.5 * * @param array $arr Array of icons. */ $arr = apply_filters( "twentytwenty_svg_icons_{$group}", $arr ); /** * Filters an SVG icon's color. * * @since Twenty Twenty 1.5 * * @param string $color The icon color. * @param string $icon The icon name. * @param string $group The icon group. */ $color = apply_filters( 'twentytwenty_svg_icon_color', $color, $icon, $group ); if ( array_key_exists( $icon, $arr ) ) { $repl = '\s*<', $svg ); // Remove whitespace between SVG tags. return $svg; } return null; } /** * GET SOCIAL LINK SVG * Detects the social network from a URL and returns the SVG code for its icon. * * @since Twenty Twenty 1.0 * * @param string $uri The URL to retrieve SVG for. */ public static function get_social_link_svg( $uri ) { static $regex_map; // Only compute regex map once, for performance. if ( ! isset( $regex_map ) ) { $regex_map = array(); /** * Filters Twenty Twenty's array of domain mappings for social icons. * * By default, each Icon ID is matched against a .com TLD. To override this behavior, * specify all the domains it covers (including the .com TLD too, if applicable). * * @since Twenty Twenty 1.5 * * @param array $social_icons_map Array of default social icons. */ $map = apply_filters( 'twentytwenty_social_icons_map', self::$social_icons_map ); /** * Filters Twenty Twenty's array of social icons. * * @since Twenty Twenty 1.5 * * @param array $social_icons Array of default social icons. */ $social_icons = apply_filters( 'twentytwenty_svg_icons_social', self::$social_icons ); foreach ( array_keys( $social_icons ) as $icon ) { $domains = array_key_exists( $icon, $map ) ? $map[ $icon ] : array( sprintf( '%s.com', $icon ) ); $domains = array_map( 'trim', $domains ); // Remove leading/trailing spaces, to prevent regex from failing to match. $domains = array_map( 'preg_quote', $domains ); $regex_map[ $icon ] = sprintf( '/(%s)/i', implode( '|', $domains ) ); } } foreach ( $regex_map as $icon => $regex ) { if ( preg_match( $regex, $uri ) ) { return twentytwenty_get_theme_svg( $icon, 'social' ); } } return null; } /** * ICON STORAGE * Store the code for all SVGs in an array. * * @since Twenty Twenty 1.0 * @var array */ public static $ui_icons = array( 'arrow-down' => ' ', 'arrow-down-circled' => ' ', 'bookmark' => ' ', 'calendar' => ' ', 'chevron-down' => ' ', 'comment' => ' ', 'cross' => ' ', 'ellipsis' => ' ', 'edit' => ' ', 'folder' => ' ', 'link' => ' ', 'search' => ' ', 'tag' => ' ', 'user' => ' ', ); /** * Social Icons – domain mappings. * * By default, each Icon ID is matched against a .com TLD. To override this behavior, * specify all the domains it covers (including the .com TLD too, if applicable). * * @since Twenty Twenty 1.0 * @var array */ public static $social_icons_map = array( 'amazon' => array( 'amazon.com', 'amazon.cn', 'amazon.in', 'amazon.fr', 'amazon.de', 'amazon.it', 'amazon.nl', 'amazon.es', 'amazon.co', 'amazon.ca', ), 'behance' => array( 'behance.net', ), 'codepen' => array( 'codepen.io', ), 'facebook' => array( 'facebook.com', 'fb.me', ), 'feed' => array( 'feed', ), 'google' => array( 'g.page', ), 'lastfm' => array( 'last.fm', ), 'mail' => array( 'mailto:', ), 'mastodon' => array( 'mastodon.social', 'pawoo.net', 'mstdn.jp', 'mastodon.cloud', 'mastodon.online', 'counter.social', 'mstdn.social', 'mas.to', 'mastodon.world', 'gc2.jp', ), 'pocket' => array( 'getpocket.com', ), 'tiktok' => array( 'tiktok.com', ), 'twitch' => array( 'twitch.tv', ), 'whatsapp' => array( 'wa.me', 'whatsapp.com', ), 'wordpress' => array( 'wordpress.com', 'wordpress.org', ), ); /** * Social Icons – svg sources. * * @since Twenty Twenty 1.0 * @var array */ public static $social_icons = array( '500px' => '', 'amazon' => '', 'bandcamp' => '', 'behance' => '', 'codepen' => '', 'deviantart' => '', 'dribbble' => '', 'dropbox' => '', 'etsy' => '', 'facebook' => '', 'feed' => '', 'flickr' => '', 'foursquare' => '', 'goodreads' => '', 'google' => '', 'github' => '', 'instagram' => '', 'lastfm' => '', 'linkedin' => '', 'mail' => '', 'mastodon' => '', 'medium' => '', 'meetup' => '', 'pinterest' => '', 'pocket' => '', 'reddit' => '', 'skype' => '', 'snapchat' => '', 'soundcloud' => '', 'spotify' => '', 'tumblr' => '', 'tiktok' => '', 'twitch' => '', 'twitter' => '', 'vimeo' => '', 'vk' => '', 'whatsapp' => ' ', // phpcs:disable WordPress.WP.CapitalPDangit.Misspelled 'wordpress' => '', 'yelp' => '', 'youtube' => '', ); } }/** * Non-latin language handling. * * Handle non-latin language styles. * * @package WordPress * @subpackage Twenty_Twenty * @since Twenty Twenty 1.0 */ if ( ! class_exists( 'TwentyTwenty_Non_Latin_Languages' ) ) { /** * Language handling. * * @since Twenty Twenty 1.0 */ class TwentyTwenty_Non_Latin_Languages { /** * Get custom CSS. * * Return CSS for non-latin language, if available, or null * * @since Twenty Twenty 1.0 * * @param string $type Whether to return CSS for the "front-end", "block-editor", or "classic-editor". * @return string|null Custom CSS, or null if not applicable. */ public static function get_non_latin_css( $type = 'front-end' ) { // Fetch site locale. $locale = get_bloginfo( 'language' ); /** * Filters the fallback fonts for non-latin languages. * * @since Twenty Twenty 1.0 * * @param array $font_family An array of locales and font families. */ $font_family = apply_filters( 'twentytwenty_get_localized_font_family_types', array( // Arabic. 'ar' => array( 'Tahoma', 'Arial', 'sans-serif' ), 'ary' => array( 'Tahoma', 'Arial', 'sans-serif' ), 'azb' => array( 'Tahoma', 'Arial', 'sans-serif' ), 'ckb' => array( 'Tahoma', 'Arial', 'sans-serif' ), 'fa-IR' => array( 'Tahoma', 'Arial', 'sans-serif' ), 'haz' => array( 'Tahoma', 'Arial', 'sans-serif' ), 'ps' => array( 'Tahoma', 'Arial', 'sans-serif' ), // Chinese Simplified (China) - Noto Sans SC. 'zh-CN' => array( '\'PingFang SC\'', '\'Helvetica Neue\'', '\'Microsoft YaHei New\'', '\'STHeiti Light\'', 'sans-serif' ), // Chinese Traditional (Taiwan) - Noto Sans TC. 'zh-TW' => array( '\'PingFang TC\'', '\'Helvetica Neue\'', '\'Microsoft YaHei New\'', '\'STHeiti Light\'', 'sans-serif' ), // Chinese (Hong Kong) - Noto Sans HK. 'zh-HK' => array( '\'PingFang HK\'', '\'Helvetica Neue\'', '\'Microsoft YaHei New\'', '\'STHeiti Light\'', 'sans-serif' ), // Cyrillic. 'bel' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'bg-BG' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'kk' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'mk-MK' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'mn' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'ru-RU' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'sah' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'sr-RS' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'tt-RU' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), 'uk' => array( '\'Helvetica Neue\'', 'Helvetica', '\'Segoe UI\'', 'Arial', 'sans-serif' ), // Devanagari. 'bn-BD' => array( 'Arial', 'sans-serif' ), 'hi-IN' => array( 'Arial', 'sans-serif' ), 'mr' => array( 'Arial', 'sans-serif' ), 'ne-NP' => array( 'Arial', 'sans-serif' ), // Greek. 'el' => array( '\'Helvetica Neue\', Helvetica, Arial, sans-serif' ), // Gujarati. 'gu' => array( 'Arial', 'sans-serif' ), // Hebrew. 'he-IL' => array( '\'Arial Hebrew\'', 'Arial', 'sans-serif' ), // Japanese. 'ja' => array( 'sans-serif' ), // Korean. 'ko-KR' => array( '\'Apple SD Gothic Neo\'', '\'Malgun Gothic\'', '\'Nanum Gothic\'', 'Dotum', 'sans-serif' ), // Thai. 'th' => array( '\'Sukhumvit Set\'', '\'Helvetica Neue\'', 'Helvetica', 'Arial', 'sans-serif' ), // Vietnamese. 'vi' => array( '\'Libre Franklin\'', 'sans-serif' ), ) ); // Return if the selected language has no fallback fonts. if ( empty( $font_family[ $locale ] ) ) { return null; } /** * Filters the elements to apply fallback fonts to. * * @since Twenty Twenty 1.0 * * @param array $elements An array of elements for "front-end", "block-editor", or "classic-editor". */ $elements = apply_filters( 'twentytwenty_get_localized_font_family_elements', array( 'front-end' => array( 'body', 'input', 'textarea', 'button', '.button', '.faux-button', '.faux-button.more-link', '.wp-block-button__link', '.wp-block-file__button', '.has-drop-cap:not(:focus)::first-letter', '.entry-content .wp-block-archives', '.entry-content .wp-block-categories', '.entry-content .wp-block-cover-image', '.entry-content .wp-block-cover-image p', '.entry-content .wp-block-latest-comments', '.entry-content .wp-block-latest-posts', '.entry-content .wp-block-pullquote', '.entry-content .wp-block-quote.is-large', '.entry-content .wp-block-quote.is-style-large', '.entry-content .wp-block-archives *', '.entry-content .wp-block-categories *', '.entry-content .wp-block-latest-posts *', '.entry-content .wp-block-latest-comments *', '.entry-content', '.entry-content h1', '.entry-content h2', '.entry-content h3', '.entry-content h4', '.entry-content h5', '.entry-content h6', '.entry-content p', '.entry-content ol', '.entry-content ul', '.entry-content dl', '.entry-content dt', '.entry-content cite', '.entry-content figcaption', '.entry-content table', '.entry-content address', '.entry-content .wp-caption-text', '.entry-content .wp-block-file', '.comment-content p', '.comment-content ol', '.comment-content ul', '.comment-content dl', '.comment-content dt', '.comment-content cite', '.comment-content figcaption', '.comment-content .wp-caption-text', '.widget_text p', '.widget_text ol', '.widget_text ul', '.widget_text dl', '.widget_text dt', '.widget-content .rssSummary', '.widget-content cite', '.widget-content figcaption', '.widget-content .wp-caption-text' ), 'block-editor' => array( '.editor-styles-wrapper > *', '.editor-styles-wrapper p', '.editor-styles-wrapper ol', '.editor-styles-wrapper ul', '.editor-styles-wrapper dl', '.editor-styles-wrapper dt', '.editor-post-title__block .editor-post-title__input', '.editor-styles-wrapper .wp-block-post-title', '.editor-styles-wrapper h1', '.editor-styles-wrapper h2', '.editor-styles-wrapper h3', '.editor-styles-wrapper h4', '.editor-styles-wrapper h5', '.editor-styles-wrapper h6', '.editor-styles-wrapper .has-drop-cap:not(:focus)::first-letter', '.editor-styles-wrapper cite', '.editor-styles-wrapper figcaption', '.editor-styles-wrapper .wp-caption-text' ), 'classic-editor' => array( 'body#tinymce.wp-editor', 'body#tinymce.wp-editor p', 'body#tinymce.wp-editor ol', 'body#tinymce.wp-editor ul', 'body#tinymce.wp-editor dl', 'body#tinymce.wp-editor dt', 'body#tinymce.wp-editor figcaption', 'body#tinymce.wp-editor .wp-caption-text', 'body#tinymce.wp-editor .wp-caption-dd', 'body#tinymce.wp-editor cite', 'body#tinymce.wp-editor table' ), ) ); // Return if the specified type doesn't exist. if ( empty( $elements[ $type ] ) ) { return null; } // Return the specified styles. return twentytwenty_generate_css( implode( ',', $elements[ $type ] ), 'font-family', implode( ',', $font_family[ $locale ] ), null, null, false ); } } }