Skip to content

Commit 523af03

Browse files
committed
[#1] Fixed missing pseudo selectors / proper media query selection
1 parent 29e8b7e commit 523af03

File tree

4 files changed

+78
-24
lines changed

4 files changed

+78
-24
lines changed

src/Css/Processor.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@ class Processor
1414
* @param array $existingRules
1515
* @return Rule[]
1616
*/
17-
public function getRules($css, $existingRules = array())
17+
public function getRules($css, $existingRules = [])
1818
{
19+
20+
1921
$css = $this->doCleanup($css);
2022
$rulesProcessor = new RuleProcessor();
2123
$rulesByMediaQuery = $rulesProcessor->splitIntoSeparateMediaQueries($css);

src/Css/Rule/Processor.php

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
namespace PageSpecificCss\Css\Rule;
44

5+
use Sabberworm\CSS\OutputFormat;
6+
use Sabberworm\CSS\Parser;
57
use Symfony\Component\CssSelector\Node\Specificity;
68
use \PageSpecificCss\Css\Property\Processor as PropertyProcessor;
79

@@ -15,26 +17,52 @@ class Processor
1517
*/
1618
public function splitIntoSeparateMediaQueries($rulesString)
1719
{
18-
$rulesString = $this->cleanup($rulesString);
20+
// $rulesString = $this->cleanup($rulesString);
1921

2022
// Intelligently break up rules, preserving mediaquery context and such
21-
$queryParts = explode('@media', $rulesString);
23+
24+
$mediaQuerySelector = '/@media[^{]+\{([\s\S]+?\})\s*\}/';
25+
$mediaQueryMatches = [];
26+
preg_match_all($mediaQuerySelector, $rulesString, $mediaQueryMatches);
27+
28+
$remainingRuleset = $rulesString;
29+
30+
$queryParts = [];
31+
foreach (reset($mediaQueryMatches) as $mediaQueryMatch) {
32+
$tokenisedRules = explode($mediaQueryMatch, $remainingRuleset);
33+
34+
$queryParts[] = reset($tokenisedRules);
35+
$queryParts[] = $mediaQueryMatch;
36+
37+
if (count($tokenisedRules) === 2) {
38+
$remainingRuleset = end($tokenisedRules);
39+
}
40+
}
41+
2242

2343
$indexedRules = [];
2444

2545
foreach ($queryParts as $part) {
26-
if (strpos($part,' ') !== 0) {
46+
47+
if (strpos($part, '@media') === FALSE) {
2748
$indexedRules[][''] = (array)explode('}', $part);
2849
continue;
2950
}
3051

31-
$mediaQueryString = "@media".substr($part, 0, strpos($part, '{'));
52+
$mediaQueryString = substr($part, 0, strpos($part, '{'));
53+
54+
// No need for print css
55+
if (trim($mediaQueryString) === '@media print') {
56+
continue;
57+
}
58+
3259
$mediaQueryRules = substr($part, strpos($part, '{') + 1);
60+
3361
$mediaQueryRules = substr($mediaQueryRules, 0, -1);
3462

35-
$indexedRules[][$mediaQueryString] = (array)explode('}', $mediaQueryRules) ;
36-
}
3763

64+
$indexedRules[][$mediaQueryString] = (array)explode('}', $mediaQueryRules);
65+
}
3866

3967
return $indexedRules;
4068
}

src/CssStore.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public function addCssStyles($cssRules)
1414
{
1515
$this->styles = array_merge($this->styles, $cssRules);
1616

17+
1718
return $this;
1819
}
1920

@@ -39,6 +40,7 @@ public function compileStyles()
3940
$styles = $this->prepareStylesForProcessing();
4041

4142

43+
4244
return join(
4345
'',
4446
array_map(
@@ -81,7 +83,7 @@ function ($rule) {
8183
return "$media { ".join(
8284
'',
8385
array_map(
84-
function ($rule, $selector) {
86+
function ($rule) {
8587
/** @var Rule $rule */
8688
return $this->parsePropertiesToString($rule->getSelector(), $rule->getProperties());
8789
},

src/PageSpecificCss.php

Lines changed: 38 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
namespace PageSpecificCss;
44

5+
use Exception;
56
use Symfony\Component\CssSelector\CssSelectorConverter;
67
use Symfony\Component\CssSelector\Exception\ExceptionInterface;
78
use PageSpecificCss\Css\Processor;
89
use PageSpecificCss\Css\Rule\Processor as RuleProcessor;
910
use PageSpecificCss\Css\Rule\Rule;
11+
use Symfony\Component\CssSelector\Exception\ExpressionErrorException;
1012

1113
class PageSpecificCss
1214
{
@@ -102,23 +104,43 @@ public function extractCss($html)
102104

103105
$xPath = new \DOMXPath($document);
104106

105-
106-
$applicable_rules = array_filter($this->rules, function (Rule $rule) use ($xPath) {
107-
try {
108-
$expression = $this->cssConverter->toXPath($rule->getSelector());
109-
110-
} catch (ExceptionInterface $e) {
111-
return false;
112-
}
113-
114-
$elements = $xPath->query($expression);
115-
116-
if ($elements === false || $elements->length == 0) {
117-
return false;
107+
$applicable_rules = array_filter(
108+
$this->rules,
109+
function (Rule $rule) use ($xPath) {
110+
try {
111+
if ($rule->getSelector() === "u-color-orange-base") {
112+
error_log("hola!!!");
113+
}
114+
115+
$expression = $this->cssConverter->toXPath($rule->getSelector());
116+
} catch (ExpressionErrorException $expressionErrorException) {
117+
118+
// Allow for pseudo selectors
119+
// TODO: Find a way to validate this exception without checking strings
120+
if ($expressionErrorException->getMessage() !== 'Pseudo-elements are not supported.') {
121+
return false;
122+
}
123+
124+
try {
125+
$tokens = explode(':', $rule->getSelector());
126+
$expression = $this->cssConverter->toXPath((string)reset($tokens));
127+
} catch (Exception $e) {
128+
return false;
129+
}
130+
131+
} catch (ExceptionInterface $e) {
132+
return false;
133+
}
134+
135+
$elements = $xPath->query($expression);
136+
137+
if ($elements === false || $elements->length == 0) {
138+
return false;
139+
}
140+
141+
return true;
118142
}
119-
120-
return true;
121-
});
143+
);
122144

123145

124146
return $applicable_rules;

0 commit comments

Comments
 (0)