From: nebulous Date: Wed, 6 Jan 2010 20:29:09 +0000 (-0500) Subject: Added JSONP module and tests. Child of Catalyst::Action::Serialize::JSON that allows... X-Git-Tag: 1.08~164 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Action-Serialize-Data-Serializer.git;a=commitdiff_plain;h=d0d292d4373d4af3455eac0b88366fef95f354be Added JSONP module and tests. Child of Catalyst::Action::Serialize::JSON that allows for a ?callback= option --- diff --git a/lib/Catalyst/Action/Serialize/JSONP.pm b/lib/Catalyst/Action/Serialize/JSONP.pm new file mode 100644 index 0000000..00c9f84 --- /dev/null +++ b/lib/Catalyst/Action/Serialize/JSONP.pm @@ -0,0 +1,30 @@ +package Catalyst::Action::Serialize::JSONP; +use base 'Catalyst::Action::Serialize::JSON'; + +sub execute { + my $self = shift; + my ($controller, $c) = @_; + + my $callback_key = ( + $controller->{'serialize'} ? + $controller->{'serialize'}->{'callback_key'} : + $controller->{'callback_key'} + ) || 'callback'; + + if ($c->req->param($callback_key)) { + $self->{_jsonp_callback} = $c->req->param($callback_key); + $c->res->content_type('text/javascript'); + } + $self->next::method($controller, $c); +} + +sub serialize { + my $self = shift; + my $json = $self->next::method(@_); + if ($self->{_jsonp_callback}) { + $json = $self->{_jsonp_callback}.'('.$json.');'; + } + return $json; +} + +1; diff --git a/lib/Catalyst/Controller/REST.pm b/lib/Catalyst/Controller/REST.pm index 847fa69..b7d4953 100644 --- a/lib/Catalyst/Controller/REST.pm +++ b/lib/Catalyst/Controller/REST.pm @@ -146,6 +146,10 @@ Uses L to generate JSON output. It is strongly advised to also have L installed. The C content type is supported but is deprecated and you will receive warnings in your log. +=item * C => C + +If a callback=? parameter is passed, this returns javascript in the form of: $callback($serializedJSON); + =item * C => C Uses the L module to generate L output. @@ -268,6 +272,9 @@ __PACKAGE__->config( 'text/x-yaml' => 'YAML', 'application/json' => 'JSON', 'text/x-json' => 'JSON', + 'application/x-javascript' => 'JSONP', + 'application/javascript' => 'JSONP', + 'text/javascript' => 'JSONP', 'text/x-data-dumper' => [ 'Data::Serializer', 'Data::Dumper' ], 'text/x-data-denter' => [ 'Data::Serializer', 'Data::Denter' ], 'text/x-data-taxi' => [ 'Data::Serializer', 'Data::Taxi' ], @@ -502,6 +509,9 @@ This class provides a default configuration for Serialization. It is currently: 'text/x-yaml' => 'YAML', 'application/json' => 'JSON', 'text/x-json' => 'JSON', + 'application/x-javascript' => 'JSONP', + 'application/javascript' => 'JSONP', + 'text/javascript' => 'JSONP', 'text/x-data-dumper' => [ 'Data::Serializer', 'Data::Dumper' ], 'text/x-data-denter' => [ 'Data::Serializer', 'Data::Denter' ], 'text/x-data-taxi' => [ 'Data::Serializer', 'Data::Taxi' ], diff --git a/t/jsonp.t b/t/jsonp.t new file mode 100644 index 0000000..70f9b18 --- /dev/null +++ b/t/jsonp.t @@ -0,0 +1,30 @@ +use strict; +use warnings; +use Test::More; +use FindBin; + +use lib ("$FindBin::Bin/lib", "$FindBin::Bin/../lib"); +use Test::Rest; +use utf8; + +eval 'use JSON 2.12'; +plan skip_all => 'Install JSON 2.12 or later to run this test' if ($@); + +plan tests => 7; + +use_ok 'Catalyst::Test', 'Test::Serialize', 'Catalyst::Action::Serialize::JSON'; + +my $json = JSON->new->utf8; + +for ('text/javascript','application/x-javascript','application/javascript') { + my $t = Test::Rest->new('content_type' => $_); + my $monkey_template = { monkey => 'likes chicken!' }; + + my $mres = request($t->get(url => '/monkey_get?callback=omnivore')); + ok( $mres->is_success, 'GET the monkey succeeded' ); + + my ($json_param) = $mres->content =~ /^omnivore\((.*)?\);$/; + is_deeply($json->decode($json_param), $monkey_template, "GET returned the right data"); +} + +1;