| Mozilla-Mechanize documentation | Contained in the Mozilla-Mechanize distribution. |
Return a reference to the embedded (Gtk2::MozEmbed) widget.
Copyright 2005,2009 Scott Lanning <slanning@cpan.org>. All rights reserved.
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
| Mozilla-Mechanize documentation | Contained in the Mozilla-Mechanize distribution. |
package Mozilla::Mechanize::Browser; use strict; use warnings; use Glib qw(FALSE G_PRIORITY_LOW); use Gtk2 '-init'; use Mozilla::Mechanize::Browser::Gtk2MozEmbed; ## xxx: hack until I wrap nsIWebProgressListener or something in Mozilla::DOM my %STATE = ( START => 1, REDIRECTING => 2, TRANSFERRING => 4, NEGOTIATING => 8, STOP => 16, IS_REQUEST => 65536, IS_DOCUMENT => 131072, IS_NETWORK => 262144, IS_WINDOW => 524288, RESTORING => 16777216, IS_INSECURE => 4, IS_BROKEN => 1, IS_SECURE => 2, SECURE_HIGH => 262144, SECURE_MED => 65536, SECURE_LOW => 131072, IDENTITY_EV_TOPLEVEL => 1048576, ); sub new { my $pkg = shift; my $opts = shift; my $debug = delete $opts->{debug}; my $self = { netstopped => 0, debug => $debug, }; bless($self, $pkg); $self->debug('Browser->new, opts: ' . join(', ', map("$_=$opts->{$_}", keys(%$opts)))); my $window = Mozilla::Mechanize::Browser::Gtk2MozEmbed->new(); $window->set_default_size($opts->{width}, $opts->{height}); $window->iconify() unless $opts->{visible}; $window->fullscreen() if $opts->{fullscreen}; # XXX: maybe this isn't necessary (or even working) $window->signal_connect(delete_event => sub { $self->debug('delete_event signal'); # XXX: how do you check to make sure that the main loop # is actually running before calling main_quit? # Something in Glib::MainLoop, maybe. Gtk2->main_quit; return FALSE; }); my $embed = $window->{embed}; $self->{embed} = $embed; $self->{window} = $window; $embed->signal_connect(net_start => sub { net_start_cb($self, @_) }); # Any time a new page loads, this adds a "single-shot" idle callback # that stops the main loop. Thanks to muppet for the idea. $embed->signal_connect(net_stop => sub { net_stop_cb($self, @_) }); $embed->signal_connect(net_state => sub { net_state_cb($self, @_) }); $embed->signal_connect(net_state_all => sub { net_state_all_cb($self, @_) }); $embed->signal_connect(progress => sub { progress_cb($self, @_) }); $embed->signal_connect(progress_all => sub { progress_all_cb($self, @_) }); # Start off with a blank page $embed->load_url('about:blank'); $window->show_all(); $self->debug('Browser->new, main'); Gtk2->main; # quits after net_stop event fires return $self; }
sub embedded { $_[0]->{embed} } sub quit { my $self = shift; warn "Browser->quit\n" if $self->{debug}; $self->{window}->destroy(); } sub debug { my ($self, $msg) = @_; if ($self->{debug}) { my (undef, $file, $line) = caller(); print STDERR "$msg at $file line $line\n"; } } # When there is a change in the progress of loading a document. # The cur value indicates how much of the document has been downloaded. # The max value indicates the length of the document. If the value of # max is less than one the full length of the document can not be determined. sub progress_cb { my ($browser, $embed, $cur, $max) = @_; $browser->debug("progress signal: cur=$cur, max=$max"); } sub progress_all_cb { my ($browser, $embed, $uri, $cur, $max) = @_; $browser->debug("progress_all signal: cur=$cur, max=$max, uri=$uri\n" . " ref uri=", ref($uri)); } sub net_start_cb { my ($browser, $data) = @_; $browser->debug("net_start signal"); $browser->{netstopped} = 0; FALSE; } sub net_stop_cb { my ($browser, $embed, $data) = @_; $browser->debug("net_stop signal"); Glib::Idle->add( sub { $browser->debug("net_stop Idle, main_quit"); $browser->{netstopped} = 1; Gtk2->main_quit; FALSE; # uninstall }, undef, G_PRIORITY_LOW ); FALSE; # let any other handlers run } # I found it did something like this in # http://code.google.com/p/google-gadgets-for-linux/source/browse/trunk/extensions/gtkmoz_browser_element/browser_child.cc my $current_doc_loaded_mask = $STATE{STOP} | $STATE{IS_REQUEST}; sub net_state_cb { my ($browser, $embed, $state_flags, $data) = @_; $browser->debug("net_state_cb signal: flags=$state_flags, status=$data"); if (($state_flags & $current_doc_loaded_mask) == $current_doc_loaded_mask) { $browser->debug("current_doc loaded!"); net_stop_cb($browser, $embed, $data); } } sub net_state_all_cb { my ($browser, $embed, $uri, $state_flags, $data) = @_; $browser->debug("net_state_all: uri=$uri, flags=$state_flags, status=$data" . "ref uri=", ref($uri)); } 1; __END__