Skip to content

Commit

Permalink
Update autofocus processing algorithm
Browse files Browse the repository at this point in the history
* Run focusing steps after an animation frame
* Don't autofocus if the top-level document has focused area
* Don't autofocus if one of ancestor document has a :target element

Fixes #3551.  Fixes #4645.
  • Loading branch information
tkent-google authored and domenic committed Sep 3, 2019
1 parent f5ae47e commit 2d783db
Showing 1 changed file with 117 additions and 16 deletions.
133 changes: 117 additions & 16 deletions source
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
additional style computation. 'Focusable area' check requires the up-to-date style computation
result. -->
</ol>
</li>

Expand Down

0 comments on commit 2d783db

Please sign in to comment.