Repository: nvaccess/nvda

Issue:
ARIA tab panels should be handled consistently inside and outside of the virtual buffer
**Reported by vtsaran on 2010-06-16 06:38**
On the yahoo.com page there are at least two ARIA tab panels, one listing the search categories and another one listing the news categories (right after the "news" heading). In both instances there is an additional HTML link between the list of tabs and the content pane for a particular tab. For example, in the "search categories" tab panel there is a "more" link followed by a content pane containing the edit field and the "search" button. At the same time the "news" tab panel contains a "move to top" or "move news down" link between the list of tabs and the content pane for a particular tab. In both instances the aria-labelledby property is used to link the list of tabs with the content pane.
When inside a virtual buffer NVDA does not establish the contextual link between the list of tabs and the content pane by saying "xyz property page", however, it does so without a problem when the user is in "focus mode". It could be the case that the link in between disorients NVDA or that the panel is not coded correctly, but then NVDA's behavior should be consistent for both "browse" and "focus" modes.
I believe aria-labelledby property should provide enough context for NVDA to associate the list of tabs with the content pane even if they do not follow each other in the tab order.

ARIA tab panels should be handled consistently inside and outside of the virtual buffer
**Reported by vtsaran on 2010-06-16 06:38**
On the yahoo.com page there are at least two ARIA tab panels, one listing the search categories and another one listing the news categories (right after the "news" heading). In both instances there is an additional HTML link between the list of tabs and the content pane for a particular tab. For example, in the "search categories" tab panel there is a "more" link followed by a content pane containing the edit field and the "search" button. At the same time the "news" tab panel contains a "move to top" or "move news down" link between the list of tabs and the content pane for a particular tab. In both instances the aria-labelledby property is used to link the list of tabs with the content pane.
When inside a virtual buffer NVDA does not establish the contextual link between the list of tabs and the content pane by saying "xyz property page", however, it does so without a problem when the user is in "focus mode". It could be the case that the link in between disorients NVDA or that the panel is not coded correctly, but then NVDA's behavior should be consistent for both "browse" and "focus" modes.
I believe aria-labelledby property should provide enough context for NVDA to associate the list of tabs with the content pane even if they do not follow each other in the tab order.



Discussion:
Comment 2 by jteh on 2010-06-16 22:59
There is a good reason that NVDA doesn't read labels for controls in browse mode like it does in focus mode. The idea is that browse mode just shows the text on the page. Let's take a simple labelled "Search" edit field as an example. If we said the label, you would hear "Search" twice when moving to this field: once because of the text on the page and then again because of the text's relation as a label. We could stop rendering this text into the buffer, but then you wouldn't get a true idea of the text on the page. Similarly, we could render all labels into the buffer, but then you'd see double text in many cases.

I think I understand your use case, but implementing it would break a lot of other cases. I'm not keen on specific exceptions for tab panels. We need to come up with a good rule here.

Comment 3 by vtsaran (in reply to comment 2) on 2010-06-17 04:43
Well, my question was really two fold:
1. As the user tabs into the tab pannel, should NVDA notify the user when they enter the content panel following the same paradigm for both "browse" and "focus modes? I am not concerned whether the label is actually rendered into the virtual buffer.
2. What can be done to provide the necessary context to the user given the current NVDA treatment of tab panels inside a virtual buffer?
Or are you saying that when NVDA is in "browse mode", tabbing is virtualized as well?

Comment 4 by jteh (in reply to comment 3) on 2010-06-17 05:10
Replying to [vtsaran](comment:3):

> 1. As the user tabs into the tab pannel, should NVDA notify the user when they enter the content panel following the same paradigm for both "browse" and "focus modes?

To answer this, let me address another of your questions:

> are you saying that when NVDA is in "browse mode", tabbing is virtualized as well?

It's more correct to say that when in browse mode, all navigation reads using browse mode logic. So, quick navigation and tabbing read in exactly the same way.

> 1. What can be done to provide the necessary context to the user given the current NVDA treatment of tab panels inside a virtual buffer?

How do sighted users know which tab panel they are in? Do they just determine this by looking to see which is the selected tab or is there some other heading somewhere? How is the situation different for screen reader users?

Let's use this ticket editing form as an example. It has a fieldset with a legend of "Change Properties", which is similar to a property page in that it is a container for controls. NVDA doesn't read this while navigating in the virtual buffer because the legend itself is already part of the buffer and is right above the text. Otherwise, when pressing down arrow, you would hear "Change Properties" as you hit the legend, then "Change Properties grouping" as you moved down into the fieldset.

Comment 5 by vtsaran (in reply to comment 4) on 2010-06-17 07:28

> How do sighted users know which tab panel they are in? Do they just determine this by looking to see which is the selected tab or is there some other heading somewhere? How is the situation different for screen reader users?

Well, the selected tab is one aspect of it. vertical Alignment is another. The third one is ability to see how the content changes in response to the tab selection with a click. There also may be coloring, but I am not sure of that.

Screen reader users do not have that luxury because the content is represented in a linear fashion inside the virtual buffer.

Another thing to remember is that sighted users rarely have a need to tab inside the content pane unless they want to interact with elements inside it. Screen reader users do not have that choice.

Ideally, the beginning and the end of tab panel, as well as other DHTML widgets, should be announced but this is beyond the scope of this ticket.

> Let's use this ticket editing form as an example. It has a fieldset with a legend of "Change Properties", which is similar to a property page in that it is a container for controls. NVDA doesn't read this while navigating in the virtual buffer because the legend itself is already part of the buffer and is right above the text. Otherwise, when pressing down arrow, you would hear "Change Properties" as you hit the legend, then "Change Properties grouping" as you moved down into the fieldset.

Well, I understand the rationale for the arrow keys, but I was expecting the TAB key to interact with the browser directly, hence was my suggestion.

Feel free to close this ticket if you don't think my suggestion goes against NVDA's philosophy. <smile>

Comment 6 by jteh on 2010-06-17 07:32
I do understand where you're coming from with this. I just can't come up with anything right now that won't cause excessive verbosity in other situations. My intent was to explain why the current behaviour exists, not to suggest that we weren't at all interested in making your use case work better.

One possibility is to make an exception for property pages, since they're rather unique in some ways. They would then be read as a container in the buffer like lists, tables, landmarks, etc., except that the name would be read as well. I'm not quite sure how this could be done yet, nor am I sure if it is the best solution.

I wonder whether it would help if we'd treat tabs as landmarks. Thus, announce the tab when you cursor in it, and announce "out of tab" when you cursor out of it.
I'm sorry to enter this call.
If I can contribute one vote, I would very much like the nvda to read the label of objects as checkboxes, boxes for editing text by navigating with the arrows on a web page.
I understand that the amount of speech would increase, and that it is possible to know what the context control is on the page, however understanding the context of a page is often tricky.
This could be an option to leave for the user to enable or not.
The jaws read the labels, and I for many times because I was not used to nvda I believed that it was a nvda problem, not a feature.
Fixing #3321 should make this get reported when tabbing. The open question is whether the property page should be read when reading with the arrow keys, etc. We don't want to do that for groupings because groupings normally have a heading and that would result in duplication. Arguably, tab panels don't have a heading beyond the selected tab itself, which isn't quite as clear.

P3 to at least consider the UX here.
Could someone please provide exact steps to reproduce it? On yahoo.com I cannot reproduce it. But the website has been redesigned.
STR:

1. Open this URL: `data:text/html,<div id="tab" role="tab" tabindex="0">Foo</div><a href="https://www.nvaccess.org/">Intervening link</a><div role="tabpanel" aria-labelledby="tab"><button>Button inside the tab panel</button></div>`
2. Tab to "Intervening link".
3. Press tab again.
    * Expected: "Foo  property page  Button inside the tab panel  button"
    * Actual: "Button inside the tab panel  button"

Now that #3321 has been fixed (via #7435), this bug is trivial to fix. Just check for controlTypes.ROLE_PROPERTYPAGE as well as ROLE_GROUPING at around [line 178 of source/speech.py](https://github.com/nvaccess/nvda/blob/master/source/speech.py#L1178).
Comment 2 by jteh on 2010-06-16 22:59
There is a good reason that NVDA doesn't read labels for controls in browse mode like it does in focus mode. The idea is that browse mode just shows the text on the page. Let's take a simple labelled "Search" edit field as an example. If we said the label, you would hear "Search" twice when moving to this field: once because of the text on the page and then again because of the text's relation as a label. We could stop rendering this text into the buffer, but then you wouldn't get a true idea of the text on the page. Similarly, we could render all labels into the buffer, but then you'd see double text in many cases.

I think I understand your use case, but implementing it would break a lot of other cases. I'm not keen on specific exceptions for tab panels. We need to come up with a good rule here.

Comment 3 by vtsaran (in reply to comment 2) on 2010-06-17 04:43
Well, my question was really two fold:
1. As the user tabs into the tab pannel, should NVDA notify the user when they enter the content panel following the same paradigm for both "browse" and "focus modes? I am not concerned whether the label is actually rendered into the virtual buffer.
2. What can be done to provide the necessary context to the user given the current NVDA treatment of tab panels inside a virtual buffer?
Or are you saying that when NVDA is in "browse mode", tabbing is virtualized as well?

Comment 4 by jteh (in reply to comment 3) on 2010-06-17 05:10
Replying to [vtsaran](comment:3):

> 1. As the user tabs into the tab pannel, should NVDA notify the user when they enter the content panel following the same paradigm for both "browse" and "focus modes?

To answer this, let me address another of your questions:

> are you saying that when NVDA is in "browse mode", tabbing is virtualized as well?

It's more correct to say that when in browse mode, all navigation reads using browse mode logic. So, quick navigation and tabbing read in exactly the same way.

> 1. What can be done to provide the necessary context to the user given the current NVDA treatment of tab panels inside a virtual buffer?

How do sighted users know which tab panel they are in? Do they just determine this by looking to see which is the selected tab or is there some other heading somewhere? How is the situation different for screen reader users?

Let's use this ticket editing form as an example. It has a fieldset with a legend of "Change Properties", which is similar to a property page in that it is a container for controls. NVDA doesn't read this while navigating in the virtual buffer because the legend itself is already part of the buffer and is right above the text. Otherwise, when pressing down arrow, you would hear "Change Properties" as you hit the legend, then "Change Properties grouping" as you moved down into the fieldset.

Comment 5 by vtsaran (in reply to comment 4) on 2010-06-17 07:28

> How do sighted users know which tab panel they are in? Do they just determine this by looking to see which is the selected tab or is there some other heading somewhere? How is the situation different for screen reader users?

Well, the selected tab is one aspect of it. vertical Alignment is another. The third one is ability to see how the content changes in response to the tab selection with a click. There also may be coloring, but I am not sure of that.

Screen reader users do not have that luxury because the content is represented in a linear fashion inside the virtual buffer.

Another thing to remember is that sighted users rarely have a need to tab inside the content pane unless they want to interact with elements inside it. Screen reader users do not have that choice.

Ideally, the beginning and the end of tab panel, as well as other DHTML widgets, should be announced but this is beyond the scope of this ticket.

> Let's use this ticket editing form as an example. It has a fieldset with a legend of "Change Properties", which is similar to a property page in that it is a container for controls. NVDA doesn't read this while navigating in the virtual buffer because the legend itself is already part of the buffer and is right above the text. Otherwise, when pressing down arrow, you would hear "Change Properties" as you hit the legend, then "Change Properties grouping" as you moved down into the fieldset.

Well, I understand the rationale for the arrow keys, but I was expecting the TAB key to interact with the browser directly, hence was my suggestion.

Feel free to close this ticket if you don't think my suggestion goes against NVDA's philosophy. <smile>

Comment 6 by jteh on 2010-06-17 07:32
I do understand where you're coming from with this. I just can't come up with anything right now that won't cause excessive verbosity in other situations. My intent was to explain why the current behaviour exists, not to suggest that we weren't at all interested in making your use case work better.

One possibility is to make an exception for property pages, since they're rather unique in some ways. They would then be read as a container in the buffer like lists, tables, landmarks, etc., except that the name would be read as well. I'm not quite sure how this could be done yet, nor am I sure if it is the best solution.

I wonder whether it would help if we'd treat tabs as landmarks. Thus, announce the tab when you cursor in it, and announce "out of tab" when you cursor out of it.
I'm sorry to enter this call.
If I can contribute one vote, I would very much like the nvda to read the label of objects as checkboxes, boxes for editing text by navigating with the arrows on a web page.
I understand that the amount of speech would increase, and that it is possible to know what the context control is on the page, however understanding the context of a page is often tricky.
This could be an option to leave for the user to enable or not.
The jaws read the labels, and I for many times because I was not used to nvda I believed that it was a nvda problem, not a feature.
Fixing #3321 should make this get reported when tabbing. The open question is whether the property page should be read when reading with the arrow keys, etc. We don't want to do that for groupings because groupings normally have a heading and that would result in duplication. Arguably, tab panels don't have a heading beyond the selected tab itself, which isn't quite as clear.

P3 to at least consider the UX here.
Could someone please provide exact steps to reproduce it? On yahoo.com I cannot reproduce it. But the website has been redesigned.
STR:

1. Open this URL: `data:text/html,<div id="tab" role="tab" tabindex="0">Foo</div><a href="https://www.nvaccess.org/">Intervening link</a><div role="tabpanel" aria-labelledby="tab"><button>Button inside the tab panel</button></div>`
2. Tab to "Intervening link".
3. Press tab again.
    * Expected: "Foo  property page  Button inside the tab panel  button"
    * Actual: "Button inside the tab panel  button"

Now that #3321 has been fixed (via #7435), this bug is trivial to fix. Just check for controlTypes.ROLE_PROPERTYPAGE as well as ROLE_GROUPING at around [line 178 of source/speech.py](https://github.com/nvaccess/nvda/blob/master/source/speech.py#L1178).

Resolving patch:
diff --git a/source/speech.py b/source/speech.py
--- a/source/speech.py
+++ b/source/speech.py
@@ -3,7 +3,7 @@
 #A part of NonVisual Desktop Access (NVDA)
 #This file is covered by the GNU General Public License.
 #See the file COPYING for more details.
-#Copyright (C) 2006-2017 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Babbage B.V.
+#Copyright (C) 2006-2019 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Babbage B.V., Bill Dengler
 
 """High-level functions to speak information.
 """ 
@@ -1227,8 +1227,8 @@ def getControlFieldSpeech(attrs,ancestorAttrs,fieldType,formatConfig=None,extraD
 	elif fieldType=="start_addedToControlFieldStack" and role==controlTypes.ROLE_TABLE and tableID:
 		# Table.
 		return " ".join((nameText,roleText,stateText, getSpeechTextForProperties(_tableID=tableID, rowCount=attrs.get("table-rowcount"), columnCount=attrs.get("table-columncount")),levelText))
-	elif nameText and reason==controlTypes.REASON_FOCUS and fieldType == "start_addedToControlFieldStack" and role==controlTypes.ROLE_GROUPING:
-		# #3321: Report the name of groupings (such as fieldsets) for quicknav and focus jumps
+	elif nameText and reason==controlTypes.REASON_FOCUS and fieldType == "start_addedToControlFieldStack" and role in (controlTypes.ROLE_GROUPING, controlTypes.ROLE_PROPERTYPAGE):
+		# #3321, #709: Report the name of groupings (such as fieldsets) and tab pages for quicknav and focus jumps
 		return " ".join((nameText,roleText))
 	elif fieldType in ("start_addedToControlFieldStack","start_relative") and role in (controlTypes.ROLE_TABLECELL,controlTypes.ROLE_TABLECOLUMNHEADER,controlTypes.ROLE_TABLEROWHEADER) and tableID:
 		# Table cell.


Test patch: