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\XPath\Translator;
|
Chris@0
|
15 use Symfony\Component\CssSelector\XPath\XPathExpr;
|
Chris@0
|
16
|
Chris@0
|
17 /**
|
Chris@0
|
18 * XPath expression translator attribute extension.
|
Chris@0
|
19 *
|
Chris@0
|
20 * This component is a port of the Python cssselect library,
|
Chris@0
|
21 * which is copyright Ian Bicking, @see https://github.com/SimonSapin/cssselect.
|
Chris@0
|
22 *
|
Chris@0
|
23 * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
|
Chris@0
|
24 *
|
Chris@0
|
25 * @internal
|
Chris@0
|
26 */
|
Chris@0
|
27 class AttributeMatchingExtension extends AbstractExtension
|
Chris@0
|
28 {
|
Chris@0
|
29 /**
|
Chris@0
|
30 * {@inheritdoc}
|
Chris@0
|
31 */
|
Chris@0
|
32 public function getAttributeMatchingTranslators()
|
Chris@0
|
33 {
|
Chris@17
|
34 return [
|
Chris@17
|
35 'exists' => [$this, 'translateExists'],
|
Chris@17
|
36 '=' => [$this, 'translateEquals'],
|
Chris@17
|
37 '~=' => [$this, 'translateIncludes'],
|
Chris@17
|
38 '|=' => [$this, 'translateDashMatch'],
|
Chris@17
|
39 '^=' => [$this, 'translatePrefixMatch'],
|
Chris@17
|
40 '$=' => [$this, 'translateSuffixMatch'],
|
Chris@17
|
41 '*=' => [$this, 'translateSubstringMatch'],
|
Chris@17
|
42 '!=' => [$this, 'translateDifferent'],
|
Chris@17
|
43 ];
|
Chris@0
|
44 }
|
Chris@0
|
45
|
Chris@0
|
46 /**
|
Chris@0
|
47 * @param XPathExpr $xpath
|
Chris@0
|
48 * @param string $attribute
|
Chris@0
|
49 * @param string $value
|
Chris@0
|
50 *
|
Chris@0
|
51 * @return XPathExpr
|
Chris@0
|
52 */
|
Chris@0
|
53 public function translateExists(XPathExpr $xpath, $attribute, $value)
|
Chris@0
|
54 {
|
Chris@0
|
55 return $xpath->addCondition($attribute);
|
Chris@0
|
56 }
|
Chris@0
|
57
|
Chris@0
|
58 /**
|
Chris@0
|
59 * @param XPathExpr $xpath
|
Chris@0
|
60 * @param string $attribute
|
Chris@0
|
61 * @param string $value
|
Chris@0
|
62 *
|
Chris@0
|
63 * @return XPathExpr
|
Chris@0
|
64 */
|
Chris@0
|
65 public function translateEquals(XPathExpr $xpath, $attribute, $value)
|
Chris@0
|
66 {
|
Chris@0
|
67 return $xpath->addCondition(sprintf('%s = %s', $attribute, Translator::getXpathLiteral($value)));
|
Chris@0
|
68 }
|
Chris@0
|
69
|
Chris@0
|
70 /**
|
Chris@0
|
71 * @param XPathExpr $xpath
|
Chris@0
|
72 * @param string $attribute
|
Chris@0
|
73 * @param string $value
|
Chris@0
|
74 *
|
Chris@0
|
75 * @return XPathExpr
|
Chris@0
|
76 */
|
Chris@0
|
77 public function translateIncludes(XPathExpr $xpath, $attribute, $value)
|
Chris@0
|
78 {
|
Chris@0
|
79 return $xpath->addCondition($value ? sprintf(
|
Chris@0
|
80 '%1$s and contains(concat(\' \', normalize-space(%1$s), \' \'), %2$s)',
|
Chris@0
|
81 $attribute,
|
Chris@0
|
82 Translator::getXpathLiteral(' '.$value.' ')
|
Chris@0
|
83 ) : '0');
|
Chris@0
|
84 }
|
Chris@0
|
85
|
Chris@0
|
86 /**
|
Chris@0
|
87 * @param XPathExpr $xpath
|
Chris@0
|
88 * @param string $attribute
|
Chris@0
|
89 * @param string $value
|
Chris@0
|
90 *
|
Chris@0
|
91 * @return XPathExpr
|
Chris@0
|
92 */
|
Chris@0
|
93 public function translateDashMatch(XPathExpr $xpath, $attribute, $value)
|
Chris@0
|
94 {
|
Chris@0
|
95 return $xpath->addCondition(sprintf(
|
Chris@0
|
96 '%1$s and (%1$s = %2$s or starts-with(%1$s, %3$s))',
|
Chris@0
|
97 $attribute,
|
Chris@0
|
98 Translator::getXpathLiteral($value),
|
Chris@0
|
99 Translator::getXpathLiteral($value.'-')
|
Chris@0
|
100 ));
|
Chris@0
|
101 }
|
Chris@0
|
102
|
Chris@0
|
103 /**
|
Chris@0
|
104 * @param XPathExpr $xpath
|
Chris@0
|
105 * @param string $attribute
|
Chris@0
|
106 * @param string $value
|
Chris@0
|
107 *
|
Chris@0
|
108 * @return XPathExpr
|
Chris@0
|
109 */
|
Chris@0
|
110 public function translatePrefixMatch(XPathExpr $xpath, $attribute, $value)
|
Chris@0
|
111 {
|
Chris@0
|
112 return $xpath->addCondition($value ? sprintf(
|
Chris@0
|
113 '%1$s and starts-with(%1$s, %2$s)',
|
Chris@0
|
114 $attribute,
|
Chris@0
|
115 Translator::getXpathLiteral($value)
|
Chris@0
|
116 ) : '0');
|
Chris@0
|
117 }
|
Chris@0
|
118
|
Chris@0
|
119 /**
|
Chris@0
|
120 * @param XPathExpr $xpath
|
Chris@0
|
121 * @param string $attribute
|
Chris@0
|
122 * @param string $value
|
Chris@0
|
123 *
|
Chris@0
|
124 * @return XPathExpr
|
Chris@0
|
125 */
|
Chris@0
|
126 public function translateSuffixMatch(XPathExpr $xpath, $attribute, $value)
|
Chris@0
|
127 {
|
Chris@0
|
128 return $xpath->addCondition($value ? sprintf(
|
Chris@0
|
129 '%1$s and substring(%1$s, string-length(%1$s)-%2$s) = %3$s',
|
Chris@0
|
130 $attribute,
|
Chris@17
|
131 \strlen($value) - 1,
|
Chris@0
|
132 Translator::getXpathLiteral($value)
|
Chris@0
|
133 ) : '0');
|
Chris@0
|
134 }
|
Chris@0
|
135
|
Chris@0
|
136 /**
|
Chris@0
|
137 * @param XPathExpr $xpath
|
Chris@0
|
138 * @param string $attribute
|
Chris@0
|
139 * @param string $value
|
Chris@0
|
140 *
|
Chris@0
|
141 * @return XPathExpr
|
Chris@0
|
142 */
|
Chris@0
|
143 public function translateSubstringMatch(XPathExpr $xpath, $attribute, $value)
|
Chris@0
|
144 {
|
Chris@0
|
145 return $xpath->addCondition($value ? sprintf(
|
Chris@0
|
146 '%1$s and contains(%1$s, %2$s)',
|
Chris@0
|
147 $attribute,
|
Chris@0
|
148 Translator::getXpathLiteral($value)
|
Chris@0
|
149 ) : '0');
|
Chris@0
|
150 }
|
Chris@0
|
151
|
Chris@0
|
152 /**
|
Chris@0
|
153 * @param XPathExpr $xpath
|
Chris@0
|
154 * @param string $attribute
|
Chris@0
|
155 * @param string $value
|
Chris@0
|
156 *
|
Chris@0
|
157 * @return XPathExpr
|
Chris@0
|
158 */
|
Chris@0
|
159 public function translateDifferent(XPathExpr $xpath, $attribute, $value)
|
Chris@0
|
160 {
|
Chris@0
|
161 return $xpath->addCondition(sprintf(
|
Chris@0
|
162 $value ? 'not(%1$s) or %1$s != %2$s' : '%s != %s',
|
Chris@0
|
163 $attribute,
|
Chris@0
|
164 Translator::getXpathLiteral($value)
|
Chris@0
|
165 ));
|
Chris@0
|
166 }
|
Chris@0
|
167
|
Chris@0
|
168 /**
|
Chris@0
|
169 * {@inheritdoc}
|
Chris@0
|
170 */
|
Chris@0
|
171 public function getName()
|
Chris@0
|
172 {
|
Chris@0
|
173 return 'attribute-matching';
|
Chris@0
|
174 }
|
Chris@0
|
175 }
|