mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 491657 - getDeepestChildAtPoint must return null when point is not inside of accessible, r=marcoz, davidb, sr=neil
This commit is contained in:
parent
e438aaa451
commit
36a1310be5
@ -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];
|
||||
}
|
||||
|
92
accessible/tests/mochitest/test_childAtPoint.html
Normal file
92
accessible/tests/mochitest/test_childAtPoint.html
Normal file
@ -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>
|
Loading…
Reference in New Issue
Block a user