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
{
PwmgrInputsEnumData(nsIMutationObserver* aMutationObserver, nsIDocument* aDoc)
: mMutationObserver(aMutationObserver), mDoc(aDoc) {}
PwmgrInputsEnumData(nsFormFillController* aFFC, nsIDocument* aDoc)
: mFFC(aFFC), mDoc(aDoc) {}
nsIMutationObserver* mMutationObserver;
nsFormFillController* mFFC;
nsCOMPtr<nsIDocument> mDoc;
};
nsFormFillController::~nsFormFillController()
{
PwmgrInputsEnumData ed(this, nsnull);
mPwmgrInputs.Enumerate(RemoveForDocumentEnumerator, &ed);
if (mListNode) {
mListNode->RemoveMutationObserver(this);
mListNode = nsnull;
}
if (mFocusedInputNode) {
mFocusedInputNode->RemoveMutationObserver(this);
MaybeRemoveMutationObserver(mFocusedInputNode);
mFocusedInputNode = nsnull;
mFocusedInput = nsnull;
}
PwmgrInputsEnumData ed(this, nsnull);
mPwmgrInputs.Enumerate(RemoveForDocumentEnumerator, &ed);
// Remove ourselves as a focus listener from all cached docShells
PRUint32 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
@ -796,7 +808,10 @@ nsFormFillController::RemoveForDocumentEnumerator(const nsINode* aKey,
{
PwmgrInputsEnumData* ed = static_cast<PwmgrInputsEnumData*>(aUserData);
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_NEXT;
@ -1105,7 +1120,7 @@ nsFormFillController::StopControllingInput()
mController->SetInput(nsnull);
if (mFocusedInputNode) {
mFocusedInputNode->RemoveMutationObserver(this);
MaybeRemoveMutationObserver(mFocusedInputNode);
mFocusedInputNode = nsnull;
mFocusedInput = nsnull;
}

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

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