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   86 use strict;
  25         30  
  25         564  
4 25     25   77 use warnings;
  25         27  
  25         739  
5              
6 25     25   84 use HTML::DOM::Exception qw'NOT_FOUND_ERR';
  25         28  
  25         835  
7 25     25   85 use HTML::DOM::_FieldHash;
  25         23  
  25         860  
8 25     25   81 use Scalar::Util 'weaken';
  25         25  
  25         3278  
9              
10             our $VERSION = '0.057';
11              
12             fieldhashes \my(%a, %h);
13              
14             use overload fallback => 1,
15             '@{}' => sub {
16 7     7   11 my $self = ${+shift};
  7         9  
17 7   66     48 $a{$self} ||= do {
18 1         3 my $t = [];
19 1         7 tie @$t, __PACKAGE__."'_atie", $self;
20 1         24 $t
21             };
22             },
23             '%{}' => sub {
24 7     7   8 my $self = ${+shift};
  7         12  
25 7   66     48 $h{$self} ||= do {
26 1         2 my $t = {};
27 1         7 tie %$t, __PACKAGE__."'_htie", $self;
28 1         9 $t
29             };
30 25     25   103 };
  25         26  
  25         173  
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 39 my $map = bless \(my $elem = $_[1]), shift;
37 19         263 weaken $$map;
38 19         71 $map;
39             }
40              
41             sub getNamedItem {
42 4     4 0 7 ${+shift}->getAttributeNode(shift);
  4         16  
43             }
44              
45             sub setNamedItem {
46 2     2 0 3 ${+shift}->setAttributeNode(shift);
  2         11  
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       4 if(ref $attr) {
59 1         3 $elem->attr($name, undef);
60 1         3 $attr->_element(undef);
61 1         6 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 16 my $elem = ${+shift};
  19         24  
73 19         43 my $name = (sort $elem->all_external_attr_names)[shift];
74 19 50       43 defined $name or return;
75 19         41 $elem->getAttributeNode($name);
76             }
77              
78             sub length {
79 22     22 0 36 scalar(() = ${$_[0]}-> all_external_attr_names);
  22         74  
80             }
81              
82             package HTML::DOM::NamedNodeMap::_atie;
83              
84             our @ISA = "Tie::Array";
85              
86             sub TIEARRAY {
87 1     1   479 require Tie::Array;
88 1         861 goto &HTML::DOM'NamedNodeMap'new;
89             }
90              
91             *FETCH = *HTML::DOM::NamedNodeMap::item;
92             *FETCHSIZE = *HTML::DOM::NamedNodeMap::length;
93 4 50   4   14 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   433 require Tie::Hash;
101 1         700 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   3 my $elem = ${+shift};
  3         4  
113 3         8 while (defined($_ = each %$elem)) {
114 6 100       21 return $_ unless /^_/;
115             }
116 1         9 return undef;
117             }
118             sub EXISTS {
119 3     3   3 my($elem,$name) = (${+shift},shift);
  3         6  
120 3         7 defined $elem->attr($name);
121             }
122             sub DELETE {
123 1     1   2 my($elem,$name) = (${+shift},shift);
  1         2  
124 1         5 $elem->attr($name, undef);
125             }
126             sub CLEAR {
127 1     1   1 my $elem = ${+shift};
  1         2  
128 1         3 $elem->attr($_,undef) for $elem->all_external_attr_names;
129             }
130             *SCALAR = *HTML::DOM::NamedNodeMap::length;
131              
132             1