зеркало из https://github.com/mozilla/gecko-dev.git
Bug 730470, FormFillController crashes, r=gavin
This commit is contained in:
Родитель
609f726108
Коммит
1caa5d5eb4
|
@ -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);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче