aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_view')
-rw-r--r--actionpack/lib/action_view/base.rb192
-rw-r--r--actionpack/lib/action_view/helpers.rb1
-rw-r--r--actionpack/lib/action_view/helpers/active_record_helper.rb12
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb34
-rw-r--r--actionpack/lib/action_view/helpers/benchmark_helper.rb6
-rw-r--r--actionpack/lib/action_view/helpers/form_country_helper.rb92
-rw-r--r--actionpack/lib/action_view/helpers/form_options_helper.rb3
-rw-r--r--actionpack/lib/action_view/helpers/form_tag_helper.rb31
-rw-r--r--actionpack/lib/action_view/helpers/prototype_helper.rb34
-rw-r--r--actionpack/lib/action_view/helpers/record_tag_helper.rb6
-rw-r--r--actionpack/lib/action_view/helpers/sanitize_helper.rb11
-rw-r--r--actionpack/lib/action_view/helpers/scriptaculous_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/text_helper.rb56
-rw-r--r--actionpack/lib/action_view/partials.rb2
-rw-r--r--actionpack/lib/action_view/renderable.rb27
-rw-r--r--actionpack/lib/action_view/renderable_partial.rb26
-rw-r--r--actionpack/lib/action_view/template.rb2
-rw-r--r--actionpack/lib/action_view/template_handlers/builder.rb2
-rw-r--r--actionpack/lib/action_view/test_case.rb2
19 files changed, 272 insertions, 269 deletions
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index d174c784f3..8c00670087 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -162,7 +162,6 @@ module ActionView #:nodoc:
attr_accessor :base_path, :assigns, :template_extension
attr_accessor :controller
- attr_accessor :_first_render, :_last_render
attr_writer :template_format
@@ -185,6 +184,17 @@ module ActionView #:nodoc:
"deprecated and has no effect. Please remove it from your config files.", caller)
end
+ # Templates that are exempt from layouts
+ @@exempt_from_layout = Set.new([/\.rjs$/])
+
+ # Don't render layouts for templates with the given extensions.
+ def self.exempt_from_layout(*extensions)
+ regexps = extensions.collect do |extension|
+ extension.is_a?(Regexp) ? extension : /\.#{Regexp.escape(extension.to_s)}$/
+ end
+ @@exempt_from_layout.merge(regexps)
+ end
+
# Specify whether RJS responses should be wrapped in a try/catch block
# that alert()s the caught exception (and then re-raises it).
@@debug_rjs = false
@@ -208,10 +218,24 @@ module ActionView #:nodoc:
ActionView::PathSet.new(Array(value))
end
+ attr_reader :helpers
+
+ class ProxyModule < Module
+ def initialize(receiver)
+ @receiver = receiver
+ end
+
+ def include(*args)
+ super(*args)
+ @receiver.extend(*args)
+ end
+ end
+
def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil)#:nodoc:
@assigns = assigns_for_first_render
@assigns_added = nil
@controller = controller
+ @helpers = ProxyModule.new(self)
self.view_paths = view_paths
end
@@ -232,33 +256,20 @@ module ActionView #:nodoc:
update_page(&block)
elsif options.is_a?(Hash)
options = options.reverse_merge(:locals => {})
-
- if partial_layout = options.delete(:layout)
- if block_given?
- begin
- @_proc_for_layout = block
- concat(render(options.merge(:partial => partial_layout)))
- ensure
- @_proc_for_layout = nil
- end
- else
- begin
- original_content_for_layout, @content_for_layout = @content_for_layout, render(options)
- render(options.merge(:partial => partial_layout))
- ensure
- @content_for_layout = original_content_for_layout
- end
- end
+ if options[:layout]
+ _render_with_layout(options, local_assigns, &block)
elsif options[:file]
if options[:use_full_path]
ActiveSupport::Deprecation.warn("use_full_path option has been deprecated and has no affect.", caller)
end
- pick_template(options[:file]).render_template(self, options[:locals])
+ _pick_template(options[:file]).render_template(self, options[:locals])
elsif options[:partial]
render_partial(options)
elsif options[:inline]
InlineTemplate.new(options[:inline], options[:type]).render(self, options[:locals])
+ elsif options[:text]
+ options[:text]
end
end
end
@@ -267,83 +278,106 @@ module ActionView #:nodoc:
# the same name but differing formats. See +Request#template_format+
# for more details.
def template_format
- return @template_format if @template_format
-
- if controller && controller.respond_to?(:request)
+ if defined? @template_format
+ @template_format
+ elsif controller && controller.respond_to?(:request)
@template_format = controller.request.template_format
else
@template_format = :html
end
end
- def file_exists?(template_path)
- pick_template(template_path) ? true : false
- rescue MissingTemplate
- false
- end
+ private
+ attr_accessor :_first_render, :_last_render
- # Gets the extension for an existing template with the given template_path.
- # Returns the format with the extension if that template exists.
- #
- # pick_template('users/show')
- # # => 'users/show.html.erb'
- #
- # pick_template('users/legacy')
- # # => 'users/legacy.rhtml'
- #
- def pick_template(template_path)
- return template_path if template_path.respond_to?(:render)
-
- path = template_path.sub(/^\//, '')
- if m = path.match(/(.*)\.(\w+)$/)
- template_file_name, template_file_extension = m[1], m[2]
- else
- template_file_name = path
- end
+ # Evaluate the local assigns and pushes them to the view.
+ def _evaluate_assigns_and_ivars #:nodoc:
+ unless @assigns_added
+ @assigns.each { |key, value| instance_variable_set("@#{key}", value) }
- # OPTIMIZE: Checks to lookup template in view path
- if template = self.view_paths["#{template_file_name}.#{template_format}"]
- template
- elsif template = self.view_paths[template_file_name]
- template
- elsif _first_render && template = self.view_paths["#{template_file_name}.#{_first_render.format_and_extension}"]
- template
- elsif template_format == :js && template = self.view_paths["#{template_file_name}.html"]
- @template_format = :html
- template
- else
- template = Template.new(template_path, view_paths)
-
- if self.class.warn_cache_misses && logger
- logger.debug "[PERFORMANCE] Rendering a template that was " +
- "not found in view path. Templates outside the view path are " +
- "not cached and result in expensive disk operations. Move this " +
- "file into #{view_paths.join(':')} or add the folder to your " +
- "view path list"
+ if @controller
+ variables = @controller.instance_variables
+ variables -= @controller.protected_instance_variables if @controller.respond_to?(:protected_instance_variables)
+ variables.each {|name| instance_variable_set(name, @controller.instance_variable_get(name)) }
+ end
+
+ @assigns_added = true
end
+ end
- template
+ def _set_controller_content_type(content_type) #:nodoc:
+ if controller.respond_to?(:response)
+ controller.response.content_type ||= content_type
+ end
end
- end
- memoize :pick_template
- private
- # Evaluate the local assigns and pushes them to the view.
- def evaluate_assigns
- unless @assigns_added
- assign_variables_from_controller
- @assigns_added = true
+ def _pick_template(template_path)
+ return template_path if template_path.respond_to?(:render)
+
+ path = template_path.sub(/^\//, '')
+ if m = path.match(/(.*)\.(\w+)$/)
+ template_file_name, template_file_extension = m[1], m[2]
+ else
+ template_file_name = path
+ end
+
+ # OPTIMIZE: Checks to lookup template in view path
+ if template = self.view_paths["#{template_file_name}.#{template_format}"]
+ template
+ elsif template = self.view_paths[template_file_name]
+ template
+ elsif _first_render && template = self.view_paths["#{template_file_name}.#{_first_render.format_and_extension}"]
+ template
+ elsif template_format == :js && template = self.view_paths["#{template_file_name}.html"]
+ @template_format = :html
+ template
+ else
+ template = Template.new(template_path, view_paths)
+
+ if self.class.warn_cache_misses && logger
+ logger.debug "[PERFORMANCE] Rendering a template that was " +
+ "not found in view path. Templates outside the view path are " +
+ "not cached and result in expensive disk operations. Move this " +
+ "file into #{view_paths.join(':')} or add the folder to your " +
+ "view path list"
+ end
+
+ template
end
end
+ memoize :_pick_template
- # Assigns instance variables from the controller to the view.
- def assign_variables_from_controller
- @assigns.each { |key, value| instance_variable_set("@#{key}", value) }
+ def _exempt_from_layout?(template_path) #:nodoc:
+ template = _pick_template(template_path).to_s
+ @@exempt_from_layout.any? { |ext| template =~ ext }
+ rescue ActionView::MissingTemplate
+ return false
end
- def set_controller_content_type(content_type)
- if controller.respond_to?(:response)
- controller.response.content_type ||= content_type
+ def _render_with_layout(options, local_assigns, &block) #:nodoc:
+ partial_layout = options.delete(:layout)
+
+ if block_given?
+ begin
+ @_proc_for_layout = block
+ concat(render(options.merge(:partial => partial_layout)))
+ ensure
+ @_proc_for_layout = nil
+ end
+ else
+ begin
+ original_content_for_layout = @content_for_layout if defined?(@content_for_layout)
+ @content_for_layout = render(options)
+
+ if (options[:inline] || options[:file] || options[:text])
+ @cached_content_for_layout = @content_for_layout
+ render(:file => partial_layout, :locals => local_assigns)
+ else
+ render(options.merge(:partial => partial_layout))
+ end
+ ensure
+ @content_for_layout = original_content_for_layout
+ end
end
end
end
diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb
index 05e1cf990a..ff97df204c 100644
--- a/actionpack/lib/action_view/helpers.rb
+++ b/actionpack/lib/action_view/helpers.rb
@@ -21,7 +21,6 @@ module ActionView #:nodoc:
include CaptureHelper
include DateHelper
include DebugHelper
- include FormCountryHelper
include FormHelper
include FormOptionsHelper
include FormTagHelper
diff --git a/actionpack/lib/action_view/helpers/active_record_helper.rb b/actionpack/lib/action_view/helpers/active_record_helper.rb
index c339e10701..8b56d241ae 100644
--- a/actionpack/lib/action_view/helpers/active_record_helper.rb
+++ b/actionpack/lib/action_view/helpers/active_record_helper.rb
@@ -246,7 +246,7 @@ module ActionView
alias_method :tag_without_error_wrapping, :tag
def tag(name, options)
- if object.respond_to?("errors") && object.errors.respond_to?("on")
+ if object.respond_to?(:errors) && object.errors.respond_to?(:on)
error_wrapping(tag_without_error_wrapping(name, options), object.errors.on(@method_name))
else
tag_without_error_wrapping(name, options)
@@ -255,7 +255,7 @@ module ActionView
alias_method :content_tag_without_error_wrapping, :content_tag
def content_tag(name, value, options)
- if object.respond_to?("errors") && object.errors.respond_to?("on")
+ if object.respond_to?(:errors) && object.errors.respond_to?(:on)
error_wrapping(content_tag_without_error_wrapping(name, value, options), object.errors.on(@method_name))
else
content_tag_without_error_wrapping(name, value, options)
@@ -264,7 +264,7 @@ module ActionView
alias_method :to_date_select_tag_without_error_wrapping, :to_date_select_tag
def to_date_select_tag(options = {}, html_options = {})
- if object.respond_to?("errors") && object.errors.respond_to?("on")
+ if object.respond_to?(:errors) && object.errors.respond_to?(:on)
error_wrapping(to_date_select_tag_without_error_wrapping(options, html_options), object.errors.on(@method_name))
else
to_date_select_tag_without_error_wrapping(options, html_options)
@@ -273,7 +273,7 @@ module ActionView
alias_method :to_datetime_select_tag_without_error_wrapping, :to_datetime_select_tag
def to_datetime_select_tag(options = {}, html_options = {})
- if object.respond_to?("errors") && object.errors.respond_to?("on")
+ if object.respond_to?(:errors) && object.errors.respond_to?(:on)
error_wrapping(to_datetime_select_tag_without_error_wrapping(options, html_options), object.errors.on(@method_name))
else
to_datetime_select_tag_without_error_wrapping(options, html_options)
@@ -282,7 +282,7 @@ module ActionView
alias_method :to_time_select_tag_without_error_wrapping, :to_time_select_tag
def to_time_select_tag(options = {}, html_options = {})
- if object.respond_to?("errors") && object.errors.respond_to?("on")
+ if object.respond_to?(:errors) && object.errors.respond_to?(:on)
error_wrapping(to_time_select_tag_without_error_wrapping(options, html_options), object.errors.on(@method_name))
else
to_time_select_tag_without_error_wrapping(options, html_options)
@@ -298,7 +298,7 @@ module ActionView
end
def column_type
- object.send("column_for_attribute", @method_name).type
+ object.send(:column_for_attribute, @method_name).type
end
end
end
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index 623ed1e8df..a926599e25 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -104,7 +104,7 @@ module ActionView
ASSETS_DIR = defined?(Rails.public_path) ? Rails.public_path : "public"
JAVASCRIPTS_DIR = "#{ASSETS_DIR}/javascripts"
STYLESHEETS_DIR = "#{ASSETS_DIR}/stylesheets"
- JAVASCRIPT_DEFAULT_SOURCES = ['prototype', 'effects', 'dragdrop', 'controls'].map(&:to_s).freeze unless const_defined?(:JAVASCRIPT_DEFAULT_SOURCES)
+ JAVASCRIPT_DEFAULT_SOURCES = ['prototype', 'effects', 'dragdrop', 'controls'].freeze unless const_defined?(:JAVASCRIPT_DEFAULT_SOURCES)
# Returns a link tag that browsers and news readers can use to auto-detect
# an RSS or ATOM feed. The +type+ can either be <tt>:rss</tt> (default) or
@@ -463,7 +463,8 @@ module ActionView
end
private
- COMPUTED_PUBLIC_PATHS = ActiveSupport::Cache::MemoryStore.new.silence!
+ COMPUTED_PUBLIC_PATHS = {}
+ COMPUTED_PUBLIC_PATHS_GUARD = Mutex.new
# Add the the extension +ext+ if not present. Return full URLs otherwise untouched.
# Prefix with <tt>/dir/</tt> if lacking a leading +/+. Account for relative URL
@@ -483,23 +484,24 @@ module ActionView
dir, source, ext, include_host ].join
end
- source = COMPUTED_PUBLIC_PATHS.fetch(cache_key) do
- begin
- source += ".#{ext}" if ext && File.extname(source).blank? || File.exist?(File.join(ASSETS_DIR, dir, "#{source}.#{ext}"))
-
- if source =~ %r{^[-a-z]+://}
- source
- else
- source = "/#{dir}/#{source}" unless source[0] == ?/
- if has_request
- unless source =~ %r{^#{ActionController::Base.relative_url_root}/}
- source = "#{ActionController::Base.relative_url_root}#{source}"
+ COMPUTED_PUBLIC_PATHS_GUARD.synchronize do
+ source = COMPUTED_PUBLIC_PATHS[cache_key] ||=
+ begin
+ source += ".#{ext}" if ext && File.extname(source).blank? || File.exist?(File.join(ASSETS_DIR, dir, "#{source}.#{ext}"))
+
+ if source =~ %r{^[-a-z]+://}
+ source
+ else
+ source = "/#{dir}/#{source}" unless source[0] == ?/
+ if has_request
+ unless source =~ %r{^#{ActionController::Base.relative_url_root}/}
+ source = "#{ActionController::Base.relative_url_root}#{source}"
+ end
end
- end
- rewrite_asset_path(source)
+ rewrite_asset_path(source)
+ end
end
- end
end
if include_host && source !~ %r{^[-a-z]+://}
diff --git a/actionpack/lib/action_view/helpers/benchmark_helper.rb b/actionpack/lib/action_view/helpers/benchmark_helper.rb
index 743d1d40ec..bd72cda700 100644
--- a/actionpack/lib/action_view/helpers/benchmark_helper.rb
+++ b/actionpack/lib/action_view/helpers/benchmark_helper.rb
@@ -15,15 +15,15 @@ module ActionView
# <%= expensive_files_operation %>
# <% end %>
#
- # That would add something like "Process data files (0.34523)" to the log,
+ # That would add something like "Process data files (345.2ms)" to the log,
# which you can then use to compare timings when optimizing your code.
#
# You may give an optional logger level as the second argument
# (:debug, :info, :warn, :error); the default value is :info.
def benchmark(message = "Benchmarking", level = :info)
if controller.logger
- real = Benchmark.realtime { yield }
- controller.logger.send(level, "#{message} (#{'%.5f' % real})")
+ seconds = Benchmark.realtime { yield }
+ controller.logger.send(level, "#{message} (#{'%.1f' % (seconds * 1000)}ms)")
else
yield
end
diff --git a/actionpack/lib/action_view/helpers/form_country_helper.rb b/actionpack/lib/action_view/helpers/form_country_helper.rb
deleted file mode 100644
index 84e811f61d..0000000000
--- a/actionpack/lib/action_view/helpers/form_country_helper.rb
+++ /dev/null
@@ -1,92 +0,0 @@
-require 'action_view/helpers/form_options_helper'
-
-module ActionView
- module Helpers
- module FormCountryHelper
-
- # Return select and option tags for the given object and method, using country_options_for_select to generate the list of option tags.
- def country_select(object, method, priority_countries = nil, options = {}, html_options = {})
- InstanceTag.new(object, method, self, options.delete(:object)).to_country_select_tag(priority_countries, options, html_options)
- end
-
- # Returns a string of option tags for pretty much any country in the world. Supply a country name as +selected+ to
- # have it marked as the selected option tag. You can also supply an array of countries as +priority_countries+, so
- # that they will be listed above the rest of the (long) list.
- #
- # NOTE: Only the option tags are returned, you have to wrap this call in a regular HTML select tag.
- def country_options_for_select(selected = nil, priority_countries = nil)
- country_options = ""
-
- if priority_countries
- country_options += options_for_select(priority_countries, selected)
- country_options += "<option value=\"\" disabled=\"disabled\">-------------</option>\n"
- end
-
- return country_options + options_for_select(COUNTRIES, selected)
- end
-
- private
-
- # All the countries included in the country_options output.
- COUNTRIES = ["Afghanistan", "Aland Islands", "Albania", "Algeria", "American Samoa", "Andorra", "Angola",
- "Anguilla", "Antarctica", "Antigua And Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria",
- "Azerbaijan", "Bahamas", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin",
- "Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegowina", "Botswana", "Bouvet Island", "Brazil",
- "British Indian Ocean Territory", "Brunei Darussalam", "Bulgaria", "Burkina Faso", "Burundi", "Cambodia",
- "Cameroon", "Canada", "Cape Verde", "Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
- "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
- "Congo, the Democratic Republic of the", "Cook Islands", "Costa Rica", "Cote d'Ivoire", "Croatia", "Cuba",
- "Cyprus", "Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "Ecuador", "Egypt",
- "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia", "Ethiopia", "Falkland Islands (Malvinas)",
- "Faroe Islands", "Fiji", "Finland", "France", "French Guiana", "French Polynesia",
- "French Southern Territories", "Gabon", "Gambia", "Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guernsey", "Guinea",
- "Guinea-Bissau", "Guyana", "Haiti", "Heard and McDonald Islands", "Holy See (Vatican City State)",
- "Honduras", "Hong Kong", "Hungary", "Iceland", "India", "Indonesia", "Iran, Islamic Republic of", "Iraq",
- "Ireland", "Isle of Man", "Israel", "Italy", "Jamaica", "Japan", "Jersey", "Jordan", "Kazakhstan", "Kenya",
- "Kiribati", "Korea, Democratic People's Republic of", "Korea, Republic of", "Kuwait", "Kyrgyzstan",
- "Lao People's Democratic Republic", "Latvia", "Lebanon", "Lesotho", "Liberia", "Libyan Arab Jamahiriya",
- "Liechtenstein", "Lithuania", "Luxembourg", "Macao", "Macedonia, The Former Yugoslav Republic Of",
- "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", "Martinique",
- "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia, Federated States of", "Moldova, Republic of",
- "Monaco", "Mongolia", "Montenegro", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia", "Nauru",
- "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand", "Nicaragua", "Niger",
- "Nigeria", "Niue", "Norfolk Island", "Northern Mariana Islands", "Norway", "Oman", "Pakistan", "Palau",
- "Palestinian Territory, Occupied", "Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines",
- "Pitcairn", "Poland", "Portugal", "Puerto Rico", "Qatar", "Reunion", "Romania", "Russian Federation",
- "Rwanda", "Saint Barthelemy", "Saint Helena", "Saint Kitts and Nevis", "Saint Lucia",
- "Saint Pierre and Miquelon", "Saint Vincent and the Grenadines", "Samoa", "San Marino",
- "Sao Tome and Principe", "Saudi Arabia", "Senegal", "Serbia", "Seychelles", "Sierra Leone", "Singapore",
- "Slovakia", "Slovenia", "Solomon Islands", "Somalia", "South Africa",
- "South Georgia and the South Sandwich Islands", "Spain", "Sri Lanka", "Sudan", "Suriname",
- "Svalbard and Jan Mayen", "Swaziland", "Sweden", "Switzerland", "Syrian Arab Republic",
- "Taiwan, Province of China", "Tajikistan", "Tanzania, United Republic of", "Thailand", "Timor-Leste",
- "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey", "Turkmenistan",
- "Turks and Caicos Islands", "Tuvalu", "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom",
- "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan", "Vanuatu", "Venezuela",
- "Viet Nam", "Virgin Islands, British", "Virgin Islands, U.S.", "Wallis and Futuna", "Western Sahara",
- "Yemen", "Zambia", "Zimbabwe"] unless const_defined?("COUNTRIES")
- end
-
- class InstanceTag #:nodoc:
- include FormCountryHelper
-
- def to_country_select_tag(priority_countries, options, html_options)
- html_options = html_options.stringify_keys
- add_default_name_and_id(html_options)
- value = value(object)
- content_tag("select",
- add_options(
- country_options_for_select(value, priority_countries),
- options, value
- ), html_options
- )
- end
- end
-
- class FormBuilder
- def country_select(method, priority_countries = nil, options = {}, html_options = {})
- @template.country_select(@object_name, method, priority_countries, objectify_options(options), @default_options.merge(html_options))
- end
- end
- end
-end \ No newline at end of file
diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb
index 9aae945408..33f8aaf9ed 100644
--- a/actionpack/lib/action_view/helpers/form_options_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_options_helper.rb
@@ -324,9 +324,6 @@ module ActionView
value == selected
end
end
-
- # All the countries included in the country_options output.
- COUNTRIES = ActiveSupport::Deprecation::DeprecatedConstantProxy.new 'COUNTRIES', 'ActionView::Helpers::FormCountryHelper::COUNTRIES'
end
class InstanceTag #:nodoc:
diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb
index e8ca02d760..294c22521e 100644
--- a/actionpack/lib/action_view/helpers/form_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb
@@ -116,7 +116,7 @@ module ActionView
# Creates a label field
#
- # ==== Options
+ # ==== Options
# * Creates standard HTML attributes for the tag.
#
# ==== Examples
@@ -155,10 +155,10 @@ module ActionView
# Creates a file upload field. If you are using file uploads then you will also need
# to set the multipart option for the form tag:
#
- # <%= form_tag { :action => "post" }, { :multipart => true } %>
+ # <% form_tag '/upload', :multipart => true do %>
# <label for="file">File to Upload</label> <%= file_field_tag "file" %>
# <%= submit_tag %>
- # <%= end_form_tag %>
+ # <% end %>
#
# The specified URL will then be passed a File object containing the selected file, or if the field
# was left blank, a StringIO object.
@@ -351,19 +351,16 @@ module ActionView
disable_with = "this.value='#{disable_with}'"
disable_with << ";#{options.delete('onclick')}" if options['onclick']
- options["onclick"] = [
- "this.setAttribute('originalValue', this.value)",
- "this.disabled=true",
- disable_with,
- "result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit())",
- "if (result == false) { this.value = this.getAttribute('originalValue'); this.disabled = false }",
- "return result;",
- ].join(";")
+ options["onclick"] = "if (window.hiddenCommit) { window.hiddenCommit.setAttribute('value', this.value); }"
+ options["onclick"] << "else { hiddenCommit = this.cloneNode(false);hiddenCommit.setAttribute('type', 'hidden');this.form.appendChild(hiddenCommit); }"
+ options["onclick"] << "this.setAttribute('originalValue', this.value);this.disabled = true;#{disable_with};"
+ options["onclick"] << "result = (this.form.onsubmit ? (this.form.onsubmit() ? this.form.submit() : false) : this.form.submit());"
+ options["onclick"] << "if (result == false) { this.value = this.getAttribute('originalValue');this.disabled = false; }return result;"
end
if confirm = options.delete("confirm")
options["onclick"] ||= ''
- options["onclick"] += "return #{confirm_javascript_function(confirm)};"
+ options["onclick"] << "return #{confirm_javascript_function(confirm)};"
end
tag :input, { "type" => "submit", "name" => "commit", "value" => value }.update(options.stringify_keys)
@@ -374,6 +371,9 @@ module ActionView
# <tt>source</tt> is passed to AssetTagHelper#image_path
#
# ==== Options
+ # * <tt>:confirm => 'question?'</tt> - This will add a JavaScript confirm
+ # prompt with the question specified. If the user accepts, the form is
+ # processed normally, otherwise no action is taken.
# * <tt>:disabled</tt> - If set to true, the user will not be able to use this input.
# * Any other key creates standard HTML options for the tag.
#
@@ -390,6 +390,13 @@ module ActionView
# image_submit_tag("agree.png", :disabled => true, :class => "agree-disagree-button")
# # => <input class="agree-disagree-button" disabled="disabled" src="/images/agree.png" type="image" />
def image_submit_tag(source, options = {})
+ options.stringify_keys!
+
+ if confirm = options.delete("confirm")
+ options["onclick"] ||= ''
+ options["onclick"] += "return #{confirm_javascript_function(confirm)};"
+ end
+
tag :input, { "type" => "image", "src" => path_to_image(source) }.update(options.stringify_keys)
end
diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb
index ff83494e94..ff41a6d417 100644
--- a/actionpack/lib/action_view/helpers/prototype_helper.rb
+++ b/actionpack/lib/action_view/helpers/prototype_helper.rb
@@ -255,6 +255,14 @@ module ActionView
link_to_function(name, remote_function(options), html_options || options.delete(:html))
end
+ # Creates a button with an onclick event which calls a remote action
+ # via XMLHttpRequest
+ # The options for specifying the target with :url
+ # and defining callbacks is the same as link_to_remote.
+ def button_to_remote(name, options = {}, html_options = {})
+ button_to_function(name, remote_function(options), html_options)
+ end
+
# Periodically calls the specified url (<tt>options[:url]</tt>) every
# <tt>options[:frequency]</tt> seconds (default is 10). Usually used to
# update a specified div (<tt>options[:update]</tt>) with the results
@@ -588,26 +596,8 @@ module ActionView
private
def include_helpers_from_context
- unless generator_methods_module = @context.instance_variable_get(:@__javascript_generator_methods__)
- modules = @context.extended_by - ([ActionView::Helpers] + ActionView::Helpers.included_modules)
-
- generator_methods_module = Module.new do
- modules.each do |mod|
- begin
- include mod
- rescue Exception => e
- # HACK: Probably not a good idea to suppress these warnings
- # AFAIK exceptions are only raised in while testing with mocha
- # because the module does not like to be included into other
- # non TestUnit classes
- end
- end
- include GeneratorMethods
- end
- @context.instance_variable_set(:@__javascript_generator_methods__, generator_methods_module)
- end
-
- extend generator_methods_module
+ extend @context.helpers if @context.respond_to?(:helpers)
+ extend GeneratorMethods
end
# JavaScriptGenerator generates blocks of JavaScript code that allow you
@@ -624,7 +614,7 @@ module ActionView
# Example:
#
# # Generates:
- # # new Element.insert("list", { bottom: <li>Some item</li>" });
+ # # new Element.insert("list", { bottom: "<li>Some item</li>" });
# # new Effect.Highlight("list");
# # ["status-indicator", "cancel-link"].each(Element.hide);
# update_page do |page|
@@ -1070,7 +1060,7 @@ module ActionView
js_options['asynchronous'] = options[:type] != :synchronous
js_options['method'] = method_option_to_s(options[:method]) if options[:method]
- js_options['insertion'] = options[:position].to_s.downcase if options[:position]
+ js_options['insertion'] = "'#{options[:position].to_s.downcase}'" if options[:position]
js_options['evalScripts'] = options[:script].nil? || options[:script]
if options[:form]
diff --git a/actionpack/lib/action_view/helpers/record_tag_helper.rb b/actionpack/lib/action_view/helpers/record_tag_helper.rb
index 9bb235175e..0cdb70e217 100644
--- a/actionpack/lib/action_view/helpers/record_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/record_tag_helper.rb
@@ -49,9 +49,9 @@ module ActionView
#
def content_tag_for(tag_name, record, *args, &block)
prefix = args.first.is_a?(Hash) ? nil : args.shift
- options = args.first.is_a?(Hash) ? args.shift : {}
- concat content_tag(tag_name, capture(&block),
- options.merge({ :class => "#{dom_class(record)} #{options[:class]}".strip, :id => dom_id(record, prefix) }))
+ options = args.extract_options!
+ options.merge!({ :class => "#{dom_class(record)} #{options[:class]}".strip, :id => dom_id(record, prefix) })
+ content_tag(tag_name, options, &block)
end
end
end
diff --git a/actionpack/lib/action_view/helpers/sanitize_helper.rb b/actionpack/lib/action_view/helpers/sanitize_helper.rb
index 637caf203b..435ba936e1 100644
--- a/actionpack/lib/action_view/helpers/sanitize_helper.rb
+++ b/actionpack/lib/action_view/helpers/sanitize_helper.rb
@@ -1,5 +1,14 @@
require 'action_view/helpers/tag_helper'
-require 'html/document'
+
+begin
+ require 'html/document'
+rescue LoadError
+ html_scanner_path = "#{File.dirname(__FILE__)}/../../action_controller/vendor/html-scanner"
+ if File.directory?(html_scanner_path)
+ $:.unshift html_scanner_path
+ require 'html/document'
+ end
+end
module ActionView
module Helpers #:nodoc:
diff --git a/actionpack/lib/action_view/helpers/scriptaculous_helper.rb b/actionpack/lib/action_view/helpers/scriptaculous_helper.rb
index b938c1a801..1d01dafd0e 100644
--- a/actionpack/lib/action_view/helpers/scriptaculous_helper.rb
+++ b/actionpack/lib/action_view/helpers/scriptaculous_helper.rb
@@ -95,7 +95,7 @@ module ActionView
# * <tt>:containment</tt> - Takes an element or array of elements to treat as
# potential drop targets (defaults to the original target element).
#
- # * <tt>:only</tt> - A CSS class name or arry of class names used to filter
+ # * <tt>:only</tt> - A CSS class name or array of class names used to filter
# out child elements as candidates.
#
# * <tt>:scroll</tt> - Determines whether to scroll the list during drag
diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb
index f9096d0029..ab1fdc80bc 100644
--- a/actionpack/lib/action_view/helpers/text_helper.rb
+++ b/actionpack/lib/action_view/helpers/text_helper.rb
@@ -1,5 +1,14 @@
require 'action_view/helpers/tag_helper'
-require 'html/document'
+
+begin
+ require 'html/document'
+rescue LoadError
+ html_scanner_path = "#{File.dirname(__FILE__)}/../../action_controller/vendor/html-scanner"
+ if File.directory?(html_scanner_path)
+ $:.unshift html_scanner_path
+ require 'html/document'
+ end
+end
module ActionView
module Helpers #:nodoc:
@@ -289,7 +298,7 @@ module ActionView
""
else
textilized = RedCloth.new(text, [ :hard_breaks ])
- textilized.hard_breaks = true if textilized.respond_to?("hard_breaks=")
+ textilized.hard_breaks = true if textilized.respond_to?(:hard_breaks=)
textilized.to_html
end
end
@@ -439,8 +448,10 @@ module ActionView
# array every time it is called. This can be used for example, to alternate
# classes for table rows. You can use named cycles to allow nesting in loops.
# Passing a Hash as the last parameter with a <tt>:name</tt> key will create a
- # named cycle. You can manually reset a cycle by calling reset_cycle and passing the
- # name of the cycle.
+ # named cycle. The default name for a cycle without a +:name+ key is
+ # <tt>"default"</tt>. You can manually reset a cycle by calling reset_cycle
+ # and passing the name of the cycle. The current cycle string can be obtained
+ # anytime using the current_cycle method.
#
# ==== Examples
# # Alternate CSS classes for even and odd numbers...
@@ -487,6 +498,23 @@ module ActionView
return cycle.to_s
end
+ # Returns the current cycle string after a cycle has been started. Useful
+ # for complex table highlighing or any other design need which requires
+ # the current cycle string in more than one place.
+ #
+ # ==== Example
+ # # Alternate background colors
+ # @items = [1,2,3,4]
+ # <% @items.each do |item| %>
+ # <div style="background-color:<%= cycle("red","white","blue") %>">
+ # <span style="background-color:<%= current_cycle %>"><%= item %></span>
+ # </div>
+ # <% end %>
+ def current_cycle(name = "default")
+ cycle = get_cycle(name)
+ cycle.current_value unless cycle.nil?
+ end
+
# Resets a cycle so that it starts from the first element the next time
# it is called. Pass in +name+ to reset a named cycle.
#
@@ -523,11 +551,29 @@ module ActionView
@index = 0
end
+ def current_value
+ @values[previous_index].to_s
+ end
+
def to_s
value = @values[@index].to_s
- @index = (@index + 1) % @values.size
+ @index = next_index
return value
end
+
+ private
+
+ def next_index
+ step_index(1)
+ end
+
+ def previous_index
+ step_index(-1)
+ end
+
+ def step_index(n)
+ (@index + n) % @values.size
+ end
end
private
diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb
index 443c49b870..373bb92dc4 100644
--- a/actionpack/lib/action_view/partials.rb
+++ b/actionpack/lib/action_view/partials.rb
@@ -196,7 +196,7 @@ module ActionView
path = "_#{partial_path}"
end
- pick_template(path)
+ _pick_template(path)
end
memoize :_pick_partial_template
end
diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb
index c011f21550..0134bc988f 100644
--- a/actionpack/lib/action_view/renderable.rb
+++ b/actionpack/lib/action_view/renderable.rb
@@ -1,8 +1,7 @@
module ActionView
- module Renderable
- # NOTE: The template that this mixin is beening include into is frozen
- # So you can not set or modify any instance variables
-
+ # NOTE: The template that this mixin is being included into is frozen
+ # so you cannot set or modify any instance variables
+ module Renderable #:nodoc:
extend ActiveSupport::Memoizable
def self.included(base)
@@ -26,17 +25,18 @@ module ActionView
def render(view, local_assigns = {})
compile(local_assigns)
- view._first_render ||= self
- view._last_render = self
+ view.send(:_first_render=, self) unless view.send(:_first_render)
+ view.send(:_last_render=, self)
- view.send(:evaluate_assigns)
- view.send(:set_controller_content_type, mime_type) if respond_to?(:mime_type)
+ view.send(:_evaluate_assigns_and_ivars)
+ view.send(:_set_controller_content_type, mime_type) if respond_to?(:mime_type)
view.send(method_name(local_assigns), local_assigns) do |*names|
- if proc = view.instance_variable_get("@_proc_for_layout")
+ ivar = :@_proc_for_layout
+ if view.instance_variable_defined?(ivar) and proc = view.instance_variable_get(ivar)
view.capture(*names, &proc)
- else
- view.instance_variable_get("@content_for_#{names.first || 'layout'}")
+ elsif view.instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}")
+ view.instance_variable_get(ivar)
end
end
end
@@ -72,12 +72,9 @@ module ActionView
end_src
begin
- logger = Base.logger
- logger.debug "Compiling template #{render_symbol}" if logger
-
ActionView::Base::CompiledTemplates.module_eval(source, filename, 0)
rescue Exception => e # errors from template code
- if logger
+ if logger = defined?(ActionController) && Base.logger
logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}"
logger.debug "Function body: #{source}"
logger.debug "Backtrace: #{e.backtrace.join("\n")}"
diff --git a/actionpack/lib/action_view/renderable_partial.rb b/actionpack/lib/action_view/renderable_partial.rb
index 342850f0f0..d92ff1b8d3 100644
--- a/actionpack/lib/action_view/renderable_partial.rb
+++ b/actionpack/lib/action_view/renderable_partial.rb
@@ -1,8 +1,7 @@
module ActionView
- module RenderablePartial
- # NOTE: The template that this mixin is beening include into is frozen
- # So you can not set or modify any instance variables
-
+ # NOTE: The template that this mixin is being included into is frozen
+ # so you cannot set or modify any instance variables
+ module RenderablePartial #:nodoc:
extend ActiveSupport::Memoizable
def variable_name
@@ -16,15 +15,28 @@ module ActionView
memoize :counter_name
def render(view, local_assigns = {})
- ActionController::Base.benchmark("Rendered #{path_without_format_and_extension}", Logger::DEBUG, false) do
+ if defined? ActionController
+ ActionController::Base.benchmark("Rendered #{path_without_format_and_extension}", Logger::DEBUG, false) do
+ super
+ end
+ else
super
end
end
def render_partial(view, object = nil, local_assigns = {}, as = nil)
object ||= local_assigns[:object] ||
- local_assigns[variable_name] ||
- view.controller.instance_variable_get("@#{variable_name}") if view.respond_to?(:controller)
+ local_assigns[variable_name]
+
+ if view.respond_to?(:controller)
+ ivar = :"@#{variable_name}"
+ object ||=
+ if view.controller.instance_variable_defined?(ivar)
+ ActiveSupport::Deprecation::DeprecatedObjectProxy.new(
+ view.controller.instance_variable_get(ivar),
+ "#{ivar} will no longer be implicitly assigned to #{variable_name}")
+ end
+ end
# Ensure correct object is reassigned to other accessors
local_assigns[:object] = local_assigns[variable_name] = object
diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb
index 5dc6708431..64597b3d39 100644
--- a/actionpack/lib/action_view/template.rb
+++ b/actionpack/lib/action_view/template.rb
@@ -1,3 +1,5 @@
+require 'action_controller/mime_type'
+
module ActionView #:nodoc:
class Template
extend TemplateHandlers
diff --git a/actionpack/lib/action_view/template_handlers/builder.rb b/actionpack/lib/action_view/template_handlers/builder.rb
index 7d24a5c423..788dc93326 100644
--- a/actionpack/lib/action_view/template_handlers/builder.rb
+++ b/actionpack/lib/action_view/template_handlers/builder.rb
@@ -6,7 +6,7 @@ module ActionView
include Compilable
def compile(template)
- "set_controller_content_type(Mime::XML);" +
+ "_set_controller_content_type(Mime::XML);" +
"xml = ::Builder::XmlMarkup.new(:indent => 2);" +
"self.output_buffer = xml.target!;" +
template.source +
diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb
index adbb37fd09..c69f9455b2 100644
--- a/actionpack/lib/action_view/test_case.rb
+++ b/actionpack/lib/action_view/test_case.rb
@@ -54,7 +54,7 @@ module ActionView
private
def method_missing(selector, *args)
controller = TestController.new
- return controller.send!(selector, *args) if ActionController::Routing::Routes.named_routes.helpers.include?(selector)
+ return controller.__send__(selector, *args) if ActionController::Routing::Routes.named_routes.helpers.include?(selector)
super
end
end