activesupport 5.0.7.2

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

Potentially problematic release.


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

Files changed (236) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1018 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.rdoc +39 -0
  5. data/lib/active_support.rb +99 -0
  6. data/lib/active_support/all.rb +3 -0
  7. data/lib/active_support/array_inquirer.rb +44 -0
  8. data/lib/active_support/backtrace_cleaner.rb +103 -0
  9. data/lib/active_support/benchmarkable.rb +49 -0
  10. data/lib/active_support/builder.rb +6 -0
  11. data/lib/active_support/cache.rb +701 -0
  12. data/lib/active_support/cache/file_store.rb +204 -0
  13. data/lib/active_support/cache/mem_cache_store.rb +207 -0
  14. data/lib/active_support/cache/memory_store.rb +167 -0
  15. data/lib/active_support/cache/null_store.rb +41 -0
  16. data/lib/active_support/cache/strategy/local_cache.rb +172 -0
  17. data/lib/active_support/cache/strategy/local_cache_middleware.rb +44 -0
  18. data/lib/active_support/callbacks.rb +791 -0
  19. data/lib/active_support/concern.rb +142 -0
  20. data/lib/active_support/concurrency/latch.rb +26 -0
  21. data/lib/active_support/concurrency/share_lock.rb +226 -0
  22. data/lib/active_support/configurable.rb +148 -0
  23. data/lib/active_support/core_ext.rb +4 -0
  24. data/lib/active_support/core_ext/array.rb +7 -0
  25. data/lib/active_support/core_ext/array/access.rb +90 -0
  26. data/lib/active_support/core_ext/array/conversions.rb +211 -0
  27. data/lib/active_support/core_ext/array/extract_options.rb +29 -0
  28. data/lib/active_support/core_ext/array/grouping.rb +107 -0
  29. data/lib/active_support/core_ext/array/inquiry.rb +17 -0
  30. data/lib/active_support/core_ext/array/prepend_and_append.rb +7 -0
  31. data/lib/active_support/core_ext/array/wrap.rb +46 -0
  32. data/lib/active_support/core_ext/benchmark.rb +14 -0
  33. data/lib/active_support/core_ext/big_decimal.rb +1 -0
  34. data/lib/active_support/core_ext/big_decimal/conversions.rb +14 -0
  35. data/lib/active_support/core_ext/class.rb +2 -0
  36. data/lib/active_support/core_ext/class/attribute.rb +128 -0
  37. data/lib/active_support/core_ext/class/attribute_accessors.rb +4 -0
  38. data/lib/active_support/core_ext/class/subclasses.rb +41 -0
  39. data/lib/active_support/core_ext/date.rb +5 -0
  40. data/lib/active_support/core_ext/date/acts_like.rb +8 -0
  41. data/lib/active_support/core_ext/date/blank.rb +12 -0
  42. data/lib/active_support/core_ext/date/calculations.rb +143 -0
  43. data/lib/active_support/core_ext/date/conversions.rb +95 -0
  44. data/lib/active_support/core_ext/date/zones.rb +6 -0
  45. data/lib/active_support/core_ext/date_and_time/calculations.rb +335 -0
  46. data/lib/active_support/core_ext/date_and_time/compatibility.rb +14 -0
  47. data/lib/active_support/core_ext/date_and_time/zones.rb +40 -0
  48. data/lib/active_support/core_ext/date_time.rb +5 -0
  49. data/lib/active_support/core_ext/date_time/acts_like.rb +14 -0
  50. data/lib/active_support/core_ext/date_time/blank.rb +12 -0
  51. data/lib/active_support/core_ext/date_time/calculations.rb +199 -0
  52. data/lib/active_support/core_ext/date_time/compatibility.rb +16 -0
  53. data/lib/active_support/core_ext/date_time/conversions.rb +105 -0
  54. data/lib/active_support/core_ext/digest/uuid.rb +51 -0
  55. data/lib/active_support/core_ext/enumerable.rb +146 -0
  56. data/lib/active_support/core_ext/file.rb +1 -0
  57. data/lib/active_support/core_ext/file/atomic.rb +68 -0
  58. data/lib/active_support/core_ext/hash.rb +9 -0
  59. data/lib/active_support/core_ext/hash/compact.rb +24 -0
  60. data/lib/active_support/core_ext/hash/conversions.rb +262 -0
  61. data/lib/active_support/core_ext/hash/deep_merge.rb +38 -0
  62. data/lib/active_support/core_ext/hash/except.rb +22 -0
  63. data/lib/active_support/core_ext/hash/indifferent_access.rb +23 -0
  64. data/lib/active_support/core_ext/hash/keys.rb +170 -0
  65. data/lib/active_support/core_ext/hash/reverse_merge.rb +22 -0
  66. data/lib/active_support/core_ext/hash/slice.rb +48 -0
  67. data/lib/active_support/core_ext/hash/transform_values.rb +29 -0
  68. data/lib/active_support/core_ext/integer.rb +3 -0
  69. data/lib/active_support/core_ext/integer/inflections.rb +29 -0
  70. data/lib/active_support/core_ext/integer/multiple.rb +10 -0
  71. data/lib/active_support/core_ext/integer/time.rb +29 -0
  72. data/lib/active_support/core_ext/kernel.rb +4 -0
  73. data/lib/active_support/core_ext/kernel/agnostics.rb +11 -0
  74. data/lib/active_support/core_ext/kernel/concern.rb +12 -0
  75. data/lib/active_support/core_ext/kernel/debugger.rb +3 -0
  76. data/lib/active_support/core_ext/kernel/reporting.rb +43 -0
  77. data/lib/active_support/core_ext/kernel/singleton_class.rb +6 -0
  78. data/lib/active_support/core_ext/load_error.rb +31 -0
  79. data/lib/active_support/core_ext/marshal.rb +22 -0
  80. data/lib/active_support/core_ext/module.rb +12 -0
  81. data/lib/active_support/core_ext/module/aliasing.rb +74 -0
  82. data/lib/active_support/core_ext/module/anonymous.rb +28 -0
  83. data/lib/active_support/core_ext/module/attr_internal.rb +36 -0
  84. data/lib/active_support/core_ext/module/attribute_accessors.rb +212 -0
  85. data/lib/active_support/core_ext/module/attribute_accessors_per_thread.rb +141 -0
  86. data/lib/active_support/core_ext/module/concerning.rb +135 -0
  87. data/lib/active_support/core_ext/module/delegation.rb +216 -0
  88. data/lib/active_support/core_ext/module/deprecation.rb +23 -0
  89. data/lib/active_support/core_ext/module/introspection.rb +68 -0
  90. data/lib/active_support/core_ext/module/method_transplanting.rb +3 -0
  91. data/lib/active_support/core_ext/module/qualified_const.rb +70 -0
  92. data/lib/active_support/core_ext/module/reachable.rb +8 -0
  93. data/lib/active_support/core_ext/module/remove_method.rb +35 -0
  94. data/lib/active_support/core_ext/name_error.rb +31 -0
  95. data/lib/active_support/core_ext/numeric.rb +4 -0
  96. data/lib/active_support/core_ext/numeric/bytes.rb +64 -0
  97. data/lib/active_support/core_ext/numeric/conversions.rb +144 -0
  98. data/lib/active_support/core_ext/numeric/inquiry.rb +26 -0
  99. data/lib/active_support/core_ext/numeric/time.rb +74 -0
  100. data/lib/active_support/core_ext/object.rb +14 -0
  101. data/lib/active_support/core_ext/object/acts_like.rb +10 -0
  102. data/lib/active_support/core_ext/object/blank.rb +143 -0
  103. data/lib/active_support/core_ext/object/conversions.rb +4 -0
  104. data/lib/active_support/core_ext/object/deep_dup.rb +53 -0
  105. data/lib/active_support/core_ext/object/duplicable.rb +124 -0
  106. data/lib/active_support/core_ext/object/inclusion.rb +27 -0
  107. data/lib/active_support/core_ext/object/instance_variables.rb +28 -0
  108. data/lib/active_support/core_ext/object/json.rb +205 -0
  109. data/lib/active_support/core_ext/object/to_param.rb +1 -0
  110. data/lib/active_support/core_ext/object/to_query.rb +84 -0
  111. data/lib/active_support/core_ext/object/try.rb +146 -0
  112. data/lib/active_support/core_ext/object/with_options.rb +69 -0
  113. data/lib/active_support/core_ext/range.rb +4 -0
  114. data/lib/active_support/core_ext/range/conversions.rb +31 -0
  115. data/lib/active_support/core_ext/range/each.rb +21 -0
  116. data/lib/active_support/core_ext/range/include_range.rb +23 -0
  117. data/lib/active_support/core_ext/range/overlaps.rb +8 -0
  118. data/lib/active_support/core_ext/regexp.rb +5 -0
  119. data/lib/active_support/core_ext/securerandom.rb +23 -0
  120. data/lib/active_support/core_ext/string.rb +13 -0
  121. data/lib/active_support/core_ext/string/access.rb +104 -0
  122. data/lib/active_support/core_ext/string/behavior.rb +6 -0
  123. data/lib/active_support/core_ext/string/conversions.rb +57 -0
  124. data/lib/active_support/core_ext/string/exclude.rb +11 -0
  125. data/lib/active_support/core_ext/string/filters.rb +102 -0
  126. data/lib/active_support/core_ext/string/indent.rb +43 -0
  127. data/lib/active_support/core_ext/string/inflections.rb +244 -0
  128. data/lib/active_support/core_ext/string/inquiry.rb +13 -0
  129. data/lib/active_support/core_ext/string/multibyte.rb +53 -0
  130. data/lib/active_support/core_ext/string/output_safety.rb +260 -0
  131. data/lib/active_support/core_ext/string/starts_ends_with.rb +4 -0
  132. data/lib/active_support/core_ext/string/strip.rb +23 -0
  133. data/lib/active_support/core_ext/string/zones.rb +14 -0
  134. data/lib/active_support/core_ext/struct.rb +3 -0
  135. data/lib/active_support/core_ext/time.rb +5 -0
  136. data/lib/active_support/core_ext/time/acts_like.rb +8 -0
  137. data/lib/active_support/core_ext/time/calculations.rb +290 -0
  138. data/lib/active_support/core_ext/time/compatibility.rb +14 -0
  139. data/lib/active_support/core_ext/time/conversions.rb +67 -0
  140. data/lib/active_support/core_ext/time/marshal.rb +3 -0
  141. data/lib/active_support/core_ext/time/zones.rb +111 -0
  142. data/lib/active_support/core_ext/uri.rb +24 -0
  143. data/lib/active_support/dependencies.rb +755 -0
  144. data/lib/active_support/dependencies/autoload.rb +77 -0
  145. data/lib/active_support/dependencies/interlock.rb +55 -0
  146. data/lib/active_support/deprecation.rb +43 -0
  147. data/lib/active_support/deprecation/behaviors.rb +90 -0
  148. data/lib/active_support/deprecation/instance_delegator.rb +37 -0
  149. data/lib/active_support/deprecation/method_wrappers.rb +70 -0
  150. data/lib/active_support/deprecation/proxy_wrappers.rb +149 -0
  151. data/lib/active_support/deprecation/reporting.rb +112 -0
  152. data/lib/active_support/descendants_tracker.rb +60 -0
  153. data/lib/active_support/duration.rb +235 -0
  154. data/lib/active_support/duration/iso8601_parser.rb +122 -0
  155. data/lib/active_support/duration/iso8601_serializer.rb +51 -0
  156. data/lib/active_support/evented_file_update_checker.rb +199 -0
  157. data/lib/active_support/execution_wrapper.rb +126 -0
  158. data/lib/active_support/executor.rb +6 -0
  159. data/lib/active_support/file_update_checker.rb +157 -0
  160. data/lib/active_support/gem_version.rb +15 -0
  161. data/lib/active_support/gzip.rb +36 -0
  162. data/lib/active_support/hash_with_indifferent_access.rb +329 -0
  163. data/lib/active_support/i18n.rb +13 -0
  164. data/lib/active_support/i18n_railtie.rb +115 -0
  165. data/lib/active_support/inflections.rb +70 -0
  166. data/lib/active_support/inflector.rb +7 -0
  167. data/lib/active_support/inflector/inflections.rb +242 -0
  168. data/lib/active_support/inflector/methods.rb +390 -0
  169. data/lib/active_support/inflector/transliterate.rb +112 -0
  170. data/lib/active_support/json.rb +2 -0
  171. data/lib/active_support/json/decoding.rb +74 -0
  172. data/lib/active_support/json/encoding.rb +127 -0
  173. data/lib/active_support/key_generator.rb +71 -0
  174. data/lib/active_support/lazy_load_hooks.rb +76 -0
  175. data/lib/active_support/locale/en.yml +135 -0
  176. data/lib/active_support/log_subscriber.rb +109 -0
  177. data/lib/active_support/log_subscriber/test_helper.rb +104 -0
  178. data/lib/active_support/logger.rb +106 -0
  179. data/lib/active_support/logger_silence.rb +28 -0
  180. data/lib/active_support/logger_thread_safe_level.rb +31 -0
  181. data/lib/active_support/message_encryptor.rb +114 -0
  182. data/lib/active_support/message_verifier.rb +134 -0
  183. data/lib/active_support/multibyte.rb +21 -0
  184. data/lib/active_support/multibyte/chars.rb +231 -0
  185. data/lib/active_support/multibyte/unicode.rb +413 -0
  186. data/lib/active_support/notifications.rb +212 -0
  187. data/lib/active_support/notifications/fanout.rb +157 -0
  188. data/lib/active_support/notifications/instrumenter.rb +91 -0
  189. data/lib/active_support/number_helper.rb +368 -0
  190. data/lib/active_support/number_helper/number_converter.rb +182 -0
  191. data/lib/active_support/number_helper/number_to_currency_converter.rb +44 -0
  192. data/lib/active_support/number_helper/number_to_delimited_converter.rb +28 -0
  193. data/lib/active_support/number_helper/number_to_human_converter.rb +68 -0
  194. data/lib/active_support/number_helper/number_to_human_size_converter.rb +62 -0
  195. data/lib/active_support/number_helper/number_to_percentage_converter.rb +12 -0
  196. data/lib/active_support/number_helper/number_to_phone_converter.rb +58 -0
  197. data/lib/active_support/number_helper/number_to_rounded_converter.rb +92 -0
  198. data/lib/active_support/option_merger.rb +25 -0
  199. data/lib/active_support/ordered_hash.rb +48 -0
  200. data/lib/active_support/ordered_options.rb +81 -0
  201. data/lib/active_support/per_thread_registry.rb +58 -0
  202. data/lib/active_support/proxy_object.rb +13 -0
  203. data/lib/active_support/rails.rb +27 -0
  204. data/lib/active_support/railtie.rb +51 -0
  205. data/lib/active_support/reloader.rb +129 -0
  206. data/lib/active_support/rescuable.rb +173 -0
  207. data/lib/active_support/security_utils.rb +27 -0
  208. data/lib/active_support/string_inquirer.rb +26 -0
  209. data/lib/active_support/subscriber.rb +120 -0
  210. data/lib/active_support/tagged_logging.rb +77 -0
  211. data/lib/active_support/test_case.rb +88 -0
  212. data/lib/active_support/testing/assertions.rb +99 -0
  213. data/lib/active_support/testing/autorun.rb +5 -0
  214. data/lib/active_support/testing/constant_lookup.rb +50 -0
  215. data/lib/active_support/testing/declarative.rb +26 -0
  216. data/lib/active_support/testing/deprecation.rb +36 -0
  217. data/lib/active_support/testing/file_fixtures.rb +34 -0
  218. data/lib/active_support/testing/isolation.rb +115 -0
  219. data/lib/active_support/testing/method_call_assertions.rb +41 -0
  220. data/lib/active_support/testing/setup_and_teardown.rb +50 -0
  221. data/lib/active_support/testing/stream.rb +42 -0
  222. data/lib/active_support/testing/tagged_logging.rb +25 -0
  223. data/lib/active_support/testing/time_helpers.rb +136 -0
  224. data/lib/active_support/time.rb +18 -0
  225. data/lib/active_support/time_with_zone.rb +511 -0
  226. data/lib/active_support/values/time_zone.rb +484 -0
  227. data/lib/active_support/values/unicode_tables.dat +0 -0
  228. data/lib/active_support/version.rb +8 -0
  229. data/lib/active_support/xml_mini.rb +209 -0
  230. data/lib/active_support/xml_mini/jdom.rb +181 -0
  231. data/lib/active_support/xml_mini/libxml.rb +77 -0
  232. data/lib/active_support/xml_mini/libxmlsax.rb +82 -0
  233. data/lib/active_support/xml_mini/nokogiri.rb +81 -0
  234. data/lib/active_support/xml_mini/nokogirisax.rb +85 -0
  235. data/lib/active_support/xml_mini/rexml.rb +128 -0
  236. metadata +349 -0
@@ -0,0 +1,43 @@
1
+ class String
2
+ # Same as +indent+, except it indents the receiver in-place.
3
+ #
4
+ # Returns the indented string, or +nil+ if there was nothing to indent.
5
+ def indent!(amount, indent_string=nil, indent_empty_lines=false)
6
+ indent_string = indent_string || self[/^[ \t]/] || ' '
7
+ re = indent_empty_lines ? /^/ : /^(?!$)/
8
+ gsub!(re, indent_string * amount)
9
+ end
10
+
11
+ # Indents the lines in the receiver:
12
+ #
13
+ # <<EOS.indent(2)
14
+ # def some_method
15
+ # some_code
16
+ # end
17
+ # EOS
18
+ # # =>
19
+ # def some_method
20
+ # some_code
21
+ # end
22
+ #
23
+ # The second argument, +indent_string+, specifies which indent string to
24
+ # use. The default is +nil+, which tells the method to make a guess by
25
+ # peeking at the first indented line, and fallback to a space if there is
26
+ # none.
27
+ #
28
+ # " foo".indent(2) # => " foo"
29
+ # "foo\n\t\tbar".indent(2) # => "\t\tfoo\n\t\t\t\tbar"
30
+ # "foo".indent(2, "\t") # => "\t\tfoo"
31
+ #
32
+ # While +indent_string+ is typically one space or tab, it may be any string.
33
+ #
34
+ # The third argument, +indent_empty_lines+, is a flag that says whether
35
+ # empty lines should be indented. Default is false.
36
+ #
37
+ # "foo\n\nbar".indent(2) # => " foo\n\n bar"
38
+ # "foo\n\nbar".indent(2, nil, true) # => " foo\n \n bar"
39
+ #
40
+ def indent(amount, indent_string=nil, indent_empty_lines=false)
41
+ dup.tap {|_| _.indent!(amount, indent_string, indent_empty_lines)}
42
+ end
43
+ end
@@ -0,0 +1,244 @@
1
+ require 'active_support/inflector/methods'
2
+ require 'active_support/inflector/transliterate'
3
+
4
+ # String inflections define new methods on the String class to transform names for different purposes.
5
+ # For instance, you can figure out the name of a table from the name of a class.
6
+ #
7
+ # 'ScaleScore'.tableize # => "scale_scores"
8
+ #
9
+ class String
10
+ # Returns the plural form of the word in the string.
11
+ #
12
+ # If the optional parameter +count+ is specified,
13
+ # the singular form will be returned if <tt>count == 1</tt>.
14
+ # For any other value of +count+ the plural will be returned.
15
+ #
16
+ # If the optional parameter +locale+ is specified,
17
+ # the word will be pluralized as a word of that language.
18
+ # By default, this parameter is set to <tt>:en</tt>.
19
+ # You must define your own inflection rules for languages other than English.
20
+ #
21
+ # 'post'.pluralize # => "posts"
22
+ # 'octopus'.pluralize # => "octopi"
23
+ # 'sheep'.pluralize # => "sheep"
24
+ # 'words'.pluralize # => "words"
25
+ # 'the blue mailman'.pluralize # => "the blue mailmen"
26
+ # 'CamelOctopus'.pluralize # => "CamelOctopi"
27
+ # 'apple'.pluralize(1) # => "apple"
28
+ # 'apple'.pluralize(2) # => "apples"
29
+ # 'ley'.pluralize(:es) # => "leyes"
30
+ # 'ley'.pluralize(1, :es) # => "ley"
31
+ def pluralize(count = nil, locale = :en)
32
+ locale = count if count.is_a?(Symbol)
33
+ if count == 1
34
+ self.dup
35
+ else
36
+ ActiveSupport::Inflector.pluralize(self, locale)
37
+ end
38
+ end
39
+
40
+ # The reverse of +pluralize+, returns the singular form of a word in a string.
41
+ #
42
+ # If the optional parameter +locale+ is specified,
43
+ # the word will be singularized as a word of that language.
44
+ # By default, this parameter is set to <tt>:en</tt>.
45
+ # You must define your own inflection rules for languages other than English.
46
+ #
47
+ # 'posts'.singularize # => "post"
48
+ # 'octopi'.singularize # => "octopus"
49
+ # 'sheep'.singularize # => "sheep"
50
+ # 'word'.singularize # => "word"
51
+ # 'the blue mailmen'.singularize # => "the blue mailman"
52
+ # 'CamelOctopi'.singularize # => "CamelOctopus"
53
+ # 'leyes'.singularize(:es) # => "ley"
54
+ def singularize(locale = :en)
55
+ ActiveSupport::Inflector.singularize(self, locale)
56
+ end
57
+
58
+ # +constantize+ tries to find a declared constant with the name specified
59
+ # in the string. It raises a NameError when the name is not in CamelCase
60
+ # or is not initialized. See ActiveSupport::Inflector.constantize
61
+ #
62
+ # 'Module'.constantize # => Module
63
+ # 'Class'.constantize # => Class
64
+ # 'blargle'.constantize # => NameError: wrong constant name blargle
65
+ def constantize
66
+ ActiveSupport::Inflector.constantize(self)
67
+ end
68
+
69
+ # +safe_constantize+ tries to find a declared constant with the name specified
70
+ # in the string. It returns nil when the name is not in CamelCase
71
+ # or is not initialized. See ActiveSupport::Inflector.safe_constantize
72
+ #
73
+ # 'Module'.safe_constantize # => Module
74
+ # 'Class'.safe_constantize # => Class
75
+ # 'blargle'.safe_constantize # => nil
76
+ def safe_constantize
77
+ ActiveSupport::Inflector.safe_constantize(self)
78
+ end
79
+
80
+ # By default, +camelize+ converts strings to UpperCamelCase. If the argument to camelize
81
+ # is set to <tt>:lower</tt> then camelize produces lowerCamelCase.
82
+ #
83
+ # +camelize+ will also convert '/' to '::' which is useful for converting paths to namespaces.
84
+ #
85
+ # 'active_record'.camelize # => "ActiveRecord"
86
+ # 'active_record'.camelize(:lower) # => "activeRecord"
87
+ # 'active_record/errors'.camelize # => "ActiveRecord::Errors"
88
+ # 'active_record/errors'.camelize(:lower) # => "activeRecord::Errors"
89
+ def camelize(first_letter = :upper)
90
+ case first_letter
91
+ when :upper
92
+ ActiveSupport::Inflector.camelize(self, true)
93
+ when :lower
94
+ ActiveSupport::Inflector.camelize(self, false)
95
+ end
96
+ end
97
+ alias_method :camelcase, :camelize
98
+
99
+ # Capitalizes all the words and replaces some characters in the string to create
100
+ # a nicer looking title. +titleize+ is meant for creating pretty output. It is not
101
+ # used in the Rails internals.
102
+ #
103
+ # +titleize+ is also aliased as +titlecase+.
104
+ #
105
+ # 'man from the boondocks'.titleize # => "Man From The Boondocks"
106
+ # 'x-men: the last stand'.titleize # => "X Men: The Last Stand"
107
+ def titleize
108
+ ActiveSupport::Inflector.titleize(self)
109
+ end
110
+ alias_method :titlecase, :titleize
111
+
112
+ # The reverse of +camelize+. Makes an underscored, lowercase form from the expression in the string.
113
+ #
114
+ # +underscore+ will also change '::' to '/' to convert namespaces to paths.
115
+ #
116
+ # 'ActiveModel'.underscore # => "active_model"
117
+ # 'ActiveModel::Errors'.underscore # => "active_model/errors"
118
+ def underscore
119
+ ActiveSupport::Inflector.underscore(self)
120
+ end
121
+
122
+ # Replaces underscores with dashes in the string.
123
+ #
124
+ # 'puni_puni'.dasherize # => "puni-puni"
125
+ def dasherize
126
+ ActiveSupport::Inflector.dasherize(self)
127
+ end
128
+
129
+ # Removes the module part from the constant expression in the string.
130
+ #
131
+ # 'ActiveRecord::CoreExtensions::String::Inflections'.demodulize # => "Inflections"
132
+ # 'Inflections'.demodulize # => "Inflections"
133
+ # '::Inflections'.demodulize # => "Inflections"
134
+ # ''.demodulize # => ''
135
+ #
136
+ # See also +deconstantize+.
137
+ def demodulize
138
+ ActiveSupport::Inflector.demodulize(self)
139
+ end
140
+
141
+ # Removes the rightmost segment from the constant expression in the string.
142
+ #
143
+ # 'Net::HTTP'.deconstantize # => "Net"
144
+ # '::Net::HTTP'.deconstantize # => "::Net"
145
+ # 'String'.deconstantize # => ""
146
+ # '::String'.deconstantize # => ""
147
+ # ''.deconstantize # => ""
148
+ #
149
+ # See also +demodulize+.
150
+ def deconstantize
151
+ ActiveSupport::Inflector.deconstantize(self)
152
+ end
153
+
154
+ # Replaces special characters in a string so that it may be used as part of a 'pretty' URL.
155
+ #
156
+ # class Person
157
+ # def to_param
158
+ # "#{id}-#{name.parameterize}"
159
+ # end
160
+ # end
161
+ #
162
+ # @person = Person.find(1)
163
+ # # => #<Person id: 1, name: "Donald E. Knuth">
164
+ #
165
+ # <%= link_to(@person.name, person_path) %>
166
+ # # => <a href="/person/1-donald-e-knuth">Donald E. Knuth</a>
167
+ #
168
+ # To preserve the case of the characters in a string, use the `preserve_case` argument.
169
+ #
170
+ # class Person
171
+ # def to_param
172
+ # "#{id}-#{name.parameterize(preserve_case: true)}"
173
+ # end
174
+ # end
175
+ #
176
+ # @person = Person.find(1)
177
+ # # => #<Person id: 1, name: "Donald E. Knuth">
178
+ #
179
+ # <%= link_to(@person.name, person_path) %>
180
+ # # => <a href="/person/1-Donald-E-Knuth">Donald E. Knuth</a>
181
+ def parameterize(sep = :unused, separator: '-', preserve_case: false)
182
+ unless sep == :unused
183
+ ActiveSupport::Deprecation.warn("Passing the separator argument as a positional parameter is deprecated and will soon be removed. Use `separator: '#{sep}'` instead.")
184
+ separator = sep
185
+ end
186
+ ActiveSupport::Inflector.parameterize(self, separator: separator, preserve_case: preserve_case)
187
+ end
188
+
189
+ # Creates the name of a table like Rails does for models to table names. This method
190
+ # uses the +pluralize+ method on the last word in the string.
191
+ #
192
+ # 'RawScaledScorer'.tableize # => "raw_scaled_scorers"
193
+ # 'ham_and_egg'.tableize # => "ham_and_eggs"
194
+ # 'fancyCategory'.tableize # => "fancy_categories"
195
+ def tableize
196
+ ActiveSupport::Inflector.tableize(self)
197
+ end
198
+
199
+ # Creates a class name from a plural table name like Rails does for table names to models.
200
+ # Note that this returns a string and not a class. (To convert to an actual class
201
+ # follow +classify+ with +constantize+.)
202
+ #
203
+ # 'ham_and_eggs'.classify # => "HamAndEgg"
204
+ # 'posts'.classify # => "Post"
205
+ def classify
206
+ ActiveSupport::Inflector.classify(self)
207
+ end
208
+
209
+ # Capitalizes the first word, turns underscores into spaces, and strips a
210
+ # trailing '_id' if present.
211
+ # Like +titleize+, this is meant for creating pretty output.
212
+ #
213
+ # The capitalization of the first word can be turned off by setting the
214
+ # optional parameter +capitalize+ to false.
215
+ # By default, this parameter is true.
216
+ #
217
+ # 'employee_salary'.humanize # => "Employee salary"
218
+ # 'author_id'.humanize # => "Author"
219
+ # 'author_id'.humanize(capitalize: false) # => "author"
220
+ # '_id'.humanize # => "Id"
221
+ def humanize(options = {})
222
+ ActiveSupport::Inflector.humanize(self, options)
223
+ end
224
+
225
+ # Converts just the first character to uppercase.
226
+ #
227
+ # 'what a Lovely Day'.upcase_first # => "What a Lovely Day"
228
+ # 'w'.upcase_first # => "W"
229
+ # ''.upcase_first # => ""
230
+ def upcase_first
231
+ ActiveSupport::Inflector.upcase_first(self)
232
+ end
233
+
234
+ # Creates a foreign key name from a class name.
235
+ # +separate_class_name_and_id_with_underscore+ sets whether
236
+ # the method should put '_' between the name and 'id'.
237
+ #
238
+ # 'Message'.foreign_key # => "message_id"
239
+ # 'Message'.foreign_key(false) # => "messageid"
240
+ # 'Admin::Post'.foreign_key # => "post_id"
241
+ def foreign_key(separate_class_name_and_id_with_underscore = true)
242
+ ActiveSupport::Inflector.foreign_key(self, separate_class_name_and_id_with_underscore)
243
+ end
244
+ end
@@ -0,0 +1,13 @@
1
+ require 'active_support/string_inquirer'
2
+
3
+ class String
4
+ # Wraps the current string in the <tt>ActiveSupport::StringInquirer</tt> class,
5
+ # which gives you a prettier way to test for equality.
6
+ #
7
+ # env = 'production'.inquiry
8
+ # env.production? # => true
9
+ # env.development? # => false
10
+ def inquiry
11
+ ActiveSupport::StringInquirer.new(self)
12
+ end
13
+ end
@@ -0,0 +1,53 @@
1
+ require 'active_support/multibyte'
2
+
3
+ class String
4
+ # == Multibyte proxy
5
+ #
6
+ # +mb_chars+ is a multibyte safe proxy for string methods.
7
+ #
8
+ # It creates and returns an instance of the ActiveSupport::Multibyte::Chars class which
9
+ # encapsulates the original string. A Unicode safe version of all the String methods are defined on this proxy
10
+ # class. If the proxy class doesn't respond to a certain method, it's forwarded to the encapsulated string.
11
+ #
12
+ # >> "lj".upcase
13
+ # => "lj"
14
+ # >> "lj".mb_chars.upcase.to_s
15
+ # => "LJ"
16
+ #
17
+ # == Method chaining
18
+ #
19
+ # All the methods on the Chars proxy which normally return a string will return a Chars object. This allows
20
+ # method chaining on the result of any of these methods.
21
+ #
22
+ # name.mb_chars.reverse.length # => 12
23
+ #
24
+ # == Interoperability and configuration
25
+ #
26
+ # The Chars object tries to be as interchangeable with String objects as possible: sorting and comparing between
27
+ # String and Char work like expected. The bang! methods change the internal string representation in the Chars
28
+ # object. Interoperability problems can be resolved easily with a +to_s+ call.
29
+ #
30
+ # For more information about the methods defined on the Chars proxy see ActiveSupport::Multibyte::Chars. For
31
+ # information about how to change the default Multibyte behavior see ActiveSupport::Multibyte.
32
+ def mb_chars
33
+ ActiveSupport::Multibyte.proxy_class.new(self)
34
+ end
35
+
36
+ # Returns +true+ if string has utf_8 encoding.
37
+ #
38
+ # utf_8_str = "some string".encode "UTF-8"
39
+ # iso_str = "some string".encode "ISO-8859-1"
40
+ #
41
+ # utf_8_str.is_utf8? # => true
42
+ # iso_str.is_utf8? # => false
43
+ def is_utf8?
44
+ case encoding
45
+ when Encoding::UTF_8
46
+ valid_encoding?
47
+ when Encoding::ASCII_8BIT, Encoding::US_ASCII
48
+ dup.force_encoding(Encoding::UTF_8).valid_encoding?
49
+ else
50
+ false
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,260 @@
1
+ require 'erb'
2
+ require 'active_support/core_ext/kernel/singleton_class'
3
+
4
+ class ERB
5
+ module Util
6
+ HTML_ESCAPE = { '&' => '&amp;', '>' => '&gt;', '<' => '&lt;', '"' => '&quot;', "'" => '&#39;' }
7
+ JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003e', '<' => '\u003c', "\u2028" => '\u2028', "\u2029" => '\u2029' }
8
+ HTML_ESCAPE_ONCE_REGEXP = /["><']|&(?!([a-zA-Z]+|(#\d+)|(#[xX][\dA-Fa-f]+));)/
9
+ JSON_ESCAPE_REGEXP = /[\u2028\u2029&><]/u
10
+
11
+ # A utility method for escaping HTML tag characters.
12
+ # This method is also aliased as <tt>h</tt>.
13
+ #
14
+ # In your ERB templates, use this method to escape any unsafe content. For example:
15
+ # <%= h @person.name %>
16
+ #
17
+ # puts html_escape('is a > 0 & a < 10?')
18
+ # # => is a &gt; 0 &amp; a &lt; 10?
19
+ def html_escape(s)
20
+ unwrapped_html_escape(s).html_safe
21
+ end
22
+
23
+ # Aliasing twice issues a warning "discarding old...". Remove first to avoid it.
24
+ remove_method(:h)
25
+ alias h html_escape
26
+
27
+ module_function :h
28
+
29
+ singleton_class.send(:remove_method, :html_escape)
30
+ module_function :html_escape
31
+
32
+ # HTML escapes strings but doesn't wrap them with an ActiveSupport::SafeBuffer.
33
+ # This method is not for public consumption! Seriously!
34
+ def unwrapped_html_escape(s) # :nodoc:
35
+ s = s.to_s
36
+ if s.html_safe?
37
+ s
38
+ else
39
+ CGI.escapeHTML(ActiveSupport::Multibyte::Unicode.tidy_bytes(s))
40
+ end
41
+ end
42
+ module_function :unwrapped_html_escape
43
+
44
+ # A utility method for escaping HTML without affecting existing escaped entities.
45
+ #
46
+ # html_escape_once('1 < 2 &amp; 3')
47
+ # # => "1 &lt; 2 &amp; 3"
48
+ #
49
+ # html_escape_once('&lt;&lt; Accept & Checkout')
50
+ # # => "&lt;&lt; Accept &amp; Checkout"
51
+ def html_escape_once(s)
52
+ result = ActiveSupport::Multibyte::Unicode.tidy_bytes(s.to_s).gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE)
53
+ s.html_safe? ? result.html_safe : result
54
+ end
55
+
56
+ module_function :html_escape_once
57
+
58
+ # A utility method for escaping HTML entities in JSON strings. Specifically, the
59
+ # &, > and < characters are replaced with their equivalent unicode escaped form -
60
+ # \u0026, \u003e, and \u003c. The Unicode sequences \u2028 and \u2029 are also
61
+ # escaped as they are treated as newline characters in some JavaScript engines.
62
+ # These sequences have identical meaning as the original characters inside the
63
+ # context of a JSON string, so assuming the input is a valid and well-formed
64
+ # JSON value, the output will have equivalent meaning when parsed:
65
+ #
66
+ # json = JSON.generate({ name: "</script><script>alert('PWNED!!!')</script>"})
67
+ # # => "{\"name\":\"</script><script>alert('PWNED!!!')</script>\"}"
68
+ #
69
+ # json_escape(json)
70
+ # # => "{\"name\":\"\\u003C/script\\u003E\\u003Cscript\\u003Ealert('PWNED!!!')\\u003C/script\\u003E\"}"
71
+ #
72
+ # JSON.parse(json) == JSON.parse(json_escape(json))
73
+ # # => true
74
+ #
75
+ # The intended use case for this method is to escape JSON strings before including
76
+ # them inside a script tag to avoid XSS vulnerability:
77
+ #
78
+ # <script>
79
+ # var currentUser = <%= raw json_escape(current_user.to_json) %>;
80
+ # </script>
81
+ #
82
+ # It is necessary to +raw+ the result of +json_escape+, so that quotation marks
83
+ # don't get converted to <tt>&quot;</tt> entities. +json_escape+ doesn't
84
+ # automatically flag the result as HTML safe, since the raw value is unsafe to
85
+ # use inside HTML attributes.
86
+ #
87
+ # If your JSON is being used downstream for insertion into the DOM, be aware of
88
+ # whether or not it is being inserted via +html()+. Most jQuery plugins do this.
89
+ # If that is the case, be sure to +html_escape+ or +sanitize+ any user-generated
90
+ # content returned by your JSON.
91
+ #
92
+ # If you need to output JSON elsewhere in your HTML, you can just do something
93
+ # like this, as any unsafe characters (including quotation marks) will be
94
+ # automatically escaped for you:
95
+ #
96
+ # <div data-user-info="<%= current_user.to_json %>">...</div>
97
+ #
98
+ # WARNING: this helper only works with valid JSON. Using this on non-JSON values
99
+ # will open up serious XSS vulnerabilities. For example, if you replace the
100
+ # +current_user.to_json+ in the example above with user input instead, the browser
101
+ # will happily eval() that string as JavaScript.
102
+ #
103
+ # The escaping performed in this method is identical to those performed in the
104
+ # Active Support JSON encoder when +ActiveSupport.escape_html_entities_in_json+ is
105
+ # set to true. Because this transformation is idempotent, this helper can be
106
+ # applied even if +ActiveSupport.escape_html_entities_in_json+ is already true.
107
+ #
108
+ # Therefore, when you are unsure if +ActiveSupport.escape_html_entities_in_json+
109
+ # is enabled, or if you are unsure where your JSON string originated from, it
110
+ # is recommended that you always apply this helper (other libraries, such as the
111
+ # JSON gem, do not provide this kind of protection by default; also some gems
112
+ # might override +to_json+ to bypass Active Support's encoder).
113
+ def json_escape(s)
114
+ result = s.to_s.gsub(JSON_ESCAPE_REGEXP, JSON_ESCAPE)
115
+ s.html_safe? ? result.html_safe : result
116
+ end
117
+
118
+ module_function :json_escape
119
+ end
120
+ end
121
+
122
+ class Object
123
+ def html_safe?
124
+ false
125
+ end
126
+ end
127
+
128
+ class Numeric
129
+ def html_safe?
130
+ true
131
+ end
132
+ end
133
+
134
+ module ActiveSupport #:nodoc:
135
+ class SafeBuffer < String
136
+ UNSAFE_STRING_METHODS = %w(
137
+ capitalize chomp chop delete downcase gsub lstrip next reverse rstrip
138
+ slice squeeze strip sub succ swapcase tr tr_s upcase
139
+ )
140
+
141
+ alias_method :original_concat, :concat
142
+ private :original_concat
143
+
144
+ # Raised when <tt>ActiveSupport::SafeBuffer#safe_concat</tt> is called on unsafe buffers.
145
+ class SafeConcatError < StandardError
146
+ def initialize
147
+ super 'Could not concatenate to the buffer because it is not html safe.'
148
+ end
149
+ end
150
+
151
+ def [](*args)
152
+ if args.size < 2
153
+ super
154
+ else
155
+ if html_safe?
156
+ new_safe_buffer = super
157
+
158
+ if new_safe_buffer
159
+ new_safe_buffer.instance_variable_set :@html_safe, true
160
+ end
161
+
162
+ new_safe_buffer
163
+ else
164
+ to_str[*args]
165
+ end
166
+ end
167
+ end
168
+
169
+ def safe_concat(value)
170
+ raise SafeConcatError unless html_safe?
171
+ original_concat(value)
172
+ end
173
+
174
+ def initialize(str = '')
175
+ @html_safe = true
176
+ super
177
+ end
178
+
179
+ def initialize_copy(other)
180
+ super
181
+ @html_safe = other.html_safe?
182
+ end
183
+
184
+ def clone_empty
185
+ self[0, 0]
186
+ end
187
+
188
+ def concat(value)
189
+ super(html_escape_interpolated_argument(value))
190
+ end
191
+ alias << concat
192
+
193
+ def prepend(value)
194
+ super(html_escape_interpolated_argument(value))
195
+ end
196
+
197
+ def +(other)
198
+ dup.concat(other)
199
+ end
200
+
201
+ def %(args)
202
+ case args
203
+ when Hash
204
+ escaped_args = Hash[args.map { |k,arg| [k, html_escape_interpolated_argument(arg)] }]
205
+ else
206
+ escaped_args = Array(args).map { |arg| html_escape_interpolated_argument(arg) }
207
+ end
208
+
209
+ self.class.new(super(escaped_args))
210
+ end
211
+
212
+ def html_safe?
213
+ defined?(@html_safe) && @html_safe
214
+ end
215
+
216
+ def to_s
217
+ self
218
+ end
219
+
220
+ def to_param
221
+ to_str
222
+ end
223
+
224
+ def encode_with(coder)
225
+ coder.represent_object nil, to_str
226
+ end
227
+
228
+ UNSAFE_STRING_METHODS.each do |unsafe_method|
229
+ if unsafe_method.respond_to?(unsafe_method)
230
+ class_eval <<-EOT, __FILE__, __LINE__ + 1
231
+ def #{unsafe_method}(*args, &block) # def capitalize(*args, &block)
232
+ to_str.#{unsafe_method}(*args, &block) # to_str.capitalize(*args, &block)
233
+ end # end
234
+
235
+ def #{unsafe_method}!(*args) # def capitalize!(*args)
236
+ @html_safe = false # @html_safe = false
237
+ super # super
238
+ end # end
239
+ EOT
240
+ end
241
+ end
242
+
243
+ private
244
+
245
+ def html_escape_interpolated_argument(arg)
246
+ (!html_safe? || arg.html_safe?) ? arg : CGI.escapeHTML(arg.to_s)
247
+ end
248
+ end
249
+ end
250
+
251
+ class String
252
+ # Marks a string as trusted safe. It will be inserted into HTML with no
253
+ # additional escaping performed. It is your responsibility to ensure that the
254
+ # string contains no malicious content. This method is equivalent to the
255
+ # `raw` helper in views. It is recommended that you use `sanitize` instead of
256
+ # this method. It should never be called on user input.
257
+ def html_safe
258
+ ActiveSupport::SafeBuffer.new(self)
259
+ end
260
+ end