aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_view')
-rw-r--r--actionpack/lib/action_view/base.rb3
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb70
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb1
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb58
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb46
-rw-r--r--actionpack/lib/action_view/helpers/atom_feed_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/capture_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/date_helper.rb116
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb40
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb35
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb11
-rw-r--r--actionpack/lib/action_view/helpers/javascript_helper.rb41
-rw-r--r--actionpack/lib/action_view/helpers/number_helper.rb265
-rw-r--r--actionpack/lib/action_view/helpers/record_tag_helper.rb6
-rw-r--r--actionpack/lib/action_view/helpers/tag_helper.rb8
-rw-r--r--actionpack/lib/action_view/helpers/tags/base.rb7
-rw-r--r--actionpack/lib/action_view/helpers/tags/check_box.rb6
-rw-r--r--actionpack/lib/action_view/helpers/tags/collection_helpers.rb2
-rw-r--r--actionpack/lib/action_view/helpers/text_helper.rb43
-rw-r--r--actionpack/lib/action_view/helpers/translation_helper.rb19
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb19
-rw-r--r--actionpack/lib/action_view/renderer/abstract_renderer.rb4
-rw-r--r--actionpack/lib/action_view/renderer/partial_renderer.rb94
-rw-r--r--actionpack/lib/action_view/template/resolver.rb1
24 files changed, 517 insertions, 382 deletions
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index f3315948b4..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'
@@ -139,7 +140,7 @@ module ActionView #:nodoc:
# How to complete the streaming when an exception occurs.
# This is our best guess: first try to close the attribute, then the tag.
cattr_accessor :streaming_completion_on_exception
- @@streaming_completion_on_exception = %("><script type="text/javascript">window.location = "/500.html"</script></html>)
+ @@streaming_completion_on_exception = %("><script>window.location = "/500.html"</script></html>)
# Specify whether rendering within namespaced controllers should prefix
# the partial paths for ActiveModel objects with the namespace.
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index 2f8b28c82b..a8d6213b13 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -13,15 +13,16 @@ module ActionView
# the assets exist before linking to them:
#
# image_tag("rails.png")
- # # => <img alt="Rails" src="/images/rails.png?1230601161" />
+ # # => <img alt="Rails" src="/assets/rails.png" />
# stylesheet_link_tag("application")
- # # => <link href="/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
+ # # => <link href="/assets/application.css?body=1" media="screen" rel="stylesheet" />
+ #
#
# === Using asset hosts
#
# By default, Rails links to these assets on the current host in the public
# folder, but you can direct Rails to link to assets from a dedicated asset
- # server by setting ActionController::Base.asset_host in the application
+ # server by setting <tt>ActionController::Base.asset_host</tt> in the application
# configuration, typically in <tt>config/environments/production.rb</tt>.
# For example, you'd define <tt>assets.example.com</tt> to be your asset
# host this way, inside the <tt>configure</tt> block of your environment-specific
@@ -32,9 +33,9 @@ module ActionView
# Helpers take that into account:
#
# image_tag("rails.png")
- # # => <img alt="Rails" src="http://assets.example.com/images/rails.png?1230601161" />
+ # # => <img alt="Rails" src="http://assets.example.com/assets/rails.png" />
# stylesheet_link_tag("application")
- # # => <link href="http://assets.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
+ # # => <link href="http://assets.example.com/assets/application.css" media="screen" rel="stylesheet" />
#
# Browsers typically open at most two simultaneous connections to a single
# host, which means your assets often have to wait for other assets to finish
@@ -45,9 +46,9 @@ module ActionView
# will open eight simultaneous connections rather than two.
#
# image_tag("rails.png")
- # # => <img alt="Rails" src="http://assets0.example.com/images/rails.png?1230601161" />
+ # # => <img alt="Rails" src="http://assets0.example.com/assets/rails.png" />
# stylesheet_link_tag("application")
- # # => <link href="http://assets2.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
+ # # => <link href="http://assets2.example.com/assets/application.css" media="screen" rel="stylesheet" />
#
# To do this, you can either setup four actual hosts, or you can use wildcard
# DNS to CNAME the wildcard to a single asset host. You can read more about
@@ -64,29 +65,28 @@ module ActionView
# "http://assets#{Digest::MD5.hexdigest(source).to_i(16) % 2 + 1}.example.com"
# }
# image_tag("rails.png")
- # # => <img alt="Rails" src="http://assets1.example.com/images/rails.png?1230601161" />
+ # # => <img alt="Rails" src="http://assets1.example.com/assets/rails.png" />
# stylesheet_link_tag("application")
- # # => <link href="http://assets2.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
+ # # => <link href="http://assets2.example.com/assets/application.css" media="screen" rel="stylesheet" />
#
# The example above generates "http://assets1.example.com" and
# "http://assets2.example.com". This option is useful for example if
# you need fewer/more than four hosts, custom host names, etc.
#
# As you see the proc takes a +source+ parameter. That's a string with the
- # absolute path of the asset with any extensions and timestamps in place,
- # for example "/images/rails.png?1230601161".
+ # absolute path of the asset, for example "/assets/rails.png".
#
# ActionController::Base.asset_host = Proc.new { |source|
- # if source.starts_with?('/images')
- # "http://images.example.com"
+ # if source.ends_with?('.css')
+ # "http://stylesheets.example.com"
# else
# "http://assets.example.com"
# end
# }
# image_tag("rails.png")
- # # => <img alt="Rails" src="http://images.example.com/images/rails.png?1230601161" />
+ # # => <img alt="Rails" src="http://assets.example.com/assets/rails.png" />
# stylesheet_link_tag("application")
- # # => <link href="http://assets.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
+ # # => <link href="http://stylesheets.example.com/assets/application.css" media="screen" rel="stylesheet" />
#
# Alternatively you may ask for a second parameter +request+. That one is
# particularly useful for serving assets from an SSL-protected page. The
@@ -163,7 +163,7 @@ module ActionView
# image_tag("rails.png")
# # => <img alt="Rails" src="/release-12345/images/rails.png" />
# stylesheet_link_tag("application")
- # # => <link href="/release-12345/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
+ # # => <link href="/release-12345/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" />
#
# Changing the asset_path does require that your web servers have
# knowledge of the asset template paths that you rewrite to so it's not
@@ -261,13 +261,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 +279,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
@@ -330,13 +330,13 @@ module ActionView
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 +344,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 +352,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
@@ -369,21 +369,21 @@ module ActionView
#
# ==== 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 => "/assets/mouse_over.png") # =>
+ # <img src="/assets/mouse.png" onmouseover="this.src='/assets/mouse_over.png'" onmouseout="this.src='/assets/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" />
+ # <img src="/assets/mouse.png" onmouseover="this.src='/assets/mouse_over.png'" onmouseout="this.src='/assets/mouse.png'" alt="Mouse" />
def image_tag(source, options={})
options = options.symbolize_keys
@@ -433,7 +433,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') # =>
@@ -442,7 +442,7 @@ module ActionView
# <video><source src="/videos/trailer.ogg" /><source src="/videos/trailer.flv" /></video>
# video_tag(["trailer.ogg", "trailer.flv"]) # =>
# <video><source src="/videos/trailer.ogg" /><source src="/videos/trailer.flv" /></video>
- # video_tag(["trailer.ogg", "trailer.flv"] :size => "160x120") # =>
+ # video_tag(["trailer.ogg", "trailer.flv"], :size => "160x120") # =>
# <video height="120" width="160"><source src="/videos/trailer.ogg" /><source src="/videos/trailer.flv" /></video>
def video_tag(*sources)
multiple_sources_tag('video', sources) do |options|
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb
index dd4e9ae4cc..35f91cec18 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb
@@ -1,5 +1,6 @@
require 'thread'
require 'active_support/core_ext/file'
+require 'active_support/core_ext/module/attribute_accessors'
module ActionView
module Helpers
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 c67f81dcf4..7bff0c1149 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
@@ -16,7 +16,7 @@ module ActionView
end
def asset_tag(source, options)
- content_tag("script", "", { "type" => Mime::JS, "src" => path_to_asset(source) }.merge(options))
+ content_tag("script", "", { "src" => path_to_asset(source) }.merge(options))
end
def custom_dir
@@ -60,9 +60,9 @@ module ActionView
# ActionView::Helpers::AssetTagHelper.register_javascript_expansion :monkey => ["head", "body", "tail"]
#
# javascript_include_tag :monkey # =>
- # <script type="text/javascript" src="/javascripts/head.js"></script>
- # <script type="text/javascript" src="/javascripts/body.js"></script>
- # <script type="text/javascript" src="/javascripts/tail.js"></script>
+ # <script src="/javascripts/head.js"></script>
+ # <script src="/javascripts/body.js"></script>
+ # <script src="/javascripts/tail.js"></script>
def register_javascript_expansion(expansions)
js_expansions = JavascriptIncludeTag.expansions
expansions.each do |key, values|
@@ -116,36 +116,34 @@ module ActionView
#
# ==== Examples
# javascript_include_tag "xmlhr"
- # # => <script type="text/javascript" src="/javascripts/xmlhr.js?1284139606"></script>
+ # # => <script src="/javascripts/xmlhr.js?1284139606"></script>
#
# javascript_include_tag "xmlhr.js"
- # # => <script type="text/javascript" src="/javascripts/xmlhr.js?1284139606"></script>
+ # # => <script src="/javascripts/xmlhr.js?1284139606"></script>
#
# javascript_include_tag "common.javascript", "/elsewhere/cools"
- # # => <script type="text/javascript" src="/javascripts/common.javascript?1284139606"></script>
- # # <script type="text/javascript" src="/elsewhere/cools.js?1423139606"></script>
+ # # => <script src="/javascripts/common.javascript?1284139606"></script>
+ # # <script src="/elsewhere/cools.js?1423139606"></script>
#
# javascript_include_tag "http://www.example.com/xmlhr"
- # # => <script type="text/javascript" src="http://www.example.com/xmlhr"></script>
+ # # => <script src="http://www.example.com/xmlhr"></script>
#
# javascript_include_tag "http://www.example.com/xmlhr.js"
- # # => <script type="text/javascript" src="http://www.example.com/xmlhr.js"></script>
+ # # => <script src="http://www.example.com/xmlhr.js"></script>
#
# javascript_include_tag :defaults
- # # => <script type="text/javascript" src="/javascripts/jquery.js?1284139606"></script>
- # # <script type="text/javascript" src="/javascripts/rails.js?1284139606"></script>
- # # <script type="text/javascript" src="/javascripts/application.js?1284139606"></script>
- #
- # * = The application.js file is only referenced if it exists
+ # # => <script src="/javascripts/jquery.js?1284139606"></script>
+ # # <script src="/javascripts/rails.js?1284139606"></script>
+ # # <script src="/javascripts/application.js?1284139606"></script>
#
# You can also include all JavaScripts in the +javascripts+ directory using <tt>:all</tt> as the source:
#
# javascript_include_tag :all
- # # => <script type="text/javascript" src="/javascripts/jquery.js?1284139606"></script>
- # # <script type="text/javascript" src="/javascripts/rails.js?1284139606"></script>
- # # <script type="text/javascript" src="/javascripts/application.js?1284139606"></script>
- # # <script type="text/javascript" src="/javascripts/shop.js?1284139606"></script>
- # # <script type="text/javascript" src="/javascripts/checkout.js?1284139606"></script>
+ # # => <script src="/javascripts/jquery.js?1284139606"></script>
+ # # <script src="/javascripts/rails.js?1284139606"></script>
+ # # <script src="/javascripts/application.js?1284139606"></script>
+ # # <script src="/javascripts/shop.js?1284139606"></script>
+ # # <script src="/javascripts/checkout.js?1284139606"></script>
#
# Note that your defaults of choice will be included first, so they will be available to all subsequently
# included files.
@@ -166,25 +164,25 @@ module ActionView
#
# # assuming config.perform_caching is false
# javascript_include_tag :all, :cache => true
- # # => <script type="text/javascript" src="/javascripts/jquery.js?1284139606"></script>
- # # <script type="text/javascript" src="/javascripts/rails.js?1284139606"></script>
- # # <script type="text/javascript" src="/javascripts/application.js?1284139606"></script>
- # # <script type="text/javascript" src="/javascripts/shop.js?1284139606"></script>
- # # <script type="text/javascript" src="/javascripts/checkout.js?1284139606"></script>
+ # # => <script src="/javascripts/jquery.js?1284139606"></script>
+ # # <script src="/javascripts/rails.js?1284139606"></script>
+ # # <script src="/javascripts/application.js?1284139606"></script>
+ # # <script src="/javascripts/shop.js?1284139606"></script>
+ # # <script src="/javascripts/checkout.js?1284139606"></script>
#
# # assuming config.perform_caching is true
# javascript_include_tag :all, :cache => true
- # # => <script type="text/javascript" src="/javascripts/all.js?1344139789"></script>
+ # # => <script src="/javascripts/all.js?1344139789"></script>
#
# # assuming config.perform_caching is false
# javascript_include_tag "jquery", "cart", "checkout", :cache => "shop"
- # # => <script type="text/javascript" src="/javascripts/jquery.js?1284139606"></script>
- # # <script type="text/javascript" src="/javascripts/cart.js?1289139157"></script>
- # # <script type="text/javascript" src="/javascripts/checkout.js?1299139816"></script>
+ # # => <script src="/javascripts/jquery.js?1284139606"></script>
+ # # <script src="/javascripts/cart.js?1289139157"></script>
+ # # <script src="/javascripts/checkout.js?1299139816"></script>
#
# # assuming config.perform_caching is true
# javascript_include_tag "jquery", "cart", "checkout", :cache => "shop"
- # # => <script type="text/javascript" src="/javascripts/shop.js?1299139816"></script>
+ # # => <script src="/javascripts/shop.js?1299139816"></script>
#
# The <tt>:recursive</tt> option is also available for caching:
#
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 2584b67548..4bcb8b9718 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
@@ -17,7 +17,7 @@ module ActionView
def asset_tag(source, options)
# We force the :request protocol here to avoid a double-download bug in IE7 and IE8
- tag("link", { "rel" => "stylesheet", "type" => Mime::CSS, "media" => "screen", "href" => path_to_asset(source, :protocol => :request) }.merge(options))
+ tag("link", { "rel" => "stylesheet", "media" => "screen", "href" => path_to_asset(source, :protocol => :request) }.merge(options))
end
def custom_dir
@@ -38,9 +38,9 @@ module ActionView
# ActionView::Helpers::AssetTagHelper.register_stylesheet_expansion :monkey => ["head", "body", "tail"]
#
# stylesheet_link_tag :monkey # =>
- # <link href="/stylesheets/head.css" media="screen" rel="stylesheet" type="text/css" />
- # <link href="/stylesheets/body.css" media="screen" rel="stylesheet" type="text/css" />
- # <link href="/stylesheets/tail.css" media="screen" rel="stylesheet" type="text/css" />
+ # <link href="/stylesheets/head.css" media="screen" rel="stylesheet" />
+ # <link href="/stylesheets/body.css" media="screen" rel="stylesheet" />
+ # <link href="/stylesheets/tail.css" media="screen" rel="stylesheet" />
def register_stylesheet_expansion(expansions)
style_expansions = StylesheetIncludeTag.expansions
expansions.each do |key, values|
@@ -81,30 +81,30 @@ module ActionView
#
# ==== Examples
# stylesheet_link_tag "style" # =>
- # <link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" />
+ # <link href="/stylesheets/style.css" media="screen" rel="stylesheet" />
#
# stylesheet_link_tag "style.css" # =>
- # <link href="/stylesheets/style.css" media="screen" rel="stylesheet" type="text/css" />
+ # <link href="/stylesheets/style.css" media="screen" rel="stylesheet" />
#
# stylesheet_link_tag "http://www.example.com/style.css" # =>
- # <link href="http://www.example.com/style.css" media="screen" rel="stylesheet" type="text/css" />
+ # <link href="http://www.example.com/style.css" media="screen" rel="stylesheet" />
#
# stylesheet_link_tag "style", :media => "all" # =>
- # <link href="/stylesheets/style.css" media="all" rel="stylesheet" type="text/css" />
+ # <link href="/stylesheets/style.css" media="all" rel="stylesheet" />
#
# stylesheet_link_tag "style", :media => "print" # =>
- # <link href="/stylesheets/style.css" media="print" rel="stylesheet" type="text/css" />
+ # <link href="/stylesheets/style.css" media="print" rel="stylesheet" />
#
# stylesheet_link_tag "random.styles", "/css/stylish" # =>
- # <link href="/stylesheets/random.styles" media="screen" rel="stylesheet" type="text/css" />
- # <link href="/css/stylish.css" media="screen" rel="stylesheet" type="text/css" />
+ # <link href="/stylesheets/random.styles" media="screen" rel="stylesheet" />
+ # <link href="/css/stylish.css" media="screen" rel="stylesheet" />
#
# You can also include all styles in the stylesheets directory using <tt>:all</tt> as the source:
#
# stylesheet_link_tag :all # =>
- # <link href="/stylesheets/style1.css" media="screen" rel="stylesheet" type="text/css" />
- # <link href="/stylesheets/styleB.css" media="screen" rel="stylesheet" type="text/css" />
- # <link href="/stylesheets/styleX2.css" media="screen" rel="stylesheet" type="text/css" />
+ # <link href="/stylesheets/style1.css" media="screen" rel="stylesheet" />
+ # <link href="/stylesheets/styleB.css" media="screen" rel="stylesheet" />
+ # <link href="/stylesheets/styleX2.css" media="screen" rel="stylesheet" />
#
# If you want Rails to search in all the subdirectories under stylesheets, you should explicitly set <tt>:recursive</tt>:
#
@@ -113,26 +113,26 @@ module ActionView
# == Caching multiple stylesheets into one
#
# You can also cache multiple stylesheets into one file, which requires less HTTP connections and can better be
- # compressed by gzip (leading to faster transfers). Caching will only happen if config.perform_caching
+ # compressed by gzip (leading to faster transfers). Caching will only happen if +config.perform_caching+
# 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" type="text/css" />
- # <link href="/stylesheets/styleB.css" media="screen" rel="stylesheet" type="text/css" />
- # <link href="/stylesheets/styleX2.css" media="screen" rel="stylesheet" type="text/css" />
+ # <link href="/stylesheets/style1.css" media="screen" rel="stylesheet" />
+ # <link href="/stylesheets/styleB.css" media="screen" rel="stylesheet" />
+ # <link href="/stylesheets/styleX2.css" media="screen" rel="stylesheet" />
#
# stylesheet_link_tag :all, :cache => true # when config.perform_caching is true =>
- # <link href="/stylesheets/all.css" media="screen" rel="stylesheet" type="text/css" />
+ # <link href="/stylesheets/all.css" media="screen" rel="stylesheet" />
#
# stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when config.perform_caching is false =>
- # <link href="/stylesheets/shop.css" media="screen" rel="stylesheet" type="text/css" />
- # <link href="/stylesheets/cart.css" media="screen" rel="stylesheet" type="text/css" />
- # <link href="/stylesheets/checkout.css" media="screen" rel="stylesheet" type="text/css" />
+ # <link href="/stylesheets/shop.css" media="screen" rel="stylesheet" />
+ # <link href="/stylesheets/cart.css" media="screen" rel="stylesheet" />
+ # <link href="/stylesheets/checkout.css" media="screen" rel="stylesheet" />
#
# stylesheet_link_tag "shop", "cart", "checkout", :cache => "payment" # when config.perform_caching is true =>
- # <link href="/stylesheets/payment.css" media="screen" rel="stylesheet" type="text/css" />
+ # <link href="/stylesheets/payment.css" media="screen" rel="stylesheet" />
#
# The <tt>:recursive</tt> option is also available for caching:
#
diff --git a/actionpack/lib/action_view/helpers/atom_feed_helper.rb b/actionpack/lib/action_view/helpers/atom_feed_helper.rb
index 70164217de..f9aa8d7cee 100644
--- a/actionpack/lib/action_view/helpers/atom_feed_helper.rb
+++ b/actionpack/lib/action_view/helpers/atom_feed_helper.rb
@@ -189,7 +189,7 @@ module ActionView
@xml.updated((options[:updated] || record.updated_at).xmlschema)
end
- type = options.fetch(:type) { 'text/html' }
+ type = options.fetch(:type, 'text/html')
@xml.link(:rel => 'alternate', :type => type, :href => options[:url] || @view.polymorphic_url(record))
diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb
index 278139cadb..d9d6f90211 100644
--- a/actionpack/lib/action_view/helpers/capture_helper.rb
+++ b/actionpack/lib/action_view/helpers/capture_helper.rb
@@ -96,7 +96,7 @@ module ActionView
# Please login!
#
# <% content_for :script do %>
- # <script type="text/javascript">alert('You are not authorized to view this page!')</script>
+ # <script>alert('You are not authorized to view this page!')</script>
# <% end %>
#
# Then, in another view, you could to do something like this:
diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb
index cb46f26d99..f0a593d2c1 100644
--- a/actionpack/lib/action_view/helpers/date_helper.rb
+++ b/actionpack/lib/action_view/helpers/date_helper.rb
@@ -12,14 +12,14 @@ module ActionView
# elements. All of the select-type methods share a number of common options that are as follows:
#
# * <tt>:prefix</tt> - overwrites the default prefix of "date" used for the select names. So specifying "birthday"
- # would give birthday[month] instead of date[month] if passed to the <tt>select_month</tt> method.
+ # would give \birthday[month] instead of \date[month] if passed to the <tt>select_month</tt> method.
# * <tt>:include_blank</tt> - set to true if it should be possible to set an empty date.
# * <tt>:discard_type</tt> - set to true if you want to discard the type part of the select name. If set to true,
# the <tt>select_month</tt> method would use simply "date" (which can be overwritten using <tt>:prefix</tt>) instead
- # of "date[month]".
+ # of \date[month].
module DateHelper
# Reports the approximate distance in time between two Time, Date or DateTime objects or integers as seconds.
- # Set <tt>include_seconds</tt> to true if you want more detailed approximations when distance < 1 min, 29 secs.
+ # Pass <tt>:include_seconds => true</tt> if you want more detailed approximations when distance < 1 min, 29 secs.
# Distances are reported based on the following table:
#
# 0 <-> 29 secs # => less than a minute
@@ -29,14 +29,15 @@ module ActionView
# 89 mins, 30 secs <-> 23 hrs, 59 mins, 29 secs # => about [2..24] hours
# 23 hrs, 59 mins, 30 secs <-> 41 hrs, 59 mins, 29 secs # => 1 day
# 41 hrs, 59 mins, 30 secs <-> 29 days, 23 hrs, 59 mins, 29 secs # => [2..29] days
- # 29 days, 23 hrs, 59 mins, 30 secs <-> 59 days, 23 hrs, 59 mins, 29 secs # => about 1 month
+ # 29 days, 23 hrs, 59 mins, 30 secs <-> 44 days, 23 hrs, 59 mins, 29 secs # => about 1 month
+ # 44 days, 23 hrs, 59 mins, 30 secs <-> 59 days, 23 hrs, 59 mins, 29 secs # => about 2 months
# 59 days, 23 hrs, 59 mins, 30 secs <-> 1 yr minus 1 sec # => [2..12] months
# 1 yr <-> 1 yr, 3 months # => about 1 year
# 1 yr, 3 months <-> 1 yr, 9 months # => over 1 year
# 1 yr, 9 months <-> 2 yr minus 1 sec # => almost 2 years
# 2 yrs <-> max time or date # => (same rules as 1 yr)
#
- # With <tt>include_seconds</tt> = true and the difference < 1 minute 29 seconds:
+ # With <tt>:include_seconds => true</tt> and the difference < 1 minute 29 seconds:
# 0-4 secs # => less than 5 seconds
# 5-9 secs # => less than 10 seconds
# 10-19 secs # => less than 20 seconds
@@ -46,36 +47,45 @@ module ActionView
#
# ==== Examples
# from_time = Time.now
- # distance_of_time_in_words(from_time, from_time + 50.minutes) # => about 1 hour
- # distance_of_time_in_words(from_time, 50.minutes.from_now) # => about 1 hour
- # distance_of_time_in_words(from_time, from_time + 15.seconds) # => less than a minute
- # distance_of_time_in_words(from_time, from_time + 15.seconds, true) # => less than 20 seconds
- # distance_of_time_in_words(from_time, 3.years.from_now) # => about 3 years
- # distance_of_time_in_words(from_time, from_time + 60.hours) # => 3 days
- # distance_of_time_in_words(from_time, from_time + 45.seconds, true) # => less than a minute
- # distance_of_time_in_words(from_time, from_time - 45.seconds, true) # => less than a minute
- # distance_of_time_in_words(from_time, 76.seconds.from_now) # => 1 minute
- # distance_of_time_in_words(from_time, from_time + 1.year + 3.days) # => about 1 year
- # distance_of_time_in_words(from_time, from_time + 3.years + 6.months) # => over 3 years
+ # distance_of_time_in_words(from_time, from_time + 50.minutes) # => about 1 hour
+ # distance_of_time_in_words(from_time, 50.minutes.from_now) # => about 1 hour
+ # distance_of_time_in_words(from_time, from_time + 15.seconds) # => less than a minute
+ # distance_of_time_in_words(from_time, from_time + 15.seconds, :include_seconds => true) # => less than 20 seconds
+ # distance_of_time_in_words(from_time, 3.years.from_now) # => about 3 years
+ # distance_of_time_in_words(from_time, from_time + 60.hours) # => 3 days
+ # distance_of_time_in_words(from_time, from_time + 45.seconds, :include_seconds => true) # => less than a minute
+ # distance_of_time_in_words(from_time, from_time - 45.seconds, :include_seconds => true) # => less than a minute
+ # distance_of_time_in_words(from_time, 76.seconds.from_now) # => 1 minute
+ # distance_of_time_in_words(from_time, from_time + 1.year + 3.days) # => about 1 year
+ # distance_of_time_in_words(from_time, from_time + 3.years + 6.months) # => over 3 years
# distance_of_time_in_words(from_time, from_time + 4.years + 9.days + 30.minutes + 5.seconds) # => about 4 years
#
# to_time = Time.now + 6.years + 19.days
- # distance_of_time_in_words(from_time, to_time, true) # => about 6 years
- # distance_of_time_in_words(to_time, from_time, true) # => about 6 years
- # distance_of_time_in_words(Time.now, Time.now) # => less than a minute
+ # 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 = false, options = {})
+ 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
+ else
+ ActiveSupport::Deprecation.warn "distance_of_time_in_words and time_ago_in_words now accept :include_seconds " +
+ "as a part of options hash, not a boolean argument", caller
+ options[:include_seconds] ||= !!include_seconds_or_options
+ end
+
from_time = from_time.to_time if from_time.respond_to?(:to_time)
to_time = to_time.to_time if to_time.respond_to?(:to_time)
- distance_in_minutes = (((to_time - from_time).abs)/60).round
- distance_in_seconds = ((to_time - from_time).abs).round
+ from_time, to_time = to_time, from_time if from_time > to_time
+ distance_in_minutes = ((to_time - from_time)/60.0).round
+ distance_in_seconds = (to_time - from_time).round
I18n.with_options :locale => options[:locale], :scope => :'datetime.distance_in_words' do |locale|
case distance_in_minutes
when 0..1
return distance_in_minutes == 0 ?
locale.t(:less_than_x_minutes, :count => 1) :
- locale.t(:x_minutes, :count => distance_in_minutes) unless include_seconds
+ locale.t(:x_minutes, :count => distance_in_minutes) unless options[:include_seconds]
case distance_in_seconds
when 0..4 then locale.t :less_than_x_seconds, :count => 5
@@ -86,26 +96,35 @@ module ActionView
else locale.t :x_minutes, :count => 1
end
- when 2..44 then locale.t :x_minutes, :count => distance_in_minutes
- when 45..89 then locale.t :about_x_hours, :count => 1
- when 90..1439 then locale.t :about_x_hours, :count => (distance_in_minutes.to_f / 60.0).round
- when 1440..2519 then locale.t :x_days, :count => 1
- when 2520..43199 then locale.t :x_days, :count => (distance_in_minutes.to_f / 1440.0).round
- when 43200..86399 then locale.t :about_x_months, :count => 1
- when 86400..525599 then locale.t :x_months, :count => (distance_in_minutes.to_f / 43200.0).round
+ when 2...45 then locale.t :x_minutes, :count => distance_in_minutes
+ when 45...90 then locale.t :about_x_hours, :count => 1
+ # 90 mins up to 24 hours
+ when 90...1440 then locale.t :about_x_hours, :count => (distance_in_minutes.to_f / 60.0).round
+ # 24 hours up to 42 hours
+ when 1440...2520 then locale.t :x_days, :count => 1
+ # 42 hours up to 30 days
+ when 2520...43200 then locale.t :x_days, :count => (distance_in_minutes.to_f / 1440.0).round
+ # 30 days up to 60 days
+ when 43200...86400 then locale.t :about_x_months, :count => (distance_in_minutes.to_f / 43200.0).round
+ # 60 days up to 365 days
+ when 86400...525600 then locale.t :x_months, :count => (distance_in_minutes.to_f / 43200.0).round
else
- fyear = from_time.year
- fyear += 1 if from_time.month >= 3
- tyear = to_time.year
- tyear -= 1 if to_time.month < 3
- leap_years = (fyear > tyear) ? 0 : (fyear..tyear).count{|x| Date.leap?(x)}
- minute_offset_for_leap_year = leap_years * 1440
- # Discount the leap year days when calculating year distance.
- # e.g. if there are 20 leap year days between 2 dates having the same day
- # and month then the based on 365 days calculation
- # the distance in years will come out to over 80 years when in written
- # english it would read better as about 80 years.
- minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year
+ if from_time.acts_like?(:time) && to_time.acts_like?(:time)
+ fyear = from_time.year
+ fyear += 1 if from_time.month >= 3
+ tyear = to_time.year
+ tyear -= 1 if to_time.month < 3
+ leap_years = (fyear > tyear) ? 0 : (fyear..tyear).count{|x| Date.leap?(x)}
+ minute_offset_for_leap_year = leap_years * 1440
+ # Discount the leap year days when calculating year distance.
+ # e.g. if there are 20 leap year days between 2 dates having the same day
+ # and month then the based on 365 days calculation
+ # the distance in years will come out to over 80 years when in written
+ # english it would read better as about 80 years.
+ minutes_with_offset = distance_in_minutes - minute_offset_for_leap_year
+ else
+ minutes_with_offset = distance_in_minutes
+ end
remainder = (minutes_with_offset % 525600)
distance_in_years = (minutes_with_offset / 525600)
if remainder < 131400
@@ -122,15 +141,16 @@ 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
+ # 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
+ # time_ago_in_words(Time.now, :include_seconds => true) # => less than 5 seconds
#
# 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 = false)
- distance_of_time_in_words(from_time, Time.now, include_seconds)
+ 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
alias_method :distance_of_time_in_words_to_now, :time_ago_in_words
@@ -997,6 +1017,8 @@ module ActionView
# Returns the separator for a given datetime component.
def separator(type)
+ return "" if @options[:use_hidden]
+
case type
when :year, :month, :day
@options[:"discard_#{type}"] ? "" : @options[:date_separator]
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 6219a7a924..0fbd6ac41b 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -5,11 +5,13 @@ 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'
require 'active_support/core_ext/array/extract_options'
require 'active_support/deprecation'
+require 'active_support/core_ext/string/inflections'
module ActionView
# = Action View Form Helpers
@@ -184,7 +186,7 @@ module ActionView
# First name: <%= f.text_field :first_name %>
# Last name : <%= f.text_field :last_name %>
# Biography : <%= text_area :person, :biography %>
- # Admin? : <%= check_box_tag "person[admin]", @person.company.admin? %>
+ # Admin? : <%= check_box_tag "person[admin]", "1", @person.company.admin? %>
# <%= f.submit %>
# <% end %>
#
@@ -673,6 +675,19 @@ module ActionView
# <% end %>
# ...
# <% end %>
+ #
+ # When a collection is used you might want to know the index of each
+ # object into the array. For this purpose, the <tt>index</tt> method
+ # is available in the FormBuilder object.
+ #
+ # <%= form_for @person do |person_form| %>
+ # ...
+ # <%= person_form.fields_for :projects do |project_fields| %>
+ # Project #<%= project_fields.index %>
+ # ...
+ # <% end %>
+ # ...
+ # <% end %>
def fields_for(record_name, record_object = nil, options = {}, &block)
builder = instantiate_builder(record_name, record_object, options)
output = capture(builder, &block)
@@ -889,7 +904,7 @@ module ActionView
# # Let's say that @post.validated? is 1:
# check_box("post", "validated")
# # => <input name="post[validated]" type="hidden" value="0" />
- # # <input type="checkbox" id="post_validated" name="post[validated]" value="1" />
+ # # <input checked="checked" type="checkbox" id="post_validated" name="post[validated]" value="1" />
#
# # Let's say that @puppy.gooddog is "no":
# check_box("puppy", "gooddog", {}, "yes", "no")
@@ -1026,9 +1041,14 @@ module ActionView
object_name = ActiveModel::Naming.param_key(object)
end
- builder = options[:builder] || ActionView::Base.default_form_builder
+ builder = options[:builder] || default_form_builder
builder.new(object_name, object, self, options)
end
+
+ def default_form_builder
+ builder = ActionView::Base.default_form_builder
+ builder.respond_to?(:constantize) ? builder.constantize : builder
+ end
end
class FormBuilder
@@ -1038,7 +1058,7 @@ module ActionView
attr_accessor :object_name, :object, :options
- attr_reader :multipart, :parent_builder
+ attr_reader :multipart, :parent_builder, :index
alias :multipart? :multipart
def multipart=(multipart)
@@ -1076,6 +1096,7 @@ module ActionView
end
end
@multipart = nil
+ @index = options[:index] || options[:child_index]
end
(field_helpers - [:label, :check_box, :radio_button, :fields_for, :hidden_field, :file_field]).each do |selector|
@@ -1107,12 +1128,14 @@ module ActionView
end
index = if options.has_key?(:index)
- "[#{options[:index]}]"
+ options[:index]
elsif defined?(@auto_index)
self.object_name = @object_name.to_s.sub(/\[\]$/,"")
- "[#{@auto_index}]"
+ @auto_index
end
- record_name = "#{object_name}#{index}[#{record_name}]"
+
+ record_name = index ? "#{object_name}[#{index}][#{record_name}]" : "#{object_name}[#{record_name}]"
+ fields_options[:child_index] = index
@template.fields_for(record_name, record_object, fields_options, &block)
end
@@ -1250,7 +1273,8 @@ module ActionView
explicit_child_index = options[:child_index]
output = ActiveSupport::SafeBuffer.new
association.each do |child|
- output << fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, options, block)
+ options[:child_index] = nested_child_index(name) unless explicit_child_index
+ output << fields_for_nested_model("#{name}[#{options[:child_index]}]", child, options, block)
end
output
elsif association
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index d61c2bbee2..cafcd93f58 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -288,38 +288,55 @@ module ActionView
#
# Examples (call, result):
# options_for_select([["Dollar", "$"], ["Kroner", "DKK"]])
- # <option value="$">Dollar</option>\n<option value="DKK">Kroner</option>
+ # # <option value="$">Dollar</option>
+ # # <option value="DKK">Kroner</option>
#
# options_for_select([ "VISA", "MasterCard" ], "MasterCard")
- # <option>VISA</option>\n<option selected="selected">MasterCard</option>
+ # # <option>VISA</option>
+ # # <option selected="selected">MasterCard</option>
#
# options_for_select({ "Basic" => "$20", "Plus" => "$40" }, "$40")
- # <option value="$20">Basic</option>\n<option value="$40" selected="selected">Plus</option>
+ # # <option value="$20">Basic</option>
+ # # <option value="$40" selected="selected">Plus</option>
#
# options_for_select([ "VISA", "MasterCard", "Discover" ], ["VISA", "Discover"])
- # <option selected="selected">VISA</option>\n<option>MasterCard</option>\n<option selected="selected">Discover</option>
+ # # <option selected="selected">VISA</option>
+ # # <option>MasterCard</option>
+ # # <option selected="selected">Discover</option>
#
# You can optionally provide html attributes as the last element of the array.
#
# Examples:
# options_for_select([ "Denmark", ["USA", {:class => 'bold'}], "Sweden" ], ["USA", "Sweden"])
- # <option value="Denmark">Denmark</option>\n<option value="USA" class="bold" selected="selected">USA</option>\n<option value="Sweden" selected="selected">Sweden</option>
+ # # <option value="Denmark">Denmark</option>
+ # # <option value="USA" class="bold" selected="selected">USA</option>
+ # # <option value="Sweden" selected="selected">Sweden</option>
#
# options_for_select([["Dollar", "$", {:class => "bold"}], ["Kroner", "DKK", {:onclick => "alert('HI');"}]])
- # <option value="$" class="bold">Dollar</option>\n<option value="DKK" onclick="alert('HI');">Kroner</option>
+ # # <option value="$" class="bold">Dollar</option>
+ # # <option value="DKK" onclick="alert('HI');">Kroner</option>
#
# If you wish to specify disabled option tags, set +selected+ to be a hash, with <tt>:disabled</tt> being either a value
# or array of values to be disabled. In this case, you can use <tt>:selected</tt> to specify selected option tags.
#
# Examples:
# options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], :disabled => "Super Platinum")
- # <option value="Free">Free</option>\n<option value="Basic">Basic</option>\n<option value="Advanced">Advanced</option>\n<option value="Super Platinum" disabled="disabled">Super Platinum</option>
+ # # <option value="Free">Free</option>
+ # # <option value="Basic">Basic</option>
+ # # <option value="Advanced">Advanced</option>
+ # # <option value="Super Platinum" disabled="disabled">Super Platinum</option>
#
# options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], :disabled => ["Advanced", "Super Platinum"])
- # <option value="Free">Free</option>\n<option value="Basic">Basic</option>\n<option value="Advanced" disabled="disabled">Advanced</option>\n<option value="Super Platinum" disabled="disabled">Super Platinum</option>
+ # # <option value="Free">Free</option>
+ # # <option value="Basic">Basic</option>
+ # # <option value="Advanced" disabled="disabled">Advanced</option>
+ # # <option value="Super Platinum" disabled="disabled">Super Platinum</option>
#
# options_for_select(["Free", "Basic", "Advanced", "Super Platinum"], :selected => "Free", :disabled => "Super Platinum")
- # <option value="Free" selected="selected">Free</option>\n<option value="Basic">Basic</option>\n<option value="Advanced">Advanced</option>\n<option value="Super Platinum" disabled="disabled">Super Platinum</option>
+ # # <option value="Free" selected="selected">Free</option>
+ # # <option value="Basic">Basic</option>
+ # # <option value="Advanced">Advanced</option>
+ # # <option value="Super Platinum" disabled="disabled">Super Platinum</option>
#
# NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
def options_for_select(container, selected = nil)
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index e403d6cf5e..248cc2f6a3 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -45,7 +45,7 @@ module ActionView
# # => <form action="/posts" method="post">
#
# form_tag('/posts/1', :method => :put)
- # # => <form action="/posts/1" method="put">
+ # # => <form action="/posts/1" method="post"> ... <input name="_method" type="hidden" value="put" /> ...
#
# form_tag('/upload', :multipart => true)
# # => <form action="/upload" method="post" enctype="multipart/form-data">
@@ -122,11 +122,11 @@ module ActionView
html_name = (options[:multiple] == true && !name.to_s.ends_with?("[]")) ? "#{name}[]" : name
if options.delete(:include_blank)
- option_tags = "<option value=\"\"></option>".html_safe + option_tags
+ option_tags = content_tag(:option, '', :value => '').safe_concat(option_tags)
end
if prompt = options.delete(:prompt)
- option_tags = "<option value=\"\">#{prompt}</option>".html_safe + option_tags
+ option_tags = content_tag(:option, prompt, :value => '').safe_concat(option_tags)
end
content_tag :select, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys)
@@ -408,7 +408,7 @@ module ActionView
# # => <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" />
+ # # => <input class="edit_button" data-disable-with="Editing..." 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?" />
@@ -502,6 +502,9 @@ module ActionView
#
# image_submit_tag("agree.png", :disabled => true, :class => "agree_disagree_button")
# # => <input class="agree_disagree_button" disabled="disabled" src="/images/agree.png" type="image" />
+ #
+ # image_submit_tag("save.png", :confirm => "Are you sure?")
+ # # => <input src="/images/save.png" data-confirm="Are you sure?" type="image" />
def image_submit_tag(source, options = {})
options = options.stringify_keys
diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb
index d88f5babb9..cc20518b93 100644
--- a/actionpack/lib/action_view/helpers/javascript_helper.rb
+++ b/actionpack/lib/action_view/helpers/javascript_helper.rb
@@ -15,7 +15,6 @@ module ActionView
JS_ESCAPE_MAP["\342\200\250".force_encoding('UTF-8').encode!] = '&#x2028;'
JS_ESCAPE_MAP["\342\200\251".force_encoding('UTF-8').encode!] = '&#x2029;'
-
# Escapes carriage returns and single and double quotes for JavaScript segments.
#
@@ -37,7 +36,7 @@ module ActionView
# javascript_tag "alert('All is good')"
#
# Returns:
- # <script type="text/javascript">
+ # <script>
# //<![CDATA[
# alert('All is good')
# //]]>
@@ -46,7 +45,7 @@ module ActionView
# +html_options+ may be a hash of attributes for the <tt>\<script></tt>
# tag. Example:
# javascript_tag "alert('All is good')", :defer => 'defer'
- # # => <script defer="defer" type="text/javascript">alert('All is good')</script>
+ # # => <script defer="defer">alert('All is good')</script>
#
# Instead of passing the content as an argument, you can also use a block
# in which case, you pass your +html_options+ as the first parameter.
@@ -62,46 +61,12 @@ module ActionView
content_or_options_with_block
end
- content_tag(:script, javascript_cdata_section(content), html_options.merge(:type => Mime::JS))
+ content_tag(:script, javascript_cdata_section(content), html_options)
end
def javascript_cdata_section(content) #:nodoc:
"\n//#{cdata_section("\n#{content}\n//")}\n".html_safe
end
-
- # Returns a button whose +onclick+ handler triggers the passed JavaScript.
- #
- # The helper receives a name, JavaScript code, and an optional hash of HTML options. The
- # name is used as button label and the JavaScript code goes into its +onclick+ attribute.
- # If +html_options+ has an <tt>:onclick</tt>, that one is put before +function+.
- #
- # button_to_function "Greeting", "alert('Hello world!')", :class => "ok"
- # # => <input class="ok" onclick="alert('Hello world!');" type="button" value="Greeting" />
- #
- def button_to_function(name, function=nil, html_options={})
- onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function};"
-
- tag(:input, html_options.merge(:type => 'button', :value => name, :onclick => onclick))
- end
-
- # Returns a link whose +onclick+ handler triggers the passed JavaScript.
- #
- # The helper receives a name, JavaScript code, and an optional hash of HTML options. The
- # name is used as the link text and the JavaScript code goes into the +onclick+ attribute.
- # If +html_options+ has an <tt>:onclick</tt>, that one is put before +function+. Once all
- # the JavaScript is set, the helper appends "; return false;".
- #
- # The +href+ attribute of the tag is set to "#" unless +html_options+ has one.
- #
- # link_to_function "Greeting", "alert('Hello world!')", :class => "nav_link"
- # # => <a class="nav_link" href="#" onclick="alert('Hello world!'); return false;">Greeting</a>
- #
- def link_to_function(name, function, html_options={})
- onclick = "#{"#{html_options[:onclick]}; " if html_options[:onclick]}#{function}; return false;"
- href = html_options[:href] || '#'
-
- content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick))
- end
end
end
end
diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb
index 485a9357be..dfc26acfad 100644
--- a/actionpack/lib/action_view/helpers/number_helper.rb
+++ b/actionpack/lib/action_view/helpers/number_helper.rb
@@ -28,17 +28,20 @@ module ActionView
end
end
- # Formats a +number+ into a US phone number (e.g., (555) 123-9876). You can customize the format
- # in the +options+ hash.
+ # Formats a +number+ into a US phone number (e.g., (555)
+ # 123-9876). You can customize the format in the +options+ hash.
#
# ==== Options
#
- # * <tt>:area_code</tt> - Adds parentheses around the area code.
- # * <tt>:delimiter</tt> - Specifies the delimiter to use (defaults to "-").
- # * <tt>:extension</tt> - Specifies an extension to add to the end of the
- # generated number.
- # * <tt>:country_code</tt> - Sets the country code for the phone number.
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when the argument is invalid.
+ # * <tt>:area_code</tt> - Adds parentheses around the area code.
+ # * <tt>:delimiter</tt> - Specifies the delimiter to use
+ # (defaults to "-").
+ # * <tt>:extension</tt> - Specifies an extension to add to the
+ # end of the generated number.
+ # * <tt>:country_code</tt> - Sets the country code for the phone
+ # number.
+ # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
+ # the argument is invalid.
#
# ==== Examples
#
@@ -74,31 +77,38 @@ module ActionView
number.slice!(0, 1) if number.start_with?(delimiter) && !delimiter.blank?
end
- str = []
+ str = ''
str << "+#{country_code}#{delimiter}" unless country_code.blank?
str << number
str << " x #{extension}" unless extension.blank?
- ERB::Util.html_escape(str.join)
+ ERB::Util.html_escape(str)
end
- # Formats a +number+ into a currency string (e.g., $13.65). You can customize the format
- # in the +options+ hash.
+ # Formats a +number+ into a currency string (e.g., $13.65). You
+ # can customize the format in the +options+ hash.
#
# ==== Options
#
- # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
- # * <tt>:precision</tt> - Sets the level of precision (defaults to 2).
- # * <tt>:unit</tt> - Sets the denomination of the currency (defaults to "$").
- # * <tt>:separator</tt> - Sets the separator between the units (defaults to ".").
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to ",").
- # * <tt>:format</tt> - Sets the format for non-negative numbers (defaults to "%u%n").
- # Fields are <tt>%u</tt> for the currency, and <tt>%n</tt>
- # for the number.
- # * <tt>:negative_format</tt> - Sets the format for negative numbers (defaults to prepending
- # an hyphen to the formatted number given by <tt>:format</tt>).
- # Accepts the same fields than <tt>:format</tt>, except
- # <tt>%n</tt> is here the absolute value of the number.
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when the argument is invalid.
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
+ # (defaults to current locale).
+ # * <tt>:precision</tt> - Sets the level of precision (defaults
+ # to 2).
+ # * <tt>:unit</tt> - Sets the denomination of the currency
+ # (defaults to "$").
+ # * <tt>:separator</tt> - Sets the separator between the units
+ # (defaults to ".").
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
+ # to ",").
+ # * <tt>:format</tt> - Sets the format for non-negative numbers
+ # (defaults to "%u%n"). Fields are <tt>%u</tt> for the
+ # currency, and <tt>%n</tt> for the number.
+ # * <tt>:negative_format</tt> - Sets the format for negative
+ # numbers (defaults to prepending an hyphen to the formatted
+ # number given by <tt>:format</tt>). Accepts the same fields
+ # than <tt>:format</tt>, except <tt>%n</tt> is here the
+ # absolute value of the number.
+ # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
+ # the argument is invalid.
#
# ==== Examples
#
@@ -137,34 +147,40 @@ module ActionView
begin
value = number_with_precision(number, options.merge(:raise => true))
- format.gsub(/%n/, value).gsub(/%u/, unit).html_safe
+ format.gsub('%n', value).gsub('%u', unit).html_safe
rescue InvalidNumberError => e
if options[:raise]
raise
else
- formatted_number = format.gsub(/%n/, e.number).gsub(/%u/, unit)
+ formatted_number = format.gsub('%n', e.number).gsub('%u', unit)
e.number.to_s.html_safe? ? formatted_number.html_safe : formatted_number
end
end
end
- # Formats a +number+ as a percentage string (e.g., 65%). You can customize the format in the +options+ hash.
+ # Formats a +number+ as a percentage string (e.g., 65%). You can
+ # customize the format in the +options+ hash.
#
# ==== Options
#
- # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current
- # locale).
- # * <tt>:precision</tt> - Sets the precision of the number (defaults to 3).
- # * <tt>:significant</tt> - If +true+, precision will be the # of significant_digits. If +false+,
- # the # of fractional digits (defaults to +false+).
- # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults
- # to ".").
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
- # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator
- # (defaults to +false+).
- # * <tt>:format</tt> - Specifies the format of the percentage string
- # The number field is <tt>%n</tt> (defaults to "%n%").
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when the argument is invalid.
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
+ # (defaults to current locale).
+ # * <tt>:precision</tt> - Sets the precision of the number
+ # (defaults to 3).
+ # * <tt>:significant</tt> - If +true+, precision will be the #
+ # of significant_digits. If +false+, the # of fractional
+ # digits (defaults to +false+).
+ # * <tt>:separator</tt> - Sets the separator between the
+ # fractional and integer digits (defaults to ".").
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
+ # to "").
+ # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
+ # insignificant zeros after the decimal separator (defaults to
+ # +false+).
+ # * <tt>:format</tt> - Specifies the format of the percentage
+ # string The number field is <tt>%n</tt> (defaults to "%n%").
+ # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
+ # the argument is invalid.
#
# ==== Examples
#
@@ -200,15 +216,20 @@ module ActionView
end
end
- # Formats a +number+ with grouped thousands using +delimiter+ (e.g., 12,324). You can
- # customize the format in the +options+ hash.
+ # Formats a +number+ with grouped thousands using +delimiter+
+ # (e.g., 12,324). You can customize the format in the +options+
+ # hash.
#
# ==== Options
#
- # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to ",").
- # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when the argument is invalid.
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
+ # (defaults to current locale).
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
+ # to ",").
+ # * <tt>:separator</tt> - Sets the separator between the
+ # fractional and integer digits (defaults to ".").
+ # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
+ # the argument is invalid.
#
# ==== Examples
#
@@ -233,26 +254,35 @@ module ActionView
parts = number.to_s.to_str.split('.')
parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{options[:delimiter]}")
- parts.join(options[:separator]).html_safe
+ safe_join(parts, options[:separator])
end
- # Formats a +number+ with the specified level of <tt>:precision</tt> (e.g., 112.32 has a precision
- # of 2 if +:significant+ is +false+, and 5 if +:significant+ is +true+).
+ # Formats a +number+ with the specified level of
+ # <tt>:precision</tt> (e.g., 112.32 has a precision of 2 if
+ # +:significant+ is +false+, and 5 if +:significant+ is +true+).
# You can customize the format in the +options+ hash.
#
# ==== Options
- # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
- # * <tt>:precision</tt> - Sets the precision of the number (defaults to 3).
- # * <tt>:significant</tt> - If +true+, precision will be the # of significant_digits. If +false+,
- # the # of fractional digits (defaults to +false+).
- # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults
- # to ".").
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
- # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator
- # (defaults to +false+).
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when the argument is invalid.
+ #
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
+ # (defaults to current locale).
+ # * <tt>:precision</tt> - Sets the precision of the number
+ # (defaults to 3).
+ # * <tt>:significant</tt> - If +true+, precision will be the #
+ # of significant_digits. If +false+, the # of fractional
+ # digits (defaults to +false+).
+ # * <tt>:separator</tt> - Sets the separator between the
+ # fractional and integer digits (defaults to ".").
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
+ # to "").
+ # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
+ # insignificant zeros after the decimal separator (defaults to
+ # +false+).
+ # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
+ # the argument is invalid.
#
# ==== Examples
+ #
# number_with_precision(111.2345) # => 111.235
# number_with_precision(111.2345, :precision => 2) # => 111.23
# number_with_precision(13, :precision => 5) # => 13.00000
@@ -305,23 +335,37 @@ module ActionView
STORAGE_UNITS = [:byte, :kb, :mb, :gb, :tb].freeze
- # Formats the bytes in +number+ into a more understandable representation
- # (e.g., giving it 1500 yields 1.5 KB). This method is useful for
- # reporting file sizes to users. You can customize the
- # format in the +options+ hash.
+ # Formats the bytes in +number+ into a more understandable
+ # representation (e.g., giving it 1500 yields 1.5 KB). This
+ # method is useful for reporting file sizes to users. You can
+ # customize the format in the +options+ hash.
#
- # See <tt>number_to_human</tt> if you want to pretty-print a generic number.
+ # See <tt>number_to_human</tt> if you want to pretty-print a
+ # generic number.
#
# ==== Options
- # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
- # * <tt>:precision</tt> - Sets the precision of the number (defaults to 3).
- # * <tt>:significant</tt> - If +true+, precision will be the # of significant_digits. If +false+, the # of fractional digits (defaults to +true+)
- # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
- # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator (defaults to +true+)
- # * <tt>:prefix</tt> - If +:si+ formats the number using the SI prefix (defaults to :binary)
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when the argument is invalid.
+ #
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
+ # (defaults to current locale).
+ # * <tt>:precision</tt> - Sets the precision of the number
+ # (defaults to 3).
+ # * <tt>:significant</tt> - If +true+, precision will be the #
+ # of significant_digits. If +false+, the # of fractional
+ # digits (defaults to +true+)
+ # * <tt>:separator</tt> - Sets the separator between the
+ # fractional and integer digits (defaults to ".").
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
+ # to "").
+ # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
+ # insignificant zeros after the decimal separator (defaults to
+ # +true+)
+ # * <tt>:prefix</tt> - If +:si+ formats the number using the SI
+ # prefix (defaults to :binary)
+ # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
+ # the argument is invalid.
+ #
# ==== Examples
+ #
# number_to_human_size(123) # => 123 Bytes
# number_to_human_size(1234) # => 1.21 KB
# number_to_human_size(12345) # => 12.1 KB
@@ -332,8 +376,10 @@ module ActionView
# number_to_human_size(483989, :precision => 2) # => 470 KB
# number_to_human_size(1234567, :precision => 2, :separator => ',') # => 1,2 MB
#
- # Non-significant zeros after the fractional separator are stripped out by default (set
- # <tt>:strip_insignificant_zeros</tt> to +false+ to change that):
+ # Non-significant zeros after the fractional separator are
+ # stripped out by default (set
+ # <tt>:strip_insignificant_zeros</tt> to +false+ to change
+ # that):
# number_to_human_size(1234567890123, :precision => 5) # => "1.1229 TB"
# number_to_human_size(524288000, :precision => 5) # => "500 MB"
def number_to_human_size(number, options = {})
@@ -371,33 +417,55 @@ module ActionView
DECIMAL_UNITS = {0 => :unit, 1 => :ten, 2 => :hundred, 3 => :thousand, 6 => :million, 9 => :billion, 12 => :trillion, 15 => :quadrillion,
-1 => :deci, -2 => :centi, -3 => :mili, -6 => :micro, -9 => :nano, -12 => :pico, -15 => :femto}.freeze
- # Pretty prints (formats and approximates) a number in a way it is more readable by humans
- # (eg.: 1200000000 becomes "1.2 Billion"). This is useful for numbers that
- # can get very large (and too hard to read).
+ # Pretty prints (formats and approximates) a number in a way it
+ # is more readable by humans (eg.: 1200000000 becomes "1.2
+ # Billion"). This is useful for numbers that can get very large
+ # (and too hard to read).
#
- # See <tt>number_to_human_size</tt> if you want to print a file size.
+ # See <tt>number_to_human_size</tt> if you want to print a file
+ # size.
#
- # You can also define you own unit-quantifier names if you want to use other decimal units
- # (eg.: 1500 becomes "1.5 kilometers", 0.150 becomes "150 milliliters", etc). You may define
- # a wide range of unit quantifiers, even fractional ones (centi, deci, mili, etc).
+ # You can also define you own unit-quantifier names if you want
+ # to use other decimal units (eg.: 1500 becomes "1.5
+ # kilometers", 0.150 becomes "150 milliliters", etc). You may
+ # define a wide range of unit quantifiers, even fractional ones
+ # (centi, deci, mili, etc).
#
# ==== Options
- # * <tt>:locale</tt> - Sets the locale to be used for formatting (defaults to current locale).
- # * <tt>:precision</tt> - Sets the precision of the number (defaults to 3).
- # * <tt>:significant</tt> - If +true+, precision will be the # of significant_digits. If +false+, the # of fractional digits (defaults to +true+)
- # * <tt>:separator</tt> - Sets the separator between the fractional and integer digits (defaults to ".").
- # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults to "").
- # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes insignificant zeros after the decimal separator (defaults to +true+)
- # * <tt>:units</tt> - A Hash of unit quantifier names. Or a string containing an i18n scope where to find this hash. It might have the following keys:
- # * *integers*: <tt>:unit</tt>, <tt>:ten</tt>, <tt>:hundred</tt>, <tt>:thousand</tt>, <tt>:million</tt>, <tt>:billion</tt>, <tt>:trillion</tt>, <tt>:quadrillion</tt>
- # * *fractionals*: <tt>:deci</tt>, <tt>:centi</tt>, <tt>:mili</tt>, <tt>:micro</tt>, <tt>:nano</tt>, <tt>:pico</tt>, <tt>:femto</tt>
- # * <tt>:format</tt> - Sets the format of the output string (defaults to "%n %u"). The field types are:
- # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when the argument is invalid.
- #
- # %u The quantifier (ex.: 'thousand')
- # %n The number
+ #
+ # * <tt>:locale</tt> - Sets the locale to be used for formatting
+ # (defaults to current locale).
+ # * <tt>:precision</tt> - Sets the precision of the number
+ # (defaults to 3).
+ # * <tt>:significant</tt> - If +true+, precision will be the #
+ # of significant_digits. If +false+, the # of fractional
+ # digits (defaults to +true+)
+ # * <tt>:separator</tt> - Sets the separator between the
+ # fractional and integer digits (defaults to ".").
+ # * <tt>:delimiter</tt> - Sets the thousands delimiter (defaults
+ # to "").
+ # * <tt>:strip_insignificant_zeros</tt> - If +true+ removes
+ # insignificant zeros after the decimal separator (defaults to
+ # +true+)
+ # * <tt>:units</tt> - A Hash of unit quantifier names. Or a
+ # string containing an i18n scope where to find this hash. It
+ # might have the following keys:
+ # * *integers*: <tt>:unit</tt>, <tt>:ten</tt>,
+ # *<tt>:hundred</tt>, <tt>:thousand</tt>, <tt>:million</tt>,
+ # *<tt>:billion</tt>, <tt>:trillion</tt>,
+ # *<tt>:quadrillion</tt>
+ # * *fractionals*: <tt>:deci</tt>, <tt>:centi</tt>,
+ # *<tt>:mili</tt>, <tt>:micro</tt>, <tt>:nano</tt>,
+ # *<tt>:pico</tt>, <tt>:femto</tt>
+ # * <tt>:format</tt> - Sets the format of the output string
+ # (defaults to "%n %u"). The field types are:
+ # * %u - The quantifier (ex.: 'thousand')
+ # * %n - The number
+ # * <tt>:raise</tt> - If true, raises +InvalidNumberError+ when
+ # the argument is invalid.
#
# ==== Examples
+ #
# number_to_human(123) # => "123"
# number_to_human(1234) # => "1.23 Thousand"
# number_to_human(12345) # => "12.3 Thousand"
@@ -414,8 +482,9 @@ module ActionView
# :separator => ',',
# :significant => false) # => "1,2 Million"
#
- # Unsignificant zeros after the decimal separator are stripped out by default (set
- # <tt>:strip_insignificant_zeros</tt> to +false+ to change that):
+ # Non-significant zeros after the decimal separator are stripped
+ # out by default (set <tt>:strip_insignificant_zeros</tt> to
+ # +false+ to change that):
# number_to_human(12345012345, :significant_digits => 6) # => "12.345 Billion"
# number_to_human(500000000, :precision => 5) # => "500 Million"
#
diff --git a/actionpack/lib/action_view/helpers/record_tag_helper.rb b/actionpack/lib/action_view/helpers/record_tag_helper.rb
index 1a15459406..9b35f076e5 100644
--- a/actionpack/lib/action_view/helpers/record_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/record_tag_helper.rb
@@ -94,10 +94,10 @@ module ActionView
# for each record.
def content_tag_for_single_record(tag_name, record, prefix, options, &block)
options = options ? options.dup : {}
- options.merge!(:class => "#{dom_class(record, prefix)} #{options[:class]}".rstrip, :id => dom_id(record, prefix))
+ options[:class] = "#{dom_class(record, prefix)} #{options[:class]}".rstrip
+ options[:id] = dom_id(record, prefix)
- content = block.arity == 0 ? capture(&block) : capture(record, &block)
- content_tag(tag_name, content, options)
+ content_tag(tag_name, capture(record, &block), options)
end
end
end
diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb
index 71be2955a8..f7afa48256 100644
--- a/actionpack/lib/action_view/helpers/tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/tag_helper.rb
@@ -14,7 +14,7 @@ module ActionView
BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer
autoplay controls loop selected hidden scoped async
defer reversed ismap seemless muted required
- autofocus novalidate formnovalidate open pubdate).to_set
+ autofocus novalidate formnovalidate open pubdate itemscope).to_set
BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map {|attribute| attribute.to_sym })
PRE_CONTENT_STRINGS = {
@@ -109,8 +109,12 @@ module ActionView
#
# cdata_section(File.read("hello_world.txt"))
# # => <![CDATA[<hello from a text file]]>
+ #
+ # cdata_section("hello]]>world")
+ # # => <![CDATA[hello]]]]><![CDATA[>world]]>
def cdata_section(content)
- "<![CDATA[#{content}]]>".html_safe
+ splitted = content.gsub(']]>', ']]]]><![CDATA[>')
+ "<![CDATA[#{splitted}]]>".html_safe
end
# Returns an escaped version of +html+ without affecting existing escaped entities.
diff --git a/actionpack/lib/action_view/helpers/tags/base.rb b/actionpack/lib/action_view/helpers/tags/base.rb
index 7c2f12d8e7..380ebe4b65 100644
--- a/actionpack/lib/action_view/helpers/tags/base.rb
+++ b/actionpack/lib/action_view/helpers/tags/base.rb
@@ -121,15 +121,20 @@ 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 }
+ if html_options["multiple"] && options.fetch(:include_hidden, true)
tag("input", :disabled => html_options["disabled"], :name => html_options["name"], :type => "hidden", :value => "") + select
else
select
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
diff --git a/actionpack/lib/action_view/helpers/tags/check_box.rb b/actionpack/lib/action_view/helpers/tags/check_box.rb
index 1a4aebb936..9d17a1dde3 100644
--- a/actionpack/lib/action_view/helpers/tags/check_box.rb
+++ b/actionpack/lib/action_view/helpers/tags/check_box.rb
@@ -41,17 +41,15 @@ module ActionView
def checked?(value)
case value
when TrueClass, FalseClass
- value
+ value == !!@checked_value
when NilClass
false
- when Integer
- value != 0
when String
value == @checked_value
when Array
value.include?(@checked_value)
else
- value.to_i != 0
+ value.to_i == @checked_value.to_i
end
end
diff --git a/actionpack/lib/action_view/helpers/tags/collection_helpers.rb b/actionpack/lib/action_view/helpers/tags/collection_helpers.rb
index 6a1479069f..4e33e79a36 100644
--- a/actionpack/lib/action_view/helpers/tags/collection_helpers.rb
+++ b/actionpack/lib/action_view/helpers/tags/collection_helpers.rb
@@ -49,7 +49,7 @@ module ActionView
accept = if current_value.respond_to?(:call)
current_value.call(item)
else
- Array(current_value).include?(value)
+ Array(current_value).map(&:to_s).include?(value.to_s)
end
if accept
diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb
index 3dc651501e..698f4434ba 100644
--- a/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/actionpack/lib/action_view/helpers/text_helper.rb
@@ -1,5 +1,6 @@
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/string/filters'
+require 'active_support/core_ext/array/extract_options'
module ActionView
# = Action View Text Helpers
@@ -44,7 +45,7 @@ module ActionView
# if logged_in
# concat "Logged in!"
# else
- # concat link_to('login', :action => login)
+ # concat link_to('login', :action => :login)
# end
# # will either display "Logged in!" or a login link
# %>
@@ -89,7 +90,7 @@ 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
@@ -107,13 +108,15 @@ 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?
- options[:highlighter] = args[0] || '<mark>\1</mark>'
+ options[:highlighter] = args[0]
end
- options.reverse_merge!(:highlighter => '<mark>\1</mark>')
+ options[:highlighter] ||= '<mark>\1</mark>'
text = sanitize(text) unless options[:sanitize] == false
if text.blank? || phrases.blank?
@@ -156,19 +159,20 @@ module ActionView
options = args.extract_options!
unless args.empty?
- options[:radius] = args[0] || 100
- options[:omission] = args[1] || "..."
+ options[:radius] = args[0]
+ options[:omission] = args[1]
end
- options.reverse_merge!(:radius => 100, :omission => "...")
+ radius = options[:radius] || 100
+ omission = options[:omission] || "..."
phrase = Regexp.escape(phrase)
return unless found_pos = text =~ /(#{phrase})/i
- start_pos = [ found_pos - options[:radius], 0 ].max
- end_pos = [ [ found_pos + phrase.length + options[:radius] - 1, 0].max, text.length ].min
+ start_pos = [ found_pos - radius, 0 ].max
+ end_pos = [ [ found_pos + phrase.length + radius - 1, 0].max, text.length ].min
- prefix = start_pos > 0 ? options[:omission] : ""
- postfix = end_pos < text.length - 1 ? options[:omission] : ""
+ prefix = start_pos > 0 ? omission : ""
+ postfix = end_pos < text.length - 1 ? omission : ""
prefix + text[start_pos..end_pos].strip + postfix
end
@@ -217,12 +221,12 @@ module ActionView
def word_wrap(text, *args)
options = args.extract_options!
unless args.blank?
- options[:line_width] = args[0] || 80
+ options[:line_width] = args[0]
end
- options.reverse_merge!(:line_width => 80)
+ line_width = options[:line_width] || 80
text.split("\n").collect do |line|
- line.length > options[:line_width] ? line.gsub(/(.{1,#{options[:line_width]}})(\s+|$)/, "\\1\n").strip : line
+ line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line
end * "\n"
end
@@ -306,12 +310,9 @@ module ActionView
# </tr>
# <% end %>
def cycle(first_value, *values)
- if (values.last.instance_of? Hash)
- params = values.pop
- name = params[:name]
- else
- name = "default"
- end
+ options = values.extract_options!
+ name = options.fetch(:name, "default")
+
values.unshift(first_value)
cycle = get_cycle(name)
diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb
index cc74eff53a..8171bea8ed 100644
--- a/actionpack/lib/action_view/helpers/translation_helper.rb
+++ b/actionpack/lib/action_view/helpers/translation_helper.rb
@@ -45,6 +45,7 @@ module ActionView
# you know what kind of output to expect when you call translate in a template.
def translate(key, options = {})
options.merge!(:rescue_format => :html) unless options.key?(:rescue_format)
+ options[:default] = wrap_translate_defaults(options[:default]) if options[:default]
if html_safe_translation_key?(key)
html_safe_options = options.dup
options.except(*I18n::RESERVED_KEYS).each do |name, value|
@@ -62,6 +63,9 @@ module ActionView
alias :t :translate
# Delegates to <tt>I18n.localize</tt> with no additional functionality.
+ #
+ # See http://rubydoc.info/github/svenfuchs/i18n/master/I18n/Backend/Base:localize
+ # for more information.
def localize(*args)
I18n.localize(*args)
end
@@ -83,6 +87,21 @@ module ActionView
def html_safe_translation_key?(key)
key.to_s =~ /(\b|_|\.)html$/
end
+
+ def wrap_translate_defaults(defaults)
+ new_defaults = []
+ defaults = Array(defaults)
+ while key = defaults.shift
+ if key.is_a?(Symbol)
+ new_defaults << lambda { |_, options| translate key, options.merge(:default => defaults) }
+ break
+ else
+ new_defautls << key
+ end
+ end
+
+ new_defaults
+ 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 4a641fada3..802bf9d29f 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -303,7 +303,10 @@ module ActionView
#
# <%= button_to "Create", :action => "create", :remote => true, :form => { "data-type" => "json" } %>
# # => "<form method="post" action="/images/create" class="button_to" data-remote="true" data-type="json">
- # # <div><input value="Create" type="submit" /></div>
+ # # <div>
+ # # <input value="Create" type="submit" />
+ # # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
+ # # </div>
# # </form>"
#
#
@@ -312,7 +315,8 @@ module ActionView
# # => "<form method="post" action="/images/delete/1" class="button_to">
# # <div>
# # <input type="hidden" name="_method" value="delete" />
- # # <input data-confirm='Are you sure?' value="Delete" type="submit" />
+ # # <input data-confirm='Are you sure?' value="Delete Image" type="submit" />
+ # # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
# # </div>
# # </form>"
#
@@ -323,6 +327,7 @@ module ActionView
# # <div>
# # <input name='_method' value='delete' type='hidden' />
# # <input value='Destroy' type='submit' disable_with='loading...' data-confirm='Are you sure?' />
+ # # <input name="authenticity_token" type="hidden" value="10f2163b45388899ad4d5ae948988266befcb6c3d1b2451cf657a0c293d605a6"/>
# # </div>
# # </form>"
# #
@@ -481,7 +486,7 @@ module ActionView
# # => <a href="mailto:me@domain.com">me@domain.com</a>
#
# mail_to "me@domain.com", "My email", :encode => "javascript"
- # # => <script type="text/javascript">eval(decodeURIComponent('%64%6f%63...%27%29%3b'))</script>
+ # # => <script>eval(decodeURIComponent('%64%6f%63...%27%29%3b'))</script>
#
# mail_to "me@domain.com", "My email", :encode => "hex"
# # => <a href="mailto:%6d%65@%64%6f%6d%61%69%6e.%63%6f%6d">My email</a>
@@ -515,7 +520,7 @@ module ActionView
"document.write('#{html}');".each_byte do |c|
string << sprintf("%%%x", c)
end
- "<script type=\"#{Mime::JS}\">eval(decodeURIComponent('#{string}'))</script>".html_safe
+ "<script>eval(decodeURIComponent('#{string}'))</script>".html_safe
when "hex"
email_address_encoded = email_address_obfuscated.unpack('C*').map {|c|
sprintf("&#%d;", c)
@@ -665,11 +670,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 8b53867aea..9100545718 100644
--- a/actionpack/lib/action_view/renderer/partial_renderer.rb
+++ b/actionpack/lib/action_view/renderer/partial_renderer.rb
@@ -158,8 +158,8 @@ module ActionView
# Name: <%= user.name %>
# </div>
#
- # If a collection is given, the layout will be rendered once for each item in the collection. Just think
- # these two snippets have the same output:
+ # If a collection is given, the layout will be rendered once for each item in
+ # the collection. Just think these two snippets have the same output:
#
# <%# app/views/users/_user.html.erb %>
# Name: <%= user.name %>
@@ -184,7 +184,7 @@ module ActionView
# <%= render :partial => "user", :layout => "li_layout", :collection => users %>
# </ul>
#
- # Given two users whose names are Alice and Bob, these snippets return:
+ # Given two users whose names are Alice and Bob, these snippets return:
#
# <ul>
# <li>
@@ -195,6 +195,10 @@ module ActionView
# </li>
# </ul>
#
+ # The current object being rendered, as well as the object_counter, will be
+ # available as local variables inside the layout template under the same names
+ # as available in the partial.
+ #
# You can also apply a layout to a block within any template:
#
# <%# app/views/users/_chief.html.erb &>
@@ -279,26 +283,19 @@ module ActionView
return nil if @collection.blank?
if @options.key?(:spacer_template)
- spacer = find_template(@options[:spacer_template]).render(@view, @locals)
- end
-
- if layout = @options[:layout]
- layout = find_template(layout)
+ spacer = find_template(@options[:spacer_template], @locals.keys).render(@view, @locals)
end
result = @template ? collection_with_template : collection_without_template
-
- result.map!{|content| layout.render(@view, @locals) { content } } if layout
-
result.join(spacer).html_safe
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)
+ layout = find_template(layout, @template_keys)
end
object ||= locals[as]
@@ -340,14 +337,15 @@ 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
if String === partial && @variable.to_s !~ /^[a-z_][a-zA-Z_0-9]*$/
raise ArgumentError.new("The partial name (#{partial}) is not a valid Ruby identifier; " +
- "make sure your partial name starts with a letter or underscore, " +
- "and is followed by any combinations of letters, numbers, or underscores.")
+ "make sure your partial name starts with a lowercase letter or underscore, " +
+ "and is followed by any combination of letters, numbers and underscores.")
end
self
@@ -361,56 +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
- locals[counter] = -1
+ if layout = @options[:layout]
+ layout = find_template(layout, @template_keys)
+ end
+
+ index = -1
+ @collection.map do |object|
+ locals[as] = object
+ locals[counter] = (index += 1)
- @collection.each do |object|
- locals[counter] += 1
- locals[as] = object
- segments << template.render(@view, locals)
+ 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)
@@ -450,8 +447,15 @@ 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[:as].try(:to_sym) || path[%r'_?(\w+)(\.\w+)*$', 1].to_sym
+ variable = @options.fetch(:as) { path[%r'_?(\w+)(\.\w+)*$', 1] }.try(:to_sym)
variable_counter = :"#{variable}_counter" if @collection
[variable, variable_counter]
end
diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb
index 8ea2e5bfe4..08155af013 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