Bug 1761242 - Make link asset parsing accessible in nsNetUtils.h r=necko-reviewers,dragana
Differential Revision: https://phabricator.services.mozilla.com/D142053
This commit is contained in:
@@ -148,7 +148,7 @@ bool HTMLLinkElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
|
||||
}
|
||||
|
||||
if (aAttribute == nsGkAtoms::as) {
|
||||
ParseAsValue(aValue, aResult);
|
||||
net::ParseAsValue(aValue, aResult);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -419,79 +419,13 @@ void HTMLLinkElement::GetAs(nsAString& aResult) {
|
||||
GetEnumAttr(nsGkAtoms::as, "", aResult);
|
||||
}
|
||||
|
||||
enum ASDestination : uint8_t {
|
||||
DESTINATION_INVALID,
|
||||
DESTINATION_AUDIO,
|
||||
DESTINATION_DOCUMENT,
|
||||
DESTINATION_EMBED,
|
||||
DESTINATION_FONT,
|
||||
DESTINATION_IMAGE,
|
||||
DESTINATION_MANIFEST,
|
||||
DESTINATION_OBJECT,
|
||||
DESTINATION_REPORT,
|
||||
DESTINATION_SCRIPT,
|
||||
DESTINATION_SERVICEWORKER,
|
||||
DESTINATION_SHAREDWORKER,
|
||||
DESTINATION_STYLE,
|
||||
DESTINATION_TRACK,
|
||||
DESTINATION_VIDEO,
|
||||
DESTINATION_WORKER,
|
||||
DESTINATION_XSLT,
|
||||
DESTINATION_FETCH
|
||||
};
|
||||
|
||||
static const nsAttrValue::EnumTable kAsAttributeTable[] = {
|
||||
{"", DESTINATION_INVALID}, {"audio", DESTINATION_AUDIO},
|
||||
{"font", DESTINATION_FONT}, {"image", DESTINATION_IMAGE},
|
||||
{"script", DESTINATION_SCRIPT}, {"style", DESTINATION_STYLE},
|
||||
{"track", DESTINATION_TRACK}, {"video", DESTINATION_VIDEO},
|
||||
{"fetch", DESTINATION_FETCH}, {nullptr, 0}};
|
||||
|
||||
/* static */
|
||||
void HTMLLinkElement::ParseAsValue(const nsAString& aValue,
|
||||
nsAttrValue& aResult) {
|
||||
DebugOnly<bool> success =
|
||||
aResult.ParseEnumValue(aValue, kAsAttributeTable, false,
|
||||
// default value is a empty string
|
||||
// if aValue is not a value we
|
||||
// understand
|
||||
&kAsAttributeTable[0]);
|
||||
MOZ_ASSERT(success);
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsContentPolicyType HTMLLinkElement::AsValueToContentPolicy(
|
||||
const nsAttrValue& aValue) {
|
||||
switch (aValue.GetEnumValue()) {
|
||||
case DESTINATION_INVALID:
|
||||
return nsIContentPolicy::TYPE_INVALID;
|
||||
case DESTINATION_AUDIO:
|
||||
return nsIContentPolicy::TYPE_INTERNAL_AUDIO;
|
||||
case DESTINATION_TRACK:
|
||||
return nsIContentPolicy::TYPE_INTERNAL_TRACK;
|
||||
case DESTINATION_VIDEO:
|
||||
return nsIContentPolicy::TYPE_INTERNAL_VIDEO;
|
||||
case DESTINATION_FONT:
|
||||
return nsIContentPolicy::TYPE_FONT;
|
||||
case DESTINATION_IMAGE:
|
||||
return nsIContentPolicy::TYPE_IMAGE;
|
||||
case DESTINATION_SCRIPT:
|
||||
return nsIContentPolicy::TYPE_SCRIPT;
|
||||
case DESTINATION_STYLE:
|
||||
return nsIContentPolicy::TYPE_STYLESHEET;
|
||||
case DESTINATION_FETCH:
|
||||
return nsIContentPolicy::TYPE_INTERNAL_FETCH_PRELOAD;
|
||||
}
|
||||
return nsIContentPolicy::TYPE_INVALID;
|
||||
}
|
||||
|
||||
void HTMLLinkElement::GetContentPolicyMimeTypeMedia(
|
||||
nsAttrValue& aAsAttr, nsContentPolicyType& aPolicyType, nsString& aMimeType,
|
||||
nsAString& aMedia) {
|
||||
nsAutoString as;
|
||||
GetAttr(kNameSpaceID_None, nsGkAtoms::as, as);
|
||||
ParseAsValue(as, aAsAttr);
|
||||
aPolicyType = AsValueToContentPolicy(aAsAttr);
|
||||
net::ParseAsValue(as, aAsAttr);
|
||||
aPolicyType = net::AsValueToContentPolicy(aAsAttr);
|
||||
|
||||
nsAutoString type;
|
||||
GetAttr(kNameSpaceID_None, nsGkAtoms::type, type);
|
||||
@@ -542,9 +476,9 @@ void HTMLLinkElement::
|
||||
GetContentPolicyMimeTypeMedia(asAttr, policyType, mimeType, media);
|
||||
|
||||
if (policyType == nsIContentPolicy::TYPE_INVALID ||
|
||||
!CheckPreloadAttrs(asAttr, mimeType, media, OwnerDoc())) {
|
||||
!net::CheckPreloadAttrs(asAttr, mimeType, media, OwnerDoc())) {
|
||||
// Ignore preload with a wrong or empty as attribute.
|
||||
WarnIgnoredPreload(*OwnerDoc(), *uri);
|
||||
net::WarnIgnoredPreload(*OwnerDoc(), *uri);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -601,11 +535,11 @@ void HTMLLinkElement::UpdatePreload(nsAtom* aName, const nsAttrValue* aValue,
|
||||
GetContentPolicyMimeTypeMedia(asAttr, asPolicyType, mimeType, media);
|
||||
|
||||
if (asPolicyType == nsIContentPolicy::TYPE_INVALID ||
|
||||
!CheckPreloadAttrs(asAttr, mimeType, media, OwnerDoc())) {
|
||||
!net::CheckPreloadAttrs(asAttr, mimeType, media, OwnerDoc())) {
|
||||
// Ignore preload with a wrong or empty as attribute, but be sure to cancel
|
||||
// the old one.
|
||||
CancelPrefetchOrPreload();
|
||||
WarnIgnoredPreload(*OwnerDoc(), *uri);
|
||||
net::WarnIgnoredPreload(*OwnerDoc(), *uri);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -623,8 +557,8 @@ void HTMLLinkElement::UpdatePreload(nsAtom* aName, const nsAttrValue* aValue,
|
||||
|
||||
if (aName == nsGkAtoms::as) {
|
||||
if (aOldValue) {
|
||||
oldPolicyType = AsValueToContentPolicy(*aOldValue);
|
||||
if (!CheckPreloadAttrs(*aOldValue, mimeType, media, OwnerDoc())) {
|
||||
oldPolicyType = net::AsValueToContentPolicy(*aOldValue);
|
||||
if (!net::CheckPreloadAttrs(*aOldValue, mimeType, media, OwnerDoc())) {
|
||||
oldPolicyType = nsIContentPolicy::TYPE_INVALID;
|
||||
}
|
||||
} else {
|
||||
@@ -638,7 +572,7 @@ void HTMLLinkElement::UpdatePreload(nsAtom* aName, const nsAttrValue* aValue,
|
||||
}
|
||||
nsAutoString oldMimeType;
|
||||
nsContentUtils::SplitMimeType(oldType, oldMimeType, notUsed);
|
||||
if (CheckPreloadAttrs(asAttr, oldMimeType, media, OwnerDoc())) {
|
||||
if (net::CheckPreloadAttrs(asAttr, oldMimeType, media, OwnerDoc())) {
|
||||
oldPolicyType = asPolicyType;
|
||||
} else {
|
||||
oldPolicyType = nsIContentPolicy::TYPE_INVALID;
|
||||
@@ -649,7 +583,7 @@ void HTMLLinkElement::UpdatePreload(nsAtom* aName, const nsAttrValue* aValue,
|
||||
if (aOldValue) {
|
||||
aOldValue->ToString(oldMedia);
|
||||
}
|
||||
if (CheckPreloadAttrs(asAttr, mimeType, oldMedia, OwnerDoc())) {
|
||||
if (net::CheckPreloadAttrs(asAttr, mimeType, oldMedia, OwnerDoc())) {
|
||||
oldPolicyType = asPolicyType;
|
||||
} else {
|
||||
oldPolicyType = nsIContentPolicy::TYPE_INVALID;
|
||||
@@ -695,95 +629,6 @@ void HTMLLinkElement::CancelPreload() {
|
||||
}
|
||||
}
|
||||
|
||||
// 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.
|
||||
// (We currectly do not support font/collection)
|
||||
static uint32_t StyleLinkElementFontMimeTypesNum = 5;
|
||||
static const char* StyleLinkElementFontMimeTypes[] = {
|
||||
"font/otf", "font/sfnt", "font/ttf", "font/woff", "font/woff2"};
|
||||
|
||||
bool IsFontMimeType(const nsAString& aType) {
|
||||
if (aType.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
for (uint32_t i = 0; i < StyleLinkElementFontMimeTypesNum; i++) {
|
||||
if (aType.EqualsASCII(StyleLinkElementFontMimeTypes[i])) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool HTMLLinkElement::CheckPreloadAttrs(const nsAttrValue& aAs,
|
||||
const nsAString& aType,
|
||||
const nsAString& aMedia,
|
||||
Document* aDocument) {
|
||||
nsContentPolicyType policyType = AsValueToContentPolicy(aAs);
|
||||
if (policyType == nsIContentPolicy::TYPE_INVALID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if media attribute is valid.
|
||||
if (!aMedia.IsEmpty()) {
|
||||
RefPtr<MediaList> mediaList =
|
||||
MediaList::Create(NS_ConvertUTF16toUTF8(aMedia));
|
||||
if (!mediaList->Matches(*aDocument)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (aType.IsEmpty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (policyType == nsIContentPolicy::TYPE_INTERNAL_FETCH_PRELOAD) {
|
||||
return true;
|
||||
}
|
||||
|
||||
nsAutoString type(aType);
|
||||
ToLowerCase(type);
|
||||
if (policyType == nsIContentPolicy::TYPE_MEDIA) {
|
||||
if (aAs.GetEnumValue() == DESTINATION_TRACK) {
|
||||
return type.EqualsASCII("text/vtt");
|
||||
}
|
||||
Maybe<MediaContainerType> mimeType = MakeMediaContainerType(aType);
|
||||
if (!mimeType) {
|
||||
return false;
|
||||
}
|
||||
DecoderDoctorDiagnostics diagnostics;
|
||||
CanPlayStatus status =
|
||||
DecoderTraits::CanHandleContainerType(*mimeType, &diagnostics);
|
||||
// Preload if this return CANPLAY_YES and CANPLAY_MAYBE.
|
||||
return status != CANPLAY_NO;
|
||||
}
|
||||
if (policyType == nsIContentPolicy::TYPE_FONT) {
|
||||
return IsFontMimeType(type);
|
||||
}
|
||||
if (policyType == nsIContentPolicy::TYPE_IMAGE) {
|
||||
return imgLoader::SupportImageWithMimeType(
|
||||
NS_ConvertUTF16toUTF8(type), AcceptedMimeTypes::IMAGES_AND_DOCUMENTS);
|
||||
}
|
||||
if (policyType == nsIContentPolicy::TYPE_SCRIPT) {
|
||||
return nsContentUtils::IsJavascriptMIMEType(type);
|
||||
}
|
||||
if (policyType == nsIContentPolicy::TYPE_STYLESHEET) {
|
||||
return type.EqualsASCII("text/css");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void HTMLLinkElement::WarnIgnoredPreload(const Document& aDoc, nsIURI& aURI) {
|
||||
AutoTArray<nsString, 1> params;
|
||||
{
|
||||
nsCString uri = nsContentUtils::TruncatedURLForDisplay(&aURI);
|
||||
AppendUTF8toUTF16(uri, *params.AppendElement());
|
||||
}
|
||||
nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, "DOM"_ns, &aDoc,
|
||||
nsContentUtils::eDOM_PROPERTIES,
|
||||
"PreloadIgnoredInvalidAttr", params);
|
||||
}
|
||||
|
||||
bool HTMLLinkElement::IsCSSMimeTypeAttributeForLinkElement(
|
||||
const Element& aSelf) {
|
||||
// Processing the type attribute per
|
||||
|
||||
Reference in New Issue
Block a user