Bug 491657 - getDeepestChildAtPoint must return null when point is not inside of accessible, r=marcoz, davidb, sr=neil

This commit is contained in:
Alexander Surkov 2009-05-11 18:57:28 +08:00
Родитель 711cd1e122
Коммит 1f4dd4eab9
16 изменённых файлов: 295 добавлений и 116 удалений

Просмотреть файл

@ -715,6 +715,16 @@ nsAccUtils::GetLiveAttrValue(PRUint32 aRule, nsAString& aValue)
}
}
already_AddRefed<nsAccessible>
nsAccUtils::QueryAccessible(nsIAccessible *aAccessible)
{
nsAccessible* accessible = nsnull;
if (aAccessible)
CallQueryInterface(aAccessible, &accessible);
return accessible;
}
#ifdef DEBUG_A11Y
PRBool

Просмотреть файл

@ -52,6 +52,7 @@
#include "nsPoint.h"
class nsAccessNode;
class nsAccessible;
class nsAccUtils
{
@ -320,6 +321,12 @@ public:
return accessNode;
}
/**
* Query nsAccessible from the given nsIAccessible.
*/
static already_AddRefed<nsAccessible>
QueryAccessible(nsIAccessible *aAccessible);
#ifdef DEBUG_A11Y
/**
* Detect whether the given accessible object implements nsIAccessibleText,

Просмотреть файл

@ -1082,29 +1082,23 @@ NS_IMETHODIMP nsAccessible::GetFocusedChild(nsIAccessible **aFocusedChild)
return NS_OK;
}
// nsIAccessible getDeepestChildAtPoint(in long x, in long y)
NS_IMETHODIMP
nsAccessible::GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
nsIAccessible **aAccessible)
// nsAccessible::GetChildAtPoint()
nsresult
nsAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY, PRBool aDeepestChild,
nsIAccessible **aChild)
{
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nsnull;
if (!mDOMNode) {
return NS_ERROR_FAILURE; // Already shut down
}
// If we can't find the point in a child, we will return the fallback answer:
// we return |this| if the point is within it, otherwise nsnull
// we return |this| if the point is within it, otherwise nsnull.
PRInt32 x = 0, y = 0, width = 0, height = 0;
nsresult rv = GetBounds(&x, &y, &width, &height);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIAccessible> fallbackAnswer;
PRInt32 x, y, width, height;
GetBounds(&x, &y, &width, &height);
if (aX >= x && aX < x + width &&
aY >= y && aY < y + height) {
if (aX >= x && aX < x + width && aY >= y && aY < y + height)
fallbackAnswer = this;
}
if (nsAccUtils::MustPrune(this)) { // Do not dig any further
NS_IF_ADDREF(*aAccessible = fallbackAnswer);
NS_IF_ADDREF(*aChild = fallbackAnswer);
return NS_OK;
}
@ -1115,7 +1109,7 @@ nsAccessible::GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
// for DOM parent but GetFrameForPoint() should be called for containing block
// to get an out of flow element.
nsCOMPtr<nsIAccessibleDocument> accDocument;
nsresult rv = GetAccessibleDocument(getter_AddRefs(accDocument));
rv = GetAccessibleDocument(getter_AddRefs(accDocument));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_TRUE(accDocument, NS_ERROR_FAILURE);
@ -1133,9 +1127,10 @@ nsAccessible::GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
nsCOMPtr<nsIPresShell> presShell = presContext->PresShell();
nsIFrame *foundFrame = presShell->GetFrameForPoint(frame, offset);
nsCOMPtr<nsIContent> content;
nsIContent* content = nsnull;
if (!foundFrame || !(content = foundFrame->GetContent())) {
NS_IF_ADDREF(*aAccessible = fallbackAnswer);
NS_IF_ADDREF(*aChild = fallbackAnswer);
return NS_OK;
}
@ -1145,7 +1140,7 @@ nsAccessible::GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
nsCOMPtr<nsIDOMNode> relevantNode;
accService->GetRelevantContentNodeFor(node, getter_AddRefs(relevantNode));
if (!relevantNode) {
NS_IF_ADDREF(*aAccessible = fallbackAnswer);
NS_IF_ADDREF(*aChild = fallbackAnswer);
return NS_OK;
}
@ -1157,16 +1152,17 @@ nsAccessible::GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
accDocument->GetAccessibleInParentChain(relevantNode, PR_TRUE,
getter_AddRefs(accessible));
if (!accessible) {
NS_IF_ADDREF(*aAccessible = fallbackAnswer);
NS_IF_ADDREF(*aChild = fallbackAnswer);
return NS_OK;
}
}
if (accessible == this) {
// Manually walk through accessible children and see if
// the are within this point.
// This takes care of cases where layout won't walk into
// things for us, such as image map areas and sub documents
// Manually walk through accessible children and see if the are within this
// point. Skip offscreen or invisible accessibles. This takes care of cases
// where layout won't walk into things for us, such as image map areas and
// sub documents (XXX: subdocuments should be handled by methods of
// nsOuterDocAccessibles).
nsCOMPtr<nsIAccessible> child;
while (NextChild(child)) {
PRInt32 childX, childY, childWidth, childHeight;
@ -1174,16 +1170,40 @@ nsAccessible::GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
if (aX >= childX && aX < childX + childWidth &&
aY >= childY && aY < childY + childHeight &&
(nsAccUtils::State(child) & nsIAccessibleStates::STATE_INVISIBLE) == 0) {
// Don't walk into offscreen or invisible items
NS_IF_ADDREF(*aAccessible = child);
if (aDeepestChild)
return child->GetDeepestChildAtPoint(aX, aY, aChild);
NS_IF_ADDREF(*aChild = child);
return NS_OK;
}
}
// Fall through -- the point is in this accessible but not in a child
// We are allowed to return |this| as the answer
// The point is in this accessible but not in a child. We are allowed to
// return |this| as the answer.
NS_IF_ADDREF(*aChild = accessible);
return NS_OK;
}
// Since DOM node of obtained accessible may be out of flow then we should
// ensure obtained accessible is a child of this accessible.
nsCOMPtr<nsIAccessible> parent, child(accessible);
while (PR_TRUE) {
child->GetParent(getter_AddRefs(parent));
if (!parent) {
// Reached the top of the hierarchy. These bounds were inside an
// accessible that is not a descendant of this one.
NS_IF_ADDREF(*aChild = fallbackAnswer);
return NS_OK;
}
if (parent == this) {
NS_ADDREF(*aChild = (aDeepestChild ? accessible : child));
return NS_OK;
}
child.swap(parent);
}
NS_IF_ADDREF(*aAccessible = accessible);
return NS_OK;
}
@ -1192,43 +1212,27 @@ NS_IMETHODIMP
nsAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
nsIAccessible **aAccessible)
{
nsresult rv = GetDeepestChildAtPoint(aX, aY, aAccessible);
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nsnull;
if (!*aAccessible || *aAccessible == this)
return NS_OK;
if (IsDefunct())
return NS_ERROR_FAILURE;
// Get direct child containing the deepest child at the given point.
nsCOMPtr<nsIAccessible> parent, accessible;
accessible.swap(*aAccessible);
return GetChildAtPoint(aX, aY, PR_FALSE, aAccessible);
}
while (PR_TRUE) {
accessible->GetParent(getter_AddRefs(parent));
if (!parent) {
NS_NOTREACHED("Obtained accessible isn't a child of this accessible.");
// nsIAccessible getDeepestChildAtPoint(in long x, in long y)
NS_IMETHODIMP
nsAccessible::GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
nsIAccessible **aAccessible)
{
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nsnull;
// Reached the top of the hierarchy. These bounds were inside an
// accessible that is not a descendant of this one.
if (IsDefunct())
return NS_ERROR_FAILURE;
// If we can't find the point in a child, we will return the fallback
// answer: we return |this| if the point is within it, otherwise nsnull.
PRInt32 x, y, width, height;
GetBounds(&x, &y, &width, &height);
if (aX >= x && aX < x + width && aY >= y && aY < y + height)
NS_ADDREF(*aAccessible = this);
return NS_OK;
}
if (parent == this) {
// We reached |this|, so |accessible| is the child we want to return.
NS_ADDREF(*aAccessible = accessible);
return NS_OK;
}
accessible.swap(parent);
}
return NS_OK;
return GetChildAtPoint(aX, aY, PR_TRUE, aAccessible);
}
void nsAccessible::GetBoundsRect(nsRect& aTotalBounds, nsIFrame** aBoundingFrame)

Просмотреть файл

@ -104,11 +104,11 @@ private:
#define NS_ACCESSIBLE_IMPL_CID \
{ /* 4E36C7A8-9203-4ef9-B619-271DDF6BB839 */ \
0x4e36c7a8, \
0x9203, \
0x4ef9, \
{ 0xb6, 0x19, 0x27, 0x1d, 0xdf, 0x6b, 0xb8, 0x39 } \
{ /* 16917f1e-6cee-4cde-be3f-8bb5943f506c */ \
0x16917f1e, \
0x6cee, \
0x4cde, \
{ 0xbe, 0x3f, 0x8b, 0xb5, 0x94, 0x3F, 0x50, 0x6c } \
}
class nsAccessible : public nsAccessNodeWrap,
@ -179,6 +179,18 @@ public:
*/
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
/**
* Return direct or deepest child at the given point.
*
* @param aX [in] x coordinate relative screen
* @param aY [in] y coordinate relative screen
* @param aDeepestChild [in] flag points if deep child should be returned
* @param aChild [out] found child
*/
virtual nsresult GetChildAtPoint(PRInt32 aX, PRInt32 aY,
PRBool aDeepestChild,
nsIAccessible **aChild);
//////////////////////////////////////////////////////////////////////////////
// Helper methods

Просмотреть файл

@ -94,6 +94,17 @@ nsLeafAccessible::GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren)
return NS_OK;
}
// nsAccessible::GetChildAtPoint()
nsresult
nsLeafAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
PRBool aDeepestChild,
nsIAccessible **aChild)
{
// Don't walk into leaf accessibles.
NS_ADDREF(*aChild = this);
return NS_OK;
}
////////////////////////////////////////////////////////////////////////////////
// nsLinkableAccessible

Просмотреть файл

@ -58,13 +58,22 @@ class nsLeafAccessible : public nsAccessibleWrap
{
public:
nsLeafAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell);
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
// nsIAccessible
NS_IMETHOD GetFirstChild(nsIAccessible **_retval);
NS_IMETHOD GetLastChild(nsIAccessible **_retval);
NS_IMETHOD GetChildCount(PRInt32 *_retval);
// nsPIAccessible
NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY, nsIAccessible **aAccessible)
{ NS_ENSURE_ARG_POINTER(aAccessible); NS_ADDREF(*aAccessible = this); return NS_OK; } // Don't walk into these
// nsAccessible
virtual nsresult GetChildAtPoint(PRInt32 aX, PRInt32 aY,
PRBool aDeepestChild,
nsIAccessible **aChild);
};
/**

Просмотреть файл

@ -70,40 +70,33 @@ nsOuterDocAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
return NS_OK;
}
// nsIAccessible::getChildAtPoint(in long x, in long y)
NS_IMETHODIMP
// nsAccessible::GetChildAtPoint()
nsresult
nsOuterDocAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
nsIAccessible **aAccessible)
PRBool aDeepestChild,
nsIAccessible **aChild)
{
NS_ENSURE_ARG_POINTER(aAccessible);
*aAccessible = nsnull;
if (!mDOMNode) {
return NS_ERROR_FAILURE;
}
PRInt32 docX, docY, docWidth, docHeight;
GetBounds(&docX, &docY, &docWidth, &docHeight);
if (aX < docX || aX >= docX + docWidth || aY < docY || aY >= docY + docHeight) {
return NS_ERROR_FAILURE;
}
PRInt32 docX = 0, docY = 0, docWidth = 0, docHeight = 0;
nsresult rv = GetBounds(&docX, &docY, &docWidth, &docHeight);
NS_ENSURE_SUCCESS(rv, rv);
return GetFirstChild(aAccessible); // Always return the inner doc unless bounds outside of it
}
if (aX < docX || aX >= docX + docWidth || aY < docY || aY >= docY + docHeight)
return NS_OK;
// nsIAccessible::getDeepestChildAtPoint(in long x, in long y)
NS_IMETHODIMP
nsOuterDocAccessible::GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
nsIAccessible **aAccessible)
{
// Call getDeepestChildAtPoint on the fist child accessible of the outer
// document accessible if the given point is inside of outer document.
// Always return the inner doc as direct child accessible unless bounds
// outside of it.
nsCOMPtr<nsIAccessible> childAcc;
nsresult rv = GetChildAtPoint(aX, aY, getter_AddRefs(childAcc));
rv = GetFirstChild(getter_AddRefs(childAcc));
NS_ENSURE_SUCCESS(rv, rv);
if (!childAcc)
return NS_OK;
return childAcc->GetDeepestChildAtPoint(aX, aY, aAccessible);
if (aDeepestChild)
return childAcc->GetDeepestChildAtPoint(aX, aY, aChild);
NS_ADDREF(*aChild = childAcc);
return NS_OK;
}
void nsOuterDocAccessible::CacheChildren()

Просмотреть файл

@ -55,11 +55,6 @@ public:
nsIWeakReference* aShell);
// nsIAccessible
NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY,
nsIAccessible **aAccessible);
NS_IMETHOD GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
nsIAccessible **aAccessible);
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
NS_IMETHOD GetActionDescription(PRUint8 aIndex, nsAString& aDescription);
@ -69,6 +64,9 @@ public:
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsresult GetAttributesInternal(nsIPersistentProperties *aAttributes);
virtual nsresult GetChildAtPoint(PRInt32 aX, PRInt32 aY,
PRBool aDeepestChild,
nsIAccessible **aChild);
protected:
// nsAccessible

Просмотреть файл

@ -161,3 +161,13 @@ nsHTMLAreaAccessible::GetBounds(PRInt32 *x, PRInt32 *y,
return NS_OK;
}
// nsAccessible::GetChildAtPoint()
nsresult
nsHTMLAreaAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
PRBool aDeepestChild,
nsIAccessible **aChild)
{
// Don't walk into area accessibles.
NS_ADDREF(*aChild = this);
return NS_OK;
}

Просмотреть файл

@ -59,11 +59,12 @@ public:
NS_IMETHOD GetChildCount(PRInt32 *_retval);
NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY, nsIAccessible **aAccessible)
{ NS_ENSURE_ARG_POINTER(aAccessible); NS_ADDREF(*aAccessible = this); return NS_OK; } // Don't walk into these
// nsAccessible
virtual nsresult GetNameInternal(nsAString& aName);
virtual nsresult GetChildAtPoint(PRInt32 aX, PRInt32 aY,
PRBool aDeepestChild,
nsIAccessible **aChild);
};
#endif

Просмотреть файл

@ -318,10 +318,11 @@ NS_IMETHODIMP nsXULTreeAccessible::GetFocusedChild(nsIAccessible **aFocusedChild
return NS_OK;
}
// nsIAccessible::getDeepestChildAtPoint(in long x, in long y)
NS_IMETHODIMP
nsXULTreeAccessible::GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
nsIAccessible **aAccessible)
// nsAccessible::GetChildAtPoint()
nsresult
nsXULTreeAccessible::GetChildAtPoint(PRInt32 aX, PRInt32 aY,
PRBool aDeepestChild,
nsIAccessible **aChild)
{
nsIFrame *frame = GetFrame();
if (!frame)
@ -350,9 +351,16 @@ nsXULTreeAccessible::GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
// tree columns.
if (row == -1 || !column)
return nsXULSelectableAccessible::
GetDeepestChildAtPoint(aX, aY, aAccessible);
GetChildAtPoint(aX, aY, aDeepestChild, aChild);
return GetCachedTreeitemAccessible(row, column, aAccessible);
nsCOMPtr<nsIAccessible> treeitemAcc;
nsresult rv = GetCachedTreeitemAccessible(row, column,
getter_AddRefs(treeitemAcc));
NS_ENSURE_SUCCESS(rv, rv);
NS_IF_ADDREF(*aChild = treeitemAcc);
return NS_OK;
}
// Ask treeselection to get all selected children

Просмотреть файл

@ -69,15 +69,15 @@ public:
NS_IMETHOD GetChildCount(PRInt32 *_retval);
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
NS_IMETHOD GetDeepestChildAtPoint(PRInt32 aX, PRInt32 aY,
nsIAccessible **aAccessible);
// nsAccessNode
virtual nsresult Shutdown();
// nsAccessible
virtual nsresult GetRoleInternal(PRUint32 *aRole);
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual nsresult GetChildAtPoint(PRInt32 aX, PRInt32 aY,
PRBool aDeepestChild,
nsIAccessible **aChild);
// nsXULTreeAccessible
static void GetTreeBoxObject(nsIDOMNode* aDOMNode, nsITreeBoxObject** aBoxObject);

Просмотреть файл

@ -76,6 +76,7 @@ _TEST_FILES =\
test_aria_role_grid.html \
test_aria_token_attrs.html \
test_bug420863.html \
test_childAtPoint.html \
$(warning test_childAtPoint.xul temporarily disabled) \
test_cssattrs.html \
test_descr.html \

Просмотреть файл

@ -40,7 +40,9 @@ const nsIDOMDocument = Components.interfaces.nsIDOMDocument;
const nsIDOMEvent = Components.interfaces.nsIDOMEvent;
const nsIDOMHTMLDocument = Components.interfaces.nsIDOMHTMLDocument;
const nsIDOMNode = Components.interfaces.nsIDOMNode;
const nsIDOMNSHTMLElement = Components.interfaces.nsIDOMNSHTMLElement;
const nsIDOMWindow = Components.interfaces.nsIDOMWindow;
const nsIDOMXULElement = Components.interfaces.nsIDOMXULElement;
const nsIPropertyElement = Components.interfaces.nsIPropertyElement;

Просмотреть файл

@ -12,14 +12,13 @@ function testChildAtPoint(aIdentifier, aX, aY, aFindDeepestChild,
aChildIdentifier)
{
var childAcc = getAccessible(aChildIdentifier);
if (!childAcc)
return;
var actualChildAcc = getChildAtPoint(aIdentifier, aX, aY, aFindDeepestChild);
var msg = "Wrong " + (aFindDeepestChild ? "deepest" : "direct");
msg += " child accessible [" + prettyName(actualChildAcc);
msg += "] at the point (" + aX + ", " + aY + ") of accessible [";
msg += prettyName(aIdentifier) + "]";
is(childAcc, actualChildAcc, msg);
}
@ -42,8 +41,7 @@ function getChildAtPoint(aIdentifier, aX, aY, aFindDeepestChild)
if (!acc || !node)
return;
var deltaX = node.boxObject.screenX;
var deltaY = node.boxObject.screenY;
var [deltaX, deltaY] = getScreenCoords(node);
var x = deltaX + aX;
var y = deltaY + aY;
@ -56,3 +54,26 @@ function getChildAtPoint(aIdentifier, aX, aY, aFindDeepestChild)
return null;
}
/**
* Return DOM node coordinates relative screen as pair (x, y).
*/
function getScreenCoords(aNode)
{
if (aNode instanceof nsIDOMXULElement)
return [node.boxObject.screenX, node.boxObject.screenY];
// Ugly hack until bug 486200 is fixed.
const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var descr = document.createElementNS(XUL_NS, "description");
descr.setAttribute("value", "helper description");
aNode.parentNode.appendChild(descr);
var descrBoxObject = descr.boxObject;
var descrRect = descr.getBoundingClientRect();
var deltaX = descrBoxObject.screenX - descrRect.left;
var deltaY = descrBoxObject.screenY - descrRect.top;
aNode.parentNode.removeChild(descr);
var rect = aNode.getBoundingClientRect();
return [rect.left + deltaX, rect.top + deltaY];
}

Просмотреть файл

@ -0,0 +1,92 @@
<!DOCTYPE html>
<html>
<head>
<title>nsIAccessible::childAtPoint() tests</title>
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/MochiKit/packed.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/common.js"></script>
<script type="application/javascript"
src="chrome://mochikit/content/a11y/accessible/layout.js"></script>
<script type="application/javascript">
function doTest()
{
// Not specific case, child and deepchild testing.
var list = getAccessible("list");
var listitem = getAccessible("listitem");
var image = getAccessible("image");
testChildAtPoint(list, 1, 1, false, listitem);
testChildAtPoint(list, 1, 1, true, image.firstChild);
// ::MustPrune case (in this case childAtPoint doesn't look inside a
// button), point is inside of button.
var btn = getAccessible("btn");
testChildAtPoint(btn, 1, 1, false, btn);
testChildAtPoint(btn, 1, 1, true, btn);
// ::MustPrune case, point is outside of button accessible but is in
// document.
testChildAtPoint(btn, -1, 1, false, null);
testChildAtPoint(btn, -1, 1, true, null);
// ::MustPrune case, point is outside of root accessible.
testChildAtPoint(btn, -10000, 10000, false, null);
testChildAtPoint(btn, -10000, 10000, true, null);
// Not specific case, point is inside of label accessible.
var label = getAccessible("label");
var labelText = label.firstChild;
testChildAtPoint(label, 1, 1, false, labelText);
testChildAtPoint(label, 1, 1, true, labelText);
// Not specific case, point is outside of label accessible.
testChildAtPoint(label, -1, 1, false, null);
testChildAtPoint(label, -1, 1, true, null);
// Out of flow accessible testing, do not return out of flow accessible
// because it's not a child of the accessible even visually it is.
var rectArea = getNode("area").getBoundingClientRect();
var outOfFlow = getNode("outofflow");
outOfFlow.style.left = rectArea.left + "px";
outOfFlow.style.top = rectArea.top + "px";
testChildAtPoint("area", 1, 1, false, "area");
testChildAtPoint("area", 1, 1, true, "area");
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTest);
</script>
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=491657"
title="nsIAccessible::childAtPoint() tests">Mozilla Bug 491657</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<div role="list" id="list">
<div role="listitem" id="listitem"><span role="image" id="image">img</span>item</div>
</div>
<span role="label">label1</span><span role="label" id="label">label2</span>
<span role="button">btn1</span><span role="button" id="btn">btn2</span>
<div id="outofflow" style="width: 10px; height: 10px; position: absolute; left: 0px; top: 0px; background-color: yellow;">
</div>
<div id="area" style="width: 100px; height: 100px; background-color: blue;"></div>
</body>
</html>