File Coverage

blib/lib/WebService/Google/Closure.pm
Criterion Covered Total %
statement 47 48 97.9
branch 5 6 83.3
condition 2 3 66.6
subroutine 12 12 100.0
pod 1 1 100.0
total 67 70 95.7


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