[orca] Present the full name for off-screen links



commit 971170697d9b6ffa8c8545a8db0ea4a4c92f9886
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Mon Apr 22 23:57:58 2019 -0400

    Present the full name for off-screen links
    
    Some web publishers (e.g. Amazon) put off-screen links in their content
    and keep them off-screen for screen reader users to find. Unfortunately,
    when we ask for the text of these links by line, Gecko gives us a single
    word at a time. In addition, when we try to work around this by using the
    character extents, we get the same results. The safest thing to do for
    these things is return the accessible name as the line content so users
    don't have to press Down Arrow a zillion times to get past it.

 src/orca/scripts/web/script_utilities.py | 39 +++++++++++++++++++++++++++-----
 1 file changed, 33 insertions(+), 6 deletions(-)
---
diff --git a/src/orca/scripts/web/script_utilities.py b/src/orca/scripts/web/script_utilities.py
index 3c3e8a324..78b04dbec 100644
--- a/src/orca/scripts/web/script_utilities.py
+++ b/src/orca/scripts/web/script_utilities.py
@@ -69,6 +69,7 @@ class Utilities(script_utilities.Utilities):
         self._isFocusableWithMathChild = {}
         self._mathNestingLevel = {}
         self._isOffScreenLabel = {}
+        self._isOffScreenLink = {}
         self._hasExplicitName = {}
         self._hasNoSize = {}
         self._hasLongDesc = {}
@@ -140,6 +141,7 @@ class Utilities(script_utilities.Utilities):
         self._isFocusableWithMathChild = {}
         self._mathNestingLevel = {}
         self._isOffScreenLabel = {}
+        self._isOffScreenLink = {}
         self._hasExplicitName = {}
         self._hasNoSize = {}
         self._hasLongDesc = {}
@@ -1165,12 +1167,18 @@ class Utilities(script_utilities.Utilities):
         if not obj:
             return []
 
-        if boundary == pyatspi.TEXT_BOUNDARY_LINE_START and self.isMath(obj):
-            if self.isMathTopLevel(obj):
-                math = obj
-            else:
-                math = self.getMathAncestor(obj)
-            return [[math, 0, 1, '']]
+        if boundary == pyatspi.TEXT_BOUNDARY_LINE_START:
+            if self.isMath(obj):
+                if self.isMathTopLevel(obj):
+                    math = obj
+                else:
+                    math = self.getMathAncestor(obj)
+                return [[math, 0, 1, '']]
+
+            if self.isOffScreenLink(obj) and self.queryNonEmptyText(obj) and obj.name:
+                msg = "WEB: Returning name as contents for %s (is off-screen)" % obj
+                debug.println(debug.LEVEL_INFO, msg, True)
+                return [[obj, 0, len(obj.name), obj.name]]
 
         role = obj.getRole()
         if role == pyatspi.ROLE_INTERNAL_FRAME and obj.childCount == 1:
@@ -2401,6 +2409,25 @@ class Utilities(script_utilities.Utilities):
         self._isLayoutOnly[hash(obj)] = rv
         return rv
 
+    def isOffScreenLink(self, obj):
+        if not (obj and self.inDocumentContent(obj)):
+            return False
+
+        rv = self._isOffScreenLink.get(hash(obj))
+        if rv is not None:
+            return rv
+
+        rv = False
+        if self.isLink(obj):
+            x, y, width, height = self.getExtents(obj, 0, -1)
+            if x < 0 or y < 0:
+                msg = "WEB: %s is off-screen link (%i, %i)" % (obj, x, y)
+                debug.println(debug.LEVEL_INFO, msg, True)
+                rv = True
+
+        self._isOffScreenLink[hash(obj)] = rv
+        return rv
+
     def isOffScreenLabel(self, obj):
         if not (obj and self.inDocumentContent(obj)):
             return False


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