Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BrowseMode: don't refuse to report focus changes for replaced controls or focused ancestors #8869

Merged
merged 5 commits into from
Oct 25, 2018

Conversation

michaelDCurran
Copy link
Member

@michaelDCurran michaelDCurran commented Oct 22, 2018

Link to issue number:

Closes #6606
Closes #8341

Summary of the issue:

NVDA sometimes fails to report focus in browseMode documents, as it is trying to filter out redundant focus events caused by moving the caret.
Particular cases:

Focus replacement

Custom checkboxes and expandable controls that draw a checkmark or + symbol using the content css property on the element's ::before selector, can cause CSS reframing in Firefox, meaning that the accessible representing the focus dies and is replaced with a new accessible. NVDA refuses in this case to announce the state change, and also the new focus. At very least, NVDA should announce the new focus.
A similar case (but this time deliberate on the part of the web author) is where the current focus is removed from the DOM completely, and a new element is inserted in its place and then focused. An example of this is the Edit title button on Github pull requests. When pressing the button, the Title edit field appears in its place, and NVDA reports nothing.

Focus moves to an ancestor

Sometimes web authors want to focus an ancestor of the previous focus. this is quite common for single-page web apps. In this case, NVDA reports nothing.

Current implementation

Currently, NVDA chooses to ignore any focus in browseMode that overlaps with the browseMode caret. This is so that any focus event that resalts from moving the caret is not reported as this would be redundant. However, this rule is clearly too limiting as it stops the above examples from working.

Description of how this pull request fixes the issue:

This PR changes browseMode so that:

  • When NVDA requests that an element be focused due to the caret moving, it remembers this object for later.
  • In the gainFocus event for any object within the browseMode document, NVDA tries to lookup the offsets for the previous focus and or the queued focus (due to the caret moving). If it successfully gets the offsets, and the start offset is equal to the new focus's start offset, then the focus is ignored. However, if the offsets differ or NVDA could not lookup the offsets (the old focus died) then the focus is reported.

Testing performed:

Tested all cases in #6606 and #8341

Known issues with pull request:

None known. Note though this does not address the underlying issue in #2039.

Change log entry:

Bug fixes:
NVDA no longer refuses to report the focus on web pages where the new focus replaces a control that no longer exists. (#6606, #8341)

…en the focus is replaced with a new focus at the same offsets, or when focus moves to an ancestor.
@@ -1231,14 +1231,21 @@ def _set_selection(self, info, reason=controlTypes.REASON_CARET):
if obj==self.rootNVDAObject:
return
if focusObj and not eventHandler.isPendingEvents("gainFocus") and focusObj!=self.rootNVDAObject and focusObj != api.getFocusObject() and self._shouldSetFocusToObj(focusObj):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you understand this condition well enough to replace any parts of it with a self-documenting variable names. Or perhaps a comment about why each condition is in there?

caretInfo.expand(textInfos.UNIT_CHARACTER)
if not self._hadFirstGainFocus or not focusInfo.isOverlapping(caretInfo):
# The virtual caret is not within the focus node.
if not self._hadFirstGainFocus or not lastFocusInfo or focusInfo.compareEndPoints(lastFocusInfo,"startToStart")!=0 or focusInfo.compareEndPoints(lastFocusInfo,"endToEnd")>0:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you extract focusInfo.compareEndPoints(lastFocusInfo,"startToStart")!=0 or focusInfo.compareEndPoints(lastFocusInfo,"endToEnd")>0 into a method that explains what it does?

Both to condense it, and to make it easier to understand.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like your other suggestion above, I think I'd prefer to just split the line up and add comments for each comparison. A method seems a bit strange as it would be only acting upon its arguments with no state.

@michaelDCurran
Copy link
Member Author

@feerrenrut I believe I have addressed your review comments.

@michaelDCurran
Copy link
Member Author

I am going to revert this from beta as it causes#8895 and it is similarly causing some buttons and links to be repeated when arrowing to them in browse mode on Github. Most likely this is due to Firefox re-framing the accessible due to a css onFocus change. The old accessible is dying, and a new accessible (with a new ID) is focused.

@jcsteh
Copy link
Contributor

jcsteh commented Feb 16, 2021

I am going to revert this from beta as it causes#8895 and it is similarly causing some buttons and links to be repeated when arrowing to them in browse mode on Github. Most likely this is due to Firefox re-framing the accessible due to a css onFocus change. The old accessible is dying, and a new accessible (with a new ID) is focused.

Note that this was fixed in Firefox some time ago now. Given that some of the issues fixed here are still relevant (#6606, #12073), it might be worth considering this again.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

aria-expanded status not announced when ::before element has content NVDA not reading focused parent
4 participants