activesupport 4.0.12 → 7.0.2.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of activesupport might be problematic. Click here for more details.

Files changed (295) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +249 -501
  3. data/MIT-LICENSE +2 -2
  4. data/README.rdoc +10 -5
  5. data/lib/active_support/actionable_error.rb +48 -0
  6. data/lib/active_support/all.rb +5 -3
  7. data/lib/active_support/array_inquirer.rb +48 -0
  8. data/lib/active_support/backtrace_cleaner.rb +41 -13
  9. data/lib/active_support/benchmarkable.rb +7 -15
  10. data/lib/active_support/builder.rb +3 -1
  11. data/lib/active_support/cache/file_store.rb +96 -74
  12. data/lib/active_support/cache/mem_cache_store.rb +211 -103
  13. data/lib/active_support/cache/memory_store.rb +90 -58
  14. data/lib/active_support/cache/null_store.rb +19 -7
  15. data/lib/active_support/cache/redis_cache_store.rb +468 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +86 -83
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +45 -0
  18. data/lib/active_support/cache.rb +580 -241
  19. data/lib/active_support/callbacks.rb +812 -425
  20. data/lib/active_support/code_generator.rb +65 -0
  21. data/lib/active_support/concern.rb +103 -14
  22. data/lib/active_support/concurrency/load_interlock_aware_monitor.rb +33 -0
  23. data/lib/active_support/concurrency/share_lock.rb +226 -0
  24. data/lib/active_support/configurable.rb +21 -19
  25. data/lib/active_support/configuration_file.rb +51 -0
  26. data/lib/active_support/core_ext/array/access.rb +47 -1
  27. data/lib/active_support/core_ext/array/conversions.rb +35 -44
  28. data/lib/active_support/core_ext/array/deprecated_conversions.rb +25 -0
  29. data/lib/active_support/core_ext/array/extract.rb +21 -0
  30. data/lib/active_support/core_ext/array/extract_options.rb +2 -0
  31. data/lib/active_support/core_ext/array/grouping.rb +26 -16
  32. data/lib/active_support/core_ext/array/inquiry.rb +19 -0
  33. data/lib/active_support/core_ext/array/wrap.rb +7 -4
  34. data/lib/active_support/core_ext/array.rb +10 -7
  35. data/lib/active_support/core_ext/benchmark.rb +5 -3
  36. data/lib/active_support/core_ext/big_decimal/conversions.rb +9 -26
  37. data/lib/active_support/core_ext/big_decimal.rb +3 -1
  38. data/lib/active_support/core_ext/class/attribute.rb +52 -49
  39. data/lib/active_support/core_ext/class/attribute_accessors.rb +5 -169
  40. data/lib/active_support/core_ext/class/subclasses.rb +25 -26
  41. data/lib/active_support/core_ext/class.rb +4 -4
  42. data/lib/active_support/core_ext/date/acts_like.rb +3 -1
  43. data/lib/active_support/core_ext/date/blank.rb +14 -0
  44. data/lib/active_support/core_ext/date/calculations.rb +31 -18
  45. data/lib/active_support/core_ext/date/conversions.rb +43 -32
  46. data/lib/active_support/core_ext/date/deprecated_conversions.rb +26 -0
  47. data/lib/active_support/core_ext/date/zones.rb +5 -34
  48. data/lib/active_support/core_ext/date.rb +7 -4
  49. data/lib/active_support/core_ext/date_and_time/calculations.rb +198 -66
  50. data/lib/active_support/core_ext/date_and_time/compatibility.rb +31 -0
  51. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  52. data/lib/active_support/core_ext/date_time/acts_like.rb +4 -2
  53. data/lib/active_support/core_ext/date_time/blank.rb +14 -0
  54. data/lib/active_support/core_ext/date_time/calculations.rb +79 -38
  55. data/lib/active_support/core_ext/date_time/compatibility.rb +18 -0
  56. data/lib/active_support/core_ext/date_time/conversions.rb +31 -26
  57. data/lib/active_support/core_ext/date_time/deprecated_conversions.rb +22 -0
  58. data/lib/active_support/core_ext/date_time.rb +8 -4
  59. data/lib/active_support/core_ext/digest/uuid.rb +79 -0
  60. data/lib/active_support/core_ext/digest.rb +3 -0
  61. data/lib/active_support/core_ext/enumerable.rb +249 -17
  62. data/lib/active_support/core_ext/file/atomic.rb +41 -32
  63. data/lib/active_support/core_ext/file.rb +3 -1
  64. data/lib/active_support/core_ext/hash/conversions.rb +71 -49
  65. data/lib/active_support/core_ext/hash/deep_merge.rb +9 -13
  66. data/lib/active_support/core_ext/hash/deep_transform_values.rb +46 -0
  67. data/lib/active_support/core_ext/hash/except.rb +14 -5
  68. data/lib/active_support/core_ext/hash/indifferent_access.rb +5 -3
  69. data/lib/active_support/core_ext/hash/keys.rb +39 -56
  70. data/lib/active_support/core_ext/hash/reverse_merge.rb +5 -2
  71. data/lib/active_support/core_ext/hash/slice.rb +8 -23
  72. data/lib/active_support/core_ext/hash.rb +10 -8
  73. data/lib/active_support/core_ext/integer/inflections.rb +3 -1
  74. data/lib/active_support/core_ext/integer/multiple.rb +3 -1
  75. data/lib/active_support/core_ext/integer/time.rb +11 -33
  76. data/lib/active_support/core_ext/integer.rb +5 -3
  77. data/lib/active_support/core_ext/kernel/concern.rb +14 -0
  78. data/lib/active_support/core_ext/kernel/reporting.rb +9 -78
  79. data/lib/active_support/core_ext/kernel/singleton_class.rb +2 -0
  80. data/lib/active_support/core_ext/kernel.rb +5 -4
  81. data/lib/active_support/core_ext/load_error.rb +5 -21
  82. data/lib/active_support/core_ext/module/aliasing.rb +6 -44
  83. data/lib/active_support/core_ext/module/anonymous.rb +12 -1
  84. data/lib/active_support/core_ext/module/attr_internal.rb +8 -8
  85. data/lib/active_support/core_ext/module/attribute_accessors.rb +186 -44
  86. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +157 -0
  87. data/lib/active_support/core_ext/module/concerning.rb +140 -0
  88. data/lib/active_support/core_ext/module/delegation.rb +172 -45
  89. data/lib/active_support/core_ext/module/deprecation.rb +3 -3
  90. data/lib/active_support/core_ext/module/introspection.rb +23 -38
  91. data/lib/active_support/core_ext/module/redefine_method.rb +40 -0
  92. data/lib/active_support/core_ext/module/remove_method.rb +8 -3
  93. data/lib/active_support/core_ext/module.rb +13 -10
  94. data/lib/active_support/core_ext/name_error.rb +45 -4
  95. data/lib/active_support/core_ext/numeric/bytes.rb +22 -0
  96. data/lib/active_support/core_ext/numeric/conversions.rb +135 -127
  97. data/lib/active_support/core_ext/numeric/deprecated_conversions.rb +60 -0
  98. data/lib/active_support/core_ext/numeric/time.rb +37 -50
  99. data/lib/active_support/core_ext/numeric.rb +6 -3
  100. data/lib/active_support/core_ext/object/acts_like.rb +41 -6
  101. data/lib/active_support/core_ext/object/blank.rb +70 -20
  102. data/lib/active_support/core_ext/object/conversions.rb +6 -4
  103. data/lib/active_support/core_ext/object/deep_dup.rb +19 -10
  104. data/lib/active_support/core_ext/object/duplicable.rb +17 -47
  105. data/lib/active_support/core_ext/object/inclusion.rb +18 -15
  106. data/lib/active_support/core_ext/object/instance_variables.rb +3 -1
  107. data/lib/active_support/core_ext/object/json.rb +244 -0
  108. data/lib/active_support/core_ext/object/to_param.rb +3 -1
  109. data/lib/active_support/core_ext/object/to_query.rb +21 -8
  110. data/lib/active_support/core_ext/object/try.rb +106 -26
  111. data/lib/active_support/core_ext/object/with_options.rb +64 -5
  112. data/lib/active_support/core_ext/object.rb +14 -12
  113. data/lib/active_support/core_ext/pathname/existence.rb +21 -0
  114. data/lib/active_support/core_ext/pathname.rb +3 -0
  115. data/lib/active_support/core_ext/range/compare_range.rb +57 -0
  116. data/lib/active_support/core_ext/range/conversions.rb +37 -15
  117. data/lib/active_support/core_ext/range/deprecated_conversions.rb +26 -0
  118. data/lib/active_support/core_ext/range/each.rb +18 -17
  119. data/lib/active_support/core_ext/range/include_time_with_zone.rb +7 -0
  120. data/lib/active_support/core_ext/range/overlaps.rb +2 -0
  121. data/lib/active_support/core_ext/range.rb +7 -4
  122. data/lib/active_support/core_ext/regexp.rb +10 -1
  123. data/lib/active_support/core_ext/securerandom.rb +45 -0
  124. data/lib/active_support/core_ext/string/access.rb +42 -51
  125. data/lib/active_support/core_ext/string/behavior.rb +3 -1
  126. data/lib/active_support/core_ext/string/conversions.rb +18 -13
  127. data/lib/active_support/core_ext/string/exclude.rb +5 -3
  128. data/lib/active_support/core_ext/string/filters.rb +97 -7
  129. data/lib/active_support/core_ext/string/indent.rb +6 -4
  130. data/lib/active_support/core_ext/string/inflections.rb +106 -25
  131. data/lib/active_support/core_ext/string/inquiry.rb +4 -1
  132. data/lib/active_support/core_ext/string/multibyte.rb +18 -9
  133. data/lib/active_support/core_ext/string/output_safety.rb +227 -54
  134. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -2
  135. data/lib/active_support/core_ext/string/strip.rb +6 -5
  136. data/lib/active_support/core_ext/string/zones.rb +4 -1
  137. data/lib/active_support/core_ext/string.rb +15 -13
  138. data/lib/active_support/core_ext/symbol/starts_ends_with.rb +6 -0
  139. data/lib/active_support/core_ext/symbol.rb +3 -0
  140. data/lib/active_support/core_ext/time/acts_like.rb +3 -1
  141. data/lib/active_support/core_ext/time/calculations.rb +178 -116
  142. data/lib/active_support/core_ext/time/compatibility.rb +16 -0
  143. data/lib/active_support/core_ext/time/conversions.rb +37 -25
  144. data/lib/active_support/core_ext/time/deprecated_conversions.rb +22 -0
  145. data/lib/active_support/core_ext/time/zones.rb +44 -42
  146. data/lib/active_support/core_ext/time.rb +8 -5
  147. data/lib/active_support/core_ext/uri.rb +4 -25
  148. data/lib/active_support/core_ext.rb +4 -2
  149. data/lib/active_support/current_attributes/test_helper.rb +13 -0
  150. data/lib/active_support/current_attributes.rb +226 -0
  151. data/lib/active_support/dependencies/autoload.rb +3 -1
  152. data/lib/active_support/dependencies/interlock.rb +49 -0
  153. data/lib/active_support/dependencies/require_dependency.rb +28 -0
  154. data/lib/active_support/dependencies.rb +71 -696
  155. data/lib/active_support/deprecation/behaviors.rb +65 -16
  156. data/lib/active_support/deprecation/constant_accessor.rb +52 -0
  157. data/lib/active_support/deprecation/disallowed.rb +56 -0
  158. data/lib/active_support/deprecation/instance_delegator.rb +16 -2
  159. data/lib/active_support/deprecation/method_wrappers.rb +62 -21
  160. data/lib/active_support/deprecation/proxy_wrappers.rb +82 -31
  161. data/lib/active_support/deprecation/reporting.rb +81 -18
  162. data/lib/active_support/deprecation.rb +19 -11
  163. data/lib/active_support/descendants_tracker.rb +192 -34
  164. data/lib/active_support/digest.rb +22 -0
  165. data/lib/active_support/duration/iso8601_parser.rb +123 -0
  166. data/lib/active_support/duration/iso8601_serializer.rb +67 -0
  167. data/lib/active_support/duration.rb +437 -39
  168. data/lib/active_support/encrypted_configuration.rb +56 -0
  169. data/lib/active_support/encrypted_file.rb +117 -0
  170. data/lib/active_support/environment_inquirer.rb +20 -0
  171. data/lib/active_support/error_reporter.rb +117 -0
  172. data/lib/active_support/evented_file_update_checker.rb +170 -0
  173. data/lib/active_support/execution_context/test_helper.rb +13 -0
  174. data/lib/active_support/execution_context.rb +53 -0
  175. data/lib/active_support/execution_wrapper.rb +151 -0
  176. data/lib/active_support/executor/test_helper.rb +7 -0
  177. data/lib/active_support/executor.rb +8 -0
  178. data/lib/active_support/file_update_checker.rb +62 -37
  179. data/lib/active_support/fork_tracker.rb +71 -0
  180. data/lib/active_support/gem_version.rb +17 -0
  181. data/lib/active_support/gzip.rb +7 -5
  182. data/lib/active_support/hash_with_indifferent_access.rb +207 -54
  183. data/lib/active_support/html_safe_translation.rb +43 -0
  184. data/lib/active_support/i18n.rb +10 -6
  185. data/lib/active_support/i18n_railtie.rb +48 -19
  186. data/lib/active_support/inflections.rb +19 -12
  187. data/lib/active_support/inflector/inflections.rb +97 -37
  188. data/lib/active_support/inflector/methods.rb +192 -157
  189. data/lib/active_support/inflector/transliterate.rb +83 -33
  190. data/lib/active_support/inflector.rb +7 -5
  191. data/lib/active_support/isolated_execution_state.rb +64 -0
  192. data/lib/active_support/json/decoding.rb +37 -42
  193. data/lib/active_support/json/encoding.rb +93 -293
  194. data/lib/active_support/json.rb +4 -2
  195. data/lib/active_support/key_generator.rb +30 -47
  196. data/lib/active_support/lazy_load_hooks.rb +54 -21
  197. data/lib/active_support/locale/en.rb +33 -0
  198. data/lib/active_support/locale/en.yml +10 -4
  199. data/lib/active_support/log_subscriber/test_helper.rb +14 -12
  200. data/lib/active_support/log_subscriber.rb +61 -18
  201. data/lib/active_support/logger.rb +40 -4
  202. data/lib/active_support/logger_silence.rb +17 -20
  203. data/lib/active_support/logger_thread_safe_level.rb +69 -0
  204. data/lib/active_support/message_encryptor.rb +178 -55
  205. data/lib/active_support/message_verifier.rb +195 -26
  206. data/lib/active_support/messages/metadata.rb +80 -0
  207. data/lib/active_support/messages/rotation_configuration.rb +23 -0
  208. data/lib/active_support/messages/rotator.rb +57 -0
  209. data/lib/active_support/multibyte/chars.rb +45 -92
  210. data/lib/active_support/multibyte/unicode.rb +44 -377
  211. data/lib/active_support/multibyte.rb +5 -3
  212. data/lib/active_support/notifications/fanout.rb +177 -44
  213. data/lib/active_support/notifications/instrumenter.rb +117 -17
  214. data/lib/active_support/notifications.rb +106 -39
  215. data/lib/active_support/number_helper/number_converter.rb +181 -0
  216. data/lib/active_support/number_helper/number_to_currency_converter.rb +46 -0
  217. data/lib/active_support/number_helper/number_to_delimited_converter.rb +30 -0
  218. data/lib/active_support/number_helper/number_to_human_converter.rb +69 -0
  219. data/lib/active_support/number_helper/number_to_human_size_converter.rb +60 -0
  220. data/lib/active_support/number_helper/number_to_percentage_converter.rb +16 -0
  221. data/lib/active_support/number_helper/number_to_phone_converter.rb +59 -0
  222. data/lib/active_support/number_helper/number_to_rounded_converter.rb +59 -0
  223. data/lib/active_support/number_helper/rounding_helper.rb +46 -0
  224. data/lib/active_support/number_helper.rb +152 -394
  225. data/lib/active_support/option_merger.rb +18 -5
  226. data/lib/active_support/ordered_hash.rb +8 -6
  227. data/lib/active_support/ordered_options.rb +43 -7
  228. data/lib/active_support/parameter_filter.rb +138 -0
  229. data/lib/active_support/per_thread_registry.rb +24 -11
  230. data/lib/active_support/proxy_object.rb +2 -0
  231. data/lib/active_support/rails.rb +10 -11
  232. data/lib/active_support/railtie.rb +118 -12
  233. data/lib/active_support/reloader.rb +130 -0
  234. data/lib/active_support/rescuable.rb +112 -57
  235. data/lib/active_support/ruby_features.rb +7 -0
  236. data/lib/active_support/secure_compare_rotator.rb +51 -0
  237. data/lib/active_support/security_utils.rb +38 -0
  238. data/lib/active_support/string_inquirer.rb +11 -4
  239. data/lib/active_support/subscriber.rb +109 -39
  240. data/lib/active_support/tagged_logging.rb +54 -17
  241. data/lib/active_support/test_case.rb +121 -37
  242. data/lib/active_support/testing/assertions.rb +177 -39
  243. data/lib/active_support/testing/autorun.rb +5 -3
  244. data/lib/active_support/testing/constant_lookup.rb +3 -6
  245. data/lib/active_support/testing/declarative.rb +10 -22
  246. data/lib/active_support/testing/deprecation.rb +65 -11
  247. data/lib/active_support/testing/file_fixtures.rb +38 -0
  248. data/lib/active_support/testing/isolation.rb +56 -87
  249. data/lib/active_support/testing/method_call_assertions.rb +70 -0
  250. data/lib/active_support/testing/parallelization/server.rb +82 -0
  251. data/lib/active_support/testing/parallelization/worker.rb +103 -0
  252. data/lib/active_support/testing/parallelization.rb +55 -0
  253. data/lib/active_support/testing/parallelize_executor.rb +76 -0
  254. data/lib/active_support/testing/setup_and_teardown.rb +30 -10
  255. data/lib/active_support/testing/stream.rb +41 -0
  256. data/lib/active_support/testing/tagged_logging.rb +6 -4
  257. data/lib/active_support/testing/time_helpers.rb +246 -0
  258. data/lib/active_support/time.rb +13 -13
  259. data/lib/active_support/time_with_zone.rb +315 -90
  260. data/lib/active_support/values/time_zone.rb +306 -135
  261. data/lib/active_support/version.rb +6 -7
  262. data/lib/active_support/xml_mini/jdom.rb +117 -115
  263. data/lib/active_support/xml_mini/libxml.rb +22 -21
  264. data/lib/active_support/xml_mini/libxmlsax.rb +17 -19
  265. data/lib/active_support/xml_mini/nokogiri.rb +19 -19
  266. data/lib/active_support/xml_mini/nokogirisax.rb +16 -17
  267. data/lib/active_support/xml_mini/rexml.rb +25 -17
  268. data/lib/active_support/xml_mini.rb +67 -56
  269. data/lib/active_support.rb +58 -3
  270. metadata +125 -66
  271. data/lib/active_support/basic_object.rb +0 -11
  272. data/lib/active_support/buffered_logger.rb +0 -21
  273. data/lib/active_support/concurrency/latch.rb +0 -27
  274. data/lib/active_support/core_ext/array/prepend_and_append.rb +0 -7
  275. data/lib/active_support/core_ext/array/uniq_by.rb +0 -19
  276. data/lib/active_support/core_ext/class/delegating_attributes.rb +0 -40
  277. data/lib/active_support/core_ext/date_time/zones.rb +0 -24
  278. data/lib/active_support/core_ext/hash/diff.rb +0 -14
  279. data/lib/active_support/core_ext/kernel/agnostics.rb +0 -11
  280. data/lib/active_support/core_ext/kernel/debugger.rb +0 -10
  281. data/lib/active_support/core_ext/logger.rb +0 -67
  282. data/lib/active_support/core_ext/marshal.rb +0 -21
  283. data/lib/active_support/core_ext/module/qualified_const.rb +0 -52
  284. data/lib/active_support/core_ext/module/reachable.rb +0 -8
  285. data/lib/active_support/core_ext/object/to_json.rb +0 -27
  286. data/lib/active_support/core_ext/proc.rb +0 -17
  287. data/lib/active_support/core_ext/range/include_range.rb +0 -23
  288. data/lib/active_support/core_ext/string/encoding.rb +0 -8
  289. data/lib/active_support/core_ext/struct.rb +0 -6
  290. data/lib/active_support/core_ext/thread.rb +0 -79
  291. data/lib/active_support/core_ext/time/marshal.rb +0 -30
  292. data/lib/active_support/file_watcher.rb +0 -36
  293. data/lib/active_support/json/variable.rb +0 -18
  294. data/lib/active_support/testing/pending.rb +0 -14
  295. data/lib/active_support/values/unicode_tables.dat +0 -0
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveSupport
4
+ module HtmlSafeTranslation # :nodoc:
5
+ extend self
6
+
7
+ def translate(key, **options)
8
+ if html_safe_translation_key?(key)
9
+ html_safe_options = html_escape_translation_options(options)
10
+ translation = I18n.translate(key, **html_safe_options)
11
+ html_safe_translation(translation)
12
+ else
13
+ I18n.translate(key, **options)
14
+ end
15
+ end
16
+
17
+ private
18
+ def html_safe_translation_key?(key)
19
+ /(?:_|\b)html\z/.match?(key)
20
+ end
21
+
22
+ def html_escape_translation_options(options)
23
+ options.each do |name, value|
24
+ unless i18n_option?(name) || (name == :count && value.is_a?(Numeric))
25
+ options[name] = ERB::Util.html_escape(value.to_s)
26
+ end
27
+ end
28
+ end
29
+
30
+ def i18n_option?(name)
31
+ (@i18n_option_names ||= I18n::RESERVED_KEYS.to_set).include?(name)
32
+ end
33
+
34
+
35
+ def html_safe_translation(translation)
36
+ if translation.respond_to?(:map)
37
+ translation.map { |element| element.respond_to?(:html_safe) ? element.html_safe : element }
38
+ else
39
+ translation.respond_to?(:html_safe) ? translation.html_safe : translation
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,13 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/deep_merge"
4
+ require "active_support/core_ext/hash/except"
5
+ require "active_support/core_ext/hash/slice"
1
6
  begin
2
- require 'active_support/core_ext/hash/deep_merge'
3
- require 'active_support/core_ext/hash/except'
4
- require 'active_support/core_ext/hash/slice'
5
- require 'i18n'
6
- require 'active_support/lazy_load_hooks'
7
+ require "i18n"
8
+ require "i18n/backend/fallbacks"
7
9
  rescue LoadError => e
8
10
  $stderr.puts "The i18n gem is not available. Please add it to your Gemfile and run bundle install"
9
11
  raise e
10
12
  end
13
+ require "active_support/lazy_load_hooks"
11
14
 
12
15
  ActiveSupport.run_load_hooks(:i18n)
13
- I18n.load_path << "#{File.dirname(__FILE__)}/locale/en.yml"
16
+ I18n.load_path << File.expand_path("locale/en.yml", __dir__)
17
+ I18n.load_path << File.expand_path("locale/en.rb", __dir__)
@@ -1,15 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support"
2
- require "active_support/file_update_checker"
3
4
  require "active_support/core_ext/array/wrap"
4
5
 
6
+ # :enddoc:
7
+
5
8
  module I18n
6
9
  class Railtie < Rails::Railtie
7
10
  config.i18n = ActiveSupport::OrderedOptions.new
8
11
  config.i18n.railties_load_path = []
9
12
  config.i18n.load_path = []
10
13
  config.i18n.fallbacks = ActiveSupport::OrderedOptions.new
11
- # Enforce I18n to check the available locales when setting a locale.
12
- config.i18n.enforce_available_locales = true
14
+
15
+ config.eager_load_namespaces << I18n
13
16
 
14
17
  # Set the i18n configuration after initialization since a lot of
15
18
  # configuration is still usually done in application initializers.
@@ -23,8 +26,6 @@ module I18n
23
26
  I18n::Railtie.initialize_i18n(app)
24
27
  end
25
28
 
26
- protected
27
-
28
29
  @i18n_inited = false
29
30
 
30
31
  # Setup i18n configuration.
@@ -36,17 +37,21 @@ module I18n
36
37
  # Avoid issues with setting the default_locale by disabling available locales
37
38
  # check while configuring.
38
39
  enforce_available_locales = app.config.i18n.delete(:enforce_available_locales)
39
- enforce_available_locales = I18n.enforce_available_locales unless I18n.enforce_available_locales.nil?
40
+ enforce_available_locales = I18n.enforce_available_locales if enforce_available_locales.nil?
40
41
  I18n.enforce_available_locales = false
41
42
 
43
+ reloadable_paths = []
42
44
  app.config.i18n.each do |setting, value|
43
45
  case setting
44
46
  when :railties_load_path
45
- app.config.i18n.load_path.unshift(*value)
47
+ reloadable_paths = value
48
+ app.config.i18n.load_path.unshift(*value.flat_map(&:existent))
46
49
  when :load_path
47
50
  I18n.load_path += value
51
+ when :raise_on_missing_translations
52
+ forward_raise_on_missing_translations_config(app)
48
53
  else
49
- I18n.send("#{setting}=", value)
54
+ I18n.public_send("#{setting}=", value)
50
55
  end
51
56
  end
52
57
 
@@ -55,29 +60,47 @@ module I18n
55
60
  # Restore available locales check so it will take place from now on.
56
61
  I18n.enforce_available_locales = enforce_available_locales
57
62
 
58
- reloader = ActiveSupport::FileUpdateChecker.new(I18n.load_path.dup){ I18n.reload! }
63
+ directories = watched_dirs_with_extensions(reloadable_paths)
64
+ reloader = app.config.file_watcher.new(I18n.load_path.dup, directories) do
65
+ I18n.load_path.keep_if { |p| File.exist?(p) }
66
+ I18n.load_path |= reloadable_paths.flat_map(&:existent)
67
+ end
68
+
59
69
  app.reloaders << reloader
60
- ActionDispatch::Reloader.to_prepare { reloader.execute_if_updated }
70
+ app.reloader.to_run do
71
+ reloader.execute_if_updated { require_unload_lock! }
72
+ end
61
73
  reloader.execute
62
74
 
63
75
  @i18n_inited = true
64
76
  end
65
77
 
78
+ def self.forward_raise_on_missing_translations_config(app)
79
+ ActiveSupport.on_load(:action_view) do
80
+ ActionView::Helpers::TranslationHelper.raise_on_missing_translations = app.config.i18n.raise_on_missing_translations
81
+ end
82
+
83
+ ActiveSupport.on_load(:action_controller) do
84
+ AbstractController::Translation.raise_on_missing_translations = app.config.i18n.raise_on_missing_translations
85
+ end
86
+ end
87
+
66
88
  def self.include_fallbacks_module
67
- I18n.backend.class.send(:include, I18n::Backend::Fallbacks)
89
+ I18n.backend.class.include(I18n::Backend::Fallbacks)
68
90
  end
69
91
 
70
92
  def self.init_fallbacks(fallbacks)
71
93
  include_fallbacks_module
72
94
 
73
- args = case fallbacks
74
- when ActiveSupport::OrderedOptions
75
- [*(fallbacks[:defaults] || []) << fallbacks[:map]].compact
76
- when Hash, Array
77
- Array.wrap(fallbacks)
78
- else # TrueClass
79
- []
80
- end
95
+ args = \
96
+ case fallbacks
97
+ when ActiveSupport::OrderedOptions
98
+ [*(fallbacks[:defaults] || []) << fallbacks[:map]].compact
99
+ when Hash, Array
100
+ Array.wrap(fallbacks)
101
+ else # TrueClass
102
+ [I18n.default_locale]
103
+ end
81
104
 
82
105
  I18n.fallbacks = I18n::Locale::Fallbacks.new(*args)
83
106
  end
@@ -92,5 +115,11 @@ module I18n
92
115
  raise "Unexpected fallback type #{fallbacks.inspect}"
93
116
  end
94
117
  end
118
+
119
+ def self.watched_dirs_with_extensions(paths)
120
+ paths.each_with_object({}) do |path, result|
121
+ result[path.absolute_current] = path.extensions
122
+ end
123
+ end
95
124
  end
96
125
  end
@@ -1,9 +1,17 @@
1
- require 'active_support/inflector/inflections'
1
+ # frozen_string_literal: true
2
2
 
3
+ require "active_support/inflector/inflections"
4
+
5
+ #--
6
+ # Defines the standard inflection rules. These are the starting point for
7
+ # new projects and are not considered complete. The current set of inflection
8
+ # rules is frozen. This means, we do not change them to become more complete.
9
+ # This is a safety measure to keep existing applications from breaking.
10
+ #++
3
11
  module ActiveSupport
4
12
  Inflector.inflections(:en) do |inflect|
5
- inflect.plural(/$/, 's')
6
- inflect.plural(/s$/i, 's')
13
+ inflect.plural(/$/, "s")
14
+ inflect.plural(/s$/i, "s")
7
15
  inflect.plural(/^(ax|test)is$/i, '\1es')
8
16
  inflect.plural(/(octop|vir)us$/i, '\1i')
9
17
  inflect.plural(/(octop|vir)i$/i, '\1i')
@@ -12,7 +20,7 @@ module ActiveSupport
12
20
  inflect.plural(/(buffal|tomat)o$/i, '\1oes')
13
21
  inflect.plural(/([ti])um$/i, '\1a')
14
22
  inflect.plural(/([ti])a$/i, '\1a')
15
- inflect.plural(/sis$/i, 'ses')
23
+ inflect.plural(/sis$/i, "ses")
16
24
  inflect.plural(/(?:([^f])fe|([lr])f)$/i, '\1\2ves')
17
25
  inflect.plural(/(hive)$/i, '\1s')
18
26
  inflect.plural(/([^aeiouy]|qu)y$/i, '\1ies')
@@ -24,7 +32,7 @@ module ActiveSupport
24
32
  inflect.plural(/^(oxen)$/i, '\1')
25
33
  inflect.plural(/(quiz)$/i, '\1zes')
26
34
 
27
- inflect.singular(/s$/i, '')
35
+ inflect.singular(/s$/i, "")
28
36
  inflect.singular(/(ss)$/i, '\1')
29
37
  inflect.singular(/(n)ews$/i, '\1ews')
30
38
  inflect.singular(/([ti])a$/i, '\1um')
@@ -52,13 +60,12 @@ module ActiveSupport
52
60
  inflect.singular(/(quiz)zes$/i, '\1')
53
61
  inflect.singular(/(database)s$/i, '\1')
54
62
 
55
- inflect.irregular('person', 'people')
56
- inflect.irregular('man', 'men')
57
- inflect.irregular('child', 'children')
58
- inflect.irregular('sex', 'sexes')
59
- inflect.irregular('move', 'moves')
60
- inflect.irregular('cow', 'kine')
61
- inflect.irregular('zombie', 'zombies')
63
+ inflect.irregular("person", "people")
64
+ inflect.irregular("man", "men")
65
+ inflect.irregular("child", "children")
66
+ inflect.irregular("sex", "sexes")
67
+ inflect.irregular("move", "moves")
68
+ inflect.irregular("zombie", "zombies")
62
69
 
63
70
  inflect.uncountable(%w(equipment information rice money species series fish sheep jeans police))
64
71
  end
@@ -1,6 +1,7 @@
1
- require 'thread_safe'
2
- require 'active_support/core_ext/array/prepend_and_append'
3
- require 'active_support/i18n'
1
+ # frozen_string_literal: true
2
+
3
+ require "concurrent/map"
4
+ require "active_support/i18n"
4
5
 
5
6
  module ActiveSupport
6
7
  module Inflector
@@ -15,33 +16,76 @@ module ActiveSupport
15
16
  # inflect.plural /^(ox)$/i, '\1\2en'
16
17
  # inflect.singular /^(ox)en/i, '\1'
17
18
  #
18
- # inflect.irregular 'octopus', 'octopi'
19
+ # inflect.irregular 'cactus', 'cacti'
19
20
  #
20
21
  # inflect.uncountable 'equipment'
21
22
  # end
22
23
  #
23
24
  # New rules are added at the top. So in the example above, the irregular
24
- # rule for octopus will now be the first of the pluralization and
25
+ # rule for cactus will now be the first of the pluralization and
25
26
  # singularization rules that is runs. This guarantees that your rules run
26
27
  # before any of the rules that may already have been loaded.
27
28
  class Inflections
28
- @__instance__ = ThreadSafe::Cache.new
29
+ @__instance__ = Concurrent::Map.new
30
+
31
+ class Uncountables < Array
32
+ def initialize
33
+ @regex_array = []
34
+ super
35
+ end
36
+
37
+ def delete(entry)
38
+ super entry
39
+ @regex_array.delete(to_regex(entry))
40
+ end
41
+
42
+ def <<(*word)
43
+ add(word)
44
+ end
45
+
46
+ def add(words)
47
+ words = words.flatten.map(&:downcase)
48
+ concat(words)
49
+ @regex_array += words.map { |word| to_regex(word) }
50
+ self
51
+ end
52
+
53
+ def uncountable?(str)
54
+ @regex_array.any? { |regex| regex.match? str }
55
+ end
56
+
57
+ private
58
+ def to_regex(string)
59
+ /\b#{::Regexp.escape(string)}\Z/i
60
+ end
61
+ end
29
62
 
30
63
  def self.instance(locale = :en)
31
64
  @__instance__[locale] ||= new
32
65
  end
33
66
 
34
- attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms, :acronym_regex
67
+ def self.instance_or_fallback(locale)
68
+ I18n.fallbacks[locale].each do |k|
69
+ return @__instance__[k] if @__instance__.key?(k)
70
+ end
71
+ instance(locale)
72
+ end
73
+
74
+ attr_reader :plurals, :singulars, :uncountables, :humans, :acronyms
75
+
76
+ attr_reader :acronyms_camelize_regex, :acronyms_underscore_regex # :nodoc:
35
77
 
36
78
  def initialize
37
- @plurals, @singulars, @uncountables, @humans, @acronyms, @acronym_regex = [], [], [], [], {}, /(?=a)b/
79
+ @plurals, @singulars, @uncountables, @humans, @acronyms = [], [], Uncountables.new, [], {}
80
+ define_acronym_regex_patterns
38
81
  end
39
82
 
40
83
  # Private, for the test suite.
41
84
  def initialize_dup(orig) # :nodoc:
42
- %w(plurals singulars uncountables humans acronyms acronym_regex).each do |scope|
43
- instance_variable_set("@#{scope}", orig.send(scope).dup)
85
+ %w(plurals singulars uncountables humans acronyms).each do |scope|
86
+ instance_variable_set("@#{scope}", orig.public_send(scope).dup)
44
87
  end
88
+ define_acronym_regex_patterns
45
89
  end
46
90
 
47
91
  # Specifies a new acronym. An acronym must be specified as it will appear
@@ -52,21 +96,21 @@ module ActiveSupport
52
96
  # into a non-delimited single lowercase word when passed to +underscore+.
53
97
  #
54
98
  # acronym 'HTML'
55
- # titleize 'html' #=> 'HTML'
56
- # camelize 'html' #=> 'HTML'
57
- # underscore 'MyHTML' #=> 'my_html'
99
+ # titleize 'html' # => 'HTML'
100
+ # camelize 'html' # => 'HTML'
101
+ # underscore 'MyHTML' # => 'my_html'
58
102
  #
59
103
  # The acronym, however, must occur as a delimited unit and not be part of
60
104
  # another word for conversions to recognize it:
61
105
  #
62
106
  # acronym 'HTTP'
63
- # camelize 'my_http_delimited' #=> 'MyHTTPDelimited'
64
- # camelize 'https' #=> 'Https', not 'HTTPs'
65
- # underscore 'HTTPS' #=> 'http_s', not 'https'
107
+ # camelize 'my_http_delimited' # => 'MyHTTPDelimited'
108
+ # camelize 'https' # => 'Https', not 'HTTPs'
109
+ # underscore 'HTTPS' # => 'http_s', not 'https'
66
110
  #
67
111
  # acronym 'HTTPS'
68
- # camelize 'https' #=> 'HTTPS'
69
- # underscore 'HTTPS' #=> 'https'
112
+ # camelize 'https' # => 'HTTPS'
113
+ # underscore 'HTTPS' # => 'https'
70
114
  #
71
115
  # Note: Acronyms that are passed to +pluralize+ will no longer be
72
116
  # recognized, since the acronym will not occur as a delimited unit in the
@@ -74,28 +118,28 @@ module ActiveSupport
74
118
  # form as an acronym as well:
75
119
  #
76
120
  # acronym 'API'
77
- # camelize(pluralize('api')) #=> 'Apis'
121
+ # camelize(pluralize('api')) # => 'Apis'
78
122
  #
79
123
  # acronym 'APIs'
80
- # camelize(pluralize('api')) #=> 'APIs'
124
+ # camelize(pluralize('api')) # => 'APIs'
81
125
  #
82
126
  # +acronym+ may be used to specify any word that contains an acronym or
83
127
  # otherwise needs to maintain a non-standard capitalization. The only
84
128
  # restriction is that the word must begin with a capital letter.
85
129
  #
86
130
  # acronym 'RESTful'
87
- # underscore 'RESTful' #=> 'restful'
88
- # underscore 'RESTfulController' #=> 'restful_controller'
89
- # titleize 'RESTfulController' #=> 'RESTful Controller'
90
- # camelize 'restful' #=> 'RESTful'
91
- # camelize 'restful_controller' #=> 'RESTfulController'
131
+ # underscore 'RESTful' # => 'restful'
132
+ # underscore 'RESTfulController' # => 'restful_controller'
133
+ # titleize 'RESTfulController' # => 'RESTful Controller'
134
+ # camelize 'restful' # => 'RESTful'
135
+ # camelize 'restful_controller' # => 'RESTfulController'
92
136
  #
93
137
  # acronym 'McDonald'
94
- # underscore 'McDonald' #=> 'mcdonald'
95
- # camelize 'mcdonald' #=> 'McDonald'
138
+ # underscore 'McDonald' # => 'mcdonald'
139
+ # camelize 'mcdonald' # => 'McDonald'
96
140
  def acronym(word)
97
141
  @acronyms[word.downcase] = word
98
- @acronym_regex = /#{@acronyms.values.join("|")}/
142
+ define_acronym_regex_patterns
99
143
  end
100
144
 
101
145
  # Specifies a new pluralization rule and its replacement. The rule can
@@ -123,7 +167,7 @@ module ActiveSupport
123
167
  # regular expressions. You simply pass the irregular in singular and
124
168
  # plural form.
125
169
  #
126
- # irregular 'octopus', 'octopi'
170
+ # irregular 'cactus', 'cacti'
127
171
  # irregular 'person', 'people'
128
172
  def irregular(singular, plural)
129
173
  @uncountables.delete(singular)
@@ -154,13 +198,13 @@ module ActiveSupport
154
198
  end
155
199
  end
156
200
 
157
- # Add uncountable words that shouldn't be attempted inflected.
201
+ # Specifies words that are uncountable and should not be inflected.
158
202
  #
159
203
  # uncountable 'money'
160
204
  # uncountable 'money', 'information'
161
205
  # uncountable %w( money information rice )
162
206
  def uncountable(*words)
163
- (@uncountables << words).flatten!
207
+ @uncountables.add(words)
164
208
  end
165
209
 
166
210
  # Specifies a humanized form of a string by a regular expression rule or
@@ -178,18 +222,34 @@ module ActiveSupport
178
222
  # Clears the loaded inflections within a given scope (default is
179
223
  # <tt>:all</tt>). Give the scope as a symbol of the inflection type, the
180
224
  # options are: <tt>:plurals</tt>, <tt>:singulars</tt>, <tt>:uncountables</tt>,
181
- # <tt>:humans</tt>.
225
+ # <tt>:humans</tt>, <tt>:acronyms</tt>.
182
226
  #
183
227
  # clear :all
184
228
  # clear :plurals
185
229
  def clear(scope = :all)
186
230
  case scope
187
- when :all
188
- @plurals, @singulars, @uncountables, @humans = [], [], [], []
189
- else
190
- instance_variable_set "@#{scope}", []
231
+ when :all
232
+ clear(:acronyms)
233
+ clear(:plurals)
234
+ clear(:singulars)
235
+ clear(:uncountables)
236
+ clear(:humans)
237
+ when :acronyms
238
+ @acronyms = {}
239
+ define_acronym_regex_patterns
240
+ when :uncountables
241
+ @uncountables = Uncountables.new
242
+ when :plurals, :singulars, :humans
243
+ instance_variable_set "@#{scope}", []
191
244
  end
192
245
  end
246
+
247
+ private
248
+ def define_acronym_regex_patterns
249
+ @acronym_regex = @acronyms.empty? ? /(?=a)b/ : /#{@acronyms.values.join("|")}/
250
+ @acronyms_camelize_regex = /^(?:#{@acronym_regex}(?=\b|[A-Z_])|\w)/
251
+ @acronyms_underscore_regex = /(?:(?<=([A-Za-z\d]))|\b)(#{@acronym_regex})(?=\b|[^a-z])/
252
+ end
193
253
  end
194
254
 
195
255
  # Yields a singleton instance of Inflector::Inflections so you can specify
@@ -204,7 +264,7 @@ module ActiveSupport
204
264
  if block_given?
205
265
  yield Inflections.instance(locale)
206
266
  else
207
- Inflections.instance(locale)
267
+ Inflections.instance_or_fallback(locale)
208
268
  end
209
269
  end
210
270
  end