зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
baab01ada6
Коммит
3ada1c19e4
|
@ -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) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче