File Coverage

blib/lib/Mojo/DOM/CSS.pm
Criterion Covered Total %
statement 230 237 97.0
branch 187 200 93.5
condition 96 114 84.2
subroutine 28 28 100.0
pod 3 3 100.0
total 544 582 93.4


line stmt bran cond sub pod time code
1             package Mojo::DOM::CSS;
2 65     65   455 use Mojo::Base -base;
  65         139  
  65         647  
3              
4 65     65   458 use Carp qw(croak);
  65         185  
  65         4497  
5 65     65   413 use Mojo::Util qw(dumper trim);
  65         158  
  65         5374  
6              
7 65   50 65   466 use constant DEBUG => $ENV{MOJO_DOM_CSS_DEBUG} || 0;
  65         184  
  65         450014  
8              
9             has 'tree';
10              
11             my $ESCAPE_RE = qr/\\[^0-9a-fA-F]|\\[0-9a-fA-F]{1,6}/;
12             my $ATTR_RE = qr/
13             \[
14             ((?:$ESCAPE_RE|[\w\-])+) # Key
15             (?:
16             (\W)?= # Operator
17             (?:"((?:\\"|[^"])*)"|'((?:\\'|[^'])*)'|([^\]]+?)) # Value
18             (?:\s+(?:(i|I)|s|S))? # Case-sensitivity
19             )?
20             \]
21             /x;
22              
23             sub matches {
24 44     44 1 114 my $tree = shift->tree;
25 44 100       127 return undef if $tree->[0] ne 'tag';
26 43         91 return _match(_compile(@_), $tree, $tree, _root($tree));
27             }
28              
29 449     449 1 1469 sub select { _select(0, shift->tree, _compile(@_)) }
30 784     784 1 2470 sub select_one { _select(1, shift->tree, _compile(@_)) }
31              
32 48 100   48   56 sub _absolutize { [map { _is_scoped($_) ? $_ : [[['pc', 'scope']], ' ', @$_] } @{shift()}] }
  51         69  
  48         75  
33              
34             sub _all_tags {
35 2336     2336   3707 my $tree = shift;
36              
37 2336         3609 my @tags;
38 2336 100       9402 my @queue = @$tree[($tree->[0] eq 'root' ? 1 : 4) .. $#$tree];
39 2336         5839 while (my $current = shift @queue) {
40 146853 100       345882 next unless $current->[0] eq 'tag';
41 49827         75376 push @tags, $current;
42 49827         135413 unshift @queue, @$current[4 .. $#$current];
43             }
44              
45 2336         9824 return \@tags;
46             }
47              
48             sub _attr {
49 2345     2345   3958 my ($name_re, $value_re, $current) = @_;
50              
51 2345         3318 my $attrs = $current->[2];
52 2345         5288 for my $name (keys %$attrs) {
53 1927         3604 my $value = $attrs->{$name};
54 1927 100 100     10716 next if $name !~ $name_re || (!defined $value && defined $value_re);
      100        
55 833 100 100     6451 return 1 if !(defined $value && defined $value_re) || $value =~ $value_re;
      100        
56             }
57              
58 1856         6386 return undef;
59             }
60              
61             sub _compile {
62 1331     1331   5693 my ($css, %ns) = (trim('' . shift), @_);
63              
64 1331         3814 my $group = [[]];
65 1331         3795 while (my $selectors = $group->[-1]) {
66 4614 100 100     14919 push @$selectors, [] unless @$selectors && ref $selectors->[-1];
67 4614         6419 my $last = $selectors->[-1];
68              
69             # Separator
70 4614 100       39655 if ($css =~ /\G\s*,\s*/gc) { push @$group, [] }
  15 100       41  
    100          
    100          
    100          
    100          
    100          
71              
72             # Combinator
73             elsif ($css =~ /\G\s*([>+~])\s*/gc) {
74 507 100       1266 push @$last, ['pc', 'scope'] unless @$last;
75 507         1662 push @$selectors, $1;
76             }
77              
78             # Descendant combinator
79             elsif ($css =~ /\G\s+/gc) {
80 261 50       623 push @$last, ['pc', 'scope'] unless @$last;
81 261         657 push @$selectors, ' ';
82             }
83              
84             # Class or ID
85             elsif ($css =~ /\G([.#])((?:$ESCAPE_RE\s?|[^,.#:[\s>~+])+)/gco) {
86 193 100       808 my ($name, $op) = $1 eq '.' ? ('class', '~') : ('id', '');
87 193         504 push @$last, ['attr', _name($name), _value($op, $2)];
88             }
89              
90             # Attributes
91 285   100     765 elsif ($css =~ /\G$ATTR_RE/gco) { push @$last, ['attr', _name($1), _value($2 // '', $3 // $4 // $5, $6)] }
      100        
      100        
92              
93             # Pseudo-class
94             elsif ($css =~ /\G:([\w\-]+)(?:\(((?:\([^)]+\)|[^)])+)\))?/gcs) {
95 302         1454 my ($name, $args) = (lc $1, $2);
96              
97             # ":text" (raw text)
98 302 100       1074 $args = [$args =~ m!^/(.+)/$! ? qr/$1/ : qr/\Q$args\E/i] if $name eq 'text';
    100          
99              
100             # ":is" and ":not" (contains more selectors)
101 302 100 100     1734 $args = _compile($args, %ns) if $name eq 'has' || $name eq 'is' || $name eq 'not';
      100        
102              
103             # ":nth-*" (with An+B notation)
104 302 100       905 $args = _equation($args) if $name =~ /^nth-/;
105              
106             # ":first-*", ":last-*" (rewrite to ":nth-(last-)*")
107 302 100       929 ($name, $args) = ("nth-$+", [0, 1]) if $name =~ /^(?:first-(.+)|(last-.+))$/;
108              
109 302         1285 push @$last, ['pc', $name, $args];
110             }
111              
112             # Tag
113             elsif ($css =~ /\G((?:$ESCAPE_RE\s|\\[\s\S]|[^,.#:[\s>~+])+)/gco) {
114 1721 100 100     7403 my $alias = (my $name = $1) =~ s/^([^|]*)\|// && $1 ne '*' ? $1 : undef;
115 1721 100 100     3978 my $ns = length $alias ? $ns{$alias} // return [['invalid']] : $alias;
116 1720 100       5008 push @$last, ['tag', $name eq '*' ? undef : _name($name), _unescape($ns)];
117             }
118              
119 1330 100       4231 else { pos $css < length $css ? croak "Unknown CSS selector: $css" : last }
120             }
121              
122 1328         1938 warn qq{-- CSS Selector ($css)\n@{[dumper $group]}} if DEBUG;
123 1328         4982 return $group;
124             }
125              
126             sub _equation {
127 117 100   117   336 return [0, 0] unless my $equation = shift;
128              
129             # "even"
130 115 100       354 return [2, 0] if $equation =~ /^\s*even\s*$/i;
131              
132             # "odd"
133 106 100       343 return [2, 1] if $equation =~ /^\s*odd\s*$/i;
134              
135             # "4", "+4" or "-4"
136 94 100       627 return [0, $1] if $equation =~ /^\s*((?:\+|-)?\d+)\s*$/;
137              
138             # "n", "4n", "+4n", "-4n", "n+1", "4n-1", "+4n-1" (and other variations)
139 52 100       304 return [0, 0] unless $equation =~ /^\s*((?:\+|-)?(?:\d+)?)?n\s*((?:\+|-)\s*\d+)?\s*$/i;
140 51 100 50     432 return [$1 eq '-' ? -1 : !length $1 ? 1 : $1, join('', split(' ', $2 // 0))];
    100          
141             }
142              
143             sub _evaluate {
144 1253     1253   2468 my ($group, $tree, $scope, $pool) = @_;
145              
146 1253         1738 my (@results, %seen);
147 1253         3792 push @results, grep { !$seen{$_}++ } _evaluate_one($_, $tree, $scope, $pool) for @$group;
  1919         7182  
148              
149 1253         3682 return \@results;
150             }
151              
152             sub _evaluate_one {
153 1264     1264   2366 my ($selector, $tree, $scope, $pool) = @_;
154              
155             # Match the leftmost compound, then propagate forward through combinators
156 1264         2723 my @parts = @$selector;
157 1264         1840 my $compound = shift @parts;
158 1264 100       2497 return () unless ref $compound;
159 1263         2154 my @candidates = grep { _selector($compound, $_, $tree, $scope) } @$pool;
  11425         18793  
160              
161 1263         2704 while (@parts) {
162 780         1221 my $combinator = shift @parts;
163 780         1259 my $next = shift @parts;
164 780 50       1437 return () unless ref $next;
165              
166 780         1143 my (%seen, @new);
167 780         1102 for my $node (@candidates) {
168 1761         3697 for my $cand (_step_forward($combinator, $node)) {
169 41036 100       98825 next if $seen{$cand}++;
170 3387 100       5233 push @new, $cand if _selector($next, $cand, $tree, $scope);
171             }
172             }
173 780         3302 @candidates = @new;
174             }
175              
176 1263         3034 return @candidates;
177             }
178              
179             sub _is_scoped {
180 1381     1381   2503 my $selector = shift;
181              
182 1381 100       2698 for my $pc (grep { $_->[0] eq 'pc' } map { ref $_ ? @$_ : () } @$selector) {
  2601         6374  
  3045         6022  
183              
184             # Selector with ":scope"
185 370 100       1106 return 1 if $pc->[1] eq 'scope';
186              
187             # Argument of functional pseudo-class with ":scope"
188 274 100 100     1574 return 1 if ($pc->[1] eq 'has' || $pc->[1] eq 'is' || $pc->[1] eq 'not') && grep { _is_scoped($_) } @{$pc->[2]};
  66   100     140  
  62         133  
189             }
190              
191 1275         3883 return undef;
192             }
193              
194             sub _match {
195 165     165   318 my ($group, $current, $tree, $scope) = @_;
196 165   100     385 _match_one($_, $current, $tree, $scope) and return 1 for @$group;
197 101         391 return undef;
198             }
199              
200             sub _match_one {
201 175     175   278 my ($selector, $current, $tree, $scope) = @_;
202              
203             # Match the rightmost compound, then propagate backward through combinators
204 175         313 my @parts = reverse @$selector;
205 175         230 my $compound = shift @parts;
206 175 100 66     466 return undef unless ref $compound && _selector($compound, $current, $tree, $scope);
207              
208 68         171 my @candidates = ($current);
209 68         139 while (@parts) {
210 8         13 my $combinator = shift @parts;
211 8         12 my $next = shift @parts;
212 8 50       15 return undef unless ref $next;
213              
214 8         10 my (%seen, @new);
215 8         9 for my $node (@candidates) {
216 8         15 for my $cand (_step_back($combinator, $node, $scope)) {
217 8 50       20 next if $seen{$cand}++;
218 8 100       17 push @new, $cand if _selector($next, $cand, $tree, $scope);
219             }
220             }
221 8 100       20 return undef unless @new;
222 4         12 @candidates = @new;
223             }
224              
225 64         470 return 1;
226             }
227              
228 2153     2153   3320 sub _name {qr/(?:^|:)\Q@{[_unescape(shift)]}\E$/}
  2153         4298  
229              
230             sub _namespace {
231 81     81   133 my ($ns, $current) = @_;
232              
233 81 100       190 my $attr = $current->[1] =~ /^([^:]+):/ ? "xmlns:$1" : 'xmlns';
234 81         126 while ($current) {
235 127 100       196 last if $current->[0] eq 'root';
236 123 100       467 return $current->[2]{$attr} eq $ns if exists $current->[2]{$attr};
237              
238 46         77 $current = $current->[3];
239             }
240              
241             # Failing to match yields true if searching for no namespace, false otherwise
242 4         26 return !length $ns;
243             }
244              
245             sub _pc {
246 1976     1976   3313 my ($class, $args, $current, $tree, $scope) = @_;
247              
248             # ":scope" (root can only be a :scope)
249 1976 100       3935 return $current eq $scope if $class eq 'scope';
250 1422 100       2549 return undef if $current->[0] eq 'root';
251              
252             # ":checked"
253 1376 100 100     2917 return exists $current->[2]{checked} || exists $current->[2]{selected} if $class eq 'checked';
254              
255             # ":not"
256 1171 100       1788 return !_match($args, $current, $current, $scope) if $class eq 'not';
257              
258             # ":is"
259 1069 100       1409 return !!_match($args, $current, $current, $scope) if $class eq 'is';
260              
261             # ":has"
262 1049 100       1552 return !!_select(1, $current, $args) if $class eq 'has';
263              
264             # ":empty"
265 1027 100 100     1428 return !grep { !($_->[0] eq 'comment' || $_->[0] eq 'pi') } @$current[4 .. $#$current] if $class eq 'empty';
  83         224  
266              
267             # ":root"
268 987 100 66     1547 return $current->[3] && $current->[3][0] eq 'root' if $class eq 'root';
269              
270             # ":text"
271 933 100 66     1382 return grep { ($_->[0] eq 'text' || $_->[0] eq 'raw') && $_->[1] =~ $args->[0] } @$current[4 .. $#$current]
  257 100       1276  
272             if $class eq 'text';
273              
274             # ":any-link", ":link" and ":visited"
275 836 100 100     2722 if ($class eq 'any-link' || $class eq 'link' || $class eq 'visited') {
      100        
276 39 100 66     197 return undef unless $current->[0] eq 'tag' && exists $current->[2]{href};
277 21         62 return !!grep { $current->[1] eq $_ } qw(a area link);
  63         181  
278             }
279              
280             # ":only-child" or ":only-of-type"
281 797 100 100     1848 if ($class eq 'only-child' || $class eq 'only-of-type') {
282 26 100       71 my $type = $class eq 'only-of-type' ? $current->[1] : undef;
283 26   100     34 $_ ne $current and return undef for @{_siblings($current, $type)};
  26         44  
284 6         33 return 1;
285             }
286              
287             # ":nth-child", ":nth-last-child", ":nth-of-type" or ":nth-last-of-type"
288 771 100       1125 if (ref $args) {
289 763 100 100     1683 my $type = $class eq 'nth-of-type' || $class eq 'nth-last-of-type' ? $current->[1] : undef;
290 763         822 my @siblings = @{_siblings($current, $type)};
  763         1016  
291 763         1092 my $index;
292 763         1351 for my $i (0 .. $#siblings) {
293 3204 100       5826 $index = $i, last if $siblings[$i] eq $current;
294             }
295 763 100 100     1908 $index = $#siblings - $index if $class eq 'nth-last-child' || $class eq 'nth-last-of-type';
296 763         866 $index++;
297              
298 763         993 my $delta = $index - $args->[1];
299 763 100       1391 return 1 if $delta == 0;
300 646   100     3330 return $args->[0] != 0 && ($delta < 0) == ($args->[0] < 0) && $delta % $args->[0] == 0;
301             }
302              
303             # Everything else
304 8         20 return undef;
305             }
306              
307             sub _root {
308 91     91   159 my $tree = shift;
309 91         346 $tree = $tree->[3] while $tree->[0] ne 'root';
310 91         192 return $tree;
311             }
312              
313             sub _select {
314 1253     1253   2777 my ($one, $scope, $group) = @_;
315              
316             # Scoped selectors require the whole tree to be searched
317 1253         1689 my $tree = $scope;
318 1253 100       2374 ($group, $tree) = (_absolutize($group), _root($scope)) if grep { _is_scoped($_) } @$group;
  1264         2886  
319              
320             # Pool includes $tree so ":scope" can match it, but results exclude it
321 1253         2546 my $tags = _all_tags($tree);
322 1253         1808 my %match = map { $_ => 1 } @{_evaluate($group, $tree, $scope, [$tree, @$tags])};
  1918         4816  
  1253         4099  
323              
324 1253         2966 my @results;
325 1253         2112 for my $node (@$tags) {
326 7409 100       14643 next unless $match{$node};
327 1773 100       6275 return $node if $one;
328 1054         1811 push @results, $node;
329             }
330              
331 534 100       4251 return $one ? undef : \@results;
332             }
333              
334             sub _selector {
335 14995     14995   23539 my ($selector, $current, $tree, $scope) = @_;
336              
337             # The root might be the scope
338 14995         22454 my $is_tag = $current->[0] eq 'tag';
339 14995         20231 for my $s (@$selector) {
340 16187         20521 my $type = $s->[0];
341              
342             # Tag
343 16187 100 100     46997 if ($is_tag && $type eq 'tag') {
    100 100        
    100          
344 10731 100 100     55960 return undef if defined $s->[1] && $current->[1] !~ $s->[1];
345 3915 100 100     9685 return undef if defined $s->[2] && !_namespace($s->[2], $current);
346             }
347              
348             # Attribute
349 2345 100       4557 elsif ($is_tag && $type eq 'attr') { return undef unless _attr(@$s[1, 2], $current) }
350              
351             # Pseudo-class
352 1976 100       3261 elsif ($type eq 'pc') { return undef unless _pc(@$s[1, 2], $current, $tree, $scope) }
353              
354             # No match
355 1135         3008 else { return undef }
356             }
357              
358 3752         9186 return 1;
359             }
360              
361             sub _siblings {
362 893     893   1307 my ($current, $type) = @_;
363 893         1120 my $parent = $current->[3];
364 893 100       2489 my @siblings = grep { $_->[0] eq 'tag' } @$parent[($parent->[0] eq 'root' ? 1 : 4) .. $#$parent];
  13486         18422  
365 893 100       1641 @siblings = grep { $type eq $_->[1] } @siblings if defined $type;
  542         828  
366 893         1768 return \@siblings;
367             }
368              
369             sub _step_back {
370 8     8   14 my ($combinator, $node, $scope) = @_;
371              
372             # " " (ancestors) and ">" (parent only)
373 8 50 33     24 if ($combinator eq ' ' || $combinator eq '>') {
374 8         9 my @ancestors;
375 8   33     66 while ($node ne $scope && $node->[0] ne 'root' && ($node = $node->[3])) {
      33        
376 8         43 push @ancestors, $node;
377 8 50 33     24 last if $combinator eq '>' || $node eq $scope;
378             }
379 8         17 return @ancestors;
380             }
381              
382             # "~" (preceding siblings) and "+" (immediately preceding)
383 0 0       0 return () if $node->[0] eq 'root';
384 0         0 my @prev;
385 0         0 for my $sib (@{_siblings($node)}) {
  0         0  
386 0 0       0 last if $sib eq $node;
387 0         0 push @prev, $sib;
388             }
389 0 0 0     0 return $combinator eq '+' ? ($prev[-1] || ()) : @prev;
390             }
391              
392             sub _step_forward {
393 1761     1761   3613 my ($combinator, $node) = @_;
394              
395             # " " (descendants)
396 1761 100       4231 return @{_all_tags($node)} if $combinator eq ' ';
  1083         2503  
397              
398             # ">" (children only)
399 678 100       2336 return grep { $_->[0] eq 'tag' } @$node[($node->[0] eq 'root' ? 1 : 4) .. $#$node] if $combinator eq '>';
  2263 100       4244  
400              
401             # "~" (following siblings) and "+" (immediately following)
402 104 50       230 return () if $node->[0] eq 'root';
403 104         172 my (@next, $found);
404 104         150 for my $sib (@{_siblings($node)}) {
  104         185  
405 420 100       742 push @next, $sib if $found;
406 420 100       927 $found = 1 if $sib eq $node;
407             }
408 104 100 66     426 return $combinator eq '+' ? ($next[0] || ()) : @next;
409             }
410              
411             sub _unescape {
412 4303 100   4303   15571 return undef unless defined(my $value = shift);
413              
414             # Remove escaped newlines
415 2651         4577 $value =~ s/\\\n//g;
416              
417             # Unescape Unicode characters
418 2651         4412 $value =~ s/\\([0-9a-fA-F]{1,6})\s?/pack 'U', hex $1/ge;
  35         197  
419              
420             # Remove backslash
421 2651         5160 $value =~ s/\\//g;
422              
423 2651         52716 return $value;
424             }
425              
426             sub _value {
427 478     478   1985 my ($op, $value, $insensitive) = @_;
428 478 100       1346 return undef unless defined $value;
429 430 100       1033 $value = ($insensitive ? '(?i)' : '') . quotemeta _unescape($value);
430              
431             # "~=" (word)
432 430 100       3084 return qr/(?:^|\s+)$value(?:\s+|$)/ if $op eq '~';
433              
434             # "|=" (hyphen-separated)
435 331 100       828 return qr/^$value(?:-|$)/ if $op eq '|';
436              
437             # "*=" (contains)
438 321 100       711 return qr/$value/ if $op eq '*';
439              
440             # "^=" (begins with)
441 309 100       832 return qr/^$value/ if $op eq '^';
442              
443             # "$=" (ends with)
444 277 100       858 return qr/$value$/ if $op eq '$';
445              
446             # Everything else
447 246         3277 return qr/^$value$/;
448             }
449              
450             1;
451              
452             =encoding utf8
453              
454             =head1 NAME
455              
456             Mojo::DOM::CSS - CSS selector engine
457              
458             =head1 SYNOPSIS
459              
460             use Mojo::DOM::CSS;
461              
462             # Select elements from DOM tree
463             my $css = Mojo::DOM::CSS->new(tree => $tree);
464             my $elements = $css->select('h1, h2, h3');
465              
466             =head1 DESCRIPTION
467              
468             L is the CSS selector engine used by L, based on the L
469             Standard|https://html.spec.whatwg.org> and L.
470              
471             =head1 SELECTORS
472              
473             All CSS selectors that make sense for a standalone parser are supported.
474              
475             =head2 *
476              
477             Any element.
478              
479             my $all = $css->select('*');
480              
481             =head2 E
482              
483             An element of type C.
484              
485             my $title = $css->select('title');
486              
487             =head2 E[foo]
488              
489             An C element with a C attribute.
490              
491             my $links = $css->select('a[href]');
492              
493             =head2 E[foo="bar"]
494              
495             An C element whose C attribute value is exactly equal to C.
496              
497             my $case_sensitive = $css->select('input[type="hidden"]');
498             my $case_sensitive = $css->select('input[type=hidden]');
499              
500             =head2 E[foo="bar" i]
501              
502             An C element whose C attribute value is exactly equal to any (ASCII-range) case-permutation of C. Note
503             that this selector is B and might change without warning!
504              
505             my $case_insensitive = $css->select('input[type="hidden" i]');
506             my $case_insensitive = $css->select('input[type=hidden i]');
507             my $case_insensitive = $css->select('input[class~="foo" i]');
508              
509             This selector is part of L, which is still a work in progress.
510              
511             =head2 E[foo="bar" s]
512              
513             An C element whose C attribute value is exactly and case-sensitively equal to C. Note that this selector
514             is B and might change without warning!
515              
516             my $case_sensitive = $css->select('input[type="hidden" s]');
517              
518             This selector is part of L, which is still a work in progress.
519              
520             =head2 E[foo~="bar"]
521              
522             An C element whose C attribute value is a list of whitespace-separated values, one of which is exactly equal to
523             C.
524              
525             my $foo = $css->select('input[class~="foo"]');
526             my $foo = $css->select('input[class~=foo]');
527              
528             =head2 E[foo^="bar"]
529              
530             An C element whose C attribute value begins exactly with the string C.
531              
532             my $begins_with = $css->select('input[name^="f"]');
533             my $begins_with = $css->select('input[name^=f]');
534              
535             =head2 E[foo$="bar"]
536              
537             An C element whose C attribute value ends exactly with the string C.
538              
539             my $ends_with = $css->select('input[name$="o"]');
540             my $ends_with = $css->select('input[name$=o]');
541              
542             =head2 E[foo*="bar"]
543              
544             An C element whose C attribute value contains the substring C.
545              
546             my $contains = $css->select('input[name*="fo"]');
547             my $contains = $css->select('input[name*=fo]');
548              
549             =head2 E[foo|="en"]
550              
551             An C element whose C attribute has a hyphen-separated list of values beginning (from the left) with C.
552              
553             my $english = $css->select('link[hreflang|=en]');
554              
555             =head2 E:root
556              
557             An C element, root of the document.
558              
559             my $root = $css->select(':root');
560              
561             =head2 E:nth-child(n)
562              
563             An C element, the C child of its parent.
564              
565             my $third = $css->select('div:nth-child(3)');
566             my $odd = $css->select('div:nth-child(odd)');
567             my $even = $css->select('div:nth-child(even)');
568             my $top3 = $css->select('div:nth-child(-n+3)');
569              
570             =head2 E:nth-last-child(n)
571              
572             An C element, the C child of its parent, counting from the last one.
573              
574             my $third = $css->select('div:nth-last-child(3)');
575             my $odd = $css->select('div:nth-last-child(odd)');
576             my $even = $css->select('div:nth-last-child(even)');
577             my $bottom3 = $css->select('div:nth-last-child(-n+3)');
578              
579             =head2 E:nth-of-type(n)
580              
581             An C element, the C sibling of its type.
582              
583             my $third = $css->select('div:nth-of-type(3)');
584             my $odd = $css->select('div:nth-of-type(odd)');
585             my $even = $css->select('div:nth-of-type(even)');
586             my $top3 = $css->select('div:nth-of-type(-n+3)');
587              
588             =head2 E:nth-last-of-type(n)
589              
590             An C element, the C sibling of its type, counting from the last one.
591              
592             my $third = $css->select('div:nth-last-of-type(3)');
593             my $odd = $css->select('div:nth-last-of-type(odd)');
594             my $even = $css->select('div:nth-last-of-type(even)');
595             my $bottom3 = $css->select('div:nth-last-of-type(-n+3)');
596              
597             =head2 E:first-child
598              
599             An C element, first child of its parent.
600              
601             my $first = $css->select('div p:first-child');
602              
603             =head2 E:last-child
604              
605             An C element, last child of its parent.
606              
607             my $last = $css->select('div p:last-child');
608              
609             =head2 E:first-of-type
610              
611             An C element, first sibling of its type.
612              
613             my $first = $css->select('div p:first-of-type');
614              
615             =head2 E:last-of-type
616              
617             An C element, last sibling of its type.
618              
619             my $last = $css->select('div p:last-of-type');
620              
621             =head2 E:only-child
622              
623             An C element, only child of its parent.
624              
625             my $lonely = $css->select('div p:only-child');
626              
627             =head2 E:only-of-type
628              
629             An C element, only sibling of its type.
630              
631             my $lonely = $css->select('div p:only-of-type');
632              
633             =head2 E:empty
634              
635             An C element that has no children (including text nodes).
636              
637             my $empty = $css->select(':empty');
638              
639             =head2 E:any-link
640              
641             Alias for L. Note that this selector is B and might change without warning! This selector is
642             part of L, which is still a work in progress.
643              
644             =head2 E:link
645              
646             An C element being the source anchor of a hyperlink of which the target is not yet visited (C<:link>) or already
647             visited (C<:visited>). Note that L is not stateful, therefore C<:any-link>, C<:link> and C<:visited>
648             yield exactly the same results.
649              
650             my $links = $css->select(':any-link');
651             my $links = $css->select(':link');
652             my $links = $css->select(':visited');
653              
654             =head2 E:visited
655              
656             Alias for L.
657              
658             =head2 E:scope
659              
660             An C element being a designated reference element. Note that this selector is B and might change
661             without warning!
662              
663             my $scoped = $css->select('a:not(:scope > a)');
664             my $scoped = $css->select('div :scope p');
665             my $scoped = $css->select('~ p');
666              
667             This selector is part of L, which is still a work in progress.
668              
669             =head2 E:checked
670              
671             A user interface element C which is checked (for instance a radio-button or checkbox).
672              
673             my $input = $css->select(':checked');
674              
675             =head2 E.warning
676              
677             An C element whose class is "warning".
678              
679             my $warning = $css->select('div.warning');
680              
681             =head2 E#myid
682              
683             An C element with C equal to "myid".
684              
685             my $foo = $css->select('div#foo');
686              
687             =head2 E:not(s1, s2)
688              
689             An C element that does not match either compound selector C or compound selector C. Note that support for
690             compound selectors is B and might change without warning!
691              
692             my $others = $css->select('div p:not(:first-child, :last-child)');
693              
694             Support for compound selectors was added as part of L, which is
695             still a work in progress.
696              
697             =head2 E:is(s1, s2)
698              
699             An C element that matches compound selector C and/or compound selector C. Note that this selector is
700             B and might change without warning!
701              
702             my $headers = $css->select(':is(section, article, aside, nav) h1');
703              
704             This selector is part of L, which is still a work in progress.
705              
706             =head2 E:has(rs1, rs2)
707              
708             An C element, if either of the relative selectors C or C, when evaluated with C as the :scope elements,
709             match an element. Note that this selector is B and might change without warning!
710              
711             my $link = $css->select('a:has(> img)');
712              
713             This selector is part of L, which is still a work in progress.
714             Also be aware that this feature is currently marked C, so there is a high chance that it will get removed
715             completely.
716              
717             =head2 E:text(string_or_regex)
718              
719             An C element containing text content that substring matches C case-insensitively or that regex
720             matches C. For regular expressions use the format C<:text(/.../)>. Note that this selector is
721             B and might change without warning!
722              
723             # Substring match
724             my $login = $css->select(':text(Log in)');
725              
726             # Regex match
727             my $login = $css->select(':text(/Log ?in/)');
728              
729             # Regex match (case-insensitive)
730             my $login = $css->select(':text(/(?i:Log ?in)/)');
731              
732             This is a custom selector for L and not part of any spec.
733              
734             =head2 A|E
735              
736             An C element that belongs to the namespace alias C from L
737             3|https://www.w3.org/TR/css-namespaces-3/>. Key/value pairs passed to selector methods are used to declare namespace
738             aliases.
739              
740             my $elem = $css->select('lq|elem', lq => 'http://example.com/q-markup');
741              
742             Using an empty alias searches for an element that belongs to no namespace.
743              
744             my $div = $c->select('|div');
745              
746             =head2 E F
747              
748             An C element descendant of an C element.
749              
750             my $headlines = $css->select('div h1');
751              
752             =head2 E E F
753              
754             An C element child of an C element.
755              
756             my $headlines = $css->select('html > body > div > h1');
757              
758             =head2 E + F
759              
760             An C element immediately preceded by an C element.
761              
762             my $second = $css->select('h1 + h2');
763              
764             =head2 E ~ F
765              
766             An C element preceded by an C element.
767              
768             my $second = $css->select('h1 ~ h2');
769              
770             =head2 E, F, G
771              
772             Elements of type C, C and C.
773              
774             my $headlines = $css->select('h1, h2, h3');
775              
776             =head2 E[foo=bar][bar=baz]
777              
778             An C element whose attributes match all following attribute selectors.
779              
780             my $links = $css->select('a[foo^=b][foo$=ar]');
781              
782             =head1 ATTRIBUTES
783              
784             L implements the following attributes.
785              
786             =head2 tree
787              
788             my $tree = $css->tree;
789             $css = $css->tree(['root']);
790              
791             Document Object Model. Note that this structure should only be used very carefully since it is very dynamic.
792              
793             =head1 METHODS
794              
795             L inherits all methods from L and implements the following new ones.
796              
797             =head2 matches
798              
799             my $bool = $css->matches('head > title');
800             my $bool = $css->matches('svg|line', svg => 'http://www.w3.org/2000/svg');
801              
802             Check if first node in L matches the CSS selector. Trailing key/value pairs can be used to declare xml
803             namespace aliases.
804              
805             =head2 select
806              
807             my $results = $css->select('head > title');
808             my $results = $css->select('svg|line', svg => 'http://www.w3.org/2000/svg');
809              
810             Run CSS selector against L. Trailing key/value pairs can be used to declare xml namespace aliases.
811              
812             =head2 select_one
813              
814             my $result = $css->select_one('head > title');
815             my $result =
816             $css->select_one('svg|line', svg => 'http://www.w3.org/2000/svg');
817              
818             Run CSS selector against L and stop as soon as the first node matched. Trailing key/value pairs can be used to
819             declare xml namespace aliases.
820              
821             =head1 DEBUGGING
822              
823             You can set the C environment variable to get some advanced diagnostics information printed to
824             C.
825              
826             MOJO_DOM_CSS_DEBUG=1
827              
828             =head1 SEE ALSO
829              
830             L, L, L.
831              
832             =cut