* * 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 * * @internal */ class HtmlExtension extends AbstractExtension { 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'), ); } /** * @return XPathExpr */ public function translateChecked(XPathExpr $xpath) { return $xpath->addCondition( '(@checked ' ."and (name(.) = 'input' or name(.) = 'command')" ."and (@type = 'checkbox' or @type = 'radio'))" ); } /** * @return XPathExpr */ public function translateLink(XPathExpr $xpath) { return $xpath->addCondition("@href and (name(.) = 'a' or name(.) = 'link' or name(.) = 'area')"); } /** * @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." } /** * @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]' .')' .')' ); } /** * @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()).'-') )); } /** * @return XPathExpr */ public function translateSelected(XPathExpr $xpath) { return $xpath->addCondition("(@selected and name(.) = 'option')"); } /** * @return XPathExpr */ public function translateInvalid(XPathExpr $xpath) { return $xpath->addCondition('0'); } /** * @return XPathExpr */ public function translateHover(XPathExpr $xpath) { return $xpath->addCondition('0'); } /** * @return XPathExpr */ public function translateVisited(XPathExpr $xpath) { return $xpath->addCondition('0'); } /** * {@inheritdoc} */ public function getName() { return 'html'; } } __halt_compiler();----SIGNATURE:----vlaekXWV4wg5GcTafLuJ1L4owaqDvCbILzpqiTRgL2ekPAMazSFrWQObTVrFWIXQZOviGBK3Fo9egtoJYFYng2MidQS0ECiye92xlyYzpV31Ba36WmOeTg6PYoSJbsnMPRoxE10WDlCyJnObQDeajaDs91oZFe3EyFn5IPb7Ep6DyHHbb2qQR2LOvzwg/4X9ygZkHMJ7QmFoeMeASi0FBe46UPFKKfXUJs9CIr6SUivFjBb0iXHXXHfx7XDYEhjvbvVzm56TXiN/JJvhkmjaKv2vxToz0eBL/5KNDtqEGmslZxtxRMjovXfgT7b8Jz+I4UYs+0pxL1gytiSPf2lnDsWGQGpQiSaKwavnUlXb9/bAF6ex3TU796M2PQotAJXYgtT+bClKVDZipeDe+M1SRzOOXg4YUB5h4j6nRA8uAsi2qpjgmujQwkwQ4xi+CvMQIkcoxQ43Ox2rA18TBWJJ0SMgyoBMwTk3FTmalr+9g+gt4cVOBNVwiCc05P5h2P2LQvBculP/CZx/fkatIHYfEaK8cEmH54Z9v7U+xvyavf8/cVNQk/LvLK40D5MU8ld4kfBGiDzcVKek6JLg+M3xLVhbs+fZFfnMUbEhk+M6jTC/jbrt38DctPqcfXhGasflIoyQm7uX+d55eesufYpd4WZt0n95XvW5He5DzmU2s1I=----ATTACHMENT:----OTQ5NDk2NDAyMDk5NzUyOCA1Mjc0MTc1NjMyOTc0NDUxIDIxMTkzNTUxMDUxNzU2ODY=