Bug 367781, adoptNode should update mMutationBits of the possible |window| object. r+sr=peterv

This commit is contained in:
Olli.Pettay%helsinki.fi 2007-01-31 22:54:24 +00:00
Родитель 17622fbadd
Коммит 774d83e41b
4 изменённых файлов: 81 добавлений и 34 удалений

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

@ -49,6 +49,7 @@
#include "pldhash.h"
#include "nsIDOMAttr.h"
#include "nsCOMArray.h"
#include "nsPIDOMWindow.h"
#ifdef MOZ_XUL
#include "nsXULElement.h"
#endif
@ -417,6 +418,16 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
else if (nodeInfoManager) {
aNode->mNodeInfo.swap(newNodeInfo);
nsIDocument* newDoc = aNode->GetOwnerDoc();
nsPIDOMWindow* window = newDoc ? newDoc->GetInnerWindow() : nsnull;
if (window) {
nsCOMPtr<nsIEventListenerManager> elm;
aNode->GetListenerManager(PR_FALSE, getter_AddRefs(elm));
if (elm) {
window->SetMutationListeners(elm->MutationListenerBits());
}
}
if (elem) {
elem->RecompileScriptEventListeners();
}

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

@ -52,8 +52,8 @@ class nsIAtom;
* Event listener manager interface.
*/
#define NS_IEVENTLISTENERMANAGER_IID \
{ 0x5e7dc4c0, 0x3d7e, 0x4934, \
{ 0xb6, 0x54, 0xd7, 0xe3, 0x74, 0xa0, 0x37, 0xdf } }
{ 0x06177dc7, 0x4ad9, 0x493c, \
{ 0x9c, 0x04, 0x28, 0xf0, 0xf7, 0x39, 0xa0, 0xfe } }
class nsIEventListenerManager : public nsISupports {
@ -174,6 +174,14 @@ public:
* listeners registered.
*/
virtual PRBool HasUnloadListeners() = 0;
/**
* Returns the mutation bits depending on which mutation listeners are
* registered to this listener manager.
* @note If a listener is an nsIDOMMutationListener, all possible mutation
* event bits are returned.
*/
virtual PRUint32 MutationListenerBits() = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIEventListenerManager,

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

@ -122,6 +122,39 @@ static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
static NS_DEFINE_CID(kDOMEventGroupCID, NS_DOMEVENTGROUP_CID);
static const PRUint32 kAllMutationBits =
NS_EVENT_BITS_MUTATION_SUBTREEMODIFIED |
NS_EVENT_BITS_MUTATION_NODEINSERTED |
NS_EVENT_BITS_MUTATION_NODEREMOVED |
NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT |
NS_EVENT_BITS_MUTATION_NODEINSERTEDINTODOCUMENT |
NS_EVENT_BITS_MUTATION_ATTRMODIFIED |
NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED;
static PRUint32
MutationBitForEventType(PRUint32 aEventType)
{
switch (aEventType) {
case NS_MUTATION_SUBTREEMODIFIED:
return NS_EVENT_BITS_MUTATION_SUBTREEMODIFIED;
case NS_MUTATION_NODEINSERTED:
return NS_EVENT_BITS_MUTATION_NODEINSERTED;
case NS_MUTATION_NODEREMOVED:
return NS_EVENT_BITS_MUTATION_NODEREMOVED;
case NS_MUTATION_NODEREMOVEDFROMDOCUMENT:
return NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT;
case NS_MUTATION_NODEINSERTEDINTODOCUMENT:
return NS_EVENT_BITS_MUTATION_NODEINSERTEDINTODOCUMENT;
case NS_MUTATION_ATTRMODIFIED:
return NS_EVENT_BITS_MUTATION_ATTRMODIFIED;
case NS_MUTATION_CHARACTERDATAMODIFIED:
return NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED;
default:
break;
}
return 0;
}
typedef
NS_STDCALL_FUNCPROTO(nsresult,
GenericHandler,
@ -544,39 +577,9 @@ nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener,
if (ls->mTypeData) {
// If we have type data, nsIDOMMutationListener is used and so we
// have to listen all mutation events.
window->SetMutationListeners(NS_EVENT_BITS_MUTATION_SUBTREEMODIFIED |
NS_EVENT_BITS_MUTATION_NODEINSERTED |
NS_EVENT_BITS_MUTATION_NODEREMOVED |
NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT |
NS_EVENT_BITS_MUTATION_NODEINSERTEDINTODOCUMENT |
NS_EVENT_BITS_MUTATION_ATTRMODIFIED |
NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED);
window->SetMutationListeners(kAllMutationBits);
} else {
switch (aType) {
case NS_MUTATION_SUBTREEMODIFIED:
window->SetMutationListeners(NS_EVENT_BITS_MUTATION_SUBTREEMODIFIED);
break;
case NS_MUTATION_NODEINSERTED:
window->SetMutationListeners(NS_EVENT_BITS_MUTATION_NODEINSERTED);
break;
case NS_MUTATION_NODEREMOVED:
window->SetMutationListeners(NS_EVENT_BITS_MUTATION_NODEREMOVED);
break;
case NS_MUTATION_NODEREMOVEDFROMDOCUMENT:
window->SetMutationListeners(NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT);
break;
case NS_MUTATION_NODEINSERTEDINTODOCUMENT:
window->SetMutationListeners(NS_EVENT_BITS_MUTATION_NODEINSERTEDINTODOCUMENT);
break;
case NS_MUTATION_ATTRMODIFIED:
window->SetMutationListeners(NS_EVENT_BITS_MUTATION_ATTRMODIFIED);
break;
case NS_MUTATION_CHARACTERDATAMODIFIED:
window->SetMutationListeners(NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED);
break;
default:
break;
}
window->SetMutationListeners(MutationBitForEventType(aType));
}
}
}
@ -1910,6 +1913,29 @@ nsEventListenerManager::HasMutationListeners(PRBool* aListener)
return NS_OK;
}
PRUint32
nsEventListenerManager::MutationListenerBits()
{
PRUint32 bits = 0;
if (mMayHaveMutationListeners) {
PRInt32 i, count = mListeners.Count();
for (i = 0; i < count; ++i) {
nsListenerStruct* ls = NS_STATIC_CAST(nsListenerStruct*,
mListeners.FastElementAt(i));
if (ls && ls->mTypeData && ls->mTypeData->iid &&
ls->mTypeData->iid->Equals(NS_GET_IID(nsIDOMMutationListener))) {
return kAllMutationBits;
}
if (ls &&
(ls->mEventType >= NS_MUTATION_START &&
ls->mEventType <= NS_MUTATION_END)) {
bits |= MutationBitForEventType(ls->mEventType);
}
}
}
return bits;
}
PRBool
nsEventListenerManager::HasUnloadListeners()
{

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

@ -127,6 +127,8 @@ public:
virtual PRBool HasUnloadListeners();
virtual PRUint32 MutationListenerBits();
static PRUint32 GetIdentifierForEvent(nsIAtom* aEvent);
// nsIDOMEventTarget