diff options
| author | 2024-09-06 09:11:37 +0200 | |
|---|---|---|
| committer | 2024-09-06 09:11:37 +0200 | |
| commit | 9f4f6e9cac6c20257ff496c28a02dd9463c6cdcb (patch) | |
| tree | b0e4ed9be545841d30458cfe31b0c0aa4828260f | |
| parent | a81656c3ed5b8fe0f31794a4fbe0d1a907fca8e8 (diff) | |
Bump phpgt/cssxpath (#6618)
Includes https://github.com/PhpGt/CssXPath/pull/227
Follow-up of https://github.com/PhpGt/CssXPath/pull/227 for PHP 8.4
Requires PHP 8.0+
Full diff https://github.com/PhpGt/CssXPath/compare/d99d35f7194bac19fb3f8726b70c1bc83de3e931...45f3ac151fc21d459e2515c3aff97cd4bf877bf8
| -rw-r--r-- | lib/composer.json | 2 | ||||
| -rw-r--r-- | lib/phpgt/cssxpath/README.md | 14 | ||||
| -rw-r--r-- | lib/phpgt/cssxpath/src/Translator.php | 91 |
3 files changed, 89 insertions, 18 deletions
diff --git a/lib/composer.json b/lib/composer.json index a0ff7bdb4..c1b3da704 100644 --- a/lib/composer.json +++ b/lib/composer.json @@ -12,7 +12,7 @@ ], "require": { "marienfressinaud/lib_opml": "0.5.1", - "phpgt/cssxpath": "dev-master#d99d35f7194bac19fb3f8726b70c1bc83de3e931", + "phpgt/cssxpath": "dev-master#45f3ac151fc21d459e2515c3aff97cd4bf877bf8", "phpmailer/phpmailer": "6.9.1" }, "config": { diff --git a/lib/phpgt/cssxpath/README.md b/lib/phpgt/cssxpath/README.md index 8dfeabc42..048547442 100644 --- a/lib/phpgt/cssxpath/README.md +++ b/lib/phpgt/cssxpath/README.md @@ -8,10 +8,10 @@ A lightweight and dependency free CSS to XPath translator. This repository is us <a href="https://github.com/PhpGt/CssXPath/actions" target="_blank"> <img src="https://badge.status.php.gt/cssxpath-build.svg" alt="Build status" /> </a> -<a href="https://scrutinizer-ci.com/g/PhpGt/CssXPath" target="_blank"> +<a href="https://app.codacy.com/gh/PhpGt/CssXPath" target="_blank"> <img src="https://badge.status.php.gt/cssxpath-quality.svg" alt="Code quality" /> </a> -<a href="https://scrutinizer-ci.com/g/PhpGt/CssXPath" target="_blank"> +<a href="https://app.codecov.io/gh/PhpGt/CssXPath" target="_blank"> <img src="https://badge.status.php.gt/cssxpath-coverage.svg" alt="Code coverage" /> </a> <a href="https://packagist.org/packages/PhpGt/CssXPath" target="_blank"> @@ -49,5 +49,15 @@ $xpath = new DOMXPath($document); $inputElementList = $xpath->query(new Translator("form>label>input"); ``` +## Using this library with XML Documents + +To correctly work with XML documents, where the attributes are case-sensitive, pass `false` to the `htmlMode` property of the constructor. + +```php +$translator = new Translator("[data-FOO='bar']", htmlMode: false); +``` + +It's perhaps worth noting that for XML-style matching to work, you must load the document content with DOMDocument->load/DOMDocument->loadXML instead of DOMDocument->loadHTMLFile/DOMDocument->loadHTML, as the HTML loading methods automatically convert the tags and attribute names to lowercase. This is handled automatically when using [PHP.Gt/Dom][gt-dom]. + [qsa]: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll [gt-dom]: https://www.php.gt/dom diff --git a/lib/phpgt/cssxpath/src/Translator.php b/lib/phpgt/cssxpath/src/Translator.php index 01ed98bc6..7bb11265c 100644 --- a/lib/phpgt/cssxpath/src/Translator.php +++ b/lib/phpgt/cssxpath/src/Translator.php @@ -12,7 +12,7 @@ class Translator { . '|(#(?P<id>[\w-]*))' . '|(\.(?P<class>[\w-]*))' . '|(?P<sibling>\s*\+\s*)' - . "|(\[(?P<attribute>[\w-]*)((?P<attribute_equals>[=~$*]+)(?P<attribute_value>(.+\[\]'?)|[^\]]+))*\])+" + . "|(\[(?P<attribute>[\w-]*)((?P<attribute_equals>[=~$|^*]+)(?P<attribute_value>(.+\[\]'?)|[^\]]+))*\])+" . '|(?P<descendant>\s+)' . '/'; @@ -20,17 +20,14 @@ class Translator { const EQUALS_CONTAINS_WORD = "~="; const EQUALS_ENDS_WITH = "$="; const EQUALS_CONTAINS = "*="; - const EQUALS_STARTS_WITH_OR_STARTS_WITH_HYPHENATED = "|="; + const EQUALS_OR_STARTS_WITH_HYPHENATED = "|="; const EQUALS_STARTS_WITH = "^="; - /** @var string */ - protected $cssSelector; - /** @var string */ - protected $prefix; - - public function __construct(string $cssSelector, string $prefix = ".//") { - $this->cssSelector = $cssSelector; - $this->prefix = $prefix; + public function __construct( + protected string $cssSelector, + protected string $prefix = ".//", + protected bool $htmlMode = true + ) { } public function __toString():string { @@ -70,7 +67,11 @@ class Translator { switch ($currentThreadItem["type"]) { case "star": case "element": - $xpath []= $currentThreadItem['content']; + if($this->htmlMode) { + $xpath []= strtolower($currentThreadItem['content']); + } else { + $xpath []= $currentThreadItem['content']; + } $hasElement = true; break; @@ -135,6 +136,30 @@ class Translator { ); } break; + + case "last-child": + $prev = count($xpath) - 1; + $xpath[$prev] = '*[last()]/self::' . $xpath[$prev]; + break; + + case 'first-of-type': + $prev = count($xpath) - 1; + $previous = $xpath[$prev]; + + if(substr($previous, -1, 1) === "]") { + array_push( + $xpath, + "[1]" + ); + } + else { + array_push( + $xpath, + "[1]" + ); + } + break; + case "nth-of-type": if (empty($specifier)) { continue 3; @@ -156,6 +181,25 @@ class Translator { ); } break; + + case "last-of-type": + $prev = count($xpath) - 1; + $previous = $xpath[$prev]; + + if(substr($previous, -1, 1) === "]") { + array_push( + $xpath, + "[last()]" + ); + } + else { + array_push( + $xpath, + "[last()]" + ); + } + break; + } break; @@ -197,6 +241,10 @@ class Translator { $hasElement = true; } + if($this->htmlMode) { + $currentThreadItem['content'] = strtolower($currentThreadItem['content']); + } + /** @var null|array<int, array<string, string>> $detail */ $detail = $currentThreadItem["detail"] ?? null; $detailType = $detail[0] ?? null; @@ -244,11 +292,24 @@ class Translator { ); break; - case self::EQUALS_STARTS_WITH_OR_STARTS_WITH_HYPHENATED: - throw new NotYetImplementedException(); + case self::EQUALS_OR_STARTS_WITH_HYPHENATED: + array_push( + $xpath, + "[" + . "@{$currentThreadItem['content']}=\"{$valueString}\" or " + . "starts-with(@{$currentThreadItem['content']}, \"{$valueString}-\")" + . "]" + ); + break; case self::EQUALS_STARTS_WITH: - throw new NotYetImplementedException(); + array_push( + $xpath, + "[starts-with(" + . "@{$currentThreadItem['content']}, \"{$valueString}\"" + . ")]" + ); + break; case self::EQUALS_ENDS_WITH: array_push( @@ -279,7 +340,7 @@ class Translator { protected function preg_match_collated( string $regex, string $string, - callable $transform = null + ?callable $transform = null ):array { preg_match_all( $regex, |
