aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/abstract_controller/callbacks.rb32
-rw-r--r--actionpack/lib/action_controller/metal/mime_responds.rb2
-rw-r--r--actionpack/lib/action_controller/metal/testing.rb9
-rw-r--r--actionpack/lib/action_controller/test_case.rb5
-rw-r--r--actionpack/lib/action_dispatch/http/request.rb21
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb5
-rw-r--r--actionpack/lib/action_dispatch/routing/route.rb3
-rw-r--r--actionpack/lib/action_dispatch/testing/test_process.rb2
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb8
-rw-r--r--actionpack/lib/action_view/helpers/capture_helper.rb3
-rw-r--r--actionpack/lib/action_view/helpers/date_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb24
-rw-r--r--actionpack/lib/action_view/helpers/number_helper.rb31
-rw-r--r--actionpack/lib/action_view/renderer/partial_renderer.rb7
-rw-r--r--actionpack/lib/action_view/template/handlers/erb.rb7
15 files changed, 104 insertions, 57 deletions
diff --git a/actionpack/lib/abstract_controller/callbacks.rb b/actionpack/lib/abstract_controller/callbacks.rb
index 7b0d80614d..f169ab7c3a 100644
--- a/actionpack/lib/abstract_controller/callbacks.rb
+++ b/actionpack/lib/abstract_controller/callbacks.rb
@@ -81,27 +81,29 @@ module AbstractController
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
# Append a before, after or around filter. See _insert_callbacks
# for details on the allowed parameters.
- def #{filter}_filter(*names, &blk) # def before_filter(*names, &blk)
- _insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options}
- set_callback(:process_action, :#{filter}, name, options) # set_callback(:process_action, :before_filter, name, options)
- end # end
- end # end
+ def #{filter}_filter(*names, &blk)
+ _insert_callbacks(names, blk) do |name, options|
+ options[:if] = (Array.wrap(options[:if]) << "!halted") if #{filter == :after}
+ set_callback(:process_action, :#{filter}, name, options)
+ end
+ end
# Prepend a before, after or around filter. See _insert_callbacks
# for details on the allowed parameters.
- def prepend_#{filter}_filter(*names, &blk) # def prepend_before_filter(*names, &blk)
- _insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
- set_callback(:process_action, :#{filter}, name, options.merge(:prepend => true)) # set_callback(:process_action, :before, name, options.merge(:prepend => true))
- end # end
- end # end
+ def prepend_#{filter}_filter(*names, &blk)
+ _insert_callbacks(names, blk) do |name, options|
+ options[:if] = (Array.wrap(options[:if]) << "!halted") if #{filter == :after}
+ set_callback(:process_action, :#{filter}, name, options.merge(:prepend => true))
+ end
+ end
# Skip a before, after or around filter. See _insert_callbacks
# for details on the allowed parameters.
- def skip_#{filter}_filter(*names, &blk) # def skip_before_filter(*names, &blk)
- _insert_callbacks(names, blk) do |name, options| # _insert_callbacks(names, blk) do |name, options|
- skip_callback(:process_action, :#{filter}, name, options) # skip_callback(:process_action, :before, name, options)
- end # end
- end # end
+ def skip_#{filter}_filter(*names, &blk)
+ _insert_callbacks(names, blk) do |name, options|
+ skip_callback(:process_action, :#{filter}, name, options)
+ end
+ end
# *_filter is the same as append_*_filter
alias_method :append_#{filter}_filter, :#{filter}_filter
diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb
index c6d4c6d936..f7dd0dcb69 100644
--- a/actionpack/lib/action_controller/metal/mime_responds.rb
+++ b/actionpack/lib/action_controller/metal/mime_responds.rb
@@ -227,7 +227,7 @@ module ActionController #:nodoc:
"controller responds to in the class level" if self.class.mimes_for_respond_to.empty?
if response = retrieve_response_from_mimes(&block)
- options = resources.extract_options!
+ options = resources.size == 1 ? {} : resources.extract_options!
options.merge!(:default_response => response)
(options.delete(:responder) || self.class.responder).call(self, resources, options)
end
diff --git a/actionpack/lib/action_controller/metal/testing.rb b/actionpack/lib/action_controller/metal/testing.rb
index 4b8c452d50..f4efeb33ba 100644
--- a/actionpack/lib/action_controller/metal/testing.rb
+++ b/actionpack/lib/action_controller/metal/testing.rb
@@ -14,18 +14,9 @@ module ActionController
cookies.write(@_response)
end
@_response.prepare!
- set_test_assigns
ret
end
- def set_test_assigns
- @assigns = {}
- (instance_variable_names - self.class.protected_instance_variables).each do |var|
- name, value = var[1..-1], instance_variable_get(var)
- @assigns[name] = value
- end
- end
-
# TODO : Rewrite tests using controller.headers= to use Rack env
def headers=(new_headers)
@_response ||= ActionDispatch::Response.new
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index 0c26071379..2b2f647d32 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -411,8 +411,9 @@ module ActionController
@controller.request = @request
@controller.params.merge!(parameters)
build_request_uri(action, parameters)
- Base.class_eval { include Testing }
+ @controller.class.class_eval { include Testing }
@controller.process_with_new_base_test(@request, @response)
+ @assigns = @controller.respond_to?(:view_assigns) ? @controller.view_assigns : {}
@request.session.delete('flash') if @request.session['flash'].blank?
@response
end
@@ -448,7 +449,7 @@ module ActionController
def build_request_uri(action, parameters)
unless @request.env["PATH_INFO"]
- options = @controller.__send__(:url_options).merge(parameters)
+ options = @controller.respond_to?(:url_options) ? @controller.__send__(:url_options).merge(parameters) : parameters
options.update(
:only_path => true,
:action => action,
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index 55a3166f6d..08f30e068d 100644
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -4,6 +4,7 @@ require 'strscan'
require 'active_support/core_ext/hash/indifferent_access'
require 'active_support/core_ext/string/access'
+require 'active_support/inflector'
require 'action_dispatch/http/headers'
module ActionDispatch
@@ -44,8 +45,24 @@ module ActionDispatch
@env.key?(key)
end
- HTTP_METHODS = %w(get head put post delete options)
- HTTP_METHOD_LOOKUP = HTTP_METHODS.inject({}) { |h, m| h[m] = h[m.upcase] = m.to_sym; h }
+ # List of HTTP request methods from the following RFCs:
+ # Hypertext Transfer Protocol -- HTTP/1.1 (http://www.ietf.org/rfc/rfc2616.txt)
+ # HTTP Extensions for Distributed Authoring -- WEBDAV (http://www.ietf.org/rfc/rfc2518.txt)
+ # Versioning Extensions to WebDAV (http://www.ietf.org/rfc/rfc3253.txt)
+ # Ordered Collections Protocol (WebDAV) (http://www.ietf.org/rfc/rfc3648.txt)
+ # Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol (http://www.ietf.org/rfc/rfc3744.txt)
+ # Web Distributed Authoring and Versioning (WebDAV) SEARCH (http://www.ietf.org/rfc/rfc5323.txt)
+ # PATCH Method for HTTP (http://www.ietf.org/rfc/rfc5789.txt)
+ RFC2616 = %w(OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT)
+ RFC2518 = %w(PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK)
+ RFC3253 = %w(VERSION-CONTROL REPORT CHECKOUT CHECKIN UNCHECKOUT MKWORKSPACE UPDATE LABEL MERGE BASELINE-CONTROL MKACTIVITY)
+ RFC3648 = %w(ORDERPATCH)
+ RFC3744 = %w(ACL)
+ RFC5323 = %w(SEARCH)
+ 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) }
# Returns the HTTP \method that the application should see.
# In the case where the \method was overridden by a middleware
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 2eb2af7a11..63a22ad105 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -1,6 +1,7 @@
require 'erb'
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/object/blank'
+require 'active_support/inflector'
module ActionDispatch
module Routing
@@ -186,8 +187,8 @@ module ActionDispatch
def request_method_condition
if via = @options[:via]
- via = Array(via).map { |m| m.to_s.upcase }
- { :request_method => Regexp.union(*via) }
+ via = Array(via).map { |m| m.to_s.dasherize.upcase }
+ { :request_method => %r[^#{via.join('|')}$] }
else
{ }
end
diff --git a/actionpack/lib/action_dispatch/routing/route.rb b/actionpack/lib/action_dispatch/routing/route.rb
index f91a48e16c..08a8408f25 100644
--- a/actionpack/lib/action_dispatch/routing/route.rb
+++ b/actionpack/lib/action_dispatch/routing/route.rb
@@ -30,7 +30,8 @@ module ActionDispatch
if method = conditions[:request_method]
case method
when Regexp
- method.source.upcase
+ source = method.source.upcase
+ source =~ /\A\^[-A-Z|]+\$\Z/ ? source[1..-2] : source
else
method.to_s.upcase
end
diff --git a/actionpack/lib/action_dispatch/testing/test_process.rb b/actionpack/lib/action_dispatch/testing/test_process.rb
index c56ebc6438..16f3674164 100644
--- a/actionpack/lib/action_dispatch/testing/test_process.rb
+++ b/actionpack/lib/action_dispatch/testing/test_process.rb
@@ -22,7 +22,7 @@ module ActionDispatch
end
def cookies
- @request.cookies.merge(@response.cookies)
+ HashWithIndifferentAccess.new(@request.cookies.merge(@response.cookies))
end
def redirect_to_url
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index a728fde748..db5f5f301a 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -878,7 +878,7 @@ module ActionView
end
def join_asset_file_contents(paths)
- paths.collect { |path| File.read(asset_file_path!(path)) }.join("\n\n")
+ paths.collect { |path| File.read(asset_file_path!(path, true)) }.join("\n\n")
end
def write_asset_file_contents(joined_asset_path, asset_paths)
@@ -896,8 +896,10 @@ module ActionView
File.join(config.assets_dir, path.split('?').first)
end
- def asset_file_path!(path)
- unless is_uri?(path)
+ def asset_file_path!(path, error_if_file_is_uri = false)
+ if is_uri?(path)
+ raise(Errno::ENOENT, "Asset file #{path} is uri and cannot be merged into single file") if error_if_file_is_uri
+ else
absolute_path = asset_file_path(path)
raise(Errno::ENOENT, "Asset file not found at '#{absolute_path}'" ) unless File.exist?(absolute_path)
return absolute_path
diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb
index 0401e6a09b..c88bd1efd5 100644
--- a/actionpack/lib/action_view/helpers/capture_helper.rb
+++ b/actionpack/lib/action_view/helpers/capture_helper.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/object/blank'
+require 'active_support/core_ext/string/output_safety'
module ActionView
# = Action View Capture Helper
@@ -38,7 +39,7 @@ module ActionView
value = nil
buffer = with_output_buffer { value = yield(*args) }
if string = buffer.presence || value and string.is_a?(String)
- string
+ ERB::Util.html_escape string
end
end
diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb
index c1214bc44e..875ec9b77b 100644
--- a/actionpack/lib/action_view/helpers/date_helper.rb
+++ b/actionpack/lib/action_view/helpers/date_helper.rb
@@ -882,6 +882,8 @@ module ActionView
# Returns the separator for a given datetime component
def separator(type)
case type
+ when :year
+ @options[:discard_year] ? "" : @options[:date_separator]
when :month
@options[:discard_month] ? "" : @options[:date_separator]
when :day
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index d6e175c7e8..8c300ec745 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -112,6 +112,7 @@ module ActionView
# <%= f.text_field :version %><br />
# <%= f.label :author, 'Author' %>:
# <%= f.text_field :author %><br />
+ # <%= f.submit %>
# <% end %>
#
# There, +form_for+ is able to generate the rest of RESTful form
@@ -129,6 +130,7 @@ module ActionView
# Last name : <%= f.text_field :last_name %><br />
# Biography : <%= f.text_area :biography %><br />
# Admin? : <%= f.check_box :admin %><br />
+ # <%= f.submit %>
# <% end %>
#
# There, the argument is a symbol or string with the name of the
@@ -160,6 +162,7 @@ module ActionView
# Last name : <%= f.text_field :last_name %>
# Biography : <%= text_area :person, :biography %>
# Admin? : <%= check_box_tag "person[admin]", @person.company.admin? %>
+ # <%= f.submit %>
# <% end %>
#
# This also works for the methods in FormOptionHelper and DateHelper that
@@ -269,8 +272,9 @@ module ActionView
# <%= form_for @person, :url => { :action => "create" }, :builder => LabellingFormBuilder do |f| %>
# <%= f.text_field :first_name %>
# <%= f.text_field :last_name %>
- # <%= text_area :person, :biography %>
- # <%= check_box_tag "person[admin]", @person.company.admin? %>
+ # <%= f.text_area :biography %>
+ # <%= f.check_box :admin %>
+ # <%= f.submit %>
# <% end %>
#
# In this case, if you use this:
@@ -294,10 +298,9 @@ module ActionView
#
# If you don't need to attach a form to a model instance, then check out
# FormTagHelper#form_tag.
- def form_for(record, options = nil, &proc)
+ def form_for(record, options = {}, &proc)
raise ArgumentError, "Missing block" unless block_given?
- options ||= {}
options[:html] ||= {}
case record
@@ -348,6 +351,8 @@ module ActionView
# <%= fields_for @person.permission do |permission_fields| %>
# Admin? : <%= permission_fields.check_box :admin %>
# <% end %>
+ #
+ # <%= f.submit %>
# <% end %>
#
# ...or if you have an object that needs to be represented as a different
@@ -409,6 +414,7 @@ module ActionView
# Street : <%= address_fields.text_field :street %>
# Zip code: <%= address_fields.text_field :zip_code %>
# <% end %>
+ # ...
# <% end %>
#
# When address is already an association on a Person you can use
@@ -438,6 +444,7 @@ module ActionView
# ...
# Delete: <%= address_fields.check_box :_destroy %>
# <% end %>
+ # ...
# <% end %>
#
# ==== One-to-many
@@ -467,6 +474,7 @@ module ActionView
# Name: <%= project_fields.text_field :name %>
# <% end %>
# <% end %>
+ # ...
# <% end %>
#
# It's also possible to specify the instance to be used:
@@ -480,6 +488,7 @@ module ActionView
# <% end %>
# <% end %>
# <% end %>
+ # ...
# <% end %>
#
# Or a collection to be used:
@@ -489,6 +498,7 @@ module ActionView
# <%= person_form.fields_for :projects, @active_projects do |project_fields| %>
# Name: <%= project_fields.text_field :name %>
# <% end %>
+ # ...
# <% end %>
#
# When projects is already an association on Person you can use
@@ -518,6 +528,7 @@ module ActionView
# <%= person_form.fields_for :projects do |project_fields| %>
# Delete: <%= project_fields.check_box :_destroy %>
# <% end %>
+ # ...
# <% end %>
def fields_for(record, record_object = nil, options = nil, &block)
capture(instantiate_builder(record, record_object, options, &block), &block)
@@ -1206,6 +1217,7 @@ module ActionView
self.multipart = true
@template.file_field(@object_name, method, objectify_options(options))
end
+
# Add the submit button for the given form. When no value is given, it checks
# if the object is a new resource or not to create the proper label:
#
@@ -1278,11 +1290,11 @@ module ActionView
if association.respond_to?(:persisted?)
association = [association] if @object.send(association_name).is_a?(Array)
- elsif !association.is_a?(Array)
+ elsif !association.respond_to?(:to_ary)
association = @object.send(association_name)
end
- if association.is_a?(Array)
+ if association.respond_to?(:to_ary)
explicit_child_index = options[:child_index]
output = ActiveSupport::SafeBuffer.new
association.each do |child|
diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb
index 1488e72c6e..a9400c347f 100644
--- a/actionpack/lib/action_view/helpers/number_helper.rb
+++ b/actionpack/lib/action_view/helpers/number_helper.rb
@@ -15,7 +15,7 @@ module ActionView
# unchanged if can't be converted into a valid number.
module NumberHelper
- DEFAULT_CURRENCY_VALUES = { :format => "%u%n", :unit => "$", :separator => ".", :delimiter => ",",
+ DEFAULT_CURRENCY_VALUES = { :format => "%u%n", :negative_format => "-%u%n", :unit => "$", :separator => ".", :delimiter => ",",
:precision => 2, :significant => false, :strip_insignificant_zeros => false }
# Raised when argument +number+ param given to the helpers is invalid and
@@ -81,15 +81,18 @@ module ActionView
# in the +options+ hash.
#
# ==== Options
- # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
- # * <tt>:precision</tt> - Sets the level of precision (defaults to 2).
- # * <tt>:unit</tt> - Sets the denomination of the currency (defaults to "$").
- # * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to ",").
- # * <tt>:format</tt> - Sets the format of the output string (defaults to "%u%n"). The field types are:
- #
- # %u The currency unit
- # %n The number
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
+ # * <tt>:precision</tt> - Sets the level of precision (defaults to 2).
+ # * <tt>:unit</tt> - Sets the denomination of the currency (defaults to "$").
+ # * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to ",").
+ # * <tt>:format</tt> - Sets the format for non-negative numbers (defaults to "%u%n").
+ # Fields are <tt>%u</tt> for the currency, and <tt>%n</tt>
+ # for the number.
+ # * <tt>:negative_format</tt> - Sets the format for negative numbers (defaults to prepending
+ # an hyphen to the formatted number given by <tt>:format</tt>).
+ # Accepts the same fields than <tt>:format</tt>, except
+ # <tt>%n</tt> is here the absolute value of the number.
#
# ==== Examples
# number_to_currency(1234567890.50) # => $1,234,567,890.50
@@ -97,6 +100,8 @@ module ActionView
# number_to_currency(1234567890.506, :precision => 3) # => $1,234,567,890.506
# number_to_currency(1234567890.506, :locale => :fr) # => 1 234 567 890,506 €
#
+ # number_to_currency(1234567890.50, :negative_format => "(%u%n)")
+ # # => ($1,234,567,890.51)
# number_to_currency(1234567890.50, :unit => "&pound;", :separator => ",", :delimiter => "")
# # => &pound;1234567890,50
# number_to_currency(1234567890.50, :unit => "&pound;", :separator => ",", :delimiter => "", :format => "%n %u")
@@ -110,11 +115,17 @@ module ActionView
currency = I18n.translate(:'number.currency.format', :locale => options[:locale], :default => {})
defaults = DEFAULT_CURRENCY_VALUES.merge(defaults).merge!(currency)
+ defaults[:negative_format] = "-" + options[:format] if options[:format]
options = defaults.merge!(options)
unit = options.delete(:unit)
format = options.delete(:format)
+ if number.to_f < 0
+ format = options.delete(:negative_format)
+ number = number.respond_to?("abs") ? number.abs : number.sub(/^-/, '')
+ end
+
begin
value = number_with_precision(number, options.merge(:raise => true))
format.gsub(/%n/, value).gsub(/%u/, unit).html_safe
diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb
index c580397cad..317479ad4c 100644
--- a/actionpack/lib/action_view/renderer/partial_renderer.rb
+++ b/actionpack/lib/action_view/renderer/partial_renderer.rb
@@ -90,13 +90,14 @@ module ActionView
def collection
if @options.key?(:collection)
- @options[:collection] || []
+ collection = @options[:collection]
+ collection.respond_to?(:to_ary) ? collection.to_ary : []
end
end
def collection_from_object
if @object.respond_to?(:to_ary)
- @object
+ @object.to_ary
end
end
@@ -163,4 +164,4 @@ module ActionView
[variable, variable_counter]
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb
index b827610456..0803114f44 100644
--- a/actionpack/lib/action_view/template/handlers/erb.rb
+++ b/actionpack/lib/action_view/template/handlers/erb.rb
@@ -15,6 +15,7 @@ module ActionView
super(value.to_s)
end
alias :append= :<<
+ alias :safe_append= :safe_concat
end
class Template
@@ -40,7 +41,11 @@ module ActionView
end
def add_expr_escaped(src, code)
- src << '@output_buffer.append= ' << escaped_expr(code) << ';'
+ if code =~ BLOCK_EXPR
+ src << "@output_buffer.safe_append= " << code
+ else
+ src << "@output_buffer.safe_concat((" << code << ").to_s);"
+ end
end
def add_postamble(src)