actionpack 3.2.19 → 4.2.11.3

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 (244) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +412 -503
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +11 -294
  5. data/lib/abstract_controller/asset_paths.rb +2 -2
  6. data/lib/abstract_controller/base.rb +52 -18
  7. data/lib/abstract_controller/callbacks.rb +87 -89
  8. data/lib/abstract_controller/collector.rb +17 -3
  9. data/lib/abstract_controller/helpers.rb +41 -14
  10. data/lib/abstract_controller/logger.rb +1 -2
  11. data/lib/abstract_controller/railties/routes_helpers.rb +3 -3
  12. data/lib/abstract_controller/rendering.rb +65 -118
  13. data/lib/abstract_controller/translation.rb +16 -1
  14. data/lib/abstract_controller/url_for.rb +7 -7
  15. data/lib/abstract_controller.rb +2 -10
  16. data/lib/action_controller/base.rb +61 -28
  17. data/lib/action_controller/caching/fragments.rb +30 -54
  18. data/lib/action_controller/caching.rb +38 -35
  19. data/lib/action_controller/log_subscriber.rb +35 -18
  20. data/lib/action_controller/metal/conditional_get.rb +103 -34
  21. data/lib/action_controller/metal/data_streaming.rb +20 -26
  22. data/lib/action_controller/metal/etag_with_template_digest.rb +50 -0
  23. data/lib/action_controller/metal/exceptions.rb +19 -6
  24. data/lib/action_controller/metal/flash.rb +41 -9
  25. data/lib/action_controller/metal/force_ssl.rb +70 -12
  26. data/lib/action_controller/metal/head.rb +30 -7
  27. data/lib/action_controller/metal/helpers.rb +11 -11
  28. data/lib/action_controller/metal/hide_actions.rb +0 -1
  29. data/lib/action_controller/metal/http_authentication.rb +140 -94
  30. data/lib/action_controller/metal/implicit_render.rb +1 -1
  31. data/lib/action_controller/metal/instrumentation.rb +11 -7
  32. data/lib/action_controller/metal/live.rb +328 -0
  33. data/lib/action_controller/metal/mime_responds.rb +161 -152
  34. data/lib/action_controller/metal/params_wrapper.rb +126 -81
  35. data/lib/action_controller/metal/rack_delegation.rb +10 -4
  36. data/lib/action_controller/metal/redirecting.rb +44 -41
  37. data/lib/action_controller/metal/renderers.rb +48 -19
  38. data/lib/action_controller/metal/rendering.rb +46 -11
  39. data/lib/action_controller/metal/request_forgery_protection.rb +250 -29
  40. data/lib/action_controller/metal/streaming.rb +30 -38
  41. data/lib/action_controller/metal/strong_parameters.rb +669 -0
  42. data/lib/action_controller/metal/testing.rb +12 -18
  43. data/lib/action_controller/metal/url_for.rb +31 -29
  44. data/lib/action_controller/metal.rb +31 -40
  45. data/lib/action_controller/model_naming.rb +12 -0
  46. data/lib/action_controller/railtie.rb +38 -18
  47. data/lib/action_controller/railties/helpers.rb +22 -0
  48. data/lib/action_controller/test_case.rb +359 -173
  49. data/lib/action_controller.rb +9 -16
  50. data/lib/action_dispatch/http/cache.rb +64 -11
  51. data/lib/action_dispatch/http/filter_parameters.rb +20 -10
  52. data/lib/action_dispatch/http/filter_redirect.rb +38 -0
  53. data/lib/action_dispatch/http/headers.rb +85 -17
  54. data/lib/action_dispatch/http/mime_negotiation.rb +55 -5
  55. data/lib/action_dispatch/http/mime_type.rb +167 -114
  56. data/lib/action_dispatch/http/mime_types.rb +2 -1
  57. data/lib/action_dispatch/http/parameter_filter.rb +44 -46
  58. data/lib/action_dispatch/http/parameters.rb +30 -46
  59. data/lib/action_dispatch/http/rack_cache.rb +2 -3
  60. data/lib/action_dispatch/http/request.rb +108 -45
  61. data/lib/action_dispatch/http/response.rb +247 -48
  62. data/lib/action_dispatch/http/upload.rb +60 -29
  63. data/lib/action_dispatch/http/url.rb +135 -45
  64. data/lib/action_dispatch/journey/backwards.rb +5 -0
  65. data/lib/action_dispatch/journey/formatter.rb +166 -0
  66. data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
  67. data/lib/action_dispatch/journey/gtg/simulator.rb +47 -0
  68. data/lib/action_dispatch/journey/gtg/transition_table.rb +157 -0
  69. data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
  70. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  71. data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
  72. data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
  73. data/lib/action_dispatch/journey/nodes/node.rb +128 -0
  74. data/lib/action_dispatch/journey/parser.rb +198 -0
  75. data/lib/action_dispatch/journey/parser.y +49 -0
  76. data/lib/action_dispatch/journey/parser_extras.rb +23 -0
  77. data/lib/action_dispatch/journey/path/pattern.rb +193 -0
  78. data/lib/action_dispatch/journey/route.rb +125 -0
  79. data/lib/action_dispatch/journey/router/strexp.rb +27 -0
  80. data/lib/action_dispatch/journey/router/utils.rb +93 -0
  81. data/lib/action_dispatch/journey/router.rb +144 -0
  82. data/lib/action_dispatch/journey/routes.rb +80 -0
  83. data/lib/action_dispatch/journey/scanner.rb +61 -0
  84. data/lib/action_dispatch/journey/visitors.rb +221 -0
  85. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  86. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  87. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  88. data/lib/action_dispatch/journey.rb +5 -0
  89. data/lib/action_dispatch/middleware/callbacks.rb +16 -11
  90. data/lib/action_dispatch/middleware/cookies.rb +346 -125
  91. data/lib/action_dispatch/middleware/debug_exceptions.rb +52 -24
  92. data/lib/action_dispatch/middleware/exception_wrapper.rb +75 -9
  93. data/lib/action_dispatch/middleware/flash.rb +85 -72
  94. data/lib/action_dispatch/middleware/params_parser.rb +16 -31
  95. data/lib/action_dispatch/middleware/public_exceptions.rb +39 -14
  96. data/lib/action_dispatch/middleware/reloader.rb +16 -7
  97. data/lib/action_dispatch/middleware/remote_ip.rb +132 -40
  98. data/lib/action_dispatch/middleware/request_id.rb +3 -7
  99. data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
  100. data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
  101. data/lib/action_dispatch/middleware/session/cookie_store.rb +84 -29
  102. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
  103. data/lib/action_dispatch/middleware/show_exceptions.rb +15 -44
  104. data/lib/action_dispatch/middleware/ssl.rb +72 -0
  105. data/lib/action_dispatch/middleware/stack.rb +6 -1
  106. data/lib/action_dispatch/middleware/static.rb +80 -23
  107. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +34 -0
  108. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  109. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +27 -0
  110. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
  111. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  112. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +16 -0
  113. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  114. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +133 -5
  115. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  116. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  117. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  121. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  122. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  123. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  124. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +200 -0
  125. data/lib/action_dispatch/railtie.rb +19 -6
  126. data/lib/action_dispatch/request/session.rb +193 -0
  127. data/lib/action_dispatch/request/utils.rb +35 -0
  128. data/lib/action_dispatch/routing/endpoint.rb +10 -0
  129. data/lib/action_dispatch/routing/inspector.rb +234 -0
  130. data/lib/action_dispatch/routing/mapper.rb +897 -436
  131. data/lib/action_dispatch/routing/polymorphic_routes.rb +213 -92
  132. data/lib/action_dispatch/routing/redirection.rb +97 -37
  133. data/lib/action_dispatch/routing/route_set.rb +432 -239
  134. data/lib/action_dispatch/routing/routes_proxy.rb +7 -4
  135. data/lib/action_dispatch/routing/url_for.rb +63 -34
  136. data/lib/action_dispatch/routing.rb +57 -89
  137. data/lib/action_dispatch/testing/assertions/dom.rb +2 -36
  138. data/lib/action_dispatch/testing/assertions/response.rb +24 -38
  139. data/lib/action_dispatch/testing/assertions/routing.rb +55 -54
  140. data/lib/action_dispatch/testing/assertions/selector.rb +2 -434
  141. data/lib/action_dispatch/testing/assertions/tag.rb +2 -137
  142. data/lib/action_dispatch/testing/assertions.rb +11 -7
  143. data/lib/action_dispatch/testing/integration.rb +88 -72
  144. data/lib/action_dispatch/testing/test_process.rb +9 -6
  145. data/lib/action_dispatch/testing/test_request.rb +13 -9
  146. data/lib/action_dispatch/testing/test_response.rb +1 -5
  147. data/lib/action_dispatch.rb +24 -21
  148. data/lib/action_pack/gem_version.rb +15 -0
  149. data/lib/action_pack/version.rb +5 -7
  150. data/lib/action_pack.rb +1 -1
  151. metadata +181 -292
  152. data/lib/abstract_controller/layouts.rb +0 -423
  153. data/lib/abstract_controller/view_paths.rb +0 -96
  154. data/lib/action_controller/caching/actions.rb +0 -185
  155. data/lib/action_controller/caching/pages.rb +0 -187
  156. data/lib/action_controller/caching/sweeping.rb +0 -97
  157. data/lib/action_controller/deprecated/integration_test.rb +0 -2
  158. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  159. data/lib/action_controller/deprecated.rb +0 -3
  160. data/lib/action_controller/metal/compatibility.rb +0 -65
  161. data/lib/action_controller/metal/responder.rb +0 -286
  162. data/lib/action_controller/metal/session_management.rb +0 -14
  163. data/lib/action_controller/railties/paths.rb +0 -25
  164. data/lib/action_controller/record_identifier.rb +0 -85
  165. data/lib/action_controller/vendor/html-scanner/html/document.rb +0 -68
  166. data/lib/action_controller/vendor/html-scanner/html/node.rb +0 -532
  167. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +0 -177
  168. data/lib/action_controller/vendor/html-scanner/html/selector.rb +0 -830
  169. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +0 -107
  170. data/lib/action_controller/vendor/html-scanner/html/version.rb +0 -11
  171. data/lib/action_controller/vendor/html-scanner.rb +0 -20
  172. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  173. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  174. data/lib/action_dispatch/middleware/head.rb +0 -18
  175. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  176. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +0 -31
  177. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +0 -26
  178. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +0 -10
  179. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +0 -2
  180. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +0 -15
  181. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +0 -17
  182. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +0 -2
  183. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  184. data/lib/action_view/asset_paths.rb +0 -142
  185. data/lib/action_view/base.rb +0 -220
  186. data/lib/action_view/buffers.rb +0 -43
  187. data/lib/action_view/context.rb +0 -36
  188. data/lib/action_view/flows.rb +0 -79
  189. data/lib/action_view/helpers/active_model_helper.rb +0 -50
  190. data/lib/action_view/helpers/asset_paths.rb +0 -7
  191. data/lib/action_view/helpers/asset_tag_helper.rb +0 -457
  192. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  193. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  194. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  195. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  196. data/lib/action_view/helpers/atom_feed_helper.rb +0 -200
  197. data/lib/action_view/helpers/cache_helper.rb +0 -64
  198. data/lib/action_view/helpers/capture_helper.rb +0 -203
  199. data/lib/action_view/helpers/controller_helper.rb +0 -25
  200. data/lib/action_view/helpers/csrf_helper.rb +0 -32
  201. data/lib/action_view/helpers/date_helper.rb +0 -1062
  202. data/lib/action_view/helpers/debug_helper.rb +0 -40
  203. data/lib/action_view/helpers/form_helper.rb +0 -1486
  204. data/lib/action_view/helpers/form_options_helper.rb +0 -658
  205. data/lib/action_view/helpers/form_tag_helper.rb +0 -685
  206. data/lib/action_view/helpers/javascript_helper.rb +0 -110
  207. data/lib/action_view/helpers/number_helper.rb +0 -622
  208. data/lib/action_view/helpers/output_safety_helper.rb +0 -38
  209. data/lib/action_view/helpers/record_tag_helper.rb +0 -111
  210. data/lib/action_view/helpers/rendering_helper.rb +0 -90
  211. data/lib/action_view/helpers/sanitize_helper.rb +0 -259
  212. data/lib/action_view/helpers/tag_helper.rb +0 -160
  213. data/lib/action_view/helpers/text_helper.rb +0 -426
  214. data/lib/action_view/helpers/translation_helper.rb +0 -91
  215. data/lib/action_view/helpers/url_helper.rb +0 -693
  216. data/lib/action_view/helpers.rb +0 -60
  217. data/lib/action_view/locale/en.yml +0 -160
  218. data/lib/action_view/log_subscriber.rb +0 -28
  219. data/lib/action_view/lookup_context.rb +0 -254
  220. data/lib/action_view/path_set.rb +0 -89
  221. data/lib/action_view/railtie.rb +0 -55
  222. data/lib/action_view/renderer/abstract_renderer.rb +0 -41
  223. data/lib/action_view/renderer/partial_renderer.rb +0 -415
  224. data/lib/action_view/renderer/renderer.rb +0 -54
  225. data/lib/action_view/renderer/streaming_template_renderer.rb +0 -106
  226. data/lib/action_view/renderer/template_renderer.rb +0 -94
  227. data/lib/action_view/template/error.rb +0 -128
  228. data/lib/action_view/template/handlers/builder.rb +0 -26
  229. data/lib/action_view/template/handlers/erb.rb +0 -125
  230. data/lib/action_view/template/handlers.rb +0 -50
  231. data/lib/action_view/template/resolver.rb +0 -272
  232. data/lib/action_view/template/text.rb +0 -30
  233. data/lib/action_view/template.rb +0 -337
  234. data/lib/action_view/test_case.rb +0 -245
  235. data/lib/action_view/testing/resolvers.rb +0 -50
  236. data/lib/action_view.rb +0 -84
  237. data/lib/sprockets/assets.rake +0 -99
  238. data/lib/sprockets/bootstrap.rb +0 -37
  239. data/lib/sprockets/compressors.rb +0 -83
  240. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  241. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  242. data/lib/sprockets/helpers.rb +0 -6
  243. data/lib/sprockets/railtie.rb +0 -62
  244. data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,622 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require 'active_support/core_ext/hash/keys'
4
- require 'active_support/core_ext/hash/reverse_merge'
5
- require 'active_support/core_ext/big_decimal/conversions'
6
- require 'active_support/core_ext/float/rounding'
7
- require 'active_support/core_ext/object/blank'
8
- require 'active_support/core_ext/string/output_safety'
9
-
10
- module ActionView
11
- # = Action View Number Helpers
12
- module Helpers #:nodoc:
13
-
14
- # Provides methods for converting numbers into formatted strings.
15
- # Methods are provided for phone numbers, currency, percentage,
16
- # precision, positional notation, file size and pretty printing.
17
- #
18
- # Most methods expect a +number+ argument, and will return it
19
- # unchanged if can't be converted into a valid number.
20
- module NumberHelper
21
-
22
- DEFAULT_CURRENCY_VALUES = { :format => "%u%n", :negative_format => "-%u%n", :unit => "$", :separator => ".", :delimiter => ",",
23
- :precision => 2, :significant => false, :strip_insignificant_zeros => false }
24
-
25
- # Raised when argument +number+ param given to the helpers is invalid and
26
- # the option :raise is set to +true+.
27
- class InvalidNumberError < StandardError
28
- attr_accessor :number
29
- def initialize(number)
30
- @number = number
31
- end
32
- end
33
-
34
- # Formats a +number+ into a US phone number (e.g., (555)
35
- # 123-9876). You can customize the format in the +options+ hash.
36
- #
37
- # ==== Options
38
- #
39
- # * <tt>:area_code</tt> - Adds parentheses around the area code.
40
- # * <tt>:delimiter</tt> - Specifies the delimiter to use
41
- # (defaults to "-").
42
- # * <tt>:extension</tt> - Specifies an extension to add to the
43
- # end of the generated number.
44
- # * <tt>:country_code</tt> - Sets the country code for the phone
45
- # number.
46
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
47
- # the argument is invalid.
48
- #
49
- # ==== Examples
50
- #
51
- # number_to_phone(5551234) # => 555-1234
52
- # number_to_phone("5551234") # => 555-1234
53
- # number_to_phone(1235551234) # => 123-555-1234
54
- # number_to_phone(1235551234, :area_code => true) # => (123) 555-1234
55
- # number_to_phone(1235551234, :delimiter => " ") # => 123 555 1234
56
- # number_to_phone(1235551234, :area_code => true, :extension => 555) # => (123) 555-1234 x 555
57
- # number_to_phone(1235551234, :country_code => 1) # => +1-123-555-1234
58
- # number_to_phone("123a456") # => 123a456
59
- #
60
- # number_to_phone("1234a567", :raise => true) # => InvalidNumberError
61
- #
62
- # number_to_phone(1235551234, :country_code => 1, :extension => 1343, :delimiter => ".")
63
- # # => +1.123.555.1234 x 1343
64
- def number_to_phone(number, options = {})
65
- return unless number
66
-
67
- begin
68
- Float(number)
69
- rescue ArgumentError, TypeError
70
- raise InvalidNumberError, number
71
- end if options[:raise]
72
-
73
- number = number.to_s.strip
74
- options = options.symbolize_keys
75
- area_code = options[:area_code]
76
- delimiter = options[:delimiter] || "-"
77
- extension = options[:extension]
78
- country_code = options[:country_code]
79
-
80
- if area_code
81
- number.gsub!(/(\d{1,3})(\d{3})(\d{4}$)/,"(\\1) \\2#{delimiter}\\3")
82
- else
83
- number.gsub!(/(\d{0,3})(\d{3})(\d{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3")
84
- number.slice!(0, 1) if number.starts_with?(delimiter) && !delimiter.blank?
85
- end
86
-
87
- str = []
88
- str << "+#{country_code}#{delimiter}" unless country_code.blank?
89
- str << number
90
- str << " x #{extension}" unless extension.blank?
91
- ERB::Util.html_escape(str.join)
92
- end
93
-
94
- # Formats a +number+ into a currency string (e.g., $13.65). You
95
- # can customize the format in the +options+ hash.
96
- #
97
- # ==== Options
98
- #
99
- # * <tt>:locale</tt> - Sets the locale to be used for formatting
100
- # (defaults to current locale).
101
- # * <tt>:precision</tt> - Sets the level of precision (defaults
102
- # to 2).
103
- # * <tt>:unit</tt> - Sets the denomination of the currency
104
- # (defaults to "$").
105
- # * <tt>:separator</tt> - Sets the separator between the units
106
- # (defaults to ".").
107
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
108
- # to ",").
109
- # * <tt>:format</tt> - Sets the format for non-negative numbers
110
- # (defaults to "%u%n"). Fields are <tt>%u</tt> for the
111
- # currency, and <tt>%n</tt> for the number.
112
- # * <tt>:negative_format</tt> - Sets the format for negative
113
- # numbers (defaults to prepending an hyphen to the formatted
114
- # number given by <tt>:format</tt>). Accepts the same fields
115
- # than <tt>:format</tt>, except <tt>%n</tt> is here the
116
- # absolute value of the number.
117
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
118
- # the argument is invalid.
119
- #
120
- # ==== Examples
121
- #
122
- # number_to_currency(1234567890.50) # => $1,234,567,890.50
123
- # number_to_currency(1234567890.506) # => $1,234,567,890.51
124
- # number_to_currency(1234567890.506, :precision => 3) # => $1,234,567,890.506
125
- # number_to_currency(1234567890.506, :locale => :fr) # => 1 234 567 890,51 €
126
- # number_to_currency("123a456") # => $123a456
127
- #
128
- # number_to_currency("123a456", :raise => true) # => InvalidNumberError
129
- #
130
- # number_to_currency(-1234567890.50, :negative_format => "(%u%n)")
131
- # # => ($1,234,567,890.50)
132
- # number_to_currency(1234567890.50, :unit => "R$", :separator => ",", :delimiter => "")
133
- # # => R$1234567890,50
134
- # number_to_currency(1234567890.50, :unit => "R$", :separator => ",", :delimiter => "", :format => "%n %u")
135
- # # => 1234567890,50 R$
136
- def number_to_currency(number, options = {})
137
- return unless number
138
-
139
- options.symbolize_keys!
140
-
141
- options[:delimiter] = ERB::Util.html_escape(options[:delimiter]) if options[:delimiter]
142
- options[:separator] = ERB::Util.html_escape(options[:separator]) if options[:separator]
143
- options[:format] = ERB::Util.html_escape(options[:format]) if options[:format]
144
- options[:negative_format] = ERB::Util.html_escape(options[:negative_format]) if options[:negative_format]
145
-
146
- defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
147
- currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :default => {})
148
- currency[:negative_format] ||= "-" + currency[:format] if currency[:format]
149
-
150
- defaults = DEFAULT_CURRENCY_VALUES.merge(defaults).merge!(currency)
151
- defaults[:negative_format] = "-" + options[:format] if options[:format]
152
-
153
- options = defaults.merge!(options)
154
-
155
- unit = options.delete(:unit)
156
- format = options.delete(:format)
157
-
158
- if number.to_f < 0
159
- format = options.delete(:negative_format)
160
- number = number.respond_to?("abs") ? number.abs : number.sub(/^-/, '')
161
- end
162
-
163
- begin
164
- value = number_with_precision(number, options.merge(:raise => true))
165
- format.gsub(/%n/, ERB::Util.html_escape(value)).gsub(/%u/, ERB::Util.html_escape(unit)).html_safe
166
- rescue InvalidNumberError => e
167
- if options[:raise]
168
- raise
169
- else
170
- formatted_number = format.gsub(/%n/, e.number).gsub(/%u/, unit)
171
- e.number.to_s.html_safe? ? formatted_number.html_safe : formatted_number
172
- end
173
- end
174
-
175
- end
176
-
177
- # Formats a +number+ as a percentage string (e.g., 65%). You can
178
- # customize the format in the +options+ hash.
179
- #
180
- # ==== Options
181
- #
182
- # * <tt>:locale</tt> - Sets the locale to be used for formatting
183
- # (defaults to current locale).
184
- # * <tt>:precision</tt> - Sets the precision of the number
185
- # (defaults to 3).
186
- # * <tt>:significant</tt> - If +true+, precision will be the #
187
- # of significant_digits. If +false+, the # of fractional
188
- # digits (defaults to +false+).
189
- # * <tt>:separator</tt> - Sets the separator between the
190
- # fractional and integer digits (defaults to ".").
191
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
192
- # to "").
193
- # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
194
- # insignificant zeros after the decimal separator (defaults to
195
- # +false+).
196
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
197
- # the argument is invalid.
198
- #
199
- # ==== Examples
200
- #
201
- # number_to_percentage(100) # => 100.000%
202
- # number_to_percentage("98") # => 98.000%
203
- # number_to_percentage(100, :precision => 0) # => 100%
204
- # number_to_percentage(1000, :delimiter => '.', :separator => ',') # => 1.000,000%
205
- # number_to_percentage(302.24398923423, :precision => 5) # => 302.24399%
206
- # number_to_percentage(1000, :locale => :fr) # => 1 000,000%
207
- # number_to_percentage("98a") # => 98a%
208
- #
209
- # number_to_percentage("98a", :raise => true) # => InvalidNumberError
210
- def number_to_percentage(number, options = {})
211
- return unless number
212
-
213
- options.symbolize_keys!
214
-
215
- options[:delimiter] = ERB::Util.html_escape(options[:delimiter]) if options[:delimiter]
216
- options[:separator] = ERB::Util.html_escape(options[:separator]) if options[:separator]
217
-
218
- defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
219
- percentage = I18n.translate(:'number.percentage.format', :locale => options[:locale], :default => {})
220
- defaults = defaults.merge(percentage)
221
-
222
- options = options.reverse_merge(defaults)
223
-
224
- begin
225
- "#{number_with_precision(number, options.merge(:raise => true))}%".html_safe
226
- rescue InvalidNumberError => e
227
- if options[:raise]
228
- raise
229
- else
230
- e.number.to_s.html_safe? ? "#{e.number}%".html_safe : "#{e.number}%"
231
- end
232
- end
233
- end
234
-
235
- # Formats a +number+ with grouped thousands using +delimiter+
236
- # (e.g., 12,324). You can customize the format in the +options+
237
- # hash.
238
- #
239
- # ==== Options
240
- #
241
- # * <tt>:locale</tt> - Sets the locale to be used for formatting
242
- # (defaults to current locale).
243
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
244
- # to ",").
245
- # * <tt>:separator</tt> - Sets the separator between the
246
- # fractional and integer digits (defaults to ".").
247
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
248
- # the argument is invalid.
249
- #
250
- # ==== Examples
251
- #
252
- # number_with_delimiter(12345678) # => 12,345,678
253
- # number_with_delimiter("123456") # => 123,456
254
- # number_with_delimiter(12345678.05) # => 12,345,678.05
255
- # number_with_delimiter(12345678, :delimiter => ".") # => 12.345.678
256
- # number_with_delimiter(12345678, :delimiter => ",") # => 12,345,678
257
- # number_with_delimiter(12345678.05, :separator => " ") # => 12,345,678 05
258
- # number_with_delimiter(12345678.05, :locale => :fr) # => 12 345 678,05
259
- # number_with_delimiter("112a") # => 112a
260
- # number_with_delimiter(98765432.98, :delimiter => " ", :separator => ",")
261
- # # => 98 765 432,98
262
- #
263
- # number_with_delimiter("112a", :raise => true) # => raise InvalidNumberError
264
- def number_with_delimiter(number, options = {})
265
- options.symbolize_keys!
266
-
267
- options[:delimiter] = ERB::Util.html_escape(options[:delimiter]) if options[:delimiter]
268
- options[:separator] = ERB::Util.html_escape(options[:separator]) if options[:separator]
269
-
270
- begin
271
- Float(number)
272
- rescue ArgumentError, TypeError
273
- if options[:raise]
274
- raise InvalidNumberError, number
275
- else
276
- return number
277
- end
278
- end
279
-
280
- defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
281
- options = options.reverse_merge(defaults)
282
-
283
- parts = number.to_s.to_str.split('.')
284
- parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
285
- parts.join(options[:separator]).html_safe
286
-
287
- end
288
-
289
- # Formats a +number+ with the specified level of
290
- # <tt>:precision</tt> (e.g., 112.32 has a precision of 2 if
291
- # +:significant+ is +false+, and 5 if +:significant+ is +true+).
292
- # You can customize the format in the +options+ hash.
293
- #
294
- # ==== Options
295
- #
296
- # * <tt>:locale</tt> - Sets the locale to be used for formatting
297
- # (defaults to current locale).
298
- # * <tt>:precision</tt> - Sets the precision of the number
299
- # (defaults to 3).
300
- # * <tt>:significant</tt> - If +true+, precision will be the #
301
- # of significant_digits. If +false+, the # of fractional
302
- # digits (defaults to +false+).
303
- # * <tt>:separator</tt> - Sets the separator between the
304
- # fractional and integer digits (defaults to ".").
305
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
306
- # to "").
307
- # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
308
- # insignificant zeros after the decimal separator (defaults to
309
- # +false+).
310
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
311
- # the argument is invalid.
312
- #
313
- # ==== Examples
314
- #
315
- # number_with_precision(111.2345) # => 111.235
316
- # number_with_precision(111.2345, :precision => 2) # => 111.23
317
- # number_with_precision(13, :precision => 5) # => 13.00000
318
- # number_with_precision(389.32314, :precision => 0) # => 389
319
- # number_with_precision(111.2345, :significant => true) # => 111
320
- # number_with_precision(111.2345, :precision => 1, :significant => true) # => 100
321
- # number_with_precision(13, :precision => 5, :significant => true) # => 13.000
322
- # number_with_precision(111.234, :locale => :fr) # => 111,234
323
- #
324
- # number_with_precision(13, :precision => 5, :significant => true, :strip_insignificant_zeros => true)
325
- # # => 13
326
- #
327
- # number_with_precision(389.32314, :precision => 4, :significant => true) # => 389.3
328
- # number_with_precision(1111.2345, :precision => 2, :separator => ',', :delimiter => '.')
329
- # # => 1.111,23
330
- def number_with_precision(number, options = {})
331
- options.symbolize_keys!
332
-
333
- number = begin
334
- Float(number)
335
- rescue ArgumentError, TypeError
336
- if options[:raise]
337
- raise InvalidNumberError, number
338
- else
339
- return number
340
- end
341
- end
342
-
343
- defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
344
- precision_defaults = I18n.translate(:'number.precision.format', :locale => options[:locale], :default => {})
345
- defaults = defaults.merge(precision_defaults)
346
-
347
- options = options.reverse_merge(defaults) # Allow the user to unset default values: Eg.: :significant => false
348
- precision = options.delete :precision
349
- significant = options.delete :significant
350
- strip_insignificant_zeros = options.delete :strip_insignificant_zeros
351
-
352
- if significant and precision > 0
353
- if number == 0
354
- digits, rounded_number = 1, 0
355
- else
356
- digits = (Math.log10(number.abs) + 1).floor
357
- rounded_number = (BigDecimal.new(number.to_s) / BigDecimal.new((10 ** (digits - precision)).to_f.to_s)).round.to_f * 10 ** (digits - precision)
358
- digits = (Math.log10(rounded_number.abs) + 1).floor # After rounding, the number of digits may have changed
359
- end
360
- precision -= digits
361
- precision = precision > 0 ? precision : 0 #don't let it be negative
362
- else
363
- rounded_number = BigDecimal.new(number.to_s).round(precision).to_f
364
- end
365
- formatted_number = number_with_delimiter("%01.#{precision}f" % rounded_number, options)
366
- if strip_insignificant_zeros
367
- escaped_separator = Regexp.escape(options[:separator])
368
- formatted_number.sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '').html_safe
369
- else
370
- formatted_number
371
- end
372
-
373
- end
374
-
375
- STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb]
376
-
377
- # Formats the bytes in +number+ into a more understandable
378
- # representation (e.g., giving it 1500 yields 1.5 KB). This
379
- # method is useful for reporting file sizes to users. You can
380
- # customize the format in the +options+ hash.
381
- #
382
- # See <tt>number_to_human</tt> if you want to pretty-print a
383
- # generic number.
384
- #
385
- # ==== Options
386
- #
387
- # * <tt>:locale</tt> - Sets the locale to be used for formatting
388
- # (defaults to current locale).
389
- # * <tt>:precision</tt> - Sets the precision of the number
390
- # (defaults to 3).
391
- # * <tt>:significant</tt> - If +true+, precision will be the #
392
- # of significant_digits. If +false+, the # of fractional
393
- # digits (defaults to +true+)
394
- # * <tt>:separator</tt> - Sets the separator between the
395
- # fractional and integer digits (defaults to ".").
396
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
397
- # to "").
398
- # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
399
- # insignificant zeros after the decimal separator (defaults to
400
- # +true+)
401
- # * <tt>:prefix</tt> - If +:si+ formats the number using the SI
402
- # prefix (defaults to :binary)
403
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
404
- # the argument is invalid.
405
- #
406
- # ==== Examples
407
- #
408
- # number_to_human_size(123) # => 123 Bytes
409
- # number_to_human_size(1234) # => 1.21 KB
410
- # number_to_human_size(12345) # => 12.1 KB
411
- # number_to_human_size(1234567) # => 1.18 MB
412
- # number_to_human_size(1234567890) # => 1.15 GB
413
- # number_to_human_size(1234567890123) # => 1.12 TB
414
- # number_to_human_size(1234567, :precision => 2) # => 1.2 MB
415
- # number_to_human_size(483989, :precision => 2) # => 470 KB
416
- # number_to_human_size(1234567, :precision => 2, :separator => ',') # => 1,2 MB
417
- #
418
- # Non-significant zeros after the fractional separator are
419
- # stripped out by default (set
420
- # <tt>:strip_insignificant_zeros</tt> to +false+ to change
421
- # that):
422
- # number_to_human_size(1234567890123, :precision => 5) # => "1.1229 TB"
423
- # number_to_human_size(524288000, :precision => 5) # => "500 MB"
424
- def number_to_human_size(number, options = {})
425
- options.symbolize_keys!
426
-
427
- number = begin
428
- Float(number)
429
- rescue ArgumentError, TypeError
430
- if options[:raise]
431
- raise InvalidNumberError, number
432
- else
433
- return number
434
- end
435
- end
436
-
437
- defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
438
- human = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {})
439
- defaults = defaults.merge(human)
440
-
441
- options = options.reverse_merge(defaults)
442
- #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
443
- options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros)
444
-
445
- storage_units_format = I18n.translate(:'number.human.storage_units.format', :locale => options[:locale], :raise => true)
446
-
447
- base = options[:prefix] == :si ? 1000 : 1024
448
-
449
- if number.to_i < base
450
- unit = I18n.translate(:'number.human.storage_units.units.byte', :locale => options[:locale], :count => number.to_i, :raise => true)
451
- storage_units_format.gsub(/%n/, number.to_i.to_s).gsub(/%u/, unit).html_safe
452
- else
453
- max_exp = STORAGE_UNITS.size - 1
454
- exponent = (Math.log(number) / Math.log(base)).to_i # Convert to base
455
- exponent = max_exp if exponent > max_exp # we need this to avoid overflow for the highest unit
456
- number /= base ** exponent
457
-
458
- unit_key = STORAGE_UNITS[exponent]
459
- unit = I18n.translate(:"number.human.storage_units.units.#{unit_key}", :locale => options[:locale], :count => number, :raise => true)
460
-
461
- formatted_number = number_with_precision(number, options)
462
- storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit).html_safe
463
- end
464
- end
465
-
466
- DECIMAL_UNITS = {0 => :unit, 1 => :ten, 2 => :hundred, 3 => :thousand, 6 => :million, 9 => :billion, 12 => :trillion, 15 => :quadrillion,
467
- -1 => :deci, -2 => :centi, -3 => :mili, -6 => :micro, -9 => :nano, -12 => :pico, -15 => :femto}
468
-
469
- # Pretty prints (formats and approximates) a number in a way it
470
- # is more readable by humans (eg.: 1200000000 becomes "1.2
471
- # Billion"). This is useful for numbers that can get very large
472
- # (and too hard to read).
473
- #
474
- # See <tt>number_to_human_size</tt> if you want to print a file
475
- # size.
476
- #
477
- # You can also define you own unit-quantifier names if you want
478
- # to use other decimal units (eg.: 1500 becomes "1.5
479
- # kilometers", 0.150 becomes "150 milliliters", etc). You may
480
- # define a wide range of unit quantifiers, even fractional ones
481
- # (centi, deci, mili, etc).
482
- #
483
- # ==== Options
484
- #
485
- # * <tt>:locale</tt> - Sets the locale to be used for formatting
486
- # (defaults to current locale).
487
- # * <tt>:precision</tt> - Sets the precision of the number
488
- # (defaults to 3).
489
- # * <tt>:significant</tt> - If +true+, precision will be the #
490
- # of significant_digits. If +false+, the # of fractional
491
- # digits (defaults to +true+)
492
- # * <tt>:separator</tt> - Sets the separator between the
493
- # fractional and integer digits (defaults to ".").
494
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
495
- # to "").
496
- # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
497
- # insignificant zeros after the decimal separator (defaults to
498
- # +true+)
499
- # * <tt>:units</tt> - A Hash of unit quantifier names. Or a
500
- # string containing an i18n scope where to find this hash. It
501
- # might have the following keys:
502
- # * *integers*: <tt>:unit</tt>, <tt>:ten</tt>,
503
- # *<tt>:hundred</tt>, <tt>:thousand</tt>, <tt>:million</tt>,
504
- # *<tt>:billion</tt>, <tt>:trillion</tt>,
505
- # *<tt>:quadrillion</tt>
506
- # * *fractionals*: <tt>:deci</tt>, <tt>:centi</tt>,
507
- # *<tt>:mili</tt>, <tt>:micro</tt>, <tt>:nano</tt>,
508
- # *<tt>:pico</tt>, <tt>:femto</tt>
509
- # * <tt>:format</tt> - Sets the format of the output string
510
- # (defaults to "%n %u"). The field types are:
511
- # * %u - The quantifier (ex.: 'thousand')
512
- # * %n - The number
513
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
514
- # the argument is invalid.
515
- #
516
- # ==== Examples
517
- #
518
- # number_to_human(123) # => "123"
519
- # number_to_human(1234) # => "1.23 Thousand"
520
- # number_to_human(12345) # => "12.3 Thousand"
521
- # number_to_human(1234567) # => "1.23 Million"
522
- # number_to_human(1234567890) # => "1.23 Billion"
523
- # number_to_human(1234567890123) # => "1.23 Trillion"
524
- # number_to_human(1234567890123456) # => "1.23 Quadrillion"
525
- # number_to_human(1234567890123456789) # => "1230 Quadrillion"
526
- # number_to_human(489939, :precision => 2) # => "490 Thousand"
527
- # number_to_human(489939, :precision => 4) # => "489.9 Thousand"
528
- # number_to_human(1234567, :precision => 4,
529
- # :significant => false) # => "1.2346 Million"
530
- # number_to_human(1234567, :precision => 1,
531
- # :separator => ',',
532
- # :significant => false) # => "1,2 Million"
533
- #
534
- # Non-significant zeros after the decimal separator are stripped
535
- # out by default (set <tt>:strip_insignificant_zeros</tt> to
536
- # +false+ to change that):
537
- # number_to_human(12345012345, :significant_digits => 6) # => "12.345 Billion"
538
- # number_to_human(500000000, :precision => 5) # => "500 Million"
539
- #
540
- # ==== Custom Unit Quantifiers
541
- #
542
- # You can also use your own custom unit quantifiers:
543
- # number_to_human(500000, :units => {:unit => "ml", :thousand => "lt"}) # => "500 lt"
544
- #
545
- # If in your I18n locale you have:
546
- # distance:
547
- # centi:
548
- # one: "centimeter"
549
- # other: "centimeters"
550
- # unit:
551
- # one: "meter"
552
- # other: "meters"
553
- # thousand:
554
- # one: "kilometer"
555
- # other: "kilometers"
556
- # billion: "gazillion-distance"
557
- #
558
- # Then you could do:
559
- #
560
- # number_to_human(543934, :units => :distance) # => "544 kilometers"
561
- # number_to_human(54393498, :units => :distance) # => "54400 kilometers"
562
- # number_to_human(54393498000, :units => :distance) # => "54.4 gazillion-distance"
563
- # number_to_human(343, :units => :distance, :precision => 1) # => "300 meters"
564
- # number_to_human(1, :units => :distance) # => "1 meter"
565
- # number_to_human(0.34, :units => :distance) # => "34 centimeters"
566
- #
567
- def number_to_human(number, options = {})
568
- options.symbolize_keys!
569
-
570
- number = begin
571
- Float(number)
572
- rescue ArgumentError, TypeError
573
- if options[:raise]
574
- raise InvalidNumberError, number
575
- else
576
- return number
577
- end
578
- end
579
-
580
- defaults = I18n.translate(:'number.format', :locale => options[:locale], :default => {})
581
- human = I18n.translate(:'number.human.format', :locale => options[:locale], :default => {})
582
- defaults = defaults.merge(human)
583
-
584
- options = options.reverse_merge(defaults)
585
- #for backwards compatibility with those that didn't add strip_insignificant_zeros to their locale files
586
- options[:strip_insignificant_zeros] = true if not options.key?(:strip_insignificant_zeros)
587
-
588
- inverted_du = DECIMAL_UNITS.invert
589
-
590
- units = options.delete :units
591
- unit_exponents = case units
592
- when Hash
593
- units = Hash[units.map { |k, v| [k, ERB::Util.html_escape(v)] }]
594
- when String, Symbol
595
- I18n.translate(:"#{units}", :locale => options[:locale], :raise => true)
596
- when nil
597
- I18n.translate(:"number.human.decimal_units.units", :locale => options[:locale], :raise => true)
598
- else
599
- raise ArgumentError, ":units must be a Hash or String translation scope."
600
- end.keys.map{|e_name| inverted_du[e_name] }.sort_by{|e| -e}
601
-
602
- number_exponent = number != 0 ? Math.log10(number.abs).floor : 0
603
- display_exponent = unit_exponents.find{ |e| number_exponent >= e } || 0
604
- number /= 10 ** display_exponent
605
-
606
- unit = case units
607
- when Hash
608
- units[DECIMAL_UNITS[display_exponent]] || ''
609
- when String, Symbol
610
- I18n.translate(:"#{units}.#{DECIMAL_UNITS[display_exponent]}", :locale => options[:locale], :count => number.to_i)
611
- else
612
- I18n.translate(:"number.human.decimal_units.units.#{DECIMAL_UNITS[display_exponent]}", :locale => options[:locale], :count => number.to_i)
613
- end
614
-
615
- decimal_format = options[:format] || I18n.translate(:'number.human.decimal_units.format', :locale => options[:locale], :default => "%n %u")
616
- formatted_number = number_with_precision(number, options)
617
- decimal_format.gsub(/%n/, formatted_number).gsub(/%u/, unit).strip.html_safe
618
- end
619
-
620
- end
621
- end
622
- 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
- def raw(stringish)
16
- stringish.to_s.html_safe
17
- end
18
-
19
- # This method returns a html safe string similar to what <tt>Array#join</tt>
20
- # would return. All items in the array, including the supplied separator, are
21
- # html escaped unless they are html safe, and the returned string is marked
22
- # as html safe.
23
- #
24
- # safe_join(["<p>foo</p>".html_safe, "<p>bar</p>"], "<br />")
25
- # # => "<p>foo</p>&lt;br /&gt;&lt;p&gt;bar&lt;/p&gt;"
26
- #
27
- # safe_join(["<p>foo</p>".html_safe, "<p>bar</p>".html_safe], "<br />".html_safe)
28
- # # => "<p>foo</p><br /><p>bar</p>"
29
- #
30
- def safe_join(array, sep=$,)
31
- sep ||= "".html_safe
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