[orca] Localize and use ARIA landmark role names



commit c5b5cadfdca0fec102285cfaaa634693f993a9f0
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Sat Aug 6 16:09:57 2016 -0400

    Localize and use ARIA landmark role names

 src/orca/braille_generator.py            |   20 +++++++++++-
 src/orca/object_properties.py            |   52 ++++++++++++++++++++++++++++++
 src/orca/script_utilities.py             |   24 ++++++++++++++
 src/orca/scripts/web/script_utilities.py |   47 ++++++++++++++++++++++++---
 src/orca/speech_generator.py             |   18 ++++++++++
 src/orca/structural_navigation.py        |    4 +-
 6 files changed, 157 insertions(+), 8 deletions(-)
---
diff --git a/src/orca/braille_generator.py b/src/orca/braille_generator.py
index e86cb2b..3a4fc8c 100644
--- a/src/orca/braille_generator.py
+++ b/src/orca/braille_generator.py
@@ -177,12 +177,30 @@ class BrailleGenerator(generator.Generator):
             if rv:
                 return rv
 
-        if not isinstance(role, pyatspi.Role):
+        if not isinstance(role, (pyatspi.Role, Atspi.Role)):
             try:
                 return obj.getLocalizedRoleName()
             except:
                 return ''
 
+        if self._script.utilities.isLandmark(obj):
+            if self._script.utilities.isLandmarkBanner(obj):
+                return object_properties.ROLE_LANDMARK_BANNER
+            if self._script.utilities.isLandmarkComplementary(obj):
+                return object_properties.ROLE_LANDMARK_COMPLEMENTARY
+            if self._script.utilities.isLandmarkContentInfo(obj):
+                return object_properties.ROLE_LANDMARK_CONTENTINFO
+            if self._script.utilities.isLandmarkMain(obj):
+                return object_properties.ROLE_LANDMARK_MAIN
+            if self._script.utilities.isLandmarkNavigation(obj):
+                return object_properties.ROLE_LANDMARK_NAVIGATION
+            if self._script.utilities.isLandmarkRegion(obj):
+                return object_properties.ROLE_LANDMARK_REGION
+            if self._script.utilities.isLandmarkSearch(obj):
+                return object_properties.ROLE_LANDMARK_SEARCH
+            if self._script.utilities.isLandmarkForm(obj):
+                role = pyatspi.ROLE_FORM
+
         if not role:
             return ''
 
diff --git a/src/orca/object_properties.py b/src/orca/object_properties.py
index a50e692..823f7ff 100644
--- a/src/orca/object_properties.py
+++ b/src/orca/object_properties.py
@@ -89,6 +89,58 @@ ROLE_ICON_PANEL = _("Icon panel")
 
 # Translators: This string should be treated as a role describing an object.
 # Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# The "banner" role is defined in the ARIA specification as "A region that
+# contains mostly site-oriented content, rather than page-specific content."
+# See https://www.w3.org/TR/wai-aria-1.1/#banner
+ROLE_LANDMARK_BANNER = C_("role", "banner")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# The "complementary" role is defined in the ARIA specification as "A supporting
+# section of the document, designed to be complementary to the main content at a
+# similar level in the DOM hierarchy, but remains meaningful when separated from
+# the main content." See https://www.w3.org/TR/wai-aria-1.1/#complementary
+ROLE_LANDMARK_COMPLEMENTARY = C_("role", "complementary content")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# The "contentinfo" role is defined in the ARIA specification as "A large
+# perceivable region that contains information about the parent document.
+# Examples of information included in this region of the page are copyrights and
+# links to privacy statements." See https://www.w3.org/TR/wai-aria-1.1/#contentinfo
+ROLE_LANDMARK_CONTENTINFO = C_("role", "information")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# The "main" role is defined in the ARIA specification as "The main content of
+# a document." See https://www.w3.org/TR/wai-aria-1.1/#main
+ROLE_LANDMARK_MAIN = C_("role", "main content")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# The "navigation" role is defined in the ARIA specification as "A collection of
+# navigational elements (usually links) for navigating the document or related
+# documents." See https://www.w3.org/TR/wai-aria-1.1/#navigation
+ROLE_LANDMARK_NAVIGATION =  C_("role", "navigation")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# The "region" role is defined in the ARIA specification as "A perceivable
+# section containing content that is relevant to a specific, author-specified
+# purpose and sufficiently important that users will likely want to be able to
+# navigate to the section easily and to have it listed in a summary of the page."
+# See https://www.w3.org/TR/wai-aria-1.1/#region
+ROLE_LANDMARK_REGION =  C_("role", "region")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
+# The "search" role is defined in the ARIA specification as "A landmark region
+# that contains a collection of items and objects that, as a whole, combine to
+# create a search facility." See https://www.w3.org/TR/wai-aria-1.1/#search
+ROLE_LANDMARK_SEARCH = C_("role", "search")
+
+# Translators: This string should be treated as a role describing an object.
+# Examples of roles include "checkbox", "radio button", "paragraph", and "link."
 # The reason for including the visited state as part of the role is to make it
 # possible for users to quickly identify if the link is associated with content
 # already read.
diff --git a/src/orca/script_utilities.py b/src/orca/script_utilities.py
index 27a27d0..4988ed0 100644
--- a/src/orca/script_utilities.py
+++ b/src/orca/script_utilities.py
@@ -687,6 +687,30 @@ class Utilities:
     def isLandmark(self, obj):
         return False
 
+    def isLandmarkBanner(self, obj):
+        return False
+
+    def isLandmarkComplementary(self, obj):
+        return False
+
+    def isLandmarkContentInfo(self, obj):
+        return False
+
+    def isLandmarkForm(self, obj):
+        return False
+
+    def isLandmarkMain(self, obj):
+        return False
+
+    def isLandmarkNavigation(self, obj):
+        return False
+
+    def isLandmarkRegion(self, obj):
+        return False
+
+    def isLandmarkSearch(self, obj):
+        return False
+
     def speakMathSymbolNames(self, obj=None):
         return False
 
diff --git a/src/orca/scripts/web/script_utilities.py b/src/orca/scripts/web/script_utilities.py
index 602656d..d7615ea 100644
--- a/src/orca/scripts/web/script_utilities.py
+++ b/src/orca/scripts/web/script_utilities.py
@@ -84,6 +84,7 @@ class Utilities(script_utilities.Utilities):
         self._shouldInferLabelFor = {}
         self._text = {}
         self._tag = {}
+        self._xmlRoles = {}
         self._treatAsDiv = {}
         self._posinset = {}
         self._setsize = {}
@@ -139,6 +140,7 @@ class Utilities(script_utilities.Utilities):
         self._shouldFilter = {}
         self._shouldInferLabelFor = {}
         self._tag = {}
+        self._xmlRoles = {}
         self._treatAsDiv = {}
         self._posinset = {}
         self._setsize = {}
@@ -466,6 +468,20 @@ class Utilities(script_utilities.Utilities):
         self._tag[hash(obj)] = rv
         return rv
 
+    def _getXMLRoles(self, obj):
+        rv = self._xmlRoles.get(hash(obj))
+        if rv is not None:
+            return rv
+
+        try:
+            attrs = dict([attr.split(':', 1) for attr in obj.getAttributes()])
+        except:
+            return None
+
+        rv = attrs.get('xml-roles', '').split()
+        self._xmlRoles[hash(obj)] = rv
+        return rv
+
     def inFindToolbar(self, obj=None):
         if not obj:
             obj = orca_state.locusOfFocus
@@ -2234,15 +2250,36 @@ class Utilities(script_utilities.Utilities):
         if obj.getRole() == pyatspi.ROLE_LANDMARK:
             rv = True
         else:
-            try:
-                attrs = dict([attr.split(':', 1) for attr in obj.getAttributes()])
-            except:
-                attrs = {}
-            rv = attrs.get('xml-roles') in self.getLandmarkTypes()
+            roles = self._getXMLRoles(obj)
+            rv = bool(list(filter(lambda x: x in self.getLandmarkTypes(), roles)))
 
         self._isLandmark[hash(obj)] = rv
         return rv
 
+    def isLandmarkBanner(self, obj):
+        return 'banner' in self._getXMLRoles(obj)
+
+    def isLandmarkComplementary(self, obj):
+        return 'complementary' in self._getXMLRoles(obj)
+
+    def isLandmarkContentInfo(self, obj):
+        return 'contentinfo' in self._getXMLRoles(obj)
+
+    def isLandmarkForm(self, obj):
+        return 'form' in self._getXMLRoles(obj)
+
+    def isLandmarkMain(self, obj):
+        return 'main' in self._getXMLRoles(obj)
+
+    def isLandmarkNavigation(self, obj):
+        return 'navigation' in self._getXMLRoles(obj)
+
+    def isLandmarkRegion(self, obj):
+        return 'region' in self._getXMLRoles(obj)
+
+    def isLandmarkSearch(self, obj):
+        return 'search' in self._getXMLRoles(obj)
+
     def isLiveRegion(self, obj):
         if not (obj and self.inDocumentContent(obj)):
             return False
diff --git a/src/orca/speech_generator.py b/src/orca/speech_generator.py
index 33f2baf..c423b5a 100644
--- a/src/orca/speech_generator.py
+++ b/src/orca/speech_generator.py
@@ -386,6 +386,24 @@ class SpeechGenerator(generator.Generator):
         if not role:
             return ''
 
+        if self._script.utilities.isLandmark(obj):
+            if self._script.utilities.isLandmarkBanner(obj):
+                return object_properties.ROLE_LANDMARK_BANNER
+            if self._script.utilities.isLandmarkComplementary(obj):
+                return object_properties.ROLE_LANDMARK_COMPLEMENTARY
+            if self._script.utilities.isLandmarkContentInfo(obj):
+                return object_properties.ROLE_LANDMARK_CONTENTINFO
+            if self._script.utilities.isLandmarkMain(obj):
+                return object_properties.ROLE_LANDMARK_MAIN
+            if self._script.utilities.isLandmarkNavigation(obj):
+                return object_properties.ROLE_LANDMARK_NAVIGATION
+            if self._script.utilities.isLandmarkRegion(obj):
+                return object_properties.ROLE_LANDMARK_REGION
+            if self._script.utilities.isLandmarkSearch(obj):
+                return object_properties.ROLE_LANDMARK_SEARCH
+            if self._script.utilities.isLandmarkForm(obj):
+                role = pyatspi.ROLE_FORM
+
         if self._script.utilities.isEditableComboBox(obj) \
            or self._script.utilities.isEditableDescendantOfComboBox(obj):
             return object_properties.ROLE_EDITABLE_COMBO_BOX
diff --git a/src/orca/structural_navigation.py b/src/orca/structural_navigation.py
index 3ed180b..dc22db8 100644
--- a/src/orca/structural_navigation.py
+++ b/src/orca/structural_navigation.py
@@ -1161,7 +1161,7 @@ class StructuralNavigation:
     def _getRoleName(self, obj):
         # Another case where we'll do this for now, and clean it up when
         # object presentation is refactored.
-        return self._script.speechGenerator.getLocalizedRoleName(obj)
+        return self._script.speechGenerator.getLocalizedRoleName(obj, obj.getRole())
 
     def _getSelectedItem(self, obj):
         # Another case where we'll do this for now, and clean it up when
@@ -2192,7 +2192,7 @@ class StructuralNavigation:
         columnHeaders.append(guilabels.SN_HEADER_ROLE)
 
         def rowData(obj):
-            return [self._getText(obj), self._getRoleName(obj)]
+            return [obj.name, self._getRoleName(obj)]
 
         return guilabels.SN_TITLE_LANDMARK, columnHeaders, rowData
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]