package Gtk::HTML::Simple;
use Gtk::HTML;
use LWP::UserAgent;
use URI;
use Gtk::LWP;
$VERSION = 0.1;
@ISA = qw(Gtk::HTML);
my $default_ua;
# TODO: handle page loading stopping nicely
sub new {
my ($self, $url) = @_;
$self = new Gtk::HTML;
$self = bless $self, __PACKAGE__;
$self->{_base} = new URI("file:./");
$self->{_aborting} = {};
$self->{_loading} = {};
$self->{_history} = [];
$self->{_histid} = undef;
$self->signal_connect('url_requested', sub {shift->load_url(@_)});
$self->signal_connect('link_clicked', sub {shift->load_url(@_)});
$self->signal_connect('submit', sub {shift->submit(@_)});
$self->signal_connect('load_done', sub {shift->load_done(@_)});
$self->load_url($url) if $url;
$self;
}
sub get_agent {
my ($self) = shift;
unless ($self->{_ua}) {
unless ($default_ua) {
$default_ua = LWP::UserAgent->new;
$default_ua->agent("Gtk::HTML::Simple/$VERSION");
$default_ua->env_proxy;
}
$self->{_ua} = $default_ua;
}
return $self->{_ua};
}
sub stop_loading {
my ($self) = shift;
warn "Aborting load...\n";
# doesn't work...
# foreach my $k (keys %{$self->{_loading}}) {
# $self->{_aborting}{$k} = 1 if $k;
# }
# $self->{_aborting}{$self->{_loading}{0}} =1;
# foreach my $k (keys %{$self->{_loading}}) {
# $self->{_aborting}{$k} = 1 if $k;
# }
#Gtk->main_iteration while (Gtk->events_pending() || keys %{$self->{_aborting}});
#warn "\ndone\n";
}
sub load_done {
my ($self) = shift;
$self->{_loading} = {};
}
sub load_url {
my ($self, $url, $handle) = @_;
my $ua = $self->get_agent;
my ($req, $res);
#Gtk->main_iteration while (Gtk->events_pending);
if (ref($url) && $url->isa('HTTP::Request')) {
$req = $url;
} else {
#warn "REQUEST: $url ($self->{_base})\n";
$req = new HTTP::Request('GET', URI->new_abs($url, $self->{_base}));
}
unless ($handle) {
$self->stop_loading() if ($self->{_loading}{0});
# that is, load a new page
$self->{_loading}{0} = $handle = $self->begin;
$self->{_base} = $req->uri;
} else {
$self->{_loading}{$handle} = 1;
}
#warn "REQUEST: $handle\n";
$res = $ua->request($req, sub {
my ($d) = shift;
warn "User interrupt of $handle\n",die "User interrupt\n" if delete $self->{_aborting}{$handle};
$self->write($handle, $d) if (defined ($d) && length($d));
}, 4096);
delete $self->{_aborting}{$handle};
if ($res->is_success) {
$self->end($handle, 'ok');
} else {
$self->write($handle, $res->status_line);
$self->end($handle, 'error');
}
return $res;
}
sub submit {
my ($self, $method, $url, $encoding) = @_;
my $req;
# no POST yet
$url .= '?'.$encoding if (defined $encoding && length($encoding));
$self->{_base} = URI->new_abs($url, $self->{_base});
$req = new HTTP::Request($method, $self->{_base});
return $self->load_url($req);
}
1;