类文档

WP_Style_Engine_Processor

💡 云策文档标注

概述

WP_Style_Engine_Processor 是 WordPress 6.1.0 引入的核心类,用于从存储或 CSS 规则集合中编译样式。它提供方法来添加规则和存储,并支持优化和美化 CSS 输出。

关键要点

  • 核心功能:编译样式,支持从 WP_Style_Engine_CSS_Rules_Store 添加存储或直接添加 WP_Style_Engine_CSS_Rule 规则。
  • 主要方法:包括 add_store()、add_rules()、get_css() 和私有方法 combine_rules_selectors(),用于管理规则和生成 CSS 字符串。
  • 优化选项:get_css() 方法接受选项参数,如 optimize 用于合并相同声明的选择器,prettify 用于美化输出(默认基于 SCRIPT_DEBUG 常量)。
  • 版本历史:自 WordPress 6.1.0 引入,后续版本如 6.4.0 和 6.6.0 有功能更新。

代码示例

// 示例:使用 WP_Style_Engine_Processor 添加规则并获取 CSS
$processor = new WP_Style_Engine_Processor();
$rule = new WP_Style_Engine_CSS_Rule('.example', array('color' => 'red'));
$processor->add_rules($rule);
$css = $processor->get_css(array('optimize' => true, 'prettify' => true));
echo $css;

注意事项

  • add_store() 方法要求参数必须是 WP_Style_Engine_CSS_Rules_Store 的实例,否则会触发 _doing_it_wrong 警告。
  • add_rules() 方法支持单个或数组形式的 WP_Style_Engine_CSS_Rule 对象,并自动处理规则组和选择器重复。
  • combine_rules_selectors() 是私有方法,仅在 optimize 选项为 true 时内部调用,用于合并具有相同样式的选择器。
  • get_css() 方法默认不优化输出,prettify 默认值取决于 SCRIPT_DEBUG 常量是否定义。

📄 原文内容

Core class used to compile styles from stores or collection of CSS rules.

Methods

Name Description
WP_Style_Engine_Processor::add_rules Adds rules to be processed.
WP_Style_Engine_Processor::add_store Adds a store to the processor.
WP_Style_Engine_Processor::combine_rules_selectors Combines selectors from the rules store when they have the same styles.
WP_Style_Engine_Processor::get_css Gets the CSS rules as a string.

Source

class WP_Style_Engine_Processor {

	/**
	 * A collection of Style Engine Store objects.
	 *
	 * @since 6.1.0
	 * @var WP_Style_Engine_CSS_Rules_Store[]
	 */
	protected $stores = array();

	/**
	 * The set of CSS rules that this processor will work on.
	 *
	 * @since 6.1.0
	 * @var WP_Style_Engine_CSS_Rule[]
	 */
	protected $css_rules = array();

	/**
	 * Adds a store to the processor.
	 *
	 * @since 6.1.0
	 *
	 * @param WP_Style_Engine_CSS_Rules_Store $store The store to add.
	 * @return WP_Style_Engine_Processor Returns the object to allow chaining methods.
	 */
	public function add_store( $store ) {
		if ( ! $store instanceof WP_Style_Engine_CSS_Rules_Store ) {
			_doing_it_wrong(
				__METHOD__,
				__( '$store must be an instance of WP_Style_Engine_CSS_Rules_Store' ),
				'6.1.0'
			);
			return $this;
		}

		$this->stores[ $store->get_name() ] = $store;

		return $this;
	}

	/**
	 * Adds rules to be processed.
	 *
	 * @since 6.1.0
	 * @since 6.6.0 Added support for rules_group.
	 *
	 * @param WP_Style_Engine_CSS_Rule|WP_Style_Engine_CSS_Rule[] $css_rules A single, or an array of,
	 *                                                                       WP_Style_Engine_CSS_Rule objects
	 *                                                                       from a store or otherwise.
	 * @return WP_Style_Engine_Processor Returns the object to allow chaining methods.
	 */
	public function add_rules( $css_rules ) {
		if ( ! is_array( $css_rules ) ) {
			$css_rules = array( $css_rules );
		}

		foreach ( $css_rules as $rule ) {
			$selector    = $rule->get_selector();
			$rules_group = $rule->get_rules_group();

			/**
			 * If there is a rules_group and it already exists in the css_rules array,
			 * add the rule to it.
			 * Otherwise, create a new entry for the rules_group.
			 */
			if ( ! empty( $rules_group ) ) {
				if ( isset( $this->css_rules[ "$rules_group $selector" ] ) ) {
					$this->css_rules[ "$rules_group $selector" ]->add_declarations( $rule->get_declarations() );
					continue;
				}
				$this->css_rules[ "$rules_group $selector" ] = $rule;
				continue;
			}

			// If the selector already exists, add the declarations to it.
			if ( isset( $this->css_rules[ $selector ] ) ) {
				$this->css_rules[ $selector ]->add_declarations( $rule->get_declarations() );
				continue;
			}
			$this->css_rules[ $rule->get_selector() ] = $rule;
		}

		return $this;
	}

	/**
	 * Gets the CSS rules as a string.
	 *
	 * @since 6.1.0
	 * @since 6.4.0 The Optimization is no longer the default.
	 *
	 * @param array $options   {
	 *     Optional. An array of options. Default empty array.
	 *
	 *     @type bool $optimize Whether to optimize the CSS output, e.g. combine rules.
	 *                          Default false.
	 *     @type bool $prettify Whether to add new lines and indents to output.
	 *                          Defaults to whether the `SCRIPT_DEBUG` constant is defined.
	 * }
	 * @return string The computed CSS.
	 */
	public function get_css( $options = array() ) {
		$defaults = array(
			'optimize' => false,
			'prettify' => defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG,
		);
		$options  = wp_parse_args( $options, $defaults );

		// If we have stores, get the rules from them.
		foreach ( $this->stores as $store ) {
			$this->add_rules( $store->get_all_rules() );
		}

		// Combine CSS selectors that have identical declarations.
		if ( true === $options['optimize'] ) {
			$this->combine_rules_selectors();
		}

		// Build the CSS.
		$css = '';
		foreach ( $this->css_rules as $rule ) {
			// See class WP_Style_Engine_CSS_Rule for the get_css method.
			$css .= $rule->get_css( $options['prettify'] );
			$css .= $options['prettify'] ? "n" : '';
		}
		return $css;
	}

	/**
	 * Combines selectors from the rules store when they have the same styles.
	 *
	 * @since 6.1.0
	 */
	private function combine_rules_selectors() {
		// Build an array of selectors along with the JSON-ified styles to make comparisons easier.
		$selectors_json = array();
		foreach ( $this->css_rules as $rule ) {
			$declarations = $rule->get_declarations()->get_declarations();
			ksort( $declarations );
			$selectors_json[ $rule->get_selector() ] = wp_json_encode( $declarations );
		}

		// Combine selectors that have the same styles.
		foreach ( $selectors_json as $selector => $json ) {
			// Get selectors that use the same styles.
			$duplicates = array_keys( $selectors_json, $json, true );
			// Skip if there are no duplicates.
			if ( 1 >= count( $duplicates ) ) {
				continue;
			}

			$declarations = $this->css_rules[ $selector ]->get_declarations();

			foreach ( $duplicates as $key ) {
				// Unset the duplicates from the $selectors_json array to avoid looping through them as well.
				unset( $selectors_json[ $key ] );
				// Remove the rules from the rules collection.
				unset( $this->css_rules[ $key ] );
			}
			// Create a new rule with the combined selectors.
			$duplicate_selectors                     = implode( ',', $duplicates );
			$this->css_rules[ $duplicate_selectors ] = new WP_Style_Engine_CSS_Rule( $duplicate_selectors, $declarations );
		}
	}
}

Changelog

Version Description
6.1.0 Introduced.