File Coverage

blib/lib/HTTP/Proxy/GreaseMonkey/Script.pm
Criterion Covered Total %
statement 52 54 96.3
branch 17 22 77.2
condition 4 6 66.6
subroutine 13 14 92.8
pod 9 9 100.0
total 95 105 90.4


line stmt bran cond sub pod time code
1             package HTTP::Proxy::GreaseMonkey::Script;
2              
3 4     4   25878 use strict;
  4         11  
  4         148  
4 4     4   22 use warnings;
  4         6  
  4         105  
5 4     4   22 use Carp;
  4         15  
  4         299  
6 4     4   4345 use HTML::Tiny;
  4         12243  
  4         3325  
7              
8             =head1 NAME
9              
10             HTTP::Proxy::GreaseMonkey::Script - A GreaseMonkey script.
11              
12             =head1 VERSION
13              
14             This document describes HTTP::Proxy::GreaseMonkey::Script version 0.05
15              
16             =cut
17              
18             our $VERSION = '0.05';
19              
20             =head1 SYNOPSIS
21              
22             use HTTP::Proxy::GreaseMonkey::Script;
23            
24             =head1 DESCRIPTION
25              
26             Represents a single GreaseMonkey user script.
27              
28             =head1 INTERFACE
29              
30             =head2 C<< new >>
31              
32             =cut
33              
34             sub new {
35 6     6 1 1397 my ( $class, $script_file ) = @_;
36              
37 6 50       157 my @stat = stat $script_file
38             or croak "Can't stat $script_file ($!)";
39              
40 6 50       625 open my $sh, '<', $script_file
41             or croak "Can't read $script_file ($!)";
42 6         12 my $script = do { local $/; <$sh> };
  6         25  
  6         135  
43 6         89 close $sh;
44              
45 6         16 my %meta = ();
46 6 50       123 if (
47             $script =~ m{^ \s* // \s+ ==UserScript== \s+
48             (.*?) ^ \s* // \s+==/UserScript== \s+ }xmsi
49             ) {
50 6         21 my $header = $1;
51 6         43 while ( $header =~ m{ ^ \s* // \s+ \@(\w+)\s+(.+)$ }xmg ) {
52 30 100 100     151 if ( $1 eq 'include' || $1 eq 'exclude' ) {
53 12         34 push @{ $meta{$1} }, _gm_wildcard( $2 );
  12         48  
54             }
55             else {
56 18         131 $meta{$1} = $2;
57             }
58             }
59             }
60              
61             # Special case - if include is empty make it match anything
62 6 100       36 $meta{include} = [qr{}] unless $meta{include};
63              
64 6         70 return bless {
65             file => $script_file,
66             meta => \%meta,
67             stat => \@stat,
68             script => $script,
69             },
70             $class;
71             }
72              
73             =head2 C<< match_uri >>
74              
75             =cut
76              
77             sub match_uri {
78 14     14 1 25 my ( $self, $uri ) = @_;
79 14 100       18 for my $exc ( @{ $self->{meta}->{exclude} || [] } ) {
  14         90  
80 13 100       224 return if $uri =~ $exc;
81             }
82 12 50       28 for my $inc ( @{ $self->{meta}->{include} || [] } ) {
  12         53  
83 15 100       95 return 1 if $uri =~ $inc;
84             }
85 1         4 return;
86             }
87              
88             =head2 C<< script >>
89              
90             The Javascript source of this script.
91              
92             =cut
93              
94 2     2 1 47 sub script { shift->{script} }
95              
96             =head2 C<< support >>
97              
98             The Javascript support code for this script
99              
100             =cut
101              
102             sub support {
103 2     2 1 3 my $self = shift;
104 2   33     66 my $h = $self->{_html} ||= HTML::Tiny->new;
105             my @args
106 2         116 = map { $h->json_encode( $_ ) } ( $self->namespace, $self->name );
  4         56  
107              
108 6         87 return join "\n", map {
109 2         35 "function GM_$_() { return GM__proxyFunction("
110             . join( ', ', $h->json_encode( $_ ), @args )
111             . ", arguments) }"
112             } qw( setValue getValue log );
113             }
114              
115             =head2 C<< file >>
116              
117             The filename of this script.
118              
119             =cut
120              
121 4     4 1 1872 sub file { shift->{file} }
122              
123             =head2 C<< stat >>
124              
125             Get the cached C array for this script.
126              
127             =cut
128              
129 0     0 1 0 sub stat { @{ shift->{stat} } }
  0         0  
130              
131             =head2 C<< name >>
132              
133             The descriptive name of this script
134              
135             =cut
136              
137 4     4 1 22 sub name { shift->{meta}->{name} }
138              
139             =head2 C<< namespace >>
140              
141             The namespace of this script.
142              
143             =cut
144              
145 4     4 1 1478 sub namespace { shift->{meta}->{namespace} }
146              
147             =head2 C<< description >>
148              
149             The description of this script.
150              
151             =cut
152              
153 2     2 1 1623 sub description { shift->{meta}->{description} }
154              
155             sub _gm_wildcard {
156 12     12   23 my $wc = shift;
157 48 50       160 my $pattern = join '',
    100          
158 12         57 map { $_ eq '*' ? '.*' : $_ eq '?' ? '.' : quotemeta( $_ ) }
159             split /([*?])/, $wc;
160 12         248 return qr{^$pattern$}i;
161             }
162              
163             1;
164             __END__