diff options
Diffstat (limited to 'actionpack/lib')
24 files changed, 306 insertions, 102 deletions
diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index a82e3dc90a..6f13ebe0d0 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -89,7 +89,7 @@ module AbstractController # class TillController < BankController # layout false # - # In these examples, we have three implicit lookup scenrios: + # In these examples, we have three implicit lookup scenarios: # * The BankController uses the "bank" layout. # * The ExchangeController uses the "exchange" layout. # * The CurrencyController inherits the layout from BankController. @@ -120,6 +120,7 @@ module AbstractController # def writers_and_readers # logged_in? ? "writer_layout" : "reader_layout" # end + # end # # Now when a new request for the index action is processed, the layout will vary depending on whether the person accessing # is logged in or not. @@ -127,7 +128,14 @@ module AbstractController # If you want to use an inline method, such as a proc, do something like this: # # class WeblogController < ActionController::Base - # layout proc{ |controller| controller.logged_in? ? "writer_layout" : "reader_layout" } + # layout proc { |controller| controller.logged_in? ? "writer_layout" : "reader_layout" } + # end + # + # If an argument isn't given to the proc, it's evaluated in the context of + # the current controller anyway. + # + # class WeblogController < ActionController::Base + # layout proc { logged_in? ? "writer_layout" : "reader_layout" } # end # # Of course, the most common way of specifying a layout is still just as a plain template name: @@ -298,12 +306,12 @@ module AbstractController end RUBY when Proc - define_method :_layout_from_proc, &_layout - "_layout_from_proc(self)" + define_method :_layout_from_proc, &_layout + _layout.arity == 0 ? "_layout_from_proc" : "_layout_from_proc(self)" when false nil when true - raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil" + raise ArgumentError, "Layouts must be specified as a String, Symbol, Proc, false, or nil" when nil name_clause end @@ -363,7 +371,7 @@ module AbstractController when false, nil then nil else raise ArgumentError, - "String, true, or false, expected for `layout'; you passed #{name.inspect}" + "String, Proc, :default, true, or false, expected for `layout'; you passed #{name.inspect}" end end diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index ddc93464cd..7d73c6af8d 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -105,6 +105,7 @@ module AbstractController # Find and renders a template based on the options given. # :api: private def _render_template(options) #:nodoc: + lookup_context.rendered_format = nil if options[:formats] view_renderer.render(view_context, options) end diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 6ce78f34b5..71425cd542 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -171,7 +171,7 @@ module ActionController class Base < Metal abstract! - # Shortcut helper that returns all the ActionController modules except the ones passed in the argument: + # Shortcut helper that returns all the ActionController::Base modules except the ones passed in the argument: # # class MetalController # ActionController::Base.without_modules(:ParamsWrapper, :Streaming).each do |left| diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb index ba96735e56..ceac11bbfb 100644 --- a/actionpack/lib/action_controller/caching/actions.rb +++ b/actionpack/lib/action_controller/caching/actions.rb @@ -170,14 +170,14 @@ module ActionController #:nodoc: options.reverse_merge!(:format => @extension) if options.is_a?(Hash) end - path = controller.url_for(options).split(%r{://}).last + path = controller.url_for(options).split('://', 2).last @path = normalize!(path) end private def normalize!(path) path << 'index' if path[-1] == ?/ - path << ".#{extension}" if extension and !path.split('?').first.ends_with?(".#{extension}") + path << ".#{extension}" if extension and !path.split('?', 2).first.ends_with?(".#{extension}") URI.parser.unescape(path) end end diff --git a/actionpack/lib/action_controller/caching/sweeping.rb b/actionpack/lib/action_controller/caching/sweeping.rb index 49cf70ec21..bb176ca3f9 100644 --- a/actionpack/lib/action_controller/caching/sweeping.rb +++ b/actionpack/lib/action_controller/caching/sweeping.rb @@ -54,6 +54,11 @@ module ActionController #:nodoc: class Sweeper < ActiveRecord::Observer #:nodoc: attr_accessor :controller + def initialize(*args) + super + @controller = nil + end + def before(controller) self.controller = controller callback(:before) if controller.perform_caching @@ -88,7 +93,7 @@ module ActionController #:nodoc: end def method_missing(method, *arguments, &block) - return unless @controller + super unless @controller @controller.__send__(method, *arguments, &block) end end diff --git a/actionpack/lib/action_controller/metal/force_ssl.rb b/actionpack/lib/action_controller/metal/force_ssl.rb index a1e40fc4e0..ac12cbb625 100644 --- a/actionpack/lib/action_controller/metal/force_ssl.rb +++ b/actionpack/lib/action_controller/metal/force_ssl.rb @@ -44,7 +44,7 @@ module ActionController redirect_options = {:protocol => 'https://', :status => :moved_permanently} redirect_options.merge!(:host => host) if host redirect_options.merge!(:params => request.query_parameters) - flash.keep + flash.keep if respond_to?(:flash) redirect_to redirect_options end end diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb index d070eaae5d..1a4bca12d2 100644 --- a/actionpack/lib/action_controller/metal/helpers.rb +++ b/actionpack/lib/action_controller/metal/helpers.rb @@ -52,6 +52,7 @@ module ActionController module Helpers extend ActiveSupport::Concern + class << self; attr_accessor :helpers_path; end include AbstractController::Helpers included do diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb index 73e044a092..fbb5d01e86 100644 --- a/actionpack/lib/action_controller/metal/mime_responds.rb +++ b/actionpack/lib/action_controller/metal/mime_responds.rb @@ -195,20 +195,106 @@ module ActionController #:nodoc: end end - # respond_with wraps a resource around a responder for default representation. - # First it invokes respond_to, if a response cannot be found (ie. no block - # for the request was given and template was not available), it instantiates - # an ActionController::Responder with the controller and resource. + # For a given controller action, respond_with generates an appropriate + # response based on the mime-type requested by the client. # - # ==== Example + # If the method is called with just a resource, as in this example - # - # def index - # @users = User.all - # respond_with(@users) + # class PeopleController < ApplicationController + # respond_to :html, :xml, :json + # + # def index + # @people = Person.all + # respond_with @people + # end # end # - # It also accepts a block to be given. It's used to overwrite a default - # response: + # then the mime-type of the response is typically selected based on the + # request's Accept header and the set of available formats declared + # by previous calls to the controller's class method +respond_to+. Alternatively + # the mime-type can be selected by explicitly setting <tt>request.format</tt> in + # the controller. + # + # If an acceptable format is not identified, the application returns a + # '406 - not acceptable' status. Otherwise, the default response is to render + # a template named after the current action and the selected format, + # e.g. <tt>index.html.erb</tt>. If no template is available, the behavior + # depends on the selected format: + # + # * for an html response - if the request method is +get+, an exception + # is raised but for other requests such as +post+ the response + # depends on whether the resource has any validation errors (i.e. + # assuming that an attempt has been made to save the resource, + # e.g. by a +create+ action) - + # 1. If there are no errors, i.e. the resource + # was saved successfully, the response +redirect+'s to the resource + # i.e. its +show+ action. + # 2. If there are validation errors, the response + # renders a default action, which is <tt>:new</tt> for a + # +post+ request or <tt>:edit</tt> for +put+. + # Thus an example like this - + # + # respond_to :html, :xml + # + # def create + # @user = User.new(params[:user]) + # flash[:notice] = 'User was successfully created.' if @user.save + # respond_with(@user) + # end + # + # is equivalent, in the absence of <tt>create.html.erb</tt>, to - + # + # def create + # @user = User.new(params[:user]) + # respond_to do |format| + # if @user.save + # flash[:notice] = 'User was successfully created.' + # format.html { redirect_to(@user) } + # format.xml { render :xml => @user } + # else + # format.html { render :action => "new" } + # format.xml { render :xml => @user } + # end + # end + # end + # + # * for a javascript request - if the template isn't found, an exception is + # raised. + # * for other requests - i.e. data formats such as xml, json, csv etc, if + # the resource passed to +respond_with+ responds to <code>to_<format></code>, + # the method attempts to render the resource in the requested format + # directly, e.g. for an xml request, the response is equivalent to calling + # <code>render :xml => resource</code>. + # + # === Nested resources + # + # As outlined above, the +resources+ argument passed to +respond_with+ + # can play two roles. It can be used to generate the redirect url + # for successful html requests (e.g. for +create+ actions when + # no template exists), while for formats other than html and javascript + # it is the object that gets rendered, by being converted directly to the + # required format (again assuming no template exists). + # + # For redirecting successful html requests, +respond_with+ also supports + # the use of nested resources, which are supplied in the same way as + # in <code>form_for</code> and <code>polymorphic_url</code>. For example - + # + # def create + # @project = Project.find(params[:project_id]) + # @task = @project.comments.build(params[:task]) + # flash[:notice] = 'Task was successfully created.' if @task.save + # respond_with(@project, @task) + # end + # + # This would cause +respond_with+ to redirect to <code>project_task_url</code> + # instead of <code>task_url</code>. For request formats other than html or + # javascript, if multiple resources are passed in this way, it is the last + # one specified that is rendered. + # + # === Customizing response behavior + # + # Like +respond_to+, +respond_with+ may also be called with a block that + # can be used to overwrite any of the default responses, e.g. - # # def create # @user = User.new(params[:user]) @@ -219,13 +305,24 @@ module ActionController #:nodoc: # end # end # - # All options given to respond_with are sent to the underlying responder, - # except for the option :responder itself. Since the responder interface - # is quite simple (it just needs to respond to call), you can even give - # a proc to it. - # - # In order to use respond_with, first you need to declare the formats your - # controller responds to in the class level with a call to <tt>respond_to</tt>. + # The argument passed to the block is an ActionController::MimeResponds::Collector + # object which stores the responses for the formats defined within the + # block. Note that formats with responses defined explicitly in this way + # do not have to first be declared using the class method +respond_to+. + # + # Also, a hash passed to +respond_with+ immediately after the specified + # resource(s) is interpreted as a set of options relevant to all + # formats. Any option accepted by +render+ can be used, e.g. + # respond_with @people, :status => 200 + # However, note that these options are ignored after an unsuccessful attempt + # to save a resource, e.g. when automatically rendering <tt>:new</tt> + # after a post request. + # + # Two additional options are relevant specifically to +respond_with+ - + # 1. <tt>:location</tt> - overwrites the default redirect location used after + # a successful html +post+ request. + # 2. <tt>:action</tt> - overwrites the default render action used after an + # unsuccessful html +post+ request. # def respond_with(*resources, &block) raise "In order to use respond_with, first you need to declare the formats your " << @@ -283,8 +380,8 @@ module ActionController #:nodoc: end end - # A container of responses available for requests with different mime-types - # sent to the current controller action. + # A container for responses available from the current controller for + # requests for different mime-types sent to a particular action. # # The public controller methods +respond_with+ and +respond_to+ may be called # with a block that is used to define responses to different mime-types, e.g. diff --git a/actionpack/lib/action_controller/metal/redirecting.rb b/actionpack/lib/action_controller/metal/redirecting.rb index b07742e0e1..3ffb7ef426 100644 --- a/actionpack/lib/action_controller/metal/redirecting.rb +++ b/actionpack/lib/action_controller/metal/redirecting.rb @@ -93,7 +93,7 @@ module ActionController _compute_redirect_to_location options.call else url_for(options) - end.gsub(/[\r\n]/, '') + end.gsub(/[\0\r\n]/, '') end end end diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 3e170d7872..851a2c4aee 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -3,33 +3,32 @@ require "action_controller" require "action_dispatch/railtie" require "action_view/railtie" require "abstract_controller/railties/routes_helpers" -require "action_controller/railties/paths" +require "action_controller/railties/helpers" module ActionController class Railtie < Rails::Railtie #:nodoc: config.action_controller = ActiveSupport::OrderedOptions.new - initializer "action_controller.logger" do - ActiveSupport.on_load(:action_controller) { self.logger ||= Rails.logger } - end - - initializer "action_controller.initialize_framework_caches" do - ActiveSupport.on_load(:action_controller) { self.cache_store ||= Rails.cache } - end - initializer "action_controller.assets_config", :group => :all do |app| app.config.action_controller.assets_dir ||= app.config.paths["public"].first end + initializer "action_controller.set_helpers_path" do |app| + ActionController::Helpers.helpers_path = app.helpers_paths + end + initializer "action_controller.set_configs" do |app| paths = app.config.paths options = app.config.action_controller + options.logger ||= Rails.logger + options.cache_store ||= Rails.cache + options.javascripts_dir ||= paths["public/javascripts"].first options.stylesheets_dir ||= paths["public/stylesheets"].first options.page_cache_directory ||= paths["public"].first - # make sure readers methods get compiled + # Ensure readers methods get compiled options.asset_path ||= app.config.asset_path options.asset_host ||= app.config.asset_host options.relative_url_root ||= app.config.relative_url_root @@ -37,8 +36,16 @@ module ActionController ActiveSupport.on_load(:action_controller) do include app.routes.mounted_helpers extend ::AbstractController::Railties::RoutesHelpers.with(app.routes) - extend ::ActionController::Railties::Paths.with(app) - options.each { |k,v| send("#{k}=", v) } + extend ::ActionController::Railties::Helpers + + options.each do |k,v| + k = "#{k}=" + if respond_to?(k) + send(k, v) + elsif !Base.respond_to?(k) + raise "Invalid option key: #{k}" + end + end end end diff --git a/actionpack/lib/action_controller/railties/helpers.rb b/actionpack/lib/action_controller/railties/helpers.rb new file mode 100644 index 0000000000..3985c6b273 --- /dev/null +++ b/actionpack/lib/action_controller/railties/helpers.rb @@ -0,0 +1,22 @@ +module ActionController + module Railties + module Helpers + def inherited(klass) + super + return unless klass.respond_to?(:helpers_path=) + + if namespace = klass.parents.detect { |m| m.respond_to?(:railtie_helpers_paths) } + paths = namespace.railtie_helpers_paths + else + paths = ActionController::Helpers.helpers_path + end + + klass.helpers_path = paths + + if klass.superclass == ActionController::Base && ActionController::Base.include_all_helpers + klass.helper :all + end + end + end + end +end diff --git a/actionpack/lib/action_controller/railties/paths.rb b/actionpack/lib/action_controller/railties/paths.rb deleted file mode 100644 index bbe63149ad..0000000000 --- a/actionpack/lib/action_controller/railties/paths.rb +++ /dev/null @@ -1,25 +0,0 @@ -module ActionController - module Railties - module Paths - def self.with(app) - Module.new do - define_method(:inherited) do |klass| - super(klass) - - if namespace = klass.parents.detect { |m| m.respond_to?(:railtie_helpers_paths) } - paths = namespace.railtie_helpers_paths - else - paths = app.helpers_paths - end - - klass.helpers_path = paths - - if klass.superclass == ActionController::Base && ActionController::Base.include_all_helpers - klass.helper :all - end - end - end - end - end - end -end diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 7af30ed690..9bd2e622ad 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -479,7 +479,6 @@ module ActionController @request.session["flash"].sweep @controller.request = @request - @controller.params.merge!(parameters) build_request_uri(action, parameters) @controller.class.class_eval { include Testing } @controller.recycle! @@ -505,11 +504,6 @@ module ActionController end end - # Cause the action to be rescued according to the regular rules for rescue_action when the visitor is not local - def rescue_action_in_public! - @request.remote_addr = '208.77.188.166' # example.com - end - included do include ActionController::TemplateAssertions include ActionDispatch::Assertions diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index a9542a7d1b..e3b04ac097 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -61,6 +61,7 @@ module ActionDispatch autoload :Reloader autoload :RemoteIp autoload :ShowExceptions + autoload :SSL autoload :Static end diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index 84732085f0..078229efd2 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -51,12 +51,13 @@ module ActionDispatch # :nodoc: # If a character set has been defined for this response (see charset=) then # the character set information will also be included in the content type # information. - attr_accessor :charset, :content_type + attr_accessor :charset + attr_reader :content_type CONTENT_TYPE = "Content-Type".freeze SET_COOKIE = "Set-Cookie".freeze LOCATION = "Location".freeze - + cattr_accessor(:default_charset) { "utf-8" } include Rack::Response::Helpers @@ -83,6 +84,10 @@ module ActionDispatch # :nodoc: @status = Rack::Utils.status_code(status) end + def content_type=(content_type) + @content_type = content_type.to_s + end + # The response code of the request def response_code @status diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index 836136eb95..ab740a0190 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -9,7 +9,7 @@ module ActionDispatch # of ShowExceptions. Everytime there is an exception, ShowExceptions will # store the exception in env["action_dispatch.exception"], rewrite the # PATH_INFO to the exception status code and call the rack app. - # + # # If the application returns a "X-Cascade" pass response, this middleware # will send an empty response as result with the correct status code. # If any exception happens inside the exceptions app, this middleware diff --git a/actionpack/lib/action_dispatch/middleware/ssl.rb b/actionpack/lib/action_dispatch/middleware/ssl.rb new file mode 100644 index 0000000000..9098f4e170 --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/ssl.rb @@ -0,0 +1,70 @@ +module ActionDispatch + class SSL + YEAR = 31536000 + + def self.default_hsts_options + { :expires => YEAR, :subdomains => false } + end + + def initialize(app, options = {}) + @app = app + + @hsts = options.fetch(:hsts, {}) + @hsts = {} if @hsts == true + @hsts = self.class.default_hsts_options.merge(@hsts) if @hsts + + @host = options[:host] + @port = options[:port] + end + + def call(env) + request = Request.new(env) + + if request.ssl? + status, headers, body = @app.call(env) + headers = hsts_headers.merge(headers) + flag_cookies_as_secure!(headers) + [status, headers, body] + else + redirect_to_https(request) + end + end + + private + def redirect_to_https(request) + url = URI(request.url) + url.scheme = "https" + url.host = @host if @host + url.port = @port if @port + headers = hsts_headers.merge('Content-Type' => 'text/html', + 'Location' => url.to_s) + + [301, headers, []] + end + + # http://tools.ietf.org/html/draft-hodges-strict-transport-sec-02 + def hsts_headers + if @hsts + value = "max-age=#{@hsts[:expires]}" + value += "; includeSubDomains" if @hsts[:subdomains] + { 'Strict-Transport-Security' => value } + else + {} + end + end + + def flag_cookies_as_secure!(headers) + if cookies = headers['Set-Cookie'] + cookies = cookies.split("\n") + + headers['Set-Cookie'] = cookies.map { |cookie| + if cookie !~ /;\s+secure(;|$)/ + "#{cookie}; secure" + else + cookie + end + }.join("\n") + end + end + end +end diff --git a/actionpack/lib/action_dispatch/middleware/static.rb b/actionpack/lib/action_dispatch/middleware/static.rb index 63b7422287..9073e6582d 100644 --- a/actionpack/lib/action_dispatch/middleware/static.rb +++ b/actionpack/lib/action_dispatch/middleware/static.rb @@ -39,6 +39,7 @@ module ActionDispatch end def escape_glob_chars(path) + path.force_encoding('binary') if path.respond_to? :force_encoding path.gsub(/[*?{}\[\]]/, "\\\\\\&") end end diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index cd215034dc..20cdf67cf0 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -1,6 +1,6 @@ require 'active_support/core_ext/hash/except' require 'active_support/core_ext/object/blank' -require 'active_support/core_ext/object/inclusion' +require 'active_support/core_ext/enumerable' require 'active_support/inflector' require 'action_dispatch/routing/redirection' @@ -880,17 +880,18 @@ module ActionDispatch # CANONICAL_ACTIONS holds all actions that does not need a prefix or # a path appended since they fit properly in their scope level. VALID_ON_OPTIONS = [:new, :collection, :member] - RESOURCE_OPTIONS = [:as, :controller, :path, :only, :except] + RESOURCE_OPTIONS = [:as, :controller, :path, :only, :except, :param] CANONICAL_ACTIONS = %w(index create new show update destroy) class Resource #:nodoc: - attr_reader :controller, :path, :options + attr_reader :controller, :path, :options, :param def initialize(entities, options = {}) @name = entities.to_s @path = (options[:path] || @name).to_s @controller = (options[:controller] || @name).to_s @as = options[:as] + @param = options[:param] || :id @options = options end @@ -935,7 +936,7 @@ module ActionDispatch alias :collection_scope :path def member_scope - "#{path}/:id" + "#{path}/:#{param}" end def new_scope(new_path) @@ -943,7 +944,7 @@ module ActionDispatch end def nested_scope - "#{path}/:#{singular}_id" + "#{path}/:#{singular}_#{param}" end end diff --git a/actionpack/lib/action_dispatch/testing/assertions/response.rb b/actionpack/lib/action_dispatch/testing/assertions/response.rb index 094cfbfc76..a5e7a8c715 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/response.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/response.rb @@ -83,7 +83,7 @@ module ActionDispatch refer else @controller.url_for(fragment) - end.gsub(/[\r\n]/, '') + end.gsub(/[\0\r\n]/, '') end end end diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index 2d37923825..2bfc6371f5 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -625,13 +625,18 @@ module ActionView # time_tag Date.today, :pubdate => true # => # <time datetime="2010-11-04" pubdate="pubdate">November 04, 2010</time> # - def time_tag(date_or_time, *args) + # <%= time_tag Time.now do %> + # <span>Right now</span> + # <% end %> + # # => <time datetime="2010-11-04T17:55:45+01:00"><span>Right now</span></time> + # + def time_tag(date_or_time, *args, &block) options = args.extract_options! format = options.delete(:format) || :long content = args.first || I18n.l(date_or_time, :format => format) datetime = date_or_time.acts_like?(:time) ? date_or_time.xmlschema : date_or_time.rfc3339 - content_tag(:time, content, options.reverse_merge(:datetime => datetime)) + content_tag(:time, content, options.reverse_merge(:datetime => datetime), &block) end end @@ -669,11 +674,7 @@ module ActionView @options[:discard_minute] ||= true if @options[:discard_hour] @options[:discard_second] ||= true unless @options[:include_seconds] && !@options[:discard_minute] - # If the day is hidden and the month is visible, the day should be set to the 1st so all month choices are - # valid (otherwise it could be 31 and February wouldn't be a valid date) - if @datetime && @options[:discard_day] && !@options[:discard_month] - @datetime = @datetime.change(:day => 1) - end + set_day_if_discarded if @options[:tag] && @options[:ignore_date] select_time @@ -696,11 +697,7 @@ module ActionView @options[:discard_month] ||= true unless order.include?(:month) @options[:discard_day] ||= true if @options[:discard_month] || !order.include?(:day) - # If the day is hidden and the month is visible, the day should be set to the 1st so all month choices are - # valid (otherwise it could be 31 and February wouldn't be a valid date) - if @datetime && @options[:discard_day] && !@options[:discard_month] - @datetime = @datetime.change(:day => 1) - end + set_day_if_discarded [:day, :month, :year].each { |o| order.unshift(o) unless order.include?(o) } @@ -802,6 +799,14 @@ module ActionView end end + # If the day is hidden, the day should be set to the 1st so all month and year choices are + # valid. Otherwise, February 31st or February 29th, 2011 can be selected, which are invalid. + def set_day_if_discarded + if @datetime && @options[:discard_day] + @datetime = @datetime.change(:day => 1) + end + end + # Returns translated month names, but also ensures that a custom month # name array has a leading nil element. def month_names diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index 9fad30a48f..41d895c15e 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -27,7 +27,9 @@ module ActionView # is added to simulate the verb over post. # * <tt>:authenticity_token</tt> - Authenticity token to use in the form. Use only if you need to # pass custom authenticity token string, or to not add authenticity_token field at all - # (by passing <tt>false</tt>). + # (by passing <tt>false</tt>). If this is a remote form, the authenticity_token will by default + # not be included as the ajax handler will get it from the meta-tag (but you can force it to be + # rendered anyway in that case by passing <tt>true</tt>). # * A list of parameters to feed to the URL the form will be posted to. # * <tt>:remote</tt> - If set to true, will allow the Unobtrusive JavaScript drivers to control the # submit behavior. By default this behavior is an ajax submit. @@ -616,8 +618,17 @@ module ActionView # responsibility of the caller to escape all the values. html_options["action"] = url_for(url_for_options) html_options["accept-charset"] = "UTF-8" + html_options["data-remote"] = true if html_options.delete("remote") - html_options["authenticity_token"] = html_options.delete("authenticity_token") if html_options.has_key?("authenticity_token") + + if html_options["data-remote"] && html_options["authenticity_token"] == true + # Include the default authenticity_token, which is only generated when its set to nil, + # but we needed the true value to override the default of no authenticity_token on data-remote. + html_options["authenticity_token"] = nil + elsif html_options["data-remote"] + # The authenticity token is taken from the meta tag in this case + html_options["authenticity_token"] = false + end end end diff --git a/actionpack/lib/action_view/renderer/partial_renderer.rb b/actionpack/lib/action_view/renderer/partial_renderer.rb index 245a19deec..232667ec01 100644 --- a/actionpack/lib/action_view/renderer/partial_renderer.rb +++ b/actionpack/lib/action_view/renderer/partial_renderer.rb @@ -32,7 +32,7 @@ module ActionView # # <%= render :partial => "account", :object => @buyer %> # - # would provide the +@buyer+ object to the partial, available under the local variable +account+ and is + # would provide the <tt>@buyer</tt> object to the partial, available under the local variable +account+ and is # equivalent to: # # <%= render :partial => "account", :locals => { :account => @buyer } %> diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 7fa86866a7..8ea2e5bfe4 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -176,7 +176,7 @@ module ActionView end end - # A resolver that loads files from the filesystem. It allows to set your own + # A resolver that loads files from the filesystem. It allows setting your own # resolving pattern. Such pattern can be a glob string supported by some variables. # # ==== Examples @@ -192,7 +192,7 @@ module ActionView # # FileSystemResolver.new("/path/to/views", ":prefix/{:formats/,}:action{.:locale,}{.:formats,}{.:handlers,}") # - # If you don't specify pattern then the default will be used. + # If you don't specify a pattern then the default will be used. # # In order to use any of the customized resolvers above in a Rails application, you just need # to configure ActionController::Base.view_paths in an initializer, for example: @@ -204,10 +204,10 @@ module ActionView # # ==== Pattern format and variables # - # Pattern have to be a valid glob string, and it allows you to use the + # Pattern has to be a valid glob string, and it allows you to use the # following variables: # - # * <tt>:prefix</tt> - usualy the controller path + # * <tt>:prefix</tt> - usually the controller path # * <tt>:action</tt> - name of the action # * <tt>:locale</tt> - possible locale versions # * <tt>:formats</tt> - possible request formats (for example html, json, xml...) |