actionpack 4.0.0.beta1 → 4.0.0.rc1

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 (106) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +195 -11
  3. data/lib/abstract_controller/base.rb +1 -1
  4. data/lib/abstract_controller/helpers.rb +2 -2
  5. data/lib/abstract_controller/layouts.rb +10 -5
  6. data/lib/abstract_controller/rendering.rb +11 -3
  7. data/lib/abstract_controller/translation.rb +1 -1
  8. data/lib/action_controller/log_subscriber.rb +5 -0
  9. data/lib/action_controller/metal.rb +2 -3
  10. data/lib/action_controller/metal/force_ssl.rb +52 -17
  11. data/lib/action_controller/metal/helpers.rb +0 -1
  12. data/lib/action_controller/metal/hide_actions.rb +1 -1
  13. data/lib/action_controller/metal/http_authentication.rb +3 -2
  14. data/lib/action_controller/metal/live.rb +34 -0
  15. data/lib/action_controller/metal/rendering.rb +1 -1
  16. data/lib/action_controller/metal/strong_parameters.rb +7 -3
  17. data/lib/action_controller/test_case.rb +45 -11
  18. data/lib/action_dispatch.rb +4 -6
  19. data/lib/action_dispatch/http/cache.rb +2 -2
  20. data/lib/action_dispatch/http/headers.rb +39 -15
  21. data/lib/action_dispatch/http/mime_negotiation.rb +1 -1
  22. data/lib/action_dispatch/http/mime_type.rb +11 -3
  23. data/lib/action_dispatch/http/parameters.rb +17 -24
  24. data/lib/action_dispatch/http/request.rb +17 -2
  25. data/lib/action_dispatch/http/response.rb +2 -1
  26. data/lib/action_dispatch/http/upload.rb +5 -5
  27. data/lib/action_dispatch/http/url.rb +53 -12
  28. data/lib/action_dispatch/journey/formatter.rb +1 -1
  29. data/lib/action_dispatch/journey/path/pattern.rb +1 -1
  30. data/lib/action_dispatch/journey/route.rb +8 -0
  31. data/lib/action_dispatch/journey/router.rb +3 -1
  32. data/lib/action_dispatch/journey/visitors.rb +8 -0
  33. data/lib/action_dispatch/middleware/cookies.rb +169 -135
  34. data/lib/action_dispatch/middleware/exception_wrapper.rb +1 -0
  35. data/lib/action_dispatch/middleware/remote_ip.rb +2 -2
  36. data/lib/action_dispatch/middleware/request_id.rb +1 -1
  37. data/lib/action_dispatch/middleware/session/cookie_store.rb +38 -58
  38. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +1 -1
  39. data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +4 -6
  40. data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +1 -1
  41. data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +1 -1
  42. data/lib/action_dispatch/routing.rb +28 -64
  43. data/lib/action_dispatch/routing/mapper.rb +61 -48
  44. data/lib/action_dispatch/routing/route_set.rb +17 -14
  45. data/lib/action_dispatch/testing/assertions/routing.rb +2 -2
  46. data/lib/action_dispatch/testing/assertions/selector.rb +2 -2
  47. data/lib/action_dispatch/testing/integration.rb +36 -35
  48. data/lib/action_dispatch/testing/test_process.rb +1 -1
  49. data/lib/action_pack/version.rb +7 -6
  50. data/lib/action_view/buffers.rb +6 -0
  51. data/lib/action_view/dependency_tracker.rb +3 -1
  52. data/lib/action_view/helpers/asset_tag_helper.rb +13 -8
  53. data/lib/action_view/helpers/capture_helper.rb +2 -2
  54. data/lib/action_view/helpers/date_helper.rb +1 -1
  55. data/lib/action_view/helpers/form_helper.rb +56 -19
  56. data/lib/action_view/helpers/form_options_helper.rb +3 -3
  57. data/lib/action_view/helpers/form_tag_helper.rb +1 -1
  58. data/lib/action_view/helpers/javascript_helper.rb +2 -2
  59. data/lib/action_view/helpers/number_helper.rb +25 -0
  60. data/lib/action_view/helpers/tags/base.rb +9 -10
  61. data/lib/action_view/helpers/tags/check_box.rb +1 -1
  62. data/lib/action_view/helpers/tags/checkable.rb +2 -2
  63. data/lib/action_view/helpers/tags/collection_check_boxes.rb +3 -3
  64. data/lib/action_view/helpers/tags/collection_helpers.rb +3 -3
  65. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +3 -3
  66. data/lib/action_view/helpers/tags/collection_select.rb +1 -1
  67. data/lib/action_view/helpers/tags/color_field.rb +2 -2
  68. data/lib/action_view/helpers/tags/date_field.rb +2 -2
  69. data/lib/action_view/helpers/tags/date_select.rb +2 -2
  70. data/lib/action_view/helpers/tags/datetime_field.rb +2 -2
  71. data/lib/action_view/helpers/tags/datetime_local_field.rb +2 -2
  72. data/lib/action_view/helpers/tags/datetime_select.rb +2 -2
  73. data/lib/action_view/helpers/tags/email_field.rb +2 -2
  74. data/lib/action_view/helpers/tags/file_field.rb +2 -2
  75. data/lib/action_view/helpers/tags/grouped_collection_select.rb +2 -2
  76. data/lib/action_view/helpers/tags/hidden_field.rb +2 -2
  77. data/lib/action_view/helpers/tags/label.rb +2 -2
  78. data/lib/action_view/helpers/tags/month_field.rb +2 -2
  79. data/lib/action_view/helpers/tags/number_field.rb +2 -2
  80. data/lib/action_view/helpers/tags/password_field.rb +2 -2
  81. data/lib/action_view/helpers/tags/radio_button.rb +2 -2
  82. data/lib/action_view/helpers/tags/range_field.rb +2 -2
  83. data/lib/action_view/helpers/tags/search_field.rb +2 -2
  84. data/lib/action_view/helpers/tags/select.rb +2 -3
  85. data/lib/action_view/helpers/tags/tel_field.rb +2 -2
  86. data/lib/action_view/helpers/tags/text_area.rb +2 -2
  87. data/lib/action_view/helpers/tags/text_field.rb +2 -2
  88. data/lib/action_view/helpers/tags/time_field.rb +2 -2
  89. data/lib/action_view/helpers/tags/time_select.rb +2 -2
  90. data/lib/action_view/helpers/tags/time_zone_select.rb +2 -2
  91. data/lib/action_view/helpers/tags/url_field.rb +2 -2
  92. data/lib/action_view/helpers/tags/week_field.rb +2 -2
  93. data/lib/action_view/helpers/text_helper.rb +8 -5
  94. data/lib/action_view/helpers/url_helper.rb +18 -6
  95. data/lib/action_view/lookup_context.rb +7 -1
  96. data/lib/action_view/path_set.rb +6 -0
  97. data/lib/action_view/renderer/abstract_renderer.rb +15 -0
  98. data/lib/action_view/renderer/partial_renderer.rb +14 -0
  99. data/lib/action_view/renderer/renderer.rb +6 -0
  100. data/lib/action_view/template.rb +3 -2
  101. data/lib/action_view/template/handlers/erb.rb +29 -3
  102. data/lib/action_view/template/resolver.rb +3 -3
  103. data/lib/action_view/test_case.rb +1 -0
  104. data/lib/action_view/vendor/html-scanner/html/sanitizer.rb +5 -5
  105. data/lib/action_view/vendor/html-scanner/html/selector.rb +8 -8
  106. metadata +8 -8
@@ -31,6 +31,8 @@ module ActionDispatch
31
31
  # If any of the path parameters has a invalid encoding then
32
32
  # raise since it's likely to trigger errors further on.
33
33
  params.each do |key, value|
34
+ next unless value.respond_to?(:valid_encoding?)
35
+
34
36
  unless value.valid_encoding?
35
37
  raise ActionController::BadRequest, "Invalid parameter: #{key} => #{value}"
36
38
  end
@@ -163,14 +165,15 @@ module ActionDispatch
163
165
  super
164
166
  @path_parts = @route.required_parts
165
167
  @arg_size = @path_parts.size
166
- @string_route = string_route(route)
168
+ @string_route = @route.optimized_path
167
169
  end
168
170
 
169
171
  def call(t, args)
170
172
  if args.size == arg_size && !args.last.is_a?(Hash) && optimize_routes_generation?(t)
171
- @options.merge!(t.url_options) if t.respond_to?(:url_options)
172
- @options[:path] = optimized_helper(args)
173
- ActionDispatch::Http::URL.url_for(@options)
173
+ options = @options.dup
174
+ options.merge!(t.url_options) if t.respond_to?(:url_options)
175
+ options[:path] = optimized_helper(args)
176
+ ActionDispatch::Http::URL.url_for(options)
174
177
  else
175
178
  super
176
179
  end
@@ -178,14 +181,6 @@ module ActionDispatch
178
181
 
179
182
  private
180
183
 
181
- def string_route(route)
182
- string_route = route.ast.to_s.dup
183
- while string_route.gsub!(/\([^\)]*\)/, "")
184
- true
185
- end
186
- string_route
187
- end
188
-
189
184
  def optimized_helper(args)
190
185
  path = @string_route.dup
191
186
  klass = Journey::Router::Utils
@@ -409,11 +404,19 @@ module ActionDispatch
409
404
  def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true)
410
405
  raise ArgumentError, "Invalid route name: '#{name}'" unless name.blank? || name.to_s.match(/^[_a-z]\w*$/i)
411
406
 
407
+ if name && named_routes[name]
408
+ raise ArgumentError, "Invalid route name, already in use: '#{name}' \n" \
409
+ "You may have defined two routes with the same name using the `:as` option, or " \
410
+ "you may be overriding a route already defined by a resource with the same naming. " \
411
+ "For the latter, you can restrict the routes created with `resources` as explained here: \n" \
412
+ "http://guides.rubyonrails.org/routing.html#restricting-the-routes-created"
413
+ end
414
+
412
415
  path = build_path(conditions.delete(:path_info), requirements, SEPARATORS, anchor)
413
416
  conditions = build_conditions(conditions, path.names.map { |x| x.to_sym })
414
417
 
415
418
  route = @set.add_route(app, path, conditions, defaults, name)
416
- named_routes[name] = route if name && !named_routes[name]
419
+ named_routes[name] = route if name
417
420
  route
418
421
  end
419
422
 
@@ -663,7 +666,7 @@ module ActionDispatch
663
666
  end
664
667
 
665
668
  req = @request_class.new(env)
666
- @router.recognize(req) do |route, matches, params|
669
+ @router.recognize(req) do |route, _matches, params|
667
670
  params.merge!(extras)
668
671
  params.each do |key, value|
669
672
  if value.is_a?(String)
@@ -81,7 +81,7 @@ module ActionDispatch
81
81
  # Load routes.rb if it hasn't been loaded.
82
82
 
83
83
  generated_path, extra_keys = @routes.generate_extras(options, defaults)
84
- found_extras = options.reject {|k, v| ! extra_keys.include? k}
84
+ found_extras = options.reject { |k, _| ! extra_keys.include? k }
85
85
 
86
86
  msg = message || sprintf("found extras <%s>, not <%s>", found_extras, extras)
87
87
  assert_equal(extras, found_extras, msg)
@@ -120,7 +120,7 @@ module ActionDispatch
120
120
  options[:controller] = "/#{controller}"
121
121
  end
122
122
 
123
- generate_options = options.dup.delete_if{ |k,v| defaults.key?(k) }
123
+ generate_options = options.dup.delete_if{ |k, _| defaults.key?(k) }
124
124
  assert_generates(path.is_a?(Hash) ? path[:path] : path, generate_options, defaults, extras, message)
125
125
  end
126
126
 
@@ -377,8 +377,8 @@ module ActionDispatch
377
377
  node.content.gsub(/<!\[CDATA\[(.*)(\]\]>)?/m) { Rack::Utils.escapeHTML($1) }
378
378
  end
379
379
 
380
- selected = elements.map do |_element|
381
- text = _element.children.select{ |c| not c.tag? }.map{ |c| fix_content[c] }.join
380
+ selected = elements.map do |elem|
381
+ text = elem.children.select{ |c| not c.tag? }.map{ |c| fix_content[c] }.join
382
382
  root = HTML::Document.new(CGI.unescapeHTML("<encoded>#{text}</encoded>")).root
383
383
  css_select(root, "encoded:root", &block)[0]
384
384
  end
@@ -17,7 +17,7 @@ module ActionDispatch
17
17
  # a Hash, or a String that is appropriately encoded
18
18
  # (<tt>application/x-www-form-urlencoded</tt> or
19
19
  # <tt>multipart/form-data</tt>).
20
- # - +headers+: Additional headers to pass, as a Hash. The headers will be
20
+ # - +headers_or_env+: Additional headers to pass, as a Hash. The headers will be
21
21
  # merged into the Rack env hash.
22
22
  #
23
23
  # This method returns a Response object, which one can use to
@@ -28,44 +28,44 @@ module ActionDispatch
28
28
  #
29
29
  # You can also perform POST, PATCH, PUT, DELETE, and HEAD requests with
30
30
  # +#post+, +#patch+, +#put+, +#delete+, and +#head+.
31
- def get(path, parameters = nil, headers = nil)
32
- process :get, path, parameters, headers
31
+ def get(path, parameters = nil, headers_or_env = nil)
32
+ process :get, path, parameters, headers_or_env
33
33
  end
34
34
 
35
35
  # Performs a POST request with the given parameters. See +#get+ for more
36
36
  # details.
37
- def post(path, parameters = nil, headers = nil)
38
- process :post, path, parameters, headers
37
+ def post(path, parameters = nil, headers_or_env = nil)
38
+ process :post, path, parameters, headers_or_env
39
39
  end
40
40
 
41
41
  # Performs a PATCH request with the given parameters. See +#get+ for more
42
42
  # details.
43
- def patch(path, parameters = nil, headers = nil)
44
- process :patch, path, parameters, headers
43
+ def patch(path, parameters = nil, headers_or_env = nil)
44
+ process :patch, path, parameters, headers_or_env
45
45
  end
46
46
 
47
47
  # Performs a PUT request with the given parameters. See +#get+ for more
48
48
  # details.
49
- def put(path, parameters = nil, headers = nil)
50
- process :put, path, parameters, headers
49
+ def put(path, parameters = nil, headers_or_env = nil)
50
+ process :put, path, parameters, headers_or_env
51
51
  end
52
52
 
53
53
  # Performs a DELETE request with the given parameters. See +#get+ for
54
54
  # more details.
55
- def delete(path, parameters = nil, headers = nil)
56
- process :delete, path, parameters, headers
55
+ def delete(path, parameters = nil, headers_or_env = nil)
56
+ process :delete, path, parameters, headers_or_env
57
57
  end
58
58
 
59
59
  # Performs a HEAD request with the given parameters. See +#get+ for more
60
60
  # details.
61
- def head(path, parameters = nil, headers = nil)
62
- process :head, path, parameters, headers
61
+ def head(path, parameters = nil, headers_or_env = nil)
62
+ process :head, path, parameters, headers_or_env
63
63
  end
64
64
 
65
65
  # Performs a OPTIONS request with the given parameters. See +#get+ for
66
66
  # more details.
67
- def options(path, parameters = nil, headers = nil)
68
- process :options, path, parameters, headers
67
+ def options(path, parameters = nil, headers_or_env = nil)
68
+ process :options, path, parameters, headers_or_env
69
69
  end
70
70
 
71
71
  # Performs an XMLHttpRequest request with the given parameters, mirroring
@@ -74,11 +74,11 @@ module ActionDispatch
74
74
  # The request_method is +:get+, +:post+, +:patch+, +:put+, +:delete+ or
75
75
  # +:head+; the parameters are +nil+, a hash, or a url-encoded or multipart
76
76
  # string; the headers are a hash.
77
- def xml_http_request(request_method, path, parameters = nil, headers = nil)
78
- headers ||= {}
79
- headers['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
80
- headers['HTTP_ACCEPT'] ||= [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ')
81
- process(request_method, path, parameters, headers)
77
+ def xml_http_request(request_method, path, parameters = nil, headers_or_env = nil)
78
+ headers_or_env ||= {}
79
+ headers_or_env['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest'
80
+ headers_or_env['HTTP_ACCEPT'] ||= [Mime::JS, Mime::HTML, Mime::XML, 'text/xml', Mime::ALL].join(', ')
81
+ process(request_method, path, parameters, headers_or_env)
82
82
  end
83
83
  alias xhr :xml_http_request
84
84
 
@@ -95,40 +95,40 @@ module ActionDispatch
95
95
  # redirect. Note that the redirects are followed until the response is
96
96
  # not a redirect--this means you may run into an infinite loop if your
97
97
  # redirect loops back to itself.
98
- def request_via_redirect(http_method, path, parameters = nil, headers = nil)
99
- process(http_method, path, parameters, headers)
98
+ def request_via_redirect(http_method, path, parameters = nil, headers_or_env = nil)
99
+ process(http_method, path, parameters, headers_or_env)
100
100
  follow_redirect! while redirect?
101
101
  status
102
102
  end
103
103
 
104
104
  # Performs a GET request, following any subsequent redirect.
105
105
  # See +request_via_redirect+ for more information.
106
- def get_via_redirect(path, parameters = nil, headers = nil)
107
- request_via_redirect(:get, path, parameters, headers)
106
+ def get_via_redirect(path, parameters = nil, headers_or_env = nil)
107
+ request_via_redirect(:get, path, parameters, headers_or_env)
108
108
  end
109
109
 
110
110
  # Performs a POST request, following any subsequent redirect.
111
111
  # See +request_via_redirect+ for more information.
112
- def post_via_redirect(path, parameters = nil, headers = nil)
113
- request_via_redirect(:post, path, parameters, headers)
112
+ def post_via_redirect(path, parameters = nil, headers_or_env = nil)
113
+ request_via_redirect(:post, path, parameters, headers_or_env)
114
114
  end
115
115
 
116
116
  # Performs a PATCH request, following any subsequent redirect.
117
117
  # See +request_via_redirect+ for more information.
118
- def patch_via_redirect(path, parameters = nil, headers = nil)
119
- request_via_redirect(:patch, path, parameters, headers)
118
+ def patch_via_redirect(path, parameters = nil, headers_or_env = nil)
119
+ request_via_redirect(:patch, path, parameters, headers_or_env)
120
120
  end
121
121
 
122
122
  # Performs a PUT request, following any subsequent redirect.
123
123
  # See +request_via_redirect+ for more information.
124
- def put_via_redirect(path, parameters = nil, headers = nil)
125
- request_via_redirect(:put, path, parameters, headers)
124
+ def put_via_redirect(path, parameters = nil, headers_or_env = nil)
125
+ request_via_redirect(:put, path, parameters, headers_or_env)
126
126
  end
127
127
 
128
128
  # Performs a DELETE request, following any subsequent redirect.
129
129
  # See +request_via_redirect+ for more information.
130
- def delete_via_redirect(path, parameters = nil, headers = nil)
131
- request_via_redirect(:delete, path, parameters, headers)
130
+ def delete_via_redirect(path, parameters = nil, headers_or_env = nil)
131
+ request_via_redirect(:delete, path, parameters, headers_or_env)
132
132
  end
133
133
  end
134
134
 
@@ -268,8 +268,7 @@ module ActionDispatch
268
268
  end
269
269
 
270
270
  # Performs the actual request.
271
- def process(method, path, parameters = nil, rack_env = nil)
272
- rack_env ||= {}
271
+ def process(method, path, parameters = nil, headers_or_env = nil)
273
272
  if path =~ %r{://}
274
273
  location = URI.parse(path)
275
274
  https! URI::HTTPS === location if location.scheme
@@ -300,10 +299,12 @@ module ActionDispatch
300
299
  "CONTENT_TYPE" => "application/x-www-form-urlencoded",
301
300
  "HTTP_ACCEPT" => accept
302
301
  }
302
+ # this modifies the passed env directly
303
+ Http::Headers.new(env).merge!(headers_or_env || {})
303
304
 
304
305
  session = Rack::Test::Session.new(_mock_session)
305
306
 
306
- env.merge!(rack_env)
307
+ env.merge!(env)
307
308
 
308
309
  # NOTE: rack-test v0.5 doesn't build a default uri correctly
309
310
  # Make sure requested path is always a full uri
@@ -6,7 +6,7 @@ module ActionDispatch
6
6
  module TestProcess
7
7
  def assigns(key = nil)
8
8
  assigns = {}.with_indifferent_access
9
- @controller.view_assigns.each {|k, v| assigns.regular_writer(k, v)}
9
+ @controller.view_assigns.each { |k, v| assigns.regular_writer(k, v) }
10
10
  key.nil? ? assigns : assigns[key]
11
11
  end
12
12
 
@@ -1,10 +1,11 @@
1
1
  module ActionPack
2
- module VERSION #:nodoc:
3
- MAJOR = 4
4
- MINOR = 0
5
- TINY = 0
6
- PRE = "beta1"
2
+ # Returns the version of the currently loaded ActionPack as a Gem::Version
3
+ def self.version
4
+ Gem::Version.new "4.0.0.rc1"
5
+ end
7
6
 
8
- STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
7
+ module VERSION #:nodoc:
8
+ MAJOR, MINOR, TINY, PRE = ActionPack.version.segments
9
+ STRING = ActionPack.version.to_s
9
10
  end
10
11
  end
@@ -8,9 +8,15 @@ module ActionView
8
8
  end
9
9
 
10
10
  def <<(value)
11
+ return self if value.nil?
11
12
  super(value.to_s)
12
13
  end
13
14
  alias :append= :<<
15
+
16
+ def safe_concat(value)
17
+ return self if value.nil?
18
+ super(value.to_s)
19
+ end
14
20
  alias :safe_append= :safe_concat
15
21
  end
16
22
 
@@ -54,8 +54,10 @@ module ActionView
54
54
  render_dependencies + explicit_dependencies
55
55
  end
56
56
 
57
+ attr_reader :name, :template
58
+ private :name, :template
59
+
57
60
  private
58
- attr_reader :name, :template
59
61
 
60
62
  def source
61
63
  template.source
@@ -14,7 +14,6 @@ module ActionView
14
14
  # # => <img alt="Rails" src="/assets/rails.png" />
15
15
  # stylesheet_link_tag("application")
16
16
  # # => <link href="/assets/application.css?body=1" media="screen" rel="stylesheet" />
17
- #
18
17
  module AssetTagHelper
19
18
  extend ActiveSupport::Concern
20
19
 
@@ -50,7 +49,6 @@ module ActionView
50
49
  #
51
50
  # javascript_include_tag "http://www.example.com/xmlhr.js"
52
51
  # # => <script src="http://www.example.com/xmlhr.js"></script>
53
- #
54
52
  def javascript_include_tag(*sources)
55
53
  options = sources.extract_options!.stringify_keys
56
54
  path_options = options.extract!('protocol').symbolize_keys
@@ -58,7 +56,7 @@ module ActionView
58
56
  sources.uniq.map { |source|
59
57
  tag_options = {
60
58
  "src" => path_to_javascript(source, path_options)
61
- }.merge(options)
59
+ }.merge!(options)
62
60
  content_tag(:script, "", tag_options)
63
61
  }.join("\n").html_safe
64
62
  end
@@ -67,7 +65,7 @@ module ActionView
67
65
  # you don't specify an extension, <tt>.css</tt> will be appended automatically.
68
66
  # You can modify the link attributes by passing a hash as the last argument.
69
67
  # For historical reasons, the 'media' attribute will always be present and defaults
70
- # to "screen", so you must explicitely set it to "all" for the stylesheet(s) to
68
+ # to "screen", so you must explicitly set it to "all" for the stylesheet(s) to
71
69
  # apply to all media types.
72
70
  #
73
71
  # stylesheet_link_tag "style"
@@ -88,7 +86,6 @@ module ActionView
88
86
  # stylesheet_link_tag "random.styles", "/css/stylish"
89
87
  # # => <link href="/assets/random.styles" media="screen" rel="stylesheet" />
90
88
  # # <link href="/css/stylish.css" media="screen" rel="stylesheet" />
91
- #
92
89
  def stylesheet_link_tag(*sources)
93
90
  options = sources.extract_options!.stringify_keys
94
91
  path_options = options.extract!('protocol').symbolize_keys
@@ -98,7 +95,7 @@ module ActionView
98
95
  "rel" => "stylesheet",
99
96
  "media" => "screen",
100
97
  "href" => path_to_stylesheet(source, path_options)
101
- }.merge(options)
98
+ }.merge!(options)
102
99
  tag(:link, tag_options)
103
100
  }.join("\n").html_safe
104
101
  end
@@ -109,10 +106,13 @@ module ActionView
109
106
  # +url_options+. You can modify the LINK tag itself in +tag_options+.
110
107
  #
111
108
  # ==== Options
109
+ #
112
110
  # * <tt>:rel</tt> - Specify the relation of this link, defaults to "alternate"
113
111
  # * <tt>:type</tt> - Override the auto-generated mime type
114
112
  # * <tt>:title</tt> - Specify the title of the link, defaults to the +type+
115
113
  #
114
+ # ==== Examples
115
+ #
116
116
  # auto_discovery_link_tag
117
117
  # # => <link rel="alternate" type="application/rss+xml" title="RSS" href="http://www.currenthost.com/controller/action" />
118
118
  # auto_discovery_link_tag(:atom)
@@ -148,9 +148,12 @@ module ActionView
148
148
  # you can override "rel" and "type".
149
149
  #
150
150
  # ==== Options
151
+ #
151
152
  # * <tt>:rel</tt> - Specify the relation of this link, defaults to 'shortcut icon'
152
153
  # * <tt>:type</tt> - Override the auto-generated mime type, defaults to 'image/vnd.microsoft.icon'
153
154
  #
155
+ # ==== Examples
156
+ #
154
157
  # favicon_link_tag '/myicon.ico'
155
158
  # # => <link href="/assets/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />
156
159
  #
@@ -160,19 +163,19 @@ module ActionView
160
163
  #
161
164
  # favicon_link_tag '/mb-icon.png', rel: 'apple-touch-icon', type: 'image/png'
162
165
  # # => <link href="/assets/mb-icon.png" rel="apple-touch-icon" type="image/png" />
163
- #
164
166
  def favicon_link_tag(source='favicon.ico', options={})
165
167
  tag('link', {
166
168
  :rel => 'shortcut icon',
167
169
  :type => 'image/vnd.microsoft.icon',
168
170
  :href => path_to_image(source)
169
- }.merge(options.symbolize_keys))
171
+ }.merge!(options.symbolize_keys))
170
172
  end
171
173
 
172
174
  # Returns an HTML image tag for the +source+. The +source+ can be a full
173
175
  # path or a file.
174
176
  #
175
177
  # ==== Options
178
+ #
176
179
  # You can add HTML attributes using the +options+. The +options+ supports
177
180
  # three additional keys for convenience and conformance:
178
181
  #
@@ -250,6 +253,8 @@ module ActionView
250
253
  # width="30" and height="45". <tt>:size</tt> will be ignored if the
251
254
  # value is not in the correct format.
252
255
  #
256
+ # ==== Examples
257
+ #
253
258
  # video_tag("trailer")
254
259
  # # => <video src="/videos/trailer" />
255
260
  # video_tag("trailer.ogg")
@@ -156,7 +156,7 @@ module ActionView
156
156
  end
157
157
  nil
158
158
  else
159
- @view_flow.get(name)
159
+ @view_flow.get(name).presence
160
160
  end
161
161
  end
162
162
 
@@ -180,7 +180,7 @@ module ActionView
180
180
  # <title>My Website</title>
181
181
  # <%= yield :script %>
182
182
  # </head>
183
- # <body class="<%= content_for?(:right_col) ? 'one-column' : 'two-column' %>">
183
+ # <body class="<%= content_for?(:right_col) ? 'two-column' : 'one-column' %>">
184
184
  # <%= yield %>
185
185
  # <%= yield :right_col %>
186
186
  # </body>
@@ -808,7 +808,7 @@ module ActionView
808
808
  options[:max_years_allowed] = @options[:max_years_allowed] || 1000
809
809
 
810
810
  if (options[:end] - options[:start]).abs > options[:max_years_allowed]
811
- raise ArgumentError, "There're too many years options to be built. Are you sure you haven't mistyped something? You can provide the :max_years_allowed parameter"
811
+ raise ArgumentError, "There are too many years options to be built. Are you sure you haven't mistyped something? You can provide the :max_years_allowed parameter."
812
812
  end
813
813
 
814
814
  build_options_and_select(:year, val, options)