Automattic\WooCommerce\Vendor\Pelago\Emogrifier
CssInliner::collateCssRules
Collates the individual rules from a CssDocument object.
Method of the class: CssInliner{}
No Hooks.
Returns
Arraystyle attributes and the key "uninlinable" containing rules which cannot. Each value is an array of sub-arrays with the following keys:
- "media" (the media query string, e.g. "@media screen and (max-width: 480px)", or an empty string if not from a
@mediarule); - "selector" (the CSS selector, e.g., "*" or "header h1");
- "hasUnmatchablePseudo" (
trueif that selector contains pseudo-elements or dynamic pseudo-classes such that the declarations cannot be applied inline); - "declarationsBlock" (the semicolon-separated CSS declarations for that selector, e.g.,
color: red; height: 4px;); - "line" (the line number, e.g. 42).
Usage
// private - for code of main (parent) class only $result = $this->collateCssRules( $parsedCss ): array;
- $parsedCss(CssDocument) (required)
- .
CssInliner::collateCssRules() CssInliner::collateCssRules code WC 10.4.3
private function collateCssRules(CssDocument $parsedCss): array
{
$matches = $parsedCss->getStyleRulesData(\array_keys($this->allowedMediaTypes));
$preg = (new Preg())->throwExceptions($this->debug);
$cssRules = [
'inlinable' => [],
'uninlinable' => [],
];
foreach ($matches as $key => $cssRule) {
if (!$cssRule->hasAtLeastOneDeclaration()) {
continue;
}
$mediaQuery = $cssRule->getContainingAtRule();
$declarationsBlock = $cssRule->getDeclarationAsText();
$selectors = $cssRule->getSelectors();
// Maybe exclude CSS selectors
if (\count($this->excludedCssSelectors) > 0) {
// Normalize spaces, line breaks & tabs
$selectorsNormalized = \array_map(static function (string $selector) use ($preg): string {
return $preg->replace('@\\s++@u', ' ', $selector);
}, $selectors);
$selectors = \array_filter($selectorsNormalized, function (string $selector): bool {
return !isset($this->excludedCssSelectors[$selector]);
});
}
foreach ($selectors as $selector) {
// don't process pseudo-elements and behavioral (dynamic) pseudo-classes;
// only allow structural pseudo-classes
$hasPseudoElement = \strpos($selector, '::') !== false;
$hasUnmatchablePseudo = $hasPseudoElement || $this->hasUnsupportedPseudoClass($selector);
$parsedCssRule = [
'media' => $mediaQuery,
'selector' => $selector,
'hasUnmatchablePseudo' => $hasUnmatchablePseudo,
'declarationsBlock' => $declarationsBlock,
// keep track of where it appears in the file, since order is important
'line' => $key,
];
$ruleType = (!$cssRule->hasContainingAtRule() && !$hasUnmatchablePseudo) ? 'inlinable' : 'uninlinable';
$cssRules[$ruleType][] = $parsedCssRule;
}
}
\usort(
$cssRules['inlinable'],
/**
* @param array{selector: string, line: int, ...} $first
* @param array{selector: string, line: int, ...} $second
*/
function (array $first, array $second): int {
return $this->sortBySelectorPrecedence($first, $second);
}
);
return $cssRules;
}