move transform usage a layer out
Matt S Trout [Thu, 1 Jul 2010 03:22:57 +0000 (04:22 +0100)]
lib/HTML/Zoom.pm
lib/HTML/Zoom/Transform.pm

index fd7602e..befc092 100644 (file)
@@ -44,14 +44,7 @@ sub to_stream {
     unless $self->{initial_events};
   my $sutils = $self->zconfig->stream_utils;
   my $stream = $sutils->stream_from_array(@{$self->{initial_events}});
-  foreach my $filter_spec (@{$self->{filters}||[]}) {
-    $stream = HTML::Zoom::Transform->new({
-                selector => $filter_spec->[0],
-                filters => [ $filter_spec->[1] ],
-                zconfig => $self->zconfig,
-              })->apply_to_stream($stream);
-    #$stream = $sutils->wrap_with_filter($stream, @{$filter_spec});
-  }
+  $stream = $_->apply_to_stream($stream) for @{$self->{transforms}||[]};
   $stream
 }
 
@@ -84,18 +77,23 @@ sub memoize {
 sub with_filter {
   my $self = shift->_self_or_new;
   my ($selector, $filter) = @_;
-  my $match = $self->parse_selector($selector);
   $self->_with({
-    filters => [ @{$self->{filters}||[]}, [ $match, $filter ] ]
+    transforms => [
+      @{$self->{transforms}||[]},
+      HTML::Zoom::Transform->new({
+        zconfig => $self->zconfig,
+        selector => $selector,
+        filters => [ $filter ]
+      })
+    ]
   });
 }
 
 sub select {
   my $self = shift->_self_or_new;
   my ($selector) = @_;
-  my $match = $self->parse_selector($selector);
   return HTML::Zoom::MatchWithoutFilter->construct(
-    $self, $match, $self->zconfig->filter_builder,
+    $self, $selector, $self->zconfig->filter_builder,
   );
 }
 
@@ -112,15 +110,9 @@ sub select {
 
 sub then {
   my $self = shift;
-  die "Can't call ->then without a previous filter"
-    unless $self->{filters};
-  $self->select($self->{filters}->[-1][0]);
-}
-
-sub parse_selector {
-  my ($self, $selector) = @_;
-  return $selector if ref($selector); # already a match sub
-  $self->zconfig->selector_parser->parse_selector($selector);
+  die "Can't call ->then without a previous transform"
+    unless $self->{transforms};
+  $self->select($self->{transforms}->[-1]->selector);
 }
 
 1;
@@ -691,14 +683,4 @@ together; the intermediary object isn't designed or expected to stick around.
 Re-runs the previous select to allow you to chain actions together on the
 same selector.
 
-=head2 parse_selector
-
-  my $matcher = $zoom->parse_selector('div');
-
-Used by L</select> and L</with_filter> to invoke the current
-L<HTML::Zoom::SelectorParser> object to create a matcher object (currently
-a coderef but this is an implementation detail) for that selector.
-
-In normal usage, you probably don't need to call this yourself.
-
 =cut
index b604c2d..627e52a 100644 (file)
@@ -8,6 +8,7 @@ sub new {
   my ($class, $args) = @_;
   my $new = $class->SUPER::new($args);
   $new->{selector} = $args->{selector};
+  $new->{match} = $args->{match} if $args->{match};
   $new->{filters} = $args->{filters}||[];
   $new;
 }
@@ -20,15 +21,24 @@ sub with_filter {
   my ($self, $filter) = @_;
   (ref $self)->new({
     selector => $self->selector,
+    ($self->{match} ? (match => $self->{match}) : ()),
     filters => [ @{$self->filters}, $filter ]
   });
 }
 
+sub match {
+  my ($self) = @_;
+  $self->{match} ||=
+    $self->_zconfig
+         ->selector_parser
+         ->parse_selector($self->{selector});
+}
+
 sub apply_to_stream {
   my ($self, $stream) = @_;
   HTML::Zoom::FilterStream->new({
     stream => $stream,
-    match => $self->selector,
+    match => $self->match,
     filters => $self->filters,
     zconfig => $self->_zconfig,
   });