line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package WebService::Google::Closure; |
2
|
|
|
|
|
|
|
|
3
|
3
|
|
|
3
|
|
171957
|
use Moose; |
|
3
|
|
|
|
|
1770123
|
|
|
3
|
|
|
|
|
28
|
|
4
|
3
|
|
|
3
|
|
35613
|
use MooseX::Types::Moose qw( ArrayRef Str Int ); |
|
3
|
|
|
|
|
256543
|
|
|
3
|
|
|
|
|
42
|
|
5
|
3
|
|
|
3
|
|
21471
|
use LWP::UserAgent; |
|
3
|
|
|
|
|
108907
|
|
|
3
|
|
|
|
|
110
|
|
6
|
3
|
|
|
3
|
|
29
|
use Carp qw( croak ); |
|
3
|
|
|
|
|
5
|
|
|
3
|
|
|
|
|
219
|
|
7
|
3
|
|
|
3
|
|
3088
|
use File::Slurp qw( slurp ); |
|
3
|
|
|
|
|
58857
|
|
|
3
|
|
|
|
|
284
|
|
8
|
|
|
|
|
|
|
|
9
|
3
|
|
|
3
|
|
2447
|
use WebService::Google::Closure::Types qw( ArrayRefOfStrings CompilationLevel ); |
|
3
|
|
|
|
|
14
|
|
|
3
|
|
|
|
|
30
|
|
10
|
3
|
|
|
3
|
|
11752
|
use WebService::Google::Closure::Response; |
|
3
|
|
|
|
|
11
|
|
|
3
|
|
|
|
|
1861
|
|
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
our $VERSION = '0.10'; |
13
|
|
|
|
|
|
|
$VERSION = eval $VERSION; |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
has js_code => ( |
16
|
|
|
|
|
|
|
is => 'rw', |
17
|
|
|
|
|
|
|
isa => Str, |
18
|
|
|
|
|
|
|
); |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
has file => ( |
21
|
|
|
|
|
|
|
is => 'ro', |
22
|
|
|
|
|
|
|
isa => ArrayRefOfStrings, |
23
|
|
|
|
|
|
|
trigger => \&_set_file, |
24
|
|
|
|
|
|
|
coerce => 1, |
25
|
|
|
|
|
|
|
); |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
has code_url => ( |
28
|
|
|
|
|
|
|
is => 'ro', |
29
|
|
|
|
|
|
|
isa => ArrayRefOfStrings, |
30
|
|
|
|
|
|
|
init_arg => 'url', |
31
|
|
|
|
|
|
|
coerce => 1, |
32
|
|
|
|
|
|
|
); |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
has compilation_level => ( |
35
|
|
|
|
|
|
|
is => 'ro', |
36
|
|
|
|
|
|
|
isa => CompilationLevel, |
37
|
|
|
|
|
|
|
coerce => 1, |
38
|
|
|
|
|
|
|
); |
39
|
|
|
|
|
|
|
|
40
|
|
|
|
|
|
|
has timeout => ( |
41
|
|
|
|
|
|
|
is => 'ro', |
42
|
|
|
|
|
|
|
isa => Int, |
43
|
|
|
|
|
|
|
default => 10, |
44
|
|
|
|
|
|
|
); |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
has post_url => ( |
47
|
|
|
|
|
|
|
is => 'ro', |
48
|
|
|
|
|
|
|
isa => Str, |
49
|
|
|
|
|
|
|
default => 'http://closure-compiler.appspot.com/compile', |
50
|
|
|
|
|
|
|
init_arg => undef, |
51
|
|
|
|
|
|
|
); |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
has output_format => ( |
54
|
|
|
|
|
|
|
is => 'ro', |
55
|
|
|
|
|
|
|
isa => Str, |
56
|
|
|
|
|
|
|
default => 'json', |
57
|
|
|
|
|
|
|
init_arg => undef, |
58
|
|
|
|
|
|
|
); |
59
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
has output_info => ( |
61
|
|
|
|
|
|
|
is => 'ro', |
62
|
|
|
|
|
|
|
isa => ArrayRef[Str], |
63
|
|
|
|
|
|
|
init_arg => undef, |
64
|
|
|
|
|
|
|
lazy_build => 1, |
65
|
|
|
|
|
|
|
); |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
has ua => ( |
68
|
|
|
|
|
|
|
is => 'ro', |
69
|
|
|
|
|
|
|
init_arg => undef, |
70
|
|
|
|
|
|
|
lazy_build => 1, |
71
|
|
|
|
|
|
|
); |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub _set_file { |
74
|
3
|
|
|
3
|
|
5
|
my $self = shift; |
75
|
3
|
|
|
|
|
6
|
my $content = ''; |
76
|
3
|
|
|
|
|
6
|
foreach my $f ( @{ $self->file } ) { |
|
3
|
|
|
|
|
179
|
|
77
|
3
|
|
|
|
|
18
|
$content .= slurp( $f ); |
78
|
|
|
|
|
|
|
} |
79
|
2
|
|
|
|
|
368
|
$self->js_code( $content ); |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
sub _build_ua { |
83
|
7
|
|
|
7
|
|
16
|
my $self = shift; |
84
|
7
|
|
|
|
|
94
|
my $ua = LWP::UserAgent->new; |
85
|
7
|
|
|
|
|
8985
|
$ua->timeout( $self->timeout ); |
86
|
7
|
|
|
|
|
133
|
$ua->env_proxy; |
87
|
7
|
|
|
|
|
33318
|
$ua->agent( __PACKAGE__ . '/' . $VERSION ); |
88
|
7
|
|
|
|
|
702
|
return $ua; |
89
|
|
|
|
|
|
|
} |
90
|
|
|
|
|
|
|
|
91
|
|
|
|
|
|
|
sub _build_output_info { |
92
|
7
|
|
|
7
|
|
302
|
return [ qw( compiled_code statistics warnings errors ) ]; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
sub compile { |
96
|
7
|
|
|
7
|
1
|
16
|
my $self = shift; |
97
|
|
|
|
|
|
|
|
98
|
7
|
50
|
66
|
|
|
319
|
if ( $self->compilation_level && $self->compilation_level eq 'NOOP' ) { |
99
|
|
|
|
|
|
|
# Don't bother the compiler |
100
|
0
|
|
|
|
|
0
|
return WebService::Google::Closure::Response->new( |
101
|
|
|
|
|
|
|
format => $self->output_format, |
102
|
|
|
|
|
|
|
code => $self->js_code, |
103
|
|
|
|
|
|
|
); |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
|
106
|
7
|
|
|
|
|
17
|
my $post_args = {}; |
107
|
7
|
|
|
|
|
21
|
foreach my $arg (qw( js_code code_url compilation_level output_format output_info )) { |
108
|
35
|
100
|
|
|
|
4668
|
next unless $self->$arg; |
109
|
25
|
|
|
|
|
2757
|
$post_args->{ $arg } = $self->$arg; |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
7
|
|
|
|
|
305
|
my $res = $self->ua->post( |
113
|
|
|
|
|
|
|
$self->post_url, $post_args |
114
|
|
|
|
|
|
|
); |
115
|
7
|
100
|
|
|
|
2784240
|
unless ( $res->is_success ) { |
116
|
1
|
|
|
|
|
14
|
croak "Error posting request to Google - " . $res->status_line; |
117
|
|
|
|
|
|
|
} |
118
|
|
|
|
|
|
|
|
119
|
6
|
|
|
|
|
523
|
return WebService::Google::Closure::Response->new( |
120
|
|
|
|
|
|
|
format => $self->output_format, |
121
|
|
|
|
|
|
|
content => $res->content, |
122
|
|
|
|
|
|
|
); |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
|
126
|
3
|
|
|
3
|
|
31
|
no Moose; |
|
3
|
|
|
|
|
122
|
|
|
3
|
|
|
|
|
26
|
|
127
|
|
|
|
|
|
|
__PACKAGE__->meta->make_immutable; |
128
|
|
|
|
|
|
|
1; |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
__END__ |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=head1 NAME |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
WebService::Google::Closure - Perl interface to the Google Closure Javascript compiler service |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=head1 SYNOPSIS |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
This module will take given Javascript code and compile it into compact, high-performance code |
140
|
|
|
|
|
|
|
using the Google Closure compiler. |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
use WebService::Google::Closure; |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
my $js_code = " |
145
|
|
|
|
|
|
|
function hello(name) { |
146
|
|
|
|
|
|
|
alert('Hello, ' + name); |
147
|
|
|
|
|
|
|
} |
148
|
|
|
|
|
|
|
hello('New user'); |
149
|
|
|
|
|
|
|
"; |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
my $res = WebService::Google::Closure->new( |
152
|
|
|
|
|
|
|
js_code => $js_code, |
153
|
|
|
|
|
|
|
)->compile; |
154
|
|
|
|
|
|
|
|
155
|
|
|
|
|
|
|
print $res->code; |
156
|
|
|
|
|
|
|
# prints; |
157
|
|
|
|
|
|
|
# function hello(a){alert("Hello, "+a)}hello("New user"); |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
# Now tell Closure to be more aggressive |
161
|
|
|
|
|
|
|
my $res2 = WebService::Google::Closure->new( |
162
|
|
|
|
|
|
|
compilation_level => "ADVANCED_OPTIMIZATIONS", |
163
|
|
|
|
|
|
|
js_code => $js_code, |
164
|
|
|
|
|
|
|
)->compile; |
165
|
|
|
|
|
|
|
|
166
|
|
|
|
|
|
|
print $res2->code; |
167
|
|
|
|
|
|
|
# prints; |
168
|
|
|
|
|
|
|
# alert("Hello, New user"); |
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
print "Original size = " . $res2->stats->original_size . "\n"; |
171
|
|
|
|
|
|
|
print "Compressed size = " . $res2->stats->compressed_size . "\n"; |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
For more information on the Google Closure compiler, visit its website at L<http://code.google.com/closure/> |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
=head1 METHODS |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
=head2 new |
180
|
|
|
|
|
|
|
|
181
|
|
|
|
|
|
|
Possible options; |
182
|
|
|
|
|
|
|
|
183
|
|
|
|
|
|
|
=over 4 |
184
|
|
|
|
|
|
|
|
185
|
|
|
|
|
|
|
=item compilation_level |
186
|
|
|
|
|
|
|
|
187
|
|
|
|
|
|
|
Specifying how aggressive the compiler should be. There are currently three options. |
188
|
|
|
|
|
|
|
|
189
|
|
|
|
|
|
|
=over 8 |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
=item "WHITESPACE_ONLY" or 1 |
192
|
|
|
|
|
|
|
|
193
|
|
|
|
|
|
|
Just removes whitespace and comments from your JavaScript. |
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
=item "SIMPLE_OPTIMIZATIONS" or 2 (default) |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
Performs compression and optimization that does not interfere with the interaction between the compiled JavaScript and other JavaScript. This level renames only local variables. |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
=item "ADVANCED_OPTIMIZATIONS" or 3 |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
Achieves the highest level of compression by renaming symbols in your JavaScript. When using ADVANCED_OPTIMIZATIONS compilation you must perform extra steps to preserve references to external symbols. |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=back |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
=item js_code |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
A string containing Javascript code. |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
=item file |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
One or more filenames of the files you want compiled |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
Example: |
214
|
|
|
|
|
|
|
|
215
|
|
|
|
|
|
|
use WebService::Google::Closure; |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
my $cl1 = WebService::Google::Closure->new( |
218
|
|
|
|
|
|
|
file => "/var/www/js/base.js", |
219
|
|
|
|
|
|
|
); |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
my $cl2 = WebService::Google::Closure->new( |
222
|
|
|
|
|
|
|
file => [qw( /var/www/js/base.js /var/www/js/classes.js )], |
223
|
|
|
|
|
|
|
); |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
=item url |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
One or more urls to the files you want compiled |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
Example: |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
use WebService::Google::Closure; |
232
|
|
|
|
|
|
|
|
233
|
|
|
|
|
|
|
my $res = WebService::Google::Closure->new( |
234
|
|
|
|
|
|
|
url => "http://code.jquery.com/jquery-1.4.2.js", |
235
|
|
|
|
|
|
|
compilation_level => 3, |
236
|
|
|
|
|
|
|
)->compile; |
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
print "Orig Size = " . $res->stats->original_size . "\n"; |
239
|
|
|
|
|
|
|
print "Comp Size = " . $res->stats->compressed_size . "\n"; |
240
|
|
|
|
|
|
|
|
241
|
|
|
|
|
|
|
# prints; |
242
|
|
|
|
|
|
|
# Orig Size = 163855 |
243
|
|
|
|
|
|
|
# Comp Size = 65523 |
244
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
=back |
246
|
|
|
|
|
|
|
|
247
|
|
|
|
|
|
|
=head2 compile |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
Returns a L<WebService::Google::Closure::Response> object. |
250
|
|
|
|
|
|
|
|
251
|
|
|
|
|
|
|
Will die if unable to connect to the Google closure service. |
252
|
|
|
|
|
|
|
|
253
|
|
|
|
|
|
|
=head1 AUTHOR |
254
|
|
|
|
|
|
|
|
255
|
|
|
|
|
|
|
Magnus Erixzon, C<< <magnus at erixzon.com> >> |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
=head1 TODO |
258
|
|
|
|
|
|
|
|
259
|
|
|
|
|
|
|
=over 4 |
260
|
|
|
|
|
|
|
|
261
|
|
|
|
|
|
|
=item externs |
262
|
|
|
|
|
|
|
|
263
|
|
|
|
|
|
|
When using the compilation level ADVANCED_OPTIMIZATIONS, the compiler achieves extra compression by being more aggressive in the ways that it transforms code and renames symbols. However, this more aggressive approach means that you must take greater care when you use ADVANCED_OPTIMIZATIONS to ensure that the output code works the same way as the input code. |
264
|
|
|
|
|
|
|
|
265
|
|
|
|
|
|
|
One problem is if your code uses external code that you're not submitting to the compiler - The compiler might then optimize code away, as its not aware of the externally defined functions. The solutions to this is using "externs". I'll implement this when I need it, or if someone asks for it. |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
See L<http://code.google.com/closure/compiler/docs/api-tutorial3.html> for more information. |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
=back |
270
|
|
|
|
|
|
|
|
271
|
|
|
|
|
|
|
=head1 BUGS |
272
|
|
|
|
|
|
|
|
273
|
|
|
|
|
|
|
Please report any bugs or feature requests to C<bug-webservice-google-closure at rt.cpan.org>, or through |
274
|
|
|
|
|
|
|
the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=WebService-Google-Closure>. I will be notified, and then you'll |
275
|
|
|
|
|
|
|
automatically be notified of progress on your bug as I make changes. |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
=head1 SUPPORT |
278
|
|
|
|
|
|
|
|
279
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
perldoc WebService::Google::Closure |
282
|
|
|
|
|
|
|
|
283
|
|
|
|
|
|
|
You can also look for information at: |
284
|
|
|
|
|
|
|
|
285
|
|
|
|
|
|
|
=over 4 |
286
|
|
|
|
|
|
|
|
287
|
|
|
|
|
|
|
=item * RT: CPAN's request tracker |
288
|
|
|
|
|
|
|
|
289
|
|
|
|
|
|
|
L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=WebService-Google-Closure> |
290
|
|
|
|
|
|
|
|
291
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
292
|
|
|
|
|
|
|
|
293
|
|
|
|
|
|
|
L<http://annocpan.org/dist/WebService-Google-Closure> |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
=item * CPAN Ratings |
296
|
|
|
|
|
|
|
|
297
|
|
|
|
|
|
|
L<http://cpanratings.perl.org/d/WebService-Google-Closure> |
298
|
|
|
|
|
|
|
|
299
|
|
|
|
|
|
|
=item * Search CPAN |
300
|
|
|
|
|
|
|
|
301
|
|
|
|
|
|
|
L<http://search.cpan.org/dist/WebService-Google-Closure/> |
302
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
=back |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
Copyright 2010-2011 Magnus Erixzon. |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify it |
310
|
|
|
|
|
|
|
under the terms of either: the GNU General Public License as published |
311
|
|
|
|
|
|
|
by the Free Software Foundation; or the Artistic License. |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
See http://dev.perl.org/licenses/ for more information. |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
=cut |