File Coverage

blib/lib/HTML/Rebase.pm
Criterion Covered Total %
statement 34 43 79.0
branch 5 8 62.5
condition 3 3 100.0
subroutine 7 9 77.7
pod 2 5 40.0
total 51 68 75.0


line stmt bran cond sub pod time code
1             package HTML::Rebase;
2 5     5   224165 use strict;
  5         38  
  5         128  
3 5     5   1827 use URI::WithBase;
  5         32605  
  5         123  
4 5     5   1964 use URI::URL;
  5         9675  
  5         241  
5 5     5   31 use Exporter 'import';
  5         10  
  5         2703  
6             our $VERSION = '0.04';
7             our @EXPORT_OK= qw(rebase_html rebase_css rebase_html_inplace rebase_css_inplace);
8              
9             =head1 NAME
10              
11             HTML::Rebase - rewrite HTML links to be relative to a given URL
12              
13             =head1 SYNOPSIS
14              
15             use HTML::Rebase qw(rebase_html rebase_css);
16             my $html = <
17            
18            
19            
20            
21            
22             Go to Perlmonks.org
23             Go to home page/a>
24            
25            
26             HTML
27              
28             my $local_html = rebase_html( "http://localhost:5000/about.html", $html );
29             print $local_html;
30             __END__
31            
32            
33            
34            
35            
36             Go to Perlmonks.org
37             Go to home page/a>
38            
39            
40              
41             =head2 C<< rebase_html >>
42              
43             Rewrites all HTML links to be relative to the given URL. This
44             only rewrites things that look like C<< src= >> and C<< href= >> attributes.
45             Unquoted attributes will not be rewritten. This should be fixed.
46              
47             =cut
48              
49             sub rebase_html {
50 8     8 1 3942 my($url, $html)= @_;
51            
52             #croak "Can only rewrite relative to an absolute URL!"
53             # unless $url->is_absolute;
54            
55             # Rewrite absolute to relative
56 8         29 rebase_html_inplace( $url, $html );
57            
58 8         182 $html
59             }
60              
61             sub rebase_html_inplace {
62 8     8 0 14 my $url = shift;
63 8         51 $url = URI::URL->new( $url );
64            
65             #croak "Can only rewrite relative to an absolute URL!"
66             # unless $url->is_absolute;
67              
68             # Check if we have a tag which should replace the user-supplied URL
69 8 100       26437 if( $_[0] =~ s!<\s*\bbase\b[^>]+\bhref=([^>]+)>!!i ) {
70             # Extract the HREF:
71 3         8 my $href= $1;
72 3 50       15 if( $href =~ m!^(['"])(.*?)\1! ) {
    0          
73             # href="..." , with quotes
74 3         8 $href = $2;
75             } elsif( $href =~ m!^([^>"' ]+)! ) {
76             # href=... , without quotes
77 0         0 $href = $1;
78             } else {
79 0         0 die "Should not get here, weirdo href= tag: [$href]"
80             };
81            
82 3         5 my $old_url = $url;
83 3         7 $url = relative_url( $url, $href );
84             #warn "base: $old_url / $href => $url";
85             };
86              
87             # Rewrite absolute to relative
88             # Rewrite all tags with quotes
89 8         75 $_[0] =~ s!((?:\bsrc|\bhref)\s*=\s*(["']))(.+?)\2!$1 . relative_url($url,"$3") . $2!ige;
  6         74  
90             # Rewrite all tags without quotes
91 8         79 $_[0] =~ s!((?:\bsrc|\bhref)\s*=\s*)([^>"' ]+)!$1 . '"' . relative_url($url,"$2") . '"'!ige;
  4         20  
92             }
93              
94             =head2 C<< rebase_css >>
95              
96             Rewrites all CSS links to be relative to the given URL. This
97             only rewrites things that look like C<< url( ... ) >> .
98              
99             =cut
100              
101             sub rebase_css {
102 0     0 1 0 my($url, $css)= @_;
103            
104             #croak "Can only rewrite relative to an absolute URL!"
105             # unless $url->is_absolute;
106              
107             # Rewrite absolute to relative
108 0         0 rebase_css_inplace( $url, $css );
109            
110 0         0 $css
111             }
112              
113             sub rebase_css_inplace {
114 0     0 0 0 my $url = shift;
115 0         0 $url = URI::URL->new( $url );
116            
117             #croak "Can only rewrite relative to an absolute URL!"
118             # unless $url->is_absolute;
119              
120             # Rewrite absolute to relative
121 0         0 $_[0] =~ s!(url\(\s*(["']?))([^)]+?)\2!$1 . relative_url($url,"$3") . $2!ige;
  0         0  
122             }
123              
124             sub relative_url {
125 13     13 0 33 my( $curr, $url ) = @_;
126 13         55 my $res = URI::WithBase->new( $url, $curr );
127             # Copy parts that URI::WithBase doesn't...
128 13         2278 for my $part (qw( scheme host port )) {
129 39 100 100     1065 if( ! defined $res->$part and defined $curr->$part ) {
130 2         95 $res->$part( $curr->$part );
131             };
132             };
133 13         345 $res = $res->rel();
134            
135             #warn "$curr / $url => $res";
136            
137 13         5359 $res
138             };
139              
140             =head1 CAVEATS
141              
142             =head2 Does handle the C<< >> tag in a specific way
143              
144             If the HTML contains a C<< >> tag, it's C<< href= >> attribute
145             is used as the page URL relative to which links are rewritten.
146              
147             =head2 Uses regular expressions to do all parsing
148              
149             Instead of parsing the HTML into a DOM, performing the modifications and
150             then writing the DOM back out, this module uses a simplicistic regular
151             expressions to recognize C<< href= >> and C<< src= >> attributes and
152             to rewrite them.
153              
154             =head1 REPOSITORY
155              
156             The public repository of this module is
157             L.
158              
159             =head1 SUPPORT
160              
161             The public support forum of this module is
162             L.
163              
164             =head1 BUG TRACKER
165              
166             Please report bugs in this module via the RT CPAN bug queue at
167             L
168             or via mail to L.
169              
170             =head1 AUTHOR
171              
172             Max Maischein C
173              
174             =head1 COPYRIGHT (c)
175              
176             Copyright 2015-2018 by Max Maischein C.
177              
178             =head1 LICENSE
179              
180             This module is released under the same terms as Perl itself.
181              
182             =cut
183              
184             1;