X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Runtime.git;a=blobdiff_plain;f=lib%2FCatalyst.pm;h=6b0c066c70524a80e986b15d4c98c4214b415198;hp=a3a0e3924fd31da5a359c21e66f4b947282bca49;hb=ed5a562b5c77df8d42b562af5733641baa73107d;hpb=7dac038c9d0d69aefa96bde4a1d574d0f983c684 diff --git a/lib/Catalyst.pm b/lib/Catalyst.pm index a3a0e39..6b0c066 100644 --- a/lib/Catalyst.pm +++ b/lib/Catalyst.pm @@ -180,7 +180,7 @@ sub composed_stats_class { __PACKAGE__->_encode_check(Encode::FB_CROAK | Encode::LEAVE_SRC); # Remember to update this in Catalyst::Runtime as well! -our $VERSION = '5.90092'; +our $VERSION = '5.90096'; $VERSION = eval $VERSION if $VERSION =~ /_/; # numify for warning-free dev releases sub import { @@ -521,7 +521,7 @@ L<< detach|/"$c->detach( $action [, \@arguments ] )" >>. Like C<< $c->visit >>, C<< $c->go >> will perform a full dispatch on the specified action or method, with localized C<< $c->action >> and C<< $c->namespace >>. Like C, C escapes the processing of the current request chain on completion, and -does not return to its cunless blessed $cunless blessed $caller. +does not return to its caller. @arguments are arguments to the final destination of $action. @captures are arguments to the intermediate steps, if any, on the way to the final sub of @@ -640,22 +640,42 @@ sub has_errors { scalar(@{shift->error}) ? 1:0 } =head2 $c->last_error Returns the most recent error in the stack (the one most recently added...) -or nothing if there are no errors. +or nothing if there are no errors. This does not modify the contents of the +error stack. =cut -sub last_error { my ($err, @errs) = @{shift->error}; return $err } +sub last_error { + my (@errs) = @{shift->error}; + return scalar(@errs) ? $errs[-1]: undef; +} =head2 shift_errors -shifts the most recently added error off the error stack and returns if. Returns +shifts the most recently added error off the error stack and returns it. Returns nothing if there are no more errors. =cut sub shift_errors { my ($self) = @_; - my ($err, @errors) = @{$self->error}; + my @errors = @{$self->error}; + my $err = shift(@errors); + $self->{error} = \@errors; + return $err; +} + +=head2 pop_errors + +pops the most recently added error off the error stack and returns it. Returns +nothing if there are no more errors. + +=cut + +sub pop_errors { + my ($self) = @_; + my @errors = @{$self->error}; + my $err = pop(@errors); $self->{error} = \@errors; return $err; } @@ -1612,6 +1632,14 @@ sub uri_for { my $query = ''; + # remove and save fragment if there is one + my $fragment; + if ($args =~ s/#(.+)$//) { + $fragment = encode_utf8($1); + $fragment =~ s/([^A-Za-z0-9\-_.!~*'() ])/$URI::Escape::escapes{$1}/go; + $fragment =~ s/ /+/g; + } + if (my @keys = keys %$params) { # somewhat lifted from URI::_query's query_form $query = '?'.join('&', map { @@ -1640,7 +1668,10 @@ sub uri_for { $base =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go; $args = encode_utf8 $args; $args =~ s/([^$URI::uric])/$URI::Escape::escapes{$1}/go; - + + # re-attach fragment on the end of everything after adding params + $query .= "#$fragment" if $fragment; + my $res = bless(\"${base}${args}${query}", $class); $res; } @@ -2228,9 +2259,10 @@ sub finalize_encoding { # Set the charset if necessary. This might be a bit bonkers since encodable response # is false when the set charset is not the same as the encoding mimetype (maybe # confusing action at a distance here.. - # Don't try to set the charset if one already exists + # Don't try to set the charset if one already exists or if headers are already finalized $c->res->content_type($c->res->content_type . "; charset=" . $c->encoding->mime_name) - unless($c->res->content_type_charset); + unless($c->res->content_type_charset || + ($c->res->_context && $c->res->finalized_headers && !$c->res->_has_response_cb)); } } @@ -2916,10 +2948,10 @@ sub setup_components { # of named components in the configuration that are not actually existing (not a # real file). - $class->setup_injected_components; + my @injected = $class->setup_injected_components; # All components are registered, now we need to 'init' them. - foreach my $component_name (keys %{$class->components||+{}}) { + foreach my $component_name (@comps, @injected) { $class->components->{$component_name} = $class->components->{$component_name}->() if (ref($class->components->{$component_name}) || '') eq 'CODE'; } @@ -2940,6 +2972,9 @@ sub setup_injected_components { $injected_comp_name, $class->config->{inject_components}->{$injected_comp_name}); } + + return map { $class ."::" . $_ } + @injected_components; } =head2 $app->setup_injected_component( $injected_component_name, $config )