File Coverage

blib/lib/HTML/Rebase.pm
Criterion Covered Total %
statement 37 46 80.4
branch 5 8 62.5
condition 3 3 100.0
subroutine 8 10 80.0
pod 2 5 40.0
total 55 72 76.3


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