aboutsummaryrefslogtreecommitdiff
path: root/lib/phpgt/cssxpath
diff options
context:
space:
mode:
Diffstat (limited to 'lib/phpgt/cssxpath')
-rw-r--r--lib/phpgt/cssxpath/README.md4
-rw-r--r--lib/phpgt/cssxpath/src/CssXPathException.php2
-rw-r--r--lib/phpgt/cssxpath/src/NotYetImplementedException.php2
-rw-r--r--lib/phpgt/cssxpath/src/Translator.php25
4 files changed, 21 insertions, 12 deletions
diff --git a/lib/phpgt/cssxpath/README.md b/lib/phpgt/cssxpath/README.md
index 9082c8bbf..8dfeabc42 100644
--- a/lib/phpgt/cssxpath/README.md
+++ b/lib/phpgt/cssxpath/README.md
@@ -1,5 +1,5 @@
-Translate CSS selectors to XPath queries.
-=========================================
+Translate CSS selectors to XPath queries
+========================================
A lightweight and dependency free CSS to XPath translator. This repository is used to bring modern DOM functionality like [`querySelectorAll()`][qsa] to PHP in the [PHP.Gt/Dom][gt-dom] project.
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);