Repository: nvaccess/nvda

Issue:
NVDA incorrectly announces the presence of empty Alert live regions when dynamically added to the DOM
[empty_alert.htm.txt](https://github.com/nvaccess/nvda/files/80203/empty_alert.htm.txt)

It appears that, in the latest release of NVDA, dynamically rendered elements that include role=alert will automatically be announced in Firefox even though these tags include no content.

The technique of dynamically adding empty alert regions to the DOM is often used by frameworks for announcing custom message strings to screen reader users, however nothing should be announced when the live region is empty.

Attached is a file that demonstrates this behavior in NVDA + Firefox.



Discussion:
role="alert" gets treated somewhat differently to normal live regions. As noted in the spec:

> If the operating system allows, the user agent SHOULD fire a system alert event through the accessibility API when the WAI-ARIA alert is created.

Firefox does fire such an event, regardless of whether there is content in the alert. According to the above, this is not contrary to the spec. NVDA responds accordingly by reporting the alert.

It's true that obviously nothing could be announced for an empty live region (since live region announcements are just the text). However, an alert is special in that it reports "alert" as well.

I'd probably agree that this isn't useful behaviour, but if changing this is desired, it'll need to be addressed in the spec and then the browsers.

Most other screen readers ignore the alert role if there is no content in the alert container.

The idea of the live region roles is that they get announced when content is injected or updated. When there is no content there is nothing to report, especially when live region roles are present during page load.

This issue has been brought to the attention of the ARIA working group for spec clarification
I would still recommend, if possible, that NVDA does not report a static alert with no content, as it is definitely a false alarm for the user.
Cheers

Hello, chiming in as we noticed this issue with role alert and it's true the specification says it should fire a system alert event but it also says:
https://www.w3.org/TR/wai-aria/roles#alert

> Alerts are assertive live regions and will be processed as such by assistive technologies.

Worth noting none of the other screen readers I've tested with announces "alert" if there's no change in the content of the region.
FWIW this comes out from a WordPress ARIA live region implementation, relevant ticket here:
https://core.trac.wordpress.org/ticket/36289
Best regards and thanks for your amazing work on NVDA :)
Andrea

I certainly acknowledge that the spec says:

> Alerts are assertive live regions and will be processed as such by assistive technologies.

The problem with this is that it suggests the alert role is no different in any way whatsoever to an assertive live region. If that's the case, why fire an alert event in the first place? And that would also suggest screen readers shouldn't indicate that this is an alert (e.g. by saying "alert"), which rather defeats the point of the "alert" semantic. If we followed this rule, we also wouldn't ever report buttons, etc. in modeless browser notifications, which also use the alert role. IMO, the spec is trying to have it both ways (yes, it's an alert, but actually, no, it's just a live region), but fails to clearly specify how to handle this conflict.

To be clear, there's no argument that this is annoying and superfluous behaviour. The problem is that because of the way this is implemented in both browsers and NVDA, it's difficult to fix without breaking something or other (e.g. not reading "alert", not reading browser notifications properly, etc.).

Thanks very much James. Agree the spec is a bit ambiguous, as a consequence implementation across screen readers differs. Of course, I'm seeing this from a web developer point of view, trying to find something that we can actually use so please bear with me. To recap what the major screen readers do:
- VoiceOver: doesn't say "alert"
- JAWS: does say "alert" but when there's no content change, it doesn't say anything at all
- NVDA: always says "alert" even when the live region is empty

To me, the JAWS behaviour seems the one that makes more sense. I'm afraid, given the current different implementations, many developers will just avoid to use role=alert because of the inconsistent behaviors. 

I spoke with others in the ARIA WG about this, and they agreed that the spec doesn’t actually say anywhere that a screen reader must announce Alert when a system alert is fired even when this alert is empty.

The event that is fired is simply to give an opportunity for an AT to do something with it, and the logical deduction is that if the live region is empty, then there is nothing to announce.

From: Andrea Fercia [mailto:notifications@github.com] 
Sent: Friday, May 06, 2016 2:33 AM
To: nvaccess/nvda nvda@noreply.github.com
Cc: Bryan Garaventa bryan.garaventa@whatsock.com; Author author@noreply.github.com
Subject: Re: [nvaccess/nvda] NVDA incorrectly announces the presence of empty Alert live regions when dynamically added to the DOM (#5657)

Thanks very much James. Agree the spec is a bit ambiguous, as a consequence implementation across screen readers differs. Of course, I'm seeing this from a web developer point of view, trying to find something that we can actually use so please bear with me. To recap what the major screen readers do:
-   VoiceOver: doesn't say "alert"
-   JAWS: does say "alert" but when there's no content change, it doesn't say anything at all
-   NVDA: always says "alert" even when the live region is empty

To me, the JAWS behaviour seems the one that makes more sense. I'm afraid, given the current different implementations, many developers will just avoid to use role=alert because of the inconsistent behaviors. 

—
You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub https://github.com/nvaccess/nvda/issues/5657#issuecomment-217396959   https://github.com/notifications/beacon/ABx1aMSQQHYj2676IhzCmF68eY0E0WMpks5p-wq1gaJpZM4G_0Ef.gif 

I wasn't suggesting the spec dictates that screen readers should say "alert". However, the fact that a special event is fired also suggests it's special as compared to other live regions. I agree it doesn't make sense to do anything if it's empty, but then why fire the event when it's empty? That's just wasteful, since now an AT has to process at least part of the subtree before it knows whether it's supposed to react to the event. At the very least, that's a performance fail. At worst, it's counter-intuitive from an implementer perspective.

is there any workaround for this issue? @afercia @jcsteh @accdc 

@santospro in WordPress the workaround was to... remove `role="alert"` and use just `aria-live="assertive"`. See https://core.trac.wordpress.org/ticket/36289. That's unfortunate but I'm afraid `role="alert"` can't be used reliably given the different implementations.

@afercia thank you for quickly answer!
It works!

@jcsteh, @feerrenrut is there a consensus among NVDA developers regarding to this issue? Should there be any fixes provided in NVDA itself? Or is this something which won't be fixed?

Resolving patch:
diff --git a/source/NVDAObjects/IAccessible/__init__.py b/source/NVDAObjects/IAccessible/__init__.py
--- a/source/NVDAObjects/IAccessible/__init__.py
+++ b/source/NVDAObjects/IAccessible/__init__.py
@@ -1412,6 +1412,9 @@ def event_alert(self):
 		if self.role != controlTypes.ROLE_ALERT:
 			# Ignore alert events on objects that aren't alerts.
 			return
+		if not self.name and not self.description and self.childCount == 0:
+			# Don't report if there's no content.
+			return
 		# If the focus is within the alert object, don't report anything for it.
 		if eventHandler.isPendingEvents("gainFocus"):
 			# The alert event might be fired before the focus.


Test patch: