[orca] Fix for bgo bug #530784



commit 8fbe2b043fadf882f1d9b70b76bab9faebf246c8
Author: Joanmarie Diggs <joanmarie diggs gmail com>
Date:   Sun May 24 16:38:21 2009 -0400

    Fix for bgo bug #530784
    
    Fix for bug #530784 - whereAmI info for list items in web content
    needs to be improved.
---
 ChangeLog                                          |    9 ++
 src/orca/scripts/toolkits/Gecko/where_am_i.py      |   17 +++
 src/orca/where_am_I.py                             |   29 ++++-
 test/html/lists2.html                              |   19 +++
 .../firefox/html_role_list_item_where_am_i.py      |  139 ++++++++++++++++++++
 5 files changed, 207 insertions(+), 6 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 2d94a3b..6175fc9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2009-05-24  Joanmarie Diggs <joanmarie diggs gmail com>
 
+        * src/orca/scripts/toolkits/Gecko/where_am_i.py:
+          src/orca/where_am_I.py:
+          test/html/lists2.html: (new)
+          test/keystrokes/firefox/html_role_list_item_where_am_i.py: (new)
+          Fix for bug #530784 - whereAmI info for list items in web content
+          needs to be improved.
+
+2009-05-24  Joanmarie Diggs <joanmarie diggs gmail com>
+
         * src/orca/scripts/apps/ekiga.py:
           Fix for bug #511468 - Ekiga chat window accessibility problem.
 
diff --git a/src/orca/scripts/toolkits/Gecko/where_am_i.py b/src/orca/scripts/toolkits/Gecko/where_am_i.py
index 5da20d7..3485a15 100644
--- a/src/orca/scripts/toolkits/Gecko/where_am_i.py
+++ b/src/orca/scripts/toolkits/Gecko/where_am_i.py
@@ -103,6 +103,23 @@ class GeckoWhereAmI(where_am_I.WhereAmI):
 
         return where_am_I.WhereAmI._getSpeechForRoleName(self, obj, role)
 
+    def _getObjName(self, obj):
+        """Returns the name to speak for an object.
+        """
+
+        text = ""
+        name = self._script.getDisplayedText(obj)
+        if not name:
+            name = obj.description
+            if not name and obj.getRole() == pyatspi.ROLE_LIST_ITEM:
+                name = self._script.expandEOCs(obj)
+
+        if name and name != "None":
+            text = name.strip()
+        debug.println(self._debugLevel, "%s name=<%s>" % (obj.getRole(), text))
+
+        return text
+
     def _speakObjDescription(self, obj):
         """Speaks the object's description if it is not the same as the
         object's name or label. Overridden here because Gecko tacks on
diff --git a/src/orca/where_am_I.py b/src/orca/where_am_I.py
index 1eefad8..cacb82e 100644
--- a/src/orca/where_am_I.py
+++ b/src/orca/where_am_I.py
@@ -512,10 +512,11 @@ class WhereAmI:
         Gaim, gedit, OpenOffice Writer and Terminal
         """
 
-        cell = self._script.getAncestor(obj,
-                                        [pyatspi.ROLE_TABLE_CELL],
-                                        [pyatspi.ROLE_FRAME])
-        if cell and not self._script.isLayoutOnly(cell.parent):
+        ancestor = self._script.getAncestor(obj,
+                                            [pyatspi.ROLE_TABLE_CELL,
+                                             pyatspi.ROLE_LIST_ITEM],
+                                            [pyatspi.ROLE_FRAME])
+        if ancestor and not self._script.isLayoutOnly(ancestor.parent):
             # [[[TODO: WDW - we handle ROLE_ENTRY specially here because
             # there is a bug in getRealActiveDescendant: it doesn't dive
             # deep enough into the hierarchy (see comment #12 of bug
@@ -523,8 +524,11 @@ class WhereAmI:
             # more comfortable with mucking around with
             # getRealActiveDescendant.]]]
             #
-            if obj.getRole() != pyatspi.ROLE_ENTRY:
-                return self._speakTableCell(cell, basicOnly)
+            if ancestor.getRole() == pyatspi.ROLE_TABLE_CELL:
+                if obj.getRole() != pyatspi.ROLE_ENTRY:
+                    return self._speakTableCell(ancestor, basicOnly)
+            else:
+                return self._speakListItem(ancestor, basicOnly)
 
         utterances = []
         text = self._getObjLabel(obj)
@@ -747,6 +751,19 @@ class WhereAmI:
             # view (i.e., how many ancestors a node has).
             #
             utterances.append(_("tree level %d") % (level + 1))
+        else:
+            nestingLevel = 0
+            parent = obj.parent
+            while parent.parent.getRole() == pyatspi.ROLE_LIST:
+                nestingLevel += 1
+                parent = parent.parent
+            if nestingLevel:
+                # Translators: this represents a list item in a document.
+                # The nesting level is how 'deep' the item is (e.g., a
+                # level of 2 represents a list item inside a list that's
+                # inside another list).
+                #
+                utterances.append(_("Nesting level %d") % nestingLevel)
 
         getTutorial = self._script.tutorialGenerator.getTutorial
         utterances.extend(getTutorial(obj, False, forceMessage=True))
diff --git a/test/html/lists2.html b/test/html/lists2.html
new file mode 100644
index 0000000..46ac130
--- /dev/null
+++ b/test/html/lists2.html
@@ -0,0 +1,19 @@
+<html>
+<head>
+<title>Lists test</title>
+</head>
+<body>
+<ul>
+<li>Not in a paragraph</li>
+<li><p>In a paragraph</p></li>
+<li><div>In a section</div></li>
+<ol>
+   <li>A nested list item, not in a paragraph</li>
+   <li><p>A nested list item, in a paragraph</p></li>
+   <li><div>A nested list item, in a section</div></li>
+</ol>
+<li><div><p>In a paragraph that's in a section</p></div></li>
+</ul>
+</body>
+</html>
+
diff --git a/test/keystrokes/firefox/html_role_list_item_where_am_i.py b/test/keystrokes/firefox/html_role_list_item_where_am_i.py
new file mode 100644
index 0000000..e60f244
--- /dev/null
+++ b/test/keystrokes/firefox/html_role_list_item_where_am_i.py
@@ -0,0 +1,139 @@
+# -*- coding: utf-8 -*-
+#!/usr/bin/python
+
+"""Test of HTML list output of Firefox, in particular where am I.
+"""
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+########################################################################
+# We wait for the focus to be on a blank Firefox window.
+#
+sequence.append(WaitForWindowActivate(utils.firefoxFrameNames, None))
+
+########################################################################
+# Load the local lists test case.
+#
+sequence.append(KeyComboAction("<Control>l"))
+sequence.append(WaitForFocus(acc_role=pyatspi.ROLE_ENTRY))
+
+sequence.append(TypeAction(utils.htmlURLPrefix + "lists2.html"))
+sequence.append(KeyComboAction("Return"))
+
+sequence.append(WaitForDocLoad())
+sequence.append(WaitForFocus("Lists Test",
+                             acc_role=pyatspi.ROLE_DOCUMENT_FRAME))
+
+########################################################################
+# Press Control+Home to move to the top.
+#
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("<Control>Home"))
+sequence.append(utils.AssertPresentationAction(
+    "Top of file",
+    ["BRAILLE LINE:  'â?¢ Not in a paragraph'",
+     "     VISIBLE:  'â?¢ Not in a paragraph', cursor=1",
+     "SPEECH OUTPUT: 'â?¢ Not in a paragraph'"]))
+
+########################################################################
+# Press Down Arrow to move through the lists doing a where am I for each
+# list item.
+#
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("KP_Enter"))
+sequence.append(PauseAction(3000))
+sequence.append(utils.AssertPresentationAction(
+    "1. Basic Where Am I",
+    ["BRAILLE LINE:  'â?¢ In a paragraph'",
+     "     VISIBLE:  'â?¢ In a paragraph', cursor=1",
+     "SPEECH OUTPUT: 'list item'",
+     "SPEECH OUTPUT: 'â?¢ In a paragraph'",
+     "SPEECH OUTPUT: 'item 2 of 4'"]))
+
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("KP_Enter"))
+sequence.append(PauseAction(3000))
+sequence.append(utils.AssertPresentationAction(
+    "2. Basic Where Am I",
+    ["BRAILLE LINE:  'â?¢ In a section'",
+     "     VISIBLE:  'â?¢ In a section', cursor=1",
+     "SPEECH OUTPUT: 'list item'",
+     "SPEECH OUTPUT: 'â?¢ In a section'",
+     "SPEECH OUTPUT: 'item 3 of 4'"]))
+
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("KP_Enter"))
+sequence.append(PauseAction(3000))
+sequence.append(utils.AssertPresentationAction(
+    "3. Basic Where Am I",
+    ["BRAILLE LINE:  '1. A nested list item, not in a paragraph'",
+     "     VISIBLE:  '1. A nested list item, not in a ', cursor=1",
+     "SPEECH OUTPUT: 'list item'",
+     "SPEECH OUTPUT: '1. A nested list item, not in a paragraph'",
+     "SPEECH OUTPUT: 'item 1 of 3'",
+     "SPEECH OUTPUT: 'Nesting level 1'"]))
+
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("KP_Enter"))
+sequence.append(PauseAction(3000))
+sequence.append(utils.AssertPresentationAction(
+    "4. Basic Where Am I",
+    ["BRAILLE LINE:  '2. A nested list item, in a paragraph'",
+     "     VISIBLE:  '2. A nested list item, in a para', cursor=1",
+     "SPEECH OUTPUT: 'list item'",
+     "SPEECH OUTPUT: '2. A nested list item, in a paragraph'",
+     "SPEECH OUTPUT: 'item 2 of 3'",
+     "SPEECH OUTPUT: 'Nesting level 1'"]))
+
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("KP_Enter"))
+sequence.append(PauseAction(3000))
+sequence.append(utils.AssertPresentationAction(
+    "5. Basic Where Am I",
+    ["BRAILLE LINE:  '3. A nested list item, in a section'",
+     "     VISIBLE:  '3. A nested list item, in a sect', cursor=1",
+     "SPEECH OUTPUT: 'list item'",
+     "SPEECH OUTPUT: '3. A nested list item, in a section'",
+     "SPEECH OUTPUT: 'item 3 of 3'",
+     "SPEECH OUTPUT: 'Nesting level 1'"]))
+
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("KP_Enter"))
+sequence.append(PauseAction(3000))
+sequence.append(utils.AssertPresentationAction(
+    "6. Basic Where Am I",
+    ["BRAILLE LINE:  'â?¢ In a paragraph that's in a section'",
+     "     VISIBLE:  'â?¢ In a paragraph that's in a sec', cursor=1",
+     "SPEECH OUTPUT: 'list item'",
+     "SPEECH OUTPUT: 'â?¢ In a paragraph that's in a section'",
+     "SPEECH OUTPUT: 'item 4 of 4'"]))
+
+########################################################################
+# Move to the location bar by pressing Control+L.  When it has focus
+# type "about:blank" and press Return to restore the browser to the
+# conditions at the test's start.
+#
+sequence.append(KeyComboAction("<Control>l", 1000))
+sequence.append(WaitForFocus(acc_role=pyatspi.ROLE_ENTRY))
+
+sequence.append(TypeAction("about:blank"))
+sequence.append(KeyComboAction("Return"))
+
+sequence.append(WaitForDocLoad())
+
+# Just a little extra wait to let some events get through.
+#
+sequence.append(PauseAction(3000))
+
+sequence.append(utils.AssertionSummaryAction())
+
+sequence.start()



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