aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/lib/action_controller/caching/actions.rb4
-rw-r--r--actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb11
-rw-r--r--actionpack/lib/action_dispatch/http/request.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/cookie_store.rb3
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb9
-rw-r--r--actionpack/lib/action_view/helpers/date_helper.rb5
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb12
-rw-r--r--actionpack/lib/action_view/helpers/number_helper.rb1
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb5
-rw-r--r--actionpack/lib/action_view/renderer/partial_renderer.rb10
-rw-r--r--actionpack/test/controller/render_test.rb13
-rw-r--r--actionpack/test/dispatch/routing_test.rb18
-rw-r--r--actionpack/test/fixtures/test/_partial_html_erb.html.erb1
-rw-r--r--actionpack/test/template/form_helper_test.rb20
-rw-r--r--actionpack/test/template/html-scanner/sanitizer_test.rb18
-rw-r--r--actionpack/test/template/number_helper_test.rb1
16 files changed, 117 insertions, 16 deletions
diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb
index f3ec46ce22..59ec197347 100644
--- a/actionpack/lib/action_controller/caching/actions.rb
+++ b/actionpack/lib/action_controller/caching/actions.rb
@@ -170,14 +170,14 @@ module ActionController #:nodoc:
options.reverse_merge!(:format => @extension) if options.is_a?(Hash)
end
- path = controller.url_for(options).split(%r{://}).last
+ path = controller.url_for(options).split('://', 2).last
@path = normalize!(path)
end
private
def normalize!(path)
path << 'index' if path[-1] == ?/
- path << ".#{extension}" if extension and !path.split('?').first.ends_with?(".#{extension}")
+ path << ".#{extension}" if extension and !path.split('?', 2).first.ends_with?(".#{extension}")
URI.parser.unescape(path)
end
end
diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
index 24ffc28710..e9b50ff8ce 100644
--- a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
+++ b/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
@@ -5,6 +5,7 @@ require 'active_support/core_ext/class/attribute'
module HTML
class Sanitizer
def sanitize(text, options = {})
+ validate_options(options)
return text unless sanitizeable?(text)
tokenize(text, options).join
end
@@ -27,6 +28,16 @@ module HTML
def process_node(node, result, options)
result << node.to_s
end
+
+ def validate_options(options)
+ if options[:tags] && !options[:tags].is_a?(Enumerable)
+ raise ArgumentError, "You should pass :tags as an Enumerable"
+ end
+
+ if options[:attributes] && !options[:attributes].is_a?(Enumerable)
+ raise ArgumentError, "You should pass :attributes as an Enumerable"
+ end
+ end
end
class FullSanitizer < Sanitizer
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index 4ac13695bf..796e0dbc45 100644
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -154,7 +154,7 @@ module ActionDispatch
# (case-insensitive). All major JavaScript libraries send this header with
# every Ajax request.
def xml_http_request?
- /XMLHttpRequest/i === @env['HTTP_X_REQUESTED_WITH']
+ @env['HTTP_X_REQUESTED_WITH'] =~ /XMLHttpRequest/i
end
alias :xhr? :xml_http_request?
diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
index 8ebf870b95..a4866f5a8f 100644
--- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
@@ -59,7 +59,8 @@ module ActionDispatch
end
def set_session(env, sid, session_data, options)
- session_data.merge("session_id" => sid)
+ session_data["session_id"] = sid
+ session_data
end
def set_cookie(env, session_id, cookie)
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 29dba6c7aa..fccbff1749 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -880,17 +880,18 @@ module ActionDispatch
# CANONICAL_ACTIONS holds all actions that does not need a prefix or
# a path appended since they fit properly in their scope level.
VALID_ON_OPTIONS = [:new, :collection, :member]
- RESOURCE_OPTIONS = [:as, :controller, :path, :only, :except]
+ RESOURCE_OPTIONS = [:as, :controller, :path, :only, :except, :param]
CANONICAL_ACTIONS = %w(index create new show update destroy)
class Resource #:nodoc:
- attr_reader :controller, :path, :options
+ attr_reader :controller, :path, :options, :param
def initialize(entities, options = {})
@name = entities.to_s
@path = (options[:path] || @name).to_s
@controller = (options[:controller] || @name).to_s
@as = options[:as]
+ @param = options[:param] || :id
@options = options
end
@@ -935,7 +936,7 @@ module ActionDispatch
alias :collection_scope :path
def member_scope
- "#{path}/:id"
+ "#{path}/:#{param}"
end
def new_scope(new_path)
@@ -943,7 +944,7 @@ module ActionDispatch
end
def nested_scope
- "#{path}/:#{singular}_id"
+ "#{path}/:#{singular}_#{param}"
end
end
diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb
index 2bfc6371f5..45e5a862b6 100644
--- a/actionpack/lib/action_view/helpers/date_helper.rb
+++ b/actionpack/lib/action_view/helpers/date_helper.rb
@@ -977,7 +977,10 @@ module ActionView
# Returns the id attribute for the input tag.
# => "post_written_on_1i"
def input_id_from_type(type)
- input_name_from_type(type).gsub(/([\[\(])|(\]\[)/, '_').gsub(/[\]\)]/, '')
+ id = input_name_from_type(type).gsub(/([\[\(])|(\]\[)/, '_').gsub(/[\]\)]/, '')
+ id = @options[:namespace] + '_' + id if @options[:namespace]
+
+ id
end
# Given an ordering of datetime components, create the selection HTML
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 43d5cf1471..6219a7a924 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -9,6 +9,7 @@ require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/string/output_safety'
require 'active_support/core_ext/array/extract_options'
+require 'active_support/deprecation'
module ActionView
# = Action View Form Helpers
@@ -22,7 +23,7 @@ module ActionView
# being routed to the appropriate controller action (with the appropriate <tt>:id</tt>
# parameter in the case of an existing resource), (ii) input fields should
# be named in such a way that in the controller their values appear in the
- # appropriate places within the +params+ hash, and (iii) for an existing record,
+ # appropriate places within the +params+ hash, and (iii) for an existing record,
# when the form is initially displayed, input fields corresponding to attributes
# of the resource should show the current values of those attributes.
#
@@ -156,7 +157,7 @@ module ActionView
# if <tt>:person</tt> also happens to be the name of an instance variable
# <tt>@person</tt>, the default value of the field shown when the form is
# initially displayed (e.g. in the situation where you are editing an
- # existing record) will be the value of the corresponding attribute of
+ # existing record) will be the value of the corresponding attribute of
# <tt>@person</tt>.
#
# The rightmost argument to +form_for+ is an
@@ -1057,7 +1058,12 @@ module ActionView
self
end
- def initialize(object_name, object, template, options)
+ def initialize(object_name, object, template, options, block=nil)
+ if block
+ ActiveSupport::Deprecation.warn(
+ "Giving a block to FormBuilder is deprecated and has no effect anymore.")
+ end
+
@nested_child_index = {}
@object_name, @object, @template, @options = object_name, object, template, options
@parent_builder = options[:parent_builder]
diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb
index b0860f87c4..485a9357be 100644
--- a/actionpack/lib/action_view/helpers/number_helper.rb
+++ b/actionpack/lib/action_view/helpers/number_helper.rb
@@ -292,6 +292,7 @@ module ActionView
precision = precision > 0 ? precision : 0 #don't let it be negative
else
rounded_number = BigDecimal.new(number.to_s).round(precision).to_f
+ rounded_number = rounded_number.zero? ? rounded_number.abs : rounded_number #prevent showing negative zeros
end
formatted_number = number_with_delimiter("%01.#{precision}f" % rounded_number, options)
if strip_insignificant_zeros
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index 29f556502b..4a641fada3 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -334,7 +334,7 @@ module ActionView
remote = html_options.delete('remote')
method = html_options.delete('method').to_s
- method_tag = %w{patch put delete}.include?(method) ? method_tag(method) : ""
+ method_tag = %w{patch put delete}.include?(method) ? method_tag(method) : ''.html_safe
form_method = method == 'get' ? 'get' : 'post'
form_options = html_options.delete('form') || {}
@@ -347,7 +347,8 @@ module ActionView
html_options = convert_options_to_data_attributes(options, html_options)
html_options.merge!("type" => "submit", "value" => name || url)
- "#{tag(:form, form_options, true)}<div>#{method_tag}#{tag("input", html_options)}#{request_token_tag}</div></form>".html_safe
+ inner_tags = method_tag.safe_concat tag('input', html_options).safe_concat request_token_tag
+ content_tag('form', content_tag('div', inner_tags), form_options)
end
diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb
index 232667ec01..d4c652c0d1 100644
--- a/actionpack/lib/action_view/renderer/partial_renderer.rb
+++ b/actionpack/lib/action_view/renderer/partial_renderer.rb
@@ -257,6 +257,14 @@ module ActionView
setup(context, options, block)
identifier = (@template = find_partial) ? @template.identifier : @path
+ @lookup_context.rendered_format ||= begin
+ if @template && @template.formats.present?
+ @template.formats.first
+ else
+ formats.first
+ end
+ end
+
if @collection
instrument(:collection, :identifier => identifier || "collection", :count => @collection.size) do
render_collection
@@ -316,8 +324,6 @@ module ActionView
@block = block
@details = extract_details(options)
- @lookup_context.rendered_format ||= formats.first
-
if String === partial
@object = options[:object]
@path = partial
diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb
index 09d9e65d38..e1f9b7dc9c 100644
--- a/actionpack/test/controller/render_test.rb
+++ b/actionpack/test/controller/render_test.rb
@@ -553,6 +553,10 @@ class TestController < ActionController::Base
render :partial => 'partial'
end
+ def partial_html_erb
+ render :partial => 'partial_html_erb'
+ end
+
def render_to_string_with_partial
@partial_only = render_to_string :partial => "partial_only"
@partial_with_locals = render_to_string :partial => "customer", :locals => { :customer => Customer.new("david") }
@@ -1272,6 +1276,15 @@ class RenderTest < ActionController::TestCase
assert_equal "text/html", @response.content_type
end
+ def test_render_html_formatted_partial_even_with_other_mime_time_in_accept
+ @request.accept = "text/javascript, text/html"
+
+ get :partial_html_erb
+
+ assert_equal "partial.html.erb", @response.body.strip
+ assert_equal "text/html", @response.content_type
+ end
+
def test_should_render_html_partial_with_formats
get :partial_formats_html
assert_equal "partial html", @response.body
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index 700666600b..cc4279d9dd 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -475,6 +475,11 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
get :preview, :on => :member
end
+ resources :profiles, :param => :username do
+ get :details, :on => :member
+ resources :messages
+ end
+
scope :as => "routes" do
get "/c/:id", :as => :collision, :to => "collision#show"
get "/collision", :to => "collision#show"
@@ -2183,6 +2188,19 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
assert_equal "/posts/1/admin", post_admin_root_path(:post_id => '1')
end
+ def test_custom_param
+ get '/profiles/bob'
+ assert_equal 'profiles#show', @response.body
+ assert_equal 'bob', @request.params[:username]
+
+ get '/profiles/bob/details'
+ assert_equal 'bob', @request.params[:username]
+
+ get '/profiles/bob/messages/34'
+ assert_equal 'bob', @request.params[:profile_username]
+ assert_equal '34', @request.params[:id]
+ end
+
private
def with_https
old_https = https?
diff --git a/actionpack/test/fixtures/test/_partial_html_erb.html.erb b/actionpack/test/fixtures/test/_partial_html_erb.html.erb
new file mode 100644
index 0000000000..4b54875782
--- /dev/null
+++ b/actionpack/test/fixtures/test/_partial_html_erb.html.erb
@@ -0,0 +1 @@
+<%= "partial.html.erb" %>
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index 2bdb54bd5e..c5a32635f8 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -1063,6 +1063,14 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
+ def test_form_for_with_namespace_with_date_select
+ form_for(@post, :namespace => 'namespace') do |f|
+ concat f.date_select(:written_on)
+ end
+
+ assert_select 'select#namespace_post_written_on_1i'
+ end
+
def test_form_for_with_namespace_with_label
form_for(@post, :namespace => 'namespace') do |f|
concat f.label(:title)
@@ -2223,6 +2231,18 @@ class FormHelperTest < ActionView::TestCase
assert_equal "fields", output
end
+ def test_form_builder_block_argument_deprecation
+ builder_class = Class.new(ActionView::Helpers::FormBuilder) do
+ def initialize(object_name, object, template, options, block)
+ super
+ end
+ end
+
+ assert_deprecated(/Giving a block to FormBuilder is deprecated and has no effect anymore/) do
+ builder_class.new(:foo, nil, nil, {}, proc {})
+ end
+ end
+
protected
def hidden_fields(method = nil)
diff --git a/actionpack/test/template/html-scanner/sanitizer_test.rb b/actionpack/test/template/html-scanner/sanitizer_test.rb
index 32c655c5fd..324caef224 100644
--- a/actionpack/test/template/html-scanner/sanitizer_test.rb
+++ b/actionpack/test/template/html-scanner/sanitizer_test.rb
@@ -125,6 +125,24 @@ class SanitizerTest < ActionController::TestCase
assert_equal(text, sanitizer.sanitize(text, :attributes => ['foo']))
end
+ def test_should_raise_argument_error_if_tags_is_not_enumerable
+ sanitizer = HTML::WhiteListSanitizer.new
+ e = assert_raise(ArgumentError) do
+ sanitizer.sanitize('', :tags => 'foo')
+ end
+
+ assert_equal "You should pass :tags as an Enumerable", e.message
+ end
+
+ def test_should_raise_argument_error_if_attributes_is_not_enumerable
+ sanitizer = HTML::WhiteListSanitizer.new
+ e = assert_raise(ArgumentError) do
+ sanitizer.sanitize('', :attributes => 'foo')
+ end
+
+ assert_equal "You should pass :attributes as an Enumerable", e.message
+ end
+
[%w(img src), %w(a href)].each do |(tag, attr)|
define_method "test_should_strip_#{attr}_attribute_in_#{tag}_with_bad_protocols" do
assert_sanitized %(<#{tag} #{attr}="javascript:bang" title="1">boo</#{tag}>), %(<#{tag} title="1">boo</#{tag}>)
diff --git a/actionpack/test/template/number_helper_test.rb b/actionpack/test/template/number_helper_test.rb
index 482d953907..5c6f23d70b 100644
--- a/actionpack/test/template/number_helper_test.rb
+++ b/actionpack/test/template/number_helper_test.rb
@@ -96,6 +96,7 @@ class NumberHelperTest < ActionView::TestCase
assert_equal("0.001", number_with_precision(0.00111, :precision => 3))
assert_equal("10.00", number_with_precision(9.995, :precision => 2))
assert_equal("11.00", number_with_precision(10.995, :precision => 2))
+ assert_equal("0.00", number_with_precision(-0.001, :precision => 2))
end
def test_number_with_precision_with_custom_delimiter_and_separator