Changeset 344

Show
Ignore:
Timestamp:
03/05/08 10:45:39 (2 months ago)
Author:
ingy
Message:
...
Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/src/ingy/pQuery/lib/pQuery.pm

    r324 r344  
     1# pQuery - A Perl version of jQuery. 
     2 
    13package pQuery; 
    24use strict; 
    35use warnings; 
    46use 5.006001; 
    5 use HTML::TreeBuilder
     7use pQuery::DOM
    68 
    79use base 'Exporter'; 
    8 # use XXX; 
    910 
    1011our $VERSION = '0.01'; 
    1112 
    1213our @EXPORT = qw(pQuery); 
     14 
     15our $DOM; 
    1316 
    1417my $my = {}; 
    1518my $lwp_user_agent; 
     19my $quickExpr = qr/^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/; 
     20my $isSimple = qr/^.[^:#\[\.]*$/; 
     21my $dom_element_class = 'pQuery::DOM'; 
    1622 
    1723sub pQuery { 
     
    2329    my $self = bless [], $class; 
    2430    $my->{$self} = {}; 
    25  
    26     if (not @_) { 
     31    return $self->_init(@_); 
     32
     33 
     34sub _init { 
     35    my ($self, $selector, $context) = @_; 
     36 
     37    my $document = $DOM || $main::DOM || $main::DOM; 
     38    $selector ||= $document or return $self; 
     39 
     40    if (ref($selector) eq $dom_element_class) { 
     41        @$self = $selector; 
    2742        return $self; 
    2843    } 
    29     elsif (@_ == 1 and $_[0] =~ /^\s*</) { 
    30         return $self->new_from_html(@_); 
    31     } 
    32     elsif (@_ == 1 and $_[0] =~ /^\s*(https?|file):/) { 
    33         return $self->new_from_url(@_); 
    34     } 
    35     elsif (@_ == 1 and ref($_[0]) eq 'ARRAY') { 
    36         @$self = @{$_[0]}; 
     44    elsif (not ref($selector)) { 
     45        my $match = ($selector =~ $quickExpr); 
     46 
     47        if ($match and ($1 or not $context)) { 
     48            if ($1) { 
     49                $selector = $self->_clean([$1], $context); 
     50            } 
     51            else { 
     52                my $id = $3; 
     53                my $elem = $document->getElementById($id); 
     54                if ($elem) { 
     55                    if ($elem->id ne $id) { 
     56                        return pQuery->find($selector); 
     57                    } 
     58                    else { 
     59                        $self->[0] = $elem; 
     60                        $#$self = 0; 
     61                        return $self; 
     62                    } 
     63                } 
     64                else { 
     65                    $selector = []; 
     66                } 
     67            } 
     68 
     69 
     70 
     71            @$self = pQuery::DOM->fromHTML($selector); 
     72            return $self; 
     73 
     74 
     75 
     76        } 
     77        else { 
     78 
     79 
     80            if ($selector =~ /^\s*(https?|file):/) { 
     81                return $self->_new_from_url($selector); 
     82            } 
     83            else { 
     84                die "Can't create new pQuery object with these arguments:\n(@_)"; 
     85            } 
     86        } 
     87    } 
     88    elsif (ref($selector) eq 'ARRAY') { 
     89        @$self = @$selector; 
    3790        return $self; 
    3891    } 
    39     elsif (@_ == 1 and ref($_[0]) eq 'HTML::Element') { 
    40         @$self = $_[0]; 
    41         return $self; 
    42     } 
    43     else { 
    44         die "Can't create new pQuery object with these arguments:\n(@_)"; 
    45     } 
    46 
    47  
    48 sub new_from_url { 
     92    return $self; 
     93
     94 
     95sub _clean { 
     96    my ($self, $html) = @_; 
     97    return $html->[0]; 
     98
     99 
     100sub _new_from_url { 
    49101    my $self = shift; 
    50102    my $url = shift; 
     
    53105        return $self; 
    54106    } 
    55     return $self->new_from_html($response->content); 
    56 
    57  
    58 sub new_from_html { 
    59     my ($self, $html) = @_; 
    60     @$self = ($self->html_to_dom($html)); 
    61     return $self; 
    62 
    63  
    64 sub html_to_dom { 
    65     my ($self, $html) = @_; 
    66     my $dom = HTML::TreeBuilder->new; 
    67     $dom->ignore_ignorable_whitespace(0); 
    68     $dom->no_space_compacting(1); 
    69     $dom->parse_content($html); 
    70     $dom->elementify; 
    71  
    72     if ($html =~ /\s*<html\b/) { 
    73         return $dom; 
    74     } 
    75     else { 
    76         return $dom->{_content}[1]{_content}[0]; 
    77     } 
     107    @$self = pQuery::DOM->fromHTML($response->content); 
    78108} 
    79109 
     
    86116    return unless @$self; 
    87117 
    88     my $html = ''; 
    89  
    90     _to_html($self->[0], \$html); 
    91  
    92     return $html; 
     118    return $self->[0]->innerHTML; 
     119
     120 
     121sub toHtml { 
     122    my $self = shift; 
     123    if (@_) { 
     124        my $dom = $self->html_to_dom(@_); 
     125        die "XXX - need to insert dom here"; 
     126    } 
     127    return unless @$self; 
     128 
     129    return $self->[0]->toHTML; 
    93130} 
    94131 
     
    141178 
    142179# Helper functions (not methods) 
    143 sub _to_html { 
    144     my ($elem, $html) = @_; 
    145     if (ref $elem) { 
    146         $$html .= '<' . $elem->{_tag}; 
    147         $$html .= qq{ id="$elem->{id}"} 
    148             if $elem->{id}; 
    149         $$html .= qq{ class="$elem->{class}"} 
    150             if $elem->{class}; 
    151         for (sort keys %$elem) { 
    152             next if /^(_|id$|class$)/i; 
    153             $$html .= qq{ $_="$elem->{$_}"}; 
    154         } 
    155         
    156         $$html .= '>'; 
    157         for my $child (@{$elem->{_content}}) { 
    158             _to_html($child, $html); 
    159         } 
    160         $$html .= '</' . $elem->{_tag} . '>'; 
    161     } 
    162     else { 
    163         $$html .= $elem; 
    164     } 
    165 } 
    166  
    167180sub _to_text { 
    168181    my ($elem, $text) = @_; 
     
    311324    my $pquery2 = $pquery1->find("h1,h2,h3"); 
    312325 
     326=head2 html() html($html) 
     327 
     328This method is akin to the famous JavaScript/DOM function C<innerHTML>. 
     329 
     330If called with no arguments, this will return the the B<inner> HTML 
     331string of the B<first> DOM element in the pQuery object. 
     332 
     333If called with an HTML string argument, this will set the inner HTML of all 
     334the DOM elements in the pQuery object. 
     335 
     336=head2 HTML() 
     337 
     338This function takes no arguments, and returns the B<outer> HTML of the first 
     339DOM object in the pQuery object. Outer HTML means the HTML of the current 
     340object and its inner HTML. 
     341 
     342For example: 
     343 
     344    pQuery('<p>I <b>like</b> pie</p>').HTML(); 
     345 
     346returns: 
     347 
     348    <p>I <b>like</b> pie</p> 
     349 
     350while: 
     351 
     352    pQuery('<p>I <b>like</b> pie</p>').html(); 
     353 
     354returns: 
     355 
     356    I <b>like</b> pie 
     357 
    313358=head2 end() 
    314359 
  • trunk/src/ingy/pQuery/t/contructors.t

    r328 r344  
    1 use Test::More tests => 7
     1use Test::More tests => 8
    22 
    33use pQuery; 
     
    1919is scalar(@$p3), 1, 'Object has six elements'; 
    2020 
     21my $p4 = pQuery('<p>aaa</p>bbb<p>ccc</p>'); 
     22 
     23is scalar(@$p4), 3, 'Object has 3 elements'; 
  • trunk/src/ingy/pQuery/t/html.t

    r328 r344  
    1 use Test::More tests => 3
     1use Test::More tests => 7
    22use strict; 
    33use warnings; 
     
    55use pQuery; 
    66 
    7 is pQuery->html, undef, "HTML of empty object is undef"; 
     7 
     8# Test html() method 
     9# Test toHtml() method 
     10# Test with non DOM objects 
     11# Multiple  
     12 
     13 
     14is pQuery->html, undef, "html of empty object is undef"; 
     15is pQuery->toHtml, undef, "toHtml of empty object is undef"; 
     16 
     17is pQuery('<p>aaa <b>bbb</b> ccc</p>')->toHtml, 
     18    '<p>aaa <b>bbb</b> ccc</p>', 
     19    'toHtml of single tree works'; 
     20 
     21is pQuery('<p>aaa <b>bbb</b> ccc</p>')->html, 
     22    'aaa <b>bbb</b> ccc', 
     23    'html of single tree works'; 
    824 
    925open FILE, 't/document1.html' or die $!; 
     
    1228chomp $html; 
    1329 
    14 my $html2 = pQuery($html)->html; 
     30my $html2 = pQuery($html)->toHtml; 
    1531 
    1632# XXX Work around HTML::TreeBuilder quirks 
     
    1834$html2 =~ s{(<html>|</head>)}{$1\n  }g; 
    1935 
    20 is $html2, $html, 'HTML output matches HTML input'; 
     36is $html2, $html, 'toHtml output matches toHtml input'; 
    2137 
    2238my $html3 = '<p>Foo <b>bar</b> baz</p>'; 
    2339 
    24 is pQuery($html3)->html, $html3, 'HTML Snippet'; 
     40is pQuery($html3)->toHtml, $html3, 'toHtml Snippet'; 
     41 
     42is pQuery($html3)->html, 'Foo <b>bar</b> baz', 'innerHTML works'; 
     43