From 53d3bafc8bf3f0cb90a02751aa93b0c30b26ab78 Mon Sep 17 00:00:00 2001 From: Evan Petrie Date: Thu, 14 Apr 2011 12:08:18 -0700 Subject: ruby 1.9.2 and other ruby implementations may not return the same hash value for the same string each time. This can result in your static assets being served from different asset hosts, which makes browser caching less effective. Use md5 or some other digest method instead. --- actionpack/lib/action_view/helpers/asset_tag_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index f6b2d4f3f4..c383e4990c 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -57,7 +57,7 @@ module ActionView # +asset_host+ to a proc like this: # # ActionController::Base.asset_host = Proc.new { |source| - # "http://assets#{source.hash % 2 + 1}.example.com" + # "http://assets#{Digest::MD5.hexdigest(source).to_i(16) % 2 + 1}.example.com" # } # image_tag("rails.png") # # => Rails -- cgit v1.2.3 From c09538941fad7929955ada73cc796e918af415ca Mon Sep 17 00:00:00 2001 From: Joshua Ballanco Date: Thu, 14 Apr 2011 23:18:12 -0400 Subject: Test for stripping tags from a frozen string. This test will pass under Ruby 1.8 but fail under Ruby 1.9 because of the change in behavior of gsub! w.r.t. frozen strings that do not match the pattern used [ruby-core:23664]. --- actionpack/test/template/html-scanner/sanitizer_test.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionpack') diff --git a/actionpack/test/template/html-scanner/sanitizer_test.rb b/actionpack/test/template/html-scanner/sanitizer_test.rb index fcc3782f04..678cb9eeeb 100644 --- a/actionpack/test/template/html-scanner/sanitizer_test.rb +++ b/actionpack/test/template/html-scanner/sanitizer_test.rb @@ -20,6 +20,7 @@ class SanitizerTest < ActionController::TestCase assert_equal "This has a here.", sanitizer.sanitize("This has a ]]> here.") assert_equal "This has an unclosed ", sanitizer.sanitize("This has an unclosed ]] here...") [nil, '', ' '].each { |blank| assert_equal blank, sanitizer.sanitize(blank) } + assert_nothing_raised { sanitizer.sanitize("This is a frozen string with no tags".freeze) } end def test_strip_links -- cgit v1.2.3 From 2adeaa9c90b7559387b55e7a24a7eb82671c88cc Mon Sep 17 00:00:00 2001 From: Joshua Ballanco Date: Thu, 14 Apr 2011 23:25:18 -0400 Subject: Fix for stripping tags from frozen strings. This returns behavior under Ruby 1.9 to match Ruby 1.8. --- actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb b/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb index 09dd08898c..91a97c02ff 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +++ b/actionpack/lib/action_controller/vendor/html-scanner/html/sanitizer.rb @@ -33,7 +33,7 @@ module HTML result = super # strip any comments, and if they have a newline at the end (ie. line with # only a comment) strip that too - result.gsub!(/[\n]?/m, "") if result + result = result.gsub(/[\n]?/m, "") if (result && result =~ /[\n]?/m) # Recurse - handle all dirty nested tags result == text ? result : sanitize(result, options) end -- cgit v1.2.3 From 3ca6d0e8fe72f6840049f7c2461243cf362b9896 Mon Sep 17 00:00:00 2001 From: Matt Duncan Date: Fri, 15 Apr 2011 19:56:48 -0400 Subject: Including actual usage in example --- actionpack/lib/action_view/helpers/date_helper.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index 6cd1565031..72ee31a246 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -115,7 +115,9 @@ module ActionView # time_ago_in_words(Time.now - 15.hours) # => 15 hours # time_ago_in_words(Time.now) # => less than a minute # - # from_time = Time.now - 3.days - 14.minutes - 25.seconds # => 3 days + # from_time = Time.now - 3.days - 14.minutes - 25.seconds + # time_ago_in_words(from_time) # => 3 days + # def time_ago_in_words(from_time, include_seconds = false) distance_of_time_in_words(from_time, Time.now, include_seconds) end -- cgit v1.2.3 From 8ac365f47626fd4d9569cf9c378c3a8f4f60eb58 Mon Sep 17 00:00:00 2001 From: Matt Duncan Date: Fri, 15 Apr 2011 20:03:52 -0400 Subject: Making example result match actual result --- actionpack/lib/action_view/helpers/date_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index 72ee31a246..4c65ebc1f3 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -112,7 +112,7 @@ module ActionView # # ==== Examples # time_ago_in_words(3.minutes.from_now) # => 3 minutes - # time_ago_in_words(Time.now - 15.hours) # => 15 hours + # time_ago_in_words(Time.now - 15.hours) # => about 15 hours # time_ago_in_words(Time.now) # => less than a minute # # from_time = Time.now - 3.days - 14.minutes - 25.seconds -- cgit v1.2.3 From 6ddd4a3d954cd81f96c747f515406be50041431a Mon Sep 17 00:00:00 2001 From: Matt Duncan Date: Fri, 15 Apr 2011 20:08:11 -0400 Subject: Days are never approximated using 'about' --- actionpack/lib/action_view/helpers/date_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index 4c65ebc1f3..3c0c7c319c 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -51,7 +51,7 @@ module ActionView # distance_of_time_in_words(from_time, from_time + 15.seconds) # => less than a minute # distance_of_time_in_words(from_time, from_time + 15.seconds, true) # => less than 20 seconds # distance_of_time_in_words(from_time, 3.years.from_now) # => about 3 years - # distance_of_time_in_words(from_time, from_time + 60.hours) # => about 3 days + # distance_of_time_in_words(from_time, from_time + 60.hours) # => 3 days # distance_of_time_in_words(from_time, from_time + 45.seconds, true) # => less than a minute # distance_of_time_in_words(from_time, from_time - 45.seconds, true) # => less than a minute # distance_of_time_in_words(from_time, 76.seconds.from_now) # => 1 minute -- cgit v1.2.3 From 7f98b544e3b29c7ffdb8cb4a2ad1da5d1a8c611c Mon Sep 17 00:00:00 2001 From: Matt Duncan Date: Fri, 15 Apr 2011 20:18:30 -0400 Subject: Negative format example should use a negative number --- actionpack/lib/action_view/helpers/number_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb index 05a9c5b4f1..68ebedd328 100644 --- a/actionpack/lib/action_view/helpers/number_helper.rb +++ b/actionpack/lib/action_view/helpers/number_helper.rb @@ -100,7 +100,7 @@ module ActionView # number_to_currency(1234567890.506, :precision => 3) # => $1,234,567,890.506 # number_to_currency(1234567890.506, :locale => :fr) # => 1 234 567 890,506 € # - # number_to_currency(1234567890.50, :negative_format => "(%u%n)") + # number_to_currency(-1234567890.50, :negative_format => "(%u%n)") # # => ($1,234,567,890.51) # number_to_currency(1234567890.50, :unit => "£", :separator => ",", :delimiter => "") # # => £1234567890,50 -- cgit v1.2.3 From 004042c0d94f0294e691de46094a665acd852653 Mon Sep 17 00:00:00 2001 From: Matt Duncan Date: Fri, 15 Apr 2011 20:27:05 -0400 Subject: Fixing missing colon on symbol in example --- actionpack/lib/action_view/helpers/number_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb index 68ebedd328..a150019e5c 100644 --- a/actionpack/lib/action_view/helpers/number_helper.rb +++ b/actionpack/lib/action_view/helpers/number_helper.rb @@ -238,7 +238,7 @@ module ActionView # number_with_precision(111.2345, :precision => 1, :significant => true) # => 100 # number_with_precision(13, :precision => 5, :significant => true) # => 13.000 # number_with_precision(111.234, :locale => :fr) # => 111,234 - # number_with_precision(13, :precision => 5, :significant => true, strip_insignificant_zeros => true) + # number_with_precision(13, :precision => 5, :significant => true, :strip_insignificant_zeros => true) # # => 13 # number_with_precision(389.32314, :precision => 4, :significant => true) # => 389.3 # number_with_precision(1111.2345, :precision => 2, :separator => ',', :delimiter => '.') -- cgit v1.2.3 From e8afe4e1ea9ea4c59368bb84efde785876f25061 Mon Sep 17 00:00:00 2001 From: Matt Duncan Date: Fri, 15 Apr 2011 20:30:51 -0400 Subject: Making spacing consistent --- actionpack/lib/action_view/helpers/number_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb index a150019e5c..b545031fcc 100644 --- a/actionpack/lib/action_view/helpers/number_helper.rb +++ b/actionpack/lib/action_view/helpers/number_helper.rb @@ -318,7 +318,7 @@ module ActionView # Non-significant zeros after the fractional separator are stripped out by default (set # :strip_insignificant_zeros to +false+ to change that): # number_to_human_size(1234567890123, :precision => 5) # => "1.1229 TB" - # number_to_human_size(524288000, :precision=>5) # => "500 MB" + # number_to_human_size(524288000, :precision => 5) # => "500 MB" def number_to_human_size(number, options = {}) options.symbolize_keys! @@ -407,7 +407,7 @@ module ActionView # Unsignificant zeros after the decimal separator are stripped out by default (set # :strip_insignificant_zeros to +false+ to change that): # number_to_human(12345012345, :significant_digits => 6) # => "12.345 Billion" - # number_to_human(500000000, :precision=>5) # => "500 Million" + # number_to_human(500000000, :precision => 5) # => "500 Million" # # ==== Custom Unit Quantifiers # -- cgit v1.2.3 From f274394afbedd2097d5855f8c2d7d384b46977c3 Mon Sep 17 00:00:00 2001 From: Matt Duncan Date: Fri, 15 Apr 2011 21:34:49 -0400 Subject: Fixing more spacing inconsistencies --- actionpack/lib/action_view/helpers/date_helper.rb | 2 +- actionpack/lib/action_view/helpers/url_helper.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index 3c0c7c319c..6dbd2e3e43 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -466,7 +466,7 @@ module ActionView # # # Generates a select field for hours with a custom prompt. Use :prompt => true for a # # generic prompt. - # select_hour(13, :prompt =>'Choose hour') + # select_hour(13, :prompt => 'Choose hour') # def select_hour(datetime, options = {}, html_options = {}) DateTimeSelector.new(datetime, options, html_options).select_hour diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index de75488e72..051d3eb049 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -555,10 +555,10 @@ module ActionView # current_page?(:controller => 'shop', :action => 'checkout') # # => true # - # current_page?(:controller => 'shop', :action => 'checkout', :order => 'desc', :page=>'1') + # current_page?(:controller => 'shop', :action => 'checkout', :order => 'desc', :page => '1') # # => true # - # current_page?(:controller => 'shop', :action => 'checkout', :order => 'desc', :page=>'2') + # current_page?(:controller => 'shop', :action => 'checkout', :order => 'desc', :page => '2') # # => false # # current_page?(:controller => 'shop', :action => 'checkout', :order => 'desc') -- cgit v1.2.3 From b6bfcc9115df00620e155a84f80d46342c1fe7ee Mon Sep 17 00:00:00 2001 From: Matt Duncan Date: Fri, 15 Apr 2011 21:50:29 -0400 Subject: Fix syntax error in example --- actionpack/lib/action_view/helpers/text_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index bdda1df437..d1c505d2b5 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -19,7 +19,7 @@ module ActionView # simple_format('Example') # # => "

Example

" # - # simple_format('Example') + # simple_format('Example') # # => "

Example

" # # If you want to escape all content, you should invoke the +h+ method before -- cgit v1.2.3 From 1229904602b8c3b354a144ce33468be408cf9cec Mon Sep 17 00:00:00 2001 From: Matt Duncan Date: Fri, 15 Apr 2011 21:56:01 -0400 Subject: Removing incorrect example results --- actionpack/lib/action_view/helpers/text_helper.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index d1c505d2b5..06e2b027da 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -295,11 +295,11 @@ module ActionView # +link+ as its optional second parameter and the +html_options+ hash # as its optional third parameter: # post_body = "Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com." - # auto_link(post_body, :urls) # => Once upon\na time + # auto_link(post_body, :urls) # # => "Welcome to my new blog at http://www.myblog.com. # Please e-mail me at me@email.com." # - # auto_link(post_body, :all, :target => "_blank") # => Once upon\na time + # auto_link(post_body, :all, :target => "_blank") # # => "Welcome to my new blog at http://www.myblog.com. # Please e-mail me at me@email.com." def auto_link(text, *args, &block)#link = :all, html = {}, &block) -- cgit v1.2.3 From 50b2eb8cbd6cb923026b8fbb98482e06cdbd21ce Mon Sep 17 00:00:00 2001 From: Matt Duncan Date: Fri, 15 Apr 2011 22:09:23 -0400 Subject: Fixing another example result --- actionpack/lib/action_view/helpers/sanitize_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/sanitize_helper.rb b/actionpack/lib/action_view/helpers/sanitize_helper.rb index 0fee34f8a4..841be0a567 100644 --- a/actionpack/lib/action_view/helpers/sanitize_helper.rb +++ b/actionpack/lib/action_view/helpers/sanitize_helper.rb @@ -94,7 +94,7 @@ module ActionView # # => Please e-mail me at me@email.com. # # strip_links('Blog: Visit.') - # # => Blog: Visit + # # => Blog: Visit. def strip_links(html) self.class.link_sanitizer.sanitize(html) end -- cgit v1.2.3 From 3dc4d543f177e57cb08ac8fd16a5fff6f635822f Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Fri, 15 Apr 2011 14:34:14 -0700 Subject: make our constructor signature match the superclass --- actionpack/lib/action_controller/metal.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 585bd5e5ab..0133b2ecbc 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -131,7 +131,7 @@ module ActionController attr_internal :headers, :response, :request delegate :session, :to => "@_request" - def initialize(*) + def initialize @_headers = {"Content-Type" => "text/html"} @_status = 200 @_request = nil -- cgit v1.2.3 From 4f044528c0373b0a581a12b1311a7a544ded6c58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 18 Apr 2011 08:12:51 +0200 Subject: Slightly reorganize rendering stack. --- actionpack/lib/abstract_controller/rendering.rb | 31 +++++++++++++++++----- .../lib/action_controller/metal/renderers.rb | 6 ++--- 2 files changed, 28 insertions(+), 9 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 66f6d0eebb..d0dd730b06 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -105,16 +105,22 @@ module AbstractController # Normalize arguments, options and then delegates render_to_body and # sticks the result in self.response_body. def render(*args, &block) - self.response_body = render_to_string(*args, &block) + options = _normalize_render(*args, &block) + self.response_body = render_to_body(options) end # Raw rendering of a template to a string. Just convert the results of - # render_to_body into a String. + # render_response into a String. # :api: plugin def render_to_string(*args, &block) - options = _normalize_args(*args, &block) - _normalize_options(options) - render_to_body(options).tap { self.response_body = nil } + options = _normalize_render(*args, &block) + if self.response_body = render_to_body(options) + string = "" + response_body.each { |r| string << r } + string + end + ensure + self.response_body = nil end # Raw rendering of a template to a Rack-compatible body. @@ -151,8 +157,17 @@ module AbstractController hash end - # Normalize options by converting render "foo" to render :action => "foo" and + # Normalize args and options. + # :api: private + def _normalize_render(*args, &block) + options = _normalize_args(*args, &block) + _normalize_options(options) + options + end + + # Normalize args by converting render "foo" to render :action => "foo" and # render "foo/bar" to render :file => "foo/bar". + # :api: plugin def _normalize_args(action=nil, options={}) case action when NilClass @@ -169,6 +184,8 @@ module AbstractController options end + # Normalize options. + # :api: plugin def _normalize_options(options) if options[:partial] == true options[:partial] = action_name @@ -182,6 +199,8 @@ module AbstractController options end + # Process extra options. + # :api: plugin def _process_options(options) end end diff --git a/actionpack/lib/action_controller/metal/renderers.rb b/actionpack/lib/action_controller/metal/renderers.rb index dfda6618e7..0ad9dbeda9 100644 --- a/actionpack/lib/action_controller/metal/renderers.rb +++ b/actionpack/lib/action_controller/metal/renderers.rb @@ -95,17 +95,17 @@ module ActionController json = json.to_json(options) unless json.kind_of?(String) json = "#{options[:callback]}(#{json})" unless options[:callback].blank? self.content_type ||= Mime::JSON - self.response_body = json + json end add :js do |js, options| self.content_type ||= Mime::JS - self.response_body = js.respond_to?(:to_js) ? js.to_js(options) : js + js.respond_to?(:to_js) ? js.to_js(options) : js end add :xml do |xml, options| self.content_type ||= Mime::XML - self.response_body = xml.respond_to?(:to_xml) ? xml.to_xml(options) : xml + xml.respond_to?(:to_xml) ? xml.to_xml(options) : xml end end end -- cgit v1.2.3 From 944b4d57960569d5c9a08783044677721a6de4df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 18 Apr 2011 08:13:28 +0200 Subject: Add missing dependency. --- actionpack/lib/action_controller/metal/mime_responds.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb index 16d48e4677..f10287afb4 100644 --- a/actionpack/lib/action_controller/metal/mime_responds.rb +++ b/actionpack/lib/action_controller/metal/mime_responds.rb @@ -6,6 +6,8 @@ module ActionController #:nodoc: module MimeResponds extend ActiveSupport::Concern + include ActionController::ImplicitRender + included do class_attribute :responder, :mimes_for_respond_to self.responder = ActionController::Responder -- cgit v1.2.3 From 7a152ab0127877eea6f2cef8ff6d1975a3fc16d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 18 Apr 2011 08:17:47 +0200 Subject: Rename it to DataStreaming. --- actionpack/lib/action_controller.rb | 2 +- actionpack/lib/action_controller/base.rb | 2 +- .../lib/action_controller/metal/data_streaming.rb | 145 +++++++++++++++++++++ .../lib/action_controller/metal/streaming.rb | 145 --------------------- 4 files changed, 147 insertions(+), 147 deletions(-) create mode 100644 actionpack/lib/action_controller/metal/data_streaming.rb delete mode 100644 actionpack/lib/action_controller/metal/streaming.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 62cc18b253..26e6ac770f 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -13,6 +13,7 @@ module ActionController autoload :Compatibility autoload :ConditionalGet autoload :Cookies + autoload :DataStreaming autoload :Flash autoload :ForceSSL autoload :Head @@ -30,7 +31,6 @@ module ActionController autoload :Rescue autoload :Responder autoload :SessionManagement - autoload :Streaming autoload :Testing autoload :UrlFor end diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 5f9e082cd3..53e0a4b9d1 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -199,7 +199,7 @@ module ActionController Flash, RequestForgeryProtection, ForceSSL, - Streaming, + DataStreaming, RecordIdentifier, HttpAuthentication::Basic::ControllerMethods, HttpAuthentication::Digest::ControllerMethods, diff --git a/actionpack/lib/action_controller/metal/data_streaming.rb b/actionpack/lib/action_controller/metal/data_streaming.rb new file mode 100644 index 0000000000..997bc6e958 --- /dev/null +++ b/actionpack/lib/action_controller/metal/data_streaming.rb @@ -0,0 +1,145 @@ +require 'active_support/core_ext/file/path' + +module ActionController #:nodoc: + # Methods for sending arbitrary data and for streaming files to the browser, + # instead of rendering. + module DataStreaming + extend ActiveSupport::Concern + + include ActionController::Rendering + + DEFAULT_SEND_FILE_OPTIONS = { + :type => 'application/octet-stream'.freeze, + :disposition => 'attachment'.freeze, + }.freeze + + protected + # Sends the file. This uses a server-appropriate method (such as X-Sendfile) + # via the Rack::Sendfile middleware. The header to use is set via + # config.action_dispatch.x_sendfile_header, and defaults to "X-Sendfile". + # Your server can also configure this for you by setting the X-Sendfile-Type header. + # + # Be careful to sanitize the path parameter if it is coming from a web + # page. send_file(params[:path]) allows a malicious user to + # download any file on your server. + # + # Options: + # * :filename - suggests a filename for the browser to use. + # Defaults to File.basename(path). + # * :type - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify + # either a string or a symbol for a registered type register with Mime::Type.register, for example :json + # * :disposition - specifies whether the file will be shown inline or downloaded. + # Valid values are 'inline' and 'attachment' (default). + # * :status - specifies the status code to send with the response. Defaults to '200 OK'. + # * :url_based_filename - set to +true+ if you want the browser guess the filename from + # the URL, which is necessary for i18n filenames on certain browsers + # (setting :filename overrides this option). + # + # The default Content-Type and Content-Disposition headers are + # set to download arbitrary binary files in as many browsers as + # possible. IE versions 4, 5, 5.5, and 6 are all known to have + # a variety of quirks (especially when downloading over SSL). + # + # Simple download: + # + # send_file '/path/to.zip' + # + # Show a JPEG in the browser: + # + # send_file '/path/to.jpeg', :type => 'image/jpeg', :disposition => 'inline' + # + # Show a 404 page in the browser: + # + # send_file '/path/to/404.html', :type => 'text/html; charset=utf-8', :status => 404 + # + # Read about the other Content-* HTTP headers if you'd like to + # provide the user with more information (such as Content-Description) in + # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11. + # + # Also be aware that the document may be cached by proxies and browsers. + # The Pragma and Cache-Control headers declare how the file may be cached + # by intermediaries. They default to require clients to validate with + # the server before releasing cached responses. See + # http://www.mnot.net/cache_docs/ for an overview of web caching and + # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 + # for the Cache-Control header spec. + def send_file(path, options = {}) #:doc: + raise MissingFile, "Cannot read file #{path}" unless File.file?(path) and File.readable?(path) + + options[:filename] ||= File.basename(path) unless options[:url_based_filename] + send_file_headers! options + + self.status = options[:status] || 200 + self.content_type = options[:content_type] if options.key?(:content_type) + self.response_body = File.open(path, "rb") + end + + # Sends the given binary data to the browser. This method is similar to + # render :text => data, but also allows you to specify whether + # the browser should display the response as a file attachment (i.e. in a + # download dialog) or as inline data. You may also set the content type, + # the apparent file name, and other things. + # + # Options: + # * :filename - suggests a filename for the browser to use. + # * :type - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify + # either a string or a symbol for a registered type register with Mime::Type.register, for example :json + # * :disposition - specifies whether the file will be shown inline or downloaded. + # Valid values are 'inline' and 'attachment' (default). + # * :status - specifies the status code to send with the response. Defaults to '200 OK'. + # + # Generic data download: + # + # send_data buffer + # + # Download a dynamically-generated tarball: + # + # send_data generate_tgz('dir'), :filename => 'dir.tgz' + # + # Display an image Active Record in the browser: + # + # send_data image.data, :type => image.content_type, :disposition => 'inline' + # + # See +send_file+ for more information on HTTP Content-* headers and caching. + def send_data(data, options = {}) #:doc: + send_file_headers! options.dup + render options.slice(:status, :content_type).merge(:text => data) + end + + private + def send_file_headers!(options) + options.update(DEFAULT_SEND_FILE_OPTIONS.merge(options)) + [:type, :disposition].each do |arg| + raise ArgumentError, ":#{arg} option required" if options[arg].nil? + end + + disposition = options[:disposition] + disposition += %(; filename="#{options[:filename]}") if options[:filename] + + content_type = options[:type] + + if content_type.is_a?(Symbol) + extension = Mime[content_type] + raise ArgumentError, "Unknown MIME type #{options[:type]}" unless extension + self.content_type = extension + else + self.content_type = content_type + end + + headers.merge!( + 'Content-Disposition' => disposition, + 'Content-Transfer-Encoding' => 'binary' + ) + + response.sending_file = true + + # Fix a problem with IE 6.0 on opening downloaded files: + # If Cache-Control: no-cache is set (which Rails does by default), + # IE removes the file it just downloaded from its cache immediately + # after it displays the "open/save" dialog, which means that if you + # hit "open" the file isn't there anymore when the application that + # is called for handling the download is run, so let's workaround that + response.cache_control[:public] ||= false + end + end +end diff --git a/actionpack/lib/action_controller/metal/streaming.rb b/actionpack/lib/action_controller/metal/streaming.rb deleted file mode 100644 index 312dc8eb3e..0000000000 --- a/actionpack/lib/action_controller/metal/streaming.rb +++ /dev/null @@ -1,145 +0,0 @@ -require 'active_support/core_ext/file/path' - -module ActionController #:nodoc: - # Methods for sending arbitrary data and for streaming files to the browser, - # instead of rendering. - module Streaming - extend ActiveSupport::Concern - - include ActionController::Rendering - - DEFAULT_SEND_FILE_OPTIONS = { - :type => 'application/octet-stream'.freeze, - :disposition => 'attachment'.freeze, - }.freeze - - protected - # Sends the file. This uses a server-appropriate method (such as X-Sendfile) - # via the Rack::Sendfile middleware. The header to use is set via - # config.action_dispatch.x_sendfile_header, and defaults to "X-Sendfile". - # Your server can also configure this for you by setting the X-Sendfile-Type header. - # - # Be careful to sanitize the path parameter if it is coming from a web - # page. send_file(params[:path]) allows a malicious user to - # download any file on your server. - # - # Options: - # * :filename - suggests a filename for the browser to use. - # Defaults to File.basename(path). - # * :type - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify - # either a string or a symbol for a registered type register with Mime::Type.register, for example :json - # * :disposition - specifies whether the file will be shown inline or downloaded. - # Valid values are 'inline' and 'attachment' (default). - # * :status - specifies the status code to send with the response. Defaults to '200 OK'. - # * :url_based_filename - set to +true+ if you want the browser guess the filename from - # the URL, which is necessary for i18n filenames on certain browsers - # (setting :filename overrides this option). - # - # The default Content-Type and Content-Disposition headers are - # set to download arbitrary binary files in as many browsers as - # possible. IE versions 4, 5, 5.5, and 6 are all known to have - # a variety of quirks (especially when downloading over SSL). - # - # Simple download: - # - # send_file '/path/to.zip' - # - # Show a JPEG in the browser: - # - # send_file '/path/to.jpeg', :type => 'image/jpeg', :disposition => 'inline' - # - # Show a 404 page in the browser: - # - # send_file '/path/to/404.html', :type => 'text/html; charset=utf-8', :status => 404 - # - # Read about the other Content-* HTTP headers if you'd like to - # provide the user with more information (such as Content-Description) in - # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11. - # - # Also be aware that the document may be cached by proxies and browsers. - # The Pragma and Cache-Control headers declare how the file may be cached - # by intermediaries. They default to require clients to validate with - # the server before releasing cached responses. See - # http://www.mnot.net/cache_docs/ for an overview of web caching and - # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9 - # for the Cache-Control header spec. - def send_file(path, options = {}) #:doc: - raise MissingFile, "Cannot read file #{path}" unless File.file?(path) and File.readable?(path) - - options[:filename] ||= File.basename(path) unless options[:url_based_filename] - send_file_headers! options - - self.status = options[:status] || 200 - self.content_type = options[:content_type] if options.key?(:content_type) - self.response_body = File.open(path, "rb") - end - - # Sends the given binary data to the browser. This method is similar to - # render :text => data, but also allows you to specify whether - # the browser should display the response as a file attachment (i.e. in a - # download dialog) or as inline data. You may also set the content type, - # the apparent file name, and other things. - # - # Options: - # * :filename - suggests a filename for the browser to use. - # * :type - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify - # either a string or a symbol for a registered type register with Mime::Type.register, for example :json - # * :disposition - specifies whether the file will be shown inline or downloaded. - # Valid values are 'inline' and 'attachment' (default). - # * :status - specifies the status code to send with the response. Defaults to '200 OK'. - # - # Generic data download: - # - # send_data buffer - # - # Download a dynamically-generated tarball: - # - # send_data generate_tgz('dir'), :filename => 'dir.tgz' - # - # Display an image Active Record in the browser: - # - # send_data image.data, :type => image.content_type, :disposition => 'inline' - # - # See +send_file+ for more information on HTTP Content-* headers and caching. - def send_data(data, options = {}) #:doc: - send_file_headers! options.dup - render options.slice(:status, :content_type).merge(:text => data) - end - - private - def send_file_headers!(options) - options.update(DEFAULT_SEND_FILE_OPTIONS.merge(options)) - [:type, :disposition].each do |arg| - raise ArgumentError, ":#{arg} option required" if options[arg].nil? - end - - disposition = options[:disposition] - disposition += %(; filename="#{options[:filename]}") if options[:filename] - - content_type = options[:type] - - if content_type.is_a?(Symbol) - extension = Mime[content_type] - raise ArgumentError, "Unknown MIME type #{options[:type]}" unless extension - self.content_type = extension - else - self.content_type = content_type - end - - headers.merge!( - 'Content-Disposition' => disposition, - 'Content-Transfer-Encoding' => 'binary' - ) - - response.sending_file = true - - # Fix a problem with IE 6.0 on opening downloaded files: - # If Cache-Control: no-cache is set (which Rails does by default), - # IE removes the file it just downloaded from its cache immediately - # after it displays the "open/save" dialog, which means that if you - # hit "open" the file isn't there anymore when the application that - # is called for handling the download is run, so let's workaround that - response.cache_control[:public] ||= false - end - end -end -- cgit v1.2.3 From 389d15ef139e50696b274f2d61dd309ba2632877 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 18 Apr 2011 08:52:29 +0200 Subject: Body... wanna *stream* my body? Body... such a thrill my body! Added stream as class level method to make it explicit when to stream. Render also accepts :stream as option. --- actionpack/lib/action_controller.rb | 1 + actionpack/lib/action_controller/base.rb | 1 + .../lib/action_controller/metal/streaming.rb | 57 ++++++++++++++++++++ actionpack/lib/action_view/context.rb | 1 + .../controller/new_base/render_streaming_test.rb | 62 ++++++++++++++++++++++ 5 files changed, 122 insertions(+) create mode 100644 actionpack/lib/action_controller/metal/streaming.rb create mode 100644 actionpack/test/controller/new_base/render_streaming_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 26e6ac770f..aab2b9dc25 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -31,6 +31,7 @@ module ActionController autoload :Rescue autoload :Responder autoload :SessionManagement + autoload :Streaming autoload :Testing autoload :UrlFor end diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 53e0a4b9d1..ca0dccf575 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -199,6 +199,7 @@ module ActionController Flash, RequestForgeryProtection, ForceSSL, + Streaming, DataStreaming, RecordIdentifier, HttpAuthentication::Basic::ControllerMethods, diff --git a/actionpack/lib/action_controller/metal/streaming.rb b/actionpack/lib/action_controller/metal/streaming.rb new file mode 100644 index 0000000000..adb3e94134 --- /dev/null +++ b/actionpack/lib/action_controller/metal/streaming.rb @@ -0,0 +1,57 @@ +require 'active_support/core_ext/file/path' +require 'rack/chunked' + +module ActionController #:nodoc: + # Methods for sending streaming templates back to the client. + module Streaming + extend ActiveSupport::Concern + + include AbstractController::Rendering + attr_internal :stream + + module ClassMethods + # Render streaming templates. It accepts :only, :except, :if and :unless as options + # to specify when to stream, as in ActionController filters. + def stream(options={}) + if defined?(Fiber) + before_filter :_stream_filter, options + else + raise "You cannot use streaming if Fiber is not available." + end + end + end + + protected + + # Mark following render calls as streaming. + def _stream_filter #:nodoc: + self.stream = true + end + + # Consider the stream option when normalazing options. + def _normalize_options(options) #:nodoc: + super + options[:stream] = self.stream unless options.key?(:stream) + end + + # Set proper cache control and transfer encoding when streaming + def _process_options(options) #:nodoc: + super + if options[:stream] + headers["Cache-Control"] ||= "no-cache" + headers["Transfer-Encoding"] = "chunked" + headers.delete("Content-Length") + end + end + + # Call render_to_body if we are streaming instead of usual +render+. + def _render_template(options) #:nodoc: + if options.delete(:stream) + Rack::Chunked::Body.new view_context.render_body(options) + else + super + end + end + end +end + \ No newline at end of file diff --git a/actionpack/lib/action_view/context.rb b/actionpack/lib/action_view/context.rb index 39d88333e8..a2a64de206 100644 --- a/actionpack/lib/action_view/context.rb +++ b/actionpack/lib/action_view/context.rb @@ -2,6 +2,7 @@ module ActionView module CompiledTemplates #:nodoc: # holds compiled template code end + # = Action View Context # # Action View contexts are supplied to Action Controller to render template. diff --git a/actionpack/test/controller/new_base/render_streaming_test.rb b/actionpack/test/controller/new_base/render_streaming_test.rb new file mode 100644 index 0000000000..27ba4b1a29 --- /dev/null +++ b/actionpack/test/controller/new_base/render_streaming_test.rb @@ -0,0 +1,62 @@ +require 'abstract_unit' + +module RenderStreaming + class BasicController < ActionController::Base + self.view_paths = [ActionView::FixtureResolver.new( + "render_streaming/basic/hello_world.html.erb" => "Hello world", + "layouts/application.html.erb" => "<%= yield %>, I'm here!" + )] + + layout "application" + stream :only => :hello_world + + def hello_world + end + + def explicit + render :action => "hello_world", :stream => true + end + + def no_layout + render :action => "hello_world", :stream => true, :layout => false + end + + def explicit_cache + headers["Cache-Control"] = "private" + render :action => "hello_world", :stream => true + end + end + + class StreamingTest < Rack::TestCase + test "rendering with streaming enabled at the class level" do + get "/render_streaming/basic/hello_world" + assert_body "b\r\nHello world\r\nb\r\n, I'm here!\r\n0\r\n\r\n" + assert_streaming! + end + + test "rendering with streaming given to render" do + get "/render_streaming/basic/explicit" + assert_body "b\r\nHello world\r\nb\r\n, I'm here!\r\n0\r\n\r\n" + assert_streaming! + end + + test "rendering with streaming do not override explicit cache control given to render" do + get "/render_streaming/basic/explicit_cache" + assert_body "b\r\nHello world\r\nb\r\n, I'm here!\r\n0\r\n\r\n" + assert_streaming! "private" + end + + test "rendering with streaming no layout" do + get "/render_streaming/basic/no_layout" + assert_body "b\r\nHello world\r\n0\r\n\r\n" + assert_streaming! + end + + def assert_streaming!(cache="no-cache") + assert_status 200 + assert_equal nil, headers["Content-Length"] + assert_equal "chunked", headers["Transfer-Encoding"] + assert_equal cache, headers["Cache-Control"] + end + end if defined?(Fiber) +end -- cgit v1.2.3 From 07fde1a3d36d0622d5fa9c040bfca70db675926a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 18 Apr 2011 14:25:51 +0200 Subject: Just define the controller if fibers are defined. --- actionpack/test/controller/new_base/render_streaming_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/new_base/render_streaming_test.rb b/actionpack/test/controller/new_base/render_streaming_test.rb index 27ba4b1a29..dbd6c66d1f 100644 --- a/actionpack/test/controller/new_base/render_streaming_test.rb +++ b/actionpack/test/controller/new_base/render_streaming_test.rb @@ -58,5 +58,5 @@ module RenderStreaming assert_equal "chunked", headers["Transfer-Encoding"] assert_equal cache, headers["Cache-Control"] end - end if defined?(Fiber) -end + end +end if defined?(Fiber) -- cgit v1.2.3 From 3b0f917b1dfabce6a6b338e4a7cb02995c055596 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 18 Apr 2011 14:27:30 +0200 Subject: Test explicit skip. --- actionpack/test/controller/new_base/render_streaming_test.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/new_base/render_streaming_test.rb b/actionpack/test/controller/new_base/render_streaming_test.rb index dbd6c66d1f..ffc4b331ec 100644 --- a/actionpack/test/controller/new_base/render_streaming_test.rb +++ b/actionpack/test/controller/new_base/render_streaming_test.rb @@ -8,11 +8,15 @@ module RenderStreaming )] layout "application" - stream :only => :hello_world + stream :only => [:hello_world, :skip] def hello_world end + def skip + render :action => "hello_world", :stream => false + end + def explicit render :action => "hello_world", :stream => true end @@ -52,6 +56,11 @@ module RenderStreaming assert_streaming! end + test "skip rendering with streaming at render level" do + get "/render_streaming/basic/skip" + assert_body "Hello world, I'm here!" + end + def assert_streaming!(cache="no-cache") assert_status 200 assert_equal nil, headers["Content-Length"] -- cgit v1.2.3 From 6380f1a9f45e68f38480c0805cac62eb6708f72e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 19 Apr 2011 10:34:17 +0200 Subject: Be sure to not store the closed flash in the session. --- actionpack/lib/action_dispatch/middleware/flash.rb | 41 +++++++++++++--------- actionpack/test/controller/flash_test.rb | 9 ++++- 2 files changed, 33 insertions(+), 17 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/middleware/flash.rb b/actionpack/lib/action_dispatch/middleware/flash.rb index 027ff7f8ac..414405cc9e 100644 --- a/actionpack/lib/action_dispatch/middleware/flash.rb +++ b/actionpack/lib/action_dispatch/middleware/flash.rb @@ -4,7 +4,7 @@ module ActionDispatch # read a notice you put there or flash["notice"] = "hello" # to put a new one. def flash - @env['action_dispatch.request.flash_hash'] ||= (session["flash"] || Flash::FlashHash.new) + @env[Flash::KEY] ||= (session["flash"] || Flash::FlashHash.new) end end @@ -40,18 +40,14 @@ module ActionDispatch # # See docs on the FlashHash class for more details about the flash. class Flash + KEY = 'action_dispatch.request.flash_hash'.freeze + class FlashNow #:nodoc: def initialize(flash) @flash = flash - @closed = false end - attr_reader :closed - alias :closed? :closed - def close!; @closed = true end - def []=(k, v) - raise ClosedError, :flash if closed? @flash[k] = v @flash.discard(k) v @@ -70,6 +66,10 @@ module ActionDispatch def notice=(message) self[:notice] = message end + + def close!(new_flash) + @flash = new_flash + end end class FlashHash @@ -81,10 +81,6 @@ module ActionDispatch @flashes = {} end - attr_reader :closed - alias :closed? :closed - def close!; @closed = true end - def []=(k, v) #:nodoc: raise ClosedError, :flash if closed? keep(k) @@ -152,6 +148,14 @@ module ActionDispatch @now ||= FlashNow.new(self) end + attr_reader :closed + alias :closed? :closed + + def close! + @closed = true + @now.close!(self) if @now + end + # Keeps either the entire current flash or a specific flash entry available for the next action: # # flash.keep # keeps the entire flash @@ -231,13 +235,18 @@ module ActionDispatch @app.call(env) ensure session = env['rack.session'] || {} - flash_hash = env['action_dispatch.request.flash_hash'] + flash_hash = env[KEY] if flash_hash - if !flash_hash.empty? || session.key?('flash') - session["flash"] = flash_hash - end - flash_hash.close! + if !flash_hash.empty? || session.key?('flash') + session["flash"] = flash_hash + new_hash = flash_hash.dup + else + new_hash = flash_hash + end + + env[KEY] = new_hash + new_hash.close! end if session.key?('flash') && session['flash'].empty? diff --git a/actionpack/test/controller/flash_test.rb b/actionpack/test/controller/flash_test.rb index 9c89f1334d..7b5bf8b21a 100644 --- a/actionpack/test/controller/flash_test.rb +++ b/actionpack/test/controller/flash_test.rb @@ -264,6 +264,14 @@ class FlashIntegrationTest < ActionDispatch::IntegrationTest end end + def test_setting_flash_does_not_raise_in_following_requests + with_test_route_set do + env = { 'action_dispatch.request.flash_hash' => ActionDispatch::Flash::FlashHash.new } + get '/set_flash', nil, env + get '/set_flash', nil, env + end + end + def test_setting_flash_raises_after_stream_back_to_client_even_with_an_empty_flash with_test_route_set do env = { 'action_dispatch.request.flash_hash' => ActionDispatch::Flash::FlashHash.new } @@ -294,7 +302,6 @@ class FlashIntegrationTest < ActionDispatch::IntegrationTest end end - private # Overwrite get to send SessionSecret in env hash -- cgit v1.2.3 From a66c91723565d37969de4cb46baa50fb8865b02a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 19 Apr 2011 11:54:12 +0200 Subject: Do not inherit from Rack::Response, remove a shit-ton of unused code. --- actionpack/lib/abstract_controller/rendering.rb | 8 +- .../lib/action_controller/metal/rendering.rb | 11 +++ actionpack/lib/action_dispatch/http/response.rb | 101 ++++++++++----------- actionpack/lib/action_dispatch/middleware/flash.rb | 1 + actionpack/test/dispatch/response_test.rb | 16 ---- 5 files changed, 61 insertions(+), 76 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index d0dd730b06..306bd41e2d 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -114,13 +114,7 @@ module AbstractController # :api: plugin def render_to_string(*args, &block) options = _normalize_render(*args, &block) - if self.response_body = render_to_body(options) - string = "" - response_body.each { |r| string << r } - string - end - ensure - self.response_body = nil + render_to_body(options) end # Raw rendering of a template to a Rack-compatible body. diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index 32d52c84c4..70fd79bb8b 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -18,6 +18,17 @@ module ActionController response_body end + # Overwrite render_to_string because body can now be set to a rack body. + def render_to_string(*) + if self.response_body = super + string = "" + response_body.each { |r| string << r } + string + end + ensure + self.response_body = nil + end + private # Normalize arguments by catching blocks and setting them on :update. diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index 8e03a7879f..78ecf177be 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -32,24 +32,35 @@ module ActionDispatch # :nodoc: # puts @response.body # end # end - class Response < Rack::Response - attr_accessor :request, :blank + class Response + attr_accessor :request, :header, :status + attr_writer :sending_file - attr_writer :header, :sending_file alias_method :headers=, :header= + alias_method :headers, :header + + delegate :[], :[]=, :to => :@header + delegate :each, :to => :@body + + # Sets the HTTP response's content MIME type. For example, in the controller + # you could write this: + # + # response.content_type = "text/plain" + # + # 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 + + CONTENT_TYPE = "Content-Type" + + cattr_accessor(:default_charset) { "utf-8" } module Setup def initialize(status = 200, header = {}, body = []) - @writer = lambda { |x| @body << x } - @block = nil - @length = 0 - - @header = header - self.body, self.status = body, status + self.body, self.header, self.status = body, header, status - @cookie = [] @sending_file = false - @blank = false if content_type = self["Content-Type"] @@ -62,6 +73,7 @@ module ActionDispatch # :nodoc: end end + include Rack::Response::Helpers include Setup include ActionDispatch::Http::Cache::Response @@ -106,13 +118,21 @@ module ActionDispatch # :nodoc: def body=(body) @blank = true if body == EMPTY - @body = body.respond_to?(:to_str) ? [body] : body + @body = body.respond_to?(:each) ? body : [body] end def body_parts @body end + def set_cookie(key, value) + ::Rack::Utils.set_cookie_header!(header, key, value) + end + + def delete_cookie(key, value={}) + ::Rack::Utils.delete_cookie_header!(header, key, value) + end + def location headers['Location'] end @@ -122,46 +142,21 @@ module ActionDispatch # :nodoc: headers['Location'] = url end - # Sets the HTTP response's content MIME type. For example, in the controller - # you could write this: - # - # response.content_type = "text/plain" - # - # 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 - - CONTENT_TYPE = "Content-Type" - - cattr_accessor(:default_charset) { "utf-8" } - def to_a assign_default_content_type_and_charset! handle_conditional_get! - self["Set-Cookie"] = self["Set-Cookie"].join("\n") if self["Set-Cookie"].respond_to?(:join) - super - end - alias prepare! to_a + @header["Set-Cookie"] = @header["Set-Cookie"].join("\n") if @header["Set-Cookie"].respond_to?(:join) - def each(&callback) - if @body.respond_to?(:call) - @writer = lambda { |x| callback.call(x) } - @body.call(self, self) + if [204, 304].include?(@status) + @header.delete "Content-Type" + [@status, @header, []] else - @body.each { |part| callback.call(part.to_s) } + [@status, @header, self] end - - @writer = callback - @block.call(self) if @block - end - - def write(str) - str = str.to_s - @writer.call str - str end + alias prepare! to_a + alias to_ary to_a # For implicit splat on 1.9.2 # Returns the response cookies, converted to a Hash of (name => value) pairs # @@ -180,18 +175,18 @@ module ActionDispatch # :nodoc: cookies end - private - def assign_default_content_type_and_charset! - return if headers[CONTENT_TYPE].present? + private - @content_type ||= Mime::HTML - @charset ||= self.class.default_charset + def assign_default_content_type_and_charset! + return if headers[CONTENT_TYPE].present? - type = @content_type.to_s.dup - type << "; charset=#{@charset}" unless @sending_file + @content_type ||= Mime::HTML + @charset ||= self.class.default_charset - headers[CONTENT_TYPE] = type - end + type = @content_type.to_s.dup + type << "; charset=#{@charset}" unless @sending_file + headers[CONTENT_TYPE] = type + end end end diff --git a/actionpack/lib/action_dispatch/middleware/flash.rb b/actionpack/lib/action_dispatch/middleware/flash.rb index 414405cc9e..735c72d34a 100644 --- a/actionpack/lib/action_dispatch/middleware/flash.rb +++ b/actionpack/lib/action_dispatch/middleware/flash.rb @@ -79,6 +79,7 @@ module ActionDispatch @used = Set.new @closed = false @flashes = {} + @now = nil end def []=(k, v) #:nodoc: diff --git a/actionpack/test/dispatch/response_test.rb b/actionpack/test/dispatch/response_test.rb index 6f38714b2e..5abbaf74fe 100644 --- a/actionpack/test/dispatch/response_test.rb +++ b/actionpack/test/dispatch/response_test.rb @@ -33,22 +33,6 @@ class ResponseTest < ActiveSupport::TestCase }, headers) end - test "streaming block" do - @response.body = Proc.new do |response, output| - 5.times { |n| output.write(n) } - end - - status, headers, body = @response.to_a - assert_equal 200, status - assert_equal({ - "Content-Type" => "text/html; charset=utf-8" - }, headers) - - parts = [] - body.each { |part| parts << part.to_s } - assert_equal ["0", "1", "2", "3", "4"], parts - end - test "content type" do [204, 304].each do |c| @response.status = c.to_s -- cgit v1.2.3 From b398520c1406824efd12df6bb57996aa9781f876 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 19 Apr 2011 12:25:01 +0200 Subject: Output a redirect to the 500 page if something happens when streaming. Currently, we output: "> --- actionpack/lib/action_view/base.rb | 6 ++++++ .../renderer/streaming_template_renderer.rb | 11 +++++----- .../controller/new_base/render_streaming_test.rb | 24 +++++++++++++++++++++- 3 files changed, 35 insertions(+), 6 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 9e8a3c51a3..87501d5b88 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -137,6 +137,12 @@ module ActionView #:nodoc: cattr_accessor :field_error_proc @@field_error_proc = Proc.new{ |html_tag, instance| "
#{html_tag}
".html_safe } + # How to complete the streaming when an exception occurs. + # This is our best guess: first try to close the attribute, then the tag. + # Currently this is private API and may be changed at *any* time. + cattr_accessor :streaming_completion_on_exception + @@streaming_completion_on_exception = %(">) + class_attribute :helpers class_attribute :_routes diff --git a/actionpack/lib/action_view/renderer/streaming_template_renderer.rb b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb index 52f0e9f5bd..03aab444f8 100644 --- a/actionpack/lib/action_view/renderer/streaming_template_renderer.rb +++ b/actionpack/lib/action_view/renderer/streaming_template_renderer.rb @@ -46,11 +46,8 @@ module ActionView # # == TODO # - # * Add streaming support in the controllers with no-cache settings - # * What should happen when an error happens? # * Support streaming from child templates, partials and so on. - # * Support on sprockets async JS load? - # + # * Integrate exceptions with exceptron class StreamingTemplateRenderer < TemplateRenderer #:nodoc: # A valid Rack::Body (i.e. it responds to each). # It is initialized with a block that, when called, starts @@ -61,7 +58,11 @@ module ActionView end def each(&block) - @start.call(block) + begin + @start.call(block) + rescue + block.call ActionView::Base.streaming_completion_on_exception + end self end end diff --git a/actionpack/test/controller/new_base/render_streaming_test.rb b/actionpack/test/controller/new_base/render_streaming_test.rb index ffc4b331ec..b8df5ec4e8 100644 --- a/actionpack/test/controller/new_base/render_streaming_test.rb +++ b/actionpack/test/controller/new_base/render_streaming_test.rb @@ -4,7 +4,9 @@ module RenderStreaming class BasicController < ActionController::Base self.view_paths = [ActionView::FixtureResolver.new( "render_streaming/basic/hello_world.html.erb" => "Hello world", - "layouts/application.html.erb" => "<%= yield %>, I'm here!" + "render_streaming/basic/boom.html.erb" => "<%= nil.invalid! %>", + "layouts/application.html.erb" => "<%= yield %>, I'm here!", + "layouts/boom.html.erb" => "\"<%= yield %>" )] layout "application" @@ -13,6 +15,14 @@ module RenderStreaming def hello_world end + def layout_exception + render :action => "hello_world", :stream => true, :layout => "boom" + end + + def template_exception + render :action => "boom", :stream => true + end + def skip render :action => "hello_world", :stream => false end @@ -61,6 +71,18 @@ module RenderStreaming assert_body "Hello world, I'm here!" end + test "rendering with layout exception" do + get "/render_streaming/basic/layout_exception" + assert_body "d\r\n\r\n0\r\n\r\n" + assert_streaming! + end + + test "rendering with template exception" do + get "/render_streaming/basic/template_exception" + assert_body "4e\r\n\">\r\n0\r\n\r\n" + assert_streaming! + end + def assert_streaming!(cache="no-cache") assert_status 200 assert_equal nil, headers["Content-Length"] -- cgit v1.2.3 From 069e9b004f91c4ace1373ab5203bb00ab41bd1f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 19 Apr 2011 15:04:28 +0200 Subject: Do not stream on HTTP/1.0. --- actionpack/lib/action_controller/metal/streaming.rb | 10 +++++++--- actionpack/test/controller/new_base/render_streaming_test.rb | 8 ++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/streaming.rb b/actionpack/lib/action_controller/metal/streaming.rb index adb3e94134..b9bd49f670 100644 --- a/actionpack/lib/action_controller/metal/streaming.rb +++ b/actionpack/lib/action_controller/metal/streaming.rb @@ -38,9 +38,13 @@ module ActionController #:nodoc: def _process_options(options) #:nodoc: super if options[:stream] - headers["Cache-Control"] ||= "no-cache" - headers["Transfer-Encoding"] = "chunked" - headers.delete("Content-Length") + if env["HTTP_VERSION"] == "HTTP/1.0" + options.delete(:stream) + else + headers["Cache-Control"] ||= "no-cache" + headers["Transfer-Encoding"] = "chunked" + headers.delete("Content-Length") + end end end diff --git a/actionpack/test/controller/new_base/render_streaming_test.rb b/actionpack/test/controller/new_base/render_streaming_test.rb index b8df5ec4e8..fed8d40b47 100644 --- a/actionpack/test/controller/new_base/render_streaming_test.rb +++ b/actionpack/test/controller/new_base/render_streaming_test.rb @@ -83,6 +83,14 @@ module RenderStreaming assert_streaming! end + test "do not stream on HTTP/1.0" do + get "/render_streaming/basic/hello_world", nil, "HTTP_VERSION" => "HTTP/1.0" + assert_body "Hello world, I'm here!" + assert_status 200 + assert_equal "22", headers["Content-Length"] + assert_equal nil, headers["Transfer-Encoding"] + end + def assert_streaming!(cache="no-cache") assert_status 200 assert_equal nil, headers["Content-Length"] -- cgit v1.2.3 From a3a5c7eba39c64413abd0fb4766282c9f071d248 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Tue, 19 Apr 2011 18:07:14 +0200 Subject: All assets, including images, audio, and video, now uses the asset pipeline when its on --- .../lib/action_view/helpers/asset_tag_helper.rb | 18 +++++++++++++++--- .../lib/action_view/helpers/sprockets_helper.rb | 15 ++++++++++----- .../test/fixtures/sprockets/app/images/logo.png | Bin 0 -> 6646 bytes actionpack/test/template/sprockets_helper_test.rb | 19 +++++++++++++++++++ 4 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 actionpack/test/fixtures/sprockets/app/images/logo.png (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index f6b2d4f3f4..10bdede1b4 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -274,7 +274,11 @@ module ActionView # The alias +path_to_image+ is provided to avoid that. Rails uses the alias internally, and # plugin authors are encouraged to do so. def image_path(source) - asset_paths.compute_public_path(source, 'images') + if config.use_sprockets + sprockets_asset_path(source) + else + asset_paths.compute_public_path(source, 'images') + end end alias_method :path_to_image, :image_path # aliased to avoid conflicts with an image_path named route @@ -289,7 +293,11 @@ module ActionView # video_path("/trailers/hd.avi") # => /trailers/hd.avi # video_path("http://www.railsapplication.com/vid/hd.avi") # => http://www.railsapplication.com/vid/hd.avi def video_path(source) - asset_paths.compute_public_path(source, 'videos') + if config.use_sprockets + sprockets_asset_path(source) + else + asset_paths.compute_public_path(source, 'videos') + end end alias_method :path_to_video, :video_path # aliased to avoid conflicts with a video_path named route @@ -304,7 +312,11 @@ module ActionView # audio_path("/sounds/horse.wav") # => /sounds/horse.wav # audio_path("http://www.railsapplication.com/sounds/horse.wav") # => http://www.railsapplication.com/sounds/horse.wav def audio_path(source) - asset_paths.compute_public_path(source, 'audios') + if config.use_sprockets + sprockets_asset_path(source) + else + asset_paths.compute_public_path(source, 'audios') + end end alias_method :path_to_audio, :audio_path # aliased to avoid conflicts with an audio_path named route diff --git a/actionpack/lib/action_view/helpers/sprockets_helper.rb b/actionpack/lib/action_view/helpers/sprockets_helper.rb index 408a2030ab..fee13be886 100644 --- a/actionpack/lib/action_view/helpers/sprockets_helper.rb +++ b/actionpack/lib/action_view/helpers/sprockets_helper.rb @@ -3,8 +3,12 @@ require 'uri' module ActionView module Helpers module SprocketsHelper + def sprockets_asset_path(source, default_ext = nil) + compute_sprockets_path(source, 'assets', default_ext) + end + def sprockets_javascript_path(source) - compute_sprockets_path source, 'assets', 'js' + sprockets_asset_path(source, 'js') end def sprockets_javascript_include_tag(source, options = {}) @@ -17,9 +21,9 @@ module ActionView end def sprockets_stylesheet_path(source) - compute_sprockets_path source, 'assets', 'css' + sprockets_asset_path(source, 'css') end - + def sprockets_stylesheet_link_tag(source, options = {}) options = { 'rel' => "stylesheet", @@ -31,13 +35,14 @@ module ActionView tag 'link', options end + private - def compute_sprockets_path(source, dir, default_ext) + def compute_sprockets_path(source, dir, default_ext = nil) source = source.to_s return source if URI.parse(source).host - # Add /javscripts to relative paths + # Add /assets to relative paths if source[0] != ?/ source = "/#{dir}/#{source}" end diff --git a/actionpack/test/fixtures/sprockets/app/images/logo.png b/actionpack/test/fixtures/sprockets/app/images/logo.png new file mode 100644 index 0000000000..d5edc04e65 Binary files /dev/null and b/actionpack/test/fixtures/sprockets/app/images/logo.png differ diff --git a/actionpack/test/template/sprockets_helper_test.rb b/actionpack/test/template/sprockets_helper_test.rb index 67aee86d02..67774c1893 100644 --- a/actionpack/test/template/sprockets_helper_test.rb +++ b/actionpack/test/template/sprockets_helper_test.rb @@ -22,6 +22,7 @@ class SprocketsHelperTest < ActionView::TestCase @assets = Sprockets::Environment.new @assets.paths << FIXTURES.join("sprockets/app/javascripts") @assets.paths << FIXTURES.join("sprockets/app/stylesheets") + @assets.paths << FIXTURES.join("sprockets/app/images") config.perform_caching = true end @@ -30,6 +31,24 @@ class SprocketsHelperTest < ActionView::TestCase "http://www.example.com" end + test "asset path" do + assert_equal "/assets/logo-9c0a079bdd7701d7e729bd956823d153.png", + sprockets_asset_path("logo.png") + + assert_equal "/images/logo", + sprockets_asset_path("/images/logo") + assert_equal "/images/logo.gif", + sprockets_asset_path("/images/logo.gif") + + assert_equal "/dir/audio", + sprockets_asset_path("/dir/audio") + + assert_equal "http://www.example.com/video/play", + sprockets_asset_path("http://www.example.com/video/play") + assert_equal "http://www.example.com/video/play.mp4", + sprockets_asset_path("http://www.example.com/video/play.mp4") + end + test "javascript path" do assert_equal "/assets/application-d41d8cd98f00b204e9800998ecf8427e.js", sprockets_javascript_path(:application) -- cgit v1.2.3 From d35c91225e8eea967358328ba618e6608222a615 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Tue, 19 Apr 2011 18:29:18 +0200 Subject: Cleanup compute_sprockets_path -- when you are reaching for code comments, the method could be simpler --- .../lib/action_view/helpers/sprockets_helper.rb | 51 +++++++++++++--------- 1 file changed, 30 insertions(+), 21 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/sprockets_helper.rb b/actionpack/lib/action_view/helpers/sprockets_helper.rb index fee13be886..d2a31c02d4 100644 --- a/actionpack/lib/action_view/helpers/sprockets_helper.rb +++ b/actionpack/lib/action_view/helpers/sprockets_helper.rb @@ -11,6 +11,11 @@ module ActionView sprockets_asset_path(source, 'js') end + def sprockets_stylesheet_path(source) + sprockets_asset_path(source, 'css') + end + + def sprockets_javascript_include_tag(source, options = {}) options = { 'type' => "text/javascript", @@ -20,10 +25,6 @@ module ActionView content_tag 'script', "", options end - def sprockets_stylesheet_path(source) - sprockets_asset_path(source, 'css') - end - def sprockets_stylesheet_link_tag(source, options = {}) options = { 'rel' => "stylesheet", @@ -40,30 +41,38 @@ module ActionView def compute_sprockets_path(source, dir, default_ext = nil) source = source.to_s - return source if URI.parse(source).host - - # Add /assets to relative paths - if source[0] != ?/ - source = "/#{dir}/#{source}" + unless source_is_a_url?(source) + add_asset_directory(source, dir) + add_default_extension(source, default_ext) + add_fingerprint(source, dir) + add_asset_host(source) end - # Add default extension if there isn't one - if default_ext && File.extname(source).empty? - source = "#{source}.#{default_ext}" - end - - # Fingerprint url - if source =~ /^\/#{dir}\/(.+)/ - source = assets.path($1, config.perform_caching, dir) - end + source + end + + def add_asset_directory(source, dir) + source.replace("/#{dir}/#{source}") if source[0] != ?/ + end + + def add_default_extension(source, default_ext) + source.replace("#{source}.#{default_ext}") if default_ext && File.extname(source).empty? + end + + def add_fingerprint(source, dir) + source.replace(assets.path($1, config.perform_caching, dir)) if source =~ /^\/#{dir}\/(.+)/ + end + def add_asset_host(source) host = compute_asset_host(source) if controller.respond_to?(:request) && host && URI.parse(host).host - source = "#{controller.request.protocol}#{host}#{source}" + source.replace("#{controller.request.protocol}#{host}#{source}") end - - source + end + + def source_is_a_url?(source) + URI.parse(source).host.present? end def compute_asset_host(source) -- cgit v1.2.3 From 626bcc9bf415ca9872bbdaceac30a4df9aca86bb Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Tue, 19 Apr 2011 19:05:07 +0200 Subject: Switch to asset_path and make it available in the Sprockets::Context (now you can do asset_path("logo.png") in a stylesheet.css.erb file and get fingerprinting) --- .../lib/action_view/helpers/asset_tag_helper.rb | 6 ++-- .../asset_tag_helpers/javascript_tag_helpers.rb | 2 +- .../asset_tag_helpers/stylesheet_tag_helpers.rb | 2 +- .../lib/action_view/helpers/sprockets_helper.rb | 32 ++++++++++------- actionpack/test/template/sprockets_helper_test.rb | 40 ++++++++++------------ 5 files changed, 42 insertions(+), 40 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index 10bdede1b4..e859b3ae49 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -275,7 +275,7 @@ module ActionView # plugin authors are encouraged to do so. def image_path(source) if config.use_sprockets - sprockets_asset_path(source) + asset_path(source) else asset_paths.compute_public_path(source, 'images') end @@ -294,7 +294,7 @@ module ActionView # video_path("http://www.railsapplication.com/vid/hd.avi") # => http://www.railsapplication.com/vid/hd.avi def video_path(source) if config.use_sprockets - sprockets_asset_path(source) + asset_path(source) else asset_paths.compute_public_path(source, 'videos') end @@ -313,7 +313,7 @@ module ActionView # audio_path("http://www.railsapplication.com/sounds/horse.wav") # => http://www.railsapplication.com/sounds/horse.wav def audio_path(source) if config.use_sprockets - sprockets_asset_path(source) + asset_path(source) else asset_paths.compute_public_path(source, 'audios') end diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb index ce5a7dc2e5..a0f6fb5692 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb @@ -87,7 +87,7 @@ module ActionView # javascript_path "http://www.railsapplication.com/js/xmlhr.js" # => http://www.railsapplication.com/js/xmlhr.js def javascript_path(source) if config.use_sprockets - sprockets_javascript_path(source) + asset_path(source, 'js') else asset_paths.compute_public_path(source, 'javascripts', 'js') end diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb index a994afb65e..309762ee05 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb @@ -64,7 +64,7 @@ module ActionView # stylesheet_path "http://www.railsapplication.com/css/style.css" # => http://www.railsapplication.com/css/style.css def stylesheet_path(source) if config.use_sprockets - sprockets_stylesheet_path(source) + asset_path(source, 'css') else asset_paths.compute_public_path(source, 'stylesheets', 'css') end diff --git a/actionpack/lib/action_view/helpers/sprockets_helper.rb b/actionpack/lib/action_view/helpers/sprockets_helper.rb index d2a31c02d4..bf47af6e10 100644 --- a/actionpack/lib/action_view/helpers/sprockets_helper.rb +++ b/actionpack/lib/action_view/helpers/sprockets_helper.rb @@ -3,23 +3,14 @@ require 'uri' module ActionView module Helpers module SprocketsHelper - def sprockets_asset_path(source, default_ext = nil) + def asset_path(source, default_ext = nil) compute_sprockets_path(source, 'assets', default_ext) end - def sprockets_javascript_path(source) - sprockets_asset_path(source, 'js') - end - - def sprockets_stylesheet_path(source) - sprockets_asset_path(source, 'css') - end - - def sprockets_javascript_include_tag(source, options = {}) options = { 'type' => "text/javascript", - 'src' => sprockets_javascript_path(source) + 'src' => asset_path(source, 'js') }.merge(options.stringify_keys) content_tag 'script', "", options @@ -30,7 +21,7 @@ module ActionView 'rel' => "stylesheet", 'type' => "text/css", 'media' => "screen", - 'href' => sprockets_stylesheet_path(source) + 'href' => asset_path(source, 'css') }.merge(options.stringify_keys) tag 'link', options @@ -60,10 +51,15 @@ module ActionView end def add_fingerprint(source, dir) - source.replace(assets.path($1, config.perform_caching, dir)) if source =~ /^\/#{dir}\/(.+)/ + if source =~ /^\/#{dir}\/(.+)/ + source.replace(assets.path($1, performing_caching?, dir)) + end end def add_asset_host(source) + # When included in Sprockets::Context, there's no controller + return unless respond_to?(:controller) + host = compute_asset_host(source) if controller.respond_to?(:request) && host && URI.parse(host).host @@ -94,6 +90,16 @@ module ActionView def assets Rails.application.assets end + + def performing_caching? + # When included in Sprockets::Context, we need to ask the top-level config as the controller is not available + respond_to?(:config) ? config.perform_caching : Rails.application.config.action_controller.perform_caching + end end end end + +# FIXME: Temp hack for extending Sprockets::Context so +class Sprockets::Context + include ActionView::Helpers::SprocketsHelper +end if defined?(Sprockets) \ No newline at end of file diff --git a/actionpack/test/template/sprockets_helper_test.rb b/actionpack/test/template/sprockets_helper_test.rb index 67774c1893..863e473697 100644 --- a/actionpack/test/template/sprockets_helper_test.rb +++ b/actionpack/test/template/sprockets_helper_test.rb @@ -33,38 +33,38 @@ class SprocketsHelperTest < ActionView::TestCase test "asset path" do assert_equal "/assets/logo-9c0a079bdd7701d7e729bd956823d153.png", - sprockets_asset_path("logo.png") + asset_path("logo.png") assert_equal "/images/logo", - sprockets_asset_path("/images/logo") + asset_path("/images/logo") assert_equal "/images/logo.gif", - sprockets_asset_path("/images/logo.gif") + asset_path("/images/logo.gif") assert_equal "/dir/audio", - sprockets_asset_path("/dir/audio") + asset_path("/dir/audio") assert_equal "http://www.example.com/video/play", - sprockets_asset_path("http://www.example.com/video/play") + asset_path("http://www.example.com/video/play") assert_equal "http://www.example.com/video/play.mp4", - sprockets_asset_path("http://www.example.com/video/play.mp4") + asset_path("http://www.example.com/video/play.mp4") end test "javascript path" do assert_equal "/assets/application-d41d8cd98f00b204e9800998ecf8427e.js", - sprockets_javascript_path(:application) + asset_path(:application, "js") assert_equal "/assets/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js", - sprockets_javascript_path("xmlhr") + asset_path("xmlhr", "js") assert_equal "/assets/dir/xmlhr-d41d8cd98f00b204e9800998ecf8427e.js", - sprockets_javascript_path("dir/xmlhr.js") + asset_path("dir/xmlhr.js", "js") assert_equal "/dir/xmlhr.js", - sprockets_javascript_path("/dir/xmlhr") + asset_path("/dir/xmlhr", "js") assert_equal "http://www.railsapplication.com/js/xmlhr", - sprockets_javascript_path("http://www.railsapplication.com/js/xmlhr") + asset_path("http://www.railsapplication.com/js/xmlhr", "js") assert_equal "http://www.railsapplication.com/js/xmlhr.js", - sprockets_javascript_path("http://www.railsapplication.com/js/xmlhr.js") + asset_path("http://www.railsapplication.com/js/xmlhr.js", "js") end test "javascript include tag" do @@ -80,20 +80,16 @@ class SprocketsHelperTest < ActionView::TestCase end test "stylesheet path" do - assert_equal "/assets/application-d41d8cd98f00b204e9800998ecf8427e.css", - sprockets_stylesheet_path(:application) + assert_equal "/assets/application-d41d8cd98f00b204e9800998ecf8427e.css", asset_path(:application, "css") - assert_equal "/assets/style-d41d8cd98f00b204e9800998ecf8427e.css", - sprockets_stylesheet_path("style") - assert_equal "/assets/dir/style-d41d8cd98f00b204e9800998ecf8427e.css", - sprockets_stylesheet_path("dir/style.css") - assert_equal "/dir/style.css", - sprockets_stylesheet_path("/dir/style.css") + assert_equal "/assets/style-d41d8cd98f00b204e9800998ecf8427e.css", asset_path("style", "css") + assert_equal "/assets/dir/style-d41d8cd98f00b204e9800998ecf8427e.css", asset_path("dir/style.css", "css") + assert_equal "/dir/style.css", asset_path("/dir/style.css", "css") assert_equal "http://www.railsapplication.com/css/style", - sprockets_stylesheet_path("http://www.railsapplication.com/css/style") + asset_path("http://www.railsapplication.com/css/style", "css") assert_equal "http://www.railsapplication.com/css/style.css", - sprockets_stylesheet_path("http://www.railsapplication.com/css/style.css") + asset_path("http://www.railsapplication.com/css/style.css", "css") end test "stylesheet link tag" do -- cgit v1.2.3 From 914218ef302542f3f58ef7f8f46c0ff0b540ac82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 19 Apr 2011 21:14:55 +0200 Subject: Let's use inheritance here, shall we? --- .../helpers/asset_tag_helpers/asset_include_tag.rb | 5 +- .../helpers/asset_tag_helpers/asset_paths.rb | 13 ++-- .../asset_tag_helpers/javascript_tag_helpers.rb | 3 - .../asset_tag_helpers/stylesheet_tag_helpers.rb | 3 - .../lib/action_view/helpers/sprockets_helper.rb | 77 +++++++--------------- actionpack/test/template/sprockets_helper_test.rb | 8 +++ 6 files changed, 43 insertions(+), 66 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb index 52eb43a1cd..e4662a2919 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb @@ -8,9 +8,11 @@ module ActionView module AssetTagHelper class AssetIncludeTag - attr_reader :config, :asset_paths + include TagHelper + attr_reader :config, :asset_paths class_attribute :expansions + def self.inherited(base) base.expansions = { } end @@ -56,7 +58,6 @@ module ActionView end end - private def path_to_asset(source, include_host = true) diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb index 1e00fd996b..955634bb19 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb @@ -26,15 +26,18 @@ module ActionView # roots. Rewrite the asset path for cache-busting asset ids. Include # asset host, if configured, with the correct request protocol. def compute_public_path(source, dir, ext = nil, include_host = true) + source = source.to_s return source if is_uri?(source) source = rewrite_extension(source, dir, ext) if ext source = "/#{dir}/#{source}" unless source[0] == ?/ - source = rewrite_asset_path(source, config.asset_path) + source = rewrite_asset_path(source, dir) - has_request = controller.respond_to?(:request) - source = rewrite_relative_url_root(source, controller.config.relative_url_root) if has_request && include_host - source = rewrite_host_and_protocol(source, has_request) if include_host + if controller && include_host + has_request = controller.respond_to?(:request) + source = rewrite_relative_url_root(source, controller.config.relative_url_root) if has_request + source = rewrite_host_and_protocol(source, has_request) + end source end @@ -70,6 +73,8 @@ module ActionView # Break out the asset path rewrite in case plugins wish to put the asset id # someplace other than the query string. def rewrite_asset_path(source, path = nil) + path = config.asset_path + if path && path.respond_to?(:call) return path.call(source) elsif path && path.is_a?(String) diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb index a0f6fb5692..07ff49659a 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb @@ -1,6 +1,5 @@ require 'active_support/concern' require 'active_support/core_ext/file' -require 'action_view/helpers/tag_helper' require 'action_view/helpers/asset_tag_helpers/asset_include_tag' module ActionView @@ -8,8 +7,6 @@ module ActionView module AssetTagHelper class JavascriptIncludeTag < AssetIncludeTag - include TagHelper - def asset_name 'javascript' end diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb index 309762ee05..c3dcd410bb 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb @@ -1,6 +1,5 @@ require 'active_support/concern' require 'active_support/core_ext/file' -require 'action_view/helpers/tag_helper' require 'action_view/helpers/asset_tag_helpers/asset_include_tag' module ActionView @@ -8,8 +7,6 @@ module ActionView module AssetTagHelper class StylesheetIncludeTag < AssetIncludeTag - include TagHelper - def asset_name 'stylesheet' end diff --git a/actionpack/lib/action_view/helpers/sprockets_helper.rb b/actionpack/lib/action_view/helpers/sprockets_helper.rb index bf47af6e10..e2e844c74d 100644 --- a/actionpack/lib/action_view/helpers/sprockets_helper.rb +++ b/actionpack/lib/action_view/helpers/sprockets_helper.rb @@ -1,10 +1,11 @@ require 'uri' +require 'action_view/helpers/asset_tag_helpers/asset_paths' module ActionView module Helpers module SprocketsHelper def asset_path(source, default_ext = nil) - compute_sprockets_path(source, 'assets', default_ext) + sprockets_asset_paths.compute_public_path(source, 'assets', default_ext, true) end def sprockets_javascript_include_tag(source, options = {}) @@ -27,74 +28,42 @@ module ActionView tag 'link', options end - private - def compute_sprockets_path(source, dir, default_ext = nil) - source = source.to_s - - unless source_is_a_url?(source) - add_asset_directory(source, dir) - add_default_extension(source, default_ext) - add_fingerprint(source, dir) - add_asset_host(source) - end - source - end - - def add_asset_directory(source, dir) - source.replace("/#{dir}/#{source}") if source[0] != ?/ - end - - def add_default_extension(source, default_ext) - source.replace("#{source}.#{default_ext}") if default_ext && File.extname(source).empty? - end - - def add_fingerprint(source, dir) - if source =~ /^\/#{dir}\/(.+)/ - source.replace(assets.path($1, performing_caching?, dir)) - end + def sprockets_asset_paths + @sprockets_asset_paths ||= begin + config = self.config if respond_to?(:config) + controller = self.controller if respond_to?(:controller) + SprocketsHelper::AssetPaths.new(config, controller) end + end - def add_asset_host(source) - # When included in Sprockets::Context, there's no controller - return unless respond_to?(:controller) - - host = compute_asset_host(source) - - if controller.respond_to?(:request) && host && URI.parse(host).host - source.replace("#{controller.request.protocol}#{host}#{source}") + class AssetPaths < ActionView::Helpers::AssetTagHelper::AssetPaths + def rewrite_asset_path(source, dir) + if source =~ /^\/#{dir}\/(.+)/ + assets.path($1, performing_caching?, dir) + else + source end end - - def source_is_a_url?(source) - URI.parse(source).host.present? - end - def compute_asset_host(source) - if host = config.asset_host - if host.is_a?(Proc) || host.respond_to?(:call) - case host.is_a?(Proc) ? host.arity : host.method(:call).arity - when 2 - request = controller.respond_to?(:request) && controller.request - host.call(source, request) - else - host.call(source) - end - else - (host =~ /%d/) ? host % (source.hash % 4) : host - end + def rewrite_extension(source, dir, ext) + if ext && File.extname(source).empty? + "#{source}.#{ext}" + else + source end end def assets Rails.application.assets end - + + # When included in Sprockets::Context, we need to ask the top-level config as the controller is not available def performing_caching? - # When included in Sprockets::Context, we need to ask the top-level config as the controller is not available - respond_to?(:config) ? config.perform_caching : Rails.application.config.action_controller.perform_caching + @config ? @config.perform_caching : Rails.application.config.action_controller.perform_caching end + end end end end diff --git a/actionpack/test/template/sprockets_helper_test.rb b/actionpack/test/template/sprockets_helper_test.rb index 863e473697..d8aef34bfb 100644 --- a/actionpack/test/template/sprockets_helper_test.rb +++ b/actionpack/test/template/sprockets_helper_test.rb @@ -1,5 +1,8 @@ require 'abstract_unit' require 'sprockets' +require 'mocha' + +module Rails; end class SprocketsHelperTest < ActionView::TestCase tests ActionView::Helpers::SprocketsHelper @@ -24,6 +27,11 @@ class SprocketsHelperTest < ActionView::TestCase @assets.paths << FIXTURES.join("sprockets/app/stylesheets") @assets.paths << FIXTURES.join("sprockets/app/images") + application = Object.new + Rails.stubs(:application).returns(application) + application.stubs(:config).returns(config) + application.stubs(:assets).returns(@assets) + config.perform_caching = true end -- cgit v1.2.3 From a19c260038a9b5b688a2e8d883b604983ac59eae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 19 Apr 2011 21:49:28 +0200 Subject: Include modules to the context in the railtie. --- actionpack/lib/action_view/helpers/sprockets_helper.rb | 7 +------ actionpack/lib/sprockets/railtie.rb | 6 ++++++ 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/sprockets_helper.rb b/actionpack/lib/action_view/helpers/sprockets_helper.rb index e2e844c74d..947c827f3c 100644 --- a/actionpack/lib/action_view/helpers/sprockets_helper.rb +++ b/actionpack/lib/action_view/helpers/sprockets_helper.rb @@ -66,9 +66,4 @@ module ActionView end end end -end - -# FIXME: Temp hack for extending Sprockets::Context so -class Sprockets::Context - include ActionView::Helpers::SprocketsHelper -end if defined?(Sprockets) \ No newline at end of file +end \ No newline at end of file diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb index fe3c8c9783..2f7f95c44d 100644 --- a/actionpack/lib/sprockets/railtie.rb +++ b/actionpack/lib/sprockets/railtie.rb @@ -32,6 +32,12 @@ module Sprockets next unless assets.enabled app.assets = asset_environment(app) + + # FIXME: Temp hack for extending Sprockets::Context so + ActiveSupport.on_load(:action_view) do + ::Sprockets::Context.send :include, ::ActionView::Helpers::SprocketsHelper + end + app.routes.append do mount app.assets => assets.prefix end -- cgit v1.2.3 From 22fcef90b185199563719fc511346bf4c2f5bbff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 19 Apr 2011 22:01:25 +0200 Subject: Actually add an abstract class, so it is easier to get rid of old asset paths in the future. --- actionpack/lib/action_view/helpers/asset_paths.rb | 80 ++++++++++ .../lib/action_view/helpers/asset_tag_helper.rb | 2 +- .../helpers/asset_tag_helpers/asset_paths.rb | 161 +++++++-------------- .../lib/action_view/helpers/sprockets_helper.rb | 4 +- 4 files changed, 136 insertions(+), 111 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/asset_paths.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/asset_paths.rb b/actionpack/lib/action_view/helpers/asset_paths.rb new file mode 100644 index 0000000000..55a4c442fd --- /dev/null +++ b/actionpack/lib/action_view/helpers/asset_paths.rb @@ -0,0 +1,80 @@ +require 'active_support/core_ext/file' +require 'action_view/helpers/asset_paths' + +module ActionView + module Helpers + + class AssetPaths #:nodoc: + attr_reader :config, :controller + + def initialize(config, controller) + @config = config + @controller = controller + end + + # Add the extension +ext+ if not present. Return full URLs otherwise untouched. + # Prefix with /dir/ if lacking a leading +/+. Account for relative URL + # roots. Rewrite the asset path for cache-busting asset ids. Include + # asset host, if configured, with the correct request protocol. + def compute_public_path(source, dir, ext = nil, include_host = true) + source = source.to_s + return source if is_uri?(source) + + source = rewrite_extension(source, dir, ext) if ext + source = "/#{dir}/#{source}" unless source[0] == ?/ + source = rewrite_asset_path(source, dir) + + if controller && include_host + has_request = controller.respond_to?(:request) + source = rewrite_host_and_protocol(source, has_request) + end + + source + end + + def is_uri?(path) + path =~ %r{^[-a-z]+://|^cid:} + end + + private + + def rewrite_extension(source, dir, ext) + raise NotImplementedError + end + + def rewrite_asset_path(source, path = nil) + raise NotImplementedError + end + + def rewrite_host_and_protocol(source, has_request) + host = compute_asset_host(source) + if has_request && host && !is_uri?(host) + host = "#{controller.request.protocol}#{host}" + end + "#{host}#{source}" + end + + # Pick an asset host for this source. Returns +nil+ if no host is set, + # the host if no wildcard is set, the host interpolated with the + # numbers 0-3 if it contains %d (the number is the source hash mod 4), + # or the value returned from invoking the proc if it's a proc or the value from + # invoking call if it's an object responding to call. + def compute_asset_host(source) + if host = config.asset_host + if host.is_a?(Proc) || host.respond_to?(:call) + case host.is_a?(Proc) ? host.arity : host.method(:call).arity + when 2 + request = controller.respond_to?(:request) && controller.request + host.call(source, request) + else + host.call(source) + end + else + (host =~ /%d/) ? host % (source.hash % 4) : host + end + end + end + end + + end +end \ No newline at end of file diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index e859b3ae49..a7ae6ad0bf 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -446,7 +446,7 @@ module ActionView private def asset_paths - @asset_paths ||= AssetPaths.new(config, controller) + @asset_paths ||= AssetTagHelper::AssetPaths.new(config, controller) end end end diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb index 955634bb19..38860431b4 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb @@ -1,10 +1,11 @@ require 'active_support/core_ext/file' +require 'action_view/helpers/asset_paths' module ActionView module Helpers module AssetTagHelper - class AssetPaths + class AssetPaths < ActionView::Helpers::AssetPaths #:nodoc: # You can enable or disable the asset tag ids cache. # With the cache enabled, the asset tag helper methods will make fewer # expensive file system calls (the default implementation checks the file @@ -14,34 +15,6 @@ module ActionView # ActionView::Helpers::AssetTagHelper::AssetPaths.cache_asset_ids = false mattr_accessor :cache_asset_ids - attr_reader :config, :controller - - def initialize(config, controller) - @config = config - @controller = controller - end - - # Add the extension +ext+ if not present. Return full URLs otherwise untouched. - # Prefix with /dir/ if lacking a leading +/+. Account for relative URL - # roots. Rewrite the asset path for cache-busting asset ids. Include - # asset host, if configured, with the correct request protocol. - def compute_public_path(source, dir, ext = nil, include_host = true) - source = source.to_s - return source if is_uri?(source) - - source = rewrite_extension(source, dir, ext) if ext - source = "/#{dir}/#{source}" unless source[0] == ?/ - source = rewrite_asset_path(source, dir) - - if controller && include_host - has_request = controller.respond_to?(:request) - source = rewrite_relative_url_root(source, controller.config.relative_url_root) if has_request - source = rewrite_host_and_protocol(source, has_request) - end - - source - end - # Add or change an asset id in the asset id cache. This can be used # for SASS on Heroku. # :api: public @@ -51,103 +24,75 @@ module ActionView end end - def is_uri?(path) - path =~ %r{^[-a-z]+://|^cid:} - end - - private - - def rewrite_extension(source, dir, ext) - source_ext = File.extname(source) + private - source_with_ext = if source_ext.empty? - "#{source}.#{ext}" - elsif ext != source_ext[1..-1] - with_ext = "#{source}.#{ext}" - with_ext if File.exist?(File.join(config.assets_dir, dir, with_ext)) - end + def rewrite_extension(source, dir, ext) + source_ext = File.extname(source) - source_with_ext || source + source_with_ext = if source_ext.empty? + "#{source}.#{ext}" + elsif ext != source_ext[1..-1] + with_ext = "#{source}.#{ext}" + with_ext if File.exist?(File.join(config.assets_dir, dir, with_ext)) end - # Break out the asset path rewrite in case plugins wish to put the asset id - # someplace other than the query string. - def rewrite_asset_path(source, path = nil) - path = config.asset_path + source_with_ext || source + end - if path && path.respond_to?(:call) - return path.call(source) - elsif path && path.is_a?(String) - return path % [source] - end + # Break out the asset path rewrite in case plugins wish to put the asset id + # someplace other than the query string. + def rewrite_asset_path(source, path = nil) + path = config.asset_path - asset_id = rails_asset_id(source) - if asset_id.empty? - source - else - "#{source}?#{asset_id}" - end + if path && path.respond_to?(:call) + return path.call(source) + elsif path && path.is_a?(String) + return path % [source] end - mattr_accessor :asset_ids_cache - self.asset_ids_cache = {} + asset_id = rails_asset_id(source) + if asset_id.empty? + source + else + "#{source}?#{asset_id}" + end + end + + mattr_accessor :asset_ids_cache + self.asset_ids_cache = {} - mattr_accessor :asset_ids_cache_guard - self.asset_ids_cache_guard = Mutex.new + mattr_accessor :asset_ids_cache_guard + self.asset_ids_cache_guard = Mutex.new - # Use the RAILS_ASSET_ID environment variable or the source's - # modification time as its cache-busting asset id. - def rails_asset_id(source) - if asset_id = ENV["RAILS_ASSET_ID"] + # Use the RAILS_ASSET_ID environment variable or the source's + # modification time as its cache-busting asset id. + def rails_asset_id(source) + if asset_id = ENV["RAILS_ASSET_ID"] + asset_id + else + if self.cache_asset_ids && (asset_id = self.asset_ids_cache[source]) asset_id else - if self.cache_asset_ids && (asset_id = self.asset_ids_cache[source]) - asset_id - else - path = File.join(config.assets_dir, source) - asset_id = File.exist?(path) ? File.mtime(path).to_i.to_s : '' + path = File.join(config.assets_dir, source) + asset_id = File.exist?(path) ? File.mtime(path).to_i.to_s : '' - if self.cache_asset_ids - add_to_asset_ids_cache(source, asset_id) - end - - asset_id + if self.cache_asset_ids + add_to_asset_ids_cache(source, asset_id) end - end - end - - def rewrite_relative_url_root(source, relative_url_root) - relative_url_root && !source.starts_with?("#{relative_url_root}/") ? "#{relative_url_root}#{source}" : source - end - def rewrite_host_and_protocol(source, has_request) - host = compute_asset_host(source) - if has_request && host && !is_uri?(host) - host = "#{controller.request.protocol}#{host}" + asset_id end - "#{host}#{source}" end + end - # Pick an asset host for this source. Returns +nil+ if no host is set, - # the host if no wildcard is set, the host interpolated with the - # numbers 0-3 if it contains %d (the number is the source hash mod 4), - # or the value returned from invoking the proc if it's a proc or the value from - # invoking call if it's an object responding to call. - def compute_asset_host(source) - if host = config.asset_host - if host.is_a?(Proc) || host.respond_to?(:call) - case host.is_a?(Proc) ? host.arity : host.method(:call).arity - when 2 - request = controller.respond_to?(:request) && controller.request - host.call(source, request) - else - host.call(source) - end - else - (host =~ /%d/) ? host % (source.hash % 4) : host - end - end - end + def rewrite_relative_url_root(source, relative_url_root) + relative_url_root && !source.starts_with?("#{relative_url_root}/") ? "#{relative_url_root}#{source}" : source + end + + def rewrite_host_and_protocol(source, has_request) + source = rewrite_relative_url_root(source, controller.config.relative_url_root) if has_request + super(source, has_request) + end end end diff --git a/actionpack/lib/action_view/helpers/sprockets_helper.rb b/actionpack/lib/action_view/helpers/sprockets_helper.rb index 947c827f3c..b43b91178c 100644 --- a/actionpack/lib/action_view/helpers/sprockets_helper.rb +++ b/actionpack/lib/action_view/helpers/sprockets_helper.rb @@ -1,5 +1,5 @@ require 'uri' -require 'action_view/helpers/asset_tag_helpers/asset_paths' +require 'action_view/helpers/asset_paths' module ActionView module Helpers @@ -38,7 +38,7 @@ module ActionView end end - class AssetPaths < ActionView::Helpers::AssetTagHelper::AssetPaths + class AssetPaths < ActionView::Helpers::AssetPaths #:nodoc: def rewrite_asset_path(source, dir) if source =~ /^\/#{dir}\/(.+)/ assets.path($1, performing_caching?, dir) -- cgit v1.2.3 From 89ed9fbd1917e431e489dc856042d996d0f088c5 Mon Sep 17 00:00:00 2001 From: Florent Piteau Date: Wed, 20 Apr 2011 02:10:29 +0800 Subject: Don't reuse a closed flash when using now --- actionpack/lib/action_dispatch/middleware/flash.rb | 6 +++++- actionpack/test/controller/flash_test.rb | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/middleware/flash.rb b/actionpack/lib/action_dispatch/middleware/flash.rb index 735c72d34a..c7f7d4d4f0 100644 --- a/actionpack/lib/action_dispatch/middleware/flash.rb +++ b/actionpack/lib/action_dispatch/middleware/flash.rb @@ -70,6 +70,10 @@ module ActionDispatch def close!(new_flash) @flash = new_flash end + + def closed? + @flash.closed? + end end class FlashHash @@ -146,7 +150,7 @@ module ActionDispatch # # Entries set via now are accessed the same way as standard entries: flash['my-key']. def now - @now ||= FlashNow.new(self) + @now = (!@now || @now.closed?) ? FlashNow.new(self) : @now end attr_reader :closed diff --git a/actionpack/test/controller/flash_test.rb b/actionpack/test/controller/flash_test.rb index 7b5bf8b21a..e19612eace 100644 --- a/actionpack/test/controller/flash_test.rb +++ b/actionpack/test/controller/flash_test.rb @@ -272,6 +272,14 @@ class FlashIntegrationTest < ActionDispatch::IntegrationTest end end + def test_setting_flash_now_does_not_raise_in_following_requests + with_test_route_set do + env = { 'action_dispatch.request.flash_hash' => ActionDispatch::Flash::FlashHash.new } + get '/set_flash_now', nil, env + get '/set_flash_now', nil, env + end + end + def test_setting_flash_raises_after_stream_back_to_client_even_with_an_empty_flash with_test_route_set do env = { 'action_dispatch.request.flash_hash' => ActionDispatch::Flash::FlashHash.new } -- cgit v1.2.3 From 2f549b8bbd733ad0563d977e83a9b2a2b6b8e07c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 19 Apr 2011 22:38:51 +0200 Subject: Use initialize_copy! to proper initialize now on clone. --- actionpack/lib/action_dispatch/middleware/flash.rb | 33 ++++++++++++---------- 1 file changed, 18 insertions(+), 15 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/middleware/flash.rb b/actionpack/lib/action_dispatch/middleware/flash.rb index c7f7d4d4f0..2adbce031b 100644 --- a/actionpack/lib/action_dispatch/middleware/flash.rb +++ b/actionpack/lib/action_dispatch/middleware/flash.rb @@ -43,6 +43,8 @@ module ActionDispatch KEY = 'action_dispatch.request.flash_hash'.freeze class FlashNow #:nodoc: + attr_accessor :flash + def initialize(flash) @flash = flash end @@ -66,14 +68,6 @@ module ActionDispatch def notice=(message) self[:notice] = message end - - def close!(new_flash) - @flash = new_flash - end - - def closed? - @flash.closed? - end end class FlashHash @@ -86,6 +80,14 @@ module ActionDispatch @now = nil end + def initialize_copy(other) + if other.now_is_loaded? + @now = other.now.dup + @now.flash = self + end + super + end + def []=(k, v) #:nodoc: raise ClosedError, :flash if closed? keep(k) @@ -150,16 +152,12 @@ module ActionDispatch # # Entries set via now are accessed the same way as standard entries: flash['my-key']. def now - @now = (!@now || @now.closed?) ? FlashNow.new(self) : @now + @now ||= FlashNow.new(self) end attr_reader :closed alias :closed? :closed - - def close! - @closed = true - @now.close!(self) if @now - end + def close!; @closed = true; end # Keeps either the entire current flash or a specific flash entry available for the next action: # @@ -214,7 +212,12 @@ module ActionDispatch self[:notice] = message end - private + protected + + def now_is_loaded? + !!@now + end + # Used internally by the keep and discard methods # use() # marks the entire flash as used # use('msg') # marks the "msg" entry as used -- cgit v1.2.3 From d31af44012a6ba3ac5dbec45417ae9bfb5454d8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 20 Apr 2011 21:54:19 +0200 Subject: Fix tests on 1.8 by explicitly checking for strings (which also improves performance). --- actionpack/lib/action_dispatch/http/response.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index 78ecf177be..1f4f3ac0da 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -118,7 +118,15 @@ module ActionDispatch # :nodoc: def body=(body) @blank = true if body == EMPTY - @body = body.respond_to?(:each) ? body : [body] + + # Explicitly check for strings. This is *wrong* theoretically + # but if we don't check this, the performance on string bodies + # is bad on Ruby 1.8 (because strings responds to each then). + @body = if body.respond_to?(:to_str) || !body.respond_to?(:each) + [body] + else + body + end end def body_parts -- cgit v1.2.3 From 783007a8ad7b4b61a1a671d1737a8a6e0369ceb9 Mon Sep 17 00:00:00 2001 From: Joost Baaij Date: Thu, 21 Apr 2011 16:32:02 +0200 Subject: Replace example hostname with "example.com". The hostname used in these comments actually exists, which is undesirable. See also RFC 2606. --- .../lib/action_view/helpers/asset_tag_helper.rb | 6 +++--- .../asset_tag_helpers/javascript_tag_helpers.rb | 18 ++++++++-------- .../asset_tag_helpers/stylesheet_tag_helpers.rb | 14 ++++++------- actionpack/lib/action_view/helpers/url_helper.rb | 2 +- actionpack/test/template/sprockets_helper_test.rb | 24 +++++++++++----------- 5 files changed, 32 insertions(+), 32 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index a7ae6ad0bf..f7cb1f5b58 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -268,7 +268,7 @@ module ActionView # image_path("edit.png") # => "/images/edit.png" # image_path("icons/edit.png") # => "/images/icons/edit.png" # image_path("/icons/edit.png") # => "/icons/edit.png" - # image_path("http://www.railsapplication.com/img/edit.png") # => "http://www.railsapplication.com/img/edit.png" + # image_path("http://www.example.com/img/edit.png") # => "http://www.example.com/img/edit.png" # # If you have images as application resources this method may conflict with their named routes. # The alias +path_to_image+ is provided to avoid that. Rails uses the alias internally, and @@ -291,7 +291,7 @@ module ActionView # video_path("hd.avi") # => /videos/hd.avi # video_path("trailers/hd.avi") # => /videos/trailers/hd.avi # video_path("/trailers/hd.avi") # => /trailers/hd.avi - # video_path("http://www.railsapplication.com/vid/hd.avi") # => http://www.railsapplication.com/vid/hd.avi + # video_path("http://www.example.com/vid/hd.avi") # => http://www.example.com/vid/hd.avi def video_path(source) if config.use_sprockets asset_path(source) @@ -310,7 +310,7 @@ module ActionView # audio_path("horse.wav") # => /audios/horse.wav # audio_path("sounds/horse.wav") # => /audios/sounds/horse.wav # audio_path("/sounds/horse.wav") # => /sounds/horse.wav - # audio_path("http://www.railsapplication.com/sounds/horse.wav") # => http://www.railsapplication.com/sounds/horse.wav + # audio_path("http://www.example.com/sounds/horse.wav") # => http://www.example.com/sounds/horse.wav def audio_path(source) if config.use_sprockets asset_path(source) diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb index 07ff49659a..3d815b5e1f 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb @@ -77,11 +77,11 @@ module ActionView # Used internally by javascript_include_tag to build the script path. # # ==== Examples - # javascript_path "xmlhr" # => /javascripts/xmlhr.js - # javascript_path "dir/xmlhr.js" # => /javascripts/dir/xmlhr.js - # javascript_path "/dir/xmlhr" # => /dir/xmlhr.js - # javascript_path "http://www.railsapplication.com/js/xmlhr" # => http://www.railsapplication.com/js/xmlhr - # javascript_path "http://www.railsapplication.com/js/xmlhr.js" # => http://www.railsapplication.com/js/xmlhr.js + # javascript_path "xmlhr" # => /javascripts/xmlhr.js + # javascript_path "dir/xmlhr.js" # => /javascripts/dir/xmlhr.js + # javascript_path "/dir/xmlhr" # => /dir/xmlhr.js + # javascript_path "http://www.example.com/js/xmlhr" # => http://www.example.com/js/xmlhr + # javascript_path "http://www.example.com/js/xmlhr.js" # => http://www.example.com/js/xmlhr.js def javascript_path(source) if config.use_sprockets asset_path(source, 'js') @@ -123,11 +123,11 @@ module ActionView # # => # # # - # javascript_include_tag "http://www.railsapplication.com/xmlhr" - # # => + # javascript_include_tag "http://www.example.com/xmlhr" + # # => # - # javascript_include_tag "http://www.railsapplication.com/xmlhr.js" - # # => + # javascript_include_tag "http://www.example.com/xmlhr.js" + # # => # # javascript_include_tag :defaults # # => diff --git a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb index c3dcd410bb..a95eb221be 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb @@ -54,11 +54,11 @@ module ActionView # Used internally by +stylesheet_link_tag+ to build the stylesheet path. # # ==== Examples - # stylesheet_path "style" # => /stylesheets/style.css - # stylesheet_path "dir/style.css" # => /stylesheets/dir/style.css - # stylesheet_path "/dir/style.css" # => /dir/style.css - # stylesheet_path "http://www.railsapplication.com/css/style" # => http://www.railsapplication.com/css/style - # stylesheet_path "http://www.railsapplication.com/css/style.css" # => http://www.railsapplication.com/css/style.css + # stylesheet_path "style" # => /stylesheets/style.css + # stylesheet_path "dir/style.css" # => /stylesheets/dir/style.css + # stylesheet_path "/dir/style.css" # => /dir/style.css + # stylesheet_path "http://www.example.com/css/style" # => http://www.example.com/css/style + # stylesheet_path "http://www.example.com/css/style.css" # => http://www.example.com/css/style.css def stylesheet_path(source) if config.use_sprockets asset_path(source, 'css') @@ -79,8 +79,8 @@ module ActionView # stylesheet_link_tag "style.css" # => # # - # stylesheet_link_tag "http://www.railsapplication.com/style.css" # => - # + # stylesheet_link_tag "http://www.example.com/style.css" # => + # # # stylesheet_link_tag "style", :media => "all" # => # diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index 051d3eb049..ffa9a5bb0b 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -68,7 +68,7 @@ module ActionView # # => /books/find # # <%= url_for(:action => 'login', :controller => 'members', :only_path => false, :protocol => 'https') %> - # # => https://www.railsapplication.com/members/login/ + # # => https://www.example.com/members/login/ # # <%= url_for(:action => 'play', :anchor => 'player') %> # # => /messages/play/#player diff --git a/actionpack/test/template/sprockets_helper_test.rb b/actionpack/test/template/sprockets_helper_test.rb index d8aef34bfb..8d3be09a4f 100644 --- a/actionpack/test/template/sprockets_helper_test.rb +++ b/actionpack/test/template/sprockets_helper_test.rb @@ -69,10 +69,10 @@ class SprocketsHelperTest < ActionView::TestCase assert_equal "/dir/xmlhr.js", asset_path("/dir/xmlhr", "js") - assert_equal "http://www.railsapplication.com/js/xmlhr", - asset_path("http://www.railsapplication.com/js/xmlhr", "js") - assert_equal "http://www.railsapplication.com/js/xmlhr.js", - asset_path("http://www.railsapplication.com/js/xmlhr.js", "js") + assert_equal "http://www.example.com/js/xmlhr", + asset_path("http://www.example.com/js/xmlhr", "js") + assert_equal "http://www.example.com/js/xmlhr.js", + asset_path("http://www.example.com/js/xmlhr.js", "js") end test "javascript include tag" do @@ -83,8 +83,8 @@ class SprocketsHelperTest < ActionView::TestCase sprockets_javascript_include_tag("xmlhr") assert_equal '', sprockets_javascript_include_tag("xmlhr.js") - assert_equal '', - sprockets_javascript_include_tag("http://www.railsapplication.com/xmlhr") + assert_equal '', + sprockets_javascript_include_tag("http://www.example.com/xmlhr") end test "stylesheet path" do @@ -94,10 +94,10 @@ class SprocketsHelperTest < ActionView::TestCase assert_equal "/assets/dir/style-d41d8cd98f00b204e9800998ecf8427e.css", asset_path("dir/style.css", "css") assert_equal "/dir/style.css", asset_path("/dir/style.css", "css") - assert_equal "http://www.railsapplication.com/css/style", - asset_path("http://www.railsapplication.com/css/style", "css") - assert_equal "http://www.railsapplication.com/css/style.css", - asset_path("http://www.railsapplication.com/css/style.css", "css") + assert_equal "http://www.example.com/css/style", + asset_path("http://www.example.com/css/style", "css") + assert_equal "http://www.example.com/css/style.css", + asset_path("http://www.example.com/css/style.css", "css") end test "stylesheet link tag" do @@ -109,8 +109,8 @@ class SprocketsHelperTest < ActionView::TestCase assert_equal '', sprockets_stylesheet_link_tag("style.css") - assert_equal '', - sprockets_stylesheet_link_tag("http://www.railsapplication.com/style.css") + assert_equal '', + sprockets_stylesheet_link_tag("http://www.example.com/style.css") assert_equal '', sprockets_stylesheet_link_tag("style", :media => "all") assert_equal '', -- cgit v1.2.3 From 84f1b83df84d36b75cc7b6d1c84ffd84c6c07260 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Thu, 21 Apr 2011 11:03:56 -0500 Subject: Only include SprocketsHelper into assets context --- actionpack/lib/sprockets/railtie.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb index 2f7f95c44d..ccec65ba95 100644 --- a/actionpack/lib/sprockets/railtie.rb +++ b/actionpack/lib/sprockets/railtie.rb @@ -33,9 +33,10 @@ module Sprockets app.assets = asset_environment(app) - # FIXME: Temp hack for extending Sprockets::Context so ActiveSupport.on_load(:action_view) do - ::Sprockets::Context.send :include, ::ActionView::Helpers::SprocketsHelper + app.assets.context.instance_eval do + include ::ActionView::Helpers::SprocketsHelper + end end app.routes.append do @@ -59,4 +60,4 @@ module Sprockets env end end -end \ No newline at end of file +end -- cgit v1.2.3 From 6822f39f67729884d7911b42542c965434a22250 Mon Sep 17 00:00:00 2001 From: Semyon Perepelitsa Date: Fri, 22 Apr 2011 23:12:14 +0800 Subject: Remove HTML escaping from Record Tag Helper docs. --- actionpack/lib/action_view/helpers/record_tag_helper.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/record_tag_helper.rb b/actionpack/lib/action_view/helpers/record_tag_helper.rb index 4d300a1469..142a25f118 100644 --- a/actionpack/lib/action_view/helpers/record_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/record_tag_helper.rb @@ -10,7 +10,7 @@ module ActionView # relate to the specified Active Record object. Usage example: # # <%= div_for(@person, :class => "foo") do %> - # <%=h @person.name %> + # <%= @person.name %> # <% end %> # # produces: @@ -25,8 +25,8 @@ module ActionView # that relate to the specified Active Record object. For example: # # <%= content_tag_for(:tr, @person) do %> - # <%=h @person.first_name %> - # <%=h @person.last_name %> + # <%= @person.first_name %> + # <%= @person.last_name %> # <% end %> # # would produce the following HTML (assuming @person is an instance of -- cgit v1.2.3 From dab96a267eeccd7380ad99fa19cefdfd3cd5ad2b Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Fri, 22 Apr 2011 10:49:55 -0500 Subject: Add shorthand for js and css compressors --- actionpack/lib/sprockets/railtie.rb | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/sprockets/railtie.rb b/actionpack/lib/sprockets/railtie.rb index ccec65ba95..9c10decd60 100644 --- a/actionpack/lib/sprockets/railtie.rb +++ b/actionpack/lib/sprockets/railtie.rb @@ -57,7 +57,44 @@ module Sprockets env.static_root = File.join(app.root.join("public"), assets.prefix) env.paths.concat assets.paths env.logger = Rails.logger + env.js_compressor = expand_js_compressor(assets.js_compressor) + env.css_compressor = expand_css_compressor(assets.css_compressor) env end + + def expand_js_compressor(sym) + case sym + when :closure + require 'closure-compiler' + Closure::Compiler.new + when :uglifier + require 'uglifier' + Uglifier.new + when :yui + require 'yui/compressor' + YUI::JavaScriptCompressor.new + else + sym + end + end + + def expand_css_compressor(sym) + case sym + when :scss + require 'sass' + compressor = Object.new + def compressor.compress(source) + Sass::Engine.new(source, + :syntax => :scss, :style => :compressed + ).render + end + compressor + when :yui + require 'yui/compressor' + YUI::JavaScriptCompressor.new(:munge => true) + else + sym + end + end end end -- cgit v1.2.3 From 89f315bfb287f5428e78195e7c93c85c0892ab64 Mon Sep 17 00:00:00 2001 From: David Heinemeier Hansson Date: Fri, 22 Apr 2011 19:37:52 +0200 Subject: We cant use assert_block because its buggy in MiniTest and wont actually show you the failure message you provide -- instead you just always get a "Expected block to return true" --- actionpack/lib/action_dispatch/testing/assertions/response.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/testing/assertions/response.rb b/actionpack/lib/action_dispatch/testing/assertions/response.rb index 8a04cfa886..e209978fb7 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/response.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/response.rb @@ -42,7 +42,7 @@ module ActionDispatch elsif type.is_a?(Symbol) && @response.response_code == Rack::Utils::SYMBOL_TO_STATUS_CODE[type] assert_block("") { true } # to count the assertion else - assert_block(build_message(message, "Expected response to be a , but was ", type, @response.response_code)) { false } + assert(false, build_message(message, "Expected response to be a , but was ", type, @response.response_code)) end end -- cgit v1.2.3 From a8870d140ececc6327533d08b112cece03c41499 Mon Sep 17 00:00:00 2001 From: Schneems Date: Sat, 23 Apr 2011 02:23:12 +0800 Subject: show http method in routing error message --- actionpack/lib/action_dispatch/middleware/show_exceptions.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb index dbe3206808..b1adf3d2d1 100644 --- a/actionpack/lib/action_dispatch/middleware/show_exceptions.rb +++ b/actionpack/lib/action_dispatch/middleware/show_exceptions.rb @@ -50,7 +50,7 @@ module ActionDispatch # Only this middleware cares about RoutingError. So, let's just raise # it here. if headers['X-Cascade'] == 'pass' - raise ActionController::RoutingError, "No route matches #{env['PATH_INFO'].inspect}" + raise ActionController::RoutingError, "No route matches [#{env['REQUEST_METHOD']}] #{env['PATH_INFO'].inspect}" end rescue Exception => exception raise exception if env['action_dispatch.show_exceptions'] == false -- cgit v1.2.3 From 3e1f4dbb4db852a3278a883b3f599664e5705de3 Mon Sep 17 00:00:00 2001 From: misfo Date: Sat, 23 Apr 2011 10:15:38 -0500 Subject: document HTML::Selector's :has(string) pseudo class --- actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'actionpack') 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 0fe2e6d1a6..1eadfc0390 100644 --- a/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb +++ b/actionpack/lib/action_controller/vendor/html-scanner/html/selector.rb @@ -128,6 +128,8 @@ module HTML # (no parent element). # * :empty -- Match the element only if it has no child elements, # and no text content. + # * :content(string) -- Match the element only if it has string + # as its text content (ignoring leading and trailing whitespace). # * :only-child -- Match the element if it is the only child (element) # of its parent element. # * :only-of-type -- Match the element if it is the only child (element) -- cgit v1.2.3 From 8d00dfca7f6ea528ed5344b6cc1058c9f0402361 Mon Sep 17 00:00:00 2001 From: David Chelimsky Date: Sat, 23 Apr 2011 17:18:06 -0500 Subject: rename test case to better describe use case MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: José Valim --- actionpack/test/controller/view_paths_test.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/view_paths_test.rb b/actionpack/test/controller/view_paths_test.rb index 9280a1c2d3..42356be1ea 100644 --- a/actionpack/test/controller/view_paths_test.rb +++ b/actionpack/test/controller/view_paths_test.rb @@ -131,8 +131,8 @@ class ViewLoadPathsTest < ActionController::TestCase assert_equal "Hello overridden world!", @response.body end - def test_override_view_paths_with_custom_resolver - resolver_class = Class.new(ActionView::PathResolver) do + def test_decorate_view_paths_with_custom_resolver + decorator_class = Class.new(ActionView::PathResolver) do def initialize(path_set) @path_set = path_set end @@ -140,7 +140,7 @@ class ViewLoadPathsTest < ActionController::TestCase def find_all(*args) @path_set.find_all(*args).collect do |template| ::ActionView::Template.new( - "Customized body", + "Decorated body", template.identifier, template.handler, { @@ -152,12 +152,12 @@ class ViewLoadPathsTest < ActionController::TestCase end end - resolver = resolver_class.new(TestController.view_paths) - TestController.view_paths = ActionView::PathSet.new.push(resolver) + decorator = decorator_class.new(TestController.view_paths) + TestController.view_paths = ActionView::PathSet.new.push(decorator) get :hello_world assert_response :success - assert_equal "Customized body", @response.body + assert_equal "Decorated body", @response.body end def test_inheritance -- cgit v1.2.3 From 820c0feda33495cfe68add8c3f25adc515ab3e04 Mon Sep 17 00:00:00 2001 From: Piotr Sarnacki Date: Mon, 25 Apr 2011 14:56:58 +0200 Subject: Explicitly define main_app proxy --- actionpack/lib/action_dispatch/routing/route_set.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index b28f6c2297..1d09091dc7 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -275,8 +275,7 @@ module ActionDispatch module MountedHelpers end - def mounted_helpers(name = :main_app) - define_mounted_helper(name) if name + def mounted_helpers MountedHelpers end -- cgit v1.2.3 From d4bea35f1ae458246a9e3bb1c914c5d05b8e9cdf Mon Sep 17 00:00:00 2001 From: Piotr Sarnacki Date: Mon, 25 Apr 2011 15:02:41 +0200 Subject: Make ActionController::Base.modules_for_helpers and ActionController::Base.all_helpers_from_path public methods --- actionpack/lib/abstract_controller/helpers.rb | 22 +++++----- actionpack/lib/action_controller/metal/helpers.rb | 52 +++++++++++------------ 2 files changed, 37 insertions(+), 37 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/helpers.rb b/actionpack/lib/abstract_controller/helpers.rb index 20f8601a8e..0ff1c0491a 100644 --- a/actionpack/lib/abstract_controller/helpers.rb +++ b/actionpack/lib/abstract_controller/helpers.rb @@ -112,17 +112,6 @@ module AbstractController default_helper_module! unless anonymous? end - private - # Makes all the (instance) methods in the helper module available to templates - # rendered through this controller. - # - # ==== Parameters - # * module - The module to include into the current helper module - # for the class - def add_template_helper(mod) - _helpers.module_eval { include mod } - end - # Returns a list of modules, normalized from the acceptable kinds of # helpers with the following behavior: # @@ -155,6 +144,17 @@ module AbstractController end end + private + # Makes all the (instance) methods in the helper module available to templates + # rendered through this controller. + # + # ==== Parameters + # * module - The module to include into the current helper module + # for the class + def add_template_helper(mod) + _helpers.module_eval { include mod } + end + def default_helper_module! module_name = name.sub(/Controller$/, '') module_path = module_name.underscore diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb index 91a88ab68a..75757db564 100644 --- a/actionpack/lib/action_controller/metal/helpers.rb +++ b/actionpack/lib/action_controller/metal/helpers.rb @@ -76,35 +76,35 @@ module ActionController @helper_proxy ||= ActionView::Base.new.extend(_helpers) end - private - # Overwrite modules_for_helpers to accept :all as argument, which loads - # all helpers in helpers_path. - # - # ==== Parameters - # * args - A list of helpers - # - # ==== Returns - # * array - A normalized list of modules for the list of helpers provided. - def modules_for_helpers(args) - args += all_application_helpers if args.delete(:all) - super(args) - end + # Overwrite modules_for_helpers to accept :all as argument, which loads + # all helpers in helpers_path. + # + # ==== Parameters + # * args - A list of helpers + # + # ==== Returns + # * array - A normalized list of modules for the list of helpers provided. + def modules_for_helpers(args) + args += all_application_helpers if args.delete(:all) + super(args) + end - # Extract helper names from files in app/helpers/**/*_helper.rb - def all_application_helpers - all_helpers_from_path(helpers_path) + def all_helpers_from_path(path) + helpers = [] + Array.wrap(path).each do |_path| + extract = /^#{Regexp.quote(_path.to_s)}\/?(.*)_helper.rb$/ + helpers += Dir["#{_path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') } end + helpers.sort! + helpers.uniq! + helpers + end - def all_helpers_from_path(path) - helpers = [] - Array.wrap(path).each do |_path| - extract = /^#{Regexp.quote(_path.to_s)}\/?(.*)_helper.rb$/ - helpers += Dir["#{_path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') } - end - helpers.sort! - helpers.uniq! - helpers - end + private + # Extract helper names from files in app/helpers/**/*_helper.rb + def all_application_helpers + all_helpers_from_path(helpers_path) + end end end end -- cgit v1.2.3 From f545a5081ec7052dd9319cab84ab52d41ee267bd Mon Sep 17 00:00:00 2001 From: Piotr Sarnacki Date: Mon, 25 Apr 2011 17:57:41 +0200 Subject: Fix tests, main_app mounted helper must be defined explicitly now. --- actionpack/test/dispatch/prefix_generation_test.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionpack') diff --git a/actionpack/test/dispatch/prefix_generation_test.rb b/actionpack/test/dispatch/prefix_generation_test.rb index 18f28deee4..b28a058250 100644 --- a/actionpack/test/dispatch/prefix_generation_test.rb +++ b/actionpack/test/dispatch/prefix_generation_test.rb @@ -69,6 +69,7 @@ module TestGenerationPrefix # force draw RailsApplication.routes + RailsApplication.routes.define_mounted_helper(:main_app) class ::InsideEngineGeneratingController < ActionController::Base include BlogEngine.routes.url_helpers -- cgit v1.2.3 From 873c13fc0ddc35e64a6b3abc8bde9721bd12b6b7 Mon Sep 17 00:00:00 2001 From: Diego Carrion Date: Wed, 20 Apr 2011 14:26:45 -0300 Subject: added test for number_to_phone with an empty string and area code true Signed-off-by: Santiago Pastorino --- actionpack/test/template/number_helper_test.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionpack') diff --git a/actionpack/test/template/number_helper_test.rb b/actionpack/test/template/number_helper_test.rb index c8d50ebf75..23a7e17e65 100644 --- a/actionpack/test/template/number_helper_test.rb +++ b/actionpack/test/template/number_helper_test.rb @@ -32,6 +32,7 @@ class NumberHelperTest < ActionView::TestCase assert_equal("555-1234", number_to_phone(5551234)) assert_equal("800-555-1212", number_to_phone(8005551212)) assert_equal("(800) 555-1212", number_to_phone(8005551212, {:area_code => true})) + assert_equal("", number_to_phone("", {:area_code => true})) assert_equal("800 555 1212", number_to_phone(8005551212, {:delimiter => " "})) assert_equal("(800) 555-1212 x 123", number_to_phone(8005551212, {:area_code => true, :extension => 123})) assert_equal("800-555-1212", number_to_phone(8005551212, :extension => " ")) -- cgit v1.2.3 From 057412ce38ead06307a887dca333837a99f84f22 Mon Sep 17 00:00:00 2001 From: Chad Krsek Date: Mon, 25 Apr 2011 21:57:28 -0700 Subject: asset helpers should understand scheme-relative URLs --- actionpack/lib/action_view/helpers/asset_paths.rb | 11 +++++++++-- actionpack/test/template/asset_tag_helper_test.rb | 15 +++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/asset_paths.rb b/actionpack/lib/action_view/helpers/asset_paths.rb index 55a4c442fd..0429e60cd5 100644 --- a/actionpack/lib/action_view/helpers/asset_paths.rb +++ b/actionpack/lib/action_view/helpers/asset_paths.rb @@ -12,13 +12,13 @@ module ActionView @controller = controller end - # Add the extension +ext+ if not present. Return full URLs otherwise untouched. + # Add the extension +ext+ if not present. Return full or scheme-relative URLs otherwise untouched. # Prefix with /dir/ if lacking a leading +/+. Account for relative URL # roots. Rewrite the asset path for cache-busting asset ids. Include # asset host, if configured, with the correct request protocol. def compute_public_path(source, dir, ext = nil, include_host = true) source = source.to_s - return source if is_uri?(source) + return source if is_uri?(source) || is_scheme_relative_uri?(source) source = rewrite_extension(source, dir, ext) if ext source = "/#{dir}/#{source}" unless source[0] == ?/ @@ -36,6 +36,13 @@ module ActionView path =~ %r{^[-a-z]+://|^cid:} end + # A URI relative to a base URI's scheme? + # See http://labs.apache.org/webarch/uri/rfc/rfc3986.html#relative-normal + # "//g" => "http://g" + def is_scheme_relative_uri?(path) + path =~ %r{^//} + end + private def rewrite_extension(source, dir, ext) diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index 4a93def5a8..2abc806e97 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -66,6 +66,7 @@ class AssetTagHelperTest < ActionView::TestCase %(auto_discovery_link_tag(:xml)) => %(), %(auto_discovery_link_tag(:rss, :action => "feed")) => %(), %(auto_discovery_link_tag(:rss, "http://localhost/feed")) => %(), + %(auto_discovery_link_tag(:rss, "//localhost/feed")) => %(), %(auto_discovery_link_tag(:rss, {:action => "feed"}, {:title => "My RSS"})) => %(), %(auto_discovery_link_tag(:rss, {}, {:title => "My RSS"})) => %(), %(auto_discovery_link_tag(nil, {}, {:type => "text/html"})) => %(), @@ -100,6 +101,7 @@ class AssetTagHelperTest < ActionView::TestCase %(javascript_include_tag("http://example.com/all")) => %(), %(javascript_include_tag("http://example.com/all.js")) => %(), + %(javascript_include_tag("//example.com/all.js")) => %(), } StylePathToTag = { @@ -129,6 +131,7 @@ class AssetTagHelperTest < ActionView::TestCase %(stylesheet_link_tag("http://www.example.com/styles/style")) => %(), %(stylesheet_link_tag("http://www.example.com/styles/style.css")) => %(), + %(stylesheet_link_tag("//www.example.com/styles/style.css")) => %(), } ImagePathToTag = { @@ -157,6 +160,7 @@ class AssetTagHelperTest < ActionView::TestCase %(image_tag("slash..png")) => %(Slash.), %(image_tag(".pdf.png")) => %(.pdf), %(image_tag("http://www.rubyonrails.com/images/rails.png")) => %(Rails), + %(image_tag("//www.rubyonrails.com/images/rails.png")) => %(Rails), %(image_tag("mouse.png", :mouseover => "/images/mouse_over.png")) => %(Mouse), %(image_tag("mouse.png", :mouseover => image_path("mouse_over.png"))) => %(Mouse), %(image_tag("mouse.png", :alt => nil)) => %() @@ -195,6 +199,7 @@ class AssetTagHelperTest < ActionView::TestCase %(video_tag("error.avi", "size" => "100 x 100")) => %(