Changeset 347
- Timestamp:
- 03/08/08 14:47:58 (2 months ago)
- Files:
-
- trunk/src/ingy/pQuery/Changes (modified) (1 diff)
- trunk/src/ingy/pQuery/MANIFEST (modified) (2 diffs)
- trunk/src/ingy/pQuery/README (modified) (9 diffs)
- trunk/src/ingy/pQuery/lib/pQuery.pm (modified) (16 diffs)
- trunk/src/ingy/pQuery/lib/pQuery/DOM.pm (modified) (3 diffs)
- trunk/src/ingy/pQuery/t/contructors.t (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/src/ingy/pQuery/Changes
r324 r347 1 --- 2 version: 0.02 3 date: Sat Mar 8 19:56:33 EET 2008 4 changes: 5 - Added a pQuery::DOM class. 6 - Finished porting constructor from jQuery. 7 1 8 --- 2 9 version: 0.01 trunk/src/ingy/pQuery/MANIFEST
r328 r347 17 17 inc/Test/More.pm 18 18 lib/pQuery.pm 19 lib/pQuery/DOM.pm 19 20 Makefile.PL 20 21 MANIFEST This list of files … … 23 24 t/contructors.t 24 25 t/document1.html 26 t/dom.t 25 27 t/each.t 26 28 t/find.t trunk/src/ingy/pQuery/README
r324 r347 6 6 7 7 pQuery("http://google.com/search?q=pquery") 8 ->find("h2 .r")8 ->find("h2") 9 9 ->each(sub { 10 10 my $i = shift; 11 print ($i + 1), ") ", pQuery($_)->text, "\n";11 print $i + 1, ") ", pQuery($_)->text, "\n"; 12 12 }); 13 13 … … 24 24 25 25 A pQuery object acts like an array reference (because, in fact, it is). 26 Typically it is an array of HTML::DOM elements, but it can be an array26 Typically it is an array of pQuery::DOM elements, but it can be an array 27 27 of anything. 28 29 pQuery::DOM is roughly an attempt to duplicate JavaScript's DOM in Perl. 30 It subclasses HTML::TreeBuilder/HTML::Element so there are a few 31 differences to be aware of. See the pQuery::DOM documentation for 32 details. 28 33 29 34 Like jQuery, pQuery methods return a pQuery object; either the original … … 31 36 32 37 CONSTRUCTORS 33 T He pQuery constructor is an exported function called "pQuery". It does38 The pQuery constructor is an exported function called "pQuery". It does 34 39 different things depending on the arguments you pass it. 35 40 36 41 A URL 37 42 If you pass pQuery a URL, it will attempt to get the page and use its 38 HTML to create a HTML::DOM object. The pQuery object will contain the39 top level HTML::DOM object.43 HTML to create a pQuery::DOM object. The pQuery object will contain the 44 top level pQuery::DOM object. 40 45 41 46 pQuery("http://google.com"); 42 47 48 It will also set the global variable $pQuery::document to the resulting 49 DOM object. Future calls to pQuery methods will use this document if 50 none other is supplied. 51 43 52 HTML 44 53 If you already have an HTML string, pass it to pQuery and it will create 45 a HTML::DOM object. The pQuery object will contain the top level46 HTML::DOM object.54 a pQuery::DOM object. The pQuery object will contain the top level 55 pQuery::DOM object. 47 56 48 57 pQuery("<p>Hello <b>world</b>.</p>"); … … 50 59 Selector String 51 60 You can create a pQuery object with a selector string just like in 52 jQuery. The problem is that Perl doesn't have a global DOM object lying 53 around like JavaScript does. You need to pass the DOM to select on as 54 the second parameter. (jQuery also has this second parameter). 61 jQuery. The problem is that Perl doesn't have a global document object 62 lying around like JavaScript does. 63 64 One thing you can do is set the global variable, $pQuery::document, to a 65 pQuery::DOM document. This will be used by future selectors. 66 67 Another thing you can do is pass the document to select on as the second 68 parameter. (jQuery also has this second, context parameter). 55 69 56 70 pQuery("table.mygrid > td:eq(7)", $dom); … … 64 78 Array Reference 65 79 You can create a pQuery object as an array of anything you want; not 66 just HTML::DOM elements. This can be useful to use the "each" method to67 iterate over the array.80 just pQuery::DOM elements. This can be useful to use the "each" method 81 to iterate over the array. 68 82 69 83 pQuery(\ @some_array); … … 78 92 METHODS 79 93 This is a reference of all the methods you can call on a pQuery object. 80 They are al lported from jQuery.94 They are almost entirely ported from jQuery. 81 95 82 96 each($sub) … … 95 109 96 110 find($selector) 97 This method will search all the HTML::DOM elements of the its caller for98 all sub elements that match the selector string. It will return a new99 pQuery object containing all the elements found.111 This method will search all the pQuery::DOM elements of the its caller 112 for all sub elements that match the selector string. It will return a 113 new pQuery object containing all the elements found. 100 114 101 115 my $pquery2 = $pquery1->find("h1,h2,h3"); 116 117 html() html($html) 118 This method is akin to the famous JavaScript/DOM function "innerHTML". 119 120 If called with no arguments, this will return the the inner HTML string 121 of the first DOM element in the pQuery object. 122 123 If called with an HTML string argument, this will set the inner HTML of 124 all the DOM elements in the pQuery object. 125 126 toHtml() 127 This extremely handy method is not ported from jQuery. Maybe jQuery will 128 port it back some day. :) 129 130 This function takes no arguments, and returns the outer HTML of the 131 first DOM object in the pQuery object. Outer HTML means the HTML of the 132 current object and its inner HTML. 133 134 For example: 135 136 pQuery('<p>I <b>like</b> pie</p>').HTML(); 137 138 returns: 139 140 <p>I <b>like</b> pie</p> 141 142 while: 143 144 pQuery('<p>I <b>like</b> pie</p>').html(); 145 146 returns: 147 148 I <b>like</b> pie 102 149 103 150 end() … … 112 159 ->end() # Go back to the tables selection 113 160 ->each(sub { ... }); # Do something with the tables 161 162 NOTE: Not implemented yet. :( 114 163 115 164 get($url) … … 127 176 only). 128 177 129 There is still much more code to port. Stay tuned... 178 Version 0.02 added the pQuery::DOM class which is a huge improvement, 179 and should facilitate making the rest of the porting easy. 180 181 But there is still much more code to port. Stay tuned... 130 182 131 183 AUTHOR trunk/src/ingy/pQuery/lib/pQuery.pm
r344 r347 9 9 use base 'Exporter'; 10 10 11 our $VERSION = '0.0 1';11 our $VERSION = '0.02'; 12 12 13 13 our @EXPORT = qw(pQuery); 14 14 15 our $ DOM;15 our $document; 16 16 17 17 my $my = {}; 18 18 my $lwp_user_agent; 19 my $quickExpr = qr/^ [^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/;19 my $quickExpr = qr/^([^<]*<(.|\s)+>[^>]*)$|^#(\w+)$/; 20 20 my $isSimple = qr/^.[^:#\[\.]*$/; 21 21 my $dom_element_class = 'pQuery::DOM'; … … 35 35 my ($self, $selector, $context) = @_; 36 36 37 my $document = $DOM || $main::DOM || $main::DOM;38 37 $selector ||= $document or return $self; 39 38 … … 47 46 if ($match and ($1 or not $context)) { 48 47 if ($1) { 49 $selector = $self->_clean([$1], $context); 48 $selector = [pQuery::DOM->fromHTML($1)]; 49 # $selector = $self->_clean([$1], $context); 50 50 } 51 51 else { 52 my $id = $3; 53 my $elem = $document->getElementById($id); 52 my $elem = $document->getElementById($3); 54 53 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 } 54 @$self = $elem; 55 return $self; 63 56 } 64 57 else { … … 66 59 } 67 60 } 68 69 70 71 @$self = pQuery::DOM->fromHTML($selector);72 return $self;73 74 75 76 61 } 77 62 else { 78 79 80 63 if ($selector =~ /^\s*(https?|file):/) { 81 return $ self->_new_from_url($selector);64 return $document = $self->_new_from_url($selector); 82 65 } 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; 90 return $self; 91 } 66 return pQuery($context)->find($selector); 67 } 68 } 69 @$self = (ref($selector) eq 'ARRAY' or ref($selector) eq 'pQuery') 70 ? @$selector 71 : $selector; 92 72 return $self; 93 }94 95 sub _clean {96 my ($self, $html) = @_;97 return $html->[0];98 73 } 99 74 … … 102 77 my $url = shift; 103 78 my $response = $self->get($url); 104 if (! $response->is_success) { 79 return $self 80 unless $response->is_success; 81 @$self = pQuery::DOM->fromHTML($response->content); 82 return $self; 83 } 84 85 sub html { 86 my $self = shift; 87 return unless @$self; 88 if (@_) { 89 for (@$self) { 90 next unless ref($_); 91 $_->innerHTML(@_); 92 } 105 93 return $self; 106 94 } 107 @$self = pQuery::DOM->fromHTML($response->content); 108 } 109 110 sub html { 111 my $self = shift; 112 if (@_) { 113 my $dom = $self->html_to_dom(@_); 114 die "XXX - need to insert dom here"; 115 } 95 return $self->[0]->innerHTML(@_); 96 } 97 98 sub toHtml { 99 my $self = shift; 116 100 return unless @$self; 117 118 return $self->[0]->innerHTML;119 }120 121 sub 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 101 return $self->[0]->toHTML; 130 102 } … … 217 189 218 190 pQuery("http://google.com/search?q=pquery") 219 ->find("h2 .r")191 ->find("h2") 220 192 ->each(sub { 221 193 my $i = shift; 222 print ($i + 1), ") ", pQuery($_)->text, "\n";194 print $i + 1, ") ", pQuery($_)->text, "\n"; 223 195 }); 224 196 … … 236 208 237 209 A pQuery object acts like an array reference (because, in fact, it is). 238 Typically it is an array of HTML::DOM elements, but it can be an array210 Typically it is an array of pQuery::DOM elements, but it can be an array 239 211 of anything. 212 213 pQuery::DOM is roughly an attempt to duplicate JavaScript's DOM in 214 Perl. It subclasses HTML::TreeBuilder/HTML::Element so there are a 215 few differences to be aware of. See the L<pQuery::DOM> documentation 216 for details. 240 217 241 218 Like jQuery, pQuery methods return a pQuery object; either the … … 245 222 =head1 CONSTRUCTORS 246 223 247 T He pQuery constructor is an exported function called C<pQuery>. It does224 The pQuery constructor is an exported function called C<pQuery>. It does 248 225 different things depending on the arguments you pass it. 249 226 … … 251 228 252 229 If you pass pQuery a URL, it will attempt to get the page and use its 253 HTML to create a HTML::DOM object. The pQuery object will contain the254 top level HTML::DOM object.230 HTML to create a pQuery::DOM object. The pQuery object will contain the 231 top level pQuery::DOM object. 255 232 256 233 pQuery("http://google.com"); 257 234 235 It will also set the global variable C<$pQuery::document> to the 236 resulting DOM object. Future calls to pQuery methods will use this 237 document if none other is supplied. 238 258 239 =head2 HTML 259 240 260 241 If you already have an HTML string, pass it to pQuery and it will create 261 a HTML::DOM object. The pQuery object will contain the top level262 HTML::DOM object.242 a pQuery::DOM object. The pQuery object will contain the top level 243 pQuery::DOM object. 263 244 264 245 pQuery("<p>Hello <b>world</b>.</p>"); … … 267 248 268 249 You can create a pQuery object with a selector string just like in 269 jQuery. The problem is that Perl doesn't have a global DOM object lying 270 around like JavaScript does. You need to pass the DOM to select on as 271 the second parameter. (jQuery also has this second parameter). 250 jQuery. The problem is that Perl doesn't have a global document object 251 lying around like JavaScript does. 252 253 One thing you can do is set the global variable, C<$pQuery::document>, 254 to a pQuery::DOM document. This will be used by future selectors. 255 256 Another thing you can do is pass the document to select on as the second 257 parameter. (jQuery also has this second, context parameter). 272 258 273 259 pQuery("table.mygrid > td:eq(7)", $dom); … … 283 269 284 270 You can create a pQuery object as an array of anything you want; not 285 just HTML::DOM elements. This can be useful to use the C<each> method to271 just pQuery::DOM elements. This can be useful to use the C<each> method to 286 272 iterate over the array. 287 273 … … 299 285 300 286 This is a reference of all the methods you can call on a pQuery object. They 301 are al lported from jQuery.287 are almost entirely ported from jQuery. 302 288 303 289 =head2 each($sub) … … 318 304 =head2 find($selector) 319 305 320 This method will search all the HTML::DOM elements of the its caller for306 This method will search all the pQuery::DOM elements of the its caller for 321 307 all sub elements that match the selector string. It will return a new 322 308 pQuery object containing all the elements found. … … 334 320 the DOM elements in the pQuery object. 335 321 336 =head2 HTML() 322 =head2 toHtml() 323 324 This extremely handy method is not ported from jQuery. Maybe jQuery will 325 port it back some day. :) 337 326 338 327 This function takes no arguments, and returns the B<outer> HTML of the first … … 369 358 ->each(sub { ... }); # Do something with the tables 370 359 360 NOTE: Not implemented yet. :( 361 371 362 =head2 get($url) 372 363 … … 385 376 only). 386 377 387 There is still much more code to port. Stay tuned... 378 Version 0.02 added the pQuery::DOM class which is a huge improvement, and 379 should facilitate making the rest of the porting easy. 380 381 But there is still much more code to port. Stay tuned... 388 382 389 383 =head1 AUTHOR trunk/src/ingy/pQuery/lib/pQuery/DOM.pm
r346 r347 96 96 sub fromHTML { 97 97 my ($class, $html) = @_; 98 my $dom = $class->_builder->parse_content($html); 99 if ($html =~ /^\s*<html.*?>/) { 98 my $dom; 99 if ($html =~ /^\s*<html.*?>.*<\/html>\s*\z/s) { 100 $dom = $class->_builder->parse_content($html); 100 101 return $dom; 101 102 } 103 $dom = $class->_builder->parse_content('<dummy>' . $html . '</dummy>'); 102 104 my @dom = map { 103 105 if (ref($_)) { … … 319 321 320 322 To deal with children, use the childNodes method which returns a list 321 of all the child nodes. Then you can youstandard Perl idioms to323 of all the child nodes. Then you can use standard Perl idioms to 322 324 process them. 323 325 … … 342 344 =item createElement($tag) 343 345 344 Create a new HTML Element node with the specified tag. This node will be empty345 and have no attributes.346 Create a new HTML Element node with the specified tag. This node will be 347 empty and have no attributes. 346 348 347 349 =item createComment($text) trunk/src/ingy/pQuery/t/contructors.t
r344 r347 1 use Test::More tests => 8; 1 use Test::More tests => 13; 2 use strict; 2 3 3 4 use pQuery; 4 5 5 my $p 1 = pQuery;6 my $pq; 6 7 7 is ref($p1), 'pQuery', 'Empty object created';8 is scalar(@$p1), 0, 'Empty object is empty';8 is $pQuery::document, undef, '$pQuery::document is not defined by default'; 9 $pq = pQuery; 9 10 10 my $p2 = pQuery([5..10]); 11 is ref($pq), 'pQuery', 'Empty object created'; 12 is scalar(@$pq), 0, 'Empty object is empty'; 11 13 12 is ref($p2), 'pQuery', 'Array object created';13 is scalar(@$p2), 6, 'Object has six elements';14 is $p2->[2], 7, 'Check value of aelement';14 $pq = pQuery(pQuery::DOM->fromHTML('<div>')); 15 is ref($pq), 'pQuery', 'pQuery object created'; 16 is scalar(@$pq), 1, 'Object has one element'; 15 17 16 my $p3 = pQuery('<ul><li>one</li><li>two</li></ul>'); 18 $pq = pQuery([pQuery::DOM->fromHTML('I <b>Like</b> <ul>Pie</ul>.')]); 19 is ref($pq), 'pQuery', 'pQuery object created'; 20 is scalar(@$pq), 5, 'Object has 5 elements'; 17 21 18 is ref($p3), 'pQuery', 'HTML object created'; 19 is scalar(@$p3), 1, 'Object has six elements'; 22 $pq = pQuery('<ul><li>one</li><li>two</li></ul>'); 20 23 21 my $p4 = pQuery('<p>aaa</p>bbb<p>ccc</p>'); 24 is ref($pq), 'pQuery', 'HTML object created'; 25 is scalar(@$pq), 1, 'Object has six elements'; 22 26 23 is scalar(@$p4), 3, 'Object has 3 elements'; 27 $pq = pQuery('<p>aaa</p>bbb<p>ccc</p>'); 28 29 is scalar(@$pq), 3, 'Object has 3 elements'; 30 31 $pq = pQuery([5..10]); 32 33 is ref($pq), 'pQuery', 'Array object created'; 34 is scalar(@$pq), 6, 'Object has six elements'; 35 is $pq->[2], 7, 'Check value of a element'; 36
