summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/core/loader/preload_helper.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/blink/renderer/core/loader/preload_helper.cc')
-rw-r--r--chromium/third_party/blink/renderer/core/loader/preload_helper.cc146
1 files changed, 94 insertions, 52 deletions
diff --git a/chromium/third_party/blink/renderer/core/loader/preload_helper.cc b/chromium/third_party/blink/renderer/core/loader/preload_helper.cc
index 96fe8650bf3..7ad53e5e884 100644
--- a/chromium/third_party/blink/renderer/core/loader/preload_helper.cc
+++ b/chromium/third_party/blink/renderer/core/loader/preload_helper.cc
@@ -33,8 +33,10 @@
#include "third_party/blink/renderer/core/loader/resource/link_fetch_resource.h"
#include "third_party/blink/renderer/core/loader/resource/script_resource.h"
#include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h"
+#include "third_party/blink/renderer/core/page/viewport_description.h"
#include "third_party/blink/renderer/core/script/modulator.h"
#include "third_party/blink/renderer/core/script/script_loader.h"
+#include "third_party/blink/renderer/platform/heap/heap.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h"
#include "third_party/blink/renderer/platform/loader/fetch/raw_resource.h"
@@ -90,10 +92,10 @@ bool IsSupportedType(ResourceType resource_type, const String& mime_type) {
MediaValues* CreateMediaValues(
Document& document,
- const base::Optional<ViewportDescription>& viewport_description) {
+ const ViewportDescription* viewport_description) {
MediaValues* media_values =
MediaValues::CreateDynamicIfFrameExists(document.GetFrame());
- if (viewport_description.has_value()) {
+ if (viewport_description) {
FloatSize initial_viewport(media_values->DeviceWidth(),
media_values->DeviceHeight());
PageScaleConstraints constraints = viewport_description->Resolve(
@@ -104,8 +106,11 @@ MediaValues* CreateMediaValues(
return media_values;
}
-bool MediaMatches(const String& media, MediaValues* media_values) {
- scoped_refptr<MediaQuerySet> media_queries = MediaQuerySet::Create(media);
+bool MediaMatches(const String& media,
+ MediaValues* media_values,
+ const ExecutionContext* execution_context) {
+ scoped_refptr<MediaQuerySet> media_queries =
+ MediaQuerySet::Create(media, execution_context);
MediaQueryEvaluator evaluator(*media_values);
return evaluator.Eval(*media_queries);
}
@@ -116,13 +121,26 @@ KURL GetBestFitImageURL(const Document& document,
const KURL& href,
const String& image_srcset,
const String& image_sizes) {
- float source_size = SizesAttributeParser(media_values, image_sizes).length();
+ float source_size = SizesAttributeParser(media_values, image_sizes,
+ document.ToExecutionContext())
+ .length();
ImageCandidate candidate = BestFitSourceForImageAttributes(
media_values->DevicePixelRatio(), source_size, href, image_srcset);
return base_url.IsNull() ? document.CompleteURL(candidate.ToString())
: KURL(base_url, candidate.ToString());
}
+// Check whether the `as` attribute is valid according to the spec, even if we
+// don't currently support it yet.
+bool IsValidButUnsupportedAsAttribute(const String& as) {
+ DCHECK(as != "fetch" && as != "image" && as != "font" && as != "script" &&
+ as != "style" && as != "track");
+ return as == "audio" || as == "audioworklet" || as == "document" ||
+ as == "embed" || as == "manifest" || as == "object" ||
+ as == "paintworklet" || as == "report" || as == "sharedworker" ||
+ as == "video" || as == "worker" || as == "xslt";
+}
+
} // namespace
void PreloadHelper::DnsPrefetchIfNeeded(
@@ -142,7 +160,7 @@ void PreloadHelper::DnsPrefetchIfNeeded(
params.href.IsValid() && !params.href.IsEmpty()) {
if (settings->GetLogDnsPrefetchAndPreconnect()) {
SendMessageToConsoleForPossiblyNullDocument(
- ConsoleMessage::Create(
+ MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kVerbose,
String("DNS prefetch triggered for " + params.href.Host())),
@@ -170,20 +188,21 @@ void PreloadHelper::PreconnectIfNeeded(
Settings* settings = frame ? frame->GetSettings() : nullptr;
if (settings && settings->GetLogDnsPrefetchAndPreconnect()) {
SendMessageToConsoleForPossiblyNullDocument(
- ConsoleMessage::Create(
+ MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kVerbose,
String("Preconnect triggered for ") + params.href.GetString()),
document, frame);
if (params.cross_origin != kCrossOriginAttributeNotSet) {
SendMessageToConsoleForPossiblyNullDocument(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kOther,
- mojom::ConsoleMessageLevel::kVerbose,
- String("Preconnect CORS setting is ") +
- String((params.cross_origin ==
- kCrossOriginAttributeAnonymous)
- ? "anonymous"
- : "use-credentials")),
+ MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kOther,
+ mojom::ConsoleMessageLevel::kVerbose,
+ String("Preconnect CORS setting is ") +
+ String(
+ (params.cross_origin == kCrossOriginAttributeAnonymous)
+ ? "anonymous"
+ : "use-credentials")),
document, frame);
}
}
@@ -228,7 +247,7 @@ Resource* PreloadHelper::PreloadIfNeeded(
Document& document,
const KURL& base_url,
LinkCaller caller,
- const base::Optional<ViewportDescription>& viewport_description,
+ const ViewportDescription* viewport_description,
ParserDisposition parser_disposition) {
if (!document.Loader() || !params.rel.IsLinkPreload())
return nullptr;
@@ -249,7 +268,7 @@ Resource* PreloadHelper::PreloadIfNeeded(
UseCounter::Count(document, WebFeature::kLinkRelPreload);
if (!url.IsValid() || url.IsEmpty()) {
- document.AddConsoleMessage(ConsoleMessage::Create(
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning,
String("<link rel=preload> has an invalid `href` value")));
@@ -260,22 +279,27 @@ Resource* PreloadHelper::PreloadIfNeeded(
if (!params.media.IsEmpty()) {
if (!media_values)
media_values = CreateMediaValues(document, viewport_description);
- if (!MediaMatches(params.media, media_values))
+ if (!MediaMatches(params.media, media_values,
+ document.ToExecutionContext()))
return nullptr;
}
if (caller == kLinkCalledFromHeader)
UseCounter::Count(document, WebFeature::kLinkHeaderPreload);
if (resource_type == base::nullopt) {
- document.AddConsoleMessage(ConsoleMessage::Create(
- mojom::ConsoleMessageSource::kOther,
- mojom::ConsoleMessageLevel::kWarning,
- String("<link rel=preload> must have a valid `as` value")));
+ String message;
+ if (IsValidButUnsupportedAsAttribute(params.as)) {
+ message = String("<link rel=preload> uses an unsupported `as` value");
+ } else {
+ message = String("<link rel=preload> must have a valid `as` value");
+ }
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::blink::ConsoleMessageSource::kOther,
+ mojom::blink::ConsoleMessageLevel::kWarning, message));
return nullptr;
}
-
if (!IsSupportedType(resource_type.value(), params.type)) {
- document.AddConsoleMessage(ConsoleMessage::Create(
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning,
String("<link rel=preload> has an unsupported `type` value")));
@@ -284,6 +308,8 @@ Resource* PreloadHelper::PreloadIfNeeded(
ResourceRequest resource_request(url);
resource_request.SetRequestContext(ResourceFetcher::DetermineRequestContext(
resource_type.value(), ResourceFetcher::kImageNotImageSet));
+ resource_request.SetRequestDestination(
+ ResourceFetcher::DetermineRequestDestination(resource_type.value()));
resource_request.SetReferrerPolicy(params.referrer_policy);
@@ -293,7 +319,7 @@ Resource* PreloadHelper::PreloadIfNeeded(
ResourceLoaderOptions options;
options.initiator_info.name = fetch_initiator_type_names::kLink;
options.parser_disposition = parser_disposition;
- FetchParameters link_fetch_params(resource_request, options);
+ FetchParameters link_fetch_params(std::move(resource_request), options);
link_fetch_params.SetCharset(document.Encoding());
if (params.cross_origin != kCrossOriginAttributeNotSet) {
@@ -310,7 +336,9 @@ Resource* PreloadHelper::PreloadIfNeeded(
if (!integrity_attr.IsEmpty()) {
IntegrityMetadataSet metadata_set;
SubresourceIntegrity::ParseIntegrityAttribute(
- integrity_attr, SubresourceIntegrityHelper::GetFeatures(&document),
+ integrity_attr,
+ SubresourceIntegrityHelper::GetFeatures(
+ document.ToExecutionContext()),
metadata_set);
link_fetch_params.SetIntegrityMetadata(metadata_set);
link_fetch_params.MutableResourceRequest().SetFetchIntegrity(
@@ -318,7 +346,7 @@ Resource* PreloadHelper::PreloadIfNeeded(
}
} else {
if (!integrity_attr.IsEmpty()) {
- document.AddConsoleMessage(ConsoleMessage::Create(
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning,
String("The `integrity` attribute is currently ignored for preload "
@@ -330,21 +358,21 @@ Resource* PreloadHelper::PreloadIfNeeded(
link_fetch_params.SetContentSecurityPolicyNonce(params.nonce);
Settings* settings = document.GetSettings();
if (settings && settings->GetLogPreload()) {
- document.AddConsoleMessage(ConsoleMessage::Create(
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kVerbose,
String("Preload triggered for " + url.Host() + url.GetPath())));
}
link_fetch_params.SetLinkPreload(true);
return PreloadHelper::StartPreload(resource_type.value(), link_fetch_params,
- document.Fetcher());
+ document);
}
// https://html.spec.whatwg.org/C/#link-type-modulepreload
void PreloadHelper::ModulePreloadIfNeeded(
const LinkLoadParameters& params,
Document& document,
- const base::Optional<ViewportDescription>& viewport_description,
+ const ViewportDescription* viewport_description,
SingleModuleClient* client) {
if (!document.Loader() || !params.rel.IsModulePreload())
return;
@@ -354,10 +382,10 @@ void PreloadHelper::ModulePreloadIfNeeded(
// Step 1. "If the href attribute's value is the empty string, then return."
// [spec text]
if (params.href.IsEmpty()) {
- document.AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kOther,
- mojom::ConsoleMessageLevel::kWarning,
- "<link rel=modulepreload> has no `href` value"));
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kOther,
+ mojom::ConsoleMessageLevel::kWarning,
+ "<link rel=modulepreload> has no `href` value"));
return;
}
@@ -379,7 +407,7 @@ void PreloadHelper::ModulePreloadIfNeeded(
// and return." [spec text]
// Currently we only support as="script".
if (!params.as.IsEmpty() && params.as != "script") {
- document.AddConsoleMessage(ConsoleMessage::Create(
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning,
String("<link rel=modulepreload> has an invalid `as` value " +
@@ -393,14 +421,16 @@ void PreloadHelper::ModulePreloadIfNeeded(
}
return;
}
- mojom::RequestContextType destination = mojom::RequestContextType::SCRIPT;
+ mojom::RequestContextType context_type = mojom::RequestContextType::SCRIPT;
+ network::mojom::RequestDestination destination =
+ network::mojom::RequestDestination::kScript;
// Step 4. "Parse the URL given by the href attribute, relative to the
// element's node document. If that fails, then return. Otherwise, let url be
// the resulting URL record." [spec text]
// |href| is already resolved in caller side.
if (!params.href.IsValid()) {
- document.AddConsoleMessage(ConsoleMessage::Create(
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
mojom::ConsoleMessageSource::kOther,
mojom::ConsoleMessageLevel::kWarning,
"<link rel=modulepreload> has an invalid `href` value " +
@@ -413,7 +443,8 @@ void PreloadHelper::ModulePreloadIfNeeded(
if (!params.media.IsEmpty()) {
MediaValues* media_values =
CreateMediaValues(document, viewport_description);
- if (!MediaMatches(params.media, media_values))
+ if (!MediaMatches(params.media, media_values,
+ document.ToExecutionContext()))
return;
}
@@ -431,11 +462,12 @@ void PreloadHelper::ModulePreloadIfNeeded(
IntegrityMetadataSet integrity_metadata;
if (!params.integrity.IsEmpty()) {
SubresourceIntegrity::IntegrityFeatures integrity_features =
- SubresourceIntegrityHelper::GetFeatures(&document);
+ SubresourceIntegrityHelper::GetFeatures(document.ToExecutionContext());
SubresourceIntegrity::ReportInfo report_info;
SubresourceIntegrity::ParseIntegrityAttribute(
params.integrity, integrity_features, integrity_metadata, &report_info);
- SubresourceIntegrityHelper::DoReport(document, report_info);
+ SubresourceIntegrityHelper::DoReport(*document.ToExecutionContext(),
+ report_info);
}
// Step 9. "Let referrer policy be the current state of the element's
@@ -447,7 +479,7 @@ void PreloadHelper::ModulePreloadIfNeeded(
// metadata is "not-parser-inserted", credentials mode is credentials mode,
// and referrer policy is referrer policy." [spec text]
ModuleScriptFetchRequest request(
- params.href, destination,
+ params.href, context_type, destination,
ScriptFetchOptions(params.nonce, integrity_metadata, params.integrity,
kNotParserInserted, credentials_mode,
params.referrer_policy,
@@ -464,11 +496,11 @@ void PreloadHelper::ModulePreloadIfNeeded(
Settings* settings = document.GetSettings();
if (settings && settings->GetLogPreload()) {
- document.AddConsoleMessage(
- ConsoleMessage::Create(mojom::ConsoleMessageSource::kOther,
- mojom::ConsoleMessageLevel::kVerbose,
- "Module preload triggered for " +
- params.href.Host() + params.href.GetPath()));
+ document.AddConsoleMessage(MakeGarbageCollected<ConsoleMessage>(
+ mojom::ConsoleMessageSource::kOther,
+ mojom::ConsoleMessageLevel::kVerbose,
+ "Module preload triggered for " + params.href.Host() +
+ params.href.GetPath()));
}
// Asynchronously continue processing after
@@ -510,7 +542,7 @@ Resource* PreloadHelper::PrefetchIfNeeded(const LinkLoadParameters& params,
ResourceLoaderOptions options;
options.initiator_info.name = fetch_initiator_type_names::kLink;
- FetchParameters link_fetch_params(resource_request, options);
+ FetchParameters link_fetch_params(std::move(resource_request), options);
if (params.cross_origin != kCrossOriginAttributeNotSet) {
link_fetch_params.SetCrossOriginAccessControl(
document.GetSecurityOrigin(), params.cross_origin);
@@ -533,10 +565,10 @@ void PreloadHelper::LoadLinksFromHeader(
Document* document,
CanLoadResources can_load_resources,
MediaPreloadPolicy media_policy,
- const base::Optional<ViewportDescription>& viewport_description,
+ const ViewportDescription* viewport_description,
std::unique_ptr<AlternateSignedExchangeResourceInfo>
alternate_resource_info,
- base::Optional<base::UnguessableToken> recursive_prefetch_token) {
+ const base::UnguessableToken* recursive_prefetch_token) {
if (header_value.IsEmpty())
return;
LinkHeaderSet header_set(header_value);
@@ -550,12 +582,14 @@ void PreloadHelper::LoadLinksFromHeader(
continue;
LinkLoadParameters params(header, base_url);
+ bool change_rel_to_prefetch = false;
+
if (params.rel.IsLinkPreload() && recursive_prefetch_token) {
// Only preload headers are expected to have a recursive prefetch token
// In response to that token's existence, we treat the request as a
// prefetch.
- params.recursive_prefetch_token = recursive_prefetch_token;
- params.rel = LinkRelAttribute("prefetch");
+ params.recursive_prefetch_token = *recursive_prefetch_token;
+ change_rel_to_prefetch = true;
}
if (alternate_resource_info && params.rel.IsLinkPreload()) {
@@ -598,9 +632,13 @@ void PreloadHelper::LoadLinksFromHeader(
// navigation, but can only populate things in the cache that can be
// used by the next navigation only when they requested the same URL
// with the same association mapping.
- params.rel = LinkRelAttribute("prefetch");
+ change_rel_to_prefetch = true;
}
}
+
+ if (change_rel_to_prefetch)
+ params.rel = LinkRelAttribute("prefetch");
+
// Sanity check to avoid re-entrancy here.
if (params.href == base_url)
continue;
@@ -625,7 +663,8 @@ void PreloadHelper::LoadLinksFromHeader(
Resource* PreloadHelper::StartPreload(ResourceType type,
FetchParameters& params,
- ResourceFetcher* resource_fetcher) {
+ Document& document) {
+ ResourceFetcher* resource_fetcher = document.Fetcher();
Resource* resource = nullptr;
switch (type) {
case ResourceType::kImage:
@@ -633,6 +672,7 @@ Resource* PreloadHelper::StartPreload(ResourceType type,
break;
case ResourceType::kScript:
params.SetRequestContext(mojom::RequestContextType::SCRIPT);
+ params.SetRequestDestination(network::mojom::RequestDestination::kScript);
resource = ScriptResource::Fetch(params, resource_fetcher, nullptr,
ScriptResource::kAllowStreaming);
break;
@@ -642,6 +682,8 @@ Resource* PreloadHelper::StartPreload(ResourceType type,
break;
case ResourceType::kFont:
resource = FontResource::Fetch(params, resource_fetcher, nullptr);
+ document.GetFontPreloadManager().FontPreloadingStarted(
+ ToFontResource(resource));
break;
case ResourceType::kAudio:
case ResourceType::kVideo: