actionpack 4.0.1 → 4.2.11.1

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 (241) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +402 -1173
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +7 -7
  5. data/lib/abstract_controller/base.rb +39 -7
  6. data/lib/abstract_controller/callbacks.rb +32 -53
  7. data/lib/abstract_controller/collector.rb +11 -1
  8. data/lib/abstract_controller/helpers.rb +26 -16
  9. data/lib/abstract_controller/railties/routes_helpers.rb +3 -3
  10. data/lib/abstract_controller/rendering.rb +57 -127
  11. data/lib/abstract_controller/url_for.rb +1 -1
  12. data/lib/abstract_controller.rb +1 -2
  13. data/lib/action_controller/base.rb +19 -10
  14. data/lib/action_controller/caching/fragments.rb +7 -1
  15. data/lib/action_controller/caching.rb +2 -12
  16. data/lib/action_controller/log_subscriber.rb +29 -20
  17. data/lib/action_controller/metal/conditional_get.rb +37 -12
  18. data/lib/action_controller/metal/data_streaming.rb +1 -1
  19. data/lib/action_controller/metal/etag_with_template_digest.rb +50 -0
  20. data/lib/action_controller/metal/exceptions.rb +1 -1
  21. data/lib/action_controller/metal/flash.rb +17 -0
  22. data/lib/action_controller/metal/force_ssl.rb +2 -2
  23. data/lib/action_controller/metal/head.rb +8 -6
  24. data/lib/action_controller/metal/helpers.rb +6 -2
  25. data/lib/action_controller/metal/http_authentication.rb +45 -23
  26. data/lib/action_controller/metal/instrumentation.rb +9 -6
  27. data/lib/action_controller/metal/live.rb +173 -20
  28. data/lib/action_controller/metal/mime_responds.rb +127 -232
  29. data/lib/action_controller/metal/params_wrapper.rb +16 -9
  30. data/lib/action_controller/metal/rack_delegation.rb +1 -1
  31. data/lib/action_controller/metal/redirecting.rb +34 -26
  32. data/lib/action_controller/metal/renderers.rb +39 -12
  33. data/lib/action_controller/metal/rendering.rb +41 -14
  34. data/lib/action_controller/metal/request_forgery_protection.rb +147 -19
  35. data/lib/action_controller/metal/streaming.rb +19 -21
  36. data/lib/action_controller/metal/strong_parameters.rb +166 -22
  37. data/lib/action_controller/metal/testing.rb +0 -1
  38. data/lib/action_controller/metal/url_for.rb +11 -12
  39. data/lib/action_controller/metal.rb +14 -8
  40. data/lib/action_controller/model_naming.rb +1 -1
  41. data/lib/action_controller/railtie.rb +5 -1
  42. data/lib/action_controller/test_case.rb +160 -94
  43. data/lib/action_controller.rb +2 -18
  44. data/lib/action_dispatch/http/cache.rb +5 -4
  45. data/lib/action_dispatch/http/filter_parameters.rb +2 -2
  46. data/lib/action_dispatch/http/filter_redirect.rb +5 -4
  47. data/lib/action_dispatch/http/headers.rb +46 -10
  48. data/lib/action_dispatch/http/mime_negotiation.rb +31 -4
  49. data/lib/action_dispatch/http/mime_type.rb +25 -26
  50. data/lib/action_dispatch/http/mime_types.rb +1 -0
  51. data/lib/action_dispatch/http/parameter_filter.rb +1 -1
  52. data/lib/action_dispatch/http/parameters.rb +25 -41
  53. data/lib/action_dispatch/http/request.rb +49 -32
  54. data/lib/action_dispatch/http/response.rb +127 -25
  55. data/lib/action_dispatch/http/upload.rb +9 -21
  56. data/lib/action_dispatch/http/url.rb +97 -70
  57. data/lib/action_dispatch/journey/formatter.rb +35 -19
  58. data/lib/action_dispatch/journey/gtg/builder.rb +3 -3
  59. data/lib/action_dispatch/journey/gtg/simulator.rb +10 -7
  60. data/lib/action_dispatch/journey/gtg/transition_table.rb +23 -33
  61. data/lib/action_dispatch/journey/nfa/dot.rb +2 -2
  62. data/lib/action_dispatch/journey/nfa/simulator.rb +1 -1
  63. data/lib/action_dispatch/journey/nfa/transition_table.rb +5 -5
  64. data/lib/action_dispatch/journey/nodes/node.rb +4 -0
  65. data/lib/action_dispatch/journey/parser.rb +51 -59
  66. data/lib/action_dispatch/journey/parser.y +12 -10
  67. data/lib/action_dispatch/journey/path/pattern.rb +16 -19
  68. data/lib/action_dispatch/journey/route.rb +8 -19
  69. data/lib/action_dispatch/journey/router/strexp.rb +9 -6
  70. data/lib/action_dispatch/journey/router/utils.rb +54 -18
  71. data/lib/action_dispatch/journey/router.rb +53 -75
  72. data/lib/action_dispatch/journey/routes.rb +4 -0
  73. data/lib/action_dispatch/journey/scanner.rb +5 -5
  74. data/lib/action_dispatch/journey/visitors.rb +81 -60
  75. data/lib/action_dispatch/journey/visualizer/fsm.css +0 -4
  76. data/lib/action_dispatch/journey/visualizer/index.html.erb +2 -2
  77. data/lib/action_dispatch/middleware/callbacks.rb +7 -7
  78. data/lib/action_dispatch/middleware/cookies.rb +119 -43
  79. data/lib/action_dispatch/middleware/debug_exceptions.rb +32 -13
  80. data/lib/action_dispatch/middleware/exception_wrapper.rb +60 -20
  81. data/lib/action_dispatch/middleware/flash.rb +37 -24
  82. data/lib/action_dispatch/middleware/params_parser.rb +2 -2
  83. data/lib/action_dispatch/middleware/public_exceptions.rb +12 -3
  84. data/lib/action_dispatch/middleware/reloader.rb +11 -2
  85. data/lib/action_dispatch/middleware/remote_ip.rb +40 -54
  86. data/lib/action_dispatch/middleware/request_id.rb +1 -1
  87. data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
  88. data/lib/action_dispatch/middleware/session/cookie_store.rb +8 -7
  89. data/lib/action_dispatch/middleware/show_exceptions.rb +6 -2
  90. data/lib/action_dispatch/middleware/ssl.rb +10 -7
  91. data/lib/action_dispatch/middleware/static.rb +79 -23
  92. data/lib/action_dispatch/middleware/templates/rescues/{_request_and_response.erb → _request_and_response.html.erb} +0 -0
  93. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  94. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +21 -19
  95. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
  96. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  97. data/lib/action_dispatch/middleware/templates/rescues/{diagnostics.erb → diagnostics.html.erb} +1 -1
  98. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  99. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +6 -0
  100. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  101. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  102. data/lib/action_dispatch/middleware/templates/rescues/{routing_error.erb → routing_error.html.erb} +3 -1
  103. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  104. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  105. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  106. data/lib/action_dispatch/middleware/templates/rescues/{unknown_action.erb → unknown_action.html.erb} +1 -1
  107. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  108. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +120 -64
  109. data/lib/action_dispatch/railtie.rb +5 -2
  110. data/lib/action_dispatch/request/session.rb +12 -0
  111. data/lib/action_dispatch/request/utils.rb +35 -0
  112. data/lib/action_dispatch/routing/endpoint.rb +10 -0
  113. data/lib/action_dispatch/routing/inspector.rb +11 -17
  114. data/lib/action_dispatch/routing/mapper.rb +519 -312
  115. data/lib/action_dispatch/routing/polymorphic_routes.rb +204 -79
  116. data/lib/action_dispatch/routing/redirection.rb +51 -26
  117. data/lib/action_dispatch/routing/route_set.rb +331 -206
  118. data/lib/action_dispatch/routing/routes_proxy.rb +5 -4
  119. data/lib/action_dispatch/routing/url_for.rb +19 -5
  120. data/lib/action_dispatch/routing.rb +9 -6
  121. data/lib/action_dispatch/testing/assertions/dom.rb +2 -26
  122. data/lib/action_dispatch/testing/assertions/response.rb +9 -15
  123. data/lib/action_dispatch/testing/assertions/routing.rb +22 -22
  124. data/lib/action_dispatch/testing/assertions/selector.rb +2 -429
  125. data/lib/action_dispatch/testing/assertions/tag.rb +2 -134
  126. data/lib/action_dispatch/testing/assertions.rb +11 -7
  127. data/lib/action_dispatch/testing/integration.rb +31 -29
  128. data/lib/action_dispatch/testing/test_request.rb +1 -1
  129. data/lib/action_dispatch/testing/test_response.rb +1 -5
  130. data/lib/action_dispatch.rb +5 -8
  131. data/lib/action_pack/gem_version.rb +15 -0
  132. data/lib/action_pack/version.rb +4 -7
  133. data/lib/action_pack.rb +1 -1
  134. metadata +77 -159
  135. data/lib/abstract_controller/layouts.rb +0 -423
  136. data/lib/abstract_controller/view_paths.rb +0 -96
  137. data/lib/action_controller/deprecated/integration_test.rb +0 -5
  138. data/lib/action_controller/deprecated.rb +0 -7
  139. data/lib/action_controller/metal/responder.rb +0 -287
  140. data/lib/action_controller/record_identifier.rb +0 -31
  141. data/lib/action_controller/vendor/html-scanner.rb +0 -5
  142. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +0 -24
  143. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +0 -7
  144. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +0 -43
  145. data/lib/action_view/base.rb +0 -201
  146. data/lib/action_view/buffers.rb +0 -49
  147. data/lib/action_view/context.rb +0 -36
  148. data/lib/action_view/dependency_tracker.rb +0 -93
  149. data/lib/action_view/digestor.rb +0 -113
  150. data/lib/action_view/flows.rb +0 -76
  151. data/lib/action_view/helpers/active_model_helper.rb +0 -49
  152. data/lib/action_view/helpers/asset_tag_helper.rb +0 -320
  153. data/lib/action_view/helpers/asset_url_helper.rb +0 -355
  154. data/lib/action_view/helpers/atom_feed_helper.rb +0 -203
  155. data/lib/action_view/helpers/cache_helper.rb +0 -196
  156. data/lib/action_view/helpers/capture_helper.rb +0 -216
  157. data/lib/action_view/helpers/controller_helper.rb +0 -25
  158. data/lib/action_view/helpers/csrf_helper.rb +0 -30
  159. data/lib/action_view/helpers/date_helper.rb +0 -1083
  160. data/lib/action_view/helpers/debug_helper.rb +0 -39
  161. data/lib/action_view/helpers/form_helper.rb +0 -1880
  162. data/lib/action_view/helpers/form_options_helper.rb +0 -838
  163. data/lib/action_view/helpers/form_tag_helper.rb +0 -785
  164. data/lib/action_view/helpers/javascript_helper.rb +0 -117
  165. data/lib/action_view/helpers/number_helper.rb +0 -441
  166. data/lib/action_view/helpers/output_safety_helper.rb +0 -38
  167. data/lib/action_view/helpers/record_tag_helper.rb +0 -106
  168. data/lib/action_view/helpers/rendering_helper.rb +0 -90
  169. data/lib/action_view/helpers/sanitize_helper.rb +0 -256
  170. data/lib/action_view/helpers/tag_helper.rb +0 -173
  171. data/lib/action_view/helpers/tags/base.rb +0 -148
  172. data/lib/action_view/helpers/tags/check_box.rb +0 -64
  173. data/lib/action_view/helpers/tags/checkable.rb +0 -16
  174. data/lib/action_view/helpers/tags/collection_check_boxes.rb +0 -44
  175. data/lib/action_view/helpers/tags/collection_helpers.rb +0 -84
  176. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +0 -36
  177. data/lib/action_view/helpers/tags/collection_select.rb +0 -28
  178. data/lib/action_view/helpers/tags/color_field.rb +0 -25
  179. data/lib/action_view/helpers/tags/date_field.rb +0 -13
  180. data/lib/action_view/helpers/tags/date_select.rb +0 -72
  181. data/lib/action_view/helpers/tags/datetime_field.rb +0 -22
  182. data/lib/action_view/helpers/tags/datetime_local_field.rb +0 -19
  183. data/lib/action_view/helpers/tags/datetime_select.rb +0 -8
  184. data/lib/action_view/helpers/tags/email_field.rb +0 -8
  185. data/lib/action_view/helpers/tags/file_field.rb +0 -8
  186. data/lib/action_view/helpers/tags/grouped_collection_select.rb +0 -29
  187. data/lib/action_view/helpers/tags/hidden_field.rb +0 -8
  188. data/lib/action_view/helpers/tags/label.rb +0 -66
  189. data/lib/action_view/helpers/tags/month_field.rb +0 -13
  190. data/lib/action_view/helpers/tags/number_field.rb +0 -18
  191. data/lib/action_view/helpers/tags/password_field.rb +0 -12
  192. data/lib/action_view/helpers/tags/radio_button.rb +0 -31
  193. data/lib/action_view/helpers/tags/range_field.rb +0 -8
  194. data/lib/action_view/helpers/tags/search_field.rb +0 -24
  195. data/lib/action_view/helpers/tags/select.rb +0 -40
  196. data/lib/action_view/helpers/tags/tel_field.rb +0 -8
  197. data/lib/action_view/helpers/tags/text_area.rb +0 -18
  198. data/lib/action_view/helpers/tags/text_field.rb +0 -29
  199. data/lib/action_view/helpers/tags/time_field.rb +0 -13
  200. data/lib/action_view/helpers/tags/time_select.rb +0 -8
  201. data/lib/action_view/helpers/tags/time_zone_select.rb +0 -20
  202. data/lib/action_view/helpers/tags/url_field.rb +0 -8
  203. data/lib/action_view/helpers/tags/week_field.rb +0 -13
  204. data/lib/action_view/helpers/tags.rb +0 -39
  205. data/lib/action_view/helpers/text_helper.rb +0 -443
  206. data/lib/action_view/helpers/translation_helper.rb +0 -107
  207. data/lib/action_view/helpers/url_helper.rb +0 -635
  208. data/lib/action_view/helpers.rb +0 -58
  209. data/lib/action_view/locale/en.yml +0 -56
  210. data/lib/action_view/log_subscriber.rb +0 -30
  211. data/lib/action_view/lookup_context.rb +0 -241
  212. data/lib/action_view/model_naming.rb +0 -12
  213. data/lib/action_view/path_set.rb +0 -77
  214. data/lib/action_view/railtie.rb +0 -43
  215. data/lib/action_view/record_identifier.rb +0 -84
  216. data/lib/action_view/renderer/abstract_renderer.rb +0 -47
  217. data/lib/action_view/renderer/partial_renderer.rb +0 -492
  218. data/lib/action_view/renderer/renderer.rb +0 -50
  219. data/lib/action_view/renderer/streaming_template_renderer.rb +0 -103
  220. data/lib/action_view/renderer/template_renderer.rb +0 -96
  221. data/lib/action_view/routing_url_for.rb +0 -107
  222. data/lib/action_view/tasks/dependencies.rake +0 -17
  223. data/lib/action_view/template/error.rb +0 -138
  224. data/lib/action_view/template/handlers/builder.rb +0 -26
  225. data/lib/action_view/template/handlers/erb.rb +0 -146
  226. data/lib/action_view/template/handlers/raw.rb +0 -11
  227. data/lib/action_view/template/handlers.rb +0 -53
  228. data/lib/action_view/template/resolver.rb +0 -326
  229. data/lib/action_view/template/text.rb +0 -34
  230. data/lib/action_view/template/types.rb +0 -57
  231. data/lib/action_view/template.rb +0 -339
  232. data/lib/action_view/test_case.rb +0 -270
  233. data/lib/action_view/testing/resolvers.rb +0 -50
  234. data/lib/action_view/vendor/html-scanner/html/document.rb +0 -68
  235. data/lib/action_view/vendor/html-scanner/html/node.rb +0 -532
  236. data/lib/action_view/vendor/html-scanner/html/sanitizer.rb +0 -188
  237. data/lib/action_view/vendor/html-scanner/html/selector.rb +0 -830
  238. data/lib/action_view/vendor/html-scanner/html/tokenizer.rb +0 -107
  239. data/lib/action_view/vendor/html-scanner/html/version.rb +0 -11
  240. data/lib/action_view/vendor/html-scanner.rb +0 -20
  241. data/lib/action_view.rb +0 -93
@@ -1,117 +0,0 @@
1
- require 'action_view/helpers/tag_helper'
2
-
3
- module ActionView
4
- module Helpers
5
- module JavaScriptHelper
6
- JS_ESCAPE_MAP = {
7
- '\\' => '\\\\',
8
- '</' => '<\/',
9
- "\r\n" => '\n',
10
- "\n" => '\n',
11
- "\r" => '\n',
12
- '"' => '\\"',
13
- "'" => "\\'"
14
- }
15
-
16
- JS_ESCAPE_MAP["\342\200\250".force_encoding(Encoding::UTF_8).encode!] = '&#x2028;'
17
- JS_ESCAPE_MAP["\342\200\251".force_encoding(Encoding::UTF_8).encode!] = '&#x2029;'
18
-
19
- # Escapes carriage returns and single and double quotes for JavaScript segments.
20
- #
21
- # Also available through the alias j(). This is particularly helpful in JavaScript
22
- # responses, like:
23
- #
24
- # $('some_element').replaceWith('<%=j render 'some/element_template' %>');
25
- def escape_javascript(javascript)
26
- if javascript
27
- result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"'])/u) {|match| JS_ESCAPE_MAP[match] }
28
- javascript.html_safe? ? result.html_safe : result
29
- else
30
- ''
31
- end
32
- end
33
-
34
- alias_method :j, :escape_javascript
35
-
36
- # Returns a JavaScript tag with the +content+ inside. Example:
37
- # javascript_tag "alert('All is good')"
38
- #
39
- # Returns:
40
- # <script>
41
- # //<![CDATA[
42
- # alert('All is good')
43
- # //]]>
44
- # </script>
45
- #
46
- # +html_options+ may be a hash of attributes for the <tt>\<script></tt>
47
- # tag.
48
- #
49
- # javascript_tag "alert('All is good')", defer: 'defer'
50
- # # => <script defer="defer">alert('All is good')</script>
51
- #
52
- # Instead of passing the content as an argument, you can also use a block
53
- # in which case, you pass your +html_options+ as the first parameter.
54
- #
55
- # <%= javascript_tag defer: 'defer' do -%>
56
- # alert('All is good')
57
- # <% end -%>
58
- def javascript_tag(content_or_options_with_block = nil, html_options = {}, &block)
59
- content =
60
- if block_given?
61
- html_options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
62
- capture(&block)
63
- else
64
- content_or_options_with_block
65
- end
66
-
67
- content_tag(:script, javascript_cdata_section(content), html_options)
68
- end
69
-
70
- def javascript_cdata_section(content) #:nodoc:
71
- "\n//#{cdata_section("\n#{content}\n//")}\n".html_safe
72
- end
73
-
74
- # Returns a button whose +onclick+ handler triggers the passed JavaScript.
75
- #
76
- # The helper receives a name, JavaScript code, and an optional hash of HTML options. The
77
- # name is used as button label and the JavaScript code goes into its +onclick+ attribute.
78
- # If +html_options+ has an <tt>:onclick</tt>, that one is put before +function+.
79
- #
80
- # button_to_function "Greeting", "alert('Hello world!')", class: "ok"
81
- # # => <input class="ok" onclick="alert('Hello world!');" type="button" value="Greeting" />
82
- #
83
- def button_to_function(name, function=nil, html_options={})
84
- message = "button_to_function is deprecated and will be removed from Rails 4.1. We recommend using Unobtrusive JavaScript instead. " +
85
- "See http://guides.rubyonrails.org/working_with_javascript_in_rails.html#unobtrusive-javascript"
86
- ActiveSupport::Deprecation.warn message
87
-
88
- onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};"
89
-
90
- tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick))
91
- end
92
-
93
- # Returns a link whose +onclick+ handler triggers the passed JavaScript.
94
- #
95
- # The helper receives a name, JavaScript code, and an optional hash of HTML options. The
96
- # name is used as the link text and the JavaScript code goes into the +onclick+ attribute.
97
- # If +html_options+ has an <tt>:onclick</tt>, that one is put before +function+. Once all
98
- # the JavaScript is set, the helper appends "; return false;".
99
- #
100
- # The +href+ attribute of the tag is set to "#" unless +html_options+ has one.
101
- #
102
- # link_to_function "Greeting", "alert('Hello world!')", class: "nav_link"
103
- # # => <a class="nav_link" href="#" onclick="alert('Hello world!'); return false;">Greeting</a>
104
- #
105
- def link_to_function(name, function, html_options={})
106
- message = "link_to_function is deprecated and will be removed from Rails 4.1. We recommend using Unobtrusive JavaScript instead. " +
107
- "See http://guides.rubyonrails.org/working_with_javascript_in_rails.html#unobtrusive-javascript"
108
- ActiveSupport::Deprecation.warn message
109
-
110
- onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;"
111
- href = html_options[:href] || '#'
112
-
113
- content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick))
114
- end
115
- end
116
- end
117
- end
@@ -1,441 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'active_support/core_ext/hash/keys'
4
- require 'active_support/core_ext/string/output_safety'
5
- require 'active_support/number_helper'
6
-
7
- module ActionView
8
- # = Action View Number Helpers
9
- module Helpers #:nodoc:
10
-
11
- # Provides methods for converting numbers into formatted strings.
12
- # Methods are provided for phone numbers, currency, percentage,
13
- # precision, positional notation, file size and pretty printing.
14
- #
15
- # Most methods expect a +number+ argument, and will return it
16
- # unchanged if can't be converted into a valid number.
17
- module NumberHelper
18
-
19
- # Raised when argument +number+ param given to the helpers is invalid and
20
- # the option :raise is set to +true+.
21
- class InvalidNumberError < StandardError
22
- attr_accessor :number
23
- def initialize(number)
24
- @number = number
25
- end
26
- end
27
-
28
- # Formats a +number+ into a US phone number (e.g., (555)
29
- # 123-9876). You can customize the format in the +options+ hash.
30
- #
31
- # ==== Options
32
- #
33
- # * <tt>:area_code</tt> - Adds parentheses around the area code.
34
- # * <tt>:delimiter</tt> - Specifies the delimiter to use
35
- # (defaults to "-").
36
- # * <tt>:extension</tt> - Specifies an extension to add to the
37
- # end of the generated number.
38
- # * <tt>:country_code</tt> - Sets the country code for the phone
39
- # number.
40
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
41
- # the argument is invalid.
42
- #
43
- # ==== Examples
44
- #
45
- # number_to_phone(5551234) # => 555-1234
46
- # number_to_phone("5551234") # => 555-1234
47
- # number_to_phone(1235551234) # => 123-555-1234
48
- # number_to_phone(1235551234, area_code: true) # => (123) 555-1234
49
- # number_to_phone(1235551234, delimiter: " ") # => 123 555 1234
50
- # number_to_phone(1235551234, area_code: true, extension: 555) # => (123) 555-1234 x 555
51
- # number_to_phone(1235551234, country_code: 1) # => +1-123-555-1234
52
- # number_to_phone("123a456") # => 123a456
53
- # number_to_phone("1234a567", raise: true) # => InvalidNumberError
54
- #
55
- # number_to_phone(1235551234, country_code: 1, extension: 1343, delimiter: ".")
56
- # # => +1.123.555.1234 x 1343
57
- def number_to_phone(number, options = {})
58
- return unless number
59
- options = options.symbolize_keys
60
-
61
- parse_float(number, true) if options.delete(:raise)
62
- ERB::Util.html_escape(ActiveSupport::NumberHelper.number_to_phone(number, options))
63
- end
64
-
65
- # Formats a +number+ into a currency string (e.g., $13.65). You
66
- # can customize the format in the +options+ hash.
67
- #
68
- # ==== Options
69
- #
70
- # * <tt>:locale</tt> - Sets the locale to be used for formatting
71
- # (defaults to current locale).
72
- # * <tt>:precision</tt> - Sets the level of precision (defaults
73
- # to 2).
74
- # * <tt>:unit</tt> - Sets the denomination of the currency
75
- # (defaults to "$").
76
- # * <tt>:separator</tt> - Sets the separator between the units
77
- # (defaults to ".").
78
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
79
- # to ",").
80
- # * <tt>:format</tt> - Sets the format for non-negative numbers
81
- # (defaults to "%u%n"). Fields are <tt>%u</tt> for the
82
- # currency, and <tt>%n</tt> for the number.
83
- # * <tt>:negative_format</tt> - Sets the format for negative
84
- # numbers (defaults to prepending an hyphen to the formatted
85
- # number given by <tt>:format</tt>). Accepts the same fields
86
- # than <tt>:format</tt>, except <tt>%n</tt> is here the
87
- # absolute value of the number.
88
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
89
- # the argument is invalid.
90
- #
91
- # ==== Examples
92
- #
93
- # number_to_currency(1234567890.50) # => $1,234,567,890.50
94
- # number_to_currency(1234567890.506) # => $1,234,567,890.51
95
- # number_to_currency(1234567890.506, precision: 3) # => $1,234,567,890.506
96
- # number_to_currency(1234567890.506, locale: :fr) # => 1 234 567 890,51 €
97
- # number_to_currency("123a456") # => $123a456
98
- #
99
- # number_to_currency("123a456", raise: true) # => InvalidNumberError
100
- #
101
- # number_to_currency(-1234567890.50, negative_format: "(%u%n)")
102
- # # => ($1,234,567,890.50)
103
- # number_to_currency(1234567890.50, unit: "&pound;", separator: ",", delimiter: "")
104
- # # => &pound;1234567890,50
105
- # number_to_currency(1234567890.50, unit: "&pound;", separator: ",", delimiter: "", format: "%n %u")
106
- # # => 1234567890,50 &pound;
107
- def number_to_currency(number, options = {})
108
- return unless number
109
- options = escape_unsafe_delimiters_and_separators(options.symbolize_keys)
110
-
111
- wrap_with_output_safety_handling(number, options.delete(:raise)) {
112
- ActiveSupport::NumberHelper.number_to_currency(number, options)
113
- }
114
- end
115
-
116
- # Formats a +number+ as a percentage string (e.g., 65%). You can
117
- # customize the format in the +options+ hash.
118
- #
119
- # ==== Options
120
- #
121
- # * <tt>:locale</tt> - Sets the locale to be used for formatting
122
- # (defaults to current locale).
123
- # * <tt>:precision</tt> - Sets the precision of the number
124
- # (defaults to 3).
125
- # * <tt>:significant</tt> - If +true+, precision will be the #
126
- # of significant_digits. If +false+, the # of fractional
127
- # digits (defaults to +false+).
128
- # * <tt>:separator</tt> - Sets the separator between the
129
- # fractional and integer digits (defaults to ".").
130
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
131
- # to "").
132
- # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
133
- # insignificant zeros after the decimal separator (defaults to
134
- # +false+).
135
- # * <tt>:format</tt> - Specifies the format of the percentage
136
- # string The number field is <tt>%n</tt> (defaults to "%n%").
137
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
138
- # the argument is invalid.
139
- #
140
- # ==== Examples
141
- #
142
- # number_to_percentage(100) # => 100.000%
143
- # number_to_percentage("98") # => 98.000%
144
- # number_to_percentage(100, precision: 0) # => 100%
145
- # number_to_percentage(1000, delimiter: '.', separator: ',') # => 1.000,000%
146
- # number_to_percentage(302.24398923423, precision: 5) # => 302.24399%
147
- # number_to_percentage(1000, locale: :fr) # => 1 000,000%
148
- # number_to_percentage("98a") # => 98a%
149
- # number_to_percentage(100, format: "%n %") # => 100 %
150
- #
151
- # number_to_percentage("98a", raise: true) # => InvalidNumberError
152
- def number_to_percentage(number, options = {})
153
- return unless number
154
- options = escape_unsafe_delimiters_and_separators(options.symbolize_keys)
155
-
156
- wrap_with_output_safety_handling(number, options.delete(:raise)) {
157
- ActiveSupport::NumberHelper.number_to_percentage(number, options)
158
- }
159
- end
160
-
161
- # Formats a +number+ with grouped thousands using +delimiter+
162
- # (e.g., 12,324). You can customize the format in the +options+
163
- # hash.
164
- #
165
- # ==== Options
166
- #
167
- # * <tt>:locale</tt> - Sets the locale to be used for formatting
168
- # (defaults to current locale).
169
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
170
- # to ",").
171
- # * <tt>:separator</tt> - Sets the separator between the
172
- # fractional and integer digits (defaults to ".").
173
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
174
- # the argument is invalid.
175
- #
176
- # ==== Examples
177
- #
178
- # number_with_delimiter(12345678) # => 12,345,678
179
- # number_with_delimiter("123456") # => 123,456
180
- # number_with_delimiter(12345678.05) # => 12,345,678.05
181
- # number_with_delimiter(12345678, delimiter: ".") # => 12.345.678
182
- # number_with_delimiter(12345678, delimiter: ",") # => 12,345,678
183
- # number_with_delimiter(12345678.05, separator: " ") # => 12,345,678 05
184
- # number_with_delimiter(12345678.05, locale: :fr) # => 12 345 678,05
185
- # number_with_delimiter("112a") # => 112a
186
- # number_with_delimiter(98765432.98, delimiter: " ", separator: ",")
187
- # # => 98 765 432,98
188
- #
189
- # number_with_delimiter("112a", raise: true) # => raise InvalidNumberError
190
- def number_with_delimiter(number, options = {})
191
- options = escape_unsafe_delimiters_and_separators(options.symbolize_keys)
192
-
193
- wrap_with_output_safety_handling(number, options.delete(:raise)) {
194
- ActiveSupport::NumberHelper.number_to_delimited(number, options)
195
- }
196
- end
197
-
198
- # Formats a +number+ with the specified level of
199
- # <tt>:precision</tt> (e.g., 112.32 has a precision of 2 if
200
- # +:significant+ is +false+, and 5 if +:significant+ is +true+).
201
- # You can customize the format in the +options+ hash.
202
- #
203
- # ==== Options
204
- #
205
- # * <tt>:locale</tt> - Sets the locale to be used for formatting
206
- # (defaults to current locale).
207
- # * <tt>:precision</tt> - Sets the precision of the number
208
- # (defaults to 3).
209
- # * <tt>:significant</tt> - If +true+, precision will be the #
210
- # of significant_digits. If +false+, the # of fractional
211
- # digits (defaults to +false+).
212
- # * <tt>:separator</tt> - Sets the separator between the
213
- # fractional and integer digits (defaults to ".").
214
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
215
- # to "").
216
- # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
217
- # insignificant zeros after the decimal separator (defaults to
218
- # +false+).
219
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
220
- # the argument is invalid.
221
- #
222
- # ==== Examples
223
- #
224
- # number_with_precision(111.2345) # => 111.235
225
- # number_with_precision(111.2345, precision: 2) # => 111.23
226
- # number_with_precision(13, precision: 5) # => 13.00000
227
- # number_with_precision(389.32314, precision: 0) # => 389
228
- # number_with_precision(111.2345, significant: true) # => 111
229
- # number_with_precision(111.2345, precision: 1, significant: true) # => 100
230
- # number_with_precision(13, precision: 5, significant: true) # => 13.000
231
- # number_with_precision(111.234, locale: :fr) # => 111,234
232
- #
233
- # number_with_precision(13, precision: 5, significant: true, strip_insignificant_zeros: true)
234
- # # => 13
235
- #
236
- # number_with_precision(389.32314, precision: 4, significant: true) # => 389.3
237
- # number_with_precision(1111.2345, precision: 2, separator: ',', delimiter: '.')
238
- # # => 1.111,23
239
- def number_with_precision(number, options = {})
240
- options = escape_unsafe_delimiters_and_separators(options.symbolize_keys)
241
-
242
- wrap_with_output_safety_handling(number, options.delete(:raise)) {
243
- ActiveSupport::NumberHelper.number_to_rounded(number, options)
244
- }
245
- end
246
-
247
- # Formats the bytes in +number+ into a more understandable
248
- # representation (e.g., giving it 1500 yields 1.5 KB). This
249
- # method is useful for reporting file sizes to users. You can
250
- # customize the format in the +options+ hash.
251
- #
252
- # See <tt>number_to_human</tt> if you want to pretty-print a
253
- # generic number.
254
- #
255
- # ==== Options
256
- #
257
- # * <tt>:locale</tt> - Sets the locale to be used for formatting
258
- # (defaults to current locale).
259
- # * <tt>:precision</tt> - Sets the precision of the number
260
- # (defaults to 3).
261
- # * <tt>:significant</tt> - If +true+, precision will be the #
262
- # of significant_digits. If +false+, the # of fractional
263
- # digits (defaults to +true+)
264
- # * <tt>:separator</tt> - Sets the separator between the
265
- # fractional and integer digits (defaults to ".").
266
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
267
- # to "").
268
- # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
269
- # insignificant zeros after the decimal separator (defaults to
270
- # +true+)
271
- # * <tt>:prefix</tt> - If +:si+ formats the number using the SI
272
- # prefix (defaults to :binary)
273
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
274
- # the argument is invalid.
275
- #
276
- # ==== Examples
277
- #
278
- # number_to_human_size(123) # => 123 Bytes
279
- # number_to_human_size(1234) # => 1.21 KB
280
- # number_to_human_size(12345) # => 12.1 KB
281
- # number_to_human_size(1234567) # => 1.18 MB
282
- # number_to_human_size(1234567890) # => 1.15 GB
283
- # number_to_human_size(1234567890123) # => 1.12 TB
284
- # number_to_human_size(1234567, precision: 2) # => 1.2 MB
285
- # number_to_human_size(483989, precision: 2) # => 470 KB
286
- # number_to_human_size(1234567, precision: 2, separator: ',') # => 1,2 MB
287
- #
288
- # Non-significant zeros after the fractional separator are
289
- # stripped out by default (set
290
- # <tt>:strip_insignificant_zeros</tt> to +false+ to change
291
- # that):
292
- #
293
- # number_to_human_size(1234567890123, precision: 5) # => "1.1229 TB"
294
- # number_to_human_size(524288000, precision: 5) # => "500 MB"
295
- def number_to_human_size(number, options = {})
296
- options = escape_unsafe_delimiters_and_separators(options.symbolize_keys)
297
-
298
- wrap_with_output_safety_handling(number, options.delete(:raise)) {
299
- ActiveSupport::NumberHelper.number_to_human_size(number, options)
300
- }
301
- end
302
-
303
- # Pretty prints (formats and approximates) a number in a way it
304
- # is more readable by humans (eg.: 1200000000 becomes "1.2
305
- # Billion"). This is useful for numbers that can get very large
306
- # (and too hard to read).
307
- #
308
- # See <tt>number_to_human_size</tt> if you want to print a file
309
- # size.
310
- #
311
- # You can also define you own unit-quantifier names if you want
312
- # to use other decimal units (eg.: 1500 becomes "1.5
313
- # kilometers", 0.150 becomes "150 milliliters", etc). You may
314
- # define a wide range of unit quantifiers, even fractional ones
315
- # (centi, deci, mili, etc).
316
- #
317
- # ==== Options
318
- #
319
- # * <tt>:locale</tt> - Sets the locale to be used for formatting
320
- # (defaults to current locale).
321
- # * <tt>:precision</tt> - Sets the precision of the number
322
- # (defaults to 3).
323
- # * <tt>:significant</tt> - If +true+, precision will be the #
324
- # of significant_digits. If +false+, the # of fractional
325
- # digits (defaults to +true+)
326
- # * <tt>:separator</tt> - Sets the separator between the
327
- # fractional and integer digits (defaults to ".").
328
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
329
- # to "").
330
- # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
331
- # insignificant zeros after the decimal separator (defaults to
332
- # +true+)
333
- # * <tt>:units</tt> - A Hash of unit quantifier names. Or a
334
- # string containing an i18n scope where to find this hash. It
335
- # might have the following keys:
336
- # * *integers*: <tt>:unit</tt>, <tt>:ten</tt>,
337
- # *<tt>:hundred</tt>, <tt>:thousand</tt>, <tt>:million</tt>,
338
- # *<tt>:billion</tt>, <tt>:trillion</tt>,
339
- # *<tt>:quadrillion</tt>
340
- # * *fractionals*: <tt>:deci</tt>, <tt>:centi</tt>,
341
- # *<tt>:mili</tt>, <tt>:micro</tt>, <tt>:nano</tt>,
342
- # *<tt>:pico</tt>, <tt>:femto</tt>
343
- # * <tt>:format</tt> - Sets the format of the output string
344
- # (defaults to "%n %u"). The field types are:
345
- # * %u - The quantifier (ex.: 'thousand')
346
- # * %n - The number
347
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
348
- # the argument is invalid.
349
- #
350
- # ==== Examples
351
- #
352
- # number_to_human(123) # => "123"
353
- # number_to_human(1234) # => "1.23 Thousand"
354
- # number_to_human(12345) # => "12.3 Thousand"
355
- # number_to_human(1234567) # => "1.23 Million"
356
- # number_to_human(1234567890) # => "1.23 Billion"
357
- # number_to_human(1234567890123) # => "1.23 Trillion"
358
- # number_to_human(1234567890123456) # => "1.23 Quadrillion"
359
- # number_to_human(1234567890123456789) # => "1230 Quadrillion"
360
- # number_to_human(489939, precision: 2) # => "490 Thousand"
361
- # number_to_human(489939, precision: 4) # => "489.9 Thousand"
362
- # number_to_human(1234567, precision: 4,
363
- # significant: false) # => "1.2346 Million"
364
- # number_to_human(1234567, precision: 1,
365
- # separator: ',',
366
- # significant: false) # => "1,2 Million"
367
- #
368
- # Non-significant zeros after the decimal separator are stripped
369
- # out by default (set <tt>:strip_insignificant_zeros</tt> to
370
- # +false+ to change that):
371
- # number_to_human(12345012345, significant_digits: 6) # => "12.345 Billion"
372
- # number_to_human(500000000, precision: 5) # => "500 Million"
373
- #
374
- # ==== Custom Unit Quantifiers
375
- #
376
- # You can also use your own custom unit quantifiers:
377
- # number_to_human(500000, units: {unit: "ml", thousand: "lt"}) # => "500 lt"
378
- #
379
- # If in your I18n locale you have:
380
- # distance:
381
- # centi:
382
- # one: "centimeter"
383
- # other: "centimeters"
384
- # unit:
385
- # one: "meter"
386
- # other: "meters"
387
- # thousand:
388
- # one: "kilometer"
389
- # other: "kilometers"
390
- # billion: "gazillion-distance"
391
- #
392
- # Then you could do:
393
- #
394
- # number_to_human(543934, units: :distance) # => "544 kilometers"
395
- # number_to_human(54393498, units: :distance) # => "54400 kilometers"
396
- # number_to_human(54393498000, units: :distance) # => "54.4 gazillion-distance"
397
- # number_to_human(343, units: :distance, precision: 1) # => "300 meters"
398
- # number_to_human(1, units: :distance) # => "1 meter"
399
- # number_to_human(0.34, units: :distance) # => "34 centimeters"
400
- #
401
- def number_to_human(number, options = {})
402
- options = escape_unsafe_delimiters_and_separators(options.symbolize_keys)
403
-
404
- wrap_with_output_safety_handling(number, options.delete(:raise)) {
405
- ActiveSupport::NumberHelper.number_to_human(number, options)
406
- }
407
- end
408
-
409
- private
410
-
411
- def escape_unsafe_delimiters_and_separators(options)
412
- options[:separator] = ERB::Util.html_escape(options[:separator]) if options[:separator] && !options[:separator].html_safe?
413
- options[:delimiter] = ERB::Util.html_escape(options[:delimiter]) if options[:delimiter] && !options[:delimiter].html_safe?
414
- options
415
- end
416
-
417
- def wrap_with_output_safety_handling(number, raise_on_invalid, &block)
418
- valid_float = valid_float?(number)
419
- raise InvalidNumberError, number if raise_on_invalid && !valid_float
420
-
421
- formatted_number = yield
422
-
423
- if valid_float || number.html_safe?
424
- formatted_number.html_safe
425
- else
426
- formatted_number
427
- end
428
- end
429
-
430
- def valid_float?(number)
431
- !parse_float(number, false).nil?
432
- end
433
-
434
- def parse_float(number, raise_error)
435
- Float(number)
436
- rescue ArgumentError, TypeError
437
- raise InvalidNumberError, number if raise_error
438
- end
439
- end
440
- end
441
- end
@@ -1,38 +0,0 @@
1
- require 'active_support/core_ext/string/output_safety'
2
-
3
- module ActionView #:nodoc:
4
- # = Action View Raw Output Helper
5
- module Helpers #:nodoc:
6
- module OutputSafetyHelper
7
- # This method outputs without escaping a string. Since escaping tags is
8
- # now default, this can be used when you don't want Rails to automatically
9
- # escape tags. This is not recommended if the data is coming from the user's
10
- # input.
11
- #
12
- # For example:
13
- #
14
- # raw @user.name
15
- # # => 'Jimmy <alert>Tables</alert>'
16
- def raw(stringish)
17
- stringish.to_s.html_safe
18
- end
19
-
20
- # This method returns a html safe string similar to what <tt>Array#join</tt>
21
- # would return. All items in the array, including the supplied separator, are
22
- # html escaped unless they are html safe, and the returned string is marked
23
- # as html safe.
24
- #
25
- # safe_join(["<p>foo</p>".html_safe, "<p>bar</p>"], "<br />")
26
- # # => "<p>foo</p>&lt;br /&gt;&lt;p&gt;bar&lt;/p&gt;"
27
- #
28
- # safe_join(["<p>foo</p>".html_safe, "<p>bar</p>".html_safe], "<br />".html_safe)
29
- # # => "<p>foo</p><br /><p>bar</p>"
30
- #
31
- def safe_join(array, sep=$,)
32
- sep = ERB::Util.html_escape(sep)
33
-
34
- array.map { |i| ERB::Util.html_escape(i) }.join(sep).html_safe
35
- end
36
- end
37
- end
38
- end