activesupport 4.2.11.1 → 5.2.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +399 -440
- data/MIT-LICENSE +2 -2
- data/README.rdoc +4 -5
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +7 -5
- data/lib/active_support/benchmarkable.rb +6 -4
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +41 -35
- data/lib/active_support/cache/mem_cache_store.rb +97 -88
- data/lib/active_support/cache/memory_store.rb +27 -30
- data/lib/active_support/cache/null_store.rb +7 -8
- data/lib/active_support/cache/redis_cache_store.rb +461 -0
- data/lib/active_support/cache/strategy/local_cache.rb +67 -34
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
- data/lib/active_support/cache.rb +287 -196
- data/lib/active_support/callbacks.rb +640 -590
- data/lib/active_support/concern.rb +11 -5
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +17 -0
- data/lib/active_support/concurrency/share_lock.rb +227 -0
- data/lib/active_support/configurable.rb +8 -5
- data/lib/active_support/core_ext/array/access.rb +29 -1
- data/lib/active_support/core_ext/array/conversions.rb +22 -18
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +11 -18
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +5 -3
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +9 -6
- data/lib/active_support/core_ext/benchmark.rb +3 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +41 -22
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
- data/lib/active_support/core_ext/class/subclasses.rb +20 -6
- data/lib/active_support/core_ext/class.rb +4 -3
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +11 -9
- data/lib/active_support/core_ext/date/conversions.rb +25 -23
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date.rb +6 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +170 -58
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
- data/lib/active_support/core_ext/date_and_time/zones.rb +12 -12
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +36 -18
- data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
- data/lib/active_support/core_ext/date_time/conversions.rb +16 -12
- data/lib/active_support/core_ext/date_time.rb +7 -5
- data/lib/active_support/core_ext/digest/uuid.rb +7 -5
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +101 -33
- data/lib/active_support/core_ext/file/atomic.rb +38 -31
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/compact.rb +14 -9
- data/lib/active_support/core_ext/hash/conversions.rb +62 -41
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/except.rb +11 -8
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
- data/lib/active_support/core_ext/hash/keys.rb +33 -27
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -8
- data/lib/active_support/core_ext/hash/transform_values.rb +14 -5
- data/lib/active_support/core_ext/hash.rb +11 -9
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +2 -0
- data/lib/active_support/core_ext/integer/time.rb +11 -18
- data/lib/active_support/core_ext/integer.rb +5 -3
- data/lib/active_support/core_ext/kernel/agnostics.rb +2 -0
- data/lib/active_support/core_ext/kernel/concern.rb +5 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +6 -5
- data/lib/active_support/core_ext/load_error.rb +3 -22
- data/lib/active_support/core_ext/marshal.rb +8 -8
- data/lib/active_support/core_ext/module/aliasing.rb +6 -44
- data/lib/active_support/core_ext/module/anonymous.rb +12 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
- data/lib/active_support/core_ext/module/attribute_accessors.rb +43 -40
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +150 -0
- data/lib/active_support/core_ext/module/concerning.rb +11 -12
- data/lib/active_support/core_ext/module/delegation.rb +99 -29
- data/lib/active_support/core_ext/module/deprecation.rb +4 -2
- data/lib/active_support/core_ext/module/introspection.rb +9 -9
- data/lib/active_support/core_ext/module/reachable.rb +5 -2
- data/lib/active_support/core_ext/module/redefine_method.rb +49 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/module.rb +14 -11
- data/lib/active_support/core_ext/name_error.rb +22 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +78 -81
- data/lib/active_support/core_ext/numeric/inquiry.rb +28 -0
- data/lib/active_support/core_ext/numeric/time.rb +35 -23
- data/lib/active_support/core_ext/numeric.rb +6 -3
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +27 -2
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
- data/lib/active_support/core_ext/object/duplicable.rb +41 -14
- data/lib/active_support/core_ext/object/inclusion.rb +5 -3
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +49 -19
- data/lib/active_support/core_ext/object/to_param.rb +3 -1
- data/lib/active_support/core_ext/object/to_query.rb +10 -5
- data/lib/active_support/core_ext/object/try.rb +69 -21
- data/lib/active_support/core_ext/object/with_options.rb +16 -3
- data/lib/active_support/core_ext/object.rb +14 -13
- data/lib/active_support/core_ext/range/compare_range.rb +61 -0
- data/lib/active_support/core_ext/range/conversions.rb +27 -7
- data/lib/active_support/core_ext/range/each.rb +19 -17
- data/lib/active_support/core_ext/range/include_range.rb +2 -22
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/range.rb +7 -4
- data/lib/active_support/core_ext/regexp.rb +6 -0
- data/lib/active_support/core_ext/securerandom.rb +25 -0
- data/lib/active_support/core_ext/string/access.rb +8 -6
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +7 -4
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +6 -5
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +61 -24
- data/lib/active_support/core_ext/string/inquiry.rb +3 -1
- data/lib/active_support/core_ext/string/multibyte.rb +15 -7
- data/lib/active_support/core_ext/string/output_safety.rb +34 -38
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +4 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -2
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +85 -51
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +20 -13
- data/lib/active_support/core_ext/time/zones.rb +41 -7
- data/lib/active_support/core_ext/time.rb +7 -6
- data/lib/active_support/core_ext/uri.rb +6 -8
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes.rb +195 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/dependencies.rb +152 -161
- data/lib/active_support/deprecation/behaviors.rb +44 -11
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/instance_delegator.rb +17 -2
- data/lib/active_support/deprecation/method_wrappers.rb +66 -20
- data/lib/active_support/deprecation/proxy_wrappers.rb +56 -28
- data/lib/active_support/deprecation/reporting.rb +32 -12
- data/lib/active_support/deprecation.rb +12 -9
- data/lib/active_support/descendants_tracker.rb +2 -0
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +125 -0
- data/lib/active_support/duration/iso8601_serializer.rb +55 -0
- data/lib/active_support/duration.rb +307 -35
- data/lib/active_support/encrypted_configuration.rb +49 -0
- data/lib/active_support/encrypted_file.rb +99 -0
- data/lib/active_support/evented_file_update_checker.rb +205 -0
- data/lib/active_support/execution_wrapper.rb +128 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +63 -37
- data/lib/active_support/gem_version.rb +6 -4
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +123 -28
- data/lib/active_support/i18n.rb +8 -6
- data/lib/active_support/i18n_railtie.rb +37 -13
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector/inflections.rb +61 -12
- data/lib/active_support/inflector/methods.rb +163 -136
- data/lib/active_support/inflector/transliterate.rb +48 -27
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/json/decoding.rb +16 -13
- data/lib/active_support/json/encoding.rb +11 -58
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +25 -25
- data/lib/active_support/lazy_load_hooks.rb +50 -20
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +13 -10
- data/lib/active_support/logger.rb +8 -7
- data/lib/active_support/logger_silence.rb +6 -4
- data/lib/active_support/logger_thread_safe_level.rb +7 -5
- data/lib/active_support/message_encryptor.rb +168 -53
- data/lib/active_support/message_verifier.rb +150 -17
- data/lib/active_support/messages/metadata.rb +71 -0
- data/lib/active_support/messages/rotation_configuration.rb +22 -0
- data/lib/active_support/messages/rotator.rb +56 -0
- data/lib/active_support/multibyte/chars.rb +36 -23
- data/lib/active_support/multibyte/unicode.rb +100 -96
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/notifications/fanout.rb +11 -9
- data/lib/active_support/notifications/instrumenter.rb +27 -7
- data/lib/active_support/notifications.rb +11 -7
- data/lib/active_support/number_helper/number_converter.rb +13 -11
- data/lib/active_support/number_helper/number_to_currency_converter.rb +9 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +9 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +11 -9
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +9 -8
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +3 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +13 -4
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +23 -56
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/number_helper.rb +94 -68
- data/lib/active_support/option_merger.rb +3 -1
- data/lib/active_support/ordered_hash.rb +6 -4
- data/lib/active_support/ordered_options.rb +23 -5
- data/lib/active_support/per_thread_registry.rb +9 -4
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +16 -8
- data/lib/active_support/railtie.rb +43 -9
- data/lib/active_support/reloader.rb +131 -0
- data/lib/active_support/rescuable.rb +108 -53
- data/lib/active_support/security_utils.rb +15 -11
- data/lib/active_support/string_inquirer.rb +11 -3
- data/lib/active_support/subscriber.rb +21 -16
- data/lib/active_support/tagged_logging.rb +14 -11
- data/lib/active_support/test_case.rb +19 -47
- data/lib/active_support/testing/assertions.rb +137 -20
- data/lib/active_support/testing/autorun.rb +4 -2
- data/lib/active_support/testing/constant_lookup.rb +2 -1
- data/lib/active_support/testing/declarative.rb +3 -1
- data/lib/active_support/testing/deprecation.rb +14 -10
- data/lib/active_support/testing/file_fixtures.rb +36 -0
- data/lib/active_support/testing/isolation.rb +34 -25
- data/lib/active_support/testing/method_call_assertions.rb +43 -0
- data/lib/active_support/testing/setup_and_teardown.rb +13 -8
- data/lib/active_support/testing/stream.rb +44 -0
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +81 -15
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +169 -39
- data/lib/active_support/values/time_zone.rb +196 -61
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +116 -114
- data/lib/active_support/xml_mini/libxml.rb +16 -13
- data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
- data/lib/active_support/xml_mini/nokogiri.rb +14 -12
- data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
- data/lib/active_support/xml_mini/rexml.rb +11 -9
- data/lib/active_support/xml_mini.rb +37 -37
- data/lib/active_support.rb +12 -11
- metadata +54 -24
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_time/zones.rb +0 -6
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -86
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
@@ -1,34 +1,32 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "erb"
|
4
|
+
require "active_support/core_ext/kernel/singleton_class"
|
5
|
+
require "active_support/core_ext/module/redefine_method"
|
6
|
+
require "active_support/multibyte/unicode"
|
4
7
|
|
5
8
|
class ERB
|
6
9
|
module Util
|
7
|
-
HTML_ESCAPE = {
|
8
|
-
JSON_ESCAPE = {
|
9
|
-
HTML_ESCAPE_REGEXP = /[&"'><]/
|
10
|
+
HTML_ESCAPE = { "&" => "&", ">" => ">", "<" => "<", '"' => """, "'" => "'" }
|
11
|
+
JSON_ESCAPE = { "&" => '\u0026', ">" => '\u003e', "<" => '\u003c', "\u2028" => '\u2028', "\u2029" => '\u2029' }
|
10
12
|
HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/
|
11
13
|
JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u
|
12
14
|
|
13
15
|
# A utility method for escaping HTML tag characters.
|
14
16
|
# This method is also aliased as <tt>h</tt>.
|
15
17
|
#
|
16
|
-
# In your ERB templates, use this method to escape any unsafe content. For example:
|
17
|
-
# <%=h @person.name %>
|
18
|
-
#
|
19
18
|
# puts html_escape('is a > 0 & a < 10?')
|
20
19
|
# # => is a > 0 & a < 10?
|
21
20
|
def html_escape(s)
|
22
21
|
unwrapped_html_escape(s).html_safe
|
23
22
|
end
|
24
23
|
|
25
|
-
|
26
|
-
remove_method(:h)
|
24
|
+
silence_redefinition_of_method :h
|
27
25
|
alias h html_escape
|
28
26
|
|
29
27
|
module_function :h
|
30
28
|
|
31
|
-
singleton_class.
|
29
|
+
singleton_class.silence_redefinition_of_method :html_escape
|
32
30
|
module_function :html_escape
|
33
31
|
|
34
32
|
# HTML escapes strings but doesn't wrap them with an ActiveSupport::SafeBuffer.
|
@@ -38,7 +36,7 @@ class ERB
|
|
38
36
|
if s.html_safe?
|
39
37
|
s
|
40
38
|
else
|
41
|
-
|
39
|
+
CGI.escapeHTML(ActiveSupport::Multibyte::Unicode.tidy_bytes(s))
|
42
40
|
end
|
43
41
|
end
|
44
42
|
module_function :unwrapped_html_escape
|
@@ -51,7 +49,7 @@ class ERB
|
|
51
49
|
# html_escape_once('<< Accept & Checkout')
|
52
50
|
# # => "<< Accept & Checkout"
|
53
51
|
def html_escape_once(s)
|
54
|
-
result = s.to_s.gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
|
52
|
+
result = ActiveSupport::Multibyte::Unicode.tidy_bytes(s.to_s).gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
|
55
53
|
s.html_safe? ? result.html_safe : result
|
56
54
|
end
|
57
55
|
|
@@ -86,6 +84,11 @@ class ERB
|
|
86
84
|
# automatically flag the result as HTML safe, since the raw value is unsafe to
|
87
85
|
# use inside HTML attributes.
|
88
86
|
#
|
87
|
+
# If your JSON is being used downstream for insertion into the DOM, be aware of
|
88
|
+
# whether or not it is being inserted via +html()+. Most jQuery plugins do this.
|
89
|
+
# If that is the case, be sure to +html_escape+ or +sanitize+ any user-generated
|
90
|
+
# content returned by your JSON.
|
91
|
+
#
|
89
92
|
# If you need to output JSON elsewhere in your HTML, you can just do something
|
90
93
|
# like this, as any unsafe characters (including quotation marks) will be
|
91
94
|
# automatically escaped for you:
|
@@ -138,27 +141,26 @@ module ActiveSupport #:nodoc:
|
|
138
141
|
alias_method :original_concat, :concat
|
139
142
|
private :original_concat
|
140
143
|
|
144
|
+
# Raised when <tt>ActiveSupport::SafeBuffer#safe_concat</tt> is called on unsafe buffers.
|
141
145
|
class SafeConcatError < StandardError
|
142
146
|
def initialize
|
143
|
-
super
|
147
|
+
super "Could not concatenate to the buffer because it is not html safe."
|
144
148
|
end
|
145
149
|
end
|
146
150
|
|
147
151
|
def [](*args)
|
148
152
|
if args.size < 2
|
149
153
|
super
|
150
|
-
|
151
|
-
|
152
|
-
new_safe_buffer = super
|
153
|
-
|
154
|
-
if new_safe_buffer
|
155
|
-
new_safe_buffer.instance_variable_set :@html_safe, true
|
156
|
-
end
|
154
|
+
elsif html_safe?
|
155
|
+
new_safe_buffer = super
|
157
156
|
|
158
|
-
|
159
|
-
|
160
|
-
to_str[*args]
|
157
|
+
if new_safe_buffer
|
158
|
+
new_safe_buffer.instance_variable_set :@html_safe, true
|
161
159
|
end
|
160
|
+
|
161
|
+
new_safe_buffer
|
162
|
+
else
|
163
|
+
to_str[*args]
|
162
164
|
end
|
163
165
|
end
|
164
166
|
|
@@ -167,7 +169,7 @@ module ActiveSupport #:nodoc:
|
|
167
169
|
original_concat(value)
|
168
170
|
end
|
169
171
|
|
170
|
-
def initialize(
|
172
|
+
def initialize(str = "")
|
171
173
|
@html_safe = true
|
172
174
|
super
|
173
175
|
end
|
@@ -190,11 +192,6 @@ module ActiveSupport #:nodoc:
|
|
190
192
|
super(html_escape_interpolated_argument(value))
|
191
193
|
end
|
192
194
|
|
193
|
-
def prepend!(value)
|
194
|
-
ActiveSupport::Deprecation.deprecation_warning "ActiveSupport::SafeBuffer#prepend!", :prepend
|
195
|
-
prepend value
|
196
|
-
end
|
197
|
-
|
198
195
|
def +(other)
|
199
196
|
dup.concat(other)
|
200
197
|
end
|
@@ -202,7 +199,7 @@ module ActiveSupport #:nodoc:
|
|
202
199
|
def %(args)
|
203
200
|
case args
|
204
201
|
when Hash
|
205
|
-
escaped_args = Hash[args.map { |k,arg| [k, html_escape_interpolated_argument(arg)] }]
|
202
|
+
escaped_args = Hash[args.map { |k, arg| [k, html_escape_interpolated_argument(arg)] }]
|
206
203
|
else
|
207
204
|
escaped_args = Array(args).map { |arg| html_escape_interpolated_argument(arg) }
|
208
205
|
end
|
@@ -243,18 +240,17 @@ module ActiveSupport #:nodoc:
|
|
243
240
|
|
244
241
|
private
|
245
242
|
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
end
|
243
|
+
def html_escape_interpolated_argument(arg)
|
244
|
+
(!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s)
|
245
|
+
end
|
250
246
|
end
|
251
247
|
end
|
252
248
|
|
253
249
|
class String
|
254
250
|
# Marks a string as trusted safe. It will be inserted into HTML with no
|
255
|
-
# additional escaping performed. It is your
|
251
|
+
# additional escaping performed. It is your responsibility to ensure that the
|
256
252
|
# string contains no malicious content. This method is equivalent to the
|
257
|
-
#
|
253
|
+
# +raw+ helper in views. It is recommended that you use +sanitize+ instead of
|
258
254
|
# this method. It should never be called on user input.
|
259
255
|
def html_safe
|
260
256
|
ActiveSupport::SafeBuffer.new(self)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
class String
|
4
4
|
# Strips indentation in heredocs.
|
@@ -17,10 +17,9 @@ class String
|
|
17
17
|
#
|
18
18
|
# the user would see the usage message aligned against the left margin.
|
19
19
|
#
|
20
|
-
# Technically, it looks for the least indented line
|
21
|
-
# that amount of leading whitespace.
|
20
|
+
# Technically, it looks for the least indented non-empty line
|
21
|
+
# in the whole string, and removes that amount of leading whitespace.
|
22
22
|
def strip_heredoc
|
23
|
-
|
24
|
-
gsub(/^[ \t]{#{indent}}/, '')
|
23
|
+
gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, "".freeze)
|
25
24
|
end
|
26
25
|
end
|
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/string/conversions"
|
4
|
+
require "active_support/core_ext/time/zones"
|
3
5
|
|
4
6
|
class String
|
5
7
|
# Converts String to a TimeWithZone in the current zone if Time.zone or Time.zone_default
|
@@ -1,13 +1,15 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
9
|
-
require
|
10
|
-
require
|
11
|
-
require
|
12
|
-
require
|
13
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/string/conversions"
|
4
|
+
require "active_support/core_ext/string/filters"
|
5
|
+
require "active_support/core_ext/string/multibyte"
|
6
|
+
require "active_support/core_ext/string/starts_ends_with"
|
7
|
+
require "active_support/core_ext/string/inflections"
|
8
|
+
require "active_support/core_ext/string/access"
|
9
|
+
require "active_support/core_ext/string/behavior"
|
10
|
+
require "active_support/core_ext/string/output_safety"
|
11
|
+
require "active_support/core_ext/string/exclude"
|
12
|
+
require "active_support/core_ext/string/strip"
|
13
|
+
require "active_support/core_ext/string/inquiry"
|
14
|
+
require "active_support/core_ext/string/indent"
|
15
|
+
require "active_support/core_ext/string/zones"
|
@@ -1,9 +1,11 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/duration"
|
4
|
+
require "active_support/core_ext/time/conversions"
|
5
|
+
require "active_support/time_with_zone"
|
6
|
+
require "active_support/core_ext/time/zones"
|
7
|
+
require "active_support/core_ext/date_and_time/calculations"
|
8
|
+
require "active_support/core_ext/date/calculations"
|
7
9
|
|
8
10
|
class Time
|
9
11
|
include DateAndTime::Calculations
|
@@ -16,9 +18,9 @@ class Time
|
|
16
18
|
super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
|
17
19
|
end
|
18
20
|
|
19
|
-
#
|
21
|
+
# Returns the number of days in the given month.
|
20
22
|
# If no year is specified, it will use the current year.
|
21
|
-
def days_in_month(month, year =
|
23
|
+
def days_in_month(month, year = current.year)
|
22
24
|
if month == 2 && ::Date.gregorian_leap?(year)
|
23
25
|
29
|
24
26
|
else
|
@@ -26,6 +28,12 @@ class Time
|
|
26
28
|
end
|
27
29
|
end
|
28
30
|
|
31
|
+
# Returns the number of days in the given year.
|
32
|
+
# If no year is specified, it will use the current year.
|
33
|
+
def days_in_year(year = current.year)
|
34
|
+
days_in_month(2, year) + 337
|
35
|
+
end
|
36
|
+
|
29
37
|
# Returns <tt>Time.zone.now</tt> when <tt>Time.zone</tt> or <tt>config.time_zone</tt> are set, otherwise just returns <tt>Time.now</tt>.
|
30
38
|
def current
|
31
39
|
::Time.zone ? ::Time.zone.now : ::Time.now
|
@@ -47,11 +55,38 @@ class Time
|
|
47
55
|
end
|
48
56
|
alias_method :at_without_coercion, :at
|
49
57
|
alias_method :at, :at_with_coercion
|
58
|
+
|
59
|
+
# Creates a +Time+ instance from an RFC 3339 string.
|
60
|
+
#
|
61
|
+
# Time.rfc3339('1999-12-31T14:00:00-10:00') # => 2000-01-01 00:00:00 -1000
|
62
|
+
#
|
63
|
+
# If the time or offset components are missing then an +ArgumentError+ will be raised.
|
64
|
+
#
|
65
|
+
# Time.rfc3339('1999-12-31') # => ArgumentError: invalid date
|
66
|
+
def rfc3339(str)
|
67
|
+
parts = Date._rfc3339(str)
|
68
|
+
|
69
|
+
raise ArgumentError, "invalid date" if parts.empty?
|
70
|
+
|
71
|
+
Time.new(
|
72
|
+
parts.fetch(:year),
|
73
|
+
parts.fetch(:mon),
|
74
|
+
parts.fetch(:mday),
|
75
|
+
parts.fetch(:hour),
|
76
|
+
parts.fetch(:min),
|
77
|
+
parts.fetch(:sec) + parts.fetch(:sec_fraction, 0),
|
78
|
+
parts.fetch(:offset)
|
79
|
+
)
|
80
|
+
end
|
50
81
|
end
|
51
82
|
|
52
|
-
#
|
83
|
+
# Returns the number of seconds since 00:00:00.
|
84
|
+
#
|
85
|
+
# Time.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0.0
|
86
|
+
# Time.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296.0
|
87
|
+
# Time.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399.0
|
53
88
|
def seconds_since_midnight
|
54
|
-
to_i - change(:
|
89
|
+
to_i - change(hour: 0).to_i + (usec / 1.0e+6)
|
55
90
|
end
|
56
91
|
|
57
92
|
# Returns the number of seconds until 23:59:59.
|
@@ -74,36 +109,42 @@ class Time
|
|
74
109
|
# to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
|
75
110
|
# <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
|
76
111
|
# the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
|
77
|
-
# and minute is passed, then sec, usec and nsec is set to 0. The +options+
|
78
|
-
#
|
79
|
-
# <tt>:
|
80
|
-
# <tt>:
|
112
|
+
# and minute is passed, then sec, usec and nsec is set to 0. The +options+ parameter
|
113
|
+
# takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
|
114
|
+
# <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
|
115
|
+
# <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
|
81
116
|
#
|
82
117
|
# Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
|
83
118
|
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
|
84
119
|
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
|
85
120
|
def change(options)
|
86
|
-
new_year
|
87
|
-
new_month
|
88
|
-
new_day
|
89
|
-
new_hour
|
90
|
-
new_min
|
91
|
-
new_sec
|
121
|
+
new_year = options.fetch(:year, year)
|
122
|
+
new_month = options.fetch(:month, month)
|
123
|
+
new_day = options.fetch(:day, day)
|
124
|
+
new_hour = options.fetch(:hour, hour)
|
125
|
+
new_min = options.fetch(:min, options[:hour] ? 0 : min)
|
126
|
+
new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
|
127
|
+
new_offset = options.fetch(:offset, nil)
|
92
128
|
|
93
129
|
if new_nsec = options[:nsec]
|
94
130
|
raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
|
95
131
|
new_usec = Rational(new_nsec, 1000)
|
96
132
|
else
|
97
|
-
new_usec
|
133
|
+
new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
|
98
134
|
end
|
99
135
|
|
100
|
-
if
|
101
|
-
|
136
|
+
raise ArgumentError, "argument out of range" if new_usec >= 1000000
|
137
|
+
|
138
|
+
new_sec += Rational(new_usec, 1000000)
|
139
|
+
|
140
|
+
if new_offset
|
141
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
|
142
|
+
elsif utc?
|
143
|
+
::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
102
144
|
elsif zone
|
103
|
-
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec
|
145
|
+
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
104
146
|
else
|
105
|
-
|
106
|
-
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
|
147
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
|
107
148
|
end
|
108
149
|
end
|
109
150
|
|
@@ -131,7 +172,7 @@ class Time
|
|
131
172
|
|
132
173
|
d = to_date.advance(options)
|
133
174
|
d = d.gregorian if d.julian?
|
134
|
-
time_advanced_by_date = change(:
|
175
|
+
time_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
|
135
176
|
seconds_to_advance = \
|
136
177
|
options.fetch(:seconds, 0) +
|
137
178
|
options.fetch(:minutes, 0) * 60 +
|
@@ -159,8 +200,7 @@ class Time
|
|
159
200
|
|
160
201
|
# Returns a new Time representing the start of the day (0:00)
|
161
202
|
def beginning_of_day
|
162
|
-
|
163
|
-
change(:hour => 0)
|
203
|
+
change(hour: 0)
|
164
204
|
end
|
165
205
|
alias :midnight :beginning_of_day
|
166
206
|
alias :at_midnight :beginning_of_day
|
@@ -168,7 +208,7 @@ class Time
|
|
168
208
|
|
169
209
|
# Returns a new Time representing the middle of the day (12:00)
|
170
210
|
def middle_of_day
|
171
|
-
change(:
|
211
|
+
change(hour: 12)
|
172
212
|
end
|
173
213
|
alias :midday :middle_of_day
|
174
214
|
alias :noon :middle_of_day
|
@@ -176,53 +216,48 @@ class Time
|
|
176
216
|
alias :at_noon :middle_of_day
|
177
217
|
alias :at_middle_of_day :middle_of_day
|
178
218
|
|
179
|
-
# Returns a new Time representing the end of the day, 23:59:59.999999
|
219
|
+
# Returns a new Time representing the end of the day, 23:59:59.999999
|
180
220
|
def end_of_day
|
181
221
|
change(
|
182
|
-
:
|
183
|
-
:
|
184
|
-
:
|
185
|
-
:
|
222
|
+
hour: 23,
|
223
|
+
min: 59,
|
224
|
+
sec: 59,
|
225
|
+
usec: Rational(999999999, 1000)
|
186
226
|
)
|
187
227
|
end
|
188
228
|
alias :at_end_of_day :end_of_day
|
189
229
|
|
190
230
|
# Returns a new Time representing the start of the hour (x:00)
|
191
231
|
def beginning_of_hour
|
192
|
-
change(:
|
232
|
+
change(min: 0)
|
193
233
|
end
|
194
234
|
alias :at_beginning_of_hour :beginning_of_hour
|
195
235
|
|
196
|
-
# Returns a new Time representing the end of the hour, x:59:59.999999
|
236
|
+
# Returns a new Time representing the end of the hour, x:59:59.999999
|
197
237
|
def end_of_hour
|
198
238
|
change(
|
199
|
-
:
|
200
|
-
:
|
201
|
-
:
|
239
|
+
min: 59,
|
240
|
+
sec: 59,
|
241
|
+
usec: Rational(999999999, 1000)
|
202
242
|
)
|
203
243
|
end
|
204
244
|
alias :at_end_of_hour :end_of_hour
|
205
245
|
|
206
246
|
# Returns a new Time representing the start of the minute (x:xx:00)
|
207
247
|
def beginning_of_minute
|
208
|
-
change(:
|
248
|
+
change(sec: 0)
|
209
249
|
end
|
210
250
|
alias :at_beginning_of_minute :beginning_of_minute
|
211
251
|
|
212
|
-
# Returns a new Time representing the end of the minute, x:xx:59.999999
|
252
|
+
# Returns a new Time representing the end of the minute, x:xx:59.999999
|
213
253
|
def end_of_minute
|
214
254
|
change(
|
215
|
-
:
|
216
|
-
:
|
255
|
+
sec: 59,
|
256
|
+
usec: Rational(999999999, 1000)
|
217
257
|
)
|
218
258
|
end
|
219
259
|
alias :at_end_of_minute :end_of_minute
|
220
260
|
|
221
|
-
# Returns a Range representing the whole day of the current time.
|
222
|
-
def all_day
|
223
|
-
beginning_of_day..end_of_day
|
224
|
-
end
|
225
|
-
|
226
261
|
def plus_with_duration(other) #:nodoc:
|
227
262
|
if ActiveSupport::Duration === other
|
228
263
|
other.since(self)
|
@@ -256,7 +291,7 @@ class Time
|
|
256
291
|
# Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
|
257
292
|
# can be chronologically compared with a Time
|
258
293
|
def compare_with_coercion(other)
|
259
|
-
# we're avoiding Time#to_datetime
|
294
|
+
# we're avoiding Time#to_datetime and Time#to_time because they're expensive
|
260
295
|
if other.class == Time
|
261
296
|
compare_without_coercion(other)
|
262
297
|
elsif other.is_a?(Time)
|
@@ -277,5 +312,4 @@ class Time
|
|
277
312
|
end
|
278
313
|
alias_method :eql_without_coercion, :eql?
|
279
314
|
alias_method :eql?, :eql_with_coercion
|
280
|
-
|
281
315
|
end
|
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/core_ext/date_and_time/compatibility"
|
2
|
-
require "active_support/core_ext/module/
|
4
|
+
require "active_support/core_ext/module/redefine_method"
|
3
5
|
|
4
6
|
class Time
|
5
7
|
include DateAndTime::Compatibility
|
6
8
|
|
7
|
-
|
9
|
+
silence_redefinition_of_method :to_time
|
8
10
|
|
9
11
|
# Either return +self+ or the time in the local system timezone depending
|
10
12
|
# on the setting of +ActiveSupport.to_time_preserves_timezone+.
|
@@ -1,30 +1,33 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/inflector/methods"
|
4
|
+
require "active_support/values/time_zone"
|
3
5
|
|
4
6
|
class Time
|
5
7
|
DATE_FORMATS = {
|
6
|
-
:
|
7
|
-
:
|
8
|
-
:
|
9
|
-
:
|
10
|
-
:
|
11
|
-
:
|
12
|
-
:
|
8
|
+
db: "%Y-%m-%d %H:%M:%S",
|
9
|
+
number: "%Y%m%d%H%M%S",
|
10
|
+
nsec: "%Y%m%d%H%M%S%9N",
|
11
|
+
usec: "%Y%m%d%H%M%S%6N",
|
12
|
+
time: "%H:%M",
|
13
|
+
short: "%d %b %H:%M",
|
14
|
+
long: "%B %d, %Y %H:%M",
|
15
|
+
long_ordinal: lambda { |time|
|
13
16
|
day_format = ActiveSupport::Inflector.ordinalize(time.day)
|
14
17
|
time.strftime("%B #{day_format}, %Y %H:%M")
|
15
18
|
},
|
16
|
-
:
|
19
|
+
rfc822: lambda { |time|
|
17
20
|
offset_format = time.formatted_offset(false)
|
18
21
|
time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}")
|
19
22
|
},
|
20
|
-
:
|
23
|
+
iso8601: lambda { |time| time.iso8601 }
|
21
24
|
}
|
22
25
|
|
23
26
|
# Converts to a formatted string. See DATE_FORMATS for built-in formats.
|
24
27
|
#
|
25
28
|
# This method is aliased to <tt>to_s</tt>.
|
26
29
|
#
|
27
|
-
# time = Time.now # =>
|
30
|
+
# time = Time.now # => 2007-01-18 06:10:17 -06:00
|
28
31
|
#
|
29
32
|
# time.to_formatted_s(:time) # => "06:10"
|
30
33
|
# time.to_s(:time) # => "06:10"
|
@@ -55,11 +58,15 @@ class Time
|
|
55
58
|
alias_method :to_default_s, :to_s
|
56
59
|
alias_method :to_s, :to_formatted_s
|
57
60
|
|
58
|
-
# Returns the
|
61
|
+
# Returns a formatted string of the offset from UTC, or an alternative
|
62
|
+
# string if the time zone is already UTC.
|
59
63
|
#
|
60
64
|
# Time.local(2000).formatted_offset # => "-06:00"
|
61
65
|
# Time.local(2000).formatted_offset(false) # => "-0600"
|
62
66
|
def formatted_offset(colon = true, alternate_utc_string = nil)
|
63
67
|
utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
|
64
68
|
end
|
69
|
+
|
70
|
+
# Aliased to +xmlschema+ for compatibility with +DateTime+
|
71
|
+
alias_method :rfc3339, :xmlschema
|
65
72
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
require
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/time_with_zone"
|
4
|
+
require "active_support/core_ext/time/acts_like"
|
5
|
+
require "active_support/core_ext/date_and_time/zones"
|
4
6
|
|
5
7
|
class Time
|
6
8
|
include DateAndTime::Zones
|
@@ -26,7 +28,7 @@ class Time
|
|
26
28
|
# <tt>current_user.time_zone</tt> just needs to return a string identifying the user's preferred time zone:
|
27
29
|
#
|
28
30
|
# class ApplicationController < ActionController::Base
|
29
|
-
#
|
31
|
+
# around_action :set_time_zone
|
30
32
|
#
|
31
33
|
# def set_time_zone
|
32
34
|
# if logged_in?
|
@@ -40,7 +42,23 @@ class Time
|
|
40
42
|
Thread.current[:time_zone] = find_zone!(time_zone)
|
41
43
|
end
|
42
44
|
|
43
|
-
# Allows override of <tt>Time.zone</tt> locally inside supplied block;
|
45
|
+
# Allows override of <tt>Time.zone</tt> locally inside supplied block;
|
46
|
+
# resets <tt>Time.zone</tt> to existing value when done.
|
47
|
+
#
|
48
|
+
# class ApplicationController < ActionController::Base
|
49
|
+
# around_action :set_time_zone
|
50
|
+
#
|
51
|
+
# private
|
52
|
+
#
|
53
|
+
# def set_time_zone
|
54
|
+
# Time.use_zone(current_user.timezone) { yield }
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
|
59
|
+
# objects that have already been created, e.g. any model timestamp
|
60
|
+
# attributes that have been read before the block will remain in
|
61
|
+
# the application's default timezone.
|
44
62
|
def use_zone(time_zone)
|
45
63
|
new_zone = find_zone!(time_zone)
|
46
64
|
begin
|
@@ -51,12 +69,22 @@ class Time
|
|
51
69
|
end
|
52
70
|
end
|
53
71
|
|
54
|
-
# Returns a TimeZone instance
|
72
|
+
# Returns a TimeZone instance matching the time zone provided.
|
73
|
+
# Accepts the time zone in any format supported by <tt>Time.zone=</tt>.
|
74
|
+
# Raises an +ArgumentError+ for invalid time zones.
|
75
|
+
#
|
76
|
+
# Time.find_zone! "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
|
77
|
+
# Time.find_zone! "EST" # => #<ActiveSupport::TimeZone @name="EST" ...>
|
78
|
+
# Time.find_zone! -5.hours # => #<ActiveSupport::TimeZone @name="Bogota" ...>
|
79
|
+
# Time.find_zone! nil # => nil
|
80
|
+
# Time.find_zone! false # => false
|
81
|
+
# Time.find_zone! "NOT-A-TIMEZONE" # => ArgumentError: Invalid Timezone: NOT-A-TIMEZONE
|
55
82
|
def find_zone!(time_zone)
|
56
83
|
if !time_zone || time_zone.is_a?(ActiveSupport::TimeZone)
|
57
84
|
time_zone
|
58
85
|
else
|
59
|
-
#
|
86
|
+
# Look up the timezone based on the identifier (unless we've been
|
87
|
+
# passed a TZInfo::Timezone)
|
60
88
|
unless time_zone.respond_to?(:period_for_local)
|
61
89
|
time_zone = ActiveSupport::TimeZone[time_zone] || TZInfo::Timezone.get(time_zone)
|
62
90
|
end
|
@@ -72,6 +100,12 @@ class Time
|
|
72
100
|
raise ArgumentError, "Invalid Timezone: #{time_zone}"
|
73
101
|
end
|
74
102
|
|
103
|
+
# Returns a TimeZone instance matching the time zone provided.
|
104
|
+
# Accepts the time zone in any format supported by <tt>Time.zone=</tt>.
|
105
|
+
# Returns +nil+ for invalid time zones.
|
106
|
+
#
|
107
|
+
# Time.find_zone "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
|
108
|
+
# Time.find_zone "NOT-A-TIMEZONE" # => nil
|
75
109
|
def find_zone(time_zone)
|
76
110
|
find_zone!(time_zone) rescue nil
|
77
111
|
end
|