PluginProbe ʕ •ᴥ•ʔ
Paid Membership Plugin, Ecommerce, User Registration Form, Login Form, User Profile & Restrict Content – ProfilePress / 4.17.0
Paid Membership Plugin, Ecommerce, User Registration Form, Login Form, User Profile & Restrict Content – ProfilePress v4.17.0
4.17.2 4.17.1 4.17.0 4.16.19 4.16.18 4.16.17 4.16.16 trunk 1.0 1.0.1 1.0.2 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.5a 1.1.6 1.1.7 1.2 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.3 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.4 1.4.1 1.4.2 1.5 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.6 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.7 1.7.1 1.7.2 1.8 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.1.9 2.2.10 2.2.11 2.2.12 2.2.13 2.2.14 2.2.15 2.2.16 2.2.2 2.2.5 2.2.6 2.2.7 2.2.8 2.2.9 3.0 3.1 3.1.1 3.1.10 3.1.11 3.1.12 3.1.13 3.1.14 3.1.15 3.1.16 3.1.17 3.1.18 3.1.19 3.1.2 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.2.0 3.2.1 3.2.10 3.2.11 3.2.12 3.2.13 3.2.14 3.2.15 3.2.16 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.2.7 3.2.8 3.2.9 4.0.0 4.0.1 4.0.2 4.0.3 4.1.0 4.1.1 4.1.2 4.1.3 4.1.4 4.10.0 4.10.1 4.10.2 4.10.3 4.11.0 4.12.0 4.13.0 4.13.1 4.13.2 4.13.3 4.13.4 4.14.0 4.14.1 4.14.2 4.14.3 4.14.4 4.15.0 4.15.1 4.15.10 4.15.11 4.15.12 4.15.13 4.15.14 4.15.15 4.15.16 4.15.17 4.15.18 4.15.19 4.15.2 4.15.20 4.15.20.1 4.15.21 4.15.22 4.15.23 4.15.24 4.15.25 4.15.3 4.15.4 4.15.5 4.15.6 4.15.7 4.15.8 4.15.9 4.16.0 4.16.1 4.16.10 4.16.11 4.16.12 4.16.13 4.16.14 4.16.15 4.16.2 4.16.3 4.16.4 4.16.5 4.16.6 4.16.7 4.16.8 4.16.9 4.2.0 4.3.0 4.3.1 4.3.2 4.4.0 4.4.1 4.5.0 4.5.1 4.5.2 4.5.3 4.5.4 4.5.5 4.6.0 4.7.0 4.8.0 4.9.0
wp-user-avatar / third-party / vendor / pelago / emogrifier / src / Utilities / CssConcatenator.php
wp-user-avatar / third-party / vendor / pelago / emogrifier / src / Utilities Last commit date
ArrayIntersector.php 2 months ago CssConcatenator.php 2 months ago
CssConcatenator.php
166 lines
1 <?php
2
3 declare (strict_types=1);
4 namespace ProfilePressVendor\Pelago\Emogrifier\Utilities;
5
6 /**
7 * Facilitates building a CSS string by appending rule blocks one at a time, checking whether the media query,
8 * selectors, or declarations block are the same as those from the preceding block and combining blocks in such cases.
9 *
10 * Example:
11 * $concatenator = new CssConcatenator();
12 * $concatenator->append(['body'], 'color: blue;');
13 * $concatenator->append(['body'], 'font-size: 16px;');
14 * $concatenator->append(['p'], 'margin: 1em 0;');
15 * $concatenator->append(['ul', 'ol'], 'margin: 1em 0;');
16 * $concatenator->append(['body'], 'font-size: 14px;', '@media screen and (max-width: 400px)');
17 * $concatenator->append(['ul', 'ol'], 'margin: 0.75em 0;', '@media screen and (max-width: 400px)');
18 * $css = $concatenator->getCss();
19 *
20 * `$css` (if unminified) would contain the following CSS:
21 * ` body {
22 * ` color: blue;
23 * ` font-size: 16px;
24 * ` }
25 * ` p, ul, ol {
26 * ` margin: 1em 0;
27 * ` }
28 * ` @media screen and (max-width: 400px) {
29 * ` body {
30 * ` font-size: 14px;
31 * ` }
32 * ` ul, ol {
33 * ` margin: 0.75em 0;
34 * ` }
35 * ` }
36 *
37 * @internal
38 */
39 class CssConcatenator
40 {
41 /**
42 * Array of media rules in order. Each element is an object with the following properties:
43 * - string `media` - The media query string, e.g. "@media screen and (max-width:639px)", or an empty string for
44 * rules not within a media query block;
45 * - object[] `ruleBlocks` - Array of rule blocks in order, where each element is an object with the following
46 * properties:
47 * - mixed[] `selectorsAsKeys` - Array whose keys are selectors for the rule block (values are of no
48 * significance);
49 * - string `declarationsBlock` - The property declarations, e.g. "margin-top: 0.5em; padding: 0".
50 *
51 * @var array<int, object{
52 * media: string,
53 * ruleBlocks: array<int, object{
54 * selectorsAsKeys: array<string, array-key>,
55 * declarationsBlock: string
56 * }>
57 * }>
58 */
59 private $mediaRules = [];
60 /**
61 * Appends a declaration block to the CSS.
62 *
63 * @param array<array-key, string> $selectors
64 * array of selectors for the rule, e.g. ["ul", "ol", "p:first-child"]
65 * @param string $declarationsBlock
66 * the property declarations, e.g. "margin-top: 0.5em; padding: 0"
67 * @param string $media
68 * the media query for the rule, e.g. "@media screen and (max-width:639px)", or an empty string if none
69 */
70 public function append(array $selectors, string $declarationsBlock, string $media = ''): void
71 {
72 $selectorsAsKeys = \array_flip($selectors);
73 $mediaRule = $this->getOrCreateMediaRuleToAppendTo($media);
74 $ruleBlocks = $mediaRule->ruleBlocks;
75 $lastRuleBlock = \end($ruleBlocks);
76 $hasSameDeclarationsAsLastRule = \is_object($lastRuleBlock) && $declarationsBlock === $lastRuleBlock->declarationsBlock;
77 if ($hasSameDeclarationsAsLastRule) {
78 $lastRuleBlock->selectorsAsKeys += $selectorsAsKeys;
79 } else {
80 $lastRuleBlockSelectors = \is_object($lastRuleBlock) ? $lastRuleBlock->selectorsAsKeys : [];
81 $hasSameSelectorsAsLastRule = \is_object($lastRuleBlock) && self::hasEquivalentSelectors($selectorsAsKeys, $lastRuleBlockSelectors);
82 if ($hasSameSelectorsAsLastRule) {
83 $lastDeclarationsBlockWithoutSemicolon = \rtrim(\rtrim($lastRuleBlock->declarationsBlock), ';');
84 $lastRuleBlock->declarationsBlock = $lastDeclarationsBlockWithoutSemicolon . ';' . $declarationsBlock;
85 } else {
86 $mediaRule->ruleBlocks[] = (object) \compact('selectorsAsKeys', 'declarationsBlock');
87 }
88 }
89 }
90 /**
91 * @return string
92 */
93 public function getCss(): string
94 {
95 return \implode('', \array_map([self::class, 'getMediaRuleCss'], $this->mediaRules));
96 }
97 /**
98 * @param string $media The media query for rules to be appended, e.g. "@media screen and (max-width:639px)",
99 * or an empty string if none.
100 *
101 * @return object{
102 * media: string,
103 * ruleBlocks: array<int, object{
104 * selectorsAsKeys: array<string, array-key>,
105 * declarationsBlock: string
106 * }>
107 * }
108 */
109 private function getOrCreateMediaRuleToAppendTo(string $media): object
110 {
111 $lastMediaRule = \end($this->mediaRules);
112 if (\is_object($lastMediaRule) && $media === $lastMediaRule->media) {
113 return $lastMediaRule;
114 }
115 $newMediaRule = (object) ['media' => $media, 'ruleBlocks' => []];
116 $this->mediaRules[] = $newMediaRule;
117 return $newMediaRule;
118 }
119 /**
120 * Tests if two sets of selectors are equivalent (i.e. the same selectors, possibly in a different order).
121 *
122 * @param array<string, array-key> $selectorsAsKeys1
123 * array in which the selectors are the keys, and the values are of no significance
124 * @param array<string, array-key> $selectorsAsKeys2 another such array
125 *
126 * @return bool
127 */
128 private static function hasEquivalentSelectors(array $selectorsAsKeys1, array $selectorsAsKeys2): bool
129 {
130 return \count($selectorsAsKeys1) === \count($selectorsAsKeys2) && \count($selectorsAsKeys1) === \count($selectorsAsKeys1 + $selectorsAsKeys2);
131 }
132 /**
133 * @param object{
134 * media: string,
135 * ruleBlocks: array<int, object{
136 * selectorsAsKeys: array<string, array-key>,
137 * declarationsBlock: string
138 * }>
139 * } $mediaRule
140 *
141 * @return string CSS for the media rule.
142 */
143 private static function getMediaRuleCss(object $mediaRule): string
144 {
145 $ruleBlocks = $mediaRule->ruleBlocks;
146 $css = \implode('', \array_map([self::class, 'getRuleBlockCss'], $ruleBlocks));
147 $media = $mediaRule->media;
148 if ($media !== '') {
149 $css = $media . '{' . $css . '}';
150 }
151 return $css;
152 }
153 /**
154 * @param object{selectorsAsKeys: array<string, array-key>, declarationsBlock: string} $ruleBlock
155 *
156 * @return string CSS for the rule block.
157 */
158 private static function getRuleBlockCss(object $ruleBlock): string
159 {
160 $selectorsAsKeys = $ruleBlock->selectorsAsKeys;
161 $selectors = \array_keys($selectorsAsKeys);
162 $declarationsBlock = $ruleBlock->declarationsBlock;
163 return \implode(',', $selectors) . '{' . $declarationsBlock . '}';
164 }
165 }
166