PluginProbe
WP Job Manager / 2.4.7
WP Job Manager v2.4.7
2.4.7 2.4.6 2.4.5 2.4.4 2.4.3 2.4.2 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.1.0 1.1.1 1.1.2 1.1.3 1.10.0 1.11.0 1.11.1 1.12.0 1.12.1 1.13.0 1.14.0 1.15.0 All 154 releases
wp-job-manager / vendor / sabberworm / php-css-parser / src / Property / Selector.php
Selector.php
139 lines 3.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace Sabberworm\CSS\Property;
4
5 /**
6 * Class representing a single CSS selector. Selectors have to be split by the comma prior to being passed into this
7 * class.
8 */
9 class Selector
10 {
11 /**
12 * regexp for specificity calculations
13 *
14 * @var string
15 */
16 const NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX = '/
17 (\.[\w]+) # classes
18 |
19 \[(\w+) # attributes
20 |
21 (\:( # pseudo classes
22 link|visited|active
23 |hover|focus
24 |lang
25 |target
26 |enabled|disabled|checked|indeterminate
27 |root
28 |nth-child|nth-last-child|nth-of-type|nth-last-of-type
29 |first-child|last-child|first-of-type|last-of-type
30 |only-child|only-of-type
31 |empty|contains
32 ))
33 /ix';
34
35 /**
36 * regexp for specificity calculations
37 *
38 * @var string
39 */
40 const ELEMENTS_AND_PSEUDO_ELEMENTS_RX = '/
41 ((^|[\s\+\>\~]+)[\w]+ # elements
42 |
43 \:{1,2}( # pseudo-elements
44 after|before|first-letter|first-line|selection
45 ))
46 /ix';
47
48 /**
49 * regexp for specificity calculations
50 *
51 * @var string
52 */
53 const SELECTOR_VALIDATION_RX = '/
54 ^(
55 (?:
56 [a-zA-Z0-9\x{00A0}-\x{FFFF}_^$|*="\'~\[\]()\-\s\.:#+>]* # any sequence of valid unescaped characters
57 (?:\\\\.)? # a single escaped character
58 (?:([\'"]).*?(?<!\\\\)\2)? # a quoted text like [id="example"]
59 )*
60 )$
61 /ux';
62
63 /**
64 * @var string
65 */
66 private $sSelector;
67
68 /**
69 * @var int|null
70 */
71 private $iSpecificity;
72
73 /**
74 * @param string $sSelector
75 *
76 * @return bool
77 */
78 public static function isValid($sSelector)
79 {
80 return preg_match(static::SELECTOR_VALIDATION_RX, $sSelector);
81 }
82
83 /**
84 * @param string $sSelector
85 * @param bool $bCalculateSpecificity
86 */
87 public function __construct($sSelector, $bCalculateSpecificity = false)
88 {
89 $this->setSelector($sSelector);
90 if ($bCalculateSpecificity) {
91 $this->getSpecificity();
92 }
93 }
94
95 /**
96 * @return string
97 */
98 public function getSelector()
99 {
100 return $this->sSelector;
101 }
102
103 /**
104 * @param string $sSelector
105 *
106 * @return void
107 */
108 public function setSelector($sSelector)
109 {
110 $this->sSelector = trim($sSelector);
111 $this->iSpecificity = null;
112 }
113
114 /**
115 * @return string
116 */
117 public function __toString()
118 {
119 return $this->getSelector();
120 }
121
122 /**
123 * @return int
124 */
125 public function getSpecificity()
126 {
127 if ($this->iSpecificity === null) {
128 $a = 0;
129 /// @todo should exclude \# as well as "#"
130 $aMatches = null;
131 $b = substr_count($this->sSelector, '#');
132 $c = preg_match_all(self::NON_ID_ATTRIBUTES_AND_PSEUDO_CLASSES_RX, $this->sSelector, $aMatches);
133 $d = preg_match_all(self::ELEMENTS_AND_PSEUDO_ELEMENTS_RX, $this->sSelector, $aMatches);
134 $this->iSpecificity = ($a * 1000) + ($b * 100) + ($c * 10) + $d;
135 }
136 return $this->iSpecificity;
137 }
138 }
139