return $z;
};
+{
+ ok my $z = HTML::Zoom
+ ->from_html(q[<ul><li>Test</li></ul>])
+ ->select('ul')
+ ->repeat_content(
+ [
+ sub { $_->select('li')->replace_content('Real Life1') },
+ sub { $_->select('li')->replace_content('Real Life2') },
+ sub { $_->select('li')->replace_content('Real Life3') },
+ ],
+ )
+ ->to_html;
+
+ is $z, '<ul><li>Real Life1</li><li>Real Life2</li><li>Real Life3</li></ul>',
+ 'Got correct from repeat_content';
+}
+
+{
+ ok my $z = HTML::Zoom
+ ->from_html(q[<ul><li>Test</li></ul>])
+ ->select('ul')
+ ->repeat_content([
+ map { my $i = $_; +sub {$_->select('li')->replace_content("Real Life$i")} } (1,2,3)
+ ])
+ ->to_html;
+
+ is $z, '<ul><li>Real Life1</li><li>Real Life2</li><li>Real Life3</li></ul>',
+ 'Got correct from repeat_content';
+}
+
+
+use HTML::Zoom::CodeStream;
+sub code_stream (&) {
+ my $code = shift;
+ return sub {
+ HTML::Zoom::CodeStream->new({
+ code => $code,
+ });
+ }
+}
+
+{
+ my @list = qw(foo bar baz);
+ ok my $z = HTML::Zoom
+ ->from_html(q[<ul><li>Test</li></ul>])
+ ->select('ul')
+ ->repeat_content(code_stream {
+ if (my $name = shift @list) {
+ return sub { $_->select('li')->replace_content($name) };
+ } else {
+ return
+ }
+ })
+ ->to_html;
+
+ is $z, '<ul><li>foo</li><li>bar</li><li>baz</li></ul>',
+ 'Got correct from repeat_content';
+}
+
+{
+ my @list = qw(foo bar baz);
+ ok my $z = HTML::Zoom
+ ->from_html(q[<ul><li>Test</li></ul>])
+ ->select('ul')
+ ->repeat_content(sub {
+ HTML::Zoom::CodeStream->new({
+ code => sub {
+ if (my $name = shift @list) {
+ return sub { $_->select('li')->replace_content($name) };
+ } else {
+ return
+ }
+ }
+ });
+ })
+ ->to_html;
+
+ is $z, '<ul><li>foo</li><li>bar</li><li>baz</li></ul>',
+ 'Got correct from repeat_content';
+}
+
+{
+ use Scalar::Util ();
+ my $next_item_from_array = sub {
+ my @items = @_;
+ return sub { shift @items };
+ };
+
+ my $next_item_from_proto = sub {
+ my $proto = shift;
+ if (
+ ref $proto eq 'ARRAY' ||
+ ref $proto eq 'HASH' ||
+ Scalar::Util::blessed($proto)
+ ) {
+ return $next_item_from_array->($proto, @_);
+ } elsif(ref $proto eq 'CODE' ) {
+ return $proto;
+ } else {
+ die "Don't know what to do with $proto, it's a ". ref($proto);
+ }
+ };
+
+ my $normalize_targets = sub {
+ my $targets = shift;
+ my $targets_type = ref $targets;
+ return $targets_type eq 'ARRAY' ? $targets
+ : $targets_type eq 'HASH' ? [ map { +{$_=>$targets->{$_}} } keys %$targets ]
+ : die "targets data structure ". ref($targets). " not understood";
+ };
+
+ my $replace_from_hash_or_object = sub {
+ my ($datum, $value) = @_;
+ return ref($datum) eq 'HASH' ?
+ $datum->{$value} : $datum->$value;
+ };
+
+ my $fill = sub {
+ my ($zoom, $targets, @rest) = @_;
+ $zoom->repeat_content(sub {
+ my $itr = $next_item_from_proto->(@rest);
+ $targets = $normalize_targets->($targets);
+ HTML::Zoom::CodeStream->new({
+ code => sub {
+ my $cnt = 0;
+ if(my $datum = $itr->($zoom, $cnt)) {
+ $cnt++;
+ return sub {
+ for my $idx(0..$#{$targets}) {
+ my $target = $targets->[$idx];
+ my ($match, $replace) = do {
+ my $type = ref $target;
+ $type ? ($type eq 'HASH' ? do {
+ my ($match, $value) = %$target;
+ ref $value eq 'CODE' ?
+ ($match, $value->($datum, $idx, $_))
+ : ($match, $replace_from_hash_or_object->($datum, $value));
+ } : die "What?")
+ : do {
+ ref($datum) eq 'ARRAY' ?
+ ($target, $datum->[$idx]) :
+ ( '.'.$target, $replace_from_hash_or_object->($datum, $target));
+ };
+ };
+ $_ = $_->select($match)
+ ->replace_content($replace);
+ } $_;
+ };
+ } else {
+ return;
+ }
+ },
+ });
+ });
+ };
+
+ {
+ ok my $z = HTML::Zoom
+ ->from_html(q[<ul><li class="even">Even</li><li class="odd">Odd</li></ul>])
+ ->select('ul')
+ ->$fill(
+ ['.even','.odd'],
+ [0,1],
+ [2,3],
+ ), 'Made Zoom object from array';
+
+ is(
+ $z->to_html,
+ '<ul><li class="even">0</li><li class="odd">1</li><li class="even">2</li><li class="odd">3</li></ul>',
+ 'Got correct from repeat_content'
+ );
+ }
+
+ {
+ my @items = ( [0,1], [2,3] );
+ ok my $z = HTML::Zoom
+ ->from_html(q[<ul><li class="even">Even</li><li class="odd">Odd</li></ul>])
+ ->select('ul')
+ ->$fill(
+ ['.even','.odd'],
+ sub { shift @items }
+ ), 'Made Zoom object from itr';
+
+ for my $cnt (1..2) {
+ is(
+ $z->to_html,
+ '<ul><li class="even">0</li><li class="odd">1</li><li class="even">2</li><li class="odd">3</li></ul>',
+ 'Got correct from repeat_content: '.$cnt
+ );
+ ok(
+ (@items = ( [0,1], [2,3] )),
+ 'Reset the items array'
+ );
+ }
+ }
+
+ {
+ ok my $z = HTML::Zoom
+ ->from_html(q[<ul><li class="even">Even</li><li class="odd">Odd</li></ul>])
+ ->select('ul')
+ ->$fill(
+ [
+ {'.even' => sub { my ($i,$cnt,$z) = @_; return $i->[0]; } },
+ {'.odd' => sub { my ($i,$cnt,$z) = @_; return $i->[1]; } },
+ ],
+ [0,1],
+ [2,3],
+ ), 'Made Zoom object from code style';
+
+ for my $cnt (1..2) {
+ is(
+ $z->to_html,
+ '<ul><li class="even">0</li><li class="odd">1</li><li class="even">2</li><li class="odd">3</li></ul>',
+ 'Got correct from repeat_content: '.$cnt
+ );
+ }
+ }
+
+ {
+ ok my $z = HTML::Zoom
+ ->from_html(q[<ul><li class="even">Even</li><li class="odd">Odd</li></ul>])
+ ->select('ul')
+ ->$fill(
+ [
+ {'.even' => sub { my ($i,$cnt,$z) = @_; return $i->{even}; } },
+ {'.odd' => sub { my ($i,$cnt,$z) = @_; return $i->{odd}; } },
+ ],
+ { even => 0, odd => 1},
+ { even => 2, odd => 3},
+ ), 'Made Zoom object from code style';
+
+ for my $cnt (1..2) {
+ is(
+ $z->to_html,
+ '<ul><li class="even">0</li><li class="odd">1</li><li class="even">2</li><li class="odd">3</li></ul>',
+ 'Got correct from repeat_content: '.$cnt
+ );
+ }
+ }
+
+ {
+ ok my $even_or_odd = sub {
+ my ($i,$cnt,$z) = @_;
+ return $cnt % 2 ? $i->{odd} : $i->{even};
+ };
+
+ ok my $z = HTML::Zoom
+ ->from_html(q[<ul><li class="even">Even</li><li class="odd">Odd</li></ul>])
+ ->select('ul')
+ ->$fill(
+ [
+ {'.even' => $even_or_odd },
+ {'.odd' => $even_or_odd },
+ ],
+ { even => 0, odd => 1},
+ { even => 2, odd => 3},
+ ), 'Made Zoom object from code style';
+
+ for my $cnt (1..2) {
+ is(
+ $z->to_html,
+ '<ul><li class="even">0</li><li class="odd">1</li><li class="even">2</li><li class="odd">3</li></ul>',
+ 'Got correct from repeat_content: '.$cnt
+ );
+ }
+ }
+
+ {
+ ok my $even_or_odd = sub {
+ my ($i,$cnt,$z) = @_;
+ return $cnt % 2 ? $i->{odd} : $i->{even};
+ };
+
+ ok my $z = HTML::Zoom
+ ->from_html(q[<ul><li class="even">Even</li><li class="odd">Odd</li></ul>])
+ ->select('ul')
+ ->$fill(
+ [
+ map { +{$_ => $even_or_odd} } qw(.even .odd),
+ ],
+ { even => 0, odd => 1},
+ { even => 2, odd => 3},
+ ), 'Made Zoom object from code style';
+
+ for my $cnt (1..2) {
+ is(
+ $z->to_html,
+ '<ul><li class="even">0</li><li class="odd">1</li><li class="even">2</li><li class="odd">3</li></ul>',
+ 'Got correct from repeat_content: '.$cnt
+ );
+ }
+ }
+
+ {
+ {
+ package Test::HTML::Zoom::EvenOdd;
+
+ sub new {
+ my $class = shift;
+ bless { _e=>$_[0], _o=>$_[1] }, $class;
+ }
+
+ sub even { shift->{_e} }
+ sub odd { shift->{_o} }
+ }
+
+ ok my $even_or_odd = sub {
+ my ($i,$cnt,$z) = @_;
+ return $cnt % 2 ? $i->odd : $i->even;
+ };
+
+ ok my $z = HTML::Zoom
+ ->from_html(q[<ul><li class="even">Even</li><li class="odd">Odd</li></ul>])
+ ->select('ul')
+ ->$fill(
+ [
+ map { +{$_ => $even_or_odd} } qw(.even .odd),
+ ],
+ Test::HTML::Zoom::EvenOdd->new(0,1),
+ Test::HTML::Zoom::EvenOdd->new(2,3),
+ ), 'Made Zoom object from code style';
+
+ for my $cnt (1..2) {
+ is(
+ $z->to_html,
+ '<ul><li class="even">0</li><li class="odd">1</li><li class="even">2</li><li class="odd">3</li></ul>',
+ 'Got correct from repeat_content: '.$cnt
+ );
+ }
+ }
+
+ {
+ ok my $z = HTML::Zoom
+ ->from_html(q[<ul><li class="even">Even</li><li class="odd">Odd</li></ul>])
+ ->select('ul')
+ ->$fill(
+ [
+ { '.even' => 'even'},
+ { '.odd' => 'odd'},
+ ],
+ { even => 0, odd => 1},
+ { even => 2, odd => 3},
+ ), 'Made Zoom object from declare accessors style';
+
+ for my $cnt (1..2) {
+ is(
+ $z->to_html,
+ '<ul><li class="even">0</li><li class="odd">1</li><li class="even">2</li><li class="odd">3</li></ul>',
+ 'Got correct from repeat_content: '.$cnt
+ );
+ }
+ }
+
+ {
+ ok my $z = HTML::Zoom
+ ->from_html(q[<ul><li class="even">Even</li><li class="odd">Odd</li></ul>])
+ ->select('ul')
+ ->$fill(
+ [
+ { '.even' => 'even'},
+ { '.odd' => 'odd'},
+ ],
+ Test::HTML::Zoom::EvenOdd->new(0,1),
+ Test::HTML::Zoom::EvenOdd->new(2,3),
+ ), 'Made Zoom object from declare accessors style';
+
+ for my $cnt (1..2) {
+ is(
+ $z->to_html,
+ '<ul><li class="even">0</li><li class="odd">1</li><li class="even">2</li><li class="odd">3</li></ul>',
+ 'Got correct from repeat_content: '.$cnt
+ );
+ }
+ }
+
+ {
+ ok my $z = HTML::Zoom
+ ->from_html(q[<ul><li class="even">Even</li><li class="odd">Odd</li></ul>])
+ ->select('ul')
+ ->$fill(
+ {
+ '.even' => 'even',
+ '.odd' => 'odd'
+ },
+ Test::HTML::Zoom::EvenOdd->new(0,1),
+ Test::HTML::Zoom::EvenOdd->new(2,3),
+ ), 'Made Zoom object from declare accessors style';
+
+ for my $cnt (1..2) {
+ is(
+ $z->to_html,
+ '<ul><li class="even">0</li><li class="odd">1</li><li class="even">2</li><li class="odd">3</li></ul>',
+ 'Got correct from repeat_content: '.$cnt
+ );
+ }
+ }
+
+ ## Helper for when you have a list of object or hashs and you just want to map
+ ## target classes to accessors
+
+ {
+ ok my $z = HTML::Zoom
+ ->from_html(q[<ul><li class="even">Even</li><li class="odd">Odd</li></ul>])
+ ->select('ul')
+ ->$fill(
+ { map { ".".$_ => $_ } qw(even odd) },
+ Test::HTML::Zoom::EvenOdd->new(0,1),
+ Test::HTML::Zoom::EvenOdd->new(2,3),
+ ), 'Made Zoom object from declare accessors style';
+
+ for my $cnt (1..2) {
+ is(
+ $z->to_html,
+ '<ul><li class="even">0</li><li class="odd">1</li><li class="even">2</li><li class="odd">3</li></ul>',
+ 'Got correct from repeat_content: '.$cnt
+ );
+ }
+ }
+
+ ## if the target is arrayref but the data is a list of objects or hashes, we
+ ## guess the target is a class form of the target items, but use the value of
+ ## the item as the hash or object accessor
+
+ {
+ ok my $z = HTML::Zoom
+ ->from_html(q[<ul><li class="even">Even</li><li class="odd">Odd</li></ul>])
+ ->select('ul')
+ ->$fill(
+ [qw(even odd)],
+ Test::HTML::Zoom::EvenOdd->new(0,1),
+ Test::HTML::Zoom::EvenOdd->new(2,3),
+ ), 'Made Zoom object from declare accessors style';
+
+ for my $cnt (1..2) {
+ is(
+ $z->to_html,
+ '<ul><li class="even">0</li><li class="odd">1</li><li class="even">2</li><li class="odd">3</li></ul>',
+ 'Got correct from repeat_content: '.$cnt
+ );
+ }
+ }
+}
+
done_testing;