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

I6358 support aria current #6860

Merged
merged 9 commits into from Mar 14, 2017
Merged

I6358 support aria current #6860

merged 9 commits into from Mar 14, 2017

Conversation

feerrenrut
Copy link
Contributor

@feerrenrut feerrenrut commented Feb 9, 2017

Support for aria current. Used http://ljwatson.github.io/design-patterns/aria-current/ to test this, as described we report just 'current' if True and 'current step' etc if there is another value.

Fixes #6358

@feerrenrut
Copy link
Contributor Author

aria-current is not yet being reported for list items on any browser.

@jcsteh mentioned yesterday that:

List items are probably treated as layout by TextInfo.getPresentationCategory. A bit tricky because we don't want other states like read-only or the role to get reported, only really aria-current

Copy link
Contributor

@jcsteh jcsteh left a comment

Choose a reason for hiding this comment

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

Nice work so far. Thanks. :)

Aside from the review comments, support also needs to be implemented for braille. You'll want to look at braille.getBrailleTextForProperties, braille.NVDAObjectRegion.update and braille.getControlFieldBraille. The changes will be similar to those in speech. I realise you don't have a braille display, but you can use the Braille Viewer driver I hacked together some time ago to get braille enabled and then look at the IO log output to see the text being translated.

def getValueForAriaCurrent(self):
"""Gets the value for aria-current. Normally returns False. If this object is current
it will return one of the following values: True, "page", "step", "location", "date", "time"
"""
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. This should be a property rather than a method. Aside from consistency with other NVDAObject properties (name, description, etc.), this means this will be cached during a core tick which improves performance. In NVDA, you can do this by simply naming the method _get_foo, which will create a property named foo.
  2. While this is from the ARIA spec, we try to keep global concepts pretty abstract/platform agnostic. This one is tricky to name because just having a property called current looks kinda weird. We feel the name isCurrent is probably best. While this is perhaps a tiny bit misleading (the "is" prefix normally suggests it's a boolean), it's the best we could come up with... and it is boolean-ish anyway in the sense that it's either current or not, with the type just being a nicety for the user.
  3. The docstring should probably say that this indicates whether this object is the current element in a set of related elements... or something like that; something similar to the summary sentence in the ARIA spec. It can still say it's mapped from aria-current, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah ok. I'm not 100% comfortable with the name, but I can't think of anything better.

@@ -387,6 +389,16 @@ def _get_description(self):
pass
return super(EdgeNode,self).description

def getValueForAriaCurrent(self):
ariaProperties=self.UIAElement.currentAriaProperties
match = re.match("current=(\w+);", ariaProperties)
Copy link
Contributor

Choose a reason for hiding this comment

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

Please make this a compiled regular expression constant. See re.compile. We tend to name such constants RE_FOO.

source/speech.py Outdated
@@ -1001,6 +1002,20 @@ def getSpeechTextForProperties(reason=controlTypes.REASON_QUERY,**propertyValues
if rowCount or columnCount:
# The caller is entering a table, so ensure that it is treated as a new table, even if the previous table was the same.
oldTableID = None
ariaCurrent = propertyValues.get('current', False)
if ariaCurrent is not None and ariaCurrent != False:
Copy link
Contributor

Choose a reason for hiding this comment

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

You could simplify this to just: if ariaCurrent:

source/speech.py Outdated
ariaCurrent = propertyValues.get('current', False)
if ariaCurrent is not None and ariaCurrent != False:
if ariaCurrent=="page":
textList.append(_("current page"))
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. I'd suggest moving these names into a dict in controlTypes, perhaps named currentLabels.
  2. Each of these translatable strings needs a translators comment.

@@ -1112,7 +1129,7 @@ def getControlFieldSpeech(attrs,ancestorAttrs,fieldType,formatConfig=None,extraD
content = attrs.get("content")
if content and speakContentFirst:
out.append(content)
out.extend(x for x in (nameText,(stateText if speakStatesFirst else roleText),(roleText if speakStatesFirst else stateText),valueText,descriptionText,levelText,keyboardShortcutText) if x)
out.extend(x for x in (nameText,(stateText if speakStatesFirst else roleText),(roleText if speakStatesFirst else stateText),ariaCurrentText,valueText,descriptionText,levelText,keyboardShortcutText) if x)
if content and not speakContentFirst:
out.append(content)
return CHUNK_SEPARATOR.join(out)
Copy link
Contributor

Choose a reason for hiding this comment

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

Regarding speaking for list items, etc., this can be achieved by handling current similar to the way we handle clickable below. The conditions for current should be the same as clickable except we do want to report it even if extraDetail is True (whereas we don't for clickable). The tricky thing here is that ideally, we still want to report current if we're reporting clickable (and vice versa). So, I guess the clickable and current block will have to be merged.

@@ -257,6 +257,12 @@ def _getParagraphOffsets(self,offset):
return lineStart.value,lineEnd.value

def _normalizeControlField(self,attrs):

Copy link
Contributor

Choose a reason for hiding this comment

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

Extraneous blank line.

@@ -257,6 +257,12 @@ def _getParagraphOffsets(self,offset):
return lineStart.value,lineEnd.value

def _normalizeControlField(self,attrs):

ariaCurrent = attrs.get("IAccessible2::attribute_current")
Copy link
Contributor

Choose a reason for hiding this comment

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

Please move this into the gecko_ia2 virtual buffer.

ariaCurrent = attrs.get("IAccessible2::attribute_current")
if ariaCurrent != None:
attrs['current']= ariaCurrent
del attrs["IAccessible2::attribute_current"]
Copy link
Contributor

Choose a reason for hiding this comment

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

Probably no need to delete this; we don't do it with other attributes and leaving it there might be useful for debugging.

@@ -1112,7 +1129,7 @@ def getControlFieldSpeech(attrs,ancestorAttrs,fieldType,formatConfig=None,extraD
content = attrs.get("content")
if content and speakContentFirst:
out.append(content)
out.extend(x for x in (nameText,(stateText if speakStatesFirst else roleText),(roleText if speakStatesFirst else stateText),valueText,descriptionText,levelText,keyboardShortcutText) if x)
out.extend(x for x in (nameText,(stateText if speakStatesFirst else roleText),(roleText if speakStatesFirst else stateText),ariaCurrentText,valueText,descriptionText,levelText,keyboardShortcutText) if x)
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it's possible that someone might set aria-current on a table cell; e.g. in a calendar. So, it also needs to be reported for the table cell case above this.

- ensure that aria-current is output to braille.
- make `getValueForAriaCurrent` a property called isCurrent
- use a compiled regex
- simplify `if` statement
- move text labels for 'aria-current' values to a dictionary and
  translate
- handle aria-current in list items and tables
@feerrenrut
Copy link
Contributor Author

To test this (with clickable list items, and clickable table cells) I used the following HTML file (unzip first)
aria-current-test.zip

Copy link
Contributor

@jcsteh jcsteh left a comment

Choose a reason for hiding this comment

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

Looks good! Ta!

@@ -630,9 +633,16 @@ def getBrailleTextForProperties(**propertyValues):
# Translators: Displayed in braille for a table cell column number.
# %s is replaced with the column number.
textList.append(_("c%s") % columnNumber)
ariaCurrent = propertyValues.get('current', False)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Please rename to current.

@@ -698,12 +708,16 @@ def getControlFieldBraille(info, field, ancestors, reportStart, formatConfig):
role = field.get("role", controlTypes.ROLE_UNKNOWN)
states = field.get("states", set())
value=field.get('value',None)
ariaCurrent=field.get('current', None)
Copy link
Contributor

Choose a reason for hiding this comment

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

Please rename.

@@ -613,6 +613,23 @@
REASON_ONLYCACHE="onlyCache"
#}

# Text to use for 'current' values. These describe if an item is the current item
# within a particular kind of selection.
Copy link
Contributor

Choose a reason for hiding this comment

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

Please change the comment prefix to #::

#: l1
#: l2

This means it'll be treated as the documentation of the variable by epydoc (the code doc tool).

feerrenrut added a commit that referenced this pull request Feb 23, 2017
Incubate PR #6860 to fix issue #6358
Merge branch 'i6358-supportAriaCurrent' into next
@feerrenrut feerrenrut merged commit 2fde87e into master Mar 14, 2017
@nvaccessAuto nvaccessAuto added this to the 2017.2 milestone Mar 14, 2017
feerrenrut added a commit that referenced this pull request Mar 14, 2017
For PR #6761 - Web page menu items (menu item checkbox's and radio buttons) can now be activated while in browse mode.  Issue #6735
For PR #6866 - Excel sheet name reporting is now translated. Issue #6848
For PR #6884 - Pressing ESC while the configuration profile "Confirm Deletion" prompt is active now dismisses the dialog. Issue #6851
For PR #6895 - Cell border information can now be reported in Microsoft Excel by using `NVDA+f`. Issue #3044
For PR #6860 - Added support for aria-current attributes. Issue #6358
@feerrenrut feerrenrut deleted the i6358-supportAriaCurrent branch September 21, 2017 01:31
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.

None yet

3 participants