actionpack 3.0.1 → 3.0.2
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.
- data/CHANGELOG +7 -1
- data/lib/abstract_controller/base.rb +1 -0
- data/lib/abstract_controller/callbacks.rb +2 -0
- data/lib/abstract_controller/rendering.rb +4 -4
- data/lib/action_controller/base.rb +2 -0
- data/lib/action_controller/metal.rb +8 -3
- data/lib/action_controller/metal/head.rb +2 -4
- data/lib/action_controller/metal/http_authentication.rb +8 -10
- data/lib/action_controller/metal/mime_responds.rb +1 -1
- data/lib/action_controller/metal/redirecting.rb +4 -2
- data/lib/action_controller/metal/renderers.rb +1 -1
- data/lib/action_controller/metal/responder.rb +20 -0
- data/lib/action_controller/test_case.rb +7 -0
- data/lib/action_controller/vendor/html-scanner/html/node.rb +5 -11
- data/lib/action_dispatch/http/request.rb +19 -2
- data/lib/action_dispatch/http/response.rb +9 -10
- data/lib/action_dispatch/http/upload.rb +21 -29
- data/lib/action_dispatch/middleware/cookies.rb +11 -3
- data/lib/action_dispatch/railtie.rb +0 -5
- data/lib/action_dispatch/routing.rb +75 -22
- data/lib/action_dispatch/routing/mapper.rb +429 -60
- data/lib/action_dispatch/routing/polymorphic_routes.rb +1 -1
- data/lib/action_dispatch/routing/route.rb +2 -1
- data/lib/action_dispatch/routing/url_for.rb +4 -5
- data/lib/action_dispatch/testing/integration.rb +9 -7
- data/lib/action_pack/version.rb +2 -2
- data/lib/action_view/base.rb +1 -1
- data/lib/action_view/helpers/asset_tag_helper.rb +1 -1
- data/lib/action_view/helpers/capture_helper.rb +2 -1
- data/lib/action_view/helpers/date_helper.rb +2 -0
- data/lib/action_view/helpers/form_helper.rb +15 -12
- data/lib/action_view/helpers/form_options_helper.rb +5 -5
- data/lib/action_view/helpers/javascript_helper.rb +2 -1
- data/lib/action_view/helpers/number_helper.rb +23 -12
- data/lib/action_view/helpers/prototype_helper.rb +4 -4
- data/lib/action_view/helpers/text_helper.rb +18 -0
- data/lib/action_view/helpers/url_helper.rb +12 -10
- data/lib/action_view/render/partials.rb +52 -8
- data/lib/action_view/render/rendering.rb +1 -1
- data/lib/action_view/template/handlers/erb.rb +6 -1
- data/lib/action_view/test_case.rb +26 -10
- metadata +35 -12
@@ -17,7 +17,7 @@ module ActionDispatch
|
|
17
17
|
#
|
18
18
|
# == Usage within the framework
|
19
19
|
#
|
20
|
-
# Polymorphic URL helpers are used in a number of places throughout the Rails framework:
|
20
|
+
# Polymorphic URL helpers are used in a number of places throughout the \Rails framework:
|
21
21
|
#
|
22
22
|
# * <tt>url_for</tt>, so you can use it with a record as the argument, e.g.
|
23
23
|
# <tt>url_for(@article)</tt>;
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module ActionDispatch
|
2
2
|
module Routing
|
3
|
-
# In <
|
3
|
+
# In <tt>config/routes.rb</tt> you define URL-to-controller mappings, but the reverse
|
4
4
|
# is also possible: an URL can be generated from one of your routing definitions.
|
5
5
|
# URL generation functionality is centralized in this module.
|
6
6
|
#
|
@@ -12,15 +12,14 @@ module ActionDispatch
|
|
12
12
|
#
|
13
13
|
# == URL generation from parameters
|
14
14
|
#
|
15
|
-
# As you may know, some functions
|
15
|
+
# As you may know, some functions, such as ActionController::Base#url_for
|
16
16
|
# and ActionView::Helpers::UrlHelper#link_to, can generate URLs given a set
|
17
17
|
# of parameters. For example, you've probably had the chance to write code
|
18
18
|
# like this in one of your views:
|
19
19
|
#
|
20
20
|
# <%= link_to('Click here', :controller => 'users',
|
21
21
|
# :action => 'new', :message => 'Welcome!') %>
|
22
|
-
#
|
23
|
-
# # Generates a link to /users/new?message=Welcome%21
|
22
|
+
# # => "/users/new?message=Welcome%21"
|
24
23
|
#
|
25
24
|
# link_to, and all other functions that require URL generation functionality,
|
26
25
|
# actually use ActionController::UrlFor under the hood. And in particular,
|
@@ -61,7 +60,7 @@ module ActionDispatch
|
|
61
60
|
#
|
62
61
|
# UrlFor also allows one to access methods that have been auto-generated from
|
63
62
|
# named routes. For example, suppose that you have a 'users' resource in your
|
64
|
-
# <
|
63
|
+
# <tt>config/routes.rb</tt>:
|
65
64
|
#
|
66
65
|
# resources :users
|
67
66
|
#
|
@@ -115,8 +115,8 @@ module ActionDispatch
|
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
-
# An
|
119
|
-
# performed sequentially by
|
118
|
+
# An instance of this class represents a set of requests and responses
|
119
|
+
# performed sequentially by a test process. Because you can instantiate
|
120
120
|
# multiple sessions and run them side-by-side, you can also mimic (to some
|
121
121
|
# limited extent) multiple simultaneous users interacting with your system.
|
122
122
|
#
|
@@ -257,12 +257,14 @@ module ActionDispatch
|
|
257
257
|
end
|
258
258
|
end
|
259
259
|
|
260
|
+
hostname, port = host.split(':')
|
261
|
+
|
260
262
|
env = {
|
261
263
|
:method => method,
|
262
264
|
:params => parameters,
|
263
265
|
|
264
|
-
"SERVER_NAME" =>
|
265
|
-
"SERVER_PORT" => (https? ? "443" : "80"),
|
266
|
+
"SERVER_NAME" => hostname,
|
267
|
+
"SERVER_PORT" => port || (https? ? "443" : "80"),
|
266
268
|
"HTTPS" => https? ? "on" : "off",
|
267
269
|
"rack.url_scheme" => https? ? "https" : "http",
|
268
270
|
|
@@ -373,12 +375,12 @@ module ActionDispatch
|
|
373
375
|
end
|
374
376
|
end
|
375
377
|
|
376
|
-
# An
|
378
|
+
# An test that spans multiple controllers and actions,
|
377
379
|
# tying them all together to ensure they work together as expected. It tests
|
378
380
|
# more completely than either unit or functional tests do, exercising the
|
379
381
|
# entire stack, from the dispatcher to the database.
|
380
382
|
#
|
381
|
-
# At its simplest, you simply extend IntegrationTest and write your tests
|
383
|
+
# At its simplest, you simply extend <tt>IntegrationTest</tt> and write your tests
|
382
384
|
# using the get/post methods:
|
383
385
|
#
|
384
386
|
# require "test_helper"
|
@@ -403,7 +405,7 @@ module ActionDispatch
|
|
403
405
|
# However, you can also have multiple session instances open per test, and
|
404
406
|
# even extend those instances with assertions and methods to create a very
|
405
407
|
# powerful testing DSL that is specific for your application. You can even
|
406
|
-
# reference any named routes you happen to have defined
|
408
|
+
# reference any named routes you happen to have defined.
|
407
409
|
#
|
408
410
|
# require "test_helper"
|
409
411
|
#
|
data/lib/action_pack/version.rb
CHANGED
data/lib/action_view/base.rb
CHANGED
@@ -156,7 +156,7 @@ module ActionView #:nodoc:
|
|
156
156
|
#
|
157
157
|
# This refreshes the sidebar, removes a person element and highlights the user list.
|
158
158
|
#
|
159
|
-
# See the ActionView::Helpers::PrototypeHelper::GeneratorMethods documentation for more details.
|
159
|
+
# See the ActionView::Helpers::PrototypeHelper::JavaScriptGenerator::GeneratorMethods documentation for more details.
|
160
160
|
class Base
|
161
161
|
module Subclasses
|
162
162
|
end
|
@@ -836,7 +836,7 @@ module ActionView
|
|
836
836
|
|
837
837
|
def expand_javascript_sources(sources, recursive = false)
|
838
838
|
if sources.include?(:all)
|
839
|
-
all_javascript_files = collect_asset_files(config.javascripts_dir, ('**' if recursive), '*.js')
|
839
|
+
all_javascript_files = (collect_asset_files(config.javascripts_dir, ('**' if recursive), '*.js') - ['application']) << 'application'
|
840
840
|
((determine_source(:defaults, @@javascript_expansions).dup & all_javascript_files) + all_javascript_files).uniq
|
841
841
|
else
|
842
842
|
expanded_sources = sources.collect do |source|
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'active_support/core_ext/object/blank'
|
2
|
+
require 'active_support/core_ext/string/output_safety'
|
2
3
|
|
3
4
|
module ActionView
|
4
5
|
# = Action View Capture Helper
|
@@ -38,7 +39,7 @@ module ActionView
|
|
38
39
|
value = nil
|
39
40
|
buffer = with_output_buffer { value = yield(*args) }
|
40
41
|
if string = buffer.presence || value and string.is_a?(String)
|
41
|
-
NonConcattingString.new(string)
|
42
|
+
NonConcattingString.new(ERB::Util.html_escape(string))
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
@@ -893,6 +893,8 @@ module ActionView
|
|
893
893
|
# Returns the separator for a given datetime component
|
894
894
|
def separator(type)
|
895
895
|
case type
|
896
|
+
when :year
|
897
|
+
@options[:discard_year] ? "" : @options[:date_separator]
|
896
898
|
when :month
|
897
899
|
@options[:discard_month] ? "" : @options[:date_separator]
|
898
900
|
when :day
|
@@ -202,6 +202,12 @@ module ActionView
|
|
202
202
|
# ...
|
203
203
|
# <% end %>
|
204
204
|
#
|
205
|
+
# You can also set the answer format, like this:
|
206
|
+
#
|
207
|
+
# <%= form_for(@post, :format => :json) do |f| %>
|
208
|
+
# ...
|
209
|
+
# <% end %>
|
210
|
+
#
|
205
211
|
# If you have an object that needs to be represented as a different
|
206
212
|
# parameter, like a Client that acts as a Person:
|
207
213
|
#
|
@@ -332,7 +338,9 @@ module ActionView
|
|
332
338
|
|
333
339
|
options[:html] ||= {}
|
334
340
|
options[:html].reverse_merge!(html_options)
|
335
|
-
options[:url] ||=
|
341
|
+
options[:url] ||= options[:format] ? \
|
342
|
+
polymorphic_path(object_or_array, :format => options.delete(:format)) : \
|
343
|
+
polymorphic_path(object_or_array)
|
336
344
|
end
|
337
345
|
|
338
346
|
# Creates a scope around a specific model object like form_for, but
|
@@ -803,7 +811,7 @@ module ActionView
|
|
803
811
|
options["incremental"] = true unless options.has_key?("incremental")
|
804
812
|
end
|
805
813
|
|
806
|
-
InstanceTag.new(object_name, method, self, options.delete(
|
814
|
+
InstanceTag.new(object_name, method, self, options.delete("object")).to_input_field_tag("search", options)
|
807
815
|
end
|
808
816
|
|
809
817
|
# Returns a text_field of type "tel".
|
@@ -1006,14 +1014,9 @@ module ActionView
|
|
1006
1014
|
|
1007
1015
|
def value_before_type_cast(object, method_name)
|
1008
1016
|
unless object.nil?
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
elsif object.respond_to?(method_name + "_before_type_cast")
|
1013
|
-
object.send(method_name + "_before_type_cast")
|
1014
|
-
else
|
1015
|
-
raise NoMethodError, "Model #{object.class} does not respond to #{method_name}"
|
1016
|
-
end
|
1017
|
+
object.respond_to?(method_name + "_before_type_cast") ?
|
1018
|
+
object.send(method_name + "_before_type_cast") :
|
1019
|
+
object.send(method_name)
|
1017
1020
|
end
|
1018
1021
|
end
|
1019
1022
|
|
@@ -1258,11 +1261,11 @@ module ActionView
|
|
1258
1261
|
|
1259
1262
|
if association.respond_to?(:persisted?)
|
1260
1263
|
association = [association] if @object.send(association_name).is_a?(Array)
|
1261
|
-
elsif !association.
|
1264
|
+
elsif !association.respond_to?(:to_ary)
|
1262
1265
|
association = @object.send(association_name)
|
1263
1266
|
end
|
1264
1267
|
|
1265
|
-
if association.
|
1268
|
+
if association.respond_to?(:to_ary)
|
1266
1269
|
explicit_child_index = options[:child_index]
|
1267
1270
|
output = ActiveSupport::SafeBuffer.new
|
1268
1271
|
association.each do |child|
|
@@ -395,12 +395,12 @@ module ActionView
|
|
395
395
|
# <b>Note:</b> Only the <tt><optgroup></tt> and <tt><option></tt> tags are returned, so you still have to
|
396
396
|
# wrap the output in an appropriate <tt><select></tt> tag.
|
397
397
|
def option_groups_from_collection_for_select(collection, group_method, group_label_method, option_key_method, option_value_method, selected_key = nil)
|
398
|
-
collection.
|
398
|
+
collection.map do |group|
|
399
399
|
group_label_string = eval("group.#{group_label_method}")
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
end.html_safe
|
400
|
+
"<optgroup label=\"#{html_escape(group_label_string)}\">" +
|
401
|
+
options_from_collection_for_select(eval("group.#{group_method}"), option_key_method, option_value_method, selected_key) +
|
402
|
+
'</optgroup>'
|
403
|
+
end.join.html_safe
|
404
404
|
end
|
405
405
|
|
406
406
|
# Returns a string of <tt><option></tt> tags, like <tt>options_for_select</tt>, but
|
@@ -65,7 +65,8 @@ module ActionView
|
|
65
65
|
# //]]>
|
66
66
|
# </script>
|
67
67
|
#
|
68
|
-
# +html_options+ may be a hash of attributes for the <script> tag.
|
68
|
+
# +html_options+ may be a hash of attributes for the <tt>\<script></tt> tag.
|
69
|
+
# Example:
|
69
70
|
# javascript_tag "alert('All is good')", :defer => 'defer'
|
70
71
|
# # => <script defer="defer" type="text/javascript">alert('All is good')</script>
|
71
72
|
#
|
@@ -14,7 +14,7 @@ module ActionView
|
|
14
14
|
# unchanged if can't be converted into a valid number.
|
15
15
|
module NumberHelper
|
16
16
|
|
17
|
-
DEFAULT_CURRENCY_VALUES = { :format => "%u%n", :unit => "$", :separator => ".", :delimiter => ",",
|
17
|
+
DEFAULT_CURRENCY_VALUES = { :format => "%u%n", :negative_format => "-%u%n", :unit => "$", :separator => ".", :delimiter => ",",
|
18
18
|
:precision => 2, :significant => false, :strip_insignificant_zeros => false }
|
19
19
|
|
20
20
|
# Raised when argument +number+ param given to the helpers is invalid and
|
@@ -83,15 +83,18 @@ module ActionView
|
|
83
83
|
# in the +options+ hash.
|
84
84
|
#
|
85
85
|
# ==== Options
|
86
|
-
# * <tt>:locale</tt>
|
87
|
-
# * <tt>:precision</tt>
|
88
|
-
# * <tt>:unit</tt>
|
89
|
-
# * <tt>:separator</tt>
|
90
|
-
# * <tt>:delimiter</tt>
|
91
|
-
# * <tt>:format</tt>
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
86
|
+
# * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
|
87
|
+
# * <tt>:precision</tt> - Sets the level of precision (defaults to 2).
|
88
|
+
# * <tt>:unit</tt> - Sets the denomination of the currency (defaults to "$").
|
89
|
+
# * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
|
90
|
+
# * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to ",").
|
91
|
+
# * <tt>:format</tt> - Sets the format for non-negative numbers (defaults to "%u%n").
|
92
|
+
# Fields are <tt>%u</tt> for the currency, and <tt>%n</tt>
|
93
|
+
# for the number.
|
94
|
+
# * <tt>:negative_format</tt> - Sets the format for negative numbers (defaults to prepending
|
95
|
+
# an hyphen to the formatted number given by <tt>:format</tt>).
|
96
|
+
# Accepts the same fields than <tt>:format</tt>, except
|
97
|
+
# <tt>%n</tt> is here the absolute value of the number.
|
95
98
|
#
|
96
99
|
# ==== Examples
|
97
100
|
# number_to_currency(1234567890.50) # => $1,234,567,890.50
|
@@ -99,6 +102,8 @@ module ActionView
|
|
99
102
|
# number_to_currency(1234567890.506, :precision => 3) # => $1,234,567,890.506
|
100
103
|
# number_to_currency(1234567890.506, :locale => :fr) # => 1 234 567 890,506 €
|
101
104
|
#
|
105
|
+
# number_to_currency(1234567890.50, :negative_format => "(%u%n)")
|
106
|
+
# # => ($1,234,567,890.51)
|
102
107
|
# number_to_currency(1234567890.50, :unit => "£", :separator => ",", :delimiter => "")
|
103
108
|
# # => £1234567890,50
|
104
109
|
# number_to_currency(1234567890.50, :unit => "£", :separator => ",", :delimiter => "", :format => "%n %u")
|
@@ -112,11 +117,17 @@ module ActionView
|
|
112
117
|
currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :default => {})
|
113
118
|
|
114
119
|
defaults = DEFAULT_CURRENCY_VALUES.merge(defaults).merge!(currency)
|
120
|
+
defaults[:negative_format] = "-" + options[:format] if options[:format]
|
115
121
|
options = defaults.merge!(options)
|
116
122
|
|
117
123
|
unit = options.delete(:unit)
|
118
124
|
format = options.delete(:format)
|
119
125
|
|
126
|
+
if number.to_f < 0
|
127
|
+
format = options.delete(:negative_format)
|
128
|
+
number = number.respond_to?("abs") ? number.abs : number.sub(/^-/, '')
|
129
|
+
end
|
130
|
+
|
120
131
|
begin
|
121
132
|
value = number_with_precision(number, options.merge(:raise => true))
|
122
133
|
format.gsub(/%n/, value).gsub(/%u/, unit).html_safe
|
@@ -260,7 +271,7 @@ module ActionView
|
|
260
271
|
if number == 0
|
261
272
|
digits, rounded_number = 1, 0
|
262
273
|
else
|
263
|
-
digits = (Math.log10(number) + 1).floor
|
274
|
+
digits = (Math.log10(number.abs) + 1).floor
|
264
275
|
rounded_number = BigDecimal.new((number / 10 ** (digits - precision)).to_s).round.to_f * 10 ** (digits - precision)
|
265
276
|
end
|
266
277
|
precision = precision - digits
|
@@ -459,7 +470,7 @@ module ActionView
|
|
459
470
|
raise ArgumentError, ":units must be a Hash or String translation scope."
|
460
471
|
end.keys.map{|e_name| DECIMAL_UNITS.invert[e_name] }.sort_by{|e| -e}
|
461
472
|
|
462
|
-
number_exponent = Math.log10(number).floor
|
473
|
+
number_exponent = number != 0 ? Math.log10(number.abs).floor : 0
|
463
474
|
display_exponent = unit_exponents.find{|e| number_exponent >= e }
|
464
475
|
number /= 10 ** display_exponent
|
465
476
|
|
@@ -161,7 +161,7 @@ module ActionView
|
|
161
161
|
|
162
162
|
# JavaScriptGenerator generates blocks of JavaScript code that allow you
|
163
163
|
# to change the content and presentation of multiple DOM elements. Use
|
164
|
-
# this in your Ajax response bodies, either in a <script> tag or as plain
|
164
|
+
# this in your Ajax response bodies, either in a <tt>\<script></tt> tag or as plain
|
165
165
|
# JavaScript sent with a Content-type of "text/javascript".
|
166
166
|
#
|
167
167
|
# Create new instances with PrototypeHelper#update_page or with
|
@@ -224,7 +224,7 @@ module ActionView
|
|
224
224
|
#
|
225
225
|
# You can also use PrototypeHelper#update_page_tag instead of
|
226
226
|
# PrototypeHelper#update_page to wrap the generated JavaScript in a
|
227
|
-
# <script> tag.
|
227
|
+
# <tt>\<script></tt> tag.
|
228
228
|
module GeneratorMethods
|
229
229
|
def to_s #:nodoc:
|
230
230
|
(@lines * $/).tap do |javascript|
|
@@ -582,11 +582,11 @@ module ActionView
|
|
582
582
|
JavaScriptGenerator.new(view_context, &block).to_s.html_safe
|
583
583
|
end
|
584
584
|
|
585
|
-
# Works like update_page but wraps the generated JavaScript in a <script>
|
585
|
+
# Works like update_page but wraps the generated JavaScript in a <tt>\<script></tt>
|
586
586
|
# tag. Use this to include generated JavaScript in an ERb template.
|
587
587
|
# See JavaScriptGenerator for more information.
|
588
588
|
#
|
589
|
-
# +html_options+ may be a hash of <script> attributes to be passed
|
589
|
+
# +html_options+ may be a hash of <tt>\<script></tt> attributes to be passed
|
590
590
|
# to ActionView::Helpers::JavaScriptHelper#javascript_tag.
|
591
591
|
def update_page_tag(html_options = {}, &block)
|
592
592
|
javascript_tag update_page(&block), html_options
|
@@ -9,6 +9,24 @@ module ActionView
|
|
9
9
|
# and transforming strings, which can reduce the amount of inline Ruby code in
|
10
10
|
# your views. These helper methods extend Action View making them callable
|
11
11
|
# within your template files.
|
12
|
+
#
|
13
|
+
# ==== Sanitization
|
14
|
+
#
|
15
|
+
# Most text helpers by default sanitize the given content, but do not escape it.
|
16
|
+
# This means HTML tags will appear in the page but all malicious code will be removed.
|
17
|
+
# Let's look at some examples using the +simple_format+ method:
|
18
|
+
#
|
19
|
+
# simple_format('<a href="http://example.com/">Example</a>')
|
20
|
+
# # => "<p><a href=\"http://example.com/\">Example</a></p>"
|
21
|
+
#
|
22
|
+
# simple_format('<a href="javascript:alert('no!')">Example</a>')
|
23
|
+
# # => "<p><a>Example</a></p>"
|
24
|
+
#
|
25
|
+
# If you want to escape all content, you should invoke the +h+ method before
|
26
|
+
# calling the text helper.
|
27
|
+
#
|
28
|
+
# simple_format h('<a href="http://example.com/">Example</a>')
|
29
|
+
# # => "<p><a href=\"http://example.com/\">Example</a></p>"
|
12
30
|
module TextHelper
|
13
31
|
extend ActiveSupport::Concern
|
14
32
|
|
@@ -13,7 +13,7 @@ module ActionView
|
|
13
13
|
module UrlHelper
|
14
14
|
# This helper may be included in any class that includes the
|
15
15
|
# URL helpers of a routes (routes.url_helpers). Some methods
|
16
|
-
# provided here will only work in
|
16
|
+
# provided here will only work in the context of a request
|
17
17
|
# (link_to_unless_current, for instance), which must be provided
|
18
18
|
# as a method called #request on the context.
|
19
19
|
|
@@ -235,13 +235,8 @@ module ActionView
|
|
235
235
|
html_options = convert_options_to_data_attributes(options, html_options)
|
236
236
|
url = url_for(options)
|
237
237
|
|
238
|
-
|
239
|
-
|
240
|
-
href = html_options['href']
|
241
|
-
tag_options = tag_options(html_options)
|
242
|
-
else
|
243
|
-
tag_options = nil
|
244
|
-
end
|
238
|
+
href = html_options['href']
|
239
|
+
tag_options = tag_options(html_options)
|
245
240
|
|
246
241
|
href_attr = "href=\"#{html_escape(url)}\"" unless href
|
247
242
|
"<a #{href_attr}#{tag_options}>#{html_escape(name || url)}</a>".html_safe
|
@@ -269,8 +264,9 @@ module ActionView
|
|
269
264
|
# The +options+ hash accepts the same options as url_for.
|
270
265
|
#
|
271
266
|
# There are a few special +html_options+:
|
272
|
-
# * <tt>:method</tt> -
|
273
|
-
#
|
267
|
+
# * <tt>:method</tt> - Symbol of HTTP verb. Supported verbs are <tt>:post</tt>, <tt>:get</tt>,
|
268
|
+
# <tt>:delete</tt> and <tt>:put</tt>. By default it will be <tt>:post</tt>.
|
269
|
+
# * <tt>:disabled</tt> - If set to true, it will generate a disabled button.
|
274
270
|
# * <tt>:confirm</tt> - This will use the unobtrusive JavaScript driver to
|
275
271
|
# prompt with the question specified. If the user accepts, the link is
|
276
272
|
# processed normally, otherwise no action is taken.
|
@@ -593,6 +589,7 @@ module ActionView
|
|
593
589
|
html_options['data-remote'] = 'true'
|
594
590
|
end
|
595
591
|
|
592
|
+
disable_with = html_options.delete("disable_with")
|
596
593
|
confirm = html_options.delete("confirm")
|
597
594
|
|
598
595
|
if html_options.key?("popup")
|
@@ -601,6 +598,7 @@ module ActionView
|
|
601
598
|
|
602
599
|
method, href = html_options.delete("method"), html_options['href']
|
603
600
|
|
601
|
+
add_disable_with_to_attributes!(html_options, disable_with) if disable_with
|
604
602
|
add_confirm_to_attributes!(html_options, confirm) if confirm
|
605
603
|
add_method_to_attributes!(html_options, method) if method
|
606
604
|
|
@@ -611,6 +609,10 @@ module ActionView
|
|
611
609
|
html_options["data-confirm"] = confirm if confirm
|
612
610
|
end
|
613
611
|
|
612
|
+
def add_disable_with_to_attributes!(html_options, disable_with)
|
613
|
+
html_options["data-disable-with"] = disable_with if disable_with
|
614
|
+
end
|
615
|
+
|
614
616
|
def add_method_to_attributes!(html_options, method)
|
615
617
|
html_options["rel"] = "nofollow" if method && method.to_s.downcase != "get"
|
616
618
|
html_options["data-method"] = method if method
|