From 237e950667eebb2a48da037136a4a73044e6ada8 Mon Sep 17 00:00:00 2001 From: Terrence Brannon Date: Fri, 22 Jan 2010 19:15:28 -0500 Subject: [PATCH] update git to 4.2.b --- META.yml | 47 +- Makefile.PL | 39 +- lib/HTML/Element/Library.pm | 1170 +--------------------------------- lib/HTML/Element/Library.pod | 1153 +++++++++++++++++++++++++++++++++ 4 files changed, 1215 insertions(+), 1194 deletions(-) create mode 100644 lib/HTML/Element/Library.pod diff --git a/META.yml b/META.yml index 13548e2..022aea1 100644 --- a/META.yml +++ b/META.yml @@ -1,18 +1,31 @@ -# http://module-build.sourceforge.net/META-spec.html -#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX# -name: HTML-Element-Library -version: 3.51 -version_from: lib/HTML/Element/Library.pm -installdirs: site +--- #YAML:1.0 +name: HTML-Element-Library +version: 4.2.a +abstract: ~ +author: + - Terrence Brannon +license: unknown +distribution_type: module +configure_requires: + ExtUtils::MakeMaker: 0 +build_requires: + ExtUtils::MakeMaker: 0 requires: - Array::Group: 1 - File::Slurp: 9999.06 - HTML::PrettyPrinter: 0.03 - HTML::Tree: 3.19 - List::MoreUtils: 0.09 - List::Rotation::Cycle: 1.003 - Params::Validate: 0.8 - Scalar::Listify: 0.02 - -distribution_type: module -generated_by: ExtUtils::MakeMaker version 6.17 + Array::Group: 1 + File::Slurp: 9999.06 + HTML::FillInForm: 0 + HTML::PrettyPrinter: 0.03 + HTML::Tree: 3.19 + List::MoreUtils: 0.09 + List::Rotation::Cycle: 1.003 + Moose: 0 + Params::Validate: 0.8 + Scalar::Listify: 0.02 +no_index: + directory: + - t + - inc +generated_by: ExtUtils::MakeMaker version 6.54 +meta-spec: + url: http://module-build.sourceforge.net/META-spec-v1.4.html + version: 1.4 diff --git a/Makefile.PL b/Makefile.PL index fc8fbe3..6831d28 100644 --- a/Makefile.PL +++ b/Makefile.PL @@ -2,28 +2,33 @@ use 5.006001; use ExtUtils::MakeMaker; # See lib/ExtUtils/MakeMaker.pm for details of how to influence # the contents of the Makefile that is written. -WriteMakefile( - NAME => 'HTML::Element::Library', - VERSION_FROM => 'lib/HTML/Element/Library.pm', # finds $VERSION - PREREQ_PM => { - Array::Group => 1.00, +WriteMakefile + ( + NAME => 'HTML::Element::Library', + VERSION_FROM => 'lib/HTML/Element/Library.pm', # finds $VERSION + PREREQ_PM => + { + Array::Group => 1.00, - File::Slurp => 9999.06, + Moose => 0, + File::Slurp => 9999.06, - HTML::PrettyPrinter => 0.03, - HTML::Tree => 3.19, + HTML::FillInForm => 0, + HTML::PrettyPrinter => 0.03, + HTML::Tree => 3.19, - List::Rotation::Cycle => 1.003, - List::MoreUtils => 0.09, + List::Rotation::Cycle => 1.003, + List::MoreUtils => 0.09, - Params::Validate => 0.80, + Params::Validate => 0.80, - Scalar::Listify => 0.02, - }, - ($] >= 5.005 ? ## Add these new keywords supported since 5.005 - (ABSTRACT_FROM => 'lib/HTML/Element/Library.pm', # retrieve abstract from module - AUTHOR => 'Terrence Brannon ') : ()), -); + Scalar::Listify => 0.02, + }, + ($] >= 5.005 ? ## Add these new keywords supported since 5.005 + ( + + AUTHOR => 'Terrence Brannon ') : ()), + ); sub MY::postamble { q{ diff --git a/lib/HTML/Element/Library.pm b/lib/HTML/Element/Library.pm index 4c2d879..fa03765 100644 --- a/lib/HTML/Element/Library.pm +++ b/lib/HTML/Element/Library.pm @@ -1,6 +1,6 @@ package HTML::Element::Library; -use 5.006001; + use strict; use warnings; @@ -25,7 +25,7 @@ our @EXPORT = qw(); -our $VERSION = '3.53'; +our $VERSION = '4.2.b'; @@ -34,7 +34,7 @@ our $VERSION = '3.53'; # https://rt.cpan.org/Ticket/Display.html?id=44105 sub HTML::Element::fillinform { - my ($tree, $hashref, $return_tree)=@_; + my ($tree, $hashref, $return_tree, $guts)=@_; (ref $hashref) eq 'HASH' or die 'hashref not supplied as argument' ; @@ -43,7 +43,8 @@ sub HTML::Element::fillinform { my $new_html = HTML::FillInForm->fill(\$html, $hashref); if ($return_tree) { - HTML::TreeBuilder->new_from_content($new_html); + my $tree = HTML::TreeBuilder->new_from_content($new_html); + $tree = $guts ? $tree->guts : $tree ; } else { $new_html; } @@ -84,7 +85,7 @@ sub HTML::Element::hash_map { warn 'The container tag is ', $container->tag if $p{debug} ; warn 'hash' . Dumper($p{hash}) if $p{debug} ; - warn 'at_under' . Dumper(\@_) if $p{debug} ; + #warn 'at_under' . Dumper(\@_) if $p{debug} ; my @same_as = $container->look_down( $p{to_attr} => qr/.+/ ) ; @@ -203,6 +204,10 @@ sub HTML::Element::content_handler { } +sub HTML::Element::assign { + goto &HTML::Element::content_handler; +} + sub make_counter { my $i = 1; @@ -755,1158 +760,3 @@ sub HTML::TreeBuilder::parse_string { 1; __END__ -# Below is stub documentation for your module. You'd better edit it! - -=head1 NAME - -HTML::Element::Library - HTML::Element convenience functions - -=head1 SYNOPSIS - - use HTML::Element::Library; - use HTML::TreeBuilder; - -=head1 DESCRIPTION - -This method provides API calls for common actions on trees when using -L. - -=head1 METHODS - -The test suite contains examples of each of these methods in a -file C - -=head2 Positional Querying Methods - -=head3 $elem->siblings - -Return a list of all nodes under the same parent. - -=head3 $elem->sibdex - -Return the index of C<$elem> into the array of siblings of which it is -a part. L calls this method C but I don't think -that is a descriptive name. And such naming is deceptively close to the -C
function of C. HOWEVER, in the interest of -backwards compatibility, both methods are available. - -=head3 $elem->addr - -Same as sibdex - -=head3 $elem->position() - -Returns the coordinates of this element in the tree it inhabits. -This is accomplished by succesively calling addr() on ancestor -elements until either a) an element that does not support these -methods is found, or b) there are no more parents. The resulting -list is the n-dimensional coordinates of the element in the tree. - -=head2 Element Decoration Methods - -=head3 HTML::Element::Library::super_literal($text) - -In L, Sean Burke discusses super-literals. They are -text which does not get escaped. Great for includng Javascript in -HTML. Also great for including foreign language into a document. - -So, you basically toss C your text and back comes -your text wrapped in a C<~literal> element. - -One of these days, I'll around to writing a nice C section. - -=head2 Tree Rewriting Methods - -=head3 Simplifying calls to HTML::FillInForm - -Since HTML::FillInForm gets and returns strings, using HTML::Element instances -becomes tedious: - - 1. Seamstress has an HTML tree that it wants the form filled in on - 2. Seamstress converts this tree to a string - 3. FillInForm parses the string into an HTML tree and then fills in the form - 4. FillInForm converts the HTML tree to a string - 5. Seamstress re-parses the HTML for additional processing - -I've filed a bug about this: -L - -This function, fillinform, -allows you to pass a tree to fillinform (along with your data structure) and -get back a tree: - - my $new_tree = $html_tree->fillinform($data_structure); - - -=head3 Mapping a hashref to HTML elements - -It is very common to get a hashref of data from some external source - flat file, database, XML, etc. -Therefore, it is important to have a convenient way of mapping this data to HTML. - -As it turns out, there are 3 ways to do this in HTML::Element::Library. -The most strict and structured way to do this is with -C. Two other methods, C and C require less manual mapping and may prove -even more easy to use in certain cases. - -As is usual with Perl, a practical example is always best. So let's take some sample HTML: - -

user data

- ? - ? - ? - -Now, let's say our data structure is this: - - $ref = { email => 'jim@beam.com', gender => 'lots' } ; - -And let's start with the most strict way to get what you want: - - $tree->content_handler(email => $ref->{email} , gender => $ref->{gender}) ; - - -In this case, you manually state the mapping between id tags and hashref keys and -then C retrieves the hashref data and pops it in the specified place. - -Now let's look at the two (actually 2 and a half) other hash-mapping methods. - - $tree->hashmap(id => $ref); - -Now, what this function does is super-destructive. It finds every element in the tree -with an attribute named id (since 'id' is a parameter, it could find every element with -some other attribute also) and replaces the content of those elements with the hashref -value. - -So, in the case above, the - - ? - -would come out as - - - -(it would be blank) - because there is nothing in the hash with that value, so it substituted - - $ref->{name} - -which was blank and emptied the contents. - -Now, let's assume we want to protect name from being auto-assigned. Here is what you do: - - $tree->hashmap(id => $ref, ['name']); - -That last array ref is an exclusion list. - -But wouldnt it be nice if you could do a hashmap, but only assigned things which are defined -in the hashref? C<< defmap() >> to the rescue: - - $tree->defmap(id => $ref); - -does just that, so - - ? - -would be left alone. - - -=head4 $elem->hashmap($attr_name, \%hashref, \@excluded, $debug) - -This method is designed to take a hashref and populate a series of elements. For example: - - - - - - - - -
1(877) 255-3239*********
- -In the table above, there are several attributes named C<< smap >>. If we have a hashref whose keys are the same: - - my %data = (people_id => 888, phone => '444-4444', password => 'dont-you-dare-render'); - -Then a single API call allows us to populate the HTML while excluding those ones we dont: - - $tree->hashmap(smap => \%data, ['password']); - - -Note: the other way to prevent rendering some of the hash mapping is to not give that element the attr -you plan to use for hash mapping. - -Also note: the function C<< hashmap >> has a simple easy-to-type API. Interally, it calls C<< hash_map >> -(which has a more verbose keyword calling API). Thus, the above call to C results in this call: - - $tree->hash_map(hash => \%data, to_attr => 'sid', excluding => ['password']); - -=head4 $elem->defmap($attr_name, \%hashref, $debug) - -C was described above. - - -=head4 $elem->content_handler(%hashref) - -C is described below. - - -=head3 $elem->replace_content(@new_elem) - -Replaces all of C<$elem>'s content with C<@new_elem>. - -=head3 $elem->wrap_content($wrapper_element) - -Wraps the existing content in the provided element. If the provided element -happens to be a non-element, a push_content is performed instead. - -=head3 $elem->set_child_content(@look_down, $content) - - This method looks down $tree using the criteria specified in @look_down using the the HTML::Element look_down() method. - -After finding the node, it detaches the node's content and pushes $content as the node's content. - -=head3 $tree->content_handler(%id_content) - -This is a convenience method. Because the look_down criteria will often simply be: - - id => 'fixme' - -to find things like: - - replace_content - -You can call this method to shorten your typing a bit. You can simply type - - $elem->content_handler( fixme => 'new text' ) - -Instead of typing: - - $elem->set_child_content(sid => 'fixme', 'new text') - -ALSO NOTE: you can pass a hash whose keys are Cs and whose values are the content you want there and it will perform the replacement on each hash member: - - my %id_content = (name => "Terrence Brannon", - email => 'tbrannon@in.com', - balance => 666, - content => $main_content); - - $tree->content_handler(%id_content); - -=head3 $tree->highlander($subtree_span_id, $conditionals, @conditionals_args) - -This allows for "if-then-else" style processing. Highlander was a movie in -which only one would survive. Well, in terms of a tree when looking at a -structure that you want to process in C style, only one child -will survive. For example, given this HTML template: - - - - Hello, does your mother know you're - using her AOL account? - - - Sorry, you're not old enough to enter - (and too dumb to lie about your age) - - - Welcome - - - -We only want one child of the C tag with id C to remain -based on the age of the person visiting the page. - -So, let's setup a call that will prune the subtree as a function of age: - - sub process_page { - my $age = shift; - my $tree = HTML::TreeBuilder->new_from_file('t/html/highlander.html'); - - $tree->highlander - (age_dialog => - [ - under10 => sub { $_[0] < 10} , - under18 => sub { $_[0] < 18} , - welcome => sub { 1 } - ], - $age - ); - -And there we have it. If the age is less than 10, then the node with -id C remains. For age less than 18, the node with id C -remains. -Otherwise our "else" condition fires and the child with id C remains. - -=head3 $tree->passover(@id_of_element) - -In some cases, you know exactly which element(s) should survive. In this case, -you can simply call C to remove it's (their) siblings. For the HTML -above, you could delete C and C by simply calling: - - $tree->passover('under18'); - -Because passover takes an array, you can specify several children to preserve. - -=head3 $tree->highlander2($tree, $conditionals, @conditionals_args) - -Right around the same time that C came into being, Seamstress -began to tackle tougher and tougher processing problems. It became clear that -a more powerful highlander was needed... one that not only snipped the tree -of the nodes that should not survive, but one that allows for -post-processing of the survivor node. And one that was more flexible with -how to find the nodes to snip. - -Thus (drum roll) C. - -So let's look at our HTML which requires post-selection processing: - - - - Hello, little AGE-year old, - does your mother know you're using her AOL account? - - - Sorry, you're only AGE - (and too dumb to lie about your age) - - - Welcome, isn't it good to be AGE years old? - - - -In this case, a branch survives, but it has dummy data in it. We must take -the surviving segment of HTML and rewrite the age C with the age. -Here is how we use C to do so: - - sub replace_age { - my $branch = shift; - my $age = shift; - $branch->look_down(id => 'age')->replace_content($age); - } - - my $if_then = $tree->look_down(id => 'age_dialog'); - - $if_then->highlander2( - cond => [ - under10 => [ - sub { $_[0] < 10} , - \&replace_age - ], - under18 => [ - sub { $_[0] < 18} , - \&replace_age - ], - welcome => [ - sub { 1 }, - \&replace_age - ] - ], - cond_arg => [ $age ] - ); - -We pass it the tree (C<$if_then>), an arrayref of conditions -(C) and an arrayref of arguments which are passed to the -Cs and to the replacement subs. - -The C, C and C are id attributes in the -tree of the siblings of which only one will survive. However, -should you need to do -more complex look-downs to find the survivor, -then supply an array ref instead of a simple -scalar: - - - $if_then->highlander2( - cond => [ - [class => 'r12'] => [ - sub { $_[0] < 10} , - \&replace_age - ], - [class => 'z22'] => [ - sub { $_[0] < 18} , - \&replace_age - ], - [class => 'w88'] => [ - sub { 1 }, - \&replace_age - ] - ], - cond_arg => [ $age ] - ); - - -=head3 $tree->overwrite_attr($mutation_attr => $mutating_closures) - -This method is designed for taking a tree and reworking a set of nodes in -a stereotyped fashion. For instance let's say you have 3 remote image -archives, but you don't want to put long URLs in your img src -tags for reasons of abstraction, re-use and brevity. So instead you do this: - - - - - -and then when the tree of HTML is being processed, you make this call: - - my %closures = ( - lnc => sub { my ($tree, $mute_node, $attr_value)= @_; "http://lnc.usc.edu$attr_value" }, - playboy => sub { my ($tree, $mute_node, $attr_value)= @_; "http://playboy.com$attr_value" } - foobar => sub { my ($tree, $mute_node, $attr_value)= @_; "http://foobar.info$attr_value" } - ) - - $tree->overwrite_attr(fixup => \%closures) ; - -and the tags come out modified like so: - - - - - -=head3 $tree->mute_elem($mutation_attr => $mutating_closures, [ $post_hook ] ) - -This is a generalization of C. C -assumes the return value of the -closure is supposed overwrite an attribute value and does it for you. -C is a more general function which does nothing but -hand the closure the element and let it mutate it as it jolly well pleases :) - -In fact, here is the implementation of C -to give you a taste of how C is used: - - sub overwrite_action { - my ($mute_node, %X) = @_; - - $mute_node->attr($X{local_attr}{name} => $X{local_attr}{value}{new}); - } - - - sub HTML::Element::overwrite_attr { - my $tree = shift; - - $tree->mute_elem(@_, \&overwrite_action); - } - - - - -=head2 Tree-Building Methods - - - -=head3 Unrolling an array via a single sample element (
    container) - -This is best described by example. Given this HTML: - - Here are the things I need from the store: -
      -
    • Sample item
    • -
    - -We can unroll it like so: - - my $li = $tree->look_down(class => 'store_items'); - - my @items = qw(bread butter vodka); - - $tree->iter($li => @items); - -To produce this: - - - - - Here are the things I need from the store: -
      -
    • bread
    • -
    • butter
    • -
    • vodka
    • -
    - - - -Now, you might be wondering why the API call is: - - $tree->iter($li => @items) - -instead of: - - $li->iter(@items) - -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 n sample elements (
    container) - -C was fine for awhile, but some things -(e.g. definition lists) need a more general function to make them easy to -do. Hence C. This function will be explained by example of unrolling -a simple definition list. - -So here's our mock-up HTML from the designer: - -
    -
    - Artist -
    -
    - A person who draws blood. -
    - -
    - Musician -
    -
    - A clone of Iggy Pop. -
    - -
    - Poet -
    -
    - A relative of Edgar Allan Poe. -
    - -
    sample header
    -
    sample data
    - -
    - - -And we want to unroll our data set: - - my @items = ( - ['the pros' => 'never have to worry about service again'], - ['the cons' => 'upfront extra charge on purchase'], - ['our choice' => 'go with the extended service plan'] - ); - - -Now, let's make this problem a bit harder to show off the power of C. -Let's assume that we want only the last
    and it's accompanying
    -(the one with "sample data") to be used as the sample data -for unrolling with our data set. Let's further assume that we want them to -remain in the final output. - -So now, the API to C will be discussed and we will explain how our -goal of getting our data into HTML fits into the API. - -=over 4 - -=item * wrapper_ld - -This is how to look down and find the container of all the elements we will -be unrolling. The
    tag is the container for the dt and dd tags we will be -unrolling. - -If you pass an anonymous subroutine, then it is presumed that execution of -this subroutine will return the HTML::Element representing the container tag. -If you pass an array ref, then this will be dereferenced and passed to -C. - -default value: C<< ['_tag' => 'dl'] >> - -Based on the mock HTML above, this default is fine for finding our container -tag. So let's move on. - -=item * wrapper_data - -This is an array reference of data that we will be putting into the container. -You must supply this. C<@items> above is our C. - -=item * wrapper_proc - -After we find the container via C, we may want to pre-process -some aspect of this tree. In our case the first two sets of dt and dd need -to be removed, leaving the last dt and dd. So, we supply a C -which will do this. - -default: undef - -=item * item_ld - -This anonymous subroutine returns an array ref of Cs that will -be cloned and populated with item data -(item data is a "row" of C). - -default: returns an arrayref consisting of the dt and dd element inside the -container. - -=item * item_data - -This is a subroutine that takes C and retrieves one "row" -to be "pasted" into the array ref of Cs found via C. -I hope that makes sense. - -default: shifts C. - -=item * item_proc - -This is a subroutine that takes the C and the Cs -found via C and produces an arrayref of Cs which will -eventually be spliced into the container. - -Note that this subroutine MUST return the new items. This is done -So that more items than were passed in can be returned. This is -useful when, for example, you must return 2 dts for an input data item. -And when would you do this? When a single term has multiple spellings -for instance. - -default: expects C to be an arrayref of two elements and -C to be an arrayref of two Cs. It replaces the -content of the Cs with the C. - -=item * splice - -After building up an array of C<@item_elems>, the subroutine passed as -C will be given the parent container HTML::Element and the -C<@item_elems>. How the C<@item_elems> end up in the container is up to this -routine: it could put half of them in. It could unshift them or whatever. - -default: C<< $container->splice_content(0, 2, @item_elems) >> -In other words, kill the 2 sample elements with the newly generated -@item_elems - -=back - -So now that we have documented the API, let's see the call we need: - - $tree->iter2( - # default wrapper_ld ok. - wrapper_data => \@items, - wrapper_proc => sub { - my ($container) = @_; - - # only keep the last 2 dts and dds - my @content_list = $container->content_list; - $container->splice_content(0, @content_list - 2); - }, - - # default item_ld is fine. - # default item_data is fine. - # default item_proc is fine. - splice => sub { - my ($container, @item_elems) = @_; - $container->unshift_content(@item_elems); - }, - debug => 1, - ); - - - - -=head3 Select Unrolling - -The C method has this API: - - $tree->unroll_select( - select_label => $id_label, - option_value => $closure, # how to get option value from data row - option_content => $closure, # how to get option content from data row - option_selected => $closure, # boolean to decide if SELECTED - data => $data # the data to be put into the SELECT - data_iter => $closure # the thing that will get a row of data - debug => $boolean, - append => $boolean, # remove the sample