Bug 386836 - same map used in several img caused firefox crash, patch=me, ginn.chen, r=me

This commit is contained in:
surkov.alexander@gmail.com 2007-07-16 05:42:36 -07:00
Родитель dba6073690
Коммит 1c2ae99628
4 изменённых файлов: 68 добавлений и 40 удалений

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

@ -45,14 +45,13 @@ interface nsIFrame;
interface nsObjectFrame;
interface nsIContent;
[uuid(0e9e2f00-b6f1-440d-821f-6b09d264cdaf)]
[uuid(933f7472-cbe3-4d95-a77a-ce7ea3812b32)]
interface nsIAccessibilityService : nsIAccessibleRetrieval
{
nsIAccessible createOuterDocAccessible(in nsIDOMNode aNode);
nsIAccessible createRootAccessible(in nsIPresShell aShell, in nsIDocument aDocument);
nsIAccessible createHTML4ButtonAccessible(in nsISupports aFrame);
nsIAccessible createHTMLAreaAccessible(in nsIWeakReference aPresShell, in nsIDOMNode aDOMNode, in nsIAccessible aAccParent);
nsIAccessible createHyperTextAccessible(in nsISupports aFrame);
nsIAccessible createHTMLBRAccessible(in nsISupports aFrame);
nsIAccessible createHTMLButtonAccessible(in nsISupports aFrame);

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

@ -42,7 +42,6 @@
#include "nsAccessibilityUtils.h"
#include "nsCURILoader.h"
#include "nsDocAccessible.h"
#include "nsHTMLAreaAccessible.h"
#include "nsHTMLImageAccessibleWrap.h"
#include "nsHTMLLinkAccessible.h"
#include "nsHTMLSelectAccessible.h"
@ -412,19 +411,6 @@ nsAccessibilityService::CreateHTML4ButtonAccessible(nsISupports *aFrame, nsIAcce
return NS_OK;
}
NS_IMETHODIMP
nsAccessibilityService::CreateHTMLAreaAccessible(nsIWeakReference *aShell, nsIDOMNode *aDOMNode, nsIAccessible *aParent,
nsIAccessible **_retval)
{
*_retval = new nsHTMLAreaAccessible(aDOMNode, aParent, aShell);
if (! *_retval)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(*_retval);
return NS_OK;
}
NS_IMETHODIMP
nsAccessibilityService::CreateHTMLButtonAccessible(nsISupports *aFrame, nsIAccessible **_retval)
{

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

@ -38,9 +38,11 @@
#include "imgIContainer.h"
#include "imgIRequest.h"
#include "nsHTMLImageAccessible.h"
#include "nsAccessibilityAtoms.h"
#include "nsIAccessibilityService.h"
#include "nsHTMLAreaAccessible.h"
#include "nsIDOMHTMLCollection.h"
#include "nsIDocument.h"
#include "nsIHTMLDocument.h"
@ -53,8 +55,10 @@
// --- image -----
const PRUint32 kDefaultImageCacheSize = 256;
nsHTMLImageAccessible::nsHTMLImageAccessible(nsIDOMNode* aDOMNode, nsIWeakReference* aShell):
nsLinkableAccessible(aDOMNode, aShell)
nsLinkableAccessible(aDOMNode, aShell), mAccessNodeCache(nsnull)
{
nsCOMPtr<nsIDOMElement> element(do_QueryInterface(aDOMNode));
nsCOMPtr<nsIPresShell> shell(do_QueryReferent(mWeakShell));
@ -73,6 +77,11 @@ nsLinkableAccessible(aDOMNode, aShell)
mMapElement = htmlDoc->GetImageMap(mapElementName);
}
}
if (mMapElement) {
mAccessNodeCache = new nsAccessNodeHashtable();
mAccessNodeCache->Init(kDefaultImageCacheSize);
}
}
NS_IMPL_ISUPPORTS_INHERITED1(nsHTMLImageAccessible, nsLinkableAccessible, nsIAccessibleImage)
@ -140,37 +149,46 @@ NS_IMETHODIMP nsHTMLImageAccessible::GetRole(PRUint32 *_retval)
}
already_AddRefed<nsIAccessible> nsHTMLImageAccessible::CreateAreaAccessible(PRInt32 areaNum)
already_AddRefed<nsIAccessible>
nsHTMLImageAccessible::GetAreaAccessible(PRInt32 aAreaNum)
{
if (!mMapElement)
if (!mMapElement)
return nsnull;
nsCOMPtr<nsIDOMHTMLCollection> mapAreas;
mMapElement->GetAreas(getter_AddRefs(mapAreas));
if (!mapAreas)
if (!mapAreas)
return nsnull;
nsCOMPtr<nsIDOMNode> domNode;
mapAreas->Item(areaNum,getter_AddRefs(domNode));
mapAreas->Item(aAreaNum,getter_AddRefs(domNode));
if (!domNode)
return nsnull;
nsCOMPtr<nsIAccessibilityService> accService(do_GetService("@mozilla.org/accessibilityService;1"));
if (!accService)
return nsnull;
if (accService) {
nsIAccessible* acc = nsnull;
accService->GetCachedAccessible(domNode, mWeakShell, &acc);
if (!acc) {
accService->CreateHTMLAreaAccessible(mWeakShell, domNode, this, &acc);
nsCOMPtr<nsPIAccessNode> accessNode(do_QueryInterface(acc));
if (accessNode) {
accessNode->Init();
}
}
return acc;
nsCOMPtr<nsIAccessNode> accessNode;
GetCacheEntry(*mAccessNodeCache, (void*)(aAreaNum),
getter_AddRefs(accessNode));
if (!accessNode) {
accessNode = new nsHTMLAreaAccessible(domNode, this, mWeakShell);
if (!accessNode)
return nsnull;
nsCOMPtr<nsPIAccessNode> privateAccessNode(do_QueryInterface(accessNode));
NS_ASSERTION(privateAccessNode,
"Accessible doesn't implement nsPIAccessNode");
nsresult rv = privateAccessNode->Init();
if (NS_FAILED(rv))
return nsnull;
PutCacheEntry(*mAccessNodeCache, (void*)(aAreaNum), accessNode);
}
return nsnull;
nsCOMPtr<nsIAccessible> accessible(do_QueryInterface(accessNode));
nsIAccessible *accPtr;
NS_IF_ADDREF(accPtr = accessible);
return accPtr;
}
@ -202,7 +220,7 @@ void nsHTMLImageAccessible::CacheChildren()
nsCOMPtr<nsIAccessible> areaAccessible;
nsCOMPtr<nsPIAccessible> privatePrevAccessible;
while (childCount < (PRInt32)numMapAreas &&
(areaAccessible = CreateAreaAccessible(childCount)) != nsnull) {
(areaAccessible = GetAreaAccessible(childCount)) != nsnull) {
if (privatePrevAccessible) {
privatePrevAccessible->SetNextSibling(areaAccessible);
}
@ -246,3 +264,18 @@ NS_IMETHODIMP nsHTMLImageAccessible::GetImageBounds(PRInt32 *x, PRInt32 *y, PRIn
{
return GetBounds(x, y, width, height);
}
NS_IMETHODIMP
nsHTMLImageAccessible::Shutdown()
{
nsLinkableAccessible::Shutdown();
if (mAccessNodeCache) {
ClearCache(*mAccessNodeCache);
delete mAccessNodeCache;
mAccessNodeCache = nsnull;
}
return NS_OK;
}

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

@ -60,6 +60,7 @@ public:
nsHTMLImageAccessible(nsIDOMNode* aDomNode, nsIWeakReference* aShell);
// nsIAccessible
NS_IMETHOD GetName(nsAString& _retval);
NS_IMETHOD GetState(PRUint32 *aState, PRUint32 *aExtraState);
NS_IMETHOD GetRole(PRUint32 *_retval);
@ -67,10 +68,19 @@ public:
NS_IMETHOD GetImageBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
// nsPIAccessNode
NS_IMETHOD Shutdown();
protected:
virtual void CacheChildren();
already_AddRefed<nsIAccessible> CreateAreaAccessible(PRInt32 areaNum);
already_AddRefed<nsIAccessible> GetAreaAccessible(PRInt32 aAreaNum);
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.
nsAccessNodeHashtable *mAccessNodeCache;
};
#endif
#endif