Bläddra i källkod

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
Alexandre Alapetite 3 år sedan
förälder
incheckning
2acf3a4dd8

+ 1 - 3
lib/.gitignore

@@ -1,9 +1,7 @@
 autoload.php
 composer.lock
 composer/
-phpgt/cssxpath/.github/
-phpgt/cssxpath/.gitignore
-phpgt/cssxpath/.scrutinizer.yml
+phpgt/cssxpath/.*
 phpgt/cssxpath/composer.json
 phpgt/cssxpath/CONTRIBUTING.md
 phpgt/cssxpath/test/

+ 7 - 1
lib/composer.json

@@ -4,9 +4,15 @@
     "type": "project",
     "homepage": "https://freshrss.org/",
     "license": "AGPL-3.0",
+    "repositories": [
+        {
+            "type": "git",
+            "url": "https://github.com/PhpGt/CssXPath.git"
+        }
+    ],
     "require": {
         "php": ">=7.0.0",
-        "phpgt/cssxpath": "v1.1.4",
+        "phpgt/cssxpath": "dev-master#4fbe420aba3d9e729940107ded4236a835a1a132",
         "phpmailer/phpmailer": "6.6.0"
     },
     "config": {

+ 2 - 2
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.
 

+ 1 - 1
lib/phpgt/cssxpath/src/CssXPathException.php

@@ -3,4 +3,4 @@ namespace Gt\CssXPath;
 
 use RuntimeException;
 
-class CssXPathException extends RuntimeException {}
+class CssXPathException extends RuntimeException {}

+ 1 - 1
lib/phpgt/cssxpath/src/NotYetImplementedException.php

@@ -1,4 +1,4 @@
 <?php
 namespace Gt\CssXPath;
 
-class NotYetImplementedException extends CssXPathException {}
+class NotYetImplementedException extends CssXPathException {}

+ 17 - 8
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);