package HTML::DOM::Element::Form; use strict; use warnings; no Carp(); use URI; require HTML::DOM::Element; require HTML::DOM::NodeList::Magic; #require HTML::DOM::Collection::Elements; our $VERSION = '0.035'; our @ISA = qw'HTML::DOM::Element'; use overload fallback => 1, '@{}' => sub { shift->elements }, '%{}' => sub { my $self = shift; $self->isa(scalar caller) || caller->isa('HTML::TreeBuilder') and return $self; $self->elements; }; my %elem_elems = ( input => 1, button => 1, select => 1, textarea => 1, ); sub elements { my $self = shift; my $collection = $self->{_HTML_DOM_elems} ||= do { my $collection = HTML::DOM::Collection::Elements->new( my $list = HTML::DOM::NodeList::Magic->new( sub { no warnings 'uninitialized'; grep( $elem_elems{tag $_} && attr $_ 'type', ne 'image', $self->descendants ), @{ $self->{_HTML_DOM_mg_elems}||[] } } )); $self->ownerDocument-> _register_magic_node_list($list); $collection; }; weaken $self; if (wantarray) { @$collection } else { $collection; } } sub add_element { # helper routine that formies use to add themselves to my $self = shift; # the elements list push @{ $self->{_HTML_DOM_mg_elems} ||= [] }, shift if $elem_elems{ $_[0]->tag }; return; } sub remove_element { # and this is how formies remove themselves when they my $self = shift; # get moved around the DOM my $removee = shift; @{ $self->{_HTML_DOM_mg_elems} } = grep $_ != $removee, @{ $self->{_HTML_DOM_elems} ||= [] } } sub length { shift->elements -> length } sub name { no warnings; shift->_attr( name => @_) . '' } sub acceptCharset { shift->_attr('accept-charset' => @_) } sub action { my $self = shift; (my $base = $self->ownerDocument->base) or return $self->_attr('action', @_); (new_abs URI $self->_attr('action' => @_), $self->ownerDocument->base) ->as_string } sub enctype { my $ret = shift->_attr('enctype' => @_); defined $ret ? $ret : 'application/x-www-form-urlencoded' } *encoding=*enctype; sub method { my $ret = shift->_attr('method' => @_); defined $ret ? lc $ret : 'get' } sub target { shift->_attr('target' => @_) } sub submit { shift->trigger_event('submit') } sub reset { shift->trigger_event('reset'); } sub trigger_event { my ($a,$evnt) = (shift,shift); $a->SUPER::trigger_event( $evnt, submit_default => $a->ownerDocument-> default_event_handler_for('submit'), reset_default => sub { $_->_reset for shift->target->elements }, @_, ); } # ------ HTML::Form compatibility methods ------ # sub inputs { my @ret; my %pos; my $self = shift; # This used to use ‘$self->elements’, but ->elements no longer # includes image buttons. for( grep($elem_elems{tag $_}, $self->descendants), @{ $self->{_HTML_DOM_mg_elems}||[] } ) { next if (my $tag = tag $_) eq 'button'; # HTML::Form doesn't deal # with