package HTML::Display::Common; =head1 NAME HTML::Display::Common - routines common to all HTML::Display subclasses =cut use strict; use HTML::TokeParser; use URI::URL; use vars qw($VERSION); $VERSION='0.39'; use Carp qw( croak ); =head2 __PACKAGE__-Enew %ARGS Creates a new object as a blessed hash. The passed arguments are stored within the hash. If you need to do other things in your constructor, remember to call this constructor as well : =for example no warnings 'redefine'; *HTML::Display::WhizBang::display_html = sub {}; =for example begin package HTML::Display::WhizBang; use parent 'HTML::Display::Common'; sub new { my ($class) = shift; my %args = @_; my $self = $class->SUPER::new(%args); # do stuff $self; }; =for example end =for example_testing package main; use HTML::Display; my $browser = HTML::Display->new( class => "HTML::Display::WhizBang"); isa_ok($browser,"HTML::Display::Common"); =cut sub new { my ($class) = shift; #croak "Odd number" if @_ % 2; my $self = { @_ }; bless $self,$class; $self; }; =head2 $display->display %ARGS This is the routine used to display the HTML to the user. It takes the following parameters : html => SCALAR containing the HTML file => SCALAR containing the filename of the file to be displayed base => optional base url for the HTML, so that relative links still work location (synonymous to base) =head3 Basic usage : =for example no warnings 'redefine'; *HTML::Display::new = sub { my $class = shift; require HTML::Display::Dump; return HTML::Display::Dump->new(@_); }; =for example begin my $html = "

Hello world!

"; my $browser = HTML::Display->new(); $browser->display( html => $html ); =for example end =for example_testing isa_ok($browser, "HTML::Display::Dump","The browser"); is( $main::_STDOUT_,"

Hello world!

","HTML gets output"); =head3 Location parameter : If you fetch a page from a remote site but still want to display it to the user, the C parameter comes in very handy : =for example no warnings 'redefine'; *HTML::Display::new = sub { my $class = shift; require HTML::Display::Dump; return HTML::Display::Dump->new(@_); }; =for example begin my $html = ''; my $browser = HTML::Display->new(); # This will display part of the Google logo $browser->display( html => $html, base => 'http://www.google.com' ); =for example end =for example_testing isa_ok($browser, "HTML::Display::Dump","The browser"); is( $main::_STDOUT_, '', "HTML gets output"); $main::_STDOUT_ = ""; $browser->display( html => $html, location => 'http://www.google.com' ); is( $main::_STDOUT_, '', "HTML gets output"); =cut sub display { my ($self) = shift; my %args; if (scalar @_ == 1) { %args = ( html => $_[0] ); } else { %args = @_; }; if ($args{file}) { my $filename = delete $args{file}; local $/; local *FILE; open FILE, "<", $filename or croak "Couldn't read $filename"; $args{html} = ; }; $args{base} = delete $args{location} if (! exists $args{base} and exists $args{location}); my $new_html; if (exists $args{base}) { # trim to directory create BASE HREF # We are carefull to not trim if we just have http://domain.com my $location = URI::URL->new( $args{base} ); my $path = $location->path; $path =~ s%(?scheme, $location->authority , $path; require HTML::TokeParser::Simple; my $p = HTML::TokeParser::Simple->new(\$args{html}) || die 'could not create HTML::TokeParser::Simple object'; my ($has_head,$has_base); while (my $token = $p->get_token) { if ( $token->is_start_tag('head') ) { $has_head++; } elsif ( $token->is_start_tag('base')) { $has_base++; last; }; }; # restart parsing $p = HTML::TokeParser::Simple->new(\$args{html}) || die 'could not create HTML::TokeParser::Simple object'; while (my $token = $p->get_token) { if ( $token->is_start_tag('html') and not $has_head) { $new_html .= $token->as_is . qq{}; } elsif ( $token->is_start_tag('head') and not $has_base) { # handle an empty : if ($token->as_is =~ m!^<\s*head\s*/>$!i) { $new_html .= qq{} } else { $new_html .= $token->as_is . qq{}; }; } elsif ( $token->is_start_tag('base') ) { # If they already have a , give up if ($token->return_attr->{href}) { $new_html = $args{html}; last; } else { $token->set_attr('href',$location); $new_html .= $token->as_is; }; } else { $new_html .= $token->as_is; } }; } else { $new_html = $args{html}; }; $self->display_html($new_html); }; =head1 AUTHOR Copyright (c) 2004-2007 Max Maischein C<< >> =head1 LICENSE This module is released under the same terms as Perl itself. =cut 1;