Bug 377737. Fix Shutdown() process for a11y objects whose refcount becomes 0. Patch by mats.palmgren. r=aaronlev, sr=bz

This commit is contained in:
aaronleventhal@moonset.net 2007-04-23 08:37:55 -07:00
Родитель baab01ada6
Коммит 3ada1c19e4
9 изменённых файлов: 39 добавлений и 16 удалений

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

@ -78,6 +78,7 @@ NS_IMETHODIMP nsRootAccessibleWrap::Shutdown()
nsAppRootAccessible *root = nsAppRootAccessible::Create();
if (root) {
root->RemoveRootAccessible(this);
root = nsnull;
}
return nsRootAccessible::Shutdown();
}

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

@ -98,7 +98,9 @@ nsIAccessibilityService *nsAccessNode::GetAccService()
//-----------------------------------------------------
// construction
//-----------------------------------------------------
NS_IMPL_ISUPPORTS2(nsAccessNode, nsIAccessNode, nsPIAccessNode)
NS_IMPL_QUERY_INTERFACE2(nsAccessNode, nsIAccessNode, nsPIAccessNode)
NS_IMPL_ADDREF(nsAccessNode)
NS_IMPL_RELEASE_WITH_DESTROY(nsAccessNode, LastRelease())
nsAccessNode::nsAccessNode(nsIDOMNode *aNode, nsIWeakReference* aShell):
mDOMNode(aNode), mWeakShell(aShell)
@ -113,9 +115,18 @@ nsAccessNode::nsAccessNode(nsIDOMNode *aNode, nsIWeakReference* aShell):
//-----------------------------------------------------
nsAccessNode::~nsAccessNode()
{
NS_ASSERTION(!mWeakShell, "LastRelease was never called!?!");
}
void nsAccessNode::LastRelease()
{
// First cleanup if needed...
if (mWeakShell) {
Shutdown(); // Otherwise virtual Shutdown() methods could get fired twice
Shutdown();
NS_ASSERTION(!mWeakShell, "A Shutdown() impl forgot to call its parent's Shutdown?");
}
// ... then die.
NS_DELETEXPCOM(this);
}
NS_IMETHODIMP nsAccessNode::Init()

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

@ -156,6 +156,7 @@ protected:
already_AddRefed<nsIPresShell> GetPresShell();
nsPresContext* GetPresContext();
already_AddRefed<nsIAccessibleDocument> GetDocAccessible();
void LastRelease();
nsCOMPtr<nsIDOMNode> mDOMNode;
nsCOMPtr<nsIWeakReference> mWeakShell;

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

@ -255,14 +255,17 @@ nsAccessible::nsAccessible(nsIDOMNode* aNode, nsIWeakReference* aShell): nsAcces
#ifdef NS_DEBUG_X
{
nsCOMPtr<nsIPresShell> shell(do_QueryReferent(aShell));
printf(">>> %p Created Acc - Con: %p Acc: %p PS: %p",
(nsIAccessible*)this, aContent, aAccessible, shell.get());
if (shell && aContent != nsnull) {
nsIFrame* frame = shell->GetPrimaryFrameFor(aContent);
char * name;
if (GetNameForFrame(frame, &name)) {
printf(" Name:[%s]", name);
nsMemory::Free(name);
printf(">>> %p Created Acc - DOM: %p PS: %p",
(void*)NS_STATIC_CAST(nsIAccessible*, this), (void*)aNode,
(void*)shell.get());
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
if (content) {
nsAutoString buf;
if (content->NodeInfo())
content->NodeInfo()->GetQualifiedName(buf);
printf(" Con: %s@%p", NS_ConvertUTF16toUTF8(buf).get(), (void *)content.get());
if (NS_SUCCEEDED(GetName(buf))) {
printf(" Name:[%s]", NS_ConvertUTF16toUTF8(buf).get());
}
}
printf("\n");

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

@ -67,7 +67,8 @@ NS_IMETHODIMP nsCaretAccessible::Shutdown()
mLastNodeWithCaret = nsnull;
mSelectionControllerNode = nsnull;
RemoveSelectionListener();
return NS_OK;
return nsLeafAccessible::Shutdown();
}
NS_IMETHODIMP nsCaretAccessible::RemoveSelectionListener()

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

@ -497,7 +497,9 @@ NS_IMETHODIMP nsDocAccessible::Init()
NS_IMETHODIMP nsDocAccessible::Destroy()
{
gGlobalDocAccessibleCache.Remove(NS_STATIC_CAST(void*, mWeakShell));
if (mWeakShell) {
gGlobalDocAccessibleCache.Remove(NS_STATIC_CAST(void*, mWeakShell));
}
return Shutdown();
}

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

@ -892,7 +892,7 @@ void nsRootAccessible::FireFocusCallback(nsITimer *aTimer, void *aClosure)
NS_IMETHODIMP nsRootAccessible::Shutdown()
{
// Called manually or by nsAccessNode::~nsAccessNode()
// Called manually or by nsAccessNode::LastRelease()
if (!mWeakShell) {
return NS_OK; // Already shutdown
}

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

@ -252,7 +252,7 @@ NS_IMETHODIMP nsHTMLLIAccessible::Shutdown()
// Ensure that weak pointer to this is nulled out
mBulletAccessible->Shutdown();
}
nsresult rv = nsAccessibleWrap::Shutdown();
nsresult rv = nsHyperTextAccessible::Shutdown();
mBulletAccessible = nsnull;
return rv;
}

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

@ -741,8 +741,12 @@ nsXULTextFieldAccessible::GetState(PRUint32 *aState, PRUint32 *aExtraState)
// Create a temporary accessible from the HTML text field
// to get the accessible state from. Doesn't add to cache
// because Init() is not called.
nsHTMLTextFieldAccessible tempAccessible(inputField, mWeakShell);
rv = tempAccessible.GetState(aState, nsnull);
nsHTMLTextFieldAccessible* tempAccessible =
new nsHTMLTextFieldAccessible(inputField, mWeakShell);
if (!tempAccessible)
return NS_ERROR_OUT_OF_MEMORY;
nsCOMPtr<nsIAccessible> kungFuDeathGrip = tempAccessible;
rv = tempAccessible->GetState(aState, nsnull);
NS_ENSURE_SUCCESS(rv, rv);
if (gLastFocusedNode == mDOMNode) {