aboutsummaryrefslogtreecommitdiffstats
path: root/actionview
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2014-01-10 11:00:30 -0800
committerAaron Patterson <aaron.patterson@gmail.com>2014-01-10 11:00:30 -0800
commitcaa981d88112f019ade868f75af6b5f399c244a4 (patch)
treeb760cd5a28612eae612f6055680083cff206b043 /actionview
parent71d19f15171e59b5dfddd66f3fa3a234c3f7911d (diff)
parentbd1bf2c5b8480fae0379890347d58b9fe8231e3e (diff)
downloadrails-caa981d88112f019ade868f75af6b5f399c244a4.tar.gz
rails-caa981d88112f019ade868f75af6b5f399c244a4.tar.bz2
rails-caa981d88112f019ade868f75af6b5f399c244a4.zip
Merge branch 'master' into laurocaetano-fix_send_file
* master: (536 commits) doc, API example on how to use `Model#exists?` with multiple IDs. [ci skip] Restore DATABASE_URL even if it's nil in connection_handler test [ci skip] - error_messages_for has been deprecated since 2.3.8 - lets reduce any confusion for users Ensure Active Record connection consistency Revert "ask the fixture set for the sql statements" Check `respond_to` before delegation due to: https://github.com/ruby/ruby/commit/d781caaf313b8649948c107bba277e5ad7307314 Adding Hash#compact and Hash#compact! methods MySQL version 4.1 was EOL on December 31, 2009 We should at least recommend modern versions of MySQL to users. clear cache on body close so that cache remains during rendering add a more restricted codepath for templates fixes #13390 refactor generator tests to use block form of Tempfile Fix typo [ci skip] Move finish_template as the last public method in the generator Minor typos fix [ci skip] make `change_column_null` reversible. Closes #13576. create/drop test and development databases only if RAILS_ENV is nil Revert "Speedup String#to" typo fix in test name. [ci skip]. `core_ext/string/access.rb` test what we are documenting. Fix typo in image_tag documentation ... Conflicts: actionpack/CHANGELOG.md
Diffstat (limited to 'actionview')
-rw-r--r--actionview/CHANGELOG.md70
-rw-r--r--actionview/MIT-LICENSE2
-rw-r--r--actionview/actionview.gemspec6
-rw-r--r--actionview/lib/action_view.rb4
-rw-r--r--actionview/lib/action_view/base.rb2
-rw-r--r--actionview/lib/action_view/helpers.rb6
-rw-r--r--actionview/lib/action_view/helpers/active_model_helper.rb2
-rw-r--r--actionview/lib/action_view/helpers/asset_tag_helper.rb34
-rw-r--r--actionview/lib/action_view/helpers/date_helper.rb10
-rw-r--r--actionview/lib/action_view/helpers/form_helper.rb15
-rw-r--r--actionview/lib/action_view/helpers/form_options_helper.rb2
-rw-r--r--actionview/lib/action_view/helpers/form_tag_helper.rb4
-rw-r--r--actionview/lib/action_view/helpers/number_helper.rb9
-rw-r--r--actionview/lib/action_view/helpers/tags.rb64
-rw-r--r--actionview/lib/action_view/helpers/tags/collection_helpers.rb2
-rw-r--r--actionview/lib/action_view/helpers/tags/label.rb1
-rw-r--r--actionview/lib/action_view/helpers/text_helper.rb9
-rw-r--r--actionview/lib/action_view/helpers/translation_helper.rb30
-rw-r--r--actionview/lib/action_view/lookup_context.rb8
-rw-r--r--actionview/lib/action_view/railtie.rb9
-rw-r--r--actionview/lib/action_view/renderer/streaming_template_renderer.rb2
-rw-r--r--actionview/lib/action_view/rendering.rb6
-rw-r--r--actionview/lib/action_view/template/error.rb3
-rw-r--r--actionview/lib/action_view/template/handlers/erb.rb4
-rw-r--r--actionview/lib/action_view/template/resolver.rb19
-rw-r--r--actionview/lib/action_view/template/types.rb2
-rw-r--r--actionview/lib/action_view/testing/resolvers.rb2
-rw-r--r--actionview/lib/action_view/vendor/html-scanner/html/node.rb4
-rw-r--r--actionview/lib/action_view/vendor/html-scanner/html/sanitizer.rb2
-rw-r--r--actionview/lib/action_view/vendor/html-scanner/html/selector.rb2
-rw-r--r--actionview/lib/action_view/vendor/html-scanner/html/tokenizer.rb2
-rw-r--r--actionview/lib/action_view/version.rb2
-rw-r--r--actionview/test/abstract_unit.rb5
-rw-r--r--actionview/test/actionpack/abstract/helper_test.rb6
-rw-r--r--actionview/test/actionpack/controller/layout_test.rb6
-rw-r--r--actionview/test/actionpack/controller/render_test.rb10
-rw-r--r--actionview/test/activerecord/form_helper_activerecord_test.rb2
-rw-r--r--actionview/test/fixtures/developer.rb4
-rw-r--r--actionview/test/template/asset_tag_helper_test.rb10
-rw-r--r--actionview/test/template/erb_util_test.rb46
-rw-r--r--actionview/test/template/form_collections_helper_test.rb40
-rw-r--r--actionview/test/template/form_helper_test.rb38
-rw-r--r--actionview/test/template/form_tag_helper_test.rb2
-rw-r--r--actionview/test/template/lookup_context_test.rb11
-rw-r--r--actionview/test/template/number_helper_test.rb3
-rw-r--r--actionview/test/template/render_test.rb4
-rw-r--r--actionview/test/template/testing/fixture_resolver_test.rb4
-rw-r--r--actionview/test/template/text_helper_test.rb12
-rw-r--r--actionview/test/template/translation_helper_test.rb8
49 files changed, 388 insertions, 162 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md
index 787e6d68be..a57da72d8c 100644
--- a/actionview/CHANGELOG.md
+++ b/actionview/CHANGELOG.md
@@ -1,3 +1,73 @@
+* Use `display:none` instead of `display:inline` for hidden fields
+
+ Fixes #6403
+
+ *Gaelian Ditchburn*
+
+* The `video_tag` helper accepts a number as `:size`
+
+ The `:size` option of the `video_tag` helper now can be specified
+ with a stringified number. The `width` and `height` attributes of
+ the generated tag will be the same.
+
+ *Kuldeep Aggarwal*
+
+* A Cycle object should accept an array and cycle through it as it would with a set of
+ comma-separated objects.
+
+ arr = [1,2,3]
+ cycle(arr) # => '1'
+ cycle(arr) # => '2'
+ cycle(arr) # => '3'
+
+ Previously, it would return the array as a string, because it took the array as a
+ single object:
+
+ arr = [1,2,3]
+ cycle(arr) # => '[1,2,3]'
+ cycle(arr) # => '[1,2,3]'
+ cycle(arr) # => '[1,2,3]'
+
+ *Kristian Freeman*
+
+* Label tags generated by collection helpers only inherit the `:index` and
+ `:namespace` from the input, because only these attributes modifies the
+ `for` attribute of the label. Also, the input attributes don't have
+ precedence over the label attributes anymore.
+
+ Before:
+
+ collection = [[1, true, { class: 'foo' }]]
+ f.collection_check_boxes :options, collection, :second, :first do |b|
+ b.label(class: 'my_custom_class')
+ end
+
+ # => <label class="foo" for="user_active_true">1</label>
+
+ After:
+
+ collection = [[1, true, { class: 'foo' }]]
+ f.collection_check_boxes :options, collection, :second, :first do |b|
+ b.label(class: 'my_custom_class')
+ end
+
+ # => <label class="my_custom_class" for="user_active_true">1</label>
+
+ *Andriel Nuernberg*
+
+* Fixed a long-standing bug in `json_escape` that causes quotation marks to be stripped.
+ This method also escapes the \u2028 and \u2029 unicode newline characters which are
+ treated as \n in JavaScript. This matches the behaviour of the AS::JSON encoder. (The
+ original change in the encoder was introduced in #10534.)
+
+ *Godfrey Chan*
+
+* `ActionView::MissingTemplate` includes underscore when raised for a partial.
+
+ Fixes #13002.
+
+ *Yves Senn*
+
* Use `set_backtrace` instead of instance variable `@backtrace` in ActionView exceptions
*Shimpei Makimoto*
diff --git a/actionview/MIT-LICENSE b/actionview/MIT-LICENSE
index 5c668d9624..d58dd9ed9b 100644
--- a/actionview/MIT-LICENSE
+++ b/actionview/MIT-LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2004-2013 David Heinemeier Hansson
+Copyright (c) 2004-2014 David Heinemeier Hansson
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
diff --git a/actionview/actionview.gemspec b/actionview/actionview.gemspec
index cdac074973..e45dd04225 100644
--- a/actionview/actionview.gemspec
+++ b/actionview/actionview.gemspec
@@ -20,10 +20,10 @@ Gem::Specification.new do |s|
s.requirements << 'none'
s.add_dependency 'activesupport', version
- s.add_dependency 'activemodel', version
- s.add_dependency 'builder', '~> 3.1.0'
+ s.add_dependency 'builder', '~> 3.1'
s.add_dependency 'erubis', '~> 2.7.0'
- s.add_development_dependency 'actionpack', version
+ s.add_development_dependency 'actionpack', version
+ s.add_development_dependency 'activemodel', version
end
diff --git a/actionview/lib/action_view.rb b/actionview/lib/action_view.rb
index 39c0c6c856..5c729345dc 100644
--- a/actionview/lib/action_view.rb
+++ b/actionview/lib/action_view.rb
@@ -1,5 +1,5 @@
#--
-# Copyright (c) 2004-2013 David Heinemeier Hansson
+# Copyright (c) 2004-2014 David Heinemeier Hansson
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@@ -23,6 +23,7 @@
require 'active_support'
require 'active_support/rails'
+require 'action_view/version'
module ActionView
extend ActiveSupport::Autoload
@@ -84,6 +85,7 @@ module ActionView
def self.eager_load!
super
+ ActionView::Helpers.eager_load!
ActionView::Template.eager_load!
HTML.eager_load!
end
diff --git a/actionview/lib/action_view/base.rb b/actionview/lib/action_view/base.rb
index caade8f43b..8eb7072d0c 100644
--- a/actionview/lib/action_view/base.rb
+++ b/actionview/lib/action_view/base.rb
@@ -1,5 +1,5 @@
require 'active_support/core_ext/module/attr_internal'
-require 'active_support/core_ext/class/attribute_accessors'
+require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/ordered_options'
require 'action_view/log_subscriber'
require 'action_view/helpers'
diff --git a/actionview/lib/action_view/helpers.rb b/actionview/lib/action_view/helpers.rb
index 8a78685ae1..787e9d67b2 100644
--- a/actionview/lib/action_view/helpers.rb
+++ b/actionview/lib/action_view/helpers.rb
@@ -27,6 +27,12 @@ module ActionView #:nodoc:
autoload :TextHelper
autoload :TranslationHelper
autoload :UrlHelper
+ autoload :Tags
+
+ def self.eager_load!
+ super
+ Tags.eager_load!
+ end
extend ActiveSupport::Concern
diff --git a/actionview/lib/action_view/helpers/active_model_helper.rb b/actionview/lib/action_view/helpers/active_model_helper.rb
index 901f433c70..d5222e3616 100644
--- a/actionview/lib/action_view/helpers/active_model_helper.rb
+++ b/actionview/lib/action_view/helpers/active_model_helper.rb
@@ -1,4 +1,4 @@
-require 'active_support/core_ext/class/attribute_accessors'
+require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/enumerable'
module ActionView
diff --git a/actionview/lib/action_view/helpers/asset_tag_helper.rb b/actionview/lib/action_view/helpers/asset_tag_helper.rb
index b1ba9da4cf..aa49f1edc1 100644
--- a/actionview/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionview/lib/action_view/helpers/asset_tag_helper.rb
@@ -103,7 +103,7 @@ module ActionView
}.join("\n").html_safe
end
- # Returns a link tag that browsers and news readers can use to auto-detect
+ # Returns a link tag that browsers and feed readers can use to auto-detect
# an RSS or Atom feed. The +type+ can either be <tt>:rss</tt> (default) or
# <tt>:atom</tt>. Control the link options in url_for format using the
# +url_options+. You can modify the LINK tag itself in +tag_options+.
@@ -176,7 +176,7 @@ module ActionView
# ==== Options
#
# You can add HTML attributes using the +options+. The +options+ supports
- # three additional keys for convenience and conformance:
+ # two additional keys for convenience and conformance:
#
# * <tt>:alt</tt> - If no alt text is given, the file name part of the
# +source+ is used (capitalized and without the extension)
@@ -207,14 +207,7 @@ module ActionView
options[:alt] = options.fetch(:alt){ image_alt(src) }
end
- if size = options.delete(:size)
- if size =~ %r{\A\d+x\d+\z}
- options[:width], options[:height] = size.split('x')
- elsif size =~ %r{\A\d+\z}
- options[:width] = options[:height] = size
- end
- end
-
+ options[:width], options[:height] = extract_dimensions(options.delete(:size)) if options[:size]
tag("img", options)
end
@@ -251,9 +244,9 @@ module ActionView
#
# * <tt>:poster</tt> - Set an image (like a screenshot) to be shown
# before the video loads. The path is calculated like the +src+ of +image_tag+.
- # * <tt>:size</tt> - Supplied as "{Width}x{Height}", so "30x45" becomes
- # width="30" and height="45". <tt>:size</tt> will be ignored if the
- # value is not in the correct format.
+ # * <tt>:size</tt> - Supplied as "{Width}x{Height}" or "{Number}", so "30x45" becomes
+ # width="30" and height="45", and "50" becomes width="50" and height="50".
+ # <tt>:size</tt> will be ignored if the value is not in the correct format.
#
# ==== Examples
#
@@ -267,6 +260,8 @@ module ActionView
# # => <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", size: "16")
+ # # => <video height="16" src="/trailers/hd.avi" width="16" />
# video_tag("/trailers/hd.avi", height: '32', width: '32')
# # => <video height="32" src="/trailers/hd.avi" width="32" />
# video_tag("trailer.ogg", "trailer.flv")
@@ -278,10 +273,7 @@ module ActionView
def video_tag(*sources)
multiple_sources_tag('video', sources) do |options|
options[:poster] = path_to_image(options[:poster]) if options[:poster]
-
- if size = options.delete(:size)
- options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$}
- end
+ options[:width], options[:height] = extract_dimensions(options.delete(:size)) if options[:size]
end
end
@@ -317,6 +309,14 @@ module ActionView
content_tag(type, nil, options)
end
end
+
+ def extract_dimensions(size)
+ if size =~ %r{\A\d+x\d+\z}
+ size.split('x')
+ elsif size =~ %r{\A\d+\z}
+ [size, size]
+ end
+ end
end
end
end
diff --git a/actionview/lib/action_view/helpers/date_helper.rb b/actionview/lib/action_view/helpers/date_helper.rb
index 523f8aed7a..3d091c4a00 100644
--- a/actionview/lib/action_view/helpers/date_helper.rb
+++ b/actionview/lib/action_view/helpers/date_helper.rb
@@ -170,8 +170,12 @@ module ActionView
# * <tt>:use_month_names</tt> - Set to an array with 12 month names if you want to customize month names.
# Note: You can also use Rails' i18n functionality for this.
# * <tt>:date_separator</tt> - Specifies a string to separate the date fields. Default is "" (i.e. nothing).
- # * <tt>:start_year</tt> - Set the start year for the year select. Default is <tt>Time.now.year - 5</tt>.
- # * <tt>:end_year</tt> - Set the end year for the year select. Default is <tt>Time.now.year + 5</tt>.
+ # * <tt>:start_year</tt> - Set the start year for the year select. Default is <tt>Date.today.year - 5</tt>if
+ # you are creating new record. While editing existing record, <tt>:start_year</tt> defaults to
+ # the current selected year minus 5.
+ # * <tt>:end_year</tt> - Set the end year for the year select. Default is <tt>Date.today.year + 5</tt> if
+ # you are creating new record. While editing existing record, <tt>:end_year</tt> defaults to
+ # the current selected year plus 5.
# * <tt>:discard_day</tt> - Set to true if you don't want to show a day select. This includes the day
# as a hidden field instead of showing a select field. Also note that this implicitly sets the day to be the
# first of the given month in order to not create invalid dates like 31 February.
@@ -1062,7 +1066,7 @@ module ActionView
# Wraps ActionView::Helpers::DateHelper#datetime_select for form builders:
#
# <%= form_for @person do |f| %>
- # <%= f.time_select :last_request_at %>
+ # <%= f.datetime_select :last_request_at %>
# <%= f.submit %>
# <% end %>
#
diff --git a/actionview/lib/action_view/helpers/form_helper.rb b/actionview/lib/action_view/helpers/form_helper.rb
index 38d969ed0c..5235962f9f 100644
--- a/actionview/lib/action_view/helpers/form_helper.rb
+++ b/actionview/lib/action_view/helpers/form_helper.rb
@@ -3,9 +3,8 @@ 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 'action_view/helpers/tags'
require 'action_view/model_naming'
-require 'active_support/core_ext/class/attribute_accessors'
+require 'active_support/core_ext/module/attribute_accessors'
require 'active_support/core_ext/hash/slice'
require 'active_support/core_ext/string/output_safety'
require 'active_support/core_ext/string/inflections'
@@ -52,7 +51,7 @@ module ActionView
# The HTML generated for this would be (modulus formatting):
#
# <form action="/people" class="new_person" id="new_person" method="post">
- # <div style="margin:0;padding:0;display:inline">
+ # <div style="display:none">
# <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
# </div>
# <label for="person_first_name">First name</label>:
@@ -82,7 +81,7 @@ module ActionView
# the code above as is would yield instead:
#
# <form action="/people/256" class="edit_person" id="edit_person_256" method="post">
- # <div style="margin:0;padding:0;display:inline">
+ # <div style="display:none">
# <input name="_method" type="hidden" value="patch" />
# <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" />
# </div>
@@ -316,7 +315,7 @@ module ActionView
# The HTML generated for this would be:
#
# <form action='http://www.example.com' method='post' data-remote='true'>
- # <div style='margin:0;padding:0;display:inline'>
+ # <div style='display:none'>
# <input name='_method' type='hidden' value='patch' />
# </div>
# ...
@@ -334,7 +333,7 @@ module ActionView
# The HTML generated for this would be:
#
# <form action='http://www.example.com' method='post' data-behavior='autosave' name='go'>
- # <div style='margin:0;padding:0;display:inline'>
+ # <div style='display:none'>
# <input name='_method' type='hidden' value='patch' />
# </div>
# ...
@@ -763,8 +762,8 @@ module ActionView
# text_field(:post, :title, class: "create_input")
# # => <input type="text" id="post_title" name="post[title]" value="#{@post.title}" class="create_input" />
#
- # text_field(:session, :user, onchange: "if ($('#session_user').val() === 'admin') { alert('Your login can not be admin!'); }")
- # # => <input type="text" id="session_user" name="session[user]" value="#{@session.user}" onchange="if ($('#session_user').val() === 'admin') { alert('Your login can not be admin!'); }"/>
+ # text_field(:session, :user, onchange: "if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }")
+ # # => <input type="text" id="session_user" name="session[user]" value="#{@session.user}" onchange="if ($('#session_user').val() === 'admin') { alert('Your login cannot be admin!'); }"/>
#
# text_field(:snippet, :code, size: 20, class: 'code_input')
# # => <input type="text" id="snippet_code" name="snippet[code]" size="20" value="#{@snippet.code}" class="code_input" />
diff --git a/actionview/lib/action_view/helpers/form_options_helper.rb b/actionview/lib/action_view/helpers/form_options_helper.rb
index 4347983bad..f625a9ff49 100644
--- a/actionview/lib/action_view/helpers/form_options_helper.rb
+++ b/actionview/lib/action_view/helpers/form_options_helper.rb
@@ -260,7 +260,7 @@ module ActionView
Tags::GroupedCollectionSelect.new(object, method, self, collection, group_method, group_label_method, option_key_method, option_value_method, options, html_options).render
end
- # Return select and option tags for the given object and method, using
+ # Returns select and option tags for the given object and method, using
# #time_zone_options_for_select to generate the list of option tags.
#
# In addition to the <tt>:include_blank</tt> option documented above,
diff --git a/actionview/lib/action_view/helpers/form_tag_helper.rb b/actionview/lib/action_view/helpers/form_tag_helper.rb
index 142c27ace0..80f066b3be 100644
--- a/actionview/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionview/lib/action_view/helpers/form_tag_helper.rb
@@ -465,7 +465,7 @@ module ActionView
# # <strong>Ask me!</strong>
# # </button>
#
- # button_tag "Checkout", data: { disable_with => "Please wait..." }
+ # button_tag "Checkout", data: { :disable_with => "Please wait..." }
# # => <button data-disable-with="Please wait..." name="button" type="submit">Checkout</button>
#
def button_tag(content_or_options = nil, options = nil, &block)
@@ -722,7 +722,7 @@ module ActionView
enforce_utf8 = html_options.delete("enforce_utf8") { true }
tags = (enforce_utf8 ? utf8_enforcer_tag : ''.html_safe) << method_tag
- content_tag(:div, tags, :style => 'margin:0;padding:0;display:inline')
+ content_tag(:div, tags, :style => 'display:none')
end
def form_tag_html(html_options)
diff --git a/actionview/lib/action_view/helpers/number_helper.rb b/actionview/lib/action_view/helpers/number_helper.rb
index 9adc2c1a8f..ad825cd1f1 100644
--- a/actionview/lib/action_view/helpers/number_helper.rb
+++ b/actionview/lib/action_view/helpers/number_helper.rb
@@ -100,10 +100,10 @@ module ActionView
#
# number_to_currency(-1234567890.50, negative_format: "(%u%n)")
# # => ($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")
- # # => 1234567890,50 &pound;
+ # number_to_currency(1234567890.50, unit: "R$", separator: ",", delimiter: "")
+ # # => R$1234567890,50
+ # number_to_currency(1234567890.50, unit: "R$", separator: ",", delimiter: "", format: "%n %u")
+ # # => 1234567890,50 R$
def number_to_currency(number, options = {})
delegate_number_helper_method(:number_to_currency, number, options)
end
@@ -394,6 +394,7 @@ module ActionView
def escape_unsafe_delimiters_and_separators(options)
options[:separator] = ERB::Util.html_escape(options[:separator]) if options[:separator] && !options[:separator].html_safe?
options[:delimiter] = ERB::Util.html_escape(options[:delimiter]) if options[:delimiter] && !options[:delimiter].html_safe?
+ options[:unit] = ERB::Util.html_escape(options[:unit]) if options[:unit] && !options[:unit].html_safe?
options
end
diff --git a/actionview/lib/action_view/helpers/tags.rb b/actionview/lib/action_view/helpers/tags.rb
index a05e16979a..45c75d10c0 100644
--- a/actionview/lib/action_view/helpers/tags.rb
+++ b/actionview/lib/action_view/helpers/tags.rb
@@ -3,37 +3,39 @@ module ActionView
module Tags #:nodoc:
extend ActiveSupport::Autoload
- autoload :Base
- autoload :CheckBox
- autoload :CollectionCheckBoxes
- autoload :CollectionRadioButtons
- autoload :CollectionSelect
- autoload :ColorField
- autoload :DateField
- autoload :DateSelect
- autoload :DatetimeField
- autoload :DatetimeLocalField
- autoload :DatetimeSelect
- autoload :EmailField
- autoload :FileField
- autoload :GroupedCollectionSelect
- autoload :HiddenField
- autoload :Label
- autoload :MonthField
- autoload :NumberField
- autoload :PasswordField
- autoload :RadioButton
- autoload :RangeField
- autoload :SearchField
- autoload :Select
- autoload :TelField
- autoload :TextArea
- autoload :TextField
- autoload :TimeField
- autoload :TimeSelect
- autoload :TimeZoneSelect
- autoload :UrlField
- autoload :WeekField
+ eager_autoload do
+ autoload :Base
+ autoload :CheckBox
+ autoload :CollectionCheckBoxes
+ autoload :CollectionRadioButtons
+ autoload :CollectionSelect
+ autoload :ColorField
+ autoload :DateField
+ autoload :DateSelect
+ autoload :DatetimeField
+ autoload :DatetimeLocalField
+ autoload :DatetimeSelect
+ autoload :EmailField
+ autoload :FileField
+ autoload :GroupedCollectionSelect
+ autoload :HiddenField
+ autoload :Label
+ autoload :MonthField
+ autoload :NumberField
+ autoload :PasswordField
+ autoload :RadioButton
+ autoload :RangeField
+ autoload :SearchField
+ autoload :Select
+ autoload :TelField
+ autoload :TextArea
+ autoload :TextField
+ autoload :TimeField
+ autoload :TimeSelect
+ autoload :TimeZoneSelect
+ autoload :UrlField
+ autoload :WeekField
+ end
end
end
end
diff --git a/actionview/lib/action_view/helpers/tags/collection_helpers.rb b/actionview/lib/action_view/helpers/tags/collection_helpers.rb
index 787039c82e..991f32cea2 100644
--- a/actionview/lib/action_view/helpers/tags/collection_helpers.rb
+++ b/actionview/lib/action_view/helpers/tags/collection_helpers.rb
@@ -18,7 +18,7 @@ module ActionView
end
def label(label_html_options={}, &block)
- html_options = label_html_options.merge(@input_html_options)
+ html_options = @input_html_options.slice(:index, :namespace).merge(label_html_options)
@template_object.label(@object_name, @sanitized_attribute_name, @text, html_options, &block)
end
end
diff --git a/actionview/lib/action_view/helpers/tags/label.rb b/actionview/lib/action_view/helpers/tags/label.rb
index 180aa9ac27..35d3ba8434 100644
--- a/actionview/lib/action_view/helpers/tags/label.rb
+++ b/actionview/lib/action_view/helpers/tags/label.rb
@@ -30,7 +30,6 @@ module ActionView
add_default_name_and_id_for_value(tag_value, name_and_id)
options.delete("index")
options.delete("namespace")
- options.delete("multiple")
options["for"] = name_and_id["id"] unless options.key?("for")
if block_given?
diff --git a/actionview/lib/action_view/helpers/text_helper.rb b/actionview/lib/action_view/helpers/text_helper.rb
index b0e4aa3cd3..7cfbca5b6f 100644
--- a/actionview/lib/action_view/helpers/text_helper.rb
+++ b/actionview/lib/action_view/helpers/text_helper.rb
@@ -31,6 +31,8 @@ module ActionView
include SanitizeHelper
include TagHelper
+ include OutputSafetyHelper
+
# 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
@@ -80,6 +82,9 @@ module ActionView
# # => "And they f... (continued)"
#
# truncate("<p>Once upon a time in a world far far away</p>")
+ # # => "&lt;p&gt;Once upon a time in a wo..."
+ #
+ # truncate("<p>Once upon a time in a world far far away</p>", escape: false)
# # => "<p>Once upon a time in a wo..."
#
# truncate("Once upon a time in a world far far away") { link_to "Continue", "#" }
@@ -268,7 +273,7 @@ module ActionView
content_tag(wrapper_tag, nil, html_options)
else
paragraphs.map! { |paragraph|
- content_tag(wrapper_tag, paragraph, html_options, false)
+ content_tag(wrapper_tag, raw(paragraph), html_options)
}.join("\n\n").html_safe
end
end
@@ -314,7 +319,7 @@ module ActionView
options = values.extract_options!
name = options.fetch(:name, 'default')
- values.unshift(first_value)
+ values.unshift(*first_value)
cycle = get_cycle(name)
unless cycle && cycle.values == values
diff --git a/actionview/lib/action_view/helpers/translation_helper.rb b/actionview/lib/action_view/helpers/translation_helper.rb
index ad8eb47f1f..3ae1df04fe 100644
--- a/actionview/lib/action_view/helpers/translation_helper.rb
+++ b/actionview/lib/action_view/helpers/translation_helper.rb
@@ -1,24 +1,14 @@
require 'action_view/helpers/tag_helper'
require 'i18n/exceptions'
-module I18n
- class ExceptionHandler
- include Module.new {
- def call(exception, locale, key, options)
- exception.is_a?(MissingTranslation) && options[:rescue_format] == :html ? super.html_safe : super
- end
- }
- end
-end
-
module ActionView
# = Action View Translation Helpers
module Helpers
module TranslationHelper
# Delegates to <tt>I18n#translate</tt> but also performs three additional functions.
#
- # First, it'll pass the <tt>rescue_format: :html</tt> option to I18n so that any
- # thrown +MissingTranslation+ messages will be turned into inline spans that
+ # First, it will ensure that any thrown +MissingTranslation+ messages will be turned
+ # into inline spans that:
#
# * have a "translation-missing" class set,
# * contain the missing key as a title attribute and
@@ -44,8 +34,17 @@ module ActionView
# naming convention helps to identify translations that include HTML tags so that
# 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 the user has specified rescue_format then pass it all through, otherwise use
+ # raise and do the work ourselves
+ if options.key?(:raise) || options.key?(:rescue_format)
+ raise_error = options[:raise] || options[:rescue_format]
+ else
+ raise_error = false
+ options[:raise] = true
+ end
+
if html_safe_translation_key?(key)
html_safe_options = options.dup
options.except(*I18n::RESERVED_KEYS).each do |name, value|
@@ -59,6 +58,11 @@ module ActionView
else
I18n.translate(scope_key_by_partial(key), options)
end
+ rescue I18n::MissingTranslationData => e
+ raise e if raise_error
+
+ keys = I18n.normalize_keys(e.locale, e.key, e.options[:scope])
+ content_tag('span', keys.last.to_s.titleize, :class => 'translation_missing', :title => "translation missing: #{keys.join('.')}")
end
alias :t :translate
diff --git a/actionview/lib/action_view/lookup_context.rb b/actionview/lib/action_view/lookup_context.rb
index f9d5b97fe3..e07d9b6314 100644
--- a/actionview/lib/action_view/lookup_context.rb
+++ b/actionview/lib/action_view/lookup_context.rb
@@ -52,6 +52,7 @@ module ActionView
locales
end
register_detail(:formats) { ActionView::Base.default_formats || [:html, :text, :js, :css, :xml, :json] }
+ register_detail(:variants) { [] }
register_detail(:handlers){ Template::Handlers.extensions }
class DetailsKey #:nodoc:
@@ -62,6 +63,13 @@ module ActionView
@details_keys = ThreadSafe::Cache.new
def self.get(details)
+ if details[:formats]
+ details = details.dup
+ syms = Set.new Mime::SET.symbols
+ details[:formats] = details[:formats].select { |v|
+ syms.include? v
+ }
+ end
@details_keys[details] ||= new
end
diff --git a/actionview/lib/action_view/railtie.rb b/actionview/lib/action_view/railtie.rb
index c2783f6377..81f9c40b85 100644
--- a/actionview/lib/action_view/railtie.rb
+++ b/actionview/lib/action_view/railtie.rb
@@ -36,19 +36,12 @@ module ActionView
end
end
- initializer "action_view.setup_action_pack", before: :add_view_paths do |app|
+ initializer "action_view.setup_action_pack" do |app|
ActiveSupport.on_load(:action_controller) do
- ActionController::Base.superclass.send(:include, ActionView::Layouts)
ActionView::RoutingUrlFor.send(:include, ActionDispatch::Routing::UrlFor)
end
end
- initializer "action_view.setup_action_mailer", before: :add_view_paths do |app|
- ActiveSupport.on_load(:action_mailer) do
- ActionMailer::Base.send(:include, ActionView::Layouts)
- end
- end
-
rake_tasks do
load "action_view/tasks/dependencies.rake"
end
diff --git a/actionview/lib/action_view/renderer/streaming_template_renderer.rb b/actionview/lib/action_view/renderer/streaming_template_renderer.rb
index 9cf6eb0c65..3ab2cd36fc 100644
--- a/actionview/lib/action_view/renderer/streaming_template_renderer.rb
+++ b/actionview/lib/action_view/renderer/streaming_template_renderer.rb
@@ -58,7 +58,7 @@ module ActionView
def delayed_render(buffer, template, layout, view, locals)
# Wrap the given buffer in the StreamingBuffer and pass it to the
- # underlying template handler. Now, everytime something is concatenated
+ # underlying template handler. Now, every time something is concatenated
# to the buffer, it is not appended to an array, but streamed straight
# to the client.
output = ActionView::StreamingBuffer.new(buffer)
diff --git a/actionview/lib/action_view/rendering.rb b/actionview/lib/action_view/rendering.rb
index 82db9e26df..99b95fdfb7 100644
--- a/actionview/lib/action_view/rendering.rb
+++ b/actionview/lib/action_view/rendering.rb
@@ -88,10 +88,14 @@ module ActionView
private
- # Find and renders a template based on the options given.
+ # Find and render a template based on the options given.
# :api: private
def _render_template(options) #:nodoc:
+ variant = options[:variant]
+
lookup_context.rendered_format = nil if options[:formats]
+ lookup_context.variants = [variant] if variant
+
view_renderer.render(view_context, options)
end
diff --git a/actionview/lib/action_view/template/error.rb b/actionview/lib/action_view/template/error.rb
index 7b4b5e13e0..743ef6de0a 100644
--- a/actionview/lib/action_view/template/error.rb
+++ b/actionview/lib/action_view/template/error.rb
@@ -41,6 +41,9 @@ module ActionView
'template'
end
+ if partial && path.present?
+ path = path.sub(%r{([^/]+)$}, "_\\1")
+ end
searched_paths = prefixes.map { |prefix| [prefix, path].join("/") }
out = "Missing #{template_type} #{searched_paths.join(", ")} with #{details.inspect}. Searched in:\n"
diff --git a/actionview/lib/action_view/template/handlers/erb.rb b/actionview/lib/action_view/template/handlers/erb.rb
index c8a0059596..4523060442 100644
--- a/actionview/lib/action_view/template/handlers/erb.rb
+++ b/actionview/lib/action_view/template/handlers/erb.rb
@@ -18,7 +18,7 @@ module ActionView
src << "@output_buffer.safe_append='"
src << "\n" * @newline_pending if @newline_pending > 0
src << escape_text(text)
- src << "';"
+ src << "'.freeze;"
@newline_pending = 0
end
@@ -67,7 +67,7 @@ module ActionView
def flush_newline_if_pending(src)
if @newline_pending > 0
- src << "@output_buffer.safe_append='#{"\n" * @newline_pending}';"
+ src << "@output_buffer.safe_append='#{"\n" * @newline_pending}'.freeze;"
@newline_pending = 0
end
end
diff --git a/actionview/lib/action_view/template/resolver.rb b/actionview/lib/action_view/template/resolver.rb
index 3304605c1a..3a3b74cdd5 100644
--- a/actionview/lib/action_view/template/resolver.rb
+++ b/actionview/lib/action_view/template/resolver.rb
@@ -1,6 +1,6 @@
require "pathname"
require "active_support/core_ext/class"
-require "active_support/core_ext/class/attribute_accessors"
+require "active_support/core_ext/module/attribute_accessors"
require "action_view/template"
require "thread"
require "thread_safe"
@@ -162,8 +162,8 @@ module ActionView
# An abstract class that implements a Resolver with path semantics.
class PathResolver < Resolver #:nodoc:
- EXTENSIONS = [:locale, :formats, :handlers]
- DEFAULT_PATTERN = ":prefix/:action{.:locale,}{.:formats,}{.:handlers,}"
+ EXTENSIONS = { :locale => ".", :formats => ".", :variants => "+", :handlers => "." }
+ DEFAULT_PATTERN = ":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}"
def initialize(pattern=nil)
@pattern = pattern || DEFAULT_PATTERN
@@ -240,7 +240,9 @@ module ActionView
end
handler = Template.handler_for_extension(extension)
- format = pieces.last && Template::Types[pieces.last]
+ format = pieces.last && pieces.last.split(EXTENSIONS[:variants], 2).first # remove variant from format
+ format &&= Template::Types[format]
+
[handler, format]
end
end
@@ -303,12 +305,13 @@ module ActionView
# An Optimized resolver for Rails' most common case.
class OptimizedFileSystemResolver < FileSystemResolver #:nodoc:
def build_query(path, details)
- exts = EXTENSIONS.map { |ext| details[ext] }
query = escape_entry(File.join(@path, path))
- query + exts.map { |ext|
- "{#{ext.compact.uniq.map { |e| ".#{e}," }.join}}"
- }.join
+ exts = EXTENSIONS.map do |ext, prefix|
+ "{#{details[ext].compact.uniq.map { |e| "#{prefix}#{e}," }.join}}"
+ end.join
+
+ query + exts
end
end
diff --git a/actionview/lib/action_view/template/types.rb b/actionview/lib/action_view/template/types.rb
index db77cb5d19..b84e0281ae 100644
--- a/actionview/lib/action_view/template/types.rb
+++ b/actionview/lib/action_view/template/types.rb
@@ -1,5 +1,5 @@
require 'set'
-require 'active_support/core_ext/class/attribute_accessors'
+require 'active_support/core_ext/module/attribute_accessors'
module ActionView
class Template
diff --git a/actionview/lib/action_view/testing/resolvers.rb b/actionview/lib/action_view/testing/resolvers.rb
index 7afa2fa613..af53ad3b25 100644
--- a/actionview/lib/action_view/testing/resolvers.rb
+++ b/actionview/lib/action_view/testing/resolvers.rb
@@ -21,7 +21,7 @@ module ActionView #:nodoc:
def query(path, exts, formats)
query = ""
- EXTENSIONS.each do |ext|
+ EXTENSIONS.each_key do |ext|
query << '(' << exts[ext].map {|e| e && Regexp.escape(".#{e}") }.join('|') << '|)'
end
query = /^(#{Regexp.escape(path)})#{query}$/
diff --git a/actionview/lib/action_view/vendor/html-scanner/html/node.rb b/actionview/lib/action_view/vendor/html-scanner/html/node.rb
index 7e7cd4f7b6..27f0f2f6f8 100644
--- a/actionview/lib/action_view/vendor/html-scanner/html/node.rb
+++ b/actionview/lib/action_view/vendor/html-scanner/html/node.rb
@@ -71,12 +71,12 @@ module HTML #:nodoc:
@line, @position = line, pos
end
- # Return a textual representation of the node.
+ # Returns a textual representation of the node.
def to_s
@children.join()
end
- # Return false (subclasses must override this to provide specific matching
+ # Returns false (subclasses must override this to provide specific matching
# behavior.) +conditions+ may be of any type.
def match(conditions)
false
diff --git a/actionview/lib/action_view/vendor/html-scanner/html/sanitizer.rb b/actionview/lib/action_view/vendor/html-scanner/html/sanitizer.rb
index 30b6b8b141..ed34eecf55 100644
--- a/actionview/lib/action_view/vendor/html-scanner/html/sanitizer.rb
+++ b/actionview/lib/action_view/vendor/html-scanner/html/sanitizer.rb
@@ -1,6 +1,6 @@
require 'set'
require 'cgi'
-require 'active_support/core_ext/class/attribute_accessors'
+require 'active_support/core_ext/module/attribute_accessors'
module HTML
class Sanitizer
diff --git a/actionview/lib/action_view/vendor/html-scanner/html/selector.rb b/actionview/lib/action_view/vendor/html-scanner/html/selector.rb
index 7f8609c408..dfdd724b9b 100644
--- a/actionview/lib/action_view/vendor/html-scanner/html/selector.rb
+++ b/actionview/lib/action_view/vendor/html-scanner/html/selector.rb
@@ -488,7 +488,7 @@ module HTML
end
- # Return the next element after this one. Skips sibling text nodes.
+ # Returns the next element after this one. Skips sibling text nodes.
#
# With the +name+ argument, returns the next element with that name,
# skipping other sibling elements.
diff --git a/actionview/lib/action_view/vendor/html-scanner/html/tokenizer.rb b/actionview/lib/action_view/vendor/html-scanner/html/tokenizer.rb
index 8ac8d34430..adf4e45930 100644
--- a/actionview/lib/action_view/vendor/html-scanner/html/tokenizer.rb
+++ b/actionview/lib/action_view/vendor/html-scanner/html/tokenizer.rb
@@ -30,7 +30,7 @@ module HTML #:nodoc:
@current_line = 1
end
- # Return the next token in the sequence, or +nil+ if there are no more tokens in
+ # Returns the next token in the sequence, or +nil+ if there are no more tokens in
# the stream.
def next
return nil if @scanner.eos?
diff --git a/actionview/lib/action_view/version.rb b/actionview/lib/action_view/version.rb
index 094dd474df..edb6d8f116 100644
--- a/actionview/lib/action_view/version.rb
+++ b/actionview/lib/action_view/version.rb
@@ -1,7 +1,7 @@
module ActionView
# Returns the version of the currently loaded ActionView as a Gem::Version
def self.version
- Gem::Version.new "4.1.0.beta"
+ Gem::Version.new "4.1.0.beta1"
end
module VERSION #:nodoc:
diff --git a/actionview/test/abstract_unit.rb b/actionview/test/abstract_unit.rb
index 6623b47e83..9928da4774 100644
--- a/actionview/test/abstract_unit.rb
+++ b/actionview/test/abstract_unit.rb
@@ -42,6 +42,9 @@ Thread.abort_on_exception = true
# Show backtraces for deprecated behavior for quicker cleanup.
ActiveSupport::Deprecation.debug = true
+# Disable available locale checks to avoid warnings running the test suite.
+I18n.enforce_available_locales = false
+
# Register danish language for testing
I18n.backend.store_translations 'da', {}
I18n.backend.store_translations 'pt-BR', {}
@@ -267,8 +270,6 @@ class Rack::TestCase < ActionDispatch::IntegrationTest
end
end
-# Emulate AV railtie.
-ActionController::Base.superclass.send(:include, ActionView::Layouts)
ActionView::RoutingUrlFor.send(:include, ActionDispatch::Routing::UrlFor)
module ActionController
diff --git a/actionview/test/actionpack/abstract/helper_test.rb b/actionview/test/actionpack/abstract/helper_test.rb
index 89c4567715..7d346e917d 100644
--- a/actionview/test/actionpack/abstract/helper_test.rb
+++ b/actionview/test/actionpack/abstract/helper_test.rb
@@ -78,9 +78,9 @@ module AbstractController
end
def test_declare_missing_helper
- AbstractHelpers.helper :missing
- flunk "should have raised an exception"
- rescue LoadError => e
+ e = assert_raise AbstractController::Helpers::MissingHelperError do
+ AbstractHelpers.helper :missing
+ end
assert_equal "helpers/missing_helper.rb", e.path
end
diff --git a/actionview/test/actionpack/controller/layout_test.rb b/actionview/test/actionpack/controller/layout_test.rb
index 5dd23c4b31..b44f57a23e 100644
--- a/actionview/test/actionpack/controller/layout_test.rb
+++ b/actionview/test/actionpack/controller/layout_test.rb
@@ -215,12 +215,6 @@ class LayoutSetInResponseTest < ActionController::TestCase
end
end
-class RenderWithTemplateOptionController < LayoutTest
- def hello
- render :template => 'alt/hello'
- end
-end
-
class SetsNonExistentLayoutFile < LayoutTest
layout "nofile"
end
diff --git a/actionview/test/actionpack/controller/render_test.rb b/actionview/test/actionpack/controller/render_test.rb
index 8c99504050..45b8049b83 100644
--- a/actionview/test/actionpack/controller/render_test.rb
+++ b/actionview/test/actionpack/controller/render_test.rb
@@ -44,8 +44,6 @@ module Quiz
end
end
- class Store < Question; end
-
# Controller
class QuestionsController < ApplicationController
def new
@@ -693,9 +691,9 @@ class RenderTest < ActionController::TestCase
end
def test_line_offset
- get :render_line_offset
- flunk "the action should have raised an exception"
- rescue StandardError => exc
+ exc = assert_raises ActionView::Template::Error do
+ get :render_line_offset
+ end
line = exc.backtrace.first
assert(line =~ %r{:(\d+):})
assert_equal "1", $1,
@@ -971,7 +969,7 @@ class RenderTest < ActionController::TestCase
end
def test_should_implicitly_render_js_template_without_layout
- get :render_implicit_js_template_without_layout, :format => :js
+ xhr :get, :render_implicit_js_template_without_layout, :format => :js
assert_no_match %r{<html>}, @response.body
end
diff --git a/actionview/test/activerecord/form_helper_activerecord_test.rb b/actionview/test/activerecord/form_helper_activerecord_test.rb
index 2e302c65a7..0a9628da8d 100644
--- a/actionview/test/activerecord/form_helper_activerecord_test.rb
+++ b/actionview/test/activerecord/form_helper_activerecord_test.rb
@@ -59,7 +59,7 @@ class FormHelperActiveRecordTest < ActionView::TestCase
protected
def hidden_fields(method = nil)
- txt = %{<div style="margin:0;padding:0;display:inline">}
+ txt = %{<div style="display:none">}
txt << %{<input name="utf8" type="hidden" value="&#x2713;" />}
if method && !%w(get post).include?(method.to_s)
txt << %{<input name="_method" type="hidden" value="#{method}" />}
diff --git a/actionview/test/fixtures/developer.rb b/actionview/test/fixtures/developer.rb
index 4941463015..8b3f0a8039 100644
--- a/actionview/test/fixtures/developer.rb
+++ b/actionview/test/fixtures/developer.rb
@@ -4,7 +4,3 @@ class Developer < ActiveRecord::Base
has_many :topics, :through => :replies
accepts_nested_attributes_for :projects
end
-
-class DeVeLoPeR < ActiveRecord::Base
- self.table_name = "developers"
-end
diff --git a/actionview/test/template/asset_tag_helper_test.rb b/actionview/test/template/asset_tag_helper_test.rb
index 214a13654e..3ca71d3376 100644
--- a/actionview/test/template/asset_tag_helper_test.rb
+++ b/actionview/test/template/asset_tag_helper_test.rb
@@ -2,14 +2,6 @@ require 'zlib'
require 'abstract_unit'
require 'active_support/ordered_options'
-class FakeController
- attr_accessor :request
-
- def config
- @config ||= ActiveSupport::InheritableOptions.new(ActionController::Base.config)
- end
-end
-
class AssetTagHelperTest < ActionView::TestCase
tests ActionView::Helpers::AssetTagHelper
@@ -245,7 +237,7 @@ class AssetTagHelperTest < ActionView::TestCase
%(video_tag("gold.m4v", :size => "160x120")) => %(<video height="120" src="/videos/gold.m4v" width="160"></video>),
%(video_tag("gold.m4v", "size" => "320x240")) => %(<video height="240" src="/videos/gold.m4v" width="320"></video>),
%(video_tag("trailer.ogg", :poster => "screenshot.png")) => %(<video poster="/images/screenshot.png" src="/videos/trailer.ogg"></video>),
- %(video_tag("error.avi", "size" => "100")) => %(<video src="/videos/error.avi"></video>),
+ %(video_tag("error.avi", "size" => "100")) => %(<video height="100" src="/videos/error.avi" width="100"></video>),
%(video_tag("error.avi", "size" => "100 x 100")) => %(<video src="/videos/error.avi"></video>),
%(video_tag("error.avi", "size" => "x")) => %(<video src="/videos/error.avi"></video>),
%(video_tag("http://media.rubyonrails.org/video/rails_blog_2.mov")) => %(<video src="http://media.rubyonrails.org/video/rails_blog_2.mov"></video>),
diff --git a/actionview/test/template/erb_util_test.rb b/actionview/test/template/erb_util_test.rb
index 9a7c617eb3..9bacbba908 100644
--- a/actionview/test/template/erb_util_test.rb
+++ b/actionview/test/template/erb_util_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'active_support/json'
class ErbUtilTest < ActiveSupport::TestCase
include ERB::Util
@@ -15,6 +16,51 @@ class ErbUtilTest < ActiveSupport::TestCase
end
end
+ HTML_ESCAPE_TEST_CASES = [
+ ['<br>', '&lt;br&gt;'],
+ ['a & b', 'a &amp; b'],
+ ['"quoted" string', '&quot;quoted&quot; string'],
+ ["'quoted' string", '&#39;quoted&#39; string'],
+ [
+ '<script type="application/javascript">alert("You are \'pwned\'!")</script>',
+ '&lt;script type=&quot;application/javascript&quot;&gt;alert(&quot;You are &#39;pwned&#39;!&quot;)&lt;/script&gt;'
+ ]
+ ]
+
+ JSON_ESCAPE_TEST_CASES = [
+ ['1', '1'],
+ ['null', 'null'],
+ ['"&"', '"\u0026"'],
+ ['"</script>"', '"\u003c/script\u003e"'],
+ ['["</script>"]', '["\u003c/script\u003e"]'],
+ ['{"name":"</script>"}', '{"name":"\u003c/script\u003e"}'],
+ [%({"name":"d\u2028h\u2029h"}), '{"name":"d\u2028h\u2029h"}']
+ ]
+
+ def test_html_escape
+ HTML_ESCAPE_TEST_CASES.each do |(raw, expected)|
+ assert_equal expected, html_escape(raw)
+ end
+ end
+
+ def test_json_escape
+ JSON_ESCAPE_TEST_CASES.each do |(raw, expected)|
+ assert_equal expected, json_escape(raw)
+ end
+ end
+
+ def test_json_escape_does_not_alter_json_string_meaning
+ JSON_ESCAPE_TEST_CASES.each do |(raw, _)|
+ assert_equal ActiveSupport::JSON.decode(raw), ActiveSupport::JSON.decode(json_escape(raw))
+ end
+ end
+
+ def test_json_escape_is_idempotent
+ JSON_ESCAPE_TEST_CASES.each do |(raw, _)|
+ assert_equal json_escape(raw), json_escape(json_escape(raw))
+ end
+ end
+
def test_json_escape_returns_unsafe_strings_when_passed_unsafe_strings
value = json_escape("asdf")
assert !value.html_safe?
diff --git a/actionview/test/template/form_collections_helper_test.rb b/actionview/test/template/form_collections_helper_test.rb
index d28e4aeb48..7a62b9d907 100644
--- a/actionview/test/template/form_collections_helper_test.rb
+++ b/actionview/test/template/form_collections_helper_test.rb
@@ -60,7 +60,7 @@ class FormCollectionsHelperTest < ActionView::TestCase
assert_no_select 'input[type=radio][value=other][disabled=disabled]'
end
- test 'collection radio accepts single disable item' do
+ test 'collection radio accepts single disabled item' do
collection = [[1, true], [0, false]]
with_collection_radio_buttons :user, :active, collection, :last, :first, :disabled => true
@@ -84,6 +84,24 @@ class FormCollectionsHelperTest < ActionView::TestCase
assert_select 'input[type=radio][value=false].bar#user_active_false'
end
+ test 'collection radio sets the label class defined inside the block' do
+ collection = [[1, true, {class: 'foo'}], [0, false, {class: 'bar'}]]
+ with_collection_radio_buttons :user, :active, collection, :second, :first do |b|
+ b.label(class: "collection_radio_buttons")
+ end
+
+ assert_select 'label.collection_radio_buttons[for=user_active_true]'
+ assert_select 'label.collection_radio_buttons[for=user_active_false]'
+ end
+
+ test 'collection radio does not include the input class in the respective label' do
+ collection = [[1, true, {class: 'foo'}], [0, false, {class: 'bar'}]]
+ with_collection_radio_buttons :user, :active, collection, :second, :first
+
+ assert_no_select 'label.foo[for=user_active_true]'
+ assert_no_select 'label.bar[for=user_active_false]'
+ end
+
test 'collection radio does not wrap input inside the label' do
with_collection_radio_buttons :user, :active, [true, false], :to_s, :to_s
@@ -215,6 +233,24 @@ class FormCollectionsHelperTest < ActionView::TestCase
assert_select 'input[type=checkbox][value=2].bar'
end
+ test 'collection check boxes sets the label class defined inside the block' do
+ collection = [[1, 'Category 1', {class: 'foo'}], [2, 'Category 2', {class: 'bar'}]]
+ with_collection_check_boxes :user, :active, collection, :second, :first do |b|
+ b.label(class: 'collection_check_boxes')
+ end
+
+ assert_select 'label.collection_check_boxes[for=user_active_category_1]'
+ assert_select 'label.collection_check_boxes[for=user_active_category_2]'
+ end
+
+ test 'collection check boxes does not include the input class in the respective label' do
+ collection = [[1, 'Category 1', {class: 'foo'}], [2, 'Category 2', {class: 'bar'}]]
+ with_collection_check_boxes :user, :active, collection, :second, :first
+
+ assert_no_select 'label.foo[for=user_active_category_1]'
+ assert_no_select 'label.bar[for=user_active_category_2]'
+ end
+
test 'collection check boxes accepts selected values as :checked option' do
collection = (1..3).map{|i| [i, "Category #{i}"] }
with_collection_check_boxes :user, :category_ids, collection, :first, :last, :checked => [1, 3]
@@ -264,7 +300,7 @@ class FormCollectionsHelperTest < ActionView::TestCase
assert_no_select 'input[type=checkbox][value=2][disabled=disabled]'
end
- test 'collection check boxes accepts single disable item' do
+ test 'collection check boxes accepts single disabled item' do
collection = (1..3).map{|i| [i, "Category #{i}"] }
with_collection_check_boxes :user, :category_ids, collection, :first, :last, :disabled => 1
diff --git a/actionview/test/template/form_helper_test.rb b/actionview/test/template/form_helper_test.rb
index 3e8a2468ed..fe82349265 100644
--- a/actionview/test/template/form_helper_test.rb
+++ b/actionview/test/template/form_helper_test.rb
@@ -1300,6 +1300,24 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
+ def test_form_with_index_and_with_collection_radio_buttons
+ post = Post.new
+ def post.active; false; end
+
+ form_for(post, index: '1') do |f|
+ concat f.collection_radio_buttons(:active, [true, false], :to_s, :to_s)
+ end
+
+ expected = whole_form("/posts", "new_post", "new_post") do
+ "<input id='post_1_active_true' name='post[1][active]' type='radio' value='true' />" +
+ "<label for='post_1_active_true'>true</label>" +
+ "<input checked='checked' id='post_1_active_false' name='post[1][active]' type='radio' value='false' />" +
+ "<label for='post_1_active_false'>false</label>"
+ end
+
+ assert_dom_equal expected, output_buffer
+ end
+
def test_form_for_with_collection_check_boxes
post = Post.new
def post.tag_ids; [1, 3]; end
@@ -1397,6 +1415,24 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
+ def test_form_with_index_and_with_collection_check_boxes
+ post = Post.new
+ def post.tag_ids; [1]; end
+ collection = [[1, "Tag 1"]]
+
+ form_for(post, index: '1') do |f|
+ concat f.collection_check_boxes(:tag_ids, collection, :first, :last)
+ end
+
+ expected = whole_form("/posts", "new_post", "new_post") do
+ "<input checked='checked' id='post_1_tag_ids_1' name='post[1][tag_ids][]' type='checkbox' value='1' />" +
+ "<label for='post_1_tag_ids_1'>Tag 1</label>" +
+ "<input name='post[tag_ids][]' type='hidden' value='' />"
+ end
+
+ assert_dom_equal expected, output_buffer
+ end
+
def test_form_for_with_file_field_generate_multipart
Post.send :attr_accessor, :file
@@ -2987,7 +3023,7 @@ class FormHelperTest < ActionView::TestCase
protected
def hidden_fields(method = nil)
- txt = %{<div style="margin:0;padding:0;display:inline">}
+ txt = %{<div style="display:none">}
txt << %{<input name="utf8" type="hidden" value="&#x2713;" />}
if method && !%w(get post).include?(method.to_s)
txt << %{<input name="_method" type="hidden" value="#{method}" />}
diff --git a/actionview/test/template/form_tag_helper_test.rb b/actionview/test/template/form_tag_helper_test.rb
index 22bf438a56..0d5831dc6f 100644
--- a/actionview/test/template/form_tag_helper_test.rb
+++ b/actionview/test/template/form_tag_helper_test.rb
@@ -14,7 +14,7 @@ class FormTagHelperTest < ActionView::TestCase
method = options[:method]
enforce_utf8 = options.fetch(:enforce_utf8, true)
- txt = %{<div style="margin:0;padding:0;display:inline">}
+ txt = %{<div style="display:none">}
txt << %{<input name="utf8" type="hidden" value="&#x2713;" />} if enforce_utf8
if method && !%w(get post).include?(method.to_s)
txt << %{<input name="_method" type="hidden" value="#{method}" />}
diff --git a/actionview/test/template/lookup_context_test.rb b/actionview/test/template/lookup_context_test.rb
index 203ad6d910..ce9485e146 100644
--- a/actionview/test/template/lookup_context_test.rb
+++ b/actionview/test/template/lookup_context_test.rb
@@ -36,6 +36,11 @@ class LookupContextTest < ActiveSupport::TestCase
assert @lookup_context.formats.frozen?
end
+ test "provides getters and setters for variants" do
+ @lookup_context.variants = [:mobile]
+ assert_equal [:mobile], @lookup_context.variants
+ end
+
test "provides getters and setters for formats" do
@lookup_context.formats = [:html]
assert_equal [:html], @lookup_context.formats
@@ -249,15 +254,15 @@ class TestMissingTemplate < ActiveSupport::TestCase
e = assert_raise ActionView::MissingTemplate do
@lookup_context.find("foo", %w(parent child), true)
end
- assert_match %r{Missing partial parent/foo, child/foo with .* Searched in:\n \* "/Path/to/views"\n}, e.message
+ assert_match %r{Missing partial parent/_foo, child/_foo with .* Searched in:\n \* "/Path/to/views"\n}, e.message
end
test "if a single prefix is passed as a string and the lookup fails, MissingTemplate accepts it" do
e = assert_raise ActionView::MissingTemplate do
- details = {:handlers=>[], :formats=>[], :locale=>[]}
+ details = {:handlers=>[], :formats=>[], :variants=>[], :locale=>[]}
@lookup_context.view_paths.find("foo", "parent", true, details)
end
- assert_match %r{Missing partial parent/foo with .* Searched in:\n \* "/Path/to/views"\n}, e.message
+ assert_match %r{Missing partial parent/_foo with .* Searched in:\n \* "/Path/to/views"\n}, e.message
end
end
diff --git a/actionview/test/template/number_helper_test.rb b/actionview/test/template/number_helper_test.rb
index 6e640889d2..be336ea3fb 100644
--- a/actionview/test/template/number_helper_test.rb
+++ b/actionview/test/template/number_helper_test.rb
@@ -14,7 +14,8 @@ class NumberHelperTest < ActionView::TestCase
assert_equal nil, number_to_currency(nil)
assert_equal "$1,234,567,890.50", number_to_currency(1234567890.50)
assert_equal "$1,234,567,892", number_to_currency(1234567891.50, precision: 0)
- assert_equal "1,234,567,890.50 - K&#269;", number_to_currency("-1234567890.50", unit: "K&#269;", format: "%n %u", negative_format: "%n - %u")
+ assert_equal "1,234,567,890.50 - K&#269;", number_to_currency("-1234567890.50", unit: raw("K&#269;"), format: "%n %u", negative_format: "%n - %u")
+ assert_equal "&amp;pound;1,234,567,890.50", number_to_currency("1234567890.50", unit: "&pound;")
end
def test_number_to_percentage
diff --git a/actionview/test/template/render_test.rb b/actionview/test/template/render_test.rb
index 5a7d11f513..055a273cc3 100644
--- a/actionview/test/template/render_test.rb
+++ b/actionview/test/template/render_test.rb
@@ -63,7 +63,7 @@ module RenderTestCases
def test_render_template_with_a_missing_partial_of_another_format
@view.lookup_context.formats = [:html]
- assert_raise ActionView::Template::Error, "Missing partial /missing with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder]}" do
+ assert_raise ActionView::Template::Error, "Missing partial /_missing with {:locale=>[:en], :formats=>[:json], :handlers=>[:erb, :builder]}" do
@view.render(:template => "with_format", :formats => [:json])
end
end
@@ -444,7 +444,7 @@ module RenderTestCases
def test_render_partial_with_layout_raises_descriptive_error
e = assert_raises(ActionView::MissingTemplate) { @view.render(partial: 'test/partial', layout: true) }
- assert_match "Missing partial /true with", e.message
+ assert_match "Missing partial /_true with", e.message
end
def test_render_with_nested_layout
diff --git a/actionview/test/template/testing/fixture_resolver_test.rb b/actionview/test/template/testing/fixture_resolver_test.rb
index 9649f349cb..d6cfa997cd 100644
--- a/actionview/test/template/testing/fixture_resolver_test.rb
+++ b/actionview/test/template/testing/fixture_resolver_test.rb
@@ -3,13 +3,13 @@ require 'abstract_unit'
class FixtureResolverTest < ActiveSupport::TestCase
def test_should_return_empty_list_for_unknown_path
resolver = ActionView::FixtureResolver.new()
- templates = resolver.find_all("path", "arbitrary", false, {:locale => [], :formats => [:html], :handlers => []})
+ templates = resolver.find_all("path", "arbitrary", false, {:locale => [], :formats => [:html], :variants => [], :handlers => []})
assert_equal [], templates, "expected an empty list of templates"
end
def test_should_return_template_for_declared_path
resolver = ActionView::FixtureResolver.new("arbitrary/path.erb" => "this text")
- templates = resolver.find_all("path", "arbitrary", false, {:locale => [], :formats => [:html], :handlers => [:erb]})
+ templates = resolver.find_all("path", "arbitrary", false, {:locale => [], :formats => [:html], :variants => [], :handlers => [:erb]})
assert_equal 1, templates.size, "expected one template"
assert_equal "this text", templates.first.source
assert_equal "arbitrary/path", templates.first.virtual_path
diff --git a/actionview/test/template/text_helper_test.rb b/actionview/test/template/text_helper_test.rb
index dd1a92acfb..a514bba83d 100644
--- a/actionview/test/template/text_helper_test.rb
+++ b/actionview/test/template/text_helper_test.rb
@@ -21,6 +21,11 @@ class TextHelperTest < ActionView::TestCase
assert simple_format("<b> test with html tags </b>").html_safe?
end
+ def test_simple_format_included_in_isolation
+ helper_klass = Class.new { include ActionView::Helpers::TextHelper }
+ assert helper_klass.new.simple_format("<b> test with html tags </b>").html_safe?
+ end
+
def test_simple_format
assert_equal "<p></p>", simple_format(nil)
@@ -381,6 +386,13 @@ class TextHelperTest < ActionView::TestCase
assert_equal("3", cycle("one", 2, "3"))
end
+ def test_cycle_with_array
+ array = [1, 2, 3]
+ assert_equal("1", cycle(array))
+ assert_equal("2", cycle(array))
+ assert_equal("3", cycle(array))
+ end
+
def test_cycle_with_no_arguments
assert_raise(ArgumentError) { cycle }
end
diff --git a/actionview/test/template/translation_helper_test.rb b/actionview/test/template/translation_helper_test.rb
index d496dbb35e..269714fad0 100644
--- a/actionview/test/template/translation_helper_test.rb
+++ b/actionview/test/template/translation_helper_test.rb
@@ -31,7 +31,7 @@ class TranslationHelperTest < ActiveSupport::TestCase
end
def test_delegates_to_i18n_setting_the_rescue_format_option_to_html
- I18n.expects(:translate).with(:foo, :locale => 'en', :rescue_format => :html).returns("")
+ I18n.expects(:translate).with(:foo, :locale => 'en', :raise=>true).returns("")
translate :foo, :locale => 'en'
end
@@ -53,6 +53,12 @@ class TranslationHelperTest < ActiveSupport::TestCase
assert_equal false, translate(:"translations.missing", :rescue_format => nil).html_safe?
end
+ def test_raises_missing_translation_message_with_raise_option
+ assert_raise(I18n::MissingTranslationData) do
+ translate(:"translations.missing", :raise => true)
+ end
+ end
+
def test_i18n_translate_defaults_to_nil_rescue_format
expected = 'translation missing: en.translations.missing'
assert_equal expected, I18n.translate(:"translations.missing")