Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update autofocus processing algorithm #4763

Merged
merged 8 commits into from
Sep 3, 2019
133 changes: 117 additions & 16 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -74520,9 +74520,15 @@ END:VCARD</pre>

<div w-nodev>

<p>Each <code>Document</code> has an <dfn>autofocus candidates</dfn> <span>list</span>,
initially empty.</p>

<p>Each <code>Document</code> has an <dfn>autofocus processed flag</dfn> boolean, initially
false.</p>

<p>When an element with the <code data-x="attr-fe-autofocus">autofocus</code> attribute specified
is <span data-x="node is inserted into a document">inserted into a document</span>, <span>queue a
task</span> on the <span>user interaction task source</span> to run the following steps:</p>
is <span data-x="node is inserted into a document">inserted into a document</span>, run the
following steps:</p>

<ol>
<li><p>If the user has indicated (for example, by starting to type in a form control) that they
Expand All @@ -74536,32 +74542,119 @@ END:VCARD</pre>
<li><p>If <var>target</var>'s <span>active sandboxing flag set</span> has the
<span>sandboxed automatic features browsing context flag</span>, then return.</p></li>

<li><p>Let <var>topDocument</var> be the <span>active document</span> of <var>target</var>'s
<span data-x="concept-document-bc">browsing context</span>'s
<span>top-level browsing context</span>.</p></li>

<li><p>If <var>target</var>'s <span>origin</span> is not the <span data-x="same
origin">same</span> as the <span>origin</span> of the <span>node document</span> of the currently
focused element in <var>target</var>'s <span>top-level browsing context</span>, then
origin">same</span> as the <span>origin</span> of <var>topDocument</var>, then return.</p></li>

<li><p>If <var>topDocument</var>'s <span>autofocus processed flag</span> is false, then
<span data-x="list remove">remove</span> the element from <var>topDocument</var>'s
<span>autofocus candidates</span>, and <span data-x="list append">append</span> the element to
<var>topDocument</var>'s <span>autofocus candidates</span>.</p></li>
</ol>

<p class="note">We do not check if an element is a <span>focusable area</span> before storing it
in the <span>autofocus candidates</span> list, because even if it is not a focusable area when it
is inserted, it could become one by the time <span>flush autofocus candidates</span> sees it.</p>

<p>To <dfn>flush autofocus candidates</dfn> for a document <var>topDocument</var>, run these
steps:</p>

<ol>
<li><p>If <var>topDocument</var>'s <span>autofocus processed flag</span> is true, then
return.</p></li>

<li><p>If <var>target</var>'s <span>origin</span> is not the <span data-x="same
origin">same</span> as the <span>origin</span> of the <span>active document</span> of
<var>target</var>'s <span>top-level browsing context</span>, then return.</p></li>
<li><p>Let <var>candidates</var> be <var>topDocument</var>'s <span>autofocus
candidates</span>.</p></li>

<li><p>If <var>candidates</var> <span data-x="list is empty">is empty</span>, then
return.</p></li>

<li>
<p>If <var>topDocument</var>'s <span data-x="focused area of the document">focused area</span>
is not <var>topDocument</var> itself, or <var>topDocument</var>'s
<span data-x="concept-document-url">URL</span>'s
<span data-x="concept-url-fragment">fragment</span> is not empty, then:</p>

<ol>
<li><p><span data-x="list empty">Empty</span> <var>candidates</var>.</p></li>

<li><p>If the user agent has already reached the last step of this list of steps in response to
an element being <span data-x="node is inserted into a document">inserted</span> into a
<code>Document</code> whose <span>top-level browsing context</span>'s <span>active
document</span> is the same as <var>target</var>'s <span>top-level browsing
context</span>'s <span>active document</span>, then return.</p></li>
<li><p>Set <var>topDocument</var>'s <span>autofocus processed flag</span> to true.</p></li>

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

<li>
<p>While <var>candidates</var> is not <span data-x="list is empty">empty</span>:</p>

<li><p>Run the <span>focusing steps</span> for the element. User agents may also change the
scrolling position of the document, or perform some other action that brings the element to the
user's attention.</p></li>
<ol>
<li><p>Let <var>element</var> be <var>candidates</var>[0].</p></li>

<li><p>Let <var>doc</var> be <var>element</var>'s <span>node document</span>.</p></li>

<li><p>If <var>doc</var> is not <span>fully active</span>, then
<span data-x="list remove">remove</span> <var>element</var> from <var>candidates</var>, and
<span>continue</span>.</p></li>

<li><p>If <var>doc</var>'s <span data-x="concept-document-bc">browsing context</span>'s
<span>top-level browsing context</span> is not same as <var>topDocument</var>'s
<span data-x="concept-document-bc">browsing context</span>, then
<span data-x="list remove">remove</span> <var>element</var> from <var>candidates</var>, and
<span>continue</span>.</p></li>

<li>
<p>If <var>doc</var>'s <span>script-blocking style sheet counter</span> is greater than 0,
then return.</p>

<p class="note">In this case, <var>element</var> is the currently-best candidate, but
<var>doc</var> is not ready for autofocusing. We'll try again next time <span>flush
autofocus candidates</span> is called.</p>
</li>

<li><p><span data-x="list remove">Remove</span> <var>element</var> from
<var>candidates</var>.</p></li>

<li><p>Let <var>inclusiveAncestorDocuments</var> be a <span>list</span> consisting of
<var>doc</var>, plus the <span data-x="active document">active documents</span> of each of
<var>doc</var>'s <span data-x="concept-document-bc">browsing context</span>'s
<span data-x="ancestor browsing context">ancestor browsing contexts</span>.</p></li>

<li><p>If <span data-x="concept-document-url">URL</span>'s
<span data-x="concept-url-fragment">fragment</span> of any <code>Document</code> in
<var>inclusiveAncestorDocuments</var> is not empty, then <span>continue</span>.</p></li>

<li>
<p>If <var>element</var> is a <span>focusable area</span>, then:</p>

<ol>
<li><p><span data-x="list empty">Empty</span> <var>candidates</var>.</p></li>

<li><p>Set <var>topDocument</var>'s <span>autofocus processed flag</span> to true.</p></li>

<li><p>Run the <span>focusing steps</span> for <var>element</var>.</p></li>
</ol>

<p class="note"><span>Autofocus candidates</span> can <span data-x="list
contains">contain</span> elements which are not <span data-x="focusable area">focusable
areas</span>. This can happen either because a non-<span>focusable area</span> element with an
<code data-x="attr-fe-autofocus">autofocus</code> attribute was <span data-x="node is inserted
into a document">inserted into a document</span> and it never became focusable, or because the
element was focusable but its status changed while it was stored in <span>autofocus
candidates</span>.</p>
</li>
</ol>
</li>
</ol>

<p class="note">This handles the automatic focusing during document load. The <code
data-x="dom-dialog-show">show()</code> and <code data-x="dom-dialog-showModal">showModal()</code>
methods of <code>dialog</code> elements also processes the <code
data-x="attr-fe-autofocus">autofocus</code> attribute.</p>

<p class="note">Focusing the control does not imply that the user agent has to focus the browser
<p class="note">Focusing the element does not imply that the user agent has to focus the browser
window if it has lost focus.</p>

<p>The <dfn><code data-x="dom-fe-autofocus">autofocus</code></dfn> IDL attribute must
Expand Down Expand Up @@ -91215,6 +91308,14 @@ dictionary <dfn>PromiseRejectionEventInit</dfn> : <span>EventInit</span> {
<li><p>For each <span>fully active</span> <code>Document</code> in <var>docs</var>, update the
rendering or user interface of that <code>Document</code> and its <span
data-x="concept-document-bc">browsing context</span> to reflect the current state.</p></li>

<li><p>For each <span>fully active</span> <code>Document</code> in <var>docs</var>, <span>flush
autofocus candidates</span> for that <code>Document</code> if its
<span data-x="concept-document-bc">browsing context</span> is a
<span>top-level browsing context</span>.</p></li>
<!-- The above step is placed just after 'update the rendering' step in order to avoid
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem right. We've already marked the painting time. Why are we focusing an element and potentially arbitrary author scripts for arbitrary amount of time?

Also, "update the rendering or user interface of that Document and its browsing context to reflect the current state." updates the painting of the document. If we had focused an element, there is a good chance, the focus ring may should be drawn around the newly focused element. Yet autofocusing step being after this rendering update would mean that it would necessarily be one frame / rAF later.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tracking this in #4992.

additional style computation. 'Focusable area' check requires the up-to-date style computation
result. -->
</ol>
</li>

Expand Down