mirror of https://github.com/FreshRSS/FreshRSS.git
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
This commit is contained in:
parent
ea0d924985
commit
2acf3a4dd8
|
@ -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/
|
||||
|
|
|
@ -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": {
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -3,4 +3,4 @@ namespace Gt\CssXPath;
|
|||
|
||||
use RuntimeException;
|
||||
|
||||
class CssXPathException extends RuntimeException {}
|
||||
class CssXPathException extends RuntimeException {}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?php
|
||||
namespace Gt\CssXPath;
|
||||
|
||||
class NotYetImplementedException extends CssXPathException {}
|
||||
class NotYetImplementedException extends CssXPathException {}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue