1 package HTML::Zoom::SelectorParser;
4 use warnings FATAL => 'all';
5 use base qw(HTML::Zoom::SubObject);
9 my $sel_re = qr/([$sel_char]+)/;
11 sub new { bless({}, shift) }
13 sub _raw_parse_simple_selector {
14 for ($_[1]) { # same pos() as outside
16 # '*' - match anything
21 # 'element' - match on tag name
26 sub { $_[0]->{name} && $_[0]->{name} eq $name }
29 # '#id' - match on id attribute
34 sub { $_[0]->{attrs}{id} && $_[0]->{attrs}{id} eq $id }
37 # '.class1.class2' - match on intersection of classes
39 /\G((?:\.$sel_re)+)/gc and
41 my $cls = $1; $cls =~ s/^\.//;
42 my @cl = split(/\./, $cls);
45 && !grep $_[0]->{attrs}{class} !~ /(^|\s+)$_($|\s+)/, @cl
49 confess "Couldn't parse $_ as starting with simple selector";
55 my $sel = $_[1]; # my pos() only please
56 die "No selector provided" unless $sel;
61 push(@sub, $self->_raw_parse_simple_selector($_));
62 last PARSE if (pos == length);
63 /\G\s*,\s*/gc or confess "Selectors not comma separated";
64 } until (pos == length) };
65 return $sub[0] if (@sub == 1);
67 foreach my $inner (@sub) {
68 if (my $r = $inner->(@_)) { return $r }