[orca] Add support for aria-errormessage



commit e98f123504e379fe932180fea52524c678f46cc9
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Thu Aug 3 11:05:01 2017 -0400

    Add support for aria-errormessage

 src/orca/generator.py                    |   13 +++++--
 src/orca/script_utilities.py             |    6 +++
 src/orca/scripts/web/script_utilities.py |   56 ++++++++++++++++++++++++++++++
 3 files changed, 72 insertions(+), 3 deletions(-)
---
diff --git a/src/orca/generator.py b/src/orca/generator.py
index 97a4980..4caada4 100644
--- a/src/orca/generator.py
+++ b/src/orca/generator.py
@@ -487,11 +487,18 @@ class Generator:
         indicators = self._script.formatting.getString(**args)
 
         if error == 'spelling':
-            result.append(indicators[1])
+            indicator = indicators[1]
         elif error == 'grammar':
-            result.append(indicators[2])
+            indicator = indicators[2]
         else:
-            result.append(indicators[0])
+            indicator = indicators[0]
+
+        errorMessage = self._script.utilities.getErrorMessage(obj)
+        if errorMessage:
+            result.append("%s: %s" % (indicator, errorMessage))
+        else:
+            result.append(indicator)
+
         return result
 
     def _generateRequired(self, obj, **args):
diff --git a/src/orca/script_utilities.py b/src/orca/script_utilities.py
index 4f0db51..b9d5918 100644
--- a/src/orca/script_utilities.py
+++ b/src/orca/script_utilities.py
@@ -2525,6 +2525,12 @@ class Utilities:
     def getError(self, obj):
         return obj.getState().contains(pyatspi.STATE_INVALID_ENTRY)
 
+    def getErrorMessage(self, obj):
+        return ""
+
+    def isErrorMessage(self, obj):
+        return False
+
     def getCharacterAtOffset(self, obj, offset=None):
         text = self.queryNonEmptyText(obj)
         if text:
diff --git a/src/orca/scripts/web/script_utilities.py b/src/orca/scripts/web/script_utilities.py
index cb01369..9731258 100644
--- a/src/orca/scripts/web/script_utilities.py
+++ b/src/orca/scripts/web/script_utilities.py
@@ -75,6 +75,7 @@ class Utilities(script_utilities.Utilities):
         self._isAnchor = {}
         self._isEditableComboBox = {}
         self._isEditableDescendantOfComboBox = {}
+        self._isErrorMessage = {}
         self._isLandmark = {}
         self._isLiveRegion = {}
         self._isLink = {}
@@ -137,6 +138,7 @@ class Utilities(script_utilities.Utilities):
         self._isAnchor = {}
         self._isEditableComboBox = {}
         self._isEditableDescendantOfComboBox = {}
+        self._isErrorMessage = {}
         self._isLandmark = {}
         self._isLiveRegion = {}
         self._isLink = {}
@@ -2059,6 +2061,7 @@ class Utilities(script_utilities.Utilities):
                or self.isHidden(obj) \
                or self.isOffScreenLabel(obj) \
                or self.isUselessImage(obj) \
+               or self.isErrorForContents(obj, contents) \
                or self.isLabellingContents(obj, contents):
                 rv = False
 
@@ -2561,6 +2564,26 @@ class Utilities(script_utilities.Utilities):
     def isDPubToc(self, obj):
         return 'doc-toc' in self._getXMLRoles(obj)
 
+    def isErrorMessage(self, obj):
+        if not (obj and self.inDocumentContent(obj)):
+            return super().isErrorMessage(obj)
+
+        rv = self._isErrorMessage.get(hash(obj))
+        if rv is not None:
+            return rv
+
+        # Remove this when we bump dependencies to 2.26
+        try:
+            relationType = pyatspi.RELATION_ERROR_FOR
+        except:
+            rv = False
+        else:
+            isMessage = lambda r: r.getRelationType() == relationType
+            rv = bool(list(filter(isMessage, obj.getRelationSet())))
+
+        self._isErrorMessage[hash(obj)] = rv
+        return rv
+
     def isFeed(self, obj):
         return 'feed' in self._getXMLRoles(obj)
 
@@ -3169,6 +3192,39 @@ class Utilities(script_utilities.Utilities):
 
         return error
 
+    def _getErrorMessageContainer(self, obj):
+        if not (obj and self.inDocumentContent(obj)):
+            return None
+
+        if not self.getError(obj):
+            return None
+
+        # Remove this when we bump dependencies to 2.26
+        try:
+            relationType = pyatspi.RELATION_ERROR_MESSAGE
+        except:
+            return None
+
+        isMessage = lambda r: r.getRelationType() == relationType
+        relations = list(filter(isMessage, obj.getRelationSet()))
+        if not relations:
+            return None
+
+        return relations[0].getTarget(0)
+
+    def getErrorMessage(self, obj):
+        return self.expandEOCs(self._getErrorMessageContainer(obj))
+
+    def isErrorForContents(self, obj, contents=[]):
+        if not self.isErrorMessage(obj):
+            return False
+
+        for acc, start, end, string in contents:
+            if self._getErrorMessageContainer(acc) == obj:
+                return True
+
+        return False
+
     def hasNoSize(self, obj):
         if not (obj and self.inDocumentContent(obj)):
             return super().hasNoSize(obj)


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