PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.8
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.8
4.4.8 4.4.7 4.4.6 4.4.5 4.4.4 4.4.3 4.4.2 4.4.1 4.4.0 4.3.9.1 4.3.9 4.3.8 4.3.7 4.1.6.9 4.1.6.9.1 4.1.6.9.2 4.1.6.9.3 4.1.6.9.4 4.1.7 4.1.7.1 4.1.7.2 4.1.7.3 4.1.7.3.1 4.1.7.3.2 4.2.0 All 139 releases
learnpress / vendor / symfony / css-selector / XPath / Extension / FunctionExtension.php

FunctionExtension.php in LearnPress – WordPress LMS Plugin for Create and Sell Online Courses 4.4.8, at vendor/symfony/css-selector/XPath/Extension/FunctionExtension.php

166 lines 5.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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\Exception\SyntaxErrorException;
16 use Symfony\Component\CssSelector\Node\FunctionNode;
17 use Symfony\Component\CssSelector\Parser\Parser;
18 use Symfony\Component\CssSelector\XPath\Translator;
19 use Symfony\Component\CssSelector\XPath\XPathExpr;
20
21 /**
22 * XPath expression translator function extension.
23 *
24 * This component is a port of the Python cssselect library,
25 * which is copyright Ian Bicking, @see https://github.com/SimonSapin/cssselect.
26 *
27 * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
28 *
29 * @internal
30 */
31 class FunctionExtension extends AbstractExtension
32 {
33 public function getFunctionTranslators(): array
34 {
35 return [
36 'nth-child' => $this->translateNthChild(...),
37 'nth-last-child' => $this->translateNthLastChild(...),
38 'nth-of-type' => $this->translateNthOfType(...),
39 'nth-last-of-type' => $this->translateNthLastOfType(...),
40 'contains' => $this->translateContains(...),
41 'lang' => $this->translateLang(...),
42 ];
43 }
44
45 /**
46 * @throws ExpressionErrorException
47 */
48 public function translateNthChild(XPathExpr $xpath, FunctionNode $function, bool $last = false, bool $addNameTest = true): XPathExpr
49 {
50 try {
51 [$a, $b] = Parser::parseSeries($function->getArguments());
52 } catch (SyntaxErrorException $e) {
53 throw new ExpressionErrorException(\sprintf('Invalid series: "%s".', implode('", "', $function->getArguments())), 0, $e);
54 }
55
56 $xpath->addStarPrefix();
57 if ($addNameTest) {
58 $xpath->addNameTest();
59 }
60
61 if (0 === $a) {
62 return $xpath->addCondition('position() = '.($last ? 'last() - '.($b - 1) : $b));
63 }
64
65 if ($a < 0) {
66 if ($b < 1) {
67 return $xpath->addCondition('false()');
68 }
69
70 $sign = '<=';
71 } else {
72 $sign = '>=';
73 }
74
75 $expr = 'position()';
76
77 if ($last) {
78 $expr = 'last() - '.$expr;
79 --$b;
80 }
81
82 if (0 !== $b) {
83 $expr .= ' - '.$b;
84 }
85
86 $conditions = [\sprintf('%s %s 0', $expr, $sign)];
87
88 if (1 !== $a && -1 !== $a) {
89 $conditions[] = \sprintf('(%s) mod %d = 0', $expr, $a);
90 }
91
92 return $xpath->addCondition(implode(' and ', $conditions));
93
94 // todo: handle an+b, odd, even
95 // an+b means every-a, plus b, e.g., 2n+1 means odd
96 // 0n+b means b
97 // n+0 means a=1, i.e., all elements
98 // an means every a elements, i.e., 2n means even
99 // -n means -1n
100 // -1n+6 means elements 6 and previous
101 }
102
103 public function translateNthLastChild(XPathExpr $xpath, FunctionNode $function): XPathExpr
104 {
105 return $this->translateNthChild($xpath, $function, true);
106 }
107
108 public function translateNthOfType(XPathExpr $xpath, FunctionNode $function): XPathExpr
109 {
110 return $this->translateNthChild($xpath, $function, false, false);
111 }
112
113 /**
114 * @throws ExpressionErrorException
115 */
116 public function translateNthLastOfType(XPathExpr $xpath, FunctionNode $function): XPathExpr
117 {
118 if ('*' === $xpath->getElement()) {
119 throw new ExpressionErrorException('"*:nth-of-type()" is not implemented.');
120 }
121
122 return $this->translateNthChild($xpath, $function, true, false);
123 }
124
125 /**
126 * @throws ExpressionErrorException
127 */
128 public function translateContains(XPathExpr $xpath, FunctionNode $function): XPathExpr
129 {
130 $arguments = $function->getArguments();
131 foreach ($arguments as $token) {
132 if (!($token->isString() || $token->isIdentifier())) {
133 throw new ExpressionErrorException('Expected a single string or identifier for :contains(), got '.implode(', ', $arguments));
134 }
135 }
136
137 return $xpath->addCondition(\sprintf(
138 'contains(string(.), %s)',
139 Translator::getXpathLiteral($arguments[0]->getValue())
140 ));
141 }
142
143 /**
144 * @throws ExpressionErrorException
145 */
146 public function translateLang(XPathExpr $xpath, FunctionNode $function): XPathExpr
147 {
148 $arguments = $function->getArguments();
149 foreach ($arguments as $token) {
150 if (!($token->isString() || $token->isIdentifier())) {
151 throw new ExpressionErrorException('Expected a single string or identifier for :lang(), got '.implode(', ', $arguments));
152 }
153 }
154
155 return $xpath->addCondition(\sprintf(
156 'lang(%s)',
157 Translator::getXpathLiteral($arguments[0]->getValue())
158 ));
159 }
160
161 public function getName(): string
162 {
163 return 'function';
164 }
165 }
166