Skip to content

Commit 5bae038

Browse files
committed
Cache expressions
1 parent ac4d9a6 commit 5bae038

File tree

1 file changed

+38
-23
lines changed

1 file changed

+38
-23
lines changed

src/CssFromHTMLExtractor.php

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Doctrine\Common\Cache\ArrayCache;
66
use Doctrine\Common\Cache\Cache;
77
use DOMNodeList;
8+
use DOMXPath;
89
use Exception;
910
use Symfony\Component\CssSelector\CssSelectorConverter;
1011
use Symfony\Component\CssSelector\Exception\ExceptionInterface;
@@ -125,33 +126,12 @@ public function extractCss($html)
125126
{
126127
$document = $this->createDomDocumentFromHtml($html);
127128

128-
$xPath = new \DOMXPath($document);
129-
129+
$xPath = new DOMXPath($document);
130130

131131
$applicable_rules = array_filter(
132132
$this->rules,
133133
function (Rule $rule) use ($xPath) {
134-
135-
try {
136-
$expression = $this->cssConverter->toXPath($rule->getSelector());
137-
} catch (ExpressionErrorException $expressionErrorException) {
138-
139-
// Allow for pseudo selectors
140-
// TODO: Find a way to validate this exception without checking strings
141-
if ($expressionErrorException->getMessage() !== 'Pseudo-elements are not supported.') {
142-
return false;
143-
}
144-
145-
try {
146-
$tokens = explode(':', $rule->getSelector());
147-
$expression = $this->cssConverter->toXPath((string)reset($tokens));
148-
} catch (Exception $e) {
149-
return false;
150-
}
151-
152-
} catch (ExceptionInterface $e) {
153-
return false;
154-
}
134+
$expression = $this->buildExpressionForSelector($rule->getSelector());
155135

156136
/** @var DOMNodeList $elements */
157137
$elements = $xPath->query($expression);
@@ -192,4 +172,39 @@ public function purgeCssStore()
192172

193173
return $this;
194174
}
175+
176+
private function buildExpressionForSelector(string $selector)
177+
{
178+
179+
if ($expression = $this->resultCache->fetch($selector)) {
180+
return $expression;
181+
}
182+
183+
184+
try {
185+
$expression = $this->cssConverter->toXPath($selector);
186+
} catch (ExpressionErrorException $expressionErrorException) {
187+
188+
// Allow for pseudo selectors
189+
// TODO: Find a way to validate this exception without checking strings
190+
if ($expressionErrorException->getMessage() !== 'Pseudo-elements are not supported.') {
191+
return false;
192+
}
193+
194+
try {
195+
$tokens = explode(':', $selector);
196+
$expression = $this->cssConverter->toXPath((string)reset($tokens));
197+
} catch (Exception $e) {
198+
return false;
199+
}
200+
201+
} catch (ExceptionInterface $e) {
202+
return false;
203+
}
204+
205+
206+
$this->resultCache->save($selector, $expression);
207+
208+
return $expression;
209+
}
195210
}

0 commit comments

Comments
 (0)