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