Skip to content

Commit e8b7de8

Browse files
Merge 01e5261 into e019a24
2 parents e019a24 + 01e5261 commit e8b7de8

4 files changed

Lines changed: 47 additions & 1 deletion

File tree

source/browseMode.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1553,6 +1553,13 @@ def event_gainFocus(self, obj, nextHandler):
15531553
return
15541554
if not self.passThrough and self._shouldIgnoreFocus(obj):
15551555
return
1556+
1557+
# If the previous focus object was removed, we might hit a false positive for overlap detection.
1558+
# Track the previous focus target so that we can account for this scenario.
1559+
previousFocusObjIsDefunct = False
1560+
if self._lastFocusObj and controlTypes.STATE_DEFUNCT in self._lastFocusObj.states:
1561+
previousFocusObjIsDefunct = True
1562+
15561563
self._lastFocusObj=obj
15571564

15581565
try:
@@ -1570,7 +1577,8 @@ def event_gainFocus(self, obj, nextHandler):
15701577
caretInfo=self.makeTextInfo(textInfos.POSITION_CARET)
15711578
# Expand to one character, as isOverlapping() doesn't treat, for example, (4,4) and (4,5) as overlapping.
15721579
caretInfo.expand(textInfos.UNIT_CHARACTER)
1573-
if not self._hadFirstGainFocus or not focusInfo.isOverlapping(caretInfo):
1580+
isOverlapping = focusInfo.isOverlapping(caretInfo)
1581+
if not self._hadFirstGainFocus or not isOverlapping or (isOverlapping and previousFocusObjIsDefunct):
15741582
# The virtual caret is not within the focus node.
15751583
oldPassThrough=self.passThrough
15761584
passThrough = self.shouldPassThrough(obj, reason=OutputReason.FOCUS)

tests/system/robot/chromeTests.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,3 +345,37 @@ def test_ariaCheckbox_browseMode():
345345
actualSpeech,
346346
"Sandwich Condiments grouping list with 4 items Lettuce check box not checked"
347347
)
348+
349+
350+
def test_i12147():
351+
"""
352+
New focus target should be announced if the triggering element is removed when activated.
353+
"""
354+
_chrome.prepareChrome(
355+
f"""
356+
<div>
357+
<button id='trigger0'>trigger 0</button>
358+
<h4 id='target0' tabindex='-1'>target 0</h4>
359+
</div>
360+
<script>
361+
let trigger0 = document.querySelector('#trigger0');
362+
trigger0.addEventListener('click', e => {{
363+
let focusTarget = document.querySelector('#target0');
364+
trigger0.remove();
365+
focusTarget.focus();
366+
}})
367+
</script>
368+
"""
369+
)
370+
# Jump to the first button (the trigger)
371+
actualSpeech = _chrome.getSpeechAfterKey("tab")
372+
_asserts.strings_match(
373+
actualSpeech,
374+
"trigger 0 button"
375+
)
376+
# Activate the button, we should hear the new focus target.
377+
actualSpeech = _chrome.getSpeechAfterKey("enter")
378+
_asserts.strings_match(
379+
actualSpeech,
380+
"target 0 heading level 4"
381+
)

tests/system/robot/chromeTests.robot

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,6 @@ ARIA checkbox
4747
[Documentation] Navigate to an unchecked checkbox in reading mode.
4848
[Tags] aria-at
4949
test_ariaCheckbox_browseMode
50+
i12147
51+
[Documentation] New focus target should be announced if the triggering element is removed when activated
52+
test_i12147

user_docs/en/changes.t2t

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ What's New in NVDA
4343
- - TextInfo.getTextInChunks no longer freezes when called on Rich Edit controls such as the NVDA log viewer. (#11613)
4444
- It is once again possible to use NVDA in a languages containing underscores in the locale name such as de_CH on Windows 10 1803 and 1809. (#12250)
4545
- In WordPad, configuration of superscript/subscript reporting works as expected. (#12262)
46+
- NVDA no longer fails to announce the newly focused content on a web page if the old focus disappears and is replaced by the new focus in the same position. (#12147)
4647

4748

4849
== Changes for Developers ==

0 commit comments

Comments
 (0)