halorgium-actionpack 3.0.pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +5179 -0
- data/MIT-LICENSE +21 -0
- data/README +409 -0
- data/lib/abstract_controller.rb +16 -0
- data/lib/abstract_controller/base.rb +158 -0
- data/lib/abstract_controller/callbacks.rb +113 -0
- data/lib/abstract_controller/exceptions.rb +12 -0
- data/lib/abstract_controller/helpers.rb +151 -0
- data/lib/abstract_controller/layouts.rb +250 -0
- data/lib/abstract_controller/localized_cache.rb +49 -0
- data/lib/abstract_controller/logger.rb +61 -0
- data/lib/abstract_controller/rendering_controller.rb +188 -0
- data/lib/action_controller.rb +72 -0
- data/lib/action_controller/base.rb +168 -0
- data/lib/action_controller/caching.rb +80 -0
- data/lib/action_controller/caching/actions.rb +163 -0
- data/lib/action_controller/caching/fragments.rb +116 -0
- data/lib/action_controller/caching/pages.rb +154 -0
- data/lib/action_controller/caching/sweeping.rb +97 -0
- data/lib/action_controller/deprecated.rb +4 -0
- data/lib/action_controller/deprecated/integration_test.rb +2 -0
- data/lib/action_controller/deprecated/performance_test.rb +1 -0
- data/lib/action_controller/dispatch/dispatcher.rb +57 -0
- data/lib/action_controller/metal.rb +129 -0
- data/lib/action_controller/metal/benchmarking.rb +73 -0
- data/lib/action_controller/metal/compatibility.rb +145 -0
- data/lib/action_controller/metal/conditional_get.rb +86 -0
- data/lib/action_controller/metal/configuration.rb +28 -0
- data/lib/action_controller/metal/cookies.rb +105 -0
- data/lib/action_controller/metal/exceptions.rb +55 -0
- data/lib/action_controller/metal/filter_parameter_logging.rb +77 -0
- data/lib/action_controller/metal/flash.rb +162 -0
- data/lib/action_controller/metal/head.rb +27 -0
- data/lib/action_controller/metal/helpers.rb +115 -0
- data/lib/action_controller/metal/hide_actions.rb +47 -0
- data/lib/action_controller/metal/http_authentication.rb +312 -0
- data/lib/action_controller/metal/layouts.rb +171 -0
- data/lib/action_controller/metal/mime_responds.rb +317 -0
- data/lib/action_controller/metal/rack_convenience.rb +27 -0
- data/lib/action_controller/metal/redirector.rb +22 -0
- data/lib/action_controller/metal/render_options.rb +103 -0
- data/lib/action_controller/metal/rendering_controller.rb +57 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +108 -0
- data/lib/action_controller/metal/rescuable.rb +13 -0
- data/lib/action_controller/metal/responder.rb +200 -0
- data/lib/action_controller/metal/session.rb +15 -0
- data/lib/action_controller/metal/session_management.rb +45 -0
- data/lib/action_controller/metal/streaming.rb +188 -0
- data/lib/action_controller/metal/testing.rb +39 -0
- data/lib/action_controller/metal/url_for.rb +41 -0
- data/lib/action_controller/metal/verification.rb +130 -0
- data/lib/action_controller/middleware.rb +38 -0
- data/lib/action_controller/notifications.rb +10 -0
- data/lib/action_controller/polymorphic_routes.rb +183 -0
- data/lib/action_controller/record_identifier.rb +91 -0
- data/lib/action_controller/testing/process.rb +111 -0
- data/lib/action_controller/testing/test_case.rb +345 -0
- data/lib/action_controller/translation.rb +13 -0
- data/lib/action_controller/url_rewriter.rb +204 -0
- data/lib/action_controller/vendor/html-scanner.rb +16 -0
- data/lib/action_controller/vendor/html-scanner/html/document.rb +68 -0
- data/lib/action_controller/vendor/html-scanner/html/node.rb +537 -0
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +176 -0
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +828 -0
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +105 -0
- data/lib/action_controller/vendor/html-scanner/html/version.rb +11 -0
- data/lib/action_dispatch.rb +70 -0
- data/lib/action_dispatch/http/headers.rb +33 -0
- data/lib/action_dispatch/http/mime_type.rb +231 -0
- data/lib/action_dispatch/http/mime_types.rb +23 -0
- data/lib/action_dispatch/http/request.rb +539 -0
- data/lib/action_dispatch/http/response.rb +290 -0
- data/lib/action_dispatch/http/status_codes.rb +42 -0
- data/lib/action_dispatch/http/utils.rb +20 -0
- data/lib/action_dispatch/middleware/callbacks.rb +50 -0
- data/lib/action_dispatch/middleware/params_parser.rb +79 -0
- data/lib/action_dispatch/middleware/rescue.rb +26 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +208 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +235 -0
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +47 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +143 -0
- data/lib/action_dispatch/middleware/stack.rb +116 -0
- data/lib/action_dispatch/middleware/static.rb +44 -0
- data/lib/action_dispatch/middleware/string_coercion.rb +29 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +24 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +26 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +10 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +29 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +2 -0
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +10 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +21 -0
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +2 -0
- data/lib/action_dispatch/routing.rb +381 -0
- data/lib/action_dispatch/routing/deprecated_mapper.rb +878 -0
- data/lib/action_dispatch/routing/mapper.rb +327 -0
- data/lib/action_dispatch/routing/route.rb +49 -0
- data/lib/action_dispatch/routing/route_set.rb +497 -0
- data/lib/action_dispatch/testing/assertions.rb +8 -0
- data/lib/action_dispatch/testing/assertions/dom.rb +35 -0
- data/lib/action_dispatch/testing/assertions/model.rb +19 -0
- data/lib/action_dispatch/testing/assertions/response.rb +145 -0
- data/lib/action_dispatch/testing/assertions/routing.rb +144 -0
- data/lib/action_dispatch/testing/assertions/selector.rb +639 -0
- data/lib/action_dispatch/testing/assertions/tag.rb +123 -0
- data/lib/action_dispatch/testing/integration.rb +504 -0
- data/lib/action_dispatch/testing/performance_test.rb +15 -0
- data/lib/action_dispatch/testing/test_request.rb +83 -0
- data/lib/action_dispatch/testing/test_response.rb +131 -0
- data/lib/action_pack.rb +24 -0
- data/lib/action_pack/version.rb +9 -0
- data/lib/action_view.rb +58 -0
- data/lib/action_view/base.rb +308 -0
- data/lib/action_view/context.rb +44 -0
- data/lib/action_view/erb/util.rb +48 -0
- data/lib/action_view/helpers.rb +62 -0
- data/lib/action_view/helpers/active_model_helper.rb +306 -0
- data/lib/action_view/helpers/ajax_helper.rb +68 -0
- data/lib/action_view/helpers/asset_tag_helper.rb +830 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +198 -0
- data/lib/action_view/helpers/cache_helper.rb +39 -0
- data/lib/action_view/helpers/capture_helper.rb +168 -0
- data/lib/action_view/helpers/date_helper.rb +988 -0
- data/lib/action_view/helpers/debug_helper.rb +38 -0
- data/lib/action_view/helpers/form_helper.rb +1102 -0
- data/lib/action_view/helpers/form_options_helper.rb +600 -0
- data/lib/action_view/helpers/form_tag_helper.rb +495 -0
- data/lib/action_view/helpers/javascript_helper.rb +208 -0
- data/lib/action_view/helpers/number_helper.rb +311 -0
- data/lib/action_view/helpers/prototype_helper.rb +1309 -0
- data/lib/action_view/helpers/raw_output_helper.rb +9 -0
- data/lib/action_view/helpers/record_identification_helper.rb +20 -0
- data/lib/action_view/helpers/record_tag_helper.rb +58 -0
- data/lib/action_view/helpers/sanitize_helper.rb +259 -0
- data/lib/action_view/helpers/scriptaculous_helper.rb +226 -0
- data/lib/action_view/helpers/tag_helper.rb +151 -0
- data/lib/action_view/helpers/text_helper.rb +594 -0
- data/lib/action_view/helpers/translation_helper.rb +39 -0
- data/lib/action_view/helpers/url_helper.rb +639 -0
- data/lib/action_view/locale/en.yml +117 -0
- data/lib/action_view/paths.rb +80 -0
- data/lib/action_view/render/partials.rb +342 -0
- data/lib/action_view/render/rendering.rb +134 -0
- data/lib/action_view/safe_buffer.rb +28 -0
- data/lib/action_view/template/error.rb +101 -0
- data/lib/action_view/template/handler.rb +36 -0
- data/lib/action_view/template/handlers.rb +52 -0
- data/lib/action_view/template/handlers/builder.rb +17 -0
- data/lib/action_view/template/handlers/erb.rb +53 -0
- data/lib/action_view/template/handlers/rjs.rb +18 -0
- data/lib/action_view/template/resolver.rb +165 -0
- data/lib/action_view/template/template.rb +131 -0
- data/lib/action_view/template/text.rb +38 -0
- data/lib/action_view/test_case.rb +163 -0
- metadata +236 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
require 'action_view/helpers/tag_helper'
|
|
2
|
+
require 'action_view/helpers/prototype_helper'
|
|
3
|
+
|
|
4
|
+
module ActionView
|
|
5
|
+
module Helpers
|
|
6
|
+
# Provides functionality for working with JavaScript in your views.
|
|
7
|
+
#
|
|
8
|
+
# == Ajax, controls and visual effects
|
|
9
|
+
#
|
|
10
|
+
# * For information on using Ajax, see
|
|
11
|
+
# ActionView::Helpers::PrototypeHelper.
|
|
12
|
+
# * For information on using controls and visual effects, see
|
|
13
|
+
# ActionView::Helpers::ScriptaculousHelper.
|
|
14
|
+
#
|
|
15
|
+
# == Including the JavaScript libraries into your pages
|
|
16
|
+
#
|
|
17
|
+
# Rails includes the Prototype JavaScript framework and the Scriptaculous
|
|
18
|
+
# JavaScript controls and visual effects library. If you wish to use
|
|
19
|
+
# these libraries and their helpers (ActionView::Helpers::PrototypeHelper
|
|
20
|
+
# and ActionView::Helpers::ScriptaculousHelper), you must do one of the
|
|
21
|
+
# following:
|
|
22
|
+
#
|
|
23
|
+
# * Use <tt><%= javascript_include_tag :defaults %></tt> in the HEAD
|
|
24
|
+
# section of your page (recommended): This function will return
|
|
25
|
+
# references to the JavaScript files created by the +rails+ command in
|
|
26
|
+
# your <tt>public/javascripts</tt> directory. Using it is recommended as
|
|
27
|
+
# the browser can then cache the libraries instead of fetching all the
|
|
28
|
+
# functions anew on every request.
|
|
29
|
+
# * Use <tt><%= javascript_include_tag 'prototype' %></tt>: As above, but
|
|
30
|
+
# will only include the Prototype core library, which means you are able
|
|
31
|
+
# to use all basic AJAX functionality. For the Scriptaculous-based
|
|
32
|
+
# JavaScript helpers, like visual effects, autocompletion, drag and drop
|
|
33
|
+
# and so on, you should use the method described above.
|
|
34
|
+
#
|
|
35
|
+
# For documentation on +javascript_include_tag+ see
|
|
36
|
+
# ActionView::Helpers::AssetTagHelper.
|
|
37
|
+
module JavaScriptHelper
|
|
38
|
+
unless const_defined? :JAVASCRIPT_PATH
|
|
39
|
+
JAVASCRIPT_PATH = File.join(File.dirname(__FILE__), 'javascripts')
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
include PrototypeHelper
|
|
43
|
+
|
|
44
|
+
# Returns a link of the given +name+ that will trigger a JavaScript +function+ using the
|
|
45
|
+
# onclick handler and return false after the fact.
|
|
46
|
+
#
|
|
47
|
+
# The first argument +name+ is used as the link text.
|
|
48
|
+
#
|
|
49
|
+
# The next arguments are optional and may include the javascript function definition and a hash of html_options.
|
|
50
|
+
#
|
|
51
|
+
# The +function+ argument can be omitted in favor of an +update_page+
|
|
52
|
+
# block, which evaluates to a string when the template is rendered
|
|
53
|
+
# (instead of making an Ajax request first).
|
|
54
|
+
#
|
|
55
|
+
# The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"
|
|
56
|
+
#
|
|
57
|
+
# Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil
|
|
58
|
+
#
|
|
59
|
+
#
|
|
60
|
+
# Examples:
|
|
61
|
+
# link_to_function "Greeting", "alert('Hello world!')"
|
|
62
|
+
# Produces:
|
|
63
|
+
# <a onclick="alert('Hello world!'); return false;" href="#">Greeting</a>
|
|
64
|
+
#
|
|
65
|
+
# link_to_function(image_tag("delete"), "if (confirm('Really?')) do_delete()")
|
|
66
|
+
# Produces:
|
|
67
|
+
# <a onclick="if (confirm('Really?')) do_delete(); return false;" href="#">
|
|
68
|
+
# <img src="/images/delete.png?" alt="Delete"/>
|
|
69
|
+
# </a>
|
|
70
|
+
#
|
|
71
|
+
# link_to_function("Show me more", nil, :id => "more_link") do |page|
|
|
72
|
+
# page[:details].visual_effect :toggle_blind
|
|
73
|
+
# page[:more_link].replace_html "Show me less"
|
|
74
|
+
# end
|
|
75
|
+
# Produces:
|
|
76
|
+
# <a href="#" id="more_link" onclick="try {
|
|
77
|
+
# $("details").visualEffect("toggle_blind");
|
|
78
|
+
# $("more_link").update("Show me less");
|
|
79
|
+
# }
|
|
80
|
+
# catch (e) {
|
|
81
|
+
# alert('RJS error:\n\n' + e.toString());
|
|
82
|
+
# alert('$(\"details\").visualEffect(\"toggle_blind\");
|
|
83
|
+
# \n$(\"more_link\").update(\"Show me less\");');
|
|
84
|
+
# throw e
|
|
85
|
+
# };
|
|
86
|
+
# return false;">Show me more</a>
|
|
87
|
+
#
|
|
88
|
+
def link_to_function(name, *args, &block)
|
|
89
|
+
html_options = args.extract_options!.symbolize_keys
|
|
90
|
+
|
|
91
|
+
function = block_given? ? update_page(&block) : args[0] || ''
|
|
92
|
+
onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;"
|
|
93
|
+
href = html_options[:href] || '#'
|
|
94
|
+
|
|
95
|
+
content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick))
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Returns a button with the given +name+ text that'll trigger a JavaScript +function+ using the
|
|
99
|
+
# onclick handler.
|
|
100
|
+
#
|
|
101
|
+
# The first argument +name+ is used as the button's value or display text.
|
|
102
|
+
#
|
|
103
|
+
# The next arguments are optional and may include the javascript function definition and a hash of html_options.
|
|
104
|
+
#
|
|
105
|
+
# The +function+ argument can be omitted in favor of an +update_page+
|
|
106
|
+
# block, which evaluates to a string when the template is rendered
|
|
107
|
+
# (instead of making an Ajax request first).
|
|
108
|
+
#
|
|
109
|
+
# The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"
|
|
110
|
+
#
|
|
111
|
+
# Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil
|
|
112
|
+
#
|
|
113
|
+
# Examples:
|
|
114
|
+
# button_to_function "Greeting", "alert('Hello world!')"
|
|
115
|
+
# button_to_function "Delete", "if (confirm('Really?')) do_delete()"
|
|
116
|
+
# button_to_function "Details" do |page|
|
|
117
|
+
# page[:details].visual_effect :toggle_slide
|
|
118
|
+
# end
|
|
119
|
+
# button_to_function "Details", :class => "details_button" do |page|
|
|
120
|
+
# page[:details].visual_effect :toggle_slide
|
|
121
|
+
# end
|
|
122
|
+
def button_to_function(name, *args, &block)
|
|
123
|
+
html_options = args.extract_options!.symbolize_keys
|
|
124
|
+
|
|
125
|
+
function = block_given? ? update_page(&block) : args[0] || ''
|
|
126
|
+
onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};"
|
|
127
|
+
|
|
128
|
+
tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick))
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
JS_ESCAPE_MAP = {
|
|
132
|
+
'\\' => '\\\\',
|
|
133
|
+
'</' => '<\/',
|
|
134
|
+
"\r\n" => '\n',
|
|
135
|
+
"\n" => '\n',
|
|
136
|
+
"\r" => '\n',
|
|
137
|
+
'"' => '\\"',
|
|
138
|
+
"'" => "\\'" }
|
|
139
|
+
|
|
140
|
+
# Escape carrier returns and single and double quotes for JavaScript segments.
|
|
141
|
+
def escape_javascript(javascript)
|
|
142
|
+
if javascript
|
|
143
|
+
javascript.gsub(/(\\|<\/|\r\n|[\n\r"'])/) { JS_ESCAPE_MAP[$1] }
|
|
144
|
+
else
|
|
145
|
+
''
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Returns a JavaScript tag with the +content+ inside. Example:
|
|
150
|
+
# javascript_tag "alert('All is good')"
|
|
151
|
+
#
|
|
152
|
+
# Returns:
|
|
153
|
+
# <script type="text/javascript">
|
|
154
|
+
# //<![CDATA[
|
|
155
|
+
# alert('All is good')
|
|
156
|
+
# //]]>
|
|
157
|
+
# </script>
|
|
158
|
+
#
|
|
159
|
+
# +html_options+ may be a hash of attributes for the <script> tag. Example:
|
|
160
|
+
# javascript_tag "alert('All is good')", :defer => 'defer'
|
|
161
|
+
# # => <script defer="defer" type="text/javascript">alert('All is good')</script>
|
|
162
|
+
#
|
|
163
|
+
# Instead of passing the content as an argument, you can also use a block
|
|
164
|
+
# in which case, you pass your +html_options+ as the first parameter.
|
|
165
|
+
# <% javascript_tag :defer => 'defer' do -%>
|
|
166
|
+
# alert('All is good')
|
|
167
|
+
# <% end -%>
|
|
168
|
+
def javascript_tag(content_or_options_with_block = nil, html_options = {}, &block)
|
|
169
|
+
content =
|
|
170
|
+
if block_given?
|
|
171
|
+
html_options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
|
|
172
|
+
capture(&block)
|
|
173
|
+
else
|
|
174
|
+
content_or_options_with_block
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
tag = content_tag(:script, javascript_cdata_section(content), html_options.merge(:type => Mime::JS))
|
|
178
|
+
|
|
179
|
+
if block_called_from_erb?(block)
|
|
180
|
+
concat(tag)
|
|
181
|
+
else
|
|
182
|
+
tag
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
|
|
186
|
+
def javascript_cdata_section(content) #:nodoc:
|
|
187
|
+
"\n//#{cdata_section("\n#{content}\n//")}\n"
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
protected
|
|
191
|
+
def options_for_javascript(options)
|
|
192
|
+
if options.empty?
|
|
193
|
+
'{}'
|
|
194
|
+
else
|
|
195
|
+
"{#{options.keys.map { |k| "#{k}:#{options[k]}" }.sort.join(', ')}}"
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def array_or_string_for_javascript(option)
|
|
200
|
+
if option.kind_of?(Array)
|
|
201
|
+
"['#{option.join('\',\'')}']"
|
|
202
|
+
elsif !option.nil?
|
|
203
|
+
"'#{option}'"
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
require 'active_support/core_ext/big_decimal/conversions'
|
|
2
|
+
require 'active_support/core_ext/float/rounding'
|
|
3
|
+
|
|
4
|
+
module ActionView
|
|
5
|
+
module Helpers #:nodoc:
|
|
6
|
+
# Provides methods for converting numbers into formatted strings.
|
|
7
|
+
# Methods are provided for phone numbers, currency, percentage,
|
|
8
|
+
# precision, positional notation, and file size.
|
|
9
|
+
module NumberHelper
|
|
10
|
+
# Formats a +number+ into a US phone number (e.g., (555) 123-9876). You can customize the format
|
|
11
|
+
# in the +options+ hash.
|
|
12
|
+
#
|
|
13
|
+
# ==== Options
|
|
14
|
+
# * <tt>:area_code</tt> - Adds parentheses around the area code.
|
|
15
|
+
# * <tt>:delimiter</tt> - Specifies the delimiter to use (defaults to "-").
|
|
16
|
+
# * <tt>:extension</tt> - Specifies an extension to add to the end of the
|
|
17
|
+
# generated number.
|
|
18
|
+
# * <tt>:country_code</tt> - Sets the country code for the phone number.
|
|
19
|
+
#
|
|
20
|
+
# ==== Examples
|
|
21
|
+
# number_to_phone(5551234) # => 555-1234
|
|
22
|
+
# number_to_phone(1235551234) # => 123-555-1234
|
|
23
|
+
# number_to_phone(1235551234, :area_code => true) # => (123) 555-1234
|
|
24
|
+
# number_to_phone(1235551234, :delimiter => " ") # => 123 555 1234
|
|
25
|
+
# number_to_phone(1235551234, :area_code => true, :extension => 555) # => (123) 555-1234 x 555
|
|
26
|
+
# number_to_phone(1235551234, :country_code => 1) # => +1-123-555-1234
|
|
27
|
+
#
|
|
28
|
+
# number_to_phone(1235551234, :country_code => 1, :extension => 1343, :delimiter => ".")
|
|
29
|
+
# => +1.123.555.1234 x 1343
|
|
30
|
+
def number_to_phone(number, options = {})
|
|
31
|
+
number = number.to_s.strip unless number.nil?
|
|
32
|
+
options = options.symbolize_keys
|
|
33
|
+
area_code = options[:area_code] || nil
|
|
34
|
+
delimiter = options[:delimiter] || "-"
|
|
35
|
+
extension = options[:extension].to_s.strip || nil
|
|
36
|
+
country_code = options[:country_code] || nil
|
|
37
|
+
|
|
38
|
+
begin
|
|
39
|
+
str = ""
|
|
40
|
+
str << "+#{country_code}#{delimiter}" unless country_code.blank?
|
|
41
|
+
str << if area_code
|
|
42
|
+
number.gsub!(/([0-9]{1,3})([0-9]{3})([0-9]{4}$)/,"(\\1) \\2#{delimiter}\\3")
|
|
43
|
+
else
|
|
44
|
+
number.gsub!(/([0-9]{0,3})([0-9]{3})([0-9]{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3")
|
|
45
|
+
number.starts_with?('-') ? number.slice!(1..-1) : number
|
|
46
|
+
end
|
|
47
|
+
str << " x #{extension}" unless extension.blank?
|
|
48
|
+
str
|
|
49
|
+
rescue
|
|
50
|
+
number
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Formats a +number+ into a currency string (e.g., $13.65). You can customize the format
|
|
55
|
+
# in the +options+ hash.
|
|
56
|
+
#
|
|
57
|
+
# ==== Options
|
|
58
|
+
# * <tt>:precision</tt> - Sets the level of precision (defaults to 2).
|
|
59
|
+
# * <tt>:unit</tt> - Sets the denomination of the currency (defaults to "$").
|
|
60
|
+
# * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
|
|
61
|
+
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to ",").
|
|
62
|
+
# * <tt>:format</tt> - Sets the format of the output string (defaults to "%u%n"). The field types are:
|
|
63
|
+
#
|
|
64
|
+
# %u The currency unit
|
|
65
|
+
# %n The number
|
|
66
|
+
#
|
|
67
|
+
# ==== Examples
|
|
68
|
+
# number_to_currency(1234567890.50) # => $1,234,567,890.50
|
|
69
|
+
# number_to_currency(1234567890.506) # => $1,234,567,890.51
|
|
70
|
+
# number_to_currency(1234567890.506, :precision => 3) # => $1,234,567,890.506
|
|
71
|
+
#
|
|
72
|
+
# number_to_currency(1234567890.50, :unit => "£", :separator => ",", :delimiter => "")
|
|
73
|
+
# # => £1234567890,50
|
|
74
|
+
# number_to_currency(1234567890.50, :unit => "£", :separator => ",", :delimiter => "", :format => "%n %u")
|
|
75
|
+
# # => 1234567890,50 £
|
|
76
|
+
def number_to_currency(number, options = {})
|
|
77
|
+
options.symbolize_keys!
|
|
78
|
+
|
|
79
|
+
defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
|
|
80
|
+
currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :raise => true) rescue {}
|
|
81
|
+
defaults = defaults.merge(currency)
|
|
82
|
+
|
|
83
|
+
precision = options[:precision] || defaults[:precision]
|
|
84
|
+
unit = options[:unit] || defaults[:unit]
|
|
85
|
+
separator = options[:separator] || defaults[:separator]
|
|
86
|
+
delimiter = options[:delimiter] || defaults[:delimiter]
|
|
87
|
+
format = options[:format] || defaults[:format]
|
|
88
|
+
separator = '' if precision == 0
|
|
89
|
+
|
|
90
|
+
begin
|
|
91
|
+
format.gsub(/%n/, number_with_precision(number,
|
|
92
|
+
:precision => precision,
|
|
93
|
+
:delimiter => delimiter,
|
|
94
|
+
:separator => separator)
|
|
95
|
+
).gsub(/%u/, unit)
|
|
96
|
+
rescue
|
|
97
|
+
number
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Formats a +number+ as a percentage string (e.g., 65%). You can customize the
|
|
102
|
+
# format in the +options+ hash.
|
|
103
|
+
#
|
|
104
|
+
# ==== Options
|
|
105
|
+
# * <tt>:precision</tt> - Sets the level of precision (defaults to 3).
|
|
106
|
+
# * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
|
|
107
|
+
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
|
|
108
|
+
#
|
|
109
|
+
# ==== Examples
|
|
110
|
+
# number_to_percentage(100) # => 100.000%
|
|
111
|
+
# number_to_percentage(100, :precision => 0) # => 100%
|
|
112
|
+
# number_to_percentage(1000, :delimiter => '.', :separator => ',') # => 1.000,000%
|
|
113
|
+
# number_to_percentage(302.24398923423, :precision => 5) # => 302.24399%
|
|
114
|
+
def number_to_percentage(number, options = {})
|
|
115
|
+
options.symbolize_keys!
|
|
116
|
+
|
|
117
|
+
defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
|
|
118
|
+
percentage = I18n.translate(:'number.percentage.format', :locale => options[:locale], :raise => true) rescue {}
|
|
119
|
+
defaults = defaults.merge(percentage)
|
|
120
|
+
|
|
121
|
+
precision = options[:precision] || defaults[:precision]
|
|
122
|
+
separator = options[:separator] || defaults[:separator]
|
|
123
|
+
delimiter = options[:delimiter] || defaults[:delimiter]
|
|
124
|
+
|
|
125
|
+
begin
|
|
126
|
+
number_with_precision(number,
|
|
127
|
+
:precision => precision,
|
|
128
|
+
:separator => separator,
|
|
129
|
+
:delimiter => delimiter) + "%"
|
|
130
|
+
rescue
|
|
131
|
+
number
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Formats a +number+ with grouped thousands using +delimiter+ (e.g., 12,324). You can
|
|
136
|
+
# customize the format in the +options+ hash.
|
|
137
|
+
#
|
|
138
|
+
# ==== Options
|
|
139
|
+
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to ",").
|
|
140
|
+
# * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
|
|
141
|
+
#
|
|
142
|
+
# ==== Examples
|
|
143
|
+
# number_with_delimiter(12345678) # => 12,345,678
|
|
144
|
+
# number_with_delimiter(12345678.05) # => 12,345,678.05
|
|
145
|
+
# number_with_delimiter(12345678, :delimiter => ".") # => 12.345.678
|
|
146
|
+
# number_with_delimiter(12345678, :separator => ",") # => 12,345,678
|
|
147
|
+
# number_with_delimiter(98765432.98, :delimiter => " ", :separator => ",")
|
|
148
|
+
# # => 98 765 432,98
|
|
149
|
+
#
|
|
150
|
+
# You can still use <tt>number_with_delimiter</tt> with the old API that accepts the
|
|
151
|
+
# +delimiter+ as its optional second and the +separator+ as its
|
|
152
|
+
# optional third parameter:
|
|
153
|
+
# number_with_delimiter(12345678, " ") # => 12 345.678
|
|
154
|
+
# number_with_delimiter(12345678.05, ".", ",") # => 12.345.678,05
|
|
155
|
+
def number_with_delimiter(number, *args)
|
|
156
|
+
options = args.extract_options!
|
|
157
|
+
options.symbolize_keys!
|
|
158
|
+
|
|
159
|
+
defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
|
|
160
|
+
|
|
161
|
+
unless args.empty?
|
|
162
|
+
ActiveSupport::Deprecation.warn('number_with_delimiter takes an option hash ' +
|
|
163
|
+
'instead of separate delimiter and precision arguments.', caller)
|
|
164
|
+
delimiter = args[0] || defaults[:delimiter]
|
|
165
|
+
separator = args[1] || defaults[:separator]
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
delimiter ||= (options[:delimiter] || defaults[:delimiter])
|
|
169
|
+
separator ||= (options[:separator] || defaults[:separator])
|
|
170
|
+
|
|
171
|
+
begin
|
|
172
|
+
parts = number.to_s.split('.')
|
|
173
|
+
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}")
|
|
174
|
+
parts.join(separator)
|
|
175
|
+
rescue
|
|
176
|
+
number
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Formats a +number+ with the specified level of <tt>:precision</tt> (e.g., 112.32 has a precision of 2).
|
|
181
|
+
# You can customize the format in the +options+ hash.
|
|
182
|
+
#
|
|
183
|
+
# ==== Options
|
|
184
|
+
# * <tt>:precision</tt> - Sets the level of precision (defaults to 3).
|
|
185
|
+
# * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
|
|
186
|
+
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
|
|
187
|
+
#
|
|
188
|
+
# ==== Examples
|
|
189
|
+
# number_with_precision(111.2345) # => 111.235
|
|
190
|
+
# number_with_precision(111.2345, :precision => 2) # => 111.23
|
|
191
|
+
# number_with_precision(13, :precision => 5) # => 13.00000
|
|
192
|
+
# number_with_precision(389.32314, :precision => 0) # => 389
|
|
193
|
+
# number_with_precision(1111.2345, :precision => 2, :separator => ',', :delimiter => '.')
|
|
194
|
+
# # => 1.111,23
|
|
195
|
+
#
|
|
196
|
+
# You can still use <tt>number_with_precision</tt> with the old API that accepts the
|
|
197
|
+
# +precision+ as its optional second parameter:
|
|
198
|
+
# number_with_precision(number_with_precision(111.2345, 2) # => 111.23
|
|
199
|
+
def number_with_precision(number, *args)
|
|
200
|
+
options = args.extract_options!
|
|
201
|
+
options.symbolize_keys!
|
|
202
|
+
|
|
203
|
+
defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
|
|
204
|
+
precision_defaults = I18n.translate(:'number.precision.format', :locale => options[:locale],
|
|
205
|
+
:raise => true) rescue {}
|
|
206
|
+
defaults = defaults.merge(precision_defaults)
|
|
207
|
+
|
|
208
|
+
unless args.empty?
|
|
209
|
+
ActiveSupport::Deprecation.warn('number_with_precision takes an option hash ' +
|
|
210
|
+
'instead of a separate precision argument.', caller)
|
|
211
|
+
precision = args[0] || defaults[:precision]
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
precision ||= (options[:precision] || defaults[:precision])
|
|
215
|
+
separator ||= (options[:separator] || defaults[:separator])
|
|
216
|
+
delimiter ||= (options[:delimiter] || defaults[:delimiter])
|
|
217
|
+
|
|
218
|
+
begin
|
|
219
|
+
rounded_number = BigDecimal.new((Float(number) * (10 ** precision)).to_s).round.to_f / 10 ** precision
|
|
220
|
+
number_with_delimiter("%01.#{precision}f" % rounded_number,
|
|
221
|
+
:separator => separator,
|
|
222
|
+
:delimiter => delimiter)
|
|
223
|
+
rescue
|
|
224
|
+
number
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb].freeze
|
|
229
|
+
|
|
230
|
+
# Formats the bytes in +size+ into a more understandable representation
|
|
231
|
+
# (e.g., giving it 1500 yields 1.5 KB). This method is useful for
|
|
232
|
+
# reporting file sizes to users. This method returns nil if
|
|
233
|
+
# +size+ cannot be converted into a number. You can customize the
|
|
234
|
+
# format in the +options+ hash.
|
|
235
|
+
#
|
|
236
|
+
# ==== Options
|
|
237
|
+
# * <tt>:precision</tt> - Sets the level of precision (defaults to 1).
|
|
238
|
+
# * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
|
|
239
|
+
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
|
|
240
|
+
#
|
|
241
|
+
# ==== Examples
|
|
242
|
+
# number_to_human_size(123) # => 123 Bytes
|
|
243
|
+
# number_to_human_size(1234) # => 1.2 KB
|
|
244
|
+
# number_to_human_size(12345) # => 12.1 KB
|
|
245
|
+
# number_to_human_size(1234567) # => 1.2 MB
|
|
246
|
+
# number_to_human_size(1234567890) # => 1.1 GB
|
|
247
|
+
# number_to_human_size(1234567890123) # => 1.1 TB
|
|
248
|
+
# number_to_human_size(1234567, :precision => 2) # => 1.18 MB
|
|
249
|
+
# number_to_human_size(483989, :precision => 0) # => 473 KB
|
|
250
|
+
# number_to_human_size(1234567, :precision => 2, :separator => ',') # => 1,18 MB
|
|
251
|
+
#
|
|
252
|
+
# Zeros after the decimal point are always stripped out, regardless of the
|
|
253
|
+
# specified precision:
|
|
254
|
+
# helper.number_to_human_size(1234567890123, :precision => 5) # => "1.12283 TB"
|
|
255
|
+
# helper.number_to_human_size(524288000, :precision=>5) # => "500 MB"
|
|
256
|
+
#
|
|
257
|
+
# You can still use <tt>number_to_human_size</tt> with the old API that accepts the
|
|
258
|
+
# +precision+ as its optional second parameter:
|
|
259
|
+
# number_to_human_size(1234567, 2) # => 1.18 MB
|
|
260
|
+
# number_to_human_size(483989, 0) # => 473 KB
|
|
261
|
+
def number_to_human_size(number, *args)
|
|
262
|
+
return nil if number.nil?
|
|
263
|
+
|
|
264
|
+
options = args.extract_options!
|
|
265
|
+
options.symbolize_keys!
|
|
266
|
+
|
|
267
|
+
defaults = I18n.translate(:'number.format', :locale => options[:locale], :raise => true) rescue {}
|
|
268
|
+
human = I18n.translate(:'number.human.format', :locale => options[:locale], :raise => true) rescue {}
|
|
269
|
+
defaults = defaults.merge(human)
|
|
270
|
+
|
|
271
|
+
unless args.empty?
|
|
272
|
+
ActiveSupport::Deprecation.warn('number_to_human_size takes an option hash ' +
|
|
273
|
+
'instead of a separate precision argument.', caller)
|
|
274
|
+
precision = args[0] || defaults[:precision]
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
precision ||= (options[:precision] || defaults[:precision])
|
|
278
|
+
separator ||= (options[:separator] || defaults[:separator])
|
|
279
|
+
delimiter ||= (options[:delimiter] || defaults[:delimiter])
|
|
280
|
+
|
|
281
|
+
storage_units_format = I18n.translate(:'number.human.storage_units.format', :locale => options[:locale], :raise => true)
|
|
282
|
+
|
|
283
|
+
if number.to_i < 1024
|
|
284
|
+
unit = I18n.translate(:'number.human.storage_units.units.byte', :locale => options[:locale], :count => number.to_i, :raise => true)
|
|
285
|
+
storage_units_format.gsub(/%n/, number.to_i.to_s).gsub(/%u/, unit)
|
|
286
|
+
else
|
|
287
|
+
max_exp = STORAGE_UNITS.size - 1
|
|
288
|
+
number = Float(number)
|
|
289
|
+
exponent = (Math.log(number) / Math.log(1024)).to_i # Convert to base 1024
|
|
290
|
+
exponent = max_exp if exponent > max_exp # we need this to avoid overflow for the highest unit
|
|
291
|
+
number /= 1024 ** exponent
|
|
292
|
+
|
|
293
|
+
unit_key = STORAGE_UNITS[exponent]
|
|
294
|
+
unit = I18n.translate(:"number.human.storage_units.units.#{unit_key}", :locale => options[:locale], :count => number, :raise => true)
|
|
295
|
+
|
|
296
|
+
begin
|
|
297
|
+
escaped_separator = Regexp.escape(separator)
|
|
298
|
+
formatted_number = number_with_precision(number,
|
|
299
|
+
:precision => precision,
|
|
300
|
+
:separator => separator,
|
|
301
|
+
:delimiter => delimiter
|
|
302
|
+
).sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '')
|
|
303
|
+
storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit)
|
|
304
|
+
rescue
|
|
305
|
+
number
|
|
306
|
+
end
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
end
|