File Coverage

blib/lib/Mojolicious/Plugin/AssetPack/Asset.pm
Criterion Covered Total %
statement 36 45 80.0
branch 12 16 75.0
condition n/a
subroutine 10 13 76.9
pod 7 7 100.0
total 65 81 80.2


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::AssetPack::Asset;
2 16     16   11983 use Mojo::Base -base;
  16         44  
  16         191  
3              
4 16     16   4263 use Mojo::Asset::Memory;
  16         39  
  16         258  
5 16     16   655 use Mojo::URL;
  16         68  
  16         204  
6 16     16   553 use Mojo::File;
  16         41  
  16         1047  
7 16     16   118 use Mojolicious::Plugin::AssetPack::Util qw(diag has_ro DEBUG);
  16         30  
  16         33164  
8              
9             my %TAG_TEMPLATE;
10             $TAG_TEMPLATE{css} = [qw(link rel stylesheet href)];
11             $TAG_TEMPLATE{ico} = [qw(link rel icon href)];
12             $TAG_TEMPLATE{js} = [qw(script src)];
13             $TAG_TEMPLATE{$_} = [qw(img src)] for qw(gif jpg jpeg png svg);
14             $TAG_TEMPLATE{$_} = [qw(source src)] for qw(mp3 mp4 ogg ogv webm);
15              
16             has checksum => sub { Mojolicious::Plugin::AssetPack::Util::checksum(shift->content) };
17             has format => sub {
18             my $self = shift;
19             my $name = $self->url =~ /^https?:/ ? Mojo::URL->new($self->url)->path->[-1] : (split m!(\\|/)!, $self->url)[-1];
20              
21             return $name =~ /\.(\w+)$/ ? lc $1 : '';
22             };
23              
24             has minified => sub { shift->url =~ /\bmin\b/ ? 1 : 0 };
25             has renderer => undef;
26             has tag_for => sub { \&_default_tag_for };
27              
28             has _asset => sub {
29             my $self = shift;
30             return $self->content(delete $self->{content})->_asset if $self->{content};
31             return Mojo::Asset::File->new(path => delete $self->{path}) if $self->{path};
32             return Mojo::Asset::Memory->new;
33             };
34              
35             has_ro name => sub {
36             my $self = shift;
37             my $name;
38              
39             if ($self->url =~ /^https?:/) {
40             my $url = Mojo::URL->new($self->url);
41             my $qs = $url->query->to_string;
42             $name = $url->path->[-1];
43             $qs =~ s!\W!_!g;
44             $name =~ s!\.\w+$!!;
45             $name .= "_$qs" if $qs;
46             }
47             else {
48             $name = (split m!(\\|/)!, $self->url)[-1];
49             $name =~ s!\.\w+$!!;
50             }
51              
52             return $name;
53             };
54              
55             has_ro 'url';
56              
57             sub asset {
58 25     25 1 83 my $self = shift;
59 25         104 my $orig = $self->_asset;
60 25         230 my $clone = $orig->new;
61              
62 25 100       626 if ($orig->is_file) {
63 13         152 $clone->cleanup(0)->path($orig->path);
64             }
65             else {
66 12         126 $clone->auto_upgrade(0)->mtime($orig->mtime)->add_chunk($orig->slurp);
67             }
68              
69 25         1139 return $clone;
70             }
71              
72             sub content {
73 102     102 1 1309 my $self = shift;
74 102 100       456 return $self->_asset->slurp unless @_;
75 50 100       342 return $self->_asset($_[0]->_asset) if UNIVERSAL::isa($_[0], __PACKAGE__);
76 44 100       323 return $self->_asset($_[0]) if UNIVERSAL::isa($_[0], 'Mojo::Asset');
77 12         73 return $self->_asset(Mojo::Asset::Memory->new->add_chunk($_[0]));
78             }
79              
80             sub path {
81 0     0 1 0 my $self = shift;
82 0 0       0 return $self->_asset(Mojo::Asset::File->new(path => $_[0])) if $_[0];
83 0 0       0 return Mojo::File->new($self->_asset->path) if $self->_asset->isa('Mojo::Asset::File');
84 0         0 return undef;
85             }
86              
87 0     0 1 0 sub size { $_[0]->_asset->size }
88              
89 82     82 1 1827 sub url_for { $_[1]->url_for(assetpack => $_[0]->TO_JSON); }
90              
91             sub _default_tag_for {
92 80     80   405 my ($asset, $c, $args, @attrs) = @_;
93 80         316 my $url = $asset->url_for($c);
94 80 100       40903 my @template = @{$TAG_TEMPLATE{$asset->format} || $TAG_TEMPLATE{css}};
  80         353  
95 80 100       987 splice @template, 1, 0, type => $c->app->types->type($asset->format) if $template[0] eq 'source';
96 80         1452 return $c->tag(@template, Mojo::URL->new("$args->{base_url}$url"), @attrs);
97             }
98              
99             sub FROM_JSON {
100 0     0 1 0 my ($self, $attrs) = @_;
101 0         0 $self->$_($attrs->{$_}) for grep { defined $attrs->{$_} } qw(checksum format minified);
  0         0  
102 0         0 $self;
103             }
104              
105             sub TO_JSON {
106 90     90 1 207 return {map { ($_ => $_[0]->$_) } qw(checksum format minified name url)};
  450         2158  
107             }
108              
109             1;
110              
111             =encoding utf8
112              
113             =head1 NAME
114              
115             Mojolicious::Plugin::AssetPack::Asset - An asset
116              
117             =head1 DESCRIPTION
118              
119             L represents an asset.
120              
121             =head1 SYNOPSIS
122              
123             use Mojolicious::Plugin::AssetPack::Asset;
124             my $asset = Mojolicious::Plugin::AssetPack::Asset->new(url => "...");
125              
126             =head1 ATTRIBUTES
127              
128             =head2 checksum
129              
130             $str = $self->checksum;
131             $self = $self->checksum($str);
132              
133             The L of L.
134              
135             =head2 format
136              
137             $str = $self->format;
138             $self = $self->format($str);
139              
140             The format of L. Defaults to the extension of L or empty string.
141              
142             =head2 minified
143              
144             $bool = $self->minified;
145             $self = $self->minified($bool);
146              
147             Will be set to true if either L contains "min" or if a pipe has
148             minified L.
149              
150             =head2 name
151              
152             $str = $self->name;
153              
154             Returns the basename of L, without extension.
155              
156             =head2 renderer
157              
158             $code = $self->renderer;
159             $self = $self->renderer(sub { my ($self, $c) = @_; $c->render(data => "...""); })
160              
161             Can be used to register a custom render method for this asset. This is called
162             by L.
163              
164             =head2 tag_for
165              
166             $code = $self->tag_for;
167             $self = $self->tag_for(sub { my ($c, \%args, @attrs) = @_; return qq() });
168              
169             Used to register a custom tag renderer for this asset. The arguments passed
170             in are:
171              
172             =over 2
173              
174             =item * C<$c>
175              
176             The L object used for this request.
177              
178             =item * C<%args>
179              
180             A hash-ref with "base_url" and
181             L.
182              
183             =item * C<@attrs>
184              
185             The HTML attributes passed in from the template.
186              
187             =item
188              
189             =back
190              
191             =head2 url
192              
193             $str = $self->url;
194              
195             Returns the location of the asset.
196              
197             =head1 METHODS
198              
199             =head2 asset
200              
201             $asset = $self->asset;
202              
203             Returns a new L or L object, with the
204             content or path from this object.
205              
206             This method is EXPERIMENTAL.
207              
208             =head2 content
209              
210             $bytes = $self->content;
211             $self = $self->content($bytes);
212             $self = $self->content(Mojo::Asset::Memory->new);
213              
214             Used to get or set the content of this asset. The default will be built from
215             passing L to L.
216              
217             =head2 path
218              
219             $str = $self->path;
220              
221             Returns a L object that holds the location to the asset on disk or
222             C if this asset is in memory.
223              
224             =head2 size
225              
226             $int = $self->size;
227              
228             Returns the size of the asset in bytes.
229              
230             =head2 url_for
231              
232             $url = $self->url_for($c);
233              
234             Returns a L object for this asset. C<$c> need to be a
235             L.
236              
237             =head2 FROM_JSON
238              
239             $self = $self->FROM_JSON($hash_ref);
240              
241             The opposite of L. Will set the read/write L from the
242             values in C<$hash_ref>.
243              
244             =head2 TO_JSON
245              
246             $hash_ref = $self->FROM_JSON;
247              
248             The opposite of L. Will generate a hash ref from L.
249              
250             =head1 SEE ALSO
251              
252             L.
253              
254             =cut