fix for certain fields failing silently when they are required and left blank
[catagits/Reaction.git] / lib / Reaction / UI / WidgetClass.pm
CommitLineData
7adfd53f 1package Reaction::UI::WidgetClass;
2
3use Reaction::ClassExporter;
4use Reaction::Class;
5use Reaction::UI::Widget;
6use Data::Dumper;
ce0ce002 7use Devel::Declare;
206ce503 8use HTML::Entities ();
f2fef590 9use aliased 'Reaction::UI::WidgetClass::_OVER';
7adfd53f 10
11no warnings 'once';
12
81393881 13use namespace::clean -except => [ qw(meta) ];
7adfd53f 14
7adfd53f 15
81393881 16# for local() for fragment wrap
17our ($next_call, $fragment_args, $current_widget, $do_render, $new_args);
7adfd53f 18
81393881 19after 'do_import' => sub {
20 my ($self, $package) = @_;
21 Devel::Declare->install_declarator(
22 $package, 'fragment', DECLARE_NAME,
23 sub { },
24 sub {
25 WidgetClass->handle_fragment(@_);
26 }
27 );
28};
7adfd53f 29
81393881 30after 'setup_and_cleanup' => sub {
31 my ($self, $package) = @_;
32 {
33 no strict 'refs';
34 delete ${"${package}::"}{'fragment'};
35 }
36 #Devel::Declare->teardown_for($package);
37};
38override exports_for_package => sub {
39 my ($self, $package) = @_;
40 return (super(),
41 over => sub {
42 my ($collection) = @_;
43 confess "too many args, should be: over \$collection" if @_ > 1;
44 _OVER->new(collection => $collection);
45 },
46 render => sub {
47 my ($name, $over) = @_;
48
49 my $sig = "should be: render 'name' or render 'name' => over \$coll";
50 if (!defined $name) { confess "name undefined: $sig"; }
a6a29a32 51 if (ref $name) { confess "name is a ${\ref $name} ref, not a plain string: $sig"; }
81393881 52 if (defined $over && !(blessed($over) && $over->isa(_OVER))) {
53 confess "invalid args after name, $sig";
54 }
55 $do_render->($package, $current_widget, $name, $over);
56 },
57 arg => sub {
58 my ($name, $value) = @_;
59
60 my $sig = "should be: arg 'name' => \$value";
2f6669e1 61 if (@_ < 2) {
62 $name ||= 'undef';
63 $value ||= 'undef';
64 confess "Not enough arguments, $sig, got: $name => $value";
65 }
81393881 66 if (!defined $name) { confess "name undefined, $sig"; }
67 if (ref $name) { confess "name is not a string, $sig"; }
68
69 $new_args->{$name} = $value;
70 },
00b55ddd 71 localized => sub {
72 my($value) = @_;
73 return $_{self}->view->localize($value);
74 },
81393881 75 call_next => sub {
76 confess "args passed, should be just call_next; or call_next();"
77 if @_;
78 $next_call->(@$fragment_args);
79 },
80 event_id => sub {
81 my ($name) = @_;
82 $_{viewport}->event_id_for($name);
83 },
84 event_uri => sub {
85 my ($events) = @_;
86 my $vp = $_{viewport};
87 my %args = map{ $vp->event_id_for($_) => $events->{$_} } keys %$events;
88 $vp->ctx->req->uri_with(\%args);
89 },
a86de581 90 attrs => sub {
91 my ($attrs) = @_;
92 return join(' ', map {
206ce503 93 my $text = HTML::Entities::encode_entities( $attrs->{$_} );
a86de581 94 qq{$_="${text}"};
95 } keys %$attrs);
96 },
a3c28d59 97 implements => sub {
98 my ($name, $sub) = @_;
99 $package->meta->add_method($name, $sub);
100 },
81393881 101 );
102};
103override default_base => sub { ('Reaction::UI::Widget') };
104sub handle_fragment {
105 my ($self, $name, $proto, $code) = @_;
d7b00a50 106#warn ($self, $name, $code);
81393881 107 return ("_fragment_${name}" => $self->wrap_as_fragment($code));
108};
109sub wrap_as_fragment {
110 my ($self, $code) = @_;
111 return sub {
112 local $next_call;
113 if (ref $_[0] eq 'CODE') { # inside 'around' modifier
114 $next_call = shift;
115 }
116 local $fragment_args = \@_;
117
118 # $self->$method($do_render, \%_, $new_args)
119 local $current_widget = $_[0];
120 local $do_render = $_[1];
121 local *_ = \%{$_[2]};
122 local $_ = $_[2]->{_};
123 local $new_args = $_[3];
124 $code->(@_);
f2fef590 125 };
81393881 126};
7adfd53f 127
81393881 128__PACKAGE__->meta->make_immutable;
87018d74 129
7adfd53f 130
87018d74 1311;
132
7adfd53f 133=head1 NAME
134
135Reaction::UI::WidgetClass
136
137=head1 DESCRIPTION
138
139=head1 AUTHORS
140
141See L<Reaction::Class> for authors.
142
143=head1 LICENSE
144
145See L<Reaction::Class> for the license.
146
147=cut