package ActiveState::Browser; our $VERSION = "1.03"; use strict; use ActiveState::Handy qw(shell_quote); use ActiveState::Path qw(find_prog abs_path join_path); use ActiveState::Run qw(run); use constant IS_WIN32 => ($^O eq "MSWin32"); use constant IS_DARWIN => ($^O eq "darwin"); our $BROWSER ||= $ENV{AS_BROWSER}; unless ($BROWSER) { if (IS_WIN32) { $BROWSER = "start %s"; } elsif (IS_DARWIN) { $BROWSER = "/usr/bin/open %s"; } else { my @try = qw(xdg-open); if ($ENV{BROWSER}) { push(@try, split(/:/, $ENV{BROWSER})); } else { push(@try, qw(firefox galeon mozilla opera netscape)); } unshift(@try, "kfmclient") if $ENV{KDE_FULL_SESSION}; unshift(@try, "gnome-open") if $ENV{GNOME_DESKTOP_SESSION_ID}; for (@try) { if (my $p = find_prog($_)) { $BROWSER = $p; if ($_ eq "kfmclient") { $BROWSER = [$BROWSER, "openURL"]; } elsif ($_ eq "gnome-open" || $_ eq "opera") { # fine as it is } else { $BROWSER = shell_quote($BROWSER) . " %s &"; } last; } } } } our $HTML_DIR; $HTML_DIR ||= abs_path("."); sub can_open { my $url = shift; return 0 unless $BROWSER; return 1 if $url =~ /^(\w+):/; return !!eval { _resolve_file_url($url) }; } sub _resolve_file_url { my $url = shift; my $frag; $frag = $1 if $url =~ s/#(.*)//; $url = join_path($HTML_DIR, $url); die "Help file $url not found\n" unless -f $url; $url = Win32::GetShortPathName($url) if IS_WIN32; $url = (IS_WIN32 ? "file:///" : "file://") . $url; $url .= "#$frag" if defined $frag; return $url; } sub _browser_cmd { my($url, $browser) = @_; $browser ||= $BROWSER || die "No browser specified"; my $cmd; if (ref($browser)) { $cmd = shell_quote(@$browser, $url); } elsif ($browser =~ /%/) { $cmd = $browser; $url = shell_quote($url); # substitute %s with url, and %% to %. $cmd =~ s/%([%s])/$1 eq '%' ? '%' : $url/eg; } else { $cmd = shell_quote($browser, $url); } #$cmd .= " 2>/dev/null 1>&2 " unless IS_WIN32; return $cmd; } sub open { my $url = shift; if (IS_WIN32 && eval { require ActiveState::Win32::Shell }) { my($document,$fragment) = $url =~ m,^(?:file:///?)?([^#]+)(?:#(.*))?$,; unless ($document =~ /^\w{2,}:/) { $document = join_path($HTML_DIR, $document); return if ActiveState::Win32::Shell::BrowseDocument($document, $fragment); } ActiveState::Win32::Shell::BrowseUrl($url); return; } $url = _resolve_file_url($url) unless $url =~ /^\w{2,}:/; die "Can't find any browser to use. Try to set the AS_BROWSER environment variable.\n" unless $BROWSER; run(_browser_cmd($url, $BROWSER)); } 1; __END__ =head1 NAME ActiveState::Browser - Interface to invoke the web-browser =head1 SYNOPSIS use ActiveState::Browser; ActiveState::Browser::open("http://www.activestate.com"); =head1 DESCRIPTION The ActiveState::Browser module provides an interface to make a web browser pop up showing some URL or file. The following functions are provided: =over =item open( $url ) This will try to open up a web browser displaying the given URL. The function will croak if the $url can't be resolved or if no suitable browser could be found. The can_open() test can be used to protect against such failure, but note that such a test is not race-proof. If the $url is absolute it is passed directly to the browser. If the $url is relative it is looked up relative to the directory C<$ActiveState::Browser::HTML_DIR>, which defaults to the current directory. =item can_open( $url ) Will return TRUE if we can invoke a browser for the given URL. If the URL is not to a local file, then this always returns TRUE, given that a browser program was found. =back =head1 ENVIRONMENT The AS_BROWSER environment variable can be set to override what browser to use. The string C<%s> will be replaced with the URL to open. If no C<%s> is present the string is taken as a command to invoke with the URL as the only argument. The C<%s> template was inspired by the BROWSER environment variable suggestion that appear quite dead; see L. Note that the AS_BROWSER is B a colon separated list. =head1 BUGS none. =cut