File Coverage

blib/lib/HTML/DOM/NamedNodeMap.pm
Criterion Covered Total %
statement 74 78 94.8
branch 6 10 60.0
condition 4 6 66.6
subroutine 22 22 100.0
pod 0 6 0.0
total 106 122 86.8


line stmt bran cond sub pod time code
1             package HTML::DOM::NamedNodeMap;
2              
3 25     25   160 use strict;
  25         45  
  25         587  
4 25     25   104 use warnings;
  25         38  
  25         589  
5              
6 25     25   102 use HTML::DOM::Exception qw'NOT_FOUND_ERR';
  25         39  
  25         820  
7 25     25   109 use HTML::DOM::_FieldHash;
  25         37  
  25         892  
8 25     25   113 use Scalar::Util 'weaken';
  25         39  
  25         4006  
9              
10             our $VERSION = '0.058';
11              
12             fieldhashes \my(%a, %h);
13              
14             use overload fallback => 1,
15             '@{}' => sub {
16 7     7   13 my $self = ${+shift};
  7         11  
17 7   66     43 $a{$self} ||= do {
18 1         3 my $t = [];
19 1         7 tie @$t, __PACKAGE__."'_atie", $self;
20 1         7 $t
21             };
22             },
23             '%{}' => sub {
24 7     7   12 my $self = ${+shift};
  7         14  
25 7   66     47 $h{$self} ||= do {
26 1         2 my $t = {};
27 1         7 tie %$t, __PACKAGE__."'_htie", $self;
28 1         18 $t
29             };
30 25     25   147 };
  25         37  
  25         210  
31              
32              
33             # This object stores nothing more than the Element object whose attributes
34             # it purports to hold.
35             sub new { # [0] class [1] element obj
36 19     19 0 46 my $map = bless \(my $elem = $_[1]), shift;
37 19         143 weaken $$map;
38 19         63 $map;
39             }
40              
41             sub getNamedItem {
42 4     4 0 11 ${+shift}->getAttributeNode(shift);
  4         15  
43             }
44              
45             sub setNamedItem {
46 2     2 0 2 ${+shift}->setAttributeNode(shift);
  2         9  
47             }
48              
49             sub removeNamedItem {
50             # The spec contradicts itself slightly. It says that null is
51             # returned if no node with such a name exists, but then it says
52             # that a NOT_FOUND_ERR is thrown if no node with such a name
53             # exists. I can't do both.
54 1     1 0 3 my($elem,$name) = (${+shift},shift);
  1         3  
55 1         4 my $attr = $elem->attr($name);
56 1 50       4 defined $attr or die HTML::DOM::Exception->new(NOT_FOUND_ERR,
57             "No attribute named $name exists");
58 1 50       3 if(ref $attr) {
59 1         2 $elem->attr($name, undef);
60 1         4 $attr->_element(undef);
61 1         5 return $attr
62             }
63             else {
64 0         0 my $new_attr = HTML::DOM::Attr->new($name);
65 0         0 $new_attr->_set_ownerDocument($elem->ownerDocument);
66 0         0 $new_attr->value($attr);
67 0         0 return $new_attr;
68             }
69             }
70              
71             sub item {
72 19     19 0 31 my $elem = ${+shift};
  19         28  
73 19         44 my $name = (sort $elem->all_external_attr_names)[shift];
74 19 50       46 defined $name or return;
75 19         49 $elem->getAttributeNode($name);
76             }
77              
78             sub length {
79 22     22 0 48 scalar(() = ${$_[0]}-> all_external_attr_names);
  22         75  
80             }
81              
82             package HTML::DOM::NamedNodeMap::_atie;
83              
84             our @ISA = "Tie::Array";
85              
86             sub TIEARRAY {
87 1     1   388 require Tie::Array;
88 1         932 goto &HTML::DOM'NamedNodeMap'new;
89             }
90              
91             *FETCH = *HTML::DOM::NamedNodeMap::item;
92             *FETCHSIZE = *HTML::DOM::NamedNodeMap::length;
93 4 50   4   12 sub EXISTS { $_[1] >=0 && $_[1] < &FETCHSIZE }
94              
95             package HTML::DOM::NamedNodeMap::_htie;
96              
97             our @ISA = "Tie::Hash";
98              
99             sub TIEHASH {
100 1     1   406 require Tie::Hash;
101 1         750 goto &HTML::DOM'NamedNodeMap'new;
102             }
103             *STORE = *HTML'DOM'NamedNodeMap'setNamedItem;
104             *FETCH = *HTML'DOM'NamedNodeMap'getNamedItem;
105              
106             sub FIRSTKEY {
107             # reset iterator; I don’t *think* any other code uses it.
108 1     1   2 keys %${$_[0]};
  1         3  
109 1         4 goto &NEXTKEY;
110             }
111             sub NEXTKEY {
112 3     3   5 my $elem = ${+shift};
  3         4  
113 3         7 while (defined($_ = each %$elem)) {
114 6 100       22 return $_ unless /^_/;
115             }
116 1         8 return undef;
117             }
118             sub EXISTS {
119 3     3   4 my($elem,$name) = (${+shift},shift);
  3         8  
120 3         9 defined $elem->attr($name);
121             }
122             sub DELETE {
123 1     1   3 my($elem,$name) = (${+shift},shift);
  1         3  
124 1         3 $elem->attr($name, undef);
125             }
126             sub CLEAR {
127 1     1   2 my $elem = ${+shift};
  1         2  
128 1         5 $elem->attr($_,undef) for $elem->all_external_attr_names;
129             }
130             *SCALAR = *HTML::DOM::NamedNodeMap::length;
131              
132             1