annotate vendor/symfony/css-selector/XPath/Extension/HtmlExtension.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 1fec387a4317
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 /**
Chris@0 32 * Constructor.
Chris@0 33 *
Chris@0 34 * @param Translator $translator
Chris@0 35 */
Chris@0 36 public function __construct(Translator $translator)
Chris@0 37 {
Chris@0 38 $translator
Chris@0 39 ->getExtension('node')
Chris@0 40 ->setFlag(NodeExtension::ELEMENT_NAME_IN_LOWER_CASE, true)
Chris@0 41 ->setFlag(NodeExtension::ATTRIBUTE_NAME_IN_LOWER_CASE, true);
Chris@0 42 }
Chris@0 43
Chris@0 44 /**
Chris@0 45 * {@inheritdoc}
Chris@0 46 */
Chris@0 47 public function getPseudoClassTranslators()
Chris@0 48 {
Chris@0 49 return array(
Chris@0 50 'checked' => array($this, 'translateChecked'),
Chris@0 51 'link' => array($this, 'translateLink'),
Chris@0 52 'disabled' => array($this, 'translateDisabled'),
Chris@0 53 'enabled' => array($this, 'translateEnabled'),
Chris@0 54 'selected' => array($this, 'translateSelected'),
Chris@0 55 'invalid' => array($this, 'translateInvalid'),
Chris@0 56 'hover' => array($this, 'translateHover'),
Chris@0 57 'visited' => array($this, 'translateVisited'),
Chris@0 58 );
Chris@0 59 }
Chris@0 60
Chris@0 61 /**
Chris@0 62 * {@inheritdoc}
Chris@0 63 */
Chris@0 64 public function getFunctionTranslators()
Chris@0 65 {
Chris@0 66 return array(
Chris@0 67 'lang' => array($this, 'translateLang'),
Chris@0 68 );
Chris@0 69 }
Chris@0 70
Chris@0 71 /**
Chris@0 72 * @param XPathExpr $xpath
Chris@0 73 *
Chris@0 74 * @return XPathExpr
Chris@0 75 */
Chris@0 76 public function translateChecked(XPathExpr $xpath)
Chris@0 77 {
Chris@0 78 return $xpath->addCondition(
Chris@0 79 '(@checked '
Chris@0 80 ."and (name(.) = 'input' or name(.) = 'command')"
Chris@0 81 ."and (@type = 'checkbox' or @type = 'radio'))"
Chris@0 82 );
Chris@0 83 }
Chris@0 84
Chris@0 85 /**
Chris@0 86 * @param XPathExpr $xpath
Chris@0 87 *
Chris@0 88 * @return XPathExpr
Chris@0 89 */
Chris@0 90 public function translateLink(XPathExpr $xpath)
Chris@0 91 {
Chris@0 92 return $xpath->addCondition("@href and (name(.) = 'a' or name(.) = 'link' or name(.) = 'area')");
Chris@0 93 }
Chris@0 94
Chris@0 95 /**
Chris@0 96 * @param XPathExpr $xpath
Chris@0 97 *
Chris@0 98 * @return XPathExpr
Chris@0 99 */
Chris@0 100 public function translateDisabled(XPathExpr $xpath)
Chris@0 101 {
Chris@0 102 return $xpath->addCondition(
Chris@0 103 '('
Chris@0 104 .'@disabled and'
Chris@0 105 .'('
Chris@0 106 ."(name(.) = 'input' and @type != 'hidden')"
Chris@0 107 ." or name(.) = 'button'"
Chris@0 108 ." or name(.) = 'select'"
Chris@0 109 ." or name(.) = 'textarea'"
Chris@0 110 ." or name(.) = 'command'"
Chris@0 111 ." or name(.) = 'fieldset'"
Chris@0 112 ." or name(.) = 'optgroup'"
Chris@0 113 ." or name(.) = 'option'"
Chris@0 114 .')'
Chris@0 115 .') or ('
Chris@0 116 ."(name(.) = 'input' and @type != 'hidden')"
Chris@0 117 ." or name(.) = 'button'"
Chris@0 118 ." or name(.) = 'select'"
Chris@0 119 ." or name(.) = 'textarea'"
Chris@0 120 .')'
Chris@0 121 .' and ancestor::fieldset[@disabled]'
Chris@0 122 );
Chris@0 123 // todo: in the second half, add "and is not a descendant of that fieldset element's first legend element child, if any."
Chris@0 124 }
Chris@0 125
Chris@0 126 /**
Chris@0 127 * @param XPathExpr $xpath
Chris@0 128 *
Chris@0 129 * @return XPathExpr
Chris@0 130 */
Chris@0 131 public function translateEnabled(XPathExpr $xpath)
Chris@0 132 {
Chris@0 133 return $xpath->addCondition(
Chris@0 134 '('
Chris@0 135 .'@href and ('
Chris@0 136 ."name(.) = 'a'"
Chris@0 137 ." or name(.) = 'link'"
Chris@0 138 ." or name(.) = 'area'"
Chris@0 139 .')'
Chris@0 140 .') or ('
Chris@0 141 .'('
Chris@0 142 ."name(.) = 'command'"
Chris@0 143 ." or name(.) = 'fieldset'"
Chris@0 144 ." or name(.) = 'optgroup'"
Chris@0 145 .')'
Chris@0 146 .' and not(@disabled)'
Chris@0 147 .') or ('
Chris@0 148 .'('
Chris@0 149 ."(name(.) = 'input' and @type != 'hidden')"
Chris@0 150 ." or name(.) = 'button'"
Chris@0 151 ." or name(.) = 'select'"
Chris@0 152 ." or name(.) = 'textarea'"
Chris@0 153 ." or name(.) = 'keygen'"
Chris@0 154 .')'
Chris@0 155 .' and not (@disabled or ancestor::fieldset[@disabled])'
Chris@0 156 .') or ('
Chris@0 157 ."name(.) = 'option' and not("
Chris@0 158 .'@disabled or ancestor::optgroup[@disabled]'
Chris@0 159 .')'
Chris@0 160 .')'
Chris@0 161 );
Chris@0 162 }
Chris@0 163
Chris@0 164 /**
Chris@0 165 * @param XPathExpr $xpath
Chris@0 166 * @param FunctionNode $function
Chris@0 167 *
Chris@0 168 * @return XPathExpr
Chris@0 169 *
Chris@0 170 * @throws ExpressionErrorException
Chris@0 171 */
Chris@0 172 public function translateLang(XPathExpr $xpath, FunctionNode $function)
Chris@0 173 {
Chris@0 174 $arguments = $function->getArguments();
Chris@0 175 foreach ($arguments as $token) {
Chris@0 176 if (!($token->isString() || $token->isIdentifier())) {
Chris@0 177 throw new ExpressionErrorException(
Chris@0 178 'Expected a single string or identifier for :lang(), got '
Chris@0 179 .implode(', ', $arguments)
Chris@0 180 );
Chris@0 181 }
Chris@0 182 }
Chris@0 183
Chris@0 184 return $xpath->addCondition(sprintf(
Chris@0 185 'ancestor-or-self::*[@lang][1][starts-with(concat('
Chris@0 186 ."translate(@%s, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '-')"
Chris@0 187 .', %s)]',
Chris@0 188 'lang',
Chris@0 189 Translator::getXpathLiteral(strtolower($arguments[0]->getValue()).'-')
Chris@0 190 ));
Chris@0 191 }
Chris@0 192
Chris@0 193 /**
Chris@0 194 * @param XPathExpr $xpath
Chris@0 195 *
Chris@0 196 * @return XPathExpr
Chris@0 197 */
Chris@0 198 public function translateSelected(XPathExpr $xpath)
Chris@0 199 {
Chris@0 200 return $xpath->addCondition("(@selected and name(.) = 'option')");
Chris@0 201 }
Chris@0 202
Chris@0 203 /**
Chris@0 204 * @param XPathExpr $xpath
Chris@0 205 *
Chris@0 206 * @return XPathExpr
Chris@0 207 */
Chris@0 208 public function translateInvalid(XPathExpr $xpath)
Chris@0 209 {
Chris@0 210 return $xpath->addCondition('0');
Chris@0 211 }
Chris@0 212
Chris@0 213 /**
Chris@0 214 * @param XPathExpr $xpath
Chris@0 215 *
Chris@0 216 * @return XPathExpr
Chris@0 217 */
Chris@0 218 public function translateHover(XPathExpr $xpath)
Chris@0 219 {
Chris@0 220 return $xpath->addCondition('0');
Chris@0 221 }
Chris@0 222
Chris@0 223 /**
Chris@0 224 * @param XPathExpr $xpath
Chris@0 225 *
Chris@0 226 * @return XPathExpr
Chris@0 227 */
Chris@0 228 public function translateVisited(XPathExpr $xpath)
Chris@0 229 {
Chris@0 230 return $xpath->addCondition('0');
Chris@0 231 }
Chris@0 232
Chris@0 233 /**
Chris@0 234 * {@inheritdoc}
Chris@0 235 */
Chris@0 236 public function getName()
Chris@0 237 {
Chris@0 238 return 'html';
Chris@0 239 }
Chris@0 240 }