Mozilla-Mechanize

 view release on metacpan or  search on metacpan

lib/Mozilla/Mechanize.pm  view on Meta::CPAN


=cut

sub close {
    my $self = shift;
    $self->agent->quit();
    $self->{agent} = undef;

    # XXX: do we need to run the GUI here?
}

sub open {
    my $self = shift;
    defined $self->{agent} and return;

    my $browser_opts = $self->{_opt};
    $browser_opts->{debug} = $self->{debug};

    $self->{agent} = Mozilla::Mechanize::Browser->new($browser_opts)
      or $self->die("Cannot create a new Browser");

#    foreach my $prop ( keys %{ $self->{_opt} } ) {
#        defined $self->{_opt}{ $prop } and
#            $self->{agent}->{ $prop } = $self->{_opt}{ $prop };
#    }

    return $self;
}

=head2 $moz->agent

Return a reference to the Browser object.

=cut

sub agent { $_[0]->{agent} }


=head1 PAGE-FETCHING METHODS

=head2 $moz->get( $url )

Fetch C<$url>.

=cut

sub get {
    my $self = shift;
    my $agent = $self->agent;
    my ($url) = @_;

    my $uri = $self->uri
        ? URI->new_abs($url, $self->uri->as_string)
        : URI->new($url);

    # XXX: how to add headers?
#    $agent->navigate({ URL     => $uri->as_string,
#                       Headers => $self->_extra_headers($uri) });

    $agent->embedded->load_url($uri->as_string);
    $self->_wait_while_busy;
}

=head2 $moz->reload()

Reload the page.

=cut

sub reload {
    $_[0]->agent->embedded->reload('reloadnormal');
    $_[0]->_wait_while_busy;
}

=head2 $moz->back()

Go back a page in the browser history.

=cut

sub back {
    $_[0]->agent->embedded->go_back;
    $_[0]->_wait_while_busy;
}

=head1 STATUS METHODS

=head2 $moz->success

B<XXX: I don't know how to implement this yet.
So this always returns true for now.>
In fact, if a URL doesn't exist, it'll pop up a dialog. :/

=cut

sub success {
#    $_[0]->agent->ReadyState >= 2;

    # XXX: uh??

    return 1;
}

=head2 $moz->uri

Return the URI of this document (as a URI object).
Note: whenever you do a submit, Mozilla appends a question mark
followed by any form input (name=value pairs separated by ampersands).

=cut

sub uri {
    my $self = shift;
    my $agent = $self->agent;
    my $embed = $agent->embedded;
    my $uri = $embed->get_location;
    URI->new($uri);
}

=head2 $moz->ct

Fetch the content-type of the document.

=cut

sub ct {
    my $self = shift;

    my $doc = $self->get_document;
    my $diid = Mozilla::DOM::NSDocument->GetIID;
    my $nsdoc = $doc->QueryInterface($diid);
    return $nsdoc->GetContentType;
}

=head2 $moz->current_form

Returns the current form as a C<Mozilla::Mechanize::Form> object.

=cut

sub current_form {
    my $self = shift;
    defined $self->{cur_form} or $self->form_number( 1 );

lib/Mozilla/Mechanize.pm  view on Meta::CPAN


=head2 $moz->_extract_images()

Return a list of images.
All images are mapped onto the L<Mozilla::Mechanize::Image|Mozilla::Mechanize::Image>
interface that mimics L<WWW::Mechanize::Image|WWW::Mechanize::Image>.

=cut

{
    # Recursively get image elements. This is necessary in order
    # to preserve their order. Too bad Mozilla doesn't have
    # an `all' method like Internet Explorer.

    my @images;

    sub _extract_images {
        my ($self, $subelement) = @_;
        my $node;

        # The first time, it's called with no subelement
        if (defined $subelement) {
            $node = $subelement;
        } else {
            @images = ();
            $node = $self->get_document_element;
        }

        # If it's an image element, get it; otherwise, recurse if has children
        if ($node->GetNodeName =~ /^(img|input)$/i) {
            my $tagname = lc $1;

            if ($tagname eq 'input') {
                # Element interface is more convenient for attributes
                my $element = $node->QueryInterface(Mozilla::DOM::Element->GetIID);
                # <input> are images only if they have a src
                # (XXX: or maybe should be if type="image"...)
                push @images, Mozilla::Mechanize::Image->new($element, $self)
                  if $element->HasAttribute('src');
                $self->debug("added '$tagname' image");
            } else {
                push @images, Mozilla::Mechanize::Image->new($node, $self);
                $self->debug("added '$tagname' image");
            }
        } elsif ($node->HasChildNodes) {
            my @children = $node->GetChildNodes;
            # skips #text nodes
            foreach my $child (grep {$_->GetNodeName !~ /^#/} @children) {
                $self->_extract_images($child);
            }
        }

        # Continue only at the top-level
        return if defined $subelement;

        $self->{images} = \@images;
        return wantarray ? @{ $self->{forms} } : $self->{forms};
    }
}

=head2 $self->_wait_while_busy()

This adds a "single-shot" idle callback that does Gtk2->main_quit,
then does Gtk2->main. The result is that whenever the UI becomes idle
it will exit the main loop. Thanks to muppet for the idea.
This is repeated until the net_stop event fires, indicating that
the new page has finished loading. (Note therefore that you can only
call this when you expect a new page to load.)

=cut

sub _wait_while_busy {
    my $self = shift;
    my $agent = $self->agent;

    do {
        Glib::Idle->add(sub {
            Gtk2->main_quit;
            FALSE;  # uninstall
        }, undef, G_PRIORITY_LOW);
        Gtk2->main;
    } until $agent->{netstopped};

    $self->{$_} = undef for qw(forms cur_form links images);
    return $self->success;
}

=head2 warn( @messages )

Centralized warning method, for diagnostics and non-fatal problems.
Defaults to calling C<CORE::warn>, but may be overridden by setting
C<onwarn> in the construcotr.

=cut

sub warn {
    my $self = shift;

    return unless my $handler = $self->{onwarn};

    return if $self->quiet;

    $handler->(@_);
}

=head2 die( @messages )

Centralized error method.  Defaults to calling C<CORE::die>, but
may be overridden by setting C<onerror> in the constructor.

=cut

sub die {
    my $self = shift;

    return unless my $handler = $self->{onerror};

    $handler->(@_);
}

# Not a method
sub __warn {

    eval "require Carp";
    if ( $@ ) {
        CORE::warn @_;
    } else {
        &Carp::carp;
    }
}

# Not a method



( run in 0.793 second using v1.01-cache-2.11-cpan-98e64b0badf )