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   83 use strict;
  25         25  
  25         596  
4 25     25   71 use warnings;
  25         28  
  25         666  
5              
6 25     25   81 use HTML::DOM::Exception qw'NOT_FOUND_ERR';
  25         23  
  25         815  
7 25     25   86 use HTML::DOM::_FieldHash;
  25         19  
  25         1117  
8 25     25   86 use Scalar::Util 'weaken';
  25         18  
  25         3270  
9              
10             our $VERSION = '0.056';
11              
12             fieldhashes \my(%a, %h);
13              
14             use overload fallback => 1,
15             '@{}' => sub {
16 7     7   7 my $self = ${+shift};
  7         11  
17 7   66     39 $a{$self} ||= do {
18 1         1 my $t = [];
19 1         6 tie @$t, __PACKAGE__."'_atie", $self;
20 1         8 $t
21             };
22             },
23             '%{}' => sub {
24 7     7   8 my $self = ${+shift};
  7         9  
25 7   66     39 $h{$self} ||= do {
26 1         1 my $t = {};
27 1         6 tie %$t, __PACKAGE__."'_htie", $self;
28 1         7 $t
29             };
30 25     25   93 };
  25         22  
  25         165  
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 35 my $map = bless \(my $elem = $_[1]), shift;
37 19         210 weaken $$map;
38 19         59 $map;
39             }
40              
41             sub getNamedItem {
42 4     4 0 6 ${+shift}->getAttributeNode(shift);
  4         12  
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 2 my($elem,$name) = (${+shift},shift);
  1         3  
55 1         3 my $attr = $elem->attr($name);
56 1 50       3 defined $attr or die HTML::DOM::Exception->new(NOT_FOUND_ERR,
57             "No attribute named $name exists");
58 1 50       2 if(ref $attr) {
59 1         3 $elem->attr($name, undef);
60 1         3 $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 17 my $elem = ${+shift};
  19         22  
73 19         61 my $name = (sort $elem->all_external_attr_names)[shift];
74 19 50       37 defined $name or return;
75 19         35 $elem->getAttributeNode($name);
76             }
77              
78             sub length {
79 22     22 0 44 scalar(() = ${$_[0]}-> all_external_attr_names);
  22         64  
80             }
81              
82             package HTML::DOM::NamedNodeMap::_atie;
83              
84             our @ISA = "Tie::Array";
85              
86             sub TIEARRAY {
87 1     1   399 require Tie::Array;
88 1         771 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   391 require Tie::Hash;
101 1         623 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         2  
109 1         3 goto &NEXTKEY;
110             }
111             sub NEXTKEY {
112 3     3   2 my $elem = ${+shift};
  3         2  
113 3         8 while (defined($_ = each %$elem)) {
114 6 100       18 return $_ unless /^_/;
115             }
116 1         6 return undef;
117             }
118             sub EXISTS {
119 3     3   2 my($elem,$name) = (${+shift},shift);
  3         5  
120 3         8 defined $elem->attr($name);
121             }
122             sub DELETE {
123 1     1   2 my($elem,$name) = (${+shift},shift);
  1         2  
124 1         3 $elem->attr($name, undef);
125             }
126             sub CLEAR {
127 1     1   1 my $elem = ${+shift};
  1         1  
128 1         3 $elem->attr($_,undef) for $elem->all_external_attr_names;
129             }
130             *SCALAR = *HTML::DOM::NamedNodeMap::length;
131              
132             1