diff --git a/src/Symfony/Component/CssSelector/CssSelectorConverter.php b/src/Symfony/Component/CssSelector/CssSelectorConverter.php index 82064424e2..bbb6afe217 100644 --- a/src/Symfony/Component/CssSelector/CssSelectorConverter.php +++ b/src/Symfony/Component/CssSelector/CssSelectorConverter.php @@ -27,6 +27,10 @@ use Symfony\Component\CssSelector\XPath\Translator; class CssSelectorConverter { private $translator; + private $cache; + + private static $xmlCache = []; + private static $htmlCache = []; /** * @param bool $html Whether HTML support should be enabled. Disable it for XML documents @@ -37,6 +41,9 @@ class CssSelectorConverter if ($html) { $this->translator->registerExtension(new HtmlExtension($this->translator)); + $this->cache = &self::$htmlCache; + } else { + $this->cache = &self::$xmlCache; } $this->translator @@ -57,6 +64,6 @@ class CssSelectorConverter */ public function toXPath(string $cssExpr, string $prefix = 'descendant-or-self::') { - return $this->translator->cssToXPath($cssExpr, $prefix); + return $this->cache[$prefix][$cssExpr] ?? $this->cache[$prefix][$cssExpr] = $this->translator->cssToXPath($cssExpr, $prefix); } } diff --git a/src/Symfony/Component/CssSelector/Tests/CssSelectorConverterTest.php b/src/Symfony/Component/CssSelector/Tests/CssSelectorConverterTest.php index 82e527c62e..420c33087d 100644 --- a/src/Symfony/Component/CssSelector/Tests/CssSelectorConverterTest.php +++ b/src/Symfony/Component/CssSelector/Tests/CssSelectorConverterTest.php @@ -26,6 +26,10 @@ class CssSelectorConverterTest extends TestCase $this->assertEquals("descendant-or-self::h1[@class and contains(concat(' ', normalize-space(@class), ' '), ' foo ')]", $converter->toXPath('h1.foo')); $this->assertEquals('descendant-or-self::foo:h1', $converter->toXPath('foo|h1')); $this->assertEquals('descendant-or-self::h1', $converter->toXPath('H1')); + + // Test the cache layer + $converter = new CssSelectorConverter(); + $this->assertEquals('descendant-or-self::h1', $converter->toXPath('H1')); } public function testCssToXPathXml() @@ -33,6 +37,10 @@ class CssSelectorConverterTest extends TestCase $converter = new CssSelectorConverter(false); $this->assertEquals('descendant-or-self::H1', $converter->toXPath('H1')); + + $converter = new CssSelectorConverter(false); + // Test the cache layer + $this->assertEquals('descendant-or-self::H1', $converter->toXPath('H1')); } public function testParseExceptions() diff --git a/src/Symfony/Component/DomCrawler/CHANGELOG.md b/src/Symfony/Component/DomCrawler/CHANGELOG.md index fa043cfd1e..b55e781f27 100644 --- a/src/Symfony/Component/DomCrawler/CHANGELOG.md +++ b/src/Symfony/Component/DomCrawler/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +5.1.0 +----- + +* Added an internal cache layer on top of the CssSelectorConverter + 5.0.0 -----