--- /dev/null
+package HTML::Zoom::FlattenedStream;
+
+use strict;
+use warnings FATAL => 'all';
+use base qw(HTML::Zoom::StreamBase);
+
+sub new {
+ my ($class, $args) = @_;
+ bless({ _source => $args->{source}, _zconfig => $args->{zconfig} }, $class);
+}
+
+sub next {
+ return unless (my $self = shift)->{_source};
+ my ($next, $s);
+ until (($next) = ($s = $self->{_cur}) ? $s->next : ()) {
+ unless (($self->{_cur}) = $self->{_source}->next) {
+ delete $self->{_source}; return;
+ }
+ }
+ return $next;
+}
+
+1;
--- /dev/null
+package HTML::Zoom::MappedStream;
+
+use strict;
+use warnings FATAL => 'all';
+use base qw(HTML::Zoom::StreamBase);
+
+sub new {
+ my ($class, $args) = @_;
+ bless({
+ _source => $args->{source}, _mapper => $args->{mapper},
+ _zconfig => $args->{zconfig}
+ }, $class);
+}
+
+sub next {
+ return unless (my $self = shift)->{_source};
+ # If we were aiming for a "true" perl-like map then we should
+ # elegantly handle the case where the map function returns 0 events
+ # and the case where it returns >1 - if you're reading this comment
+ # because you wanted it to do that, now would be the time to fix it :)
+ if (my ($next) = $self->{_source}->next) {
+ local $_ = $next;
+ return $self->{_mapper}->($next);
+ }
+ delete $self->{_source};
+ return
+}
+
+1;
}
sub flatten {
- my $source_stream = shift;
- require HTML::Zoom::CodeStream;
- 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;
- }
+ my $self = shift;
+ require HTML::Zoom::FlattenedStream;
+ HTML::Zoom::FlattenedStream->new({
+ source => $self,
+ zconfig => $self->_zconfig
});
}
sub map {
- my ($source_stream, $map_func) = @_;
- require HTML::Zoom::CodeStream;
- HTML::Zoom::CodeStream->new({
- code => sub {
- return unless $source_stream;
- # If we were aiming for a "true" perl-like map then we should
- # elegantly handle the case where the map function returns 0 events
- # and the case where it returns >1 - if you're reading this comment
- # because you wanted it to do that, now would be the time to fix it :)
- if (my ($next) = $source_stream->next) {
- #### XXXX collapsing this into a return doesn't work. what the
- #### flying fornication ... -- mst
- my $mapped = do { local $_ = $next; $map_func->($next) };
- return $mapped;
- }
- undef $source_stream; return;
- }
+ my ($self, $mapper) = @_;
+ require HTML::Zoom::MappedStream;
+ HTML::Zoom::MappedStream->new({
+ source => $self, mapper => $mapper, zconfig => $self->_zconfig
});
}
my $zoom = HTML::Zoom->from_html('<p>Hello my name is <span id="name" /></p>');
my $html = $zoom->select('#name')->replace_content('Foo foo')->to_html;
-is($html, '<p>Hello my name is <span id="#name">Foo foo</span>');
+is($html, '<p>Hello my name is <span id="#name">Foo foo</span></p>');