File Coverage

lib/HTML/Object/DOM.pm
Criterion Covered Total %
statement 117 124 94.3
branch 12 22 54.5
condition 10 21 47.6
subroutine 35 37 94.5
pod 19 19 100.0
total 193 223 86.5


line stmt bran cond sub pod time code
1             ##----------------------------------------------------------------------------
2             ## HTML Object - ~/lib/HTML/Object/DOM.pm
3             ## Version v0.2.0
4             ## Copyright(c) 2021 DEGUEST Pte. Ltd.
5             ## Author: Jacques Deguest <jack@deguest.jp>
6             ## Created 2021/12/13
7             ## Modified 2022/09/18
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;
15             BEGIN
16             {
17 28     28   3399270 use strict;
  28         330  
  28         882  
18 28     28   206 use warnings;
  28         61  
  28         861  
19 28     28   10781 use parent qw( HTML::Object );
  28         7219  
  28         182  
20 28     28   4627 use vars qw( @EXPORT_OK %EXPORT_TAGS $SCREEN $WINDOW $TAG_TO_CLASS $GLOBAL_DOM $VERSION );
  28         78  
  28         4250  
21 28     28   21184 use HTML::Object::DOM::Closing;
  28         97  
  28         1880  
22 28     28   27940 use HTML::Object::DOM::Comment;
  28         79  
  28         413  
23 28     28   18465 use HTML::Object::DOM::Declaration;
  28         78  
  28         507  
24 28     28   26894 use HTML::Object::DOM::Document;
  28         104  
  28         532  
25 28     28   9890 use HTML::Object::DOM::Element;
  28         76  
  28         479  
26 28     28   17834 use HTML::Object::DOM::Space;
  28         100  
  28         455  
27 28     28   18475 use HTML::Object::DOM::Text;
  28         81  
  28         436  
28 28     28   18854 use HTML::Object::DOM::Screen;
  28         101  
  28         399  
29 28     28   22929 use HTML::Object::DOM::Window;
  28         118  
  28         391  
30 28     28   7237 use Scalar::Util ();
  28         87  
  28         3017  
31             use constant {
32             # For HTML::Object::DOM::Node
33 28         22058 DOCUMENT_POSITION_IDENTICAL => 0,
34             DOCUMENT_POSITION_DISCONNECTED => 1,
35             DOCUMENT_POSITION_PRECEDING => 2,
36             DOCUMENT_POSITION_FOLLOWING => 4,
37             DOCUMENT_POSITION_CONTAINS => 8,
38             DOCUMENT_POSITION_CONTAINED_BY => 16,
39             DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC => 32,
40            
41             ELEMENT_NODE => 1,
42             ATTRIBUTE_NODE => 2,
43             TEXT_NODE => 3,
44             CDATA_SECTION_NODE => 4,
45             # Deprecated
46             ENTITY_REFERENCE_NODE => 5,
47             # Deprecated
48             ENTITY_NODE => 6,
49             PROCESSING_INSTRUCTION_NODE => 7,
50             COMMENT_NODE => 8,
51             DOCUMENT_NODE => 9,
52             DOCUMENT_TYPE_NODE => 10,
53             DOCUMENT_FRAGMENT_NODE => 11,
54             NOTATION_NODE => 12,
55             # non-standard addition, because we distinguish space from text
56             SPACE_NODE => 13,
57            
58             # For HTML::Object::DOM::Element::Media
59             # There is no data yet. Also, readyState is HAVE_NOTHING.
60             NETWORK_EMPTY => 0,
61             # HTMLMediaElement is active and has selected a resource, but is not using the network.
62             NETWORK_IDLE => 1,
63             # The browser is downloading HTMLMediaElement data.
64             NETWORK_LOADING => 2,
65             # No HTMLMediaElement src found.
66             NETWORK_NO_SOURCE => 3,
67            
68             # For HTML::Object::DOM::Element::Track
69             # Indicates that the text track's cues have not been obtained.
70             NONE => 0,
71             # Indicates that the text track is loading and there have been no fatal errors encountered so far. Further cues might still be added to the track by the parser.
72             LOADING => 1,
73             # Indicates that the text track has been loaded with no fatal errors.
74             LOADED => 2,
75             # Indicates that the text track was enabled, but when the user agent attempted to obtain it, this failed in some way. Some or all of the cues are likely missing and will not be obtained.
76             ERROR => 3,
77            
78             # For HTML::Object::Event
79             # NONE => 0,
80             CAPTURING_PHASE => 1,
81             AT_TARGET => 2,
82             BUBBLING_PHASE => 3,
83            
84             CANCEL_PROPAGATION => 1,
85             CANCEL_IMMEDIATE_PROPAGATION => 2,
86            
87             # HTML::Object::DOM::NodeFilter
88             # Shows all nodes.
89             SHOW_ALL => 4294967295,
90             # Shows Element nodes.
91             SHOW_ELEMENT => 1,
92             # Shows attribute Attr nodes.
93             SHOW_ATTRIBUTE => 2,
94             # Shows Text nodes.
95             SHOW_TEXT => 4,
96             # Shows CDATASection nodes.
97             SHOW_CDATA_SECTION => 8,
98             # Legacy, no more used.
99             SHOW_ENTITY_REFERENCE => 16,
100             # Legacy, no more used.
101             SHOW_ENTITY => 32,
102             # Shows ProcessingInstruction nodes.
103             SHOW_PROCESSING_INSTRUCTION => 64,
104             # Shows Comment nodes.
105             SHOW_COMMENT => 128,
106             # Shows Document nodes.
107             SHOW_DOCUMENT => 256,
108             # Shows DocumentType nodes.
109             SHOW_DOCUMENT_TYPE => 512,
110             # Shows DocumentFragment nodes.
111             SHOW_DOCUMENT_FRAGMENT => 1024,
112             # Legacy, no more used.
113             SHOW_NOTATION => 2048,
114             # Show spaces
115             SHOW_SPACE => 4096,
116            
117             FILTER_ACCEPT => 1,
118             FILTER_REJECT => 2,
119             FILTER_SKIP => 3,
120            
121             # HTML::Object::DOM::XPathResult
122             # A result set containing whatever type naturally results from evaluation of the expression. Note that if the result is a node-set then UNORDERED_NODE_ITERATOR_TYPE is always the resulting type.
123             ANY_TYPE => 0,
124             # A result containing a single number. This is useful for example, in an XPath expression using the count() function.
125             NUMBER_TYPE => 1,
126             # A result containing a single string.
127             STRING_TYPE => 2,
128             # A result containing a single boolean value. This is useful for example, in an XPath expression using the not() function.
129             BOOLEAN_TYPE => 3,
130             # A result node-set containing all the nodes matching the expression. The nodes may not necessarily be in the same order that they appear in the document.
131             UNORDERED_NODE_ITERATOR_TYPE => 4,
132             # A result node-set containing all the nodes matching the expression. The nodes in the result set are in the same order that they appear in the document.
133             ORDERED_NODE_ITERATOR_TYPE => 5,
134             # A result node-set containing snapshots of all the nodes matching the expression. The nodes may not necessarily be in the same order that they appear in the document.
135             UNORDERED_NODE_SNAPSHOT_TYPE => 6,
136             # A result node-set containing snapshots of all the nodes matching the expression. The nodes in the result set are in the same order that they appear in the document.
137             ORDERED_NODE_SNAPSHOT_TYPE => 7,
138             # A result node-set containing any single node that matches the expression. The node is not necessarily the first node in the document that matches the expression.
139             ANY_UNORDERED_NODE_TYPE => 8,
140             # A result node-set containing the first node in the document that matches the expression.
141             FIRST_ORDERED_NODE_TYPE => 9,
142 28     28   181 };
  28         70  
143 28     28   412 our @EXPORT_OK = qw(
144             screen window
145            
146             DOCUMENT_POSITION_IDENTICAL
147             DOCUMENT_POSITION_DISCONNECTED
148             DOCUMENT_POSITION_PRECEDING
149             DOCUMENT_POSITION_FOLLOWING
150             DOCUMENT_POSITION_CONTAINS
151             DOCUMENT_POSITION_CONTAINED_BY
152             DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
153            
154             ELEMENT_NODE
155             ATTRIBUTE_NODE
156             TEXT_NODE
157             CDATA_SECTION_NODE
158             ENTITY_REFERENCE_NODE
159             ENTITY_NODE
160             PROCESSING_INSTRUCTION_NODE
161             COMMENT_NODE
162             DOCUMENT_NODE
163             DOCUMENT_TYPE_NODE
164             DOCUMENT_FRAGMENT_NODE
165             NOTATION_NODE
166             SPACE_NODE
167            
168             NETWORK_EMPTY NETWORK_IDLE NETWORK_LOADING NETWORK_NO_SOURCE
169             NONE LOADING LOADED ERROR
170             CAPTURING_PHASE AT_TARGET BUBBLING_PHASE CANCEL_PROPAGATION CANCEL_IMMEDIATE_PROPAGATION
171            
172             SHOW_ALL SHOW_ELEMENT SHOW_ATTRIBUTE SHOW_TEXT SHOW_CDATA_SECTION
173             SHOW_ENTITY_REFERENCE SHOW_ENTITY SHOW_PROCESSING_INSTRUCTION SHOW_COMMENT
174             SHOW_DOCUMENT SHOW_DOCUMENT_TYPE SHOW_DOCUMENT_FRAGMENT SHOW_NOTATION SHOW_SPACE
175             FILTER_ACCEPT FILTER_REJECT FILTER_SKIP
176            
177             ANY_TYPE NUMBER_TYPE STRING_TYPE BOOLEAN_TYPE
178             UNORDERED_NODE_ITERATOR_TYPE ORDERED_NODE_ITERATOR_TYPE
179             UNORDERED_NODE_SNAPSHOT_TYPE ORDERED_NODE_SNAPSHOT_TYPE
180             ANY_UNORDERED_NODE_TYPE FIRST_ORDERED_NODE_TYPE
181             );
182 28         412 our %EXPORT_TAGS = (
183             event => [qw(
184             NONE LOADING LOADED ERROR
185             CAPTURING_PHASE AT_TARGET BUBBLING_PHASE CANCEL_PROPAGATION CANCEL_IMMEDIATE_PROPAGATION
186             )],
187             filter => [qw(
188             SHOW_ALL SHOW_ELEMENT SHOW_ATTRIBUTE SHOW_TEXT SHOW_CDATA_SECTION
189             SHOW_ENTITY_REFERENCE SHOW_ENTITY SHOW_PROCESSING_INSTRUCTION SHOW_COMMENT
190             SHOW_DOCUMENT SHOW_DOCUMENT_TYPE SHOW_DOCUMENT_FRAGMENT SHOW_NOTATION SHOW_SPACE
191             FILTER_ACCEPT FILTER_REJECT FILTER_SKIP
192             )],
193             # HTML::Object::DOM::Element::Media
194             media => [qw( NETWORK_EMPTY NETWORK_IDLE NETWORK_LOADING NETWORK_NO_SOURCE )],
195             # HTML::Object::DOM::Node
196             node => [qw(
197             DOCUMENT_POSITION_IDENTICAL
198             DOCUMENT_POSITION_DISCONNECTED
199             DOCUMENT_POSITION_PRECEDING
200             DOCUMENT_POSITION_FOLLOWING
201             DOCUMENT_POSITION_CONTAINS
202             DOCUMENT_POSITION_CONTAINED_BY
203             DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC
204            
205             ELEMENT_NODE
206             ATTRIBUTE_NODE
207             TEXT_NODE
208             CDATA_SECTION_NODE
209             ENTITY_REFERENCE_NODE
210             ENTITY_NODE
211             PROCESSING_INSTRUCTION_NODE
212             COMMENT_NODE
213             DOCUMENT_NODE
214             DOCUMENT_TYPE_NODE
215             DOCUMENT_FRAGMENT_NODE
216             NOTATION_NODE
217             SPACE_NODE
218             )],
219             track => [qw( NONE LOADING LOADED ERROR )],
220             xpath => [qw(
221             ANY_TYPE NUMBER_TYPE STRING_TYPE BOOLEAN_TYPE
222             UNORDERED_NODE_ITERATOR_TYPE ORDERED_NODE_ITERATOR_TYPE
223             UNORDERED_NODE_SNAPSHOT_TYPE ORDERED_NODE_SNAPSHOT_TYPE
224             ANY_UNORDERED_NODE_TYPE FIRST_ORDERED_NODE_TYPE
225             )],
226             );
227 28         260 $EXPORT_TAGS{all} = [@EXPORT_OK];
228 28         475 our $SCREEN = HTML::Object::DOM::Screen->new;
229 28         176 our $WINDOW;
230             # An hash reference map to lowercase HTML tag name to perl class, for those who have special classes, otherwise the fallback is HTML::Object::Element.
231 28         67 our $TAG_TO_CLASS = {};
232 28         53 our $GLOBAL_DOM;
233 28         973 our $VERSION = 'v0.2.0';
234             };
235              
236 28     28   208 use strict;
  28         61  
  28         769  
237 28     28   171 use warnings;
  28         73  
  28         33126  
238              
239             {
240             # "If name is applet, bgsound, blink, isindex, keygen, multicol, nextid, or spacer, then return HTMLUnknownElement."
241             # "If name is acronym, basefont, big, center, nobr, noembed, noframes, plaintext, rb, rtc, strike, or tt, then return HTMLElement."
242             # "If name is listing or xmp, then return HTMLPreElement."
243             # <https://html.spec.whatwg.org/multipage/dom.html#htmlunknownelement>
244             $TAG_TO_CLASS =
245             {
246             a => 'HTML::Object::DOM::Element::Anchor',
247             acronym => 'HTML::Object::DOM::Element',
248             # Deprecated
249             applet => 'HTML::Object::DOM::Element::Unknown',
250             area => 'HTML::Object::DOM::Element::Area',
251             audio => 'HTML::Object::DOM::Element::Audio',
252             base => 'HTML::Object::DOM::Element::Base',
253             basefont => 'HTML::Object::DOM::Element',
254             # Deprecated
255             bgsound => 'HTML::Object::DOM::Element::Unknown',
256             big => 'HTML::Object::DOM::Element',
257             # Deprecated
258             blink => 'HTML::Object::DOM::Element::Unknown',
259             blockquote => 'HTML::Object::DOM::Element::Quote',
260             body => 'HTML::Object::DOM::Element::Body',
261             br => 'HTML::Object::DOM::Element::BR',
262             button => 'HTML::Object::DOM::Element::Button',
263             canvas => 'HTML::Object::DOM::Element::Canvas',
264             caption => 'HTML::Object::DOM::Element::TableCaption',
265             center => 'HTML::Object::DOM::Element',
266             col => 'HTML::Object::DOM::Element::TableCol',
267             colgroup => 'HTML::Object::DOM::Element::TableCol',
268             data => 'HTML::Object::DOM::Element::Data',
269             datalist => 'HTML::Object::DOM::Element::DataList',
270             details => 'HTML::Object::DOM::Element::Details',
271             dialog => 'HTML::Object::DOM::Element::Dialog',
272             div => 'HTML::Object::DOM::Element::Div',
273             dl => 'HTML::Object::DOM::Element::DList',
274             # "Firefox implements the HTMLSpanElement interface for this element."
275             # <https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dt>
276             dt => 'HTML::Object::DOM::Element::Span',
277             dd => 'HTML::Object::DOM::Element',
278             embed => 'HTML::Object::DOM::Element::Embed',
279             fieldset => 'HTML::Object::DOM::Element::FieldSet',
280             font => 'HTML::Object::DOM::Element::Unknown',
281             form => 'HTML::Object::DOM::Element::Form',
282             frame => 'HTML::Object::DOM::Element::Unknown',
283             frameset => 'HTML::Object::DOM::Element::Unknown',
284             head => 'HTML::Object::DOM::Element::Head',
285             h1 => 'HTML::Object::DOM::Element::Heading',
286             h2 => 'HTML::Object::DOM::Element::Heading',
287             h3 => 'HTML::Object::DOM::Element::Heading',
288             h4 => 'HTML::Object::DOM::Element::Heading',
289             h5 => 'HTML::Object::DOM::Element::Heading',
290             h6 => 'HTML::Object::DOM::Element::Heading',
291             hr => 'HTML::Object::DOM::Element::HR',
292             html => 'HTML::Object::DOM::Element::HTML',
293             iframe => 'HTML::Object::DOM::Element::IFrame',
294             image => 'HTML::Object::DOM::Element::Image',
295             input => 'HTML::Object::DOM::Element::Input',
296             # Deprecated
297             isindex => 'HTML::Object::DOM::Element::Unknown',
298             # Deprecated
299             keygen => 'HTML::Object::DOM::Element::Unknown',
300             label => 'HTML::Object::DOM::Element::Label',
301             legend => 'HTML::Object::DOM::Element::Legend',
302             li => 'HTML::Object::DOM::Element::LI',
303             'link' => 'HTML::Object::DOM::Element::Link',
304             listing => 'HTML::Object::DOM::Element::Pre',
305             'map' => 'HTML::Object::DOM::Element::Map',
306             marquee => 'HTML::Object::DOM::Element::Marquee',
307             media => 'HTML::Object::DOM::Element::Media',
308             menu => 'HTML::Object::DOM::Element::Unknown',
309             meta => 'HTML::Object::DOM::Element::Meta',
310             meter => 'HTML::Object::DOM::Element::Meter',
311             mod => 'HTML::Object::DOM::Element::Mod',
312             # Deprecated
313             multicol => 'HTML::Object::DOM::Element::Unknown',
314             # Deprecated
315             nextid => 'HTML::Object::DOM::Element::Unknown',
316             nobr => 'HTML::Object::DOM::Element',
317             noembed => 'HTML::Object::DOM::Element',
318             noframes => 'HTML::Object::DOM::Element',
319             object => 'HTML::Object::DOM::Element::Object',
320             ol => 'HTML::Object::DOM::Element::OList',
321             optgroup => 'HTML::Object::DOM::Element::OptGroup',
322             option => 'HTML::Object::DOM::Element::Option',
323             output => 'HTML::Object::DOM::Element::Output',
324             p => 'HTML::Object::DOM::Element::Paragraph',
325             param => 'HTML::Object::DOM::Element::Param',
326             picture => 'HTML::Object::DOM::Element::Picture',
327             plaintext => 'HTML::Object::DOM::Element',
328             pre => 'HTML::Object::DOM::Element::Pre',
329             progress => 'HTML::Object::DOM::Element::Progress',
330             quote => 'HTML::Object::DOM::Element::Quote',
331             'q' => 'HTML::Object::DOM::Element::Quote',
332             rb => 'HTML::Object::DOM::Element',
333             rtc => 'HTML::Object::DOM::Element',
334             script => 'HTML::Object::DOM::Element::Script',
335             'select' => 'HTML::Object::DOM::Element::Select',
336             slot => 'HTML::Object::DOM::Element::Slot',
337             source => 'HTML::Object::DOM::Element::Source',
338             # Deprecated
339             spacert => 'HTML::Object::DOM::Element::Unknown',
340             span => 'HTML::Object::DOM::Element::Span',
341             strike => 'HTML::Object::DOM::Element',
342             style => 'HTML::Object::DOM::Element::Style',
343             table => 'HTML::Object::DOM::Element::Table',
344             td => 'HTML::Object::DOM::Element::TableCell',
345             th => 'HTML::Object::DOM::Element::TableCell',
346             'tr' => 'HTML::Object::DOM::Element::TableRow',
347             tbody => 'HTML::Object::DOM::Element::TableSection',
348             tfoot => 'HTML::Object::DOM::Element::TableSection',
349             thead => 'HTML::Object::DOM::Element::TableSection',
350             template => 'HTML::Object::DOM::Element::Template',
351             textarea => 'HTML::Object::DOM::Element::TextArea',
352             'time' => 'HTML::Object::DOM::Element::Time',
353             title => 'HTML::Object::DOM::Element::Title',
354             track => 'HTML::Object::DOM::Element::Track',
355             tt => 'HTML::Object::DOM::Element',
356             video => 'HTML::Object::DOM::Element::Video',
357             xmp => 'HTML::Object::DOM::Element::Pre',
358             };
359             }
360              
361             # *import = \&Exporter::import;
362              
363             sub init
364             {
365 69     69 1 179499 my $self = shift( @_ );
366 69         2795 $self->{onload} = undef;
367 69         283 $self->{onreadystatechange} = undef;
368 69         228 $self->{_init_strict_use_sub} = 1;
369 69 50       692 $self->SUPER::init( @_ ) || return( $self->pass_error );
370 69         550 my $win = $self->new_window( debug => $self->debug );
371 69         412 $self->window( $win );
372 69         3903 return( $self );
373             }
374              
375 1725     1725 1 7493 sub current_parent { return( shift->_set_get_object_without_init( 'current_parent', 'HTML::Object::DOM::Node', @_ ) ); }
376              
377 106     106 1 494 sub document { return( shift->_set_get_object( 'document', 'HTML::Object::DOM::Document', @_ ) ); }
378              
379             sub get_definition
380             {
381 305     305 1 2590 my $self = shift( @_ );
382 305         808 my $tag = shift( @_ );
383 305 50       1605 return( $self->error( "No tag was provided to get its definition." ) ) if( !length( $tag ) );
384             # Just to be sure
385 305         909 $tag = lc( $tag );
386 305   50     2087 my $def = $self->SUPER::get_definition( $tag, @_ ) || return( $self->pass_error );
387 305 100       2469 $def->{class} = $TAG_TO_CLASS->{ $tag } if( CORE::exists( $TAG_TO_CLASS->{ $tag } ) );
388 305         907 return( $def );
389             }
390              
391 1     1 1 12 sub get_dom { return( $GLOBAL_DOM ); }
392              
393             sub new_closing
394             {
395 198     198 1 7432 my $self = shift( @_ );
396 198   50     1571 my $e = HTML::Object::DOM::Closing->new( @_ ) ||
397             return( $self->pass_error( HTML::Object::DOM::Closing->error ) );
398 198         3344 return( $e );
399             }
400              
401             sub new_comment
402             {
403 6     6 1 195 my $self = shift( @_ );
404 6   50     115 my $e = HTML::Object::DOM::Comment->new( @_ ) ||
405             return( $self->pass_error( HTML::Object::DOM::Comment->error ) );
406 6         92 return( $e );
407             }
408              
409             sub new_declaration
410             {
411 18     18 1 632 my $self = shift( @_ );
412 18   50     264 my $e = HTML::Object::DOM::Declaration->new( @_ ) ||
413             return( $self->pass_error( HTML::Object::DOM::Declaration->error ) );
414 18         281 return( $e );
415             }
416              
417             sub new_document
418             {
419 51     51 1 2430324 my $self = shift( @_ );
420 51   50     683 my $e = HTML::Object::DOM::Document->new( @_ ) ||
421             return( $self->pass_error( HTML::Object::DOM::Document->error ) );
422 51         703 my $win = $self->window;
423 51         1938 $e->defaultView( $win );
424 51         43600 return( $e );
425             }
426              
427             sub new_element
428             {
429 30     30 1 8511 my $self = shift( @_ );
430 30   50     247 my $e = HTML::Object::DOM::Element->new( @_ ) ||
431             return( $self->pass_error( HTML::Object::DOM::Element->error ) );
432 30         429 return( $e );
433             }
434              
435             sub new_space
436             {
437 332     332 1 1110 my $self = shift( @_ );
438 332   50     2707 my $e = HTML::Object::DOM::Space->new( @_ ) ||
439             return( $self->pass_error( HTML::Object::DOM::Space->error ) );
440 332         5371 return( $e );
441             }
442              
443             sub new_text
444             {
445 107     107 1 3488 my $self = shift( @_ );
446 107   50     1014 my $e = HTML::Object::DOM::Text->new( @_ ) ||
447             return( $self->pass_error( HTML::Object::DOM::Text->error ) );
448 107         1823 return( $e );
449             }
450              
451             sub new_window
452             {
453 69     69 1 2047 my $self = shift( @_ );
454 69   50     1027 my $e = HTML::Object::DOM::Window->new( @_ ) ||
455             return( $self->pass_error( HTML::Object::DOM::Window->error ) );
456 69         1043 $e->screen( $SCREEN );
457 69 100       57012 $WINDOW = $e unless( ref( $WINDOW ) );
458 69         243 return( $e );
459             }
460              
461 48     48 1 708 sub onload : lvalue { return( shift->_set_get_code( 'onload', @_ ) ); }
462              
463 47     47 1 1204 sub onreadystatechange : lvalue { return( shift->_set_get_code( 'onreadystatechange', @_ ) ); }
464              
465 0     0 1 0 sub parseFromString { return( shift->parse_data( @_ ) ); }
466              
467 0     0 1 0 sub screen { return( $SCREEN ); }
468              
469             sub set_dom
470             {
471 2     2 1 11757 my( $this, $html ) = @_;
472 2 50       9 if( defined( $html ) )
473             {
474 2 50 33     80 if( Scalar::Util::blessed( $html ) && $html->isa( 'HTML::Object::DOM::Document' ) )
    50          
475             {
476 0         0 $GLOBAL_DOM = $html;
477             }
478             elsif( CORE::length( $html ) )
479             {
480 2         23 $GLOBAL_DOM = $this->new->parse( $html );
481             }
482             }
483 2         10 return( $this );
484             }
485              
486             sub window
487             {
488 120 50   120 1 581 if( !scalar( @_ ) )
489             {
490 0         0 return( $WINDOW );
491             }
492 120         282 my $self = shift( @_ );
493 120 50       641 if( Scalar::Util::blessed( $self ) )
494             {
495 120 50       721 if( $self->isa( 'HTML::Object::DOM' ) )
496             {
497 120         813 return( $self->_set_get_object( 'window', 'HTML::Object::DOM::Window', @_ ) );
498             }
499             else
500             {
501 0 0         die( "You cannot call window as a class function and passing it an object other than a HTML::Object::DOM::Window object.\n" ) unless( $self->isa( 'HTML::Object::DOM::Window' ) );
502 0           $WINDOW = $self;
503             }
504             }
505             else
506             {
507 0           die( "Unknown value (", overload::StrVal( $self ), ") provided to window() called as a HTML::Object::DOM class function\n" );
508             }
509             }
510              
511             1;
512             # NOTE: POD
513             __END__
514              
515             =encoding utf-8
516              
517             =head1 NAME
518              
519             HTML::Object::DOM - HTML Object DOM Class
520              
521             =head1 SYNOPSIS
522              
523             use HTML::Object::DOM;
524             my $this = HTML::Object::DOM->new || die( HTML::Object::DOM->error, "\n" );
525              
526             =head1 VERSION
527              
528             v0.2.0
529              
530             =head1 DESCRIPTION
531              
532             This module implement DOM-like interface to HTML objects and inherits from L<HTML::Object>, so you can call this module instead, to parse HTML data and it the resulting tree of objects will have DOM capabilities.
533              
534             DOM stands for Document Object Model.
535              
536             There are 2 divergences from the standard:
537              
538             =over 4
539              
540             =item 1. nodeName
541              
542             L<nodeName|HTML::Object::DOM::Node/nodeName> returns the tag name in lower case instead of the upper case
543              
544             =item 2. Space and text
545              
546             This interface makes the difference between L<text|HTML::Object::DOM::Text> and L<space-only text|HTML::Object::DOM::Space> whereas the DOM standard specification treats both as a text node.
547              
548             This leads to a new non-standard constant L<nodeType|HTML::Object::DOM::Node/nodeType> for space having a value C<SPACE_NODE> (13) and the non-standard constant C<SHOW_SPACE> in L<HTML::Object::DOM::NodeFilter>
549              
550             =back
551              
552             =head1 INHERITANCE
553              
554             +--------------+ +-------------------+
555             | HTML::Object | --> | HTML::Object::DOM |
556             +--------------+ +-------------------+
557              
558             =head1 CONSTRUCTOR
559              
560             =head2 new
561              
562             Provided with an hash or hash reference of options and this returns a new L<HTML::Object::DOM> object. Options available are the same as the methods available.
563              
564             =head1 METHODS
565              
566             =head2 current_parent
567              
568             This represent the parent for the current element being processed by the parser.
569              
570             =head2 document
571              
572             Set or get the L<element object|HTML::Object::DOM::Document> for the document.
573              
574             =head2 get_definition
575              
576             Provided with a tag name and this will return its corresponding L<hash reference|HTML::Object/dictionary> or C<undef> if there is no such tag or an L<error|Module::Generic/error> occurred somehow.
577              
578             =head2 get_dom
579              
580             Get the value for the global variable C<$GLOBAL_DOM>, which should be a L<HTML::Object::DOM::Document> object.
581              
582             =head2 new_closing
583              
584             Instantiates a new L<closing element|HTML::Object::DOM::Closing>, passing it any arguments received, and returns the new object.
585              
586             =head2 new_comment
587              
588             Instantiates a new L<comment element|HTML::Object::DOM::Comment>, passing it any arguments received, and returns the new object.
589              
590             =head2 new_declaration
591              
592             Instantiates a new L<declaration element|HTML::Object::DOM::Declaration>, passing it any arguments received, and returns the new object.
593              
594             =head2 new_document
595              
596             Instantiates a new L<document element|HTML::Object::DOM::Document>, passing it any arguments received, and returns the new object.
597              
598             The new document object has its property C<defaultView> set to a new L<window object|HTML::Object::DOM::Window>
599              
600             =head2 new_element
601              
602             Instantiates a new L<element|HTML::Object::DOM::Element>, passing it any arguments received, and returns the new object.
603              
604             =head2 new_space
605              
606             Instantiates a new L<space element|HTML::Object::DOM::Space>, passing it any arguments received, and returns the new object.
607              
608             =head2 new_text
609              
610             Instantiates a new L<text element|HTML::Object::DOM::Text>, passing it any arguments received, and returns the new object.
611              
612             =head2 new_window
613              
614             Instantiates a new L<window object|HTML::Object::DOM::Window>, passing it any arguments received, and returns the new object.
615              
616             =head2 onload
617              
618             Set or get the code reference to be executed when the parsing of the html data has been completed.
619              
620             The value of this code reference is provided to the new document when it is instantiated.
621              
622             Upon execution, C<$_> is set to the L<HTML document object|HTML::Object::DOM::Document>, and a new event is passed of type C<readstate> and with the C<detail> property having the following data available:
623              
624             =over 4
625              
626             =item document
627              
628             The L<document object|HTML::Object::DOM::Document>
629              
630             =item state
631              
632             The state of the document parsing.
633              
634             =back
635              
636             The event C<target> property is also set to the L<document object|HTML::Object::DOM::Document>.
637              
638             =head2 onreadystatechange
639              
640             Set or get the code reference to be executed whenever there is a change of state to the document. 3 states are available: C<loading>, C<interactive> and C<complete>
641              
642             The value of this code reference is provided to the new document when it is instantiated.
643              
644             Upon execution, C<$_> is set to the L<HTML document object|HTML::Object::DOM::Document>, and a new event is passed of type C<readstate> and with the C<detail> property having the following data available:
645              
646             =over 4
647              
648             =item document
649              
650             The L<document object|HTML::Object::DOM::Document>
651              
652             =item state
653              
654             The state of the document parsing.
655              
656             =back
657              
658             The event C<target> property is also set to the L<document object|HTML::Object::DOM::Document>.
659              
660             =head2 parseFromString
661              
662             Provided with some HTML data, and this will parse it and return a new L<document object|HTML::Object::DOM::Document> or C<undef> if an L<error|Module::Generic/error> occurred.
663              
664             =head2 screen
665              
666             Returns the L<HTML::Object::DOM::Screen> object.
667              
668             =head2 set_dom
669              
670             Set the global variable C<$GLOBAL_DOM> which must be a L<HTML::Object::DOM::Document>
671              
672             =head2 window
673              
674             Set or get the L<window object|HTML::Object::DOM::Window> for this new parser and the L<document|HTML::Object::DOM::Document> it creates.
675              
676             =head1 CONSTANTS
677              
678             The following constants can be exported and used, such as:
679              
680             use HTML::Object::DOM qw( :event );
681             # or directly
682             use HTML::Object::Event qw( :all );
683              
684             =over 4
685              
686             =item NONE (0)
687              
688             The event is not being processed at this time.
689              
690             =item CAPTURING_PHASE (1)
691              
692             The event is being propagated through the target's ancestor objects. This process starts with the L<Document|HTML::Object::Document>, then the L<HTML html element|HTML::Object::Element>, and so on through the elements until the target's parent is reached. Event listeners registered for capture mode when L<HTML::Object::EventTarget/addEventListener> was called are triggered during this phase.
693              
694             =item AT_TARGET (2)
695              
696             The event has arrived at the event's target. Event listeners registered for this phase are called at this time. If L</bubbles> is false, processing the event is finished after this phase is complete.
697              
698             =item BUBBLING_PHASE (3)
699              
700             The event is propagating back up through the target's ancestors in reverse order, starting with the parent, and eventually reaching the containing L<document|HTML::Object::Document>. This is known as bubbling, and occurs only if L</bubbles> is true. Event listeners registered for this phase are triggered during this process.
701              
702             =item CANCEL_PROPAGATION (1)
703              
704             State of the propagation being cancelled.
705              
706             $event->stopPropagation();
707             $event->cancelled == CANCEL_PROPAGATION;
708              
709             =item CANCEL_IMMEDIATE_PROPAGATION (2)
710              
711             State of immediate propagation being cancelled.
712              
713             $event->stopImmediatePropagation();
714             $event->cancelled == CANCEL_IMMEDIATE_PROPAGATION;
715              
716             =back
717              
718             For L<HTML::Object::DOM::Element::Media>:
719              
720             use HTML::Object::DOM qw( :media );
721             # or directly from HTML::Object::DOM::Element::Media
722             use HTML::Object::DOM::Element::Media qw( :all );
723              
724             =over 4
725              
726             =item NETWORK_EMPTY (0)
727              
728             There is no data yet. Also, readyState is HAVE_NOTHING.
729              
730             =item NETWORK_IDLE (1)
731              
732             L<Media element|HTML::Object::DOM::Element::Media> is active and has selected a resource, but is not using the network.
733              
734             =item NETWORK_LOADING (2)
735              
736             The browser is downloading L<HTML::Object::DOM::Element::Media> data.
737              
738             =item NETWORK_NO_SOURCE (3)
739              
740             No L<HTML::Object::DOM::Element::Media> src found.
741              
742             =back
743              
744             For L<HTML::Object::DOM::Element::Track>:
745              
746             use HTML::Object::DOM qw( :track );
747             # or directly from HTML::Object::DOM::Element::Track
748             use HTML::Object::DOM::Element::Track qw( :all );
749              
750             =over 4
751              
752             =item NONE (0)
753              
754             Indicates that the text track's cues have not been obtained.
755              
756             Also used in L<HTML::Object::Event> to indicate the event is not being processed at this time.
757              
758             =item LOADING (1)
759              
760             Indicates that the text track is loading and there have been no fatal errors encountered so far. Further cues might still be added to the track by the parser.
761              
762             =item LOADED (2)
763              
764             Indicates that the text track has been loaded with no fatal errors.
765              
766             =item ERROR (3)
767              
768             Indicates that the text track was enabled, but when the user agent attempted to obtain it, this failed in some way. Some or all of the cues are likely missing and will not be obtained.
769              
770             =back
771              
772             For L<HTML::Object::DOM::Node>:
773              
774             use HTML::Object::DOM qw( :node );
775             # or directly from HTML::Object::DOM::Node
776             # Automatically exported
777             use HTML::Object::DOM::Node;
778              
779             =over 4
780              
781             =item * DOCUMENT_POSITION_IDENTICAL (0 or in bits: 000000)
782              
783             Elements are identical.
784              
785             =item * DOCUMENT_POSITION_DISCONNECTED (1 or in bits: 000001)
786              
787             No relationship, both nodes are in different documents or different trees in the same document.
788              
789             =item * DOCUMENT_POSITION_PRECEDING (2 or in bits: 000010)
790              
791             The specified node precedes the current node.
792              
793             =item * DOCUMENT_POSITION_FOLLOWING (4 or in bits: 000100)
794              
795             The specified node follows the current node.
796              
797             =item * DOCUMENT_POSITION_CONTAINS (8 or in bits: 001000)
798              
799             The otherNode is an ancestor of / contains the current node.
800              
801             =item * DOCUMENT_POSITION_CONTAINED_BY (16 or in bits: 010000)
802              
803             The otherNode is a descendant of / contained by the node.
804              
805             =item * DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC (32 or in bits: 100000)
806              
807             The specified node and the current node have no common container node or the two nodes are different attributes of the same node.
808              
809             =back
810              
811             And also the following constants:
812              
813             =over 4
814              
815             =item ELEMENT_NODE (1)
816              
817             =item ATTRIBUTE_NODE (2)
818              
819             =item TEXT_NODE (3)
820              
821             =item CDATA_SECTION_NODE (4)
822              
823             =item ENTITY_REFERENCE_NODE (5)
824              
825             =item ENTITY_NODE (6)
826              
827             =item PROCESSING_INSTRUCTION_NODE (7)
828              
829             =item COMMENT_NODE (8)
830              
831             =item DOCUMENT_NODE (9)
832              
833             =item DOCUMENT_TYPE_NODE (10)
834              
835             =item DOCUMENT_FRAGMENT_NODE (11)
836              
837             =item NOTATION_NODE (12)
838              
839             =item SPACE_NODE (13)
840              
841             =back
842              
843             For L<HTML::Object::DOM::NodeFilter>:
844              
845             use HTML::Object::DOM qw( :filter );
846             # or directly from HTML::Object::DOM::NodeFilter
847             # Exportable constants
848             use HTML::Object::DOM::NodeFilter qw( :all );
849              
850             =over 4
851              
852             =item SHOW_ALL (4294967295)
853              
854             Shows all nodes.
855              
856             =item SHOW_ELEMENT (1)
857              
858             Shows Element nodes.
859              
860             =item SHOW_ATTRIBUTE (2)
861              
862             Shows attribute L<Attribute nodes|HTML::Object::DOM::Attribute>.
863              
864             =item SHOW_TEXT (4)
865              
866             Shows Text nodes.
867              
868             =item SHOW_CDATA_SECTION (8)
869              
870             Will always returns nothing, because there is no support for xml documents.
871              
872             =item SHOW_ENTITY_REFERENCE (16)
873              
874             Legacy, no more used.
875              
876             =item SHOW_ENTITY (32)
877              
878             Legacy, no more used.
879              
880             =item SHOW_PROCESSING_INSTRUCTION (64)
881              
882             Shows ProcessingInstruction nodes.
883              
884             =item SHOW_COMMENT (128)
885              
886             Shows Comment nodes.
887              
888             =item SHOW_DOCUMENT (256)
889              
890             Shows Document nodes
891              
892             =item SHOW_DOCUMENT_TYPE (512)
893              
894             Shows C<DocumentType> nodes
895              
896             =item SHOW_DOCUMENT_FRAGMENT (1024)
897              
898             Shows L<HTML::Object::DOM::DocumentFragment> nodes.
899              
900             =item SHOW_NOTATION (2048)
901              
902             Legacy, no more used.
903              
904             =item SHOW_SPACE (4096)
905              
906             Show Space nodes. This is a non-standard extension under this perl framework.
907              
908             =back
909              
910             For L<HTML::Object::DOM::XPathResult>:
911              
912             use HTML::Object::DOM qw( :xpath );
913             # or directly from HTML::Object::DOM::Element::Track
914             # Automatically exported
915             use HTML::Object::DOM::XPathResult;
916              
917             =over 4
918              
919             =item ANY_TYPE (0)
920              
921             A result set containing whatever type naturally results from evaluation of the expression. Note that if the result is a node-set then C<UNORDERED_NODE_ITERATOR_TYPE> is always the resulting type.
922              
923             =item NUMBER_TYPE (1)
924              
925             A result containing a single number. This is useful for example, in an XPath expression using the count() function.
926              
927             =item STRING_TYPE (2)
928              
929             A result containing a single string.
930              
931             =item BOOLEAN_TYPE (3)
932              
933             A result containing a single boolean value. This is useful for example, in an XPath expression using the not() function.
934              
935             =item UNORDERED_NODE_ITERATOR_TYPE (4)
936              
937             A result node-set containing all the nodes matching the expression. The nodes may not necessarily be in the same order that they appear in the document.
938              
939             =item ORDERED_NODE_ITERATOR_TYPE (5)
940              
941             A result node-set containing all the nodes matching the expression. The nodes in the result set are in the same order that they appear in the document.
942              
943             =item UNORDERED_NODE_SNAPSHOT_TYPE (6)
944              
945             A result node-set containing snapshots of all the nodes matching the expression. The nodes may not necessarily be in the same order that they appear in the document.
946              
947             =item ORDERED_NODE_SNAPSHOT_TYPE (7)
948              
949             A result node-set containing snapshots of all the nodes matching the expression. The nodes in the result set are in the same order that they appear in the document.
950              
951             =item ANY_UNORDERED_NODE_TYPE (8)
952              
953             A result node-set containing any single node that matches the expression. The node is not necessarily the first node in the document that matches the expression.
954              
955             =item FIRST_ORDERED_NODE_TYPE (9)
956              
957             A result node-set containing the first node in the document that matches the expression.
958              
959             =back
960              
961             =head1 AUTHOR
962              
963             Jacques Deguest E<lt>F<jack@deguest.jp>E<gt>
964              
965             =head1 SEE ALSO
966              
967             L<Mozilla documentation|https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model>
968              
969             L<Mozilla documentation on HTML DOM API|https://developer.mozilla.org/en-US/docs/Web/API/HTML_DOM_API>
970              
971             L<W3C standard|https://html.spec.whatwg.org/multipage/dom.html>, L<HTML elements specifications|https://html.spec.whatwg.org/>
972              
973             =head1 COPYRIGHT & LICENSE
974              
975             Copyright(c) 2021 DEGUEST Pte. Ltd.
976              
977             All rights reserved
978              
979             This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
980              
981             =cut