actionpack 1.12.5 → 1.13.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (179) hide show
  1. data/CHANGELOG +517 -15
  2. data/MIT-LICENSE +1 -1
  3. data/README +18 -20
  4. data/Rakefile +7 -4
  5. data/examples/address_book_controller.rb +3 -3
  6. data/examples/blog_controller.cgi +3 -3
  7. data/examples/debate_controller.cgi +5 -5
  8. data/lib/action_controller.rb +2 -2
  9. data/lib/action_controller/assertions.rb +73 -311
  10. data/lib/action_controller/{deprecated_assertions.rb → assertions/deprecated_assertions.rb} +32 -8
  11. data/lib/action_controller/assertions/dom_assertions.rb +25 -0
  12. data/lib/action_controller/assertions/model_assertions.rb +12 -0
  13. data/lib/action_controller/assertions/response_assertions.rb +140 -0
  14. data/lib/action_controller/assertions/routing_assertions.rb +82 -0
  15. data/lib/action_controller/assertions/selector_assertions.rb +571 -0
  16. data/lib/action_controller/assertions/tag_assertions.rb +117 -0
  17. data/lib/action_controller/base.rb +334 -163
  18. data/lib/action_controller/benchmarking.rb +3 -6
  19. data/lib/action_controller/caching.rb +83 -22
  20. data/lib/action_controller/cgi_ext/cgi_ext.rb +0 -7
  21. data/lib/action_controller/cgi_ext/cgi_methods.rb +167 -173
  22. data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +43 -22
  23. data/lib/action_controller/cgi_process.rb +50 -27
  24. data/lib/action_controller/components.rb +21 -25
  25. data/lib/action_controller/cookies.rb +10 -9
  26. data/lib/action_controller/{dependencies.rb → deprecated_dependencies.rb} +9 -27
  27. data/lib/action_controller/filters.rb +448 -225
  28. data/lib/action_controller/flash.rb +24 -20
  29. data/lib/action_controller/helpers.rb +2 -5
  30. data/lib/action_controller/integration.rb +40 -16
  31. data/lib/action_controller/layout.rb +11 -8
  32. data/lib/action_controller/macros/auto_complete.rb +3 -2
  33. data/lib/action_controller/macros/in_place_editing.rb +3 -2
  34. data/lib/action_controller/mime_responds.rb +41 -29
  35. data/lib/action_controller/mime_type.rb +68 -10
  36. data/lib/action_controller/pagination.rb +4 -3
  37. data/lib/action_controller/request.rb +22 -14
  38. data/lib/action_controller/rescue.rb +25 -22
  39. data/lib/action_controller/resources.rb +302 -0
  40. data/lib/action_controller/response.rb +20 -2
  41. data/lib/action_controller/response.rb.rej +17 -0
  42. data/lib/action_controller/routing.rb +1165 -567
  43. data/lib/action_controller/scaffolding.rb +30 -31
  44. data/lib/action_controller/session/active_record_store.rb +2 -0
  45. data/lib/action_controller/session/drb_store.rb +4 -0
  46. data/lib/action_controller/session/mem_cache_store.rb +4 -0
  47. data/lib/action_controller/session_management.rb +6 -9
  48. data/lib/action_controller/status_codes.rb +89 -0
  49. data/lib/action_controller/streaming.rb +6 -15
  50. data/lib/action_controller/templates/rescues/_request_and_response.rhtml +5 -5
  51. data/lib/action_controller/templates/rescues/diagnostics.rhtml +2 -2
  52. data/lib/action_controller/templates/rescues/routing_error.rhtml +4 -4
  53. data/lib/action_controller/templates/rescues/template_error.rhtml +1 -1
  54. data/lib/action_controller/templates/scaffolds/list.rhtml +1 -1
  55. data/lib/action_controller/test_process.rb +52 -30
  56. data/lib/action_controller/url_rewriter.rb +63 -29
  57. data/lib/action_controller/vendor/html-scanner/html/document.rb +1 -0
  58. data/lib/action_controller/vendor/html-scanner/html/node.rb +3 -4
  59. data/lib/action_controller/vendor/html-scanner/html/selector.rb +822 -0
  60. data/lib/action_controller/verification.rb +22 -11
  61. data/lib/action_pack.rb +1 -1
  62. data/lib/action_pack/version.rb +2 -2
  63. data/lib/action_view.rb +1 -1
  64. data/lib/action_view/base.rb +46 -43
  65. data/lib/action_view/compiled_templates.rb +1 -1
  66. data/lib/action_view/helpers/active_record_helper.rb +54 -17
  67. data/lib/action_view/helpers/asset_tag_helper.rb +97 -46
  68. data/lib/action_view/helpers/capture_helper.rb +1 -1
  69. data/lib/action_view/helpers/date_helper.rb +258 -136
  70. data/lib/action_view/helpers/debug_helper.rb +1 -1
  71. data/lib/action_view/helpers/deprecated_helper.rb +34 -0
  72. data/lib/action_view/helpers/form_helper.rb +75 -35
  73. data/lib/action_view/helpers/form_options_helper.rb +7 -5
  74. data/lib/action_view/helpers/form_tag_helper.rb +44 -6
  75. data/lib/action_view/helpers/java_script_macros_helper.rb +59 -46
  76. data/lib/action_view/helpers/javascript_helper.rb +71 -10
  77. data/lib/action_view/helpers/javascripts/controls.js +41 -23
  78. data/lib/action_view/helpers/javascripts/dragdrop.js +105 -76
  79. data/lib/action_view/helpers/javascripts/effects.js +293 -163
  80. data/lib/action_view/helpers/javascripts/prototype.js +897 -389
  81. data/lib/action_view/helpers/javascripts/prototype.js.rej +561 -0
  82. data/lib/action_view/helpers/number_helper.rb +111 -65
  83. data/lib/action_view/helpers/prototype_helper.rb +84 -109
  84. data/lib/action_view/helpers/scriptaculous_helper.rb +5 -0
  85. data/lib/action_view/helpers/tag_helper.rb +69 -16
  86. data/lib/action_view/helpers/text_helper.rb +149 -112
  87. data/lib/action_view/helpers/url_helper.rb +200 -107
  88. data/lib/action_view/template_error.rb +66 -42
  89. data/test/abstract_unit.rb +4 -2
  90. data/test/active_record_unit.rb +84 -56
  91. data/test/activerecord/active_record_assertions_test.rb +26 -18
  92. data/test/activerecord/active_record_store_test.rb +4 -36
  93. data/test/activerecord/pagination_test.rb +1 -6
  94. data/test/controller/action_pack_assertions_test.rb +230 -113
  95. data/test/controller/addresses_render_test.rb +2 -6
  96. data/test/controller/assert_select_test.rb +576 -0
  97. data/test/controller/base_test.rb +73 -3
  98. data/test/controller/caching_test.rb +228 -0
  99. data/test/controller/capture_test.rb +12 -10
  100. data/test/controller/cgi_test.rb +89 -12
  101. data/test/controller/components_test.rb +24 -2
  102. data/test/controller/content_type_test.rb +139 -0
  103. data/test/controller/controller_fixtures/app/controllers/admin/user_controller.rb +0 -0
  104. data/test/controller/controller_fixtures/app/controllers/user_controller.rb +0 -0
  105. data/test/controller/controller_fixtures/vendor/plugins/bad_plugin/lib/plugin_controller.rb +0 -0
  106. data/test/controller/cookie_test.rb +33 -25
  107. data/test/controller/deprecated_instance_variables_test.rb +48 -0
  108. data/test/controller/deprecation/deprecated_base_methods_test.rb +60 -0
  109. data/test/controller/fake_controllers.rb +0 -1
  110. data/test/controller/filters_test.rb +301 -16
  111. data/test/controller/flash_test.rb +19 -2
  112. data/test/controller/helper_test.rb +2 -2
  113. data/test/controller/integration_test.rb +154 -0
  114. data/test/controller/layout_test.rb +115 -1
  115. data/test/controller/mime_responds_test.rb +94 -0
  116. data/test/controller/mime_type_test.rb +9 -0
  117. data/test/controller/new_render_test.rb +161 -11
  118. data/test/controller/raw_post_test.rb +52 -15
  119. data/test/controller/redirect_test.rb +27 -14
  120. data/test/controller/render_test.rb +76 -29
  121. data/test/controller/request_test.rb +55 -4
  122. data/test/controller/resources_test.rb +274 -0
  123. data/test/controller/routing_test.rb +1533 -824
  124. data/test/controller/selector_test.rb +628 -0
  125. data/test/controller/send_file_test.rb +9 -1
  126. data/test/controller/session_management_test.rb +51 -0
  127. data/test/controller/test_test.rb +113 -29
  128. data/test/controller/url_rewriter_test.rb +86 -17
  129. data/test/controller/verification_test.rb +19 -17
  130. data/test/controller/webservice_test.rb +0 -7
  131. data/test/fixtures/content_type/render_default_content_types_for_respond_to.rhtml +1 -0
  132. data/test/fixtures/content_type/render_default_for_rhtml.rhtml +1 -0
  133. data/test/fixtures/content_type/render_default_for_rjs.rjs +1 -0
  134. data/test/fixtures/content_type/render_default_for_rxml.rxml +1 -0
  135. data/test/fixtures/deprecated_instance_variables/_cookies_ivar.rhtml +1 -0
  136. data/test/fixtures/deprecated_instance_variables/_cookies_method.rhtml +1 -0
  137. data/test/fixtures/deprecated_instance_variables/_flash_ivar.rhtml +1 -0
  138. data/test/fixtures/deprecated_instance_variables/_flash_method.rhtml +1 -0
  139. data/test/fixtures/deprecated_instance_variables/_headers_ivar.rhtml +1 -0
  140. data/test/fixtures/deprecated_instance_variables/_headers_method.rhtml +1 -0
  141. data/test/fixtures/deprecated_instance_variables/_params_ivar.rhtml +1 -0
  142. data/test/fixtures/deprecated_instance_variables/_params_method.rhtml +1 -0
  143. data/test/fixtures/deprecated_instance_variables/_request_ivar.rhtml +1 -0
  144. data/test/fixtures/deprecated_instance_variables/_request_method.rhtml +1 -0
  145. data/test/fixtures/deprecated_instance_variables/_response_ivar.rhtml +1 -0
  146. data/test/fixtures/deprecated_instance_variables/_response_method.rhtml +1 -0
  147. data/test/fixtures/deprecated_instance_variables/_session_ivar.rhtml +1 -0
  148. data/test/fixtures/deprecated_instance_variables/_session_method.rhtml +1 -0
  149. data/test/fixtures/multipart/binary_file +0 -0
  150. data/test/fixtures/public/javascripts/application.js +1 -0
  151. data/test/fixtures/test/_hello.rxml +1 -0
  152. data/test/fixtures/test/hello_world_container.rxml +3 -0
  153. data/test/fixtures/topic.rb +2 -2
  154. data/test/template/active_record_helper_test.rb +83 -12
  155. data/test/template/asset_tag_helper_test.rb +75 -95
  156. data/test/template/compiled_templates_test.rb +1 -0
  157. data/test/template/date_helper_test.rb +873 -181
  158. data/test/template/deprecated_helper_test.rb +36 -0
  159. data/test/template/deprecated_instance_variables_test.rb +43 -0
  160. data/test/template/form_helper_test.rb +77 -1
  161. data/test/template/form_options_helper_test.rb +4 -0
  162. data/test/template/form_tag_helper_test.rb +66 -2
  163. data/test/template/java_script_macros_helper_test.rb +4 -1
  164. data/test/template/javascript_helper_test.rb +29 -0
  165. data/test/template/number_helper_test.rb +63 -27
  166. data/test/template/prototype_helper_test.rb +77 -34
  167. data/test/template/tag_helper_test.rb +34 -6
  168. data/test/template/text_helper_test.rb +69 -34
  169. data/test/template/url_helper_test.rb +168 -16
  170. data/test/testing_sandbox.rb +7 -22
  171. metadata +66 -20
  172. data/filler.txt +0 -50
  173. data/lib/action_controller/code_generation.rb +0 -235
  174. data/lib/action_controller/vendor/xml_simple.rb +0 -1019
  175. data/test/controller/caching_filestore.rb +0 -74
  176. data/test/fixtures/application_root/app/controllers/a_class_that_contains_a_controller/poorly_placed_controller.rb +0 -7
  177. data/test/fixtures/application_root/app/controllers/module_that_holds_controllers/nested_controller.rb +0 -3
  178. data/test/fixtures/application_root/app/models/a_class_that_contains_a_controller.rb +0 -7
  179. data/test/fixtures/dont_load.rb +0 -3
@@ -17,7 +17,7 @@ module ActionController #:nodoc:
17
17
  # end
18
18
  #
19
19
  # display.rhtml
20
- # <% if @flash[:notice] %><div class="notice"><%= @flash[:notice] %></div><% end %>
20
+ # <% if flash[:notice] %><div class="notice"><%= flash[:notice] %></div><% end %>
21
21
  #
22
22
  # This example just places a string in the flash, but you can put any object in there. And of course, you can put as many
23
23
  # as you like at a time too. Just remember: They'll be gone by the time the next action has been performed.
@@ -28,11 +28,9 @@ module ActionController #:nodoc:
28
28
  base.send :include, InstanceMethods
29
29
 
30
30
  base.class_eval do
31
- alias_method :assign_shortcuts_without_flash, :assign_shortcuts
32
- alias_method :assign_shortcuts, :assign_shortcuts_with_flash
33
-
34
- alias_method :process_cleanup_without_flash, :process_cleanup
35
- alias_method :process_cleanup, :process_cleanup_with_flash
31
+ alias_method_chain :assign_shortcuts, :flash
32
+ alias_method_chain :process_cleanup, :flash
33
+ alias_method_chain :reset_session, :flash
36
34
  end
37
35
  end
38
36
 
@@ -94,7 +92,7 @@ module ActionController #:nodoc:
94
92
  #
95
93
  # flash.keep # keeps the entire flash
96
94
  # flash.keep(:notice) # keeps only the "notice" entry, the rest of the flash is discarded
97
- def keep(k=nil)
95
+ def keep(k = nil)
98
96
  use(k, false)
99
97
  end
100
98
 
@@ -102,7 +100,7 @@ module ActionController #:nodoc:
102
100
  #
103
101
  # flash.keep # keep entire flash available for the next action
104
102
  # flash.discard(:warning) # discard the "warning" entry (it'll still be available for the current action)
105
- def discard(k=nil)
103
+ def discard(k = nil)
106
104
  use(k)
107
105
  end
108
106
 
@@ -118,6 +116,7 @@ module ActionController #:nodoc:
118
116
  @used.delete(k)
119
117
  end
120
118
  end
119
+
121
120
  (@used.keys - keys).each{|k| @used.delete k } # clean up after keys that could have been left over by calling reject! or shift on the flash
122
121
  end
123
122
 
@@ -143,36 +142,41 @@ module ActionController #:nodoc:
143
142
  end
144
143
 
145
144
  def process_cleanup_with_flash
146
- flash.sweep if @session
145
+ flash.sweep if @_session
147
146
  process_cleanup_without_flash
148
147
  end
148
+
149
+ def reset_session_with_flash
150
+ reset_session_without_flash
151
+ remove_instance_variable(:@_flash)
152
+ flash(:refresh)
153
+ end
149
154
 
150
155
  protected
151
156
  # Access the contents of the flash. Use <tt>flash["notice"]</tt> to read a notice you put there or
152
157
  # <tt>flash["notice"] = "hello"</tt> to put a new one.
153
158
  # Note that if sessions are disabled only flash.now will work.
154
159
  def flash(refresh = false) #:doc:
155
- if @flash.nil? || refresh
156
- @flash =
157
- if @session.is_a?(Hash)
158
- # @session is a Hash, if sessions are disabled
159
- # we don't put the flash in the session in this case
160
+ if !defined?(@_flash) || refresh
161
+ @_flash =
162
+ if session.is_a?(Hash)
163
+ # don't put flash in session if disabled
160
164
  FlashHash.new
161
165
  else
162
- # otherwise, @session is a CGI::Session or a TestSession
166
+ # otherwise, session is a CGI::Session or a TestSession
163
167
  # so make sure it gets retrieved from/saved to session storage after request processing
164
- @session["flash"] ||= FlashHash.new
168
+ session["flash"] ||= FlashHash.new
165
169
  end
166
170
  end
167
-
168
- @flash
171
+
172
+ @_flash
169
173
  end
170
174
 
171
175
  # deprecated. use <tt>flash.keep</tt> instead
172
176
  def keep_flash #:doc:
173
- warn 'keep_flash is deprecated; use flash.keep instead.'
177
+ ActiveSupport::Deprecation.warn 'keep_flash is deprecated; use flash.keep instead.', caller
174
178
  flash.keep
175
179
  end
176
180
  end
177
181
  end
178
- end
182
+ end
@@ -1,8 +1,6 @@
1
1
  module ActionController #:nodoc:
2
2
  module Helpers #:nodoc:
3
- def self.append_features(base)
4
- super
5
-
3
+ def self.included(base)
6
4
  # Initialize the base module to aggregate its helpers.
7
5
  base.class_inheritable_accessor :master_helper_module
8
6
  base.master_helper_module = Module.new
@@ -13,8 +11,7 @@ module ActionController #:nodoc:
13
11
  base.class_eval do
14
12
  # Wrap inherited to create a new master helper module for subclasses.
15
13
  class << self
16
- alias_method :inherited_without_helper, :inherited
17
- alias_method :inherited, :inherited_with_helper
14
+ alias_method_chain :inherited, :helper
18
15
  end
19
16
  end
20
17
  end
@@ -1,6 +1,7 @@
1
1
  require 'dispatcher'
2
2
  require 'stringio'
3
3
  require 'uri'
4
+ require 'action_controller/test_process'
4
5
 
5
6
  module ActionController
6
7
  module Integration #:nodoc:
@@ -13,6 +14,7 @@ module ActionController
13
14
  # rather than instantiating Integration::Session directly.
14
15
  class Session
15
16
  include Test::Unit::Assertions
17
+ include ActionController::Assertions
16
18
  include ActionController::TestProcess
17
19
 
18
20
  # The integer HTTP status code of the last request.
@@ -73,11 +75,11 @@ module ActionController
73
75
  unless @named_routes_configured
74
76
  # install the named routes in this session instance.
75
77
  klass = class<<self; self; end
76
- Routing::NamedRoutes.install(klass)
78
+ Routing::Routes.named_routes.install(klass)
77
79
 
78
80
  # the helpers are made protected by default--we make them public for
79
81
  # easier access during testing and troubleshooting.
80
- klass.send(:public, *Routing::NamedRoutes::Helpers)
82
+ klass.send(:public, *Routing::Routes.named_routes.helpers)
81
83
  @named_routes_configured = true
82
84
  end
83
85
  end
@@ -111,7 +113,7 @@ module ActionController
111
113
  # performed on the location header.
112
114
  def follow_redirect!
113
115
  raise "not a redirect! #{@status} #{@status_message}" unless redirect?
114
- get(interpret_uri(headers["location"].first))
116
+ get(interpret_uri(headers['location'].first))
115
117
  status
116
118
  end
117
119
 
@@ -143,19 +145,33 @@ module ActionController
143
145
  # (application/x-www-form-urlencoded or multipart/form-data). The headers
144
146
  # should be a hash. The keys will automatically be upcased, with the
145
147
  # prefix 'HTTP_' added if needed.
148
+ #
149
+ # You can also perform POST, PUT, DELETE, and HEAD requests with #post,
150
+ # #put, #delete, and #head.
146
151
  def get(path, parameters=nil, headers=nil)
147
152
  process :get, path, parameters, headers
148
153
  end
149
154
 
150
- # Performs a POST request with the given parameters. The parameters may
151
- # be +nil+, a Hash, or a string that is appropriately encoded
152
- # (application/x-www-form-urlencoded or multipart/form-data). The headers
153
- # should be a hash. The keys will automatically be upcased, with the
154
- # prefix 'HTTP_' added if needed.
155
+ # Performs a POST request with the given parameters. See get() for more details.
155
156
  def post(path, parameters=nil, headers=nil)
156
157
  process :post, path, parameters, headers
157
158
  end
158
159
 
160
+ # Performs a PUT request with the given parameters. See get() for more details.
161
+ def put(path, parameters=nil, headers=nil)
162
+ process :put, path, parameters, headers
163
+ end
164
+
165
+ # Performs a DELETE request with the given parameters. See get() for more details.
166
+ def delete(path, parameters=nil, headers=nil)
167
+ process :delete, path, parameters, headers
168
+ end
169
+
170
+ # Performs a HEAD request with the given parameters. See get() for more details.
171
+ def head(path, parameters=nil, headers=nil)
172
+ process :head, path, parameters, headers
173
+ end
174
+
159
175
  # Performs an XMLHttpRequest request with the given parameters, mimicing
160
176
  # the request environment created by the Prototype library. The parameters
161
177
  # may be +nil+, a Hash, or a string that is appropriately encoded
@@ -163,7 +179,11 @@ module ActionController
163
179
  # should be a hash. The keys will automatically be upcased, with the
164
180
  # prefix 'HTTP_' added if needed.
165
181
  def xml_http_request(path, parameters=nil, headers=nil)
166
- headers = (headers || {}).merge("X-Requested-With" => "XMLHttpRequest")
182
+ headers = (headers || {}).merge(
183
+ "X-Requested-With" => "XMLHttpRequest",
184
+ "Accept" => "text/javascript, text/html, application/xml, text/xml, */*"
185
+ )
186
+
167
187
  post(path, parameters, headers)
168
188
  end
169
189
 
@@ -174,7 +194,6 @@ module ActionController
174
194
  end
175
195
 
176
196
  private
177
-
178
197
  class MockCGI < CGI #:nodoc:
179
198
  attr_accessor :stdinput, :stdoutput, :env_table
180
199
 
@@ -224,7 +243,7 @@ module ActionController
224
243
 
225
244
  (headers || {}).each do |key, value|
226
245
  key = key.to_s.upcase.gsub(/-/, "_")
227
- key = "HTTP_#{key}" unless env.has_key?(key) || env =~ /^X|HTTP/
246
+ key = "HTTP_#{key}" unless env.has_key?(key) || key =~ /^HTTP_/
228
247
  env[key] = value
229
248
  end
230
249
 
@@ -247,6 +266,8 @@ module ActionController
247
266
  # tests.
248
267
  @response.extend(TestResponseBehavior)
249
268
 
269
+ @html_document = nil
270
+
250
271
  parse_result
251
272
  return status
252
273
  end
@@ -317,9 +338,8 @@ module ActionController
317
338
  def self.included(base)
318
339
  base.extend(ClassMethods)
319
340
  base.class_eval do
320
- class <<self
321
- alias_method :new_without_capture, :new
322
- alias_method :new, :new_with_capture
341
+ class << self
342
+ alias_method_chain :new, :capture
323
343
  end
324
344
  end
325
345
  end
@@ -330,9 +350,11 @@ module ActionController
330
350
  def clear_last_instantiation!
331
351
  self.last_instantiation = nil
332
352
  end
333
-
353
+
334
354
  def new_with_capture(*args)
335
- self.last_instantiation ||= new_without_capture(*args)
355
+ controller = new_without_capture(*args)
356
+ self.last_instantiation ||= controller
357
+ controller
336
358
  end
337
359
  end
338
360
  end
@@ -471,6 +493,8 @@ module ActionController
471
493
  %w(get post cookies assigns xml_http_request).each do |method|
472
494
  define_method(method) do |*args|
473
495
  reset! unless @integration_session
496
+ # reset the html_document variable, but only for new get/post calls
497
+ @html_document = nil unless %w(cookies assigns).include?(method)
474
498
  returning @integration_session.send(method, *args) do
475
499
  copy_session_variables!
476
500
  end
@@ -3,12 +3,13 @@ module ActionController #:nodoc:
3
3
  def self.included(base)
4
4
  base.extend(ClassMethods)
5
5
  base.class_eval do
6
+ # NOTE: Can't use alias_method_chain here because +render_without_layout+ is already
7
+ # defined as a publicly exposed method
6
8
  alias_method :render_with_no_layout, :render
7
9
  alias_method :render, :render_with_a_layout
8
10
 
9
11
  class << self
10
- alias_method :inherited_without_layout, :inherited
11
- alias_method :inherited, :inherited_with_layout
12
+ alias_method_chain :inherited, :layout
12
13
  end
13
14
  end
14
15
  end
@@ -26,9 +27,9 @@ module ActionController #:nodoc:
26
27
  # With layouts, you can flip it around and have the common structure know where to insert changing content. This means
27
28
  # that the header and footer are only mentioned in one place, like this:
28
29
  #
29
- # <!-- The header part of this layout -->
30
+ # // The header part of this layout
30
31
  # <%= yield %>
31
- # <!-- The footer part of this layout -->
32
+ # // The footer part of this layout -->
32
33
  #
33
34
  # And then you have content pages that look like this:
34
35
  #
@@ -37,9 +38,9 @@ module ActionController #:nodoc:
37
38
  # Not a word about common structures. At rendering time, the content page is computed and then inserted in the layout,
38
39
  # like this:
39
40
  #
40
- # <!-- The header part of this layout -->
41
+ # // The header part of this layout
41
42
  # hello world
42
- # <!-- The footer part of this layout -->
43
+ # // The footer part of this layout -->
43
44
  #
44
45
  # == Accessing shared variables
45
46
  #
@@ -182,7 +183,6 @@ module ActionController #:nodoc:
182
183
  private
183
184
  def inherited_with_layout(child)
184
185
  inherited_without_layout(child)
185
- child.send :include, Reloadable
186
186
  layout_match = child.name.underscore.sub(/_controller$/, '').sub(/^controllers\//, '')
187
187
  child.layout(layout_match) unless layout_list.grep(%r{layouts/#{layout_match}\.[a-z][0-9a-z]*$}).empty?
188
188
  end
@@ -235,6 +235,8 @@ module ActionController #:nodoc:
235
235
  template_with_options = options.is_a?(Hash)
236
236
 
237
237
  if apply_layout?(template_with_options, options) && (layout = pick_layout(template_with_options, options, deprecated_layout))
238
+ assert_existence_of_template_file(layout)
239
+
238
240
  options = options.merge :layout => false if template_with_options
239
241
  logger.info("Rendering #{options} within #{layout}") if logger
240
242
 
@@ -248,6 +250,7 @@ module ActionController #:nodoc:
248
250
  erase_render_results
249
251
  add_variables_to_assigns
250
252
  @template.instance_variable_set("@content_for_layout", content_for_layout)
253
+ response.layout = layout
251
254
  render_text(@template.render_file(layout, true), deprecated_status)
252
255
  else
253
256
  render_with_no_layout(options, deprecated_status, &block)
@@ -263,7 +266,7 @@ module ActionController #:nodoc:
263
266
 
264
267
  def candidate_for_layout?(options)
265
268
  (options.has_key?(:layout) && options[:layout] != false) ||
266
- options.values_at(:text, :xml, :file, :inline, :partial, :nothing).compact.empty? &&
269
+ options.values_at(:text, :xml, :json, :file, :inline, :partial, :nothing).compact.empty? &&
267
270
  !template_exempt_from_layout?(default_template_name(options[:action] || options[:template]))
268
271
  end
269
272
 
@@ -4,11 +4,12 @@ module ActionController
4
4
  # backing.
5
5
  module Macros
6
6
  module AutoComplete #:nodoc:
7
- def self.append_features(base) #:nodoc:
8
- super
7
+ def self.included(base) #:nodoc:
9
8
  base.extend(ClassMethods)
10
9
  end
11
10
 
11
+ # DEPRECATION WARNING: This method will become a separate plugin when Rails 2.0 ships.
12
+ #
12
13
  # Example:
13
14
  #
14
15
  # # Controller
@@ -1,11 +1,12 @@
1
1
  module ActionController
2
2
  module Macros
3
3
  module InPlaceEditing #:nodoc:
4
- def self.append_features(base) #:nodoc:
5
- super
4
+ def self.included(base) #:nodoc:
6
5
  base.extend(ClassMethods)
7
6
  end
8
7
 
8
+ # DEPRECATION WARNING: This method will become a separate plugin when Rails 2.0 ships.
9
+ #
9
10
  # Example:
10
11
  #
11
12
  # # Controller
@@ -8,18 +8,18 @@ module ActionController #:nodoc:
8
8
  # Without web-service support, an action which collects the data for displaying a list of people
9
9
  # might look something like this:
10
10
  #
11
- # def list
11
+ # def index
12
12
  # @people = Person.find(:all)
13
13
  # end
14
14
  #
15
15
  # Here's the same action, with web-service support baked in:
16
16
  #
17
- # def list
17
+ # def index
18
18
  # @people = Person.find(:all)
19
19
  #
20
- # respond_to do |wants|
21
- # wants.html
22
- # wants.xml { render :xml => @people.to_xml }
20
+ # respond_to do |format|
21
+ # format.html
22
+ # format.xml { render :xml => @people.to_xml }
23
23
  # end
24
24
  # end
25
25
  #
@@ -30,7 +30,7 @@ module ActionController #:nodoc:
30
30
  # Supposing you have an action that adds a new person, optionally creating their company
31
31
  # (by name) if it does not already exist, without web-services, it might look like this:
32
32
  #
33
- # def add
33
+ # def create
34
34
  # @company = Company.find_or_create_by_name(params[:company][:name])
35
35
  # @person = @company.people.create(params[:person])
36
36
  #
@@ -39,15 +39,15 @@ module ActionController #:nodoc:
39
39
  #
40
40
  # Here's the same action, with web-service support baked in:
41
41
  #
42
- # def add
42
+ # def create
43
43
  # company = params[:person].delete(:company)
44
44
  # @company = Company.find_or_create_by_name(company[:name])
45
45
  # @person = @company.people.create(params[:person])
46
46
  #
47
- # respond_to do |wants|
48
- # wants.html { redirect_to(person_list_url) }
49
- # wants.js
50
- # wants.xml { render :xml => @person.to_xml(:include => @company) }
47
+ # respond_to do |format|
48
+ # format.html { redirect_to(person_list_url) }
49
+ # format.js
50
+ # format.xml { render :xml => @person.to_xml(:include => @company) }
51
51
  # end
52
52
  # end
53
53
  #
@@ -97,9 +97,8 @@ module ActionController #:nodoc:
97
97
  # environment.rb as follows.
98
98
  #
99
99
  # Mime::Type.register "image/jpg", :jpg
100
- #
101
100
  def respond_to(*types, &block)
102
- raise ArgumentError, "respond_to takes either types or a block, never bot" unless types.any? ^ block
101
+ raise ArgumentError, "respond_to takes either types or a block, never both" unless types.any? ^ block
103
102
  block ||= lambda { |responder| types.each { |type| responder.send(type) } }
104
103
  responder = Responder.new(block.binding)
105
104
  block.call(responder)
@@ -108,15 +107,19 @@ module ActionController #:nodoc:
108
107
  end
109
108
 
110
109
  class Responder #:nodoc:
111
- DEFAULT_BLOCKS = {
112
- :html => 'Proc.new { render }',
113
- :js => 'Proc.new { render :action => "#{action_name}.rjs" }',
114
- :xml => 'Proc.new { render :action => "#{action_name}.rxml" }'
115
- }
110
+ DEFAULT_BLOCKS = [:html, :js, :xml].inject({}) do |blocks, ext|
111
+ template_extension = (ext == :html ? '' : ".r#{ext}")
112
+ blocks.update ext => %(Proc.new { render :action => "\#{action_name}#{template_extension}", :content_type => Mime::#{ext.to_s.upcase} })
113
+ end
116
114
 
117
115
  def initialize(block_binding)
118
116
  @block_binding = block_binding
119
- @mime_type_priority = eval("request.accepts", block_binding)
117
+ @mime_type_priority = eval(
118
+ "(params[:format] && Mime::EXTENSION_LOOKUP[params[:format]]) ? " +
119
+ "[ Mime::EXTENSION_LOOKUP[params[:format]] ] : request.accepts",
120
+ block_binding
121
+ )
122
+
120
123
  @order = []
121
124
  @responses = {}
122
125
  end
@@ -127,24 +130,33 @@ module ActionController #:nodoc:
127
130
  @order << mime_type
128
131
 
129
132
  if block_given?
130
- @responses[mime_type] = block
133
+ @responses[mime_type] = Proc.new do
134
+ eval "response.content_type = '#{mime_type.to_s}'", @block_binding
135
+ block.call
136
+ end
131
137
  else
132
- @responses[mime_type] = eval(DEFAULT_BLOCKS[mime_type.to_sym], @block_binding)
133
- end
134
- end
135
-
136
- for mime_type in %w( all html js xml rss atom yaml )
137
- eval <<-EOT
138
- def #{mime_type}(&block)
139
- custom(Mime::#{mime_type.upcase}, &block)
138
+ if source = DEFAULT_BLOCKS[mime_type.to_sym]
139
+ @responses[mime_type] = eval(source, @block_binding)
140
+ else
141
+ raise ActionController::RenderError, "Expected a block but none was given for custom mime handler #{mime_type}"
140
142
  end
141
- EOT
143
+ end
142
144
  end
143
145
 
144
146
  def any(*args, &block)
145
147
  args.each { |type| send(type, &block) }
146
148
  end
147
149
 
150
+ def method_missing(symbol, &block)
151
+ mime_constant = symbol.to_s.upcase
152
+
153
+ if Mime::SET.include?(Mime.const_get(mime_constant))
154
+ custom(Mime.const_get(mime_constant), &block)
155
+ else
156
+ super
157
+ end
158
+ end
159
+
148
160
  def respond
149
161
  for priority in @mime_type_priority
150
162
  if priority == Mime::ALL