actionview 4.2.11 → 5.0.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionview might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +304 -184
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/action_view.rb +1 -1
- data/lib/action_view/base.rb +14 -2
- data/lib/action_view/dependency_tracker.rb +51 -18
- data/lib/action_view/digestor.rb +83 -81
- data/lib/action_view/flows.rb +4 -5
- data/lib/action_view/gem_version.rb +3 -3
- data/lib/action_view/helpers/asset_tag_helper.rb +15 -5
- data/lib/action_view/helpers/asset_url_helper.rb +51 -12
- data/lib/action_view/helpers/atom_feed_helper.rb +6 -5
- data/lib/action_view/helpers/cache_helper.rb +62 -21
- data/lib/action_view/helpers/capture_helper.rb +5 -4
- data/lib/action_view/helpers/controller_helper.rb +11 -2
- data/lib/action_view/helpers/date_helper.rb +59 -13
- data/lib/action_view/helpers/debug_helper.rb +1 -1
- data/lib/action_view/helpers/form_helper.rb +74 -72
- data/lib/action_view/helpers/form_options_helper.rb +79 -39
- data/lib/action_view/helpers/form_tag_helper.rb +74 -44
- data/lib/action_view/helpers/javascript_helper.rb +4 -4
- data/lib/action_view/helpers/number_helper.rb +28 -13
- data/lib/action_view/helpers/output_safety_helper.rb +32 -2
- data/lib/action_view/helpers/record_tag_helper.rb +12 -99
- data/lib/action_view/helpers/rendering_helper.rb +2 -2
- data/lib/action_view/helpers/sanitize_helper.rb +1 -2
- data/lib/action_view/helpers/tag_helper.rb +19 -11
- data/lib/action_view/helpers/tags/base.rb +45 -29
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +4 -28
- data/lib/action_view/helpers/tags/collection_helpers.rb +32 -0
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +1 -9
- data/lib/action_view/helpers/tags/datetime_field.rb +1 -1
- data/lib/action_view/helpers/tags/label.rb +1 -1
- data/lib/action_view/helpers/tags/placeholderable.rb +1 -1
- data/lib/action_view/helpers/tags/search_field.rb +12 -9
- data/lib/action_view/helpers/tags/text_field.rb +0 -1
- data/lib/action_view/helpers/tags/translator.rb +1 -1
- data/lib/action_view/helpers/text_helper.rb +27 -11
- data/lib/action_view/helpers/translation_helper.rb +56 -26
- data/lib/action_view/helpers/url_helper.rb +108 -79
- data/lib/action_view/layouts.rb +11 -10
- data/lib/action_view/log_subscriber.rb +35 -1
- data/lib/action_view/lookup_context.rb +69 -48
- data/lib/action_view/model_naming.rb +1 -1
- data/lib/action_view/path_set.rb +9 -0
- data/lib/action_view/railtie.rb +18 -3
- data/lib/action_view/record_identifier.rb +45 -19
- data/lib/action_view/renderer/abstract_renderer.rb +7 -3
- data/lib/action_view/renderer/partial_renderer.rb +38 -37
- data/lib/action_view/renderer/partial_renderer/collection_caching.rb +49 -0
- data/lib/action_view/renderer/renderer.rb +2 -6
- data/lib/action_view/renderer/streaming_template_renderer.rb +1 -1
- data/lib/action_view/renderer/template_renderer.rb +11 -10
- data/lib/action_view/rendering.rb +15 -7
- data/lib/action_view/routing_url_for.rb +18 -6
- data/lib/action_view/tasks/{dependencies.rake → cache_digests.rake} +2 -2
- data/lib/action_view/template.rb +36 -12
- data/lib/action_view/template/error.rb +20 -9
- data/lib/action_view/template/handlers.rb +6 -4
- data/lib/action_view/template/handlers/html.rb +9 -0
- data/lib/action_view/template/handlers/raw.rb +1 -3
- data/lib/action_view/template/resolver.rb +49 -42
- data/lib/action_view/template/types.rb +14 -16
- data/lib/action_view/test_case.rb +15 -9
- data/lib/action_view/testing/resolvers.rb +1 -2
- data/lib/action_view/view_paths.rb +6 -24
- metadata +16 -20
@@ -20,7 +20,7 @@ module ActionView
|
|
20
20
|
mattr_accessor :embed_authenticity_token_in_remote_forms
|
21
21
|
self.embed_authenticity_token_in_remote_forms = false
|
22
22
|
|
23
|
-
# Starts a form tag that points the action to
|
23
|
+
# Starts a form tag that points the action to a url configured with <tt>url_for_options</tt> just like
|
24
24
|
# ActionController::Base#url_for. The method for the form defaults to POST.
|
25
25
|
#
|
26
26
|
# ==== Options
|
@@ -80,7 +80,7 @@ module ActionView
|
|
80
80
|
# associated records. <tt>option_tags</tt> is a string containing the option tags for the select box.
|
81
81
|
#
|
82
82
|
# ==== Options
|
83
|
-
# * <tt>:multiple</tt> - If set to true the selection will allow multiple choices.
|
83
|
+
# * <tt>:multiple</tt> - If set to true, the selection will allow multiple choices.
|
84
84
|
# * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
|
85
85
|
# * <tt>:include_blank</tt> - If set to true, an empty option will be created. If set to a string, the string will be used as the option's content and the value will be empty.
|
86
86
|
# * <tt>:prompt</tt> - Create a prompt option with blank value and the text asking user to select something.
|
@@ -93,22 +93,22 @@ module ActionView
|
|
93
93
|
# select_tag "people", options_from_collection_for_select(@people, "id", "name", "1")
|
94
94
|
# # <select id="people" name="people"><option value="1" selected="selected">David</option></select>
|
95
95
|
#
|
96
|
-
# select_tag "people", "<option>David</option>"
|
96
|
+
# select_tag "people", raw("<option>David</option>")
|
97
97
|
# # => <select id="people" name="people"><option>David</option></select>
|
98
98
|
#
|
99
|
-
# select_tag "count", "<option>1</option><option>2</option><option>3</option><option>4</option>"
|
99
|
+
# select_tag "count", raw("<option>1</option><option>2</option><option>3</option><option>4</option>")
|
100
100
|
# # => <select id="count" name="count"><option>1</option><option>2</option>
|
101
101
|
# # <option>3</option><option>4</option></select>
|
102
102
|
#
|
103
|
-
# select_tag "colors", "<option>Red</option><option>Green</option><option>Blue</option>"
|
103
|
+
# select_tag "colors", raw("<option>Red</option><option>Green</option><option>Blue</option>"), multiple: true
|
104
104
|
# # => <select id="colors" multiple="multiple" name="colors[]"><option>Red</option>
|
105
105
|
# # <option>Green</option><option>Blue</option></select>
|
106
106
|
#
|
107
|
-
# select_tag "locations", "<option>Home</option><option selected='selected'>Work</option><option>Out</option>"
|
107
|
+
# select_tag "locations", raw("<option>Home</option><option selected='selected'>Work</option><option>Out</option>")
|
108
108
|
# # => <select id="locations" name="locations"><option>Home</option><option selected='selected'>Work</option>
|
109
109
|
# # <option>Out</option></select>
|
110
110
|
#
|
111
|
-
# select_tag "access", "<option>Read</option><option>Write</option>"
|
111
|
+
# select_tag "access", raw("<option>Read</option><option>Write</option>"), multiple: true, class: 'form_input', id: 'unique_id'
|
112
112
|
# # => <select class="form_input" id="unique_id" multiple="multiple" name="access[]"><option>Read</option>
|
113
113
|
# # <option>Write</option></select>
|
114
114
|
#
|
@@ -121,7 +121,7 @@ module ActionView
|
|
121
121
|
# select_tag "people", options_from_collection_for_select(@people, "id", "name"), prompt: "Select something"
|
122
122
|
# # => <select id="people" name="people"><option value="">Select something</option><option value="1">David</option></select>
|
123
123
|
#
|
124
|
-
# select_tag "destination", "<option>NYC</option><option>Paris</option><option>Rome</option>"
|
124
|
+
# select_tag "destination", raw("<option>NYC</option><option>Paris</option><option>Rome</option>"), disabled: true
|
125
125
|
# # => <select disabled="disabled" id="destination" name="destination"><option>NYC</option>
|
126
126
|
# # <option>Paris</option><option>Rome</option></select>
|
127
127
|
#
|
@@ -134,21 +134,23 @@ module ActionView
|
|
134
134
|
|
135
135
|
if options.include?(:include_blank)
|
136
136
|
include_blank = options.delete(:include_blank)
|
137
|
+
options_for_blank_options_tag = { value: '' }
|
137
138
|
|
138
139
|
if include_blank == true
|
139
140
|
include_blank = ''
|
141
|
+
options_for_blank_options_tag[:label] = ' '
|
140
142
|
end
|
141
143
|
|
142
144
|
if include_blank
|
143
|
-
option_tags = content_tag(
|
145
|
+
option_tags = content_tag("option".freeze, include_blank, options_for_blank_options_tag).safe_concat(option_tags)
|
144
146
|
end
|
145
147
|
end
|
146
148
|
|
147
149
|
if prompt = options.delete(:prompt)
|
148
|
-
option_tags = content_tag(
|
150
|
+
option_tags = content_tag("option".freeze, prompt, value: '').safe_concat(option_tags)
|
149
151
|
end
|
150
152
|
|
151
|
-
content_tag
|
153
|
+
content_tag "select".freeze, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys)
|
152
154
|
end
|
153
155
|
|
154
156
|
# Creates a standard text field; use these text fields to input smaller chunks of text like a username
|
@@ -414,42 +416,45 @@ module ActionView
|
|
414
416
|
# the form is processed normally, otherwise no action is taken.
|
415
417
|
# * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a
|
416
418
|
# disabled version of the submit button when the form is submitted. This feature is
|
417
|
-
# provided by the unobtrusive JavaScript driver.
|
419
|
+
# provided by the unobtrusive JavaScript driver. To disable this feature for a single submit tag
|
420
|
+
# pass <tt>:data => { disable_with: false }</tt> Defaults to value attribute.
|
418
421
|
#
|
419
422
|
# ==== Examples
|
420
423
|
# submit_tag
|
421
|
-
# # => <input name="commit" type="submit" value="Save changes" />
|
424
|
+
# # => <input name="commit" data-disable-with="Save changes" type="submit" value="Save changes" />
|
422
425
|
#
|
423
426
|
# submit_tag "Edit this article"
|
424
|
-
# # => <input name="commit" type="submit" value="Edit this article" />
|
427
|
+
# # => <input name="commit" data-disable-with="Edit this article" type="submit" value="Edit this article" />
|
425
428
|
#
|
426
429
|
# submit_tag "Save edits", disabled: true
|
427
|
-
# # => <input disabled="disabled" name="commit" type="submit" value="Save edits" />
|
430
|
+
# # => <input disabled="disabled" name="commit" data-disable-with="Save edits" type="submit" value="Save edits" />
|
428
431
|
#
|
429
|
-
# submit_tag "Complete sale", data: { disable_with: "
|
430
|
-
# # => <input name="commit" data-disable-with="
|
432
|
+
# submit_tag "Complete sale", data: { disable_with: "Submitting..." }
|
433
|
+
# # => <input name="commit" data-disable-with="Submitting..." type="submit" value="Complete sale" />
|
431
434
|
#
|
432
435
|
# submit_tag nil, class: "form_submit"
|
433
436
|
# # => <input class="form_submit" name="commit" type="submit" />
|
434
437
|
#
|
435
438
|
# submit_tag "Edit", class: "edit_button"
|
436
|
-
# # => <input class="edit_button" name="commit" type="submit" value="Edit" />
|
439
|
+
# # => <input class="edit_button" data-disable-with="Edit" name="commit" type="submit" value="Edit" />
|
437
440
|
#
|
438
441
|
# submit_tag "Save", data: { confirm: "Are you sure?" }
|
439
|
-
# # => <input name='commit' type='submit' value='Save' data-confirm="Are you sure?" />
|
442
|
+
# # => <input name='commit' type='submit' value='Save' data-disable-with="Save" data-confirm="Are you sure?" />
|
440
443
|
#
|
441
444
|
def submit_tag(value = "Save changes", options = {})
|
442
|
-
options = options.
|
443
|
-
|
444
|
-
|
445
|
+
options = options.deep_stringify_keys
|
446
|
+
tag_options = { "type" => "submit", "name" => "commit", "value" => value }.update(options)
|
447
|
+
set_default_disable_with value, tag_options
|
448
|
+
tag :input, tag_options
|
445
449
|
end
|
446
450
|
|
447
451
|
# Creates a button element that defines a <tt>submit</tt> button,
|
448
452
|
# <tt>reset</tt>button or a generic button which can be used in
|
449
453
|
# JavaScript, for example. You can use the button tag as a regular
|
450
454
|
# submit tag but it isn't supported in legacy browsers. However,
|
451
|
-
# the button tag
|
452
|
-
# so this helper will also accept a block.
|
455
|
+
# the button tag does allow for richer labels such as images and emphasis,
|
456
|
+
# so this helper will also accept a block. By default, it will create
|
457
|
+
# a button tag with type `submit`, if type is not given.
|
453
458
|
#
|
454
459
|
# ==== Options
|
455
460
|
# * <tt>:data</tt> - This option can be used to add custom data attributes.
|
@@ -472,6 +477,15 @@ module ActionView
|
|
472
477
|
# button_tag
|
473
478
|
# # => <button name="button" type="submit">Button</button>
|
474
479
|
#
|
480
|
+
# button_tag 'Reset', type: 'reset'
|
481
|
+
# # => <button name="button" type="reset">Reset</button>
|
482
|
+
#
|
483
|
+
# button_tag 'Button', type: 'button'
|
484
|
+
# # => <button name="button" type="button">Button</button>
|
485
|
+
#
|
486
|
+
# button_tag 'Reset', type: 'reset', disabled: true
|
487
|
+
# # => <button name="button" type="reset" disabled="disabled">Reset</button>
|
488
|
+
#
|
475
489
|
# button_tag(type: 'button') do
|
476
490
|
# content_tag(:strong, 'Ask me!')
|
477
491
|
# end
|
@@ -479,6 +493,9 @@ module ActionView
|
|
479
493
|
# # <strong>Ask me!</strong>
|
480
494
|
# # </button>
|
481
495
|
#
|
496
|
+
# button_tag "Save", data: { confirm: "Are you sure?" }
|
497
|
+
# # => <button name="button" type="submit" data-confirm="Are you sure?">Save</button>
|
498
|
+
#
|
482
499
|
# button_tag "Checkout", data: { disable_with: "Please wait..." }
|
483
500
|
# # => <button data-disable-with="Please wait..." name="button" type="submit">Checkout</button>
|
484
501
|
#
|
@@ -555,7 +572,7 @@ module ActionView
|
|
555
572
|
# # => <fieldset class="format"><p><input id="name" name="name" type="text" /></p></fieldset>
|
556
573
|
def field_set_tag(legend = nil, options = nil, &block)
|
557
574
|
output = tag(:fieldset, options, true)
|
558
|
-
output.safe_concat(content_tag(
|
575
|
+
output.safe_concat(content_tag("legend".freeze, legend)) unless legend.blank?
|
559
576
|
output.concat(capture(&block)) if block_given?
|
560
577
|
output.safe_concat("</fieldset>")
|
561
578
|
end
|
@@ -656,17 +673,6 @@ module ActionView
|
|
656
673
|
text_field_tag(name, value, options.merge(type: :time))
|
657
674
|
end
|
658
675
|
|
659
|
-
# Creates a text field of type "datetime".
|
660
|
-
#
|
661
|
-
# === Options
|
662
|
-
# * <tt>:min</tt> - The minimum acceptable value.
|
663
|
-
# * <tt>:max</tt> - The maximum acceptable value.
|
664
|
-
# * <tt>:step</tt> - The acceptable value granularity.
|
665
|
-
# * Otherwise accepts the same options as text_field_tag.
|
666
|
-
def datetime_field_tag(name, value = nil, options = {})
|
667
|
-
text_field_tag(name, value, options.merge(type: :datetime))
|
668
|
-
end
|
669
|
-
|
670
676
|
# Creates a text field of type "datetime-local".
|
671
677
|
#
|
672
678
|
# === Options
|
@@ -674,10 +680,12 @@ module ActionView
|
|
674
680
|
# * <tt>:max</tt> - The maximum acceptable value.
|
675
681
|
# * <tt>:step</tt> - The acceptable value granularity.
|
676
682
|
# * Otherwise accepts the same options as text_field_tag.
|
677
|
-
def
|
683
|
+
def datetime_field_tag(name, value = nil, options = {})
|
678
684
|
text_field_tag(name, value, options.merge(type: 'datetime-local'))
|
679
685
|
end
|
680
686
|
|
687
|
+
alias datetime_local_field_tag datetime_field_tag
|
688
|
+
|
681
689
|
# Creates a text field of type "month".
|
682
690
|
#
|
683
691
|
# === Options
|
@@ -776,10 +784,10 @@ module ActionView
|
|
776
784
|
# # => <input id="quantity" name="quantity" min="1" max="9" type="number" />
|
777
785
|
#
|
778
786
|
# number_field_tag 'quantity', nil, min: 1, max: 10
|
779
|
-
# # => <input id="quantity" name="quantity" min="1" max="
|
787
|
+
# # => <input id="quantity" name="quantity" min="1" max="10" type="number" />
|
780
788
|
#
|
781
789
|
# number_field_tag 'quantity', nil, min: 1, max: 10, step: 2
|
782
|
-
# # => <input id="quantity" name="quantity" min="1" max="
|
790
|
+
# # => <input id="quantity" name="quantity" min="1" max="10" step="2" type="number" />
|
783
791
|
#
|
784
792
|
# number_field_tag 'quantity', '1', class: 'special_input', disabled: true
|
785
793
|
# # => <input disabled="disabled" class="special_input" id="quantity" name="quantity" type="number" value="1" />
|
@@ -835,18 +843,24 @@ module ActionView
|
|
835
843
|
|
836
844
|
def extra_tags_for_form(html_options)
|
837
845
|
authenticity_token = html_options.delete("authenticity_token")
|
838
|
-
method = html_options.delete("method").to_s
|
846
|
+
method = html_options.delete("method").to_s.downcase
|
839
847
|
|
840
848
|
method_tag = case method
|
841
|
-
when
|
849
|
+
when 'get'
|
842
850
|
html_options["method"] = "get"
|
843
851
|
''
|
844
|
-
when
|
852
|
+
when 'post', ''
|
845
853
|
html_options["method"] = "post"
|
846
|
-
token_tag(authenticity_token
|
854
|
+
token_tag(authenticity_token, form_options: {
|
855
|
+
action: html_options["action"],
|
856
|
+
method: "post"
|
857
|
+
})
|
847
858
|
else
|
848
859
|
html_options["method"] = "post"
|
849
|
-
method_tag(method) + token_tag(authenticity_token
|
860
|
+
method_tag(method) + token_tag(authenticity_token, form_options: {
|
861
|
+
action: html_options["action"],
|
862
|
+
method: method
|
863
|
+
})
|
850
864
|
end
|
851
865
|
|
852
866
|
if html_options.delete("enforce_utf8") { true }
|
@@ -871,6 +885,22 @@ module ActionView
|
|
871
885
|
def sanitize_to_id(name)
|
872
886
|
name.to_s.delete(']').tr('^-a-zA-Z0-9:.', "_")
|
873
887
|
end
|
888
|
+
|
889
|
+
def set_default_disable_with(value, tag_options)
|
890
|
+
return unless ActionView::Base.automatically_disable_submit_tag
|
891
|
+
data = tag_options["data"]
|
892
|
+
|
893
|
+
unless tag_options["data-disable-with"] == false || (data && data["disable_with"] == false)
|
894
|
+
disable_with_text = tag_options["data-disable-with"]
|
895
|
+
disable_with_text ||= data["disable_with"] if data
|
896
|
+
disable_with_text ||= value.to_s.clone
|
897
|
+
tag_options.deep_merge!("data" => { "disable_with" => disable_with_text })
|
898
|
+
else
|
899
|
+
data.delete("disable_with") if data
|
900
|
+
end
|
901
|
+
|
902
|
+
tag_options.delete("data-disable-with")
|
903
|
+
end
|
874
904
|
end
|
875
905
|
end
|
876
906
|
end
|
@@ -21,7 +21,7 @@ module ActionView
|
|
21
21
|
# Also available through the alias j(). This is particularly helpful in JavaScript
|
22
22
|
# responses, like:
|
23
23
|
#
|
24
|
-
# $('some_element').replaceWith('<%=j render 'some/element_template' %>');
|
24
|
+
# $('some_element').replaceWith('<%= j render 'some/element_template' %>');
|
25
25
|
def escape_javascript(javascript)
|
26
26
|
if javascript
|
27
27
|
result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"'])/u) {|match| JS_ESCAPE_MAP[match] }
|
@@ -47,8 +47,8 @@ module ActionView
|
|
47
47
|
# tag.
|
48
48
|
#
|
49
49
|
# javascript_tag "alert('All is good')", defer: 'defer'
|
50
|
-
#
|
51
|
-
# Returns:
|
50
|
+
#
|
51
|
+
# Returns:
|
52
52
|
# <script defer="defer">
|
53
53
|
# //<![CDATA[
|
54
54
|
# alert('All is good')
|
@@ -70,7 +70,7 @@ module ActionView
|
|
70
70
|
content_or_options_with_block
|
71
71
|
end
|
72
72
|
|
73
|
-
content_tag(
|
73
|
+
content_tag("script".freeze, javascript_cdata_section(content), html_options)
|
74
74
|
end
|
75
75
|
|
76
76
|
def javascript_cdata_section(content) #:nodoc:
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
require 'active_support/core_ext/hash/keys'
|
4
2
|
require 'active_support/core_ext/string/output_safety'
|
5
3
|
require 'active_support/number_helper'
|
@@ -25,7 +23,7 @@ module ActionView
|
|
25
23
|
end
|
26
24
|
end
|
27
25
|
|
28
|
-
# Formats a +number+ into a
|
26
|
+
# Formats a +number+ into a phone number (US by default e.g., (555)
|
29
27
|
# 123-9876). You can customize the format in the +options+ hash.
|
30
28
|
#
|
31
29
|
# ==== Options
|
@@ -37,6 +35,8 @@ module ActionView
|
|
37
35
|
# end of the generated number.
|
38
36
|
# * <tt>:country_code</tt> - Sets the country code for the phone
|
39
37
|
# number.
|
38
|
+
# * <tt>:pattern</tt> - Specifies how the number is divided into three
|
39
|
+
# groups with the custom regexp to override the default format.
|
40
40
|
# * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
|
41
41
|
# the argument is invalid.
|
42
42
|
#
|
@@ -54,6 +54,11 @@ module ActionView
|
|
54
54
|
#
|
55
55
|
# number_to_phone(1235551234, country_code: 1, extension: 1343, delimiter: ".")
|
56
56
|
# # => +1.123.555.1234 x 1343
|
57
|
+
#
|
58
|
+
# number_to_phone(75561234567, pattern: /(\d{1,4})(\d{4})(\d{4})$/, area_code: true)
|
59
|
+
# # => "(755) 6123-4567"
|
60
|
+
# number_to_phone(13312345678, pattern: /(\d{3})(\d{4})(\d{4})$/))
|
61
|
+
# # => "133-1234-5678"
|
57
62
|
def number_to_phone(number, options = {})
|
58
63
|
return unless number
|
59
64
|
options = options.symbolize_keys
|
@@ -65,6 +70,14 @@ module ActionView
|
|
65
70
|
# Formats a +number+ into a currency string (e.g., $13.65). You
|
66
71
|
# can customize the format in the +options+ hash.
|
67
72
|
#
|
73
|
+
# The currency unit and number formatting of the current locale will be used
|
74
|
+
# unless otherwise specified in the provided options. No currency conversion
|
75
|
+
# is performed. If the user is given a way to change their locale, they will
|
76
|
+
# also be able to change the relative value of the currency displayed with
|
77
|
+
# this helper. If your application will ever support multiple locales, you
|
78
|
+
# may want to specify a constant <tt>:locale</tt> option or consider
|
79
|
+
# using a library capable of currency conversion.
|
80
|
+
#
|
68
81
|
# ==== Options
|
69
82
|
#
|
70
83
|
# * <tt>:locale</tt> - Sets the locale to be used for formatting
|
@@ -117,8 +130,8 @@ module ActionView
|
|
117
130
|
# (defaults to current locale).
|
118
131
|
# * <tt>:precision</tt> - Sets the precision of the number
|
119
132
|
# (defaults to 3).
|
120
|
-
# * <tt>:significant</tt> - If +true+, precision will be the
|
121
|
-
# of significant_digits. If +false+, the
|
133
|
+
# * <tt>:significant</tt> - If +true+, precision will be the number
|
134
|
+
# of significant_digits. If +false+, the number of fractional
|
122
135
|
# digits (defaults to +false+).
|
123
136
|
# * <tt>:separator</tt> - Sets the separator between the
|
124
137
|
# fractional and integer digits (defaults to ".").
|
@@ -141,7 +154,7 @@ module ActionView
|
|
141
154
|
# number_to_percentage(302.24398923423, precision: 5) # => 302.24399%
|
142
155
|
# number_to_percentage(1000, locale: :fr) # => 1 000,000%
|
143
156
|
# number_to_percentage("98a") # => 98a%
|
144
|
-
# number_to_percentage(100, format: "%n %") # => 100 %
|
157
|
+
# number_to_percentage(100, format: "%n %") # => 100.000 %
|
145
158
|
#
|
146
159
|
# number_to_percentage("98a", raise: true) # => InvalidNumberError
|
147
160
|
def number_to_percentage(number, options = {})
|
@@ -192,8 +205,8 @@ module ActionView
|
|
192
205
|
# (defaults to current locale).
|
193
206
|
# * <tt>:precision</tt> - Sets the precision of the number
|
194
207
|
# (defaults to 3).
|
195
|
-
# * <tt>:significant</tt> - If +true+, precision will be the
|
196
|
-
# of significant_digits. If +false+, the
|
208
|
+
# * <tt>:significant</tt> - If +true+, precision will be the number
|
209
|
+
# of significant_digits. If +false+, the number of fractional
|
197
210
|
# digits (defaults to +false+).
|
198
211
|
# * <tt>:separator</tt> - Sets the separator between the
|
199
212
|
# fractional and integer digits (defaults to ".").
|
@@ -240,8 +253,8 @@ module ActionView
|
|
240
253
|
# (defaults to current locale).
|
241
254
|
# * <tt>:precision</tt> - Sets the precision of the number
|
242
255
|
# (defaults to 3).
|
243
|
-
# * <tt>:significant</tt> - If +true+, precision will be the
|
244
|
-
# of significant_digits. If +false+, the
|
256
|
+
# * <tt>:significant</tt> - If +true+, precision will be the number
|
257
|
+
# of significant_digits. If +false+, the number of fractional
|
245
258
|
# digits (defaults to +true+)
|
246
259
|
# * <tt>:separator</tt> - Sets the separator between the
|
247
260
|
# fractional and integer digits (defaults to ".").
|
@@ -263,6 +276,8 @@ module ActionView
|
|
263
276
|
# number_to_human_size(1234567) # => 1.18 MB
|
264
277
|
# number_to_human_size(1234567890) # => 1.15 GB
|
265
278
|
# number_to_human_size(1234567890123) # => 1.12 TB
|
279
|
+
# number_to_human_size(1234567890123456) # => 1.1 PB
|
280
|
+
# number_to_human_size(1234567890123456789) # => 1.07 EB
|
266
281
|
# number_to_human_size(1234567, precision: 2) # => 1.2 MB
|
267
282
|
# number_to_human_size(483989, precision: 2) # => 470 KB
|
268
283
|
# number_to_human_size(1234567, precision: 2, separator: ',') # => 1,2 MB
|
@@ -280,7 +295,7 @@ module ActionView
|
|
280
295
|
# See <tt>number_to_human_size</tt> if you want to print a file
|
281
296
|
# size.
|
282
297
|
#
|
283
|
-
# You can also define
|
298
|
+
# You can also define your own unit-quantifier names if you want
|
284
299
|
# to use other decimal units (eg.: 1500 becomes "1.5
|
285
300
|
# kilometers", 0.150 becomes "150 milliliters", etc). You may
|
286
301
|
# define a wide range of unit quantifiers, even fractional ones
|
@@ -292,8 +307,8 @@ module ActionView
|
|
292
307
|
# (defaults to current locale).
|
293
308
|
# * <tt>:precision</tt> - Sets the precision of the number
|
294
309
|
# (defaults to 3).
|
295
|
-
# * <tt>:significant</tt> - If +true+, precision will be the
|
296
|
-
# of significant_digits. If +false+, the
|
310
|
+
# * <tt>:significant</tt> - If +true+, precision will be the number
|
311
|
+
# of significant_digits. If +false+, the number of fractional
|
297
312
|
# digits (defaults to +true+)
|
298
313
|
# * <tt>:separator</tt> - Sets the separator between the
|
299
314
|
# fractional and integer digits (defaults to ".").
|
@@ -22,10 +22,10 @@ module ActionView #:nodoc:
|
|
22
22
|
# the supplied separator, are HTML escaped unless they are HTML
|
23
23
|
# safe, and the returned string is marked as HTML safe.
|
24
24
|
#
|
25
|
-
# safe_join(["<p>foo</p>"
|
25
|
+
# safe_join([raw("<p>foo</p>"), "<p>bar</p>"], "<br />")
|
26
26
|
# # => "<p>foo</p><br /><p>bar</p>"
|
27
27
|
#
|
28
|
-
# safe_join(["<p>foo</p>"
|
28
|
+
# safe_join([raw("<p>foo</p>"), raw("<p>bar</p>")], raw("<br />")
|
29
29
|
# # => "<p>foo</p><br /><p>bar</p>"
|
30
30
|
#
|
31
31
|
def safe_join(array, sep=$,)
|
@@ -33,6 +33,36 @@ module ActionView #:nodoc:
|
|
33
33
|
|
34
34
|
array.flatten.map! { |i| ERB::Util.unwrapped_html_escape(i) }.join(sep).html_safe
|
35
35
|
end
|
36
|
+
|
37
|
+
# Converts the array to a comma-separated sentence where the last element is
|
38
|
+
# joined by the connector word. This is the html_safe-aware version of
|
39
|
+
# ActiveSupport's {Array#to_sentence}[http://api.rubyonrails.org/classes/Array.html#method-i-to_sentence].
|
40
|
+
#
|
41
|
+
def to_sentence(array, options = {})
|
42
|
+
options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector, :locale)
|
43
|
+
|
44
|
+
default_connectors = {
|
45
|
+
:words_connector => ', ',
|
46
|
+
:two_words_connector => ' and ',
|
47
|
+
:last_word_connector => ', and '
|
48
|
+
}
|
49
|
+
if defined?(I18n)
|
50
|
+
i18n_connectors = I18n.translate(:'support.array', locale: options[:locale], default: {})
|
51
|
+
default_connectors.merge!(i18n_connectors)
|
52
|
+
end
|
53
|
+
options = default_connectors.merge!(options)
|
54
|
+
|
55
|
+
case array.length
|
56
|
+
when 0
|
57
|
+
''.html_safe
|
58
|
+
when 1
|
59
|
+
ERB::Util.html_escape(array[0])
|
60
|
+
when 2
|
61
|
+
safe_join([array[0], array[1]], options[:two_words_connector])
|
62
|
+
else
|
63
|
+
safe_join([safe_join(array[0...-1], options[:words_connector]), options[:last_word_connector], array[-1]])
|
64
|
+
end
|
65
|
+
end
|
36
66
|
end
|
37
67
|
end
|
38
68
|
end
|