[orca] Add some utility methods to identify WebKitGtk content embedded in Evolution



commit 22813eab93e2fa17e1cca5517cb43f86a285ff97
Author: Joanmarie Diggs <jdiggs igalia com>
Date:   Wed Jan 21 20:00:42 2015 -0500

    Add some utility methods to identify WebKitGtk content embedded in Evolution

 src/orca/scripts/apps/evolution/script.py          |    2 +-
 .../scripts/apps/evolution/script_utilities.py     |   53 +++++++++++++++++++
 src/orca/scripts/toolkits/WebKitGtk/script.py      |   54 +++-----------------
 .../scripts/toolkits/WebKitGtk/script_utilities.py |   45 ++++++++++++++++-
 .../toolkits/WebKitGtk/structural_navigation.py    |    2 +-
 5 files changed, 105 insertions(+), 51 deletions(-)
---
diff --git a/src/orca/scripts/apps/evolution/script.py b/src/orca/scripts/apps/evolution/script.py
index e2cb780..fdfef7a 100644
--- a/src/orca/scripts/apps/evolution/script.py
+++ b/src/orca/scripts/apps/evolution/script.py
@@ -53,7 +53,7 @@ class Script(WebKitGtk.Script):
         - app: the application to create a script for.
         """
 
-        WebKitGtk.Script.__init__(self, app, False)
+        super().__init__(app)
         self.presentIfInactive = False
 
     def getBrailleGenerator(self):
diff --git a/src/orca/scripts/apps/evolution/script_utilities.py 
b/src/orca/scripts/apps/evolution/script_utilities.py
index ce3e3b3..73ca81f 100644
--- a/src/orca/scripts/apps/evolution/script_utilities.py
+++ b/src/orca/scripts/apps/evolution/script_utilities.py
@@ -35,6 +35,39 @@ class Utilities(WebKitGtk.Utilities):
     def __init__(self, script):
         super().__init__(script)
 
+    def isComposeMessageBody(self, obj):
+        if not obj.getState().contains(pyatspi.STATE_EDITABLE):
+            return False
+
+        return self.isEmbeddedDocument(obj)
+
+    def isReceivedMessage(self, obj):
+        if obj.getState().contains(pyatspi.STATE_EDITABLE):
+            return False
+
+        return self.isEmbeddedDocument(obj)
+
+    def isReceivedMessageHeader(self, obj):
+        if not (obj and obj.getRole() == pyatspi.ROLE_TABLE):
+            return False
+
+        return self.isReceivedMessage(obj.parent)
+
+    def isReceivedMessageContent(self, obj):
+        if not (obj and obj.getRole() == pyatspi.ROLE_SECTION):
+            return False
+
+        return self.isReceivedMessage(obj.parent)
+
+    def findMessageBodyChild(self, root):
+        roles = [pyatspi.ROLE_DOCUMENT_FRAME, pyatspi.ROLE_DOCUMENT_WEB]
+        isDocument = lambda x: x and x.getRole() in roles
+        candidate = pyatspi.findDescendant(root, isDocument)
+        if self.isEmbeddedDocument(candidate):
+            return self.findMessageBodyChild(candidate)
+
+        return candidate
+
     def isMessageListToggleCell(self, obj):
         if self.isWebKitGtk(obj):
             return False
@@ -59,3 +92,23 @@ class Utilities(WebKitGtk.Utilities):
             return pyatspi.utils.findDescendant(obj, isTreeTable) or obj
 
         return gtk.Utilities.realActiveDescendant(self, obj)
+
+    def setCaretAtStart(self, obj):
+        if self.isReceivedMessageContent(obj):
+            obj = self.utilities.findMessageBodyChild(obj) or obj
+
+        child, index = super().setCaretAtStart(obj)
+        if child and index == -1:
+            child, index = super().setCaretAtStart(child)
+
+        return child, index
+
+    def treatAsBrowser(self, obj):
+        if not self.isEmbeddedDocument(obj):
+            return False
+
+        isSplitPane = lambda x: x and x.getRole() == pyatspi.ROLE_SPLIT_PANE
+        if pyatspi.utils.findAncestor(obj, isSplitPane):
+            return False
+
+        return True
diff --git a/src/orca/scripts/toolkits/WebKitGtk/script.py b/src/orca/scripts/toolkits/WebKitGtk/script.py
index 614436a..e36fc45 100644
--- a/src/orca/scripts/toolkits/WebKitGtk/script.py
+++ b/src/orca/scripts/toolkits/WebKitGtk/script.py
@@ -60,16 +60,15 @@ class Script(default.Script):
 
     CARET_NAVIGATION_KEYS = ['Left', 'Right', 'Up', 'Down', 'Home', 'End']
 
-    def __init__(self, app, isBrowser=True):
+    def __init__(self, app):
         """Creates a new script for WebKitGtk applications.
 
         Arguments:
         - app: the application to create a script for.
         """
 
-        default.Script.__init__(self, app)
+        super().__init__(app)
         self._loadingDocumentContent = False
-        self._isBrowser = isBrowser
         self._lastCaretContext = None, -1
         self.sayAllOnLoadCheckButton = None
 
@@ -209,25 +208,21 @@ class Script(default.Script):
     def onDocumentReload(self, event):
         """Callback for document:reload accessibility events."""
 
-        docRoles = [pyatspi.ROLE_DOCUMENT_FRAME, pyatspi.ROLE_DOCUMENT_WEB]
-        if event.source.getRole() in docRoles:
+        if self.utilities.treatAsBrowser(event.source):
             self._loadingDocumentContent = True
 
     def onDocumentLoadComplete(self, event):
         """Callback for document:load-complete accessibility events."""
 
-        docRoles = [pyatspi.ROLE_DOCUMENT_FRAME, pyatspi.ROLE_DOCUMENT_WEB]
-        if not event.source.getRole() in docRoles:
+        if not self.utilities.treatAsBrowser(event.source):
             return
 
         self._loadingDocumentContent = False
-        if not self._isBrowser:
-            return
 
         # TODO: We need to see what happens in Epiphany on pages where focus
         # is grabbed rather than set the caret at the start. But for simple
         # content in both Yelp and Epiphany this is alright for now.
-        obj, offset = self.setCaretAtStart(event.source)
+        obj, offset = self.utilities.setCaretAtStart(event.source)
         orca.setLocusOfFocus(event, obj, False)
 
         self.updateBraille(obj)
@@ -238,8 +233,7 @@ class Script(default.Script):
     def onDocumentLoadStopped(self, event):
         """Callback for document:load-stopped accessibility events."""
 
-        docRoles = [pyatspi.ROLE_DOCUMENT_FRAME, pyatspi.ROLE_DOCUMENT_WEB]
-        if event.source.getRole() in docRoles:
+        if self.utilities.treatAsBrowser(event.source):
             self._loadingDocumentContent = False
 
     def onFocusedChanged(self, event):
@@ -288,8 +282,7 @@ class Script(default.Script):
         except:
             return
 
-        docRoles = [pyatspi.ROLE_DOCUMENT_FRAME, pyatspi.ROLE_DOCUMENT_WEB]
-        if role not in docRoles or not self._isBrowser:
+        if not self.utilities.treatAsBrowser(obj):
             return
 
         if event.detail1:
@@ -439,39 +432,6 @@ class Script(default.Script):
 
         return True
 
-    def setCaretAtStart(self, obj):
-        """Attempts to set the caret at the specified offset in obj. Because
-        this is not always possible, this method will attempt to locate the
-        first place inside of obj in which the caret can be positioned.
-
-        Arguments:
-        - obj: the accessible object in which the caret should be placed.
-
-        Returns the object and offset in which we were able to set the caret.
-        Otherwise, None if we could not find a text object, and -1 if we were
-        not able to set the caret.
-        """
-
-        def implementsText(obj):
-            if obj.getRole() == pyatspi.ROLE_LIST:
-                return False
-            return 'Text' in utils.listInterfaces(obj)
-
-        child = obj
-        if not implementsText(obj):
-            child = utils.findDescendant(obj, implementsText)
-            if not child:
-                return None, -1
-
-        index = -1
-        text = child.queryText()
-        for i in range(text.characterCount):
-            if text.setCaretOffset(i):
-                index = i
-                break
-
-        return child, index
-
     def panBrailleLeft(self, inputEvent=None, panAmount=0):
         """In document content, we want to use the panning keys to browse the
         entire document.
diff --git a/src/orca/scripts/toolkits/WebKitGtk/script_utilities.py 
b/src/orca/scripts/toolkits/WebKitGtk/script_utilities.py
index 74cb47c..8e2e192 100644
--- a/src/orca/scripts/toolkits/WebKitGtk/script_utilities.py
+++ b/src/orca/scripts/toolkits/WebKitGtk/script_utilities.py
@@ -47,8 +47,7 @@ class Utilities(script_utilities.Utilities):
         Arguments:
         - script: the script with which this instance is associated.
         """
-
-        script_utilities.Utilities.__init__(self, script)
+        super().__init__(script)
 
     def isWebKitGtk(self, obj):
         """Returns True if this object is a WebKitGtk object."""
@@ -232,3 +231,45 @@ class Utilities(script_utilities.Utilities):
             return self.onSameLine(obj[0], obj[1])
 
         return False
+
+    def isEmbeddedDocument(self, obj):
+        if not self.isWebKitGtk(obj):
+            return False
+
+        docRoles = [pyatspi.ROLE_DOCUMENT_FRAME, pyatspi.ROLE_DOCUMENT_WEB]
+        if not (obj and obj.getRole() in docRoles):
+            return False
+
+        parent = obj.parent
+        if not (parent and self.isWebKitGtk(parent)):
+            return False
+
+        parent = parent.parent
+        if not (parent and not self.isWebKitGtk(parent)):
+            return False
+
+        return True
+
+    def setCaretAtStart(self, obj):
+        def implementsText(obj):
+            if obj.getRole() == pyatspi.ROLE_LIST:
+                return False
+            return 'Text' in pyatspi.utils.listInterfaces(obj)
+
+        child = obj
+        if not implementsText(obj):
+            child = pyatspi.utils.findDescendant(obj, implementsText)
+            if not child:
+                return None, -1
+
+        index = -1
+        text = child.queryText()
+        for i in range(text.characterCount):
+            if text.setCaretOffset(i):
+                index = i
+                break
+
+        return child, index
+
+    def treatAsBrowser(self, obj):
+        return self.isEmbeddedDocument(obj)
diff --git a/src/orca/scripts/toolkits/WebKitGtk/structural_navigation.py 
b/src/orca/scripts/toolkits/WebKitGtk/structural_navigation.py
index d11d74f..12fb2fd 100644
--- a/src/orca/scripts/toolkits/WebKitGtk/structural_navigation.py
+++ b/src/orca/scripts/toolkits/WebKitGtk/structural_navigation.py
@@ -82,7 +82,7 @@ class StructuralNavigation(structural_navigation.StructuralNavigation):
         """
 
         if characterOffset == 0:
-            child, offset = self._script.setCaretAtStart(obj)
+            child, offset = self._script.utilities.setCaretAtStart(obj)
 
             if child and child.getRole() == pyatspi.ROLE_LIST_ITEM:
                 for c in child:


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