actionpack 3.0.0.beta4 → 3.0.0.rc

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 (102) hide show
  1. data/CHANGELOG +36 -0
  2. data/{README → README.rdoc} +79 -137
  3. data/lib/abstract_controller.rb +1 -0
  4. data/lib/abstract_controller/asset_paths.rb +1 -1
  5. data/lib/abstract_controller/base.rb +3 -12
  6. data/lib/abstract_controller/rendering.rb +2 -2
  7. data/lib/abstract_controller/view_paths.rb +2 -1
  8. data/lib/action_controller.rb +1 -2
  9. data/lib/action_controller/base.rb +3 -9
  10. data/lib/action_controller/log_subscriber.rb +56 -0
  11. data/lib/action_controller/metal.rb +10 -3
  12. data/lib/action_controller/metal/helpers.rb +5 -4
  13. data/lib/action_controller/metal/hide_actions.rb +3 -3
  14. data/lib/action_controller/metal/instrumentation.rb +2 -1
  15. data/lib/action_controller/metal/mime_responds.rb +13 -10
  16. data/lib/action_controller/metal/rack_delegation.rb +0 -4
  17. data/lib/action_controller/metal/request_forgery_protection.rb +1 -1
  18. data/lib/action_controller/metal/rescue.rb +9 -0
  19. data/lib/action_controller/metal/responder.rb +13 -5
  20. data/lib/action_controller/metal/streaming.rb +2 -0
  21. data/lib/action_controller/metal/url_for.rb +5 -5
  22. data/lib/action_controller/railtie.rb +14 -23
  23. data/lib/action_controller/record_identifier.rb +6 -25
  24. data/lib/action_controller/test_case.rb +18 -6
  25. data/lib/action_controller/vendor/html-scanner/html/node.rb +1 -0
  26. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +1 -0
  27. data/lib/action_dispatch.rb +6 -0
  28. data/lib/action_dispatch/http/cache.rb +2 -2
  29. data/lib/action_dispatch/http/filter_parameters.rb +10 -66
  30. data/lib/action_dispatch/http/mime_type.rb +1 -1
  31. data/lib/action_dispatch/http/parameter_filter.rb +72 -0
  32. data/lib/action_dispatch/http/parameters.rb +31 -2
  33. data/lib/action_dispatch/http/request.rb +4 -1
  34. data/lib/action_dispatch/http/upload.rb +2 -2
  35. data/lib/action_dispatch/middleware/callbacks.rb +4 -4
  36. data/lib/action_dispatch/middleware/cookies.rb +39 -6
  37. data/lib/action_dispatch/middleware/flash.rb +9 -2
  38. data/lib/action_dispatch/middleware/session/abstract_store.rb +121 -36
  39. data/lib/action_dispatch/middleware/session/cookie_store.rb +26 -19
  40. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +9 -1
  41. data/lib/action_dispatch/middleware/show_exceptions.rb +2 -2
  42. data/lib/action_dispatch/middleware/stack.rb +12 -5
  43. data/lib/action_dispatch/railtie.rb +1 -1
  44. data/lib/action_dispatch/routing.rb +11 -13
  45. data/lib/action_dispatch/routing/deprecated_mapper.rb +6 -388
  46. data/lib/action_dispatch/routing/mapper.rb +364 -234
  47. data/lib/action_dispatch/routing/polymorphic_routes.rb +186 -0
  48. data/lib/action_dispatch/routing/route.rb +11 -2
  49. data/lib/action_dispatch/routing/route_set.rb +62 -28
  50. data/lib/action_dispatch/routing/url_for.rb +2 -1
  51. data/lib/action_dispatch/testing/assertions.rb +0 -2
  52. data/lib/action_dispatch/testing/assertions/routing.rb +0 -1
  53. data/lib/action_dispatch/testing/assertions/selector.rb +20 -24
  54. data/lib/action_dispatch/testing/integration.rb +2 -2
  55. data/lib/action_dispatch/testing/test_response.rb +2 -2
  56. data/lib/action_pack/version.rb +1 -1
  57. data/lib/action_view.rb +1 -0
  58. data/lib/action_view/base.rb +20 -21
  59. data/lib/action_view/context.rb +9 -12
  60. data/lib/action_view/helpers.rb +0 -2
  61. data/lib/action_view/helpers/active_model_helper.rb +17 -2
  62. data/lib/action_view/helpers/asset_tag_helper.rb +15 -33
  63. data/lib/action_view/helpers/atom_feed_helper.rb +5 -3
  64. data/lib/action_view/helpers/cache_helper.rb +4 -2
  65. data/lib/action_view/helpers/capture_helper.rb +4 -4
  66. data/lib/action_view/helpers/csrf_helper.rb +3 -1
  67. data/lib/action_view/helpers/date_helper.rb +10 -5
  68. data/lib/action_view/helpers/debug_helper.rb +3 -1
  69. data/lib/action_view/helpers/form_helper.rb +36 -30
  70. data/lib/action_view/helpers/form_options_helper.rb +7 -6
  71. data/lib/action_view/helpers/form_tag_helper.rb +17 -6
  72. data/lib/action_view/helpers/javascript_helper.rb +1 -0
  73. data/lib/action_view/helpers/number_helper.rb +16 -45
  74. data/lib/action_view/helpers/prototype_helper.rb +14 -16
  75. data/lib/action_view/helpers/raw_output_helper.rb +9 -0
  76. data/lib/action_view/helpers/record_tag_helper.rb +5 -0
  77. data/lib/action_view/helpers/sanitize_helper.rb +26 -20
  78. data/lib/action_view/helpers/scriptaculous_helper.rb +6 -5
  79. data/lib/action_view/helpers/tag_helper.rb +2 -1
  80. data/lib/action_view/helpers/text_helper.rb +24 -111
  81. data/lib/action_view/helpers/translation_helper.rb +17 -10
  82. data/lib/action_view/helpers/url_helper.rb +26 -33
  83. data/lib/action_view/log_subscriber.rb +28 -0
  84. data/lib/action_view/lookup_context.rb +2 -0
  85. data/lib/action_view/paths.rb +1 -0
  86. data/lib/action_view/railtie.rb +15 -3
  87. data/lib/action_view/render/layouts.rb +2 -1
  88. data/lib/action_view/render/partials.rb +3 -1
  89. data/lib/action_view/render/rendering.rb +2 -1
  90. data/lib/action_view/template.rb +12 -8
  91. data/lib/action_view/template/error.rb +1 -0
  92. data/lib/action_view/template/handlers.rb +1 -0
  93. data/lib/action_view/template/resolver.rb +2 -1
  94. data/lib/action_view/template/text.rb +1 -0
  95. data/lib/action_view/test_case.rb +42 -20
  96. metadata +44 -23
  97. data/lib/action_controller/polymorphic_routes.rb +0 -182
  98. data/lib/action_controller/railties/log_subscriber.rb +0 -56
  99. data/lib/action_controller/railties/url_helpers.rb +0 -14
  100. data/lib/action_dispatch/testing/assertions/model.rb +0 -19
  101. data/lib/action_view/helpers/record_identification_helper.rb +0 -20
  102. data/lib/action_view/railties/log_subscriber.rb +0 -24
@@ -1,9 +1,11 @@
1
1
  require 'active_support/core_ext/object/blank'
2
2
 
3
3
  module ActionView
4
+ # = Action View Capture Helper
4
5
  module Helpers
5
6
  # CaptureHelper exposes methods to let you extract generated markup which
6
7
  # can be used in other parts of a template or layout file.
8
+ #
7
9
  # It provides a method to capture blocks into variables through capture and
8
10
  # a way to capture a block of markup for use in a layout through content_for.
9
11
  module CaptureHelper
@@ -163,7 +165,7 @@ module ActionView
163
165
  def with_output_buffer(buf = nil) #:nodoc:
164
166
  unless buf
165
167
  buf = ActionView::OutputBuffer.new
166
- buf.force_encoding(output_buffer.encoding) if output_buffer && buf.respond_to?(:force_encoding)
168
+ buf.force_encoding(output_buffer.encoding) if output_buffer.respond_to?(:encoding) && buf.respond_to?(:force_encoding)
167
169
  end
168
170
  self.output_buffer, old_buffer = buf, output_buffer
169
171
  yield
@@ -176,9 +178,7 @@ module ActionView
176
178
  def flush_output_buffer #:nodoc:
177
179
  if output_buffer && !output_buffer.empty?
178
180
  response.body_parts << output_buffer
179
- new = ''
180
- new.force_encoding(output_buffer.encoding) if new.respond_to?(:force_encoding)
181
- self.output_buffer = new
181
+ self.output_buffer = output_buffer[0,0]
182
182
  nil
183
183
  end
184
184
  end
@@ -1,7 +1,9 @@
1
1
  module ActionView
2
+ # = Action View CSRF Helper
2
3
  module Helpers
3
4
  module CsrfHelper
4
- # Returns a meta tag with the request forgery protection token for forms to use. Put this in your head.
5
+ # Returns a meta tag with the cross-site request forgery protection token
6
+ # for forms to use. Place this in your head.
5
7
  def csrf_meta_tag
6
8
  if protect_against_forgery?
7
9
  %(<meta name="csrf-param" content="#{Rack::Utils.escape_html(request_forgery_protection_token)}"/>\n<meta name="csrf-token" content="#{Rack::Utils.escape_html(form_authenticity_token)}"/>).html_safe
@@ -4,6 +4,8 @@ require 'active_support/core_ext/hash/slice'
4
4
 
5
5
  module ActionView
6
6
  module Helpers
7
+ # = Action View Date Helpers
8
+ #
7
9
  # The Date Helper primarily creates select/option tags for different kinds of dates and date elements. All of the
8
10
  # select-type methods share a number of common options that are as follows:
9
11
  #
@@ -580,10 +582,10 @@ module ActionView
580
582
  extend ActiveSupport::Memoizable
581
583
  include ActionView::Helpers::TagHelper
582
584
 
583
- DEFAULT_PREFIX = 'date'.freeze unless const_defined?('DEFAULT_PREFIX')
585
+ DEFAULT_PREFIX = 'date'.freeze
584
586
  POSITION = {
585
587
  :year => 1, :month => 2, :day => 3, :hour => 4, :minute => 5, :second => 6
586
- }.freeze unless const_defined?('POSITION')
588
+ }.freeze
587
589
 
588
590
  def initialize(datetime, options = {}, html_options = {})
589
591
  @options = options.dup
@@ -798,7 +800,8 @@ module ActionView
798
800
  start = options.delete(:start) || 0
799
801
  stop = options.delete(:end) || 59
800
802
  step = options.delete(:step) || 1
801
- leading_zeros = options.delete(:leading_zeros).nil? ? true : false
803
+ options.reverse_merge!({:leading_zeros => true})
804
+ leading_zeros = options.delete(:leading_zeros)
802
805
 
803
806
  select_options = []
804
807
  start.step(stop, step) do |i|
@@ -894,8 +897,10 @@ module ActionView
894
897
  # Returns the separator for a given datetime component
895
898
  def separator(type)
896
899
  case type
897
- when :month, :day
898
- @options[:date_separator]
900
+ when :month
901
+ @options[:discard_month] ? "" : @options[:date_separator]
902
+ when :day
903
+ @options[:discard_day] ? "" : @options[:date_separator]
899
904
  when :hour
900
905
  (@options[:discard_year] && @options[:discard_day]) ? "" : @options[:datetime_separator]
901
906
  when :minute
@@ -1,6 +1,8 @@
1
1
  module ActionView
2
+ # = Action View Debug Helper
3
+ #
4
+ # Provides a set of methods for making it easier to debug Rails objects.
2
5
  module Helpers
3
- # Provides a set of methods for making it easier to debug Rails objects.
4
6
  module DebugHelper
5
7
  # Returns a YAML representation of +object+ wrapped with <pre> and </pre>.
6
8
  # If the object cannot be converted to YAML using +to_yaml+, +inspect+ will be called instead.
@@ -7,6 +7,7 @@ require 'active_support/core_ext/hash/slice'
7
7
  require 'active_support/core_ext/object/blank'
8
8
 
9
9
  module ActionView
10
+ # = Action View Form Helpers
10
11
  module Helpers
11
12
  # Form helpers are designed to make working with resources much easier
12
13
  # compared to using vanilla HTML.
@@ -92,7 +93,7 @@ module ActionView
92
93
  # # error handling
93
94
  # end
94
95
  #
95
- # That's how you tipically work with resources.
96
+ # That's how you typically work with resources.
96
97
  module FormHelper
97
98
  extend ActiveSupport::Concern
98
99
 
@@ -123,7 +124,6 @@ module ActionView
123
124
  # model:
124
125
  #
125
126
  # <%= form_for :person do |f| %>
126
- # <%= f.error_messages %>
127
127
  # First name: <%= f.text_field :first_name %><br />
128
128
  # Last name : <%= f.text_field :last_name %><br />
129
129
  # Biography : <%= f.text_area :biography %><br />
@@ -150,10 +150,6 @@ module ActionView
150
150
  # here a named route directly as well. Defaults to the current action.
151
151
  # * <tt>:html</tt> - Optional HTML attributes for the form tag.
152
152
  #
153
- # Worth noting is that the +form_for+ tag is called in a ERb evaluation
154
- # block, not an ERb output block. So that's <tt><% %></tt>, not
155
- # <tt><%= %></tt>.
156
- #
157
153
  # Also note that +form_for+ doesn't create an exclusive scope. It's still
158
154
  # possible to use both the stand-alone FormHelper methods and methods
159
155
  # from FormTagHelper. For example:
@@ -213,22 +209,32 @@ module ActionView
213
209
  # ...
214
210
  # <% end %>
215
211
  #
216
- # And for namespaced routes, like +admin_post_url+:
212
+ # For namespaced routes, like +admin_post_url+:
217
213
  #
218
214
  # <%= form_for([:admin, @post]) do |f| %>
219
215
  # ...
220
216
  # <% end %>
221
217
  #
218
+ # If your resource has associations defined, for example, you want to add comments
219
+ # to the post given that the routes are set correctly:
220
+ #
221
+ # <%= form_for([@document, @comment]) do |f| %>
222
+ # ...
223
+ # <% end %>
224
+ #
225
+ # Where +@document = Document.find(params[:id])+ and
226
+ # +@comment = Comment.new+.
227
+ #
222
228
  # === Unobtrusive JavaScript
223
- #
224
- # Specifying:
225
- #
229
+ #
230
+ # Specifying:
231
+ #
226
232
  # :remote => true
227
233
  #
228
234
  # in the options hash creates a form that will allow the unobtrusive JavaScript drivers to modify its
229
- # behaviour. The expected default behaviour is an XMLHttpRequest in the background instead of the regular
235
+ # behaviour. The expected default behaviour is an XMLHttpRequest in the background instead of the regular
230
236
  # POST arrangement, but ultimately the behaviour is the choice of the JavaScript driver implementor.
231
- # Even though it's using JavaScript to serialize the form elements, the form submission will work just like
237
+ # Even though it's using JavaScript to serialize the form elements, the form submission will work just like
232
238
  # a regular submission as viewed by the receiving side (all elements available in <tt>params</tt>).
233
239
  #
234
240
  # Example:
@@ -269,7 +275,7 @@ module ActionView
269
275
  # <tt>labelling_form</tt>.
270
276
  #
271
277
  # The custom FormBuilder class is automatically merged with the options
272
- # of a nested fields_for call, unless it's explicitely set.
278
+ # of a nested fields_for call, unless it's explicitly set.
273
279
  #
274
280
  # In many cases you will want to wrap the above in another helper, so you
275
281
  # could do something like the following:
@@ -292,17 +298,17 @@ module ActionView
292
298
  object_name = record_or_name_or_array
293
299
  when Array
294
300
  object = record_or_name_or_array.last
295
- object_name = options[:as] || ActionController::RecordIdentifier.singular_class_name(object)
301
+ object_name = options[:as] || ActiveModel::Naming.singular(object)
296
302
  apply_form_for_options!(record_or_name_or_array, options)
297
303
  args.unshift object
298
304
  else
299
305
  object = record_or_name_or_array
300
- object_name = options[:as] || ActionController::RecordIdentifier.singular_class_name(object)
306
+ object_name = options[:as] || ActiveModel::Naming.singular(object)
301
307
  apply_form_for_options!([object], options)
302
308
  args.unshift object
303
309
  end
304
310
 
305
- options[:html][:remote] = true if options.delete(:remote)
311
+ (options[:html] ||= {})[:remote] = true if options.delete(:remote)
306
312
 
307
313
  output = form_tag(options.delete(:url) || {}, options.delete(:html) || {})
308
314
  output << fields_for(object_name, *(args << options), &proc)
@@ -523,7 +529,7 @@ module ActionView
523
529
  object = args.first
524
530
  else
525
531
  object = record_or_name_or_array
526
- object_name = ActionController::RecordIdentifier.singular_class_name(object)
532
+ object_name = ActiveModel::Naming.singular(object)
527
533
  end
528
534
 
529
535
  builder = options[:builder] || ActionView::Base.default_form_builder
@@ -666,7 +672,7 @@ module ActionView
666
672
  # # => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
667
673
  #
668
674
  def file_field(object_name, method, options = {})
669
- InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("file", options)
675
+ InstanceTag.new(object_name, method, self, options.delete(:object)).to_input_field_tag("file", options.update({:size => nil}))
670
676
  end
671
677
 
672
678
  # Returns a textarea opening and closing tag set tailored for accessing a specified attribute (identified by +method+)
@@ -717,7 +723,7 @@ module ActionView
717
723
  #
718
724
  # To prevent this the helper generates an auxiliary hidden field before
719
725
  # the very check box. The hidden field has the same name and its
720
- # attributes mimick an unchecked check box.
726
+ # attributes mimic an unchecked check box.
721
727
  #
722
728
  # This way, the client either sends only the hidden field (representing
723
729
  # the check box is unchecked), or both fields. Since the HTML specification
@@ -838,9 +844,9 @@ module ActionView
838
844
 
839
845
  attr_reader :method_name, :object_name
840
846
 
841
- DEFAULT_FIELD_OPTIONS = { "size" => 30 }.freeze unless const_defined?(:DEFAULT_FIELD_OPTIONS)
842
- DEFAULT_RADIO_OPTIONS = { }.freeze unless const_defined?(:DEFAULT_RADIO_OPTIONS)
843
- DEFAULT_TEXT_AREA_OPTIONS = { "cols" => 40, "rows" => 20 }.freeze unless const_defined?(:DEFAULT_TEXT_AREA_OPTIONS)
847
+ DEFAULT_FIELD_OPTIONS = { "size" => 30 }.freeze
848
+ DEFAULT_RADIO_OPTIONS = { }.freeze
849
+ DEFAULT_TEXT_AREA_OPTIONS = { "cols" => 40, "rows" => 20 }.freeze
844
850
 
845
851
  def initialize(object_name, method_name, template_object, object = nil)
846
852
  @object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup
@@ -897,7 +903,7 @@ module ActionView
897
903
  options.delete("size")
898
904
  end
899
905
  options["type"] ||= field_type
900
- options["value"] ||= value_before_type_cast(object) unless field_type == "file"
906
+ options["value"] = options.fetch("value"){ value_before_type_cast(object) } unless field_type == "file"
901
907
  options["value"] &&= html_escape(options["value"])
902
908
  add_default_name_and_id(options)
903
909
  tag("input", options)
@@ -1030,7 +1036,7 @@ module ActionView
1030
1036
  private
1031
1037
  def add_default_name_and_id_for_value(tag_value, options)
1032
1038
  unless tag_value.nil?
1033
- pretty_tag_value = tag_value.to_s.gsub(/\s/, "_").gsub(/\W/, "").downcase
1039
+ pretty_tag_value = tag_value.to_s.gsub(/\s/, "_").gsub(/[^-\w]/, "").downcase
1034
1040
  specified_id = options["id"]
1035
1041
  add_default_name_and_id(options)
1036
1042
  options["id"] += "_#{pretty_tag_value}" if specified_id.blank? && options["id"].present?
@@ -1042,14 +1048,14 @@ module ActionView
1042
1048
  def add_default_name_and_id(options)
1043
1049
  if options.has_key?("index")
1044
1050
  options["name"] ||= tag_name_with_index(options["index"])
1045
- options["id"] = options.fetch("id", tag_id_with_index(options["index"]))
1051
+ options["id"] = options.fetch("id"){ tag_id_with_index(options["index"]) }
1046
1052
  options.delete("index")
1047
1053
  elsif defined?(@auto_index)
1048
1054
  options["name"] ||= tag_name_with_index(@auto_index)
1049
- options["id"] = options.fetch("id", tag_id_with_index(@auto_index))
1055
+ options["id"] = options.fetch("id"){ tag_id_with_index(@auto_index) }
1050
1056
  else
1051
1057
  options["name"] ||= tag_name + (options.has_key?('multiple') ? '[]' : '')
1052
- options["id"] = options.fetch("id", tag_id)
1058
+ options["id"] = options.fetch("id"){ tag_id }
1053
1059
  end
1054
1060
  end
1055
1061
 
@@ -1146,11 +1152,11 @@ module ActionView
1146
1152
  end
1147
1153
  when Array
1148
1154
  object = record_or_name_or_array.last
1149
- name = "#{object_name}#{index}[#{ActionController::RecordIdentifier.singular_class_name(object)}]"
1155
+ name = "#{object_name}#{index}[#{ActiveModel::Naming.singular(object)}]"
1150
1156
  args.unshift(object)
1151
1157
  else
1152
1158
  object = record_or_name_or_array
1153
- name = "#{object_name}#{index}[#{ActionController::RecordIdentifier.singular_class_name(object)}]"
1159
+ name = "#{object_name}#{index}[#{ActiveModel::Naming.singular(object)}]"
1154
1160
  args.unshift(object)
1155
1161
  end
1156
1162
 
@@ -1180,7 +1186,7 @@ module ActionView
1180
1186
  # <%= form_for @post do |f| %>
1181
1187
  # <%= f.submit %>
1182
1188
  # <% end %>
1183
- #
1189
+ #
1184
1190
  # In the example above, if @post is a new record, it will use "Create Post" as
1185
1191
  # submit button label, otherwise, it uses "Update Post".
1186
1192
  #
@@ -4,6 +4,7 @@ require 'action_view/helpers/form_helper'
4
4
  require 'active_support/core_ext/object/blank'
5
5
 
6
6
  module ActionView
7
+ # = Action View Form Option Helpers
7
8
  module Helpers
8
9
  # Provides a number of methods for turning different kinds of containers into a set of option tags.
9
10
  # == Options
@@ -398,7 +399,7 @@ module ActionView
398
399
  options_for_select += "<optgroup label=\"#{html_escape(group_label_string)}\">"
399
400
  options_for_select += options_from_collection_for_select(eval("group.#{group_method}"), option_key_method, option_value_method, selected_key)
400
401
  options_for_select += '</optgroup>'
401
- end
402
+ end.html_safe
402
403
  end
403
404
 
404
405
  # Returns a string of <tt><option></tt> tags, like <tt>options_for_select</tt>, but
@@ -412,8 +413,8 @@ module ActionView
412
413
  # * +selected_key+ - A value equal to the +value+ attribute for one of the <tt><option></tt> tags,
413
414
  # which will have the +selected+ attribute set. Note: It is possible for this value to match multiple options
414
415
  # as you might have the same option in multiple groups. Each will then get <tt>selected="selected"</tt>.
415
- # * +prompt+ - set to true or a prompt string. When the select element doesnt have a value yet, this
416
- # prepends an option with a generic prompt "Please select" or the given prompt string.
416
+ # * +prompt+ - set to true or a prompt string. When the select element doesn't have a value yet, this
417
+ # prepends an option with a generic prompt - "Please select" - or the given prompt string.
417
418
  #
418
419
  # Sample usage (Array):
419
420
  # grouped_options = [
@@ -446,7 +447,7 @@ module ActionView
446
447
  # wrap the output in an appropriate <tt><select></tt> tag.
447
448
  def grouped_options_for_select(grouped_options, selected_key = nil, prompt = nil)
448
449
  body = ''
449
- body << content_tag(:option, prompt, :value => "") if prompt
450
+ body << content_tag(:option, prompt, { :value => "" }, true) if prompt
450
451
 
451
452
  grouped_options = grouped_options.sort if grouped_options.is_a?(Hash)
452
453
 
@@ -592,11 +593,11 @@ module ActionView
592
593
  private
593
594
  def add_options(option_tags, options, value = nil)
594
595
  if options[:include_blank]
595
- option_tags = "<option value=\"\">#{options[:include_blank] if options[:include_blank].kind_of?(String)}</option>\n" + option_tags
596
+ option_tags = "<option value=\"\">#{html_escape(options[:include_blank]) if options[:include_blank].kind_of?(String)}</option>\n" + option_tags
596
597
  end
597
598
  if value.blank? && options[:prompt]
598
599
  prompt = options[:prompt].kind_of?(String) ? options[:prompt] : I18n.translate('helpers.select.prompt', :default => 'Please select')
599
- option_tags = "<option value=\"\">#{prompt}</option>\n" + option_tags
600
+ option_tags = "<option value=\"\">#{html_escape(prompt)}</option>\n" + option_tags
600
601
  end
601
602
  option_tags.html_safe
602
603
  end
@@ -1,9 +1,9 @@
1
1
  require 'cgi'
2
2
  require 'action_view/helpers/tag_helper'
3
- require 'active_support/core_ext/object/returning'
4
3
  require 'active_support/core_ext/object/blank'
5
4
 
6
5
  module ActionView
6
+ # = Action View Form Tag Helpers
7
7
  module Helpers
8
8
  # Provides a number of methods for creating form tags that doesn't rely on an Active Record object assigned to the template like
9
9
  # FormHelper does. Instead, you provide the names and values manually.
@@ -526,25 +526,36 @@ module ActionView
526
526
 
527
527
  private
528
528
  def html_options_for_form(url_for_options, options, *parameters_for_url)
529
- returning options.stringify_keys do |html_options|
529
+ options.stringify_keys.tap do |html_options|
530
530
  html_options["enctype"] = "multipart/form-data" if html_options.delete("multipart")
531
+ # The following URL is unescaped, this is just a hash of options, and it is the
532
+ # responsability of the caller to escape all the values.
531
533
  html_options["action"] = url_for(url_for_options, *parameters_for_url)
534
+ html_options["accept-charset"] = "UTF-8"
532
535
  html_options["data-remote"] = true if html_options.delete("remote")
533
536
  end
534
537
  end
535
538
 
536
539
  def extra_tags_for_form(html_options)
537
- case method = html_options.delete("method").to_s
538
- when /^get$/i # must be case-insentive, but can't use downcase as might be nil
540
+ snowman_tag = tag(:input, :type => "hidden",
541
+ :name => "_snowman", :value => "&#9731;".html_safe)
542
+
543
+ method = html_options.delete("method").to_s
544
+
545
+ method_tag = case method
546
+ when /^get$/i # must be case-insensitive, but can't use downcase as might be nil
539
547
  html_options["method"] = "get"
540
548
  ''
541
549
  when /^post$/i, "", nil
542
550
  html_options["method"] = "post"
543
- protect_against_forgery? ? content_tag(:div, token_tag, :style => 'margin:0;padding:0;display:inline') : ''
551
+ token_tag
544
552
  else
545
553
  html_options["method"] = "post"
546
- content_tag(:div, tag(:input, :type => "hidden", :name => "_method", :value => method) + token_tag, :style => 'margin:0;padding:0;display:inline')
554
+ tag(:input, :type => "hidden", :name => "_method", :value => method) + token_tag
547
555
  end
556
+
557
+ tags = snowman_tag << method_tag
558
+ content_tag(:div, tags, :style => 'margin:0;padding:0;display:inline')
548
559
  end
549
560
 
550
561
  def form_tag_html(html_options)
@@ -1,6 +1,7 @@
1
1
  require 'action_view/helpers/tag_helper'
2
2
 
3
3
  module ActionView
4
+ # = Action View JavaScript Helpers
4
5
  module Helpers
5
6
  # Provides functionality for working with JavaScript in your views.
6
7
  #
@@ -3,6 +3,7 @@ require 'active_support/core_ext/float/rounding'
3
3
  require 'active_support/core_ext/object/blank'
4
4
 
5
5
  module ActionView
6
+ # = Action View Number Helpers
6
7
  module Helpers #:nodoc:
7
8
 
8
9
  # Provides methods for converting numbers into formatted strings.
@@ -82,6 +83,7 @@ module ActionView
82
83
  # in the +options+ hash.
83
84
  #
84
85
  # ==== Options
86
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
85
87
  # * <tt>:precision</tt> - Sets the level of precision (defaults to 2).
86
88
  # * <tt>:unit</tt> - Sets the denomination of the currency (defaults to "$").
87
89
  # * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
@@ -95,6 +97,7 @@ module ActionView
95
97
  # number_to_currency(1234567890.50) # => $1,234,567,890.50
96
98
  # number_to_currency(1234567890.506) # => $1,234,567,890.51
97
99
  # number_to_currency(1234567890.506, :precision => 3) # => $1,234,567,890.506
100
+ # number_to_currency(1234567890.506, :locale => :fr) # => 1 234 567 890,506 €
98
101
  #
99
102
  # number_to_currency(1234567890.50, :unit => "&pound;", :separator => ",", :delimiter => "")
100
103
  # # => &pound;1234567890,50
@@ -132,6 +135,7 @@ module ActionView
132
135
  # format in the +options+ hash.
133
136
  #
134
137
  # ==== Options
138
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
135
139
  # * <tt>:precision</tt> - Sets the precision of the number (defaults to 3).
136
140
  # * <tt>:significant</tt> - If +true+, precision will be the # of significant_digits. If +false+, the # of fractional digits (defaults to +false+)
137
141
  # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").
@@ -143,6 +147,7 @@ module ActionView
143
147
  # number_to_percentage(100, :precision => 0) # => 100%
144
148
  # number_to_percentage(1000, :delimiter => '.', :separator => ',') # => 1.000,000%
145
149
  # number_to_percentage(302.24398923423, :precision => 5) # => 302.24399%
150
+ # number_to_percentage(1000, :locale => :fr) # => 1 000,000%
146
151
  def number_to_percentage(number, options = {})
147
152
  return nil if number.nil?
148
153
 
@@ -169,6 +174,7 @@ module ActionView
169
174
  # customize the format in the +options+ hash.
170
175
  #
171
176
  # ==== Options
177
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
172
178
  # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to ",").
173
179
  # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").
174
180
  #
@@ -177,16 +183,10 @@ module ActionView
177
183
  # number_with_delimiter(12345678.05) # => 12,345,678.05
178
184
  # number_with_delimiter(12345678, :delimiter => ".") # => 12.345.678
179
185
  # number_with_delimiter(12345678, :separator => ",") # => 12,345,678
186
+ # number_with_delimiter(12345678.05, :locale => :fr) # => 12 345 678,05
180
187
  # number_with_delimiter(98765432.98, :delimiter => " ", :separator => ",")
181
188
  # # => 98 765 432,98
182
- #
183
- # You can still use <tt>number_with_delimiter</tt> with the old API that accepts the
184
- # +delimiter+ as its optional second and the +separator+ as its
185
- # optional third parameter:
186
- # number_with_delimiter(12345678, " ") # => 12 345 678
187
- # number_with_delimiter(12345678.05, ".", ",") # => 12.345.678,05
188
- def number_with_delimiter(number, *args)
189
- options = args.extract_options!
189
+ def number_with_delimiter(number, options = {})
190
190
  options.symbolize_keys!
191
191
 
192
192
  begin
@@ -200,14 +200,6 @@ module ActionView
200
200
  end
201
201
 
202
202
  defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
203
-
204
- unless args.empty?
205
- ActiveSupport::Deprecation.warn('number_with_delimiter takes an option hash ' +
206
- 'instead of separate delimiter and precision arguments.', caller)
207
- options[:delimiter] ||= args[0] if args[0]
208
- options[:separator] ||= args[1] if args[1]
209
- end
210
-
211
203
  options = options.reverse_merge(defaults)
212
204
 
213
205
  parts = number.to_s.split('.')
@@ -221,6 +213,7 @@ module ActionView
221
213
  # You can customize the format in the +options+ hash.
222
214
  #
223
215
  # ==== Options
216
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
224
217
  # * <tt>:precision</tt> - Sets the precision of the number (defaults to 3).
225
218
  # * <tt>:significant</tt> - If +true+, precision will be the # of significant_digits. If +false+, the # of fractional digits (defaults to +false+)
226
219
  # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").
@@ -235,18 +228,13 @@ module ActionView
235
228
  # number_with_precision(111.2345, :significant => true) # => 111
236
229
  # number_with_precision(111.2345, :precision => 1, :significant => true) # => 100
237
230
  # number_with_precision(13, :precision => 5, :significant => true) # => 13.000
231
+ # number_with_precision(111.234, :locale => :fr) # => 111,234
238
232
  # number_with_precision(13, :precision => 5, :significant => true, strip_insignificant_zeros => true)
239
233
  # # => 13
240
234
  # number_with_precision(389.32314, :precision => 4, :significant => true) # => 389.3
241
235
  # number_with_precision(1111.2345, :precision => 2, :separator => ',', :delimiter => '.')
242
236
  # # => 1.111,23
243
- #
244
- # You can still use <tt>number_with_precision</tt> with the old API that accepts the
245
- # +precision+ as its optional second parameter:
246
- # number_with_precision(111.2345, 2) # => 111.23
247
- def number_with_precision(number, *args)
248
-
249
- options = args.extract_options!
237
+ def number_with_precision(number, options = {})
250
238
  options.symbolize_keys!
251
239
 
252
240
  number = begin
@@ -263,13 +251,6 @@ module ActionView
263
251
  precision_defaults = I18n.translate(:'number.precision.format', :locale => options[:locale], :default => {})
264
252
  defaults = defaults.merge(precision_defaults)
265
253
 
266
- #Backwards compatibility
267
- unless args.empty?
268
- ActiveSupport::Deprecation.warn('number_with_precision takes an option hash ' +
269
- 'instead of a separate precision argument.', caller)
270
- options[:precision] ||= args[0] if args[0]
271
- end
272
-
273
254
  options = options.reverse_merge(defaults) # Allow the user to unset default values: Eg.: :significant => false
274
255
  precision = options.delete :precision
275
256
  significant = options.delete :significant
@@ -307,6 +288,7 @@ module ActionView
307
288
  # See <tt>number_to_human</tt> if you want to pretty-print a generic number.
308
289
  #
309
290
  # ==== Options
291
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
310
292
  # * <tt>:precision</tt> - Sets the precision of the number (defaults to 3).
311
293
  # * <tt>:significant</tt> - If +true+, precision will be the # of significant_digits. If +false+, the # of fractional digits (defaults to +true+)
312
294
  # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").
@@ -323,17 +305,11 @@ module ActionView
323
305
  # number_to_human_size(483989, :precision => 2) # => 470 KB
324
306
  # number_to_human_size(1234567, :precision => 2, :separator => ',') # => 1,2 MB
325
307
  #
326
- # Unsignificant zeros after the fractional separator are stripped out by default (set
308
+ # Non-significant zeros after the fractional separator are stripped out by default (set
327
309
  # <tt>:strip_insignificant_zeros</tt> to +false+ to change that):
328
310
  # number_to_human_size(1234567890123, :precision => 5) # => "1.1229 TB"
329
311
  # number_to_human_size(524288000, :precision=>5) # => "500 MB"
330
- #
331
- # You can still use <tt>number_to_human_size</tt> with the old API that accepts the
332
- # +precision+ as its optional second parameter:
333
- # number_to_human_size(1234567, 1) # => 1 MB
334
- # number_to_human_size(483989, 2) # => 470 KB
335
- def number_to_human_size(number, *args)
336
- options = args.extract_options!
312
+ def number_to_human_size(number, options = {})
337
313
  options.symbolize_keys!
338
314
 
339
315
  number = begin
@@ -349,13 +325,7 @@ module ActionView
349
325
  defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
350
326
  human = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {})
351
327
  defaults = defaults.merge(human)
352
-
353
- unless args.empty?
354
- ActiveSupport::Deprecation.warn('number_to_human_size takes an option hash ' +
355
- 'instead of a separate precision argument.', caller)
356
- options[:precision] ||= args[0] if args[0]
357
- end
358
-
328
+
359
329
  options = options.reverse_merge(defaults)
360
330
  #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
361
331
  options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros)
@@ -393,6 +363,7 @@ module ActionView
393
363
  # a wide range of unit quantifiers, even fractional ones (centi, deci, mili, etc).
394
364
  #
395
365
  # ==== Options
366
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
396
367
  # * <tt>:precision</tt> - Sets the precision of the number (defaults to 3).
397
368
  # * <tt>:significant</tt> - If +true+, precision will be the # of significant_digits. If +false+, the # of fractional digits (defaults to +true+)
398
369
  # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").