Skip to content

Commit

Permalink
Fix the processing model for img.decode()
Browse files Browse the repository at this point in the history
As discussed in #2898, there are two primary problems being addressed:

* By not delaying a microtask, we are not properly waiting for any image
  data updates. This introduces such a delay.
* By testing for the presence of src or srcset, we do not work for <img>
  elements who get the current request from a containing <picture>
  element. This removes that check.

Closes #2898.
  • Loading branch information
domenic committed Sep 21, 2017
1 parent 470e168 commit 07f699a
Showing 1 changed file with 65 additions and 54 deletions.
119 changes: 65 additions & 54 deletions source
Expand Up @@ -25800,80 +25800,91 @@ interface <dfn>HTMLImageElement</dfn> : <span>HTMLElement</span> {
<p>The <dfn data-x="dom-img-currentSrc"><code>currentSrc</code></dfn> IDL attribute
must return the <code>img</code> element's <span>current request</span>'s <span data-x="img-req-url">current URL</span>.</p>

<p>The <dfn data-x="dom-img-decode"><code>decode</code></dfn>() method, when invoked, must perform
<p>The <dfn data-x="dom-img-decode"><code>decode()</code></dfn> method, when invoked, must perform
the following steps:</p>

<ol>
<!-- TODO: much of this could be phrased entirely in terms of the current request if
https://github.com/whatwg/html/issues/1055 gets fixed. See
https://github.com/whatwg/html/pull/2332#issuecomment-278613713 -->
<li><p>Let <var>promise</var> be a new promise.</p></li>

<li>
<p>If any of the following conditions are true about this <code>img</code> element:</p>
<p><span>Queue a microtask</span> to perform the following steps:</p>

<ul class="brief">
<li><p>its <span>node document</span> is not an <span>active document</span>;</p></li>
<div class="note">
<p>This is done because <span data-x="update the image data">updating the image data</span>
takes place in a microtask as well. Thus, to make code such as</p>

<li><p>it has neither a <code data-x="attr-img-src">src</code> nor a <code
data-x="attr-img-srcset">srcset</code> attribute;</p></li>
<pre>img.src = "stars.jpg";
img.decode();</pre>

<li><p>it has a <code data-x="attr-img-src">src</code> attribute but its value is the empty
string; or</p></li>
<p>properly decode <code data-x="">stars.jpg</code>, we need to delay any processing by one
microtask.</p>
</div>

<li><p>its <span>current request</span>'s <span data-x="img-req-state">state</span> is <span
data-x="img-error">broken</span>,</p></li>
</ul>
<ol>
<!-- TODO: much of this could be phrased entirely in terms of the current request if
https://github.com/whatwg/html/issues/1055 gets fixed. See
https://github.com/whatwg/html/pull/2332#issuecomment-278613713 -->
<li>
<p>If any of the following conditions are true about this <code>img</code> element:</p>

<p>then return a promise rejected with an <span>"<code>EncodingError</code>"</span>
<code>DOMException</code>.</p>
</li>
<ul class="brief">
<li><p>its <span>node document</span> is not an <span>active document</span>;</p></li>

<li><p>Let <var>promise</var> be a new promise.</p></li>
<li><p>its <span>current request</span>'s <span data-x="img-req-state">state</span> is <span
data-x="img-error">broken</span>,</p></li>
</ul>

<li>
<p><span>In parallel</span>, wait for one of the following cases to occur, and perform the
corresponding actions:</p>
<p>then reject <var>promise</var> with an <span>"<code>EncodingError</code>"</span>
<code>DOMException</code>.</p>
</li>

<dl class="switch">
<dt>This <code>img</code> element's <span>node document</span> stops being an <span>active
document</span></dt>
<dt>This <code>img</code> element's <span>current request</span> changes or is mutated</dt>
<dt>This <code>img</code> element's <span>current request</span>'s <span
data-x="img-req-state">state</span> becomes <span data-x="img-error">broken</span></dt>
<li>
<p>Otherwise, <span>in parallel</span>, wait for one of the following cases to occur, and
perform the corresponding actions:</p>

<dd>
<p>Reject <var>promise</var> with an <span>"<code>EncodingError</code>"</span>
<code>DOMException</code>.</p>
</dd>
<dl class="switch">
<dt>This <code>img</code> element's <span>node document</span> stops being an <span>active
document</span></dt>
<dt>This <code>img</code> element's <span>current request</span> changes or is mutated</dt>
<dt>This <code>img</code> element's <span>current request</span>'s <span
data-x="img-req-state">state</span> becomes <span data-x="img-error">broken</span></dt>

<dt>This <code>img</code> element becomes <span data-x="img-all">completely
available</span></dt>
<dd>
<p>Reject <var>promise</var> with an <span>"<code>EncodingError</code>"</span>
<code>DOMException</code>.</p>
</dd>

<dd>
<p>Decode the image's media data entirely into its bitmap form, suitable for rapid painting to
the screen.</p>
<dt>This <code>img</code> element becomes <span data-x="img-all">completely
available</span></dt>

<p>If decoding does not need to be performed for this image (for example because it is a
vector graphic), resolve <var>promise</var> with undefined.</p>
<dd>
<p>Decode the image's media data entirely into its bitmap form, suitable for rapid painting
to the screen.</p>

<p>If decoding fails (for example due to invalid image data), reject <var>promise</var> with
an <span>"<code>EncodingError</code>"</span> <code>DOMException</code>.</p>
<p>If decoding does not need to be performed for this image (for example because it is a
vector graphic), resolve <var>promise</var> with undefined.</p>

<p>If the decoding process completes successfully, resolve <var>promise</var> with
undefined.</p>
<p>If decoding fails (for example due to invalid image data), reject <var>promise</var> with
an <span>"<code>EncodingError</code>"</span> <code>DOMException</code>.</p>

<p>User agents should ensure that the decoded media data stays readily available until at
least the end of the next <span>update the rendering</span> step in the <span>event
loop</span>. This is an important part of the API contract, and should not be broken if at all
possible. (Typically, this would only be violated in low-memory situations that require
evicting decoded image data, or when the image is too large to keep in decoded form for this
period of time.)</p>
</dd>
</dl>
<p>If the decoding process completes successfully, resolve <var>promise</var> with
undefined.</p>

<p>User agents should ensure that the decoded media data stays readily available until at
least the end of the next successful <span>update the rendering</span> step in the
<span>event loop</span>. This is an important part of the API contract, and should not be
broken if at all possible. (Typically, this would only be violated in low-memory situations
that require evicting decoded image data, or when the image is too large to keep in decoded
form for this period of time.)</p>
</dd>
</dl>

<p class="note">Animated images will become <span data-x="img-all">completely available</span>
only after all their frames are loaded. Thus, even though an implementation could decode the
first frame before that point, the above steps will not do so, instead waiting until all frames
are available.</p>
<p class="note">Animated images will become <span data-x="img-all">completely available</span>
only after all their frames are loaded. Thus, even though an implementation could decode the
first frame before that point, the above steps will not do so, instead waiting until all
frames are available.</p>
</li>
</ol>
</li>

<li><p>Return <var>promise</var>.</p></li>
Expand Down

0 comments on commit 07f699a

Please sign in to comment.