aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/CHANGELOG.md19
-rw-r--r--actionpack/Rakefile1
-rw-r--r--actionpack/lib/abstract_controller.rb4
-rw-r--r--actionpack/lib/abstract_controller/callbacks.rb2
-rw-r--r--actionpack/lib/action_controller/caching/pages.rb14
-rw-r--r--actionpack/lib/action_controller/log_subscriber.rb2
-rw-r--r--actionpack/lib/action_controller/metal/conditional_get.rb1
-rw-r--r--actionpack/lib/action_controller/metal/helpers.rb1
-rw-r--r--actionpack/lib/action_controller/metal/http_authentication.rb86
-rw-r--r--actionpack/lib/action_controller/metal/mime_responds.rb7
-rw-r--r--actionpack/lib/action_controller/metal/redirecting.rb5
-rw-r--r--actionpack/lib/action_controller/metal/renderers.rb1
-rw-r--r--actionpack/lib/action_controller/metal/request_forgery_protection.rb2
-rw-r--r--actionpack/lib/action_controller/metal/url_for.rb3
-rw-r--r--actionpack/lib/action_controller/record_identifier.rb6
-rw-r--r--actionpack/lib/action_controller/test_case.rb7
-rw-r--r--actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb1
-rw-r--r--actionpack/lib/action_dispatch.rb6
-rw-r--r--actionpack/lib/action_dispatch/http/filter_parameters.rb3
-rw-r--r--actionpack/lib/action_dispatch/http/request.rb3
-rw-r--r--actionpack/lib/action_dispatch/middleware/exception_wrapper.rb3
-rw-r--r--actionpack/lib/action_dispatch/middleware/flash.rb2
-rw-r--r--actionpack/lib/action_dispatch/middleware/session/cookie_store.rb2
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb37
-rw-r--r--actionpack/lib/action_dispatch/routing/route_set.rb13
-rw-r--r--actionpack/lib/action_dispatch/routing/url_for.rb2
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/dom.rb6
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/response.rb6
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/routing.rb3
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/selector.rb6
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/tag.rb3
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb31
-rw-r--r--actionpack/lib/action_view.rb9
-rw-r--r--actionpack/lib/action_view/asset_paths.rb2
-rw-r--r--actionpack/lib/action_view/base.rb1
-rw-r--r--actionpack/lib/action_view/context.rb4
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb69
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb4
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb3
-rw-r--r--actionpack/lib/action_view/helpers/cache_helper.rb1
-rw-r--r--actionpack/lib/action_view/helpers/capture_helper.rb1
-rw-r--r--actionpack/lib/action_view/helpers/date_helper.rb26
-rw-r--r--actionpack/lib/action_view/helpers/debug_helper.rb3
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb6
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb52
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb24
-rw-r--r--actionpack/lib/action_view/helpers/number_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/sanitize_helper.rb3
-rw-r--r--actionpack/lib/action_view/helpers/tag_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/tags/base.rb8
-rw-r--r--actionpack/lib/action_view/helpers/tags/date_field.rb1
-rw-r--r--actionpack/lib/action_view/helpers/tags/file_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/hidden_field.rb4
-rw-r--r--actionpack/lib/action_view/helpers/tags/number_field.rb1
-rw-r--r--actionpack/lib/action_view/helpers/text_helper.rb53
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb14
-rw-r--r--actionpack/lib/action_view/renderer/abstract_renderer.rb4
-rw-r--r--actionpack/lib/action_view/renderer/partial_renderer.rb71
-rw-r--r--actionpack/lib/action_view/template/handlers.rb2
-rw-r--r--actionpack/lib/action_view/template/handlers/raw.rb11
-rw-r--r--actionpack/lib/action_view/template/resolver.rb5
-rw-r--r--actionpack/test/abstract_unit.rb6
-rw-r--r--actionpack/test/controller/integration_test.rb80
-rw-r--r--actionpack/test/controller/new_base/render_text_test.rb4
-rw-r--r--actionpack/test/dispatch/routing_assertions_test.rb6
-rw-r--r--actionpack/test/dispatch/routing_test.rb135
-rw-r--r--actionpack/test/fixtures/plain_text.raw1
-rw-r--r--actionpack/test/fixtures/plain_text_with_characters.raw1
-rw-r--r--actionpack/test/fixtures/routes/bogus.rb1
-rw-r--r--actionpack/test/fixtures/routes/external.rb1
-rw-r--r--actionpack/test/template/asset_tag_helper_test.rb11
-rw-r--r--actionpack/test/template/form_options_helper_test.rb78
-rw-r--r--actionpack/test/template/form_tag_helper_test.rb16
-rw-r--r--actionpack/test/template/render_test.rb8
-rw-r--r--actionpack/test/template/template_test.rb7
-rw-r--r--actionpack/test/template/testing/fixture_resolver_test.rb4
-rw-r--r--actionpack/test/template/testing/null_resolver_test.rb4
-rw-r--r--actionpack/test/template/text_helper_test.rb8
-rw-r--r--actionpack/test/template/url_helper_test.rb16
-rw-r--r--actionpack/test/ts_isolated.rb3
80 files changed, 650 insertions, 418 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md
index b819f2e613..8df943139e 100644
--- a/actionpack/CHANGELOG.md
+++ b/actionpack/CHANGELOG.md
@@ -1,5 +1,22 @@
## Rails 4.0.0 (unreleased) ##
+* Templates without a handler extension now raises a deprecation warning but still
+ defaults to ERb. In future releases, it will simply return the template contents. *Steve Klabnik*
+
+* Remove `:disable_with` in favor of `'data-disable-with'` option from `submit_tag`, `button_tag` and `button_to` helpers.
+
+ *Carlos Galdino + Rafael Mendonça França*
+
+* Remove `:mouseover` option from `image_tag` helper. *Rafael Mendonça França*
+
+* The `select` method (select tag) forces :include_blank if `required` is true and
+ `display size` is one and `multiple` is not true. *Angelo Capilleri*
+
+* Copy literal route constraints to defaults so that url generation know about them.
+ The copied constraints are `:protocol`, `:subdomain`, `:domain`, `:host` and `:port`.
+
+ *Andrew White*
+
* `respond_to` and `respond_with` now raise ActionController::UnknownFormat instead
of directly returning head 406. The exception is rescued and converted to 406
in the exception handling middleware. *Steven Soroka*
@@ -5775,7 +5792,7 @@
== Rendering a collection of partials
The example of partial use describes a familar pattern where a template needs
- to iterate over a array and render a sub template for each of the elements.
+ to iterate over an array and render a sub template for each of the elements.
This pattern has been implemented as a single method that accepts an array and
renders a partial by the same name of as the elements contained within. So the
three-lined example in "Using partials" can be rewritten with a single line:
diff --git a/actionpack/Rakefile b/actionpack/Rakefile
index 17d95bfd1d..50e3bb0d48 100644
--- a/actionpack/Rakefile
+++ b/actionpack/Rakefile
@@ -23,6 +23,7 @@ end
namespace :test do
Rake::TestTask.new(:isolated) do |t|
+ t.libs << 'test'
t.pattern = 'test/ts_isolated.rb'
end
diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb
index cc5878c88e..b95ea5f0b2 100644
--- a/actionpack/lib/abstract_controller.rb
+++ b/actionpack/lib/abstract_controller.rb
@@ -1,9 +1,5 @@
-activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__)
-$:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)
-
require 'action_pack'
require 'active_support/concern'
-require 'active_support/ruby/shim'
require 'active_support/dependencies/autoload'
require 'active_support/core_ext/class/attribute'
require 'active_support/core_ext/module/attr_internal'
diff --git a/actionpack/lib/abstract_controller/callbacks.rb b/actionpack/lib/abstract_controller/callbacks.rb
index 520c210721..5705ab590c 100644
--- a/actionpack/lib/abstract_controller/callbacks.rb
+++ b/actionpack/lib/abstract_controller/callbacks.rb
@@ -14,7 +14,7 @@ module AbstractController
# Override AbstractController::Base's process_action to run the
# process_action callbacks around the normal behavior.
def process_action(*args)
- run_callbacks(:process_action, action_name) do
+ run_callbacks(:process_action) do
super
end
end
diff --git a/actionpack/lib/action_controller/caching/pages.rb b/actionpack/lib/action_controller/caching/pages.rb
index 307594d54a..dd4eddbe9a 100644
--- a/actionpack/lib/action_controller/caching/pages.rb
+++ b/actionpack/lib/action_controller/caching/pages.rb
@@ -60,7 +60,8 @@ module ActionController #:nodoc:
end
module ClassMethods
- # Expires the page that was cached with the +path+ as a key. Example:
+ # Expires the page that was cached with the +path+ as a key.
+ #
# expire_page "/lists/show"
def expire_page(path)
return unless perform_caching
@@ -72,7 +73,8 @@ module ActionController #:nodoc:
end
end
- # Manually cache the +content+ in the key determined by +path+. Example:
+ # Manually cache the +content+ in the key determined by +path+.
+ #
# cache_page "I'm the cached content", "/lists/show"
def cache_page(content, path, extension = nil, gzip = Zlib::BEST_COMPRESSION)
return unless perform_caching
@@ -93,8 +95,6 @@ module ActionController #:nodoc:
#
# You can also pass a :gzip option to override the class configuration one.
#
- # Usage:
- #
# # cache the index action
# caches_page :index
#
@@ -142,7 +142,8 @@ module ActionController #:nodoc:
end
end
- # Expires the page that was cached with the +options+ as a key. Example:
+ # Expires the page that was cached with the +options+ as a key.
+ #
# expire_page :controller => "lists", :action => "show"
def expire_page(options = {})
return unless self.class.perform_caching
@@ -161,7 +162,8 @@ module ActionController #:nodoc:
end
# Manually cache the +content+ in the key determined by +options+. If no content is provided, the contents of response.body is used.
- # If no options are provided, the url of the current request being handled is used. Example:
+ # If no options are provided, the url of the current request being handled is used.
+ #
# cache_page "I'm the cached content", :controller => "lists", :action => "show"
def cache_page(content = nil, options = nil, gzip = Zlib::BEST_COMPRESSION)
return unless self.class.perform_caching && caching_allowed?
diff --git a/actionpack/lib/action_controller/log_subscriber.rb b/actionpack/lib/action_controller/log_subscriber.rb
index 4c76f4c43b..11aa393bf9 100644
--- a/actionpack/lib/action_controller/log_subscriber.rb
+++ b/actionpack/lib/action_controller/log_subscriber.rb
@@ -20,7 +20,7 @@ module ActionController
status = payload[:status]
if status.nil? && payload[:exception].present?
- status = Rack::Utils.status_code(ActionDispatch::ExceptionWrapper.new({}, payload[:exception]).status_code)
+ status = ActionDispatch::ExceptionWrapper.new({}, payload[:exception]).status_code
end
message = "Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in %.0fms" % event.duration
message << " (#{additions.join(" | ")})" unless additions.blank?
diff --git a/actionpack/lib/action_controller/metal/conditional_get.rb b/actionpack/lib/action_controller/metal/conditional_get.rb
index 5b25a0d303..2193dde667 100644
--- a/actionpack/lib/action_controller/metal/conditional_get.rb
+++ b/actionpack/lib/action_controller/metal/conditional_get.rb
@@ -108,7 +108,6 @@ module ActionController
# Sets a HTTP 1.1 Cache-Control header. Defaults to issuing a <tt>private</tt> instruction, so that
# intermediate caches must not cache the response.
#
- # Examples:
# expires_in 20.minutes
# expires_in 3.hours, :public => true
# expires_in 3.hours, :public => true, :must_revalidate => true
diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb
index 1a4bca12d2..86d061e3b7 100644
--- a/actionpack/lib/action_controller/metal/helpers.rb
+++ b/actionpack/lib/action_controller/metal/helpers.rb
@@ -16,7 +16,6 @@ module ActionController
# Additional helpers can be specified using the +helper+ class method in ActionController::Base or any
# controller which inherits from it.
#
- # ==== Examples
# The +to_s+ method from the \Time class can be wrapped in a helper method to display a custom message if
# a \Time object is blank:
#
diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb
index 87225d74c1..57bb0e2a32 100644
--- a/actionpack/lib/action_controller/metal/http_authentication.rb
+++ b/actionpack/lib/action_controller/metal/http_authentication.rb
@@ -2,8 +2,9 @@ require 'base64'
require 'active_support/core_ext/object/blank'
module ActionController
+ # Makes it dead easy to do HTTP Basic, Digest and Token authentication.
module HttpAuthentication
- # Makes it dead easy to do HTTP \Basic and \Digest authentication.
+ # Makes it dead easy to do HTTP \Basic authentication.
#
# === Simple \Basic example
#
@@ -60,47 +61,6 @@ module ActionController
#
# assert_equal 200, status
# end
- #
- # === Simple \Digest example
- #
- # require 'digest/md5'
- # class PostsController < ApplicationController
- # REALM = "SuperSecret"
- # USERS = {"dhh" => "secret", #plain text password
- # "dap" => Digest::MD5.hexdigest(["dap",REALM,"secret"].join(":"))} #ha1 digest password
- #
- # before_filter :authenticate, :except => [:index]
- #
- # def index
- # render :text => "Everyone can see me!"
- # end
- #
- # def edit
- # render :text => "I'm only accessible if you know the password"
- # end
- #
- # private
- # def authenticate
- # authenticate_or_request_with_http_digest(REALM) do |username|
- # USERS[username]
- # end
- # end
- # end
- #
- # === Notes
- #
- # The +authenticate_or_request_with_http_digest+ block must return the user's password
- # or the ha1 digest hash so the framework can appropriately hash to check the user's
- # credentials. Returning +nil+ will cause authentication to fail.
- #
- # Storing the ha1 hash: MD5(username:realm:password), is better than storing a plain password. If
- # the password file or database is compromised, the attacker would be able to use the ha1 hash to
- # authenticate as the user at this +realm+, but would not have the user's password to try using at
- # other sites.
- #
- # In rare instances, web servers or front proxies strip authorization headers before
- # they reach your application. You can debug this situation by logging all environment
- # variables, and check for HTTP_AUTHORIZATION, amongst others.
module Basic
extend self
@@ -155,6 +115,48 @@ module ActionController
end
end
+ # Makes it dead easy to do HTTP \Digest authentication.
+ #
+ # === Simple \Digest example
+ #
+ # require 'digest/md5'
+ # class PostsController < ApplicationController
+ # REALM = "SuperSecret"
+ # USERS = {"dhh" => "secret", #plain text password
+ # "dap" => Digest::MD5.hexdigest(["dap",REALM,"secret"].join(":"))} #ha1 digest password
+ #
+ # before_filter :authenticate, :except => [:index]
+ #
+ # def index
+ # render :text => "Everyone can see me!"
+ # end
+ #
+ # def edit
+ # render :text => "I'm only accessible if you know the password"
+ # end
+ #
+ # private
+ # def authenticate
+ # authenticate_or_request_with_http_digest(REALM) do |username|
+ # USERS[username]
+ # end
+ # end
+ # end
+ #
+ # === Notes
+ #
+ # The +authenticate_or_request_with_http_digest+ block must return the user's password
+ # or the ha1 digest hash so the framework can appropriately hash to check the user's
+ # credentials. Returning +nil+ will cause authentication to fail.
+ #
+ # Storing the ha1 hash: MD5(username:realm:password), is better than storing a plain password. If
+ # the password file or database is compromised, the attacker would be able to use the ha1 hash to
+ # authenticate as the user at this +realm+, but would not have the user's password to try using at
+ # other sites.
+ #
+ # In rare instances, web servers or front proxies strip authorization headers before
+ # they reach your application. You can debug this situation by logging all environment
+ # variables, and check for HTTP_AUTHORIZATION, amongst others.
module Digest
extend self
diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb
index 7917926978..0b800c3c62 100644
--- a/actionpack/lib/action_controller/metal/mime_responds.rb
+++ b/actionpack/lib/action_controller/metal/mime_responds.rb
@@ -16,8 +16,6 @@ module ActionController #:nodoc:
# Defines mime types that are rendered by default when invoking
# <tt>respond_with</tt>.
#
- # Examples:
- #
# respond_to :html, :xml, :json
#
# Specifies that all actions in the controller respond to requests
@@ -185,7 +183,6 @@ module ActionController #:nodoc:
# end
#
# Be sure to check respond_with and respond_to documentation for more examples.
- #
def respond_to(*mimes, &block)
raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?
@@ -323,7 +320,6 @@ module ActionController #:nodoc:
# a successful html +post+ request.
# 2. <tt>:action</tt> - overwrites the default render action used after an
# unsuccessful html +post+ request.
- #
def respond_with(*resources, &block)
raise "In order to use respond_with, first you need to declare the formats your " <<
"controller responds to in the class level" if self.class.mimes_for_respond_to.empty?
@@ -339,7 +335,6 @@ module ActionController #:nodoc:
# Collect mimes declared in the class method respond_to valid for the
# current action.
- #
def collect_mimes_from_class_level #:nodoc:
action = action_name.to_s
@@ -362,7 +357,6 @@ module ActionController #:nodoc:
#
# Sends :not_acceptable to the client and returns nil if no suitable format
# is available.
- #
def retrieve_collector_from_mimes(mimes=nil, &block) #:nodoc:
mimes ||= collect_mimes_from_class_level
collector = Collector.new(mimes)
@@ -401,7 +395,6 @@ module ActionController #:nodoc:
# A subsequent call to #negotiate_format(request) will enable the Collector
# to determine which specific mime-type it should respond with for the current
# request, with this response then being accessible by calling #response.
- #
class Collector
include AbstractController::Collector
attr_accessor :order, :format
diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb
index 5e7bd44562..ee0e69d87c 100644
--- a/actionpack/lib/action_controller/metal/redirecting.rb
+++ b/actionpack/lib/action_controller/metal/redirecting.rb
@@ -24,7 +24,6 @@ module ActionController
# * <tt>:back</tt> - Back to the page that issued the request. Useful for forms that are triggered from multiple places.
# Short-hand for <tt>redirect_to(request.env["HTTP_REFERER"])</tt>
#
- # Examples:
# redirect_to :action => "show", :id => 5
# redirect_to post
# redirect_to "http://www.rubyonrails.org"
@@ -35,7 +34,6 @@ module ActionController
#
# The redirection happens as a "302 Moved" header unless otherwise specified.
#
- # Examples:
# redirect_to post_url(@post), :status => :found
# redirect_to :action=>'atom', :status => :moved_permanently
# redirect_to post_url(@post), :status => 301
@@ -51,14 +49,12 @@ module ActionController
# around this you can return a <tt>303 See Other</tt> status code which will be
# followed using a GET request.
#
- # Examples:
# redirect_to posts_url, :status => :see_other
# redirect_to :action => 'index', :status => 303
#
# It is also possible to assign a flash message as part of the redirection. There are two special accessors for the commonly used flash names
# +alert+ and +notice+ as well as a general purpose +flash+ bucket.
#
- # Examples:
# redirect_to post_url(@post), :alert => "Watch it, mister!"
# redirect_to post_url(@post), :status=> :found, :notice => "Pay attention to the road"
# redirect_to post_url(@post), :status => 301, :flash => { :updated_post_id => @post.id }
@@ -69,6 +65,7 @@ module ActionController
def redirect_to(options = {}, response_status = {}) #:doc:
raise ActionControllerError.new("Cannot redirect to nil!") unless options
raise AbstractController::DoubleRenderError if response_body
+ logger.debug { "Redirected by #{caller(1).first rescue "unknown"}" } if logger
self.status = _extract_redirect_to_status(options, response_status)
self.location = _compute_redirect_to_location(options)
diff --git a/actionpack/lib/action_controller/metal/renderers.rb b/actionpack/lib/action_controller/metal/renderers.rb
index 4a0c1c7dd7..1927c8bdc7 100644
--- a/actionpack/lib/action_controller/metal/renderers.rb
+++ b/actionpack/lib/action_controller/metal/renderers.rb
@@ -49,7 +49,6 @@ module ActionController
# is the value paired with its key and the second is the remaining
# hash of options passed to +render+.
#
- # === Example
# Create a csv renderer:
#
# ActionController::Renderers.add :csv do |obj, options|
diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
index 0bff1825d9..95b0e99ed5 100644
--- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb
@@ -51,8 +51,6 @@ module ActionController #:nodoc:
module ClassMethods
# Turn on request forgery protection. Bear in mind that only non-GET, HTML/JavaScript requests are checked.
#
- # Example:
- #
# class FooController < ApplicationController
# protect_from_forgery :except => :index
#
diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb
index 8e7b56dbcc..e28c05cc2d 100644
--- a/actionpack/lib/action_controller/metal/url_for.rb
+++ b/actionpack/lib/action_controller/metal/url_for.rb
@@ -6,8 +6,6 @@ module ActionController
# url options like the +host+. In order to do so, this module requires the host class
# to implement +env+ and +request+, which need to be a Rack-compatible.
#
- # Example:
- #
# class RootUrl
# include ActionController::UrlFor
# include Rails.application.routes.url_helpers
@@ -19,7 +17,6 @@ module ActionController
# @url = root_path # named route from the application.
# end
# end
- #
module UrlFor
extend ActiveSupport::Concern
diff --git a/actionpack/lib/action_controller/record_identifier.rb b/actionpack/lib/action_controller/record_identifier.rb
index e7af3f5b8d..16a5decc62 100644
--- a/actionpack/lib/action_controller/record_identifier.rb
+++ b/actionpack/lib/action_controller/record_identifier.rb
@@ -3,7 +3,7 @@ require 'active_support/core_ext/module'
module ActionController
# The record identifier encapsulates a number of naming conventions for dealing with records, like Active Records or
# pretty much any other model type that has an id. These patterns are then used to try elevate the view actions to
- # a higher logical level. Example:
+ # a higher logical level.
#
# # routes
# resources :posts
@@ -30,7 +30,7 @@ module ActionController
JOIN = '_'.freeze
NEW = 'new'.freeze
- # The DOM class convention is to use the singular form of an object or class. Examples:
+ # The DOM class convention is to use the singular form of an object or class.
#
# dom_class(post) # => "post"
# dom_class(Person) # => "person"
@@ -45,7 +45,7 @@ module ActionController
end
# The DOM id convention is to use the singular form of an object or class with the id following an underscore.
- # If no id is found, prefix with "new_" instead. Examples:
+ # If no id is found, prefix with "new_" instead.
#
# dom_id(Post.find(45)) # => "post_45"
# dom_id(Post.new) # => "new_post"
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index ad02375f12..76d07891c9 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -56,8 +56,6 @@ module ActionController
# Asserts that the request was rendered with the appropriate template file or partials.
#
- # ==== Examples
- #
# # assert that the "new" view template was rendered
# assert_template "new"
#
@@ -84,7 +82,6 @@ module ActionController
#
# # assert that the "_customer" partial was rendered with a specific object
# assert_template :partial => '_customer', :locals => { :customer => @customer }
- #
def assert_template(options = {}, message = nil)
# Force body to be read in case the
# template is being streamed
@@ -350,7 +347,6 @@ module ActionController
# == \Testing named routes
#
# If you're using named routes, they can be easily tested using the original named routes' methods straight in the test case.
- # Example:
#
# assert_redirected_to page_url(:title => 'foo')
class TestCase < ActiveSupport::TestCase
@@ -369,12 +365,11 @@ module ActionController
module ClassMethods
# Sets the controller class name. Useful if the name can't be inferred from test class.
- # Normalizes +controller_class+ before using. Examples:
+ # Normalizes +controller_class+ before using.
#
# tests WidgetController
# tests :widget
# tests 'widget'
- #
def tests(controller_class)
case controller_class
when String, Symbol
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 114b0e73c9..6b269e7a31 100644
--- a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
+++ b/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb
@@ -1,6 +1,7 @@
require 'set'
require 'cgi'
require 'active_support/core_ext/class/attribute'
+require 'active_support/core_ext/class/attribute_accessors'
module HTML
class Sanitizer
diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb
index e3b04ac097..1e4ac70f3d 100644
--- a/actionpack/lib/action_dispatch.rb
+++ b/actionpack/lib/action_dispatch.rb
@@ -21,12 +21,6 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
-activesupport_path = File.expand_path('../../../activesupport/lib', __FILE__)
-$:.unshift(activesupport_path) if File.directory?(activesupport_path) && !$:.include?(activesupport_path)
-
-activemodel_path = File.expand_path('../../../activemodel/lib', __FILE__)
-$:.unshift(activemodel_path) if File.directory?(activemodel_path) && !$:.include?(activemodel_path)
-
require 'active_support'
require 'active_support/dependencies/autoload'
require 'active_support/core_ext/module/attribute_accessors'
diff --git a/actionpack/lib/action_dispatch/http/filter_parameters.rb b/actionpack/lib/action_dispatch/http/filter_parameters.rb
index 132b0c82bc..6413929be3 100644
--- a/actionpack/lib/action_dispatch/http/filter_parameters.rb
+++ b/actionpack/lib/action_dispatch/http/filter_parameters.rb
@@ -10,8 +10,6 @@ module ActionDispatch
# value of the params hash and all subhashes is passed to it, the value
# or key can be replaced using String#replace or similar method.
#
- # Examples:
- #
# env["action_dispatch.parameter_filter"] = [:password]
# => replaces the value to all keys matching /password/i with "[FILTERED]"
#
@@ -22,7 +20,6 @@ module ActionDispatch
# v.reverse! if k =~ /secret/i
# end
# => reverses the value to all keys matching /secret/i
- #
module FilterParameters
extend ActiveSupport::Concern
diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb
index 9748956052..56908b5794 100644
--- a/actionpack/lib/action_dispatch/http/request.rb
+++ b/actionpack/lib/action_dispatch/http/request.rb
@@ -6,7 +6,6 @@ require 'active_support/core_ext/hash/indifferent_access'
require 'active_support/core_ext/string/access'
require 'active_support/inflector'
require 'action_dispatch/http/headers'
-require 'action_dispatch/request/session'
require 'action_controller/metal/exceptions'
module ActionDispatch
@@ -18,6 +17,8 @@ module ActionDispatch
include ActionDispatch::Http::Upload
include ActionDispatch::Http::URL
+ autoload :Session, 'action_dispatch/request/session'
+
LOCALHOST = Regexp.union [/^127\.0\.0\.\d{1,3}$/, /^::1$/, /^0:0:0:0:0:0:0:1(%.*)?$/]
ENV_METHODS = %w[ AUTH_TYPE GATEWAY_INTERFACE
diff --git a/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb b/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb
index 982f6641bf..a8f49bd3bd 100644
--- a/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb
+++ b/actionpack/lib/action_dispatch/middleware/exception_wrapper.rb
@@ -1,5 +1,6 @@
require 'action_controller/metal/exceptions'
require 'active_support/core_ext/exception'
+require 'active_support/core_ext/class/attribute_accessors'
module ActionDispatch
class ExceptionWrapper
@@ -76,4 +77,4 @@ module ActionDispatch
@backtrace_cleaner ||= @env['action_dispatch.backtrace_cleaner']
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_dispatch/middleware/flash.rb b/actionpack/lib/action_dispatch/middleware/flash.rb
index 17776c2356..9928b7cc3a 100644
--- a/actionpack/lib/action_dispatch/middleware/flash.rb
+++ b/actionpack/lib/action_dispatch/middleware/flash.rb
@@ -11,7 +11,7 @@ module ActionDispatch
# The flash provides a way to pass temporary objects between actions. Anything you place in the flash will be exposed
# to the very next action and then cleared out. This is a great way of doing notices and alerts, such as a create
# action that sets <tt>flash[:notice] = "Post successfully created"</tt> before redirecting to a display action that can
- # then expose the flash to its template. Actually, that exposure is automatically done. Example:
+ # then expose the flash to its template. Actually, that exposure is automatically done.
#
# class PostsController < ActionController::Base
# def create
diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
index dbcf703ec3..7efc094f98 100644
--- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
+++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb
@@ -27,7 +27,7 @@ module ActionDispatch
# 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:
+ # characters.
#
# :secret => '449fe2e7daee471bffae2fd8dc02313d'
# :secret => Proc.new { User.current_user.secret_key }
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 2a7d540517..67a208263b 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/hash/except'
require 'active_support/core_ext/hash/reverse_merge'
+require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/enumerable'
require 'active_support/inflector'
@@ -100,6 +101,10 @@ module ActionDispatch
raise ArgumentError, "Regexp multiline option not allowed in routing requirements: #{requirement.inspect}"
end
end
+
+ if @options[:constraints].is_a?(Hash)
+ (@options[:defaults] ||= {}).reverse_merge!(defaults_from_constraints(@options[:constraints]))
+ end
end
# match "account/overview"
@@ -245,6 +250,11 @@ module ActionDispatch
def default_action
@options[:action] || @scope[:action]
end
+
+ def defaults_from_constraints(constraints)
+ url_keys = [:protocol, :subdomain, :domain, :host, :port]
+ constraints.slice(*url_keys).select{ |k, v| v.is_a?(String) || v.is_a?(Fixnum) }
+ end
end
# Invokes Rack::Mount::Utils.normalize path and ensure that
@@ -485,8 +495,6 @@ module ActionDispatch
# Define a route that only recognizes HTTP GET.
# For supported arguments, see <tt>Base#match</tt>.
#
- # Example:
- #
# get 'bacon', :to => 'food#bacon'
def get(*args, &block)
map_method(:get, args, &block)
@@ -495,8 +503,6 @@ module ActionDispatch
# Define a route that only recognizes HTTP POST.
# For supported arguments, see <tt>Base#match</tt>.
#
- # Example:
- #
# post 'bacon', :to => 'food#bacon'
def post(*args, &block)
map_method(:post, args, &block)
@@ -505,8 +511,6 @@ module ActionDispatch
# Define a route that only recognizes HTTP PATCH.
# For supported arguments, see <tt>Base#match</tt>.
#
- # Example:
- #
# patch 'bacon', :to => 'food#bacon'
def patch(*args, &block)
map_method(:patch, args, &block)
@@ -515,8 +519,6 @@ module ActionDispatch
# Define a route that only recognizes HTTP PUT.
# For supported arguments, see <tt>Base#match</tt>.
#
- # Example:
- #
# put 'bacon', :to => 'food#bacon'
def put(*args, &block)
map_method(:put, args, &block)
@@ -525,8 +527,6 @@ module ActionDispatch
# Define a route that only recognizes HTTP DELETE.
# For supported arguments, see <tt>Base#match</tt>.
#
- # Example:
- #
# delete 'broccoli', :to => 'food#broccoli'
def delete(*args, &block)
map_method(:delete, args, &block)
@@ -641,6 +641,10 @@ module ActionDispatch
block, options[:constraints] = options[:constraints], {}
end
+ if options[:constraints].is_a?(Hash)
+ (options[:defaults] ||= {}).reverse_merge!(defaults_from_constraints(options[:constraints]))
+ end
+
scope_options.each do |option|
if value = options.delete(option)
recover[option] = @scope[option]
@@ -667,7 +671,6 @@ module ActionDispatch
# Scopes routes to a specific controller
#
- # Example:
# controller "food" do
# match "bacon", :action => "bacon"
# end
@@ -849,6 +852,11 @@ module ActionDispatch
def override_keys(child) #:nodoc:
child.key?(:only) || child.key?(:except) ? [:only, :except] : []
end
+
+ def defaults_from_constraints(constraints)
+ url_keys = [:protocol, :subdomain, :domain, :host, :port]
+ constraints.slice(*url_keys).select{ |k, v| v.is_a?(String) || v.is_a?(Fixnum) }
+ end
end
# Resource routing allows you to quickly declare all of the common routes
@@ -1317,10 +1325,11 @@ module ActionDispatch
msg = "Your router tried to #draw the external file #{name}.rb,\n" \
"but the file was not found in:\n\n"
msg += @draw_paths.map { |_path| " * #{_path}" }.join("\n")
- raise msg
+ raise ArgumentError, msg
end
-
- instance_eval(path.join("#{name}.rb").read)
+
+ route_path = path.join("#{name}.rb")
+ instance_eval(route_path.read, route_path.to_s)
end
# match 'path' => 'controller#action'
diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb
index 8fc0f283fc..0ae668d42a 100644
--- a/actionpack/lib/action_dispatch/routing/route_set.rb
+++ b/actionpack/lib/action_dispatch/routing/route_set.rb
@@ -103,7 +103,7 @@ module ActionDispatch
inner_options = args.extract_options!
result = options.dup
- if args.any?
+ if args.size > 0
keys = segment_keys
if args.size < keys.size - 1 # take format into account
keys -= self.url_options.keys if self.respond_to?(:url_options)
@@ -460,12 +460,12 @@ module ActionDispatch
normalize_options!
normalize_controller_action_id!
use_relative_controller!
- controller.sub!(%r{^/}, '') if controller
+ normalize_controller!
handle_nil_action!
end
def controller
- @controller ||= @options[:controller]
+ @options[:controller]
end
def current_controller
@@ -522,10 +522,15 @@ module ActionDispatch
old_parts = current_controller.split('/')
size = controller.count("/") + 1
parts = old_parts[0...-size] << controller
- @controller = @options[:controller] = parts.join("/")
+ @options[:controller] = parts.join("/")
end
end
+ # Remove leading slashes from controllers
+ def normalize_controller!
+ @options[:controller] = controller.sub(%r{^/}, '') if controller
+ end
+
# This handles the case of :action => nil being explicitly passed.
# It is identical to :action => "index"
def handle_nil_action!
diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb
index ee02f4b531..fd3bed7e8f 100644
--- a/actionpack/lib/action_dispatch/routing/url_for.rb
+++ b/actionpack/lib/action_dispatch/routing/url_for.rb
@@ -132,8 +132,6 @@ module ActionDispatch
# Any other key (<tt>:controller</tt>, <tt>:action</tt>, etc.) given to
# +url_for+ is forwarded to the Routes module.
#
- # Examples:
- #
# url_for :controller => 'tasks', :action => 'testing', :host => 'somehost.org', :port => '8080'
# # => 'http://somehost.org:8080/tasks/testing'
# url_for :controller => 'tasks', :action => 'testing', :host => 'somehost.org', :anchor => 'ok', :only_path => true
diff --git a/actionpack/lib/action_dispatch/testing/assertions/dom.rb b/actionpack/lib/action_dispatch/testing/assertions/dom.rb
index edea6dab39..7dc3d0f97c 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/dom.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/dom.rb
@@ -5,11 +5,8 @@ module ActionDispatch
module DomAssertions
# \Test two HTML strings for equivalency (e.g., identical up to reordering of attributes)
#
- # ==== Examples
- #
# # assert that the referenced method generates the appropriate HTML string
# assert_dom_equal '<a href="http://www.example.com">Apples</a>', link_to("Apples", "http://www.example.com")
- #
def assert_dom_equal(expected, actual, message = "")
expected_dom = HTML::Document.new(expected).root
actual_dom = HTML::Document.new(actual).root
@@ -18,11 +15,8 @@ module ActionDispatch
# The negated form of +assert_dom_equivalent+.
#
- # ==== Examples
- #
# # assert that the referenced method does not generate the specified HTML string
# assert_dom_not_equal '<a href="http://www.example.com">Apples</a>', link_to("Oranges", "http://www.example.com")
- #
def assert_dom_not_equal(expected, actual, message = "")
expected_dom = HTML::Document.new(expected).root
actual_dom = HTML::Document.new(actual).root
diff --git a/actionpack/lib/action_dispatch/testing/assertions/response.rb b/actionpack/lib/action_dispatch/testing/assertions/response.rb
index 8f6fff5d32..3d121b6b9c 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/response.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/response.rb
@@ -15,14 +15,11 @@ module ActionDispatch
# or its symbolic equivalent <tt>assert_response(:not_implemented)</tt>.
# See Rack::Utils::SYMBOL_TO_STATUS_CODE for a full list.
#
- # ==== Examples
- #
# # assert that the response was a redirection
# assert_response :redirect
#
# # assert that the response code was status code 401 (unauthorized)
# assert_response 401
- #
def assert_response(type, message = nil)
message ||= "Expected response to be a <#{type}>, but was <#{@response.response_code}>"
@@ -42,8 +39,6 @@ module ActionDispatch
# This match can be partial, such that <tt>assert_redirected_to(:controller => "weblog")</tt> will also
# match the redirection of <tt>redirect_to(:controller => "weblog", :action => "show")</tt> and so on.
#
- # ==== Examples
- #
# # assert that the redirection was to the "index" action on the WeblogController
# assert_redirected_to :controller => "weblog", :action => "index"
#
@@ -55,7 +50,6 @@ module ActionDispatch
#
# # asserts that the redirection matches the regular expression
# assert_redirected_to %r(\Ahttp://example.org)
- #
def assert_redirected_to(options = {}, message=nil)
assert_response(:redirect, message)
return true if options === @response.location
diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
index 1f4b905d18..567ca0c392 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
@@ -26,7 +26,6 @@ module ActionDispatch
#
# The +message+ parameter allows you to pass in an error message that is displayed upon failure.
#
- # ==== Examples
# # Check the default route (i.e., the index action)
# assert_recognizes({:controller => 'items', :action => 'index'}, 'items')
#
@@ -57,7 +56,6 @@ module ActionDispatch
#
# The +defaults+ parameter is unused.
#
- # ==== Examples
# # Asserts that the default action is generated for a route with no action
# assert_generates "/items", :controller => "items", :action => "index"
#
@@ -100,7 +98,6 @@ module ActionDispatch
# The +extras+ hash allows you to specify options that would normally be provided as a query string to the action. The
# +message+ parameter allows you to specify a custom error message to display upon failure.
#
- # ==== Examples
# # Assert a basic route: a controller with the default action (index)
# assert_routing '/home', :controller => 'home', :action => 'index'
#
diff --git a/actionpack/lib/action_dispatch/testing/assertions/selector.rb b/actionpack/lib/action_dispatch/testing/assertions/selector.rb
index ea1ed20f3c..5f9c3bbf48 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/selector.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/selector.rb
@@ -39,7 +39,6 @@ module ActionDispatch
# The selector may be a CSS selector expression (String), an expression
# with substitution values (Array) or an HTML::Selector object.
#
- # ==== Examples
# # Selects all div tags
# divs = css_select("div")
#
@@ -58,7 +57,6 @@ module ActionDispatch
# inputs = css_select(form, "input")
# ...
# end
- #
def css_select(*args)
# See assert_select to understand what's going on here.
arg = args.shift
@@ -340,7 +338,6 @@ module ActionDispatch
# The content of each element is un-encoded, and wrapped in the root
# element +encoded+. It then calls the block with all un-encoded elements.
#
- # ==== Examples
# # Selects all bold tags from within the title of an Atom feed's entries (perhaps to nab a section name prefix)
# assert_select "feed[xmlns='http://www.w3.org/2005/Atom']" do
# # Select each entry item and then the title item
@@ -401,8 +398,6 @@ module ActionDispatch
# You must enable deliveries for this assertion to work, use:
# ActionMailer::Base.perform_deliveries = true
#
- # ==== Examples
- #
# assert_select_email do
# assert_select "h1", "Email alert"
# end
@@ -413,7 +408,6 @@ module ActionDispatch
# # Work with items here...
# end
# end
- #
def assert_select_email(&block)
deliveries = ActionMailer::Base.deliveries
assert !deliveries.empty?, "No e-mail in delivery list"
diff --git a/actionpack/lib/action_dispatch/testing/assertions/tag.rb b/actionpack/lib/action_dispatch/testing/assertions/tag.rb
index 5c735e61b2..68f1347e7c 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/tag.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/tag.rb
@@ -48,8 +48,6 @@ module ActionDispatch
# * if the condition is +true+, the value must not be +nil+.
# * if the condition is +false+ or +nil+, the value must be +nil+.
#
- # === Examples
- #
# # Assert that there is a "span" tag
# assert_tag :tag => "span"
#
@@ -104,7 +102,6 @@ module ActionDispatch
# Identical to +assert_tag+, but asserts that a matching tag does _not_
# exist. (See +assert_tag+ for a full discussion of the syntax.)
#
- # === Examples
# # Assert that there is not a "div" containing a "p"
# assert_no_tag :tag => "div", :descendant => { :tag => "p" }
#
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index 69d54f6981..08fd28d72d 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -201,9 +201,16 @@ module ActionDispatch
reset!
end
- remove_method :default_url_options
- def default_url_options
- { :host => host, :protocol => https? ? "https" : "http" }
+ def url_options
+ @url_options ||= default_url_options.dup.tap do |url_options|
+ url_options.reverse_merge!(controller.url_options) if controller
+
+ if @app.respond_to?(:routes) && @app.routes.respond_to?(:default_url_options)
+ url_options.reverse_merge!(@app.routes.default_url_options)
+ end
+
+ url_options.reverse_merge!(:host => host, :protocol => https? ? "https" : "http")
+ end
end
# Resets the instance. This can be used to reset the state information
@@ -216,6 +223,7 @@ module ActionDispatch
@controller = @request = @response = nil
@_mock_session = nil
@request_count = 0
+ @url_options = nil
self.host = DEFAULT_HOST
self.remote_addr = "127.0.0.1"
@@ -310,6 +318,7 @@ module ActionDispatch
response = _mock_session.last_response
@response = ActionDispatch::TestResponse.new(response.status, response.headers, response.body)
@html_document = nil
+ @url_options = nil
@controller = session.last_request.env['action_controller.instance']
@@ -367,12 +376,14 @@ module ActionDispatch
end
end
- extend ActiveSupport::Concern
- include ActionDispatch::Routing::UrlFor
+ def default_url_options
+ reset! unless integration_session
+ integration_session.default_url_options
+ end
- def url_options
+ def default_url_options=(options)
reset! unless integration_session
- integration_session.url_options
+ integration_session.default_url_options = options
end
def respond_to?(method, include_private = false)
@@ -476,6 +487,7 @@ module ActionDispatch
class IntegrationTest < ActiveSupport::TestCase
include Integration::Runner
include ActionController::TemplateAssertions
+ include ActionDispatch::Routing::UrlFor
@@app = nil
@@ -495,5 +507,10 @@ module ActionDispatch
def app
super || self.class.app
end
+
+ def url_options
+ reset! unless integration_session
+ integration_session.url_options
+ end
end
end
diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb
index 349a3fcc6e..3823f87027 100644
--- a/actionpack/lib/action_view.rb
+++ b/actionpack/lib/action_view.rb
@@ -21,9 +21,7 @@
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#++
-require 'active_support/ruby/shim'
-require 'active_support/core_ext/class/attribute_accessors'
-
+require 'active_support'
require 'action_pack'
module ActionView
@@ -78,7 +76,8 @@ module ActionView
ENCODING_FLAG = '#.*coding[:=]\s*(\S+)[ \t]*'
end
-require 'active_support/i18n'
require 'active_support/core_ext/string/output_safety'
-I18n.load_path << "#{File.dirname(__FILE__)}/action_view/locale/en.yml"
+ActiveSupport.on_load(:i18n) do
+ I18n.load_path << "#{File.dirname(__FILE__)}/action_view/locale/en.yml"
+end
diff --git a/actionpack/lib/action_view/asset_paths.rb b/actionpack/lib/action_view/asset_paths.rb
index add8d94b70..4ce41d51f1 100644
--- a/actionpack/lib/action_view/asset_paths.rb
+++ b/actionpack/lib/action_view/asset_paths.rb
@@ -4,7 +4,7 @@ require 'action_controller/metal/exceptions'
module ActionView
class AssetPaths #:nodoc:
- URI_REGEXP = %r{^[-a-z]+://|^cid:|^//}
+ URI_REGEXP = %r{^[-a-z]+://|^(?:cid|data):|^//}
attr_reader :config, :controller
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index 5f81f24a2e..f98648d930 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -1,6 +1,7 @@
require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/class/attribute'
+require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/ordered_options'
require 'action_view/log_subscriber'
diff --git a/actionpack/lib/action_view/context.rb b/actionpack/lib/action_view/context.rb
index 083856b2ca..245849d706 100644
--- a/actionpack/lib/action_view/context.rb
+++ b/actionpack/lib/action_view/context.rb
@@ -5,7 +5,7 @@ module ActionView
# = Action View Context
#
- # Action View contexts are supplied to Action Controller to render template.
+ # Action View contexts are supplied to Action Controller to render a template.
# The default Action View context is ActionView::Base.
#
# In order to work with ActionController, a Context must just include this module.
@@ -25,7 +25,7 @@ module ActionView
end
# Encapsulates the interaction with the view flow so it
- # returns the correct buffer on yield. This is usually
+ # returns the correct buffer on +yield+. This is usually
# overwriten by helpers to add more behavior.
# :api: plugin
def _layout_for(name=nil)
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index adc62ec6a9..a7a4ce21ff 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -252,7 +252,6 @@ module ActionView
# The following call would generate such a tag:
#
# <%= favicon_link_tag 'mb-icon.png', :rel => 'apple-touch-icon', :type => 'image/png' %>
- #
def favicon_link_tag(source='favicon.ico', options={})
tag('link', {
:rel => 'shortcut icon',
@@ -261,13 +260,13 @@ module ActionView
}.merge(options.symbolize_keys))
end
- # Computes the path to an image asset in the public images directory.
+ # Computes the path to an image asset.
# Full paths from the document root will be passed through.
# Used internally by +image_tag+ to build the image path:
#
- # image_path("edit") # => "/images/edit"
- # image_path("edit.png") # => "/images/edit.png"
- # image_path("icons/edit.png") # => "/images/icons/edit.png"
+ # image_path("edit") # => "/assets/edit"
+ # image_path("edit.png") # => "/assets/edit.png"
+ # image_path("icons/edit.png") # => "/assets/icons/edit.png"
# image_path("/icons/edit.png") # => "/icons/edit.png"
# image_path("http://www.example.com/img/edit.png") # => "http://www.example.com/img/edit.png"
#
@@ -279,7 +278,7 @@ module ActionView
end
alias_method :path_to_image, :image_path # aliased to avoid conflicts with an image_path named route
- # Computes the full URL to an image asset in the public images directory.
+ # Computes the full URL to an image asset.
# This will use +image_path+ internally, so most of their behaviors will be the same.
def image_url(source)
URI.join(current_host, path_to_image(source)).to_s
@@ -290,7 +289,6 @@ module ActionView
# Full paths from the document root will be passed through.
# Used internally by +video_tag+ to build the video path.
#
- # ==== Examples
# video_path("hd") # => /videos/hd
# video_path("hd.avi") # => /videos/hd.avi
# video_path("trailers/hd.avi") # => /videos/trailers/hd.avi
@@ -312,7 +310,6 @@ module ActionView
# Full paths from the document root will be passed through.
# Used internally by +audio_tag+ to build the audio path.
#
- # ==== Examples
# audio_path("horse") # => /audios/horse
# audio_path("horse.wav") # => /audios/horse.wav
# audio_path("sounds/horse.wav") # => /audios/sounds/horse.wav
@@ -323,20 +320,19 @@ module ActionView
end
alias_method :path_to_audio, :audio_path # aliased to avoid conflicts with an audio_path named route
- # Computes the full URL to a audio asset in the public audios directory.
+ # Computes the full URL to an audio asset in the public audios directory.
# This will use +audio_path+ internally, so most of their behaviors will be the same.
def audio_url(source)
URI.join(current_host, path_to_audio(source)).to_s
end
alias_method :url_to_audio, :audio_url # aliased to avoid conflicts with an audio_url named route
- # Computes the path to a font asset in the public fonts directory.
+ # Computes the path to a font asset.
# Full paths from the document root will be passed through.
#
- # ==== Examples
- # font_path("font") # => /fonts/font
- # font_path("font.ttf") # => /fonts/font.ttf
- # font_path("dir/font.ttf") # => /fonts/dir/font.ttf
+ # font_path("font") # => /assets/font
+ # font_path("font.ttf") # => /assets/font.ttf
+ # font_path("dir/font.ttf") # => /assets/dir/font.ttf
# font_path("/dir/font.ttf") # => /dir/font.ttf
# font_path("http://www.example.com/dir/font.ttf") # => http://www.example.com/dir/font.ttf
def font_path(source)
@@ -344,7 +340,7 @@ module ActionView
end
alias_method :path_to_font, :font_path # aliased to avoid conflicts with an font_path named route
- # Computes the full URL to a font asset in the public fonts directory.
+ # Computes the full URL to a font asset.
# This will use +font_path+ internally, so most of their behaviors will be the same.
def font_url(source)
URI.join(current_host, path_to_font(source)).to_s
@@ -352,7 +348,7 @@ module ActionView
alias_method :url_to_font, :font_url # aliased to avoid conflicts with an font_url named route
# Returns an html image tag for the +source+. The +source+ can be a full
- # path or a file that exists in your public images directory.
+ # path or a file.
#
# ==== Options
# You can add HTML attributes using the +options+. The +options+ supports
@@ -363,33 +359,25 @@ module ActionView
# * <tt>:size</tt> - Supplied as "{Width}x{Height}", so "30x45" becomes
# width="30" and height="45". <tt>:size</tt> will be ignored if the
# value is not in the correct format.
- # * <tt>:mouseover</tt> - Set an alternate image to be used when the onmouseover
- # event is fired, and sets the original image to be replaced onmouseout.
- # This can be used to implement an easy image toggle that fires on onmouseover.
#
- # ==== Examples
# image_tag("icon") # =>
- # <img src="/images/icon" alt="Icon" />
+ # <img src="/assets/icon" alt="Icon" />
# image_tag("icon.png") # =>
- # <img src="/images/icon.png" alt="Icon" />
+ # <img src="/assets/icon.png" alt="Icon" />
# image_tag("icon.png", :size => "16x10", :alt => "Edit Entry") # =>
- # <img src="/images/icon.png" width="16" height="10" alt="Edit Entry" />
+ # <img src="/assets/icon.png" width="16" height="10" alt="Edit Entry" />
# image_tag("/icons/icon.gif", :size => "16x16") # =>
# <img src="/icons/icon.gif" width="16" height="16" alt="Icon" />
# image_tag("/icons/icon.gif", :height => '32', :width => '32') # =>
# <img alt="Icon" height="32" src="/icons/icon.gif" width="32" />
# image_tag("/icons/icon.gif", :class => "menu_icon") # =>
# <img alt="Icon" class="menu_icon" src="/icons/icon.gif" />
- # image_tag("mouse.png", :mouseover => "/images/mouse_over.png") # =>
- # <img src="/images/mouse.png" onmouseover="this.src='/images/mouse_over.png'" onmouseout="this.src='/images/mouse.png'" alt="Mouse" />
- # image_tag("mouse.png", :mouseover => image_path("mouse_over.png")) # =>
- # <img src="/images/mouse.png" onmouseover="this.src='/images/mouse_over.png'" onmouseout="this.src='/images/mouse.png'" alt="Mouse" />
def image_tag(source, options={})
options = options.symbolize_keys
src = options[:src] = path_to_image(source)
- unless src =~ /^cid:/
+ unless src =~ /^(?:cid|data):/
options[:alt] = options.fetch(:alt){ image_alt(src) }
end
@@ -397,11 +385,6 @@ module ActionView
options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$}
end
- if mouseover = options.delete(:mouseover)
- options[:onmouseover] = "this.src='#{path_to_image(mouseover)}'"
- options[:onmouseout] = "this.src='#{src}'"
- end
-
tag("img", options)
end
@@ -425,7 +408,6 @@ module ActionView
# width="30" and height="45". <tt>:size</tt> will be ignored if the
# value is not in the correct format.
#
- # ==== Examples
# video_tag("trailer") # =>
# <video src="/videos/trailer" />
# video_tag("trailer.ogg") # =>
@@ -433,7 +415,7 @@ module ActionView
# video_tag("trailer.ogg", :controls => true, :autobuffer => true) # =>
# <video autobuffer="autobuffer" controls="controls" src="/videos/trailer.ogg" />
# video_tag("trailer.m4v", :size => "16x10", :poster => "screenshot.png") # =>
- # <video src="/videos/trailer.m4v" width="16" height="10" poster="/images/screenshot.png" />
+ # <video src="/videos/trailer.m4v" width="16" height="10" poster="/assets/screenshot.png" />
# video_tag("/trailers/hd.avi", :size => "16x16") # =>
# <video src="/trailers/hd.avi" width="16" height="16" />
# video_tag("/trailers/hd.avi", :height => '32', :width => '32') # =>
@@ -458,15 +440,14 @@ module ActionView
# The +source+ can be full path or file that exists in
# your public audios directory.
#
- # ==== Examples
- # audio_tag("sound") # =>
- # <audio src="/audios/sound" />
- # audio_tag("sound.wav") # =>
- # <audio src="/audios/sound.wav" />
- # audio_tag("sound.wav", :autoplay => true, :controls => true) # =>
- # <audio autoplay="autoplay" controls="controls" src="/audios/sound.wav" />
- # audio_tag("sound.wav", "sound.mid") # =>
- # <audio><source src="/audios/sound.wav" /><source src="/audios/sound.mid" /></audio>
+ # audio_tag("sound") # =>
+ # <audio src="/audios/sound" />
+ # audio_tag("sound.wav") # =>
+ # <audio src="/audios/sound.wav" />
+ # audio_tag("sound.wav", :autoplay => true, :controls => true) # =>
+ # <audio autoplay="autoplay" controls="controls" src="/audios/sound.wav" />
+ # audio_tag("sound.wav", "sound.mid") # =>
+ # <audio><source src="/audios/sound.wav" /><source src="/audios/sound.mid" /></audio>
def audio_tag(*sources)
multiple_sources_tag('audio', sources)
end
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb
index 7bff0c1149..4292d29f60 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb
@@ -76,7 +76,6 @@ module ActionView
# Full paths from the document root will be passed through.
# Used internally by javascript_include_tag to build the script path.
#
- # ==== Examples
# javascript_path "xmlhr" # => /javascripts/xmlhr.js
# javascript_path "dir/xmlhr.js" # => /javascripts/dir/xmlhr.js
# javascript_path "/dir/xmlhr" # => /dir/xmlhr.js
@@ -114,7 +113,6 @@ module ActionView
# You can modify the HTML attributes of the script tag by passing a hash as the
# last argument.
#
- # ==== Examples
# javascript_include_tag "xmlhr"
# # => <script src="/javascripts/xmlhr.js?1284139606"></script>
#
@@ -160,8 +158,6 @@ module ActionView
# <tt>config.perform_caching</tt> is set to true (which is the case by default for the Rails
# production environment, but not for the development environment).
#
- # ==== Examples
- #
# # assuming config.perform_caching is false
# javascript_include_tag :all, :cache => true
# # => <script src="/javascripts/jquery.js?1284139606"></script>
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb
index 4bcb8b9718..57b0627225 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb
@@ -54,7 +54,6 @@ module ActionView
# Full paths from the document root will be passed through.
# Used internally by +stylesheet_link_tag+ to build the stylesheet path.
#
- # ==== Examples
# stylesheet_path "style" # => /stylesheets/style.css
# stylesheet_path "dir/style.css" # => /stylesheets/dir/style.css
# stylesheet_path "/dir/style.css" # => /dir/style.css
@@ -79,7 +78,6 @@ module ActionView
# to "screen", so you must explicitely set it to "all" for the stylesheet(s) to
# apply to all media types.
#
- # ==== Examples
# stylesheet_link_tag "style" # =>
# <link href="/stylesheets/style.css" media="screen" rel="stylesheet" />
#
@@ -117,7 +115,6 @@ module ActionView
# is set to true (which is the case by default for the Rails production environment, but not for the development
# environment). Examples:
#
- # ==== Examples
# stylesheet_link_tag :all, :cache => true # when config.perform_caching is false =>
# <link href="/stylesheets/style1.css" media="screen" rel="stylesheet" />
# <link href="/stylesheets/styleB.css" media="screen" rel="stylesheet" />
diff --git a/actionpack/lib/action_view/helpers/cache_helper.rb b/actionpack/lib/action_view/helpers/cache_helper.rb
index 850dd5f448..33799d7d71 100644
--- a/actionpack/lib/action_view/helpers/cache_helper.rb
+++ b/actionpack/lib/action_view/helpers/cache_helper.rb
@@ -10,7 +10,6 @@ module ActionView
#
# See ActionController::Caching::Fragments for usage instructions.
#
- # ==== Examples
# If you want to cache a navigation menu, you can do following:
#
# <% cache do %>
diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb
index d9d6f90211..397738dd98 100644
--- a/actionpack/lib/action_view/helpers/capture_helper.rb
+++ b/actionpack/lib/action_view/helpers/capture_helper.rb
@@ -13,7 +13,6 @@ module ActionView
# The capture method allows you to extract part of a template into a
# variable. You can then use this variable anywhere in your templates or layout.
#
- # ==== Examples
# The capture method can be used in ERB templates...
#
# <% @greeting = capture do %>
diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb
index f0a593d2c1..659aacf6d7 100644
--- a/actionpack/lib/action_view/helpers/date_helper.rb
+++ b/actionpack/lib/action_view/helpers/date_helper.rb
@@ -64,7 +64,6 @@ module ActionView
# distance_of_time_in_words(from_time, to_time, :include_seconds => true) # => about 6 years
# distance_of_time_in_words(to_time, from_time, :include_seconds => true) # => about 6 years
# distance_of_time_in_words(Time.now, Time.now) # => less than a minute
- #
def distance_of_time_in_words(from_time, to_time = 0, include_seconds_or_options = {}, options = {})
if include_seconds_or_options.is_a?(Hash)
options = include_seconds_or_options
@@ -140,7 +139,6 @@ module ActionView
# Like <tt>distance_of_time_in_words</tt>, but where <tt>to_time</tt> is fixed to <tt>Time.now</tt>.
#
- # ==== Examples
# time_ago_in_words(3.minutes.from_now) # => 3 minutes
# time_ago_in_words(Time.now - 15.hours) # => about 15 hours
# time_ago_in_words(Time.now) # => less than a minute
@@ -148,7 +146,6 @@ module ActionView
#
# from_time = Time.now - 3.days - 14.minutes - 25.seconds
# time_ago_in_words(from_time) # => 3 days
- #
def time_ago_in_words(from_time, include_seconds_or_options = {})
distance_of_time_in_words(from_time, Time.now, include_seconds_or_options)
end
@@ -197,7 +194,6 @@ module ActionView
#
# NOTE: Discarded selects will default to 1. So if no month select is available, January will be assumed.
#
- # ==== Examples
# # Generates a date select that when POSTed is stored in the article variable, in the written_on attribute.
# date_select("article", "written_on")
#
@@ -253,7 +249,6 @@ module ActionView
#
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
#
- # ==== Examples
# # Creates a time select tag that, when POSTed, will be stored in the article variable in the sunrise attribute.
# time_select("article", "sunrise")
#
@@ -286,7 +281,6 @@ module ActionView
#
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
#
- # ==== Examples
# # Generates a datetime select that, when POSTed, will be stored in the article variable in the written_on
# # attribute.
# datetime_select("article", "written_on")
@@ -325,7 +319,6 @@ module ActionView
#
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
#
- # ==== Examples
# my_date_time = Time.now + 4.days
#
# # Generates a datetime select that defaults to the datetime in my_date_time (four days after today).
@@ -362,7 +355,6 @@ module ActionView
# select_datetime(my_date_time, :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
# select_datetime(my_date_time, :prompt => {:hour => true}) # generic prompt for hours
# select_datetime(my_date_time, :prompt => true) # generic prompts for all
- #
def select_datetime(datetime = Time.current, options = {}, html_options = {})
DateTimeSelector.new(datetime, options, html_options).select_datetime
end
@@ -374,7 +366,6 @@ module ActionView
#
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
#
- # ==== Examples
# my_date = Time.now + 6.days
#
# # Generates a date select that defaults to the date in my_date (six days after today).
@@ -403,7 +394,6 @@ module ActionView
# select_date(my_date, :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
# select_date(my_date, :prompt => {:hour => true}) # generic prompt for hours
# select_date(my_date, :prompt => true) # generic prompts for all
- #
def select_date(date = Date.current, options = {}, html_options = {})
DateTimeSelector.new(date, options, html_options).select_date
end
@@ -414,7 +404,6 @@ module ActionView
#
# If anything is passed in the html_options hash it will be applied to every select tag in the set.
#
- # ==== Examples
# my_time = Time.now + 5.days + 7.hours + 3.minutes + 14.seconds
#
# # Generates a time select that defaults to the time in my_time.
@@ -442,7 +431,6 @@ module ActionView
# select_time(my_time, :prompt => {:day => 'Choose day', :month => 'Choose month', :year => 'Choose year'})
# select_time(my_time, :prompt => {:hour => true}) # generic prompt for hours
# select_time(my_time, :prompt => true) # generic prompts for all
- #
def select_time(datetime = Time.current, options = {}, html_options = {})
DateTimeSelector.new(datetime, options, html_options).select_time
end
@@ -451,7 +439,6 @@ module ActionView
# The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
# Override the field name using the <tt>:field_name</tt> option, 'second' by default.
#
- # ==== Examples
# my_time = Time.now + 16.minutes
#
# # Generates a select field for seconds that defaults to the seconds for the time in my_time.
@@ -467,7 +454,6 @@ module ActionView
# # Generates a select field for seconds with a custom prompt. Use <tt>:prompt => true</tt> for a
# # generic prompt.
# select_second(14, :prompt => 'Choose seconds')
- #
def select_second(datetime, options = {}, html_options = {})
DateTimeSelector.new(datetime, options, html_options).select_second
end
@@ -477,7 +463,6 @@ module ActionView
# selected. The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
# Override the field name using the <tt>:field_name</tt> option, 'minute' by default.
#
- # ==== Examples
# my_time = Time.now + 6.hours
#
# # Generates a select field for minutes that defaults to the minutes for the time in my_time.
@@ -493,7 +478,6 @@ module ActionView
# # Generates a select field for minutes with a custom prompt. Use <tt>:prompt => true</tt> for a
# # generic prompt.
# select_minute(14, :prompt => 'Choose minutes')
- #
def select_minute(datetime, options = {}, html_options = {})
DateTimeSelector.new(datetime, options, html_options).select_minute
end
@@ -502,7 +486,6 @@ module ActionView
# The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
# Override the field name using the <tt>:field_name</tt> option, 'hour' by default.
#
- # ==== Examples
# my_time = Time.now + 6.hours
#
# # Generates a select field for hours that defaults to the hour for the time in my_time.
@@ -521,7 +504,6 @@ module ActionView
#
# # Generate a select field for hours in the AM/PM format
# select_hour(my_time, :ampm => true)
- #
def select_hour(datetime, options = {}, html_options = {})
DateTimeSelector.new(datetime, options, html_options).select_hour
end
@@ -531,7 +513,6 @@ module ActionView
# If you want to display days with a leading zero set the <tt>:use_two_digit_numbers</tt> key in +options+ to true.
# Override the field name using the <tt>:field_name</tt> option, 'day' by default.
#
- # ==== Examples
# my_date = Time.now + 2.days
#
# # Generates a select field for days that defaults to the day for the date in my_date.
@@ -550,7 +531,6 @@ module ActionView
# # Generates a select field for days with a custom prompt. Use <tt>:prompt => true</tt> for a
# # generic prompt.
# select_day(5, :prompt => 'Choose day')
- #
def select_day(date, options = {}, html_options = {})
DateTimeSelector.new(date, options, html_options).select_day
end
@@ -565,7 +545,6 @@ module ActionView
# If you want to display months with a leading zero set the <tt>:use_two_digit_numbers</tt> key in +options+ to true.
# Override the field name using the <tt>:field_name</tt> option, 'month' by default.
#
- # ==== Examples
# # Generates a select field for months that defaults to the current month that
# # will use keys like "January", "March".
# select_month(Date.today)
@@ -597,7 +576,6 @@ module ActionView
# # Generates a select field for months with a custom prompt. Use <tt>:prompt => true</tt> for a
# # generic prompt.
# select_month(14, :prompt => 'Choose month')
- #
def select_month(date, options = {}, html_options = {})
DateTimeSelector.new(date, options, html_options).select_month
end
@@ -608,7 +586,6 @@ module ActionView
# greater than <tt>:end_year</tt>. The <tt>date</tt> can also be substituted for a year given as a number.
# Override the field name using the <tt>:field_name</tt> option, 'year' by default.
#
- # ==== Examples
# # Generates a select field for years that defaults to the current year that
# # has ascending year values.
# select_year(Date.today, :start_year => 1992, :end_year => 2007)
@@ -628,14 +605,12 @@ module ActionView
# # Generates a select field for years with a custom prompt. Use <tt>:prompt => true</tt> for a
# # generic prompt.
# select_year(14, :prompt => 'Choose year')
- #
def select_year(date, options = {}, html_options = {})
DateTimeSelector.new(date, options, html_options).select_year
end
# Returns an html time tag for the given date or time.
#
- # ==== Examples
# time_tag Date.today # =>
# <time datetime="2010-11-04">November 04, 2010</time>
# time_tag Time.now # =>
@@ -649,7 +624,6 @@ module ActionView
# <span>Right now</span>
# <% end %>
# # => <time datetime="2010-11-04T17:55:45+01:00"><span>Right now</span></time>
- #
def time_tag(date_or_time, *args, &block)
options = args.extract_options!
format = options.delete(:format) || :long
diff --git a/actionpack/lib/action_view/helpers/debug_helper.rb b/actionpack/lib/action_view/helpers/debug_helper.rb
index c0cc7d347c..878a8734a4 100644
--- a/actionpack/lib/action_view/helpers/debug_helper.rb
+++ b/actionpack/lib/action_view/helpers/debug_helper.rb
@@ -8,8 +8,6 @@ module ActionView
# If the object cannot be converted to YAML using +to_yaml+, +inspect+ will be called instead.
# Useful for inspecting an object at the time of rendering.
#
- # ==== Example
- #
# @user = User.new({ :username => 'testing', :password => 'xyz', :age => 42}) %>
# debug(@user)
# # =>
@@ -25,7 +23,6 @@ module ActionView
#
# new_record: true
# </pre>
-
def debug(object)
begin
Marshal::dump(object)
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 67f2abe509..cc1f133196 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -5,6 +5,7 @@ require 'action_view/helpers/form_tag_helper'
require 'action_view/helpers/active_model_helper'
require 'action_view/helpers/tags'
require 'active_support/core_ext/class/attribute'
+require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/string/output_safety'
@@ -899,7 +900,6 @@ module ActionView
# In that case it is preferable to either use +check_box_tag+ or to use
# hashes instead of arrays.
#
- # ==== Examples
# # Let's say that @post.validated? is 1:
# check_box("post", "validated")
# # => <input name="post[validated]" type="hidden" value="0" />
@@ -925,7 +925,6 @@ module ActionView
# To force the radio button to be checked pass <tt>:checked => true</tt> in the
# +options+ hash. You may pass HTML options there as well.
#
- # ==== Examples
# # Let's say that @post.category returns "rails":
# radio_button("post", "category", "rails")
# radio_button("post", "category", "java")
@@ -944,8 +943,6 @@ module ActionView
# assigned to the template (identified by +object_name+). Inputs of type "search" may be styled differently by
# some browsers.
#
- # ==== Examples
- #
# search_field(:user, :name)
# # => <input id="user_name" name="user[name]" type="search" />
# search_field(:user, :name, :autosave => false)
@@ -961,7 +958,6 @@ module ActionView
# # => <input autosave="false" id="user_name" incremental="true" name="user[name]" onsearch="true" type="search" />
# search_field(:user, :name, :autosave => true, :onsearch => true)
# # => <input autosave="com.example.www" id="user_name" incremental="true" name="user[name]" onsearch="true" results="10" type="search" />
- #
def search_field(object_name, method, options = {})
Tags::SearchField.new(object_name, method, self, options).render
end
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index cafcd93f58..52eb1aa447 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -264,7 +264,6 @@ module ActionView
# Finally, this method supports a <tt>:default</tt> option, which selects
# a default ActiveSupport::TimeZone if the object's time zone is +nil+.
#
- # Examples:
# time_zone_select( "user", "time_zone", nil, :include_blank => true)
#
# time_zone_select( "user", "time_zone", nil, :default => "Pacific Time (US & Canada)" )
@@ -461,8 +460,11 @@ module ActionView
# * +selected_key+ - A value equal to the +value+ attribute for one of the <tt><option></tt> tags,
# which will have the +selected+ attribute set. Note: It is possible for this value to match multiple options
# as you might have the same option in multiple groups. Each will then get <tt>selected="selected"</tt>.
- # * +prompt+ - set to true or a prompt string. When the select element doesn't have a value yet, this
+ #
+ # Options:
+ # * <tt>:prompt</tt> - set to true or a prompt string. When the select element doesn't have a value yet, this
# prepends an option with a generic prompt - "Please select" - or the given prompt string.
+ # * <tt>:divider</tt> - the divider for the options groups.
#
# Sample usage (Array):
# grouped_options = [
@@ -491,15 +493,51 @@ module ActionView
# <option value="Canada">Canada</option>
# </optgroup>
#
+ # Sample usage (divider):
+ # grouped_options = [
+ # [['United States','US'], 'Canada'],
+ # ['Denmark','Germany','France']
+ # ]
+ # grouped_options_for_select(grouped_options, divider: '---------')
+ #
+ # Possible output:
+ # <optgroup label="---------">
+ # <option value="Denmark">Denmark</option>
+ # <option value="Germany">Germany</option>
+ # <option value="France">France</option>
+ # </optgroup>
+ # <optgroup label="---------">
+ # <option value="US">United States</option>
+ # <option value="Canada">Canada</option>
+ # </optgroup>
+ #
# <b>Note:</b> Only the <tt><optgroup></tt> and <tt><option></tt> tags are returned, so you still have to
# wrap the output in an appropriate <tt><select></tt> tag.
- def grouped_options_for_select(grouped_options, selected_key = nil, prompt = nil)
+ def grouped_options_for_select(*args)
+ grouped_options = args.shift
+ options = args.extract_options!
+ selected_key = args.shift
+ if prompt = args.shift
+ ActiveSupport::Deprecation.warn 'Passing the prompt to grouped_options_for_select as an argument is deprecated. Please pass it in an options hash.'
+ else
+ prompt = options[:prompt]
+ divider = options[:divider]
+ end
+
body = "".html_safe
- body.safe_concat content_tag(:option, prompt, :value => "") if prompt
+
+ if prompt
+ body.safe_concat content_tag(:option, prompt_text(prompt), :value => "")
+ end
grouped_options = grouped_options.sort if grouped_options.is_a?(Hash)
- grouped_options.each do |label, container|
+ grouped_options.each do |container|
+ if divider
+ label, container = divider, container
+ else
+ label, container = container
+ end
body.safe_concat content_tag(:optgroup, options_for_select(container, selected_key), :label => label)
end
@@ -715,6 +753,10 @@ module ActionView
def value_for_collection(item, value)
value.respond_to?(:call) ? value.call(item) : item.send(value)
end
+
+ def prompt_text(prompt)
+ prompt = prompt.kind_of?(String) ? prompt : I18n.translate('helpers.select.prompt', :default => 'Please select')
+ end
end
class FormBuilder
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index 248cc2f6a3..9e5c66f4a9 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -386,9 +386,6 @@ module ActionView
# drivers will provide a prompt with the question specified. If the user accepts,
# the form is processed normally, otherwise no action is taken.
# * <tt>:disabled</tt> - If true, the user will not be able to use this input.
- # * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a
- # disabled version of the submit button when the form is submitted. This feature is
- # provided by the unobtrusive JavaScript driver.
# * Any other key creates standard HTML options for the tag.
#
# ==== Examples
@@ -401,14 +398,14 @@ module ActionView
# submit_tag "Save edits", :disabled => true
# # => <input disabled="disabled" name="commit" type="submit" value="Save edits" />
#
- # submit_tag "Complete sale", :disable_with => "Please wait..."
+ # submit_tag "Complete sale", :data => { :disable_with => "Please wait..." }
# # => <input name="commit" data-disable-with="Please wait..." type="submit" value="Complete sale" />
#
# submit_tag nil, :class => "form_submit"
# # => <input class="form_submit" name="commit" type="submit" />
#
- # submit_tag "Edit", :disable_with => "Editing...", :class => "edit_button"
- # # => <input class="edit_button" data-disable-with="Editing..." name="commit" type="submit" value="Edit" />
+ # submit_tag "Edit", :class => "edit_button"
+ # # => <input class="edit_button" name="commit" type="submit" value="Edit" />
#
# submit_tag "Save", :confirm => "Are you sure?"
# # => <input name='commit' type='submit' value='Save' data-confirm="Are you sure?" />
@@ -416,10 +413,6 @@ module ActionView
def submit_tag(value = "Save changes", options = {})
options = options.stringify_keys
- if disable_with = options.delete("disable_with")
- options["data-disable-with"] = disable_with
- end
-
if confirm = options.delete("confirm")
options["data-confirm"] = confirm
end
@@ -441,10 +434,6 @@ module ActionView
# processed normally, otherwise no action is taken.
# * <tt>:disabled</tt> - If true, the user will not be able to
# use this input.
- # * <tt>:disable_with</tt> - Value of this parameter will be
- # used as the value for a disabled version of the submit
- # button when the form is submitted. This feature is provided
- # by the unobtrusive JavaScript driver.
# * Any other key creates standard HTML options for the tag.
#
# ==== Examples
@@ -458,18 +447,11 @@ module ActionView
# # <strong>Ask me!</strong>
# # </button>
#
- # button_tag "Checkout", :disable_with => "Please wait..."
- # # => <button data-disable-with="Please wait..." name="button" type="submit">Checkout</button>
- #
def button_tag(content_or_options = nil, options = nil, &block)
options = content_or_options if block_given? && content_or_options.is_a?(Hash)
options ||= {}
options = options.stringify_keys
- if disable_with = options.delete("disable_with")
- options["data-disable-with"] = disable_with
- end
-
if confirm = options.delete("confirm")
options["data-confirm"] = confirm
end
diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb
index dfc26acfad..62455b97f9 100644
--- a/actionpack/lib/action_view/helpers/number_helper.rb
+++ b/actionpack/lib/action_view/helpers/number_helper.rb
@@ -254,7 +254,7 @@ module ActionView
parts = number.to_s.to_str.split('.')
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
- safe_join(parts, options[:separator])
+ parts.join(options[:separator]).html_safe
end
# Formats a +number+ with the specified level of
diff --git a/actionpack/lib/action_view/helpers/sanitize_helper.rb b/actionpack/lib/action_view/helpers/sanitize_helper.rb
index 7768c8c151..a727b910e5 100644
--- a/actionpack/lib/action_view/helpers/sanitize_helper.rb
+++ b/actionpack/lib/action_view/helpers/sanitize_helper.rb
@@ -69,8 +69,6 @@ module ActionView
# html-scanner tokenizer and so its HTML parsing ability is limited by
# that of html-scanner.
#
- # ==== Examples
- #
# strip_tags("Strip <i>these</i> tags!")
# # => Strip these tags!
#
@@ -85,7 +83,6 @@ module ActionView
# Strips all link tags from +text+ leaving just the link text.
#
- # ==== Examples
# strip_links('<a href="http://www.rubyonrails.org">Ruby on Rails</a>')
# # => Ruby on Rails
#
diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb
index f7afa48256..d5cd60e8a1 100644
--- a/actionpack/lib/action_view/helpers/tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/tag_helper.rb
@@ -103,7 +103,6 @@ module ActionView
# otherwise be recognized as markup. CDATA sections begin with the string
# <tt><![CDATA[</tt> and end with (and may not contain) the string <tt>]]></tt>.
#
- # ==== Examples
# cdata_section("<hello world>")
# # => <![CDATA[<hello world>]]>
#
@@ -119,7 +118,6 @@ module ActionView
# Returns an escaped version of +html+ without affecting existing escaped entities.
#
- # ==== Examples
# escape_once("1 < 2 &amp; 3")
# # => "1 &lt; 2 &amp; 3"
#
diff --git a/actionpack/lib/action_view/helpers/tags/base.rb b/actionpack/lib/action_view/helpers/tags/base.rb
index e4f431a6d7..e077cd5b3c 100644
--- a/actionpack/lib/action_view/helpers/tags/base.rb
+++ b/actionpack/lib/action_view/helpers/tags/base.rb
@@ -121,6 +121,7 @@ module ActionView
def select_content_tag(option_tags, options, html_options)
html_options = html_options.stringify_keys
add_default_name_and_id(html_options)
+ options[:include_blank] ||= true unless options[:prompt] || select_not_required?(html_options)
select = content_tag("select", add_options(option_tags, options, value(object)), html_options)
if html_options["multiple"] && options.fetch(:include_hidden, true)
@@ -130,13 +131,16 @@ module ActionView
end
end
+ def select_not_required?(html_options)
+ !html_options["required"] || html_options["multiple"] || html_options["size"].to_i > 1
+ end
+
def add_options(option_tags, options, value = nil)
if options[:include_blank]
option_tags = content_tag('option', options[:include_blank].kind_of?(String) ? options[:include_blank] : nil, :value => '') + "\n" + option_tags
end
if value.blank? && options[:prompt]
- prompt = options[:prompt].kind_of?(String) ? options[:prompt] : I18n.translate('helpers.select.prompt', :default => 'Please select')
- option_tags = content_tag('option', prompt, :value => '') + "\n" + option_tags
+ option_tags = content_tag('option', prompt_text(options[:prompt]), :value => '') + "\n" + option_tags
end
option_tags
end
diff --git a/actionpack/lib/action_view/helpers/tags/date_field.rb b/actionpack/lib/action_view/helpers/tags/date_field.rb
index bb968e9f39..0e79609d52 100644
--- a/actionpack/lib/action_view/helpers/tags/date_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/date_field.rb
@@ -5,7 +5,6 @@ module ActionView
def render
options = @options.stringify_keys
options["value"] = @options.fetch("value") { value(object).try(:to_date) }
- options["size"] = nil
@options = options
super
end
diff --git a/actionpack/lib/action_view/helpers/tags/file_field.rb b/actionpack/lib/action_view/helpers/tags/file_field.rb
index 56442e1c14..59f2ff71b4 100644
--- a/actionpack/lib/action_view/helpers/tags/file_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/file_field.rb
@@ -2,10 +2,6 @@ module ActionView
module Helpers
module Tags
class FileField < TextField #:nodoc:
- def render
- @options.update(:size => nil)
- super
- end
end
end
end
diff --git a/actionpack/lib/action_view/helpers/tags/hidden_field.rb b/actionpack/lib/action_view/helpers/tags/hidden_field.rb
index ea86596e0b..a8d13dc1b1 100644
--- a/actionpack/lib/action_view/helpers/tags/hidden_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/hidden_field.rb
@@ -2,10 +2,6 @@ module ActionView
module Helpers
module Tags
class HiddenField < TextField #:nodoc:
- def render
- @options.update(:size => nil)
- super
- end
end
end
end
diff --git a/actionpack/lib/action_view/helpers/tags/number_field.rb b/actionpack/lib/action_view/helpers/tags/number_field.rb
index e89fdbec46..9cd04434f0 100644
--- a/actionpack/lib/action_view/helpers/tags/number_field.rb
+++ b/actionpack/lib/action_view/helpers/tags/number_field.rb
@@ -4,7 +4,6 @@ module ActionView
class NumberField < TextField #:nodoc:
def render
options = @options.stringify_keys
- options['size'] ||= nil
if range = options.delete("in") || options.delete("within")
options.update("min" => range.min, "max" => range.max)
diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb
index fffc37ce9e..67117077dc 100644
--- a/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/actionpack/lib/action_view/helpers/text_helper.rb
@@ -37,7 +37,6 @@ module ActionView
# do not operate as expected in an eRuby code block. If you absolutely must
# output text within a non-output code block (i.e., <% %>), you can use the concat method.
#
- # ==== Examples
# <%
# concat "hello"
# # is the equivalent of <%= "hello" %>
@@ -67,8 +66,6 @@ module ActionView
# used in views, unless wrapped by <tt>raw()</tt>. Care should be taken if +text+ contains HTML tags
# or entities, because truncation may produce invalid HTML (such as unbalanced or incomplete tags).
#
- # ==== Examples
- #
# truncate("Once upon a time in a world far far away")
# # => "Once upon a time in a world..."
#
@@ -90,10 +87,9 @@ module ActionView
# Highlights one or more +phrases+ everywhere in +text+ by inserting it into
# a <tt>:highlighter</tt> string. The highlighter can be specialized by passing <tt>:highlighter</tt>
- # as a single-quoted string with \1 where the phrase is to be inserted (defaults to
+ # as a single-quoted string with <tt>\1</tt> where the phrase is to be inserted (defaults to
# '<mark>\1</mark>')
#
- # ==== Examples
# highlight('You searched for: rails', 'rails')
# # => You searched for: <mark>rails</mark>
#
@@ -108,7 +104,9 @@ module ActionView
#
# You can still use <tt>highlight</tt> with the old API that accepts the
# +highlighter+ as its optional third parameter:
- # highlight('You searched for: rails', 'rails', '<a href="search?q=\1">\1</a>') # => You searched for: <a href="search?q=rails">rails</a>
+ #
+ # highlight('You searched for: rails', 'rails', '<a href="search?q=\1">\1</a>')
+ # # => You searched for: <a href="search?q=rails">rails</a>
def highlight(text, phrases, *args)
options = args.extract_options!
unless args.empty?
@@ -131,7 +129,6 @@ module ActionView
# then the <tt>:omission</tt> option (which defaults to "...") will be prepended/appended accordingly. The resulting string
# will be stripped in any case. If the +phrase+ isn't found, nil is returned.
#
- # ==== Examples
# excerpt('This is an example', 'an', :radius => 5)
# # => ...s is an exam...
#
@@ -179,7 +176,6 @@ module ActionView
# +plural+ is supplied, it will use that when count is > 1, otherwise
# it will use the Inflector to determine the plural form
#
- # ==== Examples
# pluralize(1, 'person')
# # => 1 person
#
@@ -199,23 +195,23 @@ module ActionView
# breaks on the first whitespace character that does not exceed +line_width+
# (which is 80 by default).
#
- # ==== Examples
- #
# word_wrap('Once upon a time')
# # => Once upon a time
#
# word_wrap('Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding a successor to the throne turned out to be more trouble than anyone could have imagined...')
- # # => Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding\n a successor to the throne turned out to be more trouble than anyone could have\n imagined...
+ # # => Once upon a time, in a kingdom called Far Far Away, a king fell ill, and finding\na successor to the throne turned out to be more trouble than anyone could have\nimagined...
#
# word_wrap('Once upon a time', :line_width => 8)
- # # => Once upon\na time
+ # # => Once\nupon a\ntime
#
# word_wrap('Once upon a time', :line_width => 1)
# # => Once\nupon\na\ntime
#
# You can still use <tt>word_wrap</tt> with the old API that accepts the
# +line_width+ as its optional second parameter:
- # word_wrap('Once upon a time', 8) # => Once upon\na time
+ #
+ # word_wrap('Once upon a time', 8)
+ # # => Once\nupon a\ntime
def word_wrap(text, *args)
options = args.extract_options!
unless args.blank?
@@ -239,6 +235,7 @@ module ActionView
#
# ==== Options
# * <tt>:sanitize</tt> - If +false+, does not sanitize +text+.
+ # * <tt>:wrapper_tag</tt> - String representing the tag wrapper, defaults to <tt>"p"</tt>
#
# ==== Examples
# my_text = "Here is some basic text...\n...with a line break."
@@ -257,16 +254,17 @@ module ActionView
# simple_format("<span>I'm allowed!</span> It's true.", {}, :sanitize => false)
# # => "<p><span>I'm allowed!</span> It's true.</p>"
def simple_format(text, html_options={}, options={})
- text = '' if text.nil?
- text = text.dup
- start_tag = tag('p', html_options, true)
text = sanitize(text) unless options[:sanitize] == false
- text = text.to_str
- text.gsub!(/\r\n?/, "\n") # \r\n and \r -> \n
- text.gsub!(/\n\n+/, "</p>\n\n#{start_tag}") # 2+ newline -> paragraph
- text.gsub!(/([^\n]\n)(?=[^\n])/, '\1<br />') # 1 newline -> br
- text.insert 0, start_tag
- text.html_safe.safe_concat("</p>")
+ wrapper_tag = options.fetch(:wrapper_tag, :p)
+ paragraphs = split_paragraphs(text)
+
+ if paragraphs.empty?
+ content_tag(wrapper_tag, nil, html_options)
+ else
+ paragraphs.map { |paragraph|
+ content_tag(wrapper_tag, paragraph, html_options, options[:sanitize])
+ }.join("\n\n").html_safe
+ end
end
# Creates a Cycle object whose _to_s_ method cycles through elements of an
@@ -278,7 +276,6 @@ module ActionView
# and passing the name of the cycle. The current cycle string can be obtained
# anytime using the current_cycle method.
#
- # ==== Examples
# # Alternate CSS classes for even and odd numbers...
# @items = [1,2,3,4]
# <table>
@@ -324,7 +321,6 @@ module ActionView
# for complex table highlighting or any other design need which requires
# the current cycle string in more than one place.
#
- # ==== Example
# # Alternate background colors
# @items = [1,2,3,4]
# <% @items.each do |item| %>
@@ -340,7 +336,6 @@ module ActionView
# Resets a cycle so that it starts from the first element the next time
# it is called. Pass in +name+ to reset a named cycle.
#
- # ==== Example
# # Alternate CSS classes for even and odd numbers...
# @items = [[1,2,3,4], [5,6,3], [3,4,5,6,7,4]]
# <table>
@@ -411,6 +406,14 @@ module ActionView
@_cycles = Hash.new unless defined?(@_cycles)
@_cycles[name] = cycle_object
end
+
+ def split_paragraphs(text)
+ return [] if text.blank?
+
+ text.to_str.gsub(/\r\n?/, "\n").split(/\n\n+/).map! do |t|
+ t.gsub!(/([^\n]\n)(?=[^\n])/, '\1<br />') || t
+ end
+ end
end
end
end
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index 1145f348c2..7e69547dab 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -108,7 +108,7 @@ module ActionView
options
when nil, Hash
options ||= {}
- options = options.symbolize_keys.reverse_merge!(:only_path => options[:host].nil?)
+ options = { :only_path => options[:host].nil? }.merge!(options.symbolize_keys)
super
when :back
controller.request.env["HTTP_REFERER"] || 'javascript:history.back()'
@@ -322,11 +322,11 @@ module ActionView
#
#
# <%= button_to('Destroy', 'http://www.example.com', :confirm => 'Are you sure?',
- # :method => "delete", :remote => true, :disable_with => 'loading...') %>
+ # :method => "delete", :remote => true) %>
# # => "<form class='button_to' method='post' action='http://www.example.com' data-remote='true'>
# # <div>
# # <input name='_method' value='delete' type='hidden' />
- # # <input value='Destroy' type='submit' disable_with='loading...' data-confirm='Are you sure?' />
+ # # <input value='Destroy' type='submit' data-confirm='Are you sure?' />
# # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
# # </div>
# # </form>"
@@ -616,11 +616,9 @@ module ActionView
html_options = html_options.stringify_keys
html_options['data-remote'] = 'true' if link_to_remote_options?(options) || link_to_remote_options?(html_options)
- disable_with = html_options.delete("disable_with")
confirm = html_options.delete('confirm')
method = html_options.delete('method')
- html_options["data-disable-with"] = disable_with if disable_with
html_options["data-confirm"] = confirm if confirm
add_method_to_attributes!(html_options, method) if method
@@ -670,11 +668,11 @@ module ActionView
end
def token_tag(token=nil)
- if token == false || !protect_against_forgery?
- ''
- else
+ if token != false && protect_against_forgery?
token ||= form_authenticity_token
tag(:input, :type => "hidden", :name => request_forgery_protection_token.to_s, :value => token)
+ else
+ ''
end
end
diff --git a/actionpack/lib/action_view/renderer/abstract_renderer.rb b/actionpack/lib/action_view/renderer/abstract_renderer.rb
index 52473cd222..72616b7463 100644
--- a/actionpack/lib/action_view/renderer/abstract_renderer.rb
+++ b/actionpack/lib/action_view/renderer/abstract_renderer.rb
@@ -14,12 +14,10 @@ module ActionView
protected
def extract_details(options)
- details = {}
- @lookup_context.registered_details.each do |key|
+ @lookup_context.registered_details.each_with_object({}) do |key, details|
next unless value = options[key]
details[key] = Array(value)
end
- details
end
def instrument(name, options={})
diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb
index 87609fd5ff..9100545718 100644
--- a/actionpack/lib/action_view/renderer/partial_renderer.rb
+++ b/actionpack/lib/action_view/renderer/partial_renderer.rb
@@ -283,7 +283,7 @@ module ActionView
return nil if @collection.blank?
if @options.key?(:spacer_template)
- spacer = find_template(@options[:spacer_template]).render(@view, @locals)
+ spacer = find_template(@options[:spacer_template], @locals.keys).render(@view, @locals)
end
result = @template ? collection_with_template : collection_without_template
@@ -291,11 +291,11 @@ module ActionView
end
def render_partial
- locals, view, block = @locals, @view, @block
+ view, locals, block = @view, @locals, @block
object, as = @object, @variable
if !block && (layout = @options[:layout])
- layout = find_template(layout, @locals.keys + [@variable])
+ layout = find_template(layout, @template_keys)
end
object ||= locals[as]
@@ -337,6 +337,7 @@ module ActionView
if @path
@variable, @variable_counter = retrieve_variable(@path)
+ @template_keys = retrieve_template_keys
else
paths.map! { |path| retrieve_variable(path).unshift(path) }
end
@@ -358,62 +359,55 @@ module ActionView
end
def collection_from_object
- if @object.respond_to?(:to_ary)
- @object.to_ary
- end
+ @object.to_ary if @object.respond_to?(:to_ary)
end
def find_partial
if path = @path
- locals = @locals.keys
- locals << @variable
- locals << @variable_counter if @collection
- find_template(path, locals)
+ find_template(path, @template_keys)
end
end
- def find_template(path=@path, locals=@locals.keys)
+ def find_template(path, locals)
prefixes = path.include?(?/) ? [] : @lookup_context.prefixes
@lookup_context.find_template(path, prefixes, true, locals, @details)
end
def collection_with_template
- segments, locals, template = [], @locals, @template
+ view, locals, template = @view, @locals, @template
as, counter = @variable, @variable_counter
if layout = @options[:layout]
- layout = find_template(layout, @locals.keys + [@variable, @variable_counter])
+ layout = find_template(layout, @template_keys)
end
- locals[counter] = -1
-
- @collection.each do |object|
- locals[counter] += 1
- locals[as] = object
+ index = -1
+ @collection.map do |object|
+ locals[as] = object
+ locals[counter] = (index += 1)
- content = template.render(@view, locals)
- content = layout.render(@view, locals) { content } if layout
- segments << content
+ content = template.render(view, locals)
+ content = layout.render(view, locals) { content } if layout
+ content
end
-
- segments
end
def collection_without_template
- segments, locals, collection_data = [], @locals, @collection_data
- index, template, cache = -1, nil, {}
- keys = @locals.keys
+ view, locals, collection_data = @view, @locals, @collection_data
+ cache = {}
+ keys = @locals.keys
- @collection.each_with_index do |object, i|
- path, *data = collection_data[i]
- template = (cache[path] ||= find_template(path, keys + data))
- locals[data[0]] = object
- locals[data[1]] = (index += 1)
- segments << template.render(@view, locals)
- end
+ index = -1
+ @collection.map do |object|
+ index += 1
+ path, as, counter = collection_data[index]
- @template = template
- segments
+ locals[as] = object
+ locals[counter] = index
+
+ template = (cache[path] ||= find_template(path, keys + [as, counter]))
+ template.render(view, locals)
+ end
end
def partial_path(object = @object)
@@ -453,6 +447,13 @@ module ActionView
end
end
+ def retrieve_template_keys
+ keys = @locals.keys
+ keys << @variable
+ keys << @variable_counter if @collection
+ keys
+ end
+
def retrieve_variable(path)
variable = @options.fetch(:as) { path[%r'_?(\w+)(\.\w+)*$', 1] }.try(:to_sym)
variable_counter = :"#{variable}_counter" if @collection
diff --git a/actionpack/lib/action_view/template/handlers.rb b/actionpack/lib/action_view/template/handlers.rb
index 4e22bec6cc..41b14373a3 100644
--- a/actionpack/lib/action_view/template/handlers.rb
+++ b/actionpack/lib/action_view/template/handlers.rb
@@ -4,10 +4,12 @@ module ActionView #:nodoc:
module Handlers #:nodoc:
autoload :ERB, 'action_view/template/handlers/erb'
autoload :Builder, 'action_view/template/handlers/builder'
+ autoload :Raw, 'action_view/template/handlers/raw'
def self.extended(base)
base.register_default_template_handler :erb, ERB.new
base.register_template_handler :builder, Builder.new
+ base.register_template_handler :raw, Raw.new
end
@@template_handlers = {}
diff --git a/actionpack/lib/action_view/template/handlers/raw.rb b/actionpack/lib/action_view/template/handlers/raw.rb
new file mode 100644
index 0000000000..0c0d1fffcb
--- /dev/null
+++ b/actionpack/lib/action_view/template/handlers/raw.rb
@@ -0,0 +1,11 @@
+module ActionView
+ module Template::Handlers
+ class Raw
+ def call(template)
+ escaped = template.source.gsub(':', '\:')
+
+ '%q:' + escaped + ':;'
+ end
+ end
+ end
+end
diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb
index 8ea2e5bfe4..fa2038f78d 100644
--- a/actionpack/lib/action_view/template/resolver.rb
+++ b/actionpack/lib/action_view/template/resolver.rb
@@ -1,5 +1,6 @@
require "pathname"
require "active_support/core_ext/class"
+require "active_support/core_ext/class/attribute_accessors"
require "action_view/template"
module ActionView
@@ -170,7 +171,9 @@ module ActionView
def extract_handler_and_format(path, default_formats)
pieces = File.basename(path).split(".")
pieces.shift
- handler = Template.handler_for_extension(pieces.pop)
+ extension = pieces.pop
+ ActiveSupport::Deprecation.warn "The file #{path} did not specify a template handler. The default is currently ERB, but will change to RAW in the future." unless extension
+ handler = Template.handler_for_extension(extension)
format = pieces.last && Mime[pieces.last]
[handler, format]
end
diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb
index 22ba047328..ba06bcae51 100644
--- a/actionpack/test/abstract_unit.rb
+++ b/actionpack/test/abstract_unit.rb
@@ -1,11 +1,5 @@
require File.expand_path('../../../load_paths', __FILE__)
-lib = File.expand_path("#{File.dirname(__FILE__)}/../lib")
-$:.unshift(lib) unless $:.include?('lib') || $:.include?(lib)
-
-activemodel_path = File.expand_path('../../../activemodel/lib', __FILE__)
-$:.unshift(activemodel_path) if File.directory?(activemodel_path) && !$:.include?(activemodel_path)
-
$:.unshift(File.dirname(__FILE__) + '/lib')
$:.unshift(File.dirname(__FILE__) + '/fixtures/helpers')
$:.unshift(File.dirname(__FILE__) + '/fixtures/alternate_helpers')
diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb
index 9f2dbda25f..fb41dcb33a 100644
--- a/actionpack/test/controller/integration_test.rb
+++ b/actionpack/test/controller/integration_test.rb
@@ -615,3 +615,83 @@ class EnvironmentFilterIntegrationTest < ActionDispatch::IntegrationTest
assert_equal '[FILTERED]', request.filtered_env['rack.request.form_vars']
end
end
+
+class UrlOptionsIntegrationTest < ActionDispatch::IntegrationTest
+ class FooController < ActionController::Base
+ def index
+ render :text => "foo#index"
+ end
+
+ def show
+ render :text => "foo#show"
+ end
+
+ def edit
+ render :text => "foo#show"
+ end
+ end
+
+ class BarController < ActionController::Base
+ def default_url_options
+ { :host => "bar.com" }
+ end
+
+ def index
+ render :text => "foo#index"
+ end
+ end
+
+ def self.routes
+ @routes ||= ActionDispatch::Routing::RouteSet.new
+ end
+
+ def self.call(env)
+ routes.call(env)
+ end
+
+ def app
+ self.class
+ end
+
+ routes.draw do
+ default_url_options :host => "foo.com"
+
+ scope :module => "url_options_integration_test" do
+ get "/foo" => "foo#index", :as => :foos
+ get "/foo/:id" => "foo#show", :as => :foo
+ get "/foo/:id/edit" => "foo#edit", :as => :edit_foo
+ get "/bar" => "bar#index", :as => :bars
+ end
+ end
+
+ test "session uses default url options from routes" do
+ assert_equal "http://foo.com/foo", foos_url
+ end
+
+ test "current host overrides default url options from routes" do
+ get "/foo"
+ assert_response :success
+ assert_equal "http://www.example.com/foo", foos_url
+ end
+
+ test "controller can override default url options from request" do
+ get "/bar"
+ assert_response :success
+ assert_equal "http://bar.com/foo", foos_url
+ end
+
+ test "test can override default url options" do
+ default_url_options[:host] = "foobar.com"
+ assert_equal "http://foobar.com/foo", foos_url
+
+ get "/bar"
+ assert_response :success
+ assert_equal "http://foobar.com/foo", foos_url
+ end
+
+ test "current request path parameters are recalled" do
+ get "/foo/1"
+ assert_response :success
+ assert_equal "/foo/1/edit", url_for(:action => 'edit', :only_path => true)
+ end
+end
diff --git a/actionpack/test/controller/new_base/render_text_test.rb b/actionpack/test/controller/new_base/render_text_test.rb
index e0b38b29fa..f8d02e8b6c 100644
--- a/actionpack/test/controller/new_base/render_text_test.rb
+++ b/actionpack/test/controller/new_base/render_text_test.rb
@@ -65,7 +65,7 @@ module RenderText
class RenderTextTest < Rack::TestCase
describe "Rendering text using render :text"
- test "rendering text from a action with default options renders the text with the layout" do
+ test "rendering text from an action with default options renders the text with the layout" do
with_routing do |set|
set.draw { get ':controller', :action => 'index' }
@@ -75,7 +75,7 @@ module RenderText
end
end
- test "rendering text from a action with default options renders the text without the layout" do
+ test "rendering text from an action with default options renders the text without the layout" do
with_routing do |set|
set.draw { get ':controller', :action => 'index' }
diff --git a/actionpack/test/dispatch/routing_assertions_test.rb b/actionpack/test/dispatch/routing_assertions_test.rb
index e953029456..517354ae58 100644
--- a/actionpack/test/dispatch/routing_assertions_test.rb
+++ b/actionpack/test/dispatch/routing_assertions_test.rb
@@ -47,7 +47,7 @@ class RoutingAssertionsTest < ActionController::TestCase
def test_assert_recognizes_with_extras
assert_recognizes({ :controller => 'articles', :action => 'index', :page => '1' }, '/articles', { :page => '1' })
end
-
+
def test_assert_recognizes_with_method
assert_recognizes({ :controller => 'articles', :action => 'create' }, { :path => '/articles', :method => :post })
assert_recognizes({ :controller => 'articles', :action => 'update', :id => '1' }, { :path => '/articles/1', :method => :put })
@@ -57,7 +57,7 @@ class RoutingAssertionsTest < ActionController::TestCase
assert_raise(ActionController::RoutingError) do
assert_recognizes({ :controller => 'secure_articles', :action => 'index' }, 'http://test.host/secure/articles')
end
- assert_recognizes({ :controller => 'secure_articles', :action => 'index' }, 'https://test.host/secure/articles')
+ assert_recognizes({ :controller => 'secure_articles', :action => 'index', :protocol => 'https://' }, 'https://test.host/secure/articles')
end
def test_assert_recognizes_with_block_constraint
@@ -90,7 +90,7 @@ class RoutingAssertionsTest < ActionController::TestCase
assert_raise(ActionController::RoutingError) do
assert_routing('http://test.host/secure/articles', { :controller => 'secure_articles', :action => 'index' })
end
- assert_routing('https://test.host/secure/articles', { :controller => 'secure_articles', :action => 'index' })
+ assert_routing('https://test.host/secure/articles', { :controller => 'secure_articles', :action => 'index', :protocol => 'https://' })
end
def test_assert_routing_with_block_constraint
diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb
index e5345754cd..1a8f40037f 100644
--- a/actionpack/test/dispatch/routing_test.rb
+++ b/actionpack/test/dispatch/routing_test.rb
@@ -829,6 +829,15 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest
assert_equal original_options, options
end
+ def test_url_for_does_not_modify_controller
+ controller = '/projects'
+ options = {:controller => controller, :action => 'status', :only_path => true}
+ url = url_for(options)
+
+ assert_equal '/projects/status', url
+ assert_equal '/projects', controller
+ end
+
# tests the arguments modification free version of define_hash_access
def test_named_route_with_no_side_effects
original_options = { :host => 'test.host' }
@@ -2315,6 +2324,55 @@ class TestNamespaceWithControllerOption < ActionDispatch::IntegrationTest
end
end
+class TestDrawExternalFile < ActionDispatch::IntegrationTest
+ class ExternalController < ActionController::Base
+ def index
+ render :text => "external#index"
+ end
+ end
+
+ DRAW_PATH = Pathname.new(File.expand_path('../../fixtures/routes', __FILE__))
+
+ DefaultScopeRoutes = ActionDispatch::Routing::RouteSet.new.tap do |app|
+ app.draw_paths << DRAW_PATH
+ end
+
+ def app
+ DefaultScopeRoutes
+ end
+
+ def test_draw_external_file
+ DefaultScopeRoutes.draw do
+ scope :module => 'test_draw_external_file' do
+ draw :external
+ end
+ end
+
+ get '/external'
+ assert_equal "external#index", @response.body
+ end
+
+ def test_draw_nonexistent_file
+ exception = assert_raise ArgumentError do
+ DefaultScopeRoutes.draw do
+ draw :nonexistent
+ end
+ end
+ assert_match 'Your router tried to #draw the external file nonexistent.rb', exception.message
+ assert_match DRAW_PATH.to_s, exception.message
+ end
+
+ def test_draw_bogus_file
+ exception = assert_raise NoMethodError do
+ DefaultScopeRoutes.draw do
+ draw :bogus
+ end
+ end
+ assert_match "undefined method `wrong'", exception.message
+ assert_match 'test/fixtures/routes/bogus.rb:1', exception.backtrace.first
+ end
+end
+
class TestDefaultScope < ActionDispatch::IntegrationTest
module ::Blog
class PostsController < ActionController::Base
@@ -2562,3 +2620,80 @@ class TestOptimizedNamedRoutes < ActionDispatch::IntegrationTest
assert_equal '/foo', foo_path
end
end
+
+class TestNamedRouteUrlHelpers < ActionDispatch::IntegrationTest
+ class CategoriesController < ActionController::Base
+ def show
+ render :text => "categories#show"
+ end
+ end
+
+ class ProductsController < ActionController::Base
+ def show
+ render :text => "products#show"
+ end
+ end
+
+ Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
+ app.draw do
+ scope :module => "test_named_route_url_helpers" do
+ get "/categories/:id" => 'categories#show', :as => :category
+ get "/products/:id" => 'products#show', :as => :product
+ end
+ end
+ end
+
+ def app; Routes end
+
+ include Routes.url_helpers
+
+ test "url helpers do not ignore nil parameters when using non-optimized routes" do
+ Routes.stubs(:optimize_routes_generation?).returns(false)
+
+ get "/categories/1"
+ assert_response :success
+ assert_raises(ActionController::RoutingError) { product_path(nil) }
+ end
+end
+
+class TestUrlConstraints < ActionDispatch::IntegrationTest
+ Routes = ActionDispatch::Routing::RouteSet.new.tap do |app|
+ app.draw do
+ ok = lambda { |env| [200, { 'Content-Type' => 'text/plain' }, []] }
+
+ constraints :subdomain => 'admin' do
+ get '/' => ok, :as => :admin_root
+ end
+
+ scope :constraints => { :protocol => 'https://' } do
+ get '/' => ok, :as => :secure_root
+ end
+
+ get '/' => ok, :as => :alternate_root, :constraints => { :port => 8080 }
+ end
+ end
+
+ include Routes.url_helpers
+ def app; Routes end
+
+ test "constraints are copied to defaults when using constraints method" do
+ assert_equal 'http://admin.example.com/', admin_root_url
+
+ get 'http://admin.example.com/'
+ assert_response :success
+ end
+
+ test "constraints are copied to defaults when using scope constraints hash" do
+ assert_equal 'https://www.example.com/', secure_root_url
+
+ get 'https://www.example.com/'
+ assert_response :success
+ end
+
+ test "constraints are copied to defaults when using route constraints hash" do
+ assert_equal 'http://www.example.com:8080/', alternate_root_url
+
+ get 'http://www.example.com:8080/'
+ assert_response :success
+ end
+end
diff --git a/actionpack/test/fixtures/plain_text.raw b/actionpack/test/fixtures/plain_text.raw
new file mode 100644
index 0000000000..b13985337f
--- /dev/null
+++ b/actionpack/test/fixtures/plain_text.raw
@@ -0,0 +1 @@
+<%= hello_world %>
diff --git a/actionpack/test/fixtures/plain_text_with_characters.raw b/actionpack/test/fixtures/plain_text_with_characters.raw
new file mode 100644
index 0000000000..1e86e44fb4
--- /dev/null
+++ b/actionpack/test/fixtures/plain_text_with_characters.raw
@@ -0,0 +1 @@
+Here are some characters: !@#$%^&*()-="'}{`
diff --git a/actionpack/test/fixtures/routes/bogus.rb b/actionpack/test/fixtures/routes/bogus.rb
new file mode 100644
index 0000000000..41fbf0cd64
--- /dev/null
+++ b/actionpack/test/fixtures/routes/bogus.rb
@@ -0,0 +1 @@
+wrong :route
diff --git a/actionpack/test/fixtures/routes/external.rb b/actionpack/test/fixtures/routes/external.rb
new file mode 100644
index 0000000000..d103c39f53
--- /dev/null
+++ b/actionpack/test/fixtures/routes/external.rb
@@ -0,0 +1 @@
+get '/external' => 'external#index'
diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb
index 2736f6eff0..bfcc9dc7fe 100644
--- a/actionpack/test/template/asset_tag_helper_test.rb
+++ b/actionpack/test/template/asset_tag_helper_test.rb
@@ -203,9 +203,8 @@ class AssetTagHelperTest < ActionView::TestCase
%(image_tag(".pdf.png")) => %(<img alt=".pdf" src="/images/.pdf.png" />),
%(image_tag("http://www.rubyonrails.com/images/rails.png")) => %(<img alt="Rails" src="http://www.rubyonrails.com/images/rails.png" />),
%(image_tag("//www.rubyonrails.com/images/rails.png")) => %(<img alt="Rails" src="//www.rubyonrails.com/images/rails.png" />),
- %(image_tag("mouse.png", :mouseover => "/images/mouse_over.png")) => %(<img alt="Mouse" onmouseover="this.src='/images/mouse_over.png'" onmouseout="this.src='/images/mouse.png'" src="/images/mouse.png" />),
- %(image_tag("mouse.png", :mouseover => image_path("mouse_over.png"))) => %(<img alt="Mouse" onmouseover="this.src='/images/mouse_over.png'" onmouseout="this.src='/images/mouse.png'" src="/images/mouse.png" />),
- %(image_tag("mouse.png", :alt => nil)) => %(<img src="/images/mouse.png" />)
+ %(image_tag("mouse.png", :alt => nil)) => %(<img src="/images/mouse.png" />),
+ %(image_tag("data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==", :alt => nil)) => %(<img src="data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" />),
}
FaviconLinkToTag = {
@@ -1323,8 +1322,6 @@ class AssetTagHelperNonVhostTest < ActionView::TestCase
assert_dom_equal(%(/collaboration/hieraki/javascripts/xmlhr.js), javascript_path("xmlhr"))
assert_dom_equal(%(/collaboration/hieraki/stylesheets/style.css), stylesheet_path("style"))
assert_dom_equal(%(/collaboration/hieraki/images/xml.png), image_path("xml.png"))
- assert_dom_equal(%(<img alt="Mouse" onmouseover="this.src='/collaboration/hieraki/images/mouse_over.png'" onmouseout="this.src='/collaboration/hieraki/images/mouse.png'" src="/collaboration/hieraki/images/mouse.png" />), image_tag("mouse.png", :mouseover => "/images/mouse_over.png"))
- assert_dom_equal(%(<img alt="Mouse2" onmouseover="this.src='/collaboration/hieraki/images/mouse_over2.png'" onmouseout="this.src='/collaboration/hieraki/images/mouse2.png'" src="/collaboration/hieraki/images/mouse2.png" />), image_tag("mouse2.png", :mouseover => image_path("mouse_over2.png")))
end
def test_should_ignore_relative_root_path_on_complete_url
@@ -1337,8 +1334,6 @@ class AssetTagHelperNonVhostTest < ActionView::TestCase
assert_dom_equal(%(gopher://assets.example.com/collaboration/hieraki/javascripts/xmlhr.js), javascript_path("xmlhr"))
assert_dom_equal(%(gopher://assets.example.com/collaboration/hieraki/stylesheets/style.css), stylesheet_path("style"))
assert_dom_equal(%(gopher://assets.example.com/collaboration/hieraki/images/xml.png), image_path("xml.png"))
- assert_dom_equal(%(<img alt="Mouse" onmouseover="this.src='gopher://assets.example.com/collaboration/hieraki/images/mouse_over.png'" onmouseout="this.src='gopher://assets.example.com/collaboration/hieraki/images/mouse.png'" src="gopher://assets.example.com/collaboration/hieraki/images/mouse.png" />), image_tag("mouse.png", :mouseover => "/images/mouse_over.png"))
- assert_dom_equal(%(<img alt="Mouse2" onmouseover="this.src='gopher://assets.example.com/collaboration/hieraki/images/mouse_over2.png'" onmouseout="this.src='gopher://assets.example.com/collaboration/hieraki/images/mouse2.png'" src="gopher://assets.example.com/collaboration/hieraki/images/mouse2.png" />), image_tag("mouse2.png", :mouseover => image_path("mouse_over2.png")))
end
def test_should_compute_proper_path_with_asset_host_and_default_protocol
@@ -1347,8 +1342,6 @@ class AssetTagHelperNonVhostTest < ActionView::TestCase
assert_dom_equal(%(gopher://assets.example.com/collaboration/hieraki/javascripts/xmlhr.js), javascript_path("xmlhr"))
assert_dom_equal(%(gopher://assets.example.com/collaboration/hieraki/stylesheets/style.css), stylesheet_path("style"))
assert_dom_equal(%(gopher://assets.example.com/collaboration/hieraki/images/xml.png), image_path("xml.png"))
- assert_dom_equal(%(<img alt="Mouse" onmouseover="this.src='gopher://assets.example.com/collaboration/hieraki/images/mouse_over.png'" onmouseout="this.src='gopher://assets.example.com/collaboration/hieraki/images/mouse.png'" src="gopher://assets.example.com/collaboration/hieraki/images/mouse.png" />), image_tag("mouse.png", :mouseover => "/images/mouse_over.png"))
- assert_dom_equal(%(<img alt="Mouse2" onmouseover="this.src='gopher://assets.example.com/collaboration/hieraki/images/mouse_over2.png'" onmouseout="this.src='gopher://assets.example.com/collaboration/hieraki/images/mouse2.png'" src="gopher://assets.example.com/collaboration/hieraki/images/mouse2.png" />), image_tag("mouse2.png", :mouseover => image_path("mouse_over2.png")))
end
def test_should_compute_proper_url_with_asset_host
diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb
index 2c0da8473a..9b64bc9d81 100644
--- a/actionpack/test/template/form_options_helper_test.rb
+++ b/actionpack/test/template/form_options_helper_test.rb
@@ -296,10 +296,34 @@ class FormOptionsHelperTest < ActionView::TestCase
)
end
- def test_grouped_options_for_select_with_selected_and_prompt
+ def test_grouped_options_for_select_with_optional_divider
assert_dom_equal(
+ "<optgroup label=\"----------\"><option value=\"US\">US</option>\n<option value=\"Canada\">Canada</option></optgroup><optgroup label=\"----------\"><option value=\"GB\">GB</option>\n<option value=\"Germany\">Germany</option></optgroup>",
+
+ grouped_options_for_select([['US',"Canada"] , ["GB", "Germany"]], divider: "----------")
+ )
+ end
+
+ def test_grouped_options_for_select_with_selected_and_prompt_deprecated
+ assert_deprecated 'Passing the prompt to grouped_options_for_select as an argument is deprecated. Please pass it in an options hash.' do
+ assert_dom_equal(
"<option value=\"\">Choose a product...</option><optgroup label=\"Hats\"><option value=\"Baseball Cap\">Baseball Cap</option>\n<option selected=\"selected\" value=\"Cowboy Hat\">Cowboy Hat</option></optgroup>",
grouped_options_for_select([["Hats", ["Baseball Cap","Cowboy Hat"]]], "Cowboy Hat", "Choose a product...")
+ )
+ end
+ end
+
+ def test_grouped_options_for_select_with_selected_and_prompt
+ assert_dom_equal(
+ "<option value=\"\">Choose a product...</option><optgroup label=\"Hats\"><option value=\"Baseball Cap\">Baseball Cap</option>\n<option selected=\"selected\" value=\"Cowboy Hat\">Cowboy Hat</option></optgroup>",
+ grouped_options_for_select([["Hats", ["Baseball Cap","Cowboy Hat"]]], "Cowboy Hat", prompt: "Choose a product...")
+ )
+ end
+
+ def test_grouped_options_for_select_with_selected_and_prompt_true
+ assert_dom_equal(
+ "<option value=\"\">Please select</option><optgroup label=\"Hats\"><option value=\"Baseball Cap\">Baseball Cap</option>\n<option selected=\"selected\" value=\"Cowboy Hat\">Cowboy Hat</option></optgroup>",
+ grouped_options_for_select([["Hats", ["Baseball Cap","Cowboy Hat"]]], "Cowboy Hat", prompt: true)
)
end
@@ -307,10 +331,18 @@ class FormOptionsHelperTest < ActionView::TestCase
assert grouped_options_for_select([["Hats", ["Baseball Cap","Cowboy Hat"]]]).html_safe?
end
+ def test_grouped_options_for_select_with_prompt_returns_html_escaped_string_deprecated
+ ActiveSupport::Deprecation.silence do
+ assert_dom_equal(
+ "<option value=\"\">&lt;Choose One&gt;</option><optgroup label=\"Hats\"><option value=\"Baseball Cap\">Baseball Cap</option>\n<option value=\"Cowboy Hat\">Cowboy Hat</option></optgroup>",
+ grouped_options_for_select([["Hats", ["Baseball Cap","Cowboy Hat"]]], nil, '<Choose One>'))
+ end
+ end
+
def test_grouped_options_for_select_with_prompt_returns_html_escaped_string
assert_dom_equal(
"<option value=\"\">&lt;Choose One&gt;</option><optgroup label=\"Hats\"><option value=\"Baseball Cap\">Baseball Cap</option>\n<option value=\"Cowboy Hat\">Cowboy Hat</option></optgroup>",
- grouped_options_for_select([["Hats", ["Baseball Cap","Cowboy Hat"]]], nil, '<Choose One>'))
+ grouped_options_for_select([["Hats", ["Baseball Cap","Cowboy Hat"]]], nil, prompt: '<Choose One>'))
end
def test_optgroups_with_with_options_with_hash
@@ -634,6 +666,48 @@ class FormOptionsHelperTest < ActionView::TestCase
)
end
+ def test_required_select
+ assert_dom_equal(
+ %(<select id="post_category" name="post[category]" required="required"><option value=""></option>\n<option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>),
+ select("post", "category", %w(abe mus hest), {}, required: true)
+ )
+ end
+
+ def test_required_select_with_include_blank_prompt
+ assert_dom_equal(
+ %(<select id="post_category" name="post[category]" required="required"><option value="">Select one</option>\n<option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>),
+ select("post", "category", %w(abe mus hest), { include_blank: "Select one" }, required: true)
+ )
+ end
+
+ def test_required_select_with_prompt
+ assert_dom_equal(
+ %(<select id="post_category" name="post[category]" required="required"><option value="">Select one</option>\n<option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>),
+ select("post", "category", %w(abe mus hest), { prompt: "Select one" }, required: true)
+ )
+ end
+
+ def test_required_select_display_size_equals_to_one
+ assert_dom_equal(
+ %(<select id="post_category" name="post[category]" required="required" size="1"><option value=""></option>\n<option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>),
+ select("post", "category", %w(abe mus hest), {}, required: true, size: 1)
+ )
+ end
+
+ def test_required_select_with_display_size_bigger_than_one
+ assert_dom_equal(
+ %(<select id="post_category" name="post[category]" required="required" size="2"><option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>),
+ select("post", "category", %w(abe mus hest), {}, required: true, size: 2)
+ )
+ end
+
+ def test_required_select_with_multiple_option
+ assert_dom_equal(
+ %(<input name="post[category][]" type="hidden" value=""/><select id="post_category" multiple="multiple" name="post[category][]" required="required"><option value="abe">abe</option>\n<option value="mus">mus</option>\n<option value="hest">hest</option></select>),
+ select("post", "category", %w(abe mus hest), {}, required: true, multiple: true)
+ )
+ end
+
def test_select_with_fixnum
@post = Post.new
@post.category = ""
diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb
index 1e92ff99ff..7a645217b8 100644
--- a/actionpack/test/template/form_tag_helper_test.rb
+++ b/actionpack/test/template/form_tag_helper_test.rb
@@ -375,14 +375,7 @@ class FormTagHelperTest < ActionView::TestCase
def test_submit_tag
assert_dom_equal(
%(<input name='commit' data-disable-with="Saving..." onclick="alert('hello!')" type="submit" value="Save" />),
- submit_tag("Save", :disable_with => "Saving...", :onclick => "alert('hello!')")
- )
- end
-
- def test_submit_tag_with_no_onclick_options
- assert_dom_equal(
- %(<input name='commit' data-disable-with="Saving..." type="submit" value="Save" />),
- submit_tag("Save", :disable_with => "Saving...")
+ submit_tag("Save", 'data-disable-with' => "Saving...", :onclick => "alert('hello!')")
)
end
@@ -393,13 +386,6 @@ class FormTagHelperTest < ActionView::TestCase
)
end
- def test_submit_tag_with_confirmation_and_with_disable_with
- assert_dom_equal(
- %(<input name="commit" data-disable-with="Saving..." data-confirm="Are you sure?" type="submit" value="Save" />),
- submit_tag("Save", :disable_with => "Saving...", :confirm => "Are you sure?")
- )
- end
-
def test_button_tag
assert_dom_equal(
%(<button name="button" type="submit">Button</button>),
diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb
index e7f5f100bf..88ed8664c2 100644
--- a/actionpack/test/template/render_test.rb
+++ b/actionpack/test/template/render_test.rb
@@ -79,6 +79,14 @@ module RenderTestCases
assert_equal "<h1>No Comment</h1>\n", @view.render(:template => "comments/empty", :handlers => [:builder])
end
+ def test_render_raw_template_with_handlers
+ assert_equal "<%= hello_world %>\n", @view.render(:template => "plain_text")
+ end
+
+ def test_render_raw_template_with_quotes
+ assert_equal %q;Here are some characters: !@#$%^&*()-="'}{`; + "\n", @view.render(:template => "plain_text_with_characters")
+ end
+
def test_render_file_with_localization_on_context_level
old_locale, @view.locale = @view.locale, :da
assert_equal "Hey verden", @view.render(:file => "test/hello_world")
diff --git a/actionpack/test/template/template_test.rb b/actionpack/test/template/template_test.rb
index 8c57ada587..322bea3fb0 100644
--- a/actionpack/test/template/template_test.rb
+++ b/actionpack/test/template/template_test.rb
@@ -48,7 +48,7 @@ class TestERBTemplate < ActiveSupport::TestCase
end
def new_template(body = "<%= hello %>", details = {})
- ActionView::Template.new(body, "hello template", ERBHandler, {:virtual_path => "hello"}.merge!(details))
+ ActionView::Template.new(body, "hello template", details.fetch(:handler) { ERBHandler }, {:virtual_path => "hello"}.merge!(details))
end
def render(locals = {})
@@ -64,6 +64,11 @@ class TestERBTemplate < ActiveSupport::TestCase
assert_equal "Hello", render
end
+ def test_raw_template
+ @template = new_template("<%= hello %>", :handler => ActionView::Template::Handlers::Raw.new)
+ assert_equal "<%= hello %>", render
+ end
+
def test_template_loses_its_source_after_rendering
@template = new_template
render
diff --git a/actionpack/test/template/testing/fixture_resolver_test.rb b/actionpack/test/template/testing/fixture_resolver_test.rb
index de83540468..9649f349cb 100644
--- a/actionpack/test/template/testing/fixture_resolver_test.rb
+++ b/actionpack/test/template/testing/fixture_resolver_test.rb
@@ -8,8 +8,8 @@ class FixtureResolverTest < ActiveSupport::TestCase
end
def test_should_return_template_for_declared_path
- resolver = ActionView::FixtureResolver.new("arbitrary/path" => "this text")
- templates = resolver.find_all("path", "arbitrary", false, {:locale => [], :formats => [:html], :handlers => []})
+ resolver = ActionView::FixtureResolver.new("arbitrary/path.erb" => "this text")
+ templates = resolver.find_all("path", "arbitrary", false, {:locale => [], :formats => [:html], :handlers => [:erb]})
assert_equal 1, templates.size, "expected one template"
assert_equal "this text", templates.first.source
assert_equal "arbitrary/path", templates.first.virtual_path
diff --git a/actionpack/test/template/testing/null_resolver_test.rb b/actionpack/test/template/testing/null_resolver_test.rb
index e142506e6a..535ad3ab14 100644
--- a/actionpack/test/template/testing/null_resolver_test.rb
+++ b/actionpack/test/template/testing/null_resolver_test.rb
@@ -3,10 +3,10 @@ require 'abstract_unit'
class NullResolverTest < ActiveSupport::TestCase
def test_should_return_template_for_any_path
resolver = ActionView::NullResolver.new()
- templates = resolver.find_all("path", "arbitrary", false, {:locale => [], :formats => [:html], :handlers => []})
+ templates = resolver.find_all("path.erb", "arbitrary", false, {:locale => [], :formats => [:html], :handlers => []})
assert_equal 1, templates.size, "expected one template"
assert_equal "Template generated by Null Resolver", templates.first.source
- assert_equal "arbitrary/path", templates.first.virtual_path
+ assert_equal "arbitrary/path.erb", templates.first.virtual_path
assert_equal [:html], templates.first.formats
end
end
diff --git a/actionpack/test/template/text_helper_test.rb b/actionpack/test/template/text_helper_test.rb
index 5865b7f23c..e5cb273518 100644
--- a/actionpack/test/template/text_helper_test.rb
+++ b/actionpack/test/template/text_helper_test.rb
@@ -46,6 +46,14 @@ class TextHelperTest < ActionView::TestCase
assert_equal "<p><b> test with unsafe string </b><script>code!</script></p>", simple_format("<b> test with unsafe string </b><script>code!</script>", {}, :sanitize => false)
end
+ def test_simple_format_with_custom_wrapper
+ assert_equal "<div></div>", simple_format(nil, {}, :wrapper_tag => "div")
+ end
+
+ def test_simple_format_with_custom_wrapper_and_multi_line_breaks
+ assert_equal "<div>We want to put a wrapper...</div>\n\n<div>...right there.</div>", simple_format("We want to put a wrapper...\n\n...right there.", {}, :wrapper_tag => "div")
+ end
+
def test_simple_format_should_not_change_the_text_passed
text = "<b>Ok</b><script>code!</script>"
text_clone = text.dup
diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb
index eaa8bdbd26..fb5b35bac6 100644
--- a/actionpack/test/template/url_helper_test.rb
+++ b/actionpack/test/template/url_helper_test.rb
@@ -97,7 +97,7 @@ class UrlHelperTest < ActiveSupport::TestCase
def test_button_to_with_javascript_disable_with
assert_dom_equal(
"<form method=\"post\" action=\"http://www.example.com\" class=\"button_to\"><div><input data-disable-with=\"Greeting...\" type=\"submit\" value=\"Hello\" /></div></form>",
- button_to("Hello", "http://www.example.com", :disable_with => "Greeting...")
+ button_to("Hello", "http://www.example.com", 'data-disable-with' => "Greeting...")
)
end
@@ -112,20 +112,6 @@ class UrlHelperTest < ActiveSupport::TestCase
)
end
- def test_button_to_with_remote_and_javascript_disable_with
- assert_dom_equal(
- "<form method=\"post\" action=\"http://www.example.com\" class=\"button_to\" data-remote=\"true\"><div><input data-disable-with=\"Greeting...\" type=\"submit\" value=\"Hello\" /></div></form>",
- button_to("Hello", "http://www.example.com", :remote => true, :disable_with => "Greeting...")
- )
- end
-
- def test_button_to_with_remote_and_javascript_confirm_and_javascript_disable_with
- assert_dom_equal(
- "<form method=\"post\" action=\"http://www.example.com\" class=\"button_to\" data-remote=\"true\"><div><input data-disable-with=\"Greeting...\" data-confirm=\"Are you sure?\" type=\"submit\" value=\"Hello\" /></div></form>",
- button_to("Hello", "http://www.example.com", :remote => true, :confirm => "Are you sure?", :disable_with => "Greeting...")
- )
- end
-
def test_button_to_with_remote_false
assert_dom_equal(
"<form method=\"post\" action=\"http://www.example.com\" class=\"button_to\"><div><input type=\"submit\" value=\"Hello\" /></div></form>",
diff --git a/actionpack/test/ts_isolated.rb b/actionpack/test/ts_isolated.rb
index ae2a0c95f6..595b4018e9 100644
--- a/actionpack/test/ts_isolated.rb
+++ b/actionpack/test/ts_isolated.rb
@@ -1,6 +1,3 @@
-$:.unshift(File.dirname(__FILE__))
-$:.unshift(File.dirname(__FILE__) + '/../../activesupport/lib')
-
require 'minitest/autorun'
require 'rbconfig'
require 'abstract_unit'