Skip to content

Commit

Permalink
Make the focus fixup rule more explicit
Browse files Browse the repository at this point in the history
* Split it into two variants: one which runs synchronously on HTML element removal, and one which runs during "update the rendering". Closes #8225.

* Be clear that the fixup does not cause any of the normal focus algorithms to run, and thus blur and change events do not fire. Also, delete the confusing "somehow unfocused without another element being explicitly focused" sentence. Fixes #3847. Fixes #6729.
  • Loading branch information
domenic committed Oct 16, 2022
1 parent 37748b0 commit 14eb00c
Showing 1 changed file with 34 additions and 28 deletions.
62 changes: 34 additions & 28 deletions source
Original file line number Diff line number Diff line change
Expand Up @@ -1805,6 +1805,17 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
<var>removedNode</var> and optionally <var>oldParent</var>, are defined as the following:</p>

<ol>
<li id="node-remove-focus-fixup">
<p>If <var>removedNode</var>'s <span>node document</span>'s <span data-x="focused area of the
document">focused area</span> is <var>removedNode</var>, then set <var>removedNode</var>'s
<span>node document</span>'s <span data-x="focused area of the document">focused area</span> to
<var>removedNode</var>'s <span>node document</span>'s <span>viewport</span>.</p>

<p class="note">This does <em>not</em> perform the <span>unfocusing steps</span>,
<span>focusing steps</span>, or <span>focus update steps</span>, and thus no <code
data-x="event-blur">blur</code> event is fired.</p>
</li>

<li><p>If <var>removedNode</var> is an element whose <span
data-x="concept-element-namespace">namespace</span> is the <span>HTML namespace</span>, and this
standard defines <span data-x="html element removing steps">HTML element removing steps</span>
Expand Down Expand Up @@ -59311,9 +59322,9 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> {

<p class="note" id="note-dialog-plus-focus-fixup">This will cause the <span>focused area of the
document</span> to become <span>inert</span> (unless that currently focused area is a
<span>shadow-including descendant</span> of <var>subject</var>). In such cases, the <span>focus
fixup rule</span> will kick in and reset the <span>focused area of the document</span> to the
<span>viewport</span> for now. In a couple steps we will attempt to find a better candidate to
<span>shadow-including descendant</span> of <var>subject</var>). In such cases, the
<span>focused area of the document</span> will soon be <a href="#focus-fixup-rule">reset</a> to
the <span>viewport</span>. In a couple steps we will attempt to find a better candidate to
focus.</p>
</li>

Expand Down Expand Up @@ -77008,10 +77019,6 @@ partial interface <span id="NavigatorUserActivation-partial">Navigator</span> {
</li>
</ol>

<p>When the <span>currently focused area of a top-level browsing context</span> is somehow
unfocused without another element being explicitly focused in its stead, the user agent must
<span>immediately</span> run the <span>unfocusing steps</span> for that object.</p>

<p class="note">The <span>unfocusing steps</span> do not always result in the focus changing, even
when applied to the <span>currently focused area of a top-level browsing context</span>. For
example, if the <span>currently focused area of a top-level browsing context</span> is a
Expand All @@ -77020,27 +77027,6 @@ partial interface <span id="NavigatorUserActivation-partial">Navigator</span> {

<hr>

<p><dfn>Focus fixup rule</dfn>: When the designated <span data-x="focused area of the
document">focused area of the document</span> is removed from that <code>Document</code> in some
way (e.g. it stops being a <span>focusable area</span>, it is removed from the DOM, it becomes
<span>inert</span>, etc.), designate the <code>Document</code>'s <span>viewport</span> to be the
new <span>focused area of the document</span>.</p>

<p class="example">For example, this might happen because an element is removed from its
<code>Document</code>, or has a <code data-x="attr-hidden">hidden</code> attribute added. It might
also happen to an <code>input</code> element when the element gets <span
data-x="concept-fe-disabled">disabled</span>.</p>

<p class="example">In a <code>Document</code> whose <span data-x="focused area of the
document">focused area</span> is a <code>button</code> element, removing, disabling, or hiding
that button would cause the page's new <span data-x="focused area of the document">focused
area</span> to be the <span>viewport</span> of the <code>Document</code>. This would, in turn,
be reflected through the <code
data-x="dom-documentorshadowroot-activeElement">activeElement</code> API as <span>the body
element</span>.</p>

<hr>

<p>The <dfn>focus update steps</dfn>, given an <var>old chain</var>, a <var>new chain</var>, and a <var>new focus target</var> respectively, are as
follows:</p>

Expand Down Expand Up @@ -96741,6 +96727,26 @@ import "https://example.com/foo/../module2.mjs";</code></pre>
the animation frame callbacks</span> for that <code>Document</code>, passing in <var>now</var>
as the timestamp.</p></li>

<li id="focus-fixup-rule">
<p>For each <span>fully active</span> <code>Document</code> in <var>docs</var>, if the <span
data-x="focused area of the document">focused area</span> of that <code>Document</code> is no
longer a <span>focusable area</span>, then set that <code>Document</code>'s <span
data-x="focused area of the document">focused area</span> to its <span>viewport</span>.</p>

<p class="example">For example, this might happen because an element has the <code
data-x="attr-hidden">hidden</code> attribute added, causing it to stop <span>being
rendered</span>. It might also happen to an <code>input</code> element when the element gets
<span data-x="concept-fe-disabled">disabled</span>.</p>

<p class="note">This does <em>not</em> perform the <span>unfocusing steps</span>,
<span>focusing steps</span>, or <span>focus update steps</span>, and thus no <code
data-x="event-blur">blur</code> event is fired.</p>

<p class="note">In addition to this asynchronous fixup, if the <span>focused area of the
document</span> is removed, there is a <a href="#node-remove-focus-fixup">synchronous
fixup</a>.</p>
</li>

<li>
<p>For each <span>fully active</span> <code>Document</code> <var>doc</var> in
<var>docs</var>:</p>
Expand Down

0 comments on commit 14eb00c

Please sign in to comment.