aboutsummaryrefslogtreecommitdiffstats
path: root/actionview/lib/action_view
diff options
context:
space:
mode:
Diffstat (limited to 'actionview/lib/action_view')
-rw-r--r--actionview/lib/action_view/base.rb4
-rw-r--r--actionview/lib/action_view/helpers/asset_tag_helper.rb2
-rw-r--r--actionview/lib/action_view/helpers/asset_url_helper.rb29
-rw-r--r--actionview/lib/action_view/helpers/date_helper.rb13
-rw-r--r--actionview/lib/action_view/helpers/form_options_helper.rb8
-rw-r--r--actionview/lib/action_view/helpers/form_tag_helper.rb40
-rw-r--r--actionview/lib/action_view/helpers/javascript_helper.rb6
-rw-r--r--actionview/lib/action_view/helpers/sanitize_helper.rb2
-rw-r--r--actionview/lib/action_view/helpers/tag_helper.rb27
-rw-r--r--actionview/lib/action_view/helpers/text_helper.rb13
-rw-r--r--actionview/lib/action_view/helpers/url_helper.rb6
-rw-r--r--actionview/lib/action_view/layouts.rb15
-rw-r--r--actionview/lib/action_view/lookup_context.rb16
-rw-r--r--actionview/lib/action_view/renderer/partial_renderer.rb2
-rw-r--r--actionview/lib/action_view/renderer/streaming_template_renderer.rb2
-rw-r--r--actionview/lib/action_view/renderer/template_renderer.rb19
-rw-r--r--actionview/lib/action_view/template.rb9
-rw-r--r--actionview/lib/action_view/test_case.rb12
18 files changed, 129 insertions, 96 deletions
diff --git a/actionview/lib/action_view/base.rb b/actionview/lib/action_view/base.rb
index 43124bb904..72ca6f7ec6 100644
--- a/actionview/lib/action_view/base.rb
+++ b/actionview/lib/action_view/base.rb
@@ -161,6 +161,10 @@ module ActionView #:nodoc:
cattr_accessor :raise_on_missing_translations
@@raise_on_missing_translations = false
+ # Specify whether submit_tag should automatically disable on click
+ cattr_accessor :automatically_disable_submit_tag
+ @@automatically_disable_submit_tag = true
+
class_attribute :_routes
class_attribute :logger
diff --git a/actionview/lib/action_view/helpers/asset_tag_helper.rb b/actionview/lib/action_view/helpers/asset_tag_helper.rb
index 3041ad3ef7..e506c782d6 100644
--- a/actionview/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionview/lib/action_view/helpers/asset_tag_helper.rb
@@ -60,7 +60,7 @@ module ActionView
tag_options = {
"src" => path_to_javascript(source, path_options)
}.merge!(options)
- content_tag(:script, "", tag_options)
+ content_tag("script".freeze, "", tag_options)
}.join("\n").html_safe
end
diff --git a/actionview/lib/action_view/helpers/asset_url_helper.rb b/actionview/lib/action_view/helpers/asset_url_helper.rb
index 3beb7fefb1..717b326740 100644
--- a/actionview/lib/action_view/helpers/asset_url_helper.rb
+++ b/actionview/lib/action_view/helpers/asset_url_helper.rb
@@ -31,26 +31,33 @@ module ActionView
# stylesheet_link_tag("application")
# # => <link href="http://assets.example.com/assets/application.css" media="screen" rel="stylesheet" />
#
- # Browsers typically open at most two simultaneous connections to a single
- # host, which means your assets often have to wait for other assets to finish
- # downloading. You can alleviate this by using a <tt>%d</tt> wildcard in the
- # +asset_host+. For example, "assets%d.example.com". If that wildcard is
- # present Rails distributes asset requests among the corresponding four hosts
- # "assets0.example.com", ..., "assets3.example.com". With this trick browsers
- # will open eight simultaneous connections rather than two.
+ # Browsers open a limited number of simultaneous connections to a single
+ # host. The exact number varies by browser and version. This limit may cause
+ # some asset downloads to wait for previous assets to finish before they can
+ # begin. You can use the <tt>%d</tt> wildcard in the +asset_host+ to
+ # distribute the requests over four hosts. For example,
+ # <tt>assets%d.example.com<tt> will spread the asset requests over
+ # "assets0.example.com", ..., "assets3.example.com".
#
# image_tag("rails.png")
# # => <img alt="Rails" src="http://assets0.example.com/assets/rails.png" />
# stylesheet_link_tag("application")
# # => <link href="http://assets2.example.com/assets/application.css" media="screen" rel="stylesheet" />
#
- # To do this, you can either setup four actual hosts, or you can use wildcard
- # DNS to CNAME the wildcard to a single asset host. You can read more about
- # setting up your DNS CNAME records from your ISP.
+ # This may improve the asset loading performance of your application.
+ # It is also possible the combination of additional connection overhead
+ # (DNS, SSL) and the overall browser connection limits may result in this
+ # solution being slower. You should be sure to measure your actual
+ # performance across targeted browsers both before and after this change.
+ #
+ # To implement the corresponding hosts you can either setup four actual
+ # hosts or use wildcard DNS to CNAME the wildcard to a single asset host.
+ # You can read more about setting up your DNS CNAME records from your ISP.
#
# Note: This is purely a browser performance optimization and is not meant
# for server load balancing. See http://www.die.net/musings/page_load_time/
- # for background.
+ # for background and http://www.browserscope.org/?category=network for
+ # connection limit data.
#
# Alternatively, you can exert more control over the asset host by setting
# +asset_host+ to a proc like this:
diff --git a/actionview/lib/action_view/helpers/date_helper.rb b/actionview/lib/action_view/helpers/date_helper.rb
index fbd7261477..312e41ee48 100644
--- a/actionview/lib/action_view/helpers/date_helper.rb
+++ b/actionview/lib/action_view/helpers/date_helper.rb
@@ -228,6 +228,7 @@ module ActionView
# or the given prompt string.
# * <tt>:with_css_classes</tt> - Set to true if you want assign different styles for 'select' tags. This option
# automatically set classes 'year', 'month', 'day', 'hour', 'minute' and 'second' for your 'select' tags.
+ # * <tt>:use_hidden</tt> - Set to true if you only want to generate hidden input tags.
#
# If anything is passed in the +html_options+ hash it will be applied to every select tag in the set.
#
@@ -681,7 +682,7 @@ module ActionView
content = args.first || I18n.l(date_or_time, :format => format)
datetime = date_or_time.acts_like?(:time) ? date_or_time.xmlschema : date_or_time.iso8601
- content_tag(:time, content, options.reverse_merge(:datetime => datetime), &block)
+ content_tag("time".freeze, content, options.reverse_merge(:datetime => datetime), &block)
end
end
@@ -809,7 +810,7 @@ module ActionView
1.upto(12) do |month_number|
options = { :value => month_number }
options[:selected] = "selected" if month == month_number
- month_options << content_tag(:option, month_name(month_number), options) + "\n"
+ month_options << content_tag("option".freeze, month_name(month_number), options) + "\n"
end
build_select(:month, month_options.join)
end
@@ -971,7 +972,7 @@ module ActionView
tag_options[:selected] = "selected" if selected == i
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)
+ select_options << content_tag("option".freeze, text, tag_options)
end
(select_options.join("\n") + "\n").html_safe
@@ -991,11 +992,11 @@ module ActionView
select_options[:class] = [select_options[:class], type].compact.join(' ') if @options[:with_css_classes]
select_html = "\n"
- select_html << content_tag(:option, '', :value => '') + "\n" if @options[:include_blank]
+ select_html << content_tag("option".freeze, '', :value => '') + "\n" if @options[:include_blank]
select_html << prompt_option_tag(type, @options[:prompt]) + "\n" if @options[:prompt]
select_html << select_options_as_html
- (content_tag(:select, select_html.html_safe, select_options) + "\n").html_safe
+ (content_tag("select".freeze, select_html.html_safe, select_options) + "\n").html_safe
end
# Builds a prompt option tag with supplied options or from default options.
@@ -1012,7 +1013,7 @@ module ActionView
I18n.translate(:"datetime.prompts.#{type}", :locale => @options[:locale])
end
- prompt ? content_tag(:option, prompt, :value => '') : ''
+ prompt ? content_tag("option".freeze, prompt, :value => '') : ''
end
# Builds hidden input tag for date part and value.
diff --git a/actionview/lib/action_view/helpers/form_options_helper.rb b/actionview/lib/action_view/helpers/form_options_helper.rb
index 8e729b3c39..728e633bbf 100644
--- a/actionview/lib/action_view/helpers/form_options_helper.rb
+++ b/actionview/lib/action_view/helpers/form_options_helper.rb
@@ -456,7 +456,7 @@ module ActionView
option_tags = options_from_collection_for_select(
group.send(group_method), option_key_method, option_value_method, selected_key)
- content_tag(:optgroup, option_tags, label: group.send(group_label_method))
+ content_tag("optgroup".freeze, option_tags, label: group.send(group_label_method))
end.join.html_safe
end
@@ -528,7 +528,7 @@ module ActionView
body = "".html_safe
if prompt
- body.safe_concat content_tag(:option, prompt_text(prompt), value: "")
+ body.safe_concat content_tag("option".freeze, prompt_text(prompt), value: "")
end
grouped_options.each do |container|
@@ -541,7 +541,7 @@ module ActionView
end
html_attributes = { label: label }.merge!(html_attributes)
- body.safe_concat content_tag(:optgroup, options_for_select(container, selected_key), html_attributes)
+ body.safe_concat content_tag("optgroup".freeze, options_for_select(container, selected_key), html_attributes)
end
body
@@ -577,7 +577,7 @@ module ActionView
end
zone_options.safe_concat options_for_select(convert_zones[priority_zones], selected)
- zone_options.safe_concat content_tag(:option, '-------------', value: '', disabled: true)
+ zone_options.safe_concat content_tag("option".freeze, '-------------', value: '', disabled: true)
zone_options.safe_concat "\n"
zones = zones - priority_zones
diff --git a/actionview/lib/action_view/helpers/form_tag_helper.rb b/actionview/lib/action_view/helpers/form_tag_helper.rb
index 896020bc15..af684e05c6 100644
--- a/actionview/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionview/lib/action_view/helpers/form_tag_helper.rb
@@ -140,15 +140,15 @@ module ActionView
end
if include_blank
- option_tags = content_tag(:option, include_blank, value: '').safe_concat(option_tags)
+ option_tags = content_tag("option".freeze, include_blank, value: '').safe_concat(option_tags)
end
end
if prompt = options.delete(:prompt)
- option_tags = content_tag(:option, prompt, value: '').safe_concat(option_tags)
+ option_tags = content_tag("option".freeze, prompt, value: '').safe_concat(option_tags)
end
- content_tag :select, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys)
+ content_tag "select".freeze, option_tags, { "name" => html_name, "id" => sanitize_to_id(name) }.update(options.stringify_keys)
end
# Creates a standard text field; use these text fields to input smaller chunks of text like a username
@@ -414,34 +414,48 @@ module ActionView
# the form is processed normally, otherwise no action is taken.
# * <tt>:disable_with</tt> - Value of this parameter will be used as the value for a
# disabled version of the submit button when the form is submitted. This feature is
- # provided by the unobtrusive JavaScript driver.
+ # provided by the unobtrusive JavaScript driver. To disable this feature for a single submit tag
+ # pass <tt>:data => { disable_with: false }</tt> Defaults to value attribute.
#
# ==== Examples
# submit_tag
- # # => <input name="commit" type="submit" value="Save changes" />
+ # # => <input name="commit" data-disable-with="Save changes" type="submit" value="Save changes" />
#
# submit_tag "Edit this article"
- # # => <input name="commit" type="submit" value="Edit this article" />
+ # # => <input name="commit" data-disable-with="Edit this article" type="submit" value="Edit this article" />
#
# submit_tag "Save edits", disabled: true
- # # => <input disabled="disabled" name="commit" type="submit" value="Save edits" />
+ # # => <input disabled="disabled" name="commit" data-disable-with="Save edits" type="submit" value="Save edits" />
#
- # submit_tag "Complete sale", data: { disable_with: "Please wait..." }
- # # => <input name="commit" data-disable-with="Please wait..." type="submit" value="Complete sale" />
+ # submit_tag "Complete sale", data: { disable_with: "Submitting..." }
+ # # => <input name="commit" data-disable-with="Submitting..." type="submit" value="Complete sale" />
#
# submit_tag nil, class: "form_submit"
# # => <input class="form_submit" name="commit" type="submit" />
#
# submit_tag "Edit", class: "edit_button"
- # # => <input class="edit_button" name="commit" type="submit" value="Edit" />
+ # # => <input class="edit_button" data-disable-with="Edit" name="commit" type="submit" value="Edit" />
#
# submit_tag "Save", data: { confirm: "Are you sure?" }
- # # => <input name='commit' type='submit' value='Save' data-confirm="Are you sure?" />
+ # # => <input name='commit' type='submit' value='Save' data-disable-with="Save" data-confirm="Are you sure?" />
#
def submit_tag(value = "Save changes", options = {})
options = options.stringify_keys
+ tag_options = { "type" => "submit", "name" => "commit", "value" => value }.update(options)
+
+ if ActionView::Base.automatically_disable_submit_tag
+ unless tag_options["data-disable-with"] == false || (tag_options["data"] && tag_options["data"][:disable_with] == false)
+ disable_with_text = tag_options["data-disable-with"]
+ disable_with_text ||= tag_options["data"][:disable_with] if tag_options["data"]
+ disable_with_text ||= value.clone
+ tag_options.deep_merge!("data" => { "disable_with" => disable_with_text })
+ else
+ tag_options.delete("data-disable-with")
+ tag_options["data"].delete(:disable_with) if tag_options["data"]
+ end
+ end
- tag :input, { "type" => "submit", "name" => "commit", "value" => value }.update(options)
+ tag :input, tag_options
end
# Creates a button element that defines a <tt>submit</tt> button,
@@ -568,7 +582,7 @@ module ActionView
# # => <fieldset class="format"><p><input id="name" name="name" type="text" /></p></fieldset>
def field_set_tag(legend = nil, options = nil, &block)
output = tag(:fieldset, options, true)
- output.safe_concat(content_tag(:legend, legend)) unless legend.blank?
+ output.safe_concat(content_tag("legend".freeze, legend)) unless legend.blank?
output.concat(capture(&block)) if block_given?
output.safe_concat("</fieldset>")
end
diff --git a/actionview/lib/action_view/helpers/javascript_helper.rb b/actionview/lib/action_view/helpers/javascript_helper.rb
index e237a32cb7..ed7e882c94 100644
--- a/actionview/lib/action_view/helpers/javascript_helper.rb
+++ b/actionview/lib/action_view/helpers/javascript_helper.rb
@@ -47,8 +47,8 @@ module ActionView
# tag.
#
# javascript_tag "alert('All is good')", defer: 'defer'
- #
- # Returns:
+ #
+ # Returns:
# <script defer="defer">
# //<![CDATA[
# alert('All is good')
@@ -70,7 +70,7 @@ module ActionView
content_or_options_with_block
end
- content_tag(:script, javascript_cdata_section(content), html_options)
+ content_tag("script".freeze, javascript_cdata_section(content), html_options)
end
def javascript_cdata_section(content) #:nodoc:
diff --git a/actionview/lib/action_view/helpers/sanitize_helper.rb b/actionview/lib/action_view/helpers/sanitize_helper.rb
index a2e9f37453..191a881de0 100644
--- a/actionview/lib/action_view/helpers/sanitize_helper.rb
+++ b/actionview/lib/action_view/helpers/sanitize_helper.rb
@@ -120,7 +120,7 @@ module ActionView
attr_writer :full_sanitizer, :link_sanitizer, :white_list_sanitizer
# Vendors the full, link and white list sanitizers.
- # Provided strictly for compabitility and can be removed in Rails 5.
+ # Provided strictly for compatibility and can be removed in Rails 5.
def sanitizer_vendor
Rails::Html::Sanitizer
end
diff --git a/actionview/lib/action_view/helpers/tag_helper.rb b/actionview/lib/action_view/helpers/tag_helper.rb
index a87c223a71..2562504896 100644
--- a/actionview/lib/action_view/helpers/tag_helper.rb
+++ b/actionview/lib/action_view/helpers/tag_helper.rb
@@ -22,9 +22,10 @@ module ActionView
TAG_PREFIXES = ['aria', 'data', :aria, :data].to_set
- PRE_CONTENT_STRINGS = {
- :textarea => "\n"
- }
+ PRE_CONTENT_STRINGS = Hash.new { "".freeze }
+ PRE_CONTENT_STRINGS[:textarea] = "\n"
+ PRE_CONTENT_STRINGS["textarea"] = "\n"
+
# Returns an empty HTML tag of type +name+ which by default is XHTML
# compliant. Set +open+ to true to create an open tag compatible
@@ -143,24 +144,30 @@ module ActionView
def content_tag_string(name, content, options, escape = true)
tag_options = tag_options(options, escape) if options
content = ERB::Util.unwrapped_html_escape(content) if escape
- "<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name.to_sym]}#{content}</#{name}>".html_safe
+ "<#{name}#{tag_options}>#{PRE_CONTENT_STRINGS[name]}#{content}</#{name}>".html_safe
end
def tag_options(options, escape = true)
return if options.blank?
- attrs = []
+ output = ""
+ sep = " ".freeze
options.each_pair do |key, value|
if TAG_PREFIXES.include?(key) && value.is_a?(Hash)
value.each_pair do |k, v|
- attrs << prefix_tag_option(key, k, v, escape)
+ output << sep
+ output << prefix_tag_option(key, k, v, escape)
end
elsif BOOLEAN_ATTRIBUTES.include?(key)
- attrs << boolean_tag_option(key) if value
+ if value
+ output << sep
+ output << boolean_tag_option(key)
+ end
elsif !value.nil?
- attrs << tag_option(key, value, escape)
+ output << sep
+ output << tag_option(key, value, escape)
end
end
- " #{attrs * ' '}" unless attrs.empty?
+ output unless output.empty?
end
def prefix_tag_option(prefix, key, value, escape)
@@ -177,7 +184,7 @@ module ActionView
def tag_option(key, value, escape)
if value.is_a?(Array)
- value = escape ? safe_join(value, " ") : value.join(" ")
+ value = escape ? safe_join(value, " ".freeze) : value.join(" ".freeze)
else
value = escape ? ERB::Util.unwrapped_html_escape(value) : value
end
diff --git a/actionview/lib/action_view/helpers/text_helper.rb b/actionview/lib/action_view/helpers/text_helper.rb
index 6a3d01667d..432693bc23 100644
--- a/actionview/lib/action_view/helpers/text_helper.rb
+++ b/actionview/lib/action_view/helpers/text_helper.rb
@@ -250,12 +250,15 @@ module ActionView
#
# word_wrap('Once upon a time', line_width: 1)
# # => Once\nupon\na\ntime
- def word_wrap(text, options = {})
- line_width = options.fetch(:line_width, 80)
-
+ #
+ # You can also specify a custom +break_sequence+ ("\n" by default)
+ #
+ # word_wrap('Once upon a time', line_width: 1, break_sequence: "\r\n")
+ # # => Once\r\nupon\r\na\r\ntime
+ def word_wrap(text, line_width: 80, break_sequence: "\n")
text.split("\n").collect! do |line|
- line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1\n").strip : line
- end * "\n"
+ line.length > line_width ? line.gsub(/(.{1,#{line_width}})(\s+|$)/, "\\1#{break_sequence}").strip : line
+ end * break_sequence
end
# Returns +text+ transformed into HTML using simple formatting rules.
diff --git a/actionview/lib/action_view/helpers/url_helper.rb b/actionview/lib/action_view/helpers/url_helper.rb
index 7d92651183..d676a0a931 100644
--- a/actionview/lib/action_view/helpers/url_helper.rb
+++ b/actionview/lib/action_view/helpers/url_helper.rb
@@ -184,9 +184,9 @@ module ActionView
html_options = convert_options_to_data_attributes(options, html_options)
url = url_for(options)
- html_options['href'] ||= url
+ html_options["href".freeze] ||= url
- content_tag(:a, name || url, html_options, &block)
+ content_tag("a".freeze, name || url, html_options, &block)
end
# Generates a form containing a single button that submits to the URL created
@@ -471,7 +471,7 @@ module ActionView
encoded_email_address = ERB::Util.url_encode(email_address).gsub("%40", "@")
html_options["href"] = "mailto:#{encoded_email_address}#{extras}"
- content_tag(:a, name || email_address, html_options, &block)
+ content_tag("a".freeze, name || email_address, html_options, &block)
end
# True if the current request URI was generated by the given +options+.
diff --git a/actionview/lib/action_view/layouts.rb b/actionview/lib/action_view/layouts.rb
index 9d636c8c9e..cabba967c9 100644
--- a/actionview/lib/action_view/layouts.rb
+++ b/actionview/lib/action_view/layouts.rb
@@ -277,7 +277,7 @@ module ActionView
remove_possible_method(:_layout)
prefixes = _implied_layout_name =~ /\blayouts/ ? [] : ["layouts"]
- default_behavior = "lookup_context.find_all('#{_implied_layout_name}', #{prefixes.inspect}).first || super"
+ default_behavior = "lookup_context.find_all('#{_implied_layout_name}', #{prefixes.inspect}, false, [], { formats: formats }).first || super"
name_clause = if name
default_behavior
else
@@ -316,7 +316,7 @@ module ActionView
end
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
- def _layout
+ def _layout(formats)
if _conditional_layout?
#{layout_definition}
else
@@ -372,7 +372,7 @@ module ActionView
end
# This will be overwritten by _write_layout_method
- def _layout; end
+ def _layout(*); end
# Determine the layout for a given name, taking into account the name type.
#
@@ -382,8 +382,8 @@ module ActionView
case name
when String then _normalize_layout(name)
when Proc then name
- when true then Proc.new { _default_layout(true) }
- when :default then Proc.new { _default_layout(false) }
+ when true then Proc.new { |formats| _default_layout(formats, true) }
+ when :default then Proc.new { |formats| _default_layout(formats, false) }
when false, nil then nil
else
raise ArgumentError,
@@ -399,14 +399,15 @@ module ActionView
# Optionally raises an exception if the layout could not be found.
#
# ==== Parameters
+ # * <tt>formats</tt> - The formats accepted to this layout
# * <tt>require_layout</tt> - If set to true and layout is not found,
# an ArgumentError exception is raised (defaults to false)
#
# ==== Returns
# * <tt>template</tt> - The template object for the default layout (or nil)
- def _default_layout(require_layout = false)
+ def _default_layout(formats, require_layout = false)
begin
- value = _layout if action_has_layout?
+ value = _layout(formats) if action_has_layout?
rescue NameError => e
raise e, "Could not render layout: #{e.message}"
end
diff --git a/actionview/lib/action_view/lookup_context.rb b/actionview/lib/action_view/lookup_context.rb
index f4a10aa393..fba9a44cb1 100644
--- a/actionview/lib/action_view/lookup_context.rb
+++ b/actionview/lib/action_view/lookup_context.rb
@@ -229,21 +229,5 @@ module ActionView
super(default_locale)
end
-
- # Uses the first format in the formats array for layout lookup.
- def with_layout_format
- if formats.size == 1
- yield
- else
- old_formats = formats
- _set_detail(:formats, formats[0,1])
-
- begin
- yield
- ensure
- _set_detail(:formats, old_formats)
- end
- end
- end
end
end
diff --git a/actionview/lib/action_view/renderer/partial_renderer.rb b/actionview/lib/action_view/renderer/partial_renderer.rb
index 780fdabbd1..1f9e960488 100644
--- a/actionview/lib/action_view/renderer/partial_renderer.rb
+++ b/actionview/lib/action_view/renderer/partial_renderer.rb
@@ -520,7 +520,7 @@ module ActionView
def retrieve_variable(path, as)
variable = as || begin
- base = path[-1] == "/" ? "" : File.basename(path)
+ base = path[-1] == "/".freeze ? "".freeze : File.basename(path)
raise_invalid_identifier(path) unless base =~ /\A_?(.*)(?:\.\w+)*\z/
$1.to_sym
end
diff --git a/actionview/lib/action_view/renderer/streaming_template_renderer.rb b/actionview/lib/action_view/renderer/streaming_template_renderer.rb
index 3ab2cd36fc..f38e2764d0 100644
--- a/actionview/lib/action_view/renderer/streaming_template_renderer.rb
+++ b/actionview/lib/action_view/renderer/streaming_template_renderer.rb
@@ -47,7 +47,7 @@ module ActionView
return [super] unless layout_name && template.supports_streaming?
locals ||= {}
- layout = layout_name && find_layout(layout_name, locals.keys)
+ layout = layout_name && find_layout(layout_name, locals.keys, [formats.first])
Body.new do |buffer|
delayed_render(buffer, template, layout, @view, locals)
diff --git a/actionview/lib/action_view/renderer/template_renderer.rb b/actionview/lib/action_view/renderer/template_renderer.rb
index dbb4855e39..75217e1630 100644
--- a/actionview/lib/action_view/renderer/template_renderer.rb
+++ b/actionview/lib/action_view/renderer/template_renderer.rb
@@ -57,7 +57,7 @@ module ActionView
end
def render_with_layout(path, locals) #:nodoc:
- layout = path && find_layout(path, locals.keys)
+ layout = path && find_layout(path, locals.keys, [formats.first])
content = yield(layout)
if layout
@@ -72,27 +72,28 @@ module ActionView
# This is the method which actually finds the layout using details in the lookup
# context object. If no layout is found, it checks if at least a layout with
# the given name exists across all details before raising the error.
- def find_layout(layout, keys)
- with_layout_format { resolve_layout(layout, keys) }
+ def find_layout(layout, keys, formats)
+ resolve_layout(layout, keys, formats)
end
- def resolve_layout(layout, keys)
+ def resolve_layout(layout, keys, formats)
+ details = @details.dup
+ details[:formats] = formats
+
case layout
when String
begin
if layout =~ /^\//
- with_fallbacks { find_template(layout, nil, false, keys, @details) }
+ with_fallbacks { find_template(layout, nil, false, keys, details) }
else
- find_template(layout, nil, false, keys, @details)
+ find_template(layout, nil, false, keys, details)
end
rescue ActionView::MissingTemplate
all_details = @details.merge(:formats => @lookup_context.default_formats)
raise unless template_exists?(layout, nil, false, keys, all_details)
end
when Proc
- resolve_layout(layout.call, keys)
- when FalseClass
- nil
+ resolve_layout(layout.call(formats), keys, formats)
else
layout
end
diff --git a/actionview/lib/action_view/template.rb b/actionview/lib/action_view/template.rb
index 1ce9f94b13..e232808dcb 100644
--- a/actionview/lib/action_view/template.rb
+++ b/actionview/lib/action_view/template.rb
@@ -154,7 +154,7 @@ module ActionView
# we use a bang in this instrumentation because you don't want to
# consume this in production. This is only slow if it's being listened to.
def render(view, locals, buffer=nil, &block)
- instrument("!render_template") do
+ instrument("!render_template".freeze) do
compile!(view)
view.send(method_name, locals, buffer, &block)
end
@@ -348,7 +348,12 @@ module ActionView
def instrument(action, &block)
payload = { virtual_path: @virtual_path, identifier: @identifier }
- ActiveSupport::Notifications.instrument("#{action}.action_view", payload, &block)
+ case action
+ when "!render_template".freeze
+ ActiveSupport::Notifications.instrument("!render_template.action_view".freeze, payload, &block)
+ else
+ ActiveSupport::Notifications.instrument("#{action}.action_view".freeze, payload, &block)
+ end
end
EXPLICIT_COLLECTION = /# Template Collection: (?<resource_name>\w+)/
diff --git a/actionview/lib/action_view/test_case.rb b/actionview/lib/action_view/test_case.rb
index c4bc26ca8a..f6b5696a13 100644
--- a/actionview/lib/action_view/test_case.rb
+++ b/actionview/lib/action_view/test_case.rb
@@ -263,9 +263,15 @@ module ActionView
end
def method_missing(selector, *args)
- if @controller.respond_to?(:_routes) &&
- ( @controller._routes.named_routes.route_defined?(selector) ||
- @controller._routes.mounted_helpers.method_defined?(selector) )
+ begin
+ routes = @controller.respond_to?(:_routes) && @controller._routes
+ rescue
+ # Dont call routes, if there is an error on _routes call
+ end
+
+ if routes &&
+ ( routes.named_routes.route_defined?(selector) ||
+ routes.mounted_helpers.method_defined?(selector) )
@controller.__send__(selector, *args)
else
super