File Coverage

lib/Mojolicious/Plugin/JSLoader.pm
Criterion Covered Total %
statement 71 73 97.2
branch 45 58 77.5
condition 18 26 69.2
subroutine 10 10 100.0
pod 1 1 100.0
total 145 168 86.3


line stmt bran cond sub pod time code
1             package Mojolicious::Plugin::JSLoader;
2              
3             # ABSTRACT: move js loading to the end of the document
4              
5 9     9   3955 use strict;
  9         9  
  9         210  
6 9     9   29 use warnings;
  9         14  
  9         224  
7              
8 9     9   26 use parent 'Mojolicious::Plugin';
  9         17  
  9         62  
9              
10 9     9   4079 use HTML::ParseBrowser;
  9         17236  
  9         280  
11 9     9   46 use Mojo::ByteStream;
  9         11  
  9         378  
12 9     9   3294 use version 0.77;
  9         11390  
  9         44  
13              
14             our $VERSION = 0.06;
15              
16             sub register {
17 9     9 1 5343 my ($self, $app, $config) = @_;
18              
19 9   100     52 my $base = $config->{base} || '';
20              
21 9 100 66     60 if ( $base and substr( $base, -1 ) ne '/' ) {
22 3         5 $base .= '/';
23             }
24              
25             $app->helper( js_load => sub {
26 39     39   219682 my $c = shift;
27              
28 39 100       93 return '' unless _match_browser($c, @_);
29              
30 35 100       195 if ( $_[1]->{check} ) {
31             my $asset = $c->app->static->file(
32 7 50       19 $_[1]->{no_base} ? $_[0] : "$base$_[0]"
33             );
34              
35 7 100       875 return '' if !$asset;
36             }
37              
38 32 100 33     141 if ( $_[1] && $_[1]->{inplace} ) {
39 7         11 my ($file,$config) = @_;
40 7 50       13 my $local_base = $config->{no_base} ? '' : $base;
41              
42 7 50       12 $local_base = $c->url_for( $local_base ) if $local_base;
43              
44             my $js = $config->{no_file} ?
45 7 50       16 qq~~ :
46             qq~~;
47 7         38 return Mojo::ByteStream->new( $js );
48             }
49              
50 25         22 push @{ $c->stash->{__JSLOADERFILES__} }, [ @_ ];
  25         64  
51 9         69 } );
52              
53             $app->hook( after_render => sub {
54 26     26   1655 my ($c, $content, $format) = @_;
55              
56 26 50       72 return if $format ne 'html';
57 26 100       63 return if !$c->stash->{__JSLOADERFILES__};
58              
59             my $load_js = join "\n",
60             map{
61 25         357 my ($file,$config) = @{ $_ };
  25         43  
62 25 100       57 my $local_base = $config->{no_base} ? '' : $base;
63              
64 25 100       63 $local_base = $c->url_for( $local_base ) if $local_base;
65              
66 25 100 66     1509 if ( $config->{no_file} and $config->{on_ready} ) {
67 1         4 $file = sprintf '$(document).ready( function(){%s});', $file;
68             }
69              
70             $config->{no_file} ?
71 25 100       100 qq~~ :
72             qq~~;
73             }
74 15 50       148 @{ $c->stash->{__JSLOADERFILES__} || [] };
  15         37  
75              
76 15 50       768 return if !$load_js;
77              
78 15         18 ${$content} =~ s!()|\z)!$load_js$1!;
  15         165  
79 9         257 });
80             }
81              
82             sub _match_browser {
83 39     39   56 my ($c,$file,$config) = @_;
84              
85 39 100       117 return 1 if !$config;
86 24 50       63 return 1 if ref $config ne 'HASH';
87 24 100       71 return 1 if !$config->{browser};
88 9 50       19 return 1 if ref $config->{browser} ne 'HASH';
89              
90 9         22 my $ua_string = $c->req->headers->user_agent;
91 9         190 my $ua = HTML::ParseBrowser->new( $ua_string );
92              
93 9 50       1462 return if !$ua;
94              
95 9         44 my $name = $ua->name;
96 9         72 my $browser = $config->{browser};
97              
98 9 100 100     48 if ( !exists $browser->{$name} && !exists $browser->{default} ) {
    100 66        
99 2         18 return;
100             }
101             elsif ( !exists $browser->{$name} && exists $browser->{default} ) {
102 1         5 return 1;
103             }
104              
105 6         22 my ($op,$version) = $browser->{$name} =~ m{\A\s*([lg]t|!)?\s*([0-9\.]+)};
106              
107 6 50       12 return if !defined $version;
108              
109 6 100 66     40 if ( !$op || ( $op ne 'gt' and $op ne 'lt' and $op ne '!' ) ) {
    100 66        
    50 66        
    50          
110 2         8 return version->parse( $ua->v ) == version->parse( $version );
111             }
112             elsif ( $op eq 'gt' ) {
113 2         26 return version->parse( $version ) <= version->parse( $ua->v );
114             }
115             elsif ( $op eq 'lt' ) {
116 0         0 return version->parse( $version ) >= version->parse( $ua->v );
117             }
118             elsif ( $op eq '!' ) {
119 2         20 return version->parse( $version ) != version->parse( $ua->v );
120             }
121              
122 0           return;
123             }
124              
125             1;
126              
127             __END__