PluginProbe
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses / 4.4.0
LearnPress – WordPress LMS Plugin for Create and Sell Online Courses v4.4.0
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 / NodeExtension.php

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

192 lines 5.7 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\Node;
15 use Symfony\Component\CssSelector\XPath\Translator;
16 use Symfony\Component\CssSelector\XPath\XPathExpr;
17
18 /**
19 * XPath expression translator node extension.
20 *
21 * This component is a port of the Python cssselect library,
22 * which is copyright Ian Bicking, @see https://github.com/SimonSapin/cssselect.
23 *
24 * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
25 *
26 * @internal
27 */
28 class NodeExtension extends AbstractExtension
29 {
30 public const ELEMENT_NAME_IN_LOWER_CASE = 1;
31 public const ATTRIBUTE_NAME_IN_LOWER_CASE = 2;
32 public const ATTRIBUTE_VALUE_IN_LOWER_CASE = 4;
33
34 private int $flags;
35
36 public function __construct(int $flags = 0)
37 {
38 $this->flags = $flags;
39 }
40
41 /**
42 * @return $this
43 */
44 public function setFlag(int $flag, bool $on): static
45 {
46 if ($on && !$this->hasFlag($flag)) {
47 $this->flags += $flag;
48 }
49
50 if (!$on && $this->hasFlag($flag)) {
51 $this->flags -= $flag;
52 }
53
54 return $this;
55 }
56
57 public function hasFlag(int $flag): bool
58 {
59 return (bool) ($this->flags & $flag);
60 }
61
62 public function getNodeTranslators(): array
63 {
64 return [
65 'Selector' => $this->translateSelector(...),
66 'CombinedSelector' => $this->translateCombinedSelector(...),
67 'Negation' => $this->translateNegation(...),
68 'Function' => $this->translateFunction(...),
69 'Pseudo' => $this->translatePseudo(...),
70 'Attribute' => $this->translateAttribute(...),
71 'Class' => $this->translateClass(...),
72 'Hash' => $this->translateHash(...),
73 'Element' => $this->translateElement(...),
74 ];
75 }
76
77 public function translateSelector(Node\SelectorNode $node, Translator $translator): XPathExpr
78 {
79 return $translator->nodeToXPath($node->getTree());
80 }
81
82 public function translateCombinedSelector(Node\CombinedSelectorNode $node, Translator $translator): XPathExpr
83 {
84 return $translator->addCombination($node->getCombinator(), $node->getSelector(), $node->getSubSelector());
85 }
86
87 public function translateNegation(Node\NegationNode $node, Translator $translator): XPathExpr
88 {
89 $xpath = $translator->nodeToXPath($node->getSelector());
90 $subXpath = $translator->nodeToXPath($node->getSubSelector());
91 $subXpath->addNameTest();
92
93 if ($subXpath->getCondition()) {
94 return $xpath->addCondition(\sprintf('not(%s)', $subXpath->getCondition()));
95 }
96
97 return $xpath->addCondition('0');
98 }
99
100 public function translateFunction(Node\FunctionNode $node, Translator $translator): XPathExpr
101 {
102 $xpath = $translator->nodeToXPath($node->getSelector());
103
104 return $translator->addFunction($xpath, $node);
105 }
106
107 public function translatePseudo(Node\PseudoNode $node, Translator $translator): XPathExpr
108 {
109 $xpath = $translator->nodeToXPath($node->getSelector());
110
111 return $translator->addPseudoClass($xpath, $node->getIdentifier());
112 }
113
114 public function translateAttribute(Node\AttributeNode $node, Translator $translator): XPathExpr
115 {
116 $name = $node->getAttribute();
117 $safe = $this->isSafeName($name);
118
119 if ($this->hasFlag(self::ATTRIBUTE_NAME_IN_LOWER_CASE)) {
120 $name = strtolower($name);
121 }
122
123 if ($node->getNamespace()) {
124 $name = \sprintf('%s:%s', $node->getNamespace(), $name);
125 $safe = $safe && $this->isSafeName($node->getNamespace());
126 }
127
128 $attribute = $safe ? '@'.$name : \sprintf('attribute::*[name() = %s]', Translator::getXpathLiteral($name));
129 $value = $node->getValue();
130 $xpath = $translator->nodeToXPath($node->getSelector());
131
132 if ($this->hasFlag(self::ATTRIBUTE_VALUE_IN_LOWER_CASE)) {
133 $value = strtolower($value);
134 }
135
136 return $translator->addAttributeMatching($xpath, $node->getOperator(), $attribute, $value);
137 }
138
139 public function translateClass(Node\ClassNode $node, Translator $translator): XPathExpr
140 {
141 $xpath = $translator->nodeToXPath($node->getSelector());
142
143 return $translator->addAttributeMatching($xpath, '~=', '@class', $node->getName());
144 }
145
146 public function translateHash(Node\HashNode $node, Translator $translator): XPathExpr
147 {
148 $xpath = $translator->nodeToXPath($node->getSelector());
149
150 return $translator->addAttributeMatching($xpath, '=', '@id', $node->getId());
151 }
152
153 public function translateElement(Node\ElementNode $node): XPathExpr
154 {
155 $element = $node->getElement();
156
157 if ($element && $this->hasFlag(self::ELEMENT_NAME_IN_LOWER_CASE)) {
158 $element = strtolower($element);
159 }
160
161 if ($element) {
162 $safe = $this->isSafeName($element);
163 } else {
164 $element = '*';
165 $safe = true;
166 }
167
168 if ($node->getNamespace()) {
169 $element = \sprintf('%s:%s', $node->getNamespace(), $element);
170 $safe = $safe && $this->isSafeName($node->getNamespace());
171 }
172
173 $xpath = new XPathExpr('', $element);
174
175 if (!$safe) {
176 $xpath->addNameTest();
177 }
178
179 return $xpath;
180 }
181
182 public function getName(): string
183 {
184 return 'node';
185 }
186
187 private function isSafeName(string $name): bool
188 {
189 return 0 < preg_match('~^[a-zA-Z_][a-zA-Z0-9_.-]*$~', $name);
190 }
191 }
192