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   25844876 use strict;
  28         315  
  28         816  
18 28     28   155 use warnings;
  28         50  
  28         845  
19 28     28   10201 use parent qw( HTML::Object );
  28         6901  
  28         174  
20 28     28   4325 use vars qw( @EXPORT_OK %EXPORT_TAGS $SCREEN $WINDOW $TAG_TO_CLASS $GLOBAL_DOM $VERSION );
  28         131  
  28         4241  
21 28     28   19736 use HTML::Object::DOM::Closing;
  28         90  
  28         2030  
22 28     28   25932 use HTML::Object::DOM::Comment;
  28         121  
  28         409  
23 28     28   18079 use HTML::Object::DOM::Declaration;
  28         62  
  28         426  
24 28     28   26312 use HTML::Object::DOM::Document;
  28         98  
  28         475  
25 28     28   9497 use HTML::Object::DOM::Element;
  28         69  
  28         451  
26 28     28   17015 use HTML::Object::DOM::Space;
  28         88  
  28         405  
27 28     28   17807 use HTML::Object::DOM::Text;
  28         97  
  28         426  
28 28     28   17973 use HTML::Object::DOM::Screen;
  28         75  
  28         360  
29 28     28   21380 use HTML::Object::DOM::Window;
  28         97  
  28         373  
30 28     28   7051 use Scalar::Util ();
  28         65  
  28         3023  
31             use constant {
32             # For HTML::Object::DOM::Node
33 28         21349 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   182 };
  28         54  
143 28     28   465 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         560 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         315 $EXPORT_TAGS{all} = [@EXPORT_OK];
228 28         472 our $SCREEN = HTML::Object::DOM::Screen->new;
229 28         168 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         54 our $TAG_TO_CLASS = {};
232 28         41 our $GLOBAL_DOM;
233 28         1090 our $VERSION = 'v0.2.0';
234             };
235              
236 28     28   214 use strict;
  28         58  
  28         621  
237 28     28   225 use warnings;
  28         53  
  28         30677  
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 167163 my $self = shift( @_ );
366 69         2372 $self->{onload} = undef;
367 69         244 $self->{onreadystatechange} = undef;
368 69         255 $self->{_init_strict_use_sub} = 1;
369 69 50       525 $self->SUPER::init( @_ ) || return( $self->pass_error );
370 69         515 my $win = $self->new_window( debug => $self->debug );
371 69         367 $self->window( $win );
372 69         3225 return( $self );
373             }
374              
375 1725     1725 1 7210 sub current_parent { return( shift->_set_get_object_without_init( 'current_parent', 'HTML::Object::DOM::Node', @_ ) ); }
376              
377 106     106 1 468 sub document { return( shift->_set_get_object( 'document', 'HTML::Object::DOM::Document', @_ ) ); }
378              
379             sub get_definition
380             {
381 305     305 1 2877 my $self = shift( @_ );
382 305         778 my $tag = shift( @_ );
383 305 50       1219 return( $self->error( "No tag was provided to get its definition." ) ) if( !length( $tag ) );
384             # Just to be sure
385 305         812 $tag = lc( $tag );
386 305   50     1882 my $def = $self->SUPER::get_definition( $tag, @_ ) || return( $self->pass_error );
387 305 100       2484 $def->{class} = $TAG_TO_CLASS->{ $tag } if( CORE::exists( $TAG_TO_CLASS->{ $tag } ) );
388 305         896 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 6649 my $self = shift( @_ );
396 198   50     1541 my $e = HTML::Object::DOM::Closing->new( @_ ) ||
397             return( $self->pass_error( HTML::Object::DOM::Closing->error ) );
398 198         3217 return( $e );
399             }
400              
401             sub new_comment
402             {
403 6     6 1 236 my $self = shift( @_ );
404 6   50     145 my $e = HTML::Object::DOM::Comment->new( @_ ) ||
405             return( $self->pass_error( HTML::Object::DOM::Comment->error ) );
406 6         88 return( $e );
407             }
408              
409             sub new_declaration
410             {
411 18     18 1 574 my $self = shift( @_ );
412 18   50     297 my $e = HTML::Object::DOM::Declaration->new( @_ ) ||
413             return( $self->pass_error( HTML::Object::DOM::Declaration->error ) );
414 18         291 return( $e );
415             }
416              
417             sub new_document
418             {
419 51     51 1 12147527 my $self = shift( @_ );
420 51   50     654 my $e = HTML::Object::DOM::Document->new( @_ ) ||
421             return( $self->pass_error( HTML::Object::DOM::Document->error ) );
422 51         638 my $win = $self->window;
423 51         1639 $e->defaultView( $win );
424 51         45108 return( $e );
425             }
426              
427             sub new_element
428             {
429 30     30 1 9289 my $self = shift( @_ );
430 30   50     285 my $e = HTML::Object::DOM::Element->new( @_ ) ||
431             return( $self->pass_error( HTML::Object::DOM::Element->error ) );
432 30         407 return( $e );
433             }
434              
435             sub new_space
436             {
437 332     332 1 1080 my $self = shift( @_ );
438 332   50     2466 my $e = HTML::Object::DOM::Space->new( @_ ) ||
439             return( $self->pass_error( HTML::Object::DOM::Space->error ) );
440 332         5087 return( $e );
441             }
442              
443             sub new_text
444             {
445 107     107 1 3389 my $self = shift( @_ );
446 107   50     955 my $e = HTML::Object::DOM::Text->new( @_ ) ||
447             return( $self->pass_error( HTML::Object::DOM::Text->error ) );
448 107         1755 return( $e );
449             }
450              
451             sub new_window
452             {
453 69     69 1 1850 my $self = shift( @_ );
454 69   50     921 my $e = HTML::Object::DOM::Window->new( @_ ) ||
455             return( $self->pass_error( HTML::Object::DOM::Window->error ) );
456 69         896 $e->screen( $SCREEN );
457 69 100       61639 $WINDOW = $e unless( ref( $WINDOW ) );
458 69         226 return( $e );
459             }
460              
461 48     48 1 650 sub onload : lvalue { return( shift->_set_get_code( 'onload', @_ ) ); }
462              
463 47     47 1 1261 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 9519 my( $this, $html ) = @_;
472 2 50       10 if( defined( $html ) )
473             {
474 2 50 33     67 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         16 $GLOBAL_DOM = $this->new->parse( $html );
481             }
482             }
483 2         11 return( $this );
484             }
485              
486             sub window
487             {
488 120 50   120 1 485 if( !scalar( @_ ) )
489             {
490 0         0 return( $WINDOW );
491             }
492 120         380 my $self = shift( @_ );
493 120 50       629 if( Scalar::Util::blessed( $self ) )
494             {
495 120 50       598 if( $self->isa( 'HTML::Object::DOM' ) )
496             {
497 120         875 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