diff --git a/content/base/public/nsContentUtils.h b/content/base/public/nsContentUtils.h index 9ad2ed26920..1e93fadc231 100644 --- a/content/base/public/nsContentUtils.h +++ b/content/base/public/nsContentUtils.h @@ -105,6 +105,7 @@ class nsIUGenCategory; class nsIWidget; class nsIDragSession; class nsPIDOMWindow; +class nsPIDOMEventTarget; #ifdef MOZ_XTF class nsIXTFService; #endif @@ -1337,7 +1338,11 @@ public: static nsIInterfaceRequestor* GetSameOriginChecker(); - + + static nsIThreadJSContextStack* ThreadJSContextStack() + { + return sThreadJSContextStack; + } private: static PRBool InitializeEventTable(); @@ -1434,12 +1439,11 @@ public: ~nsCxPusher(); // Calls Pop(); // Returns PR_FALSE if something erroneous happened. - PRBool Push(nsISupports *aCurrentTarget); + PRBool Push(nsPIDOMEventTarget *aCurrentTarget); PRBool Push(JSContext *cx); void Pop(); private: - nsCOMPtr mStack; nsCOMPtr mScx; PRBool mScriptIsRunning; }; diff --git a/content/base/src/nsContentUtils.cpp b/content/base/src/nsContentUtils.cpp index 9980d97e4d5..695395f7898 100644 --- a/content/base/src/nsContentUtils.cpp +++ b/content/base/src/nsContentUtils.cpp @@ -2691,7 +2691,7 @@ IsContextOnStack(nsIJSContextStack *aStack, JSContext *aContext) } PRBool -nsCxPusher::Push(nsISupports *aCurrentTarget) +nsCxPusher::Push(nsPIDOMEventTarget *aCurrentTarget) { if (mScx) { NS_ERROR("Whaaa! No double pushing with nsCxPusher::Push()!"); @@ -2699,10 +2699,9 @@ nsCxPusher::Push(nsISupports *aCurrentTarget) return PR_FALSE; } - nsCOMPtr eventTarget = do_QueryInterface(aCurrentTarget); - NS_ENSURE_TRUE(eventTarget, PR_FALSE); + NS_ENSURE_TRUE(aCurrentTarget, PR_FALSE); nsCOMPtr scx; - nsresult rv = eventTarget->GetContextForEventHandlers(getter_AddRefs(scx)); + nsresult rv = aCurrentTarget->GetContextForEventHandlers(getter_AddRefs(scx)); NS_ENSURE_SUCCESS(rv, PR_FALSE); JSContext* cx = nsnull; @@ -2735,18 +2734,15 @@ nsCxPusher::Push(JSContext *cx) return PR_TRUE; } - if (!mStack) { - mStack = do_GetService(kJSStackContractID); - } - - if (mStack) { - if (IsContextOnStack(mStack, cx)) { + nsIThreadJSContextStack* stack = nsContentUtils::ThreadJSContextStack(); + if (stack) { + if (IsContextOnStack(stack, cx)) { // If the context is on the stack, that means that a script // is running at the moment in the context. mScriptIsRunning = PR_TRUE; } - mStack->Push(cx); + stack->Push(cx); } } return PR_TRUE; @@ -2755,7 +2751,8 @@ nsCxPusher::Push(JSContext *cx) void nsCxPusher::Pop() { - if (!mScx || !mStack) { + nsIThreadJSContextStack* stack = nsContentUtils::ThreadJSContextStack(); + if (!mScx || !stack) { mScx = nsnull; NS_ASSERTION(!mScriptIsRunning, "Huh, this can't be happening, " @@ -2765,7 +2762,7 @@ nsCxPusher::Pop() } JSContext *unused; - mStack->Pop(&unused); + stack->Pop(&unused); if (!mScriptIsRunning) { // No JS is running in the context, but executing the event handler might have diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index 7dab88d4bd0..df275ff63b8 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -5996,7 +5996,8 @@ nsDocument::PreHandleEvent(nsEventChainPreVisitor& aVisitor) // Load events must not propagate to |window| object, see bug 335251. if (aVisitor.mEvent->message != NS_LOAD) { - aVisitor.mParentTarget = GetWindow(); + nsCOMPtr parentTarget = do_QueryInterface(GetWindow()); + aVisitor.mParentTarget = parentTarget; } return NS_OK; } diff --git a/content/events/public/nsEventDispatcher.h b/content/events/public/nsEventDispatcher.h index 32e771d5aa5..982a77a1493 100644 --- a/content/events/public/nsEventDispatcher.h +++ b/content/events/public/nsEventDispatcher.h @@ -132,13 +132,15 @@ public: nsEventStatus aEventStatus = nsEventStatus_eIgnore) : nsEventChainVisitor(aPresContext, aEvent, aDOMEvent, aEventStatus), mCanHandle(PR_TRUE), mForceContentDispatch(PR_FALSE), - mRelatedTargetIsInAnon(PR_FALSE) {} + mRelatedTargetIsInAnon(PR_FALSE), mWantsWillHandleEvent(PR_FALSE), + mParentTarget(nsnull), mEventTargetAtParent(nsnull) {} void Reset() { mItemFlags = 0; mItemData = nsnull; mCanHandle = PR_TRUE; mForceContentDispatch = PR_FALSE; + mWantsWillHandleEvent = PR_FALSE; mParentTarget = nsnull; mEventTargetAtParent = nsnull; } @@ -163,17 +165,24 @@ public: * element which is anonymous for events. */ PRPackedBool mRelatedTargetIsInAnon; + + + /** + * Whether or not nsPIDOMEventTarget::WillHandleEvent will be + * called. Default is PR_FALSE; + */ + PRPackedBool mWantsWillHandleEvent; /** * Parent item in the event target chain. */ - nsCOMPtr mParentTarget; + nsPIDOMEventTarget* mParentTarget; /** * If the event needs to be retargeted, this is the event target, * which should be used when the event is handled at mParentTarget. */ - nsCOMPtr mEventTargetAtParent; + nsPIDOMEventTarget* mEventTargetAtParent; }; class nsEventChainPostVisitor : public nsEventChainVisitor { diff --git a/content/events/public/nsIEventListenerManager.h b/content/events/public/nsIEventListenerManager.h index f3ad99da9d5..efafb84a349 100644 --- a/content/events/public/nsIEventListenerManager.h +++ b/content/events/public/nsIEventListenerManager.h @@ -47,13 +47,14 @@ class nsIScriptContext; class nsIDOMEventTarget; class nsIDOMEventGroup; class nsIAtom; +class nsPIDOMEventTarget; /* * Event listener manager interface. */ #define NS_IEVENTLISTENERMANAGER_IID \ -{ 0x0056ac6b, 0xc25b, 0x4fbb, \ - { 0x92, 0x98, 0x8d, 0xce, 0x53, 0x6e } } +{ 0x0cdf1660, 0x3ac1, 0x4b84, \ + { 0xa9, 0x35, 0xc0, 0xc0, 0xe5, 0x5d, 0x73, 0xca } } class nsIEventListenerManager : public nsISupports { @@ -138,7 +139,7 @@ public: NS_IMETHOD HandleEvent(nsPresContext* aPresContext, nsEvent* aEvent, nsIDOMEvent** aDOMEvent, - nsISupports* aCurrentTarget, + nsPIDOMEventTarget* aCurrentTarget, PRUint32 aFlags, nsEventStatus* aEventStatus) = 0; diff --git a/content/events/public/nsPIDOMEventTarget.h b/content/events/public/nsPIDOMEventTarget.h index 1b2f5e002ae..14f4f4bbb9d 100644 --- a/content/events/public/nsPIDOMEventTarget.h +++ b/content/events/public/nsPIDOMEventTarget.h @@ -94,7 +94,8 @@ public: virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) = 0; /** - * Called just before possible event handlers on this object will be called. + * If nsEventChainPreVisitor.mWantsWillHandleEvent is set PR_TRUE, + * called just before possible event handlers on this object will be called. */ virtual nsresult WillHandleEvent(nsEventChainPostVisitor& aVisitor) { diff --git a/content/events/src/nsEventDispatcher.cpp b/content/events/src/nsEventDispatcher.cpp index 0efb652185b..20e736d758f 100644 --- a/content/events/src/nsEventDispatcher.cpp +++ b/content/events/src/nsEventDispatcher.cpp @@ -40,27 +40,28 @@ #include "nsPIDOMEventTarget.h" #include "nsPresContext.h" #include "nsIPrivateDOMEvent.h" -#include "nsIEventListenerManager.h" +#include "nsEventListenerManager.h" #include "nsContentUtils.h" #include "nsDOMError.h" #include "nsMutationEvent.h" #include NEW_H #include "nsFixedSizeAllocator.h" -#define NS_TARGET_CHAIN_FORCE_CONTENT_DISPATCH (1 << 0) +#define NS_TARGET_CHAIN_FORCE_CONTENT_DISPATCH (1 << 0) +#define NS_TARGET_CHAIN_WANTS_WILL_HANDLE_EVENT (1 << 1) // nsEventTargetChainItem represents a single item in the event target chain. class nsEventTargetChainItem { private: - nsEventTargetChainItem(nsISupports* aTarget, + nsEventTargetChainItem(nsPIDOMEventTarget* aTarget, nsEventTargetChainItem* aChild = nsnull); void Destroy(nsFixedSizeAllocator* aAllocator); public: static nsEventTargetChainItem* Create(nsFixedSizeAllocator* aAllocator, - nsISupports* aTarget, + nsPIDOMEventTarget* aTarget, nsEventTargetChainItem* aChild = nsnull) { void* place = aAllocator->Alloc(sizeof(nsEventTargetChainItem)); @@ -88,12 +89,13 @@ public: return mNewTarget; } - void SetNewTarget(nsISupports* aNewTarget) + void SetNewTarget(nsPIDOMEventTarget* aNewTarget) { mNewTarget = aNewTarget; } - void SetForceContentDispatch(PRBool aForce) { + void SetForceContentDispatch(PRBool aForce) + { if (aForce) { mFlags |= NS_TARGET_CHAIN_FORCE_CONTENT_DISPATCH; } else { @@ -101,10 +103,26 @@ public: } } - PRBool ForceContentDispatch() { + PRBool ForceContentDispatch() + { return !!(mFlags & NS_TARGET_CHAIN_FORCE_CONTENT_DISPATCH); } + + void SetWantsWillHandleEvent(PRBool aWants) + { + if (aWants) { + mFlags |= NS_TARGET_CHAIN_WANTS_WILL_HANDLE_EVENT; + } else { + mFlags &= ~NS_TARGET_CHAIN_WANTS_WILL_HANDLE_EVENT; + } + } + + PRBool WantsWillHandleEvent() + { + return !!(mFlags & NS_TARGET_CHAIN_WANTS_WILL_HANDLE_EVENT); + } + nsPIDOMEventTarget* CurrentTarget() { return mTarget; @@ -118,7 +136,8 @@ public: */ nsresult HandleEventTargetChain(nsEventChainPostVisitor& aVisitor, PRUint32 aFlags, - nsDispatchingCallback* aCallback); + nsDispatchingCallback* aCallback, + PRBool aMayHaveNewListenerManagers); /** * Resets aVisitor object and calls PreHandleEvent. @@ -131,7 +150,8 @@ public: * manager, this method sets the .currentTarget to the CurrentTarget() * and calls nsIEventListenerManager::HandleEvent(). */ - nsresult HandleEvent(nsEventChainPostVisitor& aVisitor, PRUint32 aFlags); + nsresult HandleEvent(nsEventChainPostVisitor& aVisitor, PRUint32 aFlags, + PRBool aMayHaveNewListenerManagers); /** * Copies mItemFlags and mItemData to aVisitor and calls PostHandleEvent. @@ -146,19 +166,16 @@ public: PRUint16 mItemFlags; nsCOMPtr mItemData; // Event retargeting must happen whenever mNewTarget is non-null. - nsCOMPtr mNewTarget; + nsCOMPtr mNewTarget; // Cache mTarget's event listener manager. nsCOMPtr mManager; }; -nsEventTargetChainItem::nsEventTargetChainItem(nsISupports* aTarget, +nsEventTargetChainItem::nsEventTargetChainItem(nsPIDOMEventTarget* aTarget, nsEventTargetChainItem* aChild) : mChild(aChild), mParent(nsnull), mFlags(0), mItemFlags(0) { - nsCOMPtr t = do_QueryInterface(aTarget); - if (t) { - mTarget = t->GetTargetForEventTargetChain(); - } + mTarget = aTarget->GetTargetForEventTargetChain(); if (mChild) { mChild->mParent = this; } @@ -186,6 +203,7 @@ nsEventTargetChainItem::PreHandleEvent(nsEventChainPreVisitor& aVisitor) aVisitor.Reset(); nsresult rv = mTarget->PreHandleEvent(aVisitor); SetForceContentDispatch(aVisitor.mForceContentDispatch); + SetWantsWillHandleEvent(aVisitor.mWantsWillHandleEvent); mItemFlags = aVisitor.mItemFlags; mItemData = aVisitor.mItemData; return rv; @@ -193,21 +211,28 @@ nsEventTargetChainItem::PreHandleEvent(nsEventChainPreVisitor& aVisitor) nsresult nsEventTargetChainItem::HandleEvent(nsEventChainPostVisitor& aVisitor, - PRUint32 aFlags) + PRUint32 aFlags, + PRBool aMayHaveNewListenerManagers) { - mTarget->WillHandleEvent(aVisitor); + if (WantsWillHandleEvent()) { + mTarget->WillHandleEvent(aVisitor); + } if (aVisitor.mEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH) { return NS_OK; } if (!mManager) { + if (!aMayHaveNewListenerManagers) { + return NS_OK; + } mTarget->GetListenerManager(PR_FALSE, getter_AddRefs(mManager)); } if (mManager) { - aVisitor.mEvent->currentTarget = CurrentTarget()->GetTargetForDOMEvent(); + nsPIDOMEventTarget* currentTarget = CurrentTarget()->GetTargetForDOMEvent(); + aVisitor.mEvent->currentTarget = currentTarget; if (aVisitor.mEvent->currentTarget) { mManager->HandleEvent(aVisitor.mPresContext, aVisitor.mEvent, &aVisitor.mDOMEvent, - aVisitor.mEvent->currentTarget, aFlags, + currentTarget, aFlags, &aVisitor.mEventStatus); aVisitor.mEvent->currentTarget = nsnull; } @@ -226,8 +251,10 @@ nsEventTargetChainItem::PostHandleEvent(nsEventChainPostVisitor& aVisitor) nsresult nsEventTargetChainItem::HandleEventTargetChain(nsEventChainPostVisitor& aVisitor, PRUint32 aFlags, - nsDispatchingCallback* aCallback) + nsDispatchingCallback* aCallback, + PRBool aMayHaveNewListenerManagers) { + PRUint32 createdELMs = nsEventListenerManager::sCreatedCount; // Save the target so that it can be restored later. nsCOMPtr firstTarget = aVisitor.mEvent->target; @@ -239,7 +266,9 @@ nsEventTargetChainItem::HandleEventTargetChain(nsEventChainPostVisitor& aVisitor if ((!(aVisitor.mEvent->flags & NS_EVENT_FLAG_NO_CONTENT_DISPATCH) || item->ForceContentDispatch()) && !(aVisitor.mEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH)) { - item->HandleEvent(aVisitor, aFlags & NS_EVENT_CAPTURE_MASK); + item->HandleEvent(aVisitor, aFlags & NS_EVENT_CAPTURE_MASK, + aMayHaveNewListenerManagers || + createdELMs != nsEventListenerManager::sCreatedCount); } if (item->GetNewTarget()) { @@ -266,7 +295,9 @@ nsEventTargetChainItem::HandleEventTargetChain(nsEventChainPostVisitor& aVisitor // FIXME Should use aFlags & NS_EVENT_BUBBLE_MASK because capture phase // event listeners should not be fired. But it breaks at least // 's buttons. Bug 235441. - item->HandleEvent(aVisitor, aFlags); + item->HandleEvent(aVisitor, aFlags, + aMayHaveNewListenerManagers || + createdELMs != nsEventListenerManager::sCreatedCount); } if (aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) { item->PostHandleEvent(aVisitor); @@ -289,7 +320,8 @@ nsEventTargetChainItem::HandleEventTargetChain(nsEventChainPostVisitor& aVisitor (!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) || aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault) && !(aVisitor.mEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH)) { - item->HandleEvent(aVisitor, aFlags & NS_EVENT_BUBBLE_MASK); + item->HandleEvent(aVisitor, aFlags & NS_EVENT_BUBBLE_MASK, + createdELMs != nsEventListenerManager::sCreatedCount); } if (aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) { item->PostHandleEvent(aVisitor); @@ -318,7 +350,8 @@ nsEventTargetChainItem::HandleEventTargetChain(nsEventChainPostVisitor& aVisitor // Setting back the target which was used also for default event group. aVisitor.mEvent->target = firstTarget; HandleEventTargetChain(aVisitor, aFlags | NS_EVENT_FLAG_SYSTEM_EVENT, - aCallback); + aCallback, + createdELMs != nsEventListenerManager::sCreatedCount); } return NS_OK; @@ -378,6 +411,7 @@ nsEventDispatcher::Dispatch(nsISupports* aTarget, NS_ENSURE_TRUE(!NS_IS_EVENT_IN_DISPATCH(aEvent), NS_ERROR_ILLEGAL_VALUE); + nsCOMPtr target = do_QueryInterface(aTarget); #ifdef DEBUG if (aDOMEvent) { nsCOMPtr privEvt(do_QueryInterface(aDOMEvent)); @@ -401,7 +435,7 @@ nsEventDispatcher::Dispatch(nsISupports* aTarget, // Create the event target chain item for the event target. nsEventTargetChainItem* targetEtci = - nsEventTargetChainItem::Create(pool.GetPool(), aTarget); + nsEventTargetChainItem::Create(pool.GetPool(), target); NS_ENSURE_TRUE(targetEtci, NS_ERROR_OUT_OF_MEMORY); if (!targetEtci->IsValid()) { nsEventTargetChainItem::Destroy(pool.GetPool(), targetEtci); @@ -438,7 +472,8 @@ nsEventDispatcher::Dispatch(nsISupports* aTarget, if (preVisitor.mCanHandle) { // At least the original target can handle the event. // Setting the retarget to the |target| simplifies retargeting code. - targetEtci->SetNewTarget(aEvent->target); + nsCOMPtr t = do_QueryInterface(aEvent->target); + targetEtci->SetNewTarget(t); nsEventTargetChainItem* topEtci = targetEtci; while (preVisitor.mParentTarget) { nsEventTargetChainItem* parentEtci = @@ -476,7 +511,8 @@ nsEventDispatcher::Dispatch(nsISupports* aTarget, rv = topEtci->HandleEventTargetChain(postVisitor, NS_EVENT_FLAG_BUBBLE | NS_EVENT_FLAG_CAPTURE, - aCallback); + aCallback, + PR_TRUE); preVisitor.mEventStatus = postVisitor.mEventStatus; // If the DOM event was created during event flow. diff --git a/content/events/src/nsEventListenerManager.cpp b/content/events/src/nsEventListenerManager.cpp index bc6fc35073b..46860bb8f40 100644 --- a/content/events/src/nsEventListenerManager.cpp +++ b/content/events/src/nsEventListenerManager.cpp @@ -339,6 +339,7 @@ nsIDOMEventGroup* gDOM2EventGroup = nsnull; nsDataHashtable* gEventIdTable = nsnull; PRUint32 nsEventListenerManager::mInstanceCount = 0; +PRUint32 nsEventListenerManager::sCreatedCount = 0; nsEventListenerManager::nsEventListenerManager() : mTarget(nsnull), @@ -346,6 +347,7 @@ nsEventListenerManager::nsEventListenerManager() : mNoListenerForEvent(NS_EVENT_TYPE_NULL) { ++mInstanceCount; + ++sCreatedCount; } nsEventListenerManager::~nsEventListenerManager() @@ -1072,10 +1074,7 @@ nsEventListenerManager::HandleEventSubType(nsListenerStruct* aListenerStruct, } } - // nsCxPusher will push and pop (automatically) the current cx onto the - // context stack - nsCxPusher pusher; - if (NS_SUCCEEDED(result) && pusher.Push(aCurrentTarget)) { + if (NS_SUCCEEDED(result)) { // nsIDOMEvent::currentTarget is set in nsEventDispatcher. result = aListener->HandleEvent(aDOMEvent); } @@ -1095,7 +1094,7 @@ static const EventDispatchData* sLatestEventDispData = nsnull; nsresult nsEventListenerManager::HandleEvent(nsPresContext* aPresContext, nsEvent* aEvent, nsIDOMEvent** aDOMEvent, - nsISupports* aCurrentTarget, + nsPIDOMEventTarget* aCurrentTarget, PRUint32 aFlags, nsEventStatus* aEventStatus) { @@ -1155,6 +1154,10 @@ found: nsAutoTObserverArray::EndLimitedIterator iter(mListeners); nsAutoPopupStatePusher popupStatePusher(nsDOMEvent::GetEventPopupControlState(aEvent)); PRBool hasListener = PR_FALSE; + // nsCxPusher will push and pop (automatically) the current cx onto the + // context stack + nsCxPusher pusher; + PRBool didPush = PR_FALSE; while (iter.HasMore()) { nsListenerStruct* ls = &iter.GetNext(); PRBool useTypeInterface = @@ -1178,9 +1181,14 @@ found: if (*aDOMEvent) { nsRefPtr kungFuDeathGrip = ls->mListener; if (useTypeInterface) { + if (didPush) { + didPush = PR_FALSE; + pusher.Pop(); + } DispatchToInterface(*aDOMEvent, ls->mListener, dispData->method, *typeData->iid); - } else if (useGenericInterface) { + } else if (useGenericInterface && + (didPush || (didPush = pusher.Push(aCurrentTarget)))) { HandleEventSubType(ls, ls->mListener, *aDOMEvent, aCurrentTarget, aFlags); } diff --git a/content/events/src/nsEventListenerManager.h b/content/events/src/nsEventListenerManager.h index b19dbd62e5e..80c4f428404 100644 --- a/content/events/src/nsEventListenerManager.h +++ b/content/events/src/nsEventListenerManager.h @@ -52,6 +52,7 @@ class nsIAtom; class nsIWidget; struct nsPoint; struct EventTypeData; +class nsEventTargetChainItem; typedef struct { nsRefPtr mListener; @@ -113,7 +114,7 @@ public: NS_IMETHOD HandleEvent(nsPresContext* aPresContext, nsEvent* aEvent, nsIDOMEvent** aDOMEvent, - nsISupports* aCurrentTarget, + nsPIDOMEventTarget* aCurrentTarget, PRUint32 aFlags, nsEventStatus* aEventStatus); @@ -202,6 +203,9 @@ protected: static PRUint32 mInstanceCount; static jsval sAddListenerID; + + friend class nsEventTargetChainItem; + static PRUint32 sCreatedCount; }; #endif // nsEventListenerManager_h__ diff --git a/content/events/src/nsEventStateManager.cpp b/content/events/src/nsEventStateManager.cpp index 2235ff4965d..02c55ae0f76 100644 --- a/content/events/src/nsEventStateManager.cpp +++ b/content/events/src/nsEventStateManager.cpp @@ -5129,7 +5129,8 @@ nsEventStateManager::SendFocusBlur(nsPresContext* aPresContext, return NS_OK; } - if (pusher.Push(window)) { + nsCOMPtr target = do_QueryInterface(window); + if (pusher.Push(target)) { nsEventDispatcher::Dispatch(window, gLastFocusedPresContextWeak, &event, nsnull, &status); diff --git a/content/html/content/src/nsHTMLFormElement.cpp b/content/html/content/src/nsHTMLFormElement.cpp index 8a6b41a000f..d35c6de3bce 100644 --- a/content/html/content/src/nsHTMLFormElement.cpp +++ b/content/html/content/src/nsHTMLFormElement.cpp @@ -808,6 +808,7 @@ nsHTMLFormElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent) nsresult nsHTMLFormElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor) { + aVisitor.mWantsWillHandleEvent = PR_TRUE; if (aVisitor.mEvent->originalTarget == static_cast(this)) { PRUint32 msg = aVisitor.mEvent->message; if (msg == NS_FORM_SUBMIT) {