4 use HTML::Zoom::Parser::BuiltIn;
5 use HTML::Zoom::Producer::BuiltIn;
6 use HTML::Zoom::SelectorParser;
7 use HTML::Zoom::FilterBuilder;
8 use HTML::Zoom::FilterStream;
12 <div name="cow" class="main">
13 <span class="hilight name">Bob</span>
14 <span class="career">Builder</span>
20 sub src_stream { HTML::Zoom::Parser::BuiltIn->new->html_to_stream($tmpl); }
22 sub html_sink { HTML::Zoom::Producer::BuiltIn->new->html_from_stream($_[0]) }
24 my $fb = HTML::Zoom::FilterBuilder->new;
26 my $sp = HTML::Zoom::SelectorParser->new;
29 my ($stream, $sel, $cb) = @_;
30 return HTML::Zoom::FilterStream->new({
32 match => $sp->parse_selector($sel),
33 filter => do { local $_ = $fb; $cb->($fb) }
50 ($expect = $tmpl) =~ s/class="main"/class="foo"/;
53 run_for { $_->set_attribute( 'class' => 'foo' ) },
55 'set attribute on existing attribute'
58 ($expect = $tmpl) =~ s/name="cow" class="main"/name="bar" class="foo"/;
61 run_for { $_->set_attr({ 'class' => 'foo', 'name' => 'bar'}) },
63 'set attributes using hashref form (shorthand)'
66 ($expect = $tmpl) =~ s/class="main"/class="main" foo="bar"/;
69 run_for { $_->set_attribute( 'foo' => 'bar' ) },
71 'set attribute on non existing attribute'
74 ($expect = $tmpl) =~ s/class="main"/class="main foo"/;
77 run_for { $_->add_to_attribute( 'class' => 'foo' ) },
79 'add attribute on existing attribute'
82 ($expect = $tmpl) =~ s/class="main"/class="main foo"/;
85 run_for { $_->add_class('foo') },
87 'add attribute on existing attribute (shorthand)'
90 ($expect = $tmpl) =~ s/class="main"/class="main" id="foo"/;
93 run_for { $_->set_id('foo') },
98 ($expect = $tmpl) =~ s/class="main"/class="main" foo="bar"/;
101 run_for { $_->add_to_attribute( 'foo' => 'bar' ) },
103 'add attribute on non existing attribute'
106 ($expect = $tmpl) =~ s/ class="main"//;
109 run_for { $_->remove_attribute({ name => 'class' }) },
111 'remove attribute on existing attribute'
115 run_for { $_->remove_attribute({ name => 'foo' }) },
117 'remove attribute on non existing attribute'
120 ($expect = $tmpl) =~ s/class="main"/class=""/;
123 run_for { $_->remove_from_attribute({ class => 'main' }) },
125 'remove name from attribute'
128 ($expect = $tmpl) =~ s/ class="main"//;
132 $_->transform_attribute({
136 return if $a eq 'main';
142 'transform_attribute deletes the attr if code returns undef',
145 ($expect = $tmpl) =~ s/ class="main"/ class="moan"/;
149 $_->transform_attribute({
152 ( my $b = shift ) =~ s/main/moan/;
158 'transform_attribute transforms something',
161 ($expect = $tmpl) =~ s/ class="main"/ class="main" noggin="zonk"/;
165 $_->transform_attribute({
167 code => sub { 'zonk' },
171 'transform_attribute adds attribute if not there before',
176 $_->transform_attribute({
182 'transform_attribute on nonexistent att does not add it if code returns undef',
186 ($expect = $tmpl) =~ s/(?=<div)/O HAI/;
188 my $ohai = [ { type => 'TEXT', raw => 'O HAI' } ];
191 run_for { $_->add_before($ohai) },
196 ($expect = $tmpl) =~ s/(?<=<\/div>)/O HAI/;
199 run_for { $_->add_after($ohai) },
204 ($expect = $tmpl) =~ s/(?<=class="main">)/O HAI/;
207 run_for { $_->prepend_content($ohai) },
212 ($expect = $tmpl) =~ s/<hr \/>/<hr>O HAI<\/hr>/;
215 (run_for { $_->prepend_content($ohai) } 'hr'),
217 'prepend_content ok with in place close'
221 run_for { $_->replace($ohai) },
232 run_for { $_->collect({ into => \@ev }) },
237 'collect removes without passthrough'
241 HTML::Zoom::Producer::BuiltIn->html_from_events(\@ev),
242 '<div name="cow" class="main">
243 <span class="hilight name">Bob</span>
244 <span class="career">Builder</span>
247 'collect collected right events'
253 run_for { $_->collect({ into => \@ev, content => 1 }) },
255 <div name="cow" class="main"></div>
258 'collect w/content removes correctly'
262 HTML::Zoom::Producer::BuiltIn->html_from_events(\@ev),
264 <span class="hilight name">Bob</span>
265 <span class="career">Builder</span>
268 'collect w/content collects correctly'
272 run_for { $_->replace($ohai, { content => 1 }) },
274 <div name="cow" class="main">O HAI</div>
280 ($expect = $tmpl) =~ s/(?=<\/div>)/O HAI/;
283 run_for { $_->append_content($ohai) },
288 my $r_content = sub { my $r = shift; sub { $_->replace($r, { content => 1 }) } };
296 filter($_ => '.name' => $r_content->('mst'))
297 => '.career' => $r_content->('Chainsaw Wielder')
301 filter($_ => '.name' => $r_content->('mdk'))
302 => '.career' => $r_content->('Adminion')
308 <div name="cow" class="main">
309 <span class="hilight name">mst</span>
310 <span class="career">Chainsaw Wielder</span>
312 </div><div name="cow" class="main">
313 <span class="hilight name">mdk</span>
314 <span class="career">Adminion</span>
328 filter($_ => '.name' => $r_content->('mst'))
329 => '.career' => $r_content->('Chainsaw Wielder')
333 filter($_ => '.name' => $r_content->('mdk'))
334 => '.career' => $r_content->('Adminion')
340 <div name="cow" class="main">
341 <span class="hilight name">mst</span>
342 <span class="career">Chainsaw Wielder</span>
345 <span class="hilight name">mdk</span>
346 <span class="career">Adminion</span>
360 HTML::Zoom::ArrayStream->new({ array => [
362 filter($_ => '.name' => $r_content->('mst'))
363 => '.career' => $r_content->('Chainsaw Wielder')),
364 HTML::Zoom::ArrayStream->new({ array => \@between })
369 filter($_ => '.name' => $r_content->('mdk'))
370 => '.career' => $r_content->('Adminion')
374 filter $_[0] => 'hr' => sub { $_->collect({ into => \@between }) }
380 <div name="cow" class="main">
381 <span class="hilight name">mst</span>
382 <span class="career">Chainsaw Wielder</span>
384 <span class="hilight name">mdk</span>
385 <span class="career">Adminion</span>
390 'repeat_content with filter ok'
400 filter($_ => '.name' => $r_content->('mst'))
401 => '.career' => $r_content->('Chainsaw Wielder')
405 filter($_ => '.name' => $r_content->('mdk'))
406 => '.career' => $r_content->('Adminion')
409 { repeat_between => 'hr' }
413 <div name="cow" class="main">
414 <span class="hilight name">mst</span>
415 <span class="career">Chainsaw Wielder</span>
417 <span class="hilight name">mdk</span>
418 <span class="career">Adminion</span>
423 'repeat_content using repeat_between ok'