actionview 4.2.10 → 5.1.0

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

Potentially problematic release.


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

Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +141 -272
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +2 -3
  5. data/lib/action_view/base.rb +33 -21
  6. data/lib/action_view/buffers.rb +1 -1
  7. data/lib/action_view/context.rb +1 -1
  8. data/lib/action_view/dependency_tracker.rb +52 -20
  9. data/lib/action_view/digestor.rb +86 -83
  10. data/lib/action_view/flows.rb +9 -11
  11. data/lib/action_view/gem_version.rb +3 -3
  12. data/lib/action_view/helpers/active_model_helper.rb +8 -8
  13. data/lib/action_view/helpers/asset_tag_helper.rb +74 -38
  14. data/lib/action_view/helpers/asset_url_helper.rb +160 -59
  15. data/lib/action_view/helpers/atom_feed_helper.rb +16 -16
  16. data/lib/action_view/helpers/cache_helper.rb +90 -35
  17. data/lib/action_view/helpers/capture_helper.rb +7 -6
  18. data/lib/action_view/helpers/controller_helper.rb +3 -2
  19. data/lib/action_view/helpers/csrf_helper.rb +3 -3
  20. data/lib/action_view/helpers/date_helper.rb +156 -108
  21. data/lib/action_view/helpers/debug_helper.rb +3 -4
  22. data/lib/action_view/helpers/form_helper.rb +475 -94
  23. data/lib/action_view/helpers/form_options_helper.rb +87 -47
  24. data/lib/action_view/helpers/form_tag_helper.rb +88 -57
  25. data/lib/action_view/helpers/javascript_helper.rb +10 -10
  26. data/lib/action_view/helpers/number_helper.rb +76 -59
  27. data/lib/action_view/helpers/output_safety_helper.rb +34 -4
  28. data/lib/action_view/helpers/record_tag_helper.rb +12 -99
  29. data/lib/action_view/helpers/rendering_helper.rb +3 -3
  30. data/lib/action_view/helpers/sanitize_helper.rb +17 -14
  31. data/lib/action_view/helpers/tag_helper.rb +198 -73
  32. data/lib/action_view/helpers/tags/base.rb +132 -97
  33. data/lib/action_view/helpers/tags/check_box.rb +17 -17
  34. data/lib/action_view/helpers/tags/collection_check_boxes.rb +9 -33
  35. data/lib/action_view/helpers/tags/collection_helpers.rb +68 -36
  36. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +3 -11
  37. data/lib/action_view/helpers/tags/collection_select.rb +2 -2
  38. data/lib/action_view/helpers/tags/date_select.rb +36 -36
  39. data/lib/action_view/helpers/tags/datetime_field.rb +1 -1
  40. data/lib/action_view/helpers/tags/grouped_collection_select.rb +2 -2
  41. data/lib/action_view/helpers/tags/label.rb +5 -1
  42. data/lib/action_view/helpers/tags/password_field.rb +1 -1
  43. data/lib/action_view/helpers/tags/placeholderable.rb +1 -1
  44. data/lib/action_view/helpers/tags/radio_button.rb +4 -4
  45. data/lib/action_view/helpers/tags/search_field.rb +12 -9
  46. data/lib/action_view/helpers/tags/select.rb +9 -9
  47. data/lib/action_view/helpers/tags/text_area.rb +1 -1
  48. data/lib/action_view/helpers/tags/text_field.rb +5 -6
  49. data/lib/action_view/helpers/tags/translator.rb +15 -13
  50. data/lib/action_view/helpers/text_helper.rb +47 -30
  51. data/lib/action_view/helpers/translation_helper.rb +60 -30
  52. data/lib/action_view/helpers/url_helper.rb +132 -104
  53. data/lib/action_view/helpers.rb +1 -1
  54. data/lib/action_view/layouts.rb +59 -54
  55. data/lib/action_view/log_subscriber.rb +56 -7
  56. data/lib/action_view/lookup_context.rb +76 -61
  57. data/lib/action_view/model_naming.rb +1 -1
  58. data/lib/action_view/path_set.rb +28 -19
  59. data/lib/action_view/railtie.rb +30 -6
  60. data/lib/action_view/record_identifier.rb +51 -25
  61. data/lib/action_view/renderer/abstract_renderer.rb +19 -15
  62. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +55 -0
  63. data/lib/action_view/renderer/partial_renderer.rb +208 -206
  64. data/lib/action_view/renderer/renderer.rb +2 -6
  65. data/lib/action_view/renderer/streaming_template_renderer.rb +46 -48
  66. data/lib/action_view/renderer/template_renderer.rb +65 -66
  67. data/lib/action_view/rendering.rb +16 -9
  68. data/lib/action_view/routing_url_for.rb +25 -17
  69. data/lib/action_view/tasks/cache_digests.rake +23 -0
  70. data/lib/action_view/template/error.rb +14 -13
  71. data/lib/action_view/template/handlers/builder.rb +7 -7
  72. data/lib/action_view/template/handlers/erb/deprecated_erubis.rb +9 -0
  73. data/lib/action_view/template/handlers/erb/erubi.rb +81 -0
  74. data/lib/action_view/template/handlers/erb/erubis.rb +81 -0
  75. data/lib/action_view/template/handlers/erb.rb +9 -76
  76. data/lib/action_view/template/handlers/html.rb +9 -0
  77. data/lib/action_view/template/handlers/raw.rb +1 -3
  78. data/lib/action_view/template/handlers.rb +8 -6
  79. data/lib/action_view/template/html.rb +2 -4
  80. data/lib/action_view/template/resolver.rb +133 -109
  81. data/lib/action_view/template/text.rb +5 -8
  82. data/lib/action_view/template/types.rb +15 -17
  83. data/lib/action_view/template.rb +51 -28
  84. data/lib/action_view/test_case.rb +32 -27
  85. data/lib/action_view/testing/resolvers.rb +29 -31
  86. data/lib/action_view/version.rb +1 -1
  87. data/lib/action_view/view_paths.rb +26 -32
  88. data/lib/action_view.rb +5 -5
  89. data/lib/assets/compiled/rails-ujs.js +685 -0
  90. metadata +23 -23
  91. data/lib/action_view/tasks/dependencies.rake +0 -23
@@ -1,4 +1,4 @@
1
- require 'zlib'
1
+ require "zlib"
2
2
 
3
3
  module ActionView
4
4
  # = Action View Asset URL Helpers
@@ -31,26 +31,33 @@ module ActionView
31
31
  # stylesheet_link_tag("application")
32
32
  # # => <link href="http://assets.example.com/assets/application.css" media="screen" rel="stylesheet" />
33
33
  #
34
- # Browsers typically open at most two simultaneous connections to a single
35
- # host, which means your assets often have to wait for other assets to finish
36
- # downloading. You can alleviate this by using a <tt>%d</tt> wildcard in the
37
- # +asset_host+. For example, "assets%d.example.com". If that wildcard is
38
- # present Rails distributes asset requests among the corresponding four hosts
39
- # "assets0.example.com", ..., "assets3.example.com". With this trick browsers
40
- # will open eight simultaneous connections rather than two.
34
+ # Browsers open a limited number of simultaneous connections to a single
35
+ # host. The exact number varies by browser and version. This limit may cause
36
+ # some asset downloads to wait for previous assets to finish before they can
37
+ # begin. You can use the <tt>%d</tt> wildcard in the +asset_host+ to
38
+ # distribute the requests over four hosts. For example,
39
+ # <tt>assets%d.example.com</tt> will spread the asset requests over
40
+ # "assets0.example.com", ..., "assets3.example.com".
41
41
  #
42
42
  # image_tag("rails.png")
43
43
  # # => <img alt="Rails" src="http://assets0.example.com/assets/rails.png" />
44
44
  # stylesheet_link_tag("application")
45
45
  # # => <link href="http://assets2.example.com/assets/application.css" media="screen" rel="stylesheet" />
46
46
  #
47
- # To do this, you can either setup four actual hosts, or you can use wildcard
48
- # DNS to CNAME the wildcard to a single asset host. You can read more about
49
- # setting up your DNS CNAME records from your ISP.
47
+ # This may improve the asset loading performance of your application.
48
+ # It is also possible the combination of additional connection overhead
49
+ # (DNS, SSL) and the overall browser connection limits may result in this
50
+ # solution being slower. You should be sure to measure your actual
51
+ # performance across targeted browsers both before and after this change.
52
+ #
53
+ # To implement the corresponding hosts you can either setup four actual
54
+ # hosts or use wildcard DNS to CNAME the wildcard to a single asset host.
55
+ # You can read more about setting up your DNS CNAME records from your ISP.
50
56
  #
51
57
  # Note: This is purely a browser performance optimization and is not meant
52
58
  # for server load balancing. See http://www.die.net/musings/page_load_time/
53
- # for background.
59
+ # for background and http://www.browserscope.org/?category=network for
60
+ # connection limit data.
54
61
  #
55
62
  # Alternatively, you can exert more control over the asset host by setting
56
63
  # +asset_host+ to a proc like this:
@@ -89,8 +96,8 @@ module ActionView
89
96
  # have SSL certificates for each of the asset hosts this technique allows you
90
97
  # to avoid warnings in the client about mixed media.
91
98
  # Note that the request parameter might not be supplied, e.g. when the assets
92
- # are precompiled via a Rake task. Make sure to use a Proc instead of a lambda,
93
- # since a Proc allows missing parameters and sets them to nil.
99
+ # are precompiled via a Rake task. Make sure to use a +Proc+ instead of a lambda,
100
+ # since a +Proc+ allows missing parameters and sets them to +nil+.
94
101
  #
95
102
  # config.action_controller.asset_host = Proc.new { |source, request|
96
103
  # if request && request.ssl?
@@ -110,29 +117,86 @@ module ActionView
110
117
  module AssetUrlHelper
111
118
  URI_REGEXP = %r{^[-a-z]+://|^(?:cid|data):|^//}i
112
119
 
113
- # Computes the path to asset in public directory. If :type
114
- # options is set, a file extension will be appended and scoped
115
- # to the corresponding public directory.
120
+ # This is the entry point for all assets.
121
+ # When using the asset pipeline (i.e. sprockets and sprockets-rails), the
122
+ # behavior is "enhanced". You can bypass the asset pipeline by passing in
123
+ # <tt>skip_pipeline: true</tt> to the options.
116
124
  #
117
125
  # All other asset *_path helpers delegate through this method.
118
126
  #
119
- # asset_path "application.js" # => /assets/application.js
120
- # asset_path "application", type: :javascript # => /assets/application.js
121
- # asset_path "application", type: :stylesheet # => /assets/application.css
122
- # asset_path "http://www.example.com/js/xmlhr.js" # => http://www.example.com/js/xmlhr.js
127
+ # === With the asset pipeline
128
+ #
129
+ # All options passed to +asset_path+ will be passed to +compute_asset_path+
130
+ # which is implemented by sprockets-rails.
131
+ #
132
+ # asset_path("application.js") # => "/assets/application-60aa4fdc5cea14baf5400fba1abf4f2a46a5166bad4772b1effe341570f07de9.js"
133
+ #
134
+ # === Without the asset pipeline (<tt>skip_pipeline: true</tt>)
135
+ #
136
+ # Accepts a <tt>type</tt> option that can specify the asset's extension. No error
137
+ # checking is done to verify the source passed into +asset_path+ is valid
138
+ # and that the file exists on disk.
139
+ #
140
+ # asset_path("application.js", skip_pipeline: true) # => "application.js"
141
+ # asset_path("filedoesnotexist.png", skip_pipeline: true) # => "filedoesnotexist.png"
142
+ # asset_path("application", type: :javascript, skip_pipeline: true) # => "/javascripts/application.js"
143
+ # asset_path("application", type: :stylesheet, skip_pipeline: true) # => "/stylesheets/application.css"
144
+ #
145
+ # === Options applying to all assets
146
+ #
147
+ # Below lists scenarios that apply to +asset_path+ whether or not you're
148
+ # using the asset pipeline.
149
+ #
150
+ # - All fully qualified urls are returned immediately. This bypasses the
151
+ # asset pipeline and all other behavior described.
152
+ #
153
+ # asset_path("http://www.example.com/js/xmlhr.js") # => "http://www.example.com/js/xmlhr.js"
154
+ #
155
+ # - All assets that begin with a forward slash are assumed to be full
156
+ # urls and will not be expanded. This will bypass the asset pipeline.
157
+ #
158
+ # asset_path("/foo.png") # => "/foo.png"
159
+ #
160
+ # - All blank strings will be returned immediately. This bypasses the
161
+ # asset pipeline and all other behavior described.
162
+ #
163
+ # asset_path("") # => ""
164
+ #
165
+ # - If <tt>config.relative_url_root</tt> is specified, all assets will have that
166
+ # root prepended.
167
+ #
168
+ # Rails.application.config.relative_url_root = "bar"
169
+ # asset_path("foo.js", skip_pipeline: true) # => "bar/foo.js"
170
+ #
171
+ # - A different asset host can be specified via <tt>config.action_controller.asset_host</tt>
172
+ # this is commonly used in conjunction with a CDN.
173
+ #
174
+ # Rails.application.config.action_controller.asset_host = "assets.example.com"
175
+ # asset_path("foo.js", skip_pipeline: true) # => "http://assets.example.com/foo.js"
176
+ #
177
+ # - An extension name can be specified manually with <tt>extname</tt>.
178
+ #
179
+ # asset_path("foo", skip_pipeline: true, extname: ".js") # => "/foo.js"
180
+ # asset_path("foo.css", skip_pipeline: true, extname: ".js") # => "/foo.css.js"
123
181
  def asset_path(source, options = {})
182
+ raise ArgumentError, "nil is not a valid asset source" if source.nil?
183
+
124
184
  source = source.to_s
125
- return "" unless source.present?
126
- return source if source =~ URI_REGEXP
185
+ return "" if source.blank?
186
+ return source if URI_REGEXP.match?(source)
127
187
 
128
- tail, source = source[/([\?#].+)$/], source.sub(/([\?#].+)$/, '')
188
+ tail, source = source[/([\?#].+)$/], source.sub(/([\?#].+)$/, "".freeze)
129
189
 
130
190
  if extname = compute_asset_extname(source, options)
131
191
  source = "#{source}#{extname}"
132
192
  end
133
193
 
134
194
  if source[0] != ?/
135
- source = compute_asset_path(source, options)
195
+ if options[:skip_pipeline]
196
+ source = public_compute_asset_path(source, options)
197
+ else
198
+ source = compute_asset_path(source, options)
199
+ end
136
200
  end
137
201
 
138
202
  relative_url_root = defined?(config.relative_url_root) && config.relative_url_root
@@ -159,31 +223,35 @@ module ActionView
159
223
  # asset_url "application.js", host: "http://cdn.example.com" # => http://cdn.example.com/assets/application.js
160
224
  #
161
225
  def asset_url(source, options = {})
162
- path_to_asset(source, options.merge(:protocol => :request))
226
+ path_to_asset(source, options.merge(protocol: :request))
163
227
  end
164
228
  alias_method :url_to_asset, :asset_url # aliased to avoid conflicts with an asset_url named route
165
229
 
166
230
  ASSET_EXTENSIONS = {
167
- javascript: '.js',
168
- stylesheet: '.css'
231
+ javascript: ".js",
232
+ stylesheet: ".css"
169
233
  }
170
234
 
171
- # Compute extname to append to asset path. Returns nil if
235
+ # Compute extname to append to asset path. Returns +nil+ if
172
236
  # nothing should be added.
173
237
  def compute_asset_extname(source, options = {})
174
238
  return if options[:extname] == false
175
239
  extname = options[:extname] || ASSET_EXTENSIONS[options[:type]]
176
- extname if extname && File.extname(source) != extname
240
+ if extname && File.extname(source) != extname
241
+ extname
242
+ else
243
+ nil
244
+ end
177
245
  end
178
246
 
179
247
  # Maps asset types to public directory.
180
248
  ASSET_PUBLIC_DIRECTORIES = {
181
- audio: '/audios',
182
- font: '/fonts',
183
- image: '/images',
184
- javascript: '/javascripts',
185
- stylesheet: '/stylesheets',
186
- video: '/videos'
249
+ audio: "/audios",
250
+ font: "/fonts",
251
+ image: "/images",
252
+ javascript: "/javascripts",
253
+ stylesheet: "/stylesheets",
254
+ video: "/videos"
187
255
  }
188
256
 
189
257
  # Computes asset path to public directory. Plugins and
@@ -193,6 +261,7 @@ module ActionView
193
261
  dir = ASSET_PUBLIC_DIRECTORIES[options[:type]] || ""
194
262
  File.join(dir, source)
195
263
  end
264
+ alias :public_compute_asset_path :compute_asset_path
196
265
 
197
266
  # Pick an asset host for this source. Returns +nil+ if no host is set,
198
267
  # the host if no wildcard is set, the host interpolated with the
@@ -204,19 +273,21 @@ module ActionView
204
273
  host = options[:host]
205
274
  host ||= config.asset_host if defined? config.asset_host
206
275
 
207
- if host.respond_to?(:call)
208
- arity = host.respond_to?(:arity) ? host.arity : host.method(:call).arity
209
- args = [source]
210
- args << request if request && (arity > 1 || arity < 0)
211
- host = host.call(*args)
212
- elsif host =~ /%d/
213
- host = host % (Zlib.crc32(source) % 4)
276
+ if host
277
+ if host.respond_to?(:call)
278
+ arity = host.respond_to?(:arity) ? host.arity : host.method(:call).arity
279
+ args = [source]
280
+ args << request if request && (arity > 1 || arity < 0)
281
+ host = host.call(*args)
282
+ elsif host.include?("%d")
283
+ host = host % (Zlib.crc32(source) % 4)
284
+ end
214
285
  end
215
286
 
216
287
  host ||= request.base_url if request && options[:protocol] == :request
217
288
  return unless host
218
289
 
219
- if host =~ URI_REGEXP
290
+ if URI_REGEXP.match?(host)
220
291
  host
221
292
  else
222
293
  protocol = options[:protocol] || config.default_asset_host_protocol || (request ? :request : :relative)
@@ -242,14 +313,19 @@ module ActionView
242
313
  # javascript_path "http://www.example.com/js/xmlhr" # => http://www.example.com/js/xmlhr
243
314
  # javascript_path "http://www.example.com/js/xmlhr.js" # => http://www.example.com/js/xmlhr.js
244
315
  def javascript_path(source, options = {})
245
- path_to_asset(source, {type: :javascript}.merge!(options))
316
+ path_to_asset(source, { type: :javascript }.merge!(options))
246
317
  end
247
318
  alias_method :path_to_javascript, :javascript_path # aliased to avoid conflicts with a javascript_path named route
248
319
 
249
320
  # Computes the full URL to a JavaScript asset in the public javascripts directory.
250
321
  # This will use +javascript_path+ internally, so most of their behaviors will be the same.
322
+ # Since +javascript_url+ is based on +asset_url+ method you can set :host options. If :host
323
+ # options is set, it overwrites global +config.action_controller.asset_host+ setting.
324
+ #
325
+ # javascript_url "js/xmlhr.js", host: "http://stage.example.com" # => http://stage.example.com/assets/dir/xmlhr.js
326
+ #
251
327
  def javascript_url(source, options = {})
252
- url_to_asset(source, {type: :javascript}.merge!(options))
328
+ url_to_asset(source, { type: :javascript }.merge!(options))
253
329
  end
254
330
  alias_method :url_to_javascript, :javascript_url # aliased to avoid conflicts with a javascript_url named route
255
331
 
@@ -264,14 +340,19 @@ module ActionView
264
340
  # stylesheet_path "http://www.example.com/css/style" # => http://www.example.com/css/style
265
341
  # stylesheet_path "http://www.example.com/css/style.css" # => http://www.example.com/css/style.css
266
342
  def stylesheet_path(source, options = {})
267
- path_to_asset(source, {type: :stylesheet}.merge!(options))
343
+ path_to_asset(source, { type: :stylesheet }.merge!(options))
268
344
  end
269
345
  alias_method :path_to_stylesheet, :stylesheet_path # aliased to avoid conflicts with a stylesheet_path named route
270
346
 
271
347
  # Computes the full URL to a stylesheet asset in the public stylesheets directory.
272
348
  # This will use +stylesheet_path+ internally, so most of their behaviors will be the same.
349
+ # Since +stylesheet_url+ is based on +asset_url+ method you can set :host options. If :host
350
+ # options is set, it overwrites global +config.action_controller.asset_host+ setting.
351
+ #
352
+ # stylesheet_url "css/style.css", host: "http://stage.example.com" # => http://stage.example.com/css/style.css
353
+ #
273
354
  def stylesheet_url(source, options = {})
274
- url_to_asset(source, {type: :stylesheet}.merge!(options))
355
+ url_to_asset(source, { type: :stylesheet }.merge!(options))
275
356
  end
276
357
  alias_method :url_to_stylesheet, :stylesheet_url # aliased to avoid conflicts with a stylesheet_url named route
277
358
 
@@ -289,14 +370,19 @@ module ActionView
289
370
  # The alias +path_to_image+ is provided to avoid that. Rails uses the alias internally, and
290
371
  # plugin authors are encouraged to do so.
291
372
  def image_path(source, options = {})
292
- path_to_asset(source, {type: :image}.merge!(options))
373
+ path_to_asset(source, { type: :image }.merge!(options))
293
374
  end
294
375
  alias_method :path_to_image, :image_path # aliased to avoid conflicts with an image_path named route
295
376
 
296
377
  # Computes the full URL to an image asset.
297
378
  # This will use +image_path+ internally, so most of their behaviors will be the same.
379
+ # Since +image_url+ is based on +asset_url+ method you can set :host options. If :host
380
+ # options is set, it overwrites global +config.action_controller.asset_host+ setting.
381
+ #
382
+ # image_url "edit.png", host: "http://stage.example.com" # => http://stage.example.com/edit.png
383
+ #
298
384
  def image_url(source, options = {})
299
- url_to_asset(source, {type: :image}.merge!(options))
385
+ url_to_asset(source, { type: :image }.merge!(options))
300
386
  end
301
387
  alias_method :url_to_image, :image_url # aliased to avoid conflicts with an image_url named route
302
388
 
@@ -310,16 +396,21 @@ module ActionView
310
396
  # video_path("/trailers/hd.avi") # => /trailers/hd.avi
311
397
  # video_path("http://www.example.com/vid/hd.avi") # => http://www.example.com/vid/hd.avi
312
398
  def video_path(source, options = {})
313
- path_to_asset(source, {type: :video}.merge!(options))
399
+ path_to_asset(source, { type: :video }.merge!(options))
314
400
  end
315
401
  alias_method :path_to_video, :video_path # aliased to avoid conflicts with a video_path named route
316
402
 
317
403
  # Computes the full URL to a video asset in the public videos directory.
318
404
  # This will use +video_path+ internally, so most of their behaviors will be the same.
405
+ # Since +video_url+ is based on +asset_url+ method you can set :host options. If :host
406
+ # options is set, it overwrites global +config.action_controller.asset_host+ setting.
407
+ #
408
+ # video_url "hd.avi", host: "http://stage.example.com" # => http://stage.example.com/hd.avi
409
+ #
319
410
  def video_url(source, options = {})
320
- url_to_asset(source, {type: :video}.merge!(options))
411
+ url_to_asset(source, { type: :video }.merge!(options))
321
412
  end
322
- alias_method :url_to_video, :video_url # aliased to avoid conflicts with an video_url named route
413
+ alias_method :url_to_video, :video_url # aliased to avoid conflicts with a video_url named route
323
414
 
324
415
  # Computes the path to an audio asset in the public audios directory.
325
416
  # Full paths from the document root will be passed through.
@@ -331,14 +422,19 @@ module ActionView
331
422
  # audio_path("/sounds/horse.wav") # => /sounds/horse.wav
332
423
  # audio_path("http://www.example.com/sounds/horse.wav") # => http://www.example.com/sounds/horse.wav
333
424
  def audio_path(source, options = {})
334
- path_to_asset(source, {type: :audio}.merge!(options))
425
+ path_to_asset(source, { type: :audio }.merge!(options))
335
426
  end
336
427
  alias_method :path_to_audio, :audio_path # aliased to avoid conflicts with an audio_path named route
337
428
 
338
429
  # Computes the full URL to an audio asset in the public audios directory.
339
430
  # This will use +audio_path+ internally, so most of their behaviors will be the same.
431
+ # Since +audio_url+ is based on +asset_url+ method you can set :host options. If :host
432
+ # options is set, it overwrites global +config.action_controller.asset_host+ setting.
433
+ #
434
+ # audio_url "horse.wav", host: "http://stage.example.com" # => http://stage.example.com/horse.wav
435
+ #
340
436
  def audio_url(source, options = {})
341
- url_to_asset(source, {type: :audio}.merge!(options))
437
+ url_to_asset(source, { type: :audio }.merge!(options))
342
438
  end
343
439
  alias_method :url_to_audio, :audio_url # aliased to avoid conflicts with an audio_url named route
344
440
 
@@ -351,16 +447,21 @@ module ActionView
351
447
  # font_path("/dir/font.ttf") # => /dir/font.ttf
352
448
  # font_path("http://www.example.com/dir/font.ttf") # => http://www.example.com/dir/font.ttf
353
449
  def font_path(source, options = {})
354
- path_to_asset(source, {type: :font}.merge!(options))
450
+ path_to_asset(source, { type: :font }.merge!(options))
355
451
  end
356
- alias_method :path_to_font, :font_path # aliased to avoid conflicts with an font_path named route
452
+ alias_method :path_to_font, :font_path # aliased to avoid conflicts with a font_path named route
357
453
 
358
454
  # Computes the full URL to a font asset.
359
455
  # This will use +font_path+ internally, so most of their behaviors will be the same.
456
+ # Since +font_url+ is based on +asset_url+ method you can set :host options. If :host
457
+ # options is set, it overwrites global +config.action_controller.asset_host+ setting.
458
+ #
459
+ # font_url "font.ttf", host: "http://stage.example.com" # => http://stage.example.com/font.ttf
460
+ #
360
461
  def font_url(source, options = {})
361
- url_to_asset(source, {type: :font}.merge!(options))
462
+ url_to_asset(source, { type: :font }.merge!(options))
362
463
  end
363
- alias_method :url_to_font, :font_url # aliased to avoid conflicts with an font_url named route
464
+ alias_method :url_to_font, :font_url # aliased to avoid conflicts with a font_url named route
364
465
  end
365
466
  end
366
467
  end
@@ -1,4 +1,4 @@
1
- require 'set'
1
+ require "set"
2
2
 
3
3
  module ActionView
4
4
  # = Action View Atom Feed Helpers
@@ -16,7 +16,7 @@ module ActionView
16
16
  # end
17
17
  #
18
18
  # app/controllers/posts_controller.rb:
19
- # class PostsController < ApplicationController::Base
19
+ # class PostsController < ApplicationController
20
20
  # # GET /posts.html
21
21
  # # GET /posts.atom
22
22
  # def index
@@ -51,7 +51,7 @@ module ActionView
51
51
  # * <tt>:language</tt>: Defaults to "en-US".
52
52
  # * <tt>:root_url</tt>: The HTML alternative that this feed is doubling for. Defaults to / on the current host.
53
53
  # * <tt>:url</tt>: The URL for this feed. Defaults to the current URL.
54
- # * <tt>:id</tt>: The id for this feed. Defaults to "tag:#{request.host},#{options[:schema_date]}:#{request.fullpath.split(".")[0]}"
54
+ # * <tt>:id</tt>: The id for this feed. Defaults to "tag:localhost,2005:/posts", in this case.
55
55
  # * <tt>:schema_date</tt>: The date at which the tag scheme for the feed was first used. A good default is the year you
56
56
  # created the feed. See http://feedvalidator.org/docs/error/InvalidTAG.html for more information. If not specified,
57
57
  # 2005 is used (as an "I don't care" value).
@@ -103,7 +103,7 @@ module ActionView
103
103
  xml = options.delete(:xml) || eval("xml", block.binding)
104
104
  xml.instruct!
105
105
  if options[:instruct]
106
- options[:instruct].each do |target,attrs|
106
+ options[:instruct].each do |target, attrs|
107
107
  if attrs.respond_to?(:keys)
108
108
  xml.instruct!(target, attrs)
109
109
  elsif attrs.respond_to?(:each)
@@ -112,13 +112,13 @@ module ActionView
112
112
  end
113
113
  end
114
114
 
115
- feed_opts = {"xml:lang" => options[:language] || "en-US", "xmlns" => 'http://www.w3.org/2005/Atom'}
116
- feed_opts.merge!(options).reject!{|k,v| !k.to_s.match(/^xml/)}
115
+ feed_opts = { "xml:lang" => options[:language] || "en-US", "xmlns" => "http://www.w3.org/2005/Atom" }
116
+ feed_opts.merge!(options).reject! { |k, v| !k.to_s.match(/^xml/) }
117
117
 
118
118
  xml.feed(feed_opts) do
119
119
  xml.id(options[:id] || "tag:#{request.host},#{options[:schema_date]}:#{request.fullpath.split(".")[0]}")
120
- xml.link(:rel => 'alternate', :type => 'text/html', :href => options[:root_url] || (request.protocol + request.host_with_port))
121
- xml.link(:rel => 'self', :type => 'application/atom+xml', :href => options[:url] || request.url)
120
+ xml.link(rel: "alternate", type: "text/html", href: options[:root_url] || (request.protocol + request.host_with_port))
121
+ xml.link(rel: "self", type: "application/atom+xml", href: options[:url] || request.url)
122
122
 
123
123
  yield AtomFeedBuilder.new(xml, self, options)
124
124
  end
@@ -132,13 +132,13 @@ module ActionView
132
132
  end
133
133
 
134
134
  private
135
- # Delegate to xml builder, first wrapping the element in a xhtml
135
+ # Delegate to xml builder, first wrapping the element in an xhtml
136
136
  # namespaced div element if the method and arguments indicate
137
137
  # that an xhtml_block? is desired.
138
138
  def method_missing(method, *arguments, &block)
139
139
  if xhtml_block?(method, arguments)
140
140
  @xml.__send__(method, *arguments) do
141
- @xml.div(:xmlns => 'http://www.w3.org/1999/xhtml') do |xhtml|
141
+ @xml.div(xmlns: "http://www.w3.org/1999/xhtml") do |xhtml|
142
142
  block.call(xhtml)
143
143
  end
144
144
  end
@@ -153,7 +153,7 @@ module ActionView
153
153
  def xhtml_block?(method, arguments)
154
154
  if XHTML_TAG_NAMES.include?(method.to_s)
155
155
  last = arguments.last
156
- last.is_a?(Hash) && last[:type].to_s == 'xhtml'
156
+ last.is_a?(Hash) && last[:type].to_s == "xhtml"
157
157
  end
158
158
  end
159
159
  end
@@ -163,7 +163,7 @@ module ActionView
163
163
  @xml, @view, @feed_options = xml, view, feed_options
164
164
  end
165
165
 
166
- # Accepts a Date or Time object and inserts it in the proper format. If nil is passed, current time in UTC is used.
166
+ # Accepts a Date or Time object and inserts it in the proper format. If +nil+ is passed, current time in UTC is used.
167
167
  def updated(date_or_time = nil)
168
168
  @xml.updated((date_or_time || Time.now.utc).xmlschema)
169
169
  end
@@ -174,7 +174,7 @@ module ActionView
174
174
  #
175
175
  # * <tt>:published</tt>: Time first published. Defaults to the created_at attribute on the record if one such exists.
176
176
  # * <tt>:updated</tt>: Time of update. Defaults to the updated_at attribute on the record if one such exists.
177
- # * <tt>:url</tt>: The URL for this entry. Defaults to the polymorphic_url for the record.
177
+ # * <tt>:url</tt>: The URL for this entry or +false+ or +nil+ for not having a link tag. Defaults to the +polymorphic_url+ for the record.
178
178
  # * <tt>:id</tt>: The ID for this entry. Defaults to "tag:#{@view.request.host},#{@feed_options[:schema_date]}:#{record.class}/#{record.id}"
179
179
  # * <tt>:type</tt>: The TYPE for this entry. Defaults to "text/html".
180
180
  def entry(record, options = {})
@@ -189,15 +189,15 @@ module ActionView
189
189
  @xml.updated((options[:updated] || record.updated_at).xmlschema)
190
190
  end
191
191
 
192
- type = options.fetch(:type, 'text/html')
192
+ type = options.fetch(:type, "text/html")
193
193
 
194
- @xml.link(:rel => 'alternate', :type => type, :href => options[:url] || @view.polymorphic_url(record))
194
+ url = options.fetch(:url) { @view.polymorphic_url(record) }
195
+ @xml.link(rel: "alternate", type: type, href: url) if url
195
196
 
196
197
  yield AtomBuilder.new(@xml)
197
198
  end
198
199
  end
199
200
  end
200
-
201
201
  end
202
202
  end
203
203
  end