зеркало из https://github.com/mozilla/pjs.git
Patch for 55595. r=joki, a=brendan
This commit is contained in:
Родитель
daa5773e5c
Коммит
56d558b610
|
@ -33,6 +33,9 @@
|
|||
#include "nsISelectionPrivate.h"
|
||||
#include "nsIEnumerator.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsMutationEvent.h"
|
||||
#include "nsEventListenerManager.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
#include "nsCRT.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
|
@ -909,6 +912,73 @@ nsGenericDOMDataNode::CopyText(nsAWritableString& aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static PRBool HasMutationListeners(nsIContent* aContent, PRUint32 aType)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aContent->GetDocument(*getter_AddRefs(doc));
|
||||
if (!doc)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> global;
|
||||
doc->GetScriptGlobalObject(getter_AddRefs(global));
|
||||
if (!global)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(global));
|
||||
if (!window)
|
||||
return PR_FALSE;
|
||||
|
||||
PRBool set;
|
||||
window->HasMutationListeners(aType, &set);
|
||||
if (!set)
|
||||
return PR_FALSE;
|
||||
|
||||
// We know a mutation listener is registered, but it might not
|
||||
// be in our chain. Check quickly to see.
|
||||
nsCOMPtr<nsIContent> curr = aContent;
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
while (curr) {
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(curr));
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> prev = curr;
|
||||
prev->GetParent(*getter_AddRefs(curr));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(doc));
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
rec = do_QueryInterface(window);
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericDOMDataNode::SetText(nsIContent *aOuterContent,
|
||||
const PRUnichar* aBuffer,
|
||||
|
@ -927,6 +997,22 @@ nsGenericDOMDataNode::SetText(nsIContent *aOuterContent,
|
|||
}
|
||||
mText.SetTo(aBuffer, aLength);
|
||||
|
||||
if (mDocument && HasMutationListeners(aOuterContent, NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(aOuterContent));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_CHARACTERDATAMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
// XXX Handle the setting of prevValue!
|
||||
nsAutoString newVal(aBuffer);
|
||||
if (!newVal.IsEmpty())
|
||||
mutation.mNewAttrValue = getter_AddRefs(NS_NewAtom(newVal));
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
// Trigger a reflow
|
||||
if (aNotify && (nsnull != mDocument)) {
|
||||
mDocument->ContentChanged(aOuterContent, nsnull);
|
||||
|
@ -951,6 +1037,22 @@ nsGenericDOMDataNode::SetText(nsIContent *aOuterContent, const char* aBuffer,
|
|||
}
|
||||
mText.SetTo(aBuffer, aLength);
|
||||
|
||||
if (mDocument && HasMutationListeners(aOuterContent, NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(aOuterContent));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_CHARACTERDATAMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
// XXX Handle the setting of prevValue!
|
||||
nsAutoString newVal; newVal.AssignWithConversion(aBuffer);
|
||||
if (!newVal.IsEmpty())
|
||||
mutation.mNewAttrValue = getter_AddRefs(NS_NewAtom(newVal));
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
// Trigger a reflow
|
||||
if (aNotify && (nsnull != mDocument)) {
|
||||
mDocument->ContentChanged(aOuterContent, nsnull);
|
||||
|
|
|
@ -61,12 +61,16 @@
|
|||
#include "prmem.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsScriptSecurityManager.h"
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
#include "nsMutationEvent.h"
|
||||
|
||||
#include "nsIBindingManager.h"
|
||||
#include "nsIXBLBinding.h"
|
||||
#include "nsIDOMCSSStyleDeclaration.h"
|
||||
#include "nsIDOMViewCSS.h"
|
||||
#include "nsIXBLService.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsEventListenerManager.h"
|
||||
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
|
@ -2718,6 +2722,73 @@ nsGenericContainerElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
return SetAttribute(ni, aValue, aNotify);
|
||||
}
|
||||
|
||||
static PRBool HasMutationListeners(nsIContent* aContent, PRUint32 aType)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aContent->GetDocument(*getter_AddRefs(doc));
|
||||
if (!doc)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> global;
|
||||
doc->GetScriptGlobalObject(getter_AddRefs(global));
|
||||
if (!global)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(global));
|
||||
if (!window)
|
||||
return PR_FALSE;
|
||||
|
||||
PRBool set;
|
||||
window->HasMutationListeners(aType, &set);
|
||||
if (!set)
|
||||
return PR_FALSE;
|
||||
|
||||
// We know a mutation listener is registered, but it might not
|
||||
// be in our chain. Check quickly to see.
|
||||
nsCOMPtr<nsIContent> curr = aContent;
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
while (curr) {
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(curr));
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> prev = curr;
|
||||
prev->GetParent(*getter_AddRefs(curr));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(doc));
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
rec = do_QueryInterface(window);
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericContainerElement::SetAttribute(nsINodeInfo* aNodeInfo,
|
||||
const nsAReadableString& aValue,
|
||||
|
@ -2725,6 +2796,9 @@ nsGenericContainerElement::SetAttribute(nsINodeInfo* aNodeInfo,
|
|||
{
|
||||
NS_ENSURE_ARG_POINTER(aNodeInfo);
|
||||
|
||||
PRBool modification = PR_FALSE;
|
||||
nsAutoString oldValue;
|
||||
|
||||
nsresult rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (!mAttributes) {
|
||||
|
@ -2742,6 +2816,8 @@ nsGenericContainerElement::SetAttribute(nsINodeInfo* aNodeInfo,
|
|||
for (index = 0; index < count; index++) {
|
||||
attr = (nsGenericAttribute*)mAttributes->ElementAt(index);
|
||||
if (attr->mNodeInfo == aNodeInfo) {
|
||||
oldValue = attr->mValue;
|
||||
modification = PR_TRUE;
|
||||
attr->mValue = aValue;
|
||||
rv = NS_OK;
|
||||
break;
|
||||
|
@ -2770,6 +2846,31 @@ nsGenericContainerElement::SetAttribute(nsINodeInfo* aNodeInfo,
|
|||
if (binding)
|
||||
binding->AttributeChanged(name, nameSpaceID, PR_FALSE);
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_ATTRMODIFIED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(mContent));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_ATTRMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsAutoString attrName;
|
||||
name->ToString(attrName);
|
||||
nsCOMPtr<nsIDOMAttr> attrNode;
|
||||
GetAttributeNode(attrName, getter_AddRefs(attrNode));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = name;
|
||||
if (!oldValue.IsEmpty())
|
||||
mutation.mPrevAttrValue = getter_AddRefs(NS_NewAtom(oldValue));
|
||||
if (!aValue.IsEmpty())
|
||||
mutation.mNewAttrValue = getter_AddRefs(NS_NewAtom(aValue));
|
||||
mutation.mAttrChange = modification ? nsIDOMMutationEvent::MODIFICATION :
|
||||
nsIDOMMutationEvent::ADDITION;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
mContent->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if (aNotify) {
|
||||
mDocument->AttributeChanged(mContent, nameSpaceID, name, NS_STYLE_HINT_UNKNOWN);
|
||||
mDocument->EndUpdate();
|
||||
|
@ -2854,6 +2955,30 @@ nsGenericContainerElement::UnsetAttribute(PRInt32 aNameSpaceID,
|
|||
if (aNotify && (nsnull != mDocument)) {
|
||||
mDocument->BeginUpdate();
|
||||
}
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_ATTRMODIFIED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(mContent));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_ATTRMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsAutoString attrName;
|
||||
aName->ToString(attrName);
|
||||
nsCOMPtr<nsIDOMAttr> attrNode;
|
||||
GetAttributeNode(attrName, getter_AddRefs(attrNode));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = aName;
|
||||
if (!attr->mValue.IsEmpty())
|
||||
mutation.mPrevAttrValue = getter_AddRefs(NS_NewAtom(attr->mValue));
|
||||
mutation.mAttrChange = nsIDOMMutationEvent::REMOVAL;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
mContent->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
mAttributes->RemoveElementAt(index);
|
||||
delete attr;
|
||||
found = PR_TRUE;
|
||||
|
@ -3036,6 +3161,21 @@ nsGenericContainerElement::InsertChildAt(nsIContent* aKid,
|
|||
if (aNotify) {
|
||||
doc->ContentInserted(mContent, aKid, aIndex);
|
||||
}
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(aKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEINSERTED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(mContent));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
aKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aNotify && (nsnull != doc)) {
|
||||
|
@ -3094,6 +3234,21 @@ nsGenericContainerElement::AppendChildTo(nsIContent* aKid, PRBool aNotify)
|
|||
if (aNotify) {
|
||||
doc->ContentAppended(mContent, mChildren.Count() - 1);
|
||||
}
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(aKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEINSERTED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(mContent));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
aKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aNotify && (nsnull != doc)) {
|
||||
|
@ -3111,6 +3266,22 @@ nsGenericContainerElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify)
|
|||
if (aNotify && (nsnull != doc)) {
|
||||
doc->BeginUpdate();
|
||||
}
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_NODEREMOVED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(oldKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEREMOVED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(mContent));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
oldKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
nsRange::OwnerChildRemoved(mContent, aIndex, oldKid);
|
||||
mChildren.RemoveElementAt(aIndex);
|
||||
if (aNotify) {
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
#
|
||||
# This is a list of local files which get copied to the mozilla:dist:layout directory
|
||||
#
|
||||
nsIEventListenerManager.h
|
||||
nsIEventStateManager.h
|
||||
nsIPrivateDOMEvent.h
|
||||
nsIPrivateTextEvent.h
|
||||
nsIPrivateTextRange.h
|
||||
nsIPrivateCompositionEvent.h
|
|
@ -29,6 +29,7 @@ include $(DEPTH)/config/autoconf.mk
|
|||
MODULE = layout
|
||||
|
||||
EXPORTS = \
|
||||
nsMutationEvent.h \
|
||||
nsIEventListenerManager.h \
|
||||
nsIEventStateManager.h \
|
||||
nsIPrivateDOMEvent.h \
|
||||
|
|
|
@ -29,6 +29,7 @@ EXPORTS = \
|
|||
nsIPrivateTextEvent.h \
|
||||
nsIPrivateTextRange.h \
|
||||
nsIPrivateCompositionEvent.h \
|
||||
nsMutationEvent.h \
|
||||
$(NULL)
|
||||
|
||||
MODULE=raptor
|
||||
|
|
|
@ -142,6 +142,11 @@ public:
|
|||
* manager.
|
||||
*/
|
||||
virtual nsresult SetListenerTarget(nsISupports* aTarget) = 0;
|
||||
|
||||
/**
|
||||
* Allows us to quickly determine if we have mutation listeners registered.
|
||||
*/
|
||||
virtual nsresult HasMutationListeners(PRBool* aListener) = 0;
|
||||
};
|
||||
|
||||
extern NS_HTML nsresult NS_NewEventListenerManager(nsIEventListenerManager** aInstancePtrResult);
|
||||
|
|
|
@ -58,5 +58,7 @@ extern nsresult NS_NewDOMUIEvent(nsIDOMEvent** aInstancePtrResult,
|
|||
nsIPresContext* aPresContext,
|
||||
const nsAReadableString& aEventType,
|
||||
nsEvent *aEvent);
|
||||
extern nsresult NS_NewDOMMutationEvent(nsIDOMEvent** aResult, nsIPresContext* aPresContext,
|
||||
nsEvent* aEvent);
|
||||
|
||||
#endif // nsIPrivateDOMEvent_h__
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
#include "nsGUIEvent.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
|
||||
struct nsMutationEvent : public nsEvent
|
||||
{
|
||||
nsCOMPtr<nsIDOMNode> mRelatedNode;
|
||||
nsCOMPtr<nsIDOMEventTarget> mTarget;
|
||||
|
||||
nsCOMPtr<nsIAtom> mAttrName;
|
||||
nsCOMPtr<nsIAtom> mPrevAttrValue;
|
||||
nsCOMPtr<nsIAtom> mNewAttrValue;
|
||||
|
||||
unsigned short mAttrChange;
|
||||
};
|
||||
|
||||
#define NS_MUTATION_EVENT 20
|
||||
|
||||
#define NS_MUTATION_START 1800
|
||||
#define NS_MUTATION_SUBTREEMODIFIED (NS_MUTATION_START)
|
||||
#define NS_MUTATION_NODEINSERTED (NS_MUTATION_START+1)
|
||||
#define NS_MUTATION_NODEREMOVED (NS_MUTATION_START+2)
|
||||
#define NS_MUTATION_NODEREMOVEDFROMDOCUMENT (NS_MUTATION_START+3)
|
||||
#define NS_MUTATION_NODEINSERTEDINTODOCUMENT (NS_MUTATION_START+4)
|
||||
#define NS_MUTATION_ATTRMODIFIED (NS_MUTATION_START+5)
|
||||
#define NS_MUTATION_CHARACTERDATAMODIFIED (NS_MUTATION_START+6)
|
||||
|
||||
// Bits are actually checked to optimize mutation event firing.
|
||||
// That's why I don't number from 0x00. The first event should
|
||||
// always be 0x01.
|
||||
#define NS_EVENT_BITS_MUTATION_SUBTREEMODIFIED 0x01
|
||||
#define NS_EVENT_BITS_MUTATION_NODEINSERTED 0x02
|
||||
#define NS_EVENT_BITS_MUTATION_NODEREMOVED 0x04
|
||||
#define NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT 0x08
|
||||
#define NS_EVENT_BITS_MUTATION_NODEINSERTEDINTODOCUMENT 0x10
|
||||
#define NS_EVENT_BITS_MUTATION_ATTRMODIFIED 0x20
|
||||
#define NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED 0x40
|
|
@ -34,6 +34,7 @@ CPPSRCS = \
|
|||
nsEventListenerManager.cpp \
|
||||
nsEventStateManager.cpp \
|
||||
nsDOMEvent.cpp \
|
||||
nsDOMMutationEvent.cpp \
|
||||
nsDOMEventsIIDs.cpp \
|
||||
nsPrivateTextRange.cpp \
|
||||
$(NULL)
|
||||
|
|
|
@ -32,6 +32,7 @@ DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
|
|||
CPPSRCS= nsEventListenerManager.cpp \
|
||||
nsEventStateManager.cpp \
|
||||
nsDOMEvent.cpp \
|
||||
nsDOMMutationEvent.cpp \
|
||||
nsDOMEventsIIDs.cpp \
|
||||
nsPrivateTextRange.cpp \
|
||||
$(NULL)
|
||||
|
@ -39,6 +40,7 @@ CPPSRCS= nsEventListenerManager.cpp \
|
|||
CPP_OBJS= .\$(OBJDIR)\nsEventListenerManager.obj \
|
||||
.\$(OBJDIR)\nsEventStateManager.obj \
|
||||
.\$(OBJDIR)\nsDOMEvent.obj \
|
||||
.\$(OBJDIR)\nsDOMMutationEvent.obj \
|
||||
.\$(OBJDIR)\nsDOMEventsIIDs.obj \
|
||||
.\$(OBJDIR)\nsPrivateTextRange.obj \
|
||||
$(NULL)
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "nsIDOMAbstractView.h"
|
||||
#include "prmem.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsMutationEvent.h"
|
||||
|
||||
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
|
||||
|
||||
|
@ -50,7 +51,10 @@ static char* mEventNames[] = {
|
|||
"submit", "reset", "change", "select", "input", "paint" ,"text",
|
||||
"create", "close", "destroy", "command", "broadcast", "commandupdate",
|
||||
"dragenter", "dragover", "dragexit", "dragdrop", "draggesture", "resize",
|
||||
"scroll","overflow", "underflow", "overflowchanged"
|
||||
"scroll","overflow", "underflow", "overflowchanged",
|
||||
"DOMSubtreeModified", "DOMNodeInserted", "DOMNodeRemoved",
|
||||
"DOMNodeRemovedFromDocument", "DOMNodeInsertedIntoDocument",
|
||||
"DOMAttrModified", "DOMCharacterDataModified"
|
||||
};
|
||||
|
||||
nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, const nsAReadableString& aEventType) {
|
||||
|
@ -76,6 +80,10 @@ nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, const nsAR
|
|||
mEvent = PR_NEWZAP(nsEvent);
|
||||
mEvent->eventStructType = NS_EVENT;
|
||||
}
|
||||
else if (eventType.EqualsIgnoreCase("MutationEvent")) {
|
||||
mEvent = PR_NEWZAP(nsMutationEvent);
|
||||
mEvent->eventStructType = NS_MUTATION_EVENT;
|
||||
}
|
||||
else {
|
||||
mEvent = PR_NEWZAP(nsEvent);
|
||||
mEvent->eventStructType = NS_EVENT;
|
||||
|
@ -1013,7 +1021,6 @@ nsDOMEvent::InitKeyEvent(const nsAReadableString& aTypeArg, PRBool aCanBubbleArg
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD nsDOMEvent::DuplicatePrivateData()
|
||||
{
|
||||
//XXX Write me!
|
||||
|
@ -1183,6 +1190,20 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
|
|||
return mEventNames[eDOMEvents_underflow];
|
||||
case NS_SCROLLPORT_OVERFLOWCHANGED:
|
||||
return mEventNames[eDOMEvents_overflowchanged];
|
||||
case NS_MUTATION_SUBTREEMODIFIED:
|
||||
return mEventNames[eDOMEvents_subtreemodified];
|
||||
case NS_MUTATION_NODEINSERTED:
|
||||
return mEventNames[eDOMEvents_nodeinserted];
|
||||
case NS_MUTATION_NODEREMOVED:
|
||||
return mEventNames[eDOMEvents_noderemoved];
|
||||
case NS_MUTATION_NODEREMOVEDFROMDOCUMENT:
|
||||
return mEventNames[eDOMEvents_noderemovedfromdocument];
|
||||
case NS_MUTATION_NODEINSERTEDINTODOCUMENT:
|
||||
return mEventNames[eDOMEvents_nodeinsertedintodocument];
|
||||
case NS_MUTATION_ATTRMODIFIED:
|
||||
return mEventNames[eDOMEvents_attrmodified];
|
||||
case NS_MUTATION_CHARACTERDATAMODIFIED:
|
||||
return mEventNames[eDOMEvents_characterdatamodified];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -87,7 +87,14 @@ public:
|
|||
eDOMEvents_scroll,
|
||||
eDOMEvents_overflow,
|
||||
eDOMEvents_underflow,
|
||||
eDOMEvents_overflowchanged
|
||||
eDOMEvents_overflowchanged,
|
||||
eDOMEvents_subtreemodified,
|
||||
eDOMEvents_nodeinserted,
|
||||
eDOMEvents_noderemoved,
|
||||
eDOMEvents_noderemovedfromdocument,
|
||||
eDOMEvents_nodeinsertedintodocument,
|
||||
eDOMEvents_attrmodified,
|
||||
eDOMEvents_characterdatamodified
|
||||
};
|
||||
|
||||
nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, const nsAReadableString& aEventType);
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "nsIDOMCompositionListener.h"
|
||||
#include "nsIDOMMenuListener.h"
|
||||
#include "nsIDOMScrollListener.h"
|
||||
#include "nsIDOMMutationListener.h"
|
||||
|
||||
NS_DEFINE_IID(kIDOMMouseListenerIID, NS_IDOMMOUSELISTENER_IID);
|
||||
NS_DEFINE_IID(kIDOMKeyListenerIID, NS_IDOMKEYLISTENER_IID);
|
||||
|
@ -45,3 +46,4 @@ NS_DEFINE_IID(kIDOMTextListenerIID,NS_IDOMTEXTLISTENER_IID);
|
|||
NS_DEFINE_IID(kIDOMCompositionListenerIID,NS_IDOMCOMPOSITIONLISTENER_IID);
|
||||
NS_DEFINE_IID(kIDOMMenuListenerIID, NS_IDOMMENULISTENER_IID);
|
||||
NS_DEFINE_IID(kIDOMScrollListenerIID, NS_IDOMSCROLLLISTENER_IID);
|
||||
NS_DEFINE_IID(kIDOMMutationListenerIID, NS_IDOMMUTATIONLISTENER_IID);
|
||||
|
|
|
@ -36,5 +36,6 @@ extern const nsIID kIDOMTextListenerIID;
|
|||
extern const nsIID kIDOMCompositionListenerIID;
|
||||
extern const nsIID kIDOMMenuListenerIID;
|
||||
extern const nsIID kIDOMScrollListenerIID;
|
||||
extern const nsIID kIDOMMutationListenerIID;
|
||||
|
||||
#endif /* nsDOMEVENTSIIDs_h___ */
|
||||
|
|
|
@ -0,0 +1,162 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
#include "nsDOMEvent.h"
|
||||
#include "nsMutationEvent.h"
|
||||
|
||||
class nsIPresContext;
|
||||
|
||||
class nsDOMMutationEvent : public nsIDOMMutationEvent, public nsDOMEvent
|
||||
{
|
||||
NS_DECL_IDOMMUTATIONEVENT
|
||||
NS_FORWARD_IDOMEVENT(nsDOMEvent::)
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
nsDOMMutationEvent(nsIPresContext* aPresContext,
|
||||
nsEvent* aEvent);
|
||||
|
||||
~nsDOMMutationEvent();
|
||||
|
||||
};
|
||||
|
||||
nsDOMMutationEvent::nsDOMMutationEvent(nsIPresContext* aPresContext,
|
||||
nsEvent* aEvent)
|
||||
:nsDOMEvent(aPresContext, aEvent, NS_LITERAL_STRING("MutationEvent"))
|
||||
{
|
||||
nsMutationEvent* mutation = (nsMutationEvent*)aEvent;
|
||||
SetTarget(mutation->mTarget);
|
||||
}
|
||||
|
||||
nsDOMMutationEvent::~nsDOMMutationEvent() {
|
||||
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsDOMMutationEvent, nsDOMEvent)
|
||||
NS_IMPL_RELEASE_INHERITED(nsDOMMutationEvent, nsDOMEvent)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsDOMMutationEvent)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEvent, nsIDOMMutationEvent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIPrivateDOMEvent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMMutationEvent)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMutationEvent::GetRelatedNode(nsIDOMNode** aRelatedNode)
|
||||
{
|
||||
*aRelatedNode = nsnull;
|
||||
if (mEvent) {
|
||||
nsMutationEvent* mutation = NS_STATIC_CAST(nsMutationEvent*, mEvent);
|
||||
*aRelatedNode = mutation->mRelatedNode;
|
||||
NS_IF_ADDREF(*aRelatedNode);
|
||||
}
|
||||
else *aRelatedNode = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMutationEvent::GetPrevValue(nsAWritableString& aPrevValue)
|
||||
{
|
||||
if (mEvent) {
|
||||
nsMutationEvent* mutation = NS_STATIC_CAST(nsMutationEvent*, mEvent);
|
||||
if (mutation && mutation->mPrevAttrValue)
|
||||
mutation->mPrevAttrValue->ToString(aPrevValue);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMutationEvent::GetNewValue(nsAWritableString& aNewValue)
|
||||
{
|
||||
if (mEvent) {
|
||||
nsMutationEvent* mutation = NS_STATIC_CAST(nsMutationEvent*, mEvent);
|
||||
if (mutation && mutation->mNewAttrValue)
|
||||
mutation->mNewAttrValue->ToString(aNewValue);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMutationEvent::GetAttrName(nsAWritableString& aAttrName)
|
||||
{
|
||||
if (mEvent) {
|
||||
nsMutationEvent* mutation = NS_STATIC_CAST(nsMutationEvent*, mEvent);
|
||||
if (mutation && mutation->mAttrName)
|
||||
mutation->mAttrName->ToString(aAttrName);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMutationEvent::GetAttrChange(PRUint16* aAttrChange)
|
||||
{
|
||||
*aAttrChange = 0;
|
||||
if (mEvent) {
|
||||
nsMutationEvent* mutation = NS_STATIC_CAST(nsMutationEvent*, mEvent);
|
||||
if (mutation && mutation->mAttrChange)
|
||||
*aAttrChange = mutation->mAttrChange;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMutationEvent::InitMutationEvent(const nsAReadableString& aTypeArg, PRBool aCanBubbleArg,
|
||||
PRBool aCancelableArg, nsIDOMNode* aRelatedNodeArg,
|
||||
const nsAReadableString& aPrevValueArg,
|
||||
const nsAReadableString& aNewValueArg,
|
||||
const nsAReadableString& aAttrNameArg)
|
||||
{
|
||||
NS_ENSURE_SUCCESS(SetEventType(aTypeArg), NS_ERROR_FAILURE);
|
||||
mEvent->flags |= aCanBubbleArg ? NS_EVENT_FLAG_NONE : NS_EVENT_FLAG_CANT_BUBBLE;
|
||||
mEvent->flags |= aCancelableArg ? NS_EVENT_FLAG_NONE : NS_EVENT_FLAG_CANT_CANCEL;
|
||||
|
||||
nsMutationEvent* mutation = NS_STATIC_CAST(nsMutationEvent*, mEvent);
|
||||
if (mutation) {
|
||||
mutation->mRelatedNode = aRelatedNodeArg;
|
||||
if (!aPrevValueArg.IsEmpty())
|
||||
mutation->mPrevAttrValue = getter_AddRefs(NS_NewAtom(aPrevValueArg));
|
||||
if (!aNewValueArg.IsEmpty())
|
||||
mutation->mNewAttrValue = getter_AddRefs(NS_NewAtom(aNewValueArg));
|
||||
if (!aAttrNameArg.IsEmpty()) {
|
||||
mutation->mAttrName = getter_AddRefs(NS_NewAtom(aAttrNameArg));
|
||||
// I guess we assume modification. Weird that this isn't specifiable.
|
||||
mutation->mAttrChange = nsIDOMMutationEvent::MODIFICATION;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
};
|
||||
|
||||
nsresult NS_NewDOMMutationEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsIPresContext* aPresContext,
|
||||
nsEvent *aEvent)
|
||||
{
|
||||
nsDOMMutationEvent* it = new nsDOMMutationEvent(aPresContext, aEvent);
|
||||
if (nsnull == it) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return it->QueryInterface(NS_GET_IID(nsIDOMEvent), (void **) aInstancePtrResult);
|
||||
}
|
|
@ -37,7 +37,9 @@
|
|||
#include "nsIDOMCompositionListener.h"
|
||||
#include "nsIDOMMenuListener.h"
|
||||
#include "nsIDOMScrollListener.h"
|
||||
#include "nsIDOMMutationListener.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsIScriptObjectOwner.h"
|
||||
#include "nsIScriptEventListener.h"
|
||||
|
@ -56,6 +58,7 @@
|
|||
#include "nsIJSContextStack.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsMutationEvent.h"
|
||||
|
||||
static NS_DEFINE_IID(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID);
|
||||
static NS_DEFINE_IID(kIDOMEventListenerIID, NS_IDOMEVENTLISTENER_IID);
|
||||
|
@ -77,6 +80,7 @@ nsEventListenerManager::nsEventListenerManager()
|
|||
mCompositionListeners = nsnull;
|
||||
mMenuListeners = nsnull;
|
||||
mScrollListeners = nsnull;
|
||||
mMutationListeners = nsnull;
|
||||
mDestroyed = PR_FALSE;
|
||||
mTarget = nsnull;
|
||||
NS_INIT_REFCNT();
|
||||
|
@ -97,6 +101,7 @@ nsEventListenerManager::~nsEventListenerManager()
|
|||
ReleaseListeners(&mCompositionListeners, PR_FALSE);
|
||||
ReleaseListeners(&mMenuListeners, PR_FALSE);
|
||||
ReleaseListeners(&mScrollListeners, PR_FALSE);
|
||||
ReleaseListeners(&mMutationListeners, PR_FALSE);
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsEventListenerManager)
|
||||
|
@ -184,6 +189,9 @@ nsVoidArray** nsEventListenerManager::GetListenersByIID(const nsIID& aIID)
|
|||
else if (aIID.Equals(kIDOMScrollListenerIID)) {
|
||||
return &mScrollListeners;
|
||||
}
|
||||
else if (aIID.Equals(kIDOMMutationListenerIID)) {
|
||||
return &mMutationListeners;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
@ -245,6 +253,25 @@ nsresult nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// For mutation listeners, we need to update the global bit on the DOM window.
|
||||
// Otherwise we won't actually fire the mutation event.
|
||||
if (aIID.Equals(NS_GET_IID(nsIDOMMutationListener))) {
|
||||
// Go from our target to the nearest enclosing DOM window.
|
||||
nsCOMPtr<nsIScriptGlobalObject> global;
|
||||
nsCOMPtr<nsIDocument> document;
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mTarget));
|
||||
if (content)
|
||||
content->GetDocument(*getter_AddRefs(document));
|
||||
else document = do_QueryInterface(mTarget);
|
||||
if (document)
|
||||
document->GetScriptGlobalObject(getter_AddRefs(global));
|
||||
else global = do_QueryInterface(mTarget);
|
||||
if (global) {
|
||||
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(global));
|
||||
window->SetMutationListeners(aSubType);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool found = PR_FALSE;
|
||||
nsListenerStruct* ls;
|
||||
nsresult rv;
|
||||
|
@ -504,6 +531,34 @@ nsresult nsEventListenerManager::GetIdentifiersForType(nsIAtom* aType, nsIID& aI
|
|||
aIID = NS_GET_IID(nsIDOMDragListener);
|
||||
*aFlags = NS_EVENT_BITS_DRAG_GESTURE;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onDOMSubtreeModified) {
|
||||
aIID = NS_GET_IID(nsIDOMMutationListener);
|
||||
*aFlags = NS_EVENT_BITS_MUTATION_SUBTREEMODIFIED;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onDOMNodeInserted) {
|
||||
aIID = NS_GET_IID(nsIDOMMutationListener);
|
||||
*aFlags = NS_EVENT_BITS_MUTATION_NODEINSERTED;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onDOMNodeRemoved) {
|
||||
aIID = NS_GET_IID(nsIDOMMutationListener);
|
||||
*aFlags = NS_EVENT_BITS_MUTATION_NODEREMOVED;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onDOMNodeInsertedIntoDocument) {
|
||||
aIID = NS_GET_IID(nsIDOMMutationListener);
|
||||
*aFlags = NS_EVENT_BITS_MUTATION_NODEINSERTEDINTODOCUMENT;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onDOMNodeRemovedFromDocument) {
|
||||
aIID = NS_GET_IID(nsIDOMMutationListener);
|
||||
*aFlags = NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onDOMAttrModified) {
|
||||
aIID = NS_GET_IID(nsIDOMMutationListener);
|
||||
*aFlags = NS_EVENT_BITS_MUTATION_ATTRMODIFIED;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onDOMCharacterDataModified) {
|
||||
aIID = NS_GET_IID(nsIDOMMutationListener);
|
||||
*aFlags = NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED;
|
||||
}
|
||||
else {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -1676,6 +1731,112 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
|
|||
}
|
||||
break;
|
||||
|
||||
case NS_MUTATION_SUBTREEMODIFIED:
|
||||
case NS_MUTATION_NODEINSERTED:
|
||||
case NS_MUTATION_NODEREMOVED:
|
||||
case NS_MUTATION_NODEINSERTEDINTODOCUMENT:
|
||||
case NS_MUTATION_NODEREMOVEDFROMDOCUMENT:
|
||||
case NS_MUTATION_ATTRMODIFIED:
|
||||
case NS_MUTATION_CHARACTERDATAMODIFIED:
|
||||
if (nsnull != mMutationListeners) {
|
||||
if (nsnull == *aDOMEvent) {
|
||||
ret = NS_NewDOMMutationEvent(aDOMEvent, aPresContext, aEvent);
|
||||
}
|
||||
if (NS_OK == ret) {
|
||||
for (int i=0; mMutationListeners && i<mMutationListeners->Count(); i++) {
|
||||
nsListenerStruct *ls;
|
||||
nsCOMPtr<nsIDOMMutationListener> mutationListener;
|
||||
|
||||
ls = (nsListenerStruct*)mMutationListeners->ElementAt(i);
|
||||
|
||||
if (ls->mFlags & aFlags) {
|
||||
mutationListener = do_QueryInterface(ls->mListener);
|
||||
if (mutationListener) {
|
||||
switch(aEvent->message) {
|
||||
case NS_MUTATION_SUBTREEMODIFIED:
|
||||
ret = mutationListener->SubtreeModified(*aDOMEvent);
|
||||
break;
|
||||
case NS_MUTATION_NODEINSERTED:
|
||||
ret = mutationListener->NodeInserted(*aDOMEvent);
|
||||
break;
|
||||
case NS_MUTATION_NODEREMOVED:
|
||||
ret = mutationListener->NodeRemoved(*aDOMEvent);
|
||||
break;
|
||||
case NS_MUTATION_NODEINSERTEDINTODOCUMENT:
|
||||
ret = mutationListener->NodeInsertedIntoDocument(*aDOMEvent);
|
||||
break;
|
||||
case NS_MUTATION_NODEREMOVEDFROMDOCUMENT:
|
||||
ret = mutationListener->NodeRemovedFromDocument(*aDOMEvent);
|
||||
break;
|
||||
case NS_MUTATION_ATTRMODIFIED:
|
||||
ret = mutationListener->AttrModified(*aDOMEvent);
|
||||
break;
|
||||
case NS_MUTATION_CHARACTERDATAMODIFIED:
|
||||
ret = mutationListener->CharacterDataModified(*aDOMEvent);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PRBool correctSubType = PR_FALSE;
|
||||
PRUint32 subType = 0;
|
||||
switch(aEvent->message) {
|
||||
case NS_MUTATION_SUBTREEMODIFIED:
|
||||
subType = NS_EVENT_BITS_MUTATION_SUBTREEMODIFIED;
|
||||
if (ls->mSubType & NS_EVENT_BITS_MUTATION_SUBTREEMODIFIED) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_MUTATION_NODEINSERTED:
|
||||
subType = NS_EVENT_BITS_MUTATION_NODEINSERTED;
|
||||
if (ls->mSubType & NS_EVENT_BITS_MUTATION_NODEINSERTED) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_MUTATION_NODEREMOVED:
|
||||
subType = NS_EVENT_BITS_MUTATION_NODEREMOVED;
|
||||
if (ls->mSubType & NS_EVENT_BITS_MUTATION_NODEREMOVED) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_MUTATION_NODEINSERTEDINTODOCUMENT:
|
||||
subType = NS_EVENT_BITS_MUTATION_NODEINSERTEDINTODOCUMENT;
|
||||
if (ls->mSubType & NS_EVENT_BITS_MUTATION_NODEINSERTEDINTODOCUMENT) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_MUTATION_NODEREMOVEDFROMDOCUMENT:
|
||||
subType = NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT;
|
||||
if (ls->mSubType & NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_MUTATION_ATTRMODIFIED:
|
||||
subType = NS_EVENT_BITS_MUTATION_ATTRMODIFIED;
|
||||
if (ls->mSubType & NS_EVENT_BITS_MUTATION_ATTRMODIFIED) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_MUTATION_CHARACTERDATAMODIFIED:
|
||||
subType = NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED;
|
||||
if (ls->mSubType & NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
|
||||
ret = HandleEventSubType(ls, *aDOMEvent, aCurrentTarget, subType, aFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1701,10 +1862,12 @@ nsresult nsEventListenerManager::CreateEvent(nsIPresContext* aPresContext,
|
|||
{
|
||||
nsAutoString str(aEventType);
|
||||
if (!aEvent && !str.EqualsIgnoreCase("MouseEvent") && !str.EqualsIgnoreCase("KeyEvent") &&
|
||||
!str.EqualsIgnoreCase("HTMLEvent")) {
|
||||
!str.EqualsIgnoreCase("HTMLEvent") && !str.EqualsIgnoreCase("MutationEvent")) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (str.EqualsIgnoreCase("MutationEvent"))
|
||||
return NS_NewDOMMutationEvent(aDOMEvent, aPresContext, aEvent);
|
||||
return NS_NewDOMUIEvent(aDOMEvent, aPresContext, aEventType, aEvent);
|
||||
}
|
||||
|
||||
|
@ -1965,6 +2128,7 @@ nsresult nsEventListenerManager::RemoveAllListeners(PRBool aScriptOnly)
|
|||
ReleaseListeners(&mPaintListeners, aScriptOnly);
|
||||
ReleaseListeners(&mTextListeners, aScriptOnly);
|
||||
ReleaseListeners(&mCompositionListeners, aScriptOnly);
|
||||
ReleaseListeners(&mMutationListeners, aScriptOnly);
|
||||
mDestroyed = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -107,6 +107,8 @@ public:
|
|||
|
||||
virtual nsresult SetListenerTarget(nsISupports* aTarget);
|
||||
|
||||
virtual nsresult HasMutationListeners(PRBool* aListener) { *aListener = (mMutationListeners != nsnull); return NS_OK; };
|
||||
|
||||
static nsresult GetIdentifiersForType(nsIAtom* aType, nsIID& aIID, PRInt32* aSubType);
|
||||
|
||||
// nsIDOMEventTarget interface
|
||||
|
@ -151,6 +153,8 @@ protected:
|
|||
nsVoidArray* mCompositionListeners;
|
||||
nsVoidArray* mMenuListeners;
|
||||
nsVoidArray* mScrollListeners;
|
||||
nsVoidArray* mMutationListeners;
|
||||
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
PRBool mDestroyed;
|
||||
|
||||
|
@ -242,4 +246,7 @@ protected:
|
|||
#define NS_EVENT_BITS_PAINT_RESIZE 0x02
|
||||
#define NS_EVENT_BITS_PAINT_SCROLL 0x04
|
||||
|
||||
//nsIDOMMutationListener
|
||||
// These bits are found in nsMutationEvent.h.
|
||||
|
||||
#endif // nsEventListenerManager_h__
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "nsIHTMLContent.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIScriptObjectOwner.h"
|
||||
#include "nsISizeOfHandler.h"
|
||||
|
@ -86,6 +87,13 @@
|
|||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsILanguageAtomService.h"
|
||||
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
#include "nsMutationEvent.h"
|
||||
#include "nsEventListenerManager.h"
|
||||
|
||||
#include "nsIBindingManager.h"
|
||||
#include "nsIXBLBinding.h"
|
||||
|
||||
#include "nsIParser.h"
|
||||
#include "nsParserCIID.h"
|
||||
#include "nsIHTMLContentSink.h"
|
||||
|
@ -1229,6 +1237,73 @@ nsGenericHTMLElement::NormalizeAttributeString(const nsAReadableString& aStr,
|
|||
return nimgr->GetNodeInfo(lower, nsnull, kNameSpaceID_None, aNodeInfo);
|
||||
}
|
||||
|
||||
static PRBool HasMutationListeners(nsIContent* aContent, PRUint32 aType)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aContent->GetDocument(*getter_AddRefs(doc));
|
||||
if (!doc)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> global;
|
||||
doc->GetScriptGlobalObject(getter_AddRefs(global));
|
||||
if (!global)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(global));
|
||||
if (!window)
|
||||
return PR_FALSE;
|
||||
|
||||
PRBool set;
|
||||
window->HasMutationListeners(aType, &set);
|
||||
if (!set)
|
||||
return PR_FALSE;
|
||||
|
||||
// We know a mutation listener is registered, but it might not
|
||||
// be in our chain. Check quickly to see.
|
||||
nsCOMPtr<nsIContent> curr = aContent;
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
while (curr) {
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(curr));
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> prev = curr;
|
||||
prev->GetParent(*getter_AddRefs(curr));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(doc));
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
rec = do_QueryInterface(window);
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::SetAttribute(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
|
@ -1302,6 +1377,9 @@ nsGenericHTMLElement::SetAttribute(PRInt32 aNameSpaceID,
|
|||
if (NS_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
nsAutoString strValue;
|
||||
PRBool modification = PR_TRUE;
|
||||
if (NS_CONTENT_ATTR_NOT_THERE !=
|
||||
htmlContent->StringToAttribute(aAttribute, aValue, val)) {
|
||||
// string value was mapped to nsHTMLValue, set it that way
|
||||
|
@ -1324,13 +1402,14 @@ nsGenericHTMLElement::SetAttribute(PRInt32 aNameSpaceID,
|
|||
}
|
||||
|
||||
// don't do any update if old == new
|
||||
nsAutoString strValue;
|
||||
result = GetAttribute(aNameSpaceID, aAttribute, strValue);
|
||||
if ((NS_CONTENT_ATTR_NOT_THERE != result) && aValue.Equals(strValue)) {
|
||||
NS_RELEASE(htmlContent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
modification = (result != NS_CONTENT_ATTR_NOT_THERE);
|
||||
|
||||
if (aNotify && (nsnull != mDocument)) {
|
||||
mDocument->BeginUpdate();
|
||||
}
|
||||
|
@ -1363,11 +1442,45 @@ nsGenericHTMLElement::SetAttribute(PRInt32 aNameSpaceID,
|
|||
}
|
||||
NS_RELEASE(htmlContent);
|
||||
|
||||
if (aNotify && (nsnull != mDocument)) {
|
||||
result = mDocument->AttributeChanged(mContent, aNameSpaceID, aAttribute, NS_STYLE_HINT_UNKNOWN);
|
||||
mDocument->EndUpdate();
|
||||
}
|
||||
if (mDocument) {
|
||||
nsCOMPtr<nsIBindingManager> bindingManager;
|
||||
mDocument->GetBindingManager(getter_AddRefs(bindingManager));
|
||||
nsCOMPtr<nsIXBLBinding> binding;
|
||||
bindingManager->GetBinding(mContent, getter_AddRefs(binding));
|
||||
if (binding)
|
||||
binding->AttributeChanged(aAttribute, aNameSpaceID, PR_FALSE);
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_ATTRMODIFIED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(mContent));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_ATTRMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsAutoString attrName;
|
||||
aAttribute->ToString(attrName);
|
||||
nsCOMPtr<nsIDOMAttr> attrNode;
|
||||
GetAttributeNode(attrName, getter_AddRefs(attrNode));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = aAttribute;
|
||||
if (!strValue.IsEmpty())
|
||||
mutation.mPrevAttrValue = getter_AddRefs(NS_NewAtom(strValue));
|
||||
if (!aValue.IsEmpty())
|
||||
mutation.mNewAttrValue = getter_AddRefs(NS_NewAtom(aValue));
|
||||
mutation.mAttrChange = modification ? nsIDOMMutationEvent::MODIFICATION :
|
||||
nsIDOMMutationEvent::ADDITION;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
mContent->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if (aNotify) {
|
||||
mDocument->AttributeChanged(mContent, aNameSpaceID, aAttribute, NS_STYLE_HINT_UNKNOWN);
|
||||
mDocument->EndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1447,6 +1560,41 @@ nsGenericHTMLElement::SetHTMLAttribute(nsIAtom* aAttribute,
|
|||
htmlContent, mAttributes);
|
||||
NS_RELEASE(sheet);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIBindingManager> bindingManager;
|
||||
mDocument->GetBindingManager(getter_AddRefs(bindingManager));
|
||||
nsCOMPtr<nsIXBLBinding> binding;
|
||||
bindingManager->GetBinding(mContent, getter_AddRefs(binding));
|
||||
if (binding)
|
||||
binding->AttributeChanged(aAttribute, kNameSpaceID_None, PR_TRUE);
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_ATTRMODIFIED)) {
|
||||
// XXX Figure out how to get the old value, so I can fill in
|
||||
// the prevValue field and so that I can correctly indicate
|
||||
// MODIFICATIONs/ADDITIONs.
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(mContent));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_ATTRMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsAutoString attrName;
|
||||
aAttribute->ToString(attrName);
|
||||
nsCOMPtr<nsIDOMAttr> attrNode;
|
||||
GetAttributeNode(attrName, getter_AddRefs(attrNode));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = aAttribute;
|
||||
nsAutoString value;
|
||||
aValue.ToString(value);
|
||||
if (!value.IsEmpty())
|
||||
mutation.mNewAttrValue = getter_AddRefs(NS_NewAtom(value));
|
||||
mutation.mAttrChange = nsIDOMMutationEvent::MODIFICATION;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
mContent->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if (aNotify) {
|
||||
mDocument->AttributeChanged(mContent, kNameSpaceID_None, aAttribute, impact);
|
||||
mDocument->EndUpdate();
|
||||
|
@ -1504,11 +1652,48 @@ nsGenericHTMLElement::UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_ATTRMODIFIED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(mContent));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_ATTRMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsAutoString attrName;
|
||||
aAttribute->ToString(attrName);
|
||||
nsCOMPtr<nsIDOMAttr> attrNode;
|
||||
GetAttributeNode(attrName, getter_AddRefs(attrNode));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = aAttribute;
|
||||
|
||||
nsHTMLValue oldAttr;
|
||||
GetHTMLAttribute(aAttribute, oldAttr);
|
||||
nsAutoString attr;
|
||||
oldAttr.ToString(attr);
|
||||
if (!attr.IsEmpty())
|
||||
mutation.mPrevAttrValue = getter_AddRefs(NS_NewAtom(attr));
|
||||
mutation.mAttrChange = nsIDOMMutationEvent::REMOVAL;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
mContent->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
nsIHTMLStyleSheet* sheet = GetAttrStyleSheet(mDocument);
|
||||
if (nsnull != sheet) {
|
||||
result = sheet->UnsetAttributeFor(aAttribute, htmlContent, mAttributes);
|
||||
NS_RELEASE(sheet);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIBindingManager> bindingManager;
|
||||
mDocument->GetBindingManager(getter_AddRefs(bindingManager));
|
||||
nsCOMPtr<nsIXBLBinding> binding;
|
||||
bindingManager->GetBinding(mContent, getter_AddRefs(binding));
|
||||
if (binding)
|
||||
binding->AttributeChanged(aAttribute, aNameSpaceID, PR_TRUE);
|
||||
|
||||
if (aNotify) {
|
||||
mDocument->AttributeChanged(mContent, aNameSpaceID, aAttribute, impact);
|
||||
mDocument->EndUpdate();
|
||||
|
@ -3198,7 +3383,6 @@ nsGenericHTMLLeafElement::GetChildNodes(nsIDOMNodeList** aChildNodes)
|
|||
return slots->mChildNodes->QueryInterface(NS_GET_IID(nsIDOMNodeList), (void **)aChildNodes);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsGenericHTMLContainerElement::nsGenericHTMLContainerElement()
|
||||
|
@ -3375,6 +3559,21 @@ nsGenericHTMLContainerElement::InsertChildAt(nsIContent* aKid,
|
|||
if (aNotify) {
|
||||
doc->ContentInserted(mContent, aKid, aIndex);
|
||||
}
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(aKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEINSERTED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(mContent));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
aKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aNotify && (nsnull != doc)) {
|
||||
|
@ -3433,6 +3632,21 @@ nsGenericHTMLContainerElement::AppendChildTo(nsIContent* aKid, PRBool aNotify)
|
|||
if (aNotify) {
|
||||
doc->ContentAppended(mContent, mChildren.Count() - 1);
|
||||
}
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(aKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEINSERTED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(mContent));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
aKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aNotify && (nsnull != doc)) {
|
||||
|
@ -3450,6 +3664,22 @@ nsGenericHTMLContainerElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify)
|
|||
}
|
||||
nsIContent* oldKid = (nsIContent *)mChildren.ElementAt(aIndex);
|
||||
if (nsnull != oldKid ) {
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_NODEREMOVED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(oldKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEREMOVED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(mContent));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
oldKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
nsRange::OwnerChildRemoved(mContent, aIndex, oldKid);
|
||||
mChildren.RemoveElementAt(aIndex);
|
||||
if (aNotify) {
|
||||
|
|
|
@ -164,6 +164,15 @@ LAYOUT_ATOM(onoverflow, "onoverflow")
|
|||
LAYOUT_ATOM(onunderflow, "onunderflow")
|
||||
LAYOUT_ATOM(onoverflowchanged, "onoverflowchanged")
|
||||
|
||||
// mutation events
|
||||
LAYOUT_ATOM(onDOMSubtreeModified, "onDOMSubtreeModified")
|
||||
LAYOUT_ATOM(onDOMNodeInserted, "onDOMNodeInserted")
|
||||
LAYOUT_ATOM(onDOMNodeRemoved, "onDOMNodeRemoved")
|
||||
LAYOUT_ATOM(onDOMNodeRemovedFromDocument, "onDOMNodeRemovedFromDocument")
|
||||
LAYOUT_ATOM(onDOMNodeInsertedIntoDocument, "onDOMNodeInsertedIntoDocument")
|
||||
LAYOUT_ATOM(onDOMAttrModified, "onDOMAttrModified")
|
||||
LAYOUT_ATOM(onDOMCharacterDataModified, "onDOMCharacterDataModified")
|
||||
|
||||
// Alphabetical list of languages for lang-specific transforms
|
||||
LAYOUT_ATOM(Japanese, "ja")
|
||||
LAYOUT_ATOM(Korean, "ko")
|
||||
|
|
|
@ -40,6 +40,7 @@ CPPSRCS = \
|
|||
nsXBLDragHandler.cpp \
|
||||
nsXBLMouseHandler.cpp \
|
||||
nsXBLMouseMotionHandler.cpp \
|
||||
nsXBLMutationHandler.cpp \
|
||||
nsXBLKeyHandler.cpp \
|
||||
nsXBLLoadHandler.cpp \
|
||||
nsXBLXULHandler.cpp \
|
||||
|
|
|
@ -35,6 +35,7 @@ CPPSRCS= \
|
|||
nsXBLKeyHandler.cpp \
|
||||
nsXBLMouseHandler.cpp \
|
||||
nsXBLMouseMotionHandler.cpp \
|
||||
nsXBLMutationHandler.cpp \
|
||||
nsXBLDragHandler.cpp \
|
||||
nsXBLFocusHandler.cpp \
|
||||
nsXBLXULHandler.cpp \
|
||||
|
@ -53,6 +54,7 @@ CPP_OBJS= \
|
|||
.\$(OBJDIR)\nsXBLKeyHandler.obj \
|
||||
.\$(OBJDIR)\nsXBLMouseHandler.obj \
|
||||
.\$(OBJDIR)\nsXBLMouseMotionHandler.obj \
|
||||
.\$(OBJDIR)\nsXBLMutationHandler.obj \
|
||||
.\$(OBJDIR)\nsXBLDragHandler.obj \
|
||||
.\$(OBJDIR)\nsXBLFocusHandler.obj \
|
||||
.\$(OBJDIR)\nsXBLXULHandler.obj \
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include "nsIDOMFormListener.h"
|
||||
#include "nsIDOMMenuListener.h"
|
||||
#include "nsIDOMDragListener.h"
|
||||
#include "nsIDOMMutationListener.h"
|
||||
|
||||
#include "nsIDOMAttr.h"
|
||||
#include "nsIDOMNamedNodeMap.h"
|
||||
|
@ -73,6 +74,7 @@
|
|||
#include "nsXBLFocusHandler.h"
|
||||
#include "nsXBLMouseHandler.h"
|
||||
#include "nsXBLMouseMotionHandler.h"
|
||||
#include "nsXBLMutationHandler.h"
|
||||
#include "nsXBLXULHandler.h"
|
||||
#include "nsXBLScrollHandler.h"
|
||||
#include "nsXBLFormHandler.h"
|
||||
|
@ -211,6 +213,14 @@ nsXBLBinding::kEventHandlerMap[] = {
|
|||
{ "dragdrop", nsnull, &NS_GET_IID(nsIDOMDragListener) },
|
||||
{ "draggesture", nsnull, &NS_GET_IID(nsIDOMDragListener) },
|
||||
|
||||
{ "DOMSubtreeModified", nsnull, &NS_GET_IID(nsIDOMMutationListener) },
|
||||
{ "DOMAttrModified", nsnull, &NS_GET_IID(nsIDOMMutationListener) },
|
||||
{ "DOMCharacterDataModified", nsnull, &NS_GET_IID(nsIDOMMutationListener) },
|
||||
{ "DOMNodeInserted", nsnull, &NS_GET_IID(nsIDOMMutationListener) },
|
||||
{ "DOMNodeRemoved", nsnull, &NS_GET_IID(nsIDOMMutationListener) },
|
||||
{ "DOMNodeInsertedIntoDocument", nsnull, &NS_GET_IID(nsIDOMMutationListener) },
|
||||
{ "DOMNodeRemovedFromDocument", nsnull, &NS_GET_IID(nsIDOMMutationListener) },
|
||||
|
||||
{ nsnull, nsnull, nsnull }
|
||||
};
|
||||
|
||||
|
@ -654,6 +664,12 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement, nsIXBLBinding** aB
|
|||
receiver->AddEventListener(type, (nsIDOMLoadListener*)loadHandler, useCapture);
|
||||
handler = loadHandler;
|
||||
}
|
||||
else if(iid.Equals(NS_GET_IID(nsIDOMMutationListener))) {
|
||||
nsXBLMutationHandler* mutationHandler;
|
||||
NS_NewXBLMutationHandler(receiver, curr, &mutationHandler);
|
||||
receiver->AddEventListener(type, (nsIDOMMutationListener*)mutationHandler, useCapture);
|
||||
handler = mutationHandler;
|
||||
}
|
||||
else {
|
||||
NS_WARNING("***** Non-compliant XBL event listener attached! *****");
|
||||
nsAutoString value;
|
||||
|
|
|
@ -0,0 +1,201 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||
*
|
||||
*/
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIXBLPrototypeHandler.h"
|
||||
#include "nsXBLMutationHandler.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIScriptObjectOwner.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIEventListenerManager.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsXBLBinding.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
#include "nsIPref.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsXPIDLString.h"
|
||||
|
||||
PRUint32 nsXBLMutationHandler::gRefCnt = 0;
|
||||
nsIAtom* nsXBLMutationHandler::kSubtreeModifiedAtom = nsnull;
|
||||
nsIAtom* nsXBLMutationHandler::kAttrModifiedAtom = nsnull;
|
||||
nsIAtom* nsXBLMutationHandler::kCharacterDataModifiedAtom = nsnull;
|
||||
nsIAtom* nsXBLMutationHandler::kNodeRemovedAtom = nsnull;
|
||||
nsIAtom* nsXBLMutationHandler::kNodeInsertedAtom = nsnull;
|
||||
nsIAtom* nsXBLMutationHandler::kNodeRemovedFromDocumentAtom = nsnull;
|
||||
nsIAtom* nsXBLMutationHandler::kNodeInsertedIntoDocumentAtom = nsnull;
|
||||
|
||||
nsXBLMutationHandler::nsXBLMutationHandler(nsIDOMEventReceiver* aReceiver, nsIXBLPrototypeHandler* aHandler)
|
||||
:nsXBLEventHandler(aReceiver,aHandler)
|
||||
{
|
||||
gRefCnt++;
|
||||
if (gRefCnt == 1) {
|
||||
kNodeRemovedAtom = NS_NewAtom("DOMNodeRemoved");
|
||||
kNodeInsertedAtom = NS_NewAtom("DOMNodeInserted");
|
||||
kNodeRemovedFromDocumentAtom = NS_NewAtom("DOMNodeRemovedFromDocument");
|
||||
kNodeInsertedIntoDocumentAtom = NS_NewAtom("DOMNodeInsertedIntoDocument");
|
||||
kSubtreeModifiedAtom = NS_NewAtom("DOMSubtreeModified");
|
||||
kAttrModifiedAtom = NS_NewAtom("DOMAttrModified");
|
||||
kCharacterDataModifiedAtom = NS_NewAtom("DOMCharacterDataModified");
|
||||
}
|
||||
}
|
||||
|
||||
nsXBLMutationHandler::~nsXBLMutationHandler()
|
||||
{
|
||||
gRefCnt--;
|
||||
if (gRefCnt == 0) {
|
||||
NS_RELEASE(kSubtreeModifiedAtom);
|
||||
NS_RELEASE(kAttrModifiedAtom);
|
||||
NS_RELEASE(kCharacterDataModifiedAtom);
|
||||
NS_RELEASE(kNodeInsertedAtom);
|
||||
NS_RELEASE(kNodeRemovedAtom);
|
||||
NS_RELEASE(kNodeInsertedIntoDocumentAtom);
|
||||
NS_RELEASE(kNodeRemovedFromDocumentAtom);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsXBLMutationHandler, nsXBLEventHandler, nsIDOMMutationListener)
|
||||
|
||||
nsresult nsXBLMutationHandler::SubtreeModified(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!mProtoHandler)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIAtom> eventName;
|
||||
mProtoHandler->GetEventName(getter_AddRefs(eventName));
|
||||
|
||||
if (eventName.get() != kSubtreeModifiedAtom)
|
||||
return NS_OK;
|
||||
|
||||
mProtoHandler->ExecuteHandler(mEventReceiver, aEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsXBLMutationHandler::AttrModified(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!mProtoHandler)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIAtom> eventName;
|
||||
mProtoHandler->GetEventName(getter_AddRefs(eventName));
|
||||
|
||||
if (eventName.get() != kAttrModifiedAtom)
|
||||
return NS_OK;
|
||||
|
||||
mProtoHandler->ExecuteHandler(mEventReceiver, aEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsXBLMutationHandler::CharacterDataModified(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!mProtoHandler)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIAtom> eventName;
|
||||
mProtoHandler->GetEventName(getter_AddRefs(eventName));
|
||||
|
||||
if (eventName.get() != kCharacterDataModifiedAtom)
|
||||
return NS_OK;
|
||||
|
||||
mProtoHandler->ExecuteHandler(mEventReceiver, aEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsXBLMutationHandler::NodeInserted(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!mProtoHandler)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIAtom> eventName;
|
||||
mProtoHandler->GetEventName(getter_AddRefs(eventName));
|
||||
|
||||
if (eventName.get() != kNodeInsertedAtom)
|
||||
return NS_OK;
|
||||
|
||||
mProtoHandler->ExecuteHandler(mEventReceiver, aEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsXBLMutationHandler::NodeRemoved(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!mProtoHandler)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIAtom> eventName;
|
||||
mProtoHandler->GetEventName(getter_AddRefs(eventName));
|
||||
|
||||
if (eventName.get() != kNodeRemovedAtom)
|
||||
return NS_OK;
|
||||
|
||||
mProtoHandler->ExecuteHandler(mEventReceiver, aEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsXBLMutationHandler::NodeInsertedIntoDocument(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!mProtoHandler)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIAtom> eventName;
|
||||
mProtoHandler->GetEventName(getter_AddRefs(eventName));
|
||||
|
||||
if (eventName.get() != kNodeInsertedAtom)
|
||||
return NS_OK;
|
||||
|
||||
mProtoHandler->ExecuteHandler(mEventReceiver, aEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsXBLMutationHandler::NodeRemovedFromDocument(nsIDOMEvent* aEvent)
|
||||
{
|
||||
if (!mProtoHandler)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIAtom> eventName;
|
||||
mProtoHandler->GetEventName(getter_AddRefs(eventName));
|
||||
|
||||
if (eventName.get() != kNodeRemovedAtom)
|
||||
return NS_OK;
|
||||
|
||||
mProtoHandler->ExecuteHandler(mEventReceiver, aEvent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
nsresult
|
||||
NS_NewXBLMutationHandler(nsIDOMEventReceiver* aRec, nsIXBLPrototypeHandler* aHandler,
|
||||
nsXBLMutationHandler** aResult)
|
||||
{
|
||||
*aResult = new nsXBLMutationHandler(aRec, aHandler);
|
||||
if (!*aResult)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
NS_ADDREF(*aResult);
|
||||
return NS_OK;
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Original Author: David W. Hyatt (hyatt@netscape.com)
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef nsXBLMutationHandler_h__
|
||||
#define nsXBLMutationHandler_h__
|
||||
|
||||
#include "nsIDOMMutationListener.h"
|
||||
#include "nsXBLEventHandler.h"
|
||||
|
||||
class nsIXBLBinding;
|
||||
class nsIDOMEvent;
|
||||
class nsIContent;
|
||||
class nsIDOMUIEvent;
|
||||
class nsIAtom;
|
||||
class nsIController;
|
||||
class nsIXBLPrototypeHandler;
|
||||
|
||||
class nsXBLMutationHandler : public nsIDOMMutationListener,
|
||||
public nsXBLEventHandler
|
||||
{
|
||||
public:
|
||||
nsXBLMutationHandler(nsIDOMEventReceiver* aReceiver, nsIXBLPrototypeHandler* aHandler);
|
||||
virtual ~nsXBLMutationHandler();
|
||||
|
||||
// nsIDOMetc.
|
||||
virtual nsresult HandleEvent(nsIDOMEvent* aEvent) { return NS_OK; };
|
||||
|
||||
NS_IMETHOD SubtreeModified(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD AttrModified(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD CharacterDataModified(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD NodeInserted(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD NodeRemoved(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD NodeInsertedIntoDocument(nsIDOMEvent* aEvent);
|
||||
NS_IMETHOD NodeRemovedFromDocument(nsIDOMEvent* aEvent);
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
protected:
|
||||
static PRUint32 gRefCnt;
|
||||
static nsIAtom* kSubtreeModifiedAtom;
|
||||
static nsIAtom* kAttrModifiedAtom;
|
||||
static nsIAtom* kCharacterDataModifiedAtom;
|
||||
static nsIAtom* kNodeInsertedAtom;
|
||||
static nsIAtom* kNodeRemovedAtom;
|
||||
static nsIAtom* kNodeInsertedIntoDocumentAtom;
|
||||
static nsIAtom* kNodeRemovedFromDocumentAtom;
|
||||
|
||||
protected:
|
||||
// Members
|
||||
};
|
||||
|
||||
extern nsresult
|
||||
NS_NewXBLMutationHandler(nsIDOMEventReceiver* aEventReceiver, nsIXBLPrototypeHandler* aHandlerElement,
|
||||
nsXBLMutationHandler** aResult);
|
||||
|
||||
|
||||
#endif
|
|
@ -116,6 +116,10 @@
|
|||
#include "nsXULAtoms.h"
|
||||
#include "nsITreeBoxObject.h"
|
||||
|
||||
#include "nsMutationEvent.h"
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
#include "prlog.h"
|
||||
#include "rdf.h"
|
||||
#include "rdfutil.h"
|
||||
|
@ -297,6 +301,75 @@ struct XULBroadcastListener
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
static PRBool HasMutationListeners(nsIContent* aContent, PRUint32 aType)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aContent->GetDocument(*getter_AddRefs(doc));
|
||||
if (!doc)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> global;
|
||||
doc->GetScriptGlobalObject(getter_AddRefs(global));
|
||||
if (!global)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(global));
|
||||
if (!window)
|
||||
return PR_FALSE;
|
||||
|
||||
PRBool set;
|
||||
window->HasMutationListeners(aType, &set);
|
||||
if (!set)
|
||||
return PR_FALSE;
|
||||
|
||||
// We know a mutation listener is registered, but it might not
|
||||
// be in our chain. Check quickly to see.
|
||||
nsCOMPtr<nsIContent> curr = aContent;
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
while (curr) {
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(curr));
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> prev = curr;
|
||||
prev->GetParent(*getter_AddRefs(curr));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(doc));
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
rec = do_QueryInterface(window);
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsrefcnt nsXULElement::gRefCnt;
|
||||
nsIRDFService* nsXULElement::gRDFService;
|
||||
nsINameSpaceManager* nsXULElement::gNameSpaceManager;
|
||||
|
@ -2353,6 +2426,22 @@ nsXULElement::InsertChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify)
|
|||
// N.B. that this is "shallow"!
|
||||
aKid->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
|
||||
if (mDocument && HasMutationListeners(NS_STATIC_CAST(nsIStyledContent*,this),
|
||||
NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(aKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEINSERTED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(NS_STATIC_CAST(nsIStyledContent*,this)));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
aKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if (aNotify && mDocument) {
|
||||
mDocument->ContentInserted(NS_STATIC_CAST(nsIStyledContent*, this), aKid, aIndex);
|
||||
}
|
||||
|
@ -2422,6 +2511,22 @@ nsXULElement::AppendChildTo(nsIContent* aKid, PRBool aNotify)
|
|||
// N.B. that this is only "shallow". Callers beware!
|
||||
aKid->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
|
||||
if (mDocument && HasMutationListeners(NS_STATIC_CAST(nsIStyledContent*,this),
|
||||
NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(aKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEINSERTED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(NS_STATIC_CAST(nsIStyledContent*,this)));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
aKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if (aNotify && mDocument) {
|
||||
mDocument->ContentAppended(NS_STATIC_CAST(nsIStyledContent*, this), mChildren.Count() - 1);
|
||||
}
|
||||
|
@ -2440,6 +2545,21 @@ nsXULElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify)
|
|||
if (! oldKid)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (HasMutationListeners(NS_STATIC_CAST(nsIStyledContent*,this), NS_EVENT_BITS_MUTATION_NODEREMOVED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(oldKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEREMOVED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(NS_STATIC_CAST(nsIStyledContent*,this)));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
oldKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
// On the removal of a <treeitem>, <treechildren>, or <treecell> element,
|
||||
// the possibility exists that some of the items in the removed subtree
|
||||
// are selected (and therefore need to be deselected). We need to account for this.
|
||||
|
@ -2706,12 +2826,16 @@ nsXULElement::SetAttribute(nsINodeInfo* aNodeInfo,
|
|||
i++;
|
||||
}
|
||||
|
||||
PRBool modification = PR_TRUE;
|
||||
nsAutoString oldValue;
|
||||
|
||||
if (i < count) {
|
||||
attr->GetValue(oldValue);
|
||||
attr->SetValueInternal(aValue);
|
||||
}
|
||||
else {
|
||||
// didn't find it
|
||||
|
||||
modification = PR_FALSE;
|
||||
rv = nsXULAttribute::Create(NS_STATIC_CAST(nsIStyledContent*, this),
|
||||
aNodeInfo, aValue, &attr);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -2767,6 +2891,31 @@ nsXULElement::SetAttribute(nsINodeInfo* aNodeInfo,
|
|||
if (binding)
|
||||
binding->AttributeChanged(attrName, attrns, PR_FALSE);
|
||||
|
||||
if (HasMutationListeners(NS_STATIC_CAST(nsIStyledContent*, this), NS_EVENT_BITS_MUTATION_ATTRMODIFIED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(NS_STATIC_CAST(nsIStyledContent*, this)));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_ATTRMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsAutoString attrName2;
|
||||
attrName->ToString(attrName2);
|
||||
nsCOMPtr<nsIDOMAttr> attrNode;
|
||||
GetAttributeNode(attrName2, getter_AddRefs(attrNode));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = attrName;
|
||||
if (!oldValue.IsEmpty())
|
||||
mutation.mPrevAttrValue = getter_AddRefs(NS_NewAtom(oldValue));
|
||||
if (!aValue.IsEmpty())
|
||||
mutation.mNewAttrValue = getter_AddRefs(NS_NewAtom(aValue));
|
||||
mutation.mAttrChange = modification ? nsIDOMMutationEvent::MODIFICATION :
|
||||
nsIDOMMutationEvent::ADDITION;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if (aNotify) {
|
||||
nsCOMPtr<nsIAtom> tagName;
|
||||
NodeInfo()->GetNameAtom(*getter_AddRefs(tagName));
|
||||
|
@ -2938,6 +3087,29 @@ nsXULElement::UnsetAttribute(PRInt32 aNameSpaceID,
|
|||
nsXULAttribute* attr = NS_REINTERPRET_CAST(nsXULAttribute*, Attributes()->ElementAt(i));
|
||||
if (attr->GetNodeInfo()->Equals(aName, aNameSpaceID)) {
|
||||
attr->GetValue(oldValue);
|
||||
|
||||
if (HasMutationListeners(NS_STATIC_CAST(nsIStyledContent*, this), NS_EVENT_BITS_MUTATION_ATTRMODIFIED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(NS_STATIC_CAST(nsIStyledContent*, this)));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_ATTRMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsAutoString attrName2;
|
||||
aName->ToString(attrName2);
|
||||
nsCOMPtr<nsIDOMAttr> attrNode;
|
||||
GetAttributeNode(attrName2, getter_AddRefs(attrNode));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = aName;
|
||||
if (!oldValue.IsEmpty())
|
||||
mutation.mPrevAttrValue = getter_AddRefs(NS_NewAtom(oldValue));
|
||||
mutation.mAttrChange = nsIDOMMutationEvent::REMOVAL;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
Attributes()->RemoveElementAt(i);
|
||||
NS_RELEASE(attr);
|
||||
successful = PR_TRUE;
|
||||
|
|
|
@ -40,7 +40,6 @@ class nsIFocusController;
|
|||
#define NS_PIDOMWINDOW_IID \
|
||||
{ 0x3aa80781, 0x7e6a, 0x11d3, { 0xbf, 0x87, 0x0, 0x10, 0x5a, 0x1b, 0x6, 0x27 } }
|
||||
|
||||
|
||||
class nsPIDOMWindow : public nsISupports {
|
||||
public:
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_PIDOMWINDOW_IID; return iid; }
|
||||
|
@ -59,6 +58,9 @@ public:
|
|||
|
||||
NS_IMETHOD GetChromeEventHandler(nsIChromeEventHandler** aHandler)=0;
|
||||
|
||||
NS_IMETHOD HasMutationListeners(PRUint32 aMutationEventType, PRBool* aResult)=0;
|
||||
NS_IMETHOD SetMutationListeners(PRUint32 aType)=0;
|
||||
|
||||
NS_IMETHOD GetRootFocusController(nsIFocusController** aResult)=0;
|
||||
|
||||
/* from nsIBaseWindow */
|
||||
|
|
|
@ -6,6 +6,7 @@ nsIDOMEvent.h
|
|||
nsIDOMUIEvent.h
|
||||
nsIDOMKeyEvent.h
|
||||
nsIDOMMouseEvent.h
|
||||
nsIDOMMutationEvent.h
|
||||
nsIDOMNSUIEvent.h
|
||||
nsIDOMEventListener.h
|
||||
nsIDOMEventCapturer.h
|
||||
|
@ -16,6 +17,7 @@ nsIDOMKeyListener.h
|
|||
nsIDOMLoadListener.h
|
||||
nsIDOMMouseListener.h
|
||||
nsIDOMMouseMotionListener.h
|
||||
nsIDOMMutationListener.h
|
||||
nsIDOMDragListener.h
|
||||
nsIDOMPaintListener.h
|
||||
nsIDOMEventTarget.h
|
||||
|
@ -24,3 +26,4 @@ nsIDOMCompositionListener.h
|
|||
nsIDOMMenuListener.h
|
||||
nsIDOMScrollListener.h
|
||||
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ EXPORTS = \
|
|||
nsIDOMUIEvent.h \
|
||||
nsIDOMKeyEvent.h \
|
||||
nsIDOMMouseEvent.h \
|
||||
nsIDOMMutationEvent.h \
|
||||
nsIDOMEventListener.h \
|
||||
nsIDOMEventCapturer.h \
|
||||
nsIDOMEventReceiver.h \
|
||||
|
@ -42,6 +43,7 @@ EXPORTS = \
|
|||
nsIDOMLoadListener.h \
|
||||
nsIDOMMouseListener.h \
|
||||
nsIDOMMouseMotionListener.h \
|
||||
nsIDOMMutationListener.h \
|
||||
nsIDOMPaintListener.h \
|
||||
nsIDOMDragListener.h \
|
||||
nsIDOMNSUIEvent.h \
|
||||
|
|
|
@ -29,6 +29,7 @@ EXPORTS = \
|
|||
nsIDOMUIEvent.h \
|
||||
nsIDOMKeyEvent.h \
|
||||
nsIDOMMouseEvent.h \
|
||||
nsIDOMMutationEvent.h \
|
||||
nsIDOMEventListener.h \
|
||||
nsIDOMEventCapturer.h \
|
||||
nsIDOMEventReceiver.h \
|
||||
|
@ -38,6 +39,7 @@ EXPORTS = \
|
|||
nsIDOMLoadListener.h \
|
||||
nsIDOMMouseListener.h \
|
||||
nsIDOMMouseMotionListener.h \
|
||||
nsIDOMMutationListener.h \
|
||||
nsIDOMPaintListener.h \
|
||||
nsIDOMDragListener.h \
|
||||
nsIDOMNSUIEvent.h \
|
||||
|
|
|
@ -0,0 +1,83 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
/* AUTO-GENERATED. DO NOT EDIT!!! */
|
||||
|
||||
#ifndef nsIDOMMutationEvent_h__
|
||||
#define nsIDOMMutationEvent_h__
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
|
||||
class nsIDOMNode;
|
||||
|
||||
#define NS_IDOMMUTATIONEVENT_IID \
|
||||
{ 0x8e440d86, 0x886a, 0x4e76, { 0x9e, 0x59, 0xc1, 0x3b, 0x93, 0x9c, 0x9a, 0x4b } }
|
||||
|
||||
class nsIDOMMutationEvent : public nsIDOMEvent {
|
||||
public:
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_IDOMMUTATIONEVENT_IID; return iid; }
|
||||
enum {
|
||||
MODIFICATION = 1,
|
||||
ADDITION = 2,
|
||||
REMOVAL = 3
|
||||
};
|
||||
|
||||
NS_IMETHOD GetRelatedNode(nsIDOMNode** aRelatedNode)=0;
|
||||
|
||||
NS_IMETHOD GetPrevValue(nsAWritableString& aPrevValue)=0;
|
||||
|
||||
NS_IMETHOD GetNewValue(nsAWritableString& aNewValue)=0;
|
||||
|
||||
NS_IMETHOD GetAttrName(nsAWritableString& aAttrName)=0;
|
||||
|
||||
NS_IMETHOD GetAttrChange(PRUint16* aAttrChange)=0;
|
||||
|
||||
NS_IMETHOD InitMutationEvent(const nsAReadableString& aTypeArg, PRBool aCanBubbleArg, PRBool aCancelableArg, nsIDOMNode* aRelatedNodeArg, const nsAReadableString& aPrevValueArg, const nsAReadableString& aNewValueArg, const nsAReadableString& aAttrNameArg)=0;
|
||||
};
|
||||
|
||||
|
||||
#define NS_DECL_IDOMMUTATIONEVENT \
|
||||
NS_IMETHOD GetRelatedNode(nsIDOMNode** aRelatedNode); \
|
||||
NS_IMETHOD GetPrevValue(nsAWritableString& aPrevValue); \
|
||||
NS_IMETHOD GetNewValue(nsAWritableString& aNewValue); \
|
||||
NS_IMETHOD GetAttrName(nsAWritableString& aAttrName); \
|
||||
NS_IMETHOD GetAttrChange(PRUint16* aAttrChange); \
|
||||
NS_IMETHOD InitMutationEvent(const nsAReadableString& aTypeArg, PRBool aCanBubbleArg, PRBool aCancelableArg, nsIDOMNode* aRelatedNodeArg, const nsAReadableString& aPrevValueArg, const nsAReadableString& aNewValueArg, const nsAReadableString& aAttrNameArg); \
|
||||
|
||||
|
||||
|
||||
#define NS_FORWARD_IDOMMUTATIONEVENT(_to) \
|
||||
NS_IMETHOD GetRelatedNode(nsIDOMNode** aRelatedNode) { return _to GetRelatedNode(aRelatedNode); } \
|
||||
NS_IMETHOD GetPrevValue(nsAWritableString& aPrevValue) { return _to GetPrevValue(aPrevValue); } \
|
||||
NS_IMETHOD GetNewValue(nsAWritableString& aNewValue) { return _to GetNewValue(aNewValue); } \
|
||||
NS_IMETHOD GetAttrName(nsAWritableString& aAttrName) { return _to GetAttrName(aAttrName); } \
|
||||
NS_IMETHOD GetAttrChange(PRUint16* aAttrChange) { return _to GetAttrChange(aAttrChange); } \
|
||||
NS_IMETHOD InitMutationEvent(const nsAReadableString& aTypeArg, PRBool aCanBubbleArg, PRBool aCancelableArg, nsIDOMNode* aRelatedNodeArg, const nsAReadableString& aPrevValueArg, const nsAReadableString& aNewValueArg, const nsAReadableString& aAttrNameArg) { return _to InitMutationEvent(aTypeArg, aCanBubbleArg, aCancelableArg, aRelatedNodeArg, aPrevValueArg, aNewValueArg, aAttrNameArg); } \
|
||||
|
||||
|
||||
extern "C" NS_DOM nsresult NS_InitMutationEventClass(nsIScriptContext *aContext, void **aPrototype);
|
||||
|
||||
extern "C" NS_DOM nsresult NS_NewScriptMutationEvent(nsIScriptContext *aContext, nsISupports *aSupports, nsISupports *aParent, void **aReturn);
|
||||
|
||||
#endif // nsIDOMMutationEvent_h__
|
|
@ -0,0 +1,48 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef nsIDOMMutationListener_h__
|
||||
#define nsIDOMMutationListener_h__
|
||||
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
|
||||
/*
|
||||
* Mutation event listener interface.
|
||||
*/
|
||||
// {0666EC94-3C54-4e16-8511-E8CC865F236C}
|
||||
#define NS_IDOMMUTATIONLISTENER_IID \
|
||||
{ 0x666ec94, 0x3c54, 0x4e16, { 0x85, 0x11, 0xe8, 0xcc, 0x86, 0x5f, 0x23, 0x6c } }
|
||||
|
||||
class nsIDOMMutationListener : public nsIDOMEventListener {
|
||||
public:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(NS_IDOMMUTATIONLISTENER_IID)
|
||||
|
||||
NS_IMETHOD SubtreeModified(nsIDOMEvent* aMutationEvent)=0;
|
||||
NS_IMETHOD NodeInserted(nsIDOMEvent* aMutationEvent)=0;
|
||||
NS_IMETHOD NodeRemoved(nsIDOMEvent* aMutationEvent)=0;
|
||||
NS_IMETHOD NodeRemovedFromDocument(nsIDOMEvent* aMutationEvent)=0;
|
||||
NS_IMETHOD NodeInsertedIntoDocument(nsIDOMEvent* aMutationEvent)=0;
|
||||
NS_IMETHOD AttrModified(nsIDOMEvent* aMutationEvent)=0;
|
||||
NS_IMETHOD CharacterDataModified(nsIDOMEvent* aMutationEvent)=0;
|
||||
};
|
||||
#endif // nsIDOMMutationListener_h__
|
|
@ -30,6 +30,8 @@ MODULE = layout
|
|||
|
||||
IDLSRCS = \
|
||||
Event.idl \
|
||||
MutationEvent.idl \
|
||||
MouseKeyEvent.idl \
|
||||
UIEvent.idl \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ IDLSRCS = \
|
|||
Event.idl \
|
||||
UIEvent.idl \
|
||||
MouseKeyEvent.idl \
|
||||
MutationEvent.idl \
|
||||
|
||||
XPCOM_DESTDIR=$(DEPTH)\dom\public\coreEvents
|
||||
JSSTUB_DESTDIR=$(DEPTH)\dom\src\events
|
||||
|
|
|
@ -706,6 +706,12 @@ enum nsDOMProp {
|
|||
NS_DOM_PROP_MOUSEEVENT_RELATEDTARGET,
|
||||
NS_DOM_PROP_MOUSEEVENT_SCREENX,
|
||||
NS_DOM_PROP_MOUSEEVENT_SCREENY,
|
||||
NS_DOM_PROP_MUTATIONEVENT_ATTRCHANGE,
|
||||
NS_DOM_PROP_MUTATIONEVENT_ATTRNAME,
|
||||
NS_DOM_PROP_MUTATIONEVENT_INITMUTATIONEVENT,
|
||||
NS_DOM_PROP_MUTATIONEVENT_NEWVALUE,
|
||||
NS_DOM_PROP_MUTATIONEVENT_PREVVALUE,
|
||||
NS_DOM_PROP_MUTATIONEVENT_RELATEDNODE,
|
||||
NS_DOM_PROP_NAMEDNODEMAP_GETNAMEDITEM,
|
||||
NS_DOM_PROP_NAMEDNODEMAP_GETNAMEDITEMNS,
|
||||
NS_DOM_PROP_NAMEDNODEMAP_ITEM,
|
||||
|
|
|
@ -704,6 +704,12 @@
|
|||
"mouseevent.relatedtarget", \
|
||||
"mouseevent.screenx", \
|
||||
"mouseevent.screeny", \
|
||||
"mutationevent.attrchange", \
|
||||
"mutationevent.attrname", \
|
||||
"mutationevent.initmutationevent", \
|
||||
"mutationevent.newvalue", \
|
||||
"mutationevent.prevvalue", \
|
||||
"mutationevent.relatednode", \
|
||||
"namednodemap.getnameditem", \
|
||||
"namednodemap.getnameditemns", \
|
||||
"namednodemap.item", \
|
||||
|
|
|
@ -141,7 +141,7 @@ GlobalWindowImpl::GlobalWindowImpl() :
|
|||
mTimeouts(nsnull), mTimeoutInsertionPoint(&mTimeouts), mRunningTimeout(nsnull),
|
||||
mTimeoutPublicIdCounter(1), mTimeoutFiringDepth(0),
|
||||
mFirstDocumentLoad(PR_TRUE), mGlobalObjectOwner(nsnull), mDocShell(nsnull),
|
||||
mChromeEventHandler(nsnull)
|
||||
mChromeEventHandler(nsnull), mMutationBits(0)
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
if (gRefCnt++ == 0) {
|
||||
|
@ -386,6 +386,9 @@ NS_IMETHODIMP GlobalWindowImpl::SetNewDocument(nsIDOMDocument* aDocument)
|
|||
if (mDocument && mContext)
|
||||
mContext->InitContext(this);
|
||||
|
||||
// Clear our mutation bitfield.
|
||||
mMutationBits = 0;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2826,7 +2829,20 @@ GlobalWindowImpl::GetRootFocusController(nsIFocusController** aController)
|
|||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GlobalWindowImpl::HasMutationListeners(PRUint32 aMutationEventType, PRBool* aResult)
|
||||
{
|
||||
*aResult = (mMutationBits & aMutationEventType) != 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
GlobalWindowImpl::SetMutationListeners(PRUint32 aType)
|
||||
{
|
||||
mMutationBits |= aType;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -161,9 +161,11 @@ public:
|
|||
|
||||
NS_IMETHOD GetChromeEventHandler(nsIChromeEventHandler** aHandler);
|
||||
|
||||
NS_IMETHOD HasMutationListeners(PRUint32 aMutationEventType, PRBool* aResult);
|
||||
NS_IMETHOD SetMutationListeners(PRUint32 aEventType);
|
||||
|
||||
NS_IMETHOD GetRootFocusController(nsIFocusController** aResult);
|
||||
|
||||
|
||||
NS_IMETHOD SetPositionAndSize(PRInt32 x, PRInt32 y, PRInt32 cx, PRInt32 cy, PRBool fRepaint);
|
||||
NS_IMETHOD GetPositionAndSize(PRInt32 *x, PRInt32 *y, PRInt32 *cx, PRInt32 *cy);
|
||||
|
||||
|
@ -254,6 +256,7 @@ protected:
|
|||
|
||||
nsIScriptGlobalObjectOwner* mGlobalObjectOwner; // Weak Reference
|
||||
nsIDocShell* mDocShell; // Weak Reference
|
||||
PRUint32 mMutationBits;
|
||||
nsCOMPtr<nsIChromeEventHandler> mChromeEventHandler; // [Strong] We break it when we get torn down.
|
||||
nsCOMPtr<nsIDOMCrypto> mCrypto;
|
||||
nsCOMPtr<nsIDOMPkcs11> mPkcs11;
|
||||
|
|
|
@ -36,6 +36,7 @@ CPPSRCS = \
|
|||
nsJSEvent.cpp \
|
||||
nsJSUIEvent.cpp \
|
||||
nsJSKeyEvent.cpp \
|
||||
nsJSMutationEvent.cpp \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
|
|
|
@ -33,10 +33,11 @@ CPPSRCS = \
|
|||
nsJSEvent.cpp \
|
||||
nsJSUIEvent.cpp \
|
||||
nsJSKeyEvent.cpp \
|
||||
nsJSMutationEvent.cpp \
|
||||
$(NULL)
|
||||
|
||||
CPP_OBJS= \
|
||||
.\$(OBJDIR)\nsJSEventListener.obj .\$(OBJDIR)\nsJSDOMEventListener.obj .\$(OBJDIR)\nsJSEvent.obj .\$(OBJDIR)\nsJSUIEvent.obj .\$(OBJDIR)\nsJSKeyEvent.obj
|
||||
.\$(OBJDIR)\nsJSEventListener.obj .\$(OBJDIR)\nsJSMutationEvent.obj .\$(OBJDIR)\nsJSDOMEventListener.obj .\$(OBJDIR)\nsJSEvent.obj .\$(OBJDIR)\nsJSUIEvent.obj .\$(OBJDIR)\nsJSKeyEvent.obj
|
||||
|
||||
LINCS=-I$(XPDIST)\public\xpcom -I$(XPDIST)\public\raptor -I$(XPDIST)\public\dom -I$(XPDIST)\public\js
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "nsJSDOMEventListener.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsJSUtils.h"
|
||||
|
@ -79,8 +80,10 @@ NS_IMPL_RELEASE(nsJSDOMEventListener)
|
|||
nsresult nsJSDOMEventListener::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
JSObject *eventObj;
|
||||
if (NS_OK != NS_NewScriptKeyEvent(mContext, aEvent, nsnull, (void**)&eventObj))
|
||||
return NS_ERROR_FAILURE;
|
||||
if (NS_OK != NS_NewScriptKeyEvent(mContext, aEvent, nsnull, (void**)&eventObj)) {
|
||||
if (NS_OK != NS_NewScriptMutationEvent(mContext, aEvent, nsnull, (void**)&eventObj))
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
jsval argv[1];
|
||||
argv[0] = OBJECT_TO_JSVAL(eventObj);
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -164,6 +164,15 @@ LAYOUT_ATOM(onoverflow, "onoverflow")
|
|||
LAYOUT_ATOM(onunderflow, "onunderflow")
|
||||
LAYOUT_ATOM(onoverflowchanged, "onoverflowchanged")
|
||||
|
||||
// mutation events
|
||||
LAYOUT_ATOM(onDOMSubtreeModified, "onDOMSubtreeModified")
|
||||
LAYOUT_ATOM(onDOMNodeInserted, "onDOMNodeInserted")
|
||||
LAYOUT_ATOM(onDOMNodeRemoved, "onDOMNodeRemoved")
|
||||
LAYOUT_ATOM(onDOMNodeRemovedFromDocument, "onDOMNodeRemovedFromDocument")
|
||||
LAYOUT_ATOM(onDOMNodeInsertedIntoDocument, "onDOMNodeInsertedIntoDocument")
|
||||
LAYOUT_ATOM(onDOMAttrModified, "onDOMAttrModified")
|
||||
LAYOUT_ATOM(onDOMCharacterDataModified, "onDOMCharacterDataModified")
|
||||
|
||||
// Alphabetical list of languages for lang-specific transforms
|
||||
LAYOUT_ATOM(Japanese, "ja")
|
||||
LAYOUT_ATOM(Korean, "ko")
|
||||
|
|
|
@ -1,190 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
/******
|
||||
|
||||
This file contains the list of all layout nsIAtoms and their values
|
||||
|
||||
It is designed to be used as inline input to nsLayoutAtoms.cpp *only*
|
||||
through the magic of C preprocessing.
|
||||
|
||||
All entires must be enclosed in the macro LAYOUT_ATOM which will have cruel
|
||||
and unusual things done to it
|
||||
|
||||
It is recommended (but not strictly necessary) to keep all entries
|
||||
in alphabetical order
|
||||
|
||||
The first argument to LAYOUT_ATOM is the C++ identifier of the atom
|
||||
The second argument is the string value of the atom
|
||||
|
||||
******/
|
||||
|
||||
|
||||
// Alphabetical list of media type atoms
|
||||
LAYOUT_ATOM(all, "all") // Media atoms must be lower case
|
||||
LAYOUT_ATOM(aural, "aural")
|
||||
LAYOUT_ATOM(braille, "braille")
|
||||
LAYOUT_ATOM(embossed, "embossed")
|
||||
LAYOUT_ATOM(handheld, "handheld")
|
||||
LAYOUT_ATOM(print, "print")
|
||||
LAYOUT_ATOM(projection, "projection")
|
||||
LAYOUT_ATOM(screen, "screen")
|
||||
LAYOUT_ATOM(tty, "tty")
|
||||
LAYOUT_ATOM(tv, "tv")
|
||||
|
||||
// Alphabetical list of standard name space prefixes
|
||||
LAYOUT_ATOM(htmlNameSpace, "html")
|
||||
LAYOUT_ATOM(xmlNameSpace, "xml")
|
||||
LAYOUT_ATOM(xmlnsNameSpace, "xmlns")
|
||||
|
||||
// Alphabetical list of frame additional child list names
|
||||
LAYOUT_ATOM(absoluteList, "Absolute-list")
|
||||
LAYOUT_ATOM(bulletList, "Bullet-list")
|
||||
LAYOUT_ATOM(captionList, "Caption-list")
|
||||
LAYOUT_ATOM(colGroupList, "ColGroup-list")
|
||||
LAYOUT_ATOM(editorDisplayList, "EditorDisplay-List")
|
||||
LAYOUT_ATOM(fixedList, "Fixed-list")
|
||||
LAYOUT_ATOM(floaterList, "Floater-list")
|
||||
LAYOUT_ATOM(overflowList, "Overflow-list")
|
||||
LAYOUT_ATOM(popupList, "Popup-list")
|
||||
|
||||
// Alphabetical list of pseudo tag names for non-element content
|
||||
LAYOUT_ATOM(canvasPseudo, ":canvas")
|
||||
LAYOUT_ATOM(commentTagName, "__moz_comment")
|
||||
LAYOUT_ATOM(dummyOptionPseudo, ":-moz-dummy-option")
|
||||
LAYOUT_ATOM(optionSelectedPseudo, "-moz-option-selected")
|
||||
LAYOUT_ATOM(textTagName, "__moz_text")
|
||||
LAYOUT_ATOM(pagePseudo, ":-moz-page")
|
||||
LAYOUT_ATOM(pageSequencePseudo, ":-moz-page-sequence")
|
||||
LAYOUT_ATOM(processingInstructionTagName, "__moz_pi")
|
||||
LAYOUT_ATOM(scrolledContentPseudo, ":scrolled-content")
|
||||
LAYOUT_ATOM(viewportPseudo, ":viewport")
|
||||
LAYOUT_ATOM(viewportScrollPseudo, ":viewport-scroll")
|
||||
LAYOUT_ATOM(selectScrolledContentPseudo, ":-moz-select-scrolled-content")
|
||||
|
||||
// Alphabetical list of frame types
|
||||
LAYOUT_ATOM(areaFrame, "AreaFrame")
|
||||
LAYOUT_ATOM(blockFrame, "BlockFrame")
|
||||
LAYOUT_ATOM(brFrame, "BRFrame")
|
||||
LAYOUT_ATOM(bulletFrame, "BulletFrame")
|
||||
LAYOUT_ATOM(hrFrame, "HRFrame")
|
||||
LAYOUT_ATOM(htmlFrameInnerFrame, "htmlFrameInnerFrame")
|
||||
LAYOUT_ATOM(htmlFrameOuterFrame, "htmlFrameOuterFrame")
|
||||
LAYOUT_ATOM(imageFrame, "ImageFrame")
|
||||
LAYOUT_ATOM(inlineFrame, "InlineFrame")
|
||||
LAYOUT_ATOM(letterFrame, "LetterFrame")
|
||||
LAYOUT_ATOM(lineFrame, "LineFrame")
|
||||
LAYOUT_ATOM(objectFrame, "ObjectFrame")
|
||||
LAYOUT_ATOM(pageFrame, "PageFrame")
|
||||
LAYOUT_ATOM(placeholderFrame, "PlaceholderFrame")
|
||||
LAYOUT_ATOM(positionedInlineFrame, "PositionedInlineFrame")
|
||||
LAYOUT_ATOM(canvasFrame, "CanvasFrame")
|
||||
LAYOUT_ATOM(rootFrame, "RootFrame")
|
||||
LAYOUT_ATOM(scrollFrame, "ScrollFrame")
|
||||
LAYOUT_ATOM(tableCaptionFrame, "TableCaptionFrame")
|
||||
LAYOUT_ATOM(tableCellFrame, "TableCellFrame")
|
||||
LAYOUT_ATOM(tableColFrame, "TableColFrame")
|
||||
LAYOUT_ATOM(tableColGroupFrame, "TableColGroupFrame")
|
||||
LAYOUT_ATOM(tableFrame, "TableFrame")
|
||||
LAYOUT_ATOM(tableOuterFrame, "TableOuterFrame")
|
||||
LAYOUT_ATOM(tableRowGroupFrame, "TableRowGroupFrame")
|
||||
LAYOUT_ATOM(tableRowFrame, "TableRowFrame")
|
||||
LAYOUT_ATOM(textInputFrame,"TextInputFrame")
|
||||
LAYOUT_ATOM(textFrame, "TextFrame")
|
||||
LAYOUT_ATOM(viewportFrame, "ViewportFrame")
|
||||
|
||||
// Alphabetical list of frame property names
|
||||
LAYOUT_ATOM(collapseOffsetProperty, "CollapseOffsetProperty") // nsPoint*
|
||||
LAYOUT_ATOM(inlineFrameAnnotation, "InlineFrameAnnotation") // BOOL
|
||||
LAYOUT_ATOM(maxElementSizeProperty, "MaxElementSizeProperty") // nsSize*
|
||||
LAYOUT_ATOM(overflowAreaProperty, "OverflowArea") // nsRect*
|
||||
LAYOUT_ATOM(overflowProperty, "OverflowProperty") // list of nsIFrame*
|
||||
LAYOUT_ATOM(overflowLinesProperty, "OverflowLinesProperty") // list of nsLineBox*
|
||||
LAYOUT_ATOM(spaceManagerProperty, "SpaceManagerProperty") // the space manager for a block
|
||||
LAYOUT_ATOM(viewProperty, "ViewProperty") // nsView*
|
||||
|
||||
// Alphabetical list of event handler names
|
||||
LAYOUT_ATOM(onabort, "onabort")
|
||||
LAYOUT_ATOM(onblur, "onblur")
|
||||
LAYOUT_ATOM(onbroadcast, "onbroadcast")
|
||||
LAYOUT_ATOM(onchange, "onchange")
|
||||
LAYOUT_ATOM(onclick, "onclick")
|
||||
LAYOUT_ATOM(onclose, "onclose")
|
||||
LAYOUT_ATOM(oncommand, "oncommand")
|
||||
LAYOUT_ATOM(oncommandupdate, "oncommandupdate")
|
||||
LAYOUT_ATOM(oncreate, "oncreate")
|
||||
LAYOUT_ATOM(ondblclick, "ondblclick")
|
||||
LAYOUT_ATOM(ondestroy, "ondestroy")
|
||||
LAYOUT_ATOM(ondragdrop, "ondragdrop")
|
||||
LAYOUT_ATOM(ondragenter, "ondragenter")
|
||||
LAYOUT_ATOM(ondragexit, "ondragexit")
|
||||
LAYOUT_ATOM(ondraggesture, "ondraggesture")
|
||||
LAYOUT_ATOM(ondragover, "ondragover")
|
||||
LAYOUT_ATOM(onerror, "onerror")
|
||||
LAYOUT_ATOM(onfocus, "onfocus")
|
||||
LAYOUT_ATOM(oninput, "oninput")
|
||||
LAYOUT_ATOM(onkeydown, "onkeydown")
|
||||
LAYOUT_ATOM(onkeypress, "onkeypress")
|
||||
LAYOUT_ATOM(onkeyup, "onkeyup")
|
||||
LAYOUT_ATOM(onload, "onload")
|
||||
LAYOUT_ATOM(onmousedown, "onmousedown")
|
||||
LAYOUT_ATOM(onmousemove, "onmousemove")
|
||||
LAYOUT_ATOM(onmouseover, "onmouseover")
|
||||
LAYOUT_ATOM(onmouseout, "onmouseout")
|
||||
LAYOUT_ATOM(onmouseup, "onmouseup")
|
||||
LAYOUT_ATOM(onpaint, "onpaint")
|
||||
LAYOUT_ATOM(onreset, "onreset")
|
||||
LAYOUT_ATOM(onresize, "onresize")
|
||||
LAYOUT_ATOM(onscroll, "onscroll")
|
||||
LAYOUT_ATOM(onselect, "onselect")
|
||||
LAYOUT_ATOM(onsubmit, "onsubmit")
|
||||
LAYOUT_ATOM(onunload, "onunload")
|
||||
|
||||
// scrolling
|
||||
LAYOUT_ATOM(onoverflow, "onoverflow")
|
||||
LAYOUT_ATOM(onunderflow, "onunderflow")
|
||||
LAYOUT_ATOM(onoverflowchanged, "onoverflowchanged")
|
||||
|
||||
// Alphabetical list of languages for lang-specific transforms
|
||||
LAYOUT_ATOM(Japanese, "ja")
|
||||
LAYOUT_ATOM(Korean, "ko")
|
||||
|
||||
// other
|
||||
LAYOUT_ATOM(wildcard, "*")
|
||||
LAYOUT_ATOM(mozdirty, "_moz_dirty")
|
||||
|
||||
#ifdef DEBUG
|
||||
// Alphabetical list of atoms used by debugging code
|
||||
LAYOUT_ATOM(cellMap, "TableCellMap")
|
||||
LAYOUT_ATOM(imageMap, "ImageMap")
|
||||
LAYOUT_ATOM(lineBoxBig, "LineBox:inline,big")
|
||||
LAYOUT_ATOM(lineBoxBlockBig, "LineBox:block,big")
|
||||
LAYOUT_ATOM(lineBoxBlockSmall, "LineBox:block,small")
|
||||
LAYOUT_ATOM(lineBoxFloaters, "LineBoxFloaters")
|
||||
LAYOUT_ATOM(lineBoxSmall, "LineBox:inline,small")
|
||||
LAYOUT_ATOM(spaceManager, "SpaceManager")
|
||||
LAYOUT_ATOM(tableColCache, "TableColumnCache")
|
||||
LAYOUT_ATOM(tableStrategy, "TableLayoutStrategy")
|
||||
LAYOUT_ATOM(textRun, "TextRun")
|
||||
LAYOUT_ATOM(xml_document_entities, "XMLDocumentEntities")
|
||||
LAYOUT_ATOM(xml_document_notations, "XMLDocumentNotations")
|
||||
#endif
|
|
@ -33,6 +33,9 @@
|
|||
#include "nsISelectionPrivate.h"
|
||||
#include "nsIEnumerator.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsMutationEvent.h"
|
||||
#include "nsEventListenerManager.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
#include "nsCRT.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
|
@ -909,6 +912,73 @@ nsGenericDOMDataNode::CopyText(nsAWritableString& aResult)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static PRBool HasMutationListeners(nsIContent* aContent, PRUint32 aType)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aContent->GetDocument(*getter_AddRefs(doc));
|
||||
if (!doc)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> global;
|
||||
doc->GetScriptGlobalObject(getter_AddRefs(global));
|
||||
if (!global)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(global));
|
||||
if (!window)
|
||||
return PR_FALSE;
|
||||
|
||||
PRBool set;
|
||||
window->HasMutationListeners(aType, &set);
|
||||
if (!set)
|
||||
return PR_FALSE;
|
||||
|
||||
// We know a mutation listener is registered, but it might not
|
||||
// be in our chain. Check quickly to see.
|
||||
nsCOMPtr<nsIContent> curr = aContent;
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
while (curr) {
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(curr));
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> prev = curr;
|
||||
prev->GetParent(*getter_AddRefs(curr));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(doc));
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
rec = do_QueryInterface(window);
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericDOMDataNode::SetText(nsIContent *aOuterContent,
|
||||
const PRUnichar* aBuffer,
|
||||
|
@ -927,6 +997,22 @@ nsGenericDOMDataNode::SetText(nsIContent *aOuterContent,
|
|||
}
|
||||
mText.SetTo(aBuffer, aLength);
|
||||
|
||||
if (mDocument && HasMutationListeners(aOuterContent, NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(aOuterContent));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_CHARACTERDATAMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
// XXX Handle the setting of prevValue!
|
||||
nsAutoString newVal(aBuffer);
|
||||
if (!newVal.IsEmpty())
|
||||
mutation.mNewAttrValue = getter_AddRefs(NS_NewAtom(newVal));
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
// Trigger a reflow
|
||||
if (aNotify && (nsnull != mDocument)) {
|
||||
mDocument->ContentChanged(aOuterContent, nsnull);
|
||||
|
@ -951,6 +1037,22 @@ nsGenericDOMDataNode::SetText(nsIContent *aOuterContent, const char* aBuffer,
|
|||
}
|
||||
mText.SetTo(aBuffer, aLength);
|
||||
|
||||
if (mDocument && HasMutationListeners(aOuterContent, NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(aOuterContent));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_CHARACTERDATAMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
// XXX Handle the setting of prevValue!
|
||||
nsAutoString newVal; newVal.AssignWithConversion(aBuffer);
|
||||
if (!newVal.IsEmpty())
|
||||
mutation.mNewAttrValue = getter_AddRefs(NS_NewAtom(newVal));
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
// Trigger a reflow
|
||||
if (aNotify && (nsnull != mDocument)) {
|
||||
mDocument->ContentChanged(aOuterContent, nsnull);
|
||||
|
|
|
@ -61,12 +61,16 @@
|
|||
#include "prmem.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsScriptSecurityManager.h"
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
#include "nsMutationEvent.h"
|
||||
|
||||
#include "nsIBindingManager.h"
|
||||
#include "nsIXBLBinding.h"
|
||||
#include "nsIDOMCSSStyleDeclaration.h"
|
||||
#include "nsIDOMViewCSS.h"
|
||||
#include "nsIXBLService.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsEventListenerManager.h"
|
||||
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsHTMLAtoms.h"
|
||||
|
@ -2718,6 +2722,73 @@ nsGenericContainerElement::SetAttribute(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
return SetAttribute(ni, aValue, aNotify);
|
||||
}
|
||||
|
||||
static PRBool HasMutationListeners(nsIContent* aContent, PRUint32 aType)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aContent->GetDocument(*getter_AddRefs(doc));
|
||||
if (!doc)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> global;
|
||||
doc->GetScriptGlobalObject(getter_AddRefs(global));
|
||||
if (!global)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(global));
|
||||
if (!window)
|
||||
return PR_FALSE;
|
||||
|
||||
PRBool set;
|
||||
window->HasMutationListeners(aType, &set);
|
||||
if (!set)
|
||||
return PR_FALSE;
|
||||
|
||||
// We know a mutation listener is registered, but it might not
|
||||
// be in our chain. Check quickly to see.
|
||||
nsCOMPtr<nsIContent> curr = aContent;
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
while (curr) {
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(curr));
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> prev = curr;
|
||||
prev->GetParent(*getter_AddRefs(curr));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(doc));
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
rec = do_QueryInterface(window);
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericContainerElement::SetAttribute(nsINodeInfo* aNodeInfo,
|
||||
const nsAReadableString& aValue,
|
||||
|
@ -2725,6 +2796,9 @@ nsGenericContainerElement::SetAttribute(nsINodeInfo* aNodeInfo,
|
|||
{
|
||||
NS_ENSURE_ARG_POINTER(aNodeInfo);
|
||||
|
||||
PRBool modification = PR_FALSE;
|
||||
nsAutoString oldValue;
|
||||
|
||||
nsresult rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (!mAttributes) {
|
||||
|
@ -2742,6 +2816,8 @@ nsGenericContainerElement::SetAttribute(nsINodeInfo* aNodeInfo,
|
|||
for (index = 0; index < count; index++) {
|
||||
attr = (nsGenericAttribute*)mAttributes->ElementAt(index);
|
||||
if (attr->mNodeInfo == aNodeInfo) {
|
||||
oldValue = attr->mValue;
|
||||
modification = PR_TRUE;
|
||||
attr->mValue = aValue;
|
||||
rv = NS_OK;
|
||||
break;
|
||||
|
@ -2770,6 +2846,31 @@ nsGenericContainerElement::SetAttribute(nsINodeInfo* aNodeInfo,
|
|||
if (binding)
|
||||
binding->AttributeChanged(name, nameSpaceID, PR_FALSE);
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_ATTRMODIFIED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(mContent));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_ATTRMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsAutoString attrName;
|
||||
name->ToString(attrName);
|
||||
nsCOMPtr<nsIDOMAttr> attrNode;
|
||||
GetAttributeNode(attrName, getter_AddRefs(attrNode));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = name;
|
||||
if (!oldValue.IsEmpty())
|
||||
mutation.mPrevAttrValue = getter_AddRefs(NS_NewAtom(oldValue));
|
||||
if (!aValue.IsEmpty())
|
||||
mutation.mNewAttrValue = getter_AddRefs(NS_NewAtom(aValue));
|
||||
mutation.mAttrChange = modification ? nsIDOMMutationEvent::MODIFICATION :
|
||||
nsIDOMMutationEvent::ADDITION;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
mContent->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if (aNotify) {
|
||||
mDocument->AttributeChanged(mContent, nameSpaceID, name, NS_STYLE_HINT_UNKNOWN);
|
||||
mDocument->EndUpdate();
|
||||
|
@ -2854,6 +2955,30 @@ nsGenericContainerElement::UnsetAttribute(PRInt32 aNameSpaceID,
|
|||
if (aNotify && (nsnull != mDocument)) {
|
||||
mDocument->BeginUpdate();
|
||||
}
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_ATTRMODIFIED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(mContent));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_ATTRMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsAutoString attrName;
|
||||
aName->ToString(attrName);
|
||||
nsCOMPtr<nsIDOMAttr> attrNode;
|
||||
GetAttributeNode(attrName, getter_AddRefs(attrNode));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = aName;
|
||||
if (!attr->mValue.IsEmpty())
|
||||
mutation.mPrevAttrValue = getter_AddRefs(NS_NewAtom(attr->mValue));
|
||||
mutation.mAttrChange = nsIDOMMutationEvent::REMOVAL;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
mContent->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
mAttributes->RemoveElementAt(index);
|
||||
delete attr;
|
||||
found = PR_TRUE;
|
||||
|
@ -3036,6 +3161,21 @@ nsGenericContainerElement::InsertChildAt(nsIContent* aKid,
|
|||
if (aNotify) {
|
||||
doc->ContentInserted(mContent, aKid, aIndex);
|
||||
}
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(aKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEINSERTED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(mContent));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
aKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aNotify && (nsnull != doc)) {
|
||||
|
@ -3094,6 +3234,21 @@ nsGenericContainerElement::AppendChildTo(nsIContent* aKid, PRBool aNotify)
|
|||
if (aNotify) {
|
||||
doc->ContentAppended(mContent, mChildren.Count() - 1);
|
||||
}
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(aKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEINSERTED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(mContent));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
aKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aNotify && (nsnull != doc)) {
|
||||
|
@ -3111,6 +3266,22 @@ nsGenericContainerElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify)
|
|||
if (aNotify && (nsnull != doc)) {
|
||||
doc->BeginUpdate();
|
||||
}
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_NODEREMOVED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(oldKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEREMOVED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(mContent));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
oldKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
nsRange::OwnerChildRemoved(mContent, aIndex, oldKid);
|
||||
mChildren.RemoveElementAt(aIndex);
|
||||
if (aNotify) {
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
#
|
||||
# This is a list of local files which get copied to the mozilla:dist:layout directory
|
||||
#
|
||||
nsIEventListenerManager.h
|
||||
nsIEventStateManager.h
|
||||
nsIPrivateDOMEvent.h
|
||||
nsIPrivateTextEvent.h
|
||||
nsIPrivateTextRange.h
|
||||
nsIPrivateCompositionEvent.h
|
|
@ -1,43 +0,0 @@
|
|||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = layout
|
||||
|
||||
EXPORTS = \
|
||||
nsIEventListenerManager.h \
|
||||
nsIEventStateManager.h \
|
||||
nsIPrivateDOMEvent.h \
|
||||
nsIPrivateTextEvent.h \
|
||||
nsIPrivateTextRange.h \
|
||||
nsIPrivateCompositionEvent.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS))
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
@ -1,37 +0,0 @@
|
|||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..
|
||||
|
||||
|
||||
EXPORTS = \
|
||||
nsIEventListenerManager.h \
|
||||
nsIEventStateManager.h \
|
||||
nsIPrivateDOMEvent.h \
|
||||
nsIPrivateTextEvent.h \
|
||||
nsIPrivateTextRange.h \
|
||||
nsIPrivateCompositionEvent.h \
|
||||
$(NULL)
|
||||
|
||||
MODULE=raptor
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
|
@ -1,149 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef nsIEventListenerManager_h__
|
||||
#define nsIEventListenerManager_h__
|
||||
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
||||
class nsIPresContext;
|
||||
class nsIDOMEventListener;
|
||||
class nsIScriptObjectOwner;
|
||||
class nsIDOMEventTarget;
|
||||
|
||||
/*
|
||||
* Event listener manager interface.
|
||||
*/
|
||||
#define NS_IEVENTLISTENERMANAGER_IID \
|
||||
{ /* cd91bcf0-ded9-11d1-bd85-00805f8ae3f4 */ \
|
||||
0xcd91bcf0, 0xded9, 0x11d1, \
|
||||
{0xbd, 0x85, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} }
|
||||
|
||||
class nsIEventListenerManager : public nsISupports {
|
||||
|
||||
public:
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_IEVENTLISTENERMANAGER_IID; return iid; }
|
||||
|
||||
/**
|
||||
* Retrieves events listeners of all types.
|
||||
* @param
|
||||
*/
|
||||
virtual nsresult GetEventListeners(nsVoidArray **aListeners, const nsIID& aIID) = 0;
|
||||
|
||||
/**
|
||||
* Sets events listeners of all types.
|
||||
* @param an event listener
|
||||
*/
|
||||
virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 flags) = 0;
|
||||
|
||||
/**
|
||||
* Removes events listeners of all types.
|
||||
* @param an event listener
|
||||
*/
|
||||
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 flags) = 0;
|
||||
|
||||
/**
|
||||
* Sets events listeners of all types.
|
||||
* @param an event listener
|
||||
*/
|
||||
virtual nsresult AddEventListenerByType(nsIDOMEventListener *aListener, const nsAReadableString& type, PRInt32 flags) = 0;
|
||||
|
||||
/**
|
||||
* Removes events listeners of all types.
|
||||
* @param an event listener
|
||||
*/
|
||||
virtual nsresult RemoveEventListenerByType(nsIDOMEventListener *aListener, const nsAReadableString& type, PRInt32 flags) = 0;
|
||||
|
||||
/**
|
||||
* Creates a script event listener for the given script object with name mName and function
|
||||
* body mFunc.
|
||||
* @param an event listener
|
||||
*/
|
||||
virtual nsresult AddScriptEventListener(nsIScriptContext*aContext,
|
||||
nsIScriptObjectOwner *aScriptObjectOwner,
|
||||
nsIAtom *aName,
|
||||
const nsAReadableString& aFunc,
|
||||
REFNSIID aIID,
|
||||
PRBool aDeferCompilation) = 0;
|
||||
|
||||
/**
|
||||
* Registers an event listener that already exists on the given script object with the event
|
||||
* listener manager.
|
||||
* @param an event listener
|
||||
*/
|
||||
virtual nsresult RegisterScriptEventListener(nsIScriptContext *aContext,
|
||||
nsIScriptObjectOwner *aScriptObjectOwner,
|
||||
nsIAtom* aName,
|
||||
REFNSIID aIID) = 0;
|
||||
|
||||
/**
|
||||
* Causes a check for event listeners and processing by them if they exist.
|
||||
* Event flags live in nsGUIEvent.h
|
||||
* @param an event listener
|
||||
*/
|
||||
virtual nsresult HandleEvent(nsIPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
nsIDOMEventTarget* aCurrentTarget,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus) = 0;
|
||||
|
||||
/**
|
||||
* Creates a DOM event that can subsequently be passed into HandleEvent.
|
||||
* (used rarely in the situation where methods on the event need to be
|
||||
* invoked prior to the processing of the event).
|
||||
*/
|
||||
virtual nsresult CreateEvent(nsIPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
const nsAReadableString& aEventType,
|
||||
nsIDOMEvent** aDOMEvent) = 0;
|
||||
|
||||
/**
|
||||
* Changes script listener of specified event types from bubbling listeners to capturing listeners.
|
||||
* @param event types
|
||||
*/
|
||||
virtual nsresult CaptureEvent(PRInt32 aEventTypes) = 0;
|
||||
|
||||
/**
|
||||
* Changes script listener of specified event types from capturing listeners to bubbling listeners.
|
||||
* @param event types
|
||||
*/
|
||||
virtual nsresult ReleaseEvent(PRInt32 aEventTypes) = 0;
|
||||
|
||||
/**
|
||||
* Removes all event listeners registered by this instance of the listener
|
||||
* manager.
|
||||
*/
|
||||
virtual nsresult RemoveAllListeners(PRBool aScriptOnly) = 0;
|
||||
|
||||
/**
|
||||
* Removes all event listeners registered by this instance of the listener
|
||||
* manager.
|
||||
*/
|
||||
virtual nsresult SetListenerTarget(nsISupports* aTarget) = 0;
|
||||
};
|
||||
|
||||
extern NS_HTML nsresult NS_NewEventListenerManager(nsIEventListenerManager** aInstancePtrResult);
|
||||
|
||||
#endif // nsIEventListenerManager_h__
|
|
@ -1,62 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef nsIPrivateDOMEvent_h__
|
||||
#define nsIPrivateDOMEvent_h__
|
||||
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsISupports.h"
|
||||
|
||||
class nsIPresContext;
|
||||
|
||||
/*
|
||||
* Event listener manager interface.
|
||||
*/
|
||||
#define NS_IPRIVATEDOMEVENT_IID \
|
||||
{ /* 80a98c80-2036-11d2-bd89-00805f8ae3f4 */ \
|
||||
0x80a98c80, 0x2036, 0x11d2, \
|
||||
{0xbd, 0x89, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} }
|
||||
|
||||
class nsIDOMEventTarget;
|
||||
class nsIDOMEvent;
|
||||
|
||||
class nsIPrivateDOMEvent : public nsISupports {
|
||||
|
||||
public:
|
||||
static const nsIID& GetIID() { static nsIID iid = NS_IPRIVATEDOMEVENT_IID; return iid; }
|
||||
|
||||
NS_IMETHOD DuplicatePrivateData() = 0;
|
||||
NS_IMETHOD SetTarget(nsIDOMEventTarget* aTarget) = 0;
|
||||
NS_IMETHOD SetCurrentTarget(nsIDOMEventTarget* aTarget) = 0;
|
||||
NS_IMETHOD SetOriginalTarget(nsIDOMEventTarget* aTarget) = 0;
|
||||
NS_IMETHOD IsDispatchStopped(PRBool* aIsDispatchPrevented) = 0;
|
||||
NS_IMETHOD GetInternalNSEvent(nsEvent** aNSEvent) = 0;
|
||||
NS_IMETHOD HasOriginalTarget(PRBool* aResult)=0;
|
||||
};
|
||||
|
||||
extern nsresult NS_NewDOMEvent(nsIDOMEvent** aInstancePtrResult, nsIPresContext* aPresContext, nsEvent *aEvent);
|
||||
extern nsresult NS_NewDOMUIEvent(nsIDOMEvent** aInstancePtrResult,
|
||||
nsIPresContext* aPresContext,
|
||||
const nsAReadableString& aEventType,
|
||||
nsEvent *aEvent);
|
||||
|
||||
#endif // nsIPrivateDOMEvent_h__
|
|
@ -34,6 +34,7 @@ CPPSRCS = \
|
|||
nsEventListenerManager.cpp \
|
||||
nsEventStateManager.cpp \
|
||||
nsDOMEvent.cpp \
|
||||
nsDOMMutationEvent.cpp \
|
||||
nsDOMEventsIIDs.cpp \
|
||||
nsPrivateTextRange.cpp \
|
||||
$(NULL)
|
||||
|
|
|
@ -32,6 +32,7 @@ DEFINES=-D_IMPL_NS_HTML -DWIN32_LEAN_AND_MEAN
|
|||
CPPSRCS= nsEventListenerManager.cpp \
|
||||
nsEventStateManager.cpp \
|
||||
nsDOMEvent.cpp \
|
||||
nsDOMMutationEvent.cpp \
|
||||
nsDOMEventsIIDs.cpp \
|
||||
nsPrivateTextRange.cpp \
|
||||
$(NULL)
|
||||
|
@ -39,6 +40,7 @@ CPPSRCS= nsEventListenerManager.cpp \
|
|||
CPP_OBJS= .\$(OBJDIR)\nsEventListenerManager.obj \
|
||||
.\$(OBJDIR)\nsEventStateManager.obj \
|
||||
.\$(OBJDIR)\nsDOMEvent.obj \
|
||||
.\$(OBJDIR)\nsDOMMutationEvent.obj \
|
||||
.\$(OBJDIR)\nsDOMEventsIIDs.obj \
|
||||
.\$(OBJDIR)\nsPrivateTextRange.obj \
|
||||
$(NULL)
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#include "nsIDOMAbstractView.h"
|
||||
#include "prmem.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsMutationEvent.h"
|
||||
|
||||
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
|
||||
|
||||
|
@ -50,7 +51,10 @@ static char* mEventNames[] = {
|
|||
"submit", "reset", "change", "select", "input", "paint" ,"text",
|
||||
"create", "close", "destroy", "command", "broadcast", "commandupdate",
|
||||
"dragenter", "dragover", "dragexit", "dragdrop", "draggesture", "resize",
|
||||
"scroll","overflow", "underflow", "overflowchanged"
|
||||
"scroll","overflow", "underflow", "overflowchanged",
|
||||
"DOMSubtreeModified", "DOMNodeInserted", "DOMNodeRemoved",
|
||||
"DOMNodeRemovedFromDocument", "DOMNodeInsertedIntoDocument",
|
||||
"DOMAttrModified", "DOMCharacterDataModified"
|
||||
};
|
||||
|
||||
nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, const nsAReadableString& aEventType) {
|
||||
|
@ -76,6 +80,10 @@ nsDOMEvent::nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, const nsAR
|
|||
mEvent = PR_NEWZAP(nsEvent);
|
||||
mEvent->eventStructType = NS_EVENT;
|
||||
}
|
||||
else if (eventType.EqualsIgnoreCase("MutationEvent")) {
|
||||
mEvent = PR_NEWZAP(nsMutationEvent);
|
||||
mEvent->eventStructType = NS_MUTATION_EVENT;
|
||||
}
|
||||
else {
|
||||
mEvent = PR_NEWZAP(nsEvent);
|
||||
mEvent->eventStructType = NS_EVENT;
|
||||
|
@ -1013,7 +1021,6 @@ nsDOMEvent::InitKeyEvent(const nsAReadableString& aTypeArg, PRBool aCanBubbleArg
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_METHOD nsDOMEvent::DuplicatePrivateData()
|
||||
{
|
||||
//XXX Write me!
|
||||
|
@ -1183,6 +1190,20 @@ const char* nsDOMEvent::GetEventName(PRUint32 aEventType)
|
|||
return mEventNames[eDOMEvents_underflow];
|
||||
case NS_SCROLLPORT_OVERFLOWCHANGED:
|
||||
return mEventNames[eDOMEvents_overflowchanged];
|
||||
case NS_MUTATION_SUBTREEMODIFIED:
|
||||
return mEventNames[eDOMEvents_subtreemodified];
|
||||
case NS_MUTATION_NODEINSERTED:
|
||||
return mEventNames[eDOMEvents_nodeinserted];
|
||||
case NS_MUTATION_NODEREMOVED:
|
||||
return mEventNames[eDOMEvents_noderemoved];
|
||||
case NS_MUTATION_NODEREMOVEDFROMDOCUMENT:
|
||||
return mEventNames[eDOMEvents_noderemovedfromdocument];
|
||||
case NS_MUTATION_NODEINSERTEDINTODOCUMENT:
|
||||
return mEventNames[eDOMEvents_nodeinsertedintodocument];
|
||||
case NS_MUTATION_ATTRMODIFIED:
|
||||
return mEventNames[eDOMEvents_attrmodified];
|
||||
case NS_MUTATION_CHARACTERDATAMODIFIED:
|
||||
return mEventNames[eDOMEvents_characterdatamodified];
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -87,7 +87,14 @@ public:
|
|||
eDOMEvents_scroll,
|
||||
eDOMEvents_overflow,
|
||||
eDOMEvents_underflow,
|
||||
eDOMEvents_overflowchanged
|
||||
eDOMEvents_overflowchanged,
|
||||
eDOMEvents_subtreemodified,
|
||||
eDOMEvents_nodeinserted,
|
||||
eDOMEvents_noderemoved,
|
||||
eDOMEvents_noderemovedfromdocument,
|
||||
eDOMEvents_nodeinsertedintodocument,
|
||||
eDOMEvents_attrmodified,
|
||||
eDOMEvents_characterdatamodified
|
||||
};
|
||||
|
||||
nsDOMEvent(nsIPresContext* aPresContext, nsEvent* aEvent, const nsAReadableString& aEventType);
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
#include "nsDOMEventsIIDs.h"
|
||||
#include "nsIDOMMouseListener.h"
|
||||
#include "nsIDOMKeyListener.h"
|
||||
#include "nsIDOMMouseMotionListener.h"
|
||||
#include "nsIDOMFocusListener.h"
|
||||
#include "nsIDOMFormListener.h"
|
||||
#include "nsIDOMLoadListener.h"
|
||||
#include "nsIDOMDragListener.h"
|
||||
#include "nsIDOMPaintListener.h"
|
||||
#include "nsIDOMTextListener.h"
|
||||
#include "nsIDOMCompositionListener.h"
|
||||
#include "nsIDOMMenuListener.h"
|
||||
#include "nsIDOMScrollListener.h"
|
||||
|
||||
NS_DEFINE_IID(kIDOMMouseListenerIID, NS_IDOMMOUSELISTENER_IID);
|
||||
NS_DEFINE_IID(kIDOMKeyListenerIID, NS_IDOMKEYLISTENER_IID);
|
||||
NS_DEFINE_IID(kIDOMMouseMotionListenerIID, NS_IDOMMOUSEMOTIONLISTENER_IID);
|
||||
NS_DEFINE_IID(kIDOMFocusListenerIID, NS_IDOMFOCUSLISTENER_IID);
|
||||
NS_DEFINE_IID(kIDOMFormListenerIID, NS_IDOMFORMLISTENER_IID);
|
||||
NS_DEFINE_IID(kIDOMLoadListenerIID, NS_IDOMLOADLISTENER_IID);
|
||||
NS_DEFINE_IID(kIDOMDragListenerIID, NS_IDOMDRAGLISTENER_IID);
|
||||
NS_DEFINE_IID(kIDOMPaintListenerIID, NS_IDOMPAINTLISTENER_IID);
|
||||
NS_DEFINE_IID(kIDOMTextListenerIID,NS_IDOMTEXTLISTENER_IID);
|
||||
NS_DEFINE_IID(kIDOMCompositionListenerIID,NS_IDOMCOMPOSITIONLISTENER_IID);
|
||||
NS_DEFINE_IID(kIDOMMenuListenerIID, NS_IDOMMENULISTENER_IID);
|
||||
NS_DEFINE_IID(kIDOMScrollListenerIID, NS_IDOMSCROLLLISTENER_IID);
|
|
@ -1,40 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
#ifndef nsDOMEVENTSIIDs_h___
|
||||
#define nsDOMEVENTSIIDs_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
|
||||
extern const nsIID kIDOMMouseListenerIID;
|
||||
extern const nsIID kIDOMKeyListenerIID;
|
||||
extern const nsIID kIDOMMouseMotionListenerIID;
|
||||
extern const nsIID kIDOMFocusListenerIID;
|
||||
extern const nsIID kIDOMFormListenerIID;
|
||||
extern const nsIID kIDOMLoadListenerIID;
|
||||
extern const nsIID kIDOMDragListenerIID;
|
||||
extern const nsIID kIDOMPaintListenerIID;
|
||||
extern const nsIID kIDOMTextListenerIID;
|
||||
extern const nsIID kIDOMCompositionListenerIID;
|
||||
extern const nsIID kIDOMMenuListenerIID;
|
||||
extern const nsIID kIDOMScrollListenerIID;
|
||||
|
||||
#endif /* nsDOMEVENTSIIDs_h___ */
|
|
@ -37,7 +37,9 @@
|
|||
#include "nsIDOMCompositionListener.h"
|
||||
#include "nsIDOMMenuListener.h"
|
||||
#include "nsIDOMScrollListener.h"
|
||||
#include "nsIDOMMutationListener.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsIScriptObjectOwner.h"
|
||||
#include "nsIScriptEventListener.h"
|
||||
|
@ -56,6 +58,7 @@
|
|||
#include "nsIJSContextStack.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsMutationEvent.h"
|
||||
|
||||
static NS_DEFINE_IID(kIEventListenerManagerIID, NS_IEVENTLISTENERMANAGER_IID);
|
||||
static NS_DEFINE_IID(kIDOMEventListenerIID, NS_IDOMEVENTLISTENER_IID);
|
||||
|
@ -77,6 +80,7 @@ nsEventListenerManager::nsEventListenerManager()
|
|||
mCompositionListeners = nsnull;
|
||||
mMenuListeners = nsnull;
|
||||
mScrollListeners = nsnull;
|
||||
mMutationListeners = nsnull;
|
||||
mDestroyed = PR_FALSE;
|
||||
mTarget = nsnull;
|
||||
NS_INIT_REFCNT();
|
||||
|
@ -97,6 +101,7 @@ nsEventListenerManager::~nsEventListenerManager()
|
|||
ReleaseListeners(&mCompositionListeners, PR_FALSE);
|
||||
ReleaseListeners(&mMenuListeners, PR_FALSE);
|
||||
ReleaseListeners(&mScrollListeners, PR_FALSE);
|
||||
ReleaseListeners(&mMutationListeners, PR_FALSE);
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsEventListenerManager)
|
||||
|
@ -184,6 +189,9 @@ nsVoidArray** nsEventListenerManager::GetListenersByIID(const nsIID& aIID)
|
|||
else if (aIID.Equals(kIDOMScrollListenerIID)) {
|
||||
return &mScrollListeners;
|
||||
}
|
||||
else if (aIID.Equals(kIDOMMutationListenerIID)) {
|
||||
return &mMutationListeners;
|
||||
}
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
|
@ -245,6 +253,25 @@ nsresult nsEventListenerManager::AddEventListener(nsIDOMEventListener *aListener
|
|||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// For mutation listeners, we need to update the global bit on the DOM window.
|
||||
// Otherwise we won't actually fire the mutation event.
|
||||
if (aIID.Equals(NS_GET_IID(nsIDOMMutationListener))) {
|
||||
// Go from our target to the nearest enclosing DOM window.
|
||||
nsCOMPtr<nsIScriptGlobalObject> global;
|
||||
nsCOMPtr<nsIDocument> document;
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mTarget));
|
||||
if (content)
|
||||
content->GetDocument(*getter_AddRefs(document));
|
||||
else document = do_QueryInterface(mTarget);
|
||||
if (document)
|
||||
document->GetScriptGlobalObject(getter_AddRefs(global));
|
||||
else global = do_QueryInterface(mTarget);
|
||||
if (global) {
|
||||
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(global));
|
||||
window->SetMutationListeners(aSubType);
|
||||
}
|
||||
}
|
||||
|
||||
PRBool found = PR_FALSE;
|
||||
nsListenerStruct* ls;
|
||||
nsresult rv;
|
||||
|
@ -504,6 +531,34 @@ nsresult nsEventListenerManager::GetIdentifiersForType(nsIAtom* aType, nsIID& aI
|
|||
aIID = NS_GET_IID(nsIDOMDragListener);
|
||||
*aFlags = NS_EVENT_BITS_DRAG_GESTURE;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onDOMSubtreeModified) {
|
||||
aIID = NS_GET_IID(nsIDOMMutationListener);
|
||||
*aFlags = NS_EVENT_BITS_MUTATION_SUBTREEMODIFIED;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onDOMNodeInserted) {
|
||||
aIID = NS_GET_IID(nsIDOMMutationListener);
|
||||
*aFlags = NS_EVENT_BITS_MUTATION_NODEINSERTED;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onDOMNodeRemoved) {
|
||||
aIID = NS_GET_IID(nsIDOMMutationListener);
|
||||
*aFlags = NS_EVENT_BITS_MUTATION_NODEREMOVED;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onDOMNodeInsertedIntoDocument) {
|
||||
aIID = NS_GET_IID(nsIDOMMutationListener);
|
||||
*aFlags = NS_EVENT_BITS_MUTATION_NODEINSERTEDINTODOCUMENT;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onDOMNodeRemovedFromDocument) {
|
||||
aIID = NS_GET_IID(nsIDOMMutationListener);
|
||||
*aFlags = NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onDOMAttrModified) {
|
||||
aIID = NS_GET_IID(nsIDOMMutationListener);
|
||||
*aFlags = NS_EVENT_BITS_MUTATION_ATTRMODIFIED;
|
||||
}
|
||||
else if (aType == nsLayoutAtoms::onDOMCharacterDataModified) {
|
||||
aIID = NS_GET_IID(nsIDOMMutationListener);
|
||||
*aFlags = NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED;
|
||||
}
|
||||
else {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
@ -1676,6 +1731,112 @@ nsresult nsEventListenerManager::HandleEvent(nsIPresContext* aPresContext,
|
|||
}
|
||||
break;
|
||||
|
||||
case NS_MUTATION_SUBTREEMODIFIED:
|
||||
case NS_MUTATION_NODEINSERTED:
|
||||
case NS_MUTATION_NODEREMOVED:
|
||||
case NS_MUTATION_NODEINSERTEDINTODOCUMENT:
|
||||
case NS_MUTATION_NODEREMOVEDFROMDOCUMENT:
|
||||
case NS_MUTATION_ATTRMODIFIED:
|
||||
case NS_MUTATION_CHARACTERDATAMODIFIED:
|
||||
if (nsnull != mMutationListeners) {
|
||||
if (nsnull == *aDOMEvent) {
|
||||
ret = NS_NewDOMMutationEvent(aDOMEvent, aPresContext, aEvent);
|
||||
}
|
||||
if (NS_OK == ret) {
|
||||
for (int i=0; mMutationListeners && i<mMutationListeners->Count(); i++) {
|
||||
nsListenerStruct *ls;
|
||||
nsCOMPtr<nsIDOMMutationListener> mutationListener;
|
||||
|
||||
ls = (nsListenerStruct*)mMutationListeners->ElementAt(i);
|
||||
|
||||
if (ls->mFlags & aFlags) {
|
||||
mutationListener = do_QueryInterface(ls->mListener);
|
||||
if (mutationListener) {
|
||||
switch(aEvent->message) {
|
||||
case NS_MUTATION_SUBTREEMODIFIED:
|
||||
ret = mutationListener->SubtreeModified(*aDOMEvent);
|
||||
break;
|
||||
case NS_MUTATION_NODEINSERTED:
|
||||
ret = mutationListener->NodeInserted(*aDOMEvent);
|
||||
break;
|
||||
case NS_MUTATION_NODEREMOVED:
|
||||
ret = mutationListener->NodeRemoved(*aDOMEvent);
|
||||
break;
|
||||
case NS_MUTATION_NODEINSERTEDINTODOCUMENT:
|
||||
ret = mutationListener->NodeInsertedIntoDocument(*aDOMEvent);
|
||||
break;
|
||||
case NS_MUTATION_NODEREMOVEDFROMDOCUMENT:
|
||||
ret = mutationListener->NodeRemovedFromDocument(*aDOMEvent);
|
||||
break;
|
||||
case NS_MUTATION_ATTRMODIFIED:
|
||||
ret = mutationListener->AttrModified(*aDOMEvent);
|
||||
break;
|
||||
case NS_MUTATION_CHARACTERDATAMODIFIED:
|
||||
ret = mutationListener->CharacterDataModified(*aDOMEvent);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PRBool correctSubType = PR_FALSE;
|
||||
PRUint32 subType = 0;
|
||||
switch(aEvent->message) {
|
||||
case NS_MUTATION_SUBTREEMODIFIED:
|
||||
subType = NS_EVENT_BITS_MUTATION_SUBTREEMODIFIED;
|
||||
if (ls->mSubType & NS_EVENT_BITS_MUTATION_SUBTREEMODIFIED) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_MUTATION_NODEINSERTED:
|
||||
subType = NS_EVENT_BITS_MUTATION_NODEINSERTED;
|
||||
if (ls->mSubType & NS_EVENT_BITS_MUTATION_NODEINSERTED) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_MUTATION_NODEREMOVED:
|
||||
subType = NS_EVENT_BITS_MUTATION_NODEREMOVED;
|
||||
if (ls->mSubType & NS_EVENT_BITS_MUTATION_NODEREMOVED) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_MUTATION_NODEINSERTEDINTODOCUMENT:
|
||||
subType = NS_EVENT_BITS_MUTATION_NODEINSERTEDINTODOCUMENT;
|
||||
if (ls->mSubType & NS_EVENT_BITS_MUTATION_NODEINSERTEDINTODOCUMENT) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_MUTATION_NODEREMOVEDFROMDOCUMENT:
|
||||
subType = NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT;
|
||||
if (ls->mSubType & NS_EVENT_BITS_MUTATION_NODEREMOVEDFROMDOCUMENT) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_MUTATION_ATTRMODIFIED:
|
||||
subType = NS_EVENT_BITS_MUTATION_ATTRMODIFIED;
|
||||
if (ls->mSubType & NS_EVENT_BITS_MUTATION_ATTRMODIFIED) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
case NS_MUTATION_CHARACTERDATAMODIFIED:
|
||||
subType = NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED;
|
||||
if (ls->mSubType & NS_EVENT_BITS_MUTATION_CHARACTERDATAMODIFIED) {
|
||||
correctSubType = PR_TRUE;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (correctSubType || ls->mSubType == NS_EVENT_BITS_NONE) {
|
||||
ret = HandleEventSubType(ls, *aDOMEvent, aCurrentTarget, subType, aFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1701,10 +1862,12 @@ nsresult nsEventListenerManager::CreateEvent(nsIPresContext* aPresContext,
|
|||
{
|
||||
nsAutoString str(aEventType);
|
||||
if (!aEvent && !str.EqualsIgnoreCase("MouseEvent") && !str.EqualsIgnoreCase("KeyEvent") &&
|
||||
!str.EqualsIgnoreCase("HTMLEvent")) {
|
||||
!str.EqualsIgnoreCase("HTMLEvent") && !str.EqualsIgnoreCase("MutationEvent")) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (str.EqualsIgnoreCase("MutationEvent"))
|
||||
return NS_NewDOMMutationEvent(aDOMEvent, aPresContext, aEvent);
|
||||
return NS_NewDOMUIEvent(aDOMEvent, aPresContext, aEventType, aEvent);
|
||||
}
|
||||
|
||||
|
@ -1965,6 +2128,7 @@ nsresult nsEventListenerManager::RemoveAllListeners(PRBool aScriptOnly)
|
|||
ReleaseListeners(&mPaintListeners, aScriptOnly);
|
||||
ReleaseListeners(&mTextListeners, aScriptOnly);
|
||||
ReleaseListeners(&mCompositionListeners, aScriptOnly);
|
||||
ReleaseListeners(&mMutationListeners, aScriptOnly);
|
||||
mDestroyed = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -1,245 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef nsEventListenerManager_h__
|
||||
#define nsEventListenerManager_h__
|
||||
|
||||
#include "nsIEventListenerManager.h"
|
||||
#include "jsapi.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
|
||||
class nsIDOMEvent;
|
||||
class nsIAtom;
|
||||
|
||||
typedef struct {
|
||||
nsIDOMEventListener* mListener;
|
||||
PRUint8 mFlags;
|
||||
PRUint8 mSubType;
|
||||
PRUint8 mHandlerIsString;
|
||||
PRUint8 mSubTypeCapture;
|
||||
} nsListenerStruct;
|
||||
|
||||
//Flag must live higher than all event flags in nsGUIEvent.h
|
||||
#define NS_PRIV_EVENT_FLAG_SCRIPT 0x80
|
||||
|
||||
/*
|
||||
* Event listener manager
|
||||
*/
|
||||
|
||||
class nsEventListenerManager : public nsIEventListenerManager,
|
||||
public nsIDOMEventReceiver
|
||||
{
|
||||
|
||||
public:
|
||||
nsEventListenerManager();
|
||||
virtual ~nsEventListenerManager();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsVoidArray** GetListenersByIID(const nsIID& aIID);
|
||||
|
||||
/**
|
||||
* Retrieves events listeners of all types.
|
||||
* @param
|
||||
*/
|
||||
|
||||
virtual nsresult GetEventListeners(nsVoidArray **aListeners, const nsIID& aIID);
|
||||
|
||||
/**
|
||||
* Sets events listeners of all types.
|
||||
* @param an event listener
|
||||
*/
|
||||
|
||||
virtual nsresult AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 aFlags);
|
||||
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 aFlags);
|
||||
virtual nsresult AddEventListenerByType(nsIDOMEventListener *aListener, const nsAReadableString& type, PRInt32 aFlags);
|
||||
virtual nsresult RemoveEventListenerByType(nsIDOMEventListener *aListener, const nsAReadableString& type, PRInt32 aFlags) ;
|
||||
|
||||
virtual nsresult AddScriptEventListener(nsIScriptContext*aContext,
|
||||
nsIScriptObjectOwner *aScriptObjectOwner,
|
||||
nsIAtom *aName,
|
||||
const nsAReadableString& aFunc,
|
||||
REFNSIID aIID,
|
||||
PRBool aDeferCompilation);
|
||||
virtual nsresult RegisterScriptEventListener(nsIScriptContext *aContext,
|
||||
nsIScriptObjectOwner *aScriptObjectOwner,
|
||||
nsIAtom* aName,
|
||||
const nsIID& aIID);
|
||||
|
||||
|
||||
virtual nsresult CaptureEvent(PRInt32 aEventTypes);
|
||||
virtual nsresult ReleaseEvent(PRInt32 aEventTypes);
|
||||
|
||||
virtual nsresult HandleEvent(nsIPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
nsIDOMEventTarget* aCurrentTarget,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
|
||||
virtual nsresult CreateEvent(nsIPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
const nsAReadableString& aEventType,
|
||||
nsIDOMEvent** aDOMEvent);
|
||||
|
||||
virtual nsresult RemoveAllListeners(PRBool aScriptOnly);
|
||||
|
||||
virtual nsresult SetListenerTarget(nsISupports* aTarget);
|
||||
|
||||
static nsresult GetIdentifiersForType(nsIAtom* aType, nsIID& aIID, PRInt32* aSubType);
|
||||
|
||||
// nsIDOMEventTarget interface
|
||||
NS_IMETHOD AddEventListener(const nsAReadableString& aType,
|
||||
nsIDOMEventListener* aListener,
|
||||
PRBool aUseCapture);
|
||||
NS_IMETHOD RemoveEventListener(const nsAReadableString& aType,
|
||||
nsIDOMEventListener* aListener,
|
||||
PRBool aUseCapture);
|
||||
NS_IMETHOD DispatchEvent(nsIDOMEvent* aEvent);
|
||||
|
||||
// nsIDOMEventReceiver interface
|
||||
NS_IMETHOD AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
|
||||
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
|
||||
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
|
||||
NS_IMETHOD GetNewListenerManager(nsIEventListenerManager **aInstancePtrResult);
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent);
|
||||
|
||||
protected:
|
||||
nsresult HandleEventSubType(nsListenerStruct* aListenerStruct,
|
||||
nsIDOMEvent* aDOMEvent,
|
||||
nsIDOMEventTarget* aCurrentTarget,
|
||||
PRUint32 aSubType,
|
||||
PRUint32 aPhaseFlags);
|
||||
nsListenerStruct* FindJSEventListener(REFNSIID aIID);
|
||||
nsresult SetJSEventListener(nsIScriptContext *aContext, nsIScriptObjectOwner *aOwner, nsIAtom* aName, REFNSIID aIID, PRBool aIsString);
|
||||
nsresult AddEventListener(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 aFlags, PRInt32 aSubType);
|
||||
nsresult RemoveEventListener(nsIDOMEventListener *aListener, const nsIID& aIID, PRInt32 aFlags, PRInt32 aSubType);
|
||||
void ReleaseListeners(nsVoidArray** aListeners, PRBool aScriptOnly);
|
||||
nsresult FlipCaptureBit(PRInt32 aEventTypes, PRBool aInitCapture);
|
||||
|
||||
nsVoidArray* mEventListeners;
|
||||
nsVoidArray* mMouseListeners;
|
||||
nsVoidArray* mMouseMotionListeners;
|
||||
nsVoidArray* mKeyListeners;
|
||||
nsVoidArray* mLoadListeners;
|
||||
nsVoidArray* mFocusListeners;
|
||||
nsVoidArray* mFormListeners;
|
||||
nsVoidArray* mDragListeners;
|
||||
nsVoidArray* mPaintListeners;
|
||||
nsVoidArray* mTextListeners;
|
||||
nsVoidArray* mCompositionListeners;
|
||||
nsVoidArray* mMenuListeners;
|
||||
nsVoidArray* mScrollListeners;
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
PRBool mDestroyed;
|
||||
|
||||
nsISupports* mTarget; //WEAK
|
||||
};
|
||||
|
||||
|
||||
//Set of defines for distinguishing event handlers within listener groupings
|
||||
//XXX Current usage allows no more than 7 types per listener grouping
|
||||
|
||||
#define NS_EVENT_BITS_NONE 0x00
|
||||
|
||||
//nsIDOMMouseListener
|
||||
#define NS_EVENT_BITS_MOUSE_NONE 0x00
|
||||
#define NS_EVENT_BITS_MOUSE_MOUSEDOWN 0x01
|
||||
#define NS_EVENT_BITS_MOUSE_MOUSEUP 0x02
|
||||
#define NS_EVENT_BITS_MOUSE_CLICK 0x04
|
||||
#define NS_EVENT_BITS_MOUSE_DBLCLICK 0x08
|
||||
#define NS_EVENT_BITS_MOUSE_MOUSEOVER 0x10
|
||||
#define NS_EVENT_BITS_MOUSE_MOUSEOUT 0x20
|
||||
|
||||
//nsIDOMMouseMotionListener
|
||||
#define NS_EVENT_BITS_MOUSEMOTION_NONE 0x00
|
||||
#define NS_EVENT_BITS_MOUSEMOTION_MOUSEMOVE 0x01
|
||||
#define NS_EVENT_BITS_MOUSEMOTION_DRAGMOVE 0x02
|
||||
|
||||
//nsIDOMKeyListener
|
||||
#define NS_EVENT_BITS_KEY_NONE 0x00
|
||||
#define NS_EVENT_BITS_KEY_KEYDOWN 0x01
|
||||
#define NS_EVENT_BITS_KEY_KEYUP 0x02
|
||||
#define NS_EVENT_BITS_KEY_KEYPRESS 0x04
|
||||
|
||||
//nsIDOMTextListener
|
||||
#define NS_EVENT_BITS_TEXT_NONE 0x00
|
||||
#define NS_EVENT_BITS_TEXT_TEXT 0x01
|
||||
|
||||
//nsIDOMCompositionListener
|
||||
#define NS_EVENT_BITS_COMPOSITION_NONE 0x00
|
||||
#define NS_EVENT_BITS_COMPOSITION_START 0x01
|
||||
#define NS_EVENT_BITS_COMPOSITION_END 0x02
|
||||
#define NS_EVENT_BITS_COMPOSITION_QUERY 0x04
|
||||
|
||||
//nsIDOMFocusListener
|
||||
#define NS_EVENT_BITS_FOCUS_NONE 0x00
|
||||
#define NS_EVENT_BITS_FOCUS_FOCUS 0x01
|
||||
#define NS_EVENT_BITS_FOCUS_BLUR 0x02
|
||||
|
||||
//nsIDOMFormListener
|
||||
#define NS_EVENT_BITS_FORM_NONE 0x00
|
||||
#define NS_EVENT_BITS_FORM_SUBMIT 0x01
|
||||
#define NS_EVENT_BITS_FORM_RESET 0x02
|
||||
#define NS_EVENT_BITS_FORM_CHANGE 0x04
|
||||
#define NS_EVENT_BITS_FORM_SELECT 0x08
|
||||
#define NS_EVENT_BITS_FORM_INPUT 0x10
|
||||
|
||||
//nsIDOMLoadListener
|
||||
#define NS_EVENT_BITS_LOAD_NONE 0x00
|
||||
#define NS_EVENT_BITS_LOAD_LOAD 0x01
|
||||
#define NS_EVENT_BITS_LOAD_UNLOAD 0x02
|
||||
#define NS_EVENT_BITS_LOAD_ABORT 0x04
|
||||
#define NS_EVENT_BITS_LOAD_ERROR 0x08
|
||||
|
||||
//nsIDOMMenuListener
|
||||
#define NS_EVENT_BITS_MENU_NONE 0x00
|
||||
#define NS_EVENT_BITS_MENU_CREATE 0x01
|
||||
#define NS_EVENT_BITS_XUL_CLOSE 0x02
|
||||
#define NS_EVENT_BITS_MENU_DESTROY 0x04
|
||||
#define NS_EVENT_BITS_MENU_ACTION 0x08
|
||||
#define NS_EVENT_BITS_XUL_BROADCAST 0x10
|
||||
#define NS_EVENT_BITS_XUL_COMMAND_UPDATE 0x20
|
||||
|
||||
//nsIScrollListener
|
||||
#define NS_EVENT_BITS_SCROLLPORT_NONE 0x00
|
||||
#define NS_EVENT_BITS_SCROLLPORT_OVERFLOW 0x01
|
||||
#define NS_EVENT_BITS_SCROLLPORT_UNDERFLOW 0x02
|
||||
#define NS_EVENT_BITS_SCROLLPORT_OVERFLOWCHANGED 0x04
|
||||
|
||||
//nsIDOMDragListener
|
||||
#define NS_EVENT_BITS_DRAG_NONE 0x00
|
||||
#define NS_EVENT_BITS_DRAG_ENTER 0x01
|
||||
#define NS_EVENT_BITS_DRAG_OVER 0x02
|
||||
#define NS_EVENT_BITS_DRAG_EXIT 0x04
|
||||
#define NS_EVENT_BITS_DRAG_DROP 0x08
|
||||
#define NS_EVENT_BITS_DRAG_GESTURE 0x10
|
||||
|
||||
//nsIDOMPaintListener
|
||||
#define NS_EVENT_BITS_PAINT_NONE 0x00
|
||||
#define NS_EVENT_BITS_PAINT_PAINT 0x01
|
||||
#define NS_EVENT_BITS_PAINT_RESIZE 0x02
|
||||
#define NS_EVENT_BITS_PAINT_SCROLL 0x04
|
||||
|
||||
#endif // nsEventListenerManager_h__
|
|
@ -42,6 +42,7 @@
|
|||
#include "nsIHTMLContent.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsILinkHandler.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIScriptObjectOwner.h"
|
||||
#include "nsISizeOfHandler.h"
|
||||
|
@ -86,6 +87,13 @@
|
|||
#include "nsIDOMHTMLFormElement.h"
|
||||
#include "nsILanguageAtomService.h"
|
||||
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
#include "nsMutationEvent.h"
|
||||
#include "nsEventListenerManager.h"
|
||||
|
||||
#include "nsIBindingManager.h"
|
||||
#include "nsIXBLBinding.h"
|
||||
|
||||
#include "nsIParser.h"
|
||||
#include "nsParserCIID.h"
|
||||
#include "nsIHTMLContentSink.h"
|
||||
|
@ -1229,6 +1237,73 @@ nsGenericHTMLElement::NormalizeAttributeString(const nsAReadableString& aStr,
|
|||
return nimgr->GetNodeInfo(lower, nsnull, kNameSpaceID_None, aNodeInfo);
|
||||
}
|
||||
|
||||
static PRBool HasMutationListeners(nsIContent* aContent, PRUint32 aType)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aContent->GetDocument(*getter_AddRefs(doc));
|
||||
if (!doc)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> global;
|
||||
doc->GetScriptGlobalObject(getter_AddRefs(global));
|
||||
if (!global)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(global));
|
||||
if (!window)
|
||||
return PR_FALSE;
|
||||
|
||||
PRBool set;
|
||||
window->HasMutationListeners(aType, &set);
|
||||
if (!set)
|
||||
return PR_FALSE;
|
||||
|
||||
// We know a mutation listener is registered, but it might not
|
||||
// be in our chain. Check quickly to see.
|
||||
nsCOMPtr<nsIContent> curr = aContent;
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
while (curr) {
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(curr));
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> prev = curr;
|
||||
prev->GetParent(*getter_AddRefs(curr));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(doc));
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
rec = do_QueryInterface(window);
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::SetAttribute(PRInt32 aNameSpaceID,
|
||||
nsIAtom* aAttribute,
|
||||
|
@ -1302,6 +1377,9 @@ nsGenericHTMLElement::SetAttribute(PRInt32 aNameSpaceID,
|
|||
if (NS_OK != result) {
|
||||
return result;
|
||||
}
|
||||
|
||||
nsAutoString strValue;
|
||||
PRBool modification = PR_TRUE;
|
||||
if (NS_CONTENT_ATTR_NOT_THERE !=
|
||||
htmlContent->StringToAttribute(aAttribute, aValue, val)) {
|
||||
// string value was mapped to nsHTMLValue, set it that way
|
||||
|
@ -1324,13 +1402,14 @@ nsGenericHTMLElement::SetAttribute(PRInt32 aNameSpaceID,
|
|||
}
|
||||
|
||||
// don't do any update if old == new
|
||||
nsAutoString strValue;
|
||||
result = GetAttribute(aNameSpaceID, aAttribute, strValue);
|
||||
if ((NS_CONTENT_ATTR_NOT_THERE != result) && aValue.Equals(strValue)) {
|
||||
NS_RELEASE(htmlContent);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
modification = (result != NS_CONTENT_ATTR_NOT_THERE);
|
||||
|
||||
if (aNotify && (nsnull != mDocument)) {
|
||||
mDocument->BeginUpdate();
|
||||
}
|
||||
|
@ -1363,11 +1442,45 @@ nsGenericHTMLElement::SetAttribute(PRInt32 aNameSpaceID,
|
|||
}
|
||||
NS_RELEASE(htmlContent);
|
||||
|
||||
if (aNotify && (nsnull != mDocument)) {
|
||||
result = mDocument->AttributeChanged(mContent, aNameSpaceID, aAttribute, NS_STYLE_HINT_UNKNOWN);
|
||||
mDocument->EndUpdate();
|
||||
}
|
||||
if (mDocument) {
|
||||
nsCOMPtr<nsIBindingManager> bindingManager;
|
||||
mDocument->GetBindingManager(getter_AddRefs(bindingManager));
|
||||
nsCOMPtr<nsIXBLBinding> binding;
|
||||
bindingManager->GetBinding(mContent, getter_AddRefs(binding));
|
||||
if (binding)
|
||||
binding->AttributeChanged(aAttribute, aNameSpaceID, PR_FALSE);
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_ATTRMODIFIED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(mContent));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_ATTRMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsAutoString attrName;
|
||||
aAttribute->ToString(attrName);
|
||||
nsCOMPtr<nsIDOMAttr> attrNode;
|
||||
GetAttributeNode(attrName, getter_AddRefs(attrNode));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = aAttribute;
|
||||
if (!strValue.IsEmpty())
|
||||
mutation.mPrevAttrValue = getter_AddRefs(NS_NewAtom(strValue));
|
||||
if (!aValue.IsEmpty())
|
||||
mutation.mNewAttrValue = getter_AddRefs(NS_NewAtom(aValue));
|
||||
mutation.mAttrChange = modification ? nsIDOMMutationEvent::MODIFICATION :
|
||||
nsIDOMMutationEvent::ADDITION;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
mContent->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if (aNotify) {
|
||||
mDocument->AttributeChanged(mContent, aNameSpaceID, aAttribute, NS_STYLE_HINT_UNKNOWN);
|
||||
mDocument->EndUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1447,6 +1560,41 @@ nsGenericHTMLElement::SetHTMLAttribute(nsIAtom* aAttribute,
|
|||
htmlContent, mAttributes);
|
||||
NS_RELEASE(sheet);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIBindingManager> bindingManager;
|
||||
mDocument->GetBindingManager(getter_AddRefs(bindingManager));
|
||||
nsCOMPtr<nsIXBLBinding> binding;
|
||||
bindingManager->GetBinding(mContent, getter_AddRefs(binding));
|
||||
if (binding)
|
||||
binding->AttributeChanged(aAttribute, kNameSpaceID_None, PR_TRUE);
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_ATTRMODIFIED)) {
|
||||
// XXX Figure out how to get the old value, so I can fill in
|
||||
// the prevValue field and so that I can correctly indicate
|
||||
// MODIFICATIONs/ADDITIONs.
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(mContent));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_ATTRMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsAutoString attrName;
|
||||
aAttribute->ToString(attrName);
|
||||
nsCOMPtr<nsIDOMAttr> attrNode;
|
||||
GetAttributeNode(attrName, getter_AddRefs(attrNode));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = aAttribute;
|
||||
nsAutoString value;
|
||||
aValue.ToString(value);
|
||||
if (!value.IsEmpty())
|
||||
mutation.mNewAttrValue = getter_AddRefs(NS_NewAtom(value));
|
||||
mutation.mAttrChange = nsIDOMMutationEvent::MODIFICATION;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
mContent->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if (aNotify) {
|
||||
mDocument->AttributeChanged(mContent, kNameSpaceID_None, aAttribute, impact);
|
||||
mDocument->EndUpdate();
|
||||
|
@ -1504,11 +1652,48 @@ nsGenericHTMLElement::UnsetAttribute(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_ATTRMODIFIED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(mContent));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_ATTRMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsAutoString attrName;
|
||||
aAttribute->ToString(attrName);
|
||||
nsCOMPtr<nsIDOMAttr> attrNode;
|
||||
GetAttributeNode(attrName, getter_AddRefs(attrNode));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = aAttribute;
|
||||
|
||||
nsHTMLValue oldAttr;
|
||||
GetHTMLAttribute(aAttribute, oldAttr);
|
||||
nsAutoString attr;
|
||||
oldAttr.ToString(attr);
|
||||
if (!attr.IsEmpty())
|
||||
mutation.mPrevAttrValue = getter_AddRefs(NS_NewAtom(attr));
|
||||
mutation.mAttrChange = nsIDOMMutationEvent::REMOVAL;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
mContent->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
nsIHTMLStyleSheet* sheet = GetAttrStyleSheet(mDocument);
|
||||
if (nsnull != sheet) {
|
||||
result = sheet->UnsetAttributeFor(aAttribute, htmlContent, mAttributes);
|
||||
NS_RELEASE(sheet);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIBindingManager> bindingManager;
|
||||
mDocument->GetBindingManager(getter_AddRefs(bindingManager));
|
||||
nsCOMPtr<nsIXBLBinding> binding;
|
||||
bindingManager->GetBinding(mContent, getter_AddRefs(binding));
|
||||
if (binding)
|
||||
binding->AttributeChanged(aAttribute, aNameSpaceID, PR_TRUE);
|
||||
|
||||
if (aNotify) {
|
||||
mDocument->AttributeChanged(mContent, aNameSpaceID, aAttribute, impact);
|
||||
mDocument->EndUpdate();
|
||||
|
@ -3198,7 +3383,6 @@ nsGenericHTMLLeafElement::GetChildNodes(nsIDOMNodeList** aChildNodes)
|
|||
return slots->mChildNodes->QueryInterface(NS_GET_IID(nsIDOMNodeList), (void **)aChildNodes);
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsGenericHTMLContainerElement::nsGenericHTMLContainerElement()
|
||||
|
@ -3375,6 +3559,21 @@ nsGenericHTMLContainerElement::InsertChildAt(nsIContent* aKid,
|
|||
if (aNotify) {
|
||||
doc->ContentInserted(mContent, aKid, aIndex);
|
||||
}
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(aKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEINSERTED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(mContent));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
aKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aNotify && (nsnull != doc)) {
|
||||
|
@ -3433,6 +3632,21 @@ nsGenericHTMLContainerElement::AppendChildTo(nsIContent* aKid, PRBool aNotify)
|
|||
if (aNotify) {
|
||||
doc->ContentAppended(mContent, mChildren.Count() - 1);
|
||||
}
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(aKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEINSERTED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(mContent));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
aKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aNotify && (nsnull != doc)) {
|
||||
|
@ -3450,6 +3664,22 @@ nsGenericHTMLContainerElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify)
|
|||
}
|
||||
nsIContent* oldKid = (nsIContent *)mChildren.ElementAt(aIndex);
|
||||
if (nsnull != oldKid ) {
|
||||
|
||||
if (HasMutationListeners(mContent, NS_EVENT_BITS_MUTATION_NODEREMOVED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(oldKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEREMOVED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(mContent));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
oldKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
nsRange::OwnerChildRemoved(mContent, aIndex, oldKid);
|
||||
mChildren.RemoveElementAt(aIndex);
|
||||
if (aNotify) {
|
||||
|
|
|
@ -40,6 +40,7 @@ CPPSRCS = \
|
|||
nsXBLDragHandler.cpp \
|
||||
nsXBLMouseHandler.cpp \
|
||||
nsXBLMouseMotionHandler.cpp \
|
||||
nsXBLMutationHandler.cpp \
|
||||
nsXBLKeyHandler.cpp \
|
||||
nsXBLLoadHandler.cpp \
|
||||
nsXBLXULHandler.cpp \
|
||||
|
|
|
@ -35,6 +35,7 @@ CPPSRCS= \
|
|||
nsXBLKeyHandler.cpp \
|
||||
nsXBLMouseHandler.cpp \
|
||||
nsXBLMouseMotionHandler.cpp \
|
||||
nsXBLMutationHandler.cpp \
|
||||
nsXBLDragHandler.cpp \
|
||||
nsXBLFocusHandler.cpp \
|
||||
nsXBLXULHandler.cpp \
|
||||
|
@ -53,6 +54,7 @@ CPP_OBJS= \
|
|||
.\$(OBJDIR)\nsXBLKeyHandler.obj \
|
||||
.\$(OBJDIR)\nsXBLMouseHandler.obj \
|
||||
.\$(OBJDIR)\nsXBLMouseMotionHandler.obj \
|
||||
.\$(OBJDIR)\nsXBLMutationHandler.obj \
|
||||
.\$(OBJDIR)\nsXBLDragHandler.obj \
|
||||
.\$(OBJDIR)\nsXBLFocusHandler.obj \
|
||||
.\$(OBJDIR)\nsXBLXULHandler.obj \
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include "nsIDOMFormListener.h"
|
||||
#include "nsIDOMMenuListener.h"
|
||||
#include "nsIDOMDragListener.h"
|
||||
#include "nsIDOMMutationListener.h"
|
||||
|
||||
#include "nsIDOMAttr.h"
|
||||
#include "nsIDOMNamedNodeMap.h"
|
||||
|
@ -73,6 +74,7 @@
|
|||
#include "nsXBLFocusHandler.h"
|
||||
#include "nsXBLMouseHandler.h"
|
||||
#include "nsXBLMouseMotionHandler.h"
|
||||
#include "nsXBLMutationHandler.h"
|
||||
#include "nsXBLXULHandler.h"
|
||||
#include "nsXBLScrollHandler.h"
|
||||
#include "nsXBLFormHandler.h"
|
||||
|
@ -211,6 +213,14 @@ nsXBLBinding::kEventHandlerMap[] = {
|
|||
{ "dragdrop", nsnull, &NS_GET_IID(nsIDOMDragListener) },
|
||||
{ "draggesture", nsnull, &NS_GET_IID(nsIDOMDragListener) },
|
||||
|
||||
{ "DOMSubtreeModified", nsnull, &NS_GET_IID(nsIDOMMutationListener) },
|
||||
{ "DOMAttrModified", nsnull, &NS_GET_IID(nsIDOMMutationListener) },
|
||||
{ "DOMCharacterDataModified", nsnull, &NS_GET_IID(nsIDOMMutationListener) },
|
||||
{ "DOMNodeInserted", nsnull, &NS_GET_IID(nsIDOMMutationListener) },
|
||||
{ "DOMNodeRemoved", nsnull, &NS_GET_IID(nsIDOMMutationListener) },
|
||||
{ "DOMNodeInsertedIntoDocument", nsnull, &NS_GET_IID(nsIDOMMutationListener) },
|
||||
{ "DOMNodeRemovedFromDocument", nsnull, &NS_GET_IID(nsIDOMMutationListener) },
|
||||
|
||||
{ nsnull, nsnull, nsnull }
|
||||
};
|
||||
|
||||
|
@ -654,6 +664,12 @@ nsXBLBinding::InstallEventHandlers(nsIContent* aBoundElement, nsIXBLBinding** aB
|
|||
receiver->AddEventListener(type, (nsIDOMLoadListener*)loadHandler, useCapture);
|
||||
handler = loadHandler;
|
||||
}
|
||||
else if(iid.Equals(NS_GET_IID(nsIDOMMutationListener))) {
|
||||
nsXBLMutationHandler* mutationHandler;
|
||||
NS_NewXBLMutationHandler(receiver, curr, &mutationHandler);
|
||||
receiver->AddEventListener(type, (nsIDOMMutationListener*)mutationHandler, useCapture);
|
||||
handler = mutationHandler;
|
||||
}
|
||||
else {
|
||||
NS_WARNING("***** Non-compliant XBL event listener attached! *****");
|
||||
nsAutoString value;
|
||||
|
|
|
@ -116,6 +116,10 @@
|
|||
#include "nsXULAtoms.h"
|
||||
#include "nsITreeBoxObject.h"
|
||||
|
||||
#include "nsMutationEvent.h"
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
||||
#include "prlog.h"
|
||||
#include "rdf.h"
|
||||
#include "rdfutil.h"
|
||||
|
@ -297,6 +301,75 @@ struct XULBroadcastListener
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
static PRBool HasMutationListeners(nsIContent* aContent, PRUint32 aType)
|
||||
{
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
aContent->GetDocument(*getter_AddRefs(doc));
|
||||
if (!doc)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIScriptGlobalObject> global;
|
||||
doc->GetScriptGlobalObject(getter_AddRefs(global));
|
||||
if (!global)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> window(do_QueryInterface(global));
|
||||
if (!window)
|
||||
return PR_FALSE;
|
||||
|
||||
PRBool set;
|
||||
window->HasMutationListeners(aType, &set);
|
||||
if (!set)
|
||||
return PR_FALSE;
|
||||
|
||||
// We know a mutation listener is registered, but it might not
|
||||
// be in our chain. Check quickly to see.
|
||||
nsCOMPtr<nsIContent> curr = aContent;
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
while (curr) {
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(curr));
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> prev = curr;
|
||||
prev->GetParent(*getter_AddRefs(curr));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(doc));
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
rec = do_QueryInterface(window);
|
||||
if (rec) {
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
if (hasMutationListeners)
|
||||
return PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
nsrefcnt nsXULElement::gRefCnt;
|
||||
nsIRDFService* nsXULElement::gRDFService;
|
||||
nsINameSpaceManager* nsXULElement::gNameSpaceManager;
|
||||
|
@ -2353,6 +2426,22 @@ nsXULElement::InsertChildAt(nsIContent* aKid, PRInt32 aIndex, PRBool aNotify)
|
|||
// N.B. that this is "shallow"!
|
||||
aKid->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
|
||||
if (mDocument && HasMutationListeners(NS_STATIC_CAST(nsIStyledContent*,this),
|
||||
NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(aKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEINSERTED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(NS_STATIC_CAST(nsIStyledContent*,this)));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
aKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if (aNotify && mDocument) {
|
||||
mDocument->ContentInserted(NS_STATIC_CAST(nsIStyledContent*, this), aKid, aIndex);
|
||||
}
|
||||
|
@ -2422,6 +2511,22 @@ nsXULElement::AppendChildTo(nsIContent* aKid, PRBool aNotify)
|
|||
// N.B. that this is only "shallow". Callers beware!
|
||||
aKid->SetDocument(mDocument, PR_FALSE, PR_TRUE);
|
||||
|
||||
if (mDocument && HasMutationListeners(NS_STATIC_CAST(nsIStyledContent*,this),
|
||||
NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(aKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEINSERTED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(NS_STATIC_CAST(nsIStyledContent*,this)));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
aKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if (aNotify && mDocument) {
|
||||
mDocument->ContentAppended(NS_STATIC_CAST(nsIStyledContent*, this), mChildren.Count() - 1);
|
||||
}
|
||||
|
@ -2440,6 +2545,21 @@ nsXULElement::RemoveChildAt(PRInt32 aIndex, PRBool aNotify)
|
|||
if (! oldKid)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (HasMutationListeners(NS_STATIC_CAST(nsIStyledContent*,this), NS_EVENT_BITS_MUTATION_NODEREMOVED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(oldKid));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_NODEREMOVED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> relNode(do_QueryInterface(NS_STATIC_CAST(nsIStyledContent*,this)));
|
||||
mutation.mRelatedNode = relNode;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
oldKid->HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
// On the removal of a <treeitem>, <treechildren>, or <treecell> element,
|
||||
// the possibility exists that some of the items in the removed subtree
|
||||
// are selected (and therefore need to be deselected). We need to account for this.
|
||||
|
@ -2706,12 +2826,16 @@ nsXULElement::SetAttribute(nsINodeInfo* aNodeInfo,
|
|||
i++;
|
||||
}
|
||||
|
||||
PRBool modification = PR_TRUE;
|
||||
nsAutoString oldValue;
|
||||
|
||||
if (i < count) {
|
||||
attr->GetValue(oldValue);
|
||||
attr->SetValueInternal(aValue);
|
||||
}
|
||||
else {
|
||||
// didn't find it
|
||||
|
||||
modification = PR_FALSE;
|
||||
rv = nsXULAttribute::Create(NS_STATIC_CAST(nsIStyledContent*, this),
|
||||
aNodeInfo, aValue, &attr);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -2767,6 +2891,31 @@ nsXULElement::SetAttribute(nsINodeInfo* aNodeInfo,
|
|||
if (binding)
|
||||
binding->AttributeChanged(attrName, attrns, PR_FALSE);
|
||||
|
||||
if (HasMutationListeners(NS_STATIC_CAST(nsIStyledContent*, this), NS_EVENT_BITS_MUTATION_ATTRMODIFIED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(NS_STATIC_CAST(nsIStyledContent*, this)));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_ATTRMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsAutoString attrName2;
|
||||
attrName->ToString(attrName2);
|
||||
nsCOMPtr<nsIDOMAttr> attrNode;
|
||||
GetAttributeNode(attrName2, getter_AddRefs(attrNode));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = attrName;
|
||||
if (!oldValue.IsEmpty())
|
||||
mutation.mPrevAttrValue = getter_AddRefs(NS_NewAtom(oldValue));
|
||||
if (!aValue.IsEmpty())
|
||||
mutation.mNewAttrValue = getter_AddRefs(NS_NewAtom(aValue));
|
||||
mutation.mAttrChange = modification ? nsIDOMMutationEvent::MODIFICATION :
|
||||
nsIDOMMutationEvent::ADDITION;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
if (aNotify) {
|
||||
nsCOMPtr<nsIAtom> tagName;
|
||||
NodeInfo()->GetNameAtom(*getter_AddRefs(tagName));
|
||||
|
@ -2938,6 +3087,29 @@ nsXULElement::UnsetAttribute(PRInt32 aNameSpaceID,
|
|||
nsXULAttribute* attr = NS_REINTERPRET_CAST(nsXULAttribute*, Attributes()->ElementAt(i));
|
||||
if (attr->GetNodeInfo()->Equals(aName, aNameSpaceID)) {
|
||||
attr->GetValue(oldValue);
|
||||
|
||||
if (HasMutationListeners(NS_STATIC_CAST(nsIStyledContent*, this), NS_EVENT_BITS_MUTATION_ATTRMODIFIED)) {
|
||||
nsCOMPtr<nsIDOMEventTarget> node(do_QueryInterface(NS_STATIC_CAST(nsIStyledContent*, this)));
|
||||
nsMutationEvent mutation;
|
||||
mutation.eventStructType = NS_MUTATION_EVENT;
|
||||
mutation.message = NS_MUTATION_ATTRMODIFIED;
|
||||
mutation.mTarget = node;
|
||||
|
||||
nsAutoString attrName2;
|
||||
aName->ToString(attrName2);
|
||||
nsCOMPtr<nsIDOMAttr> attrNode;
|
||||
GetAttributeNode(attrName2, getter_AddRefs(attrNode));
|
||||
mutation.mRelatedNode = attrNode;
|
||||
|
||||
mutation.mAttrName = aName;
|
||||
if (!oldValue.IsEmpty())
|
||||
mutation.mPrevAttrValue = getter_AddRefs(NS_NewAtom(oldValue));
|
||||
mutation.mAttrChange = nsIDOMMutationEvent::REMOVAL;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsIDOMEvent> domEvent;
|
||||
HandleDOMEvent(nsnull, &mutation, getter_AddRefs(domEvent), NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
|
||||
Attributes()->RemoveElementAt(i);
|
||||
NS_RELEASE(attr);
|
||||
successful = PR_TRUE;
|
||||
|
|
Загрузка…
Ссылка в новой задаче