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   21 use strict;
  3         5  
  3         109  
3 3     3   15 use warnings;
  3         5  
  3         161  
4              
5 3     3   15 use HTML5::DOM::Node;
  3         6  
  3         288  
6              
7             use overload
8 0     0   0 '""' => sub { $_[0]->text },
9 4     4   8 '@{}' => sub { $_[0]->_items },
10 0     0   0 'bool' => sub { 1 },
11 3     3   18 fallback => 1;
  3         9  
  3         29  
12              
13             sub new {
14 17     17 0 36 my ($class, $node, $attr) = @_;
15 17         42 my $self = {
16             node => $node,
17             attr => $attr
18             };
19 17         29 bless $self, $class;
20 17         134 return $self;
21             }
22              
23             sub text {
24 4     4 0 19 my $attr = $_[0]->{node}->attr($_[0]->{attr});
25 4 50       19 return defined $attr ? $attr : "";
26             }
27              
28             sub _items {
29 9     9   18 my ($self) = @_;
30 9         167 my $attr = $self->{node}->attr($self->{attr});
31 9 50       26 if (defined $attr) {
32 9         23 my @items = split(/\s+/, $attr);
33 9 50 66     26 return [] if (scalar(@items) == 1 && $items[0] eq '');
34 9         44 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         2 return scalar(@{$self->_items()});
  2         4  
47             }
48              
49             sub has {
50 8     8 0 11 my ($self, $token) = @_;
51 8         24 my $attr = $self->{node}->attr($self->{attr});
52 8 50       12 if (defined $attr) {
53 8         321 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         39 my $items = $self->_items();
63 2         6 for my $token (@_) {
64 8 100       17 next if ($self->has($token));
65 5         11 push @$items, $token;
66             }
67 2         16 $self->{node}->attr($self->{attr}, join(" ", @$items));
68 2         10 return $self;
69             }
70              
71             sub remove {
72 2     2 0 203 my $self = shift;
73 2         18 my $attr = $self->{node}->attr($self->{attr});
74 2 50       9 if (defined $attr) {
75 2         5 for my $token (@_) {
76 7         267 $attr =~ s/(\s|^)\Q$token\E(\s|$)/ /g;
77             }
78 2         11 $attr =~ s/^\s+|\s+$//;
79 2         15 $self->{node}->attr($self->{attr}, $attr);
80             }
81 2         9 return $self;
82             }
83              
84             sub replace {
85 1     1 0 3 my ($self, $key, $value) = @_;
86 1         8 my $attr = $self->{node}->attr($self->{attr});
87 1 50       4 if (defined $attr) {
88 1         49 $attr =~ s/(\s|^)\Q$key\E(\s|$)/$1$value$2/g;
89 1         8 $self->{node}->attr($self->{attr}, $attr);
90             }
91 1         5 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 2 my ($self, $callback) = @_;
103 1         2 my $index = 0;
104 1         2 for my $node (@{$self->_items()}) {
  1         2  
105 4         11 $callback->($node, $index);
106 4         913 ++$index;
107             }
108 1         6 return $self;
109             }
110              
111             1;