activesupport 5.1.7 → 6.1.7
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 +434 -490
- data/MIT-LICENSE +1 -1
- data/README.rdoc +6 -5
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +2 -0
- data/lib/active_support/array_inquirer.rb +6 -2
- data/lib/active_support/backtrace_cleaner.rb +31 -3
- data/lib/active_support/benchmarkable.rb +3 -1
- data/lib/active_support/builder.rb +2 -0
- data/lib/active_support/cache/file_store.rb +37 -36
- data/lib/active_support/cache/mem_cache_store.rb +72 -56
- data/lib/active_support/cache/memory_store.rb +61 -33
- data/lib/active_support/cache/null_store.rb +10 -3
- data/lib/active_support/cache/redis_cache_store.rb +493 -0
- data/lib/active_support/cache/strategy/local_cache.rb +67 -21
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +2 -0
- data/lib/active_support/cache.rb +310 -126
- data/lib/active_support/callbacks.rb +106 -100
- data/lib/active_support/concern.rb +79 -6
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +18 -0
- data/lib/active_support/concurrency/share_lock.rb +2 -1
- data/lib/active_support/configurable.rb +12 -14
- data/lib/active_support/configuration_file.rb +51 -0
- data/lib/active_support/core_ext/array/access.rb +21 -7
- data/lib/active_support/core_ext/array/conversions.rb +7 -5
- 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 +2 -0
- data/lib/active_support/core_ext/array/inquiry.rb +2 -0
- data/lib/active_support/core_ext/array/wrap.rb +2 -0
- data/lib/active_support/core_ext/array.rb +3 -1
- data/lib/active_support/core_ext/benchmark.rb +4 -2
- data/lib/active_support/core_ext/big_decimal/conversions.rb +2 -0
- data/lib/active_support/core_ext/big_decimal.rb +2 -0
- data/lib/active_support/core_ext/class/attribute.rb +50 -47
- data/lib/active_support/core_ext/class/attribute_accessors.rb +2 -0
- data/lib/active_support/core_ext/class/subclasses.rb +18 -40
- data/lib/active_support/core_ext/class.rb +2 -0
- data/lib/active_support/core_ext/date/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date/blank.rb +2 -0
- data/lib/active_support/core_ext/date/calculations.rb +8 -5
- data/lib/active_support/core_ext/date/conversions.rb +12 -10
- data/lib/active_support/core_ext/date/zones.rb +2 -0
- data/lib/active_support/core_ext/date.rb +2 -0
- data/lib/active_support/core_ext/date_and_time/calculations.rb +61 -37
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +18 -1
- data/lib/active_support/core_ext/date_and_time/zones.rb +2 -1
- data/lib/active_support/core_ext/date_time/acts_like.rb +2 -0
- data/lib/active_support/core_ext/date_time/blank.rb +2 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +3 -1
- data/lib/active_support/core_ext/date_time/compatibility.rb +7 -5
- data/lib/active_support/core_ext/date_time/conversions.rb +2 -1
- data/lib/active_support/core_ext/date_time.rb +2 -0
- data/lib/active_support/core_ext/digest/uuid.rb +4 -1
- data/lib/active_support/core_ext/digest.rb +3 -0
- data/lib/active_support/core_ext/enumerable.rb +174 -71
- data/lib/active_support/core_ext/file/atomic.rb +3 -1
- data/lib/active_support/core_ext/file.rb +2 -0
- data/lib/active_support/core_ext/hash/conversions.rb +7 -5
- 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 +2 -0
- data/lib/active_support/core_ext/hash/keys.rb +3 -30
- 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 +3 -2
- data/lib/active_support/core_ext/integer/inflections.rb +2 -0
- data/lib/active_support/core_ext/integer/multiple.rb +3 -1
- data/lib/active_support/core_ext/integer/time.rb +7 -14
- data/lib/active_support/core_ext/integer.rb +2 -0
- data/lib/active_support/core_ext/kernel/concern.rb +2 -0
- data/lib/active_support/core_ext/kernel/reporting.rb +2 -0
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +2 -1
- data/lib/active_support/core_ext/load_error.rb +3 -8
- data/lib/active_support/core_ext/marshal.rb +4 -0
- data/lib/active_support/core_ext/module/aliasing.rb +2 -0
- data/lib/active_support/core_ext/module/anonymous.rb +2 -0
- data/lib/active_support/core_ext/module/attr_internal.rb +4 -2
- data/lib/active_support/core_ext/module/attribute_accessors.rb +44 -56
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +18 -18
- data/lib/active_support/core_ext/module/concerning.rb +15 -10
- data/lib/active_support/core_ext/module/delegation.rb +103 -58
- data/lib/active_support/core_ext/module/deprecation.rb +2 -0
- data/lib/active_support/core_ext/module/introspection.rb +18 -15
- 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 +3 -1
- 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 +131 -129
- data/lib/active_support/core_ext/numeric/time.rb +7 -15
- data/lib/active_support/core_ext/numeric.rb +2 -1
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +13 -3
- data/lib/active_support/core_ext/object/conversions.rb +2 -0
- data/lib/active_support/core_ext/object/deep_dup.rb +3 -1
- data/lib/active_support/core_ext/object/duplicable.rb +9 -114
- data/lib/active_support/core_ext/object/inclusion.rb +2 -0
- data/lib/active_support/core_ext/object/instance_variables.rb +2 -0
- data/lib/active_support/core_ext/object/json.rb +22 -2
- data/lib/active_support/core_ext/object/to_param.rb +2 -0
- data/lib/active_support/core_ext/object/to_query.rb +2 -0
- data/lib/active_support/core_ext/object/try.rb +19 -7
- data/lib/active_support/core_ext/object/with_options.rb +4 -2
- data/lib/active_support/core_ext/object.rb +2 -0
- 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 +4 -1
- data/lib/active_support/core_ext/regexp.rb +10 -5
- data/lib/active_support/core_ext/securerandom.rb +25 -3
- data/lib/active_support/core_ext/string/access.rb +7 -16
- data/lib/active_support/core_ext/string/behavior.rb +2 -0
- data/lib/active_support/core_ext/string/conversions.rb +3 -0
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +44 -1
- data/lib/active_support/core_ext/string/indent.rb +2 -0
- data/lib/active_support/core_ext/string/inflections.rb +69 -16
- data/lib/active_support/core_ext/string/inquiry.rb +3 -0
- data/lib/active_support/core_ext/string/multibyte.rb +9 -4
- data/lib/active_support/core_ext/string/output_safety.rb +104 -20
- 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 +2 -0
- data/lib/active_support/core_ext/string.rb +2 -0
- 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 +2 -0
- data/lib/active_support/core_ext/time/calculations.rb +76 -18
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +4 -0
- data/lib/active_support/core_ext/time/zones.rb +6 -4
- data/lib/active_support/core_ext/time.rb +2 -0
- data/lib/active_support/core_ext/uri.rb +11 -6
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes/test_helper.rb +13 -0
- data/lib/active_support/current_attributes.rb +210 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +2 -0
- data/lib/active_support/dependencies/zeitwerk_integration.rb +120 -0
- data/lib/active_support/dependencies.rb +134 -60
- data/lib/active_support/deprecation/behaviors.rb +43 -11
- data/lib/active_support/deprecation/constant_accessor.rb +4 -2
- data/lib/active_support/deprecation/disallowed.rb +56 -0
- data/lib/active_support/deprecation/instance_delegator.rb +2 -1
- data/lib/active_support/deprecation/method_wrappers.rb +29 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +32 -6
- data/lib/active_support/deprecation/reporting.rb +54 -9
- data/lib/active_support/deprecation.rb +9 -2
- data/lib/active_support/descendants_tracker.rb +61 -9
- data/lib/active_support/digest.rb +22 -0
- data/lib/active_support/duration/iso8601_parser.rb +6 -6
- data/lib/active_support/duration/iso8601_serializer.rb +20 -14
- data/lib/active_support/duration.rb +102 -45
- 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 +84 -117
- data/lib/active_support/execution_wrapper.rb +19 -13
- data/lib/active_support/executor.rb +2 -0
- data/lib/active_support/file_update_checker.rb +2 -1
- data/lib/active_support/fork_tracker.rb +64 -0
- data/lib/active_support/gem_version.rb +3 -1
- data/lib/active_support/gzip.rb +2 -0
- data/lib/active_support/hash_with_indifferent_access.rb +123 -41
- data/lib/active_support/i18n.rb +4 -1
- data/lib/active_support/i18n_railtie.rb +19 -14
- data/lib/active_support/inflections.rb +2 -0
- data/lib/active_support/inflector/inflections.rb +19 -8
- data/lib/active_support/inflector/methods.rb +87 -77
- data/lib/active_support/inflector/transliterate.rb +56 -18
- data/lib/active_support/inflector.rb +2 -0
- data/lib/active_support/json/decoding.rb +27 -26
- data/lib/active_support/json/encoding.rb +13 -3
- data/lib/active_support/json.rb +2 -0
- data/lib/active_support/key_generator.rb +3 -33
- data/lib/active_support/lazy_load_hooks.rb +7 -2
- 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 +2 -0
- data/lib/active_support/log_subscriber.rb +42 -11
- data/lib/active_support/logger.rb +4 -17
- data/lib/active_support/logger_silence.rb +13 -20
- data/lib/active_support/logger_thread_safe_level.rb +54 -7
- data/lib/active_support/message_encryptor.rb +100 -32
- data/lib/active_support/message_verifier.rb +85 -14
- 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 +12 -68
- data/lib/active_support/multibyte/unicode.rb +17 -327
- data/lib/active_support/multibyte.rb +2 -0
- data/lib/active_support/notifications/fanout.rb +118 -16
- data/lib/active_support/notifications/instrumenter.rb +73 -9
- data/lib/active_support/notifications.rb +74 -8
- data/lib/active_support/number_helper/number_converter.rb +7 -6
- 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 -2
- data/lib/active_support/number_helper/number_to_human_converter.rb +6 -3
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +6 -3
- 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 -2
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +14 -27
- data/lib/active_support/number_helper/rounding_helper.rb +16 -30
- data/lib/active_support/number_helper.rb +40 -12
- data/lib/active_support/option_merger.rb +24 -3
- data/lib/active_support/ordered_hash.rb +3 -1
- data/lib/active_support/ordered_options.rb +17 -5
- data/lib/active_support/parameter_filter.rb +133 -0
- data/lib/active_support/per_thread_registry.rb +4 -1
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +3 -10
- data/lib/active_support/railtie.rb +60 -9
- data/lib/active_support/reloader.rb +12 -11
- data/lib/active_support/rescuable.rb +7 -6
- 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 +6 -3
- data/lib/active_support/subscriber.rb +74 -24
- data/lib/active_support/tagged_logging.rb +44 -8
- data/lib/active_support/test_case.rb +94 -2
- data/lib/active_support/testing/assertions.rb +58 -20
- data/lib/active_support/testing/autorun.rb +2 -0
- data/lib/active_support/testing/constant_lookup.rb +2 -0
- data/lib/active_support/testing/declarative.rb +2 -0
- data/lib/active_support/testing/deprecation.rb +2 -1
- data/lib/active_support/testing/file_fixtures.rb +4 -0
- data/lib/active_support/testing/isolation.rb +4 -2
- data/lib/active_support/testing/method_call_assertions.rb +30 -1
- 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 +12 -7
- data/lib/active_support/testing/stream.rb +3 -2
- data/lib/active_support/testing/tagged_logging.rb +2 -0
- data/lib/active_support/testing/time_helpers.rb +78 -13
- data/lib/active_support/time.rb +2 -0
- data/lib/active_support/time_with_zone.rb +113 -41
- data/lib/active_support/values/time_zone.rb +54 -25
- data/lib/active_support/version.rb +2 -0
- data/lib/active_support/xml_mini/jdom.rb +5 -4
- data/lib/active_support/xml_mini/libxml.rb +4 -2
- data/lib/active_support/xml_mini/libxmlsax.rb +6 -4
- data/lib/active_support/xml_mini/nokogiri.rb +4 -2
- data/lib/active_support/xml_mini/nokogirisax.rb +5 -3
- data/lib/active_support/xml_mini/rexml.rb +12 -3
- data/lib/active_support/xml_mini.rb +5 -11
- data/lib/active_support.rb +18 -13
- metadata +71 -32
- data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
- data/lib/active_support/core_ext/hash/compact.rb +0 -27
- data/lib/active_support/core_ext/hash/transform_values.rb +0 -30
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- 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/values/unicode_tables.dat +0 -0
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/inflector/methods"
|
2
4
|
require "active_support/inflector/transliterate"
|
3
5
|
|
@@ -28,6 +30,8 @@ class String
|
|
28
30
|
# 'apple'.pluralize(2) # => "apples"
|
29
31
|
# 'ley'.pluralize(:es) # => "leyes"
|
30
32
|
# 'ley'.pluralize(1, :es) # => "ley"
|
33
|
+
#
|
34
|
+
# See ActiveSupport::Inflector.pluralize.
|
31
35
|
def pluralize(count = nil, locale = :en)
|
32
36
|
locale = count if count.is_a?(Symbol)
|
33
37
|
if count == 1
|
@@ -51,28 +55,34 @@ class String
|
|
51
55
|
# 'the blue mailmen'.singularize # => "the blue mailman"
|
52
56
|
# 'CamelOctopi'.singularize # => "CamelOctopus"
|
53
57
|
# 'leyes'.singularize(:es) # => "ley"
|
58
|
+
#
|
59
|
+
# See ActiveSupport::Inflector.singularize.
|
54
60
|
def singularize(locale = :en)
|
55
61
|
ActiveSupport::Inflector.singularize(self, locale)
|
56
62
|
end
|
57
63
|
|
58
64
|
# +constantize+ tries to find a declared constant with the name specified
|
59
65
|
# in the string. It raises a NameError when the name is not in CamelCase
|
60
|
-
# or is not initialized.
|
66
|
+
# or is not initialized.
|
61
67
|
#
|
62
68
|
# 'Module'.constantize # => Module
|
63
69
|
# 'Class'.constantize # => Class
|
64
70
|
# 'blargle'.constantize # => NameError: wrong constant name blargle
|
71
|
+
#
|
72
|
+
# See ActiveSupport::Inflector.constantize.
|
65
73
|
def constantize
|
66
74
|
ActiveSupport::Inflector.constantize(self)
|
67
75
|
end
|
68
76
|
|
69
77
|
# +safe_constantize+ tries to find a declared constant with the name specified
|
70
78
|
# in the string. It returns +nil+ when the name is not in CamelCase
|
71
|
-
# or is not initialized.
|
79
|
+
# or is not initialized.
|
72
80
|
#
|
73
81
|
# 'Module'.safe_constantize # => Module
|
74
82
|
# 'Class'.safe_constantize # => Class
|
75
83
|
# 'blargle'.safe_constantize # => nil
|
84
|
+
#
|
85
|
+
# See ActiveSupport::Inflector.safe_constantize.
|
76
86
|
def safe_constantize
|
77
87
|
ActiveSupport::Inflector.safe_constantize(self)
|
78
88
|
end
|
@@ -86,12 +96,18 @@ class String
|
|
86
96
|
# 'active_record'.camelize(:lower) # => "activeRecord"
|
87
97
|
# 'active_record/errors'.camelize # => "ActiveRecord::Errors"
|
88
98
|
# 'active_record/errors'.camelize(:lower) # => "activeRecord::Errors"
|
99
|
+
#
|
100
|
+
# +camelize+ is also aliased as +camelcase+.
|
101
|
+
#
|
102
|
+
# See ActiveSupport::Inflector.camelize.
|
89
103
|
def camelize(first_letter = :upper)
|
90
104
|
case first_letter
|
91
105
|
when :upper
|
92
106
|
ActiveSupport::Inflector.camelize(self, true)
|
93
107
|
when :lower
|
94
108
|
ActiveSupport::Inflector.camelize(self, false)
|
109
|
+
else
|
110
|
+
raise ArgumentError, "Invalid option, use either :upper or :lower."
|
95
111
|
end
|
96
112
|
end
|
97
113
|
alias_method :camelcase, :camelize
|
@@ -100,12 +116,19 @@ class String
|
|
100
116
|
# a nicer looking title. +titleize+ is meant for creating pretty output. It is not
|
101
117
|
# used in the Rails internals.
|
102
118
|
#
|
119
|
+
# The trailing '_id','Id'.. can be kept and capitalized by setting the
|
120
|
+
# optional parameter +keep_id_suffix+ to true.
|
121
|
+
# By default, this parameter is false.
|
122
|
+
#
|
123
|
+
# 'man from the boondocks'.titleize # => "Man From The Boondocks"
|
124
|
+
# 'x-men: the last stand'.titleize # => "X Men: The Last Stand"
|
125
|
+
# 'string_ending_with_id'.titleize(keep_id_suffix: true) # => "String Ending With Id"
|
126
|
+
#
|
103
127
|
# +titleize+ is also aliased as +titlecase+.
|
104
128
|
#
|
105
|
-
#
|
106
|
-
|
107
|
-
|
108
|
-
ActiveSupport::Inflector.titleize(self)
|
129
|
+
# See ActiveSupport::Inflector.titleize.
|
130
|
+
def titleize(keep_id_suffix: false)
|
131
|
+
ActiveSupport::Inflector.titleize(self, keep_id_suffix: keep_id_suffix)
|
109
132
|
end
|
110
133
|
alias_method :titlecase, :titleize
|
111
134
|
|
@@ -115,6 +138,8 @@ class String
|
|
115
138
|
#
|
116
139
|
# 'ActiveModel'.underscore # => "active_model"
|
117
140
|
# 'ActiveModel::Errors'.underscore # => "active_model/errors"
|
141
|
+
#
|
142
|
+
# See ActiveSupport::Inflector.underscore.
|
118
143
|
def underscore
|
119
144
|
ActiveSupport::Inflector.underscore(self)
|
120
145
|
end
|
@@ -122,6 +147,8 @@ class String
|
|
122
147
|
# Replaces underscores with dashes in the string.
|
123
148
|
#
|
124
149
|
# 'puni_puni'.dasherize # => "puni-puni"
|
150
|
+
#
|
151
|
+
# See ActiveSupport::Inflector.dasherize.
|
125
152
|
def dasherize
|
126
153
|
ActiveSupport::Inflector.dasherize(self)
|
127
154
|
end
|
@@ -133,6 +160,8 @@ class String
|
|
133
160
|
# '::Inflections'.demodulize # => "Inflections"
|
134
161
|
# ''.demodulize # => ''
|
135
162
|
#
|
163
|
+
# See ActiveSupport::Inflector.demodulize.
|
164
|
+
#
|
136
165
|
# See also +deconstantize+.
|
137
166
|
def demodulize
|
138
167
|
ActiveSupport::Inflector.demodulize(self)
|
@@ -146,6 +175,8 @@ class String
|
|
146
175
|
# '::String'.deconstantize # => ""
|
147
176
|
# ''.deconstantize # => ""
|
148
177
|
#
|
178
|
+
# See ActiveSupport::Inflector.deconstantize.
|
179
|
+
#
|
149
180
|
# See also +demodulize+.
|
150
181
|
def deconstantize
|
151
182
|
ActiveSupport::Inflector.deconstantize(self)
|
@@ -153,6 +184,11 @@ class String
|
|
153
184
|
|
154
185
|
# Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
|
155
186
|
#
|
187
|
+
# If the optional parameter +locale+ is specified,
|
188
|
+
# the word will be parameterized as a word of that language.
|
189
|
+
# By default, this parameter is set to <tt>nil</tt> and it will use
|
190
|
+
# the configured <tt>I18n.locale</tt>.
|
191
|
+
#
|
156
192
|
# class Person
|
157
193
|
# def to_param
|
158
194
|
# "#{id}-#{name.parameterize}"
|
@@ -165,7 +201,7 @@ class String
|
|
165
201
|
# <%= link_to(@person.name, person_path) %>
|
166
202
|
# # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
|
167
203
|
#
|
168
|
-
# To preserve the case of the characters in a string, use the
|
204
|
+
# To preserve the case of the characters in a string, use the +preserve_case+ argument.
|
169
205
|
#
|
170
206
|
# class Person
|
171
207
|
# def to_param
|
@@ -178,8 +214,10 @@ class String
|
|
178
214
|
#
|
179
215
|
# <%= link_to(@person.name, person_path) %>
|
180
216
|
# # => <a href="/person/1-Donald-E-Knuth">Donald E. Knuth</a>
|
181
|
-
|
182
|
-
|
217
|
+
#
|
218
|
+
# See ActiveSupport::Inflector.parameterize.
|
219
|
+
def parameterize(separator: "-", preserve_case: false, locale: nil)
|
220
|
+
ActiveSupport::Inflector.parameterize(self, separator: separator, preserve_case: preserve_case, locale: locale)
|
183
221
|
end
|
184
222
|
|
185
223
|
# Creates the name of a table like Rails does for models to table names. This method
|
@@ -188,6 +226,8 @@ class String
|
|
188
226
|
# 'RawScaledScorer'.tableize # => "raw_scaled_scorers"
|
189
227
|
# 'ham_and_egg'.tableize # => "ham_and_eggs"
|
190
228
|
# 'fancyCategory'.tableize # => "fancy_categories"
|
229
|
+
#
|
230
|
+
# See ActiveSupport::Inflector.tableize.
|
191
231
|
def tableize
|
192
232
|
ActiveSupport::Inflector.tableize(self)
|
193
233
|
end
|
@@ -198,11 +238,13 @@ class String
|
|
198
238
|
#
|
199
239
|
# 'ham_and_eggs'.classify # => "HamAndEgg"
|
200
240
|
# 'posts'.classify # => "Post"
|
241
|
+
#
|
242
|
+
# See ActiveSupport::Inflector.classify.
|
201
243
|
def classify
|
202
244
|
ActiveSupport::Inflector.classify(self)
|
203
245
|
end
|
204
246
|
|
205
|
-
# Capitalizes the first word, turns underscores into spaces, and strips a
|
247
|
+
# Capitalizes the first word, turns underscores into spaces, and (by default)strips a
|
206
248
|
# trailing '_id' if present.
|
207
249
|
# Like +titleize+, this is meant for creating pretty output.
|
208
250
|
#
|
@@ -210,12 +252,19 @@ class String
|
|
210
252
|
# optional parameter +capitalize+ to false.
|
211
253
|
# By default, this parameter is true.
|
212
254
|
#
|
213
|
-
#
|
214
|
-
#
|
215
|
-
#
|
216
|
-
#
|
217
|
-
|
218
|
-
|
255
|
+
# The trailing '_id' can be kept and capitalized by setting the
|
256
|
+
# optional parameter +keep_id_suffix+ to true.
|
257
|
+
# By default, this parameter is false.
|
258
|
+
#
|
259
|
+
# 'employee_salary'.humanize # => "Employee salary"
|
260
|
+
# 'author_id'.humanize # => "Author"
|
261
|
+
# 'author_id'.humanize(capitalize: false) # => "author"
|
262
|
+
# '_id'.humanize # => "Id"
|
263
|
+
# 'author_id'.humanize(keep_id_suffix: true) # => "Author Id"
|
264
|
+
#
|
265
|
+
# See ActiveSupport::Inflector.humanize.
|
266
|
+
def humanize(capitalize: true, keep_id_suffix: false)
|
267
|
+
ActiveSupport::Inflector.humanize(self, capitalize: capitalize, keep_id_suffix: keep_id_suffix)
|
219
268
|
end
|
220
269
|
|
221
270
|
# Converts just the first character to uppercase.
|
@@ -223,6 +272,8 @@ class String
|
|
223
272
|
# 'what a Lovely Day'.upcase_first # => "What a Lovely Day"
|
224
273
|
# 'w'.upcase_first # => "W"
|
225
274
|
# ''.upcase_first # => ""
|
275
|
+
#
|
276
|
+
# See ActiveSupport::Inflector.upcase_first.
|
226
277
|
def upcase_first
|
227
278
|
ActiveSupport::Inflector.upcase_first(self)
|
228
279
|
end
|
@@ -234,6 +285,8 @@ class String
|
|
234
285
|
# 'Message'.foreign_key # => "message_id"
|
235
286
|
# 'Message'.foreign_key(false) # => "messageid"
|
236
287
|
# 'Admin::Post'.foreign_key # => "post_id"
|
288
|
+
#
|
289
|
+
# See ActiveSupport::Inflector.foreign_key.
|
237
290
|
def foreign_key(separate_class_name_and_id_with_underscore = true)
|
238
291
|
ActiveSupport::Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
|
239
292
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "active_support/multibyte"
|
2
4
|
|
3
5
|
class String
|
@@ -9,11 +11,14 @@ class String
|
|
9
11
|
# encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy
|
10
12
|
# class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string.
|
11
13
|
#
|
12
|
-
# >> "lj".upcase
|
13
|
-
# => "lj"
|
14
14
|
# >> "lj".mb_chars.upcase.to_s
|
15
15
|
# => "LJ"
|
16
16
|
#
|
17
|
+
# NOTE: Ruby 2.4 and later support native Unicode case mappings:
|
18
|
+
#
|
19
|
+
# >> "lj".upcase
|
20
|
+
# => "LJ"
|
21
|
+
#
|
17
22
|
# == Method chaining
|
18
23
|
#
|
19
24
|
# All the methods on the Chars proxy which normally return a string will return a Chars object. This allows
|
@@ -42,9 +47,9 @@ class String
|
|
42
47
|
# iso_str.is_utf8? # => false
|
43
48
|
def is_utf8?
|
44
49
|
case encoding
|
45
|
-
when Encoding::UTF_8
|
50
|
+
when Encoding::UTF_8, Encoding::US_ASCII
|
46
51
|
valid_encoding?
|
47
|
-
when Encoding::ASCII_8BIT
|
52
|
+
when Encoding::ASCII_8BIT
|
48
53
|
dup.force_encoding(Encoding::UTF_8).valid_encoding?
|
49
54
|
else
|
50
55
|
false
|
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require "erb"
|
2
|
-
require "active_support/core_ext/
|
4
|
+
require "active_support/core_ext/module/redefine_method"
|
3
5
|
require "active_support/multibyte/unicode"
|
4
6
|
|
5
7
|
class ERB
|
@@ -9,25 +11,29 @@ class ERB
|
|
9
11
|
HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/
|
10
12
|
JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u
|
11
13
|
|
14
|
+
# Following XML requirements: https://www.w3.org/TR/REC-xml/#NT-Name
|
15
|
+
TAG_NAME_START_REGEXP_SET = "@:A-Z_a-z\u{C0}-\u{D6}\u{D8}-\u{F6}\u{F8}-\u{2FF}\u{370}-\u{37D}\u{37F}-\u{1FFF}" \
|
16
|
+
"\u{200C}-\u{200D}\u{2070}-\u{218F}\u{2C00}-\u{2FEF}\u{3001}-\u{D7FF}\u{F900}-\u{FDCF}" \
|
17
|
+
"\u{FDF0}-\u{FFFD}\u{10000}-\u{EFFFF}"
|
18
|
+
TAG_NAME_START_REGEXP = /[^#{TAG_NAME_START_REGEXP_SET}]/
|
19
|
+
TAG_NAME_FOLLOWING_REGEXP = /[^#{TAG_NAME_START_REGEXP_SET}\-.0-9\u{B7}\u{0300}-\u{036F}\u{203F}-\u{2040}]/
|
20
|
+
TAG_NAME_REPLACEMENT_CHAR = "_"
|
21
|
+
|
12
22
|
# A utility method for escaping HTML tag characters.
|
13
23
|
# This method is also aliased as <tt>h</tt>.
|
14
24
|
#
|
15
|
-
# In your ERB templates, use this method to escape any unsafe content. For example:
|
16
|
-
# <%= h @person.name %>
|
17
|
-
#
|
18
25
|
# puts html_escape('is a > 0 & a < 10?')
|
19
26
|
# # => is a > 0 & a < 10?
|
20
27
|
def html_escape(s)
|
21
28
|
unwrapped_html_escape(s).html_safe
|
22
29
|
end
|
23
30
|
|
24
|
-
|
25
|
-
remove_method(:h)
|
31
|
+
silence_redefinition_of_method :h
|
26
32
|
alias h html_escape
|
27
33
|
|
28
34
|
module_function :h
|
29
35
|
|
30
|
-
singleton_class.
|
36
|
+
singleton_class.silence_redefinition_of_method :html_escape
|
31
37
|
module_function :html_escape
|
32
38
|
|
33
39
|
# HTML escapes strings but doesn't wrap them with an ActiveSupport::SafeBuffer.
|
@@ -86,7 +92,7 @@ class ERB
|
|
86
92
|
# use inside HTML attributes.
|
87
93
|
#
|
88
94
|
# If your JSON is being used downstream for insertion into the DOM, be aware of
|
89
|
-
# whether or not it is being inserted via
|
95
|
+
# whether or not it is being inserted via <tt>html()</tt>. Most jQuery plugins do this.
|
90
96
|
# If that is the case, be sure to +html_escape+ or +sanitize+ any user-generated
|
91
97
|
# content returned by your JSON.
|
92
98
|
#
|
@@ -117,6 +123,26 @@ class ERB
|
|
117
123
|
end
|
118
124
|
|
119
125
|
module_function :json_escape
|
126
|
+
|
127
|
+
# A utility method for escaping XML names of tags and names of attributes.
|
128
|
+
#
|
129
|
+
# xml_name_escape('1 < 2 & 3')
|
130
|
+
# # => "1___2___3"
|
131
|
+
#
|
132
|
+
# It follows the requirements of the specification: https://www.w3.org/TR/REC-xml/#NT-Name
|
133
|
+
def xml_name_escape(name)
|
134
|
+
name = name.to_s
|
135
|
+
return "" if name.blank?
|
136
|
+
|
137
|
+
starting_char = name[0].gsub(TAG_NAME_START_REGEXP, TAG_NAME_REPLACEMENT_CHAR)
|
138
|
+
|
139
|
+
return starting_char if name.size == 1
|
140
|
+
|
141
|
+
following_chars = name[1..-1].gsub(TAG_NAME_FOLLOWING_REGEXP, TAG_NAME_REPLACEMENT_CHAR)
|
142
|
+
|
143
|
+
starting_char + following_chars
|
144
|
+
end
|
145
|
+
module_function :xml_name_escape
|
120
146
|
end
|
121
147
|
end
|
122
148
|
|
@@ -135,10 +161,13 @@ end
|
|
135
161
|
module ActiveSupport #:nodoc:
|
136
162
|
class SafeBuffer < String
|
137
163
|
UNSAFE_STRING_METHODS = %w(
|
138
|
-
capitalize chomp chop delete
|
139
|
-
|
164
|
+
capitalize chomp chop delete delete_prefix delete_suffix
|
165
|
+
downcase lstrip next reverse rstrip scrub slice squeeze strip
|
166
|
+
succ swapcase tr tr_s unicode_normalize upcase
|
140
167
|
)
|
141
168
|
|
169
|
+
UNSAFE_STRING_METHODS_WITH_BACKREF = %w(gsub sub)
|
170
|
+
|
142
171
|
alias_method :original_concat, :concat
|
143
172
|
private :original_concat
|
144
173
|
|
@@ -150,15 +179,13 @@ module ActiveSupport #:nodoc:
|
|
150
179
|
end
|
151
180
|
|
152
181
|
def [](*args)
|
153
|
-
if
|
154
|
-
super
|
155
|
-
elsif html_safe?
|
156
|
-
new_safe_buffer = super
|
182
|
+
if html_safe?
|
183
|
+
new_string = super
|
157
184
|
|
158
|
-
|
159
|
-
new_safe_buffer.instance_variable_set :@html_safe, true
|
160
|
-
end
|
185
|
+
return unless new_string
|
161
186
|
|
187
|
+
new_safe_buffer = new_string.is_a?(SafeBuffer) ? new_string : SafeBuffer.new(new_string)
|
188
|
+
new_safe_buffer.instance_variable_set :@html_safe, true
|
162
189
|
new_safe_buffer
|
163
190
|
else
|
164
191
|
to_str[*args]
|
@@ -189,18 +216,41 @@ module ActiveSupport #:nodoc:
|
|
189
216
|
end
|
190
217
|
alias << concat
|
191
218
|
|
219
|
+
def insert(index, value)
|
220
|
+
super(index, html_escape_interpolated_argument(value))
|
221
|
+
end
|
222
|
+
|
192
223
|
def prepend(value)
|
193
224
|
super(html_escape_interpolated_argument(value))
|
194
225
|
end
|
195
226
|
|
227
|
+
def replace(value)
|
228
|
+
super(html_escape_interpolated_argument(value))
|
229
|
+
end
|
230
|
+
|
231
|
+
def []=(*args)
|
232
|
+
if args.length == 3
|
233
|
+
super(args[0], args[1], html_escape_interpolated_argument(args[2]))
|
234
|
+
else
|
235
|
+
super(args[0], html_escape_interpolated_argument(args[1]))
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
196
239
|
def +(other)
|
197
240
|
dup.concat(other)
|
198
241
|
end
|
199
242
|
|
243
|
+
def *(*)
|
244
|
+
new_string = super
|
245
|
+
new_safe_buffer = new_string.is_a?(SafeBuffer) ? new_string : SafeBuffer.new(new_string)
|
246
|
+
new_safe_buffer.instance_variable_set(:@html_safe, @html_safe)
|
247
|
+
new_safe_buffer
|
248
|
+
end
|
249
|
+
|
200
250
|
def %(args)
|
201
251
|
case args
|
202
252
|
when Hash
|
203
|
-
escaped_args =
|
253
|
+
escaped_args = args.transform_values { |arg| html_escape_interpolated_argument(arg) }
|
204
254
|
else
|
205
255
|
escaped_args = Array(args).map { |arg| html_escape_interpolated_argument(arg) }
|
206
256
|
end
|
@@ -239,11 +289,45 @@ module ActiveSupport #:nodoc:
|
|
239
289
|
end
|
240
290
|
end
|
241
291
|
|
242
|
-
|
292
|
+
UNSAFE_STRING_METHODS_WITH_BACKREF.each do |unsafe_method|
|
293
|
+
if unsafe_method.respond_to?(unsafe_method)
|
294
|
+
class_eval <<-EOT, __FILE__, __LINE__ + 1
|
295
|
+
def #{unsafe_method}(*args, &block) # def gsub(*args, &block)
|
296
|
+
if block # if block
|
297
|
+
to_str.#{unsafe_method}(*args) { |*params| # to_str.gsub(*args) { |*params|
|
298
|
+
set_block_back_references(block, $~) # set_block_back_references(block, $~)
|
299
|
+
block.call(*params) # block.call(*params)
|
300
|
+
} # }
|
301
|
+
else # else
|
302
|
+
to_str.#{unsafe_method}(*args) # to_str.gsub(*args)
|
303
|
+
end # end
|
304
|
+
end # end
|
305
|
+
|
306
|
+
def #{unsafe_method}!(*args, &block) # def gsub!(*args, &block)
|
307
|
+
@html_safe = false # @html_safe = false
|
308
|
+
if block # if block
|
309
|
+
super(*args) { |*params| # super(*args) { |*params|
|
310
|
+
set_block_back_references(block, $~) # set_block_back_references(block, $~)
|
311
|
+
block.call(*params) # block.call(*params)
|
312
|
+
} # }
|
313
|
+
else # else
|
314
|
+
super # super
|
315
|
+
end # end
|
316
|
+
end # end
|
317
|
+
EOT
|
318
|
+
end
|
319
|
+
end
|
243
320
|
|
321
|
+
private
|
244
322
|
def html_escape_interpolated_argument(arg)
|
245
323
|
(!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s)
|
246
324
|
end
|
325
|
+
|
326
|
+
def set_block_back_references(block, match_data)
|
327
|
+
block.binding.eval("proc { |m| $~ = m }").call(match_data)
|
328
|
+
rescue ArgumentError
|
329
|
+
# Can't create binding from C level Proc
|
330
|
+
end
|
247
331
|
end
|
248
332
|
end
|
249
333
|
|
@@ -251,7 +335,7 @@ class String
|
|
251
335
|
# Marks a string as trusted safe. It will be inserted into HTML with no
|
252
336
|
# additional escaping performed. It is your responsibility to ensure that the
|
253
337
|
# string contains no malicious content. This method is equivalent to the
|
254
|
-
#
|
338
|
+
# +raw+ helper in views. It is recommended that you use +sanitize+ instead of
|
255
339
|
# this method. It should never be called on user input.
|
256
340
|
def html_safe
|
257
341
|
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
|
@@ -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
|