[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/_test/vendor/symfony/css-selector/XPath/Extension/ -> HtmlExtension.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of the Symfony package.
   5   *
   6   * (c) Fabien Potencier <fabien@symfony.com>
   7   *
   8   * For the full copyright and license information, please view the LICENSE
   9   * file that was distributed with this source code.
  10   */
  11  
  12  namespace Symfony\Component\CssSelector\XPath\Extension;
  13  
  14  use Symfony\Component\CssSelector\Exception\ExpressionErrorException;
  15  use Symfony\Component\CssSelector\Node\FunctionNode;
  16  use Symfony\Component\CssSelector\XPath\Translator;
  17  use Symfony\Component\CssSelector\XPath\XPathExpr;
  18  
  19  /**
  20   * XPath expression translator HTML extension.
  21   *
  22   * This component is a port of the Python cssselect library,
  23   * which is copyright Ian Bicking, @see https://github.com/SimonSapin/cssselect.
  24   *
  25   * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
  26   *
  27   * @internal
  28   */
  29  class HtmlExtension extends AbstractExtension
  30  {
  31      public function __construct(Translator $translator)
  32      {
  33          $translator
  34              ->getExtension('node')
  35              ->setFlag(NodeExtension::ELEMENT_NAME_IN_LOWER_CASE, true)
  36              ->setFlag(NodeExtension::ATTRIBUTE_NAME_IN_LOWER_CASE, true);
  37      }
  38  
  39      /**
  40       * {@inheritdoc}
  41       */
  42      public function getPseudoClassTranslators(): array
  43      {
  44          return [
  45              'checked' => [$this, 'translateChecked'],
  46              'link' => [$this, 'translateLink'],
  47              'disabled' => [$this, 'translateDisabled'],
  48              'enabled' => [$this, 'translateEnabled'],
  49              'selected' => [$this, 'translateSelected'],
  50              'invalid' => [$this, 'translateInvalid'],
  51              'hover' => [$this, 'translateHover'],
  52              'visited' => [$this, 'translateVisited'],
  53          ];
  54      }
  55  
  56      /**
  57       * {@inheritdoc}
  58       */
  59      public function getFunctionTranslators(): array
  60      {
  61          return [
  62              'lang' => [$this, 'translateLang'],
  63          ];
  64      }
  65  
  66      public function translateChecked(XPathExpr $xpath): XPathExpr
  67      {
  68          return $xpath->addCondition(
  69              '(@checked '
  70              ."and (name(.) = 'input' or name(.) = 'command')"
  71              ."and (@type = 'checkbox' or @type = 'radio'))"
  72          );
  73      }
  74  
  75      public function translateLink(XPathExpr $xpath): XPathExpr
  76      {
  77          return $xpath->addCondition("@href and (name(.) = 'a' or name(.) = 'link' or name(.) = 'area')");
  78      }
  79  
  80      public function translateDisabled(XPathExpr $xpath): XPathExpr
  81      {
  82          return $xpath->addCondition(
  83              '('
  84                  .'@disabled and'
  85                  .'('
  86                      ."(name(.) = 'input' and @type != 'hidden')"
  87                      ." or name(.) = 'button'"
  88                      ." or name(.) = 'select'"
  89                      ." or name(.) = 'textarea'"
  90                      ." or name(.) = 'command'"
  91                      ." or name(.) = 'fieldset'"
  92                      ." or name(.) = 'optgroup'"
  93                      ." or name(.) = 'option'"
  94                  .')'
  95              .') or ('
  96                  ."(name(.) = 'input' and @type != 'hidden')"
  97                  ." or name(.) = 'button'"
  98                  ." or name(.) = 'select'"
  99                  ." or name(.) = 'textarea'"
 100              .')'
 101              .' and ancestor::fieldset[@disabled]'
 102          );
 103          // todo: in the second half, add "and is not a descendant of that fieldset element's first legend element child, if any."
 104      }
 105  
 106      public function translateEnabled(XPathExpr $xpath): XPathExpr
 107      {
 108          return $xpath->addCondition(
 109              '('
 110                  .'@href and ('
 111                      ."name(.) = 'a'"
 112                      ." or name(.) = 'link'"
 113                      ." or name(.) = 'area'"
 114                  .')'
 115              .') or ('
 116                  .'('
 117                      ."name(.) = 'command'"
 118                      ." or name(.) = 'fieldset'"
 119                      ." or name(.) = 'optgroup'"
 120                  .')'
 121                  .' and not(@disabled)'
 122              .') or ('
 123                  .'('
 124                      ."(name(.) = 'input' and @type != 'hidden')"
 125                      ." or name(.) = 'button'"
 126                      ." or name(.) = 'select'"
 127                      ." or name(.) = 'textarea'"
 128                      ." or name(.) = 'keygen'"
 129                  .')'
 130                  .' and not (@disabled or ancestor::fieldset[@disabled])'
 131              .') or ('
 132                  ."name(.) = 'option' and not("
 133                      .'@disabled or ancestor::optgroup[@disabled]'
 134                  .')'
 135              .')'
 136          );
 137      }
 138  
 139      /**
 140       * @throws ExpressionErrorException
 141       */
 142      public function translateLang(XPathExpr $xpath, FunctionNode $function): XPathExpr
 143      {
 144          $arguments = $function->getArguments();
 145          foreach ($arguments as $token) {
 146              if (!($token->isString() || $token->isIdentifier())) {
 147                  throw new ExpressionErrorException('Expected a single string or identifier for :lang(), got '.implode(', ', $arguments));
 148              }
 149          }
 150  
 151          return $xpath->addCondition(sprintf(
 152              'ancestor-or-self::*[@lang][1][starts-with(concat('
 153              ."translate(@%s, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '-')"
 154              .', %s)]',
 155              'lang',
 156              Translator::getXpathLiteral(strtolower($arguments[0]->getValue()).'-')
 157          ));
 158      }
 159  
 160      public function translateSelected(XPathExpr $xpath): XPathExpr
 161      {
 162          return $xpath->addCondition("(@selected and name(.) = 'option')");
 163      }
 164  
 165      public function translateInvalid(XPathExpr $xpath): XPathExpr
 166      {
 167          return $xpath->addCondition('0');
 168      }
 169  
 170      public function translateHover(XPathExpr $xpath): XPathExpr
 171      {
 172          return $xpath->addCondition('0');
 173      }
 174  
 175      public function translateVisited(XPathExpr $xpath): XPathExpr
 176      {
 177          return $xpath->addCondition('0');
 178      }
 179  
 180      /**
 181       * {@inheritdoc}
 182       */
 183      public function getName(): string
 184      {
 185          return 'html';
 186      }
 187  }