PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.9
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.9
4.4.9.1 4.4.9 4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 All 141 releases
learnpress / vendor / tijsverkoyen / css-to-inline-styles / src / Css / Rule / Processor.php

Processor.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.9, at vendor/tijsverkoyen/css-to-inline-styles/src/Css/Rule/Processor.php

170 lines 5.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace TijsVerkoyen\CssToInlineStyles\Css\Rule;
4
5 use Symfony\Component\CssSelector\Node\Specificity;
6 use \TijsVerkoyen\CssToInlineStyles\Css\Property\Processor as PropertyProcessor;
7
8 class Processor
9 {
10 /**
11 * Splits a string into separate rules
12 *
13 * @param string $rulesString
14 *
15 * @return string[]
16 */
17 public function splitIntoSeparateRules($rulesString)
18 {
19 $rulesString = $this->cleanup($rulesString);
20
21 return (array) explode('}', $rulesString);
22 }
23
24 /**
25 * @param string $string
26 *
27 * @return string
28 */
29 private function cleanup($string)
30 {
31 $string = str_replace(array("\r", "\n"), '', $string);
32 $string = str_replace(array("\t"), ' ', $string);
33 $string = str_replace('"', '\'', $string);
34 $string = preg_replace('|/\*.*?\*/|', '', $string) ?? $string;
35 $string = preg_replace('/\s\s+/', ' ', $string) ?? $string;
36
37 $string = trim($string);
38 $string = rtrim($string, '}');
39
40 return $string;
41 }
42
43 /**
44 * Converts a rule-string into an object
45 *
46 * @param string $rule
47 * @param int $originalOrder
48 *
49 * @return Rule[]
50 */
51 public function convertToObjects($rule, $originalOrder)
52 {
53 $rule = $this->cleanup($rule);
54
55 $chunks = explode('{', $rule);
56 if (!isset($chunks[1])) {
57 return array();
58 }
59 $propertiesProcessor = new PropertyProcessor();
60 $rules = array();
61 $selectors = (array) explode(',', trim($chunks[0]));
62 $properties = $propertiesProcessor->splitIntoSeparateProperties($chunks[1]);
63
64 foreach ($selectors as $selector) {
65 $selector = trim($selector);
66 $specificity = $this->calculateSpecificityBasedOnASelector($selector);
67
68 $rules[] = new Rule(
69 $selector,
70 $propertiesProcessor->convertArrayToObjects($properties, $specificity),
71 $specificity,
72 $originalOrder
73 );
74 }
75
76 return $rules;
77 }
78
79 /**
80 * Calculates the specificity based on a CSS Selector string,
81 * Based on the patterns from premailer/css_parser by Alex Dunae
82 *
83 * @see https://github.com/premailer/css_parser/blob/master/lib/css_parser/regexps.rb
84 *
85 * @param string $selector
86 *
87 * @return Specificity
88 */
89 public function calculateSpecificityBasedOnASelector($selector)
90 {
91 $idSelectorCount = preg_match_all("/ \#/ix", $selector, $matches);
92 $classAttributesPseudoClassesSelectorsPattern = " (\.[\w]+) # classes
93 |
94 \[(\w+) # attributes
95 |
96 (\:( # pseudo classes
97 link|visited|active
98 |hover|focus
99 |lang
100 |target
101 |enabled|disabled|checked|indeterminate
102 |root
103 |nth-child|nth-last-child|nth-of-type|nth-last-of-type
104 |first-child|last-child|first-of-type|last-of-type
105 |only-child|only-of-type
106 |empty|contains
107 ))";
108 $classAttributesPseudoClassesSelectorCount = preg_match_all("/{$classAttributesPseudoClassesSelectorsPattern}/ix", $selector, $matches);
109
110 $typePseudoElementsSelectorPattern = " ((^|[\s\+\>\~]+)[\w]+ # elements
111 |
112 \:{1,2}( # pseudo-elements
113 after|before
114 |first-letter|first-line
115 |selection
116 )
117 )";
118 $typePseudoElementsSelectorCount = preg_match_all("/{$typePseudoElementsSelectorPattern}/ix", $selector, $matches);
119
120 if ($idSelectorCount === false || $classAttributesPseudoClassesSelectorCount === false || $typePseudoElementsSelectorCount === false) {
121 throw new \RuntimeException('Failed to calculate specificity based on selector.');
122 }
123
124 return new Specificity(
125 $idSelectorCount,
126 $classAttributesPseudoClassesSelectorCount,
127 $typePseudoElementsSelectorCount
128 );
129 }
130
131 /**
132 * @param string[] $rules
133 * @param Rule[] $objects
134 *
135 * @return Rule[]
136 */
137 public function convertArrayToObjects(array $rules, array $objects = array())
138 {
139 $order = 1;
140 foreach ($rules as $rule) {
141 $objects = array_merge($objects, $this->convertToObjects($rule, $order));
142 $order++;
143 }
144
145 return $objects;
146 }
147
148 /**
149 * Sorts an array on the specificity element in an ascending way
150 * Lower specificity will be sorted to the beginning of the array
151 *
152 * @param Rule $e1 The first element.
153 * @param Rule $e2 The second element.
154 *
155 * @return int
156 */
157 public static function sortOnSpecificity(Rule $e1, Rule $e2)
158 {
159 $e1Specificity = $e1->getSpecificity();
160 $value = $e1Specificity->compareTo($e2->getSpecificity());
161
162 // if the specificity is the same, use the order in which the element appeared
163 if ($value === 0) {
164 $value = $e1->getOrder() - $e2->getOrder();
165 }
166
167 return $value;
168 }
169 }
170