Opened 3 years ago

Closed 2 years ago

#2390 closed defect (fixed)

NVDA doesn't handle role=dialog with supporting ARIA attributes according to spec

Reported by: bgaraventa Owned by: jteh
Priority: minor Milestone: 2012.3
Component: Core Version: 2012.2rc1
Keywords: ARIA MozillaGrantMay2011 Cc:
Operating system: Windows XP Blocked by:
Blocking:
Changes document entry (for developers):

Description

According to the spec at
http://www.w3.org/TR/wai-aria/roles

When role=dialog is used in combination with either aria-label or aria-labelledby within the same attribute, then the contents of the dialog should be ignored when setting focus to an active element within the same dialog.

This does appear to work in some cases, but not in others, which looks like the behavior is inconsistently implemented.

The two attached implementations show this.

The sample with aria-labelledby and role=dialog uses these attributes on a parent tag of a calendar table. Role=presentation is also set on the Table tag, which, also according to spec, should prevent the contents of the table from being parsed for dialog label text when aria-label and aria-labelledby are not included at all.
In this sample however, all of the contents are being announced regardless when focus is set within the dialog using Firefox.

In the second sample, which uses aria-label and role=dialog in the Table tag instead, and does not use role=presentation at all, NVDA does not announce all of the table contents when focus is set within the table after the dialog opens.
This appears to be a fluke however, since, if you activate the Advanced Calendar link, then press the Spacebar on a calendar date to bring up the Edit Comment dialog, NVDA will then announce all of the Edit Comment dialog contents in the same manner as before, regardless that aria-label is included within the same parent tag that contains role=dialog.

So to summarise, both of these implementations should be working identically in NVDA and Firefox, but they both are giving contradictory feedback.

When focus is set within the dialog, none of the dialog contents should be announced. This should be the case for both the calendar dialog, and the Edit Comment dialog. The reason being, that aria-label and aria-labelledby are used in the same tag as role=dialog, so this sets the dialog title.

Also, even if aria-label and aria-labelledby were not included in the first sample, the presence of role=presentation should prevent the contents of the table from being announced in the same manner.

Attachments (1)

samples.zip (18.7 KB) - added by bgaraventa 3 years ago.
Code samples to demonstrate bugs

Download all attachments as: .zip

Change History (17)

Changed 3 years ago by bgaraventa

Code samples to demonstrate bugs

comment:1 Changed 3 years ago by jteh

Can you quote the section of the spec you're referring to? I see this:

Authors SHOULD provide a dialog label. Labels may be provided with the aria-label or aria-labelledby attribute if other mechanisms are not available. Authors SHOULD ensure each active dialog has a focused descendant element that has keyboard focus.

This says nothing about the contents of the dialog.

The reading of the dialog content relates to the description, not the label. As documented for alertdialog:

Authors SHOULD use aria-describedby on an alertdialog to point to the alert message element in the dialog. If they do not, assistive technologies will resort to their internal recovery mechanism to determine the contents of an alert message.

It's not clear from the spec as to how description should be handled for dialog, but it does refer to alertdialog as being related. Also, dialogs do typically have a caption/description.

comment:2 Changed 3 years ago by bgaraventa

Certainly.

"Authors SHOULD provide a dialog label. Labels may be provided with the 
aria-label 
or 
aria-labelledby 
attribute 
if other mechanisms are not available. Authors SHOULD ensure each active dialog has a focused descendant 
element 
that has keyboard focus."  

Regarding naming widgets - ARIA does have a document titled "ARIA User Agent Implementation Guide".  This guide has a section titled "Name and Description". 
In this section are specific instructions that assistive technologies (user agents) are supposed to use to determine the name for a widget.   Please read
this section. 

Specifically rule 2C " Otherwise, if the attributes checked in rules A and B didn't provide results, text is collected from descendant content if the current
element's 
role 
allows "Name From: contents." The text alternatives for child nodes will be concatenated, using this same set of rules. This same rule may apply to a child,
which means the computation becomes recursive and can result in text being collected in all the nodes in this subtree, no matter how deep they are. However,
any given descendant subtree may instead collect their part of the text alternative from the preferred markup described in A and B above. These author-specified
attributes are assumed to provide the correct text alternative for the entire subtree. All in all, the node rules are applied consistently as text alternatives
are collected from descendants, and each containing element in those descendants may or may not allow their contents to be used. Each node in the subtree
is consulted only once. If text has been collected from a child node, and is referenced by another IDREF in some descendant node, then that second, or
subsequent, reference is not followed. This is done to avoid infinite loops." 
 
So basically, it should only collect content from the whole DOM if aria-label or aria-labelledby are not explicitly set. If either is set, then only that content in the label should be announced.

The exception to this is the following:

"If aria-labelledby and aria-label are both empty or undefined, and if the element is not marked as presentational (role="presentation"), check for the presence of an equivalent host language attribute or element for associating a label, and use those mechanisms to determine a text alternative."

So if role=presentation is included on a particular node, that text should not be included within the label calculation.

This makes sense, especially if you know there is data that would not make sense as part of a dialog label. There needs to be a way of preventing irrelavent information from being announced.

comment:3 Changed 3 years ago by jteh

My point is that it's not the label that's in question here. It's the description. The label is being honoured as specified. The content is being read as part of the description, not the label. This happens because no description has been specified, so we calculate it.

comment:4 follow-up: Changed 3 years ago by bgaraventa

So how do you prevent irrelevant data from being announced then, when it's not desirable or helpful?

I don't know what you mean by description, there isn't anything in the spec that I can find that says a description has to be announced, this is what the label is for.

comment:5 in reply to: ↑ 4 Changed 3 years ago by jteh

  • Keywords ARIA added

Replying to bgaraventa:

So how do you prevent irrelevant data from being announced then, when it's not desirable or helpful?

To be honest, I don't know of a clean way to enforce "no description". The best I can come up with is pointing aria-describedby at an empty element, but that looks like a big ugly hack to me. We have to fall back to calculating the description if it isn't specified because so many dialogs don't set the description properly (and the spec allows for this).

I don't know what you mean by description, there isn't anything in the spec that I can find that says a description has to be announced,

See the section I quoted above re alertdialog and aria-describedby.

this is what the label is for.

The label is a short "title" for the dialog. The description is the message or caption of the dialog. For example, the title might be "NVDA Update", but the description might be "NVDA 2012.3 is available."

comment:6 follow-up: Changed 3 years ago by bgaraventa

Can you help me out? I've been reading the spec, but I can't find where it says that user agents must parse both an aria-describedby attribute and an aria-label/aria-labelledby at the same time. Can you point me to where it says this?

This is actually a really big problem. Take the following scenario for example.

  1. There is a surrounding Div tag with role=dialog and aria-label="Choose Region".
  2. Within this dialog is a listbox control with all of the countries in the world, which is surrounded by a Div tag with role=presentation.
  3. When the dialog opens, focus is set on the listbox control to highlight the currently selected country.

Now, since NVDA ignores role=presentation (which should cause NVDA to ignore all of this content when parsing alternative text according to the user agent specification), and NVDA will announce all of the content regardless what the label is explicitly set to, every country will be announced in addition to the dialog label before it gets around to announcing the currently selected country as expected.

Also, since aria-describedby isn't documented in the user agent spec alongside the requirement for aria-label and aria-labelledby, this means that the same ARIA widgets will work differently and with varying accessibility across different Assistive Technologies, which would undermine the whole purpose of standardization.

comment:7 in reply to: ↑ 6 Changed 3 years ago by jteh

Replying to bgaraventa:

Can you help me out? I've been reading the spec, but I can't find where it says that user agents must parse both an aria-describedby attribute and an aria-label/aria-labelledby at the same time. Can you point me to where it says this?

As I said, see my quote above from the spec regarding alertdialog.

Now, since NVDA ignores role=presentation (which should cause NVDA to ignore all of this content when parsing alternative text according to the user agent specification),

From the roles spec:

However, the user agent MUST expose content and descendant elements that do not have an explicit or inherited role of presentation. Thus, the presentation role causes a given element to be treated as having no role or to be removed from the accessibility tree, but does not cause the content contained within the element to be removed from the accessible tree.

This suggests we should ignore the element, but not its descendants.

and NVDA will announce all of the content regardless what the label is explicitly set to,

First, we don't announce all the content. We try to determine what content would constitute the caption/description of the dialog. This algorithm is necessarily complex and is not perfect, but we've done our best to ensure it only reads labels and text nodes. Second, you're still confusing label and description. Dialogs (even before ARIA) have always had a label and an optional caption/description/message. The presence of a label doesn't necessarily mean there is no caption/description/message.

comment:8 Changed 2 years ago by bgaraventa

I understand what you said about alertdialog, however dialog and alertdialog are not the same widget type. If they were the same, there would be no need for two separate roles in the spec.

alertdialog is meant to have its content announced automatically, whereas dialogs are not. There are cases where both are valuable implementations.

The problem here is that NVDA is enforcing alertdialog behavior regardless, and ignoring cases when a simple dialog is more accessible.

The case for making role=presentation only apply to direct descendants doesn't work in practice, especially when you have other role types in the mix.

E.G

<div role=presentation>
<ul role=listbox>
... Countries List ...
</ul>
</div>

Since you can't change the roles of an object without rerendering the object, this is the only way to prevent the list from being included, but if you are only including the first level of descendants, then none of the list items are included in the calculation.

This is also true for more complex controls like data tables, ARIA grids, and so on. There has to be a way of roping off content like this programmatically to ensure accessibility.

comment:9 follow-ups: Changed 2 years ago by bgaraventa

Just to clarify one thing about role=presentation, I'm not saying that the node with role=presentation should be removed from the user agent, such as in the Virtual Buffer, but that role=presentation should simply prevent that roped off content from being queried as part of a description calculation.

comment:10 in reply to: ↑ 9 Changed 2 years ago by jteh

Replying to bgaraventa:

I understand what you said about alertdialog, however dialog and alertdialog are not the same widget type. If they were the same, there would be no need for two separate roles in the spec.
alertdialog is meant to have its content announced automatically, whereas dialogs are not. There are cases where both are valuable implementations.

If what you say is true for ARIA (and I'd argue the spec is unclear on this), ARIA is clearly differentiating itself from normal platform dialogs, where there is always the possibility of dialog text. Consider, for example, a properties dialog containing information that is not interactive but still very relevant to the user. It makes sense that we should read this information. NVDA just treats an ARIA dialog the same way it treats any other dialog, which is the whole point of ARIA: to make web widgets "feel" native. (Btw, a dialog and an alertdialog look the same to a screen reader. We have to do very specific interrogation to determine that there is a difference.)

The problem here is that NVDA is enforcing alertdialog behavior regardless, and ignoring cases when a simple dialog is more accessible.

I need to follow this up with others in the ARIA community. If the consensus is that dialogs shouldn't read dialog text, I guess we can implement an ARIA specific change to suppress this behaviour.

Replying to bgaraventa:

Just to clarify one thing about role=presentation, I'm not saying that the node with role=presentation should be removed from the user agent, such as in the Virtual Buffer, but that role=presentation should simply prevent that roped off content from being queried as part of a description calculation.

The roles spec makes no mention of this at all. (One of the problems here is that the roles spec and the UA spec seem to contradict each other on a few points.) In any case, what you're suggesting simply isn't possible without changes to the browser, since role="presentation" elements aren't shown to us at all.

comment:11 in reply to: ↑ 9 Changed 2 years ago by jteh

Replying to bgaraventa:

role=presentation should simply prevent that roped off content from being queried as part of a description calculation.

You noted:

Role=presentation is also set on the Table tag, which, also according to spec, should prevent the contents of the table from being parsed for dialog label text when aria-label and aria-labelledby are not included at all.

You specifically say dialog label text here, not description text. There is a clear distinction here. Label text is determined by the browser using this algorithm.

Btw, the reason that removing role="presentation" stops NVDA from reporting the dialog text in this case is that NVDA's dialog text algorithm doesn't descend into tables. The problem when you add role="presentation" is that the table element isn't seen by NVDA at all, so we have no idea that its content is actually part of a table (which obviously isn't dialog text).

comment:12 Changed 2 years ago by jteh

To take this discussion to a more practical level, does anyone know of any ARIA dialogs in the wild that benefit from our dialog text algorithm? If we're not breaking anyone by changing this, I'm less reluctant to consider it, though the ARIA specific nature of this (and the fact that we have to specifically query to distinguish between dialog and alertdialog) still bothers me a little.

comment:13 Changed 2 years ago by bgaraventa

Regarding "You specifically say dialog label text here, not description text. There

is a clear distinction here. Label text is determined by the browser using
this algorithm."

I understand, this is why aria-label and aria-labelledby are explicitly set in the role=dialog tag, which is to set the label text.

I see what you mean about the table not being recognized when role=presentation is not used, and this will be helpful for dialogs of type role=alertdialog.

I don't think it will be a problem changing the NVDA functionality to not have standard role=dialog content to not be announced automatically, because the syntax for both behaviors is so simple.

E.G

If you want a regular dialog where you can explicitly control what content is automatically announced via aria-describedby when it opens and focus is set within, use role=dialog.

If you want a dialog that automatically announces dialog content when it opens and focus is set within, use role=alertdialog.

This seems perfectly reasonable to me, and it matches the user agent spec exactly. Sometimes it's very important to have explicit control over what is announced to make sure content is intuitive.

If you want to ask if others might be impacted by such a change, the ARIA and WebAIM lists might be a good way to do it. I suspect not though, since it's not commonly practiced to use either component type at present until agreement can be reached about the general functionality.

comment:14 Changed 2 years ago by bgaraventa

About what I said " I don't think it will be a problem changing the NVDA functionality to not have standard role=dialog content to not be announced automatically"

Sorry, that's a double negative and doesn't make sense. I mean it shouldn't be a problem having standard role=dialog components not have their contents automatically announced unless explicitly set, since developers can simply use role=alertdialog for this purpose if they desire it.

You get what I mean from the E.G examples.

comment:15 Changed 2 years ago by jteh

  • Keywords MozillaGrantMay2011 added
  • Milestone set to 2012.3
  • Owner set to jteh
  • Status changed from new to accepted

Unfortunately, we'll need to implement this separately for every browser, since there's no standard way for screen readers to determine whether a dialog requires description calculation or not.

comment:16 Changed 2 years ago by jteh

  • Resolution set to fixed
  • Status changed from accepted to closed
Note: See TracTickets for help on using tickets.