зеркало из https://github.com/mozilla/gecko-dev.git
Bug 386836 - same map used in several img caused firefox crash, patch=me, ginn.chen, r=me
This commit is contained in:
Родитель
dba6073690
Коммит
1c2ae99628
|
@ -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
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче