aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view/helpers
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_view/helpers')
-rw-r--r--actionpack/lib/action_view/helpers/active_model_helper.rb5
-rw-r--r--actionpack/lib/action_view/helpers/asset_paths.rb7
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb10
-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/atom_feed_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/cache_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/capture_helper.rb39
-rw-r--r--actionpack/lib/action_view/helpers/date_helper.rb39
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb70
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb7
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb19
-rw-r--r--actionpack/lib/action_view/helpers/javascript_helper.rb8
-rw-r--r--actionpack/lib/action_view/helpers/number_helper.rb10
-rw-r--r--actionpack/lib/action_view/helpers/rendering_helper.rb4
-rw-r--r--actionpack/lib/action_view/helpers/sanitize_helper.rb1
-rw-r--r--actionpack/lib/action_view/helpers/text_helper.rb4
-rw-r--r--actionpack/lib/action_view/helpers/translation_helper.rb15
18 files changed, 161 insertions, 88 deletions
diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb
index 96c3eec337..56f15604a6 100644
--- a/actionpack/lib/action_view/helpers/active_model_helper.rb
+++ b/actionpack/lib/action_view/helpers/active_model_helper.rb
@@ -1,4 +1,3 @@
-require 'action_view/helpers/form_helper'
require 'active_support/core_ext/class/attribute_accessors'
require 'active_support/core_ext/enumerable'
require 'active_support/core_ext/object/blank'
@@ -47,9 +46,5 @@ module ActionView
options['type'] != 'hidden'
end
end
-
- class InstanceTag
- include ActiveModelInstanceTag
- end
end
end
diff --git a/actionpack/lib/action_view/helpers/asset_paths.rb b/actionpack/lib/action_view/helpers/asset_paths.rb
deleted file mode 100644
index fae2e4fc1c..0000000000
--- a/actionpack/lib/action_view/helpers/asset_paths.rb
+++ /dev/null
@@ -1,7 +0,0 @@
-ActiveSupport::Deprecation.warn "ActionView::Helpers::AssetPaths is deprecated. Please use ActionView::AssetPaths instead."
-
-module ActionView
- module Helpers
- AssetPaths = ::ActionView::AssetPaths
- end
-end \ No newline at end of file
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index 7d01e5ddb8..653e12c7d8 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -228,23 +228,19 @@ module ActionView
)
end
- # Web browsers cache favicons. If you just throw a <tt>favicon.ico</tt> into the document
- # root of your application and it changes later, clients that have it in their cache
- # won't see the update. Using this helper prevents that because it appends an asset ID:
- #
# <%= favicon_link_tag %>
#
# generates
#
- # <link href="/favicon.ico?4649789979" rel="shortcut icon" type="image/vnd.microsoft.icon" />
+ # <link href="/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />
#
# You may specify a different file in the first argument:
#
- # <%= favicon_link_tag 'favicon.ico' %>
+ # <%= favicon_link_tag '/myicon.ico' %>
#
# That's passed to +path_to_image+ as is, so it gives
#
- # <link href="/images/favicon.ico?4649789979" rel="shortcut icon" type="image/vnd.microsoft.icon" />
+ # <link href="/myicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />
#
# The helper accepts an additional options hash where you can override "rel" and "type".
#
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 09700bd0c5..d9f1f88ade 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
@@ -119,10 +119,10 @@ module ActionView
# # <script type="text/javascript" src="/elsewhere/cools.js?1423139606"></script>
#
# javascript_include_tag "http://www.example.com/xmlhr"
- # # => <script type="text/javascript" src="http://www.example.com/xmlhr.js?1284139606"></script>
+ # # => <script type="text/javascript" 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?1284139606"></script>
+ # # => <script type="text/javascript" src="http://www.example.com/xmlhr.js"></script>
#
# javascript_include_tag :defaults
# # => <script type="text/javascript" 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 343153c8c5..41958c6559 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
@@ -68,6 +68,9 @@ module ActionView
# Returns a stylesheet link tag for the sources specified as arguments. If
# you don't specify an extension, <tt>.css</tt> will be appended automatically.
# You can modify the link attributes by passing a hash as the last argument.
+ # For historical reasons, the 'media' attribute will always be present and defaults
+ # 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" # =>
diff --git a/actionpack/lib/action_view/helpers/atom_feed_helper.rb b/actionpack/lib/action_view/helpers/atom_feed_helper.rb
index 39c37b25dc..73824dc1f8 100644
--- a/actionpack/lib/action_view/helpers/atom_feed_helper.rb
+++ b/actionpack/lib/action_view/helpers/atom_feed_helper.rb
@@ -32,7 +32,7 @@ module ActionView
# app/views/posts/index.atom.builder:
# atom_feed do |feed|
# feed.title("My great blog!")
- # feed.updated(@posts.first.created_at)
+ # feed.updated(@posts[0].created_at) if @posts.length > 0
#
# @posts.each do |post|
# feed.entry(post) do |entry|
diff --git a/actionpack/lib/action_view/helpers/cache_helper.rb b/actionpack/lib/action_view/helpers/cache_helper.rb
index f81ce3e31c..850dd5f448 100644
--- a/actionpack/lib/action_view/helpers/cache_helper.rb
+++ b/actionpack/lib/action_view/helpers/cache_helper.rb
@@ -54,7 +54,7 @@ module ActionView
output_safe = output_buffer.html_safe?
fragment = output_buffer.slice!(pos..-1)
if output_safe
- self.output_buffer = output_buffer.html_safe
+ self.output_buffer = output_buffer.class.new(output_buffer)
end
controller.write_fragment(name, fragment, options)
end
diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb
index 8abd85c3a3..17bbfe2efd 100644
--- a/actionpack/lib/action_view/helpers/capture_helper.rb
+++ b/actionpack/lib/action_view/helpers/capture_helper.rb
@@ -81,8 +81,8 @@ module ActionView
# <%# This is the layout %>
# <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
# <head>
- # <title>My Website</title>
- # <%= yield :script %>
+ # <title>My Website</title>
+ # <%= yield :script %>
# </head>
# <body>
# <%= yield %>
@@ -110,7 +110,7 @@ module ActionView
# That will place +script+ tags for your default set of JavaScript files on the page;
# this technique is useful if you'll only be using these scripts in a few views.
#
- # Note that content_for concatenates the blocks it is given for a particular
+ # Note that content_for concatenates (default) the blocks it is given for a particular
# identifier in order. For example:
#
# <% content_for :navigation do %>
@@ -127,16 +127,37 @@ module ActionView
#
# <ul><%= content_for :navigation %></ul>
#
+ # If the flush parameter is true content_for replaces the blocks it is given. For example:
+ #
+ # <% content_for :navigation do %>
+ # <li><%= link_to 'Home', :action => 'index' %></li>
+ # <% end %>
+ #
+ # <%# Add some other content, or use a different template: %>
+ #
+ # <% content_for :navigation, true do %>
+ # <li><%= link_to 'Login', :action => 'login' %></li>
+ # <% end %>
+ #
+ # Then, in another template or layout, this code would render only the last link:
+ #
+ # <ul><%= content_for :navigation %></ul>
+ #
# Lastly, simple content can be passed as a parameter:
#
# <% content_for :script, javascript_include_tag(:defaults) %>
#
# WARNING: content_for is ignored in caches. So you shouldn't use it
# for elements that will be fragment cached.
- def content_for(name, content = nil, &block)
+ def content_for(name, content = nil, flush = false, &block)
if content || block_given?
- content = capture(&block) if block_given?
- @view_flow.append(name, content) if content
+ if block_given?
+ flush = content if content
+ content = capture(&block)
+ end
+ if content
+ flush ? @view_flow.set(name, content) : @view_flow.append(name, content)
+ end
nil
else
@view_flow.get(name)
@@ -164,8 +185,8 @@ module ActionView
# <%# This is the layout %>
# <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
# <head>
- # <title>My Website</title>
- # <%= yield :script %>
+ # <title>My Website</title>
+ # <%= yield :script %>
# </head>
# <body class="<%= content_for?(:right_col) ? 'one-column' : 'two-column' %>">
# <%= yield %>
@@ -181,7 +202,7 @@ module ActionView
def with_output_buffer(buf = nil) #:nodoc:
unless buf
buf = ActionView::OutputBuffer.new
- buf.force_encoding(output_buffer.encoding) if output_buffer.respond_to?(:encoding) && buf.respond_to?(:force_encoding)
+ buf.force_encoding(output_buffer.encoding) if output_buffer
end
self.output_buffer, old_buffer = buf, output_buffer
yield
diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb
index e850c258ce..2806348337 100644
--- a/actionpack/lib/action_view/helpers/date_helper.rb
+++ b/actionpack/lib/action_view/helpers/date_helper.rb
@@ -422,7 +422,7 @@ module ActionView
end
# Returns a select tag with options for each of the seconds 0 through 59 with the current second selected.
- # The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
+ # 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
@@ -448,7 +448,7 @@ module ActionView
# Returns a select tag with options for each of the minutes 0 through 59 with the current minute selected.
# Also can return a select tag with options by <tt>minute_step</tt> from 0 through 59 with the 00 minute
- # selected. The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
+ # 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
@@ -473,7 +473,7 @@ module ActionView
end
# Returns a select tag with options for each of the hours 0 through 23 with the current hour selected.
- # The <tt>datetime</tt> can be either a +Time+ or +DateTime+ object or an integer.
+ # 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
@@ -736,7 +736,7 @@ module ActionView
if @options[:use_hidden] || @options[:discard_day]
build_hidden(:day, day)
else
- build_options_and_select(:day, day, :start => 1, :end => 31, :leading_zeros => false)
+ build_options_and_select(:day, day, :start => 1, :end => 31, :leading_zeros => false, :use_two_digit_numbers => @options[:use_two_digit_numbers])
end
end
@@ -765,11 +765,16 @@ module ActionView
if @options[:use_hidden] || @options[:discard_year]
build_hidden(:year, val)
else
- options = {}
- options[:start] = @options[:start_year] || middle_year - 5
- options[:end] = @options[:end_year] || middle_year + 5
- options[:step] = options[:start] < options[:end] ? 1 : -1
- options[:leading_zeros] = false
+ options = {}
+ options[:start] = @options[:start_year] || middle_year - 5
+ options[:end] = @options[:end_year] || middle_year + 5
+ options[:step] = options[:start] < options[:end] ? 1 : -1
+ options[:leading_zeros] = false
+ options[:max_years_allowed] = @options[:max_years_allowed] || 1000
+
+ if (options[:end] - options[:start]).abs > options[:max_years_allowed]
+ raise ArgumentError, "There're too many years options to be built. Are you sure you haven't mistyped something? You can provide the :max_years_allowed parameter"
+ end
build_options_and_select(:year, val, options)
end
@@ -817,6 +822,8 @@ module ActionView
def month_name(number)
if @options[:use_month_numbers]
number
+ elsif @options[:use_two_digit_numbers]
+ sprintf "%02d", number
elsif @options[:add_month_numbers]
"#{number} - #{month_names[number]}"
else
@@ -852,7 +859,7 @@ module ActionView
start = options.delete(:start) || 0
stop = options.delete(:end) || 59
step = options.delete(:step) || 1
- options.reverse_merge!({:leading_zeros => true, :ampm => false})
+ options.reverse_merge!({:leading_zeros => true, :ampm => false, :use_two_digit_numbers => false})
leading_zeros = options.delete(:leading_zeros)
select_options = []
@@ -860,7 +867,8 @@ module ActionView
value = leading_zeros ? sprintf("%02d", i) : i
tag_options = { :value => value }
tag_options[:selected] = "selected" if selected == i
- text = options[:ampm] ? AMPM_TRANSLATION[i] : value
+ text = options[:use_two_digit_numbers] ? sprintf("%02d", i) : value
+ text = options[:ampm] ? AMPM_TRANSLATION[i] : text
select_options << content_tag(:option, text, tag_options)
end
(select_options.join("\n") + "\n").html_safe
@@ -939,8 +947,9 @@ module ActionView
# and join them with their appropriate separators.
def build_selects_from_types(order)
select = ''
+ first_visible = order.find { |type| !@options[:"discard_#{type}"] }
order.reverse.each do |type|
- separator = separator(type) unless type == order.first # don't add on last field
+ separator = separator(type) unless type == first_visible # don't add before first visible field
select.insert(0, separator.to_s + send("select_#{type}").to_s)
end
select.html_safe
@@ -965,7 +974,7 @@ module ActionView
end
end
- class InstanceTag #:nodoc:
+ module DateHelperInstanceTag
def to_date_select_tag(options = {}, html_options = {})
datetime_selector(options, html_options).select_date.html_safe
end
@@ -1021,6 +1030,10 @@ module ActionView
end
end
+ class InstanceTag #:nodoc:
+ include DateHelperInstanceTag
+ end
+
class FormBuilder
def date_select(method, options = {}, html_options = {})
@template.date_select(@object_name, method, objectify_options(options), html_options)
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index f22c466666..5a301ca9b1 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -2,9 +2,9 @@ require 'cgi'
require 'action_view/helpers/date_helper'
require 'action_view/helpers/tag_helper'
require 'action_view/helpers/form_tag_helper'
+require 'action_view/helpers/active_model_helper'
require 'active_support/core_ext/class/attribute'
require 'active_support/core_ext/hash/slice'
-require 'active_support/core_ext/module/method_names'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/string/output_safety'
require 'active_support/core_ext/array/extract_options'
@@ -158,6 +158,9 @@ module ActionView
# * <tt>:url</tt> - The URL the form is submitted to. It takes the same
# fields you pass to +url_for+ or +link_to+. In particular you may pass
# here a named route directly as well. Defaults to the current action.
+ # * <tt>:namespace</tt> - A namespace for your form to ensure uniqueness of
+ # id attributes on form elements. The namespace attribute will be prefixed
+ # with underscore on the generated HTML id.
# * <tt>:html</tt> - Optional HTML attributes for the form tag.
#
# Also note that +form_for+ doesn't create an exclusive scope. It's still
@@ -384,8 +387,8 @@ module ActionView
as = options[:as]
action, method = object.respond_to?(:persisted?) && object.persisted? ? [:edit, :put] : [:new, :post]
options[:html].reverse_merge!(
- :class => as ? "#{as}_#{action}" : dom_class(object, action),
- :id => as ? "#{as}_#{action}" : dom_id(object, action),
+ :class => as ? "#{action}_#{as}" : dom_class(object, action),
+ :id => as ? "#{action}_#{as}" : [options[:namespace], dom_id(object, action)].compact.join("_").presence,
:method => method
)
@@ -649,7 +652,7 @@ module ActionView
# # => <label for="post_privacy_public">Public Post</label>
#
# label(:post, :terms) do
- # 'Accept <a href="/terms">Terms</a>.'
+ # 'Accept <a href="/terms">Terms</a>.'.html_safe
# end
def label(object_name, method, content_or_options = nil, options = nil, &block)
content_is_options = content_or_options.is_a?(Hash)
@@ -738,7 +741,7 @@ module ActionView
# # => <input type="file" id="user_avatar" name="user[avatar]" />
#
# file_field(:post, :attached, :accept => 'text/html')
- # # => <input type="file" id="post_attached" name="post[attached]" />
+ # # => <input accept="text/html" type="file" id="post_attached" name="post[attached]" />
#
# file_field(:attachment, :file, :class => 'file_input')
# # => <input type="file" id="attachment_file" name="attachment[file]" class="file_input" />
@@ -960,7 +963,7 @@ module ActionView
end
class InstanceTag
- include Helpers::CaptureHelper, Context, Helpers::TagHelper, Helpers::FormTagHelper
+ include Helpers::ActiveModelInstanceTag, Helpers::TagHelper, Helpers::FormTagHelper
attr_reader :object, :method_name, :object_name
@@ -971,6 +974,7 @@ module ActionView
def initialize(object_name, method_name, template_object, object = nil)
@object_name, @method_name = object_name.to_s.dup, method_name.to_s.dup
@template_object = template_object
+
@object_name.sub!(/\[\]$/,"") || @object_name.sub!(/\[\]\]$/,"]")
@object = retrieve_object(object)
@auto_index = retrieve_autoindex(Regexp.last_match.pre_match) if Regexp.last_match
@@ -989,14 +993,23 @@ module ActionView
add_default_name_and_id_for_value(tag_value, name_and_id)
options.delete("index")
+ options.delete("namespace")
options["for"] ||= name_and_id["id"]
if block_given?
- label_tag(name_and_id["id"], options, &block)
+ @template_object.label_tag(name_and_id["id"], options, &block)
else
content = if text.blank?
+ object_name.gsub!(/\[(.*)_attributes\]\[\d\]/, '.\1')
method_and_value = tag_value.present? ? "#{method_name}.#{tag_value}" : method_name
- I18n.t("helpers.label.#{object_name}.#{method_and_value}", :default => "").presence
+
+ if object.respond_to?(:to_model)
+ key = object.class.model_name.i18n_key
+ i18n_default = ["#{key}.#{method_and_value}".to_sym, ""]
+ end
+
+ i18n_default ||= ""
+ I18n.t("#{object_name}.#{method_and_value}", :default => i18n_default, :scope => "helpers.label").presence
else
text.to_s
end
@@ -1027,6 +1040,8 @@ module ActionView
def to_number_field_tag(field_type, options = {})
options = options.stringify_keys
+ options['size'] ||= nil
+
if range = options.delete("in") || options.delete("within")
options.update("min" => range.min, "max" => range.max)
end
@@ -1185,6 +1200,7 @@ module ActionView
options["name"] ||= tag_name + (options['multiple'] ? '[]' : '')
options["id"] = options.fetch("id"){ tag_id }
end
+ options["id"] = [options.delete('namespace'), options["id"]].compact.join("_").presence
end
def tag_name
@@ -1215,7 +1231,7 @@ module ActionView
class FormBuilder
# The methods which wrap a form helper call.
class_attribute :field_helpers
- self.field_helpers = FormHelper.instance_method_names - %w(form_for convert_to_model)
+ self.field_helpers = FormHelper.instance_methods - [:form_for, :convert_to_model]
attr_accessor :object_name, :object, :options
@@ -1243,7 +1259,7 @@ module ActionView
@nested_child_index = {}
@object_name, @object, @template, @options, @proc = object_name, object, template, options, proc
@parent_builder = options[:parent_builder]
- @default_options = @options ? @options.slice(:index) : {}
+ @default_options = @options ? @options.slice(:index, :namespace) : {}
if @object_name.to_s.match(/\[\]$/)
if object ||= @template.instance_variable_get("@#{Regexp.last_match.pre_match}") and object.respond_to?(:to_param)
@auto_index = object.to_param
@@ -1270,6 +1286,7 @@ module ActionView
fields_options, record_object = record_object, nil if record_object.is_a?(Hash) && record_object.extractable_options?
fields_options[:builder] ||= options[:builder]
fields_options[:parent_builder] = self
+ fields_options[:namespace] = fields_options[:parent_builder].options[:namespace]
case record_name
when String, Symbol
@@ -1347,6 +1364,39 @@ module ActionView
@template.submit_tag(value, options)
end
+ # Add the submit button for the given form. When no value is given, it checks
+ # if the object is a new resource or not to create the proper label:
+ #
+ # <%= form_for @post do |f| %>
+ # <%= f.button %>
+ # <% end %>
+ #
+ # In the example above, if @post is a new record, it will use "Create Post" as
+ # submit button label, otherwise, it uses "Update Post".
+ #
+ # Those labels can be customized using I18n, under the helpers.submit key and accept
+ # the %{model} as translation interpolation:
+ #
+ # en:
+ # helpers:
+ # button:
+ # create: "Create a %{model}"
+ # update: "Confirm changes to %{model}"
+ #
+ # It also searches for a key specific for the given object:
+ #
+ # en:
+ # helpers:
+ # button:
+ # post:
+ # create: "Add %{model}"
+ #
+ def button(value=nil, options={})
+ value, options = nil, value if value.is_a?(Hash)
+ value ||= submit_default_value
+ @template.button_tag(value, options)
+ end
+
def emitted_hidden_id?
@emitted_hidden_id ||= nil
end
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index c677257d60..3ee0d8ebc5 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -579,7 +579,12 @@ module ActionView
def to_select_tag(choices, options, html_options)
selected_value = options.has_key?(:selected) ? options[:selected] : value(object)
- if !choices.empty? && choices.try(:first).try(:second).respond_to?(:each)
+ # Grouped choices look like this:
+ #
+ # [nil, []]
+ # { nil => [] }
+ #
+ if !choices.empty? && choices.first.respond_to?(:last) && Array === choices.first.last
option_tags = grouped_options_for_select(choices, :selected => selected_value, :disabled => options[:disabled])
else
option_tags = options_for_select(choices, :selected => selected_value, :disabled => options[:disabled])
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index 13b9dc8553..bb753ae27a 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -393,21 +393,17 @@ 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..."
- # # => <input name="commit" data-disable-with="Please wait..."
- # # type="submit" value="Complete sale" />
+ # # => <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" />
+ # # => <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?" />
+ # # => <input name='commit' type='submit' value='Save' data-confirm="Are you sure?" />
#
def submit_tag(value = "Save changes", options = {})
options = options.stringify_keys
@@ -451,12 +447,11 @@ module ActionView
# content_tag(:strong, 'Ask me!')
# end
# # => <button name="button" type="button">
- # <strong>Ask me!</strong>
- # </button>
+ # # <strong>Ask me!</strong>
+ # # </button>
#
# button_tag "Checkout", :disable_with => "Please wait..."
- # # => <button data-disable-with="Please wait..." name="button"
- # type="submit">Checkout</button>
+ # # => <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)
@@ -582,7 +577,7 @@ module ActionView
#
# ==== Examples
# number_field_tag 'quantity', nil, :in => 1...10
- # => <input id="quantity" name="quantity" min="1" max="9" />
+ # => <input id="quantity" name="quantity" min="1" max="9" type="number" />
def number_field_tag(name, value = nil, options = {})
options = options.stringify_keys
options["type"] ||= "number"
diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb
index 1adcd716f8..309923490c 100644
--- a/actionpack/lib/action_view/helpers/javascript_helper.rb
+++ b/actionpack/lib/action_view/helpers/javascript_helper.rb
@@ -14,11 +14,7 @@ module ActionView
"'" => "\\'"
}
- if "ruby".encoding_aware?
- JS_ESCAPE_MAP["\342\200\250".force_encoding('UTF-8').encode!] = '&#x2028;'
- else
- JS_ESCAPE_MAP["\342\200\250"] = '&#x2028;'
- end
+ JS_ESCAPE_MAP["\342\200\250".force_encoding('UTF-8').encode!] = '&#x2028;'
# Escapes carriage returns and single and double quotes for JavaScript segments.
#
@@ -94,7 +90,7 @@ module ActionView
# 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 "#" unles +html_options+ has one.
+ # 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>
diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb
index ec6c2c8db3..1c0fdb8ff9 100644
--- a/actionpack/lib/action_view/helpers/number_helper.rb
+++ b/actionpack/lib/action_view/helpers/number_helper.rb
@@ -1,7 +1,6 @@
# encoding: utf-8
require 'active_support/core_ext/big_decimal/conversions'
-require 'active_support/core_ext/float/rounding'
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/string/output_safety'
@@ -69,7 +68,7 @@ module ActionView
number.gsub!(/(\d{1,3})(\d{3})(\d{4}$)/,"(\\1) \\2#{delimiter}\\3")
else
number.gsub!(/(\d{0,3})(\d{3})(\d{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3")
- number.slice!(0, 1) if number.starts_with?('-')
+ number.slice!(0, 1) if number.starts_with?(delimiter) && !delimiter.blank?
end
str = []
@@ -100,10 +99,10 @@ module ActionView
# number_to_currency(1234567890.50) # => $1,234,567,890.50
# number_to_currency(1234567890.506) # => $1,234,567,890.51
# number_to_currency(1234567890.506, :precision => 3) # => $1,234,567,890.506
- # number_to_currency(1234567890.506, :locale => :fr) # => 1 234 567 890,506 €
+ # number_to_currency(1234567890.506, :locale => :fr) # => 1 234 567 890,51 €
#
# number_to_currency(-1234567890.50, :negative_format => "(%u%n)")
- # # => ($1,234,567,890.51)
+ # # => ($1,234,567,890.50)
# number_to_currency(1234567890.50, :unit => "&pound;", :separator => ",", :delimiter => "")
# # => &pound;1234567890,50
# number_to_currency(1234567890.50, :unit => "&pound;", :separator => ",", :delimiter => "", :format => "%n %u")
@@ -193,7 +192,8 @@ module ActionView
# number_with_delimiter(12345678) # => 12,345,678
# number_with_delimiter(12345678.05) # => 12,345,678.05
# number_with_delimiter(12345678, :delimiter => ".") # => 12.345.678
- # number_with_delimiter(12345678, :separator => ",") # => 12,345,678
+ # number_with_delimiter(12345678, :delimiter => ",") # => 12,345,678
+ # number_with_delimiter(12345678.05, :separator => " ") # => 12,345,678 05
# number_with_delimiter(12345678.05, :locale => :fr) # => 12 345 678,05
# number_with_delimiter(98765432.98, :delimiter => " ", :separator => ",")
# # => 98 765 432,98
diff --git a/actionpack/lib/action_view/helpers/rendering_helper.rb b/actionpack/lib/action_view/helpers/rendering_helper.rb
index 47efdded42..626e1a1ab7 100644
--- a/actionpack/lib/action_view/helpers/rendering_helper.rb
+++ b/actionpack/lib/action_view/helpers/rendering_helper.rb
@@ -8,7 +8,7 @@ module ActionView
module RenderingHelper
# Returns the result of a render that's dictated by the options hash. The primary options are:
#
- # * <tt>:partial</tt> - See ActionView::Partials.
+ # * <tt>:partial</tt> - See <tt>ActionView::PartialRenderer</tt>.
# * <tt>:file</tt> - Renders an explicit template file (this used to be the old default), add :locals to pass in those.
# * <tt>:inline</tt> - Renders an inline template similar to how it's done in the controller.
# * <tt>:text</tt> - Renders the text passed in out.
@@ -87,4 +87,4 @@ module ActionView
end
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_view/helpers/sanitize_helper.rb b/actionpack/lib/action_view/helpers/sanitize_helper.rb
index bcc8f6fbcb..7768c8c151 100644
--- a/actionpack/lib/action_view/helpers/sanitize_helper.rb
+++ b/actionpack/lib/action_view/helpers/sanitize_helper.rb
@@ -1,6 +1,5 @@
require 'active_support/core_ext/object/try'
require 'action_controller/vendor/html-scanner'
-require 'action_view/helpers/tag_helper'
module ActionView
# = Action View Sanitize Helpers
diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb
index 21074efe86..209360ee82 100644
--- a/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/actionpack/lib/action_view/helpers/text_helper.rb
@@ -1,6 +1,5 @@
require 'active_support/core_ext/object/blank'
require 'active_support/core_ext/string/filters'
-require 'action_view/helpers/tag_helper'
module ActionView
# = Action View Text Helpers
@@ -31,6 +30,7 @@ module ActionView
extend ActiveSupport::Concern
include SanitizeHelper
+ include TagHelper
# The preferred method of outputting text in your views is to use the
# <%= "text" %> eRuby syntax. The regular _puts_ and _print_ methods
# do not operate as expected in an eRuby code block. If you absolutely must
@@ -120,7 +120,7 @@ module ActionView
text
else
match = Array(phrases).map { |p| Regexp.escape(p) }.join('|')
- text.gsub(/(#{match})(?!(?:[^<]*?)(?:["'])[^<>]*>)/i, options[:highlighter])
+ text.gsub(/(#{match})(?![^<]*?>)/i, options[:highlighter])
end.html_safe
end
diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb
index be64dc823e..cc74eff53a 100644
--- a/actionpack/lib/action_view/helpers/translation_helper.rb
+++ b/actionpack/lib/action_view/helpers/translation_helper.rb
@@ -45,11 +45,18 @@ 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)
- translation = I18n.translate(scope_key_by_partial(key), options)
- if html_safe_translation_key?(key) && translation.respond_to?(:html_safe)
- translation.html_safe
+ if html_safe_translation_key?(key)
+ html_safe_options = options.dup
+ options.except(*I18n::RESERVED_KEYS).each do |name, value|
+ unless name == :count && value.is_a?(Numeric)
+ html_safe_options[name] = ERB::Util.html_escape(value.to_s)
+ end
+ end
+ translation = I18n.translate(scope_key_by_partial(key), html_safe_options)
+
+ translation.respond_to?(:html_safe) ? translation.html_safe : translation
else
- translation
+ I18n.translate(scope_key_by_partial(key), options)
end
end
alias :t :translate