actionpack 3.1.12 → 3.2.0.rc1

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 (128) hide show
  1. data/CHANGELOG.md +5503 -108
  2. data/README.rdoc +3 -3
  3. data/lib/abstract_controller/asset_paths.rb +1 -1
  4. data/lib/abstract_controller/base.rb +1 -1
  5. data/lib/abstract_controller/callbacks.rb +102 -18
  6. data/lib/abstract_controller/helpers.rb +1 -1
  7. data/lib/abstract_controller/layouts.rb +116 -50
  8. data/lib/abstract_controller/logger.rb +1 -1
  9. data/lib/abstract_controller/railties/routes_helpers.rb +2 -2
  10. data/lib/abstract_controller/rendering.rb +1 -6
  11. data/lib/abstract_controller/view_paths.rb +6 -5
  12. data/lib/action_controller.rb +0 -15
  13. data/lib/action_controller/caching.rb +0 -1
  14. data/lib/action_controller/caching/actions.rb +5 -6
  15. data/lib/action_controller/caching/fragments.rb +18 -18
  16. data/lib/action_controller/caching/pages.rb +7 -6
  17. data/lib/action_controller/caching/sweeping.rb +1 -1
  18. data/lib/action_controller/log_subscriber.rb +8 -4
  19. data/lib/action_controller/metal.rb +7 -1
  20. data/lib/action_controller/metal/conditional_get.rb +49 -4
  21. data/lib/action_controller/metal/data_streaming.rb +17 -5
  22. data/lib/action_controller/metal/force_ssl.rb +8 -5
  23. data/lib/action_controller/metal/helpers.rb +7 -4
  24. data/lib/action_controller/metal/http_authentication.rb +9 -12
  25. data/lib/action_controller/metal/instrumentation.rb +9 -4
  26. data/lib/action_controller/metal/mime_responds.rb +4 -4
  27. data/lib/action_controller/metal/params_wrapper.rb +12 -8
  28. data/lib/action_controller/metal/redirecting.rb +7 -6
  29. data/lib/action_controller/metal/renderers.rb +9 -11
  30. data/lib/action_controller/metal/request_forgery_protection.rb +2 -1
  31. data/lib/action_controller/metal/rescue.rb +13 -0
  32. data/lib/action_controller/metal/responder.rb +11 -23
  33. data/lib/action_controller/metal/streaming.rb +0 -25
  34. data/lib/action_controller/railtie.rb +1 -0
  35. data/lib/action_controller/railties/paths.rb +4 -3
  36. data/lib/action_controller/record_identifier.rb +4 -4
  37. data/lib/action_controller/test_case.rb +60 -56
  38. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +6 -6
  39. data/lib/action_dispatch.rb +5 -1
  40. data/lib/action_dispatch/http/cache.rb +27 -15
  41. data/lib/action_dispatch/http/filter_parameters.rb +3 -1
  42. data/lib/action_dispatch/http/headers.rb +3 -5
  43. data/lib/action_dispatch/http/mime_negotiation.rb +2 -1
  44. data/lib/action_dispatch/http/mime_type.rb +7 -3
  45. data/lib/action_dispatch/http/mime_types.rb +12 -0
  46. data/lib/action_dispatch/http/parameter_filter.rb +3 -1
  47. data/lib/action_dispatch/http/parameters.rb +0 -4
  48. data/lib/action_dispatch/http/request.rb +18 -68
  49. data/lib/action_dispatch/http/response.rb +11 -32
  50. data/lib/action_dispatch/http/upload.rb +3 -14
  51. data/lib/action_dispatch/http/url.rb +1 -1
  52. data/lib/action_dispatch/middleware/callbacks.rb +1 -2
  53. data/lib/action_dispatch/middleware/cookies.rb +20 -16
  54. data/lib/action_dispatch/middleware/debug_exceptions.rb +82 -0
  55. data/lib/action_dispatch/middleware/exception_wrapper.rb +78 -0
  56. data/lib/action_dispatch/middleware/flash.rb +6 -9
  57. data/lib/action_dispatch/middleware/params_parser.rb +6 -11
  58. data/lib/action_dispatch/middleware/public_exceptions.rb +30 -0
  59. data/lib/action_dispatch/middleware/reloader.rb +38 -14
  60. data/lib/action_dispatch/middleware/remote_ip.rb +66 -36
  61. data/lib/action_dispatch/middleware/request_id.rb +39 -0
  62. data/lib/action_dispatch/middleware/session/abstract_store.rb +4 -16
  63. data/lib/action_dispatch/middleware/session/cache_store.rb +50 -0
  64. data/lib/action_dispatch/middleware/session/cookie_store.rb +1 -1
  65. data/lib/action_dispatch/middleware/show_exceptions.rb +58 -142
  66. data/lib/action_dispatch/middleware/static.rb +2 -10
  67. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +1 -0
  68. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +13 -8
  69. data/lib/action_dispatch/railtie.rb +15 -1
  70. data/lib/action_dispatch/routing.rb +1 -2
  71. data/lib/action_dispatch/routing/mapper.rb +108 -107
  72. data/lib/action_dispatch/routing/redirection.rb +63 -69
  73. data/lib/action_dispatch/routing/route_set.rb +75 -43
  74. data/lib/action_dispatch/routing/routes_proxy.rb +0 -4
  75. data/lib/action_dispatch/routing/url_for.rb +3 -3
  76. data/lib/action_dispatch/testing/assertions/response.rb +5 -7
  77. data/lib/action_dispatch/testing/assertions/routing.rb +10 -9
  78. data/lib/action_dispatch/testing/integration.rb +8 -25
  79. data/lib/action_dispatch/testing/test_process.rb +3 -2
  80. data/lib/action_dispatch/testing/test_request.rb +4 -23
  81. data/lib/action_pack/version.rb +3 -3
  82. data/lib/action_view.rb +1 -5
  83. data/lib/action_view/asset_paths.rb +7 -8
  84. data/lib/action_view/base.rb +7 -5
  85. data/lib/action_view/helpers/asset_paths.rb +1 -1
  86. data/lib/action_view/helpers/asset_tag_helper.rb +4 -8
  87. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +3 -0
  88. data/lib/action_view/helpers/atom_feed_helper.rb +2 -2
  89. data/lib/action_view/helpers/capture_helper.rb +3 -3
  90. data/lib/action_view/helpers/controller_helper.rb +1 -1
  91. data/lib/action_view/helpers/date_helper.rb +26 -18
  92. data/lib/action_view/helpers/debug_helper.rb +1 -1
  93. data/lib/action_view/helpers/form_helper.rb +71 -13
  94. data/lib/action_view/helpers/form_options_helper.rb +65 -34
  95. data/lib/action_view/helpers/form_tag_helper.rb +24 -18
  96. data/lib/action_view/helpers/javascript_helper.rb +12 -3
  97. data/lib/action_view/helpers/number_helper.rb +3 -2
  98. data/lib/action_view/helpers/record_tag_helper.rb +51 -5
  99. data/lib/action_view/helpers/rendering_helper.rb +2 -2
  100. data/lib/action_view/helpers/sanitize_helper.rb +6 -7
  101. data/lib/action_view/helpers/tag_helper.rb +1 -1
  102. data/lib/action_view/helpers/text_helper.rb +5 -4
  103. data/lib/action_view/helpers/url_helper.rb +19 -11
  104. data/lib/action_view/locale/en.yml +6 -0
  105. data/lib/action_view/log_subscriber.rb +1 -1
  106. data/lib/action_view/lookup_context.rb +123 -125
  107. data/lib/action_view/path_set.rb +60 -13
  108. data/lib/action_view/renderer/abstract_renderer.rb +16 -11
  109. data/lib/action_view/renderer/partial_renderer.rb +59 -40
  110. data/lib/action_view/renderer/template_renderer.rb +29 -17
  111. data/lib/action_view/template.rb +0 -1
  112. data/lib/action_view/template/error.rb +6 -5
  113. data/lib/action_view/template/handlers.rb +0 -6
  114. data/lib/action_view/template/handlers/builder.rb +10 -1
  115. data/lib/action_view/template/handlers/erb.rb +2 -2
  116. data/lib/action_view/template/resolver.rb +20 -31
  117. data/lib/action_view/test_case.rb +7 -10
  118. data/lib/sprockets/assets.rake +1 -1
  119. data/lib/sprockets/bootstrap.rb +3 -31
  120. data/lib/sprockets/compressors.rb +69 -7
  121. data/lib/sprockets/helpers/rails_helper.rb +6 -11
  122. data/lib/sprockets/railtie.rb +1 -0
  123. data/lib/sprockets/static_compiler.rb +0 -3
  124. metadata +57 -86
  125. checksums.yaml +0 -7
  126. data/lib/action_dispatch/middleware/closed_error.rb +0 -7
  127. data/lib/action_dispatch/routing/route.rb +0 -67
  128. data/lib/action_view/template/handler.rb +0 -49
@@ -62,7 +62,7 @@ module ActionDispatch
62
62
  #
63
63
  # The request_method is +:get+, +:post+, +:put+, +:delete+ or +:head+; the
64
64
  # parameters are +nil+, a hash, or a url-encoded or multipart string;
65
- # the headers are a hash. Keys are automatically upcased and prefixed
65
+ # the headers are a hash. Keys are automatically upcased and prefixed
66
66
  # with 'HTTP_' if not already.
67
67
  def xml_http_request(request_method, path, parameters = nil, headers = nil)
68
68
  headers ||= {}
@@ -184,16 +184,9 @@ module ActionDispatch
184
184
  reset!
185
185
  end
186
186
 
187
- def url_options
188
- @url_options ||= default_url_options.dup.tap do |url_options|
189
- url_options.reverse_merge!(controller.url_options) if controller
190
-
191
- if @app.respond_to?(:routes) && @app.routes.respond_to?(:default_url_options)
192
- url_options.reverse_merge!(@app.routes.default_url_options)
193
- end
194
-
195
- url_options.reverse_merge!(:host => host, :protocol => https? ? "https" : "http")
196
- end
187
+ remove_method :default_url_options
188
+ def default_url_options
189
+ { :host => host, :protocol => https? ? "https" : "http" }
197
190
  end
198
191
 
199
192
  # Resets the instance. This can be used to reset the state information
@@ -206,7 +199,6 @@ module ActionDispatch
206
199
  @controller = @request = @response = nil
207
200
  @_mock_session = nil
208
201
  @request_count = 0
209
- @url_options = nil
210
202
 
211
203
  self.host = DEFAULT_HOST
212
204
  self.remote_addr = "127.0.0.1"
@@ -301,7 +293,6 @@ module ActionDispatch
301
293
  response = _mock_session.last_response
302
294
  @response = ActionDispatch::TestResponse.new(response.status, response.headers, response.body)
303
295
  @html_document = nil
304
- @url_options = nil
305
296
 
306
297
  @controller = session.last_request.env['action_controller.instance']
307
298
 
@@ -359,14 +350,12 @@ module ActionDispatch
359
350
  end
360
351
  end
361
352
 
362
- def default_url_options
363
- reset! unless integration_session
364
- integration_session.default_url_options
365
- end
353
+ extend ActiveSupport::Concern
354
+ include ActionDispatch::Routing::UrlFor
366
355
 
367
- def default_url_options=(options)
356
+ def url_options
368
357
  reset! unless integration_session
369
- integration_session.default_url_options = options
358
+ integration_session.url_options
370
359
  end
371
360
 
372
361
  def respond_to?(method, include_private = false)
@@ -470,7 +459,6 @@ module ActionDispatch
470
459
  class IntegrationTest < ActiveSupport::TestCase
471
460
  include Integration::Runner
472
461
  include ActionController::TemplateAssertions
473
- include ActionDispatch::Routing::UrlFor
474
462
 
475
463
  @@app = nil
476
464
 
@@ -487,10 +475,5 @@ module ActionDispatch
487
475
  def app
488
476
  super || self.class.app
489
477
  end
490
-
491
- def url_options
492
- reset! unless integration_session
493
- integration_session.url_options
494
- end
495
478
  end
496
479
  end
@@ -1,3 +1,4 @@
1
+ require 'action_dispatch/middleware/cookies'
1
2
  require 'action_dispatch/middleware/flash'
2
3
  require 'active_support/core_ext/hash/indifferent_access'
3
4
 
@@ -17,7 +18,7 @@ module ActionDispatch
17
18
  end
18
19
 
19
20
  def cookies
20
- @request.cookies.merge(@response.cookies).with_indifferent_access
21
+ @request.cookie_jar
21
22
  end
22
23
 
23
24
  def redirect_to_url
@@ -33,7 +34,7 @@ module ActionDispatch
33
34
  #
34
35
  # post :change_avatar, :avatar => fixture_file_upload('/files/spongebob.png', 'image/png', :binary)
35
36
  def fixture_file_upload(path, mime_type = nil, binary = false)
36
- fixture_path = ActionController::TestCase.send(:fixture_path) if ActionController::TestCase.respond_to?(:fixture_path)
37
+ fixture_path = self.class.fixture_path if self.class.respond_to?(:fixture_path)
37
38
  Rack::Test::UploadedFile.new("#{fixture_path}#{path}", mime_type, binary)
38
39
  end
39
40
  end
@@ -1,4 +1,5 @@
1
1
  require 'active_support/core_ext/object/blank'
2
+ require 'active_support/core_ext/hash/indifferent_access'
2
3
  require 'active_support/core_ext/hash/reverse_merge'
3
4
  require 'rack/utils'
4
5
 
@@ -14,18 +15,11 @@ module ActionDispatch
14
15
  env = Rails.application.env_config.merge(env) if defined?(Rails.application)
15
16
  super(DEFAULT_ENV.merge(env))
16
17
 
17
- @cookies = nil
18
18
  self.host = 'test.host'
19
19
  self.remote_addr = '0.0.0.0'
20
20
  self.user_agent = 'Rails Testing'
21
21
  end
22
22
 
23
- def env
24
- write_cookies!
25
- delete_nil_values!
26
- super
27
- end
28
-
29
23
  def request_method=(method)
30
24
  @env['REQUEST_METHOD'] = method.to_s.upcase
31
25
  end
@@ -71,23 +65,10 @@ module ActionDispatch
71
65
  @env['HTTP_ACCEPT'] = Array(mime_types).collect { |mime_type| mime_type.to_s }.join(",")
72
66
  end
73
67
 
68
+ alias :rack_cookies :cookies
69
+
74
70
  def cookies
75
- @cookies ||= super
71
+ @cookies ||= {}.with_indifferent_access
76
72
  end
77
-
78
- private
79
- def write_cookies!
80
- unless @cookies.blank?
81
- @env['HTTP_COOKIE'] = @cookies.map { |name, value| escape_cookie(name, value) }.join('; ')
82
- end
83
- end
84
-
85
- def escape_cookie(name, value)
86
- "#{Rack::Utils.escape(name)}=#{Rack::Utils.escape(value.to_s)}"
87
- end
88
-
89
- def delete_nil_values!
90
- @env.delete_if { |k, v| v.nil? }
91
- end
92
73
  end
93
74
  end
@@ -1,9 +1,9 @@
1
1
  module ActionPack
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 3
4
- MINOR = 1
5
- TINY = 12
6
- PRE = nil
4
+ MINOR = 2
5
+ TINY = 0
6
+ PRE = "rc1"
7
7
 
8
8
  STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
9
9
  end
@@ -33,6 +33,7 @@ module ActionView
33
33
  autoload :AssetPaths
34
34
  autoload :Base
35
35
  autoload :Context
36
+ autoload :CompiledTemplates, "action_view/context"
36
37
  autoload :Helpers
37
38
  autoload :LookupContext
38
39
  autoload :PathSet
@@ -72,11 +73,6 @@ module ActionView
72
73
  autoload :TemplateError
73
74
  autoload :WrongEncodingError
74
75
  end
75
-
76
- autoload_at "action_view/template" do
77
- autoload :TemplateHandler
78
- autoload :TemplateHandlers
79
- end
80
76
  end
81
77
 
82
78
  ENCODING_FLAG = '#.*coding[:=]\s*(\S+)[ \t]*'
@@ -1,8 +1,8 @@
1
1
  require 'zlib'
2
2
  require 'active_support/core_ext/file'
3
+ require 'action_controller/metal/exceptions'
3
4
 
4
5
  module ActionView
5
-
6
6
  class AssetPaths #:nodoc:
7
7
  attr_reader :config, :controller
8
8
 
@@ -37,7 +37,7 @@ module ActionView
37
37
  end
38
38
 
39
39
  def is_uri?(path)
40
- path =~ %r{^[-a-z]+://|^(?:cid|data):|^//}
40
+ path =~ %r{^[-a-z]+://|^cid:|^//}
41
41
  end
42
42
 
43
43
  private
@@ -67,7 +67,7 @@ module ActionView
67
67
  host = "#{compute_protocol(protocol)}#{host}"
68
68
  end
69
69
  end
70
- host.nil? ? source : "#{host}#{source}"
70
+ host ? "#{host}#{source}" : source
71
71
  end
72
72
 
73
73
  def compute_protocol(protocol)
@@ -96,15 +96,15 @@ module ActionView
96
96
  # Pick an asset host for this source. Returns +nil+ if no host is set,
97
97
  # the host if no wildcard is set, the host interpolated with the
98
98
  # numbers 0-3 if it contains <tt>%d</tt> (the number is the source hash mod 4),
99
- # or the value returned from invoking the proc if it's a proc or the value from
100
- # invoking call if it's an object responding to call.
99
+ # or the value returned from invoking call on an object responding to call
100
+ # (proc or otherwise).
101
101
  def compute_asset_host(source)
102
102
  if host = asset_host_config
103
103
  if host.respond_to?(:call)
104
104
  args = [source]
105
105
  arity = arity_of(host)
106
- if arity > 1 && !has_request?
107
- invalid_asset_host!("Remove the second argument to your asset_host Proc if you do not need the request.")
106
+ if (arity > 1 || arity < -2) && !has_request?
107
+ invalid_asset_host!("Remove the second argument to your asset_host Proc if you do not need the request, or make it optional.")
108
108
  end
109
109
  args << current_request if (arity > 1 || arity < 0) && has_request?
110
110
  host.call(*args)
@@ -133,5 +133,4 @@ module ActionView
133
133
  end
134
134
 
135
135
  end
136
-
137
136
  end
@@ -4,12 +4,13 @@ require 'active_support/core_ext/class/attribute'
4
4
  require 'active_support/core_ext/array/wrap'
5
5
  require 'active_support/ordered_options'
6
6
  require 'action_view/log_subscriber'
7
+ require 'active_support/core_ext/module/deprecation'
7
8
 
8
9
  module ActionView #:nodoc:
9
10
  # = Action View Base
10
11
  #
11
- # Action View templates can be written in several ways. If the template file has a <tt>.erb</tt> (or <tt>.rhtml</tt>) extension then it uses a mixture of ERb
12
- # (included in Ruby) and HTML. If the template file has a <tt>.builder</tt> (or <tt>.rxml</tt>) extension then Jim Weirich's Builder::XmlMarkup library is used.
12
+ # Action View templates can be written in several ways. If the template file has a <tt>.erb</tt> extension then it uses a mixture of ERb
13
+ # (included in Ruby) and HTML. If the template file has a <tt>.builder</tt> extension then Jim Weirich's Builder::XmlMarkup library is used.
13
14
  #
14
15
  # == ERB
15
16
  #
@@ -93,10 +94,10 @@ module ActionView #:nodoc:
93
94
  #
94
95
  # Any method with a block will be treated as an XML markup tag with nested markup in the block. For example, the following:
95
96
  #
96
- # xml.div {
97
+ # xml.div do
97
98
  # xml.h1(@person.name)
98
99
  # xml.p(@person.bio)
99
- # }
100
+ # end
100
101
  #
101
102
  # would produce something like:
102
103
  #
@@ -115,7 +116,7 @@ module ActionView #:nodoc:
115
116
  # xml.language "en-us"
116
117
  # xml.ttl "40"
117
118
  #
118
- # for item in @recent_items
119
+ # @recent_items.each do |item|
119
120
  # xml.item do
120
121
  # xml.title(item_title(item))
121
122
  # xml.description(item_description(item)) if item_description(item)
@@ -161,6 +162,7 @@ module ActionView #:nodoc:
161
162
  value.is_a?(PathSet) ?
162
163
  value.dup : ActionView::PathSet.new(Array.wrap(value))
163
164
  end
165
+ deprecate :process_view_paths
164
166
 
165
167
  def xss_safe? #:nodoc:
166
168
  true
@@ -4,4 +4,4 @@ module ActionView
4
4
  module Helpers
5
5
  AssetPaths = ::ActionView::AssetPaths
6
6
  end
7
- end
7
+ end
@@ -228,23 +228,19 @@ module ActionView
228
228
  )
229
229
  end
230
230
 
231
- # Web browsers cache favicons. If you just throw a <tt>favicon.ico</tt> into the document
232
- # root of your application and it changes later, clients that have it in their cache
233
- # won't see the update. Using this helper prevents that because it appends an asset ID:
234
- #
235
231
  # <%= favicon_link_tag %>
236
232
  #
237
233
  # generates
238
234
  #
239
- # <link href="/favicon.ico?4649789979" rel="shortcut icon" type="image/vnd.microsoft.icon" />
235
+ # <link href="/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />
240
236
  #
241
237
  # You may specify a different file in the first argument:
242
238
  #
243
- # <%= favicon_link_tag 'favicon.ico' %>
239
+ # <%= favicon_link_tag '/myicon.ico' %>
244
240
  #
245
241
  # That's passed to +path_to_image+ as is, so it gives
246
242
  #
247
- # <link href="/images/favicon.ico?4649789979" rel="shortcut icon" type="image/vnd.microsoft.icon" />
243
+ # <link href="/myicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />
248
244
  #
249
245
  # The helper accepts an additional options hash where you can override "rel" and "type".
250
246
  #
@@ -348,7 +344,7 @@ module ActionView
348
344
 
349
345
  src = options[:src] = path_to_image(source)
350
346
 
351
- unless src =~ /^(?:cid|data):/
347
+ unless src =~ /^cid:/
352
348
  options[:alt] = options.fetch(:alt){ image_alt(src) }
353
349
  end
354
350
 
@@ -68,6 +68,9 @@ module ActionView
68
68
  # Returns a stylesheet link tag for the sources specified as arguments. If
69
69
  # you don't specify an extension, <tt>.css</tt> will be appended automatically.
70
70
  # You can modify the link attributes by passing a hash as the last argument.
71
+ # For historical reasons, the 'media' attribute will always be present and defaults
72
+ # to "screen", so you must explicitely set it to "all" for the stylesheet(s) to
73
+ # apply to all media types.
71
74
  #
72
75
  # ==== Examples
73
76
  # stylesheet_link_tag "style" # =>
@@ -20,7 +20,7 @@ module ActionView
20
20
  # # GET /posts.html
21
21
  # # GET /posts.atom
22
22
  # def index
23
- # @posts = Post.find(:all)
23
+ # @posts = Post.all
24
24
  #
25
25
  # respond_to do |format|
26
26
  # format.html
@@ -32,7 +32,7 @@ module ActionView
32
32
  # app/views/posts/index.atom.builder:
33
33
  # atom_feed do |feed|
34
34
  # feed.title("My great blog!")
35
- # feed.updated(@posts.first.created_at)
35
+ # feed.updated(@posts[0].created_at) if @posts.length > 0
36
36
  #
37
37
  # @posts.each do |post|
38
38
  # feed.entry(post) do |entry|
@@ -27,7 +27,7 @@ module ActionView
27
27
  # "The current timestamp is #{Time.now}."
28
28
  # end
29
29
  #
30
- # You can then use that variable anywhere else. For example:
30
+ # You can then use that variable anywhere else. For example:
31
31
  #
32
32
  # <html>
33
33
  # <head><title><%= @greeting %></title></head>
@@ -76,7 +76,7 @@ module ActionView
76
76
  #
77
77
  # <%= stored_content %>
78
78
  #
79
- # You can use the <tt>yield</tt> syntax alongside an existing call to <tt>yield</tt> in a layout. For example:
79
+ # You can use the <tt>yield</tt> syntax alongside an existing call to <tt>yield</tt> in a layout. For example:
80
80
  #
81
81
  # <%# This is the layout %>
82
82
  # <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
@@ -194,7 +194,7 @@ module ActionView
194
194
  def flush_output_buffer #:nodoc:
195
195
  if output_buffer && !output_buffer.empty?
196
196
  response.body_parts << output_buffer
197
- self.output_buffer = output_buffer.respond_to?(:clone_empty) ? output_buffer.clone_empty : output_buffer[0, 0]
197
+ self.output_buffer = output_buffer[0,0]
198
198
  nil
199
199
  end
200
200
  end
@@ -20,4 +20,4 @@ module ActionView
20
20
  end
21
21
  end
22
22
  end
23
- end
23
+ end
@@ -290,7 +290,7 @@ module ActionView
290
290
  InstanceTag.new(object_name, method, self, options.delete(:object)).to_datetime_select_tag(options, html_options)
291
291
  end
292
292
 
293
- # Returns a set of html select-tags (one for year, month, day, hour, minute and second) pre-selected with the
293
+ # Returns a set of html select-tags (one for year, month, day, hour, minute, and second) pre-selected with the
294
294
  # +datetime+. It's also possible to explicitly set the order of the tags using the <tt>:order</tt> option with
295
295
  # an array of symbols <tt>:year</tt>, <tt>:month</tt> and <tt>:day</tt> in the desired order. If you do not
296
296
  # supply a Symbol, it will be appended onto the <tt>:order</tt> passed in. You can also add
@@ -517,7 +517,7 @@ module ActionView
517
517
  # # that is named 'due' rather than 'day'.
518
518
  # select_day(my_time, :field_name => 'due')
519
519
  #
520
- # # Generates a select field for days with a custom prompt. Use <tt>:prompt => true</tt> for a
520
+ # # Generates a select field for days with a custom prompt. Use <tt>:prompt => true</tt> for a
521
521
  # # generic prompt.
522
522
  # select_day(5, :prompt => 'Choose day')
523
523
  #
@@ -621,7 +621,6 @@ module ActionView
621
621
  end
622
622
 
623
623
  class DateTimeSelector #:nodoc:
624
- extend ActiveSupport::Memoizable
625
624
  include ActionView::Helpers::TagHelper
626
625
 
627
626
  DEFAULT_PREFIX = 'date'.freeze
@@ -737,7 +736,7 @@ module ActionView
737
736
  if @options[:use_hidden] || @options[:discard_day]
738
737
  build_hidden(:day, day)
739
738
  else
740
- build_options_and_select(:day, day, :start => 1, :end => 31, :leading_zeros => false)
739
+ build_options_and_select(:day, day, :start => 1, :end => 31, :leading_zeros => false, :use_two_digit_numbers => @options[:use_two_digit_numbers])
741
740
  end
742
741
  end
743
742
 
@@ -766,11 +765,16 @@ module ActionView
766
765
  if @options[:use_hidden] || @options[:discard_year]
767
766
  build_hidden(:year, val)
768
767
  else
769
- options = {}
770
- options[:start] = @options[:start_year] || middle_year - 5
771
- options[:end] = @options[:end_year] || middle_year + 5
772
- options[:step] = options[:start] < options[:end] ? 1 : -1
773
- options[:leading_zeros] = false
768
+ options = {}
769
+ options[:start] = @options[:start_year] || middle_year - 5
770
+ options[:end] = @options[:end_year] || middle_year + 5
771
+ options[:step] = options[:start] < options[:end] ? 1 : -1
772
+ options[:leading_zeros] = false
773
+ options[:max_years_allowed] = @options[:max_years_allowed] || 1000
774
+
775
+ if (options[:end] - options[:start]).abs > options[:max_years_allowed]
776
+ raise ArgumentError, "There're too many years options to be built. Are you sure you haven't mistyped something? You can provide the :max_years_allowed parameter"
777
+ end
774
778
 
775
779
  build_options_and_select(:year, val, options)
776
780
  end
@@ -786,11 +790,12 @@ module ActionView
786
790
  # Returns translated month names, but also ensures that a custom month
787
791
  # name array has a leading nil element.
788
792
  def month_names
789
- month_names = @options[:use_month_names] || translated_month_names
790
- month_names.unshift(nil) if month_names.size < 13
791
- month_names
793
+ @month_names ||= begin
794
+ month_names = @options[:use_month_names] || translated_month_names
795
+ month_names.unshift(nil) if month_names.size < 13
796
+ month_names
797
+ end
792
798
  end
793
- memoize :month_names
794
799
 
795
800
  # Returns translated month names.
796
801
  # => [nil, "January", "February", "March",
@@ -817,6 +822,8 @@ module ActionView
817
822
  def month_name(number)
818
823
  if @options[:use_month_numbers]
819
824
  number
825
+ elsif @options[:use_two_digit_numbers]
826
+ sprintf "%02d", number
820
827
  elsif @options[:add_month_numbers]
821
828
  "#{number} - #{month_names[number]}"
822
829
  else
@@ -825,9 +832,8 @@ module ActionView
825
832
  end
826
833
 
827
834
  def date_order
828
- @options[:order] || translated_date_order
835
+ @date_order ||= @options[:order] || translated_date_order
829
836
  end
830
- memoize :date_order
831
837
 
832
838
  def translated_date_order
833
839
  I18n.translate(:'date.order', :locale => @options[:locale]) || []
@@ -853,7 +859,7 @@ module ActionView
853
859
  start = options.delete(:start) || 0
854
860
  stop = options.delete(:end) || 59
855
861
  step = options.delete(:step) || 1
856
- options.reverse_merge!({:leading_zeros => true, :ampm => false})
862
+ options.reverse_merge!({:leading_zeros => true, :ampm => false, :use_two_digit_numbers => false})
857
863
  leading_zeros = options.delete(:leading_zeros)
858
864
 
859
865
  select_options = []
@@ -861,7 +867,8 @@ module ActionView
861
867
  value = leading_zeros ? sprintf("%02d", i) : i
862
868
  tag_options = { :value => value }
863
869
  tag_options[:selected] = "selected" if selected == i
864
- text = options[:ampm] ? AMPM_TRANSLATION[i] : value
870
+ text = options[:use_two_digit_numbers] ? sprintf("%02d", i) : value
871
+ text = options[:ampm] ? AMPM_TRANSLATION[i] : text
865
872
  select_options << content_tag(:option, text, tag_options)
866
873
  end
867
874
  (select_options.join("\n") + "\n").html_safe
@@ -940,8 +947,9 @@ module ActionView
940
947
  # and join them with their appropriate separators.
941
948
  def build_selects_from_types(order)
942
949
  select = ''
950
+ first_visible = order.find { |type| !@options[:"discard_#{type}"] }
943
951
  order.reverse.each do |type|
944
- separator = separator(type) unless type == order.first # don't add on last field
952
+ separator = separator(type) unless type == first_visible # don't add before first visible field
945
953
  select.insert(0, separator.to_s + send("select_#{type}").to_s)
946
954
  end
947
955
  select.html_safe