mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 545465 - don't keep rejected accessible in the cache, r=ginn.chen, davidb, a=blockingBetaN
This commit is contained in:
parent
0ba5de8279
commit
082408ed24
@ -456,28 +456,29 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument *aDocument)
|
||||
// We only create root accessibles for the true root, otherwise create a
|
||||
// doc accessible.
|
||||
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
|
||||
nsDocAccessible *docAcc = isRootDoc ?
|
||||
nsRefPtr<nsDocAccessible> docAcc = isRootDoc ?
|
||||
new nsRootAccessibleWrap(aDocument, rootElm, weakShell) :
|
||||
new nsDocAccessibleWrap(aDocument, rootElm, weakShell);
|
||||
|
||||
if (!docAcc)
|
||||
// Cache the document accessible into document cache.
|
||||
if (!docAcc || !mDocAccessibleCache.Put(aDocument, docAcc))
|
||||
return nsnull;
|
||||
|
||||
// Cache and addref document accessible.
|
||||
if (!mDocAccessibleCache.Put(aDocument, docAcc)) {
|
||||
delete docAcc;
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// XXX: ideally we should initialize an accessible and then put it into tree,
|
||||
// we can't since document accessible fires reorder event on its container
|
||||
// while initialized.
|
||||
if (!outerDocAcc->AppendChild(docAcc) ||
|
||||
!GetAccService()->InitAccessible(docAcc, nsAccUtils::GetRoleMapEntry(aDocument))) {
|
||||
// Bind the document accessible into tree.
|
||||
if (!outerDocAcc->AppendChild(docAcc)) {
|
||||
mDocAccessibleCache.Remove(aDocument);
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Initialize the document accessible. Note, Init() should be called after
|
||||
// the document accessible is bound to the tree.
|
||||
if (!docAcc->Init()) {
|
||||
docAcc->Shutdown();
|
||||
mDocAccessibleCache.Remove(aDocument);
|
||||
return nsnull;
|
||||
}
|
||||
docAcc->SetRoleMapEntry(nsAccUtils::GetRoleMapEntry(aDocument));
|
||||
|
||||
NS_LOG_ACCDOCCREATE("document creation finished", aDocument)
|
||||
|
||||
AddListeners(aDocument, isRootDoc);
|
||||
|
@ -837,28 +837,6 @@ nsAccessibilityService::GetCachedAccessibleOrContainer(nsINode* aNode)
|
||||
return accessible;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccessibilityService::InitAccessible(nsAccessible *aAccessible,
|
||||
nsRoleMapEntry *aRoleMapEntry)
|
||||
{
|
||||
if (!aAccessible)
|
||||
return PR_FALSE;
|
||||
|
||||
// Add to cache an accessible, etc.
|
||||
if (!aAccessible->Init()) {
|
||||
NS_ERROR("Failed to initialize an accessible!");
|
||||
|
||||
aAccessible->Shutdown();
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_ASSERTION(aAccessible->IsInCache(),
|
||||
"Initialized accessible not in the cache!");
|
||||
|
||||
aAccessible->SetRoleMapEntry(aRoleMapEntry);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
static PRBool HasRelatedContent(nsIContent *aContent)
|
||||
{
|
||||
nsAutoString id;
|
||||
@ -958,6 +936,13 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
||||
return areaAcc;
|
||||
}
|
||||
|
||||
nsDocAccessible* docAcc =
|
||||
GetAccService()->GetDocAccessible(aNode->GetOwnerDoc());
|
||||
if (!docAcc) {
|
||||
NS_NOTREACHED("No document for accessible being created!");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Attempt to create an accessible based on what we know.
|
||||
nsRefPtr<nsAccessible> newAcc;
|
||||
if (content->IsNodeOfType(nsINode::eTEXT)) {
|
||||
@ -976,7 +961,7 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
||||
}
|
||||
if (weakFrame.IsAlive()) {
|
||||
newAcc = weakFrame.GetFrame()->CreateAccessible();
|
||||
if (InitAccessible(newAcc, nsnull))
|
||||
if (docAcc->BindToDocument(newAcc, nsnull))
|
||||
return newAcc.forget();
|
||||
return nsnull;
|
||||
}
|
||||
@ -1004,7 +989,7 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
||||
}
|
||||
|
||||
newAcc = new nsHyperTextAccessibleWrap(content, aWeakShell);
|
||||
if (InitAccessible(newAcc, nsAccUtils::GetRoleMapEntry(aNode)))
|
||||
if (docAcc->BindToDocument(newAcc, nsAccUtils::GetRoleMapEntry(aNode)))
|
||||
return newAcc.forget();
|
||||
return nsnull;
|
||||
}
|
||||
@ -1191,7 +1176,7 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
||||
}
|
||||
}
|
||||
|
||||
if (InitAccessible(newAcc, roleMapEntry))
|
||||
if (docAcc->BindToDocument(newAcc, roleMapEntry))
|
||||
return newAcc.forget();
|
||||
return nsnull;
|
||||
}
|
||||
@ -1348,22 +1333,29 @@ nsAccessibilityService::GetAreaAccessible(nsIFrame* aImageFrame,
|
||||
|
||||
// Try to get image map accessible from the global cache or create it
|
||||
// if failed.
|
||||
nsRefPtr<nsAccessible> imageAcc =
|
||||
GetCachedAccessible(aImageFrame->GetContent(), aWeakShell);
|
||||
if (!imageAcc) {
|
||||
imageAcc = CreateHTMLImageAccessible(aImageFrame->GetContent(),
|
||||
nsRefPtr<nsAccessible> image = GetCachedAccessible(aImageFrame->GetContent(),
|
||||
aWeakShell);
|
||||
if (!image) {
|
||||
image = CreateHTMLImageAccessible(aImageFrame->GetContent(),
|
||||
aImageFrame->PresContext()->PresShell());
|
||||
|
||||
if (!InitAccessible(imageAcc, nsnull))
|
||||
nsDocAccessible* document =
|
||||
GetAccService()->GetDocAccessible(aAreaNode->GetOwnerDoc());
|
||||
if (!document) {
|
||||
NS_NOTREACHED("No document for accessible being created!");
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (!document->BindToDocument(image, nsnull))
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
if (aImageAccessible)
|
||||
*aImageAccessible = imageAcc;
|
||||
*aImageAccessible = image;
|
||||
|
||||
// Make sure <area> accessible children of the image map are cached so
|
||||
// that they should be available in global cache.
|
||||
imageAcc->EnsureChildren();
|
||||
image->EnsureChildren();
|
||||
|
||||
return GetCachedAccessible(aAreaNode, aWeakShell);
|
||||
}
|
||||
@ -1771,7 +1763,7 @@ nsAccessibilityService::AddNativeRootAccessible(void* aAtkAccessible)
|
||||
if (!applicationAcc)
|
||||
return nsnull;
|
||||
|
||||
nsNativeRootAccessibleWrap* nativeRootAcc =
|
||||
nsRefPtr<nsNativeRootAccessibleWrap> nativeRootAcc =
|
||||
new nsNativeRootAccessibleWrap((AtkObject*)aAtkAccessible);
|
||||
if (!nativeRootAcc)
|
||||
return nsnull;
|
||||
|
@ -202,19 +202,6 @@ public:
|
||||
GetCachedAccessibleOrContainer(aNode->GetNodeParent()) : nsnull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize an accessible and cache it. The method should be called for
|
||||
* every created accessible.
|
||||
*
|
||||
* @param aAccessible [in] accessible to initialize.
|
||||
* @param aRoleMapEntry [in] the role map entry role the ARIA role or nsnull
|
||||
* if none
|
||||
*
|
||||
* @return true if the accessible was initialized, otherwise false
|
||||
*/
|
||||
PRBool InitAccessible(nsAccessible *aAccessible,
|
||||
nsRoleMapEntry *aRoleMapEntry);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Return an accessible for the DOM node in the given presentation shell if
|
||||
|
@ -2621,19 +2621,6 @@ nsAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset, PRUint32 aLe
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessNode public methods
|
||||
|
||||
PRBool
|
||||
nsAccessible::Init()
|
||||
{
|
||||
if (!nsAccessNodeWrap::Init())
|
||||
return PR_FALSE;
|
||||
|
||||
nsDocAccessible* document =
|
||||
GetAccService()->GetDocAccessible(mContent->GetOwnerDoc());
|
||||
NS_ASSERTION(document, "Cannot cache new nsAccessible!");
|
||||
|
||||
return document ? document->CacheAccessible(this) : PR_FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
nsAccessible::Shutdown()
|
||||
{
|
||||
@ -2912,20 +2899,6 @@ nsAccessible::GetIndexOfEmbeddedChild(nsAccessible* aChild)
|
||||
return GetIndexOf(aChild);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
PRBool
|
||||
nsAccessible::IsInCache()
|
||||
{
|
||||
nsDocAccessible *docAccessible =
|
||||
GetAccService()->GetDocAccessible(mContent->GetOwnerDoc());
|
||||
if (docAccessible)
|
||||
return docAccessible->GetCachedAccessibleByUniqueID(UniqueID()) ? PR_TRUE : PR_FALSE;
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// HyperLinkAccessible methods
|
||||
|
||||
|
@ -113,7 +113,6 @@ public:
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessNode
|
||||
|
||||
virtual PRBool Init();
|
||||
virtual void Shutdown();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@ -298,13 +297,6 @@ public:
|
||||
PRBool AreChildrenCached() const { return mChildrenFlags != eChildrenUninitialized; }
|
||||
bool IsBoundToParent() const { return mParent; }
|
||||
|
||||
#ifdef DEBUG
|
||||
/**
|
||||
* Return true if the access node is cached.
|
||||
*/
|
||||
PRBool IsInCache();
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Miscellaneous methods
|
||||
|
||||
|
@ -599,31 +599,6 @@ nsDocAccessible::GetCachedAccessible(nsINode *aNode)
|
||||
return accessible;
|
||||
}
|
||||
|
||||
// nsDocAccessible public method
|
||||
PRBool
|
||||
nsDocAccessible::CacheAccessible(nsAccessible* aAccessible)
|
||||
{
|
||||
if (aAccessible->IsPrimaryForNode() &&
|
||||
!mNodeToAccessibleMap.Put(aAccessible->GetNode(), aAccessible))
|
||||
return PR_FALSE;
|
||||
|
||||
return mAccessibleCache.Put(aAccessible->UniqueID(), aAccessible);
|
||||
}
|
||||
|
||||
// nsDocAccessible public method
|
||||
void
|
||||
nsDocAccessible::ShutdownAccessible(nsAccessible *aAccessible)
|
||||
{
|
||||
// Remove an accessible from node to accessible map if it is presented there.
|
||||
if (aAccessible->IsPrimaryForNode() &&
|
||||
mNodeToAccessibleMap.Get(aAccessible->GetNode()) == aAccessible)
|
||||
mNodeToAccessibleMap.Remove(aAccessible->GetNode());
|
||||
|
||||
void* uniqueID = aAccessible->UniqueID();
|
||||
aAccessible->Shutdown();
|
||||
mAccessibleCache.Remove(uniqueID);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessNode
|
||||
|
||||
@ -1345,6 +1320,55 @@ nsDocAccessible::GetCachedAccessibleByUniqueIDInSubtree(void* aUniqueID)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocAccessible::BindToDocument(nsAccessible* aAccessible,
|
||||
nsRoleMapEntry* aRoleMapEntry)
|
||||
{
|
||||
if (!aAccessible)
|
||||
return false;
|
||||
|
||||
// Put into DOM node cache.
|
||||
if (aAccessible->IsPrimaryForNode() &&
|
||||
!mNodeToAccessibleMap.Put(aAccessible->GetNode(), aAccessible))
|
||||
return false;
|
||||
|
||||
// Put into unique ID cache.
|
||||
if (!mAccessibleCache.Put(aAccessible->UniqueID(), aAccessible)) {
|
||||
if (aAccessible->IsPrimaryForNode())
|
||||
mNodeToAccessibleMap.Remove(aAccessible->GetNode());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Initialize the accessible.
|
||||
if (!aAccessible->Init()) {
|
||||
NS_ERROR("Failed to initialize an accessible!");
|
||||
|
||||
UnbindFromDocument(aAccessible);
|
||||
return false;
|
||||
}
|
||||
|
||||
aAccessible->SetRoleMapEntry(aRoleMapEntry);
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocAccessible::UnbindFromDocument(nsAccessible* aAccessible)
|
||||
{
|
||||
// Remove an accessible from node to accessible map if it is presented there.
|
||||
if (aAccessible->IsPrimaryForNode() &&
|
||||
mNodeToAccessibleMap.Get(aAccessible->GetNode()) == aAccessible)
|
||||
mNodeToAccessibleMap.Remove(aAccessible->GetNode());
|
||||
|
||||
#ifdef DEBUG
|
||||
NS_ASSERTION(mAccessibleCache.GetWeak(aAccessible->UniqueID()),
|
||||
"Illegitimate illegitimated accessible!");
|
||||
#endif
|
||||
|
||||
void* uniqueID = aAccessible->UniqueID();
|
||||
aAccessible->Shutdown();
|
||||
mAccessibleCache.Remove(uniqueID);
|
||||
}
|
||||
|
||||
void
|
||||
nsDocAccessible::UpdateTree(nsIContent* aContainerNode,
|
||||
nsIContent* aStartNode,
|
||||
@ -1761,10 +1785,6 @@ nsDocAccessible::UncacheChildrenInSubtree(nsAccessible* aRoot)
|
||||
void
|
||||
nsDocAccessible::ShutdownChildrenInSubtree(nsAccessible* aAccessible)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
nsAccessible* incache = mAccessibleCache.GetWeak(aAccessible->UniqueID());
|
||||
#endif
|
||||
|
||||
// Traverse through children and shutdown them before this accessible. When
|
||||
// child gets shutdown then it removes itself from children array of its
|
||||
//parent. Use jdx index to process the cases if child is not attached to the
|
||||
@ -1780,6 +1800,6 @@ nsDocAccessible::ShutdownChildrenInSubtree(nsAccessible* aAccessible)
|
||||
ShutdownChildrenInSubtree(child);
|
||||
}
|
||||
|
||||
ShutdownAccessible(aAccessible);
|
||||
UnbindFromDocument(aAccessible);
|
||||
}
|
||||
|
||||
|
@ -211,18 +211,18 @@ public:
|
||||
nsAccessible* GetCachedAccessibleByUniqueIDInSubtree(void* aUniqueID);
|
||||
|
||||
/**
|
||||
* Cache the accessible.
|
||||
* Initialize the newly created accessible and put it into document caches.
|
||||
*
|
||||
* @param aAccessible [in] accessible to cache
|
||||
*
|
||||
* @return true if accessible being cached, otherwise false
|
||||
* @param aAccessible [in] created accessible
|
||||
* @param aRoleMapEntry [in] the role map entry role the ARIA role or nsnull
|
||||
* if none
|
||||
*/
|
||||
PRBool CacheAccessible(nsAccessible *aAccessible);
|
||||
bool BindToDocument(nsAccessible* aAccessible, nsRoleMapEntry* aRoleMapEntry);
|
||||
|
||||
/**
|
||||
* Shutdown the accessible and remove it from document cache.
|
||||
* Remove the existing accessible from document caches and shutdown it.
|
||||
*/
|
||||
void ShutdownAccessible(nsAccessible *aAccessible);
|
||||
void UnbindFromDocument(nsAccessible* aAccessible);
|
||||
|
||||
/**
|
||||
* Process the event when the queue of pending events is untwisted. Fire
|
||||
|
@ -40,6 +40,7 @@
|
||||
#include "nsHTMLImageMapAccessible.h"
|
||||
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsDocAccessible.h"
|
||||
|
||||
#include "nsIDOMHTMLCollection.h"
|
||||
#include "nsIServiceManager.h"
|
||||
@ -114,6 +115,8 @@ nsHTMLImageMapAccessible::CacheChildren()
|
||||
if (!mapAreas)
|
||||
return;
|
||||
|
||||
nsDocAccessible* document = GetDocAccessible();
|
||||
|
||||
PRUint32 areaCount = 0;
|
||||
mapAreas->GetLength(&areaCount);
|
||||
|
||||
@ -124,21 +127,13 @@ nsHTMLImageMapAccessible::CacheChildren()
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIContent> areaContent(do_QueryInterface(areaNode));
|
||||
nsRefPtr<nsAccessible> areaAcc =
|
||||
nsRefPtr<nsAccessible> area =
|
||||
new nsHTMLAreaAccessible(areaContent, mWeakShell);
|
||||
if (!areaAcc)
|
||||
return;
|
||||
|
||||
if (!areaAcc->Init()) {
|
||||
areaAcc->Shutdown();
|
||||
if (!document->BindToDocument(area, nsAccUtils::GetRoleMapEntry(areaContent)) ||
|
||||
!AppendChild(area)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We must respect ARIA on area elements (for the canvas map technique)
|
||||
areaAcc->SetRoleMapEntry(nsAccUtils::GetRoleMapEntry(areaContent));
|
||||
|
||||
if (!AppendChild(areaAcc))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -692,22 +692,18 @@ nsHTMLComboboxAccessible::CacheChildren()
|
||||
if (!mListAccessible) {
|
||||
mListAccessible =
|
||||
new nsHTMLComboboxListAccessible(mParent, mContent, mWeakShell);
|
||||
if (!mListAccessible)
|
||||
return;
|
||||
|
||||
// Initialize and put into cache.
|
||||
if (!mListAccessible->Init()) {
|
||||
mListAccessible->Shutdown();
|
||||
if (!GetDocAccessible()->BindToDocument(mListAccessible, nsnull))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
AppendChild(mListAccessible);
|
||||
|
||||
// Cache combobox option accessibles so that we build complete accessible tree
|
||||
// for combobox.
|
||||
if (AppendChild(mListAccessible)) {
|
||||
// Cache combobox option accessibles so that we build complete accessible
|
||||
// tree for combobox.
|
||||
mListAccessible->EnsureChildren();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsHTMLComboboxAccessible::Shutdown()
|
||||
|
@ -259,8 +259,7 @@ nsHTMLLIAccessible::
|
||||
nsBlockFrame* blockFrame = do_QueryFrame(GetFrame());
|
||||
if (blockFrame && !blockFrame->BulletIsEmptyExternal()) {
|
||||
mBulletAccessible = new nsHTMLListBulletAccessible(mContent, mWeakShell);
|
||||
if (mBulletAccessible)
|
||||
mBulletAccessible->Init();
|
||||
GetDocAccessible()->BindToDocument(mBulletAccessible, nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsAccTreeWalker.h"
|
||||
#include "nsCoreUtils.h"
|
||||
#include "nsDocAccessible.h"
|
||||
|
||||
#include "nsIDOMElement.h"
|
||||
|
||||
@ -171,5 +172,8 @@ nsXULColorPickerAccessible::CacheChildren()
|
||||
AppendChild(child);
|
||||
return;
|
||||
}
|
||||
|
||||
// Unbind rejected accessibles from the document.
|
||||
GetDocAccessible()->UnbindFromDocument(child);
|
||||
}
|
||||
}
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsAccTreeWalker.h"
|
||||
#include "nsCoreUtils.h"
|
||||
#include "nsDocAccessible.h"
|
||||
#include "nsRelUtils.h"
|
||||
|
||||
// NOTE: alphabetically ordered
|
||||
@ -222,6 +223,10 @@ nsXULButtonAccessible::CacheChildren()
|
||||
// for it. Ignore dropmarker button what is placed as a last child.
|
||||
buttonAccessible.swap(child);
|
||||
break;
|
||||
|
||||
} else {
|
||||
// Unbind rejected accessible from document.
|
||||
GetDocAccessible()->UnbindFromDocument(child);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -472,25 +472,23 @@ nsXULTreeAccessible::GetTreeItemAccessible(PRInt32 aRow)
|
||||
return nsnull;
|
||||
|
||||
void *key = reinterpret_cast<void*>(aRow);
|
||||
nsRefPtr<nsAccessible> accessible = mAccessibleCache.GetWeak(key);
|
||||
nsAccessible* cachedTreeItem = mAccessibleCache.GetWeak(key);
|
||||
if (cachedTreeItem)
|
||||
return cachedTreeItem;
|
||||
|
||||
if (!accessible) {
|
||||
accessible = CreateTreeItemAccessible(aRow);
|
||||
if (!accessible)
|
||||
return nsnull;
|
||||
nsRefPtr<nsAccessible> treeItem = CreateTreeItemAccessible(aRow);
|
||||
if (treeItem) {
|
||||
if (mAccessibleCache.Put(key, treeItem)) {
|
||||
if (GetDocAccessible()->BindToDocument(treeItem, nsnull))
|
||||
return treeItem;
|
||||
|
||||
if (!accessible->Init()) {
|
||||
accessible->Shutdown();
|
||||
return nsnull;
|
||||
mAccessibleCache.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mAccessibleCache.Put(key, accessible))
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
void
|
||||
nsXULTreeAccessible::InvalidateCache(PRInt32 aRow, PRInt32 aCount)
|
||||
{
|
||||
@ -501,22 +499,21 @@ nsXULTreeAccessible::InvalidateCache(PRInt32 aRow, PRInt32 aCount)
|
||||
if (aCount > 0)
|
||||
return;
|
||||
|
||||
nsDocAccessible* document = GetDocAccessible();
|
||||
|
||||
// Fire destroy event for removed tree items and delete them from caches.
|
||||
for (PRInt32 rowIdx = aRow; rowIdx < aRow - aCount; rowIdx++) {
|
||||
|
||||
void* key = reinterpret_cast<void*>(rowIdx);
|
||||
nsAccessible *accessible = mAccessibleCache.GetWeak(key);
|
||||
nsAccessible* treeItem = mAccessibleCache.GetWeak(key);
|
||||
|
||||
if (accessible) {
|
||||
if (treeItem) {
|
||||
nsRefPtr<AccEvent> event =
|
||||
new AccEvent(nsIAccessibleEvent::EVENT_HIDE, accessible);
|
||||
new AccEvent(nsIAccessibleEvent::EVENT_HIDE, treeItem);
|
||||
nsEventShell::FireEvent(event);
|
||||
|
||||
// Shutdown and remove accessible from document cache and tree cache.
|
||||
nsDocAccessible *docAccessible = GetDocAccessible();
|
||||
if (docAccessible)
|
||||
docAccessible->ShutdownAccessible(accessible);
|
||||
|
||||
// Unbind from document, shutdown and remove from tree cache.
|
||||
document->UnbindFromDocument(treeItem);
|
||||
mAccessibleCache.Remove(key);
|
||||
}
|
||||
}
|
||||
@ -534,14 +531,11 @@ nsXULTreeAccessible::InvalidateCache(PRInt32 aRow, PRInt32 aCount)
|
||||
for (PRInt32 rowIdx = newRowCount; rowIdx < oldRowCount; ++rowIdx) {
|
||||
|
||||
void *key = reinterpret_cast<void*>(rowIdx);
|
||||
nsAccessible *accessible = mAccessibleCache.GetWeak(key);
|
||||
|
||||
if (accessible) {
|
||||
// Shutdown and remove accessible from document cache and tree cache.
|
||||
nsDocAccessible *docAccessible = GetDocAccessible();
|
||||
if (docAccessible)
|
||||
docAccessible->ShutdownAccessible(accessible);
|
||||
nsAccessible* treeItem = mAccessibleCache.GetWeak(key);
|
||||
|
||||
if (treeItem) {
|
||||
// Unbind from document, shutdown and remove from tree cache.
|
||||
document->UnbindFromDocument(treeItem);
|
||||
mAccessibleCache.Remove(key);
|
||||
}
|
||||
}
|
||||
|
@ -41,6 +41,7 @@
|
||||
#include "nsAccCache.h"
|
||||
#include "nsAccessibilityService.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "nsDocAccessible.h"
|
||||
#include "nsEventShell.h"
|
||||
|
||||
#include "nsITreeSelection.h"
|
||||
@ -729,27 +730,25 @@ nsXULTreeGridRowAccessible::GetCellAccessible(nsITreeColumn* aColumn)
|
||||
NS_PRECONDITION(aColumn, "No tree column!");
|
||||
|
||||
void* key = static_cast<void*>(aColumn);
|
||||
nsRefPtr<nsAccessible> accessible = mAccessibleCache.GetWeak(key);
|
||||
nsAccessible* cachedCell = mAccessibleCache.GetWeak(key);
|
||||
if (cachedCell)
|
||||
return cachedCell;
|
||||
|
||||
if (!accessible) {
|
||||
accessible =
|
||||
nsRefPtr<nsAccessible> cell =
|
||||
new nsXULTreeGridCellAccessibleWrap(mContent, mWeakShell, this, mTree,
|
||||
mTreeView, mRow, aColumn);
|
||||
if (!accessible)
|
||||
return nsnull;
|
||||
if (cell) {
|
||||
if (mAccessibleCache.Put(key, cell)) {
|
||||
if (GetDocAccessible()->BindToDocument(cell, nsnull))
|
||||
return cell;
|
||||
|
||||
if (!accessible->Init()) {
|
||||
accessible->Shutdown();
|
||||
return nsnull;
|
||||
mAccessibleCache.Remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
if (!mAccessibleCache.Put(key, accessible))
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
return accessible;
|
||||
}
|
||||
|
||||
void
|
||||
nsXULTreeGridRowAccessible::RowInvalidated(PRInt32 aStartColIdx,
|
||||
PRInt32 aEndColIdx)
|
||||
|
Loading…
Reference in New Issue
Block a user