Bug 1839313 - Add "fetchpriority" attribute to <img> element. r=smaug

This patch adds fetchpriority support for the `<img>` element, also
exposing the corresponding attribute in the WebIDL. As in D197493, we
try and minimize the change and rely on a mapping configurable under a
preference to ease future experiments. We use initial mapping
PRIORITY_LOW/PRIORITY_HIGH/PRIORITY_LOW for fetchpriority=low/high/auto
and allow further adjustments in the image code.

Internal fetchpriority mapping is covered by the following tests:
- `image-initial-load.h2.html` (typos fixed here)
- `image-dynamic-load.h2.html`

DOM tests are covered by the following tests (pref enabled to make them
pass):
- `idlharness.https.html`
- `attr-img-fetchpriority.html`

Differential Revision: https://phabricator.services.mozilla.com/D202222
This commit is contained in:
Frédéric Wang 2024-02-27 18:49:08 +00:00
Родитель be4226fa61
Коммит acef313f3d
10 изменённых файлов: 28 добавлений и 42 удалений

Просмотреть файл

@ -47,6 +47,7 @@
#include "mozilla/dom/BindContext.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/FetchPriority.h"
#include "mozilla/dom/PContent.h" // For TextRecognitionResult
#include "mozilla/dom/HTMLImageElement.h"
#include "mozilla/dom/ImageTextBinding.h"
@ -1143,7 +1144,8 @@ nsresult nsImageLoadingContent::LoadImage(nsIURI* aNewURI, bool aForce,
nsresult rv = nsContentUtils::LoadImage(
aNewURI, element, aDocument, triggeringPrincipal, 0, referrerInfo, this,
loadFlags, element->LocalName(), getter_AddRefs(req), policyType,
mUseUrgentStartForChannel);
mUseUrgentStartForChannel, /* aLinkPreload */ false,
/* aEarlyHintPreloaderId */ 0, GetFetchPriorityForImage());
// Reset the flag to avoid loading from XPCOM or somewhere again else without
// initiated by user interaction.
@ -1862,3 +1864,7 @@ nsLoadFlags nsImageLoadingContent::LoadFlags() {
}
return nsIRequest::LOAD_NORMAL;
}
FetchPriority nsImageLoadingContent::GetFetchPriorityForImage() const {
return FetchPriority::Auto;
}

Просмотреть файл

@ -40,6 +40,7 @@ namespace dom {
struct BindContext;
class Document;
class Element;
enum class FetchPriority : uint8_t;
} // namespace dom
} // namespace mozilla
@ -236,6 +237,8 @@ class nsImageLoadingContent : public nsIImageLoadingContent {
// want a non-const nsIContent.
virtual nsIContent* AsContent() = 0;
virtual mozilla::dom::FetchPriority GetFetchPriorityForImage() const;
/**
* Get width and height of the current request, using given image request if
* attributes are unset.

Просмотреть файл

@ -220,6 +220,10 @@ bool HTMLImageElement::ParseAttribute(int32_t aNamespaceID, nsAtom* aAttribute,
if (aAttribute == nsGkAtoms::loading) {
return ParseLoadingAttribute(aValue, aResult);
}
if (aAttribute == nsGkAtoms::fetchpriority) {
ParseFetchPriority(aValue, aResult);
return true;
}
if (ParseImageAttribute(aAttribute, aValue, aResult)) {
return true;
}
@ -1374,4 +1378,8 @@ void HTMLImageElement::QueueImageLoadTask(bool aAlwaysLoad) {
CycleCollectedJSContext::Get()->DispatchToMicroTask(task.forget());
}
FetchPriority HTMLImageElement::GetFetchPriorityForImage() const {
return nsGenericHTMLElement::GetFetchPriority();
}
} // namespace mozilla::dom

Просмотреть файл

@ -263,6 +263,8 @@ class HTMLImageElement final : public nsGenericHTMLElement,
// element.
const StyleLockedDeclarationBlock* GetMappedAttributesFromSource() const;
FetchPriority GetFetchPriorityForImage() const override;
protected:
virtual ~HTMLImageElement();

Просмотреть файл

@ -43,6 +43,8 @@ interface HTMLImageElement : HTMLElement {
attribute DOMString decoding;
[CEReactions, SetterThrows]
attribute DOMString loading;
[Pref="network.fetchpriority.enabled", CEReactions]
attribute DOMString fetchPriority;
readonly attribute unsigned long naturalWidth;
readonly attribute unsigned long naturalHeight;
readonly attribute boolean complete;

Просмотреть файл

@ -215,13 +215,8 @@ nsIContentHandle* nsHtml5TreeBuilder::createElement(
nsHtml5AttributeName::ATTR_REFERRERPOLICY);
nsHtml5String sizes =
aAttributes->getValue(nsHtml5AttributeName::ATTR_SIZES);
// TODO: support the fetchpriority attribute in bug 1839313.
// Meanwhile the empty string is used since it's mapped to the
// auto state
// (https://html.spec.whatwg.org/#fetch-priority-attribute).
auto fetchPriority = nsHtml5String::EmptyString();
nsHtml5String fetchPriority =
aAttributes->getValue(nsHtml5AttributeName::ATTR_FETCHPRIORITY);
mSpeculativeLoadQueue.AppendElement()->InitImage(
url, crossOrigin, /* aMedia = */ nullptr, referrerPolicy,
srcset, sizes, false, fetchPriority);

Просмотреть файл

@ -1,4 +1,4 @@
prefs: [dom.security.featurePolicy.experimental.enabled:true, dom.security.featurePolicy.header.enabled:true, dom.security.featurePolicy.webidl.enabled:true, dom.iframe_lazy_loading.enabled:true, dom.webcomponents.shadowdom.declarative.enabled:true]
prefs: [dom.security.featurePolicy.experimental.enabled:true, dom.security.featurePolicy.header.enabled:true, dom.security.featurePolicy.webidl.enabled:true, dom.iframe_lazy_loading.enabled:true, dom.webcomponents.shadowdom.declarative.enabled:true, network.fetchpriority.enabled:true]
[idlharness.https.html?exclude=(Document|Window|HTML.*)]
[AudioTrack interface: existence and properties of interface prototype object]
expected: FAIL
@ -856,27 +856,6 @@ prefs: [dom.security.featurePolicy.experimental.enabled:true, dom.security.featu
[HTMLElement interface: document.createElement("noscript") must inherit property "onbeforematch" with the proper type]
expected: FAIL
[HTMLLinkElement interface: attribute fetchPriority]
expected: FAIL
[HTMLLinkElement interface: document.createElement("link") must inherit property "fetchPriority" with the proper type]
expected: FAIL
[HTMLImageElement interface: attribute fetchPriority]
expected: FAIL
[HTMLImageElement interface: document.createElement("img") must inherit property "fetchPriority" with the proper type]
expected: FAIL
[HTMLImageElement interface: new Image() must inherit property "fetchPriority" with the proper type]
expected: FAIL
[HTMLScriptElement interface: attribute fetchPriority]
expected: FAIL
[HTMLScriptElement interface: document.createElement("script") must inherit property "fetchPriority" with the proper type]
expected: FAIL
[HTMLDetailsElement interface: attribute name]
expected: FAIL

Просмотреть файл

@ -1,6 +1,2 @@
[attr-img-fetchpriority.html]
[fetchpriority attribute on <img> elements should reflect valid IDL values]
expected: FAIL
[fetchPriority of new Image() is 'auto']
expected: FAIL
prefs: [network.fetchpriority.enabled:true]

Просмотреть файл

@ -1,8 +1,3 @@
[fetchpriority.h2.html]
lsan-allowed: [mozilla::net::AddStaticElement, InitializeStaticHeaders, mozilla::net::nvFIFO::nvFIFO, mozilla::net::Http2BaseCompressor::Http2BaseCompressor] # https://bugzilla.mozilla.org/show_bug.cgi?id=1759310
prefs: [network.fetchpriority.enabled:true]
[image-dynamic-load.h2.html: test different 'fetchpriority' values]
expected: FAIL
[image-initial-load.h2.html: test different 'fetchpriority' values]
expected: FAIL

Просмотреть файл

@ -5,8 +5,8 @@
<title>fetchpriority</title>
</head>
<body>
<img fetchpriority="low" src="../resources/square_25px_x_25px.png?2" alt="img">
<img fetchpriority="high" src="../resources/square_25px_x_25px.png?1" alt="img">
<img fetchpriority="low" src="../resources/square_25px_x_25px.png?1" alt="img">
<img fetchpriority="high" src="../resources/square_25px_x_25px.png?2" alt="img">
<img fetchpriority="auto" src="../resources/square_25px_x_25px.png?3" alt="img">
<img src="../resources/square_25px_x_25px.png?4" alt="img">
<script>