diff --git a/actionview/lib/action_view/helpers/asset_tag_helper.rb b/actionview/lib/action_view/helpers/asset_tag_helper.rb
index 91794fe4e4..cbf64867aa 100644
--- a/actionview/lib/action_view/helpers/asset_tag_helper.rb
+++ b/actionview/lib/action_view/helpers/asset_tag_helper.rb
@@ -86,11 +86,11 @@ module ActionView
def javascript_include_tag(*sources)
options = sources.extract_options!.stringify_keys
path_options = options.extract!("protocol", "extname", "host", "skip_pipeline").symbolize_keys
- early_hints_links = []
+ preload_links = []
sources_tags = sources.uniq.map { |source|
href = path_to_javascript(source, path_options)
- early_hints_links << "<#{href}>; rel=preload; as=script"
+ preload_links << "<#{href}>; rel=preload; as=script"
tag_options = {
"src" => href
}.merge!(options)
@@ -100,7 +100,7 @@ module ActionView
content_tag("script", "", tag_options)
}.join("\n").html_safe
- request.send_early_hints("Link" => early_hints_links.join("\n")) if respond_to?(:request) && request
+ send_preload_links_header(preload_links)
sources_tags
end
@@ -136,11 +136,11 @@ module ActionView
def stylesheet_link_tag(*sources)
options = sources.extract_options!.stringify_keys
path_options = options.extract!("protocol", "host", "skip_pipeline").symbolize_keys
- early_hints_links = []
+ preload_links = []
sources_tags = sources.uniq.map { |source|
href = path_to_stylesheet(source, path_options)
- early_hints_links << "<#{href}>; rel=preload; as=style"
+ preload_links << "<#{href}>; rel=preload; as=style"
tag_options = {
"rel" => "stylesheet",
"media" => "screen",
@@ -149,7 +149,7 @@ module ActionView
tag(:link, tag_options)
}.join("\n").html_safe
- request.send_early_hints("Link" => early_hints_links.join("\n")) if respond_to?(:request) && request
+ send_preload_links_header(preload_links)
sources_tags
end
@@ -281,12 +281,12 @@ module ActionView
crossorigin: crossorigin
}.merge!(options.symbolize_keys))
- early_hints_link = "<#{href}>; rel=preload; as=#{as_type}"
- early_hints_link += "; type=#{mime_type}" if mime_type
- early_hints_link += "; crossorigin=#{crossorigin}" if crossorigin
- early_hints_link += "; nopush" if nopush
+ preload_link = "<#{href}>; rel=preload; as=#{as_type}"
+ preload_link += "; type=#{mime_type}" if mime_type
+ preload_link += "; crossorigin=#{crossorigin}" if crossorigin
+ preload_link += "; nopush" if nopush
- request.send_early_hints("Link" => early_hints_link) if respond_to?(:request) && request
+ send_preload_links_header([preload_link])
link_tag
end
@@ -482,6 +482,16 @@ module ActionView
type
end
end
+
+ def send_preload_links_header(preload_links)
+ if respond_to?(:request) && request
+ request.send_early_hints("Link" => preload_links.join("\n"))
+ end
+
+ if respond_to?(:response) && response
+ response.headers["Link"] = [response.headers["Link"].presence, *preload_links].compact.join(",")
+ end
+ end
end
end
end
diff --git a/actionview/test/abstract_unit.rb b/actionview/test/abstract_unit.rb
index b67fd260e6..57296e090e 100644
--- a/actionview/test/abstract_unit.rb
+++ b/actionview/test/abstract_unit.rb
@@ -84,7 +84,7 @@ class RoutedRackApp
end
class BasicController
- attr_accessor :request
+ attr_accessor :request, :response
def config
@config ||= ActiveSupport::InheritableOptions.new(ActionController::Base.config).tap do |config|
diff --git a/actionview/test/template/asset_tag_helper_test.rb b/actionview/test/template/asset_tag_helper_test.rb
index efef74ca00..a59929a2ea 100644
--- a/actionview/test/template/asset_tag_helper_test.rb
+++ b/actionview/test/template/asset_tag_helper_test.rb
@@ -9,23 +9,33 @@ ActionView::Template::Types.delegate_to Mime
class AssetTagHelperTest < ActionView::TestCase
tests ActionView::Helpers::AssetTagHelper
- attr_reader :request
+ attr_reader :request, :response
+
+ class FakeRequest
+ attr_accessor :script_name
+ def protocol() "http://" end
+ def ssl?() false end
+ def host_with_port() "localhost" end
+ def base_url() "http://www.example.com" end
+ def send_early_hints(links) end
+ end
+
+ class FakeResponse
+ def headers
+ @headers ||= {}
+ end
+ end
def setup
super
@controller = BasicController.new
- @request = Class.new do
- attr_accessor :script_name
- def protocol() "http://" end
- def ssl?() false end
- def host_with_port() "localhost" end
- def base_url() "http://www.example.com" end
- def send_early_hints(links) end
- end.new
-
+ @request = FakeRequest.new
@controller.request = @request
+
+ @response = FakeResponse.new
+ @controller.response = @response
end
def url_for(*args)
@@ -499,6 +509,14 @@ class AssetTagHelperTest < ActionView::TestCase
assert_dom_equal %(), javascript_include_tag("foo.js")
end
+
+ def test_should_set_preload_links
+ stylesheet_link_tag("http://example.com/style.css")
+ javascript_include_tag("http://example.com/all.js")
+ expected = "; rel=preload; as=style,; rel=preload; as=script"
+ assert_equal expected, @response.headers["Link"]
+ end
+
def test_image_path
ImagePathToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
end