mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 550819 - A11y test suite crash [@ nsTArray_base::Length], r=marcoz, davidb
This commit is contained in:
parent
aff371e5cb
commit
dbc0c64242
@ -1404,33 +1404,11 @@ nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
|
||||
}
|
||||
|
||||
if (weakFrame.GetFrame()->GetContent() != content) {
|
||||
// Not the main content for this frame!
|
||||
// For example, this happens because <area> elements return the
|
||||
// image frame as their primary frame. The main content for the
|
||||
// image frame is the image content.
|
||||
|
||||
// Check if frame is an image frame, and content is <area>.
|
||||
nsIImageFrame *imageFrame = do_QueryFrame(weakFrame.GetFrame());
|
||||
nsCOMPtr<nsIDOMHTMLAreaElement> areaElmt = do_QueryInterface(content);
|
||||
if (imageFrame && areaElmt) {
|
||||
// XXX: it's a hack we should try the cache before or if failed cache
|
||||
// the image accessible.
|
||||
nsCOMPtr<nsIAccessible> imageAcc;
|
||||
CreateHTMLImageAccessible(weakFrame.GetFrame(), getter_AddRefs(imageAcc));
|
||||
if (imageAcc) {
|
||||
// Cache children.
|
||||
PRInt32 childCount;
|
||||
imageAcc->GetChildCount(&childCount);
|
||||
// <area> accessible should be in cache now.
|
||||
nsAccessNode* cachedAreaAcc = GetCachedAccessNode(aNode, aWeakShell);
|
||||
if (cachedAreaAcc) {
|
||||
newAcc = nsAccUtils::QueryObject<nsAccessible>(cachedAreaAcc);
|
||||
return newAcc.forget();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
// Not the main content for this frame. This happens because <area>
|
||||
// elements return the image frame as their primary frame. The main content
|
||||
// for the image frame is the image content. If the frame is not an image
|
||||
// frame or the node is not an area element then null is returned.
|
||||
return GetAreaAccessible(weakFrame.GetFrame(), aNode, aWeakShell);
|
||||
}
|
||||
|
||||
// Attempt to create an accessible based on what we know.
|
||||
@ -1769,6 +1747,52 @@ nsAccessibilityService::GetRelevantContentNodeFor(nsIDOMNode *aNode,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
already_AddRefed<nsAccessible>
|
||||
nsAccessibilityService::GetAreaAccessible(nsIFrame *aImageFrame,
|
||||
nsIDOMNode *aAreaNode,
|
||||
nsIWeakReference *aWeakShell)
|
||||
{
|
||||
// Check if frame is an image frame, and content is <area>.
|
||||
nsIImageFrame *imageFrame = do_QueryFrame(aImageFrame);
|
||||
if (!imageFrame)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLAreaElement> areaElmt = do_QueryInterface(aAreaNode);
|
||||
if (!areaElmt)
|
||||
return nsnull;
|
||||
|
||||
// Try to get image map accessible from the global cache or create it
|
||||
// if failed.
|
||||
nsRefPtr<nsAccessible> imageAcc;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> imageNode(do_QueryInterface(aImageFrame->GetContent()));
|
||||
nsAccessNode *cachedImgAcc = GetCachedAccessNode(imageNode, aWeakShell);
|
||||
if (cachedImgAcc)
|
||||
imageAcc = nsAccUtils::QueryObject<nsAccessible>(cachedImgAcc);
|
||||
|
||||
if (!imageAcc) {
|
||||
nsCOMPtr<nsIAccessible> imageAccessible;
|
||||
CreateHTMLImageAccessible(aImageFrame,
|
||||
getter_AddRefs(imageAccessible));
|
||||
|
||||
imageAcc = nsAccUtils::QueryObject<nsAccessible>(imageAccessible);
|
||||
if (!InitAccessible(imageAcc, nsnull))
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Make sure <area> accessible children of the image map are cached so
|
||||
// that they should be available in global cache.
|
||||
imageAcc->EnsureChildren();
|
||||
|
||||
nsAccessNode *cachedAreaAcc = GetCachedAccessNode(aAreaNode, aWeakShell);
|
||||
if (!cachedAreaAcc)
|
||||
return nsnull;
|
||||
|
||||
nsRefPtr<nsAccessible> areaAcc =
|
||||
nsAccUtils::QueryObject<nsAccessible>(cachedAreaAcc);
|
||||
return areaAcc.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<nsAccessible>
|
||||
nsAccessibilityService::CreateAccessibleByType(nsIDOMNode *aNode,
|
||||
nsIWeakReference *aWeakShell)
|
||||
|
@ -149,6 +149,13 @@ private:
|
||||
PRBool InitAccessible(nsAccessible *aAccessible,
|
||||
nsRoleMapEntry *aRoleMapEntry);
|
||||
|
||||
/**
|
||||
* Return accessible for HTML area element associated with an image map.
|
||||
*/
|
||||
already_AddRefed<nsAccessible>
|
||||
GetAreaAccessible(nsIFrame *aImageFrame, nsIDOMNode *aAreaNode,
|
||||
nsIWeakReference *aWeakShell);
|
||||
|
||||
/**
|
||||
* Create accessible for the element implementing nsIAccessibleProvider
|
||||
* interface.
|
||||
|
@ -3012,6 +3012,7 @@ nsAccessible::TestChildCache(nsAccessible *aCachedChild)
|
||||
#endif
|
||||
}
|
||||
|
||||
// nsAccessible public
|
||||
PRBool
|
||||
nsAccessible::EnsureChildren()
|
||||
{
|
||||
|
@ -231,6 +231,11 @@ public:
|
||||
*/
|
||||
void SetParent(nsAccessible *aParent);
|
||||
|
||||
/**
|
||||
* Cache children if necessary. Return true if the accessible is defunct.
|
||||
*/
|
||||
PRBool EnsureChildren();
|
||||
|
||||
/**
|
||||
* Set the child count to -1 (unknown) and null out cached child pointers.
|
||||
* Should be called when accessible tree is changed because document has
|
||||
@ -317,11 +322,6 @@ protected:
|
||||
*/
|
||||
virtual void CacheChildren();
|
||||
|
||||
/**
|
||||
* Cache children if necessary. Return true if the accessible is defunct.
|
||||
*/
|
||||
PRBool EnsureChildren();
|
||||
|
||||
/**
|
||||
* Return sibling accessible at the given offset.
|
||||
*/
|
||||
|
@ -51,36 +51,17 @@
|
||||
// nsHTMLImageMapAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const PRUint32 kDefaultImageMapCacheSize = 256;
|
||||
|
||||
nsHTMLImageMapAccessible::
|
||||
nsHTMLImageMapAccessible(nsIDOMNode *aDOMNode, nsIWeakReference *aShell,
|
||||
nsIDOMHTMLMapElement *aMapElm) :
|
||||
nsHTMLImageAccessibleWrap(aDOMNode, aShell), mMapElement(aMapElm)
|
||||
{
|
||||
mAreaAccCache.Init(kDefaultImageMapCacheSize);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLImageMapAccessible: nsISupports and cycle collector
|
||||
// nsHTMLImageMapAccessible: nsISupports
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsHTMLImageMapAccessible)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLImageMapAccessible,
|
||||
nsAccessible)
|
||||
CycleCollectorTraverseCache(tmp->mAreaAccCache, &cb);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsHTMLImageMapAccessible,
|
||||
nsAccessible)
|
||||
ClearCache(tmp->mAreaAccCache);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsHTMLImageMapAccessible)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsHTMLImageAccessible)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsHTMLImageMapAccessible, nsHTMLImageAccessible)
|
||||
NS_IMPL_RELEASE_INHERITED(nsHTMLImageMapAccessible, nsHTMLImageAccessible)
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsHTMLImageMapAccessible, nsHTMLImageAccessible)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLImageMapAccessible: nsIAccessibleHyperLink
|
||||
@ -99,16 +80,14 @@ nsHTMLImageMapAccessible::GetURI(PRInt32 aIndex, nsIURI **aURI)
|
||||
NS_ENSURE_ARG_POINTER(aURI);
|
||||
*aURI = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLCollection> mapAreas = GetAreaCollection();
|
||||
if (!mapAreas)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> domNode;
|
||||
mapAreas->Item(aIndex, getter_AddRefs(domNode));
|
||||
if (!domNode)
|
||||
nsAccessible *areaAcc = GetChildAt(aIndex);
|
||||
if (!areaAcc)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsCOMPtr<nsIContent> link(do_QueryInterface(domNode));
|
||||
nsCOMPtr<nsIDOMNode> areaNode;
|
||||
areaAcc->GetDOMNode(getter_AddRefs(areaNode));
|
||||
|
||||
nsCOMPtr<nsIContent> link(do_QueryInterface(areaNode));
|
||||
if (link)
|
||||
*aURI = link->GetHrefURI().get();
|
||||
|
||||
@ -121,27 +100,11 @@ nsHTMLImageMapAccessible::GetAnchor(PRInt32 aIndex, nsIAccessible **aAccessible)
|
||||
NS_ENSURE_ARG_POINTER(aAccessible);
|
||||
*aAccessible = nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLCollection> mapAreas = GetAreaCollection();
|
||||
if (mapAreas) {
|
||||
nsRefPtr<nsIAccessible> accessible = GetAreaAccessible(mapAreas, aIndex);
|
||||
if (!accessible)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
nsAccessible *areaAcc = GetChildAt(aIndex);
|
||||
if (!areaAcc)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
NS_ADDREF(*aAccessible = accessible);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLImageAccessible: nsAccessNode
|
||||
|
||||
nsresult
|
||||
nsHTMLImageMapAccessible::Shutdown()
|
||||
{
|
||||
nsLinkableAccessible::Shutdown();
|
||||
|
||||
ClearCache(mAreaAccCache);
|
||||
NS_ADDREF(*aAccessible = areaAcc);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -161,79 +124,47 @@ nsHTMLImageMapAccessible::GetRoleInternal(PRUint32 *aRole)
|
||||
void
|
||||
nsHTMLImageMapAccessible::CacheChildren()
|
||||
{
|
||||
nsCOMPtr<nsIDOMHTMLCollection> mapAreas = GetAreaCollection();
|
||||
if (!mMapElement)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLCollection> mapAreas;
|
||||
mMapElement->GetAreas(getter_AddRefs(mapAreas));
|
||||
if (!mapAreas)
|
||||
return;
|
||||
|
||||
PRUint32 areaCount = 0;
|
||||
mapAreas->GetLength(&areaCount);
|
||||
|
||||
nsRefPtr<nsAccessible> areaAcc;
|
||||
for (PRUint32 areaIdx = 0; areaIdx < areaCount; areaIdx++) {
|
||||
areaAcc = GetAreaAccessible(mapAreas, areaIdx);
|
||||
nsCOMPtr<nsIDOMNode> areaNode;
|
||||
mapAreas->Item(areaIdx, getter_AddRefs(areaNode));
|
||||
if (!areaNode)
|
||||
return;
|
||||
|
||||
nsRefPtr<nsAccessible> areaAcc =
|
||||
new nsHTMLAreaAccessible(areaNode, mWeakShell);
|
||||
if (!areaAcc)
|
||||
return;
|
||||
|
||||
nsresult rv = areaAcc->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
areaAcc->Shutdown();
|
||||
return;
|
||||
}
|
||||
|
||||
mChildren.AppendElement(areaAcc);
|
||||
areaAcc->SetParent(this);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLImageAccessible
|
||||
|
||||
already_AddRefed<nsIDOMHTMLCollection>
|
||||
nsHTMLImageMapAccessible::GetAreaCollection()
|
||||
{
|
||||
if (!mMapElement)
|
||||
return nsnull;
|
||||
|
||||
nsIDOMHTMLCollection *mapAreas = nsnull;
|
||||
mMapElement->GetAreas(&mapAreas);
|
||||
return mapAreas;
|
||||
}
|
||||
|
||||
already_AddRefed<nsAccessible>
|
||||
nsHTMLImageMapAccessible::GetAreaAccessible(nsIDOMHTMLCollection *aAreaCollection,
|
||||
PRInt32 aAreaNum)
|
||||
{
|
||||
if (!aAreaCollection)
|
||||
return nsnull;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> domNode;
|
||||
aAreaCollection->Item(aAreaNum,getter_AddRefs(domNode));
|
||||
if (!domNode)
|
||||
return nsnull;
|
||||
|
||||
void *key = reinterpret_cast<void*>(aAreaNum);
|
||||
nsRefPtr<nsAccessible> accessible = mAreaAccCache.GetWeak(key);
|
||||
|
||||
if (!accessible) {
|
||||
accessible = new nsHTMLAreaAccessible(domNode, this, mWeakShell);
|
||||
if (!accessible)
|
||||
return nsnull;
|
||||
|
||||
nsresult rv = accessible->Init();
|
||||
if (NS_FAILED(rv)) {
|
||||
accessible->Shutdown();
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
mAreaAccCache.Put(key, accessible);
|
||||
}
|
||||
|
||||
return accessible.forget();
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsHTMLAreaAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsHTMLAreaAccessible::
|
||||
nsHTMLAreaAccessible(nsIDOMNode *aDomNode, nsIAccessible *aParent,
|
||||
nsIWeakReference* aShell):
|
||||
nsHTMLLinkAccessible(aDomNode, aShell)
|
||||
nsHTMLAreaAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell) :
|
||||
nsHTMLLinkAccessible(aNode, aShell)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -57,9 +57,6 @@ public:
|
||||
// nsISupports and cycle collector
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsHTMLImageMapAccessible,
|
||||
nsAccessible)
|
||||
|
||||
// nsIAccessibleHyperLink
|
||||
NS_IMETHOD GetAnchorCount(PRInt32 *aAnchorCount);
|
||||
NS_IMETHOD GetURI(PRInt32 aIndex, nsIURI **aURI);
|
||||
@ -69,32 +66,13 @@ public:
|
||||
virtual nsresult GetRoleInternal(PRUint32 *aRole);
|
||||
|
||||
protected:
|
||||
// nsAccessNode
|
||||
virtual nsresult Shutdown();
|
||||
|
||||
// nsAccessible
|
||||
virtual void CacheChildren();
|
||||
|
||||
// nsHTMLImageAccessible
|
||||
/**
|
||||
* Return collection of HTML area elements associated with the image map.
|
||||
*/
|
||||
already_AddRefed<nsIDOMHTMLCollection> GetAreaCollection();
|
||||
|
||||
/**
|
||||
* Return an accessible for HTML area element at the given index.
|
||||
*/
|
||||
already_AddRefed<nsAccessible>
|
||||
GetAreaAccessible(nsIDOMHTMLCollection* aAreaNodes, PRInt32 aAreaNum);
|
||||
|
||||
private:
|
||||
// Reference on linked map element if any.
|
||||
nsCOMPtr<nsIDOMHTMLMapElement> mMapElement;
|
||||
|
||||
// Cache of area accessibles. We do not use common cache because images can
|
||||
// share area elements but we need to have separate area accessibles for
|
||||
// each image accessible.
|
||||
nsAccessibleHashtable mAreaAccCache;
|
||||
};
|
||||
|
||||
|
||||
@ -105,8 +83,7 @@ class nsHTMLAreaAccessible : public nsHTMLLinkAccessible
|
||||
{
|
||||
|
||||
public:
|
||||
nsHTMLAreaAccessible(nsIDOMNode *domNode, nsIAccessible *accParent,
|
||||
nsIWeakReference* aShell);
|
||||
nsHTMLAreaAccessible(nsIDOMNode *aNode, nsIWeakReference *aShell);
|
||||
|
||||
// nsIAccessible
|
||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
||||
|
Loading…
Reference in New Issue
Block a user