From b4e081f82ee3491636b87a027e8eee2533b520f1 Mon Sep 17 00:00:00 2001 From: mateu Date: Tue, 28 Jul 2009 13:16:29 +0000 Subject: Document make_context_closure(). --- lib/Reaction/UI/Controller.pm | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) 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 for authors. -- cgit v1.2.3-54-g00ecf From 81cb15f7aa10244bab691f3beb48ff71aa6dd7ac Mon Sep 17 00:00:00 2001 From: mateu Date: Tue, 28 Jul 2009 13:30:05 +0000 Subject: Avoid circular refs with target_model for login actions --- lib/Reaction/InterfaceModel/Action/User/Login.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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); -- cgit v1.2.3-54-g00ecf From 4edebf11a6eb893a7dea6aedd7565497b8907b6b Mon Sep 17 00:00:00 2001 From: xinming Date: Wed, 29 Jul 2009 05:10:29 +0000 Subject: Merge branch utf8_support branch (r1109:1112) into trunk. --- lib/Reaction/UI/LayoutSet.pm | 2 ++ lib/Reaction/UI/Window.pm | 14 +++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) 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/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); }; -- cgit v1.2.3-54-g00ecf -- cgit v1.2.3-54-g00ecf From 565a1fc7fe67c721f2766bdc3f55c5fcb33fc760 Mon Sep 17 00:00:00 2001 From: wreis Date: Thu, 30 Jul 2009 21:13:22 +0000 Subject: added action_filter --- lib/Reaction/UI/ViewPort/Role/Actions.pm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/Reaction/UI/ViewPort/Role/Actions.pm b/lib/Reaction/UI/ViewPort/Role/Actions.pm index 6f3cd6a..e78ba4d 100644 --- a/lib/Reaction/UI/ViewPort/Role/Actions.pm +++ b/lib/Reaction/UI/ViewPort/Role/Actions.pm @@ -16,6 +16,14 @@ has action_order => ( isa => 'ArrayRef' ); +has action_filter => ( + isa => 'CodeRef', is => 'ro', + required => '1', lazy => '1', + default => sub { + sub { return [keys %{ shift->action_prototypes }] } + } +); + has action_prototypes => ( is => 'ro', isa => 'HashRef', @@ -35,7 +43,7 @@ sub _build_computed_action_order { ($self->has_action_order ? $self->action_order : []), [ keys %{ $self->action_prototypes } ] ); - return $ordered ; + return $self->action_filter->($ordered, $self->model); } sub _build_actions { -- cgit v1.2.3-54-g00ecf From f59e3c5e53dbbb3b6aa0fcedbd56f2f3f768e8c9 Mon Sep 17 00:00:00 2001 From: wreis Date: Thu, 30 Jul 2009 21:39:15 +0000 Subject: fixed default value --- lib/Reaction/UI/ViewPort/Role/Actions.pm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Reaction/UI/ViewPort/Role/Actions.pm b/lib/Reaction/UI/ViewPort/Role/Actions.pm index e78ba4d..368330b 100644 --- a/lib/Reaction/UI/ViewPort/Role/Actions.pm +++ b/lib/Reaction/UI/ViewPort/Role/Actions.pm @@ -20,7 +20,8 @@ has action_filter => ( isa => 'CodeRef', is => 'ro', required => '1', lazy => '1', default => sub { - sub { return [keys %{ shift->action_prototypes }] } + my $self = shift; + sub { return [keys %{ $self->action_prototypes }] } } ); -- cgit v1.2.3-54-g00ecf From 2accb94e380d6e57bc2625ff5ad894f4bbbce72e Mon Sep 17 00:00:00 2001 From: wreis Date: Thu, 30 Jul 2009 21:45:32 +0000 Subject: patch from groditi --- lib/Reaction/UI/ViewPort/Role/Actions.pm | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/Reaction/UI/ViewPort/Role/Actions.pm b/lib/Reaction/UI/ViewPort/Role/Actions.pm index 368330b..ebd2d3c 100644 --- a/lib/Reaction/UI/ViewPort/Role/Actions.pm +++ b/lib/Reaction/UI/ViewPort/Role/Actions.pm @@ -18,11 +18,6 @@ has action_order => ( has action_filter => ( isa => 'CodeRef', is => 'ro', - required => '1', lazy => '1', - default => sub { - my $self = shift; - sub { return [keys %{ $self->action_prototypes }] } - } ); has action_prototypes => ( @@ -44,7 +39,8 @@ sub _build_computed_action_order { ($self->has_action_order ? $self->action_order : []), [ keys %{ $self->action_prototypes } ] ); - return $self->action_filter->($ordered, $self->model); + return $self->has_action_filter ? + $self->action_filter->($ordered, $self->model) : $ordered; } sub _build_actions { -- cgit v1.2.3-54-g00ecf From eb09f78b4b13f27599dfe9dee467e4731b29c6f0 Mon Sep 17 00:00:00 2001 From: wreis Date: Fri, 31 Jul 2009 12:53:07 +0000 Subject: tweaks for SearchableListViewContainer --- lib/Reaction/UI/ViewPort/SearchableListViewContainer.pm | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) 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', -- cgit v1.2.3-54-g00ecf