activesupport 4.2.11.3 → 5.0.7.2
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 +678 -348
- data/MIT-LICENSE +2 -2
- data/README.rdoc +2 -3
- data/lib/active_support/array_inquirer.rb +44 -0
- data/lib/active_support/backtrace_cleaner.rb +1 -1
- data/lib/active_support/benchmarkable.rb +1 -1
- data/lib/active_support/cache/file_store.rb +36 -22
- data/lib/active_support/cache/mem_cache_store.rb +63 -54
- data/lib/active_support/cache/memory_store.rb +16 -21
- data/lib/active_support/cache/null_store.rb +1 -4
- data/lib/active_support/cache/strategy/local_cache.rb +31 -20
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +4 -4
- data/lib/active_support/cache.rb +71 -87
- data/lib/active_support/callbacks.rb +109 -113
- data/lib/active_support/concern.rb +1 -1
- data/lib/active_support/concurrency/latch.rb +11 -12
- data/lib/active_support/concurrency/share_lock.rb +226 -0
- data/lib/active_support/configurable.rb +1 -0
- data/lib/active_support/core_ext/array/access.rb +27 -1
- data/lib/active_support/core_ext/array/conversions.rb +6 -4
- data/lib/active_support/core_ext/array/grouping.rb +9 -18
- data/lib/active_support/core_ext/array/inquiry.rb +17 -0
- data/lib/active_support/core_ext/array/wrap.rb +5 -4
- data/lib/active_support/core_ext/array.rb +1 -0
- data/lib/active_support/core_ext/big_decimal/conversions.rb +8 -10
- data/lib/active_support/core_ext/class/attribute.rb +10 -9
- data/lib/active_support/core_ext/class/subclasses.rb +3 -2
- data/lib/active_support/core_ext/class.rb +0 -1
- data/lib/active_support/core_ext/date/blank.rb +12 -0
- data/lib/active_support/core_ext/date/calculations.rb +1 -1
- data/lib/active_support/core_ext/date/conversions.rb +7 -6
- data/lib/active_support/core_ext/date.rb +1 -1
- data/lib/active_support/core_ext/date_and_time/calculations.rb +100 -27
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +0 -1
- data/lib/active_support/core_ext/date_and_time/zones.rb +3 -4
- data/lib/active_support/core_ext/date_time/blank.rb +12 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +14 -8
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -0
- data/lib/active_support/core_ext/date_time.rb +1 -1
- data/lib/active_support/core_ext/enumerable.rb +75 -25
- data/lib/active_support/core_ext/file/atomic.rb +30 -25
- data/lib/active_support/core_ext/hash/conversions.rb +22 -2
- data/lib/active_support/core_ext/hash/deep_merge.rb +1 -1
- data/lib/active_support/core_ext/hash/except.rb +9 -8
- data/lib/active_support/core_ext/hash/indifferent_access.rb +1 -1
- data/lib/active_support/core_ext/hash/keys.rb +25 -21
- data/lib/active_support/core_ext/hash/slice.rb +1 -1
- data/lib/active_support/core_ext/hash/transform_values.rb +11 -5
- data/lib/active_support/core_ext/integer/time.rb +2 -2
- data/lib/active_support/core_ext/kernel/concern.rb +2 -0
- data/lib/active_support/core_ext/kernel/debugger.rb +3 -10
- data/lib/active_support/core_ext/kernel/reporting.rb +2 -84
- data/lib/active_support/core_ext/kernel.rb +0 -1
- data/lib/active_support/core_ext/load_error.rb +5 -2
- data/lib/active_support/core_ext/marshal.rb +7 -9
- data/lib/active_support/core_ext/module/aliasing.rb +6 -1
- data/lib/active_support/core_ext/module/anonymous.rb +10 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +2 -5
- data/lib/active_support/core_ext/module/attribute_accessors.rb +15 -15
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
- data/lib/active_support/core_ext/module/concerning.rb +4 -4
- data/lib/active_support/core_ext/module/delegation.rb +11 -20
- data/lib/active_support/core_ext/module/deprecation.rb +2 -2
- data/lib/active_support/core_ext/module/introspection.rb +8 -2
- data/lib/active_support/core_ext/module/method_transplanting.rb +3 -13
- data/lib/active_support/core_ext/module/qualified_const.rb +30 -12
- data/lib/active_support/core_ext/module/remove_method.rb +23 -0
- data/lib/active_support/core_ext/module.rb +1 -0
- data/lib/active_support/core_ext/name_error.rb +15 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +20 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +78 -77
- data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
- data/lib/active_support/core_ext/numeric/time.rb +26 -6
- data/lib/active_support/core_ext/numeric.rb +1 -0
- data/lib/active_support/core_ext/object/blank.rb +15 -3
- data/lib/active_support/core_ext/object/deep_dup.rb +10 -3
- data/lib/active_support/core_ext/object/duplicable.rb +7 -12
- data/lib/active_support/core_ext/object/inclusion.rb +2 -2
- data/lib/active_support/core_ext/object/instance_variables.rb +1 -1
- data/lib/active_support/core_ext/object/json.rb +15 -7
- data/lib/active_support/core_ext/object/to_query.rb +1 -1
- data/lib/active_support/core_ext/object/try.rb +67 -21
- data/lib/active_support/core_ext/object/with_options.rb +1 -1
- data/lib/active_support/core_ext/object.rb +0 -1
- data/lib/active_support/core_ext/range/conversions.rb +18 -6
- data/lib/active_support/core_ext/range/each.rb +16 -18
- data/lib/active_support/core_ext/range/include_range.rb +20 -20
- data/lib/active_support/core_ext/securerandom.rb +23 -0
- data/lib/active_support/core_ext/string/behavior.rb +1 -1
- data/lib/active_support/core_ext/string/conversions.rb +3 -2
- data/lib/active_support/core_ext/string/filters.rb +1 -2
- data/lib/active_support/core_ext/string/inflections.rb +32 -5
- data/lib/active_support/core_ext/string/multibyte.rb +11 -7
- data/lib/active_support/core_ext/string/output_safety.rb +12 -14
- data/lib/active_support/core_ext/string/strip.rb +3 -6
- data/lib/active_support/core_ext/struct.rb +3 -6
- data/lib/active_support/core_ext/time/calculations.rb +18 -9
- data/lib/active_support/core_ext/time/conversions.rb +4 -2
- data/lib/active_support/core_ext/time/marshal.rb +2 -29
- data/lib/active_support/core_ext/time/zones.rb +36 -4
- data/lib/active_support/core_ext/time.rb +0 -1
- data/lib/active_support/core_ext/uri.rb +1 -3
- data/lib/active_support/core_ext.rb +2 -1
- data/lib/active_support/dependencies/interlock.rb +55 -0
- data/lib/active_support/dependencies.rb +88 -95
- data/lib/active_support/deprecation/behaviors.rb +15 -1
- data/lib/active_support/deprecation/instance_delegator.rb +13 -0
- data/lib/active_support/deprecation/method_wrappers.rb +42 -16
- data/lib/active_support/deprecation/proxy_wrappers.rb +47 -24
- data/lib/active_support/deprecation/reporting.rb +23 -5
- data/lib/active_support/deprecation.rb +1 -1
- data/lib/active_support/duration/iso8601_parser.rb +122 -0
- data/lib/active_support/duration/iso8601_serializer.rb +51 -0
- data/lib/active_support/duration.rb +90 -15
- data/lib/active_support/evented_file_update_checker.rb +199 -0
- data/lib/active_support/execution_wrapper.rb +126 -0
- data/lib/active_support/executor.rb +6 -0
- data/lib/active_support/file_update_checker.rb +23 -3
- data/lib/active_support/gem_version.rb +5 -5
- data/lib/active_support/gzip.rb +1 -1
- data/lib/active_support/hash_with_indifferent_access.rb +40 -11
- data/lib/active_support/i18n_railtie.rb +25 -4
- data/lib/active_support/inflector/inflections.rb +36 -5
- data/lib/active_support/inflector/methods.rb +97 -90
- data/lib/active_support/inflector/transliterate.rb +36 -21
- data/lib/active_support/json/decoding.rb +11 -10
- data/lib/active_support/json/encoding.rb +1 -51
- data/lib/active_support/key_generator.rb +7 -9
- data/lib/active_support/lazy_load_hooks.rb +46 -18
- data/lib/active_support/locale/en.yml +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +3 -3
- data/lib/active_support/log_subscriber.rb +1 -1
- data/lib/active_support/logger.rb +3 -4
- data/lib/active_support/logger_silence.rb +2 -1
- data/lib/active_support/logger_thread_safe_level.rb +2 -3
- data/lib/active_support/message_encryptor.rb +7 -7
- data/lib/active_support/message_verifier.rb +70 -8
- data/lib/active_support/multibyte/chars.rb +12 -3
- data/lib/active_support/multibyte/unicode.rb +44 -21
- data/lib/active_support/notifications/fanout.rb +5 -5
- data/lib/active_support/notifications/instrumenter.rb +20 -2
- data/lib/active_support/notifications.rb +2 -2
- data/lib/active_support/number_helper/number_to_currency_converter.rb +7 -9
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +8 -3
- data/lib/active_support/number_helper/number_to_human_converter.rb +6 -4
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -2
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +1 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +11 -2
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +30 -25
- data/lib/active_support/number_helper.rb +90 -67
- data/lib/active_support/ordered_hash.rb +1 -1
- data/lib/active_support/ordered_options.rb +15 -1
- data/lib/active_support/per_thread_registry.rb +3 -0
- data/lib/active_support/rails.rb +2 -2
- data/lib/active_support/railtie.rb +6 -1
- data/lib/active_support/reloader.rb +129 -0
- data/lib/active_support/rescuable.rb +101 -47
- data/lib/active_support/string_inquirer.rb +1 -1
- data/lib/active_support/subscriber.rb +5 -10
- data/lib/active_support/tagged_logging.rb +8 -7
- data/lib/active_support/test_case.rb +17 -29
- data/lib/active_support/testing/assertions.rb +15 -13
- data/lib/active_support/testing/deprecation.rb +9 -8
- data/lib/active_support/testing/file_fixtures.rb +34 -0
- data/lib/active_support/testing/isolation.rb +22 -8
- data/lib/active_support/testing/method_call_assertions.rb +41 -0
- data/lib/active_support/testing/stream.rb +42 -0
- data/lib/active_support/testing/time_helpers.rb +3 -1
- data/lib/active_support/time_with_zone.rb +123 -33
- data/lib/active_support/values/time_zone.rb +101 -47
- data/lib/active_support/values/unicode_tables.dat +0 -0
- data/lib/active_support/xml_mini/jdom.rb +1 -1
- data/lib/active_support/xml_mini/libxml.rb +2 -2
- data/lib/active_support/xml_mini/nokogiri.rb +2 -2
- data/lib/active_support.rb +11 -6
- metadata +36 -17
- 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/object/itself.rb +0 -15
- data/lib/active_support/core_ext/thread.rb +0 -86
@@ -1,19 +1,31 @@
|
|
1
|
-
|
1
|
+
module ActiveSupport::RangeWithFormat
|
2
2
|
RANGE_FORMATS = {
|
3
3
|
:db => Proc.new { |start, stop| "BETWEEN '#{start.to_s(:db)}' AND '#{stop.to_s(:db)}'" }
|
4
4
|
}
|
5
5
|
|
6
|
-
#
|
6
|
+
# Convert range to a formatted string. See RANGE_FORMATS for predefined formats.
|
7
7
|
#
|
8
|
-
# (1..100)
|
9
|
-
|
8
|
+
# range = (1..100) # => 1..100
|
9
|
+
#
|
10
|
+
# range.to_s # => "1..100"
|
11
|
+
# range.to_s(:db) # => "BETWEEN '1' AND '100'"
|
12
|
+
#
|
13
|
+
# == Adding your own range formats to to_s
|
14
|
+
# You can add your own formats to the Range::RANGE_FORMATS hash.
|
15
|
+
# Use the format name as the hash key and a Proc instance.
|
16
|
+
#
|
17
|
+
# # config/initializers/range_formats.rb
|
18
|
+
# Range::RANGE_FORMATS[:short] = ->(start, stop) { "Between #{start.to_s(:db)} and #{stop.to_s(:db)}" }
|
19
|
+
def to_s(format = :default)
|
10
20
|
if formatter = RANGE_FORMATS[format]
|
11
21
|
formatter.call(first, last)
|
12
22
|
else
|
13
|
-
|
23
|
+
super()
|
14
24
|
end
|
15
25
|
end
|
16
26
|
|
17
27
|
alias_method :to_default_s, :to_s
|
18
|
-
alias_method :
|
28
|
+
alias_method :to_formatted_s, :to_s
|
19
29
|
end
|
30
|
+
|
31
|
+
Range.prepend(ActiveSupport::RangeWithFormat)
|
@@ -1,23 +1,21 @@
|
|
1
|
-
|
1
|
+
module ActiveSupport
|
2
|
+
module EachTimeWithZone #:nodoc:
|
3
|
+
def each(&block)
|
4
|
+
ensure_iteration_allowed
|
5
|
+
super
|
6
|
+
end
|
2
7
|
|
3
|
-
|
8
|
+
def step(n = 1, &block)
|
9
|
+
ensure_iteration_allowed
|
10
|
+
super
|
11
|
+
end
|
4
12
|
|
5
|
-
|
6
|
-
ensure_iteration_allowed
|
7
|
-
each_without_time_with_zone(&block)
|
8
|
-
end
|
9
|
-
alias_method_chain :each, :time_with_zone
|
13
|
+
private
|
10
14
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
15
|
-
alias_method_chain :step, :time_with_zone
|
16
|
-
|
17
|
-
private
|
18
|
-
def ensure_iteration_allowed
|
19
|
-
if first.is_a?(Time)
|
20
|
-
raise TypeError, "can't iterate from #{first.class}"
|
21
|
-
end
|
15
|
+
def ensure_iteration_allowed
|
16
|
+
raise TypeError, "can't iterate from #{first.class}" if first.is_a?(Time)
|
17
|
+
end
|
22
18
|
end
|
23
19
|
end
|
20
|
+
|
21
|
+
Range.prepend(ActiveSupport::EachTimeWithZone)
|
@@ -1,23 +1,23 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
1
|
+
module ActiveSupport
|
2
|
+
module IncludeWithRange #:nodoc:
|
3
|
+
# Extends the default Range#include? to support range comparisons.
|
4
|
+
# (1..5).include?(1..5) # => true
|
5
|
+
# (1..5).include?(2..3) # => true
|
6
|
+
# (1..5).include?(2..6) # => false
|
7
|
+
#
|
8
|
+
# The native Range#include? behavior is untouched.
|
9
|
+
# ('a'..'f').include?('c') # => true
|
10
|
+
# (5..9).include?(11) # => false
|
11
|
+
def include?(value)
|
12
|
+
if value.is_a?(::Range)
|
13
|
+
# 1...10 includes 1..9 but it does not include 1..10.
|
14
|
+
operator = exclude_end? && !value.exclude_end? ? :< : :<=
|
15
|
+
super(value.first) && value.last.send(operator, last)
|
16
|
+
else
|
17
|
+
super
|
18
|
+
end
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
22
|
-
alias_method_chain :include?, :range
|
23
21
|
end
|
22
|
+
|
23
|
+
Range.prepend(ActiveSupport::IncludeWithRange)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module SecureRandom
|
4
|
+
BASE58_ALPHABET = ('0'..'9').to_a + ('A'..'Z').to_a + ('a'..'z').to_a - ['0', 'O', 'I', 'l']
|
5
|
+
# SecureRandom.base58 generates a random base58 string.
|
6
|
+
#
|
7
|
+
# The argument _n_ specifies the length, of the random string to be generated.
|
8
|
+
#
|
9
|
+
# If _n_ is not specified or is nil, 16 is assumed. It may be larger in the future.
|
10
|
+
#
|
11
|
+
# The result may contain alphanumeric characters except 0, O, I and l
|
12
|
+
#
|
13
|
+
# p SecureRandom.base58 # => "4kUgL2pdQMSCQtjE"
|
14
|
+
# p SecureRandom.base58(24) # => "77TMHrHJFvFDwodq8w7Ev2m7"
|
15
|
+
#
|
16
|
+
def self.base58(n = 16)
|
17
|
+
SecureRandom.random_bytes(n).unpack("C*").map do |byte|
|
18
|
+
idx = byte % 64
|
19
|
+
idx = SecureRandom.random_number(58) if idx >= 58
|
20
|
+
BASE58_ALPHABET[idx]
|
21
|
+
end.join
|
22
|
+
end
|
23
|
+
end
|
@@ -14,11 +14,12 @@ class String
|
|
14
14
|
# "06:12".to_time # => 2012-12-13 06:12:00 +0100
|
15
15
|
# "2012-12-13 06:12".to_time # => 2012-12-13 06:12:00 +0100
|
16
16
|
# "2012-12-13T06:12".to_time # => 2012-12-13 06:12:00 +0100
|
17
|
-
# "2012-12-13T06:12".to_time(:utc) # => 2012-12-13
|
17
|
+
# "2012-12-13T06:12".to_time(:utc) # => 2012-12-13 06:12:00 UTC
|
18
18
|
# "12/13/2012".to_time # => ArgumentError: argument out of range
|
19
19
|
def to_time(form = :local)
|
20
20
|
parts = Date._parse(self, false)
|
21
|
-
|
21
|
+
used_keys = %i(year mon mday hour min sec sec_fraction offset)
|
22
|
+
return if (parts.keys & used_keys).empty?
|
22
23
|
|
23
24
|
now = Time.now
|
24
25
|
time = Time.new(
|
@@ -164,25 +164,43 @@ class String
|
|
164
164
|
#
|
165
165
|
# <%= link_to(@person.name, person_path) %>
|
166
166
|
# # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
|
167
|
-
|
168
|
-
|
167
|
+
#
|
168
|
+
# To preserve the case of the characters in a string, use the `preserve_case` argument.
|
169
|
+
#
|
170
|
+
# class Person
|
171
|
+
# def to_param
|
172
|
+
# "#{id}-#{name.parameterize(preserve_case: true)}"
|
173
|
+
# end
|
174
|
+
# end
|
175
|
+
#
|
176
|
+
# @person = Person.find(1)
|
177
|
+
# # => #<Person id: 1, name: "Donald E. Knuth">
|
178
|
+
#
|
179
|
+
# <%= link_to(@person.name, person_path) %>
|
180
|
+
# # => <a href="/person/1-Donald-E-Knuth">Donald E. Knuth</a>
|
181
|
+
def parameterize(sep = :unused, separator: '-', preserve_case: false)
|
182
|
+
unless sep == :unused
|
183
|
+
ActiveSupport::Deprecation.warn("Passing the separator argument as a positional parameter is deprecated and will soon be removed. Use `separator: '#{sep}'` instead.")
|
184
|
+
separator = sep
|
185
|
+
end
|
186
|
+
ActiveSupport::Inflector.parameterize(self, separator: separator, preserve_case: preserve_case)
|
169
187
|
end
|
170
188
|
|
171
189
|
# Creates the name of a table like Rails does for models to table names. This method
|
172
190
|
# uses the +pluralize+ method on the last word in the string.
|
173
191
|
#
|
174
192
|
# 'RawScaledScorer'.tableize # => "raw_scaled_scorers"
|
175
|
-
# '
|
193
|
+
# 'ham_and_egg'.tableize # => "ham_and_eggs"
|
176
194
|
# 'fancyCategory'.tableize # => "fancy_categories"
|
177
195
|
def tableize
|
178
196
|
ActiveSupport::Inflector.tableize(self)
|
179
197
|
end
|
180
198
|
|
181
|
-
#
|
199
|
+
# Creates a class name from a plural table name like Rails does for table names to models.
|
182
200
|
# Note that this returns a string and not a class. (To convert to an actual class
|
183
201
|
# follow +classify+ with +constantize+.)
|
184
202
|
#
|
185
|
-
# '
|
203
|
+
# 'ham_and_eggs'.classify # => "HamAndEgg"
|
186
204
|
# 'posts'.classify # => "Post"
|
187
205
|
def classify
|
188
206
|
ActiveSupport::Inflector.classify(self)
|
@@ -204,6 +222,15 @@ class String
|
|
204
222
|
ActiveSupport::Inflector.humanize(self, options)
|
205
223
|
end
|
206
224
|
|
225
|
+
# Converts just the first character to uppercase.
|
226
|
+
#
|
227
|
+
# 'what a Lovely Day'.upcase_first # => "What a Lovely Day"
|
228
|
+
# 'w'.upcase_first # => "W"
|
229
|
+
# ''.upcase_first # => ""
|
230
|
+
def upcase_first
|
231
|
+
ActiveSupport::Inflector.upcase_first(self)
|
232
|
+
end
|
233
|
+
|
207
234
|
# Creates a foreign key name from a class name.
|
208
235
|
# +separate_class_name_and_id_with_underscore+ sets whether
|
209
236
|
# the method should put '_' between the name and 'id'.
|
@@ -1,4 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
1
|
require 'active_support/multibyte'
|
3
2
|
|
4
3
|
class String
|
@@ -10,12 +9,10 @@ class String
|
|
10
9
|
# encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy
|
11
10
|
# class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string.
|
12
11
|
#
|
13
|
-
#
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
# name.mb_chars.reverse.to_s # => "rellüM sualC"
|
18
|
-
# name.mb_chars.length # => 12
|
12
|
+
# >> "lj".upcase
|
13
|
+
# => "lj"
|
14
|
+
# >> "lj".mb_chars.upcase.to_s
|
15
|
+
# => "LJ"
|
19
16
|
#
|
20
17
|
# == Method chaining
|
21
18
|
#
|
@@ -36,6 +33,13 @@ class String
|
|
36
33
|
ActiveSupport::Multibyte.proxy_class.new(self)
|
37
34
|
end
|
38
35
|
|
36
|
+
# Returns +true+ if string has utf_8 encoding.
|
37
|
+
#
|
38
|
+
# utf_8_str = "some string".encode "UTF-8"
|
39
|
+
# iso_str = "some string".encode "ISO-8859-1"
|
40
|
+
#
|
41
|
+
# utf_8_str.is_utf8? # => true
|
42
|
+
# iso_str.is_utf8? # => false
|
39
43
|
def is_utf8?
|
40
44
|
case encoding
|
41
45
|
when Encoding::UTF_8
|
@@ -1,12 +1,10 @@
|
|
1
1
|
require 'erb'
|
2
2
|
require 'active_support/core_ext/kernel/singleton_class'
|
3
|
-
require 'active_support/deprecation'
|
4
3
|
|
5
4
|
class ERB
|
6
5
|
module Util
|
7
6
|
HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"', "'" => ''' }
|
8
7
|
JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003e', '<' => '\u003c', "\u2028" => '\u2028', "\u2029" => '\u2029' }
|
9
|
-
HTML_ESCAPE_REGEXP = /[&"'><]/
|
10
8
|
HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/
|
11
9
|
JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u
|
12
10
|
|
@@ -14,7 +12,7 @@ class ERB
|
|
14
12
|
# This method is also aliased as <tt>h</tt>.
|
15
13
|
#
|
16
14
|
# In your ERB templates, use this method to escape any unsafe content. For example:
|
17
|
-
# <%=h @person.name %>
|
15
|
+
# <%= h @person.name %>
|
18
16
|
#
|
19
17
|
# puts html_escape('is a > 0 & a < 10?')
|
20
18
|
# # => is a > 0 & a < 10?
|
@@ -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,6 +141,7 @@ 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
147
|
super 'Could not concatenate to the buffer because it is not html safe.'
|
@@ -167,7 +171,7 @@ module ActiveSupport #:nodoc:
|
|
167
171
|
original_concat(value)
|
168
172
|
end
|
169
173
|
|
170
|
-
def initialize(
|
174
|
+
def initialize(str = '')
|
171
175
|
@html_safe = true
|
172
176
|
super
|
173
177
|
end
|
@@ -190,11 +194,6 @@ module ActiveSupport #:nodoc:
|
|
190
194
|
super(html_escape_interpolated_argument(value))
|
191
195
|
end
|
192
196
|
|
193
|
-
def prepend!(value)
|
194
|
-
ActiveSupport::Deprecation.deprecation_warning "ActiveSupport::SafeBuffer#prepend!", :prepend
|
195
|
-
prepend value
|
196
|
-
end
|
197
|
-
|
198
197
|
def +(other)
|
199
198
|
dup.concat(other)
|
200
199
|
end
|
@@ -244,15 +243,14 @@ module ActiveSupport #:nodoc:
|
|
244
243
|
private
|
245
244
|
|
246
245
|
def html_escape_interpolated_argument(arg)
|
247
|
-
(!html_safe? || arg.html_safe?) ? arg :
|
248
|
-
arg.to_s.gsub(ERB::Util::HTML_ESCAPE_REGEXP, ERB::Util::HTML_ESCAPE)
|
246
|
+
(!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s)
|
249
247
|
end
|
250
248
|
end
|
251
249
|
end
|
252
250
|
|
253
251
|
class String
|
254
252
|
# Marks a string as trusted safe. It will be inserted into HTML with no
|
255
|
-
# additional escaping performed. It is your
|
253
|
+
# additional escaping performed. It is your responsibility to ensure that the
|
256
254
|
# string contains no malicious content. This method is equivalent to the
|
257
255
|
# `raw` helper in views. It is recommended that you use `sanitize` instead of
|
258
256
|
# this method. It should never be called on user input.
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'active_support/core_ext/object/try'
|
2
|
-
|
3
1
|
class String
|
4
2
|
# Strips indentation in heredocs.
|
5
3
|
#
|
@@ -17,10 +15,9 @@ class String
|
|
17
15
|
#
|
18
16
|
# the user would see the usage message aligned against the left margin.
|
19
17
|
#
|
20
|
-
# Technically, it looks for the least indented line
|
21
|
-
# that amount of leading whitespace.
|
18
|
+
# Technically, it looks for the least indented non-empty line
|
19
|
+
# in the whole string, and removes that amount of leading whitespace.
|
22
20
|
def strip_heredoc
|
23
|
-
|
24
|
-
gsub(/^[ \t]{#{indent}}/, '')
|
21
|
+
gsub(/^#{scan(/^[ \t]*(?=\S)/).min}/, ''.freeze)
|
25
22
|
end
|
26
23
|
end
|
@@ -1,6 +1,3 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
Hash[members.zip(values)]
|
5
|
-
end
|
6
|
-
end unless Struct.instance_methods.include?(:to_h)
|
1
|
+
require 'active_support/deprecation'
|
2
|
+
|
3
|
+
ActiveSupport::Deprecation.warn("This file is deprecated and will be removed in Rails 5.1 with no replacement.")
|
@@ -16,9 +16,9 @@ class Time
|
|
16
16
|
super || (self == Time && other.is_a?(ActiveSupport::TimeWithZone))
|
17
17
|
end
|
18
18
|
|
19
|
-
#
|
19
|
+
# Returns the number of days in the given month.
|
20
20
|
# If no year is specified, it will use the current year.
|
21
|
-
def days_in_month(month, year =
|
21
|
+
def days_in_month(month, year = current.year)
|
22
22
|
if month == 2 && ::Date.gregorian_leap?(year)
|
23
23
|
29
|
24
24
|
else
|
@@ -26,6 +26,12 @@ class Time
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
+
# Returns the number of days in the given year.
|
30
|
+
# If no year is specified, it will use the current year.
|
31
|
+
def days_in_year(year = current.year)
|
32
|
+
days_in_month(2, year) + 337
|
33
|
+
end
|
34
|
+
|
29
35
|
# 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
36
|
def current
|
31
37
|
::Time.zone ? ::Time.zone.now : ::Time.now
|
@@ -49,7 +55,11 @@ class Time
|
|
49
55
|
alias_method :at, :at_with_coercion
|
50
56
|
end
|
51
57
|
|
52
|
-
#
|
58
|
+
# Returns the number of seconds since 00:00:00.
|
59
|
+
#
|
60
|
+
# Time.new(2012, 8, 29, 0, 0, 0).seconds_since_midnight # => 0.0
|
61
|
+
# Time.new(2012, 8, 29, 12, 34, 56).seconds_since_midnight # => 45296.0
|
62
|
+
# Time.new(2012, 8, 29, 23, 59, 59).seconds_since_midnight # => 86399.0
|
53
63
|
def seconds_since_midnight
|
54
64
|
to_i - change(:hour => 0).to_i + (usec / 1.0e+6)
|
55
65
|
end
|
@@ -77,7 +87,7 @@ class Time
|
|
77
87
|
# and minute is passed, then sec, usec and nsec is set to 0. The +options+
|
78
88
|
# parameter takes a hash with any of these keys: <tt>:year</tt>, <tt>:month</tt>,
|
79
89
|
# <tt>:day</tt>, <tt>:hour</tt>, <tt>:min</tt>, <tt>:sec</tt>, <tt>:usec</tt>
|
80
|
-
# <tt>:nsec</tt>.
|
90
|
+
# <tt>:nsec</tt>. Pass either <tt>:usec</tt> or <tt>:nsec</tt>, not both.
|
81
91
|
#
|
82
92
|
# Time.new(2012, 8, 29, 22, 35, 0).change(day: 1) # => Time.new(2012, 8, 1, 22, 35, 0)
|
83
93
|
# Time.new(2012, 8, 29, 22, 35, 0).change(year: 1981, day: 1) # => Time.new(1981, 8, 1, 22, 35, 0)
|
@@ -159,7 +169,6 @@ class Time
|
|
159
169
|
|
160
170
|
# Returns a new Time representing the start of the day (0:00)
|
161
171
|
def beginning_of_day
|
162
|
-
#(self - seconds_since_midnight).change(usec: 0)
|
163
172
|
change(:hour => 0)
|
164
173
|
end
|
165
174
|
alias :midnight :beginning_of_day
|
@@ -176,7 +185,7 @@ class Time
|
|
176
185
|
alias :at_noon :middle_of_day
|
177
186
|
alias :at_middle_of_day :middle_of_day
|
178
187
|
|
179
|
-
# Returns a new Time representing the end of the day, 23:59:59.999999
|
188
|
+
# Returns a new Time representing the end of the day, 23:59:59.999999
|
180
189
|
def end_of_day
|
181
190
|
change(
|
182
191
|
:hour => 23,
|
@@ -193,7 +202,7 @@ class Time
|
|
193
202
|
end
|
194
203
|
alias :at_beginning_of_hour :beginning_of_hour
|
195
204
|
|
196
|
-
# Returns a new Time representing the end of the hour, x:59:59.999999
|
205
|
+
# Returns a new Time representing the end of the hour, x:59:59.999999
|
197
206
|
def end_of_hour
|
198
207
|
change(
|
199
208
|
:min => 59,
|
@@ -209,7 +218,7 @@ class Time
|
|
209
218
|
end
|
210
219
|
alias :at_beginning_of_minute :beginning_of_minute
|
211
220
|
|
212
|
-
# Returns a new Time representing the end of the minute, x:xx:59.999999
|
221
|
+
# Returns a new Time representing the end of the minute, x:xx:59.999999
|
213
222
|
def end_of_minute
|
214
223
|
change(
|
215
224
|
:sec => 59,
|
@@ -256,7 +265,7 @@ class Time
|
|
256
265
|
# Layers additional behavior on Time#<=> so that DateTime and ActiveSupport::TimeWithZone instances
|
257
266
|
# can be chronologically compared with a Time
|
258
267
|
def compare_with_coercion(other)
|
259
|
-
# we're avoiding Time#to_datetime
|
268
|
+
# we're avoiding Time#to_datetime and Time#to_time because they're expensive
|
260
269
|
if other.class == Time
|
261
270
|
compare_without_coercion(other)
|
262
271
|
elsif other.is_a?(Time)
|
@@ -6,6 +6,7 @@ class Time
|
|
6
6
|
:db => '%Y-%m-%d %H:%M:%S',
|
7
7
|
:number => '%Y%m%d%H%M%S',
|
8
8
|
:nsec => '%Y%m%d%H%M%S%9N',
|
9
|
+
:usec => '%Y%m%d%H%M%S%6N',
|
9
10
|
:time => '%H:%M',
|
10
11
|
:short => '%d %b %H:%M',
|
11
12
|
:long => '%B %d, %Y %H:%M',
|
@@ -24,7 +25,7 @@ class Time
|
|
24
25
|
#
|
25
26
|
# This method is aliased to <tt>to_s</tt>.
|
26
27
|
#
|
27
|
-
# time = Time.now # =>
|
28
|
+
# time = Time.now # => 2007-01-18 06:10:17 -06:00
|
28
29
|
#
|
29
30
|
# time.to_formatted_s(:time) # => "06:10"
|
30
31
|
# time.to_s(:time) # => "06:10"
|
@@ -55,7 +56,8 @@ class Time
|
|
55
56
|
alias_method :to_default_s, :to_s
|
56
57
|
alias_method :to_s, :to_formatted_s
|
57
58
|
|
58
|
-
# Returns the
|
59
|
+
# Returns a formatted string of the offset from UTC, or an alternative
|
60
|
+
# string if the time zone is already UTC.
|
59
61
|
#
|
60
62
|
# Time.local(2000).formatted_offset # => "-06:00"
|
61
63
|
# Time.local(2000).formatted_offset(false) # => "-0600"
|
@@ -1,30 +1,3 @@
|
|
1
|
-
|
2
|
-
# preserves utc_offset. Preserve zone also, even though it may not
|
3
|
-
# work in some edge cases.
|
4
|
-
if Time.local(2010).zone != Marshal.load(Marshal.dump(Time.local(2010))).zone
|
5
|
-
class Time
|
6
|
-
class << self
|
7
|
-
alias_method :_load_without_zone, :_load
|
8
|
-
def _load(marshaled_time)
|
9
|
-
time = _load_without_zone(marshaled_time)
|
10
|
-
time.instance_eval do
|
11
|
-
if zone = defined?(@_zone) && remove_instance_variable('@_zone')
|
12
|
-
ary = to_a
|
13
|
-
ary[0] += subsec if ary[0] == sec
|
14
|
-
ary[-1] = zone
|
15
|
-
utc? ? Time.utc(*ary) : Time.local(*ary)
|
16
|
-
else
|
17
|
-
self
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
1
|
+
require 'active_support/deprecation'
|
22
2
|
|
23
|
-
|
24
|
-
def _dump(*args)
|
25
|
-
obj = dup
|
26
|
-
obj.instance_variable_set('@_zone', zone)
|
27
|
-
obj.send :_dump_without_zone, *args
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
3
|
+
ActiveSupport::Deprecation.warn("This is deprecated and will be removed in Rails 5.1 with no replacement.")
|
@@ -26,7 +26,7 @@ class Time
|
|
26
26
|
# <tt>current_user.time_zone</tt> just needs to return a string identifying the user's preferred time zone:
|
27
27
|
#
|
28
28
|
# class ApplicationController < ActionController::Base
|
29
|
-
#
|
29
|
+
# around_action :set_time_zone
|
30
30
|
#
|
31
31
|
# def set_time_zone
|
32
32
|
# if logged_in?
|
@@ -40,7 +40,23 @@ class Time
|
|
40
40
|
Thread.current[:time_zone] = find_zone!(time_zone)
|
41
41
|
end
|
42
42
|
|
43
|
-
# Allows override of <tt>Time.zone</tt> locally inside supplied block;
|
43
|
+
# Allows override of <tt>Time.zone</tt> locally inside supplied block;
|
44
|
+
# resets <tt>Time.zone</tt> to existing value when done.
|
45
|
+
#
|
46
|
+
# class ApplicationController < ActionController::Base
|
47
|
+
# around_action :set_time_zone
|
48
|
+
#
|
49
|
+
# private
|
50
|
+
#
|
51
|
+
# def set_time_zone
|
52
|
+
# Time.use_zone(current_user.timezone) { yield }
|
53
|
+
# end
|
54
|
+
# end
|
55
|
+
#
|
56
|
+
# NOTE: This won't affect any <tt>ActiveSupport::TimeWithZone</tt>
|
57
|
+
# objects that have already been created, e.g. any model timestamp
|
58
|
+
# attributes that have been read before the block will remain in
|
59
|
+
# the application's default timezone.
|
44
60
|
def use_zone(time_zone)
|
45
61
|
new_zone = find_zone!(time_zone)
|
46
62
|
begin
|
@@ -51,12 +67,22 @@ class Time
|
|
51
67
|
end
|
52
68
|
end
|
53
69
|
|
54
|
-
# Returns a TimeZone instance
|
70
|
+
# Returns a TimeZone instance matching the time zone provided.
|
71
|
+
# Accepts the time zone in any format supported by <tt>Time.zone=</tt>.
|
72
|
+
# Raises an +ArgumentError+ for invalid time zones.
|
73
|
+
#
|
74
|
+
# Time.find_zone! "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
|
75
|
+
# Time.find_zone! "EST" # => #<ActiveSupport::TimeZone @name="EST" ...>
|
76
|
+
# Time.find_zone! -5.hours # => #<ActiveSupport::TimeZone @name="Bogota" ...>
|
77
|
+
# Time.find_zone! nil # => nil
|
78
|
+
# Time.find_zone! false # => false
|
79
|
+
# Time.find_zone! "NOT-A-TIMEZONE" # => ArgumentError: Invalid Timezone: NOT-A-TIMEZONE
|
55
80
|
def find_zone!(time_zone)
|
56
81
|
if !time_zone || time_zone.is_a?(ActiveSupport::TimeZone)
|
57
82
|
time_zone
|
58
83
|
else
|
59
|
-
#
|
84
|
+
# Look up the timezone based on the identifier (unless we've been
|
85
|
+
# passed a TZInfo::Timezone)
|
60
86
|
unless time_zone.respond_to?(:period_for_local)
|
61
87
|
time_zone = ActiveSupport::TimeZone[time_zone] || TZInfo::Timezone.get(time_zone)
|
62
88
|
end
|
@@ -72,6 +98,12 @@ class Time
|
|
72
98
|
raise ArgumentError, "Invalid Timezone: #{time_zone}"
|
73
99
|
end
|
74
100
|
|
101
|
+
# Returns a TimeZone instance matching the time zone provided.
|
102
|
+
# Accepts the time zone in any format supported by <tt>Time.zone=</tt>.
|
103
|
+
# Returns +nil+ for invalid time zones.
|
104
|
+
#
|
105
|
+
# Time.find_zone "America/New_York" # => #<ActiveSupport::TimeZone @name="America/New_York" ...>
|
106
|
+
# Time.find_zone "NOT-A-TIMEZONE" # => nil
|
75
107
|
def find_zone(time_zone)
|
76
108
|
find_zone!(time_zone) rescue nil
|
77
109
|
end
|
@@ -2,5 +2,4 @@ require 'active_support/core_ext/time/acts_like'
|
|
2
2
|
require 'active_support/core_ext/time/calculations'
|
3
3
|
require 'active_support/core_ext/time/compatibility'
|
4
4
|
require 'active_support/core_ext/time/conversions'
|
5
|
-
require 'active_support/core_ext/time/marshal'
|
6
5
|
require 'active_support/core_ext/time/zones'
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
1
|
require 'uri'
|
4
2
|
str = "\xE6\x97\xA5\xE6\x9C\xAC\xE8\xAA\x9E" # Ni-ho-nn-go in UTF-8, means Japanese.
|
5
3
|
parser = URI::Parser.new
|
@@ -12,7 +10,7 @@ unless str == parser.unescape(parser.escape(str))
|
|
12
10
|
# YK: My initial experiments say yes, but let's be sure please
|
13
11
|
enc = str.encoding
|
14
12
|
enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
|
15
|
-
str.gsub(escaped) { [
|
13
|
+
str.gsub(escaped) { |match| [match[1, 2].hex].pack('C') }.force_encoding(enc)
|
16
14
|
end
|
17
15
|
end
|
18
16
|
end
|