File: Asset.pm

package info (click to toggle)
libmojolicious-plugin-assetpack-perl 2.15-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,888 kB
  • sloc: perl: 1,503; javascript: 52; makefile: 8; sh: 2
file content (254 lines) | stat: -rw-r--r-- 5,938 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
package Mojolicious::Plugin::AssetPack::Asset;
use Mojo::Base -base;

use Mojo::Asset::Memory;
use Mojo::URL;
use Mojo::File;
use Mojolicious::Plugin::AssetPack::Util qw(diag has_ro DEBUG);

my %TAG_TEMPLATE;
$TAG_TEMPLATE{css} = [qw(link rel stylesheet href)];
$TAG_TEMPLATE{ico} = [qw(link rel icon href)];
$TAG_TEMPLATE{js}  = [qw(script src)];
$TAG_TEMPLATE{$_}  = [qw(img src)]    for qw(gif jpg jpeg png svg);
$TAG_TEMPLATE{$_}  = [qw(source src)] for qw(mp3 mp4 ogg ogv webm);

has checksum => sub { Mojolicious::Plugin::AssetPack::Util::checksum(shift->content) };
has format   => sub {
  my $self = shift;
  my $name = $self->url =~ /^https?:/ ? Mojo::URL->new($self->url)->path->[-1] : (split m!(\\|/)!, $self->url)[-1];

  return $name =~ /\.(\w+)$/ ? lc $1 : '';
};

has minified => sub { shift->url =~ /\bmin\b/ ? 1 : 0 };
has renderer => undef;
has tag_for  => sub { \&_default_tag_for };

has _asset => sub {
  my $self = shift;
  return $self->content(delete $self->{content})->_asset      if $self->{content};
  return Mojo::Asset::File->new(path => delete $self->{path}) if $self->{path};
  return Mojo::Asset::Memory->new;
};

has_ro name => sub {
  my $self = shift;
  my $name;

  if ($self->url =~ /^https?:/) {
    my $url = Mojo::URL->new($self->url);
    my $qs  = $url->query->to_string;
    $name = $url->path->[-1];
    $qs   =~ s!\W!_!g;
    $name =~ s!\.\w+$!!;
    $name .= "_$qs" if $qs;
  }
  else {
    $name = (split m!(\\|/)!, $self->url)[-1];
    $name =~ s!\.\w+$!!;
  }

  return $name;
};

has_ro 'url';

sub asset {
  my $self  = shift;
  my $orig  = $self->_asset;
  my $clone = $orig->new;

  if ($orig->is_file) {
    $clone->cleanup(0)->path($orig->path);
  }
  else {
    $clone->auto_upgrade(0)->mtime($orig->mtime)->add_chunk($orig->slurp);
  }

  return $clone;
}

sub content {
  my $self = shift;
  return $self->_asset->slurp unless @_;
  return $self->_asset($_[0]->_asset) if UNIVERSAL::isa($_[0], __PACKAGE__);
  return $self->_asset($_[0])         if UNIVERSAL::isa($_[0], 'Mojo::Asset');
  return $self->_asset(Mojo::Asset::Memory->new->add_chunk($_[0]));
}

sub path {
  my $self = shift;
  return $self->_asset(Mojo::Asset::File->new(path => $_[0])) if $_[0];
  return Mojo::File->new($self->_asset->path)                 if $self->_asset->isa('Mojo::Asset::File');
  return undef;
}

sub size { $_[0]->_asset->size }

sub url_for { $_[1]->url_for(assetpack => $_[0]->TO_JSON); }

sub _default_tag_for {
  my ($asset, $c, $args, @attrs) = @_;
  my $url      = $asset->url_for($c);
  my @template = @{$TAG_TEMPLATE{$asset->format} || $TAG_TEMPLATE{css}};
  splice @template, 1, 0, type => $c->app->types->type($asset->format) if $template[0] eq 'source';
  return $c->tag(@template, Mojo::URL->new("$args->{base_url}$url"), @attrs);
}

sub FROM_JSON {
  my ($self, $attrs) = @_;
  $self->$_($attrs->{$_}) for grep { defined $attrs->{$_} } qw(checksum format minified);
  $self;
}

sub TO_JSON {
  return {map { ($_ => $_[0]->$_) } qw(checksum format minified name url)};
}

1;

=encoding utf8

=head1 NAME

Mojolicious::Plugin::AssetPack::Asset - An asset

=head1 DESCRIPTION

L<Mojolicious::Plugin::AssetPack::Asset> represents an asset.

=head1 SYNOPSIS

  use Mojolicious::Plugin::AssetPack::Asset;
  my $asset = Mojolicious::Plugin::AssetPack::Asset->new(url => "...");

=head1 ATTRIBUTES

=head2 checksum

  $str = $self->checksum;
  $self = $self->checksum($str);

The L<checksum|Mojolicious::Plugin::AssetPack::Util/checksum> of L</content>.

=head2 format

  $str = $self->format;
  $self = $self->format($str);

The format of L</content>. Defaults to the extension of L</url> or empty string.

=head2 minified

  $bool = $self->minified;
  $self = $self->minified($bool);

Will be set to true if either L</url> contains "min" or if a pipe has
minified L</content>.

=head2 name

  $str = $self->name;

Returns the basename of L</url>, without extension.

=head2 renderer

  $code = $self->renderer;
  $self = $self->renderer(sub { my ($self, $c) = @_; $c->render(data => "...""); })

Can be used to register a custom render method for this asset. This is called
by L<Mojolicious::Plugin::AssetPack::Store/serve_asset>.

=head2 tag_for

  $code = $self->tag_for;
  $self = $self->tag_for(sub { my ($c, \%args, @attrs) = @_; return qq(<link rel="...">) });

Used to register a custom tag renderer for this asset. The arguments passed
in are:

=over 2

=item * C<$c>

The L<Mojolicious::Controller> object used for this request.

=item * C<%args>

A hash-ref with "base_url" and
L<topic|Mojolicious::Plugin::AssetPack::Pipe/topic>.

=item * C<@attrs>

The HTML attributes passed in from the template.

=item

=back

=head2 url

  $str = $self->url;

Returns the location of the asset.

=head1 METHODS

=head2 asset

  $asset = $self->asset;

Returns a new L<Mojo::Asset::File> or L<Mojo::Asset::Memory> object, with the
content or path from this object.

This method is EXPERIMENTAL.

=head2 content

  $bytes = $self->content;
  $self = $self->content($bytes);
  $self = $self->content(Mojo::Asset::Memory->new);

Used to get or set the content of this asset. The default will be built from
passing L</url> to L<Mojolicious::Plugin::AssetPack::Store/file>.

=head2 path

  $str = $self->path;

Returns a L<Mojo::File> object that holds the location to the asset on disk or
C<undef> if this asset is in memory.

=head2 size

  $int = $self->size;

Returns the size of the asset in bytes.

=head2 url_for

  $url = $self->url_for($c);

Returns a L<Mojo::URL> object for this asset. C<$c> need to be a
L<Mojolicious::Controller>.

=head2 FROM_JSON

  $self = $self->FROM_JSON($hash_ref);

The opposite of L</TO_JSON>. Will set the read/write L</ATTRIBUTES> from the
values in C<$hash_ref>.

=head2 TO_JSON

  $hash_ref = $self->FROM_JSON;

The opposite of L</FROM_JSON>. Will generate a hash ref from L</ATTRIBUTES>.

=head1 SEE ALSO

L<Mojolicious::Plugin::AssetPack>.

=cut