Skip to content

Commit 6a5109c

Browse files
committed
Make the focus fixup rule more explicit
* Split it into two variants: one which runs synchronously on HTML element removal, and one which runs during "update the rendering". Closes #8225. * After this split, only the "update the rendering" variant causes the normal focus algorithms to run, and thus blur and change events to fire. * Delete the confusing "somehow unfocused without another element being explicitly focused" sentence. Fixes #3847. Fixes #6729.
1 parent 63e2f17 commit 6a5109c

File tree

1 file changed

+41
-32
lines changed

1 file changed

+41
-32
lines changed

source

Lines changed: 41 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1794,6 +1794,18 @@ a.setAttribute('href', 'https://example.com/'); // change the content attribute
17941794
<var>removedNode</var> and optionally <var>oldParent</var>, are defined as the following:</p>
17951795

17961796
<ol>
1797+
<li id="node-remove-focus-fixup">
1798+
<p>If <var>removedNode</var>'s <span>node document</span>'s <span data-x="focused area of the
1799+
document">focused area</span> is <var>removedNode</var>, then set <var>removedNode</var>'s
1800+
<span>node document</span>'s <span data-x="focused area of the document">focused area</span> to
1801+
<var>removedNode</var>'s <span>node document</span>'s <span>viewport</span>.</p>
1802+
1803+
<p class="note">This does <em>not</em> perform the <span>unfocusing steps</span>,
1804+
<span>focusing steps</span>, or <span>focus update steps</span>, and thus no <code
1805+
data-x="event-blur">blur</code> or <code data-x="event-change">change</code> events are
1806+
fired.</p>
1807+
</li>
1808+
17971809
<li><p>If <var>removedNode</var> is an element whose <span
17981810
data-x="concept-element-namespace">namespace</span> is the <span>HTML namespace</span>, and this
17991811
standard defines <span data-x="html element removing steps">HTML element removing steps</span>
@@ -59283,9 +59295,9 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> {
5928359295

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

@@ -76995,39 +77007,14 @@ partial interface <span id="NavigatorUserActivation-partial">Navigator</span> {
7699577007
</li>
7699677008
</ol>
7699777009

76998-
<p>When the <span>currently focused area of a top-level traversable</span> is somehow unfocused
76999-
without another element being explicitly focused in its stead, the user agent must
77000-
<span>immediately</span> run the <span>unfocusing steps</span> for that object.</p>
77001-
77002-
<p class="note">The <span>unfocusing steps</span> do not always result in the focus changing,
77003-
even when applied to the <span>currently focused area of a top-level traversable</span>. For
77010+
<p class="note">The <span>unfocusing steps</span> do not always result in the focus changing, even
77011+
when applied to the <span>currently focused area of a top-level traversable</span>. For
7700477012
example, if the <span>currently focused area of a top-level traversable</span> is a
7700577013
<span>viewport</span>, then it will usually keep its focus regardless until another
7700677014
<span>focusable area</span> is explicitly focused with the <span>focusing steps</span>.</p>
7700777015

7700877016
<hr>
7700977017

77010-
<p><dfn>Focus fixup rule</dfn>: When the designated <span data-x="focused area of the
77011-
document">focused area of the document</span> is removed from that <code>Document</code> in some
77012-
way (e.g. it stops being a <span>focusable area</span>, it is removed from the DOM, it becomes
77013-
<span>inert</span>, etc.), designate the <code>Document</code>'s <span>viewport</span> to be the
77014-
new <span>focused area of the document</span>.</p>
77015-
77016-
<p class="example">For example, this might happen because an element is removed from its
77017-
<code>Document</code>, or has a <code data-x="attr-hidden">hidden</code> attribute added. It might
77018-
also happen to an <code>input</code> element when the element gets <span
77019-
data-x="concept-fe-disabled">disabled</span>.</p>
77020-
77021-
<p class="example">In a <code>Document</code> whose <span data-x="focused area of the
77022-
document">focused area</span> is a <code>button</code> element, removing, disabling, or hiding
77023-
that button would cause the page's new <span data-x="focused area of the document">focused
77024-
area</span> to be the <span>viewport</span> of the <code>Document</code>. This would, in turn,
77025-
be reflected through the <code
77026-
data-x="dom-documentorshadowroot-activeElement">activeElement</code> API as <span>the body
77027-
element</span>.</p>
77028-
77029-
<hr>
77030-
7703177018
<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
7703277019
follows:</p>
7703377020

@@ -77074,8 +77061,9 @@ partial interface <span id="NavigatorUserActivation-partial">Navigator</span> {
7707477061
named <code data-x="event-blur">blur</code> at <var>blur event target</var>, with
7707577062
<var>related blur target</var> as the related target.</p>
7707677063

77077-
<p class="note">In some cases, e.g. if <var>entry</var> is an <code>area</code>
77078-
element's shape, a scrollable region, or a <span>viewport</span>, no event is fired.</p>
77064+
<p class="note" id="note-sometimes-no-blur-event">In some cases, e.g. if <var>entry</var> is
77065+
an <code>area</code> element's shape, a scrollable region, or a <span>viewport</span>, no
77066+
event is fired.</p>
7707977067
</li>
7708077068
</ol>
7708177069
</li>
@@ -99513,6 +99501,27 @@ import "https://example.com/foo/../module2.mjs";</code></pre>
9951399501
</ol>
9951499502
</li>
9951599503

99504+
<li id="focus-fixup-rule">
99505+
<p>For each <span>fully active</span> <code>Document</code> in <var>docs</var>, if the <span
99506+
data-x="focused area of the document">focused area</span> of that <code>Document</code> is no
99507+
longer a <span>focusable area</span>, then run the <span>focusing steps</span> for that
99508+
<code>Document</code>'s <span>viewport</span>.</p>
99509+
99510+
<p class="example">For example, this might happen because an element has the <code
99511+
data-x="attr-hidden">hidden</code> attribute added, causing it to stop <span>being
99512+
rendered</span>. It might also happen to an <code>input</code> element when the element gets
99513+
<span data-x="concept-fe-disabled">disabled</span>.</p>
99514+
99515+
<p class="note">This will <a href="#note-sometimes-no-blur-event">usually</a> fire <code
99516+
data-x="event-blur">blur</code> events, and possibly <code data-x="event-change">change</code>
99517+
events.</p>
99518+
99519+
<p class="note">In addition to this asynchronous fixup, if the <span>focused area of the
99520+
document</span> is removed, there is a <a href="#node-remove-focus-fixup">synchronous
99521+
fixup</a>. That one will <em>not</em> fire <code data-x="event-blur">blur</code> or <code
99522+
data-x="event-change">change</code> events.</p>
99523+
</li>
99524+
9951699525
<li><p>For each <span>fully active</span> <code>Document</code> in <var>docs</var>, <span>run
9951799526
the update intersection observations steps</span> for that <code>Document</code>, passing in
9951899527
<var>now</var> as the timestamp. <ref spec=INTERSECTIONOBSERVER></p></li>

0 commit comments

Comments
 (0)