diff options
author | Mark Thomson <nzl216@gmail.com> | 2012-03-17 22:29:46 -0500 |
---|---|---|
committer | Mark Thomson <nzl216@gmail.com> | 2012-03-17 22:29:46 -0500 |
commit | f2bc404ba82431d32a35b4de15cb21f179bc24c7 (patch) | |
tree | ca58ce1118eeda244ced0ef0a1d94ed7ca38e5e0 /actionpack/lib | |
parent | 98b4ef730696062b624c508d22ca76d9caa018cc (diff) | |
parent | 6ce54d4ba8c220a84e55e7dd798d364c3f48d9f7 (diff) | |
download | rails-f2bc404ba82431d32a35b4de15cb21f179bc24c7.tar.gz rails-f2bc404ba82431d32a35b4de15cb21f179bc24c7.tar.bz2 rails-f2bc404ba82431d32a35b4de15cb21f179bc24c7.zip |
Merge remote-tracking branch 'origin/master'
Diffstat (limited to 'actionpack/lib')
37 files changed, 163 insertions, 637 deletions
diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index 43cea3b79e..b068846a13 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -1,4 +1,5 @@ require 'erubis' +require 'set' require 'active_support/configurable' require 'active_support/descendants_tracker' require 'active_support/core_ext/module/anonymous' @@ -59,7 +60,7 @@ module AbstractController # itself. Finally, #hidden_actions are removed. # # ==== Returns - # * <tt>array</tt> - A list of all methods that should be considered actions. + # * <tt>set</tt> - A set of all methods that should be considered actions. def action_methods @action_methods ||= begin # All public instance methods of this class, including ancestors @@ -72,7 +73,7 @@ module AbstractController hidden_actions.to_a # Clear out AS callback method pollution - methods.reject { |method| method =~ /_one_time_conditions/ } + Set.new(methods.reject { |method| method =~ /_one_time_conditions/ }) end end 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 95de595f4f..71425cd542 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -171,11 +171,11 @@ 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 |module| - # include module + # ActionController::Base.without_modules(:ParamsWrapper, :Streaming).each do |left| + # include left # 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 1e3c2d83cf..7ff5d48c5a 100644 --- a/actionpack/lib/action_controller/metal/mime_responds.rb +++ b/actionpack/lib/action_controller/metal/mime_responds.rb @@ -355,8 +355,12 @@ module ActionController #:nodoc: end end - # Collects mimes and return the response for the negotiated format. Returns - # nil if :not_acceptable was sent to the client. + # Returns a Collector object containing the appropriate mime-type response + # for the current request, based on the available responses defined by a block. + # In typical usage this is the block passed to +respond_with+ or +respond_to+. + # + # Sends :not_acceptable to the client and returns nil if no suitable format + # is available. # def retrieve_collector_from_mimes(mimes=nil, &block) #:nodoc: mimes ||= collect_mimes_from_class_level 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/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb index afa9243f02..3081c14c09 100644 --- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb +++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb @@ -37,6 +37,10 @@ module ActionController #:nodoc: config_accessor :request_forgery_protection_token self.request_forgery_protection_token ||= :authenticity_token + # Controls how unverified request will be handled + config_accessor :request_forgery_protection_method + self.request_forgery_protection_method ||= :reset_session + # Controls whether request forgery protection is turned on or not. Turned off by default only in test mode. config_accessor :allow_forgery_protection self.allow_forgery_protection = true if allow_forgery_protection.nil? @@ -64,8 +68,10 @@ module ActionController #:nodoc: # Valid Options: # # * <tt>:only/:except</tt> - Passed to the <tt>before_filter</tt> call. Set which actions are verified. + # * <tt>:with</tt> - Set the method to handle unverified request. Valid values: <tt>:exception</tt> and <tt>:reset_session</tt> (default). def protect_from_forgery(options = {}) self.request_forgery_protection_token ||= :authenticity_token + self.request_forgery_protection_method = options.delete(:with) if options.key?(:with) prepend_before_filter :verify_authenticity_token, options end end @@ -80,9 +86,19 @@ module ActionController #:nodoc: end # This is the method that defines the application behavior when a request is found to be unverified. - # By default, \Rails resets the session when it finds an unverified request. + # By default, \Rails uses <tt>request_forgery_protection_method</tt> when it finds an unverified request: + # + # * <tt>:reset_session</tt> - Resets the session. + # * <tt>:exception</tt>: - Raises ActionController::InvalidAuthenticityToken exception. def handle_unverified_request - reset_session + case request_forgery_protection_method + when :exception + raise ActionController::InvalidAuthenticityToken + when :reset_session + reset_session + else + raise ArgumentError, 'Invalid request forgery protection method, use :exception or :reset_session' + end end # Returns true or false if a request is verified. Checks: 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/record_identifier.rb b/actionpack/lib/action_controller/record_identifier.rb index 9c38ff44d8..18dda978b3 100644 --- a/actionpack/lib/action_controller/record_identifier.rb +++ b/actionpack/lib/action_controller/record_identifier.rb @@ -2,8 +2,8 @@ require 'active_support/core_ext/module' module ActionController # The record identifier encapsulates a number of naming conventions for dealing with records, like Active Records or - # Active Resources or pretty much any other model type that has an id. These patterns are then used to try elevate - # the view actions to a higher logical level. Example: + # pretty much any other model type that has an id. These patterns are then used to try elevate the view actions to + # a higher logical level. Example: # # # routes # resources :posts diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index e9a3ec5a22..7ba8319e4c 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -56,6 +56,9 @@ module ActionController # # assert that the "new" view template was rendered # assert_template "new" # + # # assert that the exact template "admin/posts/new" was rendered + # assert_template %r{\Aadmin/posts/new\Z} + # # # assert that the "_customer" partial was rendered twice # assert_template :partial => '_customer', :count => 2 # @@ -74,11 +77,11 @@ module ActionController response.body case options - when NilClass, String, Symbol + when NilClass, String, Symbol, Regexp options = options.to_s if Symbol === options rendered = @templates msg = message || sprintf("expecting <%s> but rendering with <%s>", - options, rendered.keys) + options.inspect, rendered.keys) assert_block(msg) do if options rendered.any? { |t,num| t.match(options) } @@ -121,6 +124,8 @@ module ActionController assert @partials.empty?, "Expected no partials to be rendered" end + else + raise ArgumentError, "assert_template only accepts a String, Symbol, Hash, Regexp, or nil" end end end @@ -500,11 +505,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/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/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..cdc29fb304 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' 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/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 54e3032298..43d5cf1471 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -56,10 +56,10 @@ module ActionView # <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" /> # </div> # <label for="person_first_name">First name</label>: - # <input id="person_first_name" name="person[first_name]" size="30" type="text" /><br /> + # <input id="person_first_name" name="person[first_name]" type="text" /><br /> # # <label for="person_last_name">Last name</label>: - # <input id="person_last_name" name="person[last_name]" size="30" type="text" /><br /> + # <input id="person_last_name" name="person[last_name]" type="text" /><br /> # # <input name="commit" type="submit" value="Create Person" /> # </form> @@ -87,10 +87,10 @@ module ActionView # <input name="authenticity_token" type="hidden" value="NrOp5bsjoLRuK8IW5+dQEYjKGUJDe7TQoZVvq95Wteg=" /> # </div> # <label for="person_first_name">First name</label>: - # <input id="person_first_name" name="person[first_name]" size="30" type="text" value="John" /><br /> + # <input id="person_first_name" name="person[first_name]" type="text" value="John" /><br /> # # <label for="person_last_name">Last name</label>: - # <input id="person_last_name" name="person[last_name]" size="30" type="text" value="Smith" /><br /> + # <input id="person_last_name" name="person[last_name]" type="text" value="Smith" /><br /> # # <input name="commit" type="submit" value="Update Person" /> # </form> @@ -932,20 +932,20 @@ module ActionView # ==== Examples # # search_field(:user, :name) - # # => <input id="user_name" name="user[name]" size="30" type="search" /> + # # => <input id="user_name" name="user[name]" type="search" /> # search_field(:user, :name, :autosave => false) - # # => <input autosave="false" id="user_name" name="user[name]" size="30" type="search" /> + # # => <input autosave="false" id="user_name" name="user[name]" type="search" /> # search_field(:user, :name, :results => 3) - # # => <input id="user_name" name="user[name]" results="3" size="30" type="search" /> + # # => <input id="user_name" name="user[name]" results="3" type="search" /> # # Assume request.host returns "www.example.com" # search_field(:user, :name, :autosave => true) - # # => <input autosave="com.example.www" id="user_name" name="user[name]" results="10" size="30" type="search" /> + # # => <input autosave="com.example.www" id="user_name" name="user[name]" results="10" type="search" /> # search_field(:user, :name, :onsearch => true) - # # => <input id="user_name" incremental="true" name="user[name]" onsearch="true" size="30" type="search" /> + # # => <input id="user_name" incremental="true" name="user[name]" onsearch="true" type="search" /> # search_field(:user, :name, :autosave => false, :onsearch => true) - # # => <input autosave="false" id="user_name" incremental="true" name="user[name]" onsearch="true" size="30" type="search" /> + # # => <input autosave="false" id="user_name" incremental="true" name="user[name]" onsearch="true" type="search" /> # search_field(:user, :name, :autosave => true, :onsearch => true) - # # => <input autosave="com.example.www" id="user_name" incremental="true" name="user[name]" onsearch="true" results="10" size="30" type="search" /> + # # => <input autosave="com.example.www" id="user_name" incremental="true" name="user[name]" onsearch="true" results="10" type="search" /> # def search_field(object_name, method, options = {}) Tags::SearchField.new(object_name, method, self, options).render @@ -954,7 +954,7 @@ module ActionView # Returns a text_field of type "tel". # # telephone_field("user", "phone") - # # => <input id="user_phone" name="user[phone]" size="30" type="tel" /> + # # => <input id="user_phone" name="user[phone]" type="tel" /> # def telephone_field(object_name, method, options = {}) Tags::TelField.new(object_name, method, self, options).render @@ -982,7 +982,7 @@ module ActionView # Returns a text_field of type "url". # # url_field("user", "homepage") - # # => <input id="user_homepage" size="30" name="user[homepage]" type="url" /> + # # => <input id="user_homepage" name="user[homepage]" type="url" /> # def url_field(object_name, method, options = {}) Tags::UrlField.new(object_name, method, self, options).render @@ -991,7 +991,7 @@ module ActionView # Returns a text_field of type "email". # # email_field("user", "address") - # # => <input id="user_address" size="30" name="user[address]" type="email" /> + # # => <input id="user_address" name="user[address]" type="email" /> # def email_field(object_name, method, options = {}) Tags::EmailField.new(object_name, method, self, options).render diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index 5be3da9b94..d61c2bbee2 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -153,6 +153,8 @@ module ActionView # form, and parameters extraction gets the last occurrence of any repeated # key in the query string, that works for ordinary forms. # + # In case if you don't want the helper to generate this hidden field you can specify <tt>:include_blank => false</tt> option. + # def select(object, method, choices, options = {}, html_options = {}) Tags::Select.new(object, method, self, choices, options, html_options).render end 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/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index ac9e530f01..d88f5babb9 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -14,6 +14,8 @@ module ActionView } JS_ESCAPE_MAP["\342\200\250".force_encoding('UTF-8').encode!] = '
' + JS_ESCAPE_MAP["\342\200\251".force_encoding('UTF-8').encode!] = '
' + # Escapes carriage returns and single and double quotes for JavaScript segments. # @@ -22,7 +24,7 @@ module ActionView # $('some_element').replaceWith('<%=j render 'some/element_template' %>'); def escape_javascript(javascript) if javascript - result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|[\n\r"'])/u) {|match| JS_ESCAPE_MAP[match] } + result = javascript.gsub(/(\\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"'])/u) {|match| JS_ESCAPE_MAP[match] } javascript.html_safe? ? result.html_safe : result else '' diff --git a/actionpack/lib/action_view/helpers/tags/base.rb b/actionpack/lib/action_view/helpers/tags/base.rb index 22c16de057..7c2f12d8e7 100644 --- a/actionpack/lib/action_view/helpers/tags/base.rb +++ b/actionpack/lib/action_view/helpers/tags/base.rb @@ -5,8 +5,6 @@ module ActionView include Helpers::ActiveModelInstanceTag, Helpers::TagHelper, Helpers::FormTagHelper include FormOptionsHelper - DEFAULT_FIELD_OPTIONS = { "size" => 30 } - attr_reader :object def initialize(object_name, method_name, template_object, options = {}) @@ -124,7 +122,8 @@ module ActionView html_options = html_options.stringify_keys add_default_name_and_id(html_options) select = content_tag("select", add_options(option_tags, options, value(object)), html_options) - if html_options["multiple"] + + if html_options["multiple"] && options.fetch(:include_hidden) { true } tag("input", :disabled => html_options["disabled"], :name => html_options["name"], :type => "hidden", :value => "") + select else select diff --git a/actionpack/lib/action_view/helpers/tags/check_box.rb b/actionpack/lib/action_view/helpers/tags/check_box.rb index 579cdb9fc9..1a4aebb936 100644 --- a/actionpack/lib/action_view/helpers/tags/check_box.rb +++ b/actionpack/lib/action_view/helpers/tags/check_box.rb @@ -25,9 +25,15 @@ module ActionView add_default_name_and_id(options) end - hidden = hidden_field_for_checkbox(options) + include_hidden = options.delete("include_hidden") { true } checkbox = tag("input", options) - hidden + checkbox + + if include_hidden + hidden = hidden_field_for_checkbox(options) + hidden + checkbox + else + checkbox + end end private diff --git a/actionpack/lib/action_view/helpers/tags/text_area.rb b/actionpack/lib/action_view/helpers/tags/text_area.rb index 461a049fc2..2e48850d5c 100644 --- a/actionpack/lib/action_view/helpers/tags/text_area.rb +++ b/actionpack/lib/action_view/helpers/tags/text_area.rb @@ -2,10 +2,8 @@ module ActionView module Helpers module Tags class TextArea < Base #:nodoc: - DEFAULT_TEXT_AREA_OPTIONS = { "cols" => 40, "rows" => 20 } - def render - options = DEFAULT_TEXT_AREA_OPTIONS.merge(@options.stringify_keys) + options = @options.stringify_keys add_default_name_and_id(options) if size = options.delete("size") diff --git a/actionpack/lib/action_view/helpers/tags/text_field.rb b/actionpack/lib/action_view/helpers/tags/text_field.rb index ce5182d20f..024a1a8af2 100644 --- a/actionpack/lib/action_view/helpers/tags/text_field.rb +++ b/actionpack/lib/action_view/helpers/tags/text_field.rb @@ -4,8 +4,7 @@ module ActionView class TextField < Base #:nodoc: def render options = @options.stringify_keys - options["size"] = options["maxlength"] || DEFAULT_FIELD_OPTIONS["size"] unless options.key?("size") - options = DEFAULT_FIELD_OPTIONS.merge(options) + options["size"] = options["maxlength"] unless options.key?("size") options["type"] ||= field_type options["value"] = options.fetch("value"){ value_before_type_cast(object) } unless field_type == "file" options["value"] &&= ERB::Util.html_escape(options["value"]) diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index f4946e65b5..29f556502b 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -60,7 +60,7 @@ module ActionView # # ==== Relying on named routes # - # Passing a record (like an Active Record or Active Resource) instead of a Hash as the options parameter will + # Passing a record (like an Active Record) instead of a Hash as the options parameter will # trigger the named route for that record. The lookup will happen on the name of the class. So passing a # Workshop object will attempt to use the +workshop_path+ route. If you have a nested route, such as # +admin_workshop_path+ you'll have to call that explicitly (it's impossible for +url_for+ to guess that route). 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...) diff --git a/actionpack/lib/sprockets/assets.rake b/actionpack/lib/sprockets/assets.rake deleted file mode 100644 index 2e92fe416b..0000000000 --- a/actionpack/lib/sprockets/assets.rake +++ /dev/null @@ -1,105 +0,0 @@ -require "fileutils" - -namespace :assets do - def ruby_rake_task(task, fork = true) - env = ENV['RAILS_ENV'] || 'production' - groups = ENV['RAILS_GROUPS'] || 'assets' - args = [$0, task,"RAILS_ENV=#{env}","RAILS_GROUPS=#{groups}"] - args << "--trace" if Rake.application.options.trace - if $0 =~ /rake\.bat\Z/i - Kernel.exec $0, *args - else - fork ? ruby(*args) : Kernel.exec(FileUtils::RUBY, *args) - end - end - - # We are currently running with no explicit bundler group - # and/or no explicit environment - we have to reinvoke rake to - # execute this task. - def invoke_or_reboot_rake_task(task) - if ENV['RAILS_GROUPS'].to_s.empty? || ENV['RAILS_ENV'].to_s.empty? - ruby_rake_task task - else - Rake::Task[task].invoke - end - end - - desc "Compile all the assets named in config.assets.precompile" - task :precompile do - invoke_or_reboot_rake_task "assets:precompile:all" - end - - namespace :precompile do - def internal_precompile(digest=nil) - unless Rails.application.config.assets.enabled - warn "Cannot precompile assets if sprockets is disabled. Please set config.assets.enabled to true" - exit - end - - # Ensure that action view is loaded and the appropriate - # sprockets hooks get executed - _ = ActionView::Base - - config = Rails.application.config - config.assets.compile = true - config.assets.digest = digest unless digest.nil? - config.assets.digests = {} - - env = Rails.application.assets - target = File.join(Rails.public_path, config.assets.prefix) - compiler = Sprockets::StaticCompiler.new(env, - target, - config.assets.precompile, - :manifest_path => config.assets.manifest, - :digest => config.assets.digest, - :manifest => digest.nil?) - compiler.compile - end - - task :all do - Rake::Task["assets:precompile:primary"].invoke - # We need to reinvoke in order to run the secondary digestless - # asset compilation run - a fresh Sprockets environment is - # required in order to compile digestless assets as the - # environment has already cached the assets on the primary - # run. - ruby_rake_task("assets:precompile:nondigest", false) if Rails.application.config.assets.digest - end - - task :primary => ["assets:cache:clean"] do - internal_precompile - end - - task :nondigest => ["assets:cache:clean"] do - internal_precompile(false) - end - end - - desc "Remove compiled assets" - task :clean do - invoke_or_reboot_rake_task "assets:clean:all" - end - - namespace :clean do - task :all => ["assets:cache:clean"] do - config = Rails.application.config - public_asset_path = File.join(Rails.public_path, config.assets.prefix) - rm_rf public_asset_path, :secure => true - end - end - - namespace :cache do - task :clean => ["assets:environment"] do - Rails.application.assets.cache.clear - end - end - - task :environment do - if Rails.application.config.assets.initialize_on_precompile - Rake::Task["environment"].invoke - else - Rails.application.initialize!(:assets) - Sprockets::Bootstrap.new(Rails.application).run - end - end -end diff --git a/actionpack/lib/sprockets/bootstrap.rb b/actionpack/lib/sprockets/bootstrap.rb deleted file mode 100644 index 395b264fe7..0000000000 --- a/actionpack/lib/sprockets/bootstrap.rb +++ /dev/null @@ -1,37 +0,0 @@ -module Sprockets - class Bootstrap - def initialize(app) - @app = app - end - - # TODO: Get rid of config.assets.enabled - def run - app, config = @app, @app.config - return unless app.assets - - config.assets.paths.each { |path| app.assets.append_path(path) } - - if config.assets.compress - # temporarily hardcode default JS compressor to uglify. Soon, it will work - # the same as SCSS, where a default plugin sets the default. - unless config.assets.js_compressor == false - app.assets.js_compressor = LazyCompressor.new { Sprockets::Compressors.registered_js_compressor(config.assets.js_compressor || :uglifier) } - end - - unless config.assets.css_compressor == false - app.assets.css_compressor = LazyCompressor.new { Sprockets::Compressors.registered_css_compressor(config.assets.css_compressor) } - end - end - - if config.assets.compile - app.routes.prepend do - mount app.assets => config.assets.prefix - end - end - - if config.assets.digest - app.assets = app.assets.index - end - end - end -end diff --git a/actionpack/lib/sprockets/compressors.rb b/actionpack/lib/sprockets/compressors.rb deleted file mode 100644 index 8b728d6570..0000000000 --- a/actionpack/lib/sprockets/compressors.rb +++ /dev/null @@ -1,85 +0,0 @@ -module Sprockets - module Compressors - extend self - - @@css_compressors = {} - @@js_compressors = {} - @@default_css_compressor = nil - @@default_js_compressor = nil - - def register_css_compressor(name, klass, options = {}) - @@default_css_compressor = name.to_sym if options[:default] || @@default_css_compressor.nil? - @@css_compressors[name.to_sym] = { :klass => klass.to_s, :require => options[:require] } - end - - def register_js_compressor(name, klass, options = {}) - @@default_js_compressor = name.to_sym if options[:default] || @@default_js_compressor.nil? - @@js_compressors[name.to_sym] = { :klass => klass.to_s, :require => options[:require] } - end - - def registered_css_compressor(name) - find_registered_compressor name, @@css_compressors, @@default_css_compressor - end - - def registered_js_compressor(name) - find_registered_compressor name, @@js_compressors, @@default_js_compressor - end - - # The default compressors must be registered in default plugins (ex. Sass-Rails) - register_css_compressor(:scss, 'Sass::Rails::Compressor', :require => 'sass/rails/compressor', :default => true) - register_js_compressor(:uglifier, 'Uglifier', :require => 'uglifier', :default => true) - - # Automaticaly register some compressors - register_css_compressor(:yui, 'YUI::CssCompressor', :require => 'yui/compressor') - register_js_compressor(:closure, 'Closure::Compiler', :require => 'closure-compiler') - register_js_compressor(:yui, 'YUI::JavaScriptCompressor', :require => 'yui/compressor') - - private - - def find_registered_compressor(name, compressors_hash, default_compressor_name) - if name.respond_to?(:to_sym) - compressor = compressors_hash[name.to_sym] || compressors_hash[default_compressor_name] - require compressor[:require] if compressor[:require] - compressor[:klass].constantize.new - else - name - end - end - end - - # An asset compressor which does nothing. - # - # This compressor simply returns the asset as-is, without any compression - # whatsoever. It is useful in development mode, when compression isn't - # needed but using the same asset pipeline as production is desired. - class NullCompressor #:nodoc: - def compress(content) - content - end - end - - # An asset compressor which only initializes the underlying compression - # engine when needed. - # - # This postpones the initialization of the compressor until - # <code>#compress</code> is called the first time. - class LazyCompressor #:nodoc: - # Initializes a new LazyCompressor. - # - # The block should return a compressor when called, i.e. an object - # which responds to <code>#compress</code>. - def initialize(&block) - @block = block - end - - def compress(content) - compressor.compress(content) - end - - private - - def compressor - @compressor ||= (@block.call || NullCompressor.new) - end - end -end diff --git a/actionpack/lib/sprockets/helpers.rb b/actionpack/lib/sprockets/helpers.rb deleted file mode 100644 index fee48386e0..0000000000 --- a/actionpack/lib/sprockets/helpers.rb +++ /dev/null @@ -1,6 +0,0 @@ -module Sprockets - module Helpers - autoload :RailsHelper, "sprockets/helpers/rails_helper" - autoload :IsolatedHelper, "sprockets/helpers/isolated_helper" - end -end diff --git a/actionpack/lib/sprockets/helpers/isolated_helper.rb b/actionpack/lib/sprockets/helpers/isolated_helper.rb deleted file mode 100644 index 3adb928c45..0000000000 --- a/actionpack/lib/sprockets/helpers/isolated_helper.rb +++ /dev/null @@ -1,13 +0,0 @@ -module Sprockets - module Helpers - module IsolatedHelper - def controller - nil - end - - def config - Rails.application.config.action_controller - end - end - end -end diff --git a/actionpack/lib/sprockets/helpers/rails_helper.rb b/actionpack/lib/sprockets/helpers/rails_helper.rb deleted file mode 100644 index 839ec7635f..0000000000 --- a/actionpack/lib/sprockets/helpers/rails_helper.rb +++ /dev/null @@ -1,167 +0,0 @@ -require "action_view" - -module Sprockets - module Helpers - module RailsHelper - extend ActiveSupport::Concern - include ActionView::Helpers::AssetTagHelper - - def asset_paths - @asset_paths ||= begin - paths = RailsHelper::AssetPaths.new(config, controller) - paths.asset_environment = asset_environment - paths.asset_digests = asset_digests - paths.compile_assets = compile_assets? - paths.digest_assets = digest_assets? - paths - end - end - - def javascript_include_tag(*sources) - options = sources.extract_options! - debug = options.delete(:debug) { debug_assets? } - body = options.delete(:body) { false } - digest = options.delete(:digest) { digest_assets? } - - sources.collect do |source| - if debug && asset = asset_paths.asset_for(source, 'js') - asset.to_a.map { |dep| - super(dep.pathname.to_s, { :src => path_to_asset(dep, :ext => 'js', :body => true, :digest => digest) }.merge!(options)) - } - else - super(source.to_s, { :src => path_to_asset(source, :ext => 'js', :body => body, :digest => digest) }.merge!(options)) - end - end.join("\n").html_safe - end - - def stylesheet_link_tag(*sources) - options = sources.extract_options! - debug = options.delete(:debug) { debug_assets? } - body = options.delete(:body) { false } - digest = options.delete(:digest) { digest_assets? } - - sources.collect do |source| - if debug && asset = asset_paths.asset_for(source, 'css') - asset.to_a.map { |dep| - super(dep.pathname.to_s, { :href => path_to_asset(dep, :ext => 'css', :body => true, :protocol => :request, :digest => digest) }.merge!(options)) - } - else - super(source.to_s, { :href => path_to_asset(source, :ext => 'css', :body => body, :protocol => :request, :digest => digest) }.merge!(options)) - end - end.join("\n").html_safe - end - - def asset_path(source, options = {}) - source = source.logical_path if source.respond_to?(:logical_path) - path = asset_paths.compute_public_path(source, asset_prefix, options.merge(:body => true)) - options[:body] ? "#{path}?body=1" : path - end - alias_method :path_to_asset, :asset_path # aliased to avoid conflicts with an asset_path named route - - def image_path(source) - path_to_asset(source) - end - alias_method :path_to_image, :image_path # aliased to avoid conflicts with an image_path named route - - def font_path(source) - path_to_asset(source) - end - alias_method :path_to_font, :font_path # aliased to avoid conflicts with an font_path named route - - def javascript_path(source) - path_to_asset(source, :ext => 'js') - end - alias_method :path_to_javascript, :javascript_path # aliased to avoid conflicts with an javascript_path named route - - def stylesheet_path(source) - path_to_asset(source, :ext => 'css') - end - alias_method :path_to_stylesheet, :stylesheet_path # aliased to avoid conflicts with an stylesheet_path named route - - private - def debug_assets? - compile_assets? && (Rails.application.config.assets.debug || params[:debug_assets]) - rescue NoMethodError - false - end - - # Override to specify an alternative prefix for asset path generation. - # When combined with a custom +asset_environment+, this can be used to - # implement themes that can take advantage of the asset pipeline. - # - # If you only want to change where the assets are mounted, refer to - # +config.assets.prefix+ instead. - def asset_prefix - Rails.application.config.assets.prefix - end - - def asset_digests - Rails.application.config.assets.digests - end - - def compile_assets? - Rails.application.config.assets.compile - end - - def digest_assets? - Rails.application.config.assets.digest - end - - # Override to specify an alternative asset environment for asset - # path generation. The environment should already have been mounted - # at the prefix returned by +asset_prefix+. - def asset_environment - Rails.application.assets - end - - class AssetPaths < ::ActionView::AssetPaths #:nodoc: - attr_accessor :asset_environment, :asset_prefix, :asset_digests, :compile_assets, :digest_assets - - class AssetNotPrecompiledError < StandardError; end - - def asset_for(source, ext) - source = source.to_s - return nil if is_uri?(source) - source = rewrite_extension(source, nil, ext) - asset_environment[source] - rescue Sprockets::FileOutsidePaths - nil - end - - def digest_for(logical_path) - if digest_assets && asset_digests && (digest = asset_digests[logical_path]) - return digest - end - - if compile_assets - if digest_assets && asset = asset_environment[logical_path] - return asset.digest_path - end - return logical_path - else - raise AssetNotPrecompiledError.new("#{logical_path} isn't precompiled") - end - end - - def rewrite_asset_path(source, dir, options = {}) - if source[0] == ?/ - source - else - source = digest_for(source) unless options[:digest] == false - source = File.join(dir, source) - source = "/#{source}" unless source =~ /^\// - source - end - end - - def rewrite_extension(source, dir, ext) - if ext && File.extname(source) != ".#{ext}" - "#{source}.#{ext}" - else - source - end - end - end - end - end -end diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb deleted file mode 100644 index 2bc482a39d..0000000000 --- a/actionpack/lib/sprockets/railtie.rb +++ /dev/null @@ -1,62 +0,0 @@ -require "action_controller/railtie" - -module Sprockets - autoload :Bootstrap, "sprockets/bootstrap" - autoload :Helpers, "sprockets/helpers" - autoload :Compressors, "sprockets/compressors" - autoload :LazyCompressor, "sprockets/compressors" - autoload :NullCompressor, "sprockets/compressors" - autoload :StaticCompiler, "sprockets/static_compiler" - - # TODO: Get rid of config.assets.enabled - class Railtie < ::Rails::Railtie - rake_tasks do - load "sprockets/assets.rake" - end - - initializer "sprockets.environment", :group => :all do |app| - config = app.config - next unless config.assets.enabled - - require 'sprockets' - - app.assets = Sprockets::Environment.new(app.root.to_s) do |env| - env.version = ::Rails.env + "-#{config.assets.version}" - - if config.assets.logger != false - env.logger = config.assets.logger || ::Rails.logger - end - - if config.assets.cache_store != false - env.cache = ActiveSupport::Cache.lookup_store(config.assets.cache_store) || ::Rails.cache - end - end - - if config.assets.manifest - path = File.join(config.assets.manifest, "manifest.yml") - else - path = File.join(Rails.public_path, config.assets.prefix, "manifest.yml") - end - - if File.exist?(path) - config.assets.digests = YAML.load_file(path) - end - - ActiveSupport.on_load(:action_view) do - include ::Sprockets::Helpers::RailsHelper - app.assets.context_class.instance_eval do - include ::Sprockets::Helpers::IsolatedHelper - include ::Sprockets::Helpers::RailsHelper - end - end - end - - # We need to configure this after initialization to ensure we collect - # paths from all engines. This hook is invoked exactly before routes - # are compiled, and so that other Railties have an opportunity to - # register compressors. - config.after_initialize do |app| - Sprockets::Bootstrap.new(app).run - end - end -end diff --git a/actionpack/lib/sprockets/static_compiler.rb b/actionpack/lib/sprockets/static_compiler.rb deleted file mode 100644 index 9bbb464474..0000000000 --- a/actionpack/lib/sprockets/static_compiler.rb +++ /dev/null @@ -1,62 +0,0 @@ -require 'fileutils' - -module Sprockets - class StaticCompiler - attr_accessor :env, :target, :paths - - def initialize(env, target, paths, options = {}) - @env = env - @target = target - @paths = paths - @digest = options.fetch(:digest, true) - @manifest = options.fetch(:manifest, true) - @manifest_path = options.delete(:manifest_path) || target - @zip_files = options.delete(:zip_files) || /\.(?:css|html|js|svg|txt|xml)$/ - end - - def compile - manifest = {} - env.each_logical_path do |logical_path| - next unless compile_path?(logical_path) - if asset = env.find_asset(logical_path) - manifest[logical_path] = write_asset(asset) - end - end - write_manifest(manifest) if @manifest - end - - def write_manifest(manifest) - FileUtils.mkdir_p(@manifest_path) - File.open("#{@manifest_path}/manifest.yml", 'wb') do |f| - YAML.dump(manifest, f) - end - end - - def write_asset(asset) - path_for(asset).tap do |path| - filename = File.join(target, path) - FileUtils.mkdir_p File.dirname(filename) - asset.write_to(filename) - asset.write_to("#{filename}.gz") if filename.to_s =~ @zip_files - end - end - - def compile_path?(logical_path) - paths.each do |path| - case path - when Regexp - return true if path.match(logical_path) - when Proc - return true if path.call(logical_path) - else - return true if File.fnmatch(path.to_s, logical_path) - end - end - false - end - - def path_for(asset) - @digest ? asset.digest_path : asset.logical_path - end - end -end |