actionpack 3.2.19 → 4.2.11.3

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

Potentially problematic release.


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

Files changed (244) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +412 -503
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +11 -294
  5. data/lib/abstract_controller/asset_paths.rb +2 -2
  6. data/lib/abstract_controller/base.rb +52 -18
  7. data/lib/abstract_controller/callbacks.rb +87 -89
  8. data/lib/abstract_controller/collector.rb +17 -3
  9. data/lib/abstract_controller/helpers.rb +41 -14
  10. data/lib/abstract_controller/logger.rb +1 -2
  11. data/lib/abstract_controller/railties/routes_helpers.rb +3 -3
  12. data/lib/abstract_controller/rendering.rb +65 -118
  13. data/lib/abstract_controller/translation.rb +16 -1
  14. data/lib/abstract_controller/url_for.rb +7 -7
  15. data/lib/abstract_controller.rb +2 -10
  16. data/lib/action_controller/base.rb +61 -28
  17. data/lib/action_controller/caching/fragments.rb +30 -54
  18. data/lib/action_controller/caching.rb +38 -35
  19. data/lib/action_controller/log_subscriber.rb +35 -18
  20. data/lib/action_controller/metal/conditional_get.rb +103 -34
  21. data/lib/action_controller/metal/data_streaming.rb +20 -26
  22. data/lib/action_controller/metal/etag_with_template_digest.rb +50 -0
  23. data/lib/action_controller/metal/exceptions.rb +19 -6
  24. data/lib/action_controller/metal/flash.rb +41 -9
  25. data/lib/action_controller/metal/force_ssl.rb +70 -12
  26. data/lib/action_controller/metal/head.rb +30 -7
  27. data/lib/action_controller/metal/helpers.rb +11 -11
  28. data/lib/action_controller/metal/hide_actions.rb +0 -1
  29. data/lib/action_controller/metal/http_authentication.rb +140 -94
  30. data/lib/action_controller/metal/implicit_render.rb +1 -1
  31. data/lib/action_controller/metal/instrumentation.rb +11 -7
  32. data/lib/action_controller/metal/live.rb +328 -0
  33. data/lib/action_controller/metal/mime_responds.rb +161 -152
  34. data/lib/action_controller/metal/params_wrapper.rb +126 -81
  35. data/lib/action_controller/metal/rack_delegation.rb +10 -4
  36. data/lib/action_controller/metal/redirecting.rb +44 -41
  37. data/lib/action_controller/metal/renderers.rb +48 -19
  38. data/lib/action_controller/metal/rendering.rb +46 -11
  39. data/lib/action_controller/metal/request_forgery_protection.rb +250 -29
  40. data/lib/action_controller/metal/streaming.rb +30 -38
  41. data/lib/action_controller/metal/strong_parameters.rb +669 -0
  42. data/lib/action_controller/metal/testing.rb +12 -18
  43. data/lib/action_controller/metal/url_for.rb +31 -29
  44. data/lib/action_controller/metal.rb +31 -40
  45. data/lib/action_controller/model_naming.rb +12 -0
  46. data/lib/action_controller/railtie.rb +38 -18
  47. data/lib/action_controller/railties/helpers.rb +22 -0
  48. data/lib/action_controller/test_case.rb +359 -173
  49. data/lib/action_controller.rb +9 -16
  50. data/lib/action_dispatch/http/cache.rb +64 -11
  51. data/lib/action_dispatch/http/filter_parameters.rb +20 -10
  52. data/lib/action_dispatch/http/filter_redirect.rb +38 -0
  53. data/lib/action_dispatch/http/headers.rb +85 -17
  54. data/lib/action_dispatch/http/mime_negotiation.rb +55 -5
  55. data/lib/action_dispatch/http/mime_type.rb +167 -114
  56. data/lib/action_dispatch/http/mime_types.rb +2 -1
  57. data/lib/action_dispatch/http/parameter_filter.rb +44 -46
  58. data/lib/action_dispatch/http/parameters.rb +30 -46
  59. data/lib/action_dispatch/http/rack_cache.rb +2 -3
  60. data/lib/action_dispatch/http/request.rb +108 -45
  61. data/lib/action_dispatch/http/response.rb +247 -48
  62. data/lib/action_dispatch/http/upload.rb +60 -29
  63. data/lib/action_dispatch/http/url.rb +135 -45
  64. data/lib/action_dispatch/journey/backwards.rb +5 -0
  65. data/lib/action_dispatch/journey/formatter.rb +166 -0
  66. data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
  67. data/lib/action_dispatch/journey/gtg/simulator.rb +47 -0
  68. data/lib/action_dispatch/journey/gtg/transition_table.rb +157 -0
  69. data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
  70. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  71. data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
  72. data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
  73. data/lib/action_dispatch/journey/nodes/node.rb +128 -0
  74. data/lib/action_dispatch/journey/parser.rb +198 -0
  75. data/lib/action_dispatch/journey/parser.y +49 -0
  76. data/lib/action_dispatch/journey/parser_extras.rb +23 -0
  77. data/lib/action_dispatch/journey/path/pattern.rb +193 -0
  78. data/lib/action_dispatch/journey/route.rb +125 -0
  79. data/lib/action_dispatch/journey/router/strexp.rb +27 -0
  80. data/lib/action_dispatch/journey/router/utils.rb +93 -0
  81. data/lib/action_dispatch/journey/router.rb +144 -0
  82. data/lib/action_dispatch/journey/routes.rb +80 -0
  83. data/lib/action_dispatch/journey/scanner.rb +61 -0
  84. data/lib/action_dispatch/journey/visitors.rb +221 -0
  85. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  86. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  87. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  88. data/lib/action_dispatch/journey.rb +5 -0
  89. data/lib/action_dispatch/middleware/callbacks.rb +16 -11
  90. data/lib/action_dispatch/middleware/cookies.rb +346 -125
  91. data/lib/action_dispatch/middleware/debug_exceptions.rb +52 -24
  92. data/lib/action_dispatch/middleware/exception_wrapper.rb +75 -9
  93. data/lib/action_dispatch/middleware/flash.rb +85 -72
  94. data/lib/action_dispatch/middleware/params_parser.rb +16 -31
  95. data/lib/action_dispatch/middleware/public_exceptions.rb +39 -14
  96. data/lib/action_dispatch/middleware/reloader.rb +16 -7
  97. data/lib/action_dispatch/middleware/remote_ip.rb +132 -40
  98. data/lib/action_dispatch/middleware/request_id.rb +3 -7
  99. data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
  100. data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
  101. data/lib/action_dispatch/middleware/session/cookie_store.rb +84 -29
  102. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
  103. data/lib/action_dispatch/middleware/show_exceptions.rb +15 -44
  104. data/lib/action_dispatch/middleware/ssl.rb +72 -0
  105. data/lib/action_dispatch/middleware/stack.rb +6 -1
  106. data/lib/action_dispatch/middleware/static.rb +80 -23
  107. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +34 -0
  108. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  109. data/lib/action_dispatch/middleware/templates/rescues/_source.erb +27 -0
  110. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +52 -0
  111. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  112. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +16 -0
  113. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  114. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +133 -5
  115. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  116. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  117. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  118. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  119. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  121. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  122. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  123. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  124. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +200 -0
  125. data/lib/action_dispatch/railtie.rb +19 -6
  126. data/lib/action_dispatch/request/session.rb +193 -0
  127. data/lib/action_dispatch/request/utils.rb +35 -0
  128. data/lib/action_dispatch/routing/endpoint.rb +10 -0
  129. data/lib/action_dispatch/routing/inspector.rb +234 -0
  130. data/lib/action_dispatch/routing/mapper.rb +897 -436
  131. data/lib/action_dispatch/routing/polymorphic_routes.rb +213 -92
  132. data/lib/action_dispatch/routing/redirection.rb +97 -37
  133. data/lib/action_dispatch/routing/route_set.rb +432 -239
  134. data/lib/action_dispatch/routing/routes_proxy.rb +7 -4
  135. data/lib/action_dispatch/routing/url_for.rb +63 -34
  136. data/lib/action_dispatch/routing.rb +57 -89
  137. data/lib/action_dispatch/testing/assertions/dom.rb +2 -36
  138. data/lib/action_dispatch/testing/assertions/response.rb +24 -38
  139. data/lib/action_dispatch/testing/assertions/routing.rb +55 -54
  140. data/lib/action_dispatch/testing/assertions/selector.rb +2 -434
  141. data/lib/action_dispatch/testing/assertions/tag.rb +2 -137
  142. data/lib/action_dispatch/testing/assertions.rb +11 -7
  143. data/lib/action_dispatch/testing/integration.rb +88 -72
  144. data/lib/action_dispatch/testing/test_process.rb +9 -6
  145. data/lib/action_dispatch/testing/test_request.rb +13 -9
  146. data/lib/action_dispatch/testing/test_response.rb +1 -5
  147. data/lib/action_dispatch.rb +24 -21
  148. data/lib/action_pack/gem_version.rb +15 -0
  149. data/lib/action_pack/version.rb +5 -7
  150. data/lib/action_pack.rb +1 -1
  151. metadata +181 -292
  152. data/lib/abstract_controller/layouts.rb +0 -423
  153. data/lib/abstract_controller/view_paths.rb +0 -96
  154. data/lib/action_controller/caching/actions.rb +0 -185
  155. data/lib/action_controller/caching/pages.rb +0 -187
  156. data/lib/action_controller/caching/sweeping.rb +0 -97
  157. data/lib/action_controller/deprecated/integration_test.rb +0 -2
  158. data/lib/action_controller/deprecated/performance_test.rb +0 -1
  159. data/lib/action_controller/deprecated.rb +0 -3
  160. data/lib/action_controller/metal/compatibility.rb +0 -65
  161. data/lib/action_controller/metal/responder.rb +0 -286
  162. data/lib/action_controller/metal/session_management.rb +0 -14
  163. data/lib/action_controller/railties/paths.rb +0 -25
  164. data/lib/action_controller/record_identifier.rb +0 -85
  165. data/lib/action_controller/vendor/html-scanner/html/document.rb +0 -68
  166. data/lib/action_controller/vendor/html-scanner/html/node.rb +0 -532
  167. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +0 -177
  168. data/lib/action_controller/vendor/html-scanner/html/selector.rb +0 -830
  169. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +0 -107
  170. data/lib/action_controller/vendor/html-scanner/html/version.rb +0 -11
  171. data/lib/action_controller/vendor/html-scanner.rb +0 -20
  172. data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
  173. data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
  174. data/lib/action_dispatch/middleware/head.rb +0 -18
  175. data/lib/action_dispatch/middleware/rescue.rb +0 -26
  176. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +0 -31
  177. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +0 -26
  178. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +0 -10
  179. data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +0 -2
  180. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +0 -15
  181. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +0 -17
  182. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +0 -2
  183. data/lib/action_dispatch/testing/performance_test.rb +0 -10
  184. data/lib/action_view/asset_paths.rb +0 -142
  185. data/lib/action_view/base.rb +0 -220
  186. data/lib/action_view/buffers.rb +0 -43
  187. data/lib/action_view/context.rb +0 -36
  188. data/lib/action_view/flows.rb +0 -79
  189. data/lib/action_view/helpers/active_model_helper.rb +0 -50
  190. data/lib/action_view/helpers/asset_paths.rb +0 -7
  191. data/lib/action_view/helpers/asset_tag_helper.rb +0 -457
  192. data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
  193. data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
  194. data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
  195. data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
  196. data/lib/action_view/helpers/atom_feed_helper.rb +0 -200
  197. data/lib/action_view/helpers/cache_helper.rb +0 -64
  198. data/lib/action_view/helpers/capture_helper.rb +0 -203
  199. data/lib/action_view/helpers/controller_helper.rb +0 -25
  200. data/lib/action_view/helpers/csrf_helper.rb +0 -32
  201. data/lib/action_view/helpers/date_helper.rb +0 -1062
  202. data/lib/action_view/helpers/debug_helper.rb +0 -40
  203. data/lib/action_view/helpers/form_helper.rb +0 -1486
  204. data/lib/action_view/helpers/form_options_helper.rb +0 -658
  205. data/lib/action_view/helpers/form_tag_helper.rb +0 -685
  206. data/lib/action_view/helpers/javascript_helper.rb +0 -110
  207. data/lib/action_view/helpers/number_helper.rb +0 -622
  208. data/lib/action_view/helpers/output_safety_helper.rb +0 -38
  209. data/lib/action_view/helpers/record_tag_helper.rb +0 -111
  210. data/lib/action_view/helpers/rendering_helper.rb +0 -90
  211. data/lib/action_view/helpers/sanitize_helper.rb +0 -259
  212. data/lib/action_view/helpers/tag_helper.rb +0 -160
  213. data/lib/action_view/helpers/text_helper.rb +0 -426
  214. data/lib/action_view/helpers/translation_helper.rb +0 -91
  215. data/lib/action_view/helpers/url_helper.rb +0 -693
  216. data/lib/action_view/helpers.rb +0 -60
  217. data/lib/action_view/locale/en.yml +0 -160
  218. data/lib/action_view/log_subscriber.rb +0 -28
  219. data/lib/action_view/lookup_context.rb +0 -254
  220. data/lib/action_view/path_set.rb +0 -89
  221. data/lib/action_view/railtie.rb +0 -55
  222. data/lib/action_view/renderer/abstract_renderer.rb +0 -41
  223. data/lib/action_view/renderer/partial_renderer.rb +0 -415
  224. data/lib/action_view/renderer/renderer.rb +0 -54
  225. data/lib/action_view/renderer/streaming_template_renderer.rb +0 -106
  226. data/lib/action_view/renderer/template_renderer.rb +0 -94
  227. data/lib/action_view/template/error.rb +0 -128
  228. data/lib/action_view/template/handlers/builder.rb +0 -26
  229. data/lib/action_view/template/handlers/erb.rb +0 -125
  230. data/lib/action_view/template/handlers.rb +0 -50
  231. data/lib/action_view/template/resolver.rb +0 -272
  232. data/lib/action_view/template/text.rb +0 -30
  233. data/lib/action_view/template.rb +0 -337
  234. data/lib/action_view/test_case.rb +0 -245
  235. data/lib/action_view/testing/resolvers.rb +0 -50
  236. data/lib/action_view.rb +0 -84
  237. data/lib/sprockets/assets.rake +0 -99
  238. data/lib/sprockets/bootstrap.rb +0 -37
  239. data/lib/sprockets/compressors.rb +0 -83
  240. data/lib/sprockets/helpers/isolated_helper.rb +0 -13
  241. data/lib/sprockets/helpers/rails_helper.rb +0 -182
  242. data/lib/sprockets/helpers.rb +0 -6
  243. data/lib/sprockets/railtie.rb +0 -62
  244. data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,426 +0,0 @@
1
- require 'active_support/core_ext/object/blank'
2
- require 'active_support/core_ext/string/filters'
3
-
4
- module ActionView
5
- # = Action View Text Helpers
6
- module Helpers #:nodoc:
7
- # The TextHelper module provides a set of methods for filtering, formatting
8
- # and transforming strings, which can reduce the amount of inline Ruby code in
9
- # your views. These helper methods extend Action View making them callable
10
- # within your template files.
11
- #
12
- # ==== Sanitization
13
- #
14
- # Most text helpers by default sanitize the given content, but do not escape it.
15
- # This means HTML tags will appear in the page but all malicious code will be removed.
16
- # Let's look at some examples using the +simple_format+ method:
17
- #
18
- # simple_format('<a href="http://example.com/">Example</a>')
19
- # # => "<p><a href=\"http://example.com/\">Example</a></p>"
20
- #
21
- # simple_format('<a href="javascript:alert(\'no!\')">Example</a>')
22
- # # => "<p><a>Example</a></p>"
23
- #
24
- # If you want to escape all content, you should invoke the +h+ method before
25
- # calling the text helper.
26
- #
27
- # simple_format h('<a href="http://example.com/">Example</a>')
28
- # # => "<p>&lt;a href=\"http://example.com/\"&gt;Example&lt;/a&gt;</p>"
29
- module TextHelper
30
- extend ActiveSupport::Concern
31
-
32
- include SanitizeHelper
33
- include TagHelper
34
- # The preferred method of outputting text in your views is to use the
35
- # <%= "text" %> eRuby syntax. The regular _puts_ and _print_ methods
36
- # do not operate as expected in an eRuby code block. If you absolutely must
37
- # output text within a non-output code block (i.e., <% %>), you can use the concat method.
38
- #
39
- # ==== Examples
40
- # <%
41
- # concat "hello"
42
- # # is the equivalent of <%= "hello" %>
43
- #
44
- # if logged_in
45
- # concat "Logged in!"
46
- # else
47
- # concat link_to('login', :action => login)
48
- # end
49
- # # will either display "Logged in!" or a login link
50
- # %>
51
- def concat(string)
52
- output_buffer << string
53
- end
54
-
55
- def safe_concat(string)
56
- output_buffer.respond_to?(:safe_concat) ? output_buffer.safe_concat(string) : concat(string)
57
- end
58
-
59
- # Truncates a given +text+ after a given <tt>:length</tt> if +text+ is longer than <tt>:length</tt>
60
- # (defaults to 30). The last characters will be replaced with the <tt>:omission</tt> (defaults to "...")
61
- # for a total length not exceeding <tt>:length</tt>.
62
- #
63
- # Pass a <tt>:separator</tt> to truncate +text+ at a natural break.
64
- #
65
- # The result is not marked as HTML-safe, so will be subject to the default escaping when
66
- # used in views, unless wrapped by <tt>raw()</tt>. Care should be taken if +text+ contains HTML tags
67
- # or entities, because truncation may produce invalid HTML (such as unbalanced or incomplete tags).
68
- #
69
- # ==== Examples
70
- #
71
- # truncate("Once upon a time in a world far far away")
72
- # # => "Once upon a time in a world..."
73
- #
74
- # truncate("Once upon a time in a world far far away", :length => 17)
75
- # # => "Once upon a ti..."
76
- #
77
- # truncate("Once upon a time in a world far far away", :length => 17, :separator => ' ')
78
- # # => "Once upon a..."
79
- #
80
- # truncate("And they found that many people were sleeping better.", :length => 25, :omission => '... (continued)')
81
- # # => "And they f... (continued)"
82
- #
83
- # truncate("<p>Once upon a time in a world far far away</p>")
84
- # # => "<p>Once upon a time in a wo..."
85
- def truncate(text, options = {})
86
- options.reverse_merge!(:length => 30)
87
- text.truncate(options.delete(:length), options) if text
88
- end
89
-
90
- # Highlights one or more +phrases+ everywhere in +text+ by inserting it into
91
- # a <tt>:highlighter</tt> string. The highlighter can be specialized by passing <tt>:highlighter</tt>
92
- # as a single-quoted string with \1 where the phrase is to be inserted (defaults to
93
- # '<strong class="highlight">\1</strong>')
94
- #
95
- # ==== Examples
96
- # highlight('You searched for: rails', 'rails')
97
- # # => You searched for: <strong class="highlight">rails</strong>
98
- #
99
- # highlight('You searched for: ruby, rails, dhh', 'actionpack')
100
- # # => You searched for: ruby, rails, dhh
101
- #
102
- # highlight('You searched for: rails', ['for', 'rails'], :highlighter => '<em>\1</em>')
103
- # # => You searched <em>for</em>: <em>rails</em>
104
- #
105
- # highlight('You searched for: rails', 'rails', :highlighter => '<a href="search?q=\1">\1</a>')
106
- # # => You searched for: <a href="search?q=rails">rails</a>
107
- #
108
- # You can still use <tt>highlight</tt> with the old API that accepts the
109
- # +highlighter+ as its optional third parameter:
110
- # highlight('You searched for: rails', 'rails', '<a href="search?q=\1">\1</a>') # => You searched for: <a href="search?q=rails">rails</a>
111
- def highlight(text, phrases, *args)
112
- options = args.extract_options!
113
- unless args.empty?
114
- ActiveSupport::Deprecation.warn "Calling highlight with a highlighter as an argument is deprecated. " \
115
- "Please call with :highlighter => '#{args[0]}' instead.", caller
116
-
117
- options[:highlighter] = args[0] || '<strong class="highlight">\1</strong>'
118
- end
119
- options.reverse_merge!(:highlighter => '<strong class="highlight">\1</strong>')
120
-
121
- text = sanitize(text) unless options[:sanitize] == false
122
- if text.blank? || phrases.blank?
123
- text
124
- else
125
- match = Array(phrases).map { |p| Regexp.escape(p) }.join('|')
126
- text.gsub(/(#{match})(?![^<]*?>)/i, options[:highlighter])
127
- end.html_safe
128
- end
129
-
130
- # Extracts an excerpt from +text+ that matches the first instance of +phrase+.
131
- # The <tt>:radius</tt> option expands the excerpt on each side of the first occurrence of +phrase+ by the number of characters
132
- # defined in <tt>:radius</tt> (which defaults to 100). If the excerpt radius overflows the beginning or end of the +text+,
133
- # then the <tt>:omission</tt> option (which defaults to "...") will be prepended/appended accordingly. The resulting string
134
- # will be stripped in any case. If the +phrase+ isn't found, nil is returned.
135
- #
136
- # ==== Examples
137
- # excerpt('This is an example', 'an', :radius => 5)
138
- # # => ...s is an exam...
139
- #
140
- # excerpt('This is an example', 'is', :radius => 5)
141
- # # => This is a...
142
- #
143
- # excerpt('This is an example', 'is')
144
- # # => This is an example
145
- #
146
- # excerpt('This next thing is an example', 'ex', :radius => 2)
147
- # # => ...next...
148
- #
149
- # excerpt('This is also an example', 'an', :radius => 8, :omission => '<chop> ')
150
- # # => <chop> is also an example
151
- #
152
- # You can still use <tt>excerpt</tt> with the old API that accepts the
153
- # +radius+ as its optional third and the +ellipsis+ as its
154
- # optional forth parameter:
155
- # excerpt('This is an example', 'an', 5) # => ...s is an exam...
156
- # excerpt('This is also an example', 'an', 8, '<chop> ') # => <chop> is also an example
157
- def excerpt(text, phrase, *args)
158
- return unless text && phrase
159
-
160
- options = args.extract_options!
161
- unless args.empty?
162
- ActiveSupport::Deprecation.warn "Calling excerpt with radius and omission as arguments is deprecated. " \
163
- "Please call with :radius => #{args[0]}#{", :omission => '#{args[1]}'" if args[1]} instead.", caller
164
-
165
- options[:radius] = args[0] || 100
166
- options[:omission] = args[1] || "..."
167
- end
168
- options.reverse_merge!(:radius => 100, :omission => "...")
169
-
170
- phrase = Regexp.escape(phrase)
171
- return unless found_pos = text.mb_chars =~ /(#{phrase})/i
172
-
173
- start_pos = [ found_pos - options[:radius], 0 ].max
174
- end_pos = [ [ found_pos + phrase.mb_chars.length + options[:radius] - 1, 0].max, text.mb_chars.length ].min
175
-
176
- prefix = start_pos > 0 ? options[:omission] : ""
177
- postfix = end_pos < text.mb_chars.length - 1 ? options[:omission] : ""
178
-
179
- prefix + text.mb_chars[start_pos..end_pos].strip + postfix
180
- end
181
-
182
- # Attempts to pluralize the +singular+ word unless +count+ is 1. If
183
- # +plural+ is supplied, it will use that when count is > 1, otherwise
184
- # it will use the Inflector to determine the plural form
185
- #
186
- # ==== Examples
187
- # pluralize(1, 'person')
188
- # # => 1 person
189
- #
190
- # pluralize(2, 'person')
191
- # # => 2 people
192
- #
193
- # pluralize(3, 'person', 'users')
194
- # # => 3 users
195
- #
196
- # pluralize(0, 'person')
197
- # # => 0 people
198
- def pluralize(count, singular, plural = nil)
199
- "#{count || 0} " + ((count == 1 || count =~ /^1(\.0+)?$/) ? singular : (plural || singular.pluralize))
200
- end
201
-
202
- # Wraps the +text+ into lines no longer than +line_width+ width. This method
203
- # breaks on the first whitespace character that does not exceed +line_width+
204
- # (which is 80 by default).
205
- #
206
- # ==== Examples
207
- #
208
- # word_wrap('Once upon a time')
209
- # # => Once upon a time
210
- #
211
- # word_wrap('Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding a successor to the throne turned out to be more trouble than anyone could have imagined...')
212
- # # => Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding\n a successor to the throne turned out to be more trouble than anyone could have\n imagined...
213
- #
214
- # word_wrap('Once upon a time', :line_width => 8)
215
- # # => Once upon\na time
216
- #
217
- # word_wrap('Once upon a time', :line_width => 1)
218
- # # => Once\nupon\na\ntime
219
- #
220
- # You can still use <tt>word_wrap</tt> with the old API that accepts the
221
- # +line_width+ as its optional second parameter:
222
- # word_wrap('Once upon a time', 8) # => Once upon\na time
223
- def word_wrap(text, *args)
224
- options = args.extract_options!
225
- unless args.blank?
226
- ActiveSupport::Deprecation.warn "Calling word_wrap with line_width as an argument is deprecated. " \
227
- "Please call with :line_width => #{args[0]} instead.", caller
228
-
229
- options[:line_width] = args[0] || 80
230
- end
231
- options.reverse_merge!(:line_width => 80)
232
-
233
- text.split("\n").collect do |line|
234
- line.length > options[:line_width] ? line.gsub(/(.{1,#{options[:line_width]}})(\s+|$)/, "\\1\n").strip : line
235
- end * "\n"
236
- end
237
-
238
- # Returns +text+ transformed into HTML using simple formatting rules.
239
- # Two or more consecutive newlines(<tt>\n\n</tt>) are considered as a
240
- # paragraph and wrapped in <tt><p></tt> tags. One newline (<tt>\n</tt>) is
241
- # considered as a linebreak and a <tt><br /></tt> tag is appended. This
242
- # method does not remove the newlines from the +text+.
243
- #
244
- # You can pass any HTML attributes into <tt>html_options</tt>. These
245
- # will be added to all created paragraphs.
246
- #
247
- # ==== Options
248
- # * <tt>:sanitize</tt> - If +false+, does not sanitize +text+.
249
- #
250
- # ==== Examples
251
- # my_text = "Here is some basic text...\n...with a line break."
252
- #
253
- # simple_format(my_text)
254
- # # => "<p>Here is some basic text...\n<br />...with a line break.</p>"
255
- #
256
- # more_text = "We want to put a paragraph...\n\n...right there."
257
- #
258
- # simple_format(more_text)
259
- # # => "<p>We want to put a paragraph...</p>\n\n<p>...right there.</p>"
260
- #
261
- # simple_format("Look ma! A class!", :class => 'description')
262
- # # => "<p class='description'>Look ma! A class!</p>"
263
- #
264
- # simple_format("<span>I'm allowed!</span> It's true.", {}, :sanitize => false)
265
- # # => "<p><span>I'm allowed!</span> It's true.</p>"
266
- def simple_format(text, html_options={}, options={})
267
- text = '' if text.nil?
268
- text = text.dup
269
- start_tag = tag('p', html_options, true)
270
- text = sanitize(text) unless options[:sanitize] == false
271
- text = text.to_str
272
- text.gsub!(/\r\n?/, "\n") # \r\n and \r -> \n
273
- text.gsub!(/\n\n+/, "</p>\n\n#{start_tag}") # 2+ newline -> paragraph
274
- text.gsub!(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br
275
- text.insert 0, start_tag
276
- text.html_safe.safe_concat("</p>")
277
- end
278
-
279
- # Creates a Cycle object whose _to_s_ method cycles through elements of an
280
- # array every time it is called. This can be used for example, to alternate
281
- # classes for table rows. You can use named cycles to allow nesting in loops.
282
- # Passing a Hash as the last parameter with a <tt>:name</tt> key will create a
283
- # named cycle. The default name for a cycle without a +:name+ key is
284
- # <tt>"default"</tt>. You can manually reset a cycle by calling reset_cycle
285
- # and passing the name of the cycle. The current cycle string can be obtained
286
- # anytime using the current_cycle method.
287
- #
288
- # ==== Examples
289
- # # Alternate CSS classes for even and odd numbers...
290
- # @items = [1,2,3,4]
291
- # <table>
292
- # <% @items.each do |item| %>
293
- # <tr class="<%= cycle("odd", "even") -%>">
294
- # <td>item</td>
295
- # </tr>
296
- # <% end %>
297
- # </table>
298
- #
299
- #
300
- # # Cycle CSS classes for rows, and text colors for values within each row
301
- # @items = x = [{:first => 'Robert', :middle => 'Daniel', :last => 'James'},
302
- # {:first => 'Emily', :middle => 'Shannon', :maiden => 'Pike', :last => 'Hicks'},
303
- # {:first => 'June', :middle => 'Dae', :last => 'Jones'}]
304
- # <% @items.each do |item| %>
305
- # <tr class="<%= cycle("odd", "even", :name => "row_class") -%>">
306
- # <td>
307
- # <% item.values.each do |value| %>
308
- # <%# Create a named cycle "colors" %>
309
- # <span style="color:<%= cycle("red", "green", "blue", :name => "colors") -%>">
310
- # <%= value %>
311
- # </span>
312
- # <% end %>
313
- # <% reset_cycle("colors") %>
314
- # </td>
315
- # </tr>
316
- # <% end %>
317
- def cycle(first_value, *values)
318
- if (values.last.instance_of? Hash)
319
- params = values.pop
320
- name = params[:name]
321
- else
322
- name = "default"
323
- end
324
- values.unshift(first_value)
325
-
326
- cycle = get_cycle(name)
327
- unless cycle && cycle.values == values
328
- cycle = set_cycle(name, Cycle.new(*values))
329
- end
330
- cycle.to_s
331
- end
332
-
333
- # Returns the current cycle string after a cycle has been started. Useful
334
- # for complex table highlighting or any other design need which requires
335
- # the current cycle string in more than one place.
336
- #
337
- # ==== Example
338
- # # Alternate background colors
339
- # @items = [1,2,3,4]
340
- # <% @items.each do |item| %>
341
- # <div style="background-color:<%= cycle("red","white","blue") %>">
342
- # <span style="background-color:<%= current_cycle %>"><%= item %></span>
343
- # </div>
344
- # <% end %>
345
- def current_cycle(name = "default")
346
- cycle = get_cycle(name)
347
- cycle.current_value if cycle
348
- end
349
-
350
- # Resets a cycle so that it starts from the first element the next time
351
- # it is called. Pass in +name+ to reset a named cycle.
352
- #
353
- # ==== Example
354
- # # Alternate CSS classes for even and odd numbers...
355
- # @items = [[1,2,3,4], [5,6,3], [3,4,5,6,7,4]]
356
- # <table>
357
- # <% @items.each do |item| %>
358
- # <tr class="<%= cycle("even", "odd") -%>">
359
- # <% item.each do |value| %>
360
- # <span style="color:<%= cycle("#333", "#666", "#999", :name => "colors") -%>">
361
- # <%= value %>
362
- # </span>
363
- # <% end %>
364
- #
365
- # <% reset_cycle("colors") %>
366
- # </tr>
367
- # <% end %>
368
- # </table>
369
- def reset_cycle(name = "default")
370
- cycle = get_cycle(name)
371
- cycle.reset if cycle
372
- end
373
-
374
- class Cycle #:nodoc:
375
- attr_reader :values
376
-
377
- def initialize(first_value, *values)
378
- @values = values.unshift(first_value)
379
- reset
380
- end
381
-
382
- def reset
383
- @index = 0
384
- end
385
-
386
- def current_value
387
- @values[previous_index].to_s
388
- end
389
-
390
- def to_s
391
- value = @values[@index].to_s
392
- @index = next_index
393
- return value
394
- end
395
-
396
- private
397
-
398
- def next_index
399
- step_index(1)
400
- end
401
-
402
- def previous_index
403
- step_index(-1)
404
- end
405
-
406
- def step_index(n)
407
- (@index + n) % @values.size
408
- end
409
- end
410
-
411
- private
412
- # The cycle helpers need to store the cycles in a place that is
413
- # guaranteed to be reset every time a page is rendered, so it
414
- # uses an instance variable of ActionView::Base.
415
- def get_cycle(name)
416
- @_cycles = Hash.new unless defined?(@_cycles)
417
- return @_cycles[name]
418
- end
419
-
420
- def set_cycle(name, cycle_object)
421
- @_cycles = Hash.new unless defined?(@_cycles)
422
- @_cycles[name] = cycle_object
423
- end
424
- end
425
- end
426
- end
@@ -1,91 +0,0 @@
1
- require 'action_view/helpers/tag_helper'
2
- require 'i18n/exceptions'
3
-
4
- module ActionView
5
- # = Action View Translation Helpers
6
- module Helpers
7
- module TranslationHelper
8
- # Delegates to <tt>I18n#translate</tt> but also performs three additional functions.
9
- #
10
- # First, it will ensure that any thrown +MissingTranslation+ messages will be turned
11
- # into inline spans that:
12
- #
13
- # * have a "translation-missing" class set,
14
- # * contain the missing key as a title attribute and
15
- # * a titleized version of the last key segment as a text.
16
- #
17
- # E.g. the value returned for a missing translation key :"blog.post.title" will be
18
- # <span class="translation_missing" title="translation missing: en.blog.post.title">Title</span>.
19
- # This way your views will display rather reasonable strings but it will still
20
- # be easy to spot missing translations.
21
- #
22
- # Second, it'll scope the key by the current partial if the key starts
23
- # with a period. So if you call <tt>translate(".foo")</tt> from the
24
- # <tt>people/index.html.erb</tt> template, you'll actually be calling
25
- # <tt>I18n.translate("people.index.foo")</tt>. This makes it less repetitive
26
- # to translate many keys within the same partials and gives you a simple framework
27
- # for scoping them consistently. If you don't prepend the key with a period,
28
- # nothing is converted.
29
- #
30
- # Third, it'll mark the translation as safe HTML if the key has the suffix
31
- # "_html" or the last element of the key is the word "html". For example,
32
- # calling translate("footer_html") or translate("footer.html") will return
33
- # a safe HTML string that won't be escaped by other HTML helper methods. This
34
- # naming convention helps to identify translations that include HTML tags so that
35
- # you know what kind of output to expect when you call translate in a template.
36
- def translate(key, options = {})
37
- # If the user has specified rescue_format then pass it all through, otherwise use
38
- # raise and do the work ourselves
39
- if options.key?(:raise) || options.key?(:rescue_format)
40
- raise_error = options[:raise] || options[:rescue_format]
41
- else
42
- raise_error = false
43
- options[:raise] = true
44
- end
45
-
46
- if html_safe_translation_key?(key)
47
- html_safe_options = options.dup
48
- options.except(*I18n::RESERVED_KEYS).each do |name, value|
49
- unless name == :count && value.is_a?(Numeric)
50
- html_safe_options[name] = ERB::Util.html_escape(value.to_s)
51
- end
52
- end
53
- translation = I18n.translate(scope_key_by_partial(key), html_safe_options)
54
-
55
- translation.respond_to?(:html_safe) ? translation.html_safe : translation
56
- else
57
- I18n.translate(scope_key_by_partial(key), options)
58
- end
59
- rescue I18n::MissingTranslationData => e
60
- raise e if raise_error
61
-
62
- keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope])
63
- content_tag('span', keys.last.to_s.titleize, :class => 'translation_missing', :title => "translation missing: #{keys.join('.')}")
64
- end
65
- alias :t :translate
66
-
67
- # Delegates to <tt>I18n.localize</tt> with no additional functionality.
68
- def localize(*args)
69
- I18n.localize(*args)
70
- end
71
- alias :l :localize
72
-
73
- private
74
- def scope_key_by_partial(key)
75
- if key.to_s.first == "."
76
- if @virtual_path
77
- @virtual_path.gsub(%r{/_?}, ".") + key.to_s
78
- else
79
- raise "Cannot use t(#{key.inspect}) shortcut because path is not available"
80
- end
81
- else
82
- key
83
- end
84
- end
85
-
86
- def html_safe_translation_key?(key)
87
- key.to_s =~ /(\b|_|\.)html$/
88
- end
89
- end
90
- end
91
- end