annotate vendor/symfony/css-selector/XPath/Extension/HtmlExtension.php @ 19:fa3358dc1485 tip

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