HTML-FillInForm-2.21/ 0000755 0001751 0001751 00000000000 12373152053 012652 5 ustar mark mark HTML-FillInForm-2.21/MANIFEST 0000644 0001751 0001751 00000001254 12373152053 014005 0 ustar mark mark Changes
MANIFEST
Makefile.PL
META.yml Module meta-data (added by MakeMaker)
README
lib/HTML/FillInForm.pm
t/00_base.t
t/01_form.t
t/02_hidden.t
t/03_checkbox.t
t/04_select.t
t/05_textarea.t
t/06_radio.t
t/07_reuse.t
t/08_multiple_objects.t
t/09_default_type.t
t/10_escape.t
t/11_target.t
t/12_mult.t
t/13_warning.t
t/14_password.t
t/15_multiple_fields.t
t/16_ignore_fields.t
t/17_xhtml.t
t/18_ignore_fdat.t
t/19_extra.t
t/20_scalarref.t
t/21_disable_fields.t
t/22_undef.t
t/23_absent_checkbox.t
t/24_radio_absent_checkboxes.t
t/25_select_absent_checkboxes.t
t/26_invalid_fields.t
t/data/form1.html
META.json Module JSON meta-data (added by MakeMaker)
HTML-FillInForm-2.21/README 0000644 0001751 0001751 00000002024 12373151675 013541 0 ustar mark mark This module automatically inserts data from a previous HTML form into the HTML input and select
tags. It is a subclass of HTML::Parser and uses it to parse the HTML and insert the values into the form
tags.
One useful application is after a user submits an HTML form without filling out required field.
HTML::FillInForm can be used to redisplay the HTML form with all the form elements containing the
submitted info.
Please note that this module requires HTML::Parser 3.26 or greater.
HTML::FillInForm installed by default by several web hosting providers,
including pair.com - see
http://www.pair.com/pair/support/library/serverconfig/perlmods.html
It is also available as a package for some Linux distribution, including Mandrake.
See:
http://rpmfind.net/linux/RPM/cooker/cooker/i586/Mandrake/RPMS/perl-HTML-FillInForm-0.29-2mdk.noarch.html
Copyright (c) 2002-2007 Thomas J. Mather, tjmather@maxmind.com
All rights reserved. This package is free software; you can redistribute
it and/or modify it under the same terms as Perl itself.
HTML-FillInForm-2.21/Changes 0000644 0001751 0001751 00000015475 12373152001 014152 0 ustar mark mark
2.21 - August 14th, 2014
- Declare CGI.pm as a testing dependency (RT #98012, thanks to Martin McGrath)
2.20 - August 10th, 2013
- Updated to support HTML5 (RT #75933, thanks to charsbar)
2.11 - June 3rd, 2013
Updated tests so that they pass with Perl 5.18 (Mark Stosberg)
2.1 - August 29th, 2011
Fixed disable_fields option (#52667 Dirk Braun, Goro Fuji)
Add an option to clear absent checkboxes (#44101 Alex Kapranoff)
Fix incorrectly multiple escaped data in list context (#34081 Miika Pekkarinen)
Allow FIF to process the new field types (URL, email, and number) as defined in the HTML5 draft and already implemented by the iPhone.
(Michael Fisher)
Allow alternate parsing class (Mark Stosberg)
mark invalid fields (Sam Tregar)
2.0 - September 11th, 2007
Allow passing an arrayref of hashrefs through fdat (Mark Stosberg, Michael Graham)
Several new shortcuts: (Mark Stosberg)
Allow calling fill() as a class method as a shortcut.
Allow \$html as shortcut for scalarref => \$html
Allow \@html as shortcut for arrayref => \@html
Allow \*html as shortcut for file => \*html
Allow 'html' as shortcut for file => 'html'
Allow $q as shortcut for fobject => $q
Allow \%fdat as shortcut for fdat => \%fdat
In summary, instead of this:
my $fif = HTML::FillInForm->new;
$fif->fill( scalarref => \$html, fdat => \%data );
You can simply write:
HTML::FillInForm->fill( \$html, \%data );
Fixed disable_fields bug (Boris Zentner)
Add support for ID attribute on form tags (name attribute is
deprecated in xhtml) [rt.cpan.org #27376] (Anthony Ettinger)
1.07 - August 2nd, 2007
Added 'disable_fields' method [rt.cpan.org #6342] (Trevor Schellhorn)
Support IE down-level revealed HTML comments [rt.cpan.org #19468] (Michael Peters)
hash is not reset before each() is called [rt.cpan.org #24980] (Simon P. Ditner)
Fix a bug the last plaintext part might be chopped if called via
scalarref [rt.cpan.org #21750] (Tatsuhiko Miyagawa)
Fix bug when passing 0 in array ref to textfields, also see
[rt.cpan.org #22195] (Paul Miller)
No longer generate warning if empty array as the value for a select attribute is passed (Dave Rolsky)
1.06 - October 13th, 2005
Distinguish between selects with and without the multiple attribute set (Alexander Hartmaier)
Added warnings to PREREQ_PM
1.05 - December 19th, 2004
Added new tests in 19_extra.t (Vsevolod (Simon) Ilyushchenko)
as part of Phalanx
Make it clearer that doesn't have a CGI.pm dependency.
1.04 - March 8th, 2004
Now queries passed objects for form fields as it encounters them instead of
asking for all fields up front. This allows the type of object passed
to not have to return all the fields in a empty ->param() call.
(Dave Rolsky)
Generate XHTML-compliant tags (Dave Rolsky)
Documented behavior when passing undef values.
Fixed bug when HTML form has two or more radio buttons and second or
higher radio button is selected. (Dan Kubb)
Made ignore_fields work with fdat, included new test script
18_ignore_fdat.t (James Tolley)
1.03 - October 15th 2003
Fixed warning messages when textarea doesn't have a name attribute
(Rob Brown)
1.02 - June 10th 2003
Updated required version number for HTML::Parser to 3.26 in Makefile.PL
(Ken Williams)
1.01 - December 31st 2002
Fixed issue with HTML::Parser decoding high-bit entities, by setting
attr_encoded option, now requires HTML::Parser >= 3.26. (Jonathan Swartz)
1.00 - August 28th 2002
Workaround for Opera 6.01/02 bug with selected radio boxes -
place space before ending "/>" in (Bill Moseley)
0.29 - May 5th 2002
Added ignore_fields option (Boris Zentner)
0.28 - April 27th 2002
Added missing ! in declaration handler (Boris Zentner)
Fill all values with the same name if one value is passed
(Boris Zentner, Gabriel Burka)
0.27 - April 20th 2002
Fixes to pass through comments, processing instructions, and
declarations (Boris Zentner)
0.26 - April 16th 2002
Added fill_password option (Tatsuhiko Miyagawa)
0.25 - April 3rd 2002
Fixed bug with passing single value to multi-valued fields
(Maurice Aubrey)
0.24 - March 3rd 2002
Added no_debug to use CGI in t/13_warning.t
0.23 - January 4th 2002
Cleaned up warning messages for input fields without a name (Boris Zentner)
0.22 - November 10th 2001
Fixed bug with multiple inputs (Mark Stosberg)
0.21 - October 16th 2001
Updated credits section
0.20 - October 16th 2001
Fixed bug where selected value of '0' were skipped (Trevor Schellhorn)
0.19 - August 25th 2001
Fixed bug where option values between tags had trailing or leading
whitespace (Ade Olonoh)
Fixed bug for type tags (Andrew Creer)
Fix for error message (object -> fobject) (Mark Stosberg)
0.18 - July 7th 2001
Fix for test on HTML escaping (thanks to Jost Krieger for report)
0.17 - June 29th 2001
Added "fill in target form" feature (Tatsuhiko Miyagawa)
0.16 - June 28th 2001
Fixed problems with HTML escaping (Tatsuhiko Miyagawa)
0.15 - June 18th 2001
Works with checkbox tags that don't have value attribute. (Philip Mak)
0.14 - May 17th 2001
Removed warning message for submit tags. (Joseph Yanni)
0.13 - May 13th 2001
Fixed bug when TYPE attr of input tag not set (Martin H. Sluka)
Added docs on password caching (Mark Stosberg)
0.12 - May 11th 2001
Support for multiple fobjects.
Fixed bug where new documents were feed into a used $fif object.
0.11 - March 16th 2001
Fixed problem when fdat maps the name of a textarea to an
empty string (''). Thanks to Jim Miner for the patch!
0.10 - January 19th 2001
Fixed problem with empty option tags (e.g. )
Thanks to Ade Olonoh for the patch!
0.09 - January 15th 2001
Text in textarea is now escaped.
0.08 - January 15th 2001
Option tags without "value" attribute get filled in correctly.
Will not croak anymore if fobject's param method returns undef.
0.07 - January 5th 2001
Added support for multiple checkboxes and select fields, thanks
to Patrick Michael Kane for the patch and test script for checkboxes!
0.06 - October 9th 2000
Fixed bug with "0" value in (hidden) fields
Added docs from using HTML::FillInForm from Apache::ASP and Apache::PageKit
0.05 - August 28th 2000
Added better support for checkboxes.
0.04 - August 10th 2000
Fixed bug with hidden fields
0.03 - August 10th 2000
FillInForm now forces hidden fields to have a value. So
is transformed to if no value is set for 'foo'.
Fixed bug with case-sensitivity and missing checkbox. Thanks to
Tom Lancaster for this bug report and fix!
Added some test scripts.
0.02 - June 27th 2000
Fixed bug with option tags. Now displays all 'option' tag attributes, in addition to selected and value.
Better support for boolean attributes.
0.01 - June 18th 2000
Initial Release of Module.
HTML-FillInForm-2.21/lib/ 0000755 0001751 0001751 00000000000 12373152053 013420 5 ustar mark mark HTML-FillInForm-2.21/lib/HTML/ 0000755 0001751 0001751 00000000000 12373152053 014164 5 ustar mark mark HTML-FillInForm-2.21/lib/HTML/FillInForm.pm 0000644 0001751 0001751 00000056133 12373152007 016532 0 ustar mark mark package HTML::FillInForm;
use integer; # no floating point math so far!
use strict; # and no funny business, either.
use Carp; # generate better errors with more context
# required for UNIVERSAL->can
require 5.005;
use vars qw($VERSION @ISA);
$VERSION = '2.21';
sub new {
my $class = shift;
my $self = bless {}, $class;
# required for attr_encoded
my %arg = @_ || ();
my $parser_class = $arg{parser_class} || 'HTML::Parser';
eval "require $parser_class;" || die "require $parser_class failed: $@";
@ISA = ($parser_class);
$self->init(@_);
unless ($self->can('attr_encoded')) {
die "attr_encoded method is missing. If are using HTML::Parser, you need at least version 3.26";
}
# tell HTML::Parser not to decode attributes
$self->attr_encoded(1);
return $self;
}
# a few shortcuts to fill()
sub fill_file { my $self = shift; return $self->fill('file' ,@_); }
sub fill_arrayref { my $self = shift; return $self->fill('arrayref' ,@_); }
sub fill_scalarref { my $self = shift; return $self->fill('scalarref',@_); }
# track the keys we support. Useful for file-name detection.
sub _known_keys {
return {
scalarref => 1,
arrayref => 1,
fdat => 1,
fobject => 1,
file => 1,
target => 1,
fill_password => 1,
ignore_fields => 1,
disable_fields => 1,
invalid_fields => 1,
invalid_class => 1,
}
}
sub fill {
my $self = shift;
# If we are called as a class method, go ahead and call new().
$self = $self->new if (not ref $self);
my %option;
# If the first arg is a scalarref, translate that to scalarref => $first_arg
if (ref $_[0] eq 'SCALAR') {
$option{scalarref} = shift;
}
elsif (ref $_[0] eq 'ARRAY') {
$option{arrayref} = shift;
}
elsif (ref $_[0] eq 'GLOB') {
$option{file} = shift;
}
elsif (ref $_[0]) {
croak "data source is not a reference type we understand";
}
# Last chance, if the first arg isn't one of the known keys, we
# assume it is a file name.
elsif (not _known_keys()->{$_[0]} ) {
$option{file} = shift;
}
else {
# Should be a known key. Nothing to do.
}
# Now, check to see if the next arg is also a reference.
my $data;
if (ref $_[0]) {
$data = shift;
$data = [$data] unless ref $data eq 'ARRAY';
for my $source (@$data) {
if (ref $source eq 'HASH') {
push @{ $option{fdat} }, $source;
}
elsif (ref $source) {
if ($source->can('param')) {
push @{ $option{fobject} }, $source;
}
else {
croak "data source $source does not supply a param method";
}
}
elsif (defined $source) {
croak "data source $source is not a hash or object reference";
}
}
}
# load in the rest of the options
%option = (%option, @_);
# As suggested in the docs, merge multiple fdats into one.
if (ref $option{fdat} eq 'ARRAY') {
my %merged;
for my $hash (@{ $option{fdat} }) {
for my $key (keys %$hash) {
$merged{$key} = $hash->{$key};
}
}
$option{'fdat'} = \%merged;
}
my %ignore_fields;
%ignore_fields = map { $_ => 1 } ( ref $option{'ignore_fields'} eq 'ARRAY' )
? @{ $option{ignore_fields} } : $option{ignore_fields} if exists( $option{ignore_fields} );
$self->{ignore_fields} = \%ignore_fields;
my %disable_fields;
%disable_fields = map { $_ => 1 } ( ref $option{'disable_fields'} eq 'ARRAY' )
? @{ $option{disable_fields} } : $option{disable_fields} if exists( $option{disable_fields} );
$self->{disable_fields} = \%disable_fields;
my %invalid_fields;
%invalid_fields = map { $_ => 1 } ( ref $option{'invalid_fields'} eq 'ARRAY' )
? @{ $option{invalid_fields} } : $option{invalid_fields} if exists( $option{invalid_fields} );
$self->{invalid_fields} = \%invalid_fields;
if (my $fdat = $option{fdat}){
# Copy the structure to prevent side-effects.
my %copy;
keys %$fdat; # reset fdat if each or Dumper was called on fdat
while(my($key, $val) = each %$fdat) {
next if exists $ignore_fields{$key};
$copy{ $key } = ref $val eq 'ARRAY' ? [ @$val ] : $val;
}
$self->{fdat} = \%copy;
}
# We want the reference to these objects to go out of scope at the
# end of the method.
local $self->{objects} = [];
if(my $objects = $option{fobject}){
unless(ref($objects) eq 'ARRAY'){
$objects = [ $objects ];
}
for my $object (@$objects){
# make sure objects in 'param_object' parameter support param()
defined($object->can('param')) or
croak("HTML::FillInForm->fill called with fobject option, containing object of type " . ref($object) . " which lacks a param() method!");
}
$self->{objects} = $objects;
}
if (my $target = $option{target}){
$self->{'target'} = $target;
}
if (my $invalid_class = $option{invalid_class}){
$self->{'invalid_class'} = $invalid_class;
} else {
$self->{'invalid_class'} = 'invalid';
}
if (defined($option{fill_password})){
$self->{fill_password} = $option{fill_password};
} else {
$self->{fill_password} = 1;
}
$self->{clear_absent_checkboxes} = $option{clear_absent_checkboxes};
# make sure method has data to fill in HTML form with!
unless(exists $self->{fdat} || $self->{objects}){
croak("HTML::FillInForm->fillInForm() called without 'fobject' or 'fdat' parameter set");
}
local $self->{object_param_cache};
if(my $file = $option{file}){
$self->parse_file($file);
} elsif (my $scalarref = $option{scalarref}){
$self->parse($$scalarref);
} elsif (my $arrayref = $option{arrayref}){
for (@$arrayref){
$self->parse($_);
}
}
$self->eof;
return delete $self->{output};
}
# handles opening HTML tags such as
sub start {
my ($self, $tagname, $attr, $attrseq, $origtext) = @_;
# set the current form
if ($tagname eq 'form') {
$self->{object_param_cache} = {};
if (exists $attr->{'name'} || exists $attr->{'id'}) {
$self->{'current_form'} = $attr->{'name'} || $attr->{'id'};
} else {
# in case of previous one without
delete $self->{'current_form'};
}
}
# This form is not my target.
if (exists $self->{'target'} &&
(! exists $self->{'current_form'} ||
$self->{'current_form'} ne $self->{'target'})) {
$self->{'output'} .= $origtext;
return;
}
# HTML::Parser converts tagname to lowercase, so we don't need /i
if ($self->{option_no_value}) {
$self->{output} .= '>';
delete $self->{option_no_value};
}
# Check if we need to disable this field
$attr->{disabled} = 'disabled'
if exists $attr->{'name'} and
exists $self->{disable_fields}{ $attr->{'name'} } and
$self->{disable_fields}{ $attr->{'name'} } and
not ( exists $attr->{disabled} and $attr->{disabled} );
# Check if we need to invalidate this field
my $invalidating = 0;
if (exists $attr->{name} and
exists $self->{invalid_fields}{ $attr->{name} } and
$self->{invalid_fields}{ $attr->{name} }) {
$invalidating = 1;
if (exists $attr->{class} and length $attr->{class}) {
# don't add the class if it's already there
unless ($attr->{class} =~ /\b\Q$self->{invalid_class}\E\b/) {
$attr->{class} .= " $self->{invalid_class}";
}
} else {
$attr->{class} = $self->{invalid_class};
}
}
if ($tagname eq 'input'){
my $value = exists $attr->{'name'} ? $self->_get_param($attr->{'name'}) : undef;
# force hidden fields to have a value
$value = '' if exists($attr->{'type'}) && $attr->{'type'} eq 'hidden' && ! exists $attr->{'value'} && ! defined $value;
# browsers do not pass unchecked checkboxes at all, so hack around
$value = '' if $self->{clear_absent_checkboxes} && !defined $value && exists($attr->{'type'}) && ($attr->{'type'} eq 'checkbox' || $attr->{'type'} eq 'radio');
if (defined($value)){
# check for input type, noting that default type is text
if (!exists $attr->{'type'} ||
$attr->{'type'} =~ /^(text|textfield|hidden|tel|search|url|email|datetime|date|month|week|time|datetime\-local|number|range|color|)$/i){
if ( ref($value) eq 'ARRAY' ) {
$value = shift @$value;
$value = '' unless defined $value;
}
$attr->{'value'} = __escapeHTML($value);
} elsif (lc $attr->{'type'} eq 'password' && $self->{fill_password}) {
if ( ref($value) eq 'ARRAY' ) {
$value = shift @$value;
$value = '' unless defined $value;
}
$attr->{'value'} = __escapeHTML($value);
} elsif (lc $attr->{'type'} eq 'radio'){
if ( ref($value) eq 'ARRAY' ) {
$value = $value->[0];
$value = '' unless defined $value;
}
# value for radio boxes default to 'on', works with netscape
$attr->{'value'} = 'on' unless exists $attr->{'value'};
if ($attr->{'value'} eq __escapeHTML($value)){
$attr->{'checked'} = 'checked';
} else {
delete $attr->{'checked'};
}
} elsif (lc $attr->{'type'} eq 'checkbox'){
# value for checkboxes default to 'on', works with netscape
$attr->{'value'} = 'on' unless exists $attr->{'value'};
delete $attr->{'checked'}; # Everything is unchecked to start
$value = [ $value ] unless ref($value) eq 'ARRAY';
foreach my $v ( @$value ) {
if ( $attr->{'value'} eq __escapeHTML($v) ) {
$attr->{'checked'} = 'checked';
}
}
# } else {
# warn(qq(Input field of unknown type "$attr->{type}": $origtext));
}
}
$self->{output} .= "<$tagname";
while (my ($key, $value) = each %$attr) {
next if $key eq '/';
$self->{output} .= sprintf qq( %s="%s"), $key, $value;
}
# extra space put here to work around Opera 6.01/6.02 bug
$self->{output} .= ' /' if $attr->{'/'};
$self->{output} .= ">";
} elsif ($tagname eq 'option'){
my $value = $self->_get_param($self->{selectName});
# browsers do not pass selects with no selected options at all,
# so hack around
$value = '' if $self->{clear_absent_checkboxes} && !defined $value;
$value = [ $value ] unless ( ref($value) eq 'ARRAY' );
if ( defined $value->[0] ){
delete $attr->{selected} if exists $attr->{selected};
if(defined($attr->{'value'})){
# option tag has value attr -
if ($self->{selectMultiple}){
# check if the option tag belongs to a multiple option select
foreach my $v ( grep { defined } @$value ) {
if ( $attr->{'value'} eq __escapeHTML($v) ){
$attr->{selected} = 'selected';
}
}
} else {
# if not every value of a fdat ARRAY belongs to a different select tag
if (not $self->{selectSelected}){
if ( $attr->{'value'} eq __escapeHTML($value->[0])){
shift @$value if ref($value) eq 'ARRAY';
$attr->{selected} = 'selected';
$self->{selectSelected} = 1; # remember that an option tag is selected for this select tag
}
}
}
} else {
# option tag has no value attr -
# save for processing under text handler
$self->{option_no_value} = __escapeHTML($value);
}
}
$self->{output} .= "<$tagname";
while (my ($key, $value) = each %$attr) {
$self->{output} .= sprintf qq( %s="%s"), $key, $value;
}
unless ($self->{option_no_value}){
# we can close option tag here
$self->{output} .= ">";
}
} elsif ($tagname eq 'textarea'){
# need to re-output the