Bug 1847712 - support fetchpriority for SVG image, feImage and script elements r=emilio

Differential Revision: https://phabricator.services.mozilla.com/D246863
This commit is contained in:
longsonr
2025-04-29 03:35:00 +00:00
parent 3651b0f0e5
commit e69829766c
25 changed files with 187 additions and 92 deletions

View File

@@ -1148,6 +1148,37 @@ Element::Loading Element::LoadingState() const {
return static_cast<Loading>(val->GetEnumValue());
}
namespace {
// <https://html.spec.whatwg.org/multipage/urls-and-fetching.html#fetch-priority-attributes>.
static constexpr nsAttrValue::EnumTable kFetchPriorityEnumTable[] = {
{kFetchPriorityAttributeValueHigh, FetchPriority::High},
{kFetchPriorityAttributeValueLow, FetchPriority::Low},
{kFetchPriorityAttributeValueAuto, FetchPriority::Auto},
{nullptr, 0}};
// <https://html.spec.whatwg.org/multipage/urls-and-fetching.html#fetch-priority-attributes>.
static const nsAttrValue::EnumTable*
kFetchPriorityEnumTableInvalidValueDefault = &kFetchPriorityEnumTable[2];
} // namespace
void Element::ParseFetchPriority(const nsAString& aValue,
nsAttrValue& aResult) {
aResult.ParseEnumValue(aValue, kFetchPriorityEnumTable,
false /* aCaseSensitive */,
kFetchPriorityEnumTableInvalidValueDefault);
}
FetchPriority Element::GetFetchPriority() const {
const nsAttrValue* fetchpriorityAttribute =
GetParsedAttr(nsGkAtoms::fetchpriority);
if (fetchpriorityAttribute) {
MOZ_ASSERT(fetchpriorityAttribute->Type() == nsAttrValue::eEnum);
return FetchPriority(fetchpriorityAttribute->GetEnumValue());
}
return FetchPriority::Auto;
}
//----------------------------------------------------------------------
void Element::AddToIdTable(nsAtom* aId) {

View File

@@ -145,6 +145,7 @@ template <typename T>
class Optional;
enum class CallerType : uint32_t;
enum class ReferrerPolicy : uint8_t;
enum class FetchPriority : uint8_t;
} // namespace dom
} // namespace mozilla
@@ -2216,6 +2217,10 @@ class Element : public FragmentOrElement {
MOZ_CAN_RUN_SCRIPT
nsresult PostHandleEventForLinks(EventChainPostVisitor& aVisitor);
mozilla::dom::FetchPriority GetFetchPriority() const;
static void ParseFetchPriority(const nsAString& aValue, nsAttrValue& aResult);
public:
/**
* Check if this element is a link. This matches the CSS definition of the

View File

@@ -1295,7 +1295,7 @@ void HTMLImageElement::SetDensity(double aDensity) {
}
FetchPriority HTMLImageElement::GetFetchPriorityForImage() const {
return nsGenericHTMLElement::GetFetchPriority();
return Element::GetFetchPriority();
}
} // namespace mozilla::dom

View File

@@ -397,7 +397,7 @@ Maybe<LinkStyle::SheetInfo> HTMLLinkElement::GetStyleSheetInfo() {
alternate ? HasAlternateRel::Yes : HasAlternateRel::No,
IsInline::No,
mExplicitlyEnabled ? IsExplicitlyEnabled::Yes : IsExplicitlyEnabled::No,
GetFetchPriority(),
Element::GetFetchPriority(),
});
}

View File

@@ -318,7 +318,7 @@ CORSMode HTMLScriptElement::GetCORSMode() const {
}
FetchPriority HTMLScriptElement::GetFetchPriority() const {
return nsGenericHTMLElement::GetFetchPriority();
return Element::GetFetchPriority();
}
mozilla::dom::ReferrerPolicy HTMLScriptElement::GetReferrerPolicy() {

View File

@@ -211,38 +211,6 @@ FetchPriority nsGenericHTMLElement::ToFetchPriority(const nsAString& aValue) {
return FetchPriority(attrValue.GetEnumValue());
}
namespace {
// <https://html.spec.whatwg.org/multipage/urls-and-fetching.html#fetch-priority-attributes>.
static constexpr nsAttrValue::EnumTable kFetchPriorityEnumTable[] = {
{kFetchPriorityAttributeValueHigh, FetchPriority::High},
{kFetchPriorityAttributeValueLow, FetchPriority::Low},
{kFetchPriorityAttributeValueAuto, FetchPriority::Auto},
{nullptr, 0}};
// <https://html.spec.whatwg.org/multipage/urls-and-fetching.html#fetch-priority-attributes>.
static const nsAttrValue::EnumTable*
kFetchPriorityEnumTableInvalidValueDefault = &kFetchPriorityEnumTable[2];
} // namespace
FetchPriority nsGenericHTMLElement::GetFetchPriority() const {
const nsAttrValue* fetchpriorityAttribute =
GetParsedAttr(nsGkAtoms::fetchpriority);
if (fetchpriorityAttribute) {
MOZ_ASSERT(fetchpriorityAttribute->Type() == nsAttrValue::eEnum);
return FetchPriority(fetchpriorityAttribute->GetEnumValue());
}
return FetchPriority::Auto;
}
/* static */
void nsGenericHTMLElement::ParseFetchPriority(const nsAString& aValue,
nsAttrValue& aResult) {
aResult.ParseEnumValue(aValue, kFetchPriorityEnumTable,
false /* aCaseSensitive */,
kFetchPriorityEnumTableInvalidValueDefault);
}
void nsGenericHTMLElement::AddToNameTable(nsAtom* aName) {
MOZ_ASSERT(HasName(), "Node doesn't have name?");
Document* doc = GetUncomposedDoc();

View File

@@ -750,11 +750,6 @@ class nsGenericHTMLElement : public nsGenericHTMLElementBase {
SetHTMLAttr(nsGkAtoms::fetchpriority, aFetchPriority);
}
protected:
mozilla::dom::FetchPriority GetFetchPriority() const;
static void ParseFetchPriority(const nsAString& aValue, nsAttrValue& aResult);
private:
/**
* Add/remove this element to the documents name cache

View File

@@ -9,6 +9,7 @@
#include "mozilla/SVGObserverUtils.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/BindContext.h"
#include "mozilla/dom/FetchPriority.h"
#include "mozilla/dom/SVGFEImageElementBinding.h"
#include "mozilla/dom/SVGFilterElement.h"
#include "mozilla/dom/UserActivation.h"
@@ -105,11 +106,16 @@ bool SVGFEImageElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
const nsAString& aValue,
nsIPrincipal* aMaybeScriptedPrincipal,
nsAttrValue& aResult) {
if (aNamespaceID == kNameSpaceID_None &&
aAttribute == nsGkAtoms::crossorigin) {
if (aNamespaceID == kNameSpaceID_None) {
if (aAttribute == nsGkAtoms::crossorigin) {
ParseCORSValue(aValue, aResult);
return true;
}
if (aAttribute == nsGkAtoms::fetchpriority) {
ParseFetchPriority(aValue, aResult);
return true;
}
}
return SVGFEImageElementBase::ParseAttribute(
aNamespaceID, aAttribute, aValue, aMaybeScriptedPrincipal, aResult);
}
@@ -204,6 +210,11 @@ CORSMode SVGFEImageElement::GetCORSMode() {
return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
}
void SVGFEImageElement::GetFetchPriority(nsAString& aFetchPriority) const {
GetEnumAttr(nsGkAtoms::fetchpriority, kFetchPriorityAttributeValueAuto,
aFetchPriority);
}
//----------------------------------------------------------------------
// nsIDOMSVGFEImageElement methods

View File

@@ -93,6 +93,11 @@ class SVGFEImageElement final : public SVGFEImageElementBase,
SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError);
}
void GetFetchPriority(nsAString& aFetchPriority) const;
void SetFetchPriority(const nsAString& aFetchPriority) {
SetAttr(nsGkAtoms::fetchpriority, aFetchPriority, IgnoreErrors());
}
private:
void DidAnimateAttribute(int32_t aNameSpaceID, nsAtom* aAttribute) override;
nsresult LoadSVGImage(bool aForce, bool aNotify);
@@ -107,6 +112,10 @@ class SVGFEImageElement final : public SVGFEImageElementBase,
// Override for nsImageLoadingContent.
nsIContent* AsContent() override { return this; }
FetchPriority GetFetchPriorityForImage() const override {
return Element::GetFetchPriority();
}
enum { RESULT, HREF, XLINK_HREF };
SVGAnimatedString mStringAttributes[3];
static StringInfo sStringInfo[3];

View File

@@ -13,6 +13,7 @@
#include "nsNetUtil.h"
#include "imgINotificationObserver.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/FetchPriority.h"
#include "mozilla/dom/SVGImageElementBinding.h"
#include "mozilla/dom/SVGLengthBinding.h"
#include "mozilla/dom/UserActivation.h"
@@ -181,6 +182,11 @@ CORSMode SVGImageElement::GetCORSMode() {
return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
}
void SVGImageElement::GetFetchPriority(nsAString& aFetchPriority) const {
GetEnumAttr(nsGkAtoms::fetchpriority, kFetchPriorityAttributeValueAuto,
aFetchPriority);
}
//----------------------------------------------------------------------
// nsIContent methods:
@@ -197,6 +203,10 @@ bool SVGImageElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
return aResult.ParseEnumValue(aValue, kDecodingTable, false,
kDecodingTableDefault);
}
if (aAttribute == nsGkAtoms::fetchpriority) {
ParseFetchPriority(aValue, aResult);
return true;
}
}
return SVGImageElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue,

View File

@@ -90,6 +90,11 @@ class SVGImageElement final : public SVGImageElementBase,
SetOrRemoveNullableStringAttr(nsGkAtoms::crossorigin, aCrossOrigin, aError);
}
void GetFetchPriority(nsAString& aFetchPriority) const;
void SetFetchPriority(const nsAString& aFetchPriority) {
SetAttr(nsGkAtoms::fetchpriority, aFetchPriority, IgnoreErrors());
}
void SetDecoding(const nsAString& aDecoding, ErrorResult& aError) {
SetAttr(nsGkAtoms::decoding, aDecoding, aError);
}
@@ -114,6 +119,10 @@ class SVGImageElement final : public SVGImageElementBase,
// Override for nsImageLoadingContent.
nsIContent* AsContent() override { return this; }
FetchPriority GetFetchPriorityForImage() const override {
return Element::GetFetchPriority();
}
enum { ATTR_X, ATTR_Y, ATTR_WIDTH, ATTR_HEIGHT };
SVGAnimatedLength mLengthAttributes[4];
static LengthInfo sLengthInfo[4];

View File

@@ -203,11 +203,16 @@ bool SVGScriptElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
const nsAString& aValue,
nsIPrincipal* aMaybeScriptedPrincipal,
nsAttrValue& aResult) {
if (aNamespaceID == kNameSpaceID_None &&
aAttribute == nsGkAtoms::crossorigin) {
if (aNamespaceID == kNameSpaceID_None) {
if (aAttribute == nsGkAtoms::crossorigin) {
ParseCORSValue(aValue, aResult);
return true;
}
if (aAttribute == nsGkAtoms::fetchpriority) {
ParseFetchPriority(aValue, aResult);
return true;
}
}
return SVGScriptElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue,
aMaybeScriptedPrincipal, aResult);
@@ -217,9 +222,13 @@ CORSMode SVGScriptElement::GetCORSMode() const {
return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
}
void SVGScriptElement::GetFetchPriority(nsAString& aFetchPriority) const {
GetEnumAttr(nsGkAtoms::fetchpriority, kFetchPriorityAttributeValueAuto,
aFetchPriority);
}
FetchPriority SVGScriptElement::GetFetchPriority() const {
// <https://github.com/w3c/svgwg/issues/916>.
return FetchPriority::Auto;
return Element::GetFetchPriority();
}
} // namespace mozilla::dom

View File

@@ -70,6 +70,10 @@ class SVGScriptElement final : public SVGScriptElementBase,
void GetCrossOrigin(nsAString& aCrossOrigin);
void SetCrossOrigin(const nsAString& aCrossOrigin, ErrorResult& aError);
already_AddRefed<DOMSVGAnimatedString> Href();
void GetFetchPriority(nsAString& aFetchPriority) const;
void SetFetchPriority(const nsAString& aFetchPriority) {
SetAttr(nsGkAtoms::fetchpriority, aFetchPriority, IgnoreErrors());
}
protected:
~SVGScriptElement() = default;

View File

@@ -16,6 +16,8 @@ interface SVGFEImageElement : SVGElement {
readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio;
[SetterThrows]
attribute DOMString? crossOrigin;
[Pref="network.fetchpriority.enabled"]
attribute DOMString fetchPriority;
};
SVGFEImageElement includes SVGFilterPrimitiveStandardAttributes;

View File

@@ -24,6 +24,8 @@ interface SVGImageElement : SVGGraphicsElement {
readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio;
[SetterThrows]
attribute DOMString? crossOrigin;
[Pref="network.fetchpriority.enabled"]
attribute DOMString fetchPriority;
[CEReactions, SetterThrows]
attribute DOMString decoding;
[NewObject]

View File

@@ -19,6 +19,8 @@ interface SVGScriptElement : SVGElement {
attribute boolean defer;
[SetterThrows]
attribute DOMString? crossOrigin;
[Pref="network.fetchpriority.enabled"]
attribute DOMString fetchPriority;
};
SVGScriptElement includes SVGURIReference;

View File

@@ -547,22 +547,21 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement(
}
break;
case kNameSpaceID_SVG:
if (nsGkAtoms::image == aName) {
if (nsGkAtoms::image == aName || nsGkAtoms::feImage == aName) {
nsHtml5String url =
aAttributes->getValue(nsHtml5AttributeName::ATTR_HREF);
if (!url) {
url = aAttributes->getValue(nsHtml5AttributeName::ATTR_XLINK_HREF);
}
if (url) {
// Currently SVG's `<image>` element lacks support for
// `fetchpriority`, see bug 1847712. Hence passing nullptr which
// maps to the auto state
// (https://html.spec.whatwg.org/#fetch-priority-attribute).
auto fetchPriority = nullptr;
nsHtml5String crossOrigin =
aAttributes->getValue(nsHtml5AttributeName::ATTR_CROSSORIGIN);
nsHtml5String fetchPriority =
aAttributes->getValue(nsHtml5AttributeName::ATTR_FETCHPRIORITY);
mSpeculativeLoadQueue.AppendElement()->InitImage(
url, nullptr, nullptr, nullptr, nullptr, nullptr, false,
fetchPriority);
url, crossOrigin, /* aMedia = */ nullptr, nullptr, nullptr,
nullptr, false, fetchPriority);
}
} else if (nsGkAtoms::script == aName) {
nsHtml5TreeOperation* treeOp =
@@ -621,14 +620,8 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement(
aAttributes->getValue(nsHtml5AttributeName::ATTR_INTEGRITY);
nsHtml5String referrerPolicy = aAttributes->getValue(
nsHtml5AttributeName::ATTR_REFERRERPOLICY);
// Bug 1847712: SVG's `<script>` element doesn't support
// `fetchpriority` yet.
// Use the empty string and rely on the
// "invalid value default" state being used later.
// Compared to using a non-empty string, this doesn't
// require calling `Release()` for the string.
nsHtml5String fetchPriority = nsHtml5String::EmptyString();
nsHtml5String fetchPriority = aAttributes->getValue(
nsHtml5AttributeName::ATTR_FETCHPRIORITY);
mSpeculativeLoadQueue.AppendElement()->InitScript(
url, nullptr, type, crossOrigin, /* aMedia = */ nullptr,

View File

@@ -0,0 +1,2 @@
[attr-image-fetchpriority.html]
prefs: [network.fetchpriority.enabled:true]

View File

@@ -0,0 +1,2 @@
[attr-script-fetchpriority.html]
prefs: [network.fetchpriority.enabled:true]

View File

@@ -40,13 +40,11 @@ const kExpectedRequestsOfDynamicLoadDisabled = kExpectedRequestsOfInitialLoadDis
const kExpectedRequestsOfInitialLoadForSVGImageTagDisabled = kExpectedRequestsOfInitialLoadDisabled;
// TODO(bug 1865837): Should SVG's `<image>` element support the `fetchpriority` attribute?
const kExpectedRequestsOfInitialLoadForSVGImageTag = kExpectedRequestsOfInitialLoadForSVGImageTagDisabled;
const kExpectedRequestsOfDynamicLoadForSVGImageTagDisabled = kExpectedRequestsOfDynamicLoadDisabled;
// TODO(bug 1865837): Should SVG's `<image>` element support the `fetchpriority` attribute?
const kExpectedRequestsOfDynamicLoadForSVGImageTag = kExpectedRequestsOfDynamicLoadForSVGImageTagDisabled;
const kExpectedRequestsOfDynamicLoadForSVGImageTag = kExpectedRequestsOfInitialLoad;
const kExpectedRequestsShapeOutsideImage = [
{ fileNameAndSuffix: "square_25px_x_25px.png?1",

View File

@@ -54,10 +54,10 @@ const kExpectedRequestsForScriptsInBody = [
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL
},
{ fileNameAndSuffix: "dummy.js?5",
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW
},
{ fileNameAndSuffix: "dummy.js?6",
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGH
},
{ fileNameAndSuffix: "dummy.js?7",
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL
@@ -78,10 +78,10 @@ const kExpectedRequestsForScriptsInBody = [
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL
},
{ fileNameAndSuffix: "dummy.js?13",
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW
},
{ fileNameAndSuffix: "dummy.js?14",
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGH
},
{ fileNameAndSuffix: "dummy.js?15",
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL
@@ -158,10 +158,10 @@ const kExpectedRequestsForNonModuleAsyncAndDeferredScripts = [
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL
},
{ fileNameAndSuffix: "dummy.js?5",
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW
},
{ fileNameAndSuffix: "dummy.js?6",
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGH
},
{ fileNameAndSuffix: "dummy.js?7",
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL
@@ -214,10 +214,10 @@ const kExpectedRequestsForModuleScripts = [
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL
},
{ fileNameAndSuffix: "dummy.js?5",
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_LOW
},
{ fileNameAndSuffix: "dummy.js?6",
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_HIGH
},
{ fileNameAndSuffix: "dummy.js?7",
internalPriority: SpecialPowers.Ci.nsISupportsPriority.PRIORITY_NORMAL

View File

@@ -23,17 +23,10 @@
if (!data.svg) {
scriptElement = document.createElement("script");
scriptElement.src = data.src;
if ("fetchPriority" in data) {
scriptElement.fetchPriority = data.fetchPriority;
}
} else {
const namespaceURI = "http://www.w3.org/2000/svg";
scriptElement = document.createElementNS(namespaceURI, "script");
scriptElement.href.baseVal = data.src;
// Use setAttribute as SVGScriptElement has no fetchPriority property.
if ("fetchPriority" in data) {
scriptElement.setAttribute("fetchPriority", data.fetchPriority);
}
}
scriptElement.type = "module";

View File

@@ -24,18 +24,14 @@
if (!data.svg) {
scriptElement = document.createElement("script");
scriptElement.src = data.src;
if ("fetchPriority" in data) {
scriptElement.fetchPriority = data.fetchPriority;
}
} else {
const namespaceURI = "http://www.w3.org/2000/svg";
scriptElement = document.createElementNS(namespaceURI, "script");
scriptElement.href.baseVal = data.src;
// Use setAttribute as SVGScriptElement has no fetchPriority property.
scriptElement.setAttribute("href", data.src);
if ("fetchPriority" in data) {
scriptElement.setAttribute("fetchPriority", data.fetchPriority);
}
if ("fetchPriority" in data) {
scriptElement.fetchPriority = data.fetchPriority;
}
allScriptElements.push(scriptElement);

View File

@@ -0,0 +1,27 @@
<!DOCTYPE html>
<title>Fetch Priority - SVG Image element</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<svg>
<image id=image1 fetchpriority="high"/>
<image id=image2 fetchpriority="low"/>
<image id=image3 fetchpriority="auto"/>
<image id=image4 fetchpriority="xyz"/>
<image id=image5 />
</svg>
<script>
test(() => {
assert_equals(image1.fetchPriority, "high", "high fetchPriority is a valid IDL value on the image element");
assert_equals(image2.fetchPriority, "low", "low fetchPriority is a valid IDL value on the image element");
assert_equals(image3.fetchPriority, "auto", "auto fetchPriority is a valid IDL value on the image element");
assert_equals(image4.fetchPriority, "auto", "invalid fetchPriority reflects as 'auto' IDL attribute on the image element");
assert_equals(image5.fetchPriority, "auto", "missing fetchPriority reflects as 'auto' IDL attribute on the image element");
}, "fetchpriority attribute on <image> elements should reflect valid IDL values");
test(() => {
const image = document.createElementNS("http://www.w3.org/2000/svg", "image");
assert_equals(image.fetchPriority, "auto");
}, "default fetchpriority attribute on <image> elements should be 'auto'");
</script>

View File

@@ -0,0 +1,27 @@
<!DOCTYPE html>
<title>Fetch Priority - SVG Script element</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<svg>
<script id=script1 href="resources/script.js" fetchpriority="high"></script>
<script id=script2 href="resources/script.js" fetchpriority="low"></script>
<script id=script3 href="resources/script.js" fetchpriority="auto"></script>
<script id=script4 href="resources/script.js" fetchpriority="xyz"></script>
<script id=script5 href="resources/script.js"></script>
</svg>
<script>
test(() => {
assert_equals(script1.fetchPriority, "high", "high fetchPriority is a valid IDL value on the script element");
assert_equals(script2.fetchPriority, "low", "low fetchPriority is a valid IDL value on the script element");
assert_equals(script3.fetchPriority, "auto", "auto fetchPriority is a valid IDL value on the script element");
assert_equals(script4.fetchPriority, "auto", "invalid fetchPriority reflects as 'auto' IDL attribute on the script element");
assert_equals(script5.fetchPriority, "auto", "missing fetchPriority reflects as 'auto' IDL attribute on the script element");
}, "fetchpriority attribute on SVG <script> elements should reflect valid IDL values");
test(() => {
const script = document.createElementNS("http://www.w3.org/2000/svg", "script");
assert_equals(script.fetchPriority, "auto");
}, "default fetchpriority attribute on SVG <script> elements should be 'auto'");
</script>