actionpack 2.3.2 → 2.3.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.
- data/CHANGELOG +5 -0
- data/Rakefile +10 -9
- data/lib/action_controller.rb +2 -7
- data/lib/action_controller/assertions/response_assertions.rb +11 -3
- data/lib/action_controller/base.rb +7 -2
- data/lib/action_controller/caching.rb +1 -1
- data/lib/action_controller/caching/actions.rb +9 -1
- data/lib/action_controller/caching/sweeper.rb +45 -0
- data/lib/action_controller/caching/sweeping.rb +0 -42
- data/lib/action_controller/failsafe.rb +40 -6
- data/lib/action_controller/flash.rb +11 -3
- data/lib/action_controller/http_authentication.rb +5 -2
- data/lib/action_controller/integration.rb +5 -12
- data/lib/action_controller/middlewares.rb +0 -1
- data/lib/action_controller/reloader.rb +34 -3
- data/lib/action_controller/request.rb +6 -2
- data/lib/action_controller/response.rb +2 -2
- data/lib/action_controller/routing/route_set.rb +2 -1
- data/lib/action_controller/streaming.rb +1 -1
- data/lib/action_controller/test_process.rb +9 -1
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_view/helpers.rb +1 -1
- data/lib/action_view/helpers/asset_tag_helper.rb +21 -9
- data/lib/action_view/helpers/date_helper.rb +2 -2
- data/lib/action_view/helpers/form_helper.rb +25 -12
- data/lib/action_view/helpers/form_options_helper.rb +2 -0
- data/lib/action_view/helpers/form_tag_helper.rb +10 -4
- data/lib/action_view/helpers/number_helper.rb +1 -1
- data/lib/action_view/helpers/prototype_helper.rb +7 -7
- data/lib/action_view/helpers/scriptaculous_helper.rb +5 -5
- data/lib/action_view/helpers/text_helper.rb +3 -3
- data/lib/action_view/helpers/url_helper.rb +1 -1
- data/lib/action_view/paths.rb +1 -1
- data/lib/action_view/template.rb +22 -33
- data/test/abstract_unit.rb +1 -1
- data/test/activerecord/active_record_store_test.rb +3 -3
- data/test/controller/action_pack_assertions_test.rb +27 -0
- data/test/controller/caching_test.rb +39 -0
- data/test/controller/cookie_test.rb +10 -0
- data/test/controller/dispatcher_test.rb +9 -7
- data/test/controller/failsafe_test.rb +60 -0
- data/test/controller/filter_params_test.rb +2 -1
- data/test/controller/flash_test.rb +6 -1
- data/test/controller/http_digest_authentication_test.rb +34 -3
- data/test/controller/integration_test.rb +31 -3
- data/test/controller/redirect_test.rb +4 -1
- data/test/controller/reloader_test.rb +97 -0
- data/test/controller/render_test.rb +19 -9
- data/test/controller/request/multipart_params_parsing_test.rb +1 -62
- data/test/controller/request/test_request_test.rb +35 -0
- data/test/controller/request/url_encoded_params_parsing_test.rb +0 -38
- data/test/controller/request_test.rb +218 -230
- data/test/controller/resources_test.rb +8 -0
- data/test/controller/routing_test.rb +21 -0
- data/test/controller/send_file_test.rb +1 -1
- data/test/controller/session/cookie_store_test.rb +9 -32
- data/test/controller/test_test.rb +8 -0
- data/test/fixtures/failsafe/500.html +1 -0
- data/test/template/active_record_helper_test.rb +1 -1
- data/test/template/asset_tag_helper_test.rb +46 -0
- data/test/template/form_helper_test.rb +117 -6
- data/test/template/form_options_helper_test.rb +22 -0
- data/test/template/form_tag_helper_test.rb +23 -6
- data/test/template/prototype_helper_test.rb +11 -11
- data/test/template/template_test.rb +32 -0
- metadata +20 -63
- data/lib/action_controller/rewindable_input.rb +0 -28
- data/lib/action_controller/vendor/rack-1.0/rack.rb +0 -89
- data/lib/action_controller/vendor/rack-1.0/rack/adapter/camping.rb +0 -22
- data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb +0 -37
- data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb +0 -37
- data/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb +0 -58
- data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb +0 -124
- data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb +0 -51
- data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb +0 -55
- data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb +0 -40
- data/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb +0 -480
- data/lib/action_controller/vendor/rack-1.0/rack/builder.rb +0 -63
- data/lib/action_controller/vendor/rack-1.0/rack/cascade.rb +0 -36
- data/lib/action_controller/vendor/rack-1.0/rack/chunked.rb +0 -49
- data/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb +0 -61
- data/lib/action_controller/vendor/rack-1.0/rack/conditionalget.rb +0 -45
- data/lib/action_controller/vendor/rack-1.0/rack/content_length.rb +0 -29
- data/lib/action_controller/vendor/rack-1.0/rack/content_type.rb +0 -23
- data/lib/action_controller/vendor/rack-1.0/rack/deflater.rb +0 -85
- data/lib/action_controller/vendor/rack-1.0/rack/directory.rb +0 -153
- data/lib/action_controller/vendor/rack-1.0/rack/file.rb +0 -88
- data/lib/action_controller/vendor/rack-1.0/rack/handler.rb +0 -48
- data/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb +0 -61
- data/lib/action_controller/vendor/rack-1.0/rack/handler/evented_mongrel.rb +0 -8
- data/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb +0 -89
- data/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb +0 -55
- data/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb +0 -84
- data/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb +0 -59
- data/lib/action_controller/vendor/rack-1.0/rack/handler/swiftiplied_mongrel.rb +0 -8
- data/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb +0 -18
- data/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb +0 -67
- data/lib/action_controller/vendor/rack-1.0/rack/head.rb +0 -19
- data/lib/action_controller/vendor/rack-1.0/rack/lint.rb +0 -462
- data/lib/action_controller/vendor/rack-1.0/rack/lobster.rb +0 -65
- data/lib/action_controller/vendor/rack-1.0/rack/lock.rb +0 -16
- data/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb +0 -27
- data/lib/action_controller/vendor/rack-1.0/rack/mime.rb +0 -204
- data/lib/action_controller/vendor/rack-1.0/rack/mock.rb +0 -160
- data/lib/action_controller/vendor/rack-1.0/rack/recursive.rb +0 -57
- data/lib/action_controller/vendor/rack-1.0/rack/reloader.rb +0 -64
- data/lib/action_controller/vendor/rack-1.0/rack/request.rb +0 -241
- data/lib/action_controller/vendor/rack-1.0/rack/response.rb +0 -179
- data/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb +0 -142
- data/lib/action_controller/vendor/rack-1.0/rack/session/cookie.rb +0 -91
- data/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb +0 -109
- data/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb +0 -100
- data/lib/action_controller/vendor/rack-1.0/rack/showexceptions.rb +0 -349
- data/lib/action_controller/vendor/rack-1.0/rack/showstatus.rb +0 -106
- data/lib/action_controller/vendor/rack-1.0/rack/static.rb +0 -38
- data/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb +0 -55
- data/lib/action_controller/vendor/rack-1.0/rack/utils.rb +0 -392
@@ -7,7 +7,6 @@ use "ActionController::Failsafe"
|
|
7
7
|
use lambda { ActionController::Base.session_store },
|
8
8
|
lambda { ActionController::Base.session_options }
|
9
9
|
|
10
|
-
use "ActionController::RewindableInput"
|
11
10
|
use "ActionController::ParamsParser"
|
12
11
|
use "Rack::MethodOverride"
|
13
12
|
use "Rack::Head"
|
@@ -1,14 +1,45 @@
|
|
1
1
|
module ActionController
|
2
2
|
class Reloader
|
3
|
+
class BodyWrapper
|
4
|
+
def initialize(body)
|
5
|
+
@body = body
|
6
|
+
end
|
7
|
+
|
8
|
+
def close
|
9
|
+
@body.close if @body.respond_to?(:close)
|
10
|
+
ensure
|
11
|
+
Dispatcher.cleanup_application
|
12
|
+
end
|
13
|
+
|
14
|
+
def method_missing(*args, &block)
|
15
|
+
@body.send(*args, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def respond_to?(symbol, include_private = false)
|
19
|
+
symbol == :close || @body.respond_to?(symbol, include_private)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
3
23
|
def initialize(app)
|
4
24
|
@app = app
|
5
25
|
end
|
6
26
|
|
7
27
|
def call(env)
|
8
28
|
Dispatcher.reload_application
|
9
|
-
@app.call(env)
|
10
|
-
|
11
|
-
|
29
|
+
status, headers, body = @app.call(env)
|
30
|
+
# We do not want to call 'cleanup_application' in an ensure block
|
31
|
+
# because the returned Rack response body may lazily generate its data. This
|
32
|
+
# is for example the case if one calls
|
33
|
+
#
|
34
|
+
# render :text => lambda { ... code here which refers to application models ... }
|
35
|
+
#
|
36
|
+
# in an ActionController.
|
37
|
+
#
|
38
|
+
# Instead, we will want to cleanup the application code after the request is
|
39
|
+
# completely finished. So we wrap the body in a BodyWrapper class so that
|
40
|
+
# when the Rack handler calls #close during the end of the request, we get to
|
41
|
+
# run our cleanup code.
|
42
|
+
[status, headers, BodyWrapper.new(body)]
|
12
43
|
end
|
13
44
|
end
|
14
45
|
end
|
@@ -95,6 +95,10 @@ module ActionController
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
+
def media_type
|
99
|
+
content_type.to_s
|
100
|
+
end
|
101
|
+
|
98
102
|
# Returns the accepted MIME type for the request.
|
99
103
|
def accepts
|
100
104
|
@accepts ||= begin
|
@@ -383,7 +387,7 @@ EOM
|
|
383
387
|
alias_method :params, :parameters
|
384
388
|
|
385
389
|
def path_parameters=(parameters) #:nodoc:
|
386
|
-
@env["
|
390
|
+
@env["action_controller.request.path_parameters"] = parameters
|
387
391
|
@symbolized_path_parameters = @parameters = nil
|
388
392
|
end
|
389
393
|
|
@@ -399,7 +403,7 @@ EOM
|
|
399
403
|
#
|
400
404
|
# See <tt>symbolized_path_parameters</tt> for symbolized keys.
|
401
405
|
def path_parameters
|
402
|
-
@env["
|
406
|
+
@env["action_controller.request.path_parameters"] ||= {}
|
403
407
|
end
|
404
408
|
|
405
409
|
# The request body is an IO input stream. If the RAW_POST_DATA environment
|
@@ -151,8 +151,8 @@ module ActionController # :nodoc:
|
|
151
151
|
if @body.respond_to?(:call)
|
152
152
|
@writer = lambda { |x| callback.call(x) }
|
153
153
|
@body.call(self, self)
|
154
|
-
elsif @body.
|
155
|
-
@body
|
154
|
+
elsif @body.respond_to?(:to_str)
|
155
|
+
yield @body
|
156
156
|
else
|
157
157
|
@body.each(&callback)
|
158
158
|
end
|
@@ -305,6 +305,7 @@ module ActionController
|
|
305
305
|
end
|
306
306
|
|
307
307
|
def add_route(path, options = {})
|
308
|
+
options.each { |k, v| options[k] = v.to_s if [:controller, :action].include?(k) && v.is_a?(Symbol) }
|
308
309
|
route = builder.build(path, options)
|
309
310
|
routes << route
|
310
311
|
route
|
@@ -436,7 +437,7 @@ module ActionController
|
|
436
437
|
def recognize(request)
|
437
438
|
params = recognize_path(request.path, extract_request_environment(request))
|
438
439
|
request.path_parameters = params.with_indifferent_access
|
439
|
-
"#{params[:controller].camelize}Controller".constantize
|
440
|
+
"#{params[:controller].to_s.camelize}Controller".constantize
|
440
441
|
end
|
441
442
|
|
442
443
|
def recognize_path(path, environment={})
|
@@ -161,7 +161,7 @@ module ActionController #:nodoc:
|
|
161
161
|
content_type = content_type.to_s.strip # fixes a problem with extra '\r' with some browsers
|
162
162
|
|
163
163
|
headers.merge!(
|
164
|
-
'Content-Length' => options[:length],
|
164
|
+
'Content-Length' => options[:length].to_s,
|
165
165
|
'Content-Type' => content_type,
|
166
166
|
'Content-Disposition' => disposition,
|
167
167
|
'Content-Transfer-Encoding' => 'binary'
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'rack/session/abstract/id'
|
1
2
|
module ActionController #:nodoc:
|
2
3
|
class TestRequest < Request #:nodoc:
|
3
4
|
attr_accessor :cookies, :session_options
|
@@ -13,6 +14,8 @@ module ActionController #:nodoc:
|
|
13
14
|
|
14
15
|
@query_parameters = {}
|
15
16
|
@session = TestSession.new
|
17
|
+
default_rack_options = Rack::Session::Abstract::ID::DEFAULT_OPTIONS
|
18
|
+
@session_options ||= {:id => generate_sid(default_rack_options[:sidbits])}.merge(default_rack_options)
|
16
19
|
|
17
20
|
initialize_default_values
|
18
21
|
initialize_containers
|
@@ -110,6 +113,7 @@ module ActionController #:nodoc:
|
|
110
113
|
end
|
111
114
|
|
112
115
|
def recycle!
|
116
|
+
@env["action_controller.request.request_parameters"] = {}
|
113
117
|
self.query_parameters = {}
|
114
118
|
self.path_parameters = {}
|
115
119
|
@headers, @request_method, @accepts, @content_type = nil, nil, nil, nil
|
@@ -120,6 +124,10 @@ module ActionController #:nodoc:
|
|
120
124
|
end
|
121
125
|
|
122
126
|
private
|
127
|
+
def generate_sid(sidbits)
|
128
|
+
"%0#{sidbits / 4}x" % rand(2**sidbits - 1)
|
129
|
+
end
|
130
|
+
|
123
131
|
def initialize_containers
|
124
132
|
@cookies = {}
|
125
133
|
end
|
@@ -250,7 +258,7 @@ module ActionController #:nodoc:
|
|
250
258
|
def cookies
|
251
259
|
cookies = {}
|
252
260
|
Array(headers['Set-Cookie']).each do |cookie|
|
253
|
-
key, value = cookie.split(";").first.split("=")
|
261
|
+
key, value = cookie.split(";").first.split("=").map {|val| Rack::Utils.unescape(val)}
|
254
262
|
cookies[key] = value
|
255
263
|
end
|
256
264
|
cookies
|
data/lib/action_pack/version.rb
CHANGED
data/lib/action_view/helpers.rb
CHANGED
@@ -11,7 +11,7 @@ module ActionView #:nodoc:
|
|
11
11
|
autoload :FormHelper, 'action_view/helpers/form_helper'
|
12
12
|
autoload :FormOptionsHelper, 'action_view/helpers/form_options_helper'
|
13
13
|
autoload :FormTagHelper, 'action_view/helpers/form_tag_helper'
|
14
|
-
autoload :
|
14
|
+
autoload :JavaScriptHelper, 'action_view/helpers/javascript_helper'
|
15
15
|
autoload :NumberHelper, 'action_view/helpers/number_helper'
|
16
16
|
autoload :PrototypeHelper, 'action_view/helpers/prototype_helper'
|
17
17
|
autoload :RecordIdentificationHelper, 'action_view/helpers/record_identification_helper'
|
@@ -272,14 +272,17 @@ module ActionView
|
|
272
272
|
# javascript_include_tag :all, :cache => true, :recursive => true
|
273
273
|
def javascript_include_tag(*sources)
|
274
274
|
options = sources.extract_options!.stringify_keys
|
275
|
-
|
275
|
+
concat = options.delete("concat")
|
276
|
+
cache = concat || options.delete("cache")
|
276
277
|
recursive = options.delete("recursive")
|
277
278
|
|
278
|
-
if ActionController::Base.perform_caching && cache
|
279
|
+
if concat || (ActionController::Base.perform_caching && cache)
|
279
280
|
joined_javascript_name = (cache == true ? "all" : cache) + ".js"
|
280
|
-
joined_javascript_path = File.join(JAVASCRIPTS_DIR, joined_javascript_name)
|
281
|
+
joined_javascript_path = File.join(joined_javascript_name[/^#{File::SEPARATOR}/] ? ASSETS_DIR : JAVASCRIPTS_DIR, joined_javascript_name)
|
281
282
|
|
282
|
-
|
283
|
+
unless ActionController::Base.perform_caching && File.exists?(joined_javascript_path)
|
284
|
+
write_asset_file_contents(joined_javascript_path, compute_javascript_paths(sources, recursive))
|
285
|
+
end
|
283
286
|
javascript_src_tag(joined_javascript_name, options)
|
284
287
|
else
|
285
288
|
expand_javascript_sources(sources, recursive).collect { |source| javascript_src_tag(source, options) }.join("\n")
|
@@ -410,16 +413,25 @@ module ActionView
|
|
410
413
|
# The <tt>:recursive</tt> option is also available for caching:
|
411
414
|
#
|
412
415
|
# stylesheet_link_tag :all, :cache => true, :recursive => true
|
416
|
+
#
|
417
|
+
# To force concatenation (even in development mode) set <tt>:concat</tt> to true. This is useful if
|
418
|
+
# you have too many stylesheets for IE to load.
|
419
|
+
#
|
420
|
+
# stylesheet_link_tag :all, :concat => true
|
421
|
+
#
|
413
422
|
def stylesheet_link_tag(*sources)
|
414
423
|
options = sources.extract_options!.stringify_keys
|
415
|
-
|
424
|
+
concat = options.delete("concat")
|
425
|
+
cache = concat || options.delete("cache")
|
416
426
|
recursive = options.delete("recursive")
|
417
427
|
|
418
|
-
if ActionController::Base.perform_caching && cache
|
428
|
+
if concat || (ActionController::Base.perform_caching && cache)
|
419
429
|
joined_stylesheet_name = (cache == true ? "all" : cache) + ".css"
|
420
|
-
joined_stylesheet_path = File.join(STYLESHEETS_DIR, joined_stylesheet_name)
|
430
|
+
joined_stylesheet_path = File.join(joined_stylesheet_name[/^#{File::SEPARATOR}/] ? ASSETS_DIR : STYLESHEETS_DIR, joined_stylesheet_name)
|
421
431
|
|
422
|
-
|
432
|
+
unless ActionController::Base.perform_caching && File.exists?(joined_stylesheet_path)
|
433
|
+
write_asset_file_contents(joined_stylesheet_path, compute_stylesheet_paths(sources, recursive))
|
434
|
+
end
|
423
435
|
stylesheet_tag(joined_stylesheet_name, options)
|
424
436
|
else
|
425
437
|
expand_stylesheet_sources(sources, recursive).collect { |source| stylesheet_tag(source, options) }.join("\n")
|
@@ -679,4 +691,4 @@ module ActionView
|
|
679
691
|
end
|
680
692
|
end
|
681
693
|
end
|
682
|
-
end
|
694
|
+
end
|
@@ -876,8 +876,8 @@ module ActionView
|
|
876
876
|
input_name_from_type(type).gsub(/([\[\(])|(\]\[)/, '_').gsub(/[\]\)]/, '')
|
877
877
|
end
|
878
878
|
|
879
|
-
# Given an ordering of datetime components, create the selection
|
880
|
-
# and join them with their appropriate
|
879
|
+
# Given an ordering of datetime components, create the selection HTML
|
880
|
+
# and join them with their appropriate separators.
|
881
881
|
def build_selects_from_types(order)
|
882
882
|
select = ''
|
883
883
|
order.reverse.each do |type|
|
@@ -493,7 +493,8 @@ module ActionView
|
|
493
493
|
# Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object
|
494
494
|
# assigned to the template (identified by +object+). The text of label will default to the attribute name unless you specify
|
495
495
|
# it explicitly. Additional options on the label tag can be passed as a hash with +options+. These options will be tagged
|
496
|
-
# onto the HTML as an HTML element attribute as in the example shown
|
496
|
+
# onto the HTML as an HTML element attribute as in the example shown, except for the <tt>:value</tt> option, which is designed to
|
497
|
+
# target labels for radio_button tags (where the value is used in the ID of the input tag).
|
497
498
|
#
|
498
499
|
# ==== Examples
|
499
500
|
# label(:post, :title)
|
@@ -505,6 +506,9 @@ module ActionView
|
|
505
506
|
# label(:post, :title, "A short title", :class => "title_label")
|
506
507
|
# # => <label for="post_title" class="title_label">A short title</label>
|
507
508
|
#
|
509
|
+
# label(:post, :privacy, "Public Post", :value => "public")
|
510
|
+
# # => <label for="post_privacy_public">Public Post</label>
|
511
|
+
#
|
508
512
|
def label(object_name, method, text = nil, options = {})
|
509
513
|
InstanceTag.new(object_name, method, self, options.delete(:object)).to_label_tag(text, options)
|
510
514
|
end
|
@@ -720,8 +724,9 @@ module ActionView
|
|
720
724
|
|
721
725
|
def to_label_tag(text = nil, options = {})
|
722
726
|
options = options.stringify_keys
|
727
|
+
tag_value = options.delete("value")
|
723
728
|
name_and_id = options.dup
|
724
|
-
|
729
|
+
add_default_name_and_id_for_value(tag_value, name_and_id)
|
725
730
|
options.delete("index")
|
726
731
|
options["for"] ||= name_and_id["id"]
|
727
732
|
content = (text.blank? ? nil : text.to_s) || method_name.humanize
|
@@ -753,11 +758,7 @@ module ActionView
|
|
753
758
|
checked = self.class.radio_button_checked?(value(object), tag_value)
|
754
759
|
end
|
755
760
|
options["checked"] = "checked" if checked
|
756
|
-
|
757
|
-
options["id"] ||= defined?(@auto_index) ?
|
758
|
-
"#{tag_id_with_index(@auto_index)}_#{pretty_tag_value}" :
|
759
|
-
"#{tag_id}_#{pretty_tag_value}"
|
760
|
-
add_default_name_and_id(options)
|
761
|
+
add_default_name_and_id_for_value(tag_value, options)
|
761
762
|
tag("input", options)
|
762
763
|
end
|
763
764
|
|
@@ -858,6 +859,17 @@ module ActionView
|
|
858
859
|
end
|
859
860
|
|
860
861
|
private
|
862
|
+
def add_default_name_and_id_for_value(tag_value, options)
|
863
|
+
if tag_value
|
864
|
+
pretty_tag_value = tag_value.to_s.gsub(/\s/, "_").gsub(/\W/, "").downcase
|
865
|
+
specified_id = options["id"]
|
866
|
+
add_default_name_and_id(options)
|
867
|
+
options["id"] += "_#{pretty_tag_value}" unless specified_id
|
868
|
+
else
|
869
|
+
add_default_name_and_id(options)
|
870
|
+
end
|
871
|
+
end
|
872
|
+
|
861
873
|
def add_default_name_and_id(options)
|
862
874
|
if options.has_key?("index")
|
863
875
|
options["name"] ||= tag_name_with_index(options["index"])
|
@@ -905,6 +917,7 @@ module ActionView
|
|
905
917
|
attr_accessor :object_name, :object, :options
|
906
918
|
|
907
919
|
def initialize(object_name, object, template, options, proc)
|
920
|
+
@nested_child_index = {}
|
908
921
|
@object_name, @object, @template, @options, @proc = object_name, object, template, options, proc
|
909
922
|
@default_options = @options ? @options.slice(:index) : {}
|
910
923
|
if @object_name.to_s.match(/\[\]$/)
|
@@ -1007,7 +1020,7 @@ module ActionView
|
|
1007
1020
|
explicit_child_index = args.last[:child_index] if args.last.is_a?(Hash)
|
1008
1021
|
|
1009
1022
|
children.map do |child|
|
1010
|
-
fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index}]", child, args, block)
|
1023
|
+
fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, args, block)
|
1011
1024
|
end.join
|
1012
1025
|
else
|
1013
1026
|
fields_for_nested_model(name, explicit_object || association, args, block)
|
@@ -1025,9 +1038,9 @@ module ActionView
|
|
1025
1038
|
end
|
1026
1039
|
end
|
1027
1040
|
|
1028
|
-
def nested_child_index
|
1029
|
-
@nested_child_index ||= -1
|
1030
|
-
@nested_child_index += 1
|
1041
|
+
def nested_child_index(name)
|
1042
|
+
@nested_child_index[name] ||= -1
|
1043
|
+
@nested_child_index[name] += 1
|
1031
1044
|
end
|
1032
1045
|
end
|
1033
1046
|
end
|
@@ -1036,4 +1049,4 @@ module ActionView
|
|
1036
1049
|
cattr_accessor :default_form_builder
|
1037
1050
|
self.default_form_builder = ::ActionView::Helpers::FormBuilder
|
1038
1051
|
end
|
1039
|
-
end
|
1052
|
+
end
|
@@ -230,6 +230,8 @@ module ActionView
|
|
230
230
|
#
|
231
231
|
# NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
|
232
232
|
def options_for_select(container, selected = nil)
|
233
|
+
return container if String === container
|
234
|
+
|
233
235
|
container = container.to_a if Hash === container
|
234
236
|
selected, disabled = extract_selected_and_disabled(selected)
|
235
237
|
|
@@ -230,6 +230,8 @@ module ActionView
|
|
230
230
|
# * <tt>:rows</tt> - Specify the number of rows in the textarea
|
231
231
|
# * <tt>:cols</tt> - Specify the number of columns in the textarea
|
232
232
|
# * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
|
233
|
+
# * <tt>:escape</tt> - By default, the contents of the text input are HTML escaped.
|
234
|
+
# If you need unescaped contents, set this to false.
|
233
235
|
# * Any other key creates standard HTML attributes for the tag.
|
234
236
|
#
|
235
237
|
# ==== Examples
|
@@ -257,7 +259,10 @@ module ActionView
|
|
257
259
|
options["cols"], options["rows"] = size.split("x") if size.respond_to?(:split)
|
258
260
|
end
|
259
261
|
|
260
|
-
|
262
|
+
escape = options.key?("escape") ? options.delete("escape") : true
|
263
|
+
content = html_escape(content) if escape
|
264
|
+
|
265
|
+
content_tag :textarea, content, { "name" => name, "id" => sanitize_to_id(name) }.update(options.stringify_keys)
|
261
266
|
end
|
262
267
|
|
263
268
|
# Creates a check box form input tag.
|
@@ -353,7 +358,8 @@ module ActionView
|
|
353
358
|
disable_with << ";#{options.delete('onclick')}" if options['onclick']
|
354
359
|
|
355
360
|
options["onclick"] = "if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }"
|
356
|
-
options["onclick"] << "else { hiddenCommit =
|
361
|
+
options["onclick"] << "else { hiddenCommit = document.createElement('input');hiddenCommit.type = 'hidden';"
|
362
|
+
options["onclick"] << "hiddenCommit.value = this.value;hiddenCommit.name = this.name;this.form.appendChild(hiddenCommit); }"
|
357
363
|
options["onclick"] << "this.setAttribute('originalValue', this.value);this.disabled = true;#{disable_with};"
|
358
364
|
options["onclick"] << "result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());"
|
359
365
|
options["onclick"] << "if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;"
|
@@ -444,10 +450,10 @@ module ActionView
|
|
444
450
|
''
|
445
451
|
when /^post$/i, "", nil
|
446
452
|
html_options["method"] = "post"
|
447
|
-
protect_against_forgery? ? content_tag(:div, token_tag, :style => 'margin:0;padding:0') : ''
|
453
|
+
protect_against_forgery? ? content_tag(:div, token_tag, :style => 'margin:0;padding:0;display:inline') : ''
|
448
454
|
else
|
449
455
|
html_options["method"] = "post"
|
450
|
-
content_tag(:div, tag(:input, :type => "hidden", :name => "_method", :value => method) + token_tag, :style => 'margin:0;padding:0')
|
456
|
+
content_tag(:div, tag(:input, :type => "hidden", :name => "_method", :value => method) + token_tag, :style => 'margin:0;padding:0;display:inline')
|
451
457
|
end
|
452
458
|
end
|
453
459
|
|
@@ -140,7 +140,7 @@ module ActionView
|
|
140
140
|
# number_with_delimiter(12345678) # => 12,345,678
|
141
141
|
# number_with_delimiter(12345678.05) # => 12,345,678.05
|
142
142
|
# number_with_delimiter(12345678, :delimiter => ".") # => 12.345.678
|
143
|
-
# number_with_delimiter(12345678, :
|
143
|
+
# number_with_delimiter(12345678, :separator => ",") # => 12,345,678
|
144
144
|
# number_with_delimiter(98765432.98, :delimiter => " ", :separator => ",")
|
145
145
|
# # => 98 765 432,98
|
146
146
|
#
|
@@ -686,7 +686,7 @@ module ActionView
|
|
686
686
|
# Returns an object whose <tt>to_json</tt> evaluates to +code+. Use this to pass a literal JavaScript
|
687
687
|
# expression as an argument to another JavaScriptGenerator method.
|
688
688
|
def literal(code)
|
689
|
-
ActiveSupport::JSON::Variable.new(code.to_s)
|
689
|
+
::ActiveSupport::JSON::Variable.new(code.to_s)
|
690
690
|
end
|
691
691
|
|
692
692
|
# Returns a collection reference by finding it through a CSS +pattern+ in the DOM. This collection can then be
|
@@ -973,7 +973,7 @@ module ActionView
|
|
973
973
|
def loop_on_multiple_args(method, ids)
|
974
974
|
record(ids.size>1 ?
|
975
975
|
"#{javascript_object_for(ids)}.each(#{method})" :
|
976
|
-
"#{method}(#{ids.first
|
976
|
+
"#{method}(#{::ActiveSupport::JSON.encode(ids.first)})")
|
977
977
|
end
|
978
978
|
|
979
979
|
def page
|
@@ -997,7 +997,7 @@ module ActionView
|
|
997
997
|
end
|
998
998
|
|
999
999
|
def javascript_object_for(object)
|
1000
|
-
|
1000
|
+
::ActiveSupport::JSON.encode(object)
|
1001
1001
|
end
|
1002
1002
|
|
1003
1003
|
def arguments_for_call(arguments, block = nil)
|
@@ -1139,7 +1139,7 @@ module ActionView
|
|
1139
1139
|
class JavaScriptElementProxy < JavaScriptProxy #:nodoc:
|
1140
1140
|
def initialize(generator, id)
|
1141
1141
|
@id = id
|
1142
|
-
super(generator, "$(#{id
|
1142
|
+
super(generator, "$(#{::ActiveSupport::JSON.encode(id)})")
|
1143
1143
|
end
|
1144
1144
|
|
1145
1145
|
# Allows access of element attributes through +attribute+. Examples:
|
@@ -1211,7 +1211,7 @@ module ActionView
|
|
1211
1211
|
enumerate :eachSlice, :variable => variable, :method_args => [number], :yield_args => %w(value index), :return => true, &block
|
1212
1212
|
else
|
1213
1213
|
add_variable_assignment!(variable)
|
1214
|
-
append_enumerable_function!("eachSlice(#{number
|
1214
|
+
append_enumerable_function!("eachSlice(#{::ActiveSupport::JSON.encode(number)});")
|
1215
1215
|
end
|
1216
1216
|
end
|
1217
1217
|
|
@@ -1232,7 +1232,7 @@ module ActionView
|
|
1232
1232
|
|
1233
1233
|
def pluck(variable, property)
|
1234
1234
|
add_variable_assignment!(variable)
|
1235
|
-
append_enumerable_function!("pluck(#{property
|
1235
|
+
append_enumerable_function!("pluck(#{::ActiveSupport::JSON.encode(property)});")
|
1236
1236
|
end
|
1237
1237
|
|
1238
1238
|
def zip(variable, *arguments, &block)
|
@@ -1296,7 +1296,7 @@ module ActionView
|
|
1296
1296
|
|
1297
1297
|
class JavaScriptElementCollectionProxy < JavaScriptCollectionProxy #:nodoc:\
|
1298
1298
|
def initialize(generator, pattern)
|
1299
|
-
super(generator, "$$(#{pattern
|
1299
|
+
super(generator, "$$(#{::ActiveSupport::JSON.encode(pattern)})")
|
1300
1300
|
end
|
1301
1301
|
end
|
1302
1302
|
end
|