aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwreis <wreis@03d0b0b2-0e1a-0410-a411-fdb2f4bd65d7>2009-07-31 13:01:55 +0000
committerwreis <wreis@03d0b0b2-0e1a-0410-a411-fdb2f4bd65d7>2009-07-31 13:01:55 +0000
commit87d3d076c2d0e7f15c93c8cbdaaff34fd7caab75 (patch)
tree3b375791173f23a5bf61966af99060263a56de7a
parentfff7579c4333dc543b987f447b454772a8abe28f (diff)
parenteb09f78b4b13f27599dfe9dee467e4731b29c6f0 (diff)
downloadreaction-87d3d076c2d0e7f15c93c8cbdaaff34fd7caab75.tar.gz
reaction-87d3d076c2d0e7f15c93c8cbdaaff34fd7caab75.zip
r22767@hercule (orig r1158): mateu | 2009-07-28 14:16:29 +0100
Document make_context_closure(). r22768@hercule (orig r1159): mateu | 2009-07-28 14:30:05 +0100 Avoid circular refs with target_model for login actions r22771@hercule (orig r1162): xinming | 2009-07-29 06:10:29 +0100 Merge branch utf8_support branch (r1109:1112) into trunk. r22786@hercule (orig r1177): wreis | 2009-07-30 22:39:28 +0100 r4424@www43 (orig r1173): wallacer | 2009-07-30 14:06:53 -0500 branching for action_filter feature in Role::Actions r4426@www43 (orig r1175): wallacer | 2009-07-30 16:13:22 -0500 added action_filter r4427@www43 (orig r1176): wallacer | 2009-07-30 16:39:15 -0500 fixed default value r22788@hercule (orig r1179): wreis | 2009-07-30 22:45:32 +0100 patch from groditi r22795@hercule (orig r1186): wreis | 2009-07-31 13:53:07 +0100 tweaks for SearchableListViewContainer
-rw-r--r--lib/Reaction/InterfaceModel/Action/User/Login.pm3
-rw-r--r--lib/Reaction/UI/Controller.pm39
-rw-r--r--lib/Reaction/UI/LayoutSet.pm2
-rw-r--r--lib/Reaction/UI/ViewPort/Role/Actions.pm7
-rw-r--r--lib/Reaction/UI/ViewPort/SearchableListViewContainer.pm15
-rw-r--r--lib/Reaction/UI/Window.pm14
6 files changed, 68 insertions, 12 deletions
diff --git a/lib/Reaction/InterfaceModel/Action/User/Login.pm b/lib/Reaction/InterfaceModel/Action/User/Login.pm
index 31abd8b..21c5e03 100644
--- a/lib/Reaction/InterfaceModel/Action/User/Login.pm
+++ b/lib/Reaction/InterfaceModel/Action/User/Login.pm
@@ -7,7 +7,8 @@ use Reaction::Types::Core qw(SimpleStr Password);
use namespace::clean -except => [ qw(meta) ];
extends Action;
-
+# Avoid circular ref with target_model for Auth controller login actions.
+sub BUILD { Scalar::Util::weaken($_[0]->{target_model}) }
has 'username' => (isa => SimpleStr, is => 'rw', lazy_fail => 1);
has 'password' => (isa => Password, is => 'rw', lazy_fail => 1);
diff --git a/lib/Reaction/UI/Controller.pm b/lib/Reaction/UI/Controller.pm
index d5c2b28..46456bd 100644
--- a/lib/Reaction/UI/Controller.pm
+++ b/lib/Reaction/UI/Controller.pm
@@ -184,6 +184,45 @@ controller.
$captures and $args default to the current requests $captures and
$args if not supplied.
+=head2 make_context_closure
+
+The purpose of this method is to prevent memory leaks.
+It weakens the context object, often denoted $c, and passes it as the
+first argument to the sub{} that is passed to the make_context_closure method.
+In other words,
+
+=over 4
+
+make_context_closure returns sub { $sub_you_gave_it->($weak_c, @_)
+
+=back
+
+To further expound up this useful construct consider code written before
+make_context_closure was created:
+
+ on_apply_callback =>
+ sub {
+ $self->after_search( $c, @_ );
+ }
+ ),
+
+This could be rewritten as:
+
+ on_apply_callback => $self->make_context_closure(
+ sub {
+ my $weak_c = shift;
+ $self->after_search( $weak_c, @_ );
+ }
+ ),
+
+Or even more succintly:
+
+ on_apply_callback => $self->make_context_closure(
+ sub {
+ $self->after_search( @_ );
+ }
+ ),
+
=head1 AUTHORS
See L<Reaction::Class> for authors.
diff --git a/lib/Reaction/UI/LayoutSet.pm b/lib/Reaction/UI/LayoutSet.pm
index a976d5b..1ebc646 100644
--- a/lib/Reaction/UI/LayoutSet.pm
+++ b/lib/Reaction/UI/LayoutSet.pm
@@ -55,6 +55,8 @@ sub has_layout { exists $_[0]->layouts->{$_[1]} };
sub _load_file {
my ($self, $file, $build_args) = @_;
my $data = $file->slurp;
+ utf8::decode($data)
+ unless utf8::is_utf8($data);
my $layouts = $self->layouts;
# cheesy match for "=for layout name ... =something"
# final split group also handles last in file, (?==) is lookahead
diff --git a/lib/Reaction/UI/ViewPort/Role/Actions.pm b/lib/Reaction/UI/ViewPort/Role/Actions.pm
index 6f3cd6a..ebd2d3c 100644
--- a/lib/Reaction/UI/ViewPort/Role/Actions.pm
+++ b/lib/Reaction/UI/ViewPort/Role/Actions.pm
@@ -16,6 +16,10 @@ has action_order => (
isa => 'ArrayRef'
);
+has action_filter => (
+ isa => 'CodeRef', is => 'ro',
+);
+
has action_prototypes => (
is => 'ro',
isa => 'HashRef',
@@ -35,7 +39,8 @@ sub _build_computed_action_order {
($self->has_action_order ? $self->action_order : []),
[ keys %{ $self->action_prototypes } ]
);
- return $ordered ;
+ return $self->has_action_filter ?
+ $self->action_filter->($ordered, $self->model) : $ordered;
}
sub _build_actions {
diff --git a/lib/Reaction/UI/ViewPort/SearchableListViewContainer.pm b/lib/Reaction/UI/ViewPort/SearchableListViewContainer.pm
index b9f919d..a5696c9 100644
--- a/lib/Reaction/UI/ViewPort/SearchableListViewContainer.pm
+++ b/lib/Reaction/UI/ViewPort/SearchableListViewContainer.pm
@@ -5,6 +5,7 @@ use Reaction::Class;
use aliased 'Reaction::InterfaceModel::Action::Search::UpdateSpec', 'UpdateSearchSpec';
use aliased 'Reaction::UI::ViewPort::ListViewWithSearch';
use aliased 'Reaction::UI::ViewPort::Action' => 'ActionVP';
+use aliased 'Reaction::UI::ViewPort';
use aliased 'Reaction::UI::ViewPort::Collection::Role::Pager', 'PagerRole';
use Method::Signatures::Simple;
@@ -14,18 +15,20 @@ use namespace::clean -except => 'meta';
extends 'Reaction::UI::ViewPort';
has 'listview' => (
- isa => ListViewWithSearch,
+ isa => ViewPort,
is => 'ro',
required => 1,
);
-has 'search_form' => (isa => ActionVP, is => 'ro', required => 1);
+has 'search_form' => (isa => ViewPort, is => 'ro', required => 1);
override BUILDARGS => sub {
my $args = super;
my $spec_event_id = $args->{location}.':search-spec';
my $spec_class = $args->{spec_class}
or confess "Argument spec_class is required";
+ my $listview_class = $args->{'listview_class'} || ListViewWithSearch;
+ my $search_form_class = $args->{'search_form_class'} || ActionVP;
my $action_class = $args->{action_class}
or confess "Argument action_class is required";
# TODO: how do we autodiscover spec classes?
@@ -39,15 +42,13 @@ override BUILDARGS => sub {
}
};
my $listview_location = $args->{location}.'-listview';
- # should this maybe use the listview class in $args->{listview}?
- my $listview = $args->{listview} = ListViewWithSearch->new(
+ my $listview = $args->{listview} = $listview_class->new(
%$args,
- layout => 'list_view',
+ layout => $args->{'listview_layout'} || 'list_view',
search_spec => $spec,
location => $listview_location,
);
- # same as with listview wrt. class name
- $args->{search_form} = ActionVP->new(
+ $args->{search_form} = $search_form_class->new(
model => $action_class->new(target_model => $spec),
location => $args->{location}.'-search_form',
apply_label => 'search',
diff --git a/lib/Reaction/UI/Window.pm b/lib/Reaction/UI/Window.pm
index 610a935..876a286 100644
--- a/lib/Reaction/UI/Window.pm
+++ b/lib/Reaction/UI/Window.pm
@@ -51,14 +51,22 @@ sub flush_events {
foreach my $type (qw/query body/) {
my $meth = "${type}_parameters";
my $param_hash = { %{$ctx->req->$meth} }; # yeah, FocusStack deletes it
- $self->focus_stack->apply_events($param_hash)
- if keys %$param_hash;
+ my @param_keys = keys %$param_hash;
+ if (@param_keys) {
+ for (@param_keys) {
+ utf8::decode($param_hash->{$_})
+ unless (utf8::is_utf8($param_hash->{$_}));
+ }
+ $self->focus_stack->apply_events($param_hash);
+ }
}
};
sub flush_view {
my ($self) = @_;
my $res = $self->ctx->res;
- $res->body($self->view->render_window($self));
+ my $res_body = $self->view->render_window($self);
+ utf8::encode($res_body) if utf8::is_utf8($res_body);
+ $res->body($res_body);
$res->content_type($self->content_type);
};