diff options
| author | 2022-08-18 11:14:40 +0200 | |
|---|---|---|
| committer | 2022-08-18 11:14:40 +0200 | |
| commit | 2acf3a4dd87af5c09fcf513517cb852ff6e909ce (patch) | |
| tree | 6e1b687ad1f2359e652250f4d354645bc2f23c64 /lib/phpgt/cssxpath/src | |
| parent | ea0d924985dc0c5aa089ed59c15282ea7e84c7a4 (diff) | |
CssXPath-StarSelector (#4506)
* CssXPath-StarSelector
Add support for selectors such as `a[href*="example"]`
https://developer.mozilla.org/docs/Web/CSS/Attribute_selectors
Translated to `.//a[contains(@href,"example")]`
Upstream PR: https://github.com/PhpGt/CssXPath/pull/181
* Upstream merged
Diffstat (limited to 'lib/phpgt/cssxpath/src')
| -rw-r--r-- | lib/phpgt/cssxpath/src/CssXPathException.php | 2 | ||||
| -rw-r--r-- | lib/phpgt/cssxpath/src/NotYetImplementedException.php | 2 | ||||
| -rw-r--r-- | lib/phpgt/cssxpath/src/Translator.php | 25 |
3 files changed, 19 insertions, 10 deletions
diff --git a/lib/phpgt/cssxpath/src/CssXPathException.php b/lib/phpgt/cssxpath/src/CssXPathException.php index 81ad3ac9d..bd7798243 100644 --- a/lib/phpgt/cssxpath/src/CssXPathException.php +++ b/lib/phpgt/cssxpath/src/CssXPathException.php @@ -3,4 +3,4 @@ namespace Gt\CssXPath; use RuntimeException; -class CssXPathException extends RuntimeException {}
\ No newline at end of file +class CssXPathException extends RuntimeException {} diff --git a/lib/phpgt/cssxpath/src/NotYetImplementedException.php b/lib/phpgt/cssxpath/src/NotYetImplementedException.php index 39d12b3bc..70d9492cf 100644 --- a/lib/phpgt/cssxpath/src/NotYetImplementedException.php +++ b/lib/phpgt/cssxpath/src/NotYetImplementedException.php @@ -1,4 +1,4 @@ <?php namespace Gt\CssXPath; -class NotYetImplementedException extends CssXPathException {}
\ No newline at end of file +class NotYetImplementedException extends CssXPathException {} diff --git a/lib/phpgt/cssxpath/src/Translator.php b/lib/phpgt/cssxpath/src/Translator.php index 140909099..01ed98bc6 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+)' . '/'; @@ -61,7 +61,7 @@ class Translator { $thread = array_values($thread); $xpath = [$this->prefix]; - $prevType = ""; + $hasElement = false; foreach($thread as $threadKey => $currentThreadItem) { $next = isset($thread[$threadKey + 1]) ? $thread[$threadKey + 1] @@ -71,6 +71,7 @@ class Translator { case "star": case "element": $xpath []= $currentThreadItem['content']; + $hasElement = true; break; case "pseudo": @@ -160,23 +161,26 @@ class Translator { case "child": array_push($xpath, "/"); + $hasElement = false; break; case "id": array_push( $xpath, - ($prevType != "element" ? '*' : '') + ($hasElement ? '' : '*') . "[@id='{$currentThreadItem['content']}']" ); + $hasElement = true; break; case "class": // https://devhints.io/xpath#class-check array_push( $xpath, - (($prevType != "element" && $prevType != "class") ? '*' : '') + ($hasElement ? '' : '*') . "[contains(concat(' ',normalize-space(@class),' '),' {$currentThreadItem['content']} ')]" ); + $hasElement = true; break; case "sibling": @@ -184,11 +188,13 @@ class Translator { $xpath, "/following-sibling::*[1]/self::" ); + $hasElement = false; break; case "attribute": - if(!$prevType) { + if(!$hasElement) { array_push($xpath, "*"); + $hasElement = true; } /** @var null|array<int, array<string, string>> $detail */ @@ -220,7 +226,11 @@ class Translator { break; case self::EQUALS_CONTAINS: - throw new NotYetImplementedException(); + array_push( + $xpath, + "[contains(@{$currentThreadItem['content']},\"{$valueString}\")]" + ); + break; case self::EQUALS_CONTAINS_WORD: array_push( @@ -257,10 +267,9 @@ class Translator { case "descendant": array_push($xpath, "//"); + $hasElement = false; break; } - - $prevType = $currentThreadItem["type"]; } return implode("", $xpath); |
