aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/action_controller/metal/compatibility.rb3
-rw-r--r--actionpack/lib/action_controller/metal/hide_actions.rb10
-rw-r--r--actionpack/lib/action_controller/metal/redirecting.rb2
-rw-r--r--actionpack/lib/action_controller/test_case.rb31
-rw-r--r--actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb10
-rw-r--r--actionpack/lib/action_dispatch/http/filter_parameters.rb4
-rw-r--r--actionpack/lib/action_dispatch/http/mime_negotiation.rb4
-rw-r--r--actionpack/lib/action_dispatch/http/request.rb17
-rw-r--r--actionpack/lib/action_dispatch/http/url.rb6
-rw-r--r--actionpack/lib/action_dispatch/middleware/best_standards_support.rb4
-rw-r--r--actionpack/lib/action_dispatch/middleware/params_parser.rb4
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/abstract_store.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/cookie_store.rb11
-rw-r--r--actionpack/lib/action_dispatch/middleware/static.rb3
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb28
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb12
-rw-r--r--actionpack/lib/action_pack/version.rb2
-rw-r--r--actionpack/lib/action_view/helpers/date_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb29
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb4
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/number_helper.rb8
-rw-r--r--actionpack/lib/action_view/helpers/record_tag_helper.rb4
-rw-r--r--actionpack/lib/action_view/lookup_context.rb15
-rw-r--r--actionpack/lib/action_view/renderer/abstract_renderer.rb6
-rw-r--r--actionpack/lib/action_view/renderer/partial_renderer.rb2
-rw-r--r--actionpack/lib/action_view/renderer/template_renderer.rb5
-rw-r--r--actionpack/lib/sprockets/helpers/rails_helper.rb29
28 files changed, 151 insertions, 108 deletions
diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb
index de3354d4f9..9d1ff8cbe4 100644
--- a/actionpack/lib/action_controller/metal/compatibility.rb
+++ b/actionpack/lib/action_controller/metal/compatibility.rb
@@ -58,7 +58,8 @@ module ActionController
end
def method_for_action(action_name)
- super || (respond_to?(:method_missing) && "_handle_method_missing")
+ super || ((self.class.public_method_defined?(:method_missing) ||
+ self.class.protected_method_defined?(:method_missing)) && "_handle_method_missing")
end
end
end
diff --git a/actionpack/lib/action_controller/metal/hide_actions.rb b/actionpack/lib/action_controller/metal/hide_actions.rb
index b55c4643be..1ded166491 100644
--- a/actionpack/lib/action_controller/metal/hide_actions.rb
+++ b/actionpack/lib/action_controller/metal/hide_actions.rb
@@ -27,20 +27,14 @@ module ActionController
self.hidden_actions = hidden_actions.dup.merge(args.map(&:to_s)).freeze
end
- def inherited(klass)
- klass.class_eval { @visible_actions = {} }
- super
- end
-
def visible_action?(action_name)
- return @visible_actions[action_name] if @visible_actions.key?(action_name)
- @visible_actions[action_name] = !hidden_actions.include?(action_name)
+ not hidden_actions.include?(action_name)
end
# Overrides AbstractController::Base#action_methods to remove any methods
# that are listed as hidden methods.
def action_methods
- @action_methods ||= Set.new(super.reject { |name| hidden_actions.include?(name) })
+ @action_methods ||= Set.new(super.reject { |name| hidden_actions.include?(name) }).freeze
end
end
end
diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb
index 9abb86caf8..7630ee2926 100644
--- a/actionpack/lib/action_controller/metal/redirecting.rb
+++ b/actionpack/lib/action_controller/metal/redirecting.rb
@@ -77,7 +77,7 @@ module ActionController
private
def _extract_redirect_to_status(options, response_status)
- status = if options.is_a?(Hash) && options.key?(:status)
+ if options.is_a?(Hash) && options.key?(:status)
Rack::Utils.status_code(options.delete(:status))
elsif response_status.key?(:status)
Rack::Utils.status_code(response_status[:status])
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index b574a36430..e089feea87 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -20,7 +20,12 @@ module ActionController
ActiveSupport::Notifications.subscribe("render_template.action_view") do |name, start, finish, id, payload|
path = payload[:layout]
- @layouts[path] += 1
+ if path
+ @layouts[path] += 1
+ if path =~ /^layouts\/(.*)/
+ @layouts[$1] += 1
+ end
+ end
end
ActiveSupport::Notifications.subscribe("!render_template.action_view") do |name, start, finish, id, payload|
@@ -56,6 +61,15 @@ module ActionController
# # assert that the "new" view template was rendered
# assert_template "new"
#
+ # # assert that the layout 'admin' was rendered
+ # assert_template :layout => 'admin'
+ # assert_template :layout => 'layouts/admin'
+ # assert_template :layout => :admin
+ #
+ # # assert that no layout was rendered
+ # assert_template :layout => nil
+ # assert_template :layout => false
+ #
# # assert that the "_customer" partial was rendered twice
# assert_template :partial => '_customer', :count => 2
#
@@ -70,6 +84,8 @@ module ActionController
#
def assert_template(options = {}, message = nil)
validate_request!
+ # Force body to be read in case the template is being streamed
+ response.body
case options
when NilClass, String, Symbol
@@ -86,17 +102,18 @@ module ActionController
end
end
when Hash
- if expected_layout = options[:layout]
+ if options.key?(:layout)
+ expected_layout = options[:layout]
msg = build_message(message,
"expecting layout <?> but action rendered <?>",
expected_layout, @layouts.keys)
case expected_layout
- when String
- assert(@layouts.keys.include?(expected_layout), msg)
+ when String, Symbol
+ assert(@layouts.keys.include?(expected_layout.to_s), msg)
when Regexp
assert(@layouts.keys.any? {|l| l =~ expected_layout }, msg)
- when nil
+ when nil, false
assert(@layouts.empty?, msg)
end
end
@@ -123,7 +140,7 @@ module ActionController
options[:partial], @partials.keys)
assert(@partials.include?(expected_partial), msg)
end
- else
+ elsif options.key?(:partial)
assert @partials.empty?,
"Expected no partials to be rendered"
end
@@ -458,7 +475,7 @@ module ActionController
parameters ||= {}
controller_class_name = @controller.class.anonymous? ?
"anonymous_controller" :
- @controller.class.name.underscore.sub(/_controller$/, '')
+ @controller.class.controller_path
@request.assign_parameters(@routes, controller_class_name, action.to_s, parameters)
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 af06bffa16..994e11563d 100644
--- a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
+++ b/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
@@ -66,7 +66,7 @@ module HTML
# A regular expression of the valid characters used to separate protocols like
# the ':' in 'http://foo.com'
- self.protocol_separator = /:|(&#0*58)|(&#x70)|(%|&#37;)3A/
+ self.protocol_separator = /:|(&#0*58)|(&#x70)|(&#x0*3a)|(%|&#37;)3A/i
# Specifies a Set of HTML attributes that can have URIs.
self.uri_attributes = Set.new(%w(href src cite action longdesc xlink:href lowsrc))
@@ -110,8 +110,8 @@ module HTML
style = style.to_s.gsub(/url\s*\(\s*[^\s)]+?\s*\)\s*/, ' ')
# gauntlet
- if style !~ /^([:,;#%.\sa-zA-Z0-9!]|\w-\w|\'[\s\w]+\'|\"[\s\w]+\"|\([\d,\s]+\))*$/ ||
- style !~ /^(\s*[-\w]+\s*:\s*[^:;]*(;|$)\s*)*$/
+ if style !~ /\A([:,;#%.\sa-zA-Z0-9!]|\w-\w|\'[\s\w]+\'|\"[\s\w]+\"|\([\d,\s]+\))*\z/ ||
+ style !~ /\A(\s*[-\w]+\s*:\s*[^:;]*(;|$)\s*)*\z/
return ''
end
@@ -122,7 +122,7 @@ module HTML
elsif shorthand_css_properties.include?(prop.split('-')[0].downcase)
unless val.split().any? do |keyword|
!allowed_css_keywords.include?(keyword) &&
- keyword !~ /^(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)$/
+ keyword !~ /\A(#[0-9a-f]+|rgb\(\d+%?,\d*%?,?\d*%?\)?|\d{0,2}\.?\d{0,2}(cm|em|ex|in|mm|pc|pt|px|%|,|\))?)\z/
end
clean << prop + ': ' + val + ';'
end
@@ -171,7 +171,7 @@ module HTML
def contains_bad_protocols?(attr_name, value)
uri_attributes.include?(attr_name) &&
- (value =~ /(^[^\/:]*):|(&#0*58)|(&#x70)|(%|&#37;)3A/ && !allowed_protocols.include?(value.split(protocol_separator).first.downcase))
+ (value =~ /(^[^\/:]*):|(&#0*58)|(&#x70)|(&#x0*3a)|(%|&#37;)3A/i && !allowed_protocols.include?(value.split(protocol_separator).first.downcase.strip))
end
end
end
diff --git a/actionpack/lib/action_dispatch/http/filter_parameters.rb b/actionpack/lib/action_dispatch/http/filter_parameters.rb
index 8dd1af7f3d..d5b9e55139 100644
--- a/actionpack/lib/action_dispatch/http/filter_parameters.rb
+++ b/actionpack/lib/action_dispatch/http/filter_parameters.rb
@@ -26,8 +26,6 @@ module ActionDispatch
module FilterParameters
extend ActiveSupport::Concern
- @@parameter_filter_for = {}
-
# Return a hash of parameters with all sensitive data replaced.
def filtered_parameters
@filtered_parameters ||= parameter_filter.filter(parameters)
@@ -54,7 +52,7 @@ module ActionDispatch
end
def parameter_filter_for(filters)
- @@parameter_filter_for[filters] ||= ParameterFilter.new(filters)
+ ParameterFilter.new(filters)
end
KV_RE = '[^&;=]+'
diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
index 5c48a60469..42f14bc1e9 100644
--- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb
+++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
@@ -98,8 +98,8 @@ module ActionDispatch
BROWSER_LIKE_ACCEPTS = /,\s*\*\/\*|\*\/\*\s*,/
def valid_accept_header
- (xhr? && (accept || content_mime_type)) ||
- (accept && accept !~ BROWSER_LIKE_ACCEPTS)
+ (xhr? && (accept.present? || content_mime_type)) ||
+ (accept.present? && accept !~ BROWSER_LIKE_ACCEPTS)
end
def use_accept_header
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index 0413346d94..31155732d2 100644
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -56,7 +56,12 @@ module ActionDispatch
RFC5789 = %w(PATCH)
HTTP_METHODS = RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC5789
- HTTP_METHOD_LOOKUP = Hash.new { |h, m| h[m] = m.underscore.to_sym if HTTP_METHODS.include?(m) }
+ HTTP_METHOD_LOOKUP = {}
+
+ # Populate the HTTP method lookup cache
+ HTTP_METHODS.each do |method|
+ HTTP_METHOD_LOOKUP[method] = method.underscore.to_sym
+ end
# Returns the HTTP \method that the application should see.
# In the case where the \method was overridden by a middleware
@@ -248,18 +253,14 @@ module ActionDispatch
LOCALHOST.any? { |local_ip| local_ip === remote_addr && local_ip === remote_ip }
end
- protected
-
# Remove nils from the params hash
def deep_munge(hash)
- keys = hash.keys.find_all { |k| hash[k] == [nil] }
- keys.each { |k| hash[k] = nil }
-
- hash.each_value do |v|
+ hash.each do |k, v|
case v
when Array
v.grep(Hash) { |x| deep_munge(x) }
v.compact!
+ hash[k] = nil if v.empty?
when Hash
deep_munge(v)
end
@@ -268,6 +269,8 @@ module ActionDispatch
hash
end
+ protected
+
def parse_query(qs)
deep_munge(super)
end
diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb
index 64459836b5..f07d5adc9b 100644
--- a/actionpack/lib/action_dispatch/http/url.rb
+++ b/actionpack/lib/action_dispatch/http/url.rb
@@ -43,7 +43,11 @@ module ActionDispatch
params = options[:params] || {}
params.reject! {|k,v| v.to_param.nil? }
- rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path)
+ if options[:trailing_slash] && !path.ends_with?('/')
+ rewritten_url << path.sub(/(\?|\z)/) { "/" + $& }
+ else
+ rewritten_url << path
+ end
rewritten_url << "?#{params.to_query}" unless params.empty?
rewritten_url << "##{Journey::Router::Utils.escape_fragment(options[:anchor].to_param.to_s)}" if options[:anchor]
rewritten_url
diff --git a/actionpack/lib/action_dispatch/middleware/best_standards_support.rb b/actionpack/lib/action_dispatch/middleware/best_standards_support.rb
index d338996240..94efeb79fa 100644
--- a/actionpack/lib/action_dispatch/middleware/best_standards_support.rb
+++ b/actionpack/lib/action_dispatch/middleware/best_standards_support.rb
@@ -17,7 +17,9 @@ module ActionDispatch
status, headers, body = @app.call(env)
if headers["X-UA-Compatible"] && @header
- headers["X-UA-Compatible"] << "," << @header.to_s
+ unless headers["X-UA-Compatible"][@header]
+ headers["X-UA-Compatible"] << "," << @header.to_s
+ end
else
headers["X-UA-Compatible"] = @header
end
diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb
index 6ded9dbfed..0e03d85d9a 100644
--- a/actionpack/lib/action_dispatch/middleware/params_parser.rb
+++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb
@@ -38,7 +38,7 @@ module ActionDispatch
when Proc
strategy.call(request.raw_post)
when :xml_simple, :xml_node
- data = Hash.from_xml(request.body.read) || {}
+ data = request.deep_munge(Hash.from_xml(request.body.read) || {})
request.body.rewind if request.body.respond_to?(:rewind)
data.with_indifferent_access
when :yaml
@@ -47,7 +47,7 @@ module ActionDispatch
data = ActiveSupport::JSON.decode(request.body)
request.body.rewind if request.body.respond_to?(:rewind)
data = {:_json => data} unless data.is_a?(Hash)
- data.with_indifferent_access
+ request.deep_munge(data).with_indifferent_access
else
false
end
diff --git a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
index c04fee21dc..cb6d98f09a 100644
--- a/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/abstract_store.rb
@@ -25,6 +25,8 @@ module ActionDispatch
module Compatibility
def initialize(app, options = {})
options[:key] ||= '_session_id'
+ # FIXME Rack's secret is not being used
+ options[:secret] ||= SecureRandom.hex(30)
super
end
diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
index 29e9e6c261..80c596fd51 100644
--- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
@@ -22,15 +22,12 @@ module ActionDispatch
#
# Session options:
#
- # * <tt>:secret</tt>: An application-wide key string or block returning a
- # string called per generated digest. The block is called with the
- # CGI::Session instance as an argument. It's important that the secret
- # is not vulnerable to a dictionary attack. Therefore, you should choose
- # a secret consisting of random numbers and letters and more than 30
- # characters. Examples:
+ # * <tt>:secret</tt>: An application-wide key string. It's important that
+ # the secret is not vulnerable to a dictionary attack. Therefore, you
+ # should choose a secret consisting of random numbers and letters and
+ # more than 30 characters.
#
# :secret => '449fe2e7daee471bffae2fd8dc02313d'
- # :secret => Proc.new { User.current_user.secret_key }
#
# * <tt>:digest</tt>: The message digest algorithm used to verify session
# integrity defaults to 'SHA1' but may be any digest provided by OpenSSL,
diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb
index ad11b6a211..a8d176560c 100644
--- a/actionpack/lib/action_dispatch/middleware/static.rb
+++ b/actionpack/lib/action_dispatch/middleware/static.rb
@@ -5,7 +5,8 @@ module ActionDispatch
def initialize(root, cache_control)
@root = root.chomp('/')
@compiled_root = /^#{Regexp.escape(root)}/
- @file_server = ::Rack::File.new(@root, cache_control)
+ headers = cache_control && { 'Cache-Control' => cache_control }
+ @file_server = ::Rack::File.new(@root, headers)
end
def match?(path)
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 9a474d2e3a..d71b21efc3 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -51,7 +51,6 @@ module ActionDispatch
class Mapping #:nodoc:
IGNORE_OPTIONS = [:to, :as, :via, :on, :constraints, :defaults, :only, :except, :anchor, :shallow, :shallow_path, :shallow_prefix]
ANCHOR_CHARACTERS_REGEX = %r{\A(\\A|\^)|(\\Z|\\z|\$)\Z}
- SHORTHAND_REGEX = %r{/[\w/]+$}
WILDCARD_PATH = %r{\*([^/\)]+)\)?$}
def initialize(set, scope, path, options)
@@ -68,14 +67,7 @@ module ActionDispatch
private
def normalize_options!
- path_without_format = @path.sub(/\(\.:format\)$/, '')
-
- if using_match_shorthand?(path_without_format, @options)
- to_shorthand = @options[:to].blank?
- @options[:to] ||= path_without_format.gsub(/\(.*\)/, "")[1..-1].sub(%r{/([^/]*)$}, '#\1')
- end
-
- @options.merge!(default_controller_and_action(to_shorthand))
+ @options.merge!(default_controller_and_action)
requirements.each do |name, requirement|
# segment_keys.include?(k.to_s) || k == :controller
@@ -153,7 +145,7 @@ module ActionDispatch
end
end
- def default_controller_and_action(to_shorthand=nil)
+ def default_controller_and_action
if to.respond_to?(:call)
{ }
else
@@ -166,7 +158,7 @@ module ActionDispatch
controller ||= default_controller
action ||= default_action
- unless controller.is_a?(Regexp) || to_shorthand
+ unless controller.is_a?(Regexp)
controller = [@scope[:module], controller].compact.join("/").presence
end
@@ -1261,6 +1253,11 @@ module ActionDispatch
paths = [path] + rest
end
+ path_without_format = path.to_s.sub(/\(\.:format\)$/, '')
+ if using_match_shorthand?(path_without_format, options)
+ options[:to] ||= path_without_format.gsub(%r{^/}, "").sub(%r{/([^/]*)$}, '#\1')
+ end
+
options[:anchor] = true unless options.key?(:anchor)
if options[:on] && !VALID_ON_OPTIONS.include?(options[:on])
@@ -1271,6 +1268,10 @@ module ActionDispatch
self
end
+ def using_match_shorthand?(path, options)
+ path && (options[:to] || options[:action]).nil? && path =~ %r{/[\w/]+$}
+ end
+
def decomposed_match(path, options) # :nodoc:
if on = options.delete(:on)
send(on) { decomposed_match(path, options) }
@@ -1288,9 +1289,10 @@ module ActionDispatch
def add_route(action, options) # :nodoc:
path = path_for_action(action, options.delete(:path))
+ action = action.to_s.dup
- if action.to_s =~ /^[\w\/]+$/
- options[:action] ||= action unless action.to_s.include?("/")
+ if action =~ /^[\w\/]+$/
+ options[:action] ||= action unless action.include?("/")
else
action = nil
end
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index a993699e05..6e63f92ff3 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -97,9 +97,7 @@ module ActionDispatch
@routes = {}
@helpers = []
- @module = Module.new do
- instance_methods.each { |selector| remove_method(selector) }
- end
+ @module = Module.new
end
def helper_names
@@ -108,13 +106,11 @@ module ActionDispatch
def clear!
@helpers.each do |helper|
- @module.module_eval do
- remove_possible_method helper
- end
+ @module.remove_possible_method helper
end
- @routes = {}
- @helpers = []
+ @routes.clear
+ @helpers.clear
end
def add(name, route)
diff --git a/actionpack/lib/action_pack/version.rb b/actionpack/lib/action_pack/version.rb
index ab0dd1d618..f319266765 100644
--- a/actionpack/lib/action_pack/version.rb
+++ b/actionpack/lib/action_pack/version.rb
@@ -2,7 +2,7 @@ module ActionPack
module VERSION #:nodoc:
MAJOR = 3
MINOR = 2
- TINY = 9
+ TINY = 13
PRE = nil
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb
index 99aa144d3a..39b9a8d27c 100644
--- a/actionpack/lib/action_view/helpers/date_helper.rb
+++ b/actionpack/lib/action_view/helpers/date_helper.rb
@@ -112,7 +112,7 @@ module ActionView
# english it would read better as about 80 years.
minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year
remainder = (minutes_with_offset % 525600)
- distance_in_years = (minutes_with_offset / 525600)
+ distance_in_years = (minutes_with_offset.div 525600)
if remainder < 131400
locale.t(:about_x_years, :count => distance_in_years)
elsif remainder < 394200
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index d00bad7608..0c079256a3 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -331,9 +331,9 @@ module ActionView
# In many cases you will want to wrap the above in another helper, so you
# could do something like the following:
#
- # def labelled_form_for(record_or_name_or_array, *args, &proc)
+ # def labelled_form_for(record_or_name_or_array, *args, &block)
# options = args.extract_options!
- # form_for(record_or_name_or_array, *(args << options.merge(:builder => LabellingFormBuilder)), &proc)
+ # form_for(record_or_name_or_array, *(args << options.merge(:builder => LabellingFormBuilder)), &block)
# end
#
# If you don't need to attach a form to a model instance, then check out
@@ -355,7 +355,7 @@ module ActionView
# <%= form_for @invoice, :url => external_url, :authenticity_token => false do |f|
# ...
# <% end %>
- def form_for(record, options = {}, &proc)
+ def form_for(record, options = {}, &block)
raise ArgumentError, "Missing block" unless block_given?
options[:html] ||= {}
@@ -374,12 +374,10 @@ module ActionView
options[:html][:method] = options.delete(:method) if options.has_key?(:method)
options[:html][:authenticity_token] = options.delete(:authenticity_token)
- builder = options[:parent_builder] = instantiate_builder(object_name, object, options, &proc)
- fields_for = fields_for(object_name, object, options, &proc)
+ builder = options[:parent_builder] = instantiate_builder(object_name, object, options, &block)
+ output = capture(builder, &block)
default_options = builder.multipart? ? { :multipart => true } : {}
- output = form_tag(options.delete(:url) || {}, default_options.merge!(options.delete(:html)))
- output << fields_for
- output.safe_concat('</form>')
+ form_tag(options.delete(:url) || {}, default_options.merge!(options.delete(:html))) { output }
end
def apply_form_for_options!(object_or_array, options) #:nodoc:
@@ -1198,27 +1196,26 @@ module ActionView
def add_default_name_and_id(options)
if options.has_key?("index")
- options["name"] ||= tag_name_with_index(options["index"])
+ options["name"] ||= tag_name_with_index(options["index"], options["multiple"])
options["id"] = options.fetch("id"){ tag_id_with_index(options["index"]) }
options.delete("index")
elsif defined?(@auto_index)
- options["name"] ||= tag_name_with_index(@auto_index)
+ options["name"] ||= tag_name_with_index(@auto_index, options["multiple"])
options["id"] = options.fetch("id"){ tag_id_with_index(@auto_index) }
else
- options["name"] ||= tag_name
+ options["name"] ||= tag_name(options["multiple"])
options["id"] = options.fetch("id"){ tag_id }
end
- options["name"] += "[]" if options["multiple"]
options["id"] = [options.delete('namespace'), options["id"]].compact.join("_").presence
end
- def tag_name
- "#{@object_name}[#{sanitized_method_name}]"
+ def tag_name(multiple = false)
+ "#{@object_name}[#{sanitized_method_name}]#{"[]" if multiple}"
end
- def tag_name_with_index(index)
- "#{@object_name}[#{index}][#{sanitized_method_name}]"
+ def tag_name_with_index(index, multiple = false)
+ "#{@object_name}[#{index}][#{sanitized_method_name}]#{"[]" if multiple}"
end
def tag_id
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index 623c45fa13..f63a951c33 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -508,9 +508,9 @@ module ActionView
convert_zones = lambda { |list| list.map { |z| [ z.to_s, z.name ] } }
if priority_zones
- if priority_zones.is_a?(Regexp)
+ if priority_zones.is_a?(Regexp)
priority_zones = model.all.find_all {|z| z =~ priority_zones}
- end
+ end
zone_options += options_for_select(convert_zones[priority_zones], selected)
zone_options += "<option value=\"\" disabled=\"disabled\">-------------</option>\n"
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index f0573437ca..7268a9ff9a 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -181,7 +181,7 @@ module ActionView
# # => <label for="name">Name</label>
#
# label_tag 'name', 'Your name'
- # # => <label for="name">Your Name</label>
+ # # => <label for="name">Your name</label>
#
# label_tag 'name', nil, :class => 'small_label'
# # => <label for="name" class="small_label">Name</label>
diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb
index 2f372bd111..ad86d13456 100644
--- a/actionpack/lib/action_view/helpers/number_helper.rb
+++ b/actionpack/lib/action_view/helpers/number_helper.rb
@@ -1,5 +1,7 @@
# encoding: utf-8
+require 'active_support/core_ext/hash/keys'
+require 'active_support/core_ext/hash/reverse_merge'
require 'active_support/core_ext/big_decimal/conversions'
require 'active_support/core_ext/float/rounding'
require 'active_support/core_ext/object/blank'
@@ -358,7 +360,7 @@ module ActionView
end
- STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb].freeze
+ STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb]
# Formats the bytes in +number+ into a more understandable
# representation (e.g., giving it 1500 yields 1.5 KB). This
@@ -450,7 +452,7 @@ module ActionView
end
DECIMAL_UNITS = {0 => :unit, 1 => :ten, 2 => :hundred, 3 => :thousand, 6 => :million, 9 => :billion, 12 => :trillion, 15 => :quadrillion,
- -1 => :deci, -2 => :centi, -3 => :mili, -6 => :micro, -9 => :nano, -12 => :pico, -15 => :femto}.freeze
+ -1 => :deci, -2 => :centi, -3 => :mili, -6 => :micro, -9 => :nano, -12 => :pico, -15 => :femto}
# Pretty prints (formats and approximates) a number in a way it
# is more readable by humans (eg.: 1200000000 becomes "1.2
@@ -591,7 +593,7 @@ module ActionView
unit = case units
when Hash
- units[DECIMAL_UNITS[display_exponent]]
+ units[DECIMAL_UNITS[display_exponent]] || ''
when String, Symbol
I18n.translate(:"#{units}.#{DECIMAL_UNITS[display_exponent]}", :locale => options[:locale], :count => number.to_i)
else
diff --git a/actionpack/lib/action_view/helpers/record_tag_helper.rb b/actionpack/lib/action_view/helpers/record_tag_helper.rb
index aae6389445..709b5d2c17 100644
--- a/actionpack/lib/action_view/helpers/record_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/record_tag_helper.rb
@@ -98,7 +98,9 @@ module ActionView
options, prefix = prefix, nil if prefix.is_a?(Hash)
options = options ? options.dup : {}
options.merge!(:class => "#{dom_class(record, prefix)} #{options[:class]}".strip, :id => dom_id(record, prefix))
- if block.arity == 0
+ if !block_given?
+ content_tag(tag_name, "", options)
+ elsif block.arity == 0
content_tag(tag_name, capture(&block), options)
else
content_tag(tag_name, capture(record, &block), options)
diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb
index 33b508e9b5..1a656ed37f 100644
--- a/actionpack/lib/action_view/lookup_context.rb
+++ b/actionpack/lib/action_view/lookup_context.rb
@@ -44,7 +44,13 @@ module ActionView
module Accessors #:nodoc:
end
- register_detail(:locale) { [I18n.locale, I18n.default_locale].uniq }
+ register_detail(:locale) do
+ locales = [I18n.locale]
+ locales.concat(I18n.fallbacks[I18n.locale]) if I18n.respond_to? :fallbacks
+ locales << I18n.default_locale
+ locales.uniq!
+ locales
+ end
register_detail(:formats) { Mime::SET.symbols }
register_detail(:handlers){ Template::Handlers.extensions }
@@ -97,7 +103,7 @@ module ActionView
# Helpers related to template lookup using the lookup context information.
module ViewPaths
- attr_reader :view_paths
+ attr_reader :view_paths, :html_fallback_for_js
# Whenever setting view paths, makes a copy so we can manipulate then in
# instance objects as we wish.
@@ -194,7 +200,10 @@ module ActionView
def formats=(values)
if values
values.concat(default_formats) if values.delete "*/*"
- values << :html if values == [:js]
+ if values == [:js]
+ values << :html
+ @html_fallback_for_js = true
+ end
end
super(values)
end
diff --git a/actionpack/lib/action_view/renderer/abstract_renderer.rb b/actionpack/lib/action_view/renderer/abstract_renderer.rb
index 0b5d3785d4..b79b89e142 100644
--- a/actionpack/lib/action_view/renderer/abstract_renderer.rb
+++ b/actionpack/lib/action_view/renderer/abstract_renderer.rb
@@ -37,5 +37,11 @@ module ActionView
def instrument(name, options={})
ActiveSupport::Notifications.instrument("render_#{name}.action_view", options){ yield }
end
+
+ def prepend_formats(formats)
+ formats = Array(formats)
+ return if formats.empty? || @lookup_context.html_fallback_for_js
+ @lookup_context.formats = formats | @lookup_context.formats
+ end
end
end
diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb
index 71fa05ab3e..f3300e470b 100644
--- a/actionpack/lib/action_view/renderer/partial_renderer.rb
+++ b/actionpack/lib/action_view/renderer/partial_renderer.rb
@@ -281,6 +281,8 @@ module ActionView
@block = block
@details = extract_details(options)
+ prepend_formats(options[:formats])
+
if String === partial
@object = options[:object]
@path = partial
diff --git a/actionpack/lib/action_view/renderer/template_renderer.rb b/actionpack/lib/action_view/renderer/template_renderer.rb
index a27d5dd1b1..d15e75637a 100644
--- a/actionpack/lib/action_view/renderer/template_renderer.rb
+++ b/actionpack/lib/action_view/renderer/template_renderer.rb
@@ -10,9 +10,10 @@ module ActionView
template = determine_template(options)
context = @lookup_context
+ prepend_formats(template.formats)
+
unless context.rendered_format
- context.formats = template.formats unless template.formats.empty?
- context.rendered_format = context.formats.first
+ context.rendered_format = template.formats.first || formats.last
end
render_template(template, options[:layout], options[:locals])
diff --git a/actionpack/lib/sprockets/helpers/rails_helper.rb b/actionpack/lib/sprockets/helpers/rails_helper.rb
index 690c71b472..243c2e5e50 100644
--- a/actionpack/lib/sprockets/helpers/rails_helper.rb
+++ b/actionpack/lib/sprockets/helpers/rails_helper.rb
@@ -31,7 +31,7 @@ module Sprockets
else
super(source.to_s, { :src => path_to_asset(source, :ext => 'js', :body => body, :digest => digest) }.merge!(options))
end
- end.uniq.join("\n").html_safe
+ end.flatten.uniq.join("\n").html_safe
end
def stylesheet_link_tag(*sources)
@@ -48,7 +48,7 @@ module Sprockets
else
super(source.to_s, { :href => path_to_asset(source, :ext => 'css', :body => body, :protocol => :request, :digest => digest) }.merge!(options))
end
- end.uniq.join("\n").html_safe
+ end.flatten.uniq.join("\n").html_safe
end
def asset_path(source, options = {})
@@ -157,18 +157,25 @@ module Sprockets
end
def rewrite_extension(source, dir, ext)
- source_ext = File.extname(source)
- if ext && source_ext != ".#{ext}"
- if !source_ext.empty? && (asset = asset_environment[source]) &&
- asset.pathname.to_s =~ /#{source}\Z/
- source
- else
- "#{source}.#{ext}"
- end
- else
+ source_ext = File.extname(source)[1..-1]
+
+ if !ext || ext == source_ext
+ source
+ elsif source_ext.blank?
+ "#{source}.#{ext}"
+ elsif File.exists?(source) || exact_match_present?(source)
source
+ else
+ "#{source}.#{ext}"
end
end
+
+ def exact_match_present?(source)
+ pathname = asset_environment.resolve(source)
+ pathname.to_s =~ /#{Regexp.escape(source)}\Z/
+ rescue Sprockets::FileNotFound
+ false
+ end
end
end
end