File Coverage

blib/lib/HTML5/DOM/TokenList.pm
Criterion Covered Total %
statement 60 71 84.5
branch 8 18 44.4
condition 2 3 66.6
subroutine 14 19 73.6
pod 0 11 0.0
total 84 122 68.8


line stmt bran cond sub pod time code
1             package HTML5::DOM::TokenList;
2 3     3   22 use strict;
  3         6  
  3         88  
3 3     3   15 use warnings;
  3         5  
  3         69  
4              
5 3     3   17 use HTML5::DOM::Node;
  3         4  
  3         299  
6              
7             use overload
8 0     0   0 '""' => sub { $_[0]->text },
9 4     4   11 '@{}' => sub { $_[0]->_items },
10 0     0   0 'bool' => sub { 1 },
11 3     3   21 fallback => 1;
  3         15  
  3         73  
12              
13             sub new {
14 17     17 0 36 my ($class, $node, $attr) = @_;
15 17         45 my $self = {
16             node => $node,
17             attr => $attr
18             };
19 17         33 bless $self, $class;
20 17         90 return $self;
21             }
22              
23             sub text {
24 4     4 0 24 my $attr = $_[0]->{node}->attr($_[0]->{attr});
25 4 50       32 return defined $attr ? $attr : "";
26             }
27              
28             sub _items {
29 9     9   18 my ($self) = @_;
30 9         82 my $attr = $self->{node}->attr($self->{attr});
31 9 50       26 if (defined $attr) {
32 9         53 my @items = split(/\s+/, $attr);
33 9 50 66     37 return [] if (scalar(@items) == 1 && $items[0] eq '');
34 9         57 return \@items;
35             }
36 0         0 return [];
37             }
38              
39             sub item {
40 0     0 0 0 my ($self, $index) = @_;
41 0         0 return $self->_items()->[$index];
42             }
43              
44             sub length {
45 2     2 0 5 my ($self) = @_;
46 2         5 return scalar(@{$self->_items()});
  2         6  
47             }
48              
49             sub has {
50 8     8 0 15 my ($self, $token) = @_;
51 8         28 my $attr = $self->{node}->attr($self->{attr});
52 8 50       20 if (defined $attr) {
53 8         179 return $attr =~ /(\s|^)\Q$token\E(\s|$)/;
54             }
55 0         0 return 0;
56             }
57              
58 0     0 0 0 sub contains { shift->has(@_) }
59              
60             sub add {
61 2     2 0 4 my $self = shift;
62 2         9 my $items = $self->_items();
63 2         6 for my $token (@_) {
64 8 100       21 next if ($self->has($token));
65 5         15 push @$items, $token;
66             }
67 2         21 $self->{node}->attr($self->{attr}, join(" ", @$items));
68 2         12 return $self;
69             }
70              
71             sub remove {
72 2     2 0 5 my $self = shift;
73 2         14 my $attr = $self->{node}->attr($self->{attr});
74 2 50       8 if (defined $attr) {
75 2         6 for my $token (@_) {
76 7         140 $attr =~ s/(\s|^)\Q$token\E(\s|$)/ /g;
77             }
78 2         8 $attr =~ s/^\s+|\s+$//;
79 2         16 $self->{node}->attr($self->{attr}, $attr);
80             }
81 2         12 return $self;
82             }
83              
84             sub replace {
85 1     1 0 8 my ($self, $key, $value) = @_;
86 1         13 my $attr = $self->{node}->attr($self->{attr});
87 1 50       5 if (defined $attr) {
88 1         39 $attr =~ s/(\s|^)\Q$key\E(\s|$)/$1$value$2/g;
89 1         9 $self->{node}->attr($self->{attr}, $attr);
90             }
91 1         6 return $self;
92             }
93              
94             sub toggle {
95 0     0 0 0 my ($self, $token, $force) = @_;
96 0 0       0 my $state = defined $force ? $force : !$self->has($token);
97 0 0       0 $state ? $self->add($token) : $self->remove($token);
98 0         0 return $state;
99             }
100              
101             sub each {
102 1     1 0 3 my ($self, $callback) = @_;
103 1         3 my $index = 0;
104 1         3 for my $node (@{$self->_items()}) {
  1         3  
105 4         14 $callback->($node, $index);
106 4         1211 ++$index;
107             }
108 1         8 return $self;
109             }
110              
111             1;