aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
authorJeremy Kemper <jeremy@bitsweat.net>2008-07-17 11:52:56 -0700
committerJeremy Kemper <jeremy@bitsweat.net>2008-07-17 11:52:56 -0700
commit636e6b7138864ceb1e309939cd879e710b287f3e (patch)
tree2a36dfef02f706302a20bb5b2d428b32e9af97f0 /actionpack/lib
parent842917dea0cfdf70f158a312cc1f77f769791d8c (diff)
parent99930d499e424f4560b371412e05d10476216ece (diff)
downloadrails-636e6b7138864ceb1e309939cd879e710b287f3e.tar.gz
rails-636e6b7138864ceb1e309939cd879e710b287f3e.tar.bz2
rails-636e6b7138864ceb1e309939cd879e710b287f3e.zip
Merge branch 'master' into i18n-merge
Conflicts: actionpack/lib/action_view/helpers/form_options_helper.rb activerecord/lib/active_record/validations.rb
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/action_controller/assertions/selector_assertions.rb6
-rwxr-xr-xactionpack/lib/action_controller/base.rb2
-rw-r--r--actionpack/lib/action_controller/caching/fragments.rb2
-rw-r--r--actionpack/lib/action_controller/cookies.rb10
-rw-r--r--actionpack/lib/action_controller/integration.rb2
-rw-r--r--actionpack/lib/action_controller/rack_process.rb10
-rwxr-xr-xactionpack/lib/action_controller/request.rb6
-rw-r--r--actionpack/lib/action_controller/request_forgery_protection.rb2
-rw-r--r--actionpack/lib/action_controller/rescue.rb28
-rw-r--r--actionpack/lib/action_controller/resources.rb4
-rw-r--r--actionpack/lib/action_controller/streaming.rb23
-rw-r--r--actionpack/lib/action_controller/test_case.rb23
-rw-r--r--actionpack/lib/action_controller/test_process.rb4
-rw-r--r--actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb4
-rw-r--r--actionpack/lib/action_view/base.rb9
-rw-r--r--actionpack/lib/action_view/helpers/active_record_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/asset_tag_helper.rb25
-rw-r--r--actionpack/lib/action_view/helpers/capture_helper.rb17
-rwxr-xr-xactionpack/lib/action_view/helpers/date_helper.rb4
-rw-r--r--actionpack/lib/action_view/helpers/debug_helper.rb33
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb35
-rw-r--r--actionpack/lib/action_view/helpers/javascript_helper.rb21
-rw-r--r--actionpack/lib/action_view/helpers/prototype_helper.rb7
-rw-r--r--actionpack/lib/action_view/helpers/sanitize_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/scriptaculous_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/tag_helper.rb2
-rw-r--r--actionpack/lib/action_view/helpers/url_helper.rb2
-rw-r--r--actionpack/lib/action_view/paths.rb16
-rw-r--r--actionpack/lib/action_view/renderable.rb53
29 files changed, 237 insertions, 119 deletions
diff --git a/actionpack/lib/action_controller/assertions/selector_assertions.rb b/actionpack/lib/action_controller/assertions/selector_assertions.rb
index d3594e711c..70b0ed53e7 100644
--- a/actionpack/lib/action_controller/assertions/selector_assertions.rb
+++ b/actionpack/lib/action_controller/assertions/selector_assertions.rb
@@ -21,10 +21,8 @@ module ActionController
# from the response HTML or elements selected by the enclosing assertion.
#
# In addition to HTML responses, you can make the following assertions:
- # * +assert_select_rjs+ - Assertions on HTML content of RJS update and
- # insertion operations.
- # * +assert_select_encoded+ - Assertions on HTML encoded inside XML,
- # for example for dealing with feed item descriptions.
+ # * +assert_select_rjs+ - Assertions on HTML content of RJS update and insertion operations.
+ # * +assert_select_encoded+ - Assertions on HTML encoded inside XML, for example for dealing with feed item descriptions.
# * +assert_select_email+ - Assertions on the HTML body of an e-mail.
#
# Also see HTML::Selector to learn how to use selectors.
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index df94f78f18..c56812c2d9 100755
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -1155,7 +1155,7 @@ module ActionController #:nodoc:
def log_processing
if logger && logger.info?
- logger.info "\n\nProcessing #{controller_class_name}\##{action_name} (for #{request_origin}) [#{request.method.to_s.upcase}]"
+ logger.info "\n\nProcessing #{self.class.name}\##{action_name} (for #{request_origin}) [#{request.method.to_s.upcase}]"
logger.info " Session ID: #{@_session.session_id}" if @_session and @_session.respond_to?(:session_id)
logger.info " Parameters: #{respond_to?(:filter_parameters) ? filter_parameters(params).inspect : params.inspect}"
end
diff --git a/actionpack/lib/action_controller/caching/fragments.rb b/actionpack/lib/action_controller/caching/fragments.rb
index b1f25fdf5c..e9b434dd25 100644
--- a/actionpack/lib/action_controller/caching/fragments.rb
+++ b/actionpack/lib/action_controller/caching/fragments.rb
@@ -2,7 +2,7 @@ module ActionController #:nodoc:
module Caching
# Fragment caching is used for caching various blocks within templates without caching the entire action as a whole. This is useful when
# certain elements of an action change frequently or depend on complicated state while other parts rarely change or can be shared amongst multiple
- # parties. The caching is doing using the cache helper available in the Action View. A template with caching might look something like:
+ # parties. The caching is done using the cache helper available in the Action View. A template with caching might look something like:
#
# <b>Hello <%= @name %></b>
# <% cache do %>
diff --git a/actionpack/lib/action_controller/cookies.rb b/actionpack/lib/action_controller/cookies.rb
index a4cddbcea2..0428f2a23d 100644
--- a/actionpack/lib/action_controller/cookies.rb
+++ b/actionpack/lib/action_controller/cookies.rb
@@ -22,6 +22,16 @@ module ActionController #:nodoc:
#
# cookies.delete :user_name
#
+ # Please note that if you specify a :domain when setting a cookie, you must also specify the domain when deleting the cookie:
+ #
+ # cookies[:key] = {
+ # :value => 'a yummy cookie',
+ # :expires => 1.year.from_now,
+ # :domain => 'domain.com'
+ # }
+ #
+ # cookies.delete(:key, :domain => 'domain.com')
+ #
# The option symbols for setting cookies are:
#
# * <tt>:value</tt> - The cookie's value or list of values (as an array).
diff --git a/actionpack/lib/action_controller/integration.rb b/actionpack/lib/action_controller/integration.rb
index 18c2df8b37..2a732448f2 100644
--- a/actionpack/lib/action_controller/integration.rb
+++ b/actionpack/lib/action_controller/integration.rb
@@ -101,7 +101,7 @@ module ActionController
@https = flag
end
- # Return +true+ if the session is mimicing a secure HTTPS request.
+ # Return +true+ if the session is mimicking a secure HTTPS request.
#
# if session.https?
# ...
diff --git a/actionpack/lib/action_controller/rack_process.rb b/actionpack/lib/action_controller/rack_process.rb
index 01bc1ebb26..7e0a6b091e 100644
--- a/actionpack/lib/action_controller/rack_process.rb
+++ b/actionpack/lib/action_controller/rack_process.rb
@@ -24,7 +24,7 @@ module ActionController #:nodoc:
super()
end
- %w[ AUTH_TYPE CONTENT_TYPE GATEWAY_INTERFACE PATH_INFO
+ %w[ AUTH_TYPE GATEWAY_INTERFACE PATH_INFO
PATH_TRANSLATED QUERY_STRING REMOTE_HOST
REMOTE_IDENT REMOTE_USER SCRIPT_NAME
SERVER_NAME SERVER_PROTOCOL
@@ -98,10 +98,6 @@ module ActionController #:nodoc:
@env['REMOTE_ADDR']
end
- def request_method
- @env['REQUEST_METHOD'].downcase.to_sym
- end
-
def server_port
@env['SERVER_PORT'].to_i
end
@@ -250,11 +246,11 @@ end_msg
headers['Content-Language'] = options.delete('language') if options['language']
headers['Expires'] = options.delete('expires') if options['expires']
- @status = options['Status'] || "200 OK"
+ @status = options.delete('Status') || "200 OK"
# Convert 'cookie' header to 'Set-Cookie' headers.
# Because Set-Cookie header can appear more the once in the response body,
- # we store it in a line break seperated string that will be translated to
+ # we store it in a line break separated string that will be translated to
# multiple Set-Cookie header by the handler.
if cookie = options.delete('cookie')
cookies = []
diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb
index 2d9f6c3e6f..c42f113d2c 100755
--- a/actionpack/lib/action_controller/request.rb
+++ b/actionpack/lib/action_controller/request.rb
@@ -61,7 +61,7 @@ module ActionController
request_method == :head
end
- # Provides acccess to the request's HTTP headers, for example:
+ # Provides access to the request's HTTP headers, for example:
# request.headers["Content-Type"] # => "text/plain"
def headers
@headers ||= ActionController::Http::Headers.new(@env)
@@ -265,7 +265,7 @@ EOM
parts[0..-(tld_length+2)]
end
- # Return the query string, accounting for server idiosyncracies.
+ # Return the query string, accounting for server idiosyncrasies.
def query_string
if uri = @env['REQUEST_URI']
uri.split('?', 2)[1] || ''
@@ -274,7 +274,7 @@ EOM
end
end
- # Return the request URI, accounting for server idiosyncracies.
+ # Return the request URI, accounting for server idiosyncrasies.
# WEBrick includes the full URL. IIS leaves REQUEST_URI blank.
def request_uri
if uri = @env['REQUEST_URI']
diff --git a/actionpack/lib/action_controller/request_forgery_protection.rb b/actionpack/lib/action_controller/request_forgery_protection.rb
index 02c9d59d07..05a6d8bb79 100644
--- a/actionpack/lib/action_controller/request_forgery_protection.rb
+++ b/actionpack/lib/action_controller/request_forgery_protection.rb
@@ -17,7 +17,7 @@ module ActionController #:nodoc:
# forged link from another site, is done by embedding a token based on the session (which an attacker wouldn't know) in all
# forms and Ajax requests generated by Rails and then verifying the authenticity of that token in the controller. Only
# HTML/JavaScript requests are checked, so this will not protect your XML API (presumably you'll have a different authentication
- # scheme there anyway). Also, GET requests are not protected as these should be indempotent anyway.
+ # scheme there anyway). Also, GET requests are not protected as these should be idempotent anyway.
#
# This is turned on with the <tt>protect_from_forgery</tt> method, which will check the token and raise an
# ActionController::InvalidAuthenticityToken if it doesn't match what was expected. You can customize the error message in
diff --git a/actionpack/lib/action_controller/rescue.rb b/actionpack/lib/action_controller/rescue.rb
index 163ed87fbb..482ac7d7a4 100644
--- a/actionpack/lib/action_controller/rescue.rb
+++ b/actionpack/lib/action_controller/rescue.rb
@@ -112,19 +112,23 @@ module ActionController #:nodoc:
protected
# Exception handler called when the performance of an action raises an exception.
def rescue_action(exception)
- log_error(exception) if logger
- erase_results if performed?
+ if handler_for_rescue(exception)
+ rescue_action_with_handler(exception)
+ else
+ log_error(exception) if logger
+ erase_results if performed?
- # Let the exception alter the response if it wants.
- # For example, MethodNotAllowed sets the Allow header.
- if exception.respond_to?(:handle_response!)
- exception.handle_response!(response)
- end
+ # Let the exception alter the response if it wants.
+ # For example, MethodNotAllowed sets the Allow header.
+ if exception.respond_to?(:handle_response!)
+ exception.handle_response!(response)
+ end
- if consider_all_requests_local || local_request?
- rescue_action_locally(exception)
- else
- rescue_action_in_public(exception)
+ if consider_all_requests_local || local_request?
+ rescue_action_locally(exception)
+ else
+ rescue_action_in_public(exception)
+ end
end
end
@@ -200,7 +204,7 @@ module ActionController #:nodoc:
def perform_action_with_rescue #:nodoc:
perform_action_without_rescue
rescue Exception => exception
- rescue_action_with_handler(exception) || rescue_action(exception)
+ rescue_action(exception)
end
def rescues_path(template_name)
diff --git a/actionpack/lib/action_controller/resources.rb b/actionpack/lib/action_controller/resources.rb
index af2fcaf3ad..b11aa5625b 100644
--- a/actionpack/lib/action_controller/resources.rb
+++ b/actionpack/lib/action_controller/resources.rb
@@ -296,6 +296,10 @@ module ActionController
# article_comments_url(:article_id => @article)
# article_comment_url(:article_id => @article, :id => @comment)
#
+ # If you don't want to load all objects from the database you might want to use the <tt>article_id</tt> directly:
+ #
+ # articles_comments_url(@comment.article_id, @comment)
+ #
# * <tt>:name_prefix</tt> - Define a prefix for all generated routes, usually ending in an underscore.
# Use this if you have named routes that may clash.
#
diff --git a/actionpack/lib/action_controller/streaming.rb b/actionpack/lib/action_controller/streaming.rb
index 186e0e5531..333fb61b45 100644
--- a/actionpack/lib/action_controller/streaming.rb
+++ b/actionpack/lib/action_controller/streaming.rb
@@ -12,19 +12,21 @@ module ActionController #:nodoc:
X_SENDFILE_HEADER = 'X-Sendfile'.freeze
protected
- # Sends the file by streaming it 4096 bytes at a time. This way the
- # whole file doesn't need to be read into memory at once. This makes
- # it feasible to send even large files.
+ # Sends the file, by default streaming it 4096 bytes at a time. This way the
+ # whole file doesn't need to be read into memory at once. This makes it
+ # feasible to send even large files. You can optionally turn off streaming
+ # and send the whole file at once.
#
- # Be careful to sanitize the path parameter if it coming from a web
+ # Be careful to sanitize the path parameter if it is coming from a web
# page. <tt>send_file(params[:path])</tt> allows a malicious user to
# download any file on your server.
#
# Options:
# * <tt>:filename</tt> - suggests a filename for the browser to use.
# Defaults to <tt>File.basename(path)</tt>.
- # * <tt>:type</tt> - specifies an HTTP content type.
- # Defaults to 'application/octet-stream'.
+ # * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'.
+ # * <tt>:length</tt> - used to manually override the length (in bytes) of the content that
+ # is going to be sent to the client. Defaults to <tt>File.size(path)</tt>.
# * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
# Valid values are 'inline' and 'attachment' (default).
# * <tt>:stream</tt> - whether to send the file to the user agent as it is read (+true+)
@@ -35,6 +37,12 @@ module ActionController #:nodoc:
# * <tt>:url_based_filename</tt> - set to +true+ if you want the browser guess the filename from
# the URL, which is necessary for i18n filenames on certain browsers
# (setting <tt>:filename</tt> overrides this option).
+ # * <tt>:x_sendfile</tt> - uses X-Sendfile to send the file when set to +true+. This is currently
+ # only available with Lighttpd/Apache2 and specific modules installed and activated. Since this
+ # uses the web server to send the file, this may lower memory consumption on your server and
+ # it will not block your application for further requests.
+ # See http://blog.lighttpd.net/articles/2006/07/02/x-sendfile and
+ # http://tn123.ath.cx/mod_xsendfile/ for details. Defaults to +false+.
#
# The default Content-Type and Content-Disposition headers are
# set to download arbitrary binary files in as many browsers as
@@ -99,8 +107,7 @@ module ActionController #:nodoc:
#
# Options:
# * <tt>:filename</tt> - suggests a filename for the browser to use.
- # * <tt>:type</tt> - specifies an HTTP content type.
- # Defaults to 'application/octet-stream'.
+ # * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'.
# * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
# Valid values are 'inline' and 'attachment' (default).
# * <tt>:status</tt> - specifies the status code to send with the response. Defaults to '200 OK'.
diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb
index 77c6f26eac..c09050c390 100644
--- a/actionpack/lib/action_controller/test_case.rb
+++ b/actionpack/lib/action_controller/test_case.rb
@@ -15,6 +15,27 @@ module ActionController
end
end
+ # Superclass for Action Controller functional tests. Infers the controller under test from the test class name,
+ # and creates @controller, @request, @response instance variables.
+ #
+ # class WidgetsControllerTest < ActionController::TestCase
+ # def test_index
+ # get :index
+ # end
+ # end
+ #
+ # * @controller - WidgetController.new
+ # * @request - ActionController::TestRequest.new
+ # * @response - ActionController::TestResponse.new
+ #
+ # (Earlier versions of Rails required each functional test to subclass Test::Unit::TestCase and define
+ # @controller, @request, @response in +setup+.)
+ #
+ # If the controller cannot be inferred from the test class name, you can explicity set it with +tests+.
+ #
+ # class SpecialEdgeCaseWidgetsControllerTest < ActionController::TestCase
+ # tests WidgetController
+ # end
class TestCase < ActiveSupport::TestCase
# When the request.remote_addr remains the default for testing, which is 0.0.0.0, the exception is simply raised inline
# (bystepping the regular exception handling from rescue_action). If the request.remote_addr is anything else, the regular
@@ -41,6 +62,8 @@ module ActionController
@@controller_class = nil
class << self
+ # Sets the controller class name. Useful if the name can't be inferred from test class.
+ # Expects +controller_class+ as a constant. Example: <tt>tests WidgetController</tt>.
def tests(controller_class)
self.controller_class = controller_class
end
diff --git a/actionpack/lib/action_controller/test_process.rb b/actionpack/lib/action_controller/test_process.rb
index a6e0c98936..721592b81f 100644
--- a/actionpack/lib/action_controller/test_process.rb
+++ b/actionpack/lib/action_controller/test_process.rb
@@ -171,7 +171,7 @@ module ActionController #:nodoc:
# Was the response successful?
def success?
- response_code == 200
+ (200..299).include?(response_code)
end
# Was the URL not found?
@@ -211,7 +211,7 @@ module ActionController #:nodoc:
template._first_render
end
- # A shortcut to the flash. Returns an empyt hash if no session flash exists.
+ # A shortcut to the flash. Returns an empty hash if no session flash exists.
def flash
session['flash'] || {}
end
diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb
index 1a3c770254..376bb87409 100644
--- a/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb
+++ b/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb
@@ -64,7 +64,7 @@ module HTML
#
# When using a combination of the above, the element name comes first
# followed by identifier, class names, attributes, pseudo classes and
- # negation in any order. Do not seprate these parts with spaces!
+ # negation in any order. Do not separate these parts with spaces!
# Space separation is used for descendant selectors.
#
# For example:
@@ -158,7 +158,7 @@ module HTML
# * <tt>:not(selector)</tt> -- Match the element only if the element does not
# match the simple selector.
#
- # As you can see, <tt>:nth-child<tt> pseudo class and its varient can get quite
+ # As you can see, <tt>:nth-child<tt> pseudo class and its variant can get quite
# tricky and the CSS specification doesn't do a much better job explaining it.
# But after reading the examples and trying a few combinations, it's easy to
# figure out.
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index 04e8d3a358..85af73390d 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -171,12 +171,13 @@ module ActionView #:nodoc:
delegate :erb_trim_mode=, :to => 'ActionView::TemplateHandlers::ERB'
end
- # Specify whether templates should be cached. Otherwise the file we be read everytime it is accessed.
- @@cache_template_loading = false
- cattr_accessor :cache_template_loading
+ def self.cache_template_loading=(*args)
+ ActiveSupport::Deprecation.warn("config.action_view.cache_template_loading option has been deprecated and has no affect. " <<
+ "Please remove it from your config files.", caller)
+ end
def self.cache_template_extensions=(*args)
- ActiveSupport::Deprecation.warn("config.action_view.cache_template_extensions option has been deprecated and has no affect. " <<
+ ActiveSupport::Deprecation.warn("config.action_view.cache_template_extensions option has been deprecated and has no effect. " <<
"Please remove it from your config files.", caller)
end
diff --git a/actionpack/lib/action_view/helpers/active_record_helper.rb b/actionpack/lib/action_view/helpers/active_record_helper.rb
index aa978a33bd..959d8a8563 100644
--- a/actionpack/lib/action_view/helpers/active_record_helper.rb
+++ b/actionpack/lib/action_view/helpers/active_record_helper.rb
@@ -141,7 +141,7 @@ module ActionView
#
# error_messages_for 'user_common', 'user', :object_name => 'user'
#
- # If the objects cannot be located as instance variables, you can add an extra <tt>:object</tt> paremeter which gives the actual
+ # If the objects cannot be located as instance variables, you can add an extra <tt>:object</tt> parameter which gives the actual
# object (or array of objects to use):
#
# error_messages_for 'user', :object => @question.user
diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
index bf13945844..ac71f83336 100644
--- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb
@@ -503,21 +503,24 @@ module ActionView
source = "#{@controller.request.relative_url_root}#{source}"
end
end
- source = rewrite_asset_path(source)
- if include_host
- host = compute_asset_host(source)
+ rewrite_asset_path(source)
+ end
+ end
- if has_request && !host.blank? && host !~ %r{^[-a-z]+://}
- host = "#{@controller.request.protocol}#{host}"
- end
+ source = ActionView::Base.computed_public_paths[cache_key]
- "#{host}#{source}"
- else
- source
- end
- end
+ if include_host && source !~ %r{^[-a-z]+://}
+ host = compute_asset_host(source)
+
+ if has_request && !host.blank? && host !~ %r{^[-a-z]+://}
+ host = "#{@controller.request.protocol}#{host}"
end
+
+ "#{host}#{source}"
+ else
+ source
+ end
end
# Pick an asset host for this source. Returns +nil+ if no host is set,
diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb
index 720e2da8cc..e86ca27f31 100644
--- a/actionpack/lib/action_view/helpers/capture_helper.rb
+++ b/actionpack/lib/action_view/helpers/capture_helper.rb
@@ -122,14 +122,15 @@ module ActionView
nil
end
- private
- def with_output_buffer(buf = '')
- self.output_buffer, old_buffer = buf, output_buffer
- yield
- output_buffer
- ensure
- self.output_buffer = old_buffer
- end
+ # Use an alternate output buffer for the duration of the block.
+ # Defaults to a new empty string.
+ def with_output_buffer(buf = '') #:nodoc:
+ self.output_buffer, old_buffer = buf, output_buffer
+ yield
+ output_buffer
+ ensure
+ self.output_buffer = old_buffer
+ end
end
end
end
diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb
index 1f213127d3..2cdb9a224e 100755
--- a/actionpack/lib/action_view/helpers/date_helper.rb
+++ b/actionpack/lib/action_view/helpers/date_helper.rb
@@ -285,11 +285,11 @@ module ActionView
#
# # Generates a date select that discards the type of the field and defaults to the date in
# # my_date (six days after today)
- # select_datetime(my_date_time, :discard_type => true)
+ # select_date(my_date, :discard_type => true)
#
# # Generates a date select that defaults to the datetime in my_date (six days after today)
# # prefixed with 'payday' rather than 'date'
- # select_datetime(my_date_time, :prefix => 'payday')
+ # select_date(my_date, :prefix => 'payday')
#
def select_date(date = Date.current, options = {}, html_options = {})
options[:order] ||= []
diff --git a/actionpack/lib/action_view/helpers/debug_helper.rb b/actionpack/lib/action_view/helpers/debug_helper.rb
index 20de7e465f..90863fca08 100644
--- a/actionpack/lib/action_view/helpers/debug_helper.rb
+++ b/actionpack/lib/action_view/helpers/debug_helper.rb
@@ -2,21 +2,28 @@ module ActionView
module Helpers
# Provides a set of methods for making it easier to debug Rails objects.
module DebugHelper
- # Returns a <pre>-tag that has +object+ dumped by YAML. This creates a very
- # readable way to inspect an object.
+ # Returns a YAML representation of +object+ wrapped with <pre> and </pre>.
+ # If the object cannot be converted to YAML using +to_yaml+, +inspect+ will be called instead.
+ # Useful for inspecting an object at the time of rendering.
#
# ==== Example
- # my_hash = {'first' => 1, 'second' => 'two', 'third' => [1,2,3]}
- # debug(my_hash)
#
- # => <pre class='debug_dump'>---
- # first: 1
- # second: two
- # third:
- # - 1
- # - 2
- # - 3
- # </pre>
+ # @user = User.new({ :username => 'testing', :password => 'xyz', :age => 42}) %>
+ # debug(@user)
+ # # =>
+ # <pre class='debug_dump'>--- !ruby/object:User
+ # attributes:
+ # &nbsp; updated_at:
+ # &nbsp; username: testing
+ #
+ # &nbsp; age: 42
+ # &nbsp; password: xyz
+ # &nbsp; created_at:
+ # attributes_cache: {}
+ #
+ # new_record: true
+ # </pre>
+
def debug(object)
begin
Marshal::dump(object)
@@ -28,4 +35,4 @@ module ActionView
end
end
end
-end \ No newline at end of file
+end
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index bafc635ad2..fa26aa4640 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -76,7 +76,7 @@ module ActionView
# Creates a form and a scope around a specific model object that is used as
# a base for questioning about values for the fields.
#
- # Rails provides succint resource-oriented form generation with +form_for+
+ # Rails provides succinct resource-oriented form generation with +form_for+
# like this:
#
# <% form_for @offer do |f| %>
@@ -449,8 +449,37 @@ module ActionView
# assigned to the template (identified by +object+). It's intended that +method+ returns an integer and if that
# integer is above zero, then the checkbox is checked. Additional options on the input tag can be passed as a
# hash with +options+. The +checked_value+ defaults to 1 while the default +unchecked_value+
- # is set to 0 which is convenient for boolean values. Since HTTP standards say that unchecked checkboxes don't post anything,
- # we add a hidden value with the same name as the checkbox as a work around.
+ # is set to 0 which is convenient for boolean values.
+ #
+ # ==== Gotcha
+ #
+ # The HTML specification says unchecked check boxes are not successful, and
+ # thus web browsers do not send them. Unfortunately this introduces a gotcha:
+ # if an Invoice model has a +paid+ flag, and in the form that edits a paid
+ # invoice the user unchecks its check box, no +paid+ parameter is sent. So,
+ # any mass-assignment idiom like
+ #
+ # @invoice.update_attributes(params[:invoice])
+ #
+ # wouldn't update the flag.
+ #
+ # To prevent this the helper generates a hidden field with the same name as
+ # the checkbox after the very check box. So, the client either sends only the
+ # hidden field (representing the check box is unchecked), or both fields.
+ # Since the HTML specification says key/value pairs have to be sent in the
+ # same order they appear in the form and Rails parameters extraction always
+ # gets the first occurrence of any given key, that works in ordinary forms.
+ #
+ # Unfortunately that workaround does not work when the check box goes
+ # within an array-like parameter, as in
+ #
+ # <% fields_for "project[invoice_attributes][]", invoice, :index => nil do |form| %>
+ # <%= form.check_box :paid %>
+ # ...
+ # <% end %>
+ #
+ # because parameter name repetition is precisely what Rails seeks to distinguish
+ # the elements of the array.
#
# ==== Examples
# # Let's say that @post.validated? is 1:
diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb
index 22bd5cb440..32089442b7 100644
--- a/actionpack/lib/action_view/helpers/javascript_helper.rb
+++ b/actionpack/lib/action_view/helpers/javascript_helper.rb
@@ -44,13 +44,22 @@ module ActionView
include PrototypeHelper
- # Returns a link that will trigger a JavaScript +function+ using the
+ # Returns a link of the given +name+ that will trigger a JavaScript +function+ using the
# onclick handler and return false after the fact.
#
+ # The first argument +name+ is used as the link text.
+ #
+ # The next arguments are optional and may include the javascript function definition and a hash of html_options.
+ #
# The +function+ argument can be omitted in favor of an +update_page+
# block, which evaluates to a string when the template is rendered
# (instead of making an Ajax request first).
#
+ # The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"
+ #
+ # Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil
+ #
+ #
# Examples:
# link_to_function "Greeting", "alert('Hello world!')"
# Produces:
@@ -89,13 +98,21 @@ module ActionView
content_tag(:a, name, html_options.merge(:href => href, :onclick => onclick))
end
- # Returns a button that'll trigger a JavaScript +function+ using the
+ # Returns a button with the given +name+ text that'll trigger a JavaScript +function+ using the
# onclick handler.
#
+ # The first argument +name+ is used as the button's value or display text.
+ #
+ # The next arguments are optional and may include the javascript function definition and a hash of html_options.
+ #
# The +function+ argument can be omitted in favor of an +update_page+
# block, which evaluates to a string when the template is rendered
# (instead of making an Ajax request first).
#
+ # The +html_options+ will accept a hash of html attributes for the link tag. Some examples are :class => "nav_button", :id => "articles_nav_button"
+ #
+ # Note: if you choose to specify the javascript function in a block, but would like to pass html_options, set the +function+ parameter to nil
+ #
# Examples:
# button_to_function "Greeting", "alert('Hello world!')"
# button_to_function "Delete", "if (confirm('Really?')) do_delete()"
diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb
index edb43844a4..cb4b53a9f7 100644
--- a/actionpack/lib/action_view/helpers/prototype_helper.rb
+++ b/actionpack/lib/action_view/helpers/prototype_helper.rb
@@ -61,7 +61,7 @@ module ActionView
#
# == Designing your Rails actions for Ajax
# When building your action handlers (that is, the Rails actions that receive your background requests), it's
- # important to remember a few things. First, whatever your action would normall return to the browser, it will
+ # important to remember a few things. First, whatever your action would normally return to the browser, it will
# return to the Ajax call. As such, you typically don't want to render with a layout. This call will cause
# the layout to be transmitted back to your page, and, if you have a full HTML/CSS, will likely mess a lot of things up.
# You can turn the layout off on particular actions by doing the following:
@@ -580,9 +580,10 @@ module ActionView
class JavaScriptGenerator #:nodoc:
def initialize(context, &block) #:nodoc:
@context, @lines = context, []
- @context.output_buffer = @lines if @context
include_helpers_from_context
- @context.instance_exec(self, &block)
+ @context.with_output_buffer(@lines) do
+ @context.instance_exec(self, &block)
+ end
end
private
diff --git a/actionpack/lib/action_view/helpers/sanitize_helper.rb b/actionpack/lib/action_view/helpers/sanitize_helper.rb
index b0dacfe964..c3c03394ee 100644
--- a/actionpack/lib/action_view/helpers/sanitize_helper.rb
+++ b/actionpack/lib/action_view/helpers/sanitize_helper.rb
@@ -184,7 +184,7 @@ module ActionView
HTML::WhiteListSanitizer.allowed_attributes.merge(attributes)
end
- # Adds to the Set of allowed CSS properties for the #sanitize and +sanitize_css+ heleprs.
+ # Adds to the Set of allowed CSS properties for the #sanitize and +sanitize_css+ helpers.
#
# Rails::Initializer.run do |config|
# config.action_view.sanitized_allowed_css_properties = 'expression'
diff --git a/actionpack/lib/action_view/helpers/scriptaculous_helper.rb b/actionpack/lib/action_view/helpers/scriptaculous_helper.rb
index c9b2761cb8..b938c1a801 100644
--- a/actionpack/lib/action_view/helpers/scriptaculous_helper.rb
+++ b/actionpack/lib/action_view/helpers/scriptaculous_helper.rb
@@ -193,7 +193,7 @@ module ActionView
#
# * <tt>:onDrop</tt> - Called when a +draggable_element+ is dropped onto
# this element. Override this callback with a JavaScript expression to
- # change the default drop behavour. Example:
+ # change the default drop behaviour. Example:
#
# :onDrop => "function(draggable_element, droppable_element, event) { alert('I like bananas') }"
#
diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb
index 5a296da247..de08672d2d 100644
--- a/actionpack/lib/action_view/helpers/tag_helper.rb
+++ b/actionpack/lib/action_view/helpers/tag_helper.rb
@@ -64,7 +64,7 @@ module ActionView
# <% content_tag :div, :class => "strong" do -%>
# Hello world!
# <% end -%>
- # # => <div class="strong"><p>Hello world!</p></div>
+ # # => <div class="strong">Hello world!</div>
def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)
if block_given?
options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb
index e5178938fd..94e1f1d33a 100644
--- a/actionpack/lib/action_view/helpers/url_helper.rb
+++ b/actionpack/lib/action_view/helpers/url_helper.rb
@@ -185,7 +185,7 @@ module ActionView
# link_to "Nonsense search", searches_path(:foo => "bar", :baz => "quux")
# # => <a href="/searches?foo=bar&amp;baz=quux">Nonsense search</a>
#
- # The three options specfic to +link_to+ (<tt>:confirm</tt>, <tt>:popup</tt>, and <tt>:method</tt>) are used as follows:
+ # The three options specific to +link_to+ (<tt>:confirm</tt>, <tt>:popup</tt>, and <tt>:method</tt>) are used as follows:
#
# link_to "Visit Other Site", "http://www.rubyonrails.org/", :confirm => "Are you sure?"
# # => <a href="http://www.rubyonrails.org/" onclick="return confirm('Are you sure?');">Visit Other Site</a>
diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb
index b0ab7d0c67..c7a5df762f 100644
--- a/actionpack/lib/action_view/paths.rb
+++ b/actionpack/lib/action_view/paths.rb
@@ -16,6 +16,14 @@ module ActionView #:nodoc:
end
class Path #:nodoc:
+ def self.eager_load_templates!
+ @eager_load_templates = true
+ end
+
+ def self.eager_load_templates?
+ @eager_load_templates || false
+ end
+
attr_reader :path, :paths
delegate :to_s, :to_str, :inspect, :to => :path
@@ -37,6 +45,9 @@ module ActionView #:nodoc:
@paths = {}
templates_in_path do |template|
+ # Eager load memoized methods and freeze cached template
+ template.freeze if self.class.eager_load_templates?
+
@paths[template.path] = template
@paths[template.path_without_extension] ||= template
end
@@ -48,10 +59,7 @@ module ActionView #:nodoc:
def templates_in_path
(Dir.glob("#{@path}/**/*/**") | Dir.glob("#{@path}/**")).each do |file|
unless File.directory?(file)
- template = Template.new(file.split("#{self}/").last, self)
- # Eager load memoized methods and freeze cached template
- template.freeze if Base.cache_template_loading
- yield template
+ yield Template.new(file.split("#{self}/").last, self)
end
end
end
diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb
index f66356c939..46193670f3 100644
--- a/actionpack/lib/action_view/renderable.rb
+++ b/actionpack/lib/action_view/renderable.rb
@@ -9,6 +9,10 @@ module ActionView
include ActiveSupport::Memoizable
+ def filename
+ 'compiled-template'
+ end
+
def handler
Template.handler_class_for_extension(extension)
end
@@ -35,35 +39,41 @@ module ActionView
end
private
- # Compile and evaluate the template's code
+ # Compile and evaluate the template's code (if necessary)
def compile(local_assigns)
render_symbol = method(local_assigns)
@@mutex.synchronize do
- return false unless recompile?(render_symbol)
+ if recompile?(render_symbol)
+ compile!(render_symbol, local_assigns)
+ end
+ end
+ end
- locals_code = local_assigns.keys.map { |key| "#{key} = local_assigns[:#{key}];" }.join
+ def compile!(render_symbol, local_assigns)
+ locals_code = local_assigns.keys.map { |key| "#{key} = local_assigns[:#{key}];" }.join
- source = <<-end_src
- def #{render_symbol}(local_assigns)
- old_output_buffer = output_buffer;#{locals_code};#{compiled_source}
- ensure
- self.output_buffer = old_output_buffer
- end
- end_src
+ source = <<-end_src
+ def #{render_symbol}(local_assigns)
+ old_output_buffer = output_buffer;#{locals_code};#{compiled_source}
+ ensure
+ self.output_buffer = old_output_buffer
+ end
+ end_src
- begin
- file_name = respond_to?(:filename) ? filename : 'compiled-template'
- ActionView::Base::CompiledTemplates.module_eval(source, file_name, 0)
- rescue Exception => e # errors from template code
- if logger = ActionController::Base.logger
- logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}"
- logger.debug "Function body: #{source}"
- logger.debug "Backtrace: #{e.backtrace.join("\n")}"
- end
+ begin
+ logger = ActionController::Base.logger
+ logger.debug "Compiling template #{render_symbol}" if logger
- raise ActionView::TemplateError.new(self, {}, e)
+ ActionView::Base::CompiledTemplates.module_eval(source, filename, 0)
+ rescue Exception => e # errors from template code
+ if logger
+ logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}"
+ logger.debug "Function body: #{source}"
+ logger.debug "Backtrace: #{e.backtrace.join("\n")}"
end
+
+ raise ActionView::TemplateError.new(self, {}, e)
end
end
@@ -71,8 +81,7 @@ module ActionView
# The template will be compiled if the file has not been compiled yet, or
# if local_assigns has a new key, which isn't supported by the compiled code yet.
def recompile?(symbol)
- meth = Base::CompiledTemplates.instance_method(template.method) rescue nil
- !(meth && Base.cache_template_loading)
+ !(frozen? && Base::CompiledTemplates.method_defined?(symbol))
end
end
end