Add itercb, fid, fclass methods
authorMarius Gavrilescu <marius@ieval.ro>
Sat, 25 Jun 2016 21:33:52 +0000 (22:33 +0100)
committerMarius Gavrilescu <marius@ieval.ro>
Sat, 25 Jun 2016 21:33:52 +0000 (22:33 +0100)
MANIFEST
lib/HTML/Element/Library.pm
t/html/itercb-exp.html [new file with mode: 0644]
t/html/itercb.html [new file with mode: 0644]
t/misc.t

index ebcb91e30c5c9f404a9a7c5e72d98a195fd29a41..dc1dee202216e37554aaac71d1e1c8f836ebfe7a 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -25,6 +25,8 @@ t/html/highlander-5-exp.html
 t/html/highlander.html
 t/html/iter2-exp.html
 t/html/iter2.html
+t/html/itercb-exp.html
+t/html/itercb.html
 t/html/iter-exp.html
 t/html/iter.html
 t/html/position.html
index 2ebc43e8ce4b4ea88e7b2386d36a9adb6da915e9..928707cca6b2d891b37a675aecf69fe98cf0df09 100644 (file)
@@ -246,6 +246,19 @@ sub HTML::Element::iter {
        $p->replace_with(@item);
 }
 
+sub HTML::Element::itercb {
+       my ($self, $data, $code) = @_;
+       my $orig = $self;
+       my $prev = $orig;
+       for my $el (@$data) {
+               my $current = $orig->clone;
+               $code->($el, $current);
+               $prev->postinsert($current);
+               $prev = $current;
+       }
+       $orig->detach;
+}
+
 sub HTML::Element::iter2 { ## no critic (RequireArgUnpacking)
        my $tree = shift;
 
@@ -681,6 +694,9 @@ sub HTML::TreeBuilder::parse_string {
        HTML::TreeBuilder->parse($string);
 }
 
+sub HTML::Element::fid    { shift->look_down(id    => $_[0]) }
+sub HTML::Element::fclass { shift->look_down(class => qr/\b$_[0]\b/s) }
+
 1;
 __END__
 
@@ -701,6 +717,22 @@ HTML:::Element::Library provides extra methods for HTML::Element.
 
 =head1 METHODS
 
+=head2 Aliases
+
+These are short aliases for common operations:
+
+=over
+
+=item I<$el>->B<fid>(I<$id>)
+
+Finds an element given its id. Equivalent to C<< $el->look_down(id => $id) >>.
+
+=item I<$el>->B<fclass>(I<$class>)
+
+Finds one or more elements given one of their classes. Equivalent to C<< $el->look_down(class => qr/\b$class\b/s) >>
+
+=back
+
 =head2 Positional Querying Methods
 
 =head3 $elem->siblings
@@ -1187,6 +1219,78 @@ instead of:
 and there is no good answer. The latter would be more concise and it
 is what I should have done.
 
+=head3 Unrolling an array via a single sample element and a callback (<ul> container)
+
+This is a more advanced version of the previous method. Instead of
+cloning the sample element several times and calling
+C<replace_content> on the clone with the array element, a custom
+callback is called with the clone and array element.
+
+Here is the example from before.
+
+ <strong>Here are the things I need from the store:</strong>
+ <ul>
+   <li class="store_items">Sample item</li>
+ </ul>
+
+Code:
+
+  sub cb {
+    my ($data, $li) = @_;
+    $li->replace_content($data);
+  }
+
+  my $li = $tree->look_down(class => 'store_items');
+  my @items = qw(bread butter vodka);
+  $li->itercb(\@items, \&cb);
+
+Output is as before:
+
+ <html>
+  <head></head>
+  <body>Here are the things I need from the store:
+    <ul>
+      <li class="store_items">bread</li>
+      <li class="store_items">butter</li>
+      <li class="store_items">vodka</li>
+    </ul>
+  </body>
+ </html>
+
+Here is a more complex example (unrolling a table). HTML:
+
+  <table><thead><th>First Name<th>Last Name<th>Option</thead>
+  <tbody>
+  <tr><td class="first">First<td class="last">Last<td class="option">1
+  </tbody></table>
+
+Code:
+
+  sub tr_cb {
+    my ($data, $tr) = @_;
+    $tr->look_down(class => 'first')->replace_content($data->{first});
+    $tr->look_down(class => 'last')->replace_content($data->{last});
+    $tr->look_down(class => 'option')->replace_content($data->{option});
+  }
+
+  my @data = (
+    {first => 'Foo', last => 'Bar', option => 2},
+    {first => 'Bar', last => 'Bar', option => 3},
+    {first => 'Baz', last => 'Bar', option => 4},
+  );
+
+  my $tr = $tree->find('table')->find('tbody')->find('tr');
+  $tr->itercb(\@data, \&tr_cb);
+
+Produces:
+
+  <table><thead><th>First Name<th>Last Name<th>Option</thead>
+  <tbody>
+  <tr><td class="first">Foo<td class="last">Bar<td class="option">2
+  <tr><td class="first">Bar<td class="last">Bar<td class="option">3
+  <tr><td class="first">Baz<td class="last">Bar<td class="option">4
+  </tbody></table>
+
 =head3 Unrolling an array via n sample elements (<dl> container)
 
 C<iter()> was fine for awhile, but some things (e.g. definition lists)
diff --git a/t/html/itercb-exp.html b/t/html/itercb-exp.html
new file mode 100644 (file)
index 0000000..e6267f8
--- /dev/null
@@ -0,0 +1,8 @@
+<body>
+  <table><thead><tr><th>First Name</th><th>Last Name</th><th>Option</th></tr></thead>
+  <tbody>
+  <tr><td class="first">Foo</td><td class="last">Bar</td><td class="option">2</td></tr>
+  <tr><td class="first">Bar</td><td class="last">Bar</td><td class="option">3</td></tr>
+  <tr><td class="first">Baz</td><td class="last">Bar</td><td class="option">4</td></tr>
+  </tbody></table>
+</body>
diff --git a/t/html/itercb.html b/t/html/itercb.html
new file mode 100644 (file)
index 0000000..386c958
--- /dev/null
@@ -0,0 +1,6 @@
+<body>
+  <table><thead><tr><th>First Name</th><th>Last Name</th><th>Option</th></tr></thead>
+  <tbody>
+  <tr><td class="first">First</td><td class="last">Last</td><td class="option">1</td></tr>
+  </tbody></table>
+</body>
index a0ae26cb7cefcf3350296f13d736b356e85478cc..2af0efc81f05523f9f00f3be102c7b94157d131e 100644 (file)
--- a/t/misc.t
+++ b/t/misc.t
@@ -1,6 +1,6 @@
 #!/usr/bin/perl -T
 use lib '.';
-use t::lib tests => 26;
+use t::lib tests => 27;
 
 ##################################################
 # Short tests based on mklol
@@ -123,6 +123,25 @@ isxml $tree, 't/html/dual_iter-exp.html', 'dual_iter';
 
 ###
 
+sub cb {
+       my ($data, $tr) = @_;
+       $tr->look_down(class => 'first')->replace_content($data->{first});
+       $tr->look_down(class => 'last')->replace_content($data->{last});
+       $tr->look_down(class => 'option')->replace_content($data->{option});
+}
+
+my @cbdata = (
+       {first => 'Foo', last => 'Bar', option => 2},
+       {first => 'Bar', last => 'Bar', option => 3},
+       {first => 'Baz', last => 'Bar', option => 4},
+);
+
+$tree = mktree 't/html/itercb.html';
+$tree->find('table')->find('tbody')->find('tr')->itercb(\@cbdata, \&cb);
+isxml $tree, 't/html/itercb-exp.html', 'itercb';
+
+###
+
 for my $age (qw/5 15 50/) {
        $tree = mktree 't/html/highlander.html';
        $tree->highlander(
This page took 0.018552 seconds and 4 git commands to generate.