updated dependencies + working api connection

This commit is contained in:
Chris
2018-02-08 14:21:29 +00:00
parent dfc3c2194c
commit 30aea8e361
216 changed files with 21763 additions and 915 deletions

View File

@@ -43,17 +43,38 @@ class AttributeMatchingExtension extends AbstractExtension
);
}
public function translateExists(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr
/**
* @param XPathExpr $xpath
* @param string $attribute
* @param string $value
*
* @return XPathExpr
*/
public function translateExists(XPathExpr $xpath, $attribute, $value)
{
return $xpath->addCondition($attribute);
}
public function translateEquals(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr
/**
* @param XPathExpr $xpath
* @param string $attribute
* @param string $value
*
* @return XPathExpr
*/
public function translateEquals(XPathExpr $xpath, $attribute, $value)
{
return $xpath->addCondition(sprintf('%s = %s', $attribute, Translator::getXpathLiteral($value)));
}
public function translateIncludes(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr
/**
* @param XPathExpr $xpath
* @param string $attribute
* @param string $value
*
* @return XPathExpr
*/
public function translateIncludes(XPathExpr $xpath, $attribute, $value)
{
return $xpath->addCondition($value ? sprintf(
'%1$s and contains(concat(\' \', normalize-space(%1$s), \' \'), %2$s)',
@@ -62,7 +83,14 @@ class AttributeMatchingExtension extends AbstractExtension
) : '0');
}
public function translateDashMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr
/**
* @param XPathExpr $xpath
* @param string $attribute
* @param string $value
*
* @return XPathExpr
*/
public function translateDashMatch(XPathExpr $xpath, $attribute, $value)
{
return $xpath->addCondition(sprintf(
'%1$s and (%1$s = %2$s or starts-with(%1$s, %3$s))',
@@ -72,7 +100,14 @@ class AttributeMatchingExtension extends AbstractExtension
));
}
public function translatePrefixMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr
/**
* @param XPathExpr $xpath
* @param string $attribute
* @param string $value
*
* @return XPathExpr
*/
public function translatePrefixMatch(XPathExpr $xpath, $attribute, $value)
{
return $xpath->addCondition($value ? sprintf(
'%1$s and starts-with(%1$s, %2$s)',
@@ -81,7 +116,14 @@ class AttributeMatchingExtension extends AbstractExtension
) : '0');
}
public function translateSuffixMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr
/**
* @param XPathExpr $xpath
* @param string $attribute
* @param string $value
*
* @return XPathExpr
*/
public function translateSuffixMatch(XPathExpr $xpath, $attribute, $value)
{
return $xpath->addCondition($value ? sprintf(
'%1$s and substring(%1$s, string-length(%1$s)-%2$s) = %3$s',
@@ -91,7 +133,14 @@ class AttributeMatchingExtension extends AbstractExtension
) : '0');
}
public function translateSubstringMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr
/**
* @param XPathExpr $xpath
* @param string $attribute
* @param string $value
*
* @return XPathExpr
*/
public function translateSubstringMatch(XPathExpr $xpath, $attribute, $value)
{
return $xpath->addCondition($value ? sprintf(
'%1$s and contains(%1$s, %2$s)',
@@ -100,7 +149,14 @@ class AttributeMatchingExtension extends AbstractExtension
) : '0');
}
public function translateDifferent(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr
/**
* @param XPathExpr $xpath
* @param string $attribute
* @param string $value
*
* @return XPathExpr
*/
public function translateDifferent(XPathExpr $xpath, $attribute, $value)
{
return $xpath->addCondition(sprintf(
$value ? 'not(%1$s) or %1$s != %2$s' : '%s != %s',

View File

@@ -28,7 +28,7 @@ class CombinationExtension extends AbstractExtension
/**
* {@inheritdoc}
*/
public function getCombinationTranslators(): array
public function getCombinationTranslators()
{
return array(
' ' => array($this, 'translateDescendant'),
@@ -41,7 +41,7 @@ class CombinationExtension extends AbstractExtension
/**
* @return XPathExpr
*/
public function translateDescendant(XPathExpr $xpath, XPathExpr $combinedXpath): XPathExpr
public function translateDescendant(XPathExpr $xpath, XPathExpr $combinedXpath)
{
return $xpath->join('/descendant-or-self::*/', $combinedXpath);
}

View File

@@ -46,9 +46,16 @@ class FunctionExtension extends AbstractExtension
}
/**
* @param XPathExpr $xpath
* @param FunctionNode $function
* @param bool $last
* @param bool $addNameTest
*
* @return XPathExpr
*
* @throws ExpressionErrorException
*/
public function translateNthChild(XPathExpr $xpath, FunctionNode $function, bool $last = false, bool $addNameTest = true): XPathExpr
public function translateNthChild(XPathExpr $xpath, FunctionNode $function, $last = false, $addNameTest = true)
{
try {
list($a, $b) = Parser::parseSeries($function->getArguments());
@@ -103,20 +110,28 @@ class FunctionExtension extends AbstractExtension
// -1n+6 means elements 6 and previous
}
public function translateNthLastChild(XPathExpr $xpath, FunctionNode $function): XPathExpr
/**
* @return XPathExpr
*/
public function translateNthLastChild(XPathExpr $xpath, FunctionNode $function)
{
return $this->translateNthChild($xpath, $function, true);
}
public function translateNthOfType(XPathExpr $xpath, FunctionNode $function): XPathExpr
/**
* @return XPathExpr
*/
public function translateNthOfType(XPathExpr $xpath, FunctionNode $function)
{
return $this->translateNthChild($xpath, $function, false, false);
}
/**
* @return XPathExpr
*
* @throws ExpressionErrorException
*/
public function translateNthLastOfType(XPathExpr $xpath, FunctionNode $function): XPathExpr
public function translateNthLastOfType(XPathExpr $xpath, FunctionNode $function)
{
if ('*' === $xpath->getElement()) {
throw new ExpressionErrorException('"*:nth-of-type()" is not implemented.');
@@ -126,9 +141,11 @@ class FunctionExtension extends AbstractExtension
}
/**
* @return XPathExpr
*
* @throws ExpressionErrorException
*/
public function translateContains(XPathExpr $xpath, FunctionNode $function): XPathExpr
public function translateContains(XPathExpr $xpath, FunctionNode $function)
{
$arguments = $function->getArguments();
foreach ($arguments as $token) {
@@ -147,9 +164,11 @@ class FunctionExtension extends AbstractExtension
}
/**
* @return XPathExpr
*
* @throws ExpressionErrorException
*/
public function translateLang(XPathExpr $xpath, FunctionNode $function): XPathExpr
public function translateLang(XPathExpr $xpath, FunctionNode $function)
{
$arguments = $function->getArguments();
foreach ($arguments as $token) {

View File

@@ -33,15 +33,21 @@ class NodeExtension extends AbstractExtension
private $flags;
public function __construct(int $flags = 0)
/**
* @param int $flags
*/
public function __construct($flags = 0)
{
$this->flags = $flags;
}
/**
* @param int $flag
* @param bool $on
*
* @return $this
*/
public function setFlag(int $flag, bool $on)
public function setFlag($flag, $on)
{
if ($on && !$this->hasFlag($flag)) {
$this->flags += $flag;
@@ -54,7 +60,12 @@ class NodeExtension extends AbstractExtension
return $this;
}
public function hasFlag(int $flag): bool
/**
* @param int $flag
*
* @return bool
*/
public function hasFlag($flag)
{
return (bool) ($this->flags & $flag);
}
@@ -77,17 +88,26 @@ class NodeExtension extends AbstractExtension
);
}
public function translateSelector(Node\SelectorNode $node, Translator $translator): XPathExpr
/**
* @return XPathExpr
*/
public function translateSelector(Node\SelectorNode $node, Translator $translator)
{
return $translator->nodeToXPath($node->getTree());
}
public function translateCombinedSelector(Node\CombinedSelectorNode $node, Translator $translator): XPathExpr
/**
* @return XPathExpr
*/
public function translateCombinedSelector(Node\CombinedSelectorNode $node, Translator $translator)
{
return $translator->addCombination($node->getCombinator(), $node->getSelector(), $node->getSubSelector());
}
public function translateNegation(Node\NegationNode $node, Translator $translator): XPathExpr
/**
* @return XPathExpr
*/
public function translateNegation(Node\NegationNode $node, Translator $translator)
{
$xpath = $translator->nodeToXPath($node->getSelector());
$subXpath = $translator->nodeToXPath($node->getSubSelector());
@@ -100,21 +120,30 @@ class NodeExtension extends AbstractExtension
return $xpath->addCondition('0');
}
public function translateFunction(Node\FunctionNode $node, Translator $translator): XPathExpr
/**
* @return XPathExpr
*/
public function translateFunction(Node\FunctionNode $node, Translator $translator)
{
$xpath = $translator->nodeToXPath($node->getSelector());
return $translator->addFunction($xpath, $node);
}
public function translatePseudo(Node\PseudoNode $node, Translator $translator): XPathExpr
/**
* @return XPathExpr
*/
public function translatePseudo(Node\PseudoNode $node, Translator $translator)
{
$xpath = $translator->nodeToXPath($node->getSelector());
return $translator->addPseudoClass($xpath, $node->getIdentifier());
}
public function translateAttribute(Node\AttributeNode $node, Translator $translator): XPathExpr
/**
* @return XPathExpr
*/
public function translateAttribute(Node\AttributeNode $node, Translator $translator)
{
$name = $node->getAttribute();
$safe = $this->isSafeName($name);
@@ -139,21 +168,30 @@ class NodeExtension extends AbstractExtension
return $translator->addAttributeMatching($xpath, $node->getOperator(), $attribute, $value);
}
public function translateClass(Node\ClassNode $node, Translator $translator): XPathExpr
/**
* @return XPathExpr
*/
public function translateClass(Node\ClassNode $node, Translator $translator)
{
$xpath = $translator->nodeToXPath($node->getSelector());
return $translator->addAttributeMatching($xpath, '~=', '@class', $node->getName());
}
public function translateHash(Node\HashNode $node, Translator $translator): XPathExpr
/**
* @return XPathExpr
*/
public function translateHash(Node\HashNode $node, Translator $translator)
{
$xpath = $translator->nodeToXPath($node->getSelector());
return $translator->addAttributeMatching($xpath, '=', '@id', $node->getId());
}
public function translateElement(Node\ElementNode $node): XPathExpr
/**
* @return XPathExpr
*/
public function translateElement(Node\ElementNode $node)
{
$element = $node->getElement();
@@ -190,7 +228,14 @@ class NodeExtension extends AbstractExtension
return 'node';
}
private function isSafeName(string $name): bool
/**
* Tests if given name is safe.
*
* @param string $name
*
* @return bool
*/
private function isSafeName($name)
{
return 0 < preg_match('~^[a-zA-Z_][a-zA-Z0-9_.-]*$~', $name);
}

View File

@@ -61,7 +61,12 @@ class Translator implements TranslatorInterface
;
}
public static function getXpathLiteral(string $element): string
/**
* @param string $element
*
* @return string
*/
public static function getXpathLiteral($element)
{
if (false === strpos($element, "'")) {
return "'".$element."'";
@@ -90,7 +95,7 @@ class Translator implements TranslatorInterface
/**
* {@inheritdoc}
*/
public function cssToXPath(string $cssExpr, string $prefix = 'descendant-or-self::'): string
public function cssToXPath($cssExpr, $prefix = 'descendant-or-self::')
{
$selectors = $this->parseSelectors($cssExpr);
@@ -109,12 +114,17 @@ class Translator implements TranslatorInterface
/**
* {@inheritdoc}
*/
public function selectorToXPath(SelectorNode $selector, string $prefix = 'descendant-or-self::'): string
public function selectorToXPath(SelectorNode $selector, $prefix = 'descendant-or-self::')
{
return ($prefix ?: '').$this->nodeToXPath($selector);
}
public function registerExtension(Extension\ExtensionInterface $extension): Translator
/**
* Registers an extension.
*
* @return $this
*/
public function registerExtension(Extension\ExtensionInterface $extension)
{
$this->extensions[$extension->getName()] = $extension;
@@ -128,9 +138,13 @@ class Translator implements TranslatorInterface
}
/**
* @param string $name
*
* @return Extension\ExtensionInterface
*
* @throws ExpressionErrorException
*/
public function getExtension(string $name): Extension\ExtensionInterface
public function getExtension($name)
{
if (!isset($this->extensions[$name])) {
throw new ExpressionErrorException(sprintf('Extension "%s" not registered.', $name));
@@ -139,7 +153,12 @@ class Translator implements TranslatorInterface
return $this->extensions[$name];
}
public function registerParserShortcut(ParserInterface $shortcut): Translator
/**
* Registers a shortcut parser.
*
* @return $this
*/
public function registerParserShortcut(ParserInterface $shortcut)
{
$this->shortcutParsers[] = $shortcut;
@@ -147,9 +166,11 @@ class Translator implements TranslatorInterface
}
/**
* @return XPathExpr
*
* @throws ExpressionErrorException
*/
public function nodeToXPath(NodeInterface $node): XPathExpr
public function nodeToXPath(NodeInterface $node)
{
if (!isset($this->nodeTranslators[$node->getNodeName()])) {
throw new ExpressionErrorException(sprintf('Node "%s" not supported.', $node->getNodeName()));
@@ -159,9 +180,15 @@ class Translator implements TranslatorInterface
}
/**
* @param string $combiner
* @param NodeInterface $xpath
* @param NodeInterface $combinedXpath
*
* @return XPathExpr
*
* @throws ExpressionErrorException
*/
public function addCombination(string $combiner, NodeInterface $xpath, NodeInterface $combinedXpath): XPathExpr
public function addCombination($combiner, NodeInterface $xpath, NodeInterface $combinedXpath)
{
if (!isset($this->combinationTranslators[$combiner])) {
throw new ExpressionErrorException(sprintf('Combiner "%s" not supported.', $combiner));
@@ -171,9 +198,11 @@ class Translator implements TranslatorInterface
}
/**
* @return XPathExpr
*
* @throws ExpressionErrorException
*/
public function addFunction(XPathExpr $xpath, FunctionNode $function): XPathExpr
public function addFunction(XPathExpr $xpath, FunctionNode $function)
{
if (!isset($this->functionTranslators[$function->getName()])) {
throw new ExpressionErrorException(sprintf('Function "%s" not supported.', $function->getName()));
@@ -183,9 +212,14 @@ class Translator implements TranslatorInterface
}
/**
* @param XPathExpr $xpath
* @param string $pseudoClass
*
* @return XPathExpr
*
* @throws ExpressionErrorException
*/
public function addPseudoClass(XPathExpr $xpath, string $pseudoClass): XPathExpr
public function addPseudoClass(XPathExpr $xpath, $pseudoClass)
{
if (!isset($this->pseudoClassTranslators[$pseudoClass])) {
throw new ExpressionErrorException(sprintf('Pseudo-class "%s" not supported.', $pseudoClass));
@@ -195,9 +229,16 @@ class Translator implements TranslatorInterface
}
/**
* @param XPathExpr $xpath
* @param string $operator
* @param string $attribute
* @param string $value
*
* @return XPathExpr
*
* @throws ExpressionErrorException
*/
public function addAttributeMatching(XPathExpr $xpath, string $operator, string $attribute, $value): XPathExpr
public function addAttributeMatching(XPathExpr $xpath, $operator, $attribute, $value)
{
if (!isset($this->attributeMatchingTranslators[$operator])) {
throw new ExpressionErrorException(sprintf('Attribute matcher operator "%s" not supported.', $operator));
@@ -207,9 +248,11 @@ class Translator implements TranslatorInterface
}
/**
* @param string $css
*
* @return SelectorNode[]
*/
private function parseSelectors(string $css)
private function parseSelectors($css)
{
foreach ($this->shortcutParsers as $shortcut) {
$tokens = $shortcut->parse($css);

View File

@@ -27,11 +27,21 @@ interface TranslatorInterface
{
/**
* Translates a CSS selector to an XPath expression.
*
* @param string $cssExpr
* @param string $prefix
*
* @return string
*/
public function cssToXPath(string $cssExpr, string $prefix = 'descendant-or-self::'): string;
public function cssToXPath($cssExpr, $prefix = 'descendant-or-self::');
/**
* Translates a parsed selector node to an XPath expression.
*
* @param SelectorNode $selector
* @param string $prefix
*
* @return string
*/
public function selectorToXPath(SelectorNode $selector, string $prefix = 'descendant-or-self::'): string;
public function selectorToXPath(SelectorNode $selector, $prefix = 'descendant-or-self::');
}

View File

@@ -27,7 +27,13 @@ class XPathExpr
private $element;
private $condition;
public function __construct(string $path = '', string $element = '*', string $condition = '', bool $starPrefix = false)
/**
* @param string $path
* @param string $element
* @param string $condition
* @param bool $starPrefix
*/
public function __construct($path = '', $element = '*', $condition = '', $starPrefix = false)
{
$this->path = $path;
$this->element = $element;
@@ -38,24 +44,38 @@ class XPathExpr
}
}
public function getElement(): string
/**
* @return string
*/
public function getElement()
{
return $this->element;
}
public function addCondition(string $condition): XPathExpr
/**
* @param $condition
*
* @return $this
*/
public function addCondition($condition)
{
$this->condition = $this->condition ? sprintf('%s and (%s)', $this->condition, $condition) : $condition;
return $this;
}
public function getCondition(): string
/**
* @return string
*/
public function getCondition()
{
return $this->condition;
}
public function addNameTest(): XPathExpr
/**
* @return $this
*/
public function addNameTest()
{
if ('*' !== $this->element) {
$this->addCondition('name() = '.Translator::getXpathLiteral($this->element));
@@ -65,7 +85,10 @@ class XPathExpr
return $this;
}
public function addStarPrefix(): XPathExpr
/**
* @return $this
*/
public function addStarPrefix()
{
$this->path .= '*/';
@@ -75,9 +98,12 @@ class XPathExpr
/**
* Joins another XPathExpr with a combiner.
*
* @param string $combiner
* @param XPathExpr $expr
*
* @return $this
*/
public function join(string $combiner, XPathExpr $expr): XPathExpr
public function join($combiner, XPathExpr $expr)
{
$path = $this->__toString().$combiner;
@@ -92,7 +118,10 @@ class XPathExpr
return $this;
}
public function __toString(): string
/**
* @return string
*/
public function __toString()
{
$path = $this->path.$this->element;
$condition = null === $this->condition || '' === $this->condition ? '' : '['.$this->condition.']';