Version 1
[yaffs-website] / vendor / symfony / css-selector / XPath / Extension / HtmlExtension.php
diff --git a/vendor/symfony/css-selector/XPath/Extension/HtmlExtension.php b/vendor/symfony/css-selector/XPath/Extension/HtmlExtension.php
new file mode 100644 (file)
index 0000000..de6ce41
--- /dev/null
@@ -0,0 +1,240 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Component\CssSelector\XPath\Extension;
+
+use Symfony\Component\CssSelector\Exception\ExpressionErrorException;
+use Symfony\Component\CssSelector\Node\FunctionNode;
+use Symfony\Component\CssSelector\XPath\Translator;
+use Symfony\Component\CssSelector\XPath\XPathExpr;
+
+/**
+ * XPath expression translator HTML extension.
+ *
+ * This component is a port of the Python cssselect library,
+ * which is copyright Ian Bicking, @see https://github.com/SimonSapin/cssselect.
+ *
+ * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
+ *
+ * @internal
+ */
+class HtmlExtension extends AbstractExtension
+{
+    /**
+     * Constructor.
+     *
+     * @param Translator $translator
+     */
+    public function __construct(Translator $translator)
+    {
+        $translator
+            ->getExtension('node')
+            ->setFlag(NodeExtension::ELEMENT_NAME_IN_LOWER_CASE, true)
+            ->setFlag(NodeExtension::ATTRIBUTE_NAME_IN_LOWER_CASE, true);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getPseudoClassTranslators()
+    {
+        return array(
+            'checked' => array($this, 'translateChecked'),
+            'link' => array($this, 'translateLink'),
+            'disabled' => array($this, 'translateDisabled'),
+            'enabled' => array($this, 'translateEnabled'),
+            'selected' => array($this, 'translateSelected'),
+            'invalid' => array($this, 'translateInvalid'),
+            'hover' => array($this, 'translateHover'),
+            'visited' => array($this, 'translateVisited'),
+        );
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getFunctionTranslators()
+    {
+        return array(
+            'lang' => array($this, 'translateLang'),
+        );
+    }
+
+    /**
+     * @param XPathExpr $xpath
+     *
+     * @return XPathExpr
+     */
+    public function translateChecked(XPathExpr $xpath)
+    {
+        return $xpath->addCondition(
+            '(@checked '
+            ."and (name(.) = 'input' or name(.) = 'command')"
+            ."and (@type = 'checkbox' or @type = 'radio'))"
+        );
+    }
+
+    /**
+     * @param XPathExpr $xpath
+     *
+     * @return XPathExpr
+     */
+    public function translateLink(XPathExpr $xpath)
+    {
+        return $xpath->addCondition("@href and (name(.) = 'a' or name(.) = 'link' or name(.) = 'area')");
+    }
+
+    /**
+     * @param XPathExpr $xpath
+     *
+     * @return XPathExpr
+     */
+    public function translateDisabled(XPathExpr $xpath)
+    {
+        return $xpath->addCondition(
+            '('
+                .'@disabled and'
+                .'('
+                    ."(name(.) = 'input' and @type != 'hidden')"
+                    ." or name(.) = 'button'"
+                    ." or name(.) = 'select'"
+                    ." or name(.) = 'textarea'"
+                    ." or name(.) = 'command'"
+                    ." or name(.) = 'fieldset'"
+                    ." or name(.) = 'optgroup'"
+                    ." or name(.) = 'option'"
+                .')'
+            .') or ('
+                ."(name(.) = 'input' and @type != 'hidden')"
+                ." or name(.) = 'button'"
+                ." or name(.) = 'select'"
+                ." or name(.) = 'textarea'"
+            .')'
+            .' and ancestor::fieldset[@disabled]'
+        );
+        // todo: in the second half, add "and is not a descendant of that fieldset element's first legend element child, if any."
+    }
+
+    /**
+     * @param XPathExpr $xpath
+     *
+     * @return XPathExpr
+     */
+    public function translateEnabled(XPathExpr $xpath)
+    {
+        return $xpath->addCondition(
+            '('
+                .'@href and ('
+                    ."name(.) = 'a'"
+                    ." or name(.) = 'link'"
+                    ." or name(.) = 'area'"
+                .')'
+            .') or ('
+                .'('
+                    ."name(.) = 'command'"
+                    ." or name(.) = 'fieldset'"
+                    ." or name(.) = 'optgroup'"
+                .')'
+                .' and not(@disabled)'
+            .') or ('
+                .'('
+                    ."(name(.) = 'input' and @type != 'hidden')"
+                    ." or name(.) = 'button'"
+                    ." or name(.) = 'select'"
+                    ." or name(.) = 'textarea'"
+                    ." or name(.) = 'keygen'"
+                .')'
+                .' and not (@disabled or ancestor::fieldset[@disabled])'
+            .') or ('
+                ."name(.) = 'option' and not("
+                    .'@disabled or ancestor::optgroup[@disabled]'
+                .')'
+            .')'
+        );
+    }
+
+    /**
+     * @param XPathExpr    $xpath
+     * @param FunctionNode $function
+     *
+     * @return XPathExpr
+     *
+     * @throws ExpressionErrorException
+     */
+    public function translateLang(XPathExpr $xpath, FunctionNode $function)
+    {
+        $arguments = $function->getArguments();
+        foreach ($arguments as $token) {
+            if (!($token->isString() || $token->isIdentifier())) {
+                throw new ExpressionErrorException(
+                    'Expected a single string or identifier for :lang(), got '
+                    .implode(', ', $arguments)
+                );
+            }
+        }
+
+        return $xpath->addCondition(sprintf(
+            'ancestor-or-self::*[@lang][1][starts-with(concat('
+            ."translate(@%s, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '-')"
+            .', %s)]',
+            'lang',
+            Translator::getXpathLiteral(strtolower($arguments[0]->getValue()).'-')
+        ));
+    }
+
+    /**
+     * @param XPathExpr $xpath
+     *
+     * @return XPathExpr
+     */
+    public function translateSelected(XPathExpr $xpath)
+    {
+        return $xpath->addCondition("(@selected and name(.) = 'option')");
+    }
+
+    /**
+     * @param XPathExpr $xpath
+     *
+     * @return XPathExpr
+     */
+    public function translateInvalid(XPathExpr $xpath)
+    {
+        return $xpath->addCondition('0');
+    }
+
+    /**
+     * @param XPathExpr $xpath
+     *
+     * @return XPathExpr
+     */
+    public function translateHover(XPathExpr $xpath)
+    {
+        return $xpath->addCondition('0');
+    }
+
+    /**
+     * @param XPathExpr $xpath
+     *
+     * @return XPathExpr
+     */
+    public function translateVisited(XPathExpr $xpath)
+    {
+        return $xpath->addCondition('0');
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getName()
+    {
+        return 'html';
+    }
+}