activesupport 4.2.11.1 → 6.0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of activesupport might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +399 -411
- data/MIT-LICENSE +2 -2
- data/README.rdoc +7 -7
- data/lib/active_support/actionable_error.rb +48 -0
- data/lib/active_support/all.rb +5 -3
- data/lib/active_support/array_inquirer.rb +48 -0
- data/lib/active_support/backtrace_cleaner.rb +34 -6
- data/lib/active_support/benchmarkable.rb +6 -4
- data/lib/active_support/builder.rb +3 -1
- data/lib/active_support/cache/file_store.rb +58 -53
- data/lib/active_support/cache/mem_cache_store.rb +95 -91
- data/lib/active_support/cache/memory_store.rb +39 -36
- data/lib/active_support/cache/null_store.rb +11 -7
- data/lib/active_support/cache/redis_cache_store.rb +493 -0
- data/lib/active_support/cache/strategy/local_cache.rb +75 -42
- data/lib/active_support/cache/strategy/local_cache_middleware.rb +10 -9
- data/lib/active_support/cache.rb +331 -217
- data/lib/active_support/callbacks.rb +650 -592
- data/lib/active_support/concern.rb +35 -6
- data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +35 -0
- data/lib/active_support/concurrency/share_lock.rb +226 -0
- data/lib/active_support/configurable.rb +13 -14
- data/lib/active_support/core_ext/array/access.rb +41 -1
- data/lib/active_support/core_ext/array/conversions.rb +24 -20
- 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 +11 -18
- data/lib/active_support/core_ext/array/inquiry.rb +19 -0
- data/lib/active_support/core_ext/array/prepend_and_append.rb +4 -6
- data/lib/active_support/core_ext/array/wrap.rb +7 -4
- data/lib/active_support/core_ext/array.rb +9 -6
- data/lib/active_support/core_ext/benchmark.rb +3 -1
- data/lib/active_support/core_ext/big_decimal/conversions.rb +10 -12
- data/lib/active_support/core_ext/big_decimal.rb +3 -1
- data/lib/active_support/core_ext/class/attribute.rb +45 -31
- data/lib/active_support/core_ext/class/attribute_accessors.rb +3 -1
- data/lib/active_support/core_ext/class/subclasses.rb +20 -6
- data/lib/active_support/core_ext/class.rb +4 -3
- data/lib/active_support/core_ext/date/acts_like.rb +3 -1
- data/lib/active_support/core_ext/date/blank.rb +14 -0
- data/lib/active_support/core_ext/date/calculations.rb +17 -14
- data/lib/active_support/core_ext/date/conversions.rb +25 -23
- data/lib/active_support/core_ext/date/zones.rb +4 -2
- data/lib/active_support/core_ext/date.rb +6 -4
- data/lib/active_support/core_ext/date_and_time/calculations.rb +154 -65
- data/lib/active_support/core_ext/date_and_time/compatibility.rb +4 -3
- data/lib/active_support/core_ext/date_and_time/zones.rb +12 -13
- data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
- data/lib/active_support/core_ext/date_time/blank.rb +14 -0
- data/lib/active_support/core_ext/date_time/calculations.rb +37 -19
- data/lib/active_support/core_ext/date_time/compatibility.rb +8 -6
- data/lib/active_support/core_ext/date_time/conversions.rb +16 -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 +114 -22
- data/lib/active_support/core_ext/file/atomic.rb +38 -31
- data/lib/active_support/core_ext/file.rb +3 -1
- data/lib/active_support/core_ext/hash/compact.rb +4 -23
- data/lib/active_support/core_ext/hash/conversions.rb +62 -41
- data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
- data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
- data/lib/active_support/core_ext/hash/except.rb +12 -9
- data/lib/active_support/core_ext/hash/indifferent_access.rb +4 -3
- data/lib/active_support/core_ext/hash/keys.rb +19 -42
- data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
- data/lib/active_support/core_ext/hash/slice.rb +5 -27
- data/lib/active_support/core_ext/hash/transform_values.rb +4 -22
- 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 +5 -1
- data/lib/active_support/core_ext/kernel/reporting.rb +4 -84
- data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
- data/lib/active_support/core_ext/kernel.rb +5 -5
- data/lib/active_support/core_ext/load_error.rb +3 -22
- data/lib/active_support/core_ext/marshal.rb +8 -8
- data/lib/active_support/core_ext/module/aliasing.rb +6 -44
- data/lib/active_support/core_ext/module/anonymous.rb +12 -1
- data/lib/active_support/core_ext/module/attr_internal.rb +8 -9
- data/lib/active_support/core_ext/module/attribute_accessors.rb +46 -46
- data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +144 -0
- data/lib/active_support/core_ext/module/concerning.rb +11 -12
- data/lib/active_support/core_ext/module/delegation.rb +133 -30
- data/lib/active_support/core_ext/module/deprecation.rb +4 -2
- data/lib/active_support/core_ext/module/introspection.rb +44 -19
- data/lib/active_support/core_ext/module/reachable.rb +5 -7
- data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
- data/lib/active_support/core_ext/module/remove_method.rb +8 -3
- data/lib/active_support/core_ext/module.rb +13 -11
- data/lib/active_support/core_ext/name_error.rb +22 -2
- data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
- data/lib/active_support/core_ext/numeric/conversions.rb +129 -136
- data/lib/active_support/core_ext/numeric/inquiry.rb +5 -0
- data/lib/active_support/core_ext/numeric/time.rb +35 -23
- data/lib/active_support/core_ext/numeric.rb +5 -3
- data/lib/active_support/core_ext/object/acts_like.rb +12 -1
- data/lib/active_support/core_ext/object/blank.rb +27 -3
- data/lib/active_support/core_ext/object/conversions.rb +6 -4
- data/lib/active_support/core_ext/object/deep_dup.rb +13 -4
- data/lib/active_support/core_ext/object/duplicable.rb +13 -93
- data/lib/active_support/core_ext/object/inclusion.rb +5 -3
- data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
- data/lib/active_support/core_ext/object/json.rb +51 -20
- 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 +81 -23
- data/lib/active_support/core_ext/object/with_options.rb +16 -3
- data/lib/active_support/core_ext/object.rb +14 -13
- data/lib/active_support/core_ext/range/compare_range.rb +76 -0
- data/lib/active_support/core_ext/range/conversions.rb +37 -15
- data/lib/active_support/core_ext/range/each.rb +18 -17
- data/lib/active_support/core_ext/range/include_range.rb +7 -21
- data/lib/active_support/core_ext/range/include_time_with_zone.rb +23 -0
- data/lib/active_support/core_ext/range/overlaps.rb +2 -0
- data/lib/active_support/core_ext/range.rb +7 -4
- data/lib/active_support/core_ext/regexp.rb +2 -0
- data/lib/active_support/core_ext/securerandom.rb +45 -0
- data/lib/active_support/core_ext/string/access.rb +16 -6
- data/lib/active_support/core_ext/string/behavior.rb +3 -1
- data/lib/active_support/core_ext/string/conversions.rb +7 -4
- data/lib/active_support/core_ext/string/exclude.rb +2 -0
- data/lib/active_support/core_ext/string/filters.rb +48 -6
- data/lib/active_support/core_ext/string/indent.rb +6 -4
- data/lib/active_support/core_ext/string/inflections.rb +66 -24
- data/lib/active_support/core_ext/string/inquiry.rb +3 -1
- data/lib/active_support/core_ext/string/multibyte.rb +16 -7
- data/lib/active_support/core_ext/string/output_safety.rb +93 -40
- data/lib/active_support/core_ext/string/starts_ends_with.rb +2 -0
- data/lib/active_support/core_ext/string/strip.rb +6 -5
- data/lib/active_support/core_ext/string/zones.rb +4 -2
- data/lib/active_support/core_ext/string.rb +15 -13
- data/lib/active_support/core_ext/time/acts_like.rb +3 -1
- data/lib/active_support/core_ext/time/calculations.rb +115 -52
- data/lib/active_support/core_ext/time/compatibility.rb +4 -2
- data/lib/active_support/core_ext/time/conversions.rb +20 -13
- data/lib/active_support/core_ext/time/zones.rb +41 -7
- data/lib/active_support/core_ext/time.rb +7 -6
- data/lib/active_support/core_ext/uri.rb +6 -7
- data/lib/active_support/core_ext.rb +3 -1
- data/lib/active_support/current_attributes.rb +203 -0
- data/lib/active_support/dependencies/autoload.rb +2 -0
- data/lib/active_support/dependencies/interlock.rb +57 -0
- data/lib/active_support/dependencies/zeitwerk_integration.rb +117 -0
- data/lib/active_support/dependencies.rb +208 -166
- data/lib/active_support/deprecation/behaviors.rb +44 -11
- data/lib/active_support/deprecation/constant_accessor.rb +52 -0
- data/lib/active_support/deprecation/instance_delegator.rb +17 -2
- data/lib/active_support/deprecation/method_wrappers.rb +61 -21
- data/lib/active_support/deprecation/proxy_wrappers.rb +81 -30
- data/lib/active_support/deprecation/reporting.rb +32 -12
- data/lib/active_support/deprecation.rb +12 -9
- data/lib/active_support/descendants_tracker.rb +57 -9
- data/lib/active_support/digest.rb +20 -0
- data/lib/active_support/duration/iso8601_parser.rb +123 -0
- data/lib/active_support/duration/iso8601_serializer.rb +53 -0
- data/lib/active_support/duration.rb +315 -40
- data/lib/active_support/encrypted_configuration.rb +45 -0
- data/lib/active_support/encrypted_file.rb +100 -0
- data/lib/active_support/evented_file_update_checker.rb +234 -0
- data/lib/active_support/execution_wrapper.rb +129 -0
- data/lib/active_support/executor.rb +8 -0
- data/lib/active_support/file_update_checker.rb +62 -37
- data/lib/active_support/gem_version.rb +6 -4
- data/lib/active_support/gzip.rb +7 -5
- data/lib/active_support/hash_with_indifferent_access.rb +129 -30
- data/lib/active_support/i18n.rb +9 -6
- data/lib/active_support/i18n_railtie.rb +50 -14
- data/lib/active_support/inflections.rb +13 -11
- data/lib/active_support/inflector/inflections.rb +58 -13
- data/lib/active_support/inflector/methods.rb +159 -145
- data/lib/active_support/inflector/transliterate.rb +84 -34
- data/lib/active_support/inflector.rb +7 -5
- data/lib/active_support/json/decoding.rb +32 -30
- data/lib/active_support/json/encoding.rb +17 -60
- data/lib/active_support/json.rb +4 -2
- data/lib/active_support/key_generator.rb +11 -43
- 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 +2 -0
- data/lib/active_support/log_subscriber/test_helper.rb +14 -12
- data/lib/active_support/log_subscriber.rb +44 -19
- data/lib/active_support/logger.rb +9 -23
- data/lib/active_support/logger_silence.rb +32 -14
- data/lib/active_support/logger_thread_safe_level.rb +32 -8
- data/lib/active_support/message_encryptor.rb +166 -53
- data/lib/active_support/message_verifier.rb +149 -16
- data/lib/active_support/messages/metadata.rb +72 -0
- data/lib/active_support/messages/rotation_configuration.rb +22 -0
- data/lib/active_support/messages/rotator.rb +56 -0
- data/lib/active_support/multibyte/chars.rb +56 -63
- data/lib/active_support/multibyte/unicode.rb +56 -290
- data/lib/active_support/multibyte.rb +4 -2
- data/lib/active_support/notifications/fanout.rb +109 -22
- data/lib/active_support/notifications/instrumenter.rb +107 -16
- data/lib/active_support/notifications.rb +51 -10
- data/lib/active_support/number_helper/number_converter.rb +16 -15
- data/lib/active_support/number_helper/number_to_currency_converter.rb +14 -15
- data/lib/active_support/number_helper/number_to_delimited_converter.rb +11 -4
- data/lib/active_support/number_helper/number_to_human_converter.rb +13 -10
- data/lib/active_support/number_helper/number_to_human_size_converter.rb +11 -9
- data/lib/active_support/number_helper/number_to_percentage_converter.rb +5 -1
- data/lib/active_support/number_helper/number_to_phone_converter.rb +15 -5
- data/lib/active_support/number_helper/number_to_rounded_converter.rb +25 -57
- data/lib/active_support/number_helper/rounding_helper.rb +66 -0
- data/lib/active_support/number_helper.rb +105 -68
- data/lib/active_support/option_merger.rb +24 -4
- data/lib/active_support/ordered_hash.rb +7 -5
- data/lib/active_support/ordered_options.rb +27 -5
- data/lib/active_support/parameter_filter.rb +128 -0
- data/lib/active_support/per_thread_registry.rb +9 -4
- data/lib/active_support/proxy_object.rb +2 -0
- data/lib/active_support/rails.rb +10 -8
- data/lib/active_support/railtie.rb +43 -9
- data/lib/active_support/reloader.rb +130 -0
- data/lib/active_support/rescuable.rb +108 -53
- data/lib/active_support/security_utils.rb +15 -11
- data/lib/active_support/string_inquirer.rb +11 -4
- data/lib/active_support/subscriber.rb +74 -30
- data/lib/active_support/tagged_logging.rb +25 -13
- data/lib/active_support/test_case.rb +107 -44
- data/lib/active_support/testing/assertions.rb +151 -20
- data/lib/active_support/testing/autorun.rb +4 -2
- data/lib/active_support/testing/constant_lookup.rb +2 -1
- data/lib/active_support/testing/declarative.rb +3 -1
- data/lib/active_support/testing/deprecation.rb +13 -10
- data/lib/active_support/testing/file_fixtures.rb +38 -0
- data/lib/active_support/testing/isolation.rb +35 -26
- data/lib/active_support/testing/method_call_assertions.rb +70 -0
- data/lib/active_support/testing/parallelization.rb +134 -0
- data/lib/active_support/testing/setup_and_teardown.rb +13 -8
- data/lib/active_support/testing/stream.rb +43 -0
- data/lib/active_support/testing/tagged_logging.rb +3 -1
- data/lib/active_support/testing/time_helpers.rb +84 -20
- data/lib/active_support/time.rb +14 -12
- data/lib/active_support/time_with_zone.rb +179 -39
- data/lib/active_support/values/time_zone.rb +203 -63
- data/lib/active_support/version.rb +3 -1
- data/lib/active_support/xml_mini/jdom.rb +116 -115
- data/lib/active_support/xml_mini/libxml.rb +16 -13
- data/lib/active_support/xml_mini/libxmlsax.rb +15 -14
- data/lib/active_support/xml_mini/nokogiri.rb +14 -12
- data/lib/active_support/xml_mini/nokogirisax.rb +14 -13
- data/lib/active_support/xml_mini/rexml.rb +11 -9
- data/lib/active_support/xml_mini.rb +38 -46
- data/lib/active_support.rb +13 -11
- metadata +84 -26
- data/lib/active_support/concurrency/latch.rb +0 -27
- data/lib/active_support/core_ext/big_decimal/yaml_conversions.rb +0 -16
- data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -45
- data/lib/active_support/core_ext/date_time/zones.rb +0 -6
- data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
- data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
- data/lib/active_support/core_ext/module/method_transplanting.rb +0 -13
- data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
- data/lib/active_support/core_ext/object/itself.rb +0 -15
- data/lib/active_support/core_ext/struct.rb +0 -6
- data/lib/active_support/core_ext/thread.rb +0 -86
- data/lib/active_support/core_ext/time/marshal.rb +0 -30
- data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -1,17 +1,24 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module ActiveSupport
|
3
4
|
module Multibyte
|
4
5
|
module Unicode
|
5
|
-
|
6
6
|
extend self
|
7
7
|
|
8
8
|
# A list of all available normalization forms.
|
9
|
-
# See
|
9
|
+
# See https://www.unicode.org/reports/tr15/tr15-29.html for more
|
10
10
|
# information about normalization.
|
11
11
|
NORMALIZATION_FORMS = [:c, :kc, :d, :kd]
|
12
12
|
|
13
|
+
NORMALIZATION_FORM_ALIASES = { # :nodoc:
|
14
|
+
c: :nfc,
|
15
|
+
d: :nfd,
|
16
|
+
kc: :nfkc,
|
17
|
+
kd: :nfkd
|
18
|
+
}
|
19
|
+
|
13
20
|
# The Unicode version that is supported by the implementation
|
14
|
-
UNICODE_VERSION =
|
21
|
+
UNICODE_VERSION = RbConfig::CONFIG["UNICODE_VERSION"]
|
15
22
|
|
16
23
|
# The default normalization used for operations that require
|
17
24
|
# normalization. It can be set to any of the normalizations
|
@@ -21,199 +28,48 @@ module ActiveSupport
|
|
21
28
|
attr_accessor :default_normalization_form
|
22
29
|
@default_normalization_form = :kc
|
23
30
|
|
24
|
-
# Hangul character boundaries and properties
|
25
|
-
HANGUL_SBASE = 0xAC00
|
26
|
-
HANGUL_LBASE = 0x1100
|
27
|
-
HANGUL_VBASE = 0x1161
|
28
|
-
HANGUL_TBASE = 0x11A7
|
29
|
-
HANGUL_LCOUNT = 19
|
30
|
-
HANGUL_VCOUNT = 21
|
31
|
-
HANGUL_TCOUNT = 28
|
32
|
-
HANGUL_NCOUNT = HANGUL_VCOUNT * HANGUL_TCOUNT
|
33
|
-
HANGUL_SCOUNT = 11172
|
34
|
-
HANGUL_SLAST = HANGUL_SBASE + HANGUL_SCOUNT
|
35
|
-
HANGUL_JAMO_FIRST = 0x1100
|
36
|
-
HANGUL_JAMO_LAST = 0x11FF
|
37
|
-
|
38
|
-
# All the unicode whitespace
|
39
|
-
WHITESPACE = [
|
40
|
-
(0x0009..0x000D).to_a, # White_Space # Cc [5] <control-0009>..<control-000D>
|
41
|
-
0x0020, # White_Space # Zs SPACE
|
42
|
-
0x0085, # White_Space # Cc <control-0085>
|
43
|
-
0x00A0, # White_Space # Zs NO-BREAK SPACE
|
44
|
-
0x1680, # White_Space # Zs OGHAM SPACE MARK
|
45
|
-
(0x2000..0x200A).to_a, # White_Space # Zs [11] EN QUAD..HAIR SPACE
|
46
|
-
0x2028, # White_Space # Zl LINE SEPARATOR
|
47
|
-
0x2029, # White_Space # Zp PARAGRAPH SEPARATOR
|
48
|
-
0x202F, # White_Space # Zs NARROW NO-BREAK SPACE
|
49
|
-
0x205F, # White_Space # Zs MEDIUM MATHEMATICAL SPACE
|
50
|
-
0x3000, # White_Space # Zs IDEOGRAPHIC SPACE
|
51
|
-
].flatten.freeze
|
52
|
-
|
53
|
-
# BOM (byte order mark) can also be seen as whitespace, it's a
|
54
|
-
# non-rendering character used to distinguish between little and big
|
55
|
-
# endian. This is not an issue in utf-8, so it must be ignored.
|
56
|
-
LEADERS_AND_TRAILERS = WHITESPACE + [65279] # ZERO-WIDTH NO-BREAK SPACE aka BOM
|
57
|
-
|
58
|
-
# Returns a regular expression pattern that matches the passed Unicode
|
59
|
-
# codepoints.
|
60
|
-
def self.codepoints_to_pattern(array_of_codepoints) #:nodoc:
|
61
|
-
array_of_codepoints.collect{ |e| [e].pack 'U*' }.join('|')
|
62
|
-
end
|
63
|
-
TRAILERS_PAT = /(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+\Z/u
|
64
|
-
LEADERS_PAT = /\A(#{codepoints_to_pattern(LEADERS_AND_TRAILERS)})+/u
|
65
|
-
|
66
|
-
# Detect whether the codepoint is in a certain character class. Returns
|
67
|
-
# +true+ when it's in the specified character class and +false+ otherwise.
|
68
|
-
# Valid character classes are: <tt>:cr</tt>, <tt>:lf</tt>, <tt>:l</tt>,
|
69
|
-
# <tt>:v</tt>, <tt>:lv</tt>, <tt>:lvt</tt> and <tt>:t</tt>.
|
70
|
-
#
|
71
|
-
# Primarily used by the grapheme cluster support.
|
72
|
-
def in_char_class?(codepoint, classes)
|
73
|
-
classes.detect { |c| database.boundary[c] === codepoint } ? true : false
|
74
|
-
end
|
75
|
-
|
76
31
|
# Unpack the string at grapheme boundaries. Returns a list of character
|
77
32
|
# lists.
|
78
33
|
#
|
79
34
|
# Unicode.unpack_graphemes('क्षि') # => [[2325, 2381], [2359], [2367]]
|
80
35
|
# Unicode.unpack_graphemes('Café') # => [[67], [97], [102], [233]]
|
81
36
|
def unpack_graphemes(string)
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
pos += 1
|
89
|
-
previous = codepoints[pos-1]
|
90
|
-
current = codepoints[pos]
|
91
|
-
if (
|
92
|
-
# CR X LF
|
93
|
-
( previous == database.boundary[:cr] and current == database.boundary[:lf] ) or
|
94
|
-
# L X (L|V|LV|LVT)
|
95
|
-
( database.boundary[:l] === previous and in_char_class?(current, [:l,:v,:lv,:lvt]) ) or
|
96
|
-
# (LV|V) X (V|T)
|
97
|
-
( in_char_class?(previous, [:lv,:v]) and in_char_class?(current, [:v,:t]) ) or
|
98
|
-
# (LVT|T) X (T)
|
99
|
-
( in_char_class?(previous, [:lvt,:t]) and database.boundary[:t] === current ) or
|
100
|
-
# X Extend
|
101
|
-
(database.boundary[:extend] === current)
|
102
|
-
)
|
103
|
-
else
|
104
|
-
unpacked << codepoints[marker..pos-1]
|
105
|
-
marker = pos
|
106
|
-
end
|
107
|
-
end
|
108
|
-
unpacked
|
37
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
38
|
+
ActiveSupport::Multibyte::Unicode#unpack_graphemes is deprecated and will be
|
39
|
+
removed from Rails 6.1. Use string.scan(/\X/).map(&:codepoints) instead.
|
40
|
+
MSG
|
41
|
+
|
42
|
+
string.scan(/\X/).map(&:codepoints)
|
109
43
|
end
|
110
44
|
|
111
45
|
# Reverse operation of unpack_graphemes.
|
112
46
|
#
|
113
47
|
# Unicode.pack_graphemes(Unicode.unpack_graphemes('क्षि')) # => 'क्षि'
|
114
48
|
def pack_graphemes(unpacked)
|
115
|
-
|
116
|
-
|
49
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
50
|
+
ActiveSupport::Multibyte::Unicode#pack_graphemes is deprecated and will be
|
51
|
+
removed from Rails 6.1. Use array.flatten.pack("U*") instead.
|
52
|
+
MSG
|
117
53
|
|
118
|
-
|
119
|
-
def reorder_characters(codepoints)
|
120
|
-
length = codepoints.length- 1
|
121
|
-
pos = 0
|
122
|
-
while pos < length do
|
123
|
-
cp1, cp2 = database.codepoints[codepoints[pos]], database.codepoints[codepoints[pos+1]]
|
124
|
-
if (cp1.combining_class > cp2.combining_class) && (cp2.combining_class > 0)
|
125
|
-
codepoints[pos..pos+1] = cp2.code, cp1.code
|
126
|
-
pos += (pos > 0 ? -1 : 1)
|
127
|
-
else
|
128
|
-
pos += 1
|
129
|
-
end
|
130
|
-
end
|
131
|
-
codepoints
|
54
|
+
unpacked.flatten.pack("U*")
|
132
55
|
end
|
133
56
|
|
134
57
|
# Decompose composed characters to the decomposed form.
|
135
58
|
def decompose(type, codepoints)
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
ncp = [] # new codepoints
|
141
|
-
ncp << HANGUL_LBASE + sindex / HANGUL_NCOUNT
|
142
|
-
ncp << HANGUL_VBASE + (sindex % HANGUL_NCOUNT) / HANGUL_TCOUNT
|
143
|
-
tindex = sindex % HANGUL_TCOUNT
|
144
|
-
ncp << (HANGUL_TBASE + tindex) unless tindex == 0
|
145
|
-
decomposed.concat ncp
|
146
|
-
# if the codepoint is decomposable in with the current decomposition type
|
147
|
-
elsif (ncp = database.codepoints[cp].decomp_mapping) and (!database.codepoints[cp].decomp_type || type == :compatibility)
|
148
|
-
decomposed.concat decompose(type, ncp.dup)
|
149
|
-
else
|
150
|
-
decomposed << cp
|
151
|
-
end
|
59
|
+
if type == :compatibility
|
60
|
+
codepoints.pack("U*").unicode_normalize(:nfkd).codepoints
|
61
|
+
else
|
62
|
+
codepoints.pack("U*").unicode_normalize(:nfd).codepoints
|
152
63
|
end
|
153
64
|
end
|
154
65
|
|
155
66
|
# Compose decomposed characters to the composed form.
|
156
67
|
def compose(codepoints)
|
157
|
-
|
158
|
-
eoa = codepoints.length - 1
|
159
|
-
starter_pos = 0
|
160
|
-
starter_char = codepoints[0]
|
161
|
-
previous_combining_class = -1
|
162
|
-
while pos < eoa
|
163
|
-
pos += 1
|
164
|
-
lindex = starter_char - HANGUL_LBASE
|
165
|
-
# -- Hangul
|
166
|
-
if 0 <= lindex and lindex < HANGUL_LCOUNT
|
167
|
-
vindex = codepoints[starter_pos+1] - HANGUL_VBASE rescue vindex = -1
|
168
|
-
if 0 <= vindex and vindex < HANGUL_VCOUNT
|
169
|
-
tindex = codepoints[starter_pos+2] - HANGUL_TBASE rescue tindex = -1
|
170
|
-
if 0 <= tindex and tindex < HANGUL_TCOUNT
|
171
|
-
j = starter_pos + 2
|
172
|
-
eoa -= 2
|
173
|
-
else
|
174
|
-
tindex = 0
|
175
|
-
j = starter_pos + 1
|
176
|
-
eoa -= 1
|
177
|
-
end
|
178
|
-
codepoints[starter_pos..j] = (lindex * HANGUL_VCOUNT + vindex) * HANGUL_TCOUNT + tindex + HANGUL_SBASE
|
179
|
-
end
|
180
|
-
starter_pos += 1
|
181
|
-
starter_char = codepoints[starter_pos]
|
182
|
-
# -- Other characters
|
183
|
-
else
|
184
|
-
current_char = codepoints[pos]
|
185
|
-
current = database.codepoints[current_char]
|
186
|
-
if current.combining_class > previous_combining_class
|
187
|
-
if ref = database.composition_map[starter_char]
|
188
|
-
composition = ref[current_char]
|
189
|
-
else
|
190
|
-
composition = nil
|
191
|
-
end
|
192
|
-
unless composition.nil?
|
193
|
-
codepoints[starter_pos] = composition
|
194
|
-
starter_char = composition
|
195
|
-
codepoints.delete_at pos
|
196
|
-
eoa -= 1
|
197
|
-
pos -= 1
|
198
|
-
previous_combining_class = -1
|
199
|
-
else
|
200
|
-
previous_combining_class = current.combining_class
|
201
|
-
end
|
202
|
-
else
|
203
|
-
previous_combining_class = current.combining_class
|
204
|
-
end
|
205
|
-
if current.combining_class == 0
|
206
|
-
starter_pos = pos
|
207
|
-
starter_char = codepoints[pos]
|
208
|
-
end
|
209
|
-
end
|
210
|
-
end
|
211
|
-
codepoints
|
68
|
+
codepoints.pack("U*").unicode_normalize(:nfc).codepoints
|
212
69
|
end
|
213
70
|
|
214
|
-
# Ruby >= 2.1 has String#scrub, which is faster than the workaround used for < 2.1.
|
215
71
|
# Rubinius' String#scrub, however, doesn't support ASCII-incompatible chars.
|
216
|
-
if
|
72
|
+
if !defined?(Rubinius)
|
217
73
|
# Replaces all ISO-8859-1 or CP1252 characters by their UTF-8 equivalent
|
218
74
|
# resulting in a valid UTF-8 string.
|
219
75
|
#
|
@@ -236,7 +92,7 @@ module ActiveSupport
|
|
236
92
|
reader = Encoding::Converter.new(Encoding::UTF_8, Encoding::UTF_16LE)
|
237
93
|
|
238
94
|
source = string.dup
|
239
|
-
out =
|
95
|
+
out = "".force_encoding(Encoding::UTF_16LE)
|
240
96
|
|
241
97
|
loop do
|
242
98
|
reader.primitive_convert(source, out)
|
@@ -258,133 +114,43 @@ module ActiveSupport
|
|
258
114
|
# * <tt>string</tt> - The string to perform normalization on.
|
259
115
|
# * <tt>form</tt> - The form you want to normalize in. Should be one of
|
260
116
|
# the following: <tt>:c</tt>, <tt>:kc</tt>, <tt>:d</tt>, or <tt>:kd</tt>.
|
261
|
-
# Default is ActiveSupport::Multibyte.default_normalization_form.
|
262
|
-
def normalize(string, form=nil)
|
117
|
+
# Default is ActiveSupport::Multibyte::Unicode.default_normalization_form.
|
118
|
+
def normalize(string, form = nil)
|
263
119
|
form ||= @default_normalization_form
|
264
|
-
# See http://www.unicode.org/reports/tr15, Table 1
|
265
|
-
codepoints = string.codepoints.to_a
|
266
|
-
case form
|
267
|
-
when :d
|
268
|
-
reorder_characters(decompose(:canonical, codepoints))
|
269
|
-
when :c
|
270
|
-
compose(reorder_characters(decompose(:canonical, codepoints)))
|
271
|
-
when :kd
|
272
|
-
reorder_characters(decompose(:compatibility, codepoints))
|
273
|
-
when :kc
|
274
|
-
compose(reorder_characters(decompose(:compatibility, codepoints)))
|
275
|
-
else
|
276
|
-
raise ArgumentError, "#{form} is not a valid normalization variant", caller
|
277
|
-
end.pack('U*')
|
278
|
-
end
|
279
|
-
|
280
|
-
def downcase(string)
|
281
|
-
apply_mapping string, :lowercase_mapping
|
282
|
-
end
|
283
|
-
|
284
|
-
def upcase(string)
|
285
|
-
apply_mapping string, :uppercase_mapping
|
286
|
-
end
|
287
|
-
|
288
|
-
def swapcase(string)
|
289
|
-
apply_mapping string, :swapcase_mapping
|
290
|
-
end
|
291
|
-
|
292
|
-
# Holds data about a codepoint in the Unicode database.
|
293
|
-
class Codepoint
|
294
|
-
attr_accessor :code, :combining_class, :decomp_type, :decomp_mapping, :uppercase_mapping, :lowercase_mapping
|
295
|
-
|
296
|
-
# Initializing Codepoint object with default values
|
297
|
-
def initialize
|
298
|
-
@combining_class = 0
|
299
|
-
@uppercase_mapping = 0
|
300
|
-
@lowercase_mapping = 0
|
301
|
-
end
|
302
120
|
|
303
|
-
|
304
|
-
|
121
|
+
# See https://www.unicode.org/reports/tr15, Table 1
|
122
|
+
if alias_form = NORMALIZATION_FORM_ALIASES[form]
|
123
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
124
|
+
ActiveSupport::Multibyte::Unicode#normalize is deprecated and will be
|
125
|
+
removed from Rails 6.1. Use String#unicode_normalize(:#{alias_form}) instead.
|
126
|
+
MSG
|
127
|
+
|
128
|
+
string.unicode_normalize(alias_form)
|
129
|
+
else
|
130
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
131
|
+
ActiveSupport::Multibyte::Unicode#normalize is deprecated and will be
|
132
|
+
removed from Rails 6.1. Use String#unicode_normalize instead.
|
133
|
+
MSG
|
134
|
+
|
135
|
+
raise ArgumentError, "#{form} is not a valid normalization variant", caller
|
305
136
|
end
|
306
137
|
end
|
307
138
|
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
def initialize
|
315
|
-
@codepoints = Hash.new(Codepoint.new)
|
316
|
-
@composition_exclusion = []
|
317
|
-
@composition_map = {}
|
318
|
-
@boundary = {}
|
319
|
-
@cp1252 = {}
|
320
|
-
end
|
321
|
-
|
322
|
-
# Lazy load the Unicode database so it's only loaded when it's actually used
|
323
|
-
ATTRIBUTES.each do |attr_name|
|
324
|
-
class_eval(<<-EOS, __FILE__, __LINE__ + 1)
|
325
|
-
def #{attr_name} # def codepoints
|
326
|
-
load # load
|
327
|
-
@#{attr_name} # @codepoints
|
328
|
-
end # end
|
329
|
-
EOS
|
330
|
-
end
|
331
|
-
|
332
|
-
# Loads the Unicode database and returns all the internal objects of
|
333
|
-
# UnicodeDatabase.
|
334
|
-
def load
|
335
|
-
begin
|
336
|
-
@codepoints, @composition_exclusion, @composition_map, @boundary, @cp1252 = File.open(self.class.filename, 'rb') { |f| Marshal.load f.read }
|
337
|
-
rescue => e
|
338
|
-
raise IOError.new("Couldn't load the Unicode tables for UTF8Handler (#{e.message}), ActiveSupport::Multibyte is unusable")
|
339
|
-
end
|
340
|
-
|
341
|
-
# Redefine the === method so we can write shorter rules for grapheme cluster breaks
|
342
|
-
@boundary.each do |k,_|
|
343
|
-
@boundary[k].instance_eval do
|
344
|
-
def ===(other)
|
345
|
-
detect { |i| i === other } ? true : false
|
346
|
-
end
|
347
|
-
end if @boundary[k].kind_of?(Array)
|
348
|
-
end
|
349
|
-
|
350
|
-
# define attr_reader methods for the instance variables
|
351
|
-
class << self
|
352
|
-
attr_reader(*ATTRIBUTES)
|
353
|
-
end
|
354
|
-
end
|
139
|
+
%w(downcase upcase swapcase).each do |method|
|
140
|
+
define_method(method) do |string|
|
141
|
+
ActiveSupport::Deprecation.warn(<<-MSG.squish)
|
142
|
+
ActiveSupport::Multibyte::Unicode##{method} is deprecated and
|
143
|
+
will be removed from Rails 6.1. Use String methods directly.
|
144
|
+
MSG
|
355
145
|
|
356
|
-
|
357
|
-
def self.dirname
|
358
|
-
File.dirname(__FILE__) + '/../values/'
|
359
|
-
end
|
360
|
-
|
361
|
-
# Returns the filename for the data file for this version.
|
362
|
-
def self.filename
|
363
|
-
File.expand_path File.join(dirname, "unicode_tables.dat")
|
146
|
+
string.send(method)
|
364
147
|
end
|
365
148
|
end
|
366
149
|
|
367
150
|
private
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
string.each_codepoint.map do |codepoint|
|
372
|
-
cp = database.codepoints[codepoint]
|
373
|
-
if cp and (ncp = cp.send(mapping)) and ncp > 0
|
374
|
-
ncp
|
375
|
-
else
|
376
|
-
codepoint
|
377
|
-
end
|
378
|
-
end.pack('U*')
|
379
|
-
end
|
380
|
-
|
381
|
-
def recode_windows1252_chars(string)
|
382
|
-
string.encode(Encoding::UTF_8, Encoding::Windows_1252, invalid: :replace, undef: :replace)
|
383
|
-
end
|
384
|
-
|
385
|
-
def database
|
386
|
-
@database ||= UnicodeDatabase.new
|
387
|
-
end
|
151
|
+
def recode_windows1252_chars(string)
|
152
|
+
string.encode(Encoding::UTF_8, Encoding::Windows_1252, invalid: :replace, undef: :replace)
|
153
|
+
end
|
388
154
|
end
|
389
155
|
end
|
390
156
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActiveSupport #:nodoc:
|
2
4
|
module Multibyte
|
3
|
-
autoload :Chars,
|
4
|
-
autoload :Unicode,
|
5
|
+
autoload :Chars, "active_support/multibyte/chars"
|
6
|
+
autoload :Unicode, "active_support/multibyte/unicode"
|
5
7
|
|
6
8
|
# The proxy class returned when calling mb_chars. You can use this accessor
|
7
9
|
# to configure your own proxy class so you can support other encodings. See
|
@@ -1,5 +1,8 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "mutex_m"
|
4
|
+
require "concurrent/map"
|
5
|
+
require "set"
|
3
6
|
|
4
7
|
module ActiveSupport
|
5
8
|
module Notifications
|
@@ -11,16 +14,22 @@ module ActiveSupport
|
|
11
14
|
include Mutex_m
|
12
15
|
|
13
16
|
def initialize
|
14
|
-
@
|
15
|
-
@
|
17
|
+
@string_subscribers = Hash.new { |h, k| h[k] = [] }
|
18
|
+
@other_subscribers = []
|
19
|
+
@listeners_for = Concurrent::Map.new
|
16
20
|
super
|
17
21
|
end
|
18
22
|
|
19
|
-
def subscribe(pattern = nil,
|
20
|
-
subscriber = Subscribers.new
|
23
|
+
def subscribe(pattern = nil, callable = nil, &block)
|
24
|
+
subscriber = Subscribers.new(pattern, callable || block)
|
21
25
|
synchronize do
|
22
|
-
|
23
|
-
|
26
|
+
if String === pattern
|
27
|
+
@string_subscribers[pattern] << subscriber
|
28
|
+
@listeners_for.delete(pattern)
|
29
|
+
else
|
30
|
+
@other_subscribers << subscriber
|
31
|
+
@listeners_for.clear
|
32
|
+
end
|
24
33
|
end
|
25
34
|
subscriber
|
26
35
|
end
|
@@ -29,12 +38,19 @@ module ActiveSupport
|
|
29
38
|
synchronize do
|
30
39
|
case subscriber_or_name
|
31
40
|
when String
|
32
|
-
@
|
41
|
+
@string_subscribers[subscriber_or_name].clear
|
42
|
+
@listeners_for.delete(subscriber_or_name)
|
43
|
+
@other_subscribers.each { |sub| sub.unsubscribe!(subscriber_or_name) }
|
33
44
|
else
|
34
|
-
|
45
|
+
pattern = subscriber_or_name.try(:pattern)
|
46
|
+
if String === pattern
|
47
|
+
@string_subscribers[pattern].delete(subscriber_or_name)
|
48
|
+
@listeners_for.delete(pattern)
|
49
|
+
else
|
50
|
+
@other_subscribers.delete(subscriber_or_name)
|
51
|
+
@listeners_for.clear
|
52
|
+
end
|
35
53
|
end
|
36
|
-
|
37
|
-
@listeners_for.clear
|
38
54
|
end
|
39
55
|
end
|
40
56
|
|
@@ -42,8 +58,8 @@ module ActiveSupport
|
|
42
58
|
listeners_for(name).each { |s| s.start(name, id, payload) }
|
43
59
|
end
|
44
60
|
|
45
|
-
def finish(name, id, payload)
|
46
|
-
|
61
|
+
def finish(name, id, payload, listeners = listeners_for(name))
|
62
|
+
listeners.each { |s| s.finish(name, id, payload) }
|
47
63
|
end
|
48
64
|
|
49
65
|
def publish(name, *args)
|
@@ -51,10 +67,11 @@ module ActiveSupport
|
|
51
67
|
end
|
52
68
|
|
53
69
|
def listeners_for(name)
|
54
|
-
# this is correctly done double-checked locking (
|
70
|
+
# this is correctly done double-checked locking (Concurrent::Map's lookups have volatile semantics)
|
55
71
|
@listeners_for[name] || synchronize do
|
56
72
|
# use synchronisation when accessing @subscribers
|
57
|
-
@listeners_for[name] ||=
|
73
|
+
@listeners_for[name] ||=
|
74
|
+
@string_subscribers[name] + @other_subscribers.select { |s| s.subscribed_to?(name) }
|
58
75
|
end
|
59
76
|
end
|
60
77
|
|
@@ -68,12 +85,29 @@ module ActiveSupport
|
|
68
85
|
|
69
86
|
module Subscribers # :nodoc:
|
70
87
|
def self.new(pattern, listener)
|
71
|
-
|
72
|
-
|
88
|
+
subscriber_class = Timed
|
89
|
+
|
90
|
+
if listener.respond_to?(:start) && listener.respond_to?(:finish)
|
91
|
+
subscriber_class = Evented
|
73
92
|
else
|
74
|
-
|
93
|
+
# Doing all this to detect a block like `proc { |x| }` vs
|
94
|
+
# `proc { |*x| }` or `proc { |**x| }`
|
95
|
+
if listener.respond_to?(:parameters)
|
96
|
+
params = listener.parameters
|
97
|
+
if params.length == 1 && params.first.first == :opt
|
98
|
+
subscriber_class = EventObject
|
99
|
+
end
|
100
|
+
end
|
75
101
|
end
|
76
102
|
|
103
|
+
wrap_all pattern, subscriber_class.new(pattern, listener)
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.event_object_subscriber(pattern, block)
|
107
|
+
wrap_all pattern, EventObject.new(pattern, block)
|
108
|
+
end
|
109
|
+
|
110
|
+
def self.wrap_all(pattern, subscriber)
|
77
111
|
unless pattern
|
78
112
|
AllMessages.new(subscriber)
|
79
113
|
else
|
@@ -81,9 +115,33 @@ module ActiveSupport
|
|
81
115
|
end
|
82
116
|
end
|
83
117
|
|
118
|
+
class Matcher #:nodoc:
|
119
|
+
attr_reader :pattern, :exclusions
|
120
|
+
|
121
|
+
def self.wrap(pattern)
|
122
|
+
return pattern if String === pattern
|
123
|
+
new(pattern)
|
124
|
+
end
|
125
|
+
|
126
|
+
def initialize(pattern)
|
127
|
+
@pattern = pattern
|
128
|
+
@exclusions = Set.new
|
129
|
+
end
|
130
|
+
|
131
|
+
def unsubscribe!(name)
|
132
|
+
exclusions << -name if pattern === name
|
133
|
+
end
|
134
|
+
|
135
|
+
def ===(name)
|
136
|
+
pattern === name && !exclusions.include?(name)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
84
140
|
class Evented #:nodoc:
|
141
|
+
attr_reader :pattern
|
142
|
+
|
85
143
|
def initialize(pattern, delegate)
|
86
|
-
@pattern = pattern
|
144
|
+
@pattern = Matcher.wrap(pattern)
|
87
145
|
@delegate = delegate
|
88
146
|
@can_publish = delegate.respond_to?(:publish)
|
89
147
|
end
|
@@ -103,11 +161,15 @@ module ActiveSupport
|
|
103
161
|
end
|
104
162
|
|
105
163
|
def subscribed_to?(name)
|
106
|
-
|
164
|
+
pattern === name
|
107
165
|
end
|
108
166
|
|
109
167
|
def matches?(name)
|
110
|
-
|
168
|
+
pattern && pattern === name
|
169
|
+
end
|
170
|
+
|
171
|
+
def unsubscribe!(name)
|
172
|
+
pattern.unsubscribe!(name)
|
111
173
|
end
|
112
174
|
end
|
113
175
|
|
@@ -128,6 +190,27 @@ module ActiveSupport
|
|
128
190
|
end
|
129
191
|
end
|
130
192
|
|
193
|
+
class EventObject < Evented
|
194
|
+
def start(name, id, payload)
|
195
|
+
stack = Thread.current[:_event_stack] ||= []
|
196
|
+
event = build_event name, id, payload
|
197
|
+
event.start!
|
198
|
+
stack.push event
|
199
|
+
end
|
200
|
+
|
201
|
+
def finish(name, id, payload)
|
202
|
+
stack = Thread.current[:_event_stack]
|
203
|
+
event = stack.pop
|
204
|
+
event.finish!
|
205
|
+
@delegate.call event
|
206
|
+
end
|
207
|
+
|
208
|
+
private
|
209
|
+
def build_event(name, id, payload)
|
210
|
+
ActiveSupport::Notifications::Event.new name, nil, nil, id, payload
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
131
214
|
class AllMessages # :nodoc:
|
132
215
|
def initialize(delegate)
|
133
216
|
@delegate = delegate
|
@@ -149,6 +232,10 @@ module ActiveSupport
|
|
149
232
|
true
|
150
233
|
end
|
151
234
|
|
235
|
+
def unsubscribe!(*)
|
236
|
+
false
|
237
|
+
end
|
238
|
+
|
152
239
|
alias :matches? :===
|
153
240
|
end
|
154
241
|
end
|