Bug 1618299 - Teach dom::HTMLLinkElement about Document.Preloads(), r=smaug

Depends on D71378

Differential Revision: https://phabricator.services.mozilla.com/D67483
This commit is contained in:
Honza Bambas
2020-05-11 14:06:45 +00:00
parent 0751536080
commit 27e8bc155e
2 changed files with 62 additions and 40 deletions

View File

@@ -591,44 +591,44 @@ void HTMLLinkElement::
uint32_t linkTypes = ParseLinkTypes(rel);
if ((linkTypes & ePREFETCH) || (linkTypes & eNEXT) ||
(linkTypes & ePRELOAD)) {
if ((linkTypes & ePREFETCH) || (linkTypes & eNEXT)) {
nsCOMPtr<nsIPrefetchService> prefetchService(
components::Prefetch::Service());
if (prefetchService) {
nsCOMPtr<nsIURI> uri(GetURI());
if (uri) {
bool preload = !!(linkTypes & ePRELOAD);
nsContentPolicyType policyType;
if (preload) {
nsAttrValue asAttr;
nsAutoString mimeType;
nsAutoString media;
GetContentPolicyMimeTypeMedia(asAttr, policyType, mimeType, media);
if (policyType == nsIContentPolicy::TYPE_INVALID) {
// Ignore preload with a wrong or empty as attribute.
return;
}
if (!CheckPreloadAttrs(asAttr, mimeType, media, OwnerDoc())) {
policyType = nsIContentPolicy::TYPE_INVALID;
}
}
auto referrerInfo = MakeRefPtr<ReferrerInfo>(*this);
if (preload) {
prefetchService->PreloadURI(uri, referrerInfo, this, policyType);
} else {
prefetchService->PrefetchURI(uri, referrerInfo, this,
linkTypes & ePREFETCH);
}
prefetchService->PrefetchURI(uri, referrerInfo, this,
linkTypes & ePREFETCH);
return;
}
}
}
if (linkTypes & ePRELOAD) {
nsCOMPtr<nsIURI> uri(GetURI());
if (uri) {
nsContentPolicyType policyType;
nsAttrValue asAttr;
nsAutoString mimeType;
nsAutoString media;
GetContentPolicyMimeTypeMedia(asAttr, policyType, mimeType, media);
if (policyType == nsIContentPolicy::TYPE_INVALID) {
// Ignore preload with a wrong or empty as attribute.
return;
}
if (!CheckPreloadAttrs(asAttr, mimeType, media, OwnerDoc())) {
policyType = nsIContentPolicy::TYPE_INVALID;
}
StartPreload(policyType);
return;
}
}
if (linkTypes & ePRECONNECT) {
if (nsCOMPtr<nsIURI> uri = GetURI()) {
OwnerDoc()->MaybePreconnect(
@@ -667,11 +667,6 @@ void HTMLLinkElement::UpdatePreload(nsAtom* aName, const nsAttrValue* aValue,
return;
}
nsCOMPtr<nsIPrefetchService> prefetchService(components::Prefetch::Service());
if (!prefetchService) {
return;
}
nsCOMPtr<nsIURI> uri(GetURI());
if (!uri) {
return;
@@ -686,7 +681,7 @@ void HTMLLinkElement::UpdatePreload(nsAtom* aName, const nsAttrValue* aValue,
if (asPolicyType == nsIContentPolicy::TYPE_INVALID) {
// Ignore preload with a wrong or empty as attribute, but be sure to cancel
// the old one.
prefetchService->CancelPrefetchPreloadURI(uri, this);
CancelPrefetchOrPreload();
return;
}
@@ -699,10 +694,8 @@ void HTMLLinkElement::UpdatePreload(nsAtom* aName, const nsAttrValue* aValue,
CORSMode corsMode = AttrValueToCORSMode(aValue);
CORSMode oldCorsMode = AttrValueToCORSMode(aOldValue);
if (corsMode != oldCorsMode) {
prefetchService->CancelPrefetchPreloadURI(uri, this);
auto referrerInfo = MakeRefPtr<ReferrerInfo>(*this);
prefetchService->PreloadURI(uri, referrerInfo, this, policyType);
CancelPrefetchOrPreload();
StartPreload(policyType);
}
return;
}
@@ -750,7 +743,7 @@ void HTMLLinkElement::UpdatePreload(nsAtom* aName, const nsAttrValue* aValue,
if ((policyType != oldPolicyType) &&
(oldPolicyType != nsIContentPolicy::TYPE_INVALID)) {
prefetchService->CancelPrefetchPreloadURI(uri, this);
CancelPrefetchOrPreload();
}
// Trigger a new preload if the policy type has changed.
@@ -758,12 +751,13 @@ void HTMLLinkElement::UpdatePreload(nsAtom* aName, const nsAttrValue* aValue,
// trigger an error event.
if ((policyType != oldPolicyType) ||
(policyType == nsIContentPolicy::TYPE_INVALID)) {
auto referrerInfo = MakeRefPtr<ReferrerInfo>(*this);
prefetchService->PreloadURI(uri, referrerInfo, this, policyType);
StartPreload(policyType);
}
}
void HTMLLinkElement::CancelPrefetchOrPreload() {
CancelPreload();
nsCOMPtr<nsIPrefetchService> prefetchService(components::Prefetch::Service());
if (prefetchService) {
if (nsCOMPtr<nsIURI> uri = GetURI()) {
@@ -772,6 +766,25 @@ void HTMLLinkElement::CancelPrefetchOrPreload() {
}
}
void HTMLLinkElement::StartPreload(nsContentPolicyType policyType) {
MOZ_ASSERT(!mPreload, "Forgot to cancel the running preload");
auto referrerInfo = MakeRefPtr<ReferrerInfo>(*this);
RefPtr<PreloaderBase> preload =
OwnerDoc()->Preloads().PreloadLinkElement(this, policyType, referrerInfo);
mPreload = preload.get();
}
void HTMLLinkElement::CancelPreload() {
if (mPreload) {
// This will cancel the loading channel if this was the last referred node
// and the preload is not used up until now to satisfy a regular tag load
// request.
mPreload->RemoveLinkPreloadNode(this);
mPreload = nullptr;
}
}
// We will use official mime-types from:
// https://www.iana.org/assignments/media-types/media-types.xhtml#font
// We do not support old deprecated mime-types for preload feature.