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.
- data/CHANGELOG +36 -0
- data/{README → README.rdoc} +79 -137
- data/lib/abstract_controller.rb +1 -0
- data/lib/abstract_controller/asset_paths.rb +1 -1
- data/lib/abstract_controller/base.rb +3 -12
- data/lib/abstract_controller/rendering.rb +2 -2
- data/lib/abstract_controller/view_paths.rb +2 -1
- data/lib/action_controller.rb +1 -2
- data/lib/action_controller/base.rb +3 -9
- data/lib/action_controller/log_subscriber.rb +56 -0
- data/lib/action_controller/metal.rb +10 -3
- data/lib/action_controller/metal/helpers.rb +5 -4
- data/lib/action_controller/metal/hide_actions.rb +3 -3
- data/lib/action_controller/metal/instrumentation.rb +2 -1
- data/lib/action_controller/metal/mime_responds.rb +13 -10
- data/lib/action_controller/metal/rack_delegation.rb +0 -4
- data/lib/action_controller/metal/request_forgery_protection.rb +1 -1
- data/lib/action_controller/metal/rescue.rb +9 -0
- data/lib/action_controller/metal/responder.rb +13 -5
- data/lib/action_controller/metal/streaming.rb +2 -0
- data/lib/action_controller/metal/url_for.rb +5 -5
- data/lib/action_controller/railtie.rb +14 -23
- data/lib/action_controller/record_identifier.rb +6 -25
- data/lib/action_controller/test_case.rb +18 -6
- data/lib/action_controller/vendor/html-scanner/html/node.rb +1 -0
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +1 -0
- data/lib/action_dispatch.rb +6 -0
- data/lib/action_dispatch/http/cache.rb +2 -2
- data/lib/action_dispatch/http/filter_parameters.rb +10 -66
- data/lib/action_dispatch/http/mime_type.rb +1 -1
- data/lib/action_dispatch/http/parameter_filter.rb +72 -0
- data/lib/action_dispatch/http/parameters.rb +31 -2
- data/lib/action_dispatch/http/request.rb +4 -1
- data/lib/action_dispatch/http/upload.rb +2 -2
- data/lib/action_dispatch/middleware/callbacks.rb +4 -4
- data/lib/action_dispatch/middleware/cookies.rb +39 -6
- data/lib/action_dispatch/middleware/flash.rb +9 -2
- data/lib/action_dispatch/middleware/session/abstract_store.rb +121 -36
- data/lib/action_dispatch/middleware/session/cookie_store.rb +26 -19
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +9 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +2 -2
- data/lib/action_dispatch/middleware/stack.rb +12 -5
- data/lib/action_dispatch/railtie.rb +1 -1
- data/lib/action_dispatch/routing.rb +11 -13
- data/lib/action_dispatch/routing/deprecated_mapper.rb +6 -388
- data/lib/action_dispatch/routing/mapper.rb +364 -234
- data/lib/action_dispatch/routing/polymorphic_routes.rb +186 -0
- data/lib/action_dispatch/routing/route.rb +11 -2
- data/lib/action_dispatch/routing/route_set.rb +62 -28
- data/lib/action_dispatch/routing/url_for.rb +2 -1
- data/lib/action_dispatch/testing/assertions.rb +0 -2
- data/lib/action_dispatch/testing/assertions/routing.rb +0 -1
- data/lib/action_dispatch/testing/assertions/selector.rb +20 -24
- data/lib/action_dispatch/testing/integration.rb +2 -2
- data/lib/action_dispatch/testing/test_response.rb +2 -2
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_view.rb +1 -0
- data/lib/action_view/base.rb +20 -21
- data/lib/action_view/context.rb +9 -12
- data/lib/action_view/helpers.rb +0 -2
- data/lib/action_view/helpers/active_model_helper.rb +17 -2
- data/lib/action_view/helpers/asset_tag_helper.rb +15 -33
- data/lib/action_view/helpers/atom_feed_helper.rb +5 -3
- data/lib/action_view/helpers/cache_helper.rb +4 -2
- data/lib/action_view/helpers/capture_helper.rb +4 -4
- data/lib/action_view/helpers/csrf_helper.rb +3 -1
- data/lib/action_view/helpers/date_helper.rb +10 -5
- data/lib/action_view/helpers/debug_helper.rb +3 -1
- data/lib/action_view/helpers/form_helper.rb +36 -30
- data/lib/action_view/helpers/form_options_helper.rb +7 -6
- data/lib/action_view/helpers/form_tag_helper.rb +17 -6
- data/lib/action_view/helpers/javascript_helper.rb +1 -0
- data/lib/action_view/helpers/number_helper.rb +16 -45
- data/lib/action_view/helpers/prototype_helper.rb +14 -16
- data/lib/action_view/helpers/raw_output_helper.rb +9 -0
- data/lib/action_view/helpers/record_tag_helper.rb +5 -0
- data/lib/action_view/helpers/sanitize_helper.rb +26 -20
- data/lib/action_view/helpers/scriptaculous_helper.rb +6 -5
- data/lib/action_view/helpers/tag_helper.rb +2 -1
- data/lib/action_view/helpers/text_helper.rb +24 -111
- data/lib/action_view/helpers/translation_helper.rb +17 -10
- data/lib/action_view/helpers/url_helper.rb +26 -33
- data/lib/action_view/log_subscriber.rb +28 -0
- data/lib/action_view/lookup_context.rb +2 -0
- data/lib/action_view/paths.rb +1 -0
- data/lib/action_view/railtie.rb +15 -3
- data/lib/action_view/render/layouts.rb +2 -1
- data/lib/action_view/render/partials.rb +3 -1
- data/lib/action_view/render/rendering.rb +2 -1
- data/lib/action_view/template.rb +12 -8
- data/lib/action_view/template/error.rb +1 -0
- data/lib/action_view/template/handlers.rb +1 -0
- data/lib/action_view/template/resolver.rb +2 -1
- data/lib/action_view/template/text.rb +1 -0
- data/lib/action_view/test_case.rb +42 -20
- metadata +44 -23
- data/lib/action_controller/polymorphic_routes.rb +0 -182
- data/lib/action_controller/railties/log_subscriber.rb +0 -56
- data/lib/action_controller/railties/url_helpers.rb +0 -14
- data/lib/action_dispatch/testing/assertions/model.rb +0 -19
- data/lib/action_view/helpers/record_identification_helper.rb +0 -20
- 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
|
-
|
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
|
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
|
585
|
+
DEFAULT_PREFIX = 'date'.freeze
|
584
586
|
POSITION = {
|
585
587
|
:year => 1, :month => 2, :day => 3, :hour => 4, :minute => 5, :second => 6
|
586
|
-
}.freeze
|
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
|
-
|
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
|
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
|
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
|
-
#
|
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
|
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] ||
|
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] ||
|
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 =
|
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
|
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
|
842
|
-
DEFAULT_RADIO_OPTIONS = { }.freeze
|
843
|
-
DEFAULT_TEXT_AREA_OPTIONS = { "cols" => 40, "rows" => 20 }.freeze
|
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"]
|
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(
|
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"
|
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"
|
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"
|
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}[#{
|
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}[#{
|
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 doesn
|
416
|
-
# prepends an option with a generic prompt
|
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
|
-
|
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
|
-
|
538
|
-
|
540
|
+
snowman_tag = tag(:input, :type => "hidden",
|
541
|
+
:name => "_snowman", :value => "☃".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
|
-
|
551
|
+
token_tag
|
544
552
|
else
|
545
553
|
html_options["method"] = "post"
|
546
|
-
|
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)
|
@@ -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 => "£", :separator => ",", :delimiter => "")
|
100
103
|
# # => £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
|
-
#
|
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 ".").
|