Skip to content

Commit

Permalink
Make autofocus="" work with delegatesFocus and <area>
Browse files Browse the repository at this point in the history
Fixes #5027, by extracting out the previous step 1 of the "focusing
steps" into a new "get the focusable area" algorithm, and calling that
from the autofocus processing model as appropriate.
  • Loading branch information
tkent-google authored and domenic committed Nov 11, 2019
1 parent b48bb22 commit bcd5d61
Showing 1 changed file with 87 additions and 105 deletions.
192 changes: 87 additions & 105 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -74017,124 +74017,97 @@ END:VCARD</pre>

<h4 id="focus-processing-model"><span id="processing-model-5"></span>Processing model</h4>

<p>The <dfn data-export="">focusing steps</dfn> for an object <var>new focus target</var> that is
either a <span>focusable area</span>, or an element that is not a <span>focusable area</span>, or
a <span>browsing context</span>, are as follows. They can optionally be run with a <var>fallback
target</var> and a string <var>focus trigger</var>.</p>

<ol>

<!-- https://software.hixie.ch/utilities/js/live-dom-viewer/?saved=2816 div.focus() when it's got a scroll region -->
<!-- https://software.hixie.ch/utilities/js/live-dom-viewer/?saved=2817 img.focus() when it's got an image map -->

<li>

<p>If <var>new focus target</var> is not a <span>focusable area</span>, then run the first
matching set of steps from the following list:</p>

<dl class="switch">

<dt>If <var>new focus target</var> is an <code>area</code> element with one or more
shapes that are <span data-x="focusable area">focusable areas</span></dt>

<dd>

<p>Set <var>new focus target</var> to the shape corresponding to the first <code>img</code>
element in <span>tree order</span> that uses the image map to which the <code>area</code>
element belongs.</p>

</dd>
<p>To <dfn>get the focusable area</dfn> for a <var>focus target</var> that is either an element
that is not a <span>focusable area</span>, or is a <span>browsing context</span>, given an
optional string <var>focus trigger</var>, run the first matching set of steps from the following
list:</p>

<dl class="switch">
<dt>If <var>focus target</var> is an <code>area</code> element with one or more shapes that are
<span data-x="focusable area">focusable areas</span></dt>

<dt>If <var>new focus target</var> is an element with one or more scrollable regions
that are <span data-x="focusable area">focusable areas</span></dt>

<dd>

<p>Set <var>new focus target</var> to the element's first scrollable region, according to a
pre-order, depth-first traversal of the <span>flat tree</span>. <ref spec=CSSSCOPING></p>

</dd>


<dt>If <var>new focus target</var> is the <span>document element</span> of its
<code>Document</code></dt>

<dd>

<p>Set <var>new focus target</var> to the <code>Document</code>'s <span>viewport</span>.</p>

</dd>

<dd><p>Return the shape corresponding to the first <code>img</code> element in <span>tree
order</span> that uses the image map to which the <code>area</code> element belongs.</p></dd>

<dt>If <var>new focus target</var> is a <span>browsing context</span></dt>
<dt>If <var>focus target</var> is an element with one or more scrollable regions that are <span
data-x="focusable area">focusable areas</span></dt>

<dd>
<dd><p>Return the element's first scrollable region, according to a pre-order, depth-first
traversal of the <span>flat tree</span>. <ref spec=CSSSCOPING></p></dd>

<p>Set <var>new focus target</var> to the <span>browsing context</span>'s
<span>active document</span>.</p>
<dt>If <var>focus target</var> is the <span>document element</span> of its
<code>Document</code></dt>

</dd>
<dd><p>Return the <code>Document</code>'s <span>viewport</span>.</p></dd>

<dt>If <var>focus target</var> is a <span>browsing context</span></dt>

<dt>If <var>new focus target</var> is a <span>browsing context container</span> with a non-null
<span>nested browsing context</span></dt>
<dd><p>Return the <span>browsing context</span>'s <span>active document</span>.</p></dd>

<dd>
<dt>If <var>focus target</var> is a <span>browsing context container</span> with a non-null
<span>nested browsing context</span></dt>

<p>Set <var>new focus target</var> to the <span>browsing context container</span>'s
<span>nested browsing context</span>'s <span>active document</span>.</p>
<dd><p>Return the <span>browsing context container</span>'s <span>nested browsing
context</span>'s <span>active document</span>.</p></dd>

</dd>
<dt>If <var>focus target</var> is a <span>shadow host</span> whose <span
data-x="concept-element-shadow-root">shadow root</span>'s <span>delegates focus</span> is
true</dt>

<dt>If <var>new focus target</var> is a <span>shadow host</span> whose <span
data-x="concept-element-shadow-root">shadow root</span>'s <span>delegates focus</span> is
true</dt>
<dd>
<ol>
<li>If <var>focus target</var> is a <span>shadow-including inclusive ancestor</span> of the
<span>currently focused area of a top-level browsing context</span>'s <span>DOM anchor</span>,
then return null.</li>

<dd>
<li>
<p>Otherwise:</p>

<ol>
<li>If <var>new focus target</var> is a <span>shadow-including inclusive ancestor</span> of
the <span>currently focused area of a top-level browsing context</span>'s <span>DOM
anchor</span>, then set <var>new focus target</var> to null.</li>
<li>If <var>focus trigger</var> is "<code data-x="">click</code>", then let <var>possible
focus delegates</var> be the list of all <span>click focusable</span> <span
data-x="focusable area">focusable areas</span> whose <span>DOM anchor</span> is a
descendant of <var>new focus target</var> in the <span>flat tree</span>.</li>

<li>Otherwise, let <var>possible focus delegates</var> be the list of all <span
data-x="focusable area">focusable areas</span> whose <span>DOM anchor</span> is a
descendant of <var>new focus target</var> in the <span>flat tree</span>.</li>

<li>Set <var>new focus target</var> to the first <span>focusable area</span> in <span>tree
order</span> of their <span data-x="DOM anchor">DOM anchors</span> in <var>possible focus
delegates</var>, or null if <var>possible focus delegates</var> is empty.</li>
</ol>
</li>
</ol>

<li>
<p>Otherwise:</p>
<p class="note">For <span data-x="sequentially focusable">sequential focusability</span>, the
handling of <span data-x="shadow host">shadow hosts</span> and <span>delegates focus</span> is
done when constructing the <span>sequential focus navigation order</span>. That is, the
<span>focusing steps</span> will never be called on such <span data-x="shadow host">shadow
hosts</span> as part of sequential focus navigation.</p>

<ol>
<li>If <var>focus trigger</var> is "<code data-x="">click</code>", then let <var>possible
focus delegates</var> be the list of all <span>click focusable</span> <span
data-x="focusable area">focusable areas</span> whose <span>DOM anchor</span> is a
descendant of <var>new focus target</var> in the <span>flat tree</span>.</li>

<li>Otherwise, let <var>possible focus delegates</var> be the list of all <span
data-x="focusable area">focusable areas</span> whose <span>DOM anchor</span> is a
descendant of <var>new focus target</var> in the <span>flat tree</span>.</li>

<li>Set <var>new focus target</var> to the first <span>focusable area</span> in <span>tree
order</span> of their <span data-x="DOM anchor">DOM anchors</span> in <var>possible focus
delegates</var>, or null if <var>possible focus delegates</var> is empty.</li>
</ol>
</li>
</ol>
</dd>

<p class="note">For <span data-x="sequentially focusable">sequential focusability</span>, the
handling of <span data-x="shadow host">shadow hosts</span> and <span>delegates focus</span> is
done when constructing the <span>sequential focus navigation order</span>. That is, the
<span>focusing steps</span> will never be called on such <span data-x="shadow host">shadow
hosts</span> as part of sequential focus navigation.</p>
<dt>Otherwise</dt>

</dd>
<dd><p>Return null.</p></dd>

<dt>Otherwise</dt>
</dl>

<dd>
<p>Set <var>new focus target</var> to null.</p>
</dd>
<p>The <dfn data-export="">focusing steps</dfn> for an object <var>new focus target</var> that is
either a <span>focusable area</span>, or an element that is not a <span>focusable area</span>, or
a <span>browsing context</span>, are as follows. They can optionally be run with a <var>fallback
target</var> and a string <var>focus trigger</var>.</p>

</dl>
<ol>

</li>
<!-- https://software.hixie.ch/utilities/js/live-dom-viewer/?saved=2816 div.focus() when it's got a scroll region -->
<!-- https://software.hixie.ch/utilities/js/live-dom-viewer/?saved=2817 img.focus() when it's got an image map -->

<li><p>If <var>new focus target</var> is not a <span>focusable area</span>, then set <var>new
focus target</var> to the result of <span data-x="get the focusable area">getting the focusable
area</span> for <var>new focus target</var>, given <var>focus trigger</var> if it was
passed.</p></li>

<li>

Expand Down Expand Up @@ -74976,24 +74949,33 @@ END:VCARD</pre>
<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>Let <var>target</var> be <var>element</var>.</p></li>

<li>
<p>If <var>target</var> is not a <span>focusable area</span>, then set <var>target</var> to
the result of <span data-x="get the focusable area">getting the focusable area</span> for
<var>target</var>.</p>

<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>. In addition to the special cases handled in the <span>get the focusable
area</span> algorithm, this can happen 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>

<li>
<p>If <var>element</var> is a <span>focusable area</span>, then:</p>
<p>If <var>target</var> is not null, 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>
<li><p>Run the <span>focusing steps</span> for <var>target</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>
Expand Down

0 comments on commit bcd5d61

Please sign in to comment.