Skip to content

Commit e233336

Browse files
authored
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 901c8c5 commit e233336

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>
@@ -59396,9 +59408,9 @@ interface <dfn interface>HTMLDialogElement</dfn> : <span>HTMLElement</span> {
5939659408

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

@@ -77126,39 +77138,14 @@ partial interface <span id="NavigatorUserActivation-partial">Navigator</span> {
7712677138
</li>
7712777139
</ol>
7712877140

77129-
<p>When the <span>currently focused area of a top-level traversable</span> is somehow unfocused
77130-
without another element being explicitly focused in its stead, the user agent must
77131-
<span>immediately</span> run the <span>unfocusing steps</span> for that object.</p>
77132-
77133-
<p class="note">The <span>unfocusing steps</span> do not always result in the focus changing,
77134-
even when applied to the <span>currently focused area of a top-level traversable</span>. For
77141+
<p class="note">The <span>unfocusing steps</span> do not always result in the focus changing, even
77142+
when applied to the <span>currently focused area of a top-level traversable</span>. For
7713577143
example, if the <span>currently focused area of a top-level traversable</span> is a
7713677144
<span>viewport</span>, then it will usually keep its focus regardless until another
7713777145
<span>focusable area</span> is explicitly focused with the <span>focusing steps</span>.</p>
7713877146

7713977147
<hr>
7714077148

77141-
<p><dfn>Focus fixup rule</dfn>: When the designated <span data-x="focused area of the
77142-
document">focused area of the document</span> is removed from that <code>Document</code> in some
77143-
way (e.g. it stops being a <span>focusable area</span>, it is removed from the DOM, it becomes
77144-
<span>inert</span>, etc.), designate the <code>Document</code>'s <span>viewport</span> to be the
77145-
new <span>focused area of the document</span>.</p>
77146-
77147-
<p class="example">For example, this might happen because an element is removed from its
77148-
<code>Document</code>, or has a <code data-x="attr-hidden">hidden</code> attribute added. It might
77149-
also happen to an <code>input</code> element when the element gets <span
77150-
data-x="concept-fe-disabled">disabled</span>.</p>
77151-
77152-
<p class="example">In a <code>Document</code> whose <span data-x="focused area of the
77153-
document">focused area</span> is a <code>button</code> element, removing, disabling, or hiding
77154-
that button would cause the page's new <span data-x="focused area of the document">focused
77155-
area</span> to be the <span>viewport</span> of the <code>Document</code>. This would, in turn,
77156-
be reflected through the <code
77157-
data-x="dom-documentorshadowroot-activeElement">activeElement</code> API as <span>the body
77158-
element</span>.</p>
77159-
77160-
<hr>
77161-
7716277149
<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
7716377150
follows:</p>
7716477151

@@ -77205,8 +77192,9 @@ partial interface <span id="NavigatorUserActivation-partial">Navigator</span> {
7720577192
named <code data-x="event-blur">blur</code> at <var>blur event target</var>, with
7720677193
<var>related blur target</var> as the related target.</p>
7720777194

77208-
<p class="note">In some cases, e.g. if <var>entry</var> is an <code>area</code>
77209-
element's shape, a scrollable region, or a <span>viewport</span>, no event is fired.</p>
77195+
<p class="note" id="note-sometimes-no-blur-event">In some cases, e.g., if <var>entry</var> is
77196+
an <code>area</code> element's shape, a scrollable region, or a <span>viewport</span>, no
77197+
event is fired.</p>
7721077198
</li>
7721177199
</ol>
7721277200
</li>
@@ -99654,6 +99642,27 @@ import "https://example.com/foo/../module2.mjs";</code></pre>
9965499642
</ol>
9965599643
</li>
9965699644

99645+
<li id="focus-fixup-rule">
99646+
<p>For each <span>fully active</span> <code>Document</code> in <var>docs</var>, if the <span
99647+
data-x="focused area of the document">focused area</span> of that <code>Document</code> is
99648+
not a <span>focusable area</span>, then run the <span>focusing steps</span> for that
99649+
<code>Document</code>'s <span>viewport</span>.</p>
99650+
99651+
<p class="example">For example, this might happen because an element has the <code
99652+
data-x="attr-hidden">hidden</code> attribute added, causing it to stop <span>being
99653+
rendered</span>. It might also happen to an <code>input</code> element when the element gets
99654+
<span data-x="concept-fe-disabled">disabled</span>.</p>
99655+
99656+
<p class="note">This will <a href="#note-sometimes-no-blur-event">usually</a> fire <code
99657+
data-x="event-blur">blur</code> events, and possibly <code data-x="event-change">change</code>
99658+
events.</p>
99659+
99660+
<p class="note">In addition to this asynchronous fixup, if the <span>focused area of the
99661+
document</span> is removed, there is a <a href="#node-remove-focus-fixup">synchronous
99662+
fixup</a>. That one will <em>not</em> fire <code data-x="event-blur">blur</code> or <code
99663+
data-x="event-change">change</code> events.</p>
99664+
</li>
99665+
9965799666
<li><p>For each <span>fully active</span> <code>Document</code> in <var>docs</var>, <span>run
9965899667
the update intersection observations steps</span> for that <code>Document</code>, passing in
9965999668
<var>now</var> as the timestamp. <ref spec=INTERSECTIONOBSERVER></p></li>

0 commit comments

Comments
 (0)