From 7dcd0d7d967c613f4e447ba6330e1f616b93c1a3 Mon Sep 17 00:00:00 2001
From: David Heinemeier Hansson <david@loudthinking.com>
Date: Fri, 29 Feb 2008 18:09:23 +0000
Subject: Added that requests with JavaScript as the priority mime type in the
 accept header and no format extension in the parameters will be treated as
 though their format was :js when it comes to determining which template to
 render. This makes it possible for JS requests to automatically render
 action.js.rjs files without an explicit respond_to block  [DHH]

git-svn-id: http://svn-commit.rubyonrails.org/rails/trunk@8956 5ecf4fe2-1ee6-0310-87b1-e25e094e27de
---
 actionpack/CHANGELOG                          |  2 ++
 actionpack/lib/action_view/base.rb            | 23 +++++++++++++++++++++--
 actionpack/test/controller/new_render_test.rb |  6 ++++++
 actionpack/test/fixtures/test/greeting.js.rjs |  1 +
 4 files changed, 30 insertions(+), 2 deletions(-)
 create mode 100644 actionpack/test/fixtures/test/greeting.js.rjs

(limited to 'actionpack')

diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index b141f26288..4413ed3477 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,5 +1,7 @@
 *SVN*
 
+* Added that requests with JavaScript as the priority mime type in the accept header and no format extension in the parameters will be treated as though their format was :js when it comes to determining which template to render. This makes it possible for JS requests to automatically render action.js.rjs files without an explicit respond_to block  [DHH]
+
 * Tests for distance_of_time_in_words with TimeWithZone instances. Closes #10914 [ernesto.jimenez]
 
 * Remove support for multivalued (e.g., '&'-delimited) cookies. [Jamis Buck]
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index 9217d5ae0c..f5346bd480 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -344,10 +344,29 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
     end
 
     # symbolized version of the :format parameter of the request, or :html by default.
+    #
+    # EXCEPTION: If the :format parameter is not set, the Accept header will be examined for
+    # whether it contains the JavaScript mime type as its first priority. If that's the case,
+    # it will be used. This ensures that Ajax applications can use the same URL to support both
+    # JavaScript and non-JavaScript users.
     def template_format
       return @template_format if @template_format
-      format = controller && controller.respond_to?(:request) && controller.request.parameters[:format]
-      @template_format = format.blank? ? :html : format.to_sym
+
+      if controller && controller.respond_to?(:request)
+        parameter_format = controller.request.parameters[:format]
+        accept_format    = controller.request.accepts.first
+
+        case
+        when parameter_format.blank? && accept_format != :js
+          @template_format = :html
+        when parameter_format.blank? && accept_format == :js
+          @template_format = :js
+        else
+          @template_format = parameter_format.to_sym
+        end
+      else
+        @template_format = :html
+      end
     end
 
     private
diff --git a/actionpack/test/controller/new_render_test.rb b/actionpack/test/controller/new_render_test.rb
index 4d62647e8b..928c46cb6d 100644
--- a/actionpack/test/controller/new_render_test.rb
+++ b/actionpack/test/controller/new_render_test.rb
@@ -550,6 +550,12 @@ EOS
     assert_equal "<p>This is grand!</p>\n", @response.body
   end
 
+  def test_render_with_default_from_accept_header
+    @request.env["HTTP_ACCEPT"] = "text/javascript"
+    get :greeting
+    assert_equal "$(\"body\").visualEffect(\"highlight\");", @response.body
+  end
+
   def test_render_rjs_with_default
     get :delete_with_js
     assert_equal %!Element.remove("person");\nnew Effect.Highlight(\"project-4\",{});!, @response.body
diff --git a/actionpack/test/fixtures/test/greeting.js.rjs b/actionpack/test/fixtures/test/greeting.js.rjs
new file mode 100644
index 0000000000..469fcd8e15
--- /dev/null
+++ b/actionpack/test/fixtures/test/greeting.js.rjs
@@ -0,0 +1 @@
+page[:body].visual_effect :highlight
\ No newline at end of file
-- 
cgit v1.2.3