File Coverage

lib/HTML/Object/DOM/Document.pm
Criterion Covered Total %
statement 229 472 48.5
branch 41 164 25.0
condition 41 124 33.0
subroutine 70 146 47.9
pod 121 121 100.0
total 502 1027 48.8


line stmt bran cond sub pod time code
1             ##----------------------------------------------------------------------------
2             ## HTML Object - ~/lib/HTML/Object/DOM/Document.pm
3             ## Version v0.2.2
4             ## Copyright(c) 2022 DEGUEST Pte. Ltd.
5             ## Author: Jacques Deguest <jack@deguest.jp>
6             ## Created 2021/12/13
7             ## Modified 2023/05/07
8             ## All rights reserved
9             ##
10             ##
11             ## This program is free software; you can redistribute it and/or modify it
12             ## under the same terms as Perl itself.
13             ##----------------------------------------------------------------------------
14             package HTML::Object::DOM::Document;
15             BEGIN
16             {
17 28     28   183 use strict;
  28         53  
  28         848  
18 28     28   135 use warnings;
  28         49  
  28         839  
19 28     28   167 use parent qw( HTML::Object::Document HTML::Object::DOM::Element );
  28         45  
  28         137  
20 28     28   2598 use vars qw( $VERSION );
  28         70  
  28         1596  
21 28     28   14899 use HTML::Object::ErrorEvent;
  28         76  
  28         617  
22 28     28   10184 use Scalar::Util ();
  28         70  
  28         471  
23 28     28   138 use Want;
  28         52  
  28         1499  
24 28     28   479 our $VERSION = 'v0.2.2';
25             };
26              
27 28     28   143 use strict;
  28         63  
  28         515  
28 28     28   138 use warnings;
  28         68  
  28         134298  
29              
30             sub init
31             {
32 51     51 1 4518 my $self = shift( @_ );
33 51         2834 $self->{_init_strict_use_sub} = 1;
34 51 50       437 $self->HTML::Object::Document::init( @_ ) || return( $self->pass_error );
35 51         258 $self->{onload} = undef;
36 51         175 $self->{onreadystatechange} = undef;
37 51         213 $self->{visibilitystate} = 'visible';
38 51         193 $self->{_xpath_eval} = undef;
39             # Nodes are special in the document. In other elements, nodes are the same as children
40             # But here no. There can be only 1 element: html, but one can add a doctype or comments
41             # comments added will be part of the children, but not the doctype. So
42             # $doc->children is always equal to 1, but
43             # $doc->childNodes->length would be equal to 2 (including the doctype)
44             # So our real array is nodes, i.e. what would otherwise be children for other elements
45             # $self->{nodes} is automatically created by the read-only method 'nodes'
46             # State of the document for document->open(), document->close()
47 51         185 $self->{_closed} = 1;
48 51         152 return( $self );
49             }
50              
51 1     1 1 3357 sub activeElement : lvalue { return( shift->_set_get_object_lvalue( 'activeelement', 'HTML::Object::DOM::Element', @_ ) ); }
52              
53             sub adoptNode
54             {
55 0     0 1 0 my $self = shift( @_ );
56 0   0     0 my $elem = shift( @_ ) || return( $self->error( "No element object was provided to adopt into our document." ) );
57 0 0 0     0 return( $self->error( "Element provided ($elem) is not a HTML::Object::Element object." ) ) if( !$self->_is_a( $elem, 'HTML::Object::Element' ) || $self->_is_a( $elem, 'HTML::Object::Collection' ) );
58 0 0       0 if( $elem->parent )
59             {
60 0         0 $elem->detach;
61             }
62 0         0 return( $elem );
63             }
64              
65             # Note: method append is different from HTML::Object::DOM::Element because we need to check what goes in
66             sub append
67             {
68 0     0 1 0 my $self = shift( @_ );
69 0 0       0 return( $self ) if( !scalar( @_ ) );
70             # If a HTML::Object::DOM::DocumentFragment object is provided, its children are
71             # copied to the list and its own children array is emptied.
72 0   0     0 my $list = $self->_check_list_of_nodes_or_text( @_ ) || return( $self->pass_error );
73 0         0 my $nodes = $self->nodes;
74 0 0       0 $self->reset(1) if( !$list->is_empty );
75             $list->foreach(sub
76             {
77 0     0   0 $_->parent( $self );
78 0         0 });
79 0         0 $nodes->push( $list->list );
80 0         0 return( $self );
81             }
82              
83             # Node: method appendChild is inherited
84              
85             sub as_string
86             {
87 2     2 1 1301 my $self = shift( @_ );
88 2         16 my $a = $self->new_array;
89             $self->nodes->foreach(sub
90             {
91 2     2   25 my $e = shift( @_ );
92 2         22 my $v = $e->as_string;
93 2 50       77 $a->push( defined( $v ) ? $v->scalar : $v );
94 2         49 });
95 2         301 return( $a->join( '' ) );
96             }
97              
98             sub body : lvalue { return( shift->_set_get_callback({
99             get => sub
100             {
101 13     13   5720 my $self = shift( @_ );
102 13   50     77 my $html = $self->documentElement ||
103             die( "Unable to find a top HTML tag" );
104 13         73 my $children = $html->children;
105 13         867 my $body;
106 13         60 foreach( @$children )
107             {
108 52 100       35386 if( $_->tag eq 'body' )
109             {
110 13         11732 $body = $_;
111             # End loop
112 13         30 last;
113             }
114             }
115             # $body may be undef, and that's ok. A Module::Generic::Null object will be returned instead
116 13         48 return( $body );
117             },
118             set => sub
119             {
120 0     0   0 my $self = shift( @_ );
121 0         0 my $e = shift( @_ );
122 0   0     0 my $html = $self->documentElement ||
123             die( "Unable to find a top HTML tag" );
124 0         0 my $children = $html->children;
125 0 0       0 if( !$self->_is_a( $e, 'HTML::Object::Element' ) )
126             {
127 0         0 die( "Element provided to set as new body element is not a HTML::Object::Element object." );
128             }
129            
130 0         0 my $body;
131 0         0 for( my $pos = 0; $pos < scalar( @$children ); $pos++ )
132             {
133 0         0 my $child = $children->[$pos];
134 0 0       0 if( $child->tag eq 'body' )
135             {
136 0         0 $body = $child;
137 0         0 $children->offset( $pos, 1, $e );
138             # End loop
139 0         0 last;
140             }
141             }
142            
143             # No body was found, amazingly enough; add it now
144 0 0       0 if( !defined( $body ) )
145             {
146 0         0 $children->push( $e );
147             }
148 0         0 return( $e );
149             }
150 13     13 1 26542 }, @_ ) ); }
151              
152 0     0 1 0 sub captureEvents { return( shift->defaultView->captureEvents( @_ ) ); }
153              
154 1     1 1 541 sub caretPositionFromPoint { return; }
155              
156 0     0 1 0 sub caretRangeFromPoint { return; }
157              
158             # read-only
159             # e.g.:
160             # <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
161             # <meta charset="utf-8" />
162             sub characterSet : lvalue
163             {
164 2     2 1 1466 my $self = shift( @_ );
165             # Get an Module::Generic::Array object
166 2   50     22 my $results = $self->find( 'meta' ) || return( $self->pass_error );
167 2         540 require Module::Generic::HeaderValue;
168 2         3300 foreach my $e ( $results->list )
169             {
170 2 100 66     25 if( $e->attributes->has( 'http-equiv' ) &&
    50 66        
171             $e->attributes->get( 'http-equiv' ) eq 'Content-Type' &&
172             $e->attributes->has( 'content' ) )
173             {
174 1         475 my $type = $e->attributes->get( 'content' );
175 1 50 33     475 next if( !defined( $type ) || !CORE::length( $type ) );
176 1         5 my $hv = Module::Generic::HeaderValue->new_from_header( $type );
177 1         6199 my $charset = $hv->param( 'charset' );
178 1   50     488 return( $charset // '' );
179             }
180             elsif( $e->attributes->has( 'charset' ) )
181             {
182 1   50     500 return( $e->attributes->get( 'charset' ) // '' );
183             }
184             }
185 0         0 return( '' );
186             }
187              
188             # Note: property childElementCount read-only inherited from HTML::Object::DOM::Element
189              
190             # Note: property children read-only
191             sub children
192             {
193 261     261 1 2499 my $self = shift( @_ );
194 261 50       932 if( @_ )
195             {
196 0         0 return( $self->_set_get_object_array_object( 'children', 'HTML::Object::Element', @_ ) );
197             }
198 261         1205 $self->_init_nodes;
199 261         1124 return( $self->_set_get_object_array_object( 'children', 'HTML::Object::Element' ) );
200             }
201              
202 0     0 1 0 sub childNodes : lvalue { return( shift->_set_get_array_as_object( 'nodes', @_ ) ); }
203              
204             # Note: property children read-only inherited
205              
206             # method cloneNode is inherited from HTML::Object::DOM::Node
207              
208 0     0 1 0 sub close { return( shift->{_closed} = 1 ); }
209              
210 1     1 1 616 sub compatMode : lvalue { return; }
211              
212             # read-only
213             # e.g.:
214             # <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
215             sub contentType
216             {
217 2     2 1 639 my $self = shift( @_ );
218 2   50     6 my $results = $self->find( 'meta' ) || return( $self->pass_error );
219 2         9 require Module::Generic::HeaderValue;
220 2         5 my $default = 'text/html';
221 2         6 foreach my $e ( $results->list )
222             {
223 2 50 66     11 if( $e->attributes->has( 'http-equiv' ) &&
      66        
224             $e->attributes->get( 'http-equiv' ) eq 'Content-Type' &&
225             $e->attributes->has( 'content' ) )
226             {
227 1         496 my $type = $e->attributes->get( 'content' );
228 1 50 33     526 next if( !defined( $type ) || !CORE::length( $type ) );
229 1         5 my $hv = Module::Generic::HeaderValue->new_from_header( $type );
230 1   33     5794 return( $hv->value->first // $default );
231             }
232             }
233 1         505 return( $default );
234             }
235              
236 2     2 1 1806 sub cookie : lvalue { return( shift->_set_get_lvalue( '_cookie', @_ ) ); }
237              
238             sub createAttribute
239             {
240 1     1 1 1199 my $self = shift( @_ );
241 1         2 my $name = shift( @_ );
242 1 50       5 $name = lc( $name ) if( defined( $name ) );
243 1 50       8 return( $self->error({
244             message => "The attribute provided \"$name\" contains illegal characters.",
245             class => 'HTML::Object::SyntaxError',
246             }) ) if( !$self->is_valid_attribute( $name ) );
247 1         506 require HTML::Object::DOM::Attribute;
248 1   50     12 my $att = HTML::Object::DOM::Attribute->new( $name, @_ ) ||
249             return( $self->pass_error( HTML::Object::DOM::Attribute->error ) );
250 1         7 return( $att );
251             }
252              
253 0     0 1 0 sub createAttributeNS { return; }
254              
255 0     0 1 0 sub createCDATASection { return; }
256              
257             # TODO Create pod: https://developer.mozilla.org/en-US/docs/Web/API/Document/createComment
258             sub createComment
259             {
260 0     0 1 0 my $self = shift( @_ );
261 0         0 my $data;
262 0 0       0 $data = join( '', @_ ) if( @_ );
263 0         0 return( $self->new_comment( value => $data ) );
264             }
265              
266             sub createDocumentFragment
267             {
268 1     1 1 4 my $self = shift( @_ );
269 1         799 require HTML::Object::DOM::DocumentFragment;
270 1   50     24 my $frag = HTML::Object::DOM::DocumentFragment->new( @_ ) ||
271             return( $self->pass_error( HTML::Object::DOM::DocumentFragment->error ) );
272 1         10 return( $frag );
273             }
274              
275             sub createElement
276             {
277 15     15 1 5906 my $self = shift( @_ );
278 15   50     67 my $tag = shift( @_ ) || return( $self->error( "No tag was provided to create an element." ) );
279 15         66 my $opts = $self->_get_args_as_hash( @_ );
280 15         694 my $p = HTML::Object::DOM->new;
281 15         157 my $def = $p->get_definition( $tag );
282             # Even if the tag does not exist, the default behaviour is to accept whatever was
283             # provided and assume it is a non-empty tag
284 15 50       56 if( !defined( $def ) )
285             {
286 0         0 $def =
287             {
288             is_empty => 0,
289             is_inline => 0,
290             };
291             }
292            
293 15         87 $opts->{debug} = $self->debug;
294 15         361 @$opts{qw( is_empty is_inline )} = @$def{qw( is_empty is_inline )};
295 15         47 $opts->{tag} = $tag;
296            
297 15         28 my $e;
298 15   100     59 $def->{class} //= '';
299 15 100       53 if( $def->{class} )
300             {
301 14         80 $e = $p->new_special( $def->{class} => $opts );
302             }
303             else
304             {
305 1         5 $e = $p->new_element( $opts );
306             }
307 15         165 $e->close;
308 15         943 return( $e );
309             }
310              
311 0     0 1 0 sub createElementNS { return; }
312              
313             # TODO: createEntityReference
314 0     0 1 0 sub createEntityReference { return; }
315              
316             # TODO createEvent https://developer.mozilla.org/en-US/docs/Web/API/Document/createEvent
317             sub createEvent
318             {
319 0     0 1 0 my $self = shift( @_ );
320 0   0     0 my $type = shift( @_ ) || return( $self->error({
321             message => 'No event type was provided',
322             class => 'HTML::Objct::SyntaxError',
323             }) );
324 0 0       0 $self->_load_class( 'HTML::Object::Event' ) || return( $self->pass_error );
325 0   0     0 my $evt = HTML::Object::Event->new( $type, @_ ) ||
326             return( $self->pass_error( HTML::Object::Event->error ) );
327 0         0 return( $evt );
328             }
329              
330             # TODO: createExpression
331             sub createExpression
332             {
333 0     0 1 0 my $self = shift( @_ );
334 0         0 my $eval;
335 0 0       0 unless( $eval = $self->{_xpath_eval} )
336             {
337 0 0       0 $self->_load_class( 'HTML::Object::DOM::XPathEvaluator' ) || return( $self->pass_error );
338 0   0     0 $self->{_xpath_eval} = $eval = HTML::Object::DOM::XPathEvaluator->new ||
339             return( $self->pass_error( HTML::Object::DOM::XPathEvaluator->error ) );
340             }
341 0         0 my $expr = $eval->createExpression( @_ );
342 0 0       0 return( $self->pass_error( $eval->error ) ) if( !defined( $expr ) );
343 0         0 return( $expr );
344             }
345              
346             # TODO: createNSResolver
347 0     0 1 0 sub createNSResolver { return; }
348              
349             # TODO: createNodeIterator
350             sub createNodeIterator
351             {
352 2     2 1 175 my $self = shift( @_ );
353 2 50       21 $self->_load_class( 'HTML::Object::DOM::NodeIterator' ) || return( $self->pass_error );
354 2         134 my $iterator = HTML::Object::DOM::NodeIterator->new( @_ );
355 2 50       20 return( $self->pass_error( HTML::Object::DOM::NodeIterator->error ) ) if( !defined( $iterator ) );
356 2         7 return( $iterator );
357             }
358              
359 0     0 1 0 sub createProcessingInstruction { return; }
360              
361             # TODO: createRange
362 0     0 1 0 sub createRange { return; }
363              
364             sub createTextNode
365             {
366 1     1 1 8 my $self = shift( @_ );
367 1 50       6 my $txt = @_ == 1 ? shift( @_ ) : join( '', @_ );
368 1 50       22 $self->_load_class( 'HTML::Object::DOM::Text' ) || return( $self->pass_error );
369 1   50     53 my $node = HTML::Object::DOM::Text->new( value => $txt ) ||
370             return( $self->pass_error( HTML::Object::DOM::Text->error ) );
371 1         19 return( $node );
372             }
373              
374 0     0 1 0 sub createTouch { return; }
375              
376 0     0 1 0 sub createTouchList { return; }
377              
378             sub createTreeWalker
379             {
380 8     8 1 543 my $self = shift( @_ );
381 8 50       54 $self->_load_class( 'HTML::Object::DOM::TreeWalker' ) || return( $self->pass_error );
382 8         437 my $crawler = HTML::Object::DOM::TreeWalker->new( @_ );
383 8 50       84 return( $self->pass_error( HTML::Object::DOM::TreeWalker->error ) ) if( !defined( $crawler ) );
384 8         54 return( $crawler );
385             }
386              
387 0     0 1 0 sub currentScript { return( shift->_set_get_object_lvalue( 'currentscript', 'HTML::Object::DOM::Element', @_ ) ); }
388              
389 52     52 1 1051 sub defaultView : lvalue { return( shift->_set_get_object_lvalue( 'defaultview', 'HTML::Object::DOM::Window', @_ ) ); }
390              
391 1     1 1 970 sub designMode : lvalue { return; }
392              
393 2     2 1 448 sub dir : lvalue { return( shift->_set_get_lvalue( '_dir' ) ); }
394              
395             # Note: property doctype read-only
396             sub doctype : lvalue
397             {
398 3     3 1 1219 my $self = shift( @_ );
399 3         23 return( $self->declaration );
400             }
401              
402             # Note: property documentElement read-only
403             sub documentElement : lvalue
404             {
405 14     14 1 678 my $self = shift( @_ );
406 14 50       60 if( @_ )
407             {
408 0 0       0 warnings::warn( "This property \"documentElement\" is read-only.\n" ) if( warnings::enabled( 'HTML::Object' ) );
409             }
410 14         29 my $html;
411             # It should be the first one, but let's not assume anything
412 14         61 my $children = $self->children;
413 14         1007 foreach( @$children )
414             {
415 42 100       25635 if( $_->tag eq 'html' )
416             {
417 14         12939 $html = $_;
418 14         38 last;
419             }
420             }
421 14 50 33     521 if( !$html && Want::want( 'OBJECT' ) )
422             {
423 0         0 require Module::Generic::Null;
424 0         0 return( Module::Generic::Null->new( wants => 'OBJECT' ) );
425             }
426 14         93 return( $html );
427             }
428              
429             # Note: property documentURI read-only
430 1     1 1 1144 sub documentURI : lvalue { return( shift->_set_get_uri( 'uri', @_ ) ); }
431              
432 0     0 1 0 sub elementFromPoint { return; }
433              
434 0     0 1 0 sub elementsFromPoint { return; }
435              
436             # Note: property read-only embeds
437             sub embeds
438             {
439 1     1 1 1146 my $self = shift( @_ );
440 1   50     11 my $results = $self->find( 'embed' ) || return( $self->pass_error );
441 1         8 return( $self->new_collection( $results ) );
442             }
443              
444 0     0 1 0 sub enableStyleSheetsForSet { return; }
445              
446             sub evaluate
447             {
448 0     0 1 0 my $self = shift( @_ );
449 0         0 my $eval;
450 0 0       0 unless( $eval = $self->{_xpath_eval} )
451             {
452 0 0       0 $self->_load_class( 'HTML::Object::DOM::XPathEvaluator' ) || return( $self->pass_error );
453 0   0     0 $self->{_xpath_eval} = $eval = HTML::Object::DOM::XPathEvaluator->new ||
454             return( $self->pass_error( HTML::Object::DOM::XPathEvaluator->error ) );
455             }
456 0         0 return( $eval->evaluate( @_ ) );
457             }
458              
459 0     0 1 0 sub execCommand { return; }
460              
461 0     0 1 0 sub exitPictureInPicture { return; }
462              
463 0     0 1 0 sub exitPointerLock { return; }
464              
465 1     1 1 33284 sub featurePolicy : lvalue { return; }
466              
467             # Note: firstChild returns its values from the nodes array, not the children one; is inherited
468              
469             # Note: method firstElementChild is inherited from HTML::Object::DOM::Element
470              
471             # Note: property read-only fonts
472 1     1 1 1192 sub fonts { return; }
473              
474             # Note: property read-only forms
475             sub forms
476             {
477 1     1 1 2 my $self = shift( @_ );
478 1   50     10 my $results = $self->find( 'form' ) || return( $self->pass_error );
479 1         7 return( $self->new_collection( $results ) );
480             }
481              
482 1     1 1 34430 sub fullscreenElement : lvalue { return; }
483              
484 0     0 1 0 sub getAnimations { return; }
485              
486 0     0 1 0 sub getBoxQuads { return; }
487              
488             sub getElementById
489             {
490 19     19 1 50921 my $self = shift( @_ );
491 19         63 my $id = shift( @_ );
492 19 50 33     159 return if( !defined( $id ) || !CORE::length( $id ) );
493 19         71 my $seen = {};
494 19         41 my $crawl;
495             $crawl = sub
496             {
497 500     500   671 my $elem = shift( @_ );
498 500         866 my $addr = Scalar::Util::refaddr( $elem );
499 500 50       1223 return if( CORE::exists( $seen->{ $addr } ) );
500             # Not a true element, such as text, comment
501 500 100 100     2115 return if( $elem->tag->substr( 0, 1 ) eq '_' && !$self->_is_a( $elem => 'HTML::Object::Document' ) );
502 197         135574 $seen->{ $addr }++;
503 197 100 100     3838 if( $elem->attributes->has( 'id' ) &&
504             $elem->attributes->get( 'id' ) eq $id )
505             {
506 19         12290 return( $elem );
507             }
508 178         110827 my $e;
509             $elem->children->foreach(sub
510             {
511 481         15984 my $this = shift( @_ );
512 481 100       1087 if( my $found = $crawl->( $this ) )
513             {
514 57         120 $e = $found;
515 57         144 return;
516             }
517 424         221903 return(1);
518 178         684 });
519 178         8376 return( $e );
520 19         135 };
521 19         64 return( $crawl->( $self ) );
522             }
523              
524             # Note: method getElementsByClassName is inherited from HTML::Object::DOM::Element
525              
526             sub getElementsByName
527             {
528 0     0 1 0 my $self = shift( @_ );
529 0         0 my $name = shift( @_ );
530 0 0 0     0 return( $self->error( "No value was provided for getElementsByName()" ) ) if( !defined( $name ) || !CORE::length( "$name" ) );
531 0   0     0 my $results = $self->look_down( name => $name ) || return( $self->pass_error );
532 0   0     0 my $list = $self->new_nodelist( $results ) || return( $self->pass_error );
533 0         0 return( $list );
534             }
535              
536             # Note: method getElementsByTagName is inherited from HTML::Object::DOM::Element
537              
538 0     0 1 0 sub getElementsByTagNameNS { return; }
539              
540 23     23 1 160 sub getRootNode { return( shift->root ); }
541              
542 0     0 1 0 sub getSelection { return; }
543              
544             # Note: method hasChildNodes is inherited
545              
546 0     0 1 0 sub hasFocus { return(1); }
547              
548 0     0 1 0 sub hasStorageAccess { return; }
549              
550             # Note: property head read-only
551             sub head : lvalue
552             {
553 2     2 1 1848 my $self = shift( @_ );
554 2   50     15 my $results = $self->find( 'head' ) || return( $self->pass_error );
555 2         12 my $head = $results->first;
556 2 50 33     161 if( !$head && want( 'OBJECT' ) )
557             {
558 0         0 require Module::Generic::Null;
559 0         0 rreturn( Module::Generic::Null->new( wants => 'OBJECT' ) );
560             }
561 2         8 return( $head );
562             }
563              
564             # Note: property hidden read-only
565 1     1 1 527 sub hidden : lvalue { return; }
566              
567             # Note: property images read-only
568             sub images : lvalue
569             {
570 1     1 1 3 my $self = shift( @_ );
571 1   50     5 my $results = $self->find( 'img' ) || return( $self->pass_error );
572 1         8 return( $self->new_collection( $results ) );
573             }
574              
575             # Note: property implementation read-only
576             sub implementation
577             {
578 1     1 1 34360 my $self = shift( @_ );
579 1 50       5 unless( $self->{_implementation} )
580             {
581 1 50       5 $self->_load_class( 'HTML::Object::DOM::Implementation' ) || return( $self->pass_error );
582 1   50     252 $self->{_implementation} = HTML::Object::DOM::Implementation->new( debug => $self->debug ) ||
583             return( $self->pass_error( HTML::Object::DOM::Implementation->error ) );
584             }
585 1         10 return( $self->{_implementation} );
586             }
587              
588 0     0 1 0 sub importNode { return( shift->adoptNode( @_ ) ); }
589              
590             # Note: method insertAfter is inherited
591              
592             # Note: method insertBefore is inherited
593              
594             # Note: property lastChild is inherited
595              
596             # Note: method lastElementChild is inherited from HTML::Object::DOM::Element
597              
598 1     1 1 1309 sub lastModified : lvalue { return( shift->_set_get_datetime( '_last_modified' ) ); }
599              
600             # Note: property links read-only
601             sub links : lvalue
602             {
603 1     1 1 354094 my $self = shift( @_ );
604 1   50     11 my $results = $self->find( 'a' ) || return( $self->pass_error );
605 1         6 return( $results );
606             }
607              
608 1     1 1 33807 sub location : lvalue { return( shift->_set_get_uri( 'uri', @_ ) ); }
609              
610 0     0 1 0 sub mozSetImageElement { return; }
611              
612             # Note: property mozSyntheticDocument
613 0     0 1 0 sub mozSyntheticDocument : lvalue { return( shift->_set_get_boolean( 'mozsyntheticdocument', @_ ) ); }
614              
615 0     0 1 0 sub nextSibling { return( shift->new_null ); }
616              
617             # See also children for its alter ego
618 36     36 1 130 sub nodes { return( shift->_init_nodes ); }
619              
620             # Note: Property
621             # Should be undef for document
622             # <https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeValue>
623 2     2 1 1120 sub nodeValue { return; }
624              
625             # Note: this is merely an alias to HTML::Object::DOM::Node->normalize
626 0     0 1 0 sub normalizeDocument { return( shift->normalize( @_ ) ); }
627              
628             # Note: Property
629 0     0 1 0 sub onabort : lvalue { return( shift->_set_get_on_signal( [qw( ABRT TERM INT )], @_ ) ); }
630              
631 0     0 1 0 sub onafterscriptexecute : lvalue { return( shift->on( 'afterscriptexecute', @_ ) ); }
632              
633 0     0 1 0 sub onbeforescriptexecute : lvalue { return( shift->on( 'beforescriptexecute', @_ ) ); }
634              
635 0     0 1 0 sub oncopy : lvalue { return( shift->on( 'copy', @_ ) ); }
636              
637 0     0 1 0 sub oncut : lvalue { return( shift->on( 'cut', @_ ) ); }
638              
639 0     0 1 0 sub onerror : lvalue { return( shift->_set_get_on_signal( [qw( __WARN__ )], @_ ) ); }
640              
641 0     0 1 0 sub onfullscreenchange : lvalue { return( shift->on( 'fullscreenchange', @_ ) ); }
642              
643 0     0 1 0 sub onfullscreenerror : lvalue { return( shift->on( 'fullscreenerror', @_ ) ); }
644              
645 48     48 1 540 sub onload : lvalue { return( shift->_set_get_code( 'onload', @_ ) ); }
646              
647 0     0 1 0 sub onpaste : lvalue { return( shift->on( 'paste', @_ ) ); }
648              
649             # sub onreadystatechange : lvalue { return( shift->_set_get_code( 'onreadystatechange', @_ ) ); }
650 139     139 1 1295 sub onreadystatechange : lvalue { return( shift->on( 'readystatechange', @_ ) ); }
651              
652 0     0 1 0 sub onscroll : lvalue { return( shift->on( 'scroll', @_ ) ); }
653              
654 0     0 1 0 sub onselectionchange : lvalue { return( shift->on( 'selectionchange', @_ ) ); }
655              
656 0     0 1 0 sub onvisibilitychange : lvalue { return( shift->on( 'visibilitychange', @_ ) ); }
657              
658 0     0 1 0 sub onwheel : lvalue { return( shift->on( 'wheel', @_ ) ); }
659              
660             sub open
661             {
662 0     0 1 0 my $self = shift( @_ );
663             # Already opened
664 0 0       0 return( $self ) if( !$self->{_closed} );
665 0   0     0 my $doc = $self->_list_to_nodes( q{<html><head><title></title></head><body></body></html>} ) ||
666             return( $self->pass_error );
667             # Remove the DTD
668 0         0 $self->declaration( undef );
669 0         0 my $html = $doc->children->first;
670 0 0       0 return( $self->error( "Cannot find the top <html> element in our own standard document for document->open!" ) ) if( !$html );
671 0 0       0 return( $self->error( "HTML top element found is not a <html> element" ) ) if( $html->tag ne 'html' );
672 0         0 $html->parent( $self );
673 0         0 $self->children->reset;
674 0         0 $self->children->push( $html );
675 0         0 $self->reset(1);
676 0         0 return( $self );
677             }
678              
679             # Note: property ownerDocument inherited from HTML::Object::DOM::Node
680              
681 0     0 1 0 sub parentElement { return( shift->new_null ); }
682              
683 2     2 1 69 sub parentNode { return( shift->new_null ); }
684              
685 1     1 1 9 sub pictureInPictureElement : lvalue { return( shift->_set_get_object_lvalue( 'pictureinpictureelement', 'HTML::Object::DOM::Element', @_ ) ); }
686              
687 1     1 1 1132 sub pictureInPictureEnabled : lvalue { return( shift->_set_get_boolean( 'pictureinpictureenabled', @_ ) ); }
688              
689             # Note: property read-only plugins
690 1     1 1 1061 sub plugins { return( shift->new_collection ); }
691              
692 1     1 1 6 sub pointerLockElement : lvalue { return( shift->_set_get_object_lvalue( 'pointerlockelement', 'HTML::Object::DOM::Element', @_ ) ); }
693              
694             sub prepend
695             {
696 0     0 1 0 my $self = shift( @_ );
697 0 0       0 return( $self ) if( !scalar( @_ ) );
698             # If a HTML::Object::DOM::DocumentFragment object is provided, its children are
699             # copied to the list and its own children array is emptied.
700 0   0     0 my $list = $self->_check_list_of_nodes_or_text( @_ ) || return( $self->pass_error );
701 0         0 my $nodes = $self->nodes;
702 0 0       0 $self->reset(1) if( !$list->is_empty );
703             $list->foreach(sub
704             {
705 0     0   0 $_->parent( $self );
706 0         0 });
707 0         0 $nodes->unshift( $list->list );
708 0         0 return( $self );
709             }
710              
711 0     0 1 0 sub previousSibling { return( shift->new_null ); }
712              
713 0     0 1 0 sub queryCommandEnabled { return(0); }
714              
715 0     0 1 0 sub queryCommandIndeterm { return(1); }
716              
717 0     0 1 0 sub queryCommandState { return(0); }
718              
719 0     0 1 0 sub queryCommandSupported { return(0); }
720              
721 0     0 1 0 sub queryCommandValue { return; }
722              
723             # Note: method querySelector is inherited from HTML::Object::DOM::Element
724              
725             # Note: method querySelectorAll is inherited from HTML::Object::DOM::Element
726              
727 142     142 1 3231 sub readyState : lvalue { return( shift->_set_get_lvalue( 'readyState', @_ ) ); }
728              
729 1     1 1 1266 sub referrer : lvalue { return( shift->_set_get_uri( 'referrer', @_ ) ); }
730              
731 0     0 1 0 sub releaseCapture { return( shift->defaultView->releaseCapture( @_ ) ); }
732              
733 0     0 1 0 sub releaseEvents { return( shift->defaultView->releaseEvents( @_ ) ); }
734              
735             # Note: method removeChild is inherited
736              
737             # Note: replaceChild is inherited
738              
739             # Note: the Document replaceChildren() method is different from the HTML::Object::DOM::Element replaceChildren()
740             sub replaceChildren
741             {
742 0     0 1 0 my $self = shift( @_ );
743 0 0       0 if( !scalar( @_ ) )
744             {
745 0         0 $self->nodes->reset;
746 0         0 return( $self );
747             }
748 0         0 my $list = $self->_get_from_list_of_elements_or_html( @_ );
749 0 0       0 return( $list ) if( $list->is_empty );
750 0         0 my $html;
751 0         0 foreach my $e ( @$list )
752             {
753 0 0       0 if( $self->_is_a( $e => 'HTML::Object::DOM::Element' ) )
754             {
755 0 0       0 if( $e->tag eq 'html' )
756             {
757 0 0       0 if( defined( $html ) )
758             {
759 0         0 return( $self->error({
760             message => "You have already provided an <html> element. You can only provide one.",
761             class => 'HTML::Object::HierarchyRequestError',
762             }) );
763             }
764             else
765             {
766 0         0 $html = $e;
767             }
768             }
769             else
770             {
771 0         0 return( $self->error({
772             message => "Only the <html> element is allowed inside the Document.",
773             class => 'HTML::Object::HierarchyRequestError',
774             }) );
775             }
776             }
777             }
778 0 0       0 return( $self->error({
779             message => "You have not provided any <html> element. A document must have at least one <html> element.",
780             class => 'HTML::Object::HierarchyRequestError',
781             }) ) if( !defined( $html ) );
782 0 0       0 return( $self ) if( $list->is_empty );
783 0         0 my $nodes = $self->nodes;
784 0         0 $nodes->reset;
785             $list->foreach(sub
786             {
787 0     0   0 $_->detach;
788 0         0 $_->parent( $self );
789 0         0 });
790 0         0 $nodes->push( $list->list );
791 0         0 $self->children->reset;
792 0         0 $self->children->push( $html );
793 0         0 return( $self );
794             }
795              
796 0     0 1 0 sub requestStorageAccess { return; }
797              
798             # Note: property scripts read-only
799             sub scripts : lvalue
800             {
801 1     1 1 1113 my $self = shift( @_ );
802 1   50     6 my $results = $self->find( 'script' ) || return( $self->pass_error );
803 1         5 return( $results );
804             }
805              
806             # Note: property scrollingElement read-only
807 1     1 1 33831 sub scrollingElement : lvalue { return( shift->_set_get_object_lvalue( 'scrollingelement', 'HTML::Object::DOM::Element', @_ ) ); }
808              
809 1     1 1 1047 sub string_value { return; }
810              
811             # Note: property styleSheets read-only
812             sub styleSheets : lvalue
813             {
814 1     1 1 2 my $self = shift( @_ );
815 1   50     5 my $list = $self->find( 'link[rel="stylesheet"]' ) || return( $self->pass_error );
816 1   50     6 my $results2 = $self->find( 'stylesheet' ) || return( $self->pass_error );
817 1         7 $list->merge( $results2 );
818 1         17 return( $list );
819             }
820              
821             # Note: property timeline read-only
822 1     1 1 34730 sub timeline : lvalue { return; }
823              
824             sub title : lvalue { return( shift->_set_get_callback({
825             get => sub
826             {
827 2     2   1002 my $self = shift( @_ );
828 2   50     19 my $results = $self->find( 'title' ) || die( $self->error );
829 2 50       7 return if( $results->is_empty );
830 2         31 return( $results->first->text );
831             },
832             set => sub
833             {
834 0     0   0 my $self = shift( @_ );
835 0         0 my $arg = shift( @_ );
836 0   0     0 my $results = $self->find( 'title' ) || die( $self->error );
837 0         0 my $e;
838 0 0       0 if( $results->is_empty )
839             {
840 0   0     0 my $head_results = $self->find( 'head' ) || die( $self->error );
841 0 0       0 if( $head_results->is_empty )
842             {
843 0         0 die( "Could not find the <head> tag to set as parent of the missing <title>. Something is seriously wrong." );
844             }
845 0         0 my $head = $head_results->first;
846 0         0 $e = $self->createElement( 'title' );
847 0         0 $e->close;
848 0         0 $head->push( $e );
849 0         0 $e->parent( $head );
850             }
851             else
852             {
853 0         0 $e = $results->first;
854             }
855            
856 0         0 return( $e->text( $arg ) );
857             },
858 2     2 1 31 }, @_ ) ); }
859              
860 1     1 1 1121 sub URL : lvalue { return( shift->_set_get_uri( 'uri', @_ ) ); }
861              
862             # Note: property visibilityState read-only
863 1     1 1 1143 sub visibilityState : lvalue { return( shift->_set_get_scalar_as_object( 'visibilitystate', @_ ) ); }
864              
865             sub write
866             {
867 0     0 1 0 my $self = shift( @_ );
868 0 0       0 if( $self->{_closed} )
869             {
870 0 0       0 $self->open() || return( $self->pass_error );
871             }
872 0   0     0 my $body = $self->body || return( $self->pass_error );
873             # Using _list_to_nodes from HTML::Object::DOM::Node
874 0         0 my $list = $self->_list_to_nodes( @_ );
875             $list->foreach(sub
876             {
877 0     0   0 $_->parent( $body );
878 0         0 });
879 0         0 $body->children->push( $list->list );
880 0         0 return( $list );
881             }
882              
883             sub writeln
884             {
885 0     0 1 0 my $self = shift( @_ );
886 0         0 my @args = @_;
887 0         0 for( @args )
888             {
889 0 0 0     0 next if( ref( $_ ) && !overload::Method( $_, '""' ) );
890 0 0       0 $_ .= "\n" unless( /\n$/ );
891             }
892 0         0 return( $self->write( @args ) );
893             }
894              
895             sub _check_list_of_nodes_or_text
896             {
897 0     0   0 my $self = shift( @_ );
898             # If a HTML::Object::DOM::DocumentFragment object is provided, its children are
899             # copied to the list and its own children array is emptied.
900 0         0 my $list = $self->_get_from_list_of_elements_or_html( @_ );
901 0 0       0 return( $list ) if( $list->is_empty );
902 0         0 my $html = $self->documentElement;
903 0         0 foreach my $e ( @$list )
904             {
905 0 0       0 if( $self->_is_a( $e => 'HTML::Object::DOM::Element' ) )
906             {
907             # There can be only one element in the document: the <html> element.
908 0 0       0 if( ref( $html ) )
    0          
909             {
910 0         0 return( $self->error({
911             message => "Cannot have more than one Element child of a Document and it must be an <html> element.",
912             class => 'HTML::Object::HierarchyRequestError',
913             }) );
914             }
915             elsif( $e->tag ne 'html' )
916             {
917 0         0 return( $self->error({
918             message => "Only the <html> element is allowed inside the Document.",
919             class => 'HTML::Object::HierarchyRequestError',
920             }) );
921             }
922             }
923             }
924 0         0 return( $list );
925             }
926              
927             sub _init_nodes
928             {
929 297     297   671 my $self = shift( @_ );
930 297 100       1195 unless( CORE::exists( $self->{nodes} ) )
931             {
932 48         446 my $children = $self->_set_get_object_array_object( 'children', 'HTML::Object::Element' );
933 48         9106 $self->{nodes} = $children;
934 48 0   0   525 my $html = $children->grep(sub{ $self->_is_a( $_ => 'HTML::Object::DOM::Node' ) && $_->tag eq 'html' })->first;
  0         0  
935             # We have a document with an <html> tag, we change the children to be an array with just the <html> element
936             # and we set nodes to be the array containing all top nodes.
937             # Maybe, we should change that structural design in the future to make it better
938 48 50       7947 if( $html )
939             {
940 0         0 my $new_children = $self->new_array( $html );
941 0         0 $self->_set_get_object_array_object( 'children', 'HTML::Object::Element', $new_children );
942             }
943             }
944 297         1431 return( $self->{nodes} );
945             }
946              
947             sub _set_get_on_signal : lvalue
948             {
949 0     0     my $self = shift( @_ );
950 0   0       my $sigs = shift( @_ ) || return;
951 0 0         return if( ref( $sigs ) ne 'ARRAY' );
952 0           my $has_arg = 0;
953 0           my $arg;
954 0 0         if( want( qw( LVALUE ASSIGN ) ) )
955             {
956 0           ( $arg ) = want( 'ASSIGN' );
957 0           $has_arg = 'assign';
958             }
959             else
960             {
961 0 0 0       @_ = () if( scalar( @_ ) == 1 && !defined( $_[0] ) );
962 0 0         if( @_ )
963             {
964 0           $arg = shift( @_ );
965 0           $has_arg++;
966             }
967             }
968             # To empty it, it must be set to an empty string
969 0 0 0       if( $has_arg && defined( $arg ) )
970             {
971 0           my $code = $arg;
972 0 0         if( ref( $code ) ne 'CODE' )
973             {
974 0           my $error = "Value provided is not a code reference (reference to a subroutine or anonymous subroutine).";
975 0 0         if( $has_arg eq 'assign' )
976             {
977 0           $self->error({ message => $error, class => 'HTML::Object::TypeError' });
978 0           return( $self->{__lvalue_error} = undef );
979             }
980 0 0         return( $self->error({ message => $error, class => 'HTML::Object::TypeError' }) ) if( want( 'LVALUE' ) );
981 0           Want::rreturn( $self->error({ message => $error, class => 'HTML::Object::TypeError' }) );
982             }
983 0           foreach my $sig ( @$sigs )
984             {
985             $SIG{ $sig } = sub
986             {
987 0     0     my $type;
988 0 0 0       if( $sig eq '__WARN__' || $sig eq '__DIE__' )
989             {
990 0           ( $type = $sig ) =~ s/^__([A-Z]+)__$/$1/;
991             }
992             else
993             {
994 0           $type = shift( @_ );
995             }
996 0           my $event = HTML::Object::ErrorEvent->new( $type, @_ );
997 0           $code->( $event );
998 0           };
999             }
1000             }
1001 0           my $dummy = 1;
1002 0 0         return( $dummy ) if( want( 'LVALUE' ) );
1003 0           Want::rreturn( $dummy );
1004             }
1005              
1006             1;
1007             # NOTE: POD
1008             __END__
1009              
1010             =encoding utf-8
1011              
1012             =head1 NAME
1013              
1014             HTML::Object::DOM::Document - HTML Object DOM Document Class
1015              
1016             =head1 SYNOPSIS
1017              
1018             use HTML::Object::DOM::Document;
1019             my $doc = HTML::Object::DOM::Document->new ||
1020             die( HTML::Object::DOM::Document->error, "\n" );
1021              
1022             =head1 VERSION
1023              
1024             v0.2.2
1025              
1026             =head1 DESCRIPTION
1027              
1028             This module represents an HTML document. It inherits from L<HTML::Object::Document> and L<HTML::Object::DOM::Element>
1029              
1030             It is the top object in the hierarchy and thus has no parent. It should contain only one child, the C<html> element, and has one associated L<element|HTML::Object::DOM::Element>, the L<doctype|/doctype>, which can also be accessed with L</declaration>
1031              
1032             =head1 INHERITANCE
1033              
1034             +------------------------+ +---------------------------+ +-------------------------+ +----------------------------+ +-----------------------------+
1035             | HTML::Object::Element | --> | HTML::Object::EventTarget | --> | HTML::Object::DOM::Node | --> | HTML::Object::DOM::Element | --> | HTML::Object::DOM::Document |
1036             +------------------------+ +---------------------------+ +-------------------------+ +----------------------------+ +-----------------------------+
1037             | ^
1038             | |
1039             v |
1040             +------------------------+ |
1041             | HTML::Object::Document | -----------------------------------------------------------------------------------------------------------+
1042             +------------------------+
1043              
1044             =head1 PROPERTIES
1045              
1046             =head2 activeElement
1047              
1048             Normally this returns C<undef> under perl, but you can set it to whatever L<element object|HTML::Object::DOM::Element> you want.
1049              
1050             Under JavaScript, this returns the L<element|HTML::Object::DOM::Element> that currently has focus.
1051              
1052             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement>
1053              
1054             =head2 body
1055              
1056             Returns the C<body> L<node object|HTML::Object::Element> of the current document.
1057              
1058             Example:
1059              
1060             # Given this HTML: <body id="oldBodyElement"></body>
1061             say($doc->body->id); # "oldBodyElement"
1062              
1063             my $aNewBodyElement = $doc->createElement("body");
1064              
1065             $aNewBodyElement->id = "newBodyElement";
1066             $doc->body = $aNewBodyElement;
1067             say($doc->body->id); # "newBodyElement"
1068              
1069             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/body>
1070              
1071             =head2 characterSet
1072              
1073             This is read-only.
1074              
1075             Returns the character set being used by the document. This is always C<utf-8>
1076              
1077             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/characterSet>
1078              
1079             =head2 childElementCount
1080              
1081             This is read-only.
1082              
1083             Returns the number of child elements of the current document. This being the top document, it typically contains only 1 element, the C<<html>> tag.
1084              
1085             The total number of children is not the same as the number of child nodes.
1086              
1087             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/childElementCount>
1088              
1089             =head2 children
1090              
1091             This is read-only.
1092              
1093             Returns the child elements of the current document, as an L<array object|Module::Generic::Array>.
1094              
1095             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/children>
1096              
1097             =head2 compatMode
1098              
1099             Returns C<undef> since this is not relevant under perl.
1100              
1101             Normally, it would indicate whether the document is rendered in quirks or strict mode.
1102              
1103             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/compatMode>
1104              
1105             =head2 contentType
1106              
1107             This is read-only.
1108              
1109             Returns the Content-Type from the MIME Header of the current document.
1110              
1111             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/contentType>
1112              
1113             =head2 cookie
1114              
1115             Set or get a semicolon-separated list of the cookies for that document or sets a single cookie.
1116              
1117             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/cookie>
1118              
1119             =head2 currentScript
1120              
1121             Under perl, this does not nor return do anything special, but you can set yourself an L<HTML::Object::DOM::Element>.
1122              
1123             Normally, under JavaScript, this returns the C<currentScript> property returns the <script> element whose script is currently being processed and is not a JavaScript module.
1124              
1125             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/currentScript>
1126              
1127             =head2 defaultView
1128              
1129             This returns a reference to the L<window object|HTML::Object::DOM::Window>.
1130              
1131             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/defaultView>
1132              
1133             =head2 designMode
1134              
1135             This always returns true under perl.
1136              
1137             Under the web, with JavaScript, this would get/set the ability to edit the whole document.
1138              
1139             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/designMode>
1140              
1141             =head2 dir
1142              
1143             Get or set directionality (rtl/ltr) of the document.
1144              
1145             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/dir>
1146              
1147             =head2 doctype
1148              
1149             This is read-only.
1150              
1151             Returns the Document Type Definition (DTD) L<object|HTML::Object::Element> of the current document.
1152              
1153             Example:
1154              
1155             my $doctypeObj = $doc->doctype;
1156              
1157             say(
1158             "doctype->name: " . $doctypeObj->name . "\n" +
1159             "doctype->internalSubset: " . $doctypeObj->internalSubset . "\n" +
1160             "doctype->publicId: " . $doctypeObj->publicId . "\n" +
1161             "doctype->systemId: " . $doctypeObj->systemId
1162             );
1163              
1164             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/doctype>
1165              
1166             =head2 documentElement
1167              
1168             This is read-only.
1169              
1170             Returns the L<element|HTML::Object::DOM::Element> that is a direct child of the document. For HTML documents, this is normally the L<HTML Element|HTML::Object::Element> object representing the document's C<<html>> element.
1171              
1172             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/documentElement>
1173              
1174             =head2 documentURI
1175              
1176             Set or get the document location as a string, if any.
1177              
1178             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/documentURI>
1179              
1180             =head2 embeds
1181              
1182             This is read-only.
1183              
1184             Returns a list, as an L<html collection object|HTML::Object::DOM::Collection>, of the embedded <embed> elements within the current document.
1185              
1186             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/embeds>
1187              
1188             =head2 featurePolicy
1189              
1190             Returns C<undef> since this is not relevant under perl.
1191              
1192             Normally, under JavaScript, this would return the FeaturePolicy interface which provides a simple API for introspecting the feature policies applied to a specific document.
1193              
1194             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/featurePolicy>
1195              
1196             =head2 firstElementChild
1197              
1198             This is read-only.
1199              
1200             Returns the first child L<element|HTML::Object::DOM::Element> of the current document.
1201              
1202             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/firstElementChild>
1203              
1204             =head2 fonts
1205              
1206             Returns C<undef> since this is not relevant under perl.
1207              
1208             Normally, it would return the C<FontFaceSet> interface of the current document.
1209              
1210             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/fonts>
1211              
1212             =head2 forms
1213              
1214             This is read-only.
1215              
1216             Returns a list, as an L<html collection object|HTML::Object::DOM::Collection>, of the <form> elements within the current document.
1217              
1218             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/forms>
1219              
1220             =head2 fullscreenElement
1221              
1222             Returns C<undef> since this is not relevant under perl.
1223              
1224             Normally, it would return the element that is currently in full screen mode for this document.
1225              
1226             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/fullscreenElement>
1227              
1228             =head2 head
1229              
1230             This is read-only.
1231              
1232             Returns the L<<head> element|HTML::Object::DOM::Head> of the current document, or C<undef> if there is none.
1233              
1234             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/head>
1235              
1236             =head2 hidden
1237              
1238             Returns C<undef> since this is not relevant under perl.
1239              
1240             Normally, it would return a boolean value indicating if the page is considered hidden or not.
1241              
1242             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/hidden>
1243              
1244             =head2 images
1245              
1246             This is read-only.
1247              
1248             Returns a list, as an L<html collection object|HTML::Object::DOM::Collection>, of the images in the current document.
1249              
1250             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/images>
1251              
1252             =head2 implementation
1253              
1254             This returns the L<DOM implementation object|HTML::Object::DOM::Implementation> associated with the current document.
1255              
1256             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/implementation>
1257              
1258             =head2 lastElementChild
1259              
1260             This is read-only.
1261              
1262             Returns the last child L<element|HTML::Object::DOM::Element> of the current document, which is the root <html> element, the only child of the document.
1263              
1264             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/lastElementChild>
1265              
1266             =head2 lastModified
1267              
1268             This is read-only.
1269              
1270             Returns the date on which the document was last modified, if any, as a L<DateTime> object.
1271              
1272             This value exists if the document was read from a file, and it would contain the file last modification time.
1273              
1274             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/lastModified>
1275              
1276             =head2 links
1277              
1278             This is read-only.
1279              
1280             Returns a list, as an L<html collection object|HTML::Object::DOM::Collection>, of all the hyperlinks in the document.
1281              
1282             Example:
1283              
1284             my $links = $doc->$links;
1285             for( my $i = 0; $i < $links->length; $i++ )
1286             {
1287             my $linkHref = $doc->createTextNode( $links->[$i]->href );
1288             my $lineBreak = $doc->createElement("br");
1289             $doc->body->appendChild( $linkHref );
1290             $doc->body->appendChild( $lineBreak );
1291             }
1292              
1293             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/links>
1294              
1295             =head2 location
1296              
1297             Set or get the URI of the current document. This is the same as L</documentURI>
1298              
1299             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/location>
1300              
1301             =head2 mozSyntheticDocument
1302              
1303             Normally this is returns C<undef> under perl, byt you can set whatever boolean value you want.
1304              
1305             Under JavaScript, this returns a boolean that is true only if this document is synthetic, such as a standalone image, video, audio file, or the like.
1306              
1307             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/mozSyntheticDocument>
1308              
1309             =head2 nodeValue
1310              
1311             This returns or sets the value of the current node.
1312              
1313             For document, element or collection, this returns C<undef> and for attribute, text or comment, this returns the objct value.
1314              
1315             See L<for more information|https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeValue>
1316              
1317             =head2 ownerDocument
1318              
1319             Read-only. This always returns C<undef> since this is the top element. This is inherited from L<HTML::Object::DOM::Node>
1320              
1321             =head2 pictureInPictureElement
1322              
1323             Normally this returns C<undef> under perl, but you can set whatever L<element|HTML::Object::DOM::Element> object you want.
1324              
1325             Under JavaScript, this returns C<undef> since this is not relevant under perl.
1326              
1327             Normally, under JavaScript, this would return the Element currently being presented in picture-in-picture mode in this document.
1328              
1329             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/pictureInPictureElement>
1330              
1331             =head2 pictureInPictureEnabled
1332              
1333             Normally this returns C<undef> under perl, but you can set whatever boolean value you want.
1334              
1335             Under JavaScript, this would return true if the picture-in-picture feature is enabled, and false otherwise.
1336              
1337             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/pictureInPictureEnabled>
1338              
1339             =head2 plugins
1340              
1341             Returns always an empty L<collection object|HTML::Object::DOM::Collection> since this is not relevant under perl.
1342              
1343             Normally, under JavaScript, this would return a list, as a collection, of the available plugins.
1344              
1345             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/plugins>
1346              
1347             =head2 pointerLockElement
1348              
1349             Normally this returns C<undef> under perl, but you can set whatever L<element|HTML::Object::DOM::Element> object you want.
1350              
1351             Under JavaScript, this would return the element set as the target for mouse events while the pointer is locked. null if lock is pending, pointer is unlocked, or if the target is in another document.
1352              
1353             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/pointerLockElement>
1354              
1355             =head2 readyState
1356              
1357             This is read-only.
1358              
1359             Returns loading status of the document. This always returns a true value.
1360              
1361             The readyState of a document can be one of following:
1362              
1363             =over 4
1364              
1365             =item B<loading>
1366              
1367             The document is still loading.
1368              
1369             =item B<interactive>
1370              
1371             The document has finished loading and the document has been parsed.
1372              
1373             There is actually no distinction with the following C<complete> state.
1374              
1375             =item B<complete>
1376              
1377             The document and all its resources have finished loading. The state indicates that the load event is about to fire.
1378              
1379             This is actually the same state as C<interactive>
1380              
1381             =back
1382              
1383             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState>
1384              
1385             =head2 referrer
1386              
1387             Set or get the URI of the page that linked to this page.
1388              
1389             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/referrer>
1390              
1391             =head2 scripts
1392              
1393             This is read-only.
1394              
1395             Returns all the L<<script> elements|HTML::Object::DOM::Element::Script> on the document, as a L<collection object|HTML::Object::DOM::Collection>.
1396              
1397             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/scripts>
1398              
1399             =head2 scrollingElement
1400              
1401             Although this is meaningless under perl, you can set or get an L<element object|HTML::Object::DOM::Element> that scrolls the document.
1402              
1403             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/scrollingElement>
1404              
1405             =head2 styleSheets
1406              
1407             This is read-only.
1408              
1409             Returns a list, as an L<array object|Module::Generic::Array>, of L<CSS StyleSheet element objects|HTML::Object::Element> for stylesheets explicitly linked into, or embedded in a document.
1410              
1411             Contrary to the original JavaScript equivalent, this does not return C<CSSStyleSheet> objects, because it would be potentially heavy to parse each css in C<link> and C<style> tags. You could do this yourself by using L<CSS::Object> and looping through each L<element object|HTML::Object::Element> returned. For example:
1412              
1413             $doc->styleSheets->foreach(sub
1414             {
1415             my $e = shift( @_ );
1416             if( $e->tag eq 'link' )
1417             {
1418             my $resp = $ua->get( $e->attr( 'href' ) );
1419             die( $resp->message ) if( $resp->is_error );
1420             my $style = $resp->decoded_content;
1421             my $css = CSS::Object->new;
1422             $css->read_string( $style );
1423             $css->rules->foreach(sub
1424             {
1425             my $rule = shift( @_ );
1426             # more processing
1427             });
1428             }
1429             elsif( $e->tag eq 'style' )
1430             {
1431             my $css = CSS::Object->new;
1432             $css->read_string( $e->text );
1433             $css->rules->foreach(sub
1434             {
1435             my $rule = shift( @_ );
1436             # more processing
1437             });
1438             }
1439             });
1440              
1441             or you can use L<HTML::Object::XQuery/find> with a xpath selector, such as:
1442              
1443             use HTML::Object::XQuery; # Load jQuery style query functions
1444             # $doc is the HTML::Object::Document returned by HTML::Object->parse
1445             my $collection = $doc->find( 'link[rel="https://example.org/css/main.css"]' ) ||
1446             die( $doc->error );
1447             $collection->children->foreach(sub
1448             {
1449             # more processing
1450             });
1451              
1452             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/styleSheets>
1453              
1454             =head2 timeline
1455              
1456             Returns C<undef> since this is not relevant under perl.
1457              
1458             Normally, under JavaScript, this would return timeline as a special instance of DocumentTimeline that is automatically created on page load.
1459              
1460             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/timeline>
1461              
1462             =head2 title
1463              
1464             Set or get the title of the current document.
1465              
1466             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/title>
1467              
1468             =head2 URL
1469              
1470             Set or get the document location as a string.
1471              
1472             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/URL>
1473              
1474             =head2 visibilityState
1475              
1476             Normally this returns C<undef> under perl, but you can set whatever string value you want. This returns a L<scalar object|Module::Generic::Scalar>
1477              
1478             Under JavaScript, this would return a string denoting the visibility state of the document. Possible values are visible, hidden, prerender, and unloaded.
1479              
1480             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilityState>
1481              
1482             =head1 METHODS
1483              
1484             =head2 adoptNode
1485              
1486             L</adoptNode> transfers a L<node|HTML::Object::Element> from another document into the method's L<document|HTML::Object::Document>. The adopted L<node|HTML::Object::Element> and its subtree is removed from its original document (if any), and its ownerDocument is changed to the current document. The L<node|HTML::Object::Element> can then be inserted into the current L<document|HTML::Object::Document>.
1487              
1488             Before they can be inserted into the current document, nodes from external documents should either be:
1489              
1490             =over 4
1491              
1492             =item * cloned using L</importNode>; or
1493              
1494             =item * adopted using L</adoptNode>.
1495              
1496             =back
1497              
1498             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/adoptNode>
1499              
1500             =head2 append
1501              
1502             Inserts a set of Node objects or string objects after the last child of the document.
1503              
1504             This is inherited from L<HTML::Object::DOM::Element>
1505              
1506             Example:
1507              
1508             my $html = $doc->createElement( 'html' );
1509             $doc->append( $html );
1510             # HierarchyRequestError: The operation would yield an incorrect node tree.
1511              
1512             # Also
1513              
1514             my $doc = HTML::Object::DOM::Document->new;
1515             my $html = $doc->createElement( 'html');
1516             $doc->append( $html );
1517              
1518             $doc->children; # HTMLCollection [<html>]
1519              
1520             =head2 appendChild
1521              
1522             Provided with one or more nodes and this will add them to the list of this document's children.
1523              
1524             =head2 as_string
1525              
1526             Returns a string representation of this document and all its hierarchy.
1527              
1528             =head2 captureEvents
1529              
1530             See L<HTML::Object::DOM::Window/captureEvents>.
1531              
1532             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/captureEvents>
1533              
1534             =head2 caretRangeFromPoint
1535              
1536             Always returns C<undef> under perl.
1537              
1538             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/caretRangeFromPoint>
1539              
1540             =head2 caretPositionFromPoint
1541              
1542             Returns C<undef> since this is not relevant under perl.
1543              
1544             Normally, under JavaScript, this would return a CaretPosition object containing the DOM node containing the caret, and caret's character offset within that node.
1545              
1546             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/caretPositionFromPoint>
1547              
1548             =head2 childNodes
1549              
1550             Returns an L<array object|Module::Generic::Array> of the document child nodes.
1551              
1552             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes>
1553              
1554             =head2 close
1555              
1556             The C<close()> method finishes writing to a document, opened with L</open>.
1557              
1558             Example:
1559              
1560             # Open a document to write to it
1561             $doc->open();
1562              
1563             # Write the content of the document
1564             $doc->write("<p>The one and only content.</p>");
1565              
1566             # Close the document
1567             $doc->close();
1568              
1569             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/close>
1570              
1571             =head2 contentType
1572              
1573             =head2 createAttribute
1574              
1575             Provided with an argument and this creates a new L<attribute object|HTML::Object::Attribute> and returns it.
1576              
1577             The attribute name is converted to lowercase.
1578              
1579             Example:
1580              
1581             my $node = $doc->getElementById( 'div1' );
1582             my $a = $doc->createAttribute( 'my_attrib' );
1583             $a->value = 'newVal';
1584             $node->setAttributeNode( $a );
1585             say( $node->getAttribute( 'my_attrib' ) ); # "newVal"
1586              
1587             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createAttribute>
1588              
1589             =head2 createAttributeNS
1590              
1591             Returns C<undef> since this is not relevant under perl.
1592              
1593             Normally, under JavaScript, this would create a new attribute node in a given namespace and returns it.
1594              
1595             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createAttributeNS>
1596              
1597             =head2 createCDATASection
1598              
1599             Returns C<undef> since this is not relevant under perl.
1600              
1601             Normally, under JavaScript, this would create a new CDATA node and returns it.
1602              
1603             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createCDATASection>
1604              
1605             =head2 createComment
1606              
1607             Creates a new comment node and returns it.
1608              
1609             Example:
1610              
1611             my $comment = $doc->createComment( 'This is a not-so-secret comment in your document' );
1612             $doc->getElementsByTagName( 'div' )->[0]->appendChild( $comment );
1613             say( $doc->as_string );
1614             # <div><!--This is a not-so-secret $comment in your document--></div>
1615              
1616             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createComment>
1617              
1618             =head2 createDocumentFragment
1619              
1620             This create a new L<HTML::Object::DOM::DocumentFragment> object, passing its C<new()> constructor whatever argument was provided.
1621              
1622             It returns the newly instantiated object.
1623              
1624             L<Document fragments|HTML::Object::DOM::DocumentFragment> are L<DOM Node|HTML::Object::DOM::Node> objects which are never part of the main L<DOM tree|HTML::Object::DOM::Document>. The usual use case is to create the document fragment, append elements to the document fragment and then append the document fragment to the L<DOM tree|HTML::Object::DOM::Document>. In the L<DOM tree|HTML::Object::DOM::Document>, the document fragment is replaced by all its children.
1625              
1626             Since the L<document fragment|HTML::Object::DOM::DocumentFragment> is not part of the main L<DOM tree|HTML::Object::DOM::Document>, appending children to it does not affect the main tree.
1627              
1628             Example:
1629              
1630             <ul id="ul"></ul>
1631              
1632             use Module::Generic::Array;
1633             my $element = $doc->getElementById('ul'); # assuming ul exists
1634             my $fragment = $doc->createDocumentFragment();
1635             my $browsers = Module::Generic::Array->new( ['Firefox', 'Chrome', 'Opera',
1636             'Safari', 'Internet Explorer'] );
1637              
1638             $browsers->foreach(sub
1639             {
1640             my $browser = shift( @_ );
1641             my $li = $doc->createElement('li');
1642             $li->textContent = $browser;
1643             $fragment->appendChild( $li );
1644             });
1645              
1646             $element->appendChild( $fragment );
1647              
1648             would yield:
1649              
1650             =over 4
1651              
1652             =item * Firefox
1653              
1654             =item * Chrome
1655              
1656             =item * Opera
1657              
1658             =item * Safari
1659              
1660             =item * Internet Explorer
1661              
1662             =back
1663              
1664             See L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createDocumentFragment>
1665              
1666             =head2 createElement
1667              
1668             Provided with a tag name and this creates a new L<HTML::Object::Element> object that is returned.
1669              
1670             This methods sets an L<error|Module::Generic/error> and returns C<undef> upon error.
1671              
1672             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement>
1673              
1674             =head2 createElementNS
1675              
1676             Returns C<undef> since this is not relevant under perl.
1677              
1678             Normally, under JavaScript, this would create a new element with the given tag name and namespace URI.
1679              
1680             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createElementNS>
1681              
1682             =head2 createEntityReference
1683              
1684             Returns C<undef> since this is not relevant for HTML document. This is used for XML.
1685              
1686             This was used to create a new entity reference object and returns it.
1687              
1688             Example:
1689              
1690             $doc->createEntityReference( '&amp' ); # &
1691              
1692             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createEntityReference>
1693              
1694             =head2 createEvent
1695              
1696             Creates an event object, passing it whatever arguments were provided, and returns it.
1697              
1698             Example:
1699              
1700             my $event = $doc->createEvent( $type );
1701              
1702             # Create the $event.
1703             my $event = $doc->createEvent( 'click' );
1704              
1705             # Define that the event name is 'build'.
1706             $event->initEvent( build => { bubbles => 1 });
1707              
1708             # Listen for the $event.
1709             $elem->addEventListener( build => sub
1710             {
1711             # e->target matches elem
1712             }, { capture => 0 });
1713              
1714             # Target can be any Element or other EventTarget.
1715             $elem->dispatchEvent( $event );
1716              
1717             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createEvent>
1718              
1719             =head2 createExpression
1720              
1721             Compiles an L<HTML::Object::XPath::Expr> which can then be used for (repeated) evaluations. It returns a L<HTML::Object::DOM::XPathResult> object.
1722              
1723             Example:
1724              
1725             my $xpathExpr = $doc->createExpression( $xpathText );
1726             my $result = $xpathExpr->evaluate( $contextNode );
1727              
1728             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createExpression>
1729              
1730             =head2 createNSResolver
1731              
1732             This always returns C<undef> as XML is not used in L<HTML::Object>
1733              
1734             Normally, under JavaScript, this creates an C<XPathNSResolver> object.
1735              
1736             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createNSResolver>
1737              
1738             =head2 createNodeIterator
1739              
1740             Creates a L<HTML::Object::DOM::NodeIterator> object.
1741              
1742             Example:
1743              
1744             use Module::Generic::Array;
1745             my $nodeIterator = $doc->createNodeIterator(
1746             $doc->body,
1747             NodeFilter->SHOW_ELEMENT,
1748             {
1749             sub acceptNode
1750             {
1751             my $node = shift( @_ );
1752             return( $node->nodeName->toLowerCase() == 'p' ? NodeFilter->FILTER_ACCEPT : NodeFilter->FILTER_REJECT;
1753             }
1754             }
1755             );
1756             my $pars = Module::Generic::Array->new;
1757             my $currentNode;
1758              
1759             while( $currentNode = $nodeIterator->nextNode() )
1760             {
1761             $pars->push( $currentNode );
1762             }
1763              
1764             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createNodeIterator>
1765              
1766             =head2 createProcessingInstruction
1767              
1768             Creates a new C<ProcessingInstruction> object.
1769              
1770             Example:
1771              
1772             my $doc = HTML::Object::DOM->new->parseFromString('<foo />', 'application/xml');
1773             my $pi = $doc->createProcessingInstruction('xml-stylesheet', 'href="mycss->css" type="text/css"');
1774              
1775             $doc->insertBefore($pi, $doc->firstChild);
1776              
1777             say( $doc->as_string );
1778             # Displays: <?xml-stylesheet href="mycss->css" type="text/css"?><foo/>
1779              
1780             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createProcessingInstruction>
1781              
1782             =head2 createRange
1783              
1784             This always returns C<undef> under perl.
1785              
1786             Normally, under JavaScript, this creates a C<Range> object.
1787              
1788             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createRange>
1789              
1790             =head2 createTextNode
1791              
1792             Provided with a text, either as a string, or as a list of strings, and this creates a text node.
1793              
1794             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createTextNode>
1795              
1796             =head2 createTouch
1797              
1798             This always returns C<undef> under perl.
1799              
1800             Normally, under JavaScript, this creates a Touch object.
1801              
1802             Also, this feature is deprecated.
1803              
1804             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createTouch>
1805              
1806             =head2 createTouchList
1807              
1808             This always returns C<undef> under perl.
1809              
1810             Normally, under JavaScript, this creates a C<TouchList> object.
1811              
1812             Also, this feature is deprecated.
1813              
1814             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createTouchList>
1815              
1816             =head2 createTreeWalker
1817              
1818             Creates a C<TreeWalker> object.
1819              
1820             Example:
1821              
1822             use HTML::Object::DOM::NodeFilter qw( :all );
1823             my $treeWalker = $doc->createTreeWalker(
1824             $doc->body,
1825             SHOW_ELEMENT,
1826             sub{ return( FILTER_ACCEPT ); },
1827             );
1828              
1829             my $nodeList = Module::Generic::Array->new;
1830             my $currentNode = $treeWalker->currentNode;
1831              
1832             while( $currentNode )
1833             {
1834             $nodeList->push( $currentNode );
1835             $currentNode = $treeWalker->nextNode();
1836             }
1837              
1838             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/createTreeWalker>
1839              
1840             =head2 elementFromPoint
1841              
1842             This always returns C<undef> under perl.
1843              
1844             Normally, under JavaScript, this returns the topmost element at the specified coordinates.
1845              
1846             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/elementFromPoint>
1847              
1848             =head2 elementsFromPoint
1849              
1850             This always returns C<undef> under perl.
1851              
1852             Normally, under JavaScript, this returns an array of all elements at the specified coordinates.
1853              
1854             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/elementsFromPoint>
1855              
1856             =head2 enableStyleSheetsForSet
1857              
1858             This always returns C<undef> under perl.
1859              
1860             Normally, under JavaScript, this enables the style sheets for the specified style sheet set.
1861              
1862             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/enableStyleSheetsForSet>
1863              
1864             =head2 evaluate
1865              
1866             Evaluates an L<XPath|HTML::Object::XPath> expression.
1867              
1868             Example:
1869              
1870             my $xpathResult = $doc->evaluate(
1871             $xpathExpression,
1872             $contextNode
1873             );
1874              
1875             my $headings = $doc->evaluate( "/html/body//h2", $document );
1876             # Search the document for all h2 elements.
1877             # The result will likely be an unordered node iterator.
1878             my $thisHeading = $headings->iterateNext();
1879             my $alertText = "Level 2 $headings in this document are:\n";
1880             while( $thisHeading )
1881             {
1882             $alertText .= $thisHeading->textContent . "\n";
1883             $thisHeading = $headings->iterateNext();
1884             }
1885             say( $alertText ); # print the text of all h2 elements
1886              
1887             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/evaluate>
1888              
1889             =head2 execCommand
1890              
1891             This does absolutely nothing and always returns C<undef>.
1892              
1893             This is actually a deprecated feature of the web API.
1894              
1895             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand>
1896              
1897             =head2 exitPictureInPicture
1898              
1899             This always returns C<undef> under perl.
1900              
1901             Normally, under JavaScript, this removes the video from the floating picture-in-picture window back to its original container.
1902              
1903             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/exitPictureInPicture>
1904              
1905             =head2 exitPointerLock
1906              
1907             This always returns C<undef> under perl.
1908              
1909             Normally, under JavaScript, this releases the pointer lock.
1910              
1911             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/exitPointerLock>
1912              
1913             =head2 firstChild
1914              
1915             Returns the first child from the document list of nodes.
1916              
1917             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Node/firstChild>
1918              
1919             =head2 firstElementChild
1920              
1921             =head2 getElementById
1922              
1923             Provided with an element C<id>, and this method returns the corresponding L<element object|HTML::Object::Element>.
1924              
1925             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById>
1926              
1927             =head2 getAnimations
1928              
1929             This always returns C<undef> under perl.
1930              
1931             Normally, under JavaScript, this returns an array of all Animation objects currently in effect, whose target elements are descendants of the document.
1932              
1933             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/getAnimations>
1934              
1935             =head2 getBoxQuads
1936              
1937             This always returns C<undef> under perl.
1938              
1939             Normally, under JavaScript, this returns a list of C<DOMQuad> objects representing the CSS fragments of the node.
1940              
1941             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/getBoxQuads>
1942              
1943             =head2 getElementById
1944              
1945             Provided with a string and this returns an element object whose C<id> attribute matches the string specified.
1946              
1947             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementById>
1948              
1949             =head2 getElementsByClassName
1950              
1951             Returns a list of elements with the given class name.
1952              
1953             Example:
1954              
1955             <span class="orange fruit">Orange Fruit</span>
1956             <span class="orange juice">Orange Juice</span>
1957             <span class="apple juice">Apple Juice</span>
1958             <span class="foo bar">Something Random</span>
1959             <textarea id="resultArea" style="width:98%;height:7em"></textarea>
1960              
1961             Another example:
1962              
1963             # getElementsByClassName only selects elements that have both given classes
1964             my $allOrangeJuiceByClass = $doc->getElementsByClassName('orange juice');
1965             my $result = "$doc->getElementsByClassName('orange juice')";
1966             for( my $i=0; $i < $allOrangeJuiceByClass->length; $i++ )
1967             {
1968             $result .= "\n " . $allOrangeJuiceByClass->[$i]->textContent;
1969             }
1970              
1971             # querySelector only selects full complete matches
1972             my $allOrangeJuiceQuery = $doc->querySelectorAll('.orange->juice');
1973             $result += "\n\ndocument->querySelectorAll('.orange->juice')";
1974             for( my $i=0; $i < $allOrangeJuiceQuery->length; $i++ )
1975             {
1976             $result .= "\n " . $allOrangeJuiceQuery->[$i]->textContent;
1977             }
1978              
1979             $doc->getElementById( 'resultArea' )->value = $result;
1980              
1981             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByClassName>
1982              
1983             =head2 getElementsByName
1984              
1985             Returns a L<NodeList|HTML::Object::DOM::NodeList> Collection of elements with a given name attribute in the L<document|HTML::Object::DOM::Element>.
1986              
1987             Example:
1988              
1989             <!DOCTYPE html>
1990             <html lang="en">
1991             <head>
1992             <title>Example: using getElementsByName</title>
1993             </head>
1994             <body>
1995             <input type="hidden" name="up" />
1996             <input type="hidden" name="down" />
1997             </body>
1998             </html>
1999              
2000             my $up_names = $doc->getElementsByName( 'up' );
2001             say( $up_names->[0]->tagName ); # displays "input"
2002              
2003             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByName>
2004              
2005             =head2 getElementsByTagName
2006              
2007             Returns a L<list|HTML::Object::DOM::Collection> of elements with the given tag name.
2008              
2009             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByTagName>
2010              
2011             =head2 getElementsByTagNameNS
2012              
2013             This is merely an alias to L</getElementsByTagName> since there is no support for namespace.
2014              
2015             Normally, under JavaScript, this returns a list of elements with the given tag name and namespace.
2016              
2017             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/getElementsByTagNameNS>
2018              
2019             =head2 getRootNode
2020              
2021             Returns the current object.
2022              
2023             =head2 getSelection
2024              
2025             This always returns C<undef> under perl.
2026              
2027             Normally, under JavaScript, this returns a C<Selection> object representing the range of text selected by the user, or the current position of the caret.
2028              
2029             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/getSelection>
2030              
2031             =head2 hasChildNodes
2032              
2033             Returns true if the document list of nodes is not empty, false otherwise.
2034              
2035             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Node/hasChildNodes>
2036              
2037             =head2 hasFocus
2038              
2039             Under perl, this always returns true.
2040              
2041             Normally, under JavaScript, this returns a boolean value indicating whether the document or any element inside the document has focus. This method can be used to determine whether the active element in a document has focus.
2042              
2043             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/hasFocus>
2044              
2045             =head2 hasStorageAccess
2046              
2047             This always returns C<undef> under perl.
2048              
2049             Normally, under JavaScript, this returns a C<Promise> that resolves with a boolean value indicating whether the document has access to its first-party storage.
2050              
2051             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/hasStorageAccess>
2052              
2053             =head2 importNode
2054              
2055             Returns a clone of a node from an external document.
2056              
2057             Example:
2058              
2059             my $iframe = $doc->querySelector( 'iframe' );
2060             my $oldNode = $iframe->contentWindow->document->getElementById( 'myNode' );
2061             my $newNode = $doc->importNode( $oldNode, $true );
2062             $doc->getElementById( 'container' )->appendChild( $newNode );
2063              
2064             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/importNode>
2065              
2066             =head2 insertAfter
2067              
2068             Provided with a node and a reference node and this will insert the node after the reference node.
2069              
2070             It returns the current object upon success, or C<undef> upon L<error|Module::Generic/error>
2071              
2072             Surprisingly enough there is no C<insertAfter> method in the web API, only L</insertBefore>
2073              
2074             =head2 insertBefore
2075              
2076             Provided with a node and a reference node and this will insert the node before the reference node.
2077              
2078             It returns the current object upon success, or C<undef> upon L<error|Module::Generic/error>
2079              
2080             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Node/insertBefore>
2081              
2082             =head2 lastChild
2083              
2084             Returns the last child node from the document list of nodes.
2085              
2086             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Node/lastChild>
2087              
2088             =head2 mozSetImageElement
2089              
2090             This always returns C<undef> under perl.
2091              
2092             Normally, under JavaScript, this allows you to change the element being used as the background image for a specified element ID.
2093              
2094             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/mozSetImageElement>
2095              
2096             =head2 nextSibling
2097              
2098             Returns a L<smart undef|Module::Generic/new_null>. This means the return value will depend on what the caller expects. In scalar context it will return C<undef> and an empty list in list context, but if this method is chained, it will return a dummy object to avoid the perl error "method called on an undefined value"
2099              
2100             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Node/nextSibling>
2101              
2102             =head2 normalizeDocument
2103              
2104             Replaces entities, normalizes text nodes, etc.
2105              
2106             This is actually an alias to L<HTML::Object::DOM::Node/normalize>
2107              
2108             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/normalizeDocument>
2109              
2110             =head2 open
2111              
2112             The C<open()> method opens a document for writing and returns the current L<document|HTML::Object::DOM::Document> object.
2113              
2114             This does come with some side effects. For example:
2115              
2116             =over 4
2117              
2118             =item * All event listeners currently registered on the L<document|HTML::Object::DOM::Document>, L<nodes|HTML::Object::DOM::Node> inside the L<document|HTML::Object::DOM::Document>, or the document's L<window|HTML::Object::DOM::Window> are removed.
2119              
2120             =item * All existing L<nodes|HTML::Object::DOM::Node> are removed from the L<document|HTML::Object::DOM::Document>.
2121              
2122             =back
2123              
2124             Example:
2125              
2126             The following simple code opens the document and replaces its content with a number of different HTML fragments, before closing it again.
2127              
2128             my $doc = $parser->parse_data( $html );
2129             $doc->open();
2130             $doc->write("<p>Hello world!</p>");
2131             $doc->write("<p>I am a fish</p>");
2132             $doc->write("<p>The number is 42</p>");
2133             $doc->close();
2134              
2135             An automatic L</open> call happens when L</write> is called after the document has loaded.
2136              
2137             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/open>
2138              
2139             =head2 parentElement
2140              
2141             This interface returns the DOM node's parent Element, or C<undef> if the node either has no parent, or its parent isn't a DOM Element.
2142              
2143             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Node/parentElement>
2144              
2145             =head2 parentNode
2146              
2147             This returns the parent of the specified node in the DOM tree.
2148              
2149             Document and L<DocumentFragment|HTML::Object::DOM::DocumentFragment> nodes can never have a parent, so C<parentNode> will always return C<undef>.
2150              
2151             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Node/parentNode>
2152              
2153             =head2 prepend
2154              
2155             Inserts a set of L<Node|HTML::Object::DOM::Node> objects or string objects before the first child of the document.
2156              
2157             Example:
2158              
2159             my $html = $doc->createElement( 'html' );
2160             $doc->prepend( $html );
2161             # HierarchyRequestError: The operation would yield an incorrect node tree.
2162              
2163             Another example:
2164              
2165             my $doc = HTML::Object::DOM::Document->new;
2166             my $html = $doc->createElement( 'html' );
2167             $doc->prepend( $html );
2168              
2169             $doc->children; # HTMLCollection [<$html>]
2170              
2171             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/prepend>
2172              
2173             =head2 previousSibling
2174              
2175             This returns the node immediately preceding the specified one in its parent's childNodes list, or C<undef> if the specified node is the first in that list.
2176              
2177             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Node/previousSibling>
2178              
2179             =head2 queryCommandEnabled
2180              
2181             This always returns false under perl.
2182              
2183             Normally, under JavaScript, this reports whether or not the specified editor command is enabled by the browser.
2184              
2185             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/queryCommandEnabled>
2186              
2187             =head2 queryCommandIndeterm
2188              
2189             This always returns true under perl.
2190              
2191             Normally, under JavaScript, this returns true if the formatting command is in an indeterminate state on the current range.
2192              
2193             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/queryCommandIndeterm>
2194              
2195             =head2 queryCommandState
2196              
2197             This always returns false under perl.
2198              
2199             Normally, under JavaScript, this returns true if the formatting command has been executed on the current range.
2200              
2201             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/queryCommandState>
2202              
2203             =head2 queryCommandSupported
2204              
2205             This always returns false under perl.
2206              
2207             Normally, under JavaScript, this returns true if the formatting command is supported on the current range.
2208              
2209             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/queryCommandSupported>
2210              
2211             =head2 queryCommandValue
2212              
2213             This always returns C<undef> under perl.
2214              
2215             Normally, under JavaScript, this returns the current value of the current range for a formatting command.
2216              
2217             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/queryCommandValue>
2218              
2219             =head2 querySelector
2220              
2221             Returns the first Element node within the document, in document order, that matches the specified selectors.
2222              
2223             Example:
2224              
2225             <div id="foo\bar"></div>
2226             <div id="foo:bar"></div>
2227              
2228             $doc->querySelector( '#foo\\bar' ); # Match the first div
2229             $doc->querySelector( '#foo\:bar' ); # Match the second div
2230              
2231             my $el = $doc->querySelector(".myclass");
2232              
2233             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector>
2234              
2235             =head2 querySelectorAll
2236              
2237             Returns a list of all the Element nodes within the document that match the specified selectors.
2238              
2239             Example:
2240              
2241             <div class="outer">
2242             <div class="select">
2243             <div class="inner">
2244             </div>
2245             </div>
2246             </div>
2247              
2248             my $inner = $select->querySelectorAll( '.outer .inner' );
2249             $inner->length; # 1, not 0
2250              
2251             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelectorAll>
2252              
2253             =head2 releaseCapture
2254              
2255             Releases the current mouse capture if it's on an element in this document.
2256              
2257             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/releaseCapture>
2258              
2259             =head2 releaseEvents
2260              
2261             See L<HTML::Object::DOM::Window/releaseEvents>.
2262              
2263             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/releaseEvents>
2264              
2265             =head2 removeChild
2266              
2267             Provided with a node and this removes a child node from the DOM and returns the removed node.
2268              
2269             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Node/removeChild>
2270              
2271             =head2 replaceChild
2272              
2273             Provided with a C<new> node and and an C<old> node and this will replace the C<old> one by the C<new> one. Note that if the C<new> node is already present somewhere else in the C<DOM>, it is first removed from that position.
2274              
2275             This returns the C<old> node removed.
2276              
2277             See the document in L<HTML::Object::DOM::Node/replaceChild> for more details.
2278              
2279             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Node/replaceChild>
2280              
2281             =head2 replaceChildren
2282              
2283             Replaces the existing children of a document with a specified new set of children.
2284              
2285             Example:
2286              
2287             $doc->replaceChildren();
2288             $doc->children; # HTMLCollection []
2289              
2290             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/replaceChildren>
2291              
2292             =head2 requestStorageAccess
2293              
2294             This always returns C<undef> under perl.
2295              
2296             Normally, under JavaScript, this returns a C<Promise> that resolves if the access to first-party storage was granted, and rejects if access was denied.
2297              
2298             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/requestStorageAccess>
2299              
2300             =head2 string_value
2301              
2302             This always return C<undef>.
2303              
2304             =head2 write
2305              
2306             Provided with a list of nodes and this will write them to the body of this document. If the document is already closed, such as when it has already loaded, this will call L</open>, which will cause to empty the document.
2307              
2308             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/write>
2309              
2310             =head2 writeln
2311              
2312             Same as with L</write>, except this will add a new line.
2313              
2314             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/writeln>
2315              
2316             =head1 EVENTS
2317              
2318             There is only limited support for events under perl, but you can trigger yourself any event.
2319              
2320             Event listeners for those events can also be found by prepending C<on> before the event type:
2321              
2322             C<click> event listeners can be set also with C<onclick> method:
2323              
2324             $e->onclick(sub{ # do something });
2325             # or as an lvalue method
2326             $e->onclick = sub{ # do something };
2327              
2328             Below are some key ones, but you can see the full lists on the L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document#events>
2329              
2330             =head2 DOMContentLoaded
2331              
2332             Fired when the document has been completely loaded and parsed, without waiting for stylesheets, images, and subframes to finish loading.
2333              
2334             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/DOMContentLoaded_event>
2335              
2336             =head2 readystatechange
2337              
2338             Fired when the readyState attribute of a document has changed.
2339              
2340             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/readystatechange_event>
2341              
2342             =head2 visibilitychange
2343              
2344             Fired when the content of a tab has become visible or has been hidden. Also available via the onvisibilitychange property.
2345              
2346             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/visibilitychange_event>
2347              
2348             =head1 EVENT HANDLERS
2349              
2350             Listen to these events using L<HTML::Object::EventTarget/addEventListener> or by assigning an event listener to the C<oneventname> property of this interface.
2351              
2352             Under perl, few events are actually "fired" by L<HTML::Object::DOM::Document> and L<for the others|https://developer.mozilla.org/en-US/docs/Web/API/Element#events>, nothing prevents you from L<triggering|HTML::Object::EventTarget/dispatchEvent> whatever events you want on any L<element|HTML::Object::DOM::Element>, even private non-standard ones, and set up listeners for them.
2353              
2354             Below are the ones actually "fired" by L<HTML::Object>.
2355              
2356             =head2 onabort
2357              
2358             This takes a code reference (a reference to a subroutine or an anonymous subroutine) as its unique argument.
2359              
2360             The C<onabort> property is the L<event|HTML::Object::Event> handler for processing C<abort> events sent to the perl script.
2361              
2362             It returns C<undef> and sets an C<HTML::Object::TypeError> error if the value provided is not a code reference, i.e. a reference to an existing subroutine or an anonymous subroutine.
2363              
2364             It returns true upon success.
2365              
2366             Upon an abort signal (C<ABRT>, C<INT> or C<TERM>), this will execute the code reference, passing it an L<error event object|HTML::Object::ErrorEvent>
2367              
2368             Example:
2369              
2370             use HTML::Object::DOM;
2371             my $p = HTML::Object::DOM->new;
2372             $doc = $p->parse_data( $some_html_string );
2373             $doc->onabort = sub
2374             {
2375             my $event = shift( @_ );
2376             print( "Oh no: ", $event->trace, "\n" );
2377             };
2378             # or
2379             $doc->onabort = \&exception_handler;
2380              
2381             =head2 onafterscriptexecute
2382              
2383             Under perl, no such event is fired, but you can trigger one yourself.
2384              
2385             This property references a function that fires when a static <script> element finishes executing its script. It does not fire if the element is added dynamically, such as with appendChild().
2386              
2387             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/onafterscriptexecute>
2388              
2389             =head2 onbeforescriptexecute
2390              
2391             Under perl, no such event is fired, but you can trigger one yourself.
2392              
2393             This is fired when the code in a <script> element declared in an HTML document is about to start executing. Does not fire if the element is added dynamically, eg with appendChild().
2394              
2395             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/onbeforescriptexecute>
2396              
2397             =head2 oncopy
2398              
2399             Under perl, no such event is fired, but you can trigger one yourself.
2400              
2401             This represents the event handling code for the copy event.
2402              
2403             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/oncopy>
2404              
2405             =head2 oncut
2406              
2407             Under perl, no such event is fired, but you can trigger one yourself.
2408              
2409             This represents the event handling code for the cut event.
2410              
2411             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/oncut>
2412              
2413             =head2 onerror
2414              
2415             The C<onerror> property is an L<event|HTML::Object::Event> handler that processes error events triggered by a L<perlfunc/warn> or L<perlfunc/die>
2416              
2417             Upon an error signal (C<__WARN__>, or C<__DIE__>), this will execute the code reference, passing it an L<error event object|HTML::Object::ErrorEvent>
2418              
2419             Example:
2420              
2421             use HTML::Object::DOM;
2422             my $p = HTML::Object::DOM->new;
2423             $doc = $p->parse_data( $some_html_string );
2424             $doc->onerror = sub
2425             {
2426             my $event = shift( @_ );
2427             print( "Oh no: ", $event->trace, "\n" );
2428             };
2429             # or
2430             $doc->onerror = \&exception_handler;
2431              
2432             =head2 onfullscreenchange
2433              
2434             Under perl, no such event is fired, but you can trigger one yourself.
2435              
2436             This property is an event handler for the fullscreenchange event that is fired immediately before a document transitions into or out of full-screen mode.
2437              
2438             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/onfullscreenchange>
2439              
2440             =head2 onfullscreenerror
2441              
2442             Under perl, no such event is fired, but you can trigger one yourself.
2443              
2444             This property is an event handler for the fullscreenerror event that is sent to the document when it fails to transition into full-screen mode after a prior call to Element.requestFullscreen().
2445              
2446             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/onfullscreenerror>
2447              
2448             =head2 onload
2449              
2450             The C<onload> property is an event handler for the C<load> event that fires when the initial HTML L<document|HTML::Object::DOM::Document> has been completely loaded and parsed. It is fired after the L</readyState> has changed to C<complete>
2451              
2452             Contrary to the JavaScript environment, under perl, there is obviously no window and thus no difference between the JavaScript L<window load|https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event> event and the L<DOMContentLoaded|https://developer.mozilla.org/en-US/docs/Web/API/Document/DOMContentLoaded_event> event
2453              
2454             For example:
2455              
2456             $doc->addEventListener( load => sub
2457             {
2458             say( 'Document fully loaded and parsed' );
2459             });
2460              
2461             sub doSomething
2462             {
2463             say( 'Document loaded' );
2464             }
2465              
2466             # Loading has not finished yet
2467             if( $doc->readyState eq 'loading' )
2468             {
2469             $doc->addEventListener( load => \&doSomething );
2470             }
2471             # 'load' has already fired
2472             else
2473             {
2474             doSomething();
2475             }
2476              
2477             Upon execution, a new L<event|HTML::Object::Event> is passed of type C<readstate> and with the C<detail> property having the following data available:
2478              
2479             =over 4
2480              
2481             =item document
2482              
2483             The L<document object|HTML::Object::DOM::Document>
2484              
2485             =item state
2486              
2487             The state of the document parsing.
2488              
2489             =back
2490              
2491             The event C<target> property is also set to the L<document object|HTML::Object::DOM::Document>.
2492              
2493             =head2 onpaste
2494              
2495             Under perl, no such event is fired, but you can trigger one yourself.
2496              
2497             This property interface is an event handler that processes paste events.
2498              
2499             The paste event fires when the user attempts to paste text.
2500              
2501             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/onpaste>
2502              
2503             =head2 onreadystatechange
2504              
2505             The C<onreadystatechange> property is an event handler for the C<readystatechange> event that is fired when the L</readyState> attribute of a L<document|HTML::Object::DOM::Document> has changed.
2506              
2507             There are 3 state: C<loading>, C<interactive> and C<complete> (which is the same, under perl, as C<loading>)
2508              
2509             This event does not bubble and is not cancelable
2510              
2511             Upon execution, a new L<event|HTML::Object::Event> is passed of type C<readstate> and with the C<detail> property having the following data available:
2512              
2513             =over 4
2514              
2515             =item document
2516              
2517             The L<document object|HTML::Object::DOM::Document>
2518              
2519             =item state
2520              
2521             The state of the document parsing.
2522              
2523             =back
2524              
2525             The event C<target> property is also set to the L<document object|HTML::Object::DOM::Document>.
2526              
2527             See L<for more information|https://developer.mozilla.org/en-US/docs/Web/API/Document/readystatechange_event>
2528              
2529             =head2 onscroll
2530              
2531             Under perl, no such event is fired, but you can trigger one yourself.
2532              
2533             This property interface is an event handler that processes events when the document view or an element has been scrolled, whether by the user, a Web API, or the user agent.
2534              
2535             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onscroll>
2536              
2537             =head2 onselectionchange
2538              
2539             Under perl, no such event is fired, but you can trigger one yourself.
2540              
2541             This is fired when the Selection of a Document is changed. The Selection consists of a starting position and (optionally) a range of HTML nodes from that position. Clicking or starting a selection outside of a text field will generally fire this event.
2542              
2543             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onselectionchange>
2544              
2545             =head2 onvisibilitychange
2546              
2547             Is an event handler representing the code to be called when the visibilitychange event is raised.
2548              
2549             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document/onvisibilitychange>
2550              
2551             =head2 onwheel
2552              
2553             Under perl, no such event is fired, but you can trigger one yourself.
2554              
2555             This event is fired when the user rotates the mouse (or other pointing device) wheel.
2556              
2557             See also L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onwheel>
2558              
2559             =head1 AUTHOR
2560              
2561             Jacques Deguest E<lt>F<jack@deguest.jp>E<gt>
2562              
2563             =head1 SEE ALSO
2564              
2565             L<HTML::Object::Document>, L<HTML::Object::DOM::Element>
2566              
2567             L<Mozilla documentation on DOM|https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model>, L<Mozilla documentation on Document object|https://developer.mozilla.org/en-US/docs/Web/API/Document>
2568              
2569             =head1 COPYRIGHT & LICENSE
2570              
2571             Copyright(c) 2021 DEGUEST Pte. Ltd.
2572              
2573             All rights reserved
2574              
2575             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
2576              
2577             =cut