[orca] Add more logic for fragments, and more verbose debugging



commit d44fa18668da49452f21ec648b5b0b33e6d94fd3
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Tue Nov 24 18:24:23 2015 -0500

    Add more logic for fragments, and more verbose debugging

 src/orca/scripts/web/script.py           |   56 +++++++++++++++++++-----------
 src/orca/scripts/web/script_utilities.py |   28 +++++++++++++++
 2 files changed, 64 insertions(+), 20 deletions(-)
---
diff --git a/src/orca/scripts/web/script.py b/src/orca/scripts/web/script.py
index 1de15ad..b8499de 100644
--- a/src/orca/scripts/web/script.py
+++ b/src/orca/scripts/web/script.py
@@ -1435,32 +1435,48 @@ class Script(default.Script):
             debug.println(debug.LEVEL_INFO, msg)
             return True
 
-        if role in [pyatspi.ROLE_DOCUMENT_FRAME, pyatspi.ROLE_DOCUMENT_WEB]:
-            obj, offset = self.utilities.getCaretContext(event.source)
-            if obj and self.utilities.isZombie(obj):
-                msg = "WEB: Clearing context - obj is zombie"
-                debug.println(debug.LEVEL_INFO, msg)
-                self.utilities.clearCaretContext()
-                obj, offset = self.utilities.getCaretContext(event.source)
-
-            if obj:
-                wasFocused = obj.getState().contains(pyatspi.STATE_FOCUSED)
-                obj.clearCache()
-                isFocused = obj.getState().contains(pyatspi.STATE_FOCUSED)
-                if wasFocused == isFocused \
-                   and not (self.utilities.isLink(obj) and not isFocused):
-                    msg = "WEB: Event handled: Setting locusOfFocus to context"
-                    debug.println(debug.LEVEL_INFO, msg)
-                    orca.setLocusOfFocus(event, obj)
-                    return True
-
         if not state.contains(pyatspi.STATE_FOCUSABLE) \
            and not state.contains(pyatspi.STATE_FOCUSED):
             msg = "WEB: Event ignored: Source is not focusable or focused"
             debug.println(debug.LEVEL_INFO, msg)
             return True
 
-        return False
+        if not role in [pyatspi.ROLE_DOCUMENT_FRAME, pyatspi.ROLE_DOCUMENT_WEB]:
+            msg = "WEB: Deferring to other scripts for handling non-document source"
+            debug.println(debug.LEVEL_INFO, msg)
+            return False
+
+        obj, offset = self.utilities.getCaretContext(event.source)
+        if obj and self.utilities.isZombie(obj):
+            msg = "WEB: Clearing context - obj is zombie"
+            debug.println(debug.LEVEL_INFO, msg)
+            self.utilities.clearCaretContext()
+            obj, offset = self.utilities.getCaretContext(event.source)
+
+        if not obj:
+            msg = "WEB: Unable to get non-null, non-zombie context object"
+            debug.println(debug.LEVEL_INFO, msg)
+            return False
+
+        wasFocused = obj.getState().contains(pyatspi.STATE_FOCUSED)
+        obj.clearCache()
+        isFocused = obj.getState().contains(pyatspi.STATE_FOCUSED)
+        if wasFocused != isFocused:
+            msg = "WEB: Focused state of %s changed to %s" % (obj, isFocused)
+            debug.println(debug.LEVEL_INFO, msg)
+            return False
+
+        if not (self.utilities.isLink(obj) and not isFocused):
+            cause = "Context is not a non-focused link"
+        elif self.utilities.isChildOfCurrentFragment(obj):
+            cause = "Context is child of current fragment"
+        else:
+            return False
+
+        msg = "WEB: Event handled: Setting locusOfFocus to %s (%s)" % (obj, cause)
+        debug.println(debug.LEVEL_INFO, msg)
+        orca.setLocusOfFocus(event, obj)
+        return True
 
     def onMouseButton(self, event):
         """Callback for mouse:button accessibility events."""
diff --git a/src/orca/scripts/web/script_utilities.py b/src/orca/scripts/web/script_utilities.py
index b40315f..82c082d 100644
--- a/src/orca/scripts/web/script_utilities.py
+++ b/src/orca/scripts/web/script_utilities.py
@@ -59,6 +59,7 @@ class Utilities(script_utilities.Utilities):
         self._hasNoSize = {}
         self._hasLongDesc = {}
         self._hasUselessCanvasDescendant = {}
+        self._id = {}
         self._isClickableElement = {}
         self._isAnchor = {}
         self._isLandmark = {}
@@ -104,6 +105,7 @@ class Utilities(script_utilities.Utilities):
         self._hasNoSize = {}
         self._hasLongDesc = {}
         self._hasUselessCanvasDescendant = {}
+        self._id = {}
         self._isClickableElement = {}
         self._isAnchor = {}
         self._isLandmark = {}
@@ -362,6 +364,19 @@ class Utilities(script_utilities.Utilities):
         self._roleDescription[hash(obj)] = rv
         return rv
 
+    def _getID(self, obj):
+        if hash(obj) in self._id:
+            return self._id.get(hash(obj))
+
+        try:
+            attrs = dict([attr.split(':', 1) for attr in obj.getAttributes()])
+        except:
+            return None
+
+        rv = attrs.get('id')
+        self._id[hash(obj)] = rv
+        return rv
+
     def _getTag(self, obj):
         rv = self._tag.get(hash(obj))
         if rv is not None:
@@ -2390,8 +2405,21 @@ class Utilities(script_utilities.Utilities):
         if linkURI == docURI:
             return True
 
+        sourceID = self._getID(event.source)
+        if sourceID:
+            parseResult = urllib.parse.urlparse(docURI)
+            return parseResult.fragment == sourceID
+
         return False
 
+    def isChildOfCurrentFragment(self, obj):
+        parseResult = urllib.parse.urlparse(self.documentFrameURI())
+        if not parseResult.fragment:
+            return False
+
+        isSameFragment = lambda x: self._getID(x) == parseResult.fragment
+        return pyatspi.findAncestor(obj, isSameFragment) is not None
+
     @staticmethod
     def getHyperlinkRange(obj):
         try:


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