From: Matt S Trout Date: Sat, 20 Feb 2010 22:34:05 +0000 (+0000) Subject: refactor slightly and clean up selector code a bit X-Git-Tag: release_0.009004~71 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FHTML-Zoom.git;a=commitdiff_plain;h=6d0f20a655ed2cb8581f7ab27433febba6c44cbd refactor slightly and clean up selector code a bit --- diff --git a/lib/HTML/Zoom/FilterBuilder.pm b/lib/HTML/Zoom/FilterBuilder.pm index bdfb920..316d56c 100644 --- a/lib/HTML/Zoom/FilterBuilder.pm +++ b/lib/HTML/Zoom/FilterBuilder.pm @@ -21,6 +21,10 @@ sub _stream_concat { shift->_zconfig->stream_utils->stream_concat(@_) } +sub _flatten_stream_of_streams { + shift->_zconfig->stream_utils->flatten_stream_of_streams(@_) +} + sub set_attribute { my ($self, $args) = @_; my ($name, $value) = @{$args}{qw(name value)}; @@ -211,23 +215,23 @@ sub repeat { # hasn't been populated yet - but we can test @between in the # map routine because it has been by then and that saves us doing # the extra stream construction if we don't need it. - if ($repeat_between) { - $s->map(sub { - local $_ = $self->_stream_from_array(@into); - (@between && $s->peek) - ? $self->_stream_concat( - $_[0]->($_), $self->_stream_from_array(@between) - ) - : $_[0]->($_) - }) - ->flatten; - } else { - $s->map(sub { - local $_ = $self->_stream_from_array(@into); - $_[0]->($_) + $self->_flatten_stream_of_streams(do { + if ($repeat_between) { + $s->map(sub { + local $_ = $self->_stream_from_array(@into); + (@between && $s->peek) + ? $self->_stream_concat( + $_[0]->($_), $self->_stream_from_array(@between) + ) + : $_[0]->($_) + }) + } else { + $s->map(sub { + local $_ = $self->_stream_from_array(@into); + $_[0]->($_) }) - ->flatten; - } + } + }) }; $self->replace($repeater, $options); } diff --git a/lib/HTML/Zoom/SelectorParser.pm b/lib/HTML/Zoom/SelectorParser.pm index 7d3c6a5..ed1d586 100644 --- a/lib/HTML/Zoom/SelectorParser.pm +++ b/lib/HTML/Zoom/SelectorParser.pm @@ -2,6 +2,7 @@ package HTML::Zoom::SelectorParser; use strict; use warnings FATAL => 'all'; +use base qw(HTML::Zoom::SubObject); use Carp qw(confess); my $sel_char = '-\w_'; @@ -41,7 +42,7 @@ sub _raw_parse_simple_selector { my @cl = split(/\./, $cls); sub { $_[0]->{attrs}{class} - && !grep $_[0]->{attrs}{class} !~ /\b$_\b/, @cl + && !grep $_[0]->{attrs}{class} !~ /(^|\s+)$_($|\s+)/, @cl } }; diff --git a/lib/HTML/Zoom/StreamUtils.pm b/lib/HTML/Zoom/StreamUtils.pm index cdfa430..16a029f 100644 --- a/lib/HTML/Zoom/StreamUtils.pm +++ b/lib/HTML/Zoom/StreamUtils.pm @@ -44,8 +44,9 @@ sub stream_from_proto { return $proto->(); } elsif ($ref eq 'SCALAR') { return $self->_zconfig->parser->html_to_stream($$proto); - } elsif (blessed($proto) && $proto->can('as_stream')) { - return $proto->as_stream; + } elsif (Scalar::Util::blessed($proto) && $proto->can('as_stream')) { + my $stream = $proto->as_stream; + return $self->stream_from_code(sub { $stream->next }); } die "Don't know how to turn $proto (ref $ref) into a stream"; } @@ -67,4 +68,21 @@ sub stream_to_array { return @array; } +sub flatten_stream_of_streams { + my ($self, $source_stream) = @_; + my $cur_stream; + HTML::Zoom::CodeStream->new({ + code => sub { + return unless $source_stream; + my $next; + until (($next) = ($cur_stream ? $cur_stream->next : ())) { + unless (($cur_stream) = $source_stream->next) { + undef $source_stream; return; + } + } + return $next; + } + }); +} + 1;