package Tk::HyperText; ########################################################## # Look to the end of this file for the POD documentation # ########################################################## use strict; use warnings; use base qw(Tk::Derived Tk::ROText); use Tk::PNG; use Tk::JPEG; use Tk::BrowseEntry; use Tk::Listbox; use Tk::Text; use HTML::TokeParser; use Data::Dumper; use URI::Escape; our $VERSION = "0.06"; Construct Tk::Widget 'HyperText'; sub Populate { my ($cw,$args) = @_; # Strip out the custom arguments for this widget. my $opts = { -attributes => { -anchor => { -normal => '#0000FF', -hover => '#FF0000', -active => '#FF0000', -visited => '#990099', }, -font => { -family => 'Times', -mono => 'Courier', -size => 'medium', -bold => 0, # Bold -italic => 0, # Italic -under => 0, # Underline -over => 0, # Overstrike }, -style => { -margins => 0, -color => '#000000', # Text color -back => '#FFFFFF', # Text back }, }, -continuous => 0, -allow => [], -deny => [], }; # Copy attributes over. if (exists $args->{'-attributes'}) { my $attr = delete $args->{'-attributes'}; foreach my $tag (keys %{$attr}) { foreach my $name (keys %{$attr->{$tag}}) { $opts->{'-attributes'}->{$tag}->{$name} = $attr->{$tag}->{$name}; } } } # Copy other options over. $opts->{'-continuous'} = delete $args->{'-continuous'} || delete $args->{'-continue'}; $opts->{'-allow'} = delete $args->{'-allow'} || []; $opts->{'-deny'} = delete $args->{'-deny'} || []; # Pass the remaining arguments to ROText. $args->{'-foreground'} = $opts->{'-attributes'}->{'-style'}->{'-color'}; $args->{'-background'} = $opts->{'-attributes'}->{'-style'}->{'-back'}; $cw->SUPER::Populate($args); # Reconfigure the ROText widget with our attributes. $cw->SUPER::configure ( -highlightthickness => 0, -exportselection => 1, -insertofftime => 1000, -insertontime => 0, -cursor => undef, -font => [ -family => $opts->{'-attributes'}->{'-font'}->{'-family'}, -size => $cw->_size ($opts->{'-attributes'}->{'-font'}->{'-size'}), ], ); $cw->{hypertext} = { html => '', # Holds the HTML code continue => $opts->{'-continuous'}, attrib => $opts->{'-attributes'}, history => {}, events => {}, permissions => 'allow_all', allow => {}, deny => {}, }; if (scalar @{$opts->{'-allow'}}) { $cw->allowedTags (@{$opts->{'-allow'}}); } if (scalar @{$opts->{'-deny'}}) { $cw->deniedTags (@{$opts->{'-deny'}}); } } sub setHandler { my ($cw,%handlers) = @_; foreach my $event (keys %handlers) { my $code = $handlers{$event}; $cw->{hypertext}->{events}->{$event} = $code; } } sub _event { my ($cw,$event,@args) = @_; if (exists $cw->{hypertext}->{events}->{$event}) { return &{$cw->{hypertext}->{events}->{$event}} ($cw,@args); } return undef; } sub loadString { my $cw = shift; my $text = shift; # Clear the widget. $cw->loadBlank(); # Set the HTML buffer = our string. $cw->{hypertext}->{html} = $text; $cw->{hypertext}->{plain} = $text; $cw->{hypertext}->{plain} =~ s/<(.|\n)+?>//sig; # Render the text. $cw->render ($text); } sub loadBlank { my $cw = shift; $cw->{hypertext}->{html} = ''; $cw->{hypertext}->{plain} = ''; $cw->delete ("0.0","end"); } sub allowedTags { my ($cw,@tags) = @_; $cw->{hypertext}->{allow} = {}; foreach (@tags) { $_ = lc($_); $cw->{hypertext}->{allow}->{$_} = 1; } } sub deniedTags { my ($cw,@tags) = @_; $cw->{hypertext}->{deny} = {}; foreach (@tags) { $_ = lc($_); $cw->{hypertext}->{deny}->{$_} = 1; } } sub allowHypertext { my $cw = shift; # Allow AIM-style HTML tags. my @allow = qw(html head title body a p br hr img font center sup sub b i u s); $cw->{hypertext}->{allow} = {}; $cw->{hypertext}->{deny} = {}; foreach (@allow) { $cw->{hypertext}->{allow}->{$_} = 1; } } sub allowEverything { my $cw = shift; # Allow everything again. $cw->{hypertext}->{allow} = {}; $cw->{hypertext}->{deny} = {}; } sub getText { my $cw = shift; my $asHTML = shift || 0; if ($asHTML) { return $cw->{hypertext}->{html}; } return $cw->{hypertext}->{plain}; } sub clearHistory { my $cw = shift; $cw->{hypertext}->{history} = {}; } sub render { my ($cw,$html) = @_; # Initialize the style stack. my $mAttr = $cw->{hypertext}->{attrib}; my %style = ( weight => 'normal', # or 'bold' slant => 'roman', # or 'italic' underline => 0, # or 1 overstrike => 0, # or 1 family => $mAttr->{'-font'}->{'-family'}, size => $mAttr->{'-font'}->{'-size'}, foreground => '', background => '', justify => 'left', # or 'center' or 'right' offset => 0, # for and lmargin1 => 0, # for
lmargin2 => 0, # and
    rmargin => 0, # and
      pre => 0, # inside
       tags
      		linking    => 0,        # inside ... tags
      		linktag    => '',       # Current linktag
      		inul       => 0,        # Inside 
        inol => 0, # Inside
          ullevel => 0, ollevel => 0, intable => 0, intd => 0, ); my @escape = ( '<' => '<', '>' => '>', '"' => '"', ''' => "'", ' ' => ' ', '®' => chr(0x00ae), '©' => chr(0x00a9), '♥' => chr(0x2665), '♦' => chr(0x2666), '♠' => chr(0x2660), '♣' => chr(0x2663), '&' => '&', ); my @stackList = (); my $ulLevel = 0; my $olLevel = 0; my @stackOLLevel = (); my @stackULLevel = (); my $ulStyles = {}; my $olStyles = {}; my %hyperlink = (); # Hyperlink tags my $tabledata = {}; # Table data my $tableid = 0; # Table ID my $formdata = {}; # Form data my $formname = ''; # Current form name my $curSelect = { # Selectbox data in => 0, # Not in a