[orca] More work on attempting to handle the destruction of focused Gecko elements
- From: Joanmarie Diggs <joanied src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [orca] More work on attempting to handle the destruction of focused Gecko elements
- Date: Tue, 16 Sep 2014 00:37:41 +0000 (UTC)
commit d0625d91087a1110f29a1f5c5997cedb00476034
Author: Joanmarie Diggs <jdiggs igalia com>
Date: Mon Sep 15 20:35:07 2014 -0400
More work on attempting to handle the destruction of focused Gecko elements
src/orca/script_utilities.py | 36 ++++++++++----
src/orca/scripts/toolkits/Gecko/script.py | 8 ++-
.../scripts/toolkits/Gecko/script_utilities.py | 34 +++++++++++++
test/harness/runall.sh | 2 +-
...on-in-link-with-position-relative-on-focus.html | 18 +++++++
...utton_in_link_position_relative_on_focus.params | 1 +
...av_button_in_link_position_relative_on_focus.py | 51 ++++++++++++++++++++
7 files changed, 137 insertions(+), 13 deletions(-)
---
diff --git a/src/orca/script_utilities.py b/src/orca/script_utilities.py
index a6b7382..ebd8faa 100644
--- a/src/orca/script_utilities.py
+++ b/src/orca/script_utilities.py
@@ -873,6 +873,30 @@ class Utilities:
return readOnly
+ def _hasSamePath(self, obj1, obj2):
+ path1 = pyatspi.utils.getPath(obj1)
+ path2 = pyatspi.utils.getPath(obj2)
+ if len(path1) != len(path2):
+ return False
+
+ # The first item in all paths, even valid ones, is -1.
+ path1 = path1[1:]
+ path2 = path2[1:]
+
+ # If both have invalid child indices, all bets are off.
+ if path1.count(-1) and path2.count(-1):
+ return False
+
+ try:
+ index = path1.index(-1)
+ except ValueError:
+ try:
+ index = path2.index(-1)
+ except ValueError:
+ index = len(path2)
+
+ return path1[0:index] == path2[0:index]
+
def isSameObject(self, obj1, obj2):
if (obj1 == obj2):
return True
@@ -882,17 +906,9 @@ class Utilities:
try:
if (obj1.name != obj2.name) or (obj1.getRole() != obj2.getRole()):
return False
+ if self._hasSamePath(obj1, obj2):
+ return True
else:
- # If one of the objects was destroyed, the last index may be -1.
- # In addition, the extents likely will be zeroed out so the next
- # tests will fail. But if the rest of the path is the same and
- # the names are the same and the roles are the same, let's cross
- # our fingers and call them the same.
- path1 = pyatspi.utils.getPath(obj1)
- path2 = pyatspi.utils.getPath(obj2)
- if path1[0:-1] == path2[0:-1] and obj1.name == obj2.name != "":
- return True
-
# Comparing the extents of objects which claim to be different
# addresses both managed descendants and implementations which
# recreate accessibles for the same widget.
diff --git a/src/orca/scripts/toolkits/Gecko/script.py b/src/orca/scripts/toolkits/Gecko/script.py
index 038b6b0..71e9b42 100644
--- a/src/orca/scripts/toolkits/Gecko/script.py
+++ b/src/orca/scripts/toolkits/Gecko/script.py
@@ -1086,9 +1086,13 @@ class Script(default.Script):
# Gecko to kill the accessible object that we just moved to and create
# a new object to replace it. If we don't catch this, navigation breaks
# because the proverbial rug has just been pulled out from under us. :(
+ # To make matters worse, the replacement object can be in the ancestry.
obj, offset = self.getCaretContext()
- if self.utilities.isSameObject(event.any_data, obj):
- self.setCaretContext(event.any_data, offset)
+ if obj and self.utilities.isZombie(obj):
+ replicant = self.utilities.findReplicant(event.any_data, obj)
+ if replicant:
+ self.setCaretPosition(replicant, offset)
+ return
if self.handleAsLiveRegion(event):
self.liveMngr.handleEvent(event)
diff --git a/src/orca/scripts/toolkits/Gecko/script_utilities.py
b/src/orca/scripts/toolkits/Gecko/script_utilities.py
index 273c4f1..38a4a7c 100644
--- a/src/orca/scripts/toolkits/Gecko/script_utilities.py
+++ b/src/orca/scripts/toolkits/Gecko/script_utilities.py
@@ -989,3 +989,37 @@ class Utilities(script_utilities.Utilities):
return True
return False
+
+ def isZombie(self, obj):
+ try:
+ index = obj.getIndexInParent()
+ state = obj.getState()
+ except:
+ debug.println(debug.LEVEL_INFO, "ZOMBIE: %s is null or dead" % obj)
+ return True
+
+ if obj.getIndexInParent() == -1:
+ debug.println(debug.LEVEL_INFO, "ZOMBIE: %s's index is -1" % obj)
+ return True
+ if state.contains(pyatspi.STATE_DEFUNCT):
+ debug.println(debug.LEVEL_INFO, "ZOMBIE: %s is defunct" % obj)
+ return True
+ if state.contains(pyatspi.STATE_INVALID):
+ debug.println(debug.LEVEL_INFO, "ZOMBIE: %s is invalid" % obj)
+ return True
+
+ return False
+
+ def findReplicant(self, root, obj):
+ if not (root and obj):
+ return None
+
+ isSame = lambda x: x and self.isSameObject(x, obj)
+ if isSame(root):
+ replicant = root
+ else:
+ replicant = pyatspi.utils.findDescendant(root, isSame)
+
+ msg = "HACK: Returning %s as replicant for Zombie %s" % (replicant, obj)
+ debug.println(debug.LEVEL_INFO, msg)
+ return replicant
diff --git a/test/harness/runall.sh b/test/harness/runall.sh
index 470bc83..b35036a 100755
--- a/test/harness/runall.sh
+++ b/test/harness/runall.sh
@@ -167,7 +167,7 @@ do
#
mkdir -p ./tmp/$application
cd ./tmp/$application
- for testFile in `find $testDir -xtype f -name "*.py" | sort`; do
+ for testFile in `find $testDir -xtype f -name "aria*.py" | sort`; do
echo ========================================
echo Running $testFile
if [ "$found" -gt 0 ]
diff --git a/test/html/button-in-link-with-position-relative-on-focus.html
b/test/html/button-in-link-with-position-relative-on-focus.html
new file mode 100644
index 0000000..b37d159
--- /dev/null
+++ b/test/html/button-in-link-with-position-relative-on-focus.html
@@ -0,0 +1,18 @@
+<html>
+<head>
+<style>
+a:focus{position:relative;}
+button span{display:block;}
+button{display:inline-block;)
+</style>
+</head>
+<body>
+<p>Start</p>
+<div>
+<p>Line 1</p>
+<a href="foo"><button><span> Line 2 </span></button></a>
+<p>Line 3</p>
+</div>
+<p>End</p>
+</body>
+</html>
diff --git a/test/keystrokes/firefox/line_nav_button_in_link_position_relative_on_focus.params
b/test/keystrokes/firefox/line_nav_button_in_link_position_relative_on_focus.params
new file mode 100644
index 0000000..fcdb529
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_button_in_link_position_relative_on_focus.params
@@ -0,0 +1 @@
+PARAMS=$TEST_DIR/../../html/button-in-link-with-position-relative-on-focus.html
diff --git a/test/keystrokes/firefox/line_nav_button_in_link_position_relative_on_focus.py
b/test/keystrokes/firefox/line_nav_button_in_link_position_relative_on_focus.py
new file mode 100644
index 0000000..d735dc0
--- /dev/null
+++ b/test/keystrokes/firefox/line_nav_button_in_link_position_relative_on_focus.py
@@ -0,0 +1,51 @@
+#!/usr/bin/python
+
+from macaroon.playback import *
+import utils
+
+sequence = MacroSequence()
+
+sequence.append(KeyComboAction("<Control>Home"))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+ "1. Top of file",
+ ["BRAILLE LINE: 'Line 1'",
+ " VISIBLE: 'Line 1', cursor=1",
+ "SPEECH OUTPUT: 'Line 1'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+ "2. Line Down",
+ ["BRAILLE LINE: ' Line 2 '",
+ " VISIBLE: ' Line 2 ', cursor=1",
+ "SPEECH OUTPUT: 'Line 2'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Down"))
+sequence.append(utils.AssertPresentationAction(
+ "3. Line Down",
+ ["BRAILLE LINE: 'Line 3'",
+ " VISIBLE: 'Line 3', cursor=1",
+ "SPEECH OUTPUT: 'Line 3'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+ "4. Line Up",
+ ["BRAILLE LINE: ' Line 2 '",
+ " VISIBLE: ' Line 2 ', cursor=1",
+ "SPEECH OUTPUT: 'Line 2'"]))
+
+sequence.append(utils.StartRecordingAction())
+sequence.append(KeyComboAction("Up"))
+sequence.append(utils.AssertPresentationAction(
+ "5. Line Up",
+ ["BRAILLE LINE: 'Line 1'",
+ " VISIBLE: 'Line 1', cursor=1",
+ "SPEECH OUTPUT: 'Line 1'"]))
+
+sequence.append(utils.AssertionSummaryAction())
+sequence.start()
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]