activesupport 5.0.0 → 6.1.0
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 +5 -5
- data/CHANGELOG.md +343 -590
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -4
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +11 -5
- data/lib/active_support/backtrace_cleaner.rb +33 -5
- data/lib/active_support/benchmarkable.rb +5 -3
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +45 -53
- data/lib/active_support/cache/mem_cache_store.rb +81 -79
- data/lib/active_support/cache/memory_store.rb +69 -41
- data/lib/active_support/cache/null_store.rb +11 -4
- data/lib/active_support/cache/redis_cache_store.rb +493 -0
- data/lib/active_support/cache/strategy/local_cache.rb +74 -37
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
- data/lib/active_support/cache.rb +332 -161
- data/lib/active_support/callbacks.rb +657 -586
- data/lib/active_support/concern.rb +79 -6
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
- data/lib/active_support/concurrency/share_lock.rb +59 -19
- data/lib/active_support/configurable.rb +15 -17
- data/lib/active_support/configuration_file.rb +46 -0
- data/lib/active_support/core_ext/array/access.rb +21 -7
- data/lib/active_support/core_ext/array/conversions.rb +20 -18
- data/lib/active_support/core_ext/array/extract.rb +21 -0
- data/lib/active_support/core_ext/array/extract_options.rb +2 -0
- data/lib/active_support/core_ext/array/grouping.rb +3 -1
- data/lib/active_support/core_ext/array/inquiry.rb +3 -1
- data/lib/active_support/core_ext/array/wrap.rb +2 -0
- data/lib/active_support/core_ext/array.rb +9 -7
- data/lib/active_support/core_ext/benchmark.rb +5 -3
- data/lib/active_support/core_ext/big_decimal/conversions.rb +6 -6
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +52 -49
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
- data/lib/active_support/core_ext/class/subclasses.rb +18 -26
- data/lib/active_support/core_ext/class.rb +4 -2
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +3 -1
- data/lib/active_support/core_ext/date/calculations.rb +16 -13
- data/lib/active_support/core_ext/date/conversions.rb +23 -21
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date.rb +7 -5
- data/lib/active_support/core_ext/date_and_time/calculations.rb +82 -53
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -5
- data/lib/active_support/core_ext/date_and_time/zones.rb +9 -9
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +3 -1
- data/lib/active_support/core_ext/date_time/calculations.rb +23 -11
- data/lib/active_support/core_ext/date_time/compatibility.rb +15 -2
- data/lib/active_support/core_ext/date_time/conversions.rb +14 -13
- 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 +165 -29
- data/lib/active_support/core_ext/file/atomic.rb +7 -5
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/conversions.rb +40 -39
- data/lib/active_support/core_ext/hash/deep_merge.rb +8 -12
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +4 -2
- data/lib/active_support/core_ext/hash/indifferent_access.rb +3 -2
- data/lib/active_support/core_ext/hash/keys.rb +9 -36
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +8 -29
- data/lib/active_support/core_ext/hash.rb +10 -9
- data/lib/active_support/core_ext/integer/inflections.rb +3 -1
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- 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/concern.rb +3 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +3 -1
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +5 -4
- data/lib/active_support/core_ext/load_error.rb +2 -23
- data/lib/active_support/core_ext/marshal.rb +6 -2
- data/lib/active_support/core_ext/module/aliasing.rb +5 -48
- data/lib/active_support/core_ext/module/anonymous.rb +2 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +7 -5
- data/lib/active_support/core_ext/module/attribute_accessors.rb +53 -59
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +31 -24
- data/lib/active_support/core_ext/module/concerning.rb +16 -11
- data/lib/active_support/core_ext/module/delegation.rb +159 -44
- data/lib/active_support/core_ext/module/deprecation.rb +2 -0
- data/lib/active_support/core_ext/module/introspection.rb +23 -26
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +5 -23
- data/lib/active_support/core_ext/module.rb +13 -12
- data/lib/active_support/core_ext/name_error.rb +36 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +2 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +129 -134
- data/lib/active_support/core_ext/numeric/time.rb +18 -26
- data/lib/active_support/core_ext/numeric.rb +5 -4
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +14 -2
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +4 -2
- data/lib/active_support/core_ext/object/duplicable.rb +13 -62
- data/lib/active_support/core_ext/object/inclusion.rb +3 -1
- data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
- data/lib/active_support/core_ext/object/json.rb +42 -15
- 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 +20 -8
- data/lib/active_support/core_ext/object/with_options.rb +15 -2
- data/lib/active_support/core_ext/object.rb +14 -12
- data/lib/active_support/core_ext/range/compare_range.rb +82 -0
- data/lib/active_support/core_ext/range/conversions.rb +35 -25
- data/lib/active_support/core_ext/range/each.rb +5 -2
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +28 -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 +10 -1
- data/lib/active_support/core_ext/securerandom.rb +28 -6
- data/lib/active_support/core_ext/string/access.rb +9 -18
- data/lib/active_support/core_ext/string/behavior.rb +2 -0
- data/lib/active_support/core_ext/string/conversions.rb +5 -2
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +47 -4
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +78 -29
- data/lib/active_support/core_ext/string/inquiry.rb +4 -1
- data/lib/active_support/core_ext/string/multibyte.rb +10 -5
- data/lib/active_support/core_ext/string/output_safety.rb +86 -31
- data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
- data/lib/active_support/core_ext/string/strip.rb +5 -1
- 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/symbol/starts_ends_with.rb +14 -0
- data/lib/active_support/core_ext/symbol.rb +3 -0
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +117 -45
- data/lib/active_support/core_ext/time/compatibility.rb +13 -2
- data/lib/active_support/core_ext/time/conversions.rb +18 -12
- data/lib/active_support/core_ext/time/zones.rb +9 -7
- data/lib/active_support/core_ext/time.rb +7 -5
- data/lib/active_support/core_ext/uri.rb +12 -7
- data/lib/active_support/core_ext.rb +3 -2
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +208 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +7 -1
- data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
- data/lib/active_support/dependencies.rb +172 -98
- data/lib/active_support/deprecation/behaviors.rb +45 -13
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +16 -2
- data/lib/active_support/deprecation/method_wrappers.rb +32 -17
- data/lib/active_support/deprecation/proxy_wrappers.rb +35 -7
- data/lib/active_support/deprecation/reporting.rb +61 -16
- data/lib/active_support/deprecation.rb +17 -9
- data/lib/active_support/descendants_tracker.rb +61 -9
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +67 -66
- data/lib/active_support/duration/iso8601_serializer.rb +25 -17
- data/lib/active_support/duration.rb +349 -46
- data/lib/active_support/encrypted_configuration.rb +45 -0
- data/lib/active_support/encrypted_file.rb +117 -0
- data/lib/active_support/environment_inquirer.rb +20 -0
- data/lib/active_support/evented_file_update_checker.rb +88 -112
- data/lib/active_support/execution_wrapper.rb +25 -13
- data/lib/active_support/executor.rb +3 -1
- data/lib/active_support/file_update_checker.rb +56 -51
- data/lib/active_support/fork_tracker.rb +62 -0
- data/lib/active_support/gem_version.rb +4 -2
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +153 -49
- data/lib/active_support/i18n.rb +9 -6
- data/lib/active_support/i18n_railtie.rb +30 -20
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector/inflections.rb +28 -15
- data/lib/active_support/inflector/methods.rb +120 -109
- data/lib/active_support/inflector/transliterate.rb +60 -25
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/json/decoding.rb +30 -29
- data/lib/active_support/json/encoding.rb +22 -11
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +6 -36
- data/lib/active_support/lazy_load_hooks.rb +53 -20
- data/lib/active_support/locale/en.rb +33 -0
- data/lib/active_support/locale/en.yml +7 -3
- data/lib/active_support/log_subscriber/test_helper.rb +11 -9
- data/lib/active_support/log_subscriber.rb +51 -18
- data/lib/active_support/logger.rb +9 -22
- data/lib/active_support/logger_silence.rb +14 -21
- data/lib/active_support/logger_thread_safe_level.rb +55 -8
- data/lib/active_support/message_encryptor.rb +170 -53
- data/lib/active_support/message_verifier.rb +91 -20
- data/lib/active_support/messages/metadata.rb +80 -0
- data/lib/active_support/messages/rotation_configuration.rb +23 -0
- data/lib/active_support/messages/rotator.rb +57 -0
- data/lib/active_support/multibyte/chars.rb +24 -78
- data/lib/active_support/multibyte/unicode.rb +21 -352
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/notifications/fanout.rb +121 -19
- data/lib/active_support/notifications/instrumenter.rb +78 -14
- data/lib/active_support/notifications.rb +80 -12
- data/lib/active_support/number_helper/number_converter.rb +17 -16
- data/lib/active_support/number_helper/number_to_currency_converter.rb +6 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +5 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +13 -12
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +11 -13
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +5 -4
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +18 -55
- data/lib/active_support/number_helper/rounding_helper.rb +50 -0
- data/lib/active_support/number_helper.rb +45 -16
- data/lib/active_support/option_merger.rb +25 -4
- data/lib/active_support/ordered_hash.rb +6 -4
- data/lib/active_support/ordered_options.rb +23 -9
- data/lib/active_support/parameter_filter.rb +133 -0
- data/lib/active_support/per_thread_registry.rb +7 -5
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +8 -9
- data/lib/active_support/railtie.rb +62 -11
- data/lib/active_support/reloader.rb +12 -11
- data/lib/active_support/rescuable.rb +20 -11
- data/lib/active_support/secure_compare_rotator.rb +51 -0
- data/lib/active_support/security_utils.rb +26 -15
- data/lib/active_support/string_inquirer.rb +12 -3
- data/lib/active_support/subscriber.rb +77 -23
- data/lib/active_support/tagged_logging.rb +52 -17
- data/lib/active_support/test_case.rb +106 -29
- data/lib/active_support/testing/assertions.rb +144 -8
- data/lib/active_support/testing/autorun.rb +5 -10
- 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 +4 -2
- data/lib/active_support/testing/file_fixtures.rb +4 -0
- data/lib/active_support/testing/isolation.rb +19 -24
- data/lib/active_support/testing/method_call_assertions.rb +31 -2
- data/lib/active_support/testing/parallelization/server.rb +78 -0
- data/lib/active_support/testing/parallelization/worker.rb +100 -0
- data/lib/active_support/testing/parallelization.rb +51 -0
- data/lib/active_support/testing/setup_and_teardown.rb +13 -8
- data/lib/active_support/testing/stream.rb +30 -29
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +125 -24
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +142 -55
- data/lib/active_support/values/time_zone.rb +160 -53
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +115 -114
- data/lib/active_support/xml_mini/libxml.rb +15 -14
- data/lib/active_support/xml_mini/libxmlsax.rb +16 -18
- data/lib/active_support/xml_mini/nokogiri.rb +13 -13
- data/lib/active_support/xml_mini/nokogirisax.rb +15 -16
- data/lib/active_support/xml_mini/rexml.rb +18 -9
- data/lib/active_support/xml_mini.rb +44 -42
- data/lib/active_support.rb +19 -10
- metadata +79 -37
- data/lib/active_support/concurrency/latch.rb +0 -19
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
- data/lib/active_support/core_ext/hash/compact.rb +0 -20
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -29
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -3
- data/lib/active_support/core_ext/module/method_transplanting.rb +0 -3
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -70
- data/lib/active_support/core_ext/module/reachable.rb +0 -8
- data/lib/active_support/core_ext/numeric/inquiry.rb +0 -26
- data/lib/active_support/core_ext/range/include_range.rb +0 -23
- data/lib/active_support/core_ext/struct.rb +0 -3
- data/lib/active_support/core_ext/time/marshal.rb +0 -3
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,32 +1,31 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "erb"
|
4
|
+
require "active_support/core_ext/module/redefine_method"
|
5
|
+
require "active_support/multibyte/unicode"
|
3
6
|
|
4
7
|
class ERB
|
5
8
|
module Util
|
6
|
-
HTML_ESCAPE = {
|
7
|
-
JSON_ESCAPE = {
|
9
|
+
HTML_ESCAPE = { "&" => "&", ">" => ">", "<" => "<", '"' => """, "'" => "'" }
|
10
|
+
JSON_ESCAPE = { "&" => '\u0026', ">" => '\u003e', "<" => '\u003c', "\u2028" => '\u2028', "\u2029" => '\u2029' }
|
8
11
|
HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/
|
9
12
|
JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u
|
10
13
|
|
11
14
|
# A utility method for escaping HTML tag characters.
|
12
15
|
# This method is also aliased as <tt>h</tt>.
|
13
16
|
#
|
14
|
-
# In your ERB templates, use this method to escape any unsafe content. For example:
|
15
|
-
# <%= h @person.name %>
|
16
|
-
#
|
17
17
|
# puts html_escape('is a > 0 & a < 10?')
|
18
18
|
# # => is a > 0 & a < 10?
|
19
19
|
def html_escape(s)
|
20
20
|
unwrapped_html_escape(s).html_safe
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
|
-
remove_method(:h)
|
23
|
+
silence_redefinition_of_method :h
|
25
24
|
alias h html_escape
|
26
25
|
|
27
26
|
module_function :h
|
28
27
|
|
29
|
-
singleton_class.
|
28
|
+
singleton_class.silence_redefinition_of_method :html_escape
|
30
29
|
module_function :html_escape
|
31
30
|
|
32
31
|
# HTML escapes strings but doesn't wrap them with an ActiveSupport::SafeBuffer.
|
@@ -134,35 +133,34 @@ end
|
|
134
133
|
module ActiveSupport #:nodoc:
|
135
134
|
class SafeBuffer < String
|
136
135
|
UNSAFE_STRING_METHODS = %w(
|
137
|
-
capitalize chomp chop delete
|
138
|
-
|
136
|
+
capitalize chomp chop delete delete_prefix delete_suffix
|
137
|
+
downcase lstrip next reverse rstrip scrub slice squeeze strip
|
138
|
+
succ swapcase tr tr_s unicode_normalize upcase
|
139
139
|
)
|
140
140
|
|
141
|
+
UNSAFE_STRING_METHODS_WITH_BACKREF = %w(gsub sub)
|
142
|
+
|
141
143
|
alias_method :original_concat, :concat
|
142
144
|
private :original_concat
|
143
145
|
|
144
146
|
# Raised when <tt>ActiveSupport::SafeBuffer#safe_concat</tt> is called on unsafe buffers.
|
145
147
|
class SafeConcatError < StandardError
|
146
148
|
def initialize
|
147
|
-
super
|
149
|
+
super "Could not concatenate to the buffer because it is not html safe."
|
148
150
|
end
|
149
151
|
end
|
150
152
|
|
151
153
|
def [](*args)
|
152
|
-
if
|
153
|
-
super
|
154
|
-
else
|
155
|
-
if html_safe?
|
156
|
-
new_safe_buffer = super
|
154
|
+
if html_safe?
|
155
|
+
new_string = super
|
157
156
|
|
158
|
-
|
159
|
-
new_safe_buffer.instance_variable_set :@html_safe, true
|
160
|
-
end
|
157
|
+
return unless new_string
|
161
158
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
159
|
+
new_safe_buffer = new_string.is_a?(SafeBuffer) ? new_string : SafeBuffer.new(new_string)
|
160
|
+
new_safe_buffer.instance_variable_set :@html_safe, true
|
161
|
+
new_safe_buffer
|
162
|
+
else
|
163
|
+
to_str[*args]
|
166
164
|
end
|
167
165
|
end
|
168
166
|
|
@@ -171,7 +169,7 @@ module ActiveSupport #:nodoc:
|
|
171
169
|
original_concat(value)
|
172
170
|
end
|
173
171
|
|
174
|
-
def initialize(str =
|
172
|
+
def initialize(str = "")
|
175
173
|
@html_safe = true
|
176
174
|
super
|
177
175
|
end
|
@@ -190,18 +188,41 @@ module ActiveSupport #:nodoc:
|
|
190
188
|
end
|
191
189
|
alias << concat
|
192
190
|
|
191
|
+
def insert(index, value)
|
192
|
+
super(index, html_escape_interpolated_argument(value))
|
193
|
+
end
|
194
|
+
|
193
195
|
def prepend(value)
|
194
196
|
super(html_escape_interpolated_argument(value))
|
195
197
|
end
|
196
198
|
|
199
|
+
def replace(value)
|
200
|
+
super(html_escape_interpolated_argument(value))
|
201
|
+
end
|
202
|
+
|
203
|
+
def []=(*args)
|
204
|
+
if args.length == 3
|
205
|
+
super(args[0], args[1], html_escape_interpolated_argument(args[2]))
|
206
|
+
else
|
207
|
+
super(args[0], html_escape_interpolated_argument(args[1]))
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
197
211
|
def +(other)
|
198
212
|
dup.concat(other)
|
199
213
|
end
|
200
214
|
|
215
|
+
def *(*)
|
216
|
+
new_string = super
|
217
|
+
new_safe_buffer = new_string.is_a?(SafeBuffer) ? new_string : SafeBuffer.new(new_string)
|
218
|
+
new_safe_buffer.instance_variable_set(:@html_safe, @html_safe)
|
219
|
+
new_safe_buffer
|
220
|
+
end
|
221
|
+
|
201
222
|
def %(args)
|
202
223
|
case args
|
203
224
|
when Hash
|
204
|
-
escaped_args =
|
225
|
+
escaped_args = args.transform_values { |arg| html_escape_interpolated_argument(arg) }
|
205
226
|
else
|
206
227
|
escaped_args = Array(args).map { |arg| html_escape_interpolated_argument(arg) }
|
207
228
|
end
|
@@ -240,11 +261,45 @@ module ActiveSupport #:nodoc:
|
|
240
261
|
end
|
241
262
|
end
|
242
263
|
|
264
|
+
UNSAFE_STRING_METHODS_WITH_BACKREF.each do |unsafe_method|
|
265
|
+
if unsafe_method.respond_to?(unsafe_method)
|
266
|
+
class_eval <<-EOT, __FILE__, __LINE__ + 1
|
267
|
+
def #{unsafe_method}(*args, &block) # def gsub(*args, &block)
|
268
|
+
if block # if block
|
269
|
+
to_str.#{unsafe_method}(*args) { |*params| # to_str.gsub(*args) { |*params|
|
270
|
+
set_block_back_references(block, $~) # set_block_back_references(block, $~)
|
271
|
+
block.call(*params) # block.call(*params)
|
272
|
+
} # }
|
273
|
+
else # else
|
274
|
+
to_str.#{unsafe_method}(*args) # to_str.gsub(*args)
|
275
|
+
end # end
|
276
|
+
end # end
|
277
|
+
|
278
|
+
def #{unsafe_method}!(*args, &block) # def gsub!(*args, &block)
|
279
|
+
@html_safe = false # @html_safe = false
|
280
|
+
if block # if block
|
281
|
+
super(*args) { |*params| # super(*args) { |*params|
|
282
|
+
set_block_back_references(block, $~) # set_block_back_references(block, $~)
|
283
|
+
block.call(*params) # block.call(*params)
|
284
|
+
} # }
|
285
|
+
else # else
|
286
|
+
super # super
|
287
|
+
end # end
|
288
|
+
end # end
|
289
|
+
EOT
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
243
293
|
private
|
294
|
+
def html_escape_interpolated_argument(arg)
|
295
|
+
(!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s)
|
296
|
+
end
|
244
297
|
|
245
|
-
|
246
|
-
|
247
|
-
|
298
|
+
def set_block_back_references(block, match_data)
|
299
|
+
block.binding.eval("proc { |m| $~ = m }").call(match_data)
|
300
|
+
rescue ArgumentError
|
301
|
+
# Can't create binding from C level Proc
|
302
|
+
end
|
248
303
|
end
|
249
304
|
end
|
250
305
|
|
@@ -252,7 +307,7 @@ class String
|
|
252
307
|
# Marks a string as trusted safe. It will be inserted into HTML with no
|
253
308
|
# additional escaping performed. It is your responsibility to ensure that the
|
254
309
|
# string contains no malicious content. This method is equivalent to the
|
255
|
-
#
|
310
|
+
# +raw+ helper in views. It is recommended that you use +sanitize+ instead of
|
256
311
|
# this method. It should never be called on user input.
|
257
312
|
def html_safe
|
258
313
|
ActiveSupport::SafeBuffer.new(self)
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
class String
|
2
4
|
# Strips indentation in heredocs.
|
3
5
|
#
|
@@ -18,6 +20,8 @@ class String
|
|
18
20
|
# Technically, it looks for the least indented non-empty line
|
19
21
|
# in the whole string, and removes that amount of leading whitespace.
|
20
22
|
def strip_heredoc
|
21
|
-
gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/,
|
23
|
+
gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, "").tap do |stripped|
|
24
|
+
stripped.freeze if frozen?
|
25
|
+
end
|
22
26
|
end
|
23
27
|
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"
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Symbol
|
4
|
+
def start_with?(*prefixes)
|
5
|
+
to_s.start_with?(*prefixes)
|
6
|
+
end unless method_defined?(:start_with?)
|
7
|
+
|
8
|
+
def end_with?(*suffixes)
|
9
|
+
to_s.end_with?(*suffixes)
|
10
|
+
end unless method_defined?(:end_with?)
|
11
|
+
|
12
|
+
alias :starts_with? :start_with?
|
13
|
+
alias :ends_with? :end_with?
|
14
|
+
end
|
@@ -1,9 +1,12 @@
|
|
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"
|
9
|
+
require "active_support/core_ext/module/remove_method"
|
7
10
|
|
8
11
|
class Time
|
9
12
|
include DateAndTime::Calculations
|
@@ -45,7 +48,9 @@ class Time
|
|
45
48
|
# Time.at can be called with a time or numerical value
|
46
49
|
time_or_number = args.first
|
47
50
|
|
48
|
-
if time_or_number.is_a?(ActiveSupport::TimeWithZone)
|
51
|
+
if time_or_number.is_a?(ActiveSupport::TimeWithZone)
|
52
|
+
at_without_coercion(time_or_number.to_r).getlocal
|
53
|
+
elsif time_or_number.is_a?(DateTime)
|
49
54
|
at_without_coercion(time_or_number.to_f).getlocal
|
50
55
|
else
|
51
56
|
at_without_coercion(time_or_number)
|
@@ -53,6 +58,29 @@ class Time
|
|
53
58
|
end
|
54
59
|
alias_method :at_without_coercion, :at
|
55
60
|
alias_method :at, :at_with_coercion
|
61
|
+
|
62
|
+
# Creates a +Time+ instance from an RFC 3339 string.
|
63
|
+
#
|
64
|
+
# Time.rfc3339('1999-12-31T14:00:00-10:00') # => 2000-01-01 00:00:00 -1000
|
65
|
+
#
|
66
|
+
# If the time or offset components are missing then an +ArgumentError+ will be raised.
|
67
|
+
#
|
68
|
+
# Time.rfc3339('1999-12-31') # => ArgumentError: invalid date
|
69
|
+
def rfc3339(str)
|
70
|
+
parts = Date._rfc3339(str)
|
71
|
+
|
72
|
+
raise ArgumentError, "invalid date" if parts.empty?
|
73
|
+
|
74
|
+
Time.new(
|
75
|
+
parts.fetch(:year),
|
76
|
+
parts.fetch(:mon),
|
77
|
+
parts.fetch(:mday),
|
78
|
+
parts.fetch(:hour),
|
79
|
+
parts.fetch(:min),
|
80
|
+
parts.fetch(:sec) + parts.fetch(:sec_fraction, 0),
|
81
|
+
parts.fetch(:offset)
|
82
|
+
)
|
83
|
+
end
|
56
84
|
end
|
57
85
|
|
58
86
|
# Returns the number of seconds since 00:00:00.
|
@@ -61,7 +89,7 @@ class Time
|
|
61
89
|
# Time.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296.0
|
62
90
|
# Time.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399.0
|
63
91
|
def seconds_since_midnight
|
64
|
-
to_i - change(:
|
92
|
+
to_i - change(hour: 0).to_i + (usec / 1.0e+6)
|
65
93
|
end
|
66
94
|
|
67
95
|
# Returns the number of seconds until 23:59:59.
|
@@ -80,40 +108,61 @@ class Time
|
|
80
108
|
subsec
|
81
109
|
end
|
82
110
|
|
111
|
+
unless Time.method_defined?(:floor)
|
112
|
+
def floor(precision = 0)
|
113
|
+
change(nsec: 0) + subsec.floor(precision)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# Restricted Ruby version due to a bug in `Time#ceil`
|
118
|
+
# See https://bugs.ruby-lang.org/issues/17025 for more details
|
119
|
+
if RUBY_VERSION <= "2.8"
|
120
|
+
remove_possible_method :ceil
|
121
|
+
def ceil(precision = 0)
|
122
|
+
change(nsec: 0) + subsec.ceil(precision)
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
83
126
|
# Returns a new Time where one or more of the elements have been changed according
|
84
127
|
# to the +options+ parameter. The time options (<tt>:hour</tt>, <tt>:min</tt>,
|
85
128
|
# <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>) reset cascadingly, so if only
|
86
129
|
# the hour is passed, then minute, sec, usec and nsec is set to 0. If the hour
|
87
|
-
# and minute is passed, then sec, usec and nsec is set to 0. The +options+
|
88
|
-
#
|
89
|
-
# <tt>:
|
90
|
-
# <tt>:
|
130
|
+
# and minute is passed, then sec, usec and nsec is set to 0. The +options+ parameter
|
131
|
+
# takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>,
|
132
|
+
# <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>, <tt>:nsec</tt>,
|
133
|
+
# <tt>:offset</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
|
91
134
|
#
|
92
135
|
# Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
|
93
136
|
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
|
94
137
|
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, hour: 0) # => Time.new(1981, 8, 29, 0, 0, 0)
|
95
138
|
def change(options)
|
96
|
-
new_year
|
97
|
-
new_month
|
98
|
-
new_day
|
99
|
-
new_hour
|
100
|
-
new_min
|
101
|
-
new_sec
|
139
|
+
new_year = options.fetch(:year, year)
|
140
|
+
new_month = options.fetch(:month, month)
|
141
|
+
new_day = options.fetch(:day, day)
|
142
|
+
new_hour = options.fetch(:hour, hour)
|
143
|
+
new_min = options.fetch(:min, options[:hour] ? 0 : min)
|
144
|
+
new_sec = options.fetch(:sec, (options[:hour] || options[:min]) ? 0 : sec)
|
145
|
+
new_offset = options.fetch(:offset, nil)
|
102
146
|
|
103
147
|
if new_nsec = options[:nsec]
|
104
148
|
raise ArgumentError, "Can't change both :nsec and :usec at the same time: #{options.inspect}" if options[:usec]
|
105
149
|
new_usec = Rational(new_nsec, 1000)
|
106
150
|
else
|
107
|
-
new_usec
|
151
|
+
new_usec = options.fetch(:usec, (options[:hour] || options[:min] || options[:sec]) ? 0 : Rational(nsec, 1000))
|
108
152
|
end
|
109
153
|
|
110
|
-
if
|
111
|
-
|
154
|
+
raise ArgumentError, "argument out of range" if new_usec >= 1000000
|
155
|
+
|
156
|
+
new_sec += Rational(new_usec, 1000000)
|
157
|
+
|
158
|
+
if new_offset
|
159
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, new_offset)
|
160
|
+
elsif utc?
|
161
|
+
::Time.utc(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
112
162
|
elsif zone
|
113
|
-
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec
|
163
|
+
::Time.local(new_year, new_month, new_day, new_hour, new_min, new_sec)
|
114
164
|
else
|
115
|
-
|
116
|
-
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec + (new_usec.to_r / 1000000), utc_offset)
|
165
|
+
::Time.new(new_year, new_month, new_day, new_hour, new_min, new_sec, utc_offset)
|
117
166
|
end
|
118
167
|
end
|
119
168
|
|
@@ -139,9 +188,8 @@ class Time
|
|
139
188
|
options[:hours] = options.fetch(:hours, 0) + 24 * partial_days
|
140
189
|
end
|
141
190
|
|
142
|
-
d = to_date.advance(options)
|
143
|
-
|
144
|
-
time_advanced_by_date = change(:year => d.year, :month => d.month, :day => d.day)
|
191
|
+
d = to_date.gregorian.advance(options)
|
192
|
+
time_advanced_by_date = change(year: d.year, month: d.month, day: d.day)
|
145
193
|
seconds_to_advance = \
|
146
194
|
options.fetch(:seconds, 0) +
|
147
195
|
options.fetch(:minutes, 0) * 60 +
|
@@ -169,7 +217,7 @@ class Time
|
|
169
217
|
|
170
218
|
# Returns a new Time representing the start of the day (0:00)
|
171
219
|
def beginning_of_day
|
172
|
-
change(:
|
220
|
+
change(hour: 0)
|
173
221
|
end
|
174
222
|
alias :midnight :beginning_of_day
|
175
223
|
alias :at_midnight :beginning_of_day
|
@@ -177,7 +225,7 @@ class Time
|
|
177
225
|
|
178
226
|
# Returns a new Time representing the middle of the day (12:00)
|
179
227
|
def middle_of_day
|
180
|
-
change(:
|
228
|
+
change(hour: 12)
|
181
229
|
end
|
182
230
|
alias :midday :middle_of_day
|
183
231
|
alias :noon :middle_of_day
|
@@ -188,50 +236,45 @@ class Time
|
|
188
236
|
# Returns a new Time representing the end of the day, 23:59:59.999999
|
189
237
|
def end_of_day
|
190
238
|
change(
|
191
|
-
:
|
192
|
-
:
|
193
|
-
:
|
194
|
-
:
|
239
|
+
hour: 23,
|
240
|
+
min: 59,
|
241
|
+
sec: 59,
|
242
|
+
usec: Rational(999999999, 1000)
|
195
243
|
)
|
196
244
|
end
|
197
245
|
alias :at_end_of_day :end_of_day
|
198
246
|
|
199
247
|
# Returns a new Time representing the start of the hour (x:00)
|
200
248
|
def beginning_of_hour
|
201
|
-
change(:
|
249
|
+
change(min: 0)
|
202
250
|
end
|
203
251
|
alias :at_beginning_of_hour :beginning_of_hour
|
204
252
|
|
205
253
|
# Returns a new Time representing the end of the hour, x:59:59.999999
|
206
254
|
def end_of_hour
|
207
255
|
change(
|
208
|
-
:
|
209
|
-
:
|
210
|
-
:
|
256
|
+
min: 59,
|
257
|
+
sec: 59,
|
258
|
+
usec: Rational(999999999, 1000)
|
211
259
|
)
|
212
260
|
end
|
213
261
|
alias :at_end_of_hour :end_of_hour
|
214
262
|
|
215
263
|
# Returns a new Time representing the start of the minute (x:xx:00)
|
216
264
|
def beginning_of_minute
|
217
|
-
change(:
|
265
|
+
change(sec: 0)
|
218
266
|
end
|
219
267
|
alias :at_beginning_of_minute :beginning_of_minute
|
220
268
|
|
221
269
|
# Returns a new Time representing the end of the minute, x:xx:59.999999
|
222
270
|
def end_of_minute
|
223
271
|
change(
|
224
|
-
:
|
225
|
-
:
|
272
|
+
sec: 59,
|
273
|
+
usec: Rational(999999999, 1000)
|
226
274
|
)
|
227
275
|
end
|
228
276
|
alias :at_end_of_minute :end_of_minute
|
229
277
|
|
230
|
-
# Returns a Range representing the whole day of the current time.
|
231
|
-
def all_day
|
232
|
-
beginning_of_day..end_of_day
|
233
|
-
end
|
234
|
-
|
235
278
|
def plus_with_duration(other) #:nodoc:
|
236
279
|
if ActiveSupport::Duration === other
|
237
280
|
other.since(self)
|
@@ -287,4 +330,33 @@ class Time
|
|
287
330
|
alias_method :eql_without_coercion, :eql?
|
288
331
|
alias_method :eql?, :eql_with_coercion
|
289
332
|
|
333
|
+
# Returns a new time the specified number of days ago.
|
334
|
+
def prev_day(days = 1)
|
335
|
+
advance(days: -days)
|
336
|
+
end
|
337
|
+
|
338
|
+
# Returns a new time the specified number of days in the future.
|
339
|
+
def next_day(days = 1)
|
340
|
+
advance(days: days)
|
341
|
+
end
|
342
|
+
|
343
|
+
# Returns a new time the specified number of months ago.
|
344
|
+
def prev_month(months = 1)
|
345
|
+
advance(months: -months)
|
346
|
+
end
|
347
|
+
|
348
|
+
# Returns a new time the specified number of months in the future.
|
349
|
+
def next_month(months = 1)
|
350
|
+
advance(months: months)
|
351
|
+
end
|
352
|
+
|
353
|
+
# Returns a new time the specified number of years ago.
|
354
|
+
def prev_year(years = 1)
|
355
|
+
advance(years: -years)
|
356
|
+
end
|
357
|
+
|
358
|
+
# Returns a new time the specified number of years in the future.
|
359
|
+
def next_year(years = 1)
|
360
|
+
advance(years: years)
|
361
|
+
end
|
290
362
|
end
|
@@ -1,5 +1,16 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/date_and_time/compatibility"
|
4
|
+
require "active_support/core_ext/module/redefine_method"
|
2
5
|
|
3
6
|
class Time
|
4
|
-
|
7
|
+
include DateAndTime::Compatibility
|
8
|
+
|
9
|
+
silence_redefinition_of_method :to_time
|
10
|
+
|
11
|
+
# Either return +self+ or the time in the local system timezone depending
|
12
|
+
# on the setting of +ActiveSupport.to_time_preserves_timezone+.
|
13
|
+
def to_time
|
14
|
+
preserve_timezone ? self : getlocal
|
15
|
+
end
|
5
16
|
end
|
@@ -1,24 +1,27 @@
|
|
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
|
-
:
|
13
|
-
:
|
8
|
+
db: "%Y-%m-%d %H:%M:%S",
|
9
|
+
inspect: "%Y-%m-%d %H:%M:%S.%9N %z",
|
10
|
+
number: "%Y%m%d%H%M%S",
|
11
|
+
nsec: "%Y%m%d%H%M%S%9N",
|
12
|
+
usec: "%Y%m%d%H%M%S%6N",
|
13
|
+
time: "%H:%M",
|
14
|
+
short: "%d %b %H:%M",
|
15
|
+
long: "%B %d, %Y %H:%M",
|
16
|
+
long_ordinal: lambda { |time|
|
14
17
|
day_format = ActiveSupport::Inflector.ordinalize(time.day)
|
15
18
|
time.strftime("%B #{day_format}, %Y %H:%M")
|
16
19
|
},
|
17
|
-
:
|
20
|
+
rfc822: lambda { |time|
|
18
21
|
offset_format = time.formatted_offset(false)
|
19
22
|
time.strftime("%a, %d %b %Y %H:%M:%S #{offset_format}")
|
20
23
|
},
|
21
|
-
:
|
24
|
+
iso8601: lambda { |time| time.iso8601 }
|
22
25
|
}
|
23
26
|
|
24
27
|
# Converts to a formatted string. See DATE_FORMATS for built-in formats.
|
@@ -64,4 +67,7 @@ class Time
|
|
64
67
|
def formatted_offset(colon = true, alternate_utc_string = nil)
|
65
68
|
utc? && alternate_utc_string || ActiveSupport::TimeZone.seconds_to_utc_offset(utc_offset, colon)
|
66
69
|
end
|
70
|
+
|
71
|
+
# Aliased to +xmlschema+ for compatibility with +DateTime+
|
72
|
+
alias_method :rfc3339, :xmlschema
|
67
73
|
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
|
@@ -53,10 +55,10 @@ class Time
|
|
53
55
|
# end
|
54
56
|
# end
|
55
57
|
#
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
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.
|
60
62
|
def use_zone(time_zone)
|
61
63
|
new_zone = find_zone!(time_zone)
|
62
64
|
begin
|