p. \add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); // Save hyphenator cache on exit, if necessary. \add_action( 'shutdown', [ $this->api, 'save_hyphenator_cache_on_shutdown' ], 10 ); } /** * Adds content filter handlers. */ public function add_content_filters() : void { // Define the default filters. $filters = [ // Add filters for "full" content. 'content' => [ $this, 'enable_content_filters' ], // Add filters for headings. 'heading' => [ $this, 'enable_heading_filters' ], ]; /** * Filters the content filter enabling functions. * * @internal * * @param callable[string] $filters An array of enabling functions taking * the priority as an argument, indexed by * filter group. */ $filters = \apply_filters( 'typo_content_filters', $filters ); /** * Filters the priority used for wp-Typography's text processing filters. * * When NextGen Gallery is detected, the priority is set to PHP_INT_MAX. * * @since 3.2.0 * * @param int $priority The filter priority. Default 9999. */ $priority = \apply_filters( 'typo_filter_priority', $this->filter_priority ); foreach ( $filters as $tag => $enable ) { /** * Disables automatic filtering by wp-Typography. * * @since 3.6.0 * @since 5.2.0 WooCommerce support added ($filter_group 'woocommerce'). * @since 5.6.0 Filter group `title` removed. * * @param bool $disable Whether to disable automatic filtering. Default false. * @param string $filter_group Which filters to disable. Possible values 'content', 'heading', 'acf', 'woocommerce'. */ if ( ! \apply_filters( 'typo_disable_filtering', false, $tag ) ) { $enable( $priority ); } } } /** * Enable the content (body) filters. * * @param int $priority Filter priority. */ private function enable_content_filters( $priority ) : void { \add_filter( 'comment_author', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'the_content', [ $this->api, 'process' ], $priority ); \add_filter( 'term_description', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt_embed', [ $this->api, 'process' ], $priority ); \add_filter( 'wp_dropdown_cats', [ $this->api, 'process' ], $priority ); // FIXME: These should be moved to their own filter group in the next major release. \add_filter( 'term_name', [ $this->api, 'process_feed' ], $priority ); \add_filter( 'link_name', [ $this->api, 'process_feed' ], $priority ); // Preserve shortcode handling on WordPress 4.8+. if ( \version_compare( \get_bloginfo( 'version' ), '4.8', '>=' ) ) { \add_filter( 'widget_text_content', [ $this->api, 'process' ], $priority ); } else { \add_filter( 'widget_text', [ $this->api, 'process' ], $priority ); } } /** * Enable the heading filters. * * @param int $priority Filter priority. */ private function enable_heading_filters( $priority ) : void { \add_filter( 'the_title', [ $this->api, 'process_title' ], $priority ); \add_filter( 'widget_title', [ $this->api, 'process_title' ], $priority ); } /** * Enqueues custom styles. * * @since 5.5.3 */ public function enqueue_styles() : void { // Custom styles set via the CSS Hooks settings page. $custom_styles = \trim( (string) $this->config[ Config::STYLE_CSS ] ); if ( ! empty( $custom_styles ) ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-custom', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-custom' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-custom', $this->clean_styles( $custom_styles ) ); } // The Safari bug workaround. if ( $this->config[ Config::HYPHENATE_SAFARI_FONT_WORKAROUND ] ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-safari-font-workaround', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-safari-font-workaround' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-safari-font-workaround', 'body {-webkit-font-feature-settings: "liga";font-feature-settings: "liga";-ms-font-feature-settings: normal;}' ); } } /** * Enqueues frontend JavaScript files. */ public function enqueue_scripts() : void { if ( $this->config[ Config::HYPHENATE_CLEAN_CLIPBOARD ] ) { // Set up file suffix and plugin version. $suffix = ( \defined( 'SCRIPT_DEBUG' ) && \SCRIPT_DEBUG ) ? '' : '.min'; $version = $this->api->get_version(); $plugin_dir = \plugin_dir_url( \WP_TYPOGRAPHY_PLUGIN_FILE ); \wp_enqueue_script( 'wp-typography-cleanup-clipboard', "{$plugin_dir}js/clean-clipboard$suffix.js", [], $version, true ); } } /** * Cleans up the user-supplied CSS rules for output. Removes comments and most * whitespace and filters the rules through `safecss_filter_attr`. * * @since 5.5.3 * * @param string $css A string of CSS styles. * * @return string Filtered string of CSS styles. */ protected function clean_styles( $css ) : string { $cleaned = (string) \preg_replace( self::CLEAN_CSS_PATTERNS, self::CLEAN_CSS_REPLACEMENTS, $css ); $css = ''; if ( \preg_match_all( '/\s*(?[^{}]+?)\s*\{\s*(?[^{}]+?)\s*\}\s*/sS', $cleaned, $matches, PREG_SET_ORDER ) ) { foreach ( $matches as $m ) { $selector = \wp_strip_all_tags( $m['selector'] ); $rules = \safecss_filter_attr( $m['rules'] ); if ( ! empty( $selector ) && ! empty( $rules ) ) { $css .= "{$selector}{{$rules}}"; } } } return $css; } } p. \add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); // Save hyphenator cache on exit, if necessary. \add_action( 'shutdown', [ $this->api, 'save_hyphenator_cache_on_shutdown' ], 10 ); } /** * Adds content filter handlers. */ public function add_content_filters() : void { // Define the default filters. $filters = [ // Add filters for "full" content. 'content' => [ $this, 'enable_content_filters' ], // Add filters for headings. 'heading' => [ $this, 'enable_heading_filters' ], ]; /** * Filters the content filter enabling functions. * * @internal * * @param callable[string] $filters An array of enabling functions taking * the priority as an argument, indexed by * filter group. */ $filters = \apply_filters( 'typo_content_filters', $filters ); /** * Filters the priority used for wp-Typography's text processing filters. * * When NextGen Gallery is detected, the priority is set to PHP_INT_MAX. * * @since 3.2.0 * * @param int $priority The filter priority. Default 9999. */ $priority = \apply_filters( 'typo_filter_priority', $this->filter_priority ); foreach ( $filters as $tag => $enable ) { /** * Disables automatic filtering by wp-Typography. * * @since 3.6.0 * @since 5.2.0 WooCommerce support added ($filter_group 'woocommerce'). * @since 5.6.0 Filter group `title` removed. * * @param bool $disable Whether to disable automatic filtering. Default false. * @param string $filter_group Which filters to disable. Possible values 'content', 'heading', 'acf', 'woocommerce'. */ if ( ! \apply_filters( 'typo_disable_filtering', false, $tag ) ) { $enable( $priority ); } } } /** * Enable the content (body) filters. * * @param int $priority Filter priority. */ private function enable_content_filters( $priority ) : void { \add_filter( 'comment_author', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'the_content', [ $this->api, 'process' ], $priority ); \add_filter( 'term_description', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt_embed', [ $this->api, 'process' ], $priority ); \add_filter( 'wp_dropdown_cats', [ $this->api, 'process' ], $priority ); // FIXME: These should be moved to their own filter group in the next major release. \add_filter( 'term_name', [ $this->api, 'process_feed' ], $priority ); \add_filter( 'link_name', [ $this->api, 'process_feed' ], $priority ); // Preserve shortcode handling on WordPress 4.8+. if ( \version_compare( \get_bloginfo( 'version' ), '4.8', '>=' ) ) { \add_filter( 'widget_text_content', [ $this->api, 'process' ], $priority ); } else { \add_filter( 'widget_text', [ $this->api, 'process' ], $priority ); } } /** * Enable the heading filters. * * @param int $priority Filter priority. */ private function enable_heading_filters( $priority ) : void { \add_filter( 'the_title', [ $this->api, 'process_title' ], $priority ); \add_filter( 'widget_title', [ $this->api, 'process_title' ], $priority ); } /** * Enqueues custom styles. * * @since 5.5.3 */ public function enqueue_styles() : void { // Custom styles set via the CSS Hooks settings page. $custom_styles = \trim( (string) $this->config[ Config::STYLE_CSS ] ); if ( ! empty( $custom_styles ) ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-custom', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-custom' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-custom', $this->clean_styles( $custom_styles ) ); } // The Safari bug workaround. if ( $this->config[ Config::HYPHENATE_SAFARI_FONT_WORKAROUND ] ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-safari-font-workaround', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-safari-font-workaround' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-safari-font-workaround', 'body {-webkit-font-feature-settings: "liga";font-feature-settings: "liga";-ms-font-feature-settings: normal;}' ); } } /** * Enqueues frontend JavaScript files. */ public function enqueue_scripts() : void { if ( $this->config[ Config::HYPHENATE_CLEAN_CLIPBOARD ] ) { // Set up file suffix and plugin version. $suffix = ( \defined( 'SCRIPT_DEBUG' ) && \SCRIPT_DEBUG ) ? '' : '.min'; $version = $this->api->get_version(); $plugin_dir = \plugin_dir_url( \WP_TYPOGRAPHY_PLUGIN_FILE ); \wp_enqueue_script( 'wp-typography-cleanup-clipboard', "{$plugin_dir}js/clean-clipboard$suffix.js", [], $version, true ); } } /** * Cleans up the user-supplied CSS rules for output. Removes comments and most * whitespace and filters the rules through `safecss_filter_attr`. * * @since 5.5.3 * * @param string $css A string of CSS styles. * * @return string Filtered string of CSS styles. */ protected function clean_styles( $css ) : string { $cleaned = (string) \preg_replace( self::CLEAN_CSS_PATTERNS, self::CLEAN_CSS_REPLACEMENTS, $css ); $css = ''; if ( \preg_match_all( '/\s*(?[^{}]+?)\s*\{\s*(?[^{}]+?)\s*\}\s*/sS', $cleaned, $matches, PREG_SET_ORDER ) ) { foreach ( $matches as $m ) { $selector = \wp_strip_all_tags( $m['selector'] ); $rules = \safecss_filter_attr( $m['rules'] ); if ( ! empty( $selector ) && ! empty( $rules ) ) { $css .= "{$selector}{{$rules}}"; } } } return $css; } } p. \add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); // Save hyphenator cache on exit, if necessary. \add_action( 'shutdown', [ $this->api, 'save_hyphenator_cache_on_shutdown' ], 10 ); } /** * Adds content filter handlers. */ public function add_content_filters() : void { // Define the default filters. $filters = [ // Add filters for "full" content. 'content' => [ $this, 'enable_content_filters' ], // Add filters for headings. 'heading' => [ $this, 'enable_heading_filters' ], ]; /** * Filters the content filter enabling functions. * * @internal * * @param callable[string] $filters An array of enabling functions taking * the priority as an argument, indexed by * filter group. */ $filters = \apply_filters( 'typo_content_filters', $filters ); /** * Filters the priority used for wp-Typography's text processing filters. * * When NextGen Gallery is detected, the priority is set to PHP_INT_MAX. * * @since 3.2.0 * * @param int $priority The filter priority. Default 9999. */ $priority = \apply_filters( 'typo_filter_priority', $this->filter_priority ); foreach ( $filters as $tag => $enable ) { /** * Disables automatic filtering by wp-Typography. * * @since 3.6.0 * @since 5.2.0 WooCommerce support added ($filter_group 'woocommerce'). * @since 5.6.0 Filter group `title` removed. * * @param bool $disable Whether to disable automatic filtering. Default false. * @param string $filter_group Which filters to disable. Possible values 'content', 'heading', 'acf', 'woocommerce'. */ if ( ! \apply_filters( 'typo_disable_filtering', false, $tag ) ) { $enable( $priority ); } } } /** * Enable the content (body) filters. * * @param int $priority Filter priority. */ private function enable_content_filters( $priority ) : void { \add_filter( 'comment_author', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'the_content', [ $this->api, 'process' ], $priority ); \add_filter( 'term_description', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt_embed', [ $this->api, 'process' ], $priority ); \add_filter( 'wp_dropdown_cats', [ $this->api, 'process' ], $priority ); // FIXME: These should be moved to their own filter group in the next major release. \add_filter( 'term_name', [ $this->api, 'process_feed' ], $priority ); \add_filter( 'link_name', [ $this->api, 'process_feed' ], $priority ); // Preserve shortcode handling on WordPress 4.8+. if ( \version_compare( \get_bloginfo( 'version' ), '4.8', '>=' ) ) { \add_filter( 'widget_text_content', [ $this->api, 'process' ], $priority ); } else { \add_filter( 'widget_text', [ $this->api, 'process' ], $priority ); } } /** * Enable the heading filters. * * @param int $priority Filter priority. */ private function enable_heading_filters( $priority ) : void { \add_filter( 'the_title', [ $this->api, 'process_title' ], $priority ); \add_filter( 'widget_title', [ $this->api, 'process_title' ], $priority ); } /** * Enqueues custom styles. * * @since 5.5.3 */ public function enqueue_styles() : void { // Custom styles set via the CSS Hooks settings page. $custom_styles = \trim( (string) $this->config[ Config::STYLE_CSS ] ); if ( ! empty( $custom_styles ) ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-custom', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-custom' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-custom', $this->clean_styles( $custom_styles ) ); } // The Safari bug workaround. if ( $this->config[ Config::HYPHENATE_SAFARI_FONT_WORKAROUND ] ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-safari-font-workaround', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-safari-font-workaround' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-safari-font-workaround', 'body {-webkit-font-feature-settings: "liga";font-feature-settings: "liga";-ms-font-feature-settings: normal;}' ); } } /** * Enqueues frontend JavaScript files. */ public function enqueue_scripts() : void { if ( $this->config[ Config::HYPHENATE_CLEAN_CLIPBOARD ] ) { // Set up file suffix and plugin version. $suffix = ( \defined( 'SCRIPT_DEBUG' ) && \SCRIPT_DEBUG ) ? '' : '.min'; $version = $this->api->get_version(); $plugin_dir = \plugin_dir_url( \WP_TYPOGRAPHY_PLUGIN_FILE ); \wp_enqueue_script( 'wp-typography-cleanup-clipboard', "{$plugin_dir}js/clean-clipboard$suffix.js", [], $version, true ); } } /** * Cleans up the user-supplied CSS rules for output. Removes comments and most * whitespace and filters the rules through `safecss_filter_attr`. * * @since 5.5.3 * * @param string $css A string of CSS styles. * * @return string Filtered string of CSS styles. */ protected function clean_styles( $css ) : string { $cleaned = (string) \preg_replace( self::CLEAN_CSS_PATTERNS, self::CLEAN_CSS_REPLACEMENTS, $css ); $css = ''; if ( \preg_match_all( '/\s*(?[^{}]+?)\s*\{\s*(?[^{}]+?)\s*\}\s*/sS', $cleaned, $matches, PREG_SET_ORDER ) ) { foreach ( $matches as $m ) { $selector = \wp_strip_all_tags( $m['selector'] ); $rules = \safecss_filter_attr( $m['rules'] ); if ( ! empty( $selector ) && ! empty( $rules ) ) { $css .= "{$selector}{{$rules}}"; } } } return $css; } } p. \add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); // Save hyphenator cache on exit, if necessary. \add_action( 'shutdown', [ $this->api, 'save_hyphenator_cache_on_shutdown' ], 10 ); } /** * Adds content filter handlers. */ public function add_content_filters() : void { // Define the default filters. $filters = [ // Add filters for "full" content. 'content' => [ $this, 'enable_content_filters' ], // Add filters for headings. 'heading' => [ $this, 'enable_heading_filters' ], ]; /** * Filters the content filter enabling functions. * * @internal * * @param callable[string] $filters An array of enabling functions taking * the priority as an argument, indexed by * filter group. */ $filters = \apply_filters( 'typo_content_filters', $filters ); /** * Filters the priority used for wp-Typography's text processing filters. * * When NextGen Gallery is detected, the priority is set to PHP_INT_MAX. * * @since 3.2.0 * * @param int $priority The filter priority. Default 9999. */ $priority = \apply_filters( 'typo_filter_priority', $this->filter_priority ); foreach ( $filters as $tag => $enable ) { /** * Disables automatic filtering by wp-Typography. * * @since 3.6.0 * @since 5.2.0 WooCommerce support added ($filter_group 'woocommerce'). * @since 5.6.0 Filter group `title` removed. * * @param bool $disable Whether to disable automatic filtering. Default false. * @param string $filter_group Which filters to disable. Possible values 'content', 'heading', 'acf', 'woocommerce'. */ if ( ! \apply_filters( 'typo_disable_filtering', false, $tag ) ) { $enable( $priority ); } } } /** * Enable the content (body) filters. * * @param int $priority Filter priority. */ private function enable_content_filters( $priority ) : void { \add_filter( 'comment_author', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'the_content', [ $this->api, 'process' ], $priority ); \add_filter( 'term_description', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt_embed', [ $this->api, 'process' ], $priority ); \add_filter( 'wp_dropdown_cats', [ $this->api, 'process' ], $priority ); // FIXME: These should be moved to their own filter group in the next major release. \add_filter( 'term_name', [ $this->api, 'process_feed' ], $priority ); \add_filter( 'link_name', [ $this->api, 'process_feed' ], $priority ); // Preserve shortcode handling on WordPress 4.8+. if ( \version_compare( \get_bloginfo( 'version' ), '4.8', '>=' ) ) { \add_filter( 'widget_text_content', [ $this->api, 'process' ], $priority ); } else { \add_filter( 'widget_text', [ $this->api, 'process' ], $priority ); } } /** * Enable the heading filters. * * @param int $priority Filter priority. */ private function enable_heading_filters( $priority ) : void { \add_filter( 'the_title', [ $this->api, 'process_title' ], $priority ); \add_filter( 'widget_title', [ $this->api, 'process_title' ], $priority ); } /** * Enqueues custom styles. * * @since 5.5.3 */ public function enqueue_styles() : void { // Custom styles set via the CSS Hooks settings page. $custom_styles = \trim( (string) $this->config[ Config::STYLE_CSS ] ); if ( ! empty( $custom_styles ) ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-custom', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-custom' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-custom', $this->clean_styles( $custom_styles ) ); } // The Safari bug workaround. if ( $this->config[ Config::HYPHENATE_SAFARI_FONT_WORKAROUND ] ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-safari-font-workaround', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-safari-font-workaround' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-safari-font-workaround', 'body {-webkit-font-feature-settings: "liga";font-feature-settings: "liga";-ms-font-feature-settings: normal;}' ); } } /** * Enqueues frontend JavaScript files. */ public function enqueue_scripts() : void { if ( $this->config[ Config::HYPHENATE_CLEAN_CLIPBOARD ] ) { // Set up file suffix and plugin version. $suffix = ( \defined( 'SCRIPT_DEBUG' ) && \SCRIPT_DEBUG ) ? '' : '.min'; $version = $this->api->get_version(); $plugin_dir = \plugin_dir_url( \WP_TYPOGRAPHY_PLUGIN_FILE ); \wp_enqueue_script( 'wp-typography-cleanup-clipboard', "{$plugin_dir}js/clean-clipboard$suffix.js", [], $version, true ); } } /** * Cleans up the user-supplied CSS rules for output. Removes comments and most * whitespace and filters the rules through `safecss_filter_attr`. * * @since 5.5.3 * * @param string $css A string of CSS styles. * * @return string Filtered string of CSS styles. */ protected function clean_styles( $css ) : string { $cleaned = (string) \preg_replace( self::CLEAN_CSS_PATTERNS, self::CLEAN_CSS_REPLACEMENTS, $css ); $css = ''; if ( \preg_match_all( '/\s*(?[^{}]+?)\s*\{\s*(?[^{}]+?)\s*\}\s*/sS', $cleaned, $matches, PREG_SET_ORDER ) ) { foreach ( $matches as $m ) { $selector = \wp_strip_all_tags( $m['selector'] ); $rules = \safecss_filter_attr( $m['rules'] ); if ( ! empty( $selector ) && ! empty( $rules ) ) { $css .= "{$selector}{{$rules}}"; } } } return $css; } } p. \add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); // Save hyphenator cache on exit, if necessary. \add_action( 'shutdown', [ $this->api, 'save_hyphenator_cache_on_shutdown' ], 10 ); } /** * Adds content filter handlers. */ public function add_content_filters() : void { // Define the default filters. $filters = [ // Add filters for "full" content. 'content' => [ $this, 'enable_content_filters' ], // Add filters for headings. 'heading' => [ $this, 'enable_heading_filters' ], ]; /** * Filters the content filter enabling functions. * * @internal * * @param callable[string] $filters An array of enabling functions taking * the priority as an argument, indexed by * filter group. */ $filters = \apply_filters( 'typo_content_filters', $filters ); /** * Filters the priority used for wp-Typography's text processing filters. * * When NextGen Gallery is detected, the priority is set to PHP_INT_MAX. * * @since 3.2.0 * * @param int $priority The filter priority. Default 9999. */ $priority = \apply_filters( 'typo_filter_priority', $this->filter_priority ); foreach ( $filters as $tag => $enable ) { /** * Disables automatic filtering by wp-Typography. * * @since 3.6.0 * @since 5.2.0 WooCommerce support added ($filter_group 'woocommerce'). * @since 5.6.0 Filter group `title` removed. * * @param bool $disable Whether to disable automatic filtering. Default false. * @param string $filter_group Which filters to disable. Possible values 'content', 'heading', 'acf', 'woocommerce'. */ if ( ! \apply_filters( 'typo_disable_filtering', false, $tag ) ) { $enable( $priority ); } } } /** * Enable the content (body) filters. * * @param int $priority Filter priority. */ private function enable_content_filters( $priority ) : void { \add_filter( 'comment_author', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'the_content', [ $this->api, 'process' ], $priority ); \add_filter( 'term_description', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt_embed', [ $this->api, 'process' ], $priority ); \add_filter( 'wp_dropdown_cats', [ $this->api, 'process' ], $priority ); // FIXME: These should be moved to their own filter group in the next major release. \add_filter( 'term_name', [ $this->api, 'process_feed' ], $priority ); \add_filter( 'link_name', [ $this->api, 'process_feed' ], $priority ); // Preserve shortcode handling on WordPress 4.8+. if ( \version_compare( \get_bloginfo( 'version' ), '4.8', '>=' ) ) { \add_filter( 'widget_text_content', [ $this->api, 'process' ], $priority ); } else { \add_filter( 'widget_text', [ $this->api, 'process' ], $priority ); } } /** * Enable the heading filters. * * @param int $priority Filter priority. */ private function enable_heading_filters( $priority ) : void { \add_filter( 'the_title', [ $this->api, 'process_title' ], $priority ); \add_filter( 'widget_title', [ $this->api, 'process_title' ], $priority ); } /** * Enqueues custom styles. * * @since 5.5.3 */ public function enqueue_styles() : void { // Custom styles set via the CSS Hooks settings page. $custom_styles = \trim( (string) $this->config[ Config::STYLE_CSS ] ); if ( ! empty( $custom_styles ) ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-custom', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-custom' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-custom', $this->clean_styles( $custom_styles ) ); } // The Safari bug workaround. if ( $this->config[ Config::HYPHENATE_SAFARI_FONT_WORKAROUND ] ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-safari-font-workaround', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-safari-font-workaround' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-safari-font-workaround', 'body {-webkit-font-feature-settings: "liga";font-feature-settings: "liga";-ms-font-feature-settings: normal;}' ); } } /** * Enqueues frontend JavaScript files. */ public function enqueue_scripts() : void { if ( $this->config[ Config::HYPHENATE_CLEAN_CLIPBOARD ] ) { // Set up file suffix and plugin version. $suffix = ( \defined( 'SCRIPT_DEBUG' ) && \SCRIPT_DEBUG ) ? '' : '.min'; $version = $this->api->get_version(); $plugin_dir = \plugin_dir_url( \WP_TYPOGRAPHY_PLUGIN_FILE ); \wp_enqueue_script( 'wp-typography-cleanup-clipboard', "{$plugin_dir}js/clean-clipboard$suffix.js", [], $version, true ); } } /** * Cleans up the user-supplied CSS rules for output. Removes comments and most * whitespace and filters the rules through `safecss_filter_attr`. * * @since 5.5.3 * * @param string $css A string of CSS styles. * * @return string Filtered string of CSS styles. */ protected function clean_styles( $css ) : string { $cleaned = (string) \preg_replace( self::CLEAN_CSS_PATTERNS, self::CLEAN_CSS_REPLACEMENTS, $css ); $css = ''; if ( \preg_match_all( '/\s*(?[^{}]+?)\s*\{\s*(?[^{}]+?)\s*\}\s*/sS', $cleaned, $matches, PREG_SET_ORDER ) ) { foreach ( $matches as $m ) { $selector = \wp_strip_all_tags( $m['selector'] ); $rules = \safecss_filter_attr( $m['rules'] ); if ( ! empty( $selector ) && ! empty( $rules ) ) { $css .= "{$selector}{{$rules}}"; } } } return $css; } } p. \add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); // Save hyphenator cache on exit, if necessary. \add_action( 'shutdown', [ $this->api, 'save_hyphenator_cache_on_shutdown' ], 10 ); } /** * Adds content filter handlers. */ public function add_content_filters() : void { // Define the default filters. $filters = [ // Add filters for "full" content. 'content' => [ $this, 'enable_content_filters' ], // Add filters for headings. 'heading' => [ $this, 'enable_heading_filters' ], ]; /** * Filters the content filter enabling functions. * * @internal * * @param callable[string] $filters An array of enabling functions taking * the priority as an argument, indexed by * filter group. */ $filters = \apply_filters( 'typo_content_filters', $filters ); /** * Filters the priority used for wp-Typography's text processing filters. * * When NextGen Gallery is detected, the priority is set to PHP_INT_MAX. * * @since 3.2.0 * * @param int $priority The filter priority. Default 9999. */ $priority = \apply_filters( 'typo_filter_priority', $this->filter_priority ); foreach ( $filters as $tag => $enable ) { /** * Disables automatic filtering by wp-Typography. * * @since 3.6.0 * @since 5.2.0 WooCommerce support added ($filter_group 'woocommerce'). * @since 5.6.0 Filter group `title` removed. * * @param bool $disable Whether to disable automatic filtering. Default false. * @param string $filter_group Which filters to disable. Possible values 'content', 'heading', 'acf', 'woocommerce'. */ if ( ! \apply_filters( 'typo_disable_filtering', false, $tag ) ) { $enable( $priority ); } } } /** * Enable the content (body) filters. * * @param int $priority Filter priority. */ private function enable_content_filters( $priority ) : void { \add_filter( 'comment_author', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'the_content', [ $this->api, 'process' ], $priority ); \add_filter( 'term_description', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt_embed', [ $this->api, 'process' ], $priority ); \add_filter( 'wp_dropdown_cats', [ $this->api, 'process' ], $priority ); // FIXME: These should be moved to their own filter group in the next major release. \add_filter( 'term_name', [ $this->api, 'process_feed' ], $priority ); \add_filter( 'link_name', [ $this->api, 'process_feed' ], $priority ); // Preserve shortcode handling on WordPress 4.8+. if ( \version_compare( \get_bloginfo( 'version' ), '4.8', '>=' ) ) { \add_filter( 'widget_text_content', [ $this->api, 'process' ], $priority ); } else { \add_filter( 'widget_text', [ $this->api, 'process' ], $priority ); } } /** * Enable the heading filters. * * @param int $priority Filter priority. */ private function enable_heading_filters( $priority ) : void { \add_filter( 'the_title', [ $this->api, 'process_title' ], $priority ); \add_filter( 'widget_title', [ $this->api, 'process_title' ], $priority ); } /** * Enqueues custom styles. * * @since 5.5.3 */ public function enqueue_styles() : void { // Custom styles set via the CSS Hooks settings page. $custom_styles = \trim( (string) $this->config[ Config::STYLE_CSS ] ); if ( ! empty( $custom_styles ) ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-custom', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-custom' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-custom', $this->clean_styles( $custom_styles ) ); } // The Safari bug workaround. if ( $this->config[ Config::HYPHENATE_SAFARI_FONT_WORKAROUND ] ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-safari-font-workaround', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-safari-font-workaround' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-safari-font-workaround', 'body {-webkit-font-feature-settings: "liga";font-feature-settings: "liga";-ms-font-feature-settings: normal;}' ); } } /** * Enqueues frontend JavaScript files. */ public function enqueue_scripts() : void { if ( $this->config[ Config::HYPHENATE_CLEAN_CLIPBOARD ] ) { // Set up file suffix and plugin version. $suffix = ( \defined( 'SCRIPT_DEBUG' ) && \SCRIPT_DEBUG ) ? '' : '.min'; $version = $this->api->get_version(); $plugin_dir = \plugin_dir_url( \WP_TYPOGRAPHY_PLUGIN_FILE ); \wp_enqueue_script( 'wp-typography-cleanup-clipboard', "{$plugin_dir}js/clean-clipboard$suffix.js", [], $version, true ); } } /** * Cleans up the user-supplied CSS rules for output. Removes comments and most * whitespace and filters the rules through `safecss_filter_attr`. * * @since 5.5.3 * * @param string $css A string of CSS styles. * * @return string Filtered string of CSS styles. */ protected function clean_styles( $css ) : string { $cleaned = (string) \preg_replace( self::CLEAN_CSS_PATTERNS, self::CLEAN_CSS_REPLACEMENTS, $css ); $css = ''; if ( \preg_match_all( '/\s*(?[^{}]+?)\s*\{\s*(?[^{}]+?)\s*\}\s*/sS', $cleaned, $matches, PREG_SET_ORDER ) ) { foreach ( $matches as $m ) { $selector = \wp_strip_all_tags( $m['selector'] ); $rules = \safecss_filter_attr( $m['rules'] ); if ( ! empty( $selector ) && ! empty( $rules ) ) { $css .= "{$selector}{{$rules}}"; } } } return $css; } } p. \add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); // Save hyphenator cache on exit, if necessary. \add_action( 'shutdown', [ $this->api, 'save_hyphenator_cache_on_shutdown' ], 10 ); } /** * Adds content filter handlers. */ public function add_content_filters() : void { // Define the default filters. $filters = [ // Add filters for "full" content. 'content' => [ $this, 'enable_content_filters' ], // Add filters for headings. 'heading' => [ $this, 'enable_heading_filters' ], ]; /** * Filters the content filter enabling functions. * * @internal * * @param callable[string] $filters An array of enabling functions taking * the priority as an argument, indexed by * filter group. */ $filters = \apply_filters( 'typo_content_filters', $filters ); /** * Filters the priority used for wp-Typography's text processing filters. * * When NextGen Gallery is detected, the priority is set to PHP_INT_MAX. * * @since 3.2.0 * * @param int $priority The filter priority. Default 9999. */ $priority = \apply_filters( 'typo_filter_priority', $this->filter_priority ); foreach ( $filters as $tag => $enable ) { /** * Disables automatic filtering by wp-Typography. * * @since 3.6.0 * @since 5.2.0 WooCommerce support added ($filter_group 'woocommerce'). * @since 5.6.0 Filter group `title` removed. * * @param bool $disable Whether to disable automatic filtering. Default false. * @param string $filter_group Which filters to disable. Possible values 'content', 'heading', 'acf', 'woocommerce'. */ if ( ! \apply_filters( 'typo_disable_filtering', false, $tag ) ) { $enable( $priority ); } } } /** * Enable the content (body) filters. * * @param int $priority Filter priority. */ private function enable_content_filters( $priority ) : void { \add_filter( 'comment_author', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'the_content', [ $this->api, 'process' ], $priority ); \add_filter( 'term_description', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt_embed', [ $this->api, 'process' ], $priority ); \add_filter( 'wp_dropdown_cats', [ $this->api, 'process' ], $priority ); // FIXME: These should be moved to their own filter group in the next major release. \add_filter( 'term_name', [ $this->api, 'process_feed' ], $priority ); \add_filter( 'link_name', [ $this->api, 'process_feed' ], $priority ); // Preserve shortcode handling on WordPress 4.8+. if ( \version_compare( \get_bloginfo( 'version' ), '4.8', '>=' ) ) { \add_filter( 'widget_text_content', [ $this->api, 'process' ], $priority ); } else { \add_filter( 'widget_text', [ $this->api, 'process' ], $priority ); } } /** * Enable the heading filters. * * @param int $priority Filter priority. */ private function enable_heading_filters( $priority ) : void { \add_filter( 'the_title', [ $this->api, 'process_title' ], $priority ); \add_filter( 'widget_title', [ $this->api, 'process_title' ], $priority ); } /** * Enqueues custom styles. * * @since 5.5.3 */ public function enqueue_styles() : void { // Custom styles set via the CSS Hooks settings page. $custom_styles = \trim( (string) $this->config[ Config::STYLE_CSS ] ); if ( ! empty( $custom_styles ) ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-custom', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-custom' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-custom', $this->clean_styles( $custom_styles ) ); } // The Safari bug workaround. if ( $this->config[ Config::HYPHENATE_SAFARI_FONT_WORKAROUND ] ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-safari-font-workaround', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-safari-font-workaround' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-safari-font-workaround', 'body {-webkit-font-feature-settings: "liga";font-feature-settings: "liga";-ms-font-feature-settings: normal;}' ); } } /** * Enqueues frontend JavaScript files. */ public function enqueue_scripts() : void { if ( $this->config[ Config::HYPHENATE_CLEAN_CLIPBOARD ] ) { // Set up file suffix and plugin version. $suffix = ( \defined( 'SCRIPT_DEBUG' ) && \SCRIPT_DEBUG ) ? '' : '.min'; $version = $this->api->get_version(); $plugin_dir = \plugin_dir_url( \WP_TYPOGRAPHY_PLUGIN_FILE ); \wp_enqueue_script( 'wp-typography-cleanup-clipboard', "{$plugin_dir}js/clean-clipboard$suffix.js", [], $version, true ); } } /** * Cleans up the user-supplied CSS rules for output. Removes comments and most * whitespace and filters the rules through `safecss_filter_attr`. * * @since 5.5.3 * * @param string $css A string of CSS styles. * * @return string Filtered string of CSS styles. */ protected function clean_styles( $css ) : string { $cleaned = (string) \preg_replace( self::CLEAN_CSS_PATTERNS, self::CLEAN_CSS_REPLACEMENTS, $css ); $css = ''; if ( \preg_match_all( '/\s*(?[^{}]+?)\s*\{\s*(?[^{}]+?)\s*\}\s*/sS', $cleaned, $matches, PREG_SET_ORDER ) ) { foreach ( $matches as $m ) { $selector = \wp_strip_all_tags( $m['selector'] ); $rules = \safecss_filter_attr( $m['rules'] ); if ( ! empty( $selector ) && ! empty( $rules ) ) { $css .= "{$selector}{{$rules}}"; } } } return $css; } } p. \add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); // Save hyphenator cache on exit, if necessary. \add_action( 'shutdown', [ $this->api, 'save_hyphenator_cache_on_shutdown' ], 10 ); } /** * Adds content filter handlers. */ public function add_content_filters() : void { // Define the default filters. $filters = [ // Add filters for "full" content. 'content' => [ $this, 'enable_content_filters' ], // Add filters for headings. 'heading' => [ $this, 'enable_heading_filters' ], ]; /** * Filters the content filter enabling functions. * * @internal * * @param callable[string] $filters An array of enabling functions taking * the priority as an argument, indexed by * filter group. */ $filters = \apply_filters( 'typo_content_filters', $filters ); /** * Filters the priority used for wp-Typography's text processing filters. * * When NextGen Gallery is detected, the priority is set to PHP_INT_MAX. * * @since 3.2.0 * * @param int $priority The filter priority. Default 9999. */ $priority = \apply_filters( 'typo_filter_priority', $this->filter_priority ); foreach ( $filters as $tag => $enable ) { /** * Disables automatic filtering by wp-Typography. * * @since 3.6.0 * @since 5.2.0 WooCommerce support added ($filter_group 'woocommerce'). * @since 5.6.0 Filter group `title` removed. * * @param bool $disable Whether to disable automatic filtering. Default false. * @param string $filter_group Which filters to disable. Possible values 'content', 'heading', 'acf', 'woocommerce'. */ if ( ! \apply_filters( 'typo_disable_filtering', false, $tag ) ) { $enable( $priority ); } } } /** * Enable the content (body) filters. * * @param int $priority Filter priority. */ private function enable_content_filters( $priority ) : void { \add_filter( 'comment_author', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'the_content', [ $this->api, 'process' ], $priority ); \add_filter( 'term_description', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt_embed', [ $this->api, 'process' ], $priority ); \add_filter( 'wp_dropdown_cats', [ $this->api, 'process' ], $priority ); // FIXME: These should be moved to their own filter group in the next major release. \add_filter( 'term_name', [ $this->api, 'process_feed' ], $priority ); \add_filter( 'link_name', [ $this->api, 'process_feed' ], $priority ); // Preserve shortcode handling on WordPress 4.8+. if ( \version_compare( \get_bloginfo( 'version' ), '4.8', '>=' ) ) { \add_filter( 'widget_text_content', [ $this->api, 'process' ], $priority ); } else { \add_filter( 'widget_text', [ $this->api, 'process' ], $priority ); } } /** * Enable the heading filters. * * @param int $priority Filter priority. */ private function enable_heading_filters( $priority ) : void { \add_filter( 'the_title', [ $this->api, 'process_title' ], $priority ); \add_filter( 'widget_title', [ $this->api, 'process_title' ], $priority ); } /** * Enqueues custom styles. * * @since 5.5.3 */ public function enqueue_styles() : void { // Custom styles set via the CSS Hooks settings page. $custom_styles = \trim( (string) $this->config[ Config::STYLE_CSS ] ); if ( ! empty( $custom_styles ) ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-custom', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-custom' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-custom', $this->clean_styles( $custom_styles ) ); } // The Safari bug workaround. if ( $this->config[ Config::HYPHENATE_SAFARI_FONT_WORKAROUND ] ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-safari-font-workaround', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-safari-font-workaround' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-safari-font-workaround', 'body {-webkit-font-feature-settings: "liga";font-feature-settings: "liga";-ms-font-feature-settings: normal;}' ); } } /** * Enqueues frontend JavaScript files. */ public function enqueue_scripts() : void { if ( $this->config[ Config::HYPHENATE_CLEAN_CLIPBOARD ] ) { // Set up file suffix and plugin version. $suffix = ( \defined( 'SCRIPT_DEBUG' ) && \SCRIPT_DEBUG ) ? '' : '.min'; $version = $this->api->get_version(); $plugin_dir = \plugin_dir_url( \WP_TYPOGRAPHY_PLUGIN_FILE ); \wp_enqueue_script( 'wp-typography-cleanup-clipboard', "{$plugin_dir}js/clean-clipboard$suffix.js", [], $version, true ); } } /** * Cleans up the user-supplied CSS rules for output. Removes comments and most * whitespace and filters the rules through `safecss_filter_attr`. * * @since 5.5.3 * * @param string $css A string of CSS styles. * * @return string Filtered string of CSS styles. */ protected function clean_styles( $css ) : string { $cleaned = (string) \preg_replace( self::CLEAN_CSS_PATTERNS, self::CLEAN_CSS_REPLACEMENTS, $css ); $css = ''; if ( \preg_match_all( '/\s*(?[^{}]+?)\s*\{\s*(?[^{}]+?)\s*\}\s*/sS', $cleaned, $matches, PREG_SET_ORDER ) ) { foreach ( $matches as $m ) { $selector = \wp_strip_all_tags( $m['selector'] ); $rules = \safecss_filter_attr( $m['rules'] ); if ( ! empty( $selector ) && ! empty( $rules ) ) { $css .= "{$selector}{{$rules}}"; } } } return $css; } } p. \add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); // Save hyphenator cache on exit, if necessary. \add_action( 'shutdown', [ $this->api, 'save_hyphenator_cache_on_shutdown' ], 10 ); } /** * Adds content filter handlers. */ public function add_content_filters() : void { // Define the default filters. $filters = [ // Add filters for "full" content. 'content' => [ $this, 'enable_content_filters' ], // Add filters for headings. 'heading' => [ $this, 'enable_heading_filters' ], ]; /** * Filters the content filter enabling functions. * * @internal * * @param callable[string] $filters An array of enabling functions taking * the priority as an argument, indexed by * filter group. */ $filters = \apply_filters( 'typo_content_filters', $filters ); /** * Filters the priority used for wp-Typography's text processing filters. * * When NextGen Gallery is detected, the priority is set to PHP_INT_MAX. * * @since 3.2.0 * * @param int $priority The filter priority. Default 9999. */ $priority = \apply_filters( 'typo_filter_priority', $this->filter_priority ); foreach ( $filters as $tag => $enable ) { /** * Disables automatic filtering by wp-Typography. * * @since 3.6.0 * @since 5.2.0 WooCommerce support added ($filter_group 'woocommerce'). * @since 5.6.0 Filter group `title` removed. * * @param bool $disable Whether to disable automatic filtering. Default false. * @param string $filter_group Which filters to disable. Possible values 'content', 'heading', 'acf', 'woocommerce'. */ if ( ! \apply_filters( 'typo_disable_filtering', false, $tag ) ) { $enable( $priority ); } } } /** * Enable the content (body) filters. * * @param int $priority Filter priority. */ private function enable_content_filters( $priority ) : void { \add_filter( 'comment_author', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'the_content', [ $this->api, 'process' ], $priority ); \add_filter( 'term_description', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt_embed', [ $this->api, 'process' ], $priority ); \add_filter( 'wp_dropdown_cats', [ $this->api, 'process' ], $priority ); // FIXME: These should be moved to their own filter group in the next major release. \add_filter( 'term_name', [ $this->api, 'process_feed' ], $priority ); \add_filter( 'link_name', [ $this->api, 'process_feed' ], $priority ); // Preserve shortcode handling on WordPress 4.8+. if ( \version_compare( \get_bloginfo( 'version' ), '4.8', '>=' ) ) { \add_filter( 'widget_text_content', [ $this->api, 'process' ], $priority ); } else { \add_filter( 'widget_text', [ $this->api, 'process' ], $priority ); } } /** * Enable the heading filters. * * @param int $priority Filter priority. */ private function enable_heading_filters( $priority ) : void { \add_filter( 'the_title', [ $this->api, 'process_title' ], $priority ); \add_filter( 'widget_title', [ $this->api, 'process_title' ], $priority ); } /** * Enqueues custom styles. * * @since 5.5.3 */ public function enqueue_styles() : void { // Custom styles set via the CSS Hooks settings page. $custom_styles = \trim( (string) $this->config[ Config::STYLE_CSS ] ); if ( ! empty( $custom_styles ) ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-custom', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-custom' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-custom', $this->clean_styles( $custom_styles ) ); } // The Safari bug workaround. if ( $this->config[ Config::HYPHENATE_SAFARI_FONT_WORKAROUND ] ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-safari-font-workaround', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-safari-font-workaround' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-safari-font-workaround', 'body {-webkit-font-feature-settings: "liga";font-feature-settings: "liga";-ms-font-feature-settings: normal;}' ); } } /** * Enqueues frontend JavaScript files. */ public function enqueue_scripts() : void { if ( $this->config[ Config::HYPHENATE_CLEAN_CLIPBOARD ] ) { // Set up file suffix and plugin version. $suffix = ( \defined( 'SCRIPT_DEBUG' ) && \SCRIPT_DEBUG ) ? '' : '.min'; $version = $this->api->get_version(); $plugin_dir = \plugin_dir_url( \WP_TYPOGRAPHY_PLUGIN_FILE ); \wp_enqueue_script( 'wp-typography-cleanup-clipboard', "{$plugin_dir}js/clean-clipboard$suffix.js", [], $version, true ); } } /** * Cleans up the user-supplied CSS rules for output. Removes comments and most * whitespace and filters the rules through `safecss_filter_attr`. * * @since 5.5.3 * * @param string $css A string of CSS styles. * * @return string Filtered string of CSS styles. */ protected function clean_styles( $css ) : string { $cleaned = (string) \preg_replace( self::CLEAN_CSS_PATTERNS, self::CLEAN_CSS_REPLACEMENTS, $css ); $css = ''; if ( \preg_match_all( '/\s*(?[^{}]+?)\s*\{\s*(?[^{}]+?)\s*\}\s*/sS', $cleaned, $matches, PREG_SET_ORDER ) ) { foreach ( $matches as $m ) { $selector = \wp_strip_all_tags( $m['selector'] ); $rules = \safecss_filter_attr( $m['rules'] ); if ( ! empty( $selector ) && ! empty( $rules ) ) { $css .= "{$selector}{{$rules}}"; } } } return $css; } } p. \add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); // Save hyphenator cache on exit, if necessary. \add_action( 'shutdown', [ $this->api, 'save_hyphenator_cache_on_shutdown' ], 10 ); } /** * Adds content filter handlers. */ public function add_content_filters() : void { // Define the default filters. $filters = [ // Add filters for "full" content. 'content' => [ $this, 'enable_content_filters' ], // Add filters for headings. 'heading' => [ $this, 'enable_heading_filters' ], ]; /** * Filters the content filter enabling functions. * * @internal * * @param callable[string] $filters An array of enabling functions taking * the priority as an argument, indexed by * filter group. */ $filters = \apply_filters( 'typo_content_filters', $filters ); /** * Filters the priority used for wp-Typography's text processing filters. * * When NextGen Gallery is detected, the priority is set to PHP_INT_MAX. * * @since 3.2.0 * * @param int $priority The filter priority. Default 9999. */ $priority = \apply_filters( 'typo_filter_priority', $this->filter_priority ); foreach ( $filters as $tag => $enable ) { /** * Disables automatic filtering by wp-Typography. * * @since 3.6.0 * @since 5.2.0 WooCommerce support added ($filter_group 'woocommerce'). * @since 5.6.0 Filter group `title` removed. * * @param bool $disable Whether to disable automatic filtering. Default false. * @param string $filter_group Which filters to disable. Possible values 'content', 'heading', 'acf', 'woocommerce'. */ if ( ! \apply_filters( 'typo_disable_filtering', false, $tag ) ) { $enable( $priority ); } } } /** * Enable the content (body) filters. * * @param int $priority Filter priority. */ private function enable_content_filters( $priority ) : void { \add_filter( 'comment_author', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'the_content', [ $this->api, 'process' ], $priority ); \add_filter( 'term_description', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt_embed', [ $this->api, 'process' ], $priority ); \add_filter( 'wp_dropdown_cats', [ $this->api, 'process' ], $priority ); // FIXME: These should be moved to their own filter group in the next major release. \add_filter( 'term_name', [ $this->api, 'process_feed' ], $priority ); \add_filter( 'link_name', [ $this->api, 'process_feed' ], $priority ); // Preserve shortcode handling on WordPress 4.8+. if ( \version_compare( \get_bloginfo( 'version' ), '4.8', '>=' ) ) { \add_filter( 'widget_text_content', [ $this->api, 'process' ], $priority ); } else { \add_filter( 'widget_text', [ $this->api, 'process' ], $priority ); } } /** * Enable the heading filters. * * @param int $priority Filter priority. */ private function enable_heading_filters( $priority ) : void { \add_filter( 'the_title', [ $this->api, 'process_title' ], $priority ); \add_filter( 'widget_title', [ $this->api, 'process_title' ], $priority ); } /** * Enqueues custom styles. * * @since 5.5.3 */ public function enqueue_styles() : void { // Custom styles set via the CSS Hooks settings page. $custom_styles = \trim( (string) $this->config[ Config::STYLE_CSS ] ); if ( ! empty( $custom_styles ) ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-custom', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-custom' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-custom', $this->clean_styles( $custom_styles ) ); } // The Safari bug workaround. if ( $this->config[ Config::HYPHENATE_SAFARI_FONT_WORKAROUND ] ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-safari-font-workaround', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-safari-font-workaround' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-safari-font-workaround', 'body {-webkit-font-feature-settings: "liga";font-feature-settings: "liga";-ms-font-feature-settings: normal;}' ); } } /** * Enqueues frontend JavaScript files. */ public function enqueue_scripts() : void { if ( $this->config[ Config::HYPHENATE_CLEAN_CLIPBOARD ] ) { // Set up file suffix and plugin version. $suffix = ( \defined( 'SCRIPT_DEBUG' ) && \SCRIPT_DEBUG ) ? '' : '.min'; $version = $this->api->get_version(); $plugin_dir = \plugin_dir_url( \WP_TYPOGRAPHY_PLUGIN_FILE ); \wp_enqueue_script( 'wp-typography-cleanup-clipboard', "{$plugin_dir}js/clean-clipboard$suffix.js", [], $version, true ); } } /** * Cleans up the user-supplied CSS rules for output. Removes comments and most * whitespace and filters the rules through `safecss_filter_attr`. * * @since 5.5.3 * * @param string $css A string of CSS styles. * * @return string Filtered string of CSS styles. */ protected function clean_styles( $css ) : string { $cleaned = (string) \preg_replace( self::CLEAN_CSS_PATTERNS, self::CLEAN_CSS_REPLACEMENTS, $css ); $css = ''; if ( \preg_match_all( '/\s*(?[^{}]+?)\s*\{\s*(?[^{}]+?)\s*\}\s*/sS', $cleaned, $matches, PREG_SET_ORDER ) ) { foreach ( $matches as $m ) { $selector = \wp_strip_all_tags( $m['selector'] ); $rules = \safecss_filter_attr( $m['rules'] ); if ( ! empty( $selector ) && ! empty( $rules ) ) { $css .= "{$selector}{{$rules}}"; } } } return $css; } } p. \add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_scripts' ] ); // Save hyphenator cache on exit, if necessary. \add_action( 'shutdown', [ $this->api, 'save_hyphenator_cache_on_shutdown' ], 10 ); } /** * Adds content filter handlers. */ public function add_content_filters() : void { // Define the default filters. $filters = [ // Add filters for "full" content. 'content' => [ $this, 'enable_content_filters' ], // Add filters for headings. 'heading' => [ $this, 'enable_heading_filters' ], ]; /** * Filters the content filter enabling functions. * * @internal * * @param callable[string] $filters An array of enabling functions taking * the priority as an argument, indexed by * filter group. */ $filters = \apply_filters( 'typo_content_filters', $filters ); /** * Filters the priority used for wp-Typography's text processing filters. * * When NextGen Gallery is detected, the priority is set to PHP_INT_MAX. * * @since 3.2.0 * * @param int $priority The filter priority. Default 9999. */ $priority = \apply_filters( 'typo_filter_priority', $this->filter_priority ); foreach ( $filters as $tag => $enable ) { /** * Disables automatic filtering by wp-Typography. * * @since 3.6.0 * @since 5.2.0 WooCommerce support added ($filter_group 'woocommerce'). * @since 5.6.0 Filter group `title` removed. * * @param bool $disable Whether to disable automatic filtering. Default false. * @param string $filter_group Which filters to disable. Possible values 'content', 'heading', 'acf', 'woocommerce'. */ if ( ! \apply_filters( 'typo_disable_filtering', false, $tag ) ) { $enable( $priority ); } } } /** * Enable the content (body) filters. * * @param int $priority Filter priority. */ private function enable_content_filters( $priority ) : void { \add_filter( 'comment_author', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'comment_text', [ $this->api, 'process' ], $priority ); \add_filter( 'the_content', [ $this->api, 'process' ], $priority ); \add_filter( 'term_description', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt', [ $this->api, 'process' ], $priority ); \add_filter( 'the_excerpt_embed', [ $this->api, 'process' ], $priority ); \add_filter( 'wp_dropdown_cats', [ $this->api, 'process' ], $priority ); // FIXME: These should be moved to their own filter group in the next major release. \add_filter( 'term_name', [ $this->api, 'process_feed' ], $priority ); \add_filter( 'link_name', [ $this->api, 'process_feed' ], $priority ); // Preserve shortcode handling on WordPress 4.8+. if ( \version_compare( \get_bloginfo( 'version' ), '4.8', '>=' ) ) { \add_filter( 'widget_text_content', [ $this->api, 'process' ], $priority ); } else { \add_filter( 'widget_text', [ $this->api, 'process' ], $priority ); } } /** * Enable the heading filters. * * @param int $priority Filter priority. */ private function enable_heading_filters( $priority ) : void { \add_filter( 'the_title', [ $this->api, 'process_title' ], $priority ); \add_filter( 'widget_title', [ $this->api, 'process_title' ], $priority ); } /** * Enqueues custom styles. * * @since 5.5.3 */ public function enqueue_styles() : void { // Custom styles set via the CSS Hooks settings page. $custom_styles = \trim( (string) $this->config[ Config::STYLE_CSS ] ); if ( ! empty( $custom_styles ) ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-custom', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-custom' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-custom', $this->clean_styles( $custom_styles ) ); } // The Safari bug workaround. if ( $this->config[ Config::HYPHENATE_SAFARI_FONT_WORKAROUND ] ) { // Register and enqueue dummy stylesheet. \wp_register_style( 'wp-typography-safari-font-workaround', '' ); // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- only inline. \wp_enqueue_style( 'wp-typography-safari-font-workaround' ); // Print the inline styles. \wp_add_inline_style( 'wp-typography-safari-font-workaround', 'body {-webkit-font-feature-settings: "liga";font-feature-settings: "liga";-ms-font-feature-settings: normal;}' ); } } /** * Enqueues frontend JavaScript files. */ public function enqueue_scripts() : void { if ( $this->config[ Config::HYPHENATE_CLEAN_CLIPBOARD ] ) { // Set up file suffix and plugin version. $suffix = ( \defined( 'SCRIPT_DEBUG' ) && \SCRIPT_DEBUG ) ? '' : '.min'; $version = $this->api->get_version(); $plugin_dir = \plugin_dir_url( \WP_TYPOGRAPHY_PLUGIN_FILE ); \wp_enqueue_script( 'wp-typography-cleanup-clipboard', "{$plugin_dir}js/clean-clipboard$suffix.js", [], $version, true ); } } /** * Cleans up the user-supplied CSS rules for output. Removes comments and most * whitespace and filters the rules through `safecss_filter_attr`. * * @since 5.5.3 * * @param string $css A string of CSS styles. * * @return string Filtered string of CSS styles. */ protected function clean_styles( $css ) : string { $cleaned = (string) \preg_replace( self::CLEAN_CSS_PATTERNS, self::CLEAN_CSS_REPLACEMENTS, $css ); $css = ''; if ( \preg_match_all( '/\s*(?[^{}]+?)\s*\{\s*(?[^{}]+?)\s*\}\s*/sS', $cleaned, $matches, PREG_SET_ORDER ) ) { foreach ( $matches as $m ) { $selector = \wp_strip_all_tags( $m['selector'] ); $rules = \safecss_filter_attr( $m['rules'] ); if ( ! empty( $selector ) && ! empty( $rules ) ) { $css .= "{$selector}{{$rules}}"; } } } return $css; } }