line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Web::AssetLib::Bundle; |
2
|
|
|
|
|
|
|
|
3
|
5
|
|
|
5
|
|
2693055
|
use Method::Signatures; |
|
5
|
|
|
|
|
218703
|
|
|
5
|
|
|
|
|
33
|
|
4
|
5
|
|
|
5
|
|
2744
|
use Moose; |
|
5
|
|
|
|
|
304043
|
|
|
5
|
|
|
|
|
39
|
|
5
|
5
|
|
|
5
|
|
23409
|
use Carp; |
|
5
|
|
|
|
|
7
|
|
|
5
|
|
|
|
|
304
|
|
6
|
5
|
|
|
5
|
|
2532
|
use Web::AssetLib::Util; |
|
5
|
|
|
|
|
14
|
|
|
5
|
|
|
|
|
181
|
|
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
with 'Web::AssetLib::Role::Logger'; |
9
|
|
|
|
|
|
|
|
10
|
5
|
|
|
5
|
|
100
|
use v5.14; |
|
5
|
|
|
|
|
13
|
|
11
|
5
|
|
|
5
|
|
19
|
no if $] >= 5.018, warnings => "experimental"; |
|
5
|
|
|
|
|
6
|
|
|
5
|
|
|
|
|
37
|
|
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
has 'assets' => ( |
14
|
|
|
|
|
|
|
is => 'rw', |
15
|
|
|
|
|
|
|
isa => 'ArrayRef[Web::AssetLib::Asset]', |
16
|
|
|
|
|
|
|
traits => [qw/Array/], |
17
|
|
|
|
|
|
|
default => sub { [] }, |
18
|
|
|
|
|
|
|
handles => { |
19
|
|
|
|
|
|
|
_addAsset => 'push', |
20
|
|
|
|
|
|
|
allAssets => 'elements', |
21
|
|
|
|
|
|
|
countAssets => 'count', |
22
|
|
|
|
|
|
|
filterAssets => 'grep', |
23
|
|
|
|
|
|
|
findAsset => 'first', |
24
|
|
|
|
|
|
|
findAssetIdx => 'first_index', |
25
|
|
|
|
|
|
|
deleteAsset => 'delete', |
26
|
|
|
|
|
|
|
filterAssets => 'grep', |
27
|
|
|
|
|
|
|
getAsset => 'get' |
28
|
|
|
|
|
|
|
} |
29
|
|
|
|
|
|
|
); |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
has '_digest_map' => ( |
32
|
|
|
|
|
|
|
is => 'rw', |
33
|
|
|
|
|
|
|
isa => 'HashRef', |
34
|
|
|
|
|
|
|
traits => [qw/Hash/], |
35
|
|
|
|
|
|
|
handles => { |
36
|
|
|
|
|
|
|
addDigest => 'set', |
37
|
|
|
|
|
|
|
getDigest => 'get' |
38
|
|
|
|
|
|
|
} |
39
|
|
|
|
|
|
|
); |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
has 'isCompiled' => ( |
42
|
|
|
|
|
|
|
is => 'ro', |
43
|
|
|
|
|
|
|
isa => 'Bool', |
44
|
|
|
|
|
|
|
writer => '_set_isCompiled', |
45
|
|
|
|
|
|
|
default => 0 |
46
|
|
|
|
|
|
|
); |
47
|
|
|
|
|
|
|
|
48
|
5
|
|
|
5
|
|
8046
|
method addAssets (@_) { |
|
0
|
|
|
0
|
|
0
|
|
49
|
0
|
|
|
|
|
0
|
$self->_set_isCompiled(0); |
50
|
0
|
|
|
|
|
0
|
return $self->addAsset(@_); |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
|
53
|
5
|
|
|
5
|
|
6794
|
method addAsset (@assets) { |
|
14
|
|
|
14
|
|
25635
|
|
|
14
|
|
|
|
|
61
|
|
54
|
14
|
|
|
|
|
388
|
$self->_set_isCompiled(0); |
55
|
14
|
|
|
|
|
26
|
foreach my $asset (@assets) { |
56
|
14
|
|
|
|
|
33
|
for ( ref($asset) ) { |
57
|
14
|
|
|
|
|
46
|
when ('Web::AssetLib::Asset') { |
58
|
14
|
100
|
|
|
|
39
|
unless ( $self->_checkForDuplicate($asset) ) { |
59
|
13
|
|
|
|
|
382
|
$self->_addAsset($asset); |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
} |
62
|
0
|
|
|
|
|
0
|
when ('') { |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
# shortcut: strings will be interpreted as LocalFiles |
65
|
|
|
|
|
|
|
|
66
|
0
|
|
|
|
|
0
|
$asset =~ m/\.(\w+)$/; |
67
|
0
|
|
|
|
|
0
|
my $extension = $1; |
68
|
|
|
|
|
|
|
|
69
|
0
|
|
|
|
|
0
|
my $a = Web::AssetLib::Asset->new( |
70
|
|
|
|
|
|
|
input_args => { path => $asset }, |
71
|
|
|
|
|
|
|
type => $extension |
72
|
|
|
|
|
|
|
); |
73
|
|
|
|
|
|
|
|
74
|
0
|
0
|
|
|
|
0
|
unless ( $self->_checkForDuplicate($a) ) { |
75
|
0
|
|
|
|
|
0
|
$self->_addAsset($a); |
76
|
|
|
|
|
|
|
} |
77
|
|
|
|
|
|
|
} |
78
|
0
|
|
|
|
|
0
|
default { |
79
|
0
|
|
|
|
|
0
|
$self->log->dump( 'unknown asset type=', $asset, 'warn' ); |
80
|
0
|
|
|
|
|
0
|
croak |
81
|
|
|
|
|
|
|
"assets must be either a string or a Web::AssetLib::Asset object - got a $_"; |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
has 'output' => ( |
88
|
|
|
|
|
|
|
is => 'rw', |
89
|
|
|
|
|
|
|
isa => 'ArrayRef[Web::AssetLib::Output]', |
90
|
|
|
|
|
|
|
default => sub { [] }, |
91
|
|
|
|
|
|
|
traits => [qw/Array/], |
92
|
|
|
|
|
|
|
handles => { filterOutput => 'grep' } |
93
|
|
|
|
|
|
|
); |
94
|
|
|
|
|
|
|
|
95
|
5
|
0
|
|
5
|
|
3306
|
method groupByType () { |
|
0
|
|
|
0
|
|
0
|
|
|
0
|
|
|
|
|
0
|
|
96
|
0
|
|
|
|
|
0
|
my $types; |
97
|
0
|
|
|
|
|
0
|
foreach my $asset ( $self->allAssets ) { |
98
|
0
|
|
|
|
|
0
|
push @{ $$types{ $asset->type } }, $asset; |
|
0
|
|
|
|
|
0
|
|
99
|
|
|
|
|
|
|
} |
100
|
0
|
|
|
|
|
0
|
return $types; |
101
|
|
|
|
|
|
|
} |
102
|
|
|
|
|
|
|
|
103
|
5
|
50
|
|
5
|
|
7540
|
method _filterOutputByType ($type!) { |
|
4
|
50
|
|
4
|
|
4
|
|
|
4
|
|
|
|
|
10
|
|
|
4
|
|
|
|
|
6
|
|
|
4
|
|
|
|
|
10
|
|
104
|
4
|
|
|
10
|
|
122
|
return [ $self->filterOutput( sub { $_->type eq $type } ) ]; |
|
10
|
|
|
|
|
136
|
|
105
|
|
|
|
|
|
|
} |
106
|
|
|
|
|
|
|
|
107
|
5
|
50
|
|
5
|
|
19323
|
method as_html ( :$type!, :$html_attrs = {} ) { |
|
4
|
50
|
|
4
|
|
22
|
|
|
4
|
50
|
|
|
|
20
|
|
|
4
|
50
|
|
|
|
11
|
|
|
4
|
|
|
|
|
6
|
|
|
4
|
|
|
|
|
8
|
|
|
4
|
|
|
|
|
11
|
|
|
4
|
|
|
|
|
4
|
|
|
4
|
|
|
|
|
13
|
|
|
4
|
|
|
|
|
8
|
|
108
|
|
|
|
|
|
|
|
109
|
4
|
50
|
|
|
|
114
|
$self->log->warn('attempting to generate html before bundle is compiled') |
110
|
|
|
|
|
|
|
unless $self->isCompiled; |
111
|
|
|
|
|
|
|
|
112
|
4
|
|
|
|
|
6
|
my @tags; |
113
|
4
|
|
|
|
|
5
|
foreach my $out ( @{ $self->_filterOutputByType($type) } ) { |
|
4
|
|
|
|
|
12
|
|
114
|
|
|
|
|
|
|
my $tag = Web::AssetLib::Util::generateHtmlTag( |
115
|
|
|
|
|
|
|
output => $out, |
116
|
5
|
|
|
|
|
32
|
html_attrs => { %{ $out->default_html_attrs }, %$html_attrs } |
|
5
|
|
|
|
|
76
|
|
117
|
|
|
|
|
|
|
); |
118
|
5
|
|
|
|
|
878
|
push @tags, $tag; |
119
|
|
|
|
|
|
|
} |
120
|
|
|
|
|
|
|
|
121
|
4
|
|
|
|
|
131
|
return join( "\n", @tags ); |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
|
124
|
5
|
50
|
|
5
|
|
8633
|
method _checkForDuplicate ($asset!) { |
|
14
|
50
|
|
14
|
|
27
|
|
|
14
|
|
|
|
|
50
|
|
|
14
|
|
|
|
|
16
|
|
|
14
|
|
|
|
|
36
|
|
125
|
14
|
100
|
|
|
|
459
|
if ( my $dup |
126
|
10
|
|
|
10
|
|
247
|
= $self->findAsset( sub { $asset->fingerprint eq $_->fingerprint } ) ) |
127
|
|
|
|
|
|
|
{ |
128
|
1
|
|
|
|
|
8
|
$self->log->dump( 'duplicate fingerprint found for asset=', |
129
|
|
|
|
|
|
|
{ adding => $asset, found => $dup }, 'trace' ); |
130
|
1
|
|
|
|
|
12
|
return 1; |
131
|
|
|
|
|
|
|
} |
132
|
|
|
|
|
|
|
else { |
133
|
13
|
|
|
|
|
43
|
return 0; |
134
|
|
|
|
|
|
|
} |
135
|
|
|
|
|
|
|
} |
136
|
|
|
|
|
|
|
|
137
|
5
|
|
|
5
|
|
829
|
no Moose; |
|
5
|
|
|
|
|
8
|
|
|
5
|
|
|
|
|
40
|
|
138
|
|
|
|
|
|
|
1; |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
=pod |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=encoding UTF-8 |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
=head1 NAME |
145
|
|
|
|
|
|
|
|
146
|
|
|
|
|
|
|
Web::AssetLib::Bundle - an indexed grouping of L<Web::AssetLib::Asset> objects |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
=head1 SYNOPSIS |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
my $bundle = Web::AssetLib::Bundle->new(); |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
my $asset = Web::AssetLib::Asset->new( |
153
|
|
|
|
|
|
|
type => 'javascript', |
154
|
|
|
|
|
|
|
input_engine => 'LocalFile', |
155
|
|
|
|
|
|
|
rank => -100, |
156
|
|
|
|
|
|
|
input_args => { path => "your/local/path/jquery.min.js", } |
157
|
|
|
|
|
|
|
); |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
$bundle->addAsset( $asset ); |
160
|
|
|
|
|
|
|
$bundle->addAsset( '/my/local/file.js', '/my/local/file.css' ); |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
$library->compile( bundle => $bundle ); |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
=head1 ATTRIBUTES |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
=head2 assets |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
Arrayref of L<Web::AssetLib::Asset> objects |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
=head1 METHODS |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=head2 addAsset |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
=head2 addAssets |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
$bundle->addAsset( |
177
|
|
|
|
|
|
|
Web::AssetLib::Asset->new( |
178
|
|
|
|
|
|
|
type => 'javascript', |
179
|
|
|
|
|
|
|
input_engine => 'LocalFile', |
180
|
|
|
|
|
|
|
rank => -100, |
181
|
|
|
|
|
|
|
input_args => { path => "your/local/path/jquery.min.js", } |
182
|
|
|
|
|
|
|
); |
183
|
|
|
|
|
|
|
); |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
Adds an asset to the bundle. Accepts an array of L<Web::AssetLib::Asset> |
186
|
|
|
|
|
|
|
instances, or an array of strings. Using a string is a shortcut for defining |
187
|
|
|
|
|
|
|
a LocalFile asset, with the type determined by the file extension. |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
=head2 as_html |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
my $html_tag = $bundle->as_html( type => 'js', html_attrs => { async => 'async' } ); |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
Returns an HTML-formatted string linking to bundle's output location. Only |
194
|
|
|
|
|
|
|
available after the bundle has been compiled, otherwise returns undef. |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
C<type> is a required argument. |
197
|
|
|
|
|
|
|
|
198
|
|
|
|
|
|
|
=head1 AUTHOR |
199
|
|
|
|
|
|
|
|
200
|
|
|
|
|
|
|
Ryan Lang <rlang@cpan.org> |
201
|
|
|
|
|
|
|
|
202
|
|
|
|
|
|
|
=cut |