254 source
@@ -7177,6 +7177,37 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<code>HTMLOrSVGElement</code> must set the <span>[[CryptographicNonce]]</span> slot on the copy
to the value of the slot on the element being cloned.</p>

<h4>Lazy loading attributes</h4>

<p>A <dfn>lazy loading attribute</dfn> is an <span>enumerated attribute</span>. The following
table lists the keywords and states for the attribute &mdash; the keywords in the left column map
to the states in the cell in the second column on the same row as the keyword.</p>

<p>The attribute directs the user agent to fetch a resource immediately or to defer fetching until
some conditions associated with the element are met, according to the attribute's current
state.</p>

<table>
<thead>
<tr>
<th>Keyword
<th>State
<th>Description
<tbody>
<tr>
<td><dfn><code data-x="attr-loading-lazy">lazy</code></dfn>
<td><dfn data-x="attr-loading-lazy-state">Lazy</dfn>
<td>Used to defer fetching a resource until some conditions are met.
<tr>
<td><dfn><code data-x="attr-loading-eager">eager</code></dfn>
<td><dfn data-x="attr-loading-eager-state">Eager</dfn>
<td>Used to fetch a resource immediately; the default state.
</table>

<p>The attribute's <i data-x="missing value default">missing value default</i> and <i
data-x="invalid value default">invalid value default</i> are both the <span
data-x="attr-loading-eager-state">Eager</span> state.</p>


<h3 split-filename="common-dom-interfaces">Common DOM interfaces</h3>

@@ -26338,6 +26369,7 @@ interface <dfn>HTMLSourceElement</dfn> : <span>HTMLElement</span> {
<dd><code data-x="attr-dim-height">height</code></dd>
<dd><code data-x="attr-img-referrerpolicy">referrerpolicy</code></dd>
<dd><code data-x="attr-img-decoding">decoding</code></dd>
<dd><code data-x="attr-img-loading">loading</code></dd>
<dt><span
data-x="concept-element-accessibility-considerations">Accessibility considerations</span>:</dt>
<dd>If the element has a non-empty <code data-x="attr-img-alt">alt</code> attribute: <a
@@ -26368,6 +26400,7 @@ interface <dfn>HTMLImageElement</dfn> : <span>HTMLElement</span> {
readonly attribute USVString <span data-x="dom-img-currentSrc">currentSrc</span>;
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-img-referrerPolicy">referrerPolicy</span>;
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-img-decoding">decoding</span>;
[<span>CEReactions</span>] attribute DOMString <span data-x="dom-img-loading">loading</span>;

Promise&lt;void&gt; <span data-x="dom-img-decode">decode</span>();
};</code></pre>
@@ -26443,6 +26476,40 @@ interface <dfn>HTMLImageElement</dfn> : <span>HTMLElement</span> {
default">missing value default</i> and <i data-x="invalid value default">invalid value
default</i> are both the <span data-x="attr-img-decoding-auto-state">auto</span> state.</p>

<p>The <dfn data-x="attr-img-loading"><code>loading</code></dfn> attribute is a <span>lazy
loading attribute</span>. Its purpose is to indicate the policy for loading images that are
outside the viewport.</p>

<div class="example">
<pre><code class="html" data-x="">&lt;img src="1.jpeg" alt="1">
&lt;img src="2.jpeg" loading=eager alt="2">
&lt;img src="3.jpeg" loading=lazy alt="3">
&lt;div id=very-large>&lt;/div> &lt;!-- Everything after this div is below the viewport -->
&lt;img src="4.jpeg" alt="4">
&lt;img src="5.jpeg" loading=lazy alt="5"></code></pre>

<p>In the example above, the images load as follows:</p>

<dl class="switch">
<dt><code data-x="">1.jpeg</code>, <code data-x="">2.jpeg</code>,
<code data-x="">4.jpeg</code></dt>
<dd><p>The images load eagerly and delay the window's load event.</p></dd>

<dt><code data-x="">3.jpeg</code></dt>
<dd><p>The image loads when layout is known, due to being in the viewport, however it does not
delay the window's load event.</p></dd>

<dt><code data-x="">5.jpeg</code></dt>
<dd><p>The image loads only once scrolled into the viewport, and does not delay the window's
load event.</p></dd>
</dl>

<p class="note">Developers are encouraged to specify an intrinsic aspect ratio via <code
data-x="attr-dim-width">width</code> and <code data-x="attr-dim-height">height</code> attributes
on lazy loaded images, even if CSS sets the image's width and height properties, to prevent the
page layout from shifting around after the image loads.</p>
</div>

<hr>

<p>The <code>img</code> element must not be used as a layout tool. In particular, <code>img</code>
@@ -26631,7 +26698,11 @@ interface <dfn>HTMLImageElement</dfn> : <span>HTMLElement</span> {

<p>The <dfn><code data-x="dom-img-decoding">decoding</code></dfn> IDL attribute must
<span>reflect</span> the <code data-x="attr-img-decoding">decoding</code> content
attribute, <span>limited to only known values</span>.
attribute, <span>limited to only known values</span>.</p>

<p>The <dfn><code data-x="dom-img-loading">loading</code></dfn> IDL attribute must
<span>reflect</span> the <code data-x="attr-img-loading">loading</code> content attribute,
<span>limited to only known values</span>.</p>

</div>

@@ -28028,6 +28099,37 @@ was an English &lt;a href="/wiki/Music_hall">music hall&lt;/a> singer, ...</code

<h6>Updating the image data</h6>

<p>The <dfn>will lazy load image steps</dfn>, given an <code>img</code> element <var>img</var>,
are as follows:</p>

<ol>
<li>
<p>If <span data-x="concept-n-noscript">scripting is disabled</span> for <var>img</var>, return
false.</p>

<p class="note">This is an anti-tracking measure, because if a user agent supported lazy loading
when scripting is disabled, it would still be possible for a site to track a user's approximate
scroll position throughout a session, by strategically placing images in a page's markup such
that a server can track how many images are requested and when.</p>
</li>

<li>
<p>If <var>img</var>'s <span>lazy loading attribute</span> is in the <span
data-x="attr-loading-lazy-state">Lazy</span> state, <var>img</var> does not <span>intersect the
viewport</span>, and <var>img</var> is not about to <span>intersect the viewport</span>, then
return true.</p>

<p class="note">This allows for fetching the image during scrolling, when it does not, but is
about to intersect the viewport.</p>
</li>

<li><p>Return false.</p></li>
</ol>

<p class="note">This algorithm cannot be called from steps running <span>in parallel</span>. If
This conversation was marked as resolved by domfarolino

This comment has been minimized.

@annevk

annevk Dec 11, 2019
Member

Suggested change
<li>Let <var>delay load event</var> be true if the <code>img</code>'s <span>lazy loading
<li><p>Let <var>delay load event</var> be true if the <code>img</code>'s <span>lazy loading
a user agent needs to call this algorithm from steps running <span>in parallel</span>, it needs to
<span data-x="queue a task">queue</span> a task to do so.</p>
This conversation was marked as resolved by domfarolino

This comment has been minimized.

@annevk

annevk Dec 11, 2019
Member

Suggested change
otherwise.</li>
otherwise.</p></li>

<p>When the user agent is to <dfn>update the image data</dfn> of an <code>img</code> element,
optionally with the <i>restart animations</i> flag set,
it must run the following steps:</p>
@@ -28124,39 +28226,35 @@ was an English &lt;a href="/wiki/Music_hall">music hall&lt;/a> singer, ...</code
</ol>
</li>

<li><p><span>Await a stable state</span>, allowing the <span
data-x="concept-task">task</span> that invoked this algorithm to continue.
The <span>synchronous
section</span> consists of all the remaining steps of this algorithm until the algorithm says the
<span>synchronous section</span> has ended. (Steps in <span data-x="synchronous
section">synchronous sections</span> are marked with &#x231B;.)</p></li>
<li><p><span>Queue a microtask</span> to perform the rest of this algorithm, allowing the <span
data-x="concept-task">task</span> that invoked this algorithm to continue.</p></li>

<li>
<p>&#x231B; If another instance of this algorithm for this <code>img</code> element was started
after this instance (even if it aborted and is no longer running), then return.</p>
<p>If another instance of this algorithm for this <code>img</code> element was started after
this instance (even if it aborted and is no longer running), then return.</p>

<p class="note">Only the last instance takes effect, to avoid multiple requests when, for
example, the <code data-x="attr-img-src">src</code>, <code data-x="attr-img-srcset">srcset</code>,
and <code data-x="attr-img-crossorigin">crossorigin</code> attributes are all set in
succession.</p>
</li>

<li><p>&#x231B; Let <var>selected source</var> and <var>selected pixel density</var> be the URL
and pixel density that results from <span data-x="select an image source">selecting an image
source</span>, respectively.</p></li>
<li><p>Let <var>selected source</var> and <var>selected pixel density</var> be the URL and pixel
density that results from <span data-x="select an image source">selecting an image source</span>,
respectively.</p></li>

<li>
<p>&#x231B; If <var>selected source</var> is null, then:</p>
<p>If <var>selected source</var> is null, then:</p>

<ol>
<li><p>&#x231B; Set the <span>current request</span>'s <span
data-x="img-req-state">state</span> to <span data-x="img-error">broken</span>, <span>abort the
image request</span> for the <span>current request</span> and the <span>pending request</span>,
and set <span>pending request</span> to null.</p></li>
<li><p>Set the <span>current request</span>'s <span data-x="img-req-state">state</span> to
<span data-x="img-error">broken</span>, <span>abort the image request</span> for the
<span>current request</span> and the <span>pending request</span>, and set <span>pending
request</span> to null.</p></li>

<li>
<p>&#x231B; <span>Queue an element task</span> on the <span>DOM manipulation task
source</span> given the <code>img</code> element and the following steps:</p>
<p><span>Queue an element task</span> on the <span>DOM manipulation task source</span> given
the <code>img</code> element and the following steps:</p>

<ol>
<li><p>Change the <span>current request</span>'s <span data-x="img-req-url">current
@@ -28169,26 +28267,26 @@ was an English &lt;a href="/wiki/Music_hall">music hall&lt;/a> singer, ...</code
</ol>
</li>

<li><p>&#x231B; Return.</p></li>
<li><p>Return.</p></li>
</ol>
</li>

<li>
<p>&#x231B; <span data-x="parse a url">Parse</span> <var>selected source</var>, relative to the
element's <span>node document</span>, and let <var>urlString</var> be the <span>resulting URL
<p><span data-x="parse a url">Parse</span> <var>selected source</var>, relative to the element's
<span>node document</span>, and let <var>urlString</var> be the <span>resulting URL
string</span>. If that is not successful, then:</p>

<ol>
<li><p>&#x231B; <span>Abort the image request</span> for the <span>current request</span> and
the <span>pending request</span>.</p></li>
<li><p><span>Abort the image request</span> for the <span>current request</span> and the
<span>pending request</span>.</p></li>

<li><p>&#x231B; Set the <span>current request</span>'s <span
data-x="img-req-state">state</span> to <span data-x="img-error">broken</span>.</p></li>
<li><p>Set the <span>current request</span>'s <span data-x="img-req-state">state</span> to
<span data-x="img-error">broken</span>.</p></li>

<li><p>&#x231B; Set <span>pending request</span> to null.</p></li>
<li><p>Set <span>pending request</span> to null.</p></li>

<li>
<p>&#x231B; <span>Queue an element task</span> on the <span>DOM manipulation task
<p><span>Queue an element task</span> on the <span>DOM manipulation task
source</span> given the <code>img</code> element and the following steps:</p>

<ol>
@@ -28200,62 +28298,83 @@ was an English &lt;a href="/wiki/Music_hall">music hall&lt;/a> singer, ...</code
</ol>
</li>

<li><p>&#x231B; Return.</p></li>
<li><p>Return.</p></li>
</ol>
</li>

<li><p>&#x231B; If the <span>pending request</span> is not null and <var>urlString</var> is the
same as the <span>pending request</span>'s <span data-x="img-req-url">current URL</span>, then
<li><p>If the <span>pending request</span> is not null and <var>urlString</var> is the same as
the <span>pending request</span>'s <span data-x="img-req-url">current URL</span>, then
return.</p></li>

<li><p>&#x231B; If <var>urlString</var> is the same as the <span>current request</span>'s <span
<li><p>If <var>urlString</var> is the same as the <span>current request</span>'s <span
data-x="img-req-url">current URL</span> and <span>current request</span>'s <span
data-x="img-req-state">state</span> is <span data-x="img-inc">partially available</span>, then
<span>abort the image request</span> for the <span>pending request</span>, <span>queue a
task</span> to <span>restart the animation</span> if <i>restart animation</i> is set, and
return.</p></li>

<li><p>&#x231B; If the <span>pending request</span> is not null, then <span>abort the image
request</span> for the <span>pending request</span>.</p></li>
<li><p>If the <span>pending request</span> is not null, then <span>abort the image request</span>
for the <span>pending request</span>.</p></li>

<li><p>&#x231B; Set <var>image request</var> to a new <span>image request</span> whose <span
<li><p>Set <var>image request</var> to a new <span>image request</span> whose <span
data-x="img-req-url">current URL</span> is <var>urlString</var>.</p></li>

<li><p>&#x231B; If <span>current request</span>'s <span data-x="img-req-state">state</span> is
<span data-x="img-none">unavailable</span> or <span data-x="img-error">broken</span>, then set
the <span>current request</span> to <var>image request</var>. Otherwise, set the <span>pending
<li><p>If <span>current request</span>'s <span data-x="img-req-state">state</span> is <span
data-x="img-none">unavailable</span> or <span data-x="img-error">broken</span>, then set the
<span>current request</span> to <var>image request</var>. Otherwise, set the <span>pending
request</span> to <var>image request</var>.</p></li>

<li><p>&#x231B; Let <var>request</var> be the result of <span data-x="create a potential-CORS
<li><p>Let <var>request</var> be the result of <span data-x="create a potential-CORS
request">creating a potential-CORS request</span> given <var>urlString</var>, "<code
data-x="">image</code>", and the current state of the element's <code
data-x="attr-img-crossorigin">crossorigin</code> content attribute.</p></li>

<li><p>&#x231B; Set <var>request</var>'s <span data-x="concept-request-client">client</span> to
the element's <span>node document</span>'s <span>relevant settings object</span>.</p></li>
<li><p>Set <var>request</var>'s <span data-x="concept-request-client">client</span> to the
element's <span>node document</span>'s <span>relevant settings object</span>.</p></li>

<li><p>&#x231B; If the element <span data-x="use srcset or picture">uses <code>srcset</code> or
<li><p>If the element <span data-x="use srcset or picture">uses <code>srcset</code> or
<code>picture</code></span>, set <var>request</var>'s <span
data-x="concept-request-initiator">initiator</span> to "<code
data-x="">imageset</code>".</p></li>

<li><p>&#x231B; Set <var>request</var>'s <span data-x="concept-request-referrer-policy">referrer
<li><p>Set <var>request</var>'s <span data-x="concept-request-referrer-policy">referrer
policy</span> to the current state of the element's <code
data-x="attr-img-referrerpolicy">referrerpolicy</code> attribute.</p></li>

<li><p>Let <var>delay load event</var> be true if the <code>img</code>'s <span>lazy loading
attribute</span> is in the <span data-x="attr-loading-eager-state">Eager</span> state, or if
<span data-x="concept-n-noscript">scripting is disabled</span> for the <code>img</code>, and
false otherwise.</p></li>

<li>
<p>If the <span>will lazy load image steps</span> given the <code>img</code> return true,
then:</p>

<ol>
<li><p>Continue running this algorithm <span>in parallel</span>.</p></li>

<li><p>Wait until the <span>will lazy load image steps</span> no longer return true, given the
<code>img</code>.</p></li>

<li><p><span>Queue a task</span> to continue running the rest of this algorithm.</p></li>
</ol>
</li>

<li>
<!--FETCH-->
<p>&#x231B; <span data-x="concept-fetch">Fetch</span> <var>request</var>. Let this instance of
the <span data-x="concept-fetch">fetching</span> algorithm be associated with <var>image
request</var>.<!-- TODO "Interaction with the Preload Scanner" from the picture spec --></p>
<p><span data-x="concept-fetch">Fetch</span> <var>request</var>. Let this instance of the <span
data-x="concept-fetch">fetching</span> algorithm be associated with <var>image request</var>.
<!-- TODO "Interaction with the Preload Scanner" from the picture spec --></p>

<p>The resource obtained in this fashion, if any, is <var>image request</var>'s <span data-x="img-req-data">image data</span>.
It can be either <span>CORS-same-origin</span> or <span>CORS-cross-origin</span>; this affects
the <span>origin</span> of the image itself (e.g. when used on a <code>canvas</code>).</p>
<p>The resource obtained in this fashion, if any, is <var>image request</var>'s <span
data-x="img-req-data">image data</span>. It can be either <span>CORS-same-origin</span> or
<span>CORS-cross-origin</span>; this affects the <span>origin</span> of the image itself (e.g.
when used on a <code>canvas</code>).</p>

<!-- same text in <input type=image> section and similar text elsewhere -->
<p>Fetching the image must <span>delay the load event</span> of the element's <span>node document</span> until the
<span data-x="concept-task">task</span> that is <span data-x="queue a task">queued</span> by the
<p>When <var>delay load event</var> is true, fetching the image must <span>delay the load
event</span> of the element's <span>node document</span> until the <span
data-x="concept-task">task</span> that is <span data-x="queue a task">queued</span> by the
<span>networking task source</span> once the resource has been fetched (<a
href="#img-load">defined below</a>) has been run.
<!--TODO or the fetch was aborted, presumably --></p>
@@ -28268,8 +28387,8 @@ was an English &lt;a href="/wiki/Music_hall">music hall&lt;/a> singer, ...</code
compatible with existing Web content.</p>
</li>

<li><p>End the <span>synchronous section</span>, continuing the remaining steps <span>in
parallel</span>, but without missing any data from fetching.</p></li>
<li><p>Continue the remaining steps <span>in parallel</span>, but without missing any data from
fetching.</p></li>

<li>

@@ -32358,10 +32477,6 @@ interface <dfn>HTMLVideoElement</dfn> : <span>HTMLMediaElement</span> {
<p>The <span>default object size</span> is a width of 300 <span data-x="'px'">CSS pixels</span>
and a height of 150 <span data-x="'px'">CSS pixels</span>. <ref spec=CSSIMAGES></p>

<p>A <code>video</code> element is said to <dfn>intersect the viewport</dfn> when it is
<span>being rendered</span> and its associated CSS layout box intersects the
<span>viewport</span>.</p>

<hr>

<p>User agents should provide controls to enable or disable the display of closed captions, audio
@@ -35076,10 +35191,6 @@ interface <dfn>MediaError</dfn> {

<p>The user agent may run the following substeps:</p>

<p class="note">This specification doesn't define the precise timing for when the intersection
is tested, but it is suggested that the timing match that of the Intersection Observer API.
<ref spec=INTERSECTIONOBSERVER></p>

<ol>

<li>Set the <code data-x="dom-media-paused">paused</code> attribute to false.</li>
@@ -35104,10 +35215,6 @@ interface <dfn>MediaError</dfn> {
true and the <code data-x="attr-media-autoplay">autoplay</code> attribute is still specified,
run the following substeps:</p>

<p class="note">This specification doesn't define the precise timing for when the intersection
is tested, but it is suggested that the timing match that of the Intersection Observer API.
<ref spec=INTERSECTIONOBSERVER></p>

<ol>

<li>Run the <span>internal pause steps</span> and set the <span>can autoplay flag</span> to
@@ -114452,6 +114559,13 @@ console.assert(container.firstChild instanceof SuperP);
means the element is not <span>being rendered</span>, though this might be overridden by the style
sheets.</p>

<p>An element is said to <dfn>intersect the viewport</dfn> when it is <span>being rendered</span>
and its associated CSS layout box intersects the <span>viewport</span>.</p>

<p class="note">This specification does not define the precise timing for when the intersection is
tested, but it is suggested that the timing match that of the Intersection Observer API. <ref
spec=INTERSECTIONOBSERVER></p>

<hr>

<p>User agents that do not honor author-level CSS style sheets are nonetheless expected to act as
@@ -120397,13 +120511,15 @@ interface <dfn>External</dfn> {
<code data-x="attr-img-alt">alt</code>;
<code data-x="attr-img-src">src</code>;
<code data-x="attr-img-srcset">srcset</code>;
<code data-x="attr-img-sizes">sizes</code>;
<code data-x="attr-img-crossorigin">crossorigin</code>;
<code data-x="attr-hyperlink-usemap">usemap</code>;
<code data-x="attr-img-ismap">ismap</code>;
<code data-x="attr-dim-width">width</code>;
<code data-x="attr-dim-height">height</code>;
<code data-x="attr-img-referrerpolicy">referrerpolicy</code>;
<code data-x="attr-img-decoding">decoding</code>;
<code data-x="attr-img-referrerpolicy">referrerpolicy</code></td>
<code data-x="attr-img-loading">loading</code></td>
<td><code>HTMLImageElement</code></td>
</tr>

@@ -121985,6 +122101,12 @@ interface <dfn>External</dfn> {
<td> "<code data-x="attr-img-decoding-sync">sync</code>";
"<code data-x="attr-img-decoding-async">async</code>";
"<code data-x="attr-img-decoding-auto">auto</code>"
<tr>
<th> <code data-x="">loading</code>
<td> <code data-x="attr-img-loading">img</code>
<td> Used when determining loading deferral
<td> "<code data-x="attr-loading-lazy">lazy</code>";
"<code data-x="attr-loading-eager">eager</code>"
<tr>
<th> <code data-x="">default</code>
<td> <code data-x="attr-track-default">track</code>