Bug 730470, FormFillController crashes, r=gavin

This commit is contained in:
Olli Pettay 2012-02-28 01:31:23 +02:00
Родитель 609f726108
Коммит 1caa5d5eb4
2 изменённых файлов: 25 добавлений и 8 удалений

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

@ -101,26 +101,27 @@ nsFormFillController::nsFormFillController() :
struct PwmgrInputsEnumData struct PwmgrInputsEnumData
{ {
PwmgrInputsEnumData(nsIMutationObserver* aMutationObserver, nsIDocument* aDoc) PwmgrInputsEnumData(nsFormFillController* aFFC, nsIDocument* aDoc)
: mMutationObserver(aMutationObserver), mDoc(aDoc) {} : mFFC(aFFC), mDoc(aDoc) {}
nsIMutationObserver* mMutationObserver; nsFormFillController* mFFC;
nsCOMPtr<nsIDocument> mDoc; nsCOMPtr<nsIDocument> mDoc;
}; };
nsFormFillController::~nsFormFillController() nsFormFillController::~nsFormFillController()
{ {
PwmgrInputsEnumData ed(this, nsnull);
mPwmgrInputs.Enumerate(RemoveForDocumentEnumerator, &ed);
if (mListNode) { if (mListNode) {
mListNode->RemoveMutationObserver(this); mListNode->RemoveMutationObserver(this);
mListNode = nsnull; mListNode = nsnull;
} }
if (mFocusedInputNode) { if (mFocusedInputNode) {
mFocusedInputNode->RemoveMutationObserver(this); MaybeRemoveMutationObserver(mFocusedInputNode);
mFocusedInputNode = nsnull; mFocusedInputNode = nsnull;
mFocusedInput = nsnull; mFocusedInput = nsnull;
} }
PwmgrInputsEnumData ed(this, nsnull);
mPwmgrInputs.Enumerate(RemoveForDocumentEnumerator, &ed);
// Remove ourselves as a focus listener from all cached docShells // Remove ourselves as a focus listener from all cached docShells
PRUint32 count; PRUint32 count;
mDocShells->Count(&count); mDocShells->Count(&count);
@ -221,6 +222,17 @@ nsFormFillController::NodeWillBeDestroyed(const nsINode* aNode)
} }
} }
void
nsFormFillController::MaybeRemoveMutationObserver(nsINode* aNode)
{
// Nodes being tracked in mPwmgrInputs will have their observers removed when
// they stop being tracked.
bool dummy;
if (!mPwmgrInputs.Get(aNode, &dummy)) {
aNode->RemoveMutationObserver(this);
}
}
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
//// nsIFormFillController //// nsIFormFillController
@ -796,7 +808,10 @@ nsFormFillController::RemoveForDocumentEnumerator(const nsINode* aKey,
{ {
PwmgrInputsEnumData* ed = static_cast<PwmgrInputsEnumData*>(aUserData); PwmgrInputsEnumData* ed = static_cast<PwmgrInputsEnumData*>(aUserData);
if (aKey && (!ed->mDoc || aKey->OwnerDoc() == ed->mDoc)) { if (aKey && (!ed->mDoc || aKey->OwnerDoc() == ed->mDoc)) {
const_cast<nsINode*>(aKey)->RemoveMutationObserver(ed->mMutationObserver); // mFocusedInputNode's observer is tracked separately, don't remove it here.
if (aKey != ed->mFFC->mFocusedInputNode) {
const_cast<nsINode*>(aKey)->RemoveMutationObserver(ed->mFFC);
}
return PL_DHASH_REMOVE; return PL_DHASH_REMOVE;
} }
return PL_DHASH_NEXT; return PL_DHASH_NEXT;
@ -1105,7 +1120,7 @@ nsFormFillController::StopControllingInput()
mController->SetInput(nsnull); mController->SetInput(nsnull);
if (mFocusedInputNode) { if (mFocusedInputNode) {
mFocusedInputNode->RemoveMutationObserver(this); MaybeRemoveMutationObserver(mFocusedInputNode);
mFocusedInputNode = nsnull; mFocusedInputNode = nsnull;
mFocusedInput = nsnull; mFocusedInput = nsnull;
} }

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

@ -101,6 +101,8 @@ protected:
inline nsIDOMWindow *GetWindowForDocShell(nsIDocShell *aDocShell); inline nsIDOMWindow *GetWindowForDocShell(nsIDocShell *aDocShell);
inline PRInt32 GetIndexOfDocShell(nsIDocShell *aDocShell); inline PRInt32 GetIndexOfDocShell(nsIDocShell *aDocShell);
void MaybeRemoveMutationObserver(nsINode* aNode);
static PLDHashOperator RemoveForDocumentEnumerator(const nsINode* aKey, static PLDHashOperator RemoveForDocumentEnumerator(const nsINode* aKey,
bool& aEntry, bool& aEntry,
void* aUserData); void* aUserData);