[orca] Web: Identify and work around mismatched text, hypertext implementations



commit cf482b38cce7a84bb14514f7efc0b0a208a627f7
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Fri Sep 3 19:30:09 2021 +0200

    Web: Identify and work around mismatched text, hypertext implementations
    
    The value of hyperlink.startIndex should match the offset in the text
    implementation's character offset for the associated child object.
    When this fails, due to a bug in the browser implementation, we can
    get stuck/loop. Therefore, check for this mismatch, spew out plenty
    of debugging details, and try to recover by using the hyperlink's
    reported range instead of a character offset when we've gotten stuck
    on a line.

 src/orca/script_utilities.py             |  6 ++++++
 src/orca/scripts/web/script_utilities.py | 34 ++++++++++++++++++++++++++------
 2 files changed, 34 insertions(+), 6 deletions(-)
---
diff --git a/src/orca/script_utilities.py b/src/orca/script_utilities.py
index 367ebfb1f..219231ebf 100644
--- a/src/orca/script_utilities.py
+++ b/src/orca/script_utilities.py
@@ -2813,6 +2813,12 @@ class Utilities:
         child = hyperlink.getObject(0)
         msg = "INFO: Hyperlink object at index %i for %s is %s" % (index, obj, child)
         debug.println(debug.LEVEL_INFO, msg, True)
+
+        if offset != hyperlink.startIndex:
+            msg = "ERROR: The hyperlink start index (%i) should match the offset (%i)" \
+                % (hyperlink.startIndex, offset)
+            debug.println(debug.LEVEL_INFO, msg, True)
+
         return child
 
     def characterOffsetInParent(self, obj):
diff --git a/src/orca/scripts/web/script_utilities.py b/src/orca/scripts/web/script_utilities.py
index 2c24cf857..d7631b581 100644
--- a/src/orca/scripts/web/script_utilities.py
+++ b/src/orca/scripts/web/script_utilities.py
@@ -725,9 +725,6 @@ class Utilities(script_utilities.Utilities):
             obj, offset = self.getCaretContext()
 
         nextobj, nextoffset = self.findNextCaretInOrder(obj, offset)
-        if (obj, offset) == (nextobj, nextoffset):
-            nextobj, nextoffset = self.findNextCaretInOrder(nextobj, nextoffset)
-
         if skipSpace:
             text = self.queryNonEmptyText(nextobj)
             while text and text.getText(nextoffset, nextoffset + 1) in [" ", "\xa0"]:
@@ -741,9 +738,6 @@ class Utilities(script_utilities.Utilities):
             obj, offset = self.getCaretContext()
 
         prevobj, prevoffset = self.findPreviousCaretInOrder(obj, offset)
-        if (obj, offset) == (prevobj, prevoffset):
-            prevobj, prevoffset = self.findPreviousCaretInOrder(prevobj, prevoffset)
-
         if skipSpace:
             text = self.queryNonEmptyText(prevobj)
             while text and text.getText(prevoffset, prevoffset + 1) in [" ", "\xa0"]:
@@ -1920,6 +1914,16 @@ class Utilities(script_utilities.Utilities):
             debug.println(debug.LEVEL_INFO, msg, True)
             contents = self.getLineContentsAtOffset(obj, offset, layoutMode, useCache)
 
+        if line == contents:
+            start, end = self.getHyperlinkRange(obj)
+            msg = "WEB: Got same line. %s has range in %s of %i-%i" % (obj, obj.parent, start, end)
+            debug.println(debug.LEVEL_INFO, msg, True)
+            if start >= 0:
+                obj, offset = self.previousContext(obj.parent, start, True)
+                msg = "WEB: Trying again with %s, %i" % (obj, offset)
+                debug.println(debug.LEVEL_INFO, msg, True)
+                contents = self.getLineContentsAtOffset(obj, offset, layoutMode, useCache)
+
         return contents
 
     def getNextLineContents(self, obj=None, offset=-1, layoutMode=None, useCache=True):
@@ -1969,6 +1973,16 @@ class Utilities(script_utilities.Utilities):
             debug.println(debug.LEVEL_INFO, msg, True)
             contents = self.getLineContentsAtOffset(obj, offset, layoutMode, useCache)
 
+        if line == contents:
+            start, end = self.getHyperlinkRange(obj)
+            msg = "WEB: Got same line. %s has range in %s of %i-%i" % (obj, obj.parent, start, end)
+            debug.println(debug.LEVEL_INFO, msg, True)
+            if end >= 0:
+                obj, offset = self.nextContext(obj.parent, end, True)
+                msg = "WEB: Trying again with %s, %i" % (obj, offset)
+                debug.println(debug.LEVEL_INFO, msg, True)
+                contents = self.getLineContentsAtOffset(obj, offset, layoutMode, useCache)
+
         if not contents:
             msg = "WEB: Could not get line contents for %s, %i" % (obj, offset)
             debug.println(debug.LEVEL_INFO, msg, True)
@@ -5100,6 +5114,10 @@ class Utilities(script_utilities.Utilities):
                 allText = text.getText(0, -1)
                 for i in range(offset + 1, len(allText)):
                     child = self.getChildAtOffset(obj, i)
+                    if child and allText[i] != self.EMBEDDED_OBJECT_CHARACTER:
+                        msg = "ERROR: Child %s found at offset with char '%s'" % \
+                            (child, allText[i].replace("\n", "\\n"))
+                        debug.println(debug.LEVEL_INFO, msg, True)
                     if self._canHaveCaretContext(child):
                         if self._treatObjectAsWhole(child, -1):
                             return child, 0
@@ -5165,6 +5183,10 @@ class Utilities(script_utilities.Utilities):
                     offset = len(allText)
                 for i in range(offset - 1, -1, -1):
                     child = self.getChildAtOffset(obj, i)
+                    if child and allText[i] != self.EMBEDDED_OBJECT_CHARACTER:
+                        msg = "ERROR: Child %s found at offset with char '%s'" % \
+                            (child, allText[i].replace("\n", "\\n"))
+                        debug.println(debug.LEVEL_INFO, msg, True)
                     if self._canHaveCaretContext(child):
                         if self._treatObjectAsWhole(child, -1):
                             return child, 0


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