8889841cPKT®[Aq—|| StyleRule.phpnu„[µü¤declarationBlock = $declarationBlock; $this->containingAtRule = \trim($containingAtRule); } /** * @return array the selectors, e.g. `["h1", "p"]` */ public function getSelectors(): array { /** @var array $selectors */ $selectors = $this->declarationBlock->getSelectors(); return \array_map( static function (Selector $selector): string { return (string)$selector; }, $selectors ); } /** * @return string the CSS declarations, separated and followed by a semicolon, e.g., `color: red; height: 4px;` */ public function getDeclarationAsText(): string { return \implode(' ', $this->declarationBlock->getRules()); } /** * Checks whether the declaration block has at least one declaration. */ public function hasAtLeastOneDeclaration(): bool { return $this->declarationBlock->getRules() !== []; } /** * @returns string e.g. `@media screen and (max-width: 480px)`, or an empty string */ public function getContainingAtRule(): string { return $this->containingAtRule; } /** * Checks whether the containing at-rule is non-empty and has any non-whitespace characters. */ public function hasContainingAtRule(): bool { return $this->getContainingAtRule() !== ''; } } PKT®[ÀåY¬ççCssDocument.phpnu„[µü¤parse(); $this->sabberwormCssDocument = $sabberwormCssDocument; } /** * Collates the media query, selectors and declarations for individual rules from the parsed CSS, in order. * * @param array $allowedMediaTypes * * @return array */ public function getStyleRulesData(array $allowedMediaTypes): array { $ruleMatches = []; /** @var CssRenderable $rule */ foreach ($this->sabberwormCssDocument->getContents() as $rule) { if ($rule instanceof CssAtRuleBlockList) { $containingAtRule = $this->getFilteredAtIdentifierAndRule($rule, $allowedMediaTypes); if (\is_string($containingAtRule)) { /** @var CssRenderable $nestedRule */ foreach ($rule->getContents() as $nestedRule) { if ($nestedRule instanceof CssDeclarationBlock) { $ruleMatches[] = new StyleRule($nestedRule, $containingAtRule); } } } } elseif ($rule instanceof CssDeclarationBlock) { $ruleMatches[] = new StyleRule($rule); } } return $ruleMatches; } /** * Renders at-rules from the parsed CSS that are valid and not conditional group rules (i.e. not rules such as * `@media` which contain style rules whose data is returned by {@see getStyleRulesData}). Also does not render * `@charset` rules; these are discarded (only UTF-8 is supported). * * @return string */ public function renderNonConditionalAtRules(): string { $this->isImportRuleAllowed = true; /** @var array $cssContents */ $cssContents = $this->sabberwormCssDocument->getContents(); $atRules = \array_filter($cssContents, [$this, 'isValidAtRuleToRender']); if ($atRules === []) { return ''; } $atRulesDocument = new SabberwormCssDocument(); $atRulesDocument->setContents($atRules); /** @var string $renderedRules */ $renderedRules = $atRulesDocument->render(); return $renderedRules; } /** * @param CssAtRuleBlockList $rule * @param array $allowedMediaTypes * * @return ?string * If the nested at-rule is supported, it's opening declaration (e.g. "@media (max-width: 768px)") is * returned; otherwise the return value is null. */ private function getFilteredAtIdentifierAndRule(CssAtRuleBlockList $rule, array $allowedMediaTypes): ?string { $result = null; if ($rule->atRuleName() === 'media') { /** @var string $mediaQueryList */ $mediaQueryList = $rule->atRuleArgs(); [$mediaType] = \explode('(', $mediaQueryList, 2); if (\trim($mediaType) !== '') { $escapedAllowedMediaTypes = \array_map( static function (string $allowedMediaType): string { return \preg_quote($allowedMediaType, '/'); }, $allowedMediaTypes ); $mediaTypesMatcher = \implode('|', $escapedAllowedMediaTypes); $isAllowed = \preg_match('/^\\s*+(?:only\\s++)?+(?:' . $mediaTypesMatcher . ')/i', $mediaType) > 0; } else { $isAllowed = true; } if ($isAllowed) { $result = '@media ' . $mediaQueryList; } } return $result; } /** * Tests if a CSS rule is an at-rule that should be passed though and copied to a `