зеркало из https://github.com/mozilla/pjs.git
Bug 234455, Centralize event dispatch r=jst, sr=bz
This commit is contained in:
Родитель
87814ed31b
Коммит
c0e37e327a
|
@ -2185,8 +2185,8 @@ void nsAccessible::DoCommandCallback(nsITimer *aTimer, void *aClosure)
|
|||
nsMouseEvent::eSynthesized);
|
||||
|
||||
nsEventStatus eventStatus = nsEventStatus_eIgnore;
|
||||
content->HandleDOMEvent(presShell->GetPresContext(), &clickEvent, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &eventStatus);
|
||||
content->DispatchDOMEvent(&clickEvent, nsnull,
|
||||
presShell->GetPresContext(), &eventStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -516,7 +516,7 @@ void nsRootAccessible::FireCurrentFocusEvent()
|
|||
if (rootContent && presContext) {
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
rootContent->GetListenerManager(getter_AddRefs(manager));
|
||||
rootContent->GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
||||
if (manager && NS_SUCCEEDED(manager->CreateEvent(presContext, nsnull,
|
||||
NS_LITERAL_STRING("Events"),
|
||||
getter_AddRefs(event))) &&
|
||||
|
|
|
@ -752,23 +752,18 @@ public:
|
|||
static void RemoveRangeList(nsIContent *aContent);
|
||||
|
||||
/**
|
||||
* Look up the eventlistener manager for aContent.
|
||||
*
|
||||
* @param aContent The node for which to look up the eventlistener manager.
|
||||
* @return The eventlistener manager if one exists.
|
||||
*/
|
||||
static nsIEventListenerManager *LookupListenerManager(nsIContent *aContent);
|
||||
|
||||
/**
|
||||
* Get the eventlistener manager for aContent. This creates a new event-
|
||||
* listener manager if none exist, in that case aCreated is set to PR_TRUE.
|
||||
* Get the eventlistener manager for aContent. If a new eventlistener manager
|
||||
* was created, aCreated is set to PR_TRUE.
|
||||
*
|
||||
* @param aContent The node for which to get the eventlistener manager.
|
||||
* @param aCreateIfNotFound If PR_FALSE, returns a listener manager only if
|
||||
* one already exists.
|
||||
* @param aResult [out] Set to the eventlistener manager for aContent.
|
||||
* @param aCreated [out] Set to PR_TRUE if a new eventlistener manager was
|
||||
* created.
|
||||
*/
|
||||
static nsresult GetListenerManager(nsIContent *aContent,
|
||||
PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager **aResult,
|
||||
PRBool *aCreated);
|
||||
|
||||
|
|
|
@ -64,10 +64,9 @@ class nsAttrValue;
|
|||
class nsAttrName;
|
||||
|
||||
// IID for the nsIContent interface
|
||||
// b61222e2-88b6-4f7f-ae81-679484a4493a
|
||||
#define NS_ICONTENT_IID \
|
||||
{ 0xb61222e2, 0x88b6, 0x4f7f, \
|
||||
{ 0xae, 0x81, 0x67, 0x94, 0x84, 0xa4, 0x49, 0x3a } }
|
||||
#define NS_ICONTENT_IID \
|
||||
{ 0xda0e2f6c, 0x6cd2, 0x4fdc, \
|
||||
{ 0x9b, 0x03, 0x35, 0xb5, 0x65, 0x09, 0xa6, 0xab } }
|
||||
|
||||
/**
|
||||
* A node of content in a document's content model. This interface
|
||||
|
@ -421,43 +420,6 @@ public:
|
|||
*/
|
||||
virtual const nsVoidArray *GetRangeList() const = 0;
|
||||
|
||||
/**
|
||||
* Handle a DOM event for this piece of content. This method is responsible
|
||||
* for handling and controlling all three stages of events, capture, local
|
||||
* and bubble. It also does strange things to anonymous content which whiz
|
||||
* right by this author's head.
|
||||
*
|
||||
* Here are some beginning explanations:
|
||||
* - if in INIT or CAPTURE mode, it must pass the event to its parent in
|
||||
* CAPTURE mode (this happens before the event is fired, therefore the
|
||||
* firing of events will occur from the root up to the target).
|
||||
* - The event is fired to listeners.
|
||||
* - If in INIT or BUBBLE mode, it passes the event to its parent in BUBBLE
|
||||
* mode. This means that the events will be fired up the chain starting
|
||||
* from the target to the ancestor.
|
||||
*
|
||||
* NOTE: if you are extending nsGenericElement and have to do a default
|
||||
* action, call super::HandleDOMEvent() first and check for
|
||||
* aEventStatus != nsEventStatus_eIgnore and make sure you are not in CAPTURE
|
||||
* mode before proceeding.
|
||||
*
|
||||
* XXX Go comment that method, Will Robinson.
|
||||
* @param aPresContext the current presentation context
|
||||
* @param aEvent the event that is being propagated
|
||||
* @param aDOMEvent a special event that may contain a modified target. Pass
|
||||
* in null here or aDOMEvent if you are in HandleDOMEvent already;
|
||||
* don't worry your pretty little head about it.
|
||||
* @param aFlags flags that describe what mode we are in. Generally
|
||||
* NS_EVENT_FLAG_CAPTURE, NS_EVENT_FLAG_BUBBLE and NS_EVENT_FLAG_INIT
|
||||
* are the ones that matter.
|
||||
* @param aEventStatus the status returned from the function. Generally
|
||||
* nsEventStatus_eIgnore
|
||||
*/
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus) = 0;
|
||||
|
||||
/**
|
||||
* Set the focus on this content. This is generally something for the event
|
||||
* state manager to do, not ordinary people. Ordinary people should do
|
||||
|
@ -594,9 +556,14 @@ public:
|
|||
/**
|
||||
* Get the event listener manager, the guy you talk to to register for events
|
||||
* on this element.
|
||||
* @param aResult the event listener manager [OUT]
|
||||
* @param aCreateIfNotFound If PR_FALSE, returns a listener manager only if
|
||||
* one already exists. [IN]
|
||||
* @param aResult The event listener manager [OUT]
|
||||
*
|
||||
* FIXME! Remove this method, there is similar in nsINode. Bug 329112
|
||||
*/
|
||||
virtual nsresult GetListenerManager(nsIEventListenerManager** aResult) = 0;
|
||||
virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult) = 0;
|
||||
|
||||
/**
|
||||
* Get the base URI for any relative URIs within this piece of
|
||||
|
|
|
@ -91,10 +91,9 @@ class nsIVariant;
|
|||
class nsIDOMUserDataHandler;
|
||||
|
||||
// IID for the nsIDocument interface
|
||||
// 0a87ec89-5589-4690-93b9-6c6c86e1e072
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0x0a87ec89, 0x5589, 0x4690, \
|
||||
{ 0x93, 0xb9, 0x6c, 0x6c, 0x86, 0xe1, 0xe0, 0x72 } }
|
||||
#define NS_IDOCUMENT_IID \
|
||||
{ 0xb657335d, 0x43db, 0x41f3, \
|
||||
{ 0x8c, 0xc0, 0xe2, 0x29, 0x88, 0xb5, 0x99, 0x69 } }
|
||||
|
||||
// Flag for AddStyleSheet().
|
||||
#define NS_STYLESHEET_FROM_CATALOG (1 << 0)
|
||||
|
@ -553,11 +552,6 @@ public:
|
|||
virtual void StyleRuleRemoved(nsIStyleSheet* aStyleSheet,
|
||||
nsIStyleRule* aStyleRule) = 0;
|
||||
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus) = 0;
|
||||
|
||||
/**
|
||||
* Flush notifications for this document and its parent documents
|
||||
* (since those may affect the layout of this one).
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
#define nsINode_h___
|
||||
|
||||
#include "nsIDOMGCParticipant.h"
|
||||
#include "nsEvent.h"
|
||||
#include "nsPropertyTable.h"
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
|
@ -48,13 +49,18 @@
|
|||
|
||||
class nsIContent;
|
||||
class nsIDocument;
|
||||
class nsIDOMEvent;
|
||||
class nsPresContext;
|
||||
class nsEventChainPreVisitor;
|
||||
class nsEventChainPostVisitor;
|
||||
class nsIEventListenerManager;
|
||||
class nsIPrincipal;
|
||||
|
||||
// IID for the nsINode interface
|
||||
// 6b7a8e08-f34b-4210-af93-ec7a769498e9
|
||||
// ec67d9d2-be1e-41d8-b7d0-92f72a2667db
|
||||
#define NS_INODE_IID \
|
||||
{ 0x6b7a8e08, 0xf34b, 0x4210, \
|
||||
{ 0xaf, 0x93, 0xec, 0x7a, 0x76, 0x94, 0x98, 0xe9 } }
|
||||
{ 0xec67d9d2, 0xbe1e, 0x41d8, \
|
||||
{ 0xb7, 0xd0, 0x92, 0xf7, 0x2a, 0x26, 0x67, 0xdb } }
|
||||
|
||||
// hack to make egcs / gcc 2.95.2 happy
|
||||
class nsINode_base : public nsIDOMGCParticipant {
|
||||
|
@ -243,7 +249,66 @@ public:
|
|||
* IsNodeOfType()? Do we need a non-QI way to tell apart documents and
|
||||
* content?
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Called before the capture phase of the event flow.
|
||||
* This is used to create the event target chain and implementations
|
||||
* should set the necessary members of nsEventChainPreVisitor.
|
||||
* At least aVisitor.mCanHandle must be set,
|
||||
* usually also aVisitor.mParentTarget if mCanHandle is PR_TRUE.
|
||||
* First one tells that this object can handle the aVisitor.mEvent event and
|
||||
* the latter one is the possible parent object for the event target chain.
|
||||
* @see nsEventDispatcher.h for more documentation about aVisitor.
|
||||
*
|
||||
* @param aVisitor the visitor object which is used to create the
|
||||
* event target chain for event dispatching.
|
||||
*
|
||||
* @note Only nsEventDispatcher should call this method.
|
||||
*/
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) = 0;
|
||||
|
||||
/**
|
||||
* Called after the bubble phase of the system event group.
|
||||
* The default handling of the event should happen here.
|
||||
* @param aVisitor the visitor object which is used during post handling.
|
||||
*
|
||||
* @see nsEventDispatcher.h for documentation about aVisitor.
|
||||
* @note Only nsEventDispatcher should call this method.
|
||||
*/
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor) = 0;
|
||||
|
||||
/**
|
||||
* Dispatch an event.
|
||||
* @param aEvent the event that is being dispatched.
|
||||
* @param aDOMEvent the event that is being dispatched, use if you want to
|
||||
* dispatch nsIDOMEvent, not only nsEvent.
|
||||
* @param aPresContext the current presentation context, can be nsnull.
|
||||
* @param aEventStatus the status returned from the function, can be nsnull.
|
||||
*
|
||||
* @note If both aEvent and aDOMEvent are used, aEvent must be the internal
|
||||
* event of the aDOMEvent.
|
||||
*
|
||||
* If aDOMEvent is not nsnull (in which case aEvent can be nsnull) it is used
|
||||
* for dispatching, otherwise aEvent is used.
|
||||
*
|
||||
* @deprecated This method is here just until all the callers outside Gecko
|
||||
* have been converted to use nsIDOMEventTarget::dispatchEvent.
|
||||
*/
|
||||
virtual nsresult DispatchDOMEvent(nsEvent* aEvent,
|
||||
nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus) = 0;
|
||||
|
||||
/**
|
||||
* Get the event listener manager, the guy you talk to to register for events
|
||||
* on this node.
|
||||
* @param aCreateIfNotFound If PR_FALSE, returns a listener manager only if
|
||||
* one already exists. [IN]
|
||||
* @param aResult The event listener manager [OUT]
|
||||
*/
|
||||
virtual nsresult GetEventListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult)
|
||||
= 0;
|
||||
protected:
|
||||
|
||||
nsCOMPtr<nsINodeInfo> mNodeInfo;
|
||||
|
|
|
@ -2804,30 +2804,10 @@ nsContentUtils::HasNonEmptyAttr(nsIContent* aContent, PRInt32 aNameSpaceID,
|
|||
== nsIContent::ATTR_VALUE_NO_MATCH;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsIEventListenerManager*
|
||||
nsContentUtils::LookupListenerManager(nsIContent *aContent)
|
||||
{
|
||||
if (!sEventListenerManagersHash.ops) {
|
||||
// We're already shut down.
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
EventListenerManagerMapEntry *entry =
|
||||
NS_STATIC_CAST(EventListenerManagerMapEntry *,
|
||||
PL_DHashTableOperate(&sEventListenerManagersHash, aContent,
|
||||
PL_DHASH_LOOKUP));
|
||||
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
|
||||
return entry->mListenerManager;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
/* static */
|
||||
nsresult
|
||||
nsContentUtils::GetListenerManager(nsIContent *aContent,
|
||||
PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager **aResult,
|
||||
PRBool *aCreated)
|
||||
{
|
||||
|
@ -2841,6 +2821,18 @@ nsContentUtils::GetListenerManager(nsIContent *aContent,
|
|||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
if (!aCreateIfNotFound) {
|
||||
EventListenerManagerMapEntry *entry =
|
||||
NS_STATIC_CAST(EventListenerManagerMapEntry *,
|
||||
PL_DHashTableOperate(&sEventListenerManagersHash, aContent,
|
||||
PL_DHASH_LOOKUP));
|
||||
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
|
||||
*aResult = entry->mListenerManager;
|
||||
NS_ADDREF(*aResult);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
EventListenerManagerMapEntry *entry =
|
||||
NS_STATIC_CAST(EventListenerManagerMapEntry *,
|
||||
PL_DHashTableOperate(&sEventListenerManagersHash, aContent,
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include "nsIDOM3Attr.h"
|
||||
#include "nsIDOMUserDataHandler.h"
|
||||
#include "nsITextContent.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
PRBool nsDOMAttribute::sInitialized;
|
||||
|
@ -806,6 +807,36 @@ nsDOMAttribute::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
|||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMAttribute::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
// We don't support event dispatching to attributes yet.
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMAttribute::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMAttribute::DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMAttribute::GetEventListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDOMAttribute::EnsureChildState(PRBool aSetText, PRBool &aHasChild) const
|
||||
{
|
||||
|
|
|
@ -111,6 +111,13 @@ public:
|
|||
PRBool aNotify);
|
||||
virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult GetEventListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult);
|
||||
static void Initialize();
|
||||
static void Shutdown();
|
||||
|
||||
|
|
|
@ -137,6 +137,7 @@ static NS_DEFINE_CID(kDOMEventGroupCID, NS_DOMEVENTGROUP_CID);
|
|||
|
||||
#include "nsDateTimeFormatCID.h"
|
||||
#include "nsIDateTimeFormat.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
#ifdef MOZ_LOGGING
|
||||
// so we can get logging even in release builds
|
||||
|
@ -2326,8 +2327,8 @@ nsDocument::DispatchContentLoadedEvents()
|
|||
privateEvent->SetTrusted(PR_TRUE);
|
||||
|
||||
// To dispatch this event we must manually call
|
||||
// HandleDOMEvent() on the ancestor document since the target
|
||||
// is not in the same document, so the event would never reach
|
||||
// nsEventDispatcher::Dispatch() on the ancestor document since the
|
||||
// target is not in the same document, so the event would never reach
|
||||
// the ancestor document if we used the normal event
|
||||
// dispatching code.
|
||||
|
||||
|
@ -2341,16 +2342,8 @@ nsDocument::DispatchContentLoadedEvents()
|
|||
nsCOMPtr<nsPresContext> context = shell->GetPresContext();
|
||||
|
||||
if (context) {
|
||||
// The event argument to HandleDOMEvent() is inout, and
|
||||
// that doesn't mix well with nsCOMPtr's. We'll need to
|
||||
// perform some refcounting magic here.
|
||||
nsIDOMEvent *tmp_event = event;
|
||||
NS_ADDREF(tmp_event);
|
||||
|
||||
ancestor_doc->HandleDOMEvent(context, innerEvent, &tmp_event,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
|
||||
NS_IF_RELEASE(tmp_event);
|
||||
nsEventDispatcher::Dispatch(ancestor_doc, context, innerEvent,
|
||||
event, &status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4238,7 +4231,8 @@ nsDocument::GetOwnerDocument(nsIDOMDocument** aOwnerDocument)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::GetListenerManager(nsIEventListenerManager **aInstancePtrResult)
|
||||
nsDocument::GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aInstancePtrResult)
|
||||
{
|
||||
if (mListenerManager) {
|
||||
*aInstancePtrResult = mListenerManager;
|
||||
|
@ -4246,6 +4240,10 @@ nsDocument::GetListenerManager(nsIEventListenerManager **aInstancePtrResult)
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
if (!aCreateIfNotFound) {
|
||||
*aInstancePtrResult = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv = NS_NewEventListenerManager(getter_AddRefs(mListenerManager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -4269,7 +4267,8 @@ NS_IMETHODIMP
|
|||
nsDocument::GetSystemEventGroup(nsIDOMEventGroup **aGroup)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
if (NS_SUCCEEDED(GetListenerManager(getter_AddRefs(manager))) && manager) {
|
||||
if (NS_SUCCEEDED(GetListenerManager(PR_TRUE, getter_AddRefs(manager))) &&
|
||||
manager) {
|
||||
return manager->GetSystemEventGroupLM(aGroup);
|
||||
}
|
||||
|
||||
|
@ -4277,94 +4276,40 @@ nsDocument::GetSystemEventGroup(nsIDOMEventGroup **aGroup)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::HandleDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent, PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsDocument::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
// Make sure to tell the event that dispatch has started.
|
||||
NS_MARK_EVENT_DISPATCH_STARTED(aEvent);
|
||||
|
||||
PRBool externalDOMEvent = PR_FALSE;
|
||||
|
||||
nsIDOMEvent* domEvent = nsnull;
|
||||
|
||||
if (NS_EVENT_FLAG_INIT & aFlags) {
|
||||
if (aDOMEvent) {
|
||||
if (*aDOMEvent) {
|
||||
externalDOMEvent = PR_TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aDOMEvent = &domEvent;
|
||||
}
|
||||
aEvent->flags |= aFlags;
|
||||
aFlags &= ~(NS_EVENT_FLAG_CANT_BUBBLE | NS_EVENT_FLAG_CANT_CANCEL);
|
||||
aFlags |= NS_EVENT_FLAG_BUBBLE | NS_EVENT_FLAG_CAPTURE;
|
||||
}
|
||||
|
||||
nsPIDOMWindow *window = GetWindow();
|
||||
|
||||
// Capturing stage
|
||||
if (NS_EVENT_FLAG_CAPTURE & aFlags && window) {
|
||||
window->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
|
||||
aFlags & NS_EVENT_CAPTURE_MASK, aEventStatus);
|
||||
}
|
||||
|
||||
// Local handling stage
|
||||
// Check for null ELM, check if we're a non-bubbling
|
||||
// event in the bubbling state (bubbling state is indicated by the
|
||||
// presence of the NS_EVENT_FLAG_BUBBLE flag and not the
|
||||
// NS_EVENT_FLAG_INIT).
|
||||
if (mListenerManager &&
|
||||
!(NS_EVENT_FLAG_CANT_BUBBLE & aEvent->flags &&
|
||||
NS_EVENT_FLAG_BUBBLE & aFlags && !(NS_EVENT_FLAG_INIT & aFlags))) {
|
||||
aEvent->flags |= aFlags;
|
||||
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, this,
|
||||
aFlags, aEventStatus);
|
||||
aEvent->flags &= ~aFlags;
|
||||
}
|
||||
|
||||
// Bubbling stage
|
||||
if (NS_EVENT_FLAG_BUBBLE & aFlags && window) {
|
||||
window->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
|
||||
aFlags & NS_EVENT_BUBBLE_MASK, aEventStatus);
|
||||
}
|
||||
|
||||
if (NS_EVENT_FLAG_INIT & aFlags) {
|
||||
// We're leaving the DOM event loop so if we created a DOM event,
|
||||
// release here.
|
||||
if (*aDOMEvent && !externalDOMEvent) {
|
||||
nsrefcnt rc;
|
||||
NS_RELEASE2(*aDOMEvent, rc);
|
||||
if (0 != rc) {
|
||||
// Okay, so someone in the DOM loop (a listener, JS object)
|
||||
// still has a ref to the DOM Event but the internal data
|
||||
// hasn't been malloc'd. Force a copy of the data here so the
|
||||
// DOM Event is still valid.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent =
|
||||
do_QueryInterface(*aDOMEvent);
|
||||
if (privateEvent) {
|
||||
privateEvent->DuplicatePrivateData();
|
||||
}
|
||||
}
|
||||
aDOMEvent = nsnull;
|
||||
}
|
||||
|
||||
// Now that we're done with this event, remove the flag that says
|
||||
// we're in the process of dispatching this event.
|
||||
NS_MARK_EVENT_DISPATCH_DONE(aEvent);
|
||||
}
|
||||
|
||||
aVisitor.mCanHandle = PR_TRUE;
|
||||
// FIXME! This is a hack to make middle mouse paste working also in Editor.
|
||||
// Bug 329119
|
||||
aVisitor.mForceContentDispatch = PR_TRUE;
|
||||
aVisitor.mParentTarget = GetWindow();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::DispatchDOMEvent(nsEvent* aEvent,
|
||||
nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus)
|
||||
{
|
||||
return nsEventDispatcher::DispatchDOMEvent(NS_STATIC_CAST(nsINode*, this),
|
||||
aEvent, aDOMEvent,
|
||||
aPresContext, aEventStatus);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocument::AddEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
GetListenerManager(getter_AddRefs(manager));
|
||||
GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
return NS_OK;
|
||||
|
@ -4408,13 +4353,18 @@ nsDocument::DispatchEvent(nsIDOMEvent* aEvent, PRBool *_retval)
|
|||
{
|
||||
// Obtain a presentation context
|
||||
nsIPresShell *shell = GetShellAt(0);
|
||||
if (!shell)
|
||||
return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsPresContext> context;
|
||||
if (shell) {
|
||||
context = shell->GetPresContext();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPresContext> context = shell->GetPresContext();
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsresult rv =
|
||||
nsEventDispatcher::DispatchDOMEvent(NS_STATIC_CAST(nsINode*, this),
|
||||
nsnull, aEvent, context, &status);
|
||||
|
||||
return context->EventStateManager()->
|
||||
DispatchNewEvent(NS_STATIC_CAST(nsIDOMDocument*, this), aEvent, _retval);
|
||||
*_retval = (status != nsEventStatus_eConsumeNoDefault);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -4425,7 +4375,7 @@ nsDocument::AddGroupedEventListener(const nsAString& aType,
|
|||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
nsresult rv = GetListenerManager(getter_AddRefs(manager));
|
||||
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
||||
if (NS_SUCCEEDED(rv) && manager) {
|
||||
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
||||
|
||||
|
@ -4471,7 +4421,7 @@ nsDocument::AddEventListener(const nsAString& aType,
|
|||
PRBool aUseCapture, PRBool aWantsUntrusted)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
nsresult rv = GetListenerManager(getter_AddRefs(manager));
|
||||
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
||||
|
@ -4500,13 +4450,9 @@ nsDocument::CreateEvent(const nsAString& aEventType, nsIDOMEvent** aReturn)
|
|||
presContext = shell->GetPresContext();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
return manager->CreateEvent(presContext, nsnull, aEventType, aReturn);
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
// Create event even without presContext.
|
||||
return nsEventDispatcher::CreateEvent(presContext, nsnull,
|
||||
aEventType, aReturn);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -5141,11 +5087,11 @@ CanCacheSubDocument(PLDHashTable *table, PLDHashEntryHdr *hdr,
|
|||
PRBool
|
||||
nsDocument::CanSavePresentation(nsIRequest *aNewRequest)
|
||||
{
|
||||
// Check our event listneer manager for unload/beforeunload listeners.
|
||||
// Check our event listener manager for unload/beforeunload listeners.
|
||||
nsCOMPtr<nsIDOMEventReceiver> er = do_QueryInterface(mScriptGlobalObject);
|
||||
if (er) {
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
er->GetListenerManager(getter_AddRefs(manager));
|
||||
er->GetListenerManager(PR_FALSE, getter_AddRefs(manager));
|
||||
if (manager && manager->HasUnloadListeners()) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -5350,31 +5296,8 @@ nsDocument::DispatchEventToWindow(nsEvent *aEvent)
|
|||
if (!window)
|
||||
return;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
|
||||
// There's not always a prescontext that we can use for the event.
|
||||
// So, we force creation of a DOMEvent so that it can explicitly targeted.
|
||||
|
||||
nsCOMPtr<nsIEventListenerManager> lm;
|
||||
GetListenerManager(getter_AddRefs(lm));
|
||||
if (!lm)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> domEvt;
|
||||
lm->CreateEvent(nsnull, aEvent, EmptyString(), getter_AddRefs(domEvt));
|
||||
if (!domEvt)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privEvt = do_QueryInterface(domEvt);
|
||||
NS_ASSERTION(privEvt, "DOM Event objects must implement nsIPrivateDOMEvent");
|
||||
|
||||
privEvt->SetTarget(this);
|
||||
|
||||
nsIDOMEvent *domEvtPtr = domEvt;
|
||||
window->HandleDOMEvent(nsnull, aEvent, &domEvtPtr, NS_EVENT_FLAG_INIT,
|
||||
&status);
|
||||
|
||||
NS_ASSERTION(domEvtPtr == domEvt, "event modified during dipatch");
|
||||
aEvent->target = NS_STATIC_CAST(nsIDocument*, this);
|
||||
nsEventDispatcher::Dispatch(window, nsnull, aEvent);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -514,11 +514,6 @@ public:
|
|||
nsAString& Standalone);
|
||||
virtual PRBool IsScriptEnabled();
|
||||
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
|
||||
virtual void OnPageShow(PRBool aPersisted);
|
||||
virtual void OnPageHide(PRBool aPersisted);
|
||||
|
||||
|
@ -530,6 +525,15 @@ public:
|
|||
PRBool aNotify);
|
||||
virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult GetEventListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult) {
|
||||
return GetListenerManager(aCreateIfNotFound, aResult);
|
||||
};
|
||||
|
||||
// nsIRadioGroupContainer
|
||||
NS_IMETHOD WalkRadioGroup(const nsAString& aName,
|
||||
|
@ -606,7 +610,8 @@ public:
|
|||
const nsIID& aIID);
|
||||
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID);
|
||||
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
|
||||
NS_IMETHOD GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult);
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent);
|
||||
NS_IMETHOD GetSystemEventGroup(nsIDOMEventGroup** aGroup);
|
||||
|
||||
|
|
|
@ -153,14 +153,6 @@ public:
|
|||
{
|
||||
return nsnull;
|
||||
}
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags, nsEventStatus* aEventStatus)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEventStatus);
|
||||
*aEventStatus = nsEventStatus_eIgnore;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
protected:
|
||||
nsresult Clone(nsINodeInfo *aNodeInfo, PRBool aDeep,
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "nsLayoutAtoms.h"
|
||||
#include "nsIDOMUserDataHandler.h"
|
||||
#include "nsChangeHint.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
#include "pldhash.h"
|
||||
#include "prprf.h"
|
||||
|
@ -542,10 +543,19 @@ nsGenericDOMDataNode::ReplaceData(PRUint32 aOffset, PRUint32 aCount,
|
|||
//----------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
nsGenericDOMDataNode::GetListenerManager(nsIEventListenerManager **aResult)
|
||||
nsGenericDOMDataNode::GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult)
|
||||
{
|
||||
// No need to call nsContentUtils::GetListenerManager if we're sure that
|
||||
// there is no event listener manager.
|
||||
if (!aCreateIfNotFound && !CouldHaveEventListenerManager()) {
|
||||
*aResult = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool created;
|
||||
nsresult rv = nsContentUtils::GetListenerManager(this, aResult, &created);
|
||||
nsresult rv = nsContentUtils::GetListenerManager(this, aCreateIfNotFound,
|
||||
aResult, &created);
|
||||
if (NS_SUCCEEDED(rv) && created) {
|
||||
SetHasEventListenerManager();
|
||||
}
|
||||
|
@ -802,104 +812,32 @@ nsGenericDOMDataNode::GetAttrCount() const
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsGenericDOMDataNode::HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsGenericDOMDataNode::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
// Make sure to tell the event that dispatch has started.
|
||||
NS_MARK_EVENT_DISPATCH_STARTED(aEvent);
|
||||
|
||||
nsresult ret = NS_OK;
|
||||
nsIDOMEvent* domEvent = nsnull;
|
||||
|
||||
PRBool externalDOMEvent = PR_FALSE;
|
||||
|
||||
if (NS_EVENT_FLAG_INIT & aFlags) {
|
||||
if (!aDOMEvent) {
|
||||
aDOMEvent = &domEvent;
|
||||
} else {
|
||||
externalDOMEvent = PR_TRUE;
|
||||
}
|
||||
|
||||
aEvent->flags |= aFlags;
|
||||
aFlags &= ~(NS_EVENT_FLAG_CANT_BUBBLE | NS_EVENT_FLAG_CANT_CANCEL);
|
||||
aFlags |= NS_EVENT_FLAG_BUBBLE | NS_EVENT_FLAG_CAPTURE;
|
||||
//FIXME! Handle event retargeting, bug 329122.
|
||||
aVisitor.mCanHandle = PR_TRUE;
|
||||
aVisitor.mParentTarget = GetParent();
|
||||
if (!aVisitor.mParentTarget) {
|
||||
aVisitor.mParentTarget = GetCurrentDoc();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIContent *parent = GetParent();
|
||||
nsresult
|
||||
nsGenericDOMDataNode::PostHandleEvent(nsEventChainPostVisitor& /*aVisitor*/)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//Capturing stage evaluation
|
||||
if (NS_EVENT_FLAG_CAPTURE & aFlags) {
|
||||
//Initiate capturing phase. Special case first call to document
|
||||
if (parent) {
|
||||
parent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
|
||||
aFlags & NS_EVENT_CAPTURE_MASK, aEventStatus);
|
||||
}
|
||||
else {
|
||||
nsIDocument *document = GetCurrentDoc();
|
||||
if (document) {
|
||||
document->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
|
||||
aFlags & NS_EVENT_CAPTURE_MASK,
|
||||
aEventStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Weak pointer, which is fine since the hash table owns the
|
||||
// listener manager
|
||||
nsIEventListenerManager *listener_manager = nsnull;
|
||||
if (CouldHaveEventListenerManager()) {
|
||||
listener_manager = nsContentUtils::LookupListenerManager(this);
|
||||
}
|
||||
|
||||
//Local handling stage
|
||||
//Check for null ELM, check if we're a non-bubbling event in the bubbling state (bubbling state
|
||||
//is indicated by the presence of the NS_EVENT_FLAG_BUBBLE flag and not the NS_EVENT_FLAG_INIT), and check
|
||||
//if we're a no content dispatch event
|
||||
if (listener_manager &&
|
||||
!(NS_EVENT_FLAG_CANT_BUBBLE & aEvent->flags && NS_EVENT_FLAG_BUBBLE & aFlags && !(NS_EVENT_FLAG_INIT & aFlags)) &&
|
||||
!(aEvent->flags & NS_EVENT_FLAG_NO_CONTENT_DISPATCH)) {
|
||||
aEvent->flags |= aFlags;
|
||||
listener_manager->HandleEvent(aPresContext, aEvent, aDOMEvent, nsnull,
|
||||
aFlags, aEventStatus);
|
||||
aEvent->flags &= ~aFlags;
|
||||
}
|
||||
|
||||
//Bubbling stage
|
||||
if (NS_EVENT_FLAG_BUBBLE & aFlags && parent) {
|
||||
ret = parent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
|
||||
aFlags & NS_EVENT_BUBBLE_MASK, aEventStatus);
|
||||
}
|
||||
|
||||
if (NS_EVENT_FLAG_INIT & aFlags) {
|
||||
// We're leaving the DOM event loop so if we created a DOM event,
|
||||
// release here.
|
||||
|
||||
if (!externalDOMEvent && *aDOMEvent) {
|
||||
if (0 != (*aDOMEvent)->Release()) {
|
||||
// Okay, so someone in the DOM loop (a listener, JS object)
|
||||
// still has a ref to the DOM Event but the internal data
|
||||
// hasn't been malloc'd. Force a copy of the data here so the
|
||||
// DOM Event is still valid.
|
||||
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent =
|
||||
do_QueryInterface(*aDOMEvent);
|
||||
|
||||
if (privateEvent) {
|
||||
privateEvent->DuplicatePrivateData();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aDOMEvent = nsnull;
|
||||
|
||||
// Now that we're done with this event, remove the flag that says
|
||||
// we're in the process of dispatching this event.
|
||||
NS_MARK_EVENT_DISPATCH_DONE(aEvent);
|
||||
}
|
||||
|
||||
return ret;
|
||||
nsresult
|
||||
nsGenericDOMDataNode::DispatchDOMEvent(nsEvent* aEvent,
|
||||
nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus)
|
||||
{
|
||||
return nsEventDispatcher::DispatchDOMEvent(NS_STATIC_CAST(nsINode*, this),
|
||||
aEvent, aDOMEvent,
|
||||
aPresContext, aEventStatus);
|
||||
}
|
||||
|
||||
PRUint32
|
||||
|
@ -1139,9 +1077,7 @@ nsGenericDOMDataNode::SetText(const PRUnichar* aBuffer,
|
|||
do_GetAtom(Substring(aBuffer, aBuffer + aLength));
|
||||
}
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
HandleDOMEvent(nsnull, &mutation, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(this, nsnull, &mutation);
|
||||
}
|
||||
|
||||
// Trigger a reflow
|
||||
|
@ -1185,9 +1121,7 @@ nsGenericDOMDataNode::SetText(const char* aBuffer, PRUint32 aLength,
|
|||
do_GetAtom(Substring(aBuffer, aBuffer + aLength));
|
||||
}
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
HandleDOMEvent(nsnull, &mutation, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(this, nsnull, &mutation);
|
||||
}
|
||||
|
||||
// Trigger a reflow
|
||||
|
@ -1222,9 +1156,7 @@ nsGenericDOMDataNode::SetText(const nsAString& aStr,
|
|||
mutation.mPrevAttrValue = oldValue;
|
||||
if (!aStr.IsEmpty())
|
||||
mutation.mNewAttrValue = do_GetAtom(aStr);
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
HandleDOMEvent(nsnull, &mutation, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(this, nsnull, &mutation);
|
||||
}
|
||||
|
||||
// Trigger a reflow
|
||||
|
|
|
@ -186,6 +186,15 @@ public:
|
|||
PRBool aNotify);
|
||||
virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult GetEventListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult) {
|
||||
return GetListenerManager(aCreateIfNotFound, aResult);
|
||||
}
|
||||
virtual nsresult SetProperty(nsIAtom *aPropertyName,
|
||||
void *aValue,
|
||||
NSPropertyDtorFunc aDtor);
|
||||
|
@ -220,10 +229,7 @@ public:
|
|||
virtual void List(FILE* out, PRInt32 aIndent) const;
|
||||
virtual void DumpContent(FILE* out, PRInt32 aIndent, PRBool aDumpAll) const;
|
||||
#endif
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
|
||||
virtual nsresult RangeAdd(nsIDOMRange* aRange);
|
||||
virtual void RangeRemove(nsIDOMRange* aRange);
|
||||
virtual const nsVoidArray *GetRangeList() const;
|
||||
|
@ -231,7 +237,8 @@ public:
|
|||
virtual nsIContent *GetBindingParent() const;
|
||||
virtual PRBool IsContentOfType(PRUint32 aFlags) const;
|
||||
|
||||
virtual nsresult GetListenerManager(nsIEventListenerManager **aResult);
|
||||
virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult);
|
||||
virtual already_AddRefed<nsIURI> GetBaseURI() const;
|
||||
|
||||
virtual PRBool MayHaveFrame() const;
|
||||
|
|
|
@ -107,6 +107,7 @@
|
|||
#include "nsIDOMNSFeatureFactory.h"
|
||||
#include "nsIDOMDocumentType.h"
|
||||
#include "nsIDOMUserDataHandler.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
#ifdef MOZ_SVG
|
||||
PRBool NS_SVG_TestFeature(const nsAString &fstr);
|
||||
|
@ -598,7 +599,8 @@ nsresult
|
|||
nsDOMEventRTTearoff::GetEventReceiver(nsIDOMEventReceiver **aReceiver)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> listener_manager;
|
||||
nsresult rv = mContent->GetListenerManager(getter_AddRefs(listener_manager));
|
||||
nsresult rv =
|
||||
mContent->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return CallQueryInterface(listener_manager, aReceiver);
|
||||
|
@ -608,7 +610,8 @@ nsresult
|
|||
nsDOMEventRTTearoff::GetDOM3EventTarget(nsIDOM3EventTarget **aTarget)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> listener_manager;
|
||||
nsresult rv = mContent->GetListenerManager(getter_AddRefs(listener_manager));
|
||||
nsresult rv =
|
||||
mContent->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return CallQueryInterface(listener_manager, aTarget);
|
||||
|
@ -637,9 +640,10 @@ nsDOMEventRTTearoff::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMEventRTTearoff::GetListenerManager(nsIEventListenerManager** aResult)
|
||||
nsDOMEventRTTearoff::GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult)
|
||||
{
|
||||
return mContent->GetListenerManager(aResult);
|
||||
return mContent->GetListenerManager(aCreateIfNotFound, aResult);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -656,7 +660,7 @@ NS_IMETHODIMP
|
|||
nsDOMEventRTTearoff::GetSystemEventGroup(nsIDOMEventGroup **aGroup)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
GetListenerManager(getter_AddRefs(manager));
|
||||
GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
||||
|
||||
if (!manager) {
|
||||
return NS_ERROR_FAILURE;
|
||||
|
@ -747,7 +751,8 @@ nsDOMEventRTTearoff::AddEventListener(const nsAString& aType,
|
|||
PRBool aWantsUntrusted)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> listener_manager;
|
||||
nsresult rv = mContent->GetListenerManager(getter_AddRefs(listener_manager));
|
||||
nsresult rv =
|
||||
mContent->GetListenerManager(PR_TRUE, getter_AddRefs(listener_manager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
||||
|
@ -826,10 +831,15 @@ nsGenericElement::~nsGenericElement()
|
|||
|
||||
if (HasEventListenerManager()) {
|
||||
#ifdef DEBUG
|
||||
if (!nsContentUtils::LookupListenerManager(this) &&
|
||||
nsContentUtils::IsInitialized()) {
|
||||
NS_ERROR("Huh, our bit says we have a listener manager list, "
|
||||
"but there's nothing in the hash!?!!");
|
||||
if (nsContentUtils::IsInitialized()) {
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
PRBool created;
|
||||
nsContentUtils::GetListenerManager(this, PR_FALSE,
|
||||
getter_AddRefs(manager), &created);
|
||||
if (!manager) {
|
||||
NS_ERROR("Huh, our bit says we have a listener manager list, "
|
||||
"but there's nothing in the hash!?!!");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1870,239 +1880,58 @@ nsGenericElement::SetNativeAnonymous(PRBool aAnonymous)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsGenericElement::HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsGenericElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
// Make sure to tell the event that dispatch has started.
|
||||
NS_MARK_EVENT_DISPATCH_STARTED(aEvent);
|
||||
|
||||
nsresult ret = NS_OK;
|
||||
PRBool retarget = PR_FALSE;
|
||||
PRBool externalDOMEvent = PR_FALSE;
|
||||
nsCOMPtr<nsIDOMEventTarget> oldTarget;
|
||||
|
||||
nsIDOMEvent* domEvent = nsnull;
|
||||
if (NS_EVENT_FLAG_INIT & aFlags) {
|
||||
if (aDOMEvent) {
|
||||
if (*aDOMEvent) {
|
||||
externalDOMEvent = PR_TRUE;
|
||||
}
|
||||
} else {
|
||||
aDOMEvent = &domEvent;
|
||||
}
|
||||
aEvent->flags |= aFlags;
|
||||
aFlags &= ~(NS_EVENT_FLAG_CANT_BUBBLE | NS_EVENT_FLAG_CANT_CANCEL);
|
||||
aFlags |= NS_EVENT_FLAG_BUBBLE | NS_EVENT_FLAG_CAPTURE;
|
||||
}
|
||||
|
||||
// Find out whether we're anonymous.
|
||||
//FIXME! Document how this event retargeting works, Bug 329124.
|
||||
aVisitor.mCanHandle = PR_TRUE;
|
||||
nsCOMPtr<nsIContent> parent = GetParent();
|
||||
if (IsNativeAnonymous()) {
|
||||
retarget = PR_TRUE;
|
||||
} else {
|
||||
nsIContent* parent = GetParent();
|
||||
if (parent) {
|
||||
if (*aDOMEvent) {
|
||||
(*aDOMEvent)->GetTarget(getter_AddRefs(oldTarget));
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(oldTarget));
|
||||
if (content && content->GetBindingParent() == parent)
|
||||
retarget = PR_TRUE;
|
||||
} else if (GetBindingParent() == parent) {
|
||||
retarget = PR_TRUE;
|
||||
}
|
||||
aVisitor.mEventTargetAtParent = parent;
|
||||
} else if (parent) {
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(aVisitor.mEvent->target));
|
||||
if (content && content->GetBindingParent() == parent) {
|
||||
aVisitor.mEventTargetAtParent = parent;
|
||||
}
|
||||
}
|
||||
|
||||
// check for an anonymous parent
|
||||
nsCOMPtr<nsIContent> parent;
|
||||
// XXX XBL2/sXBL issue
|
||||
nsIDocument* ownerDoc = GetOwnerDoc();
|
||||
if (ownerDoc) {
|
||||
ownerDoc->BindingManager()->GetInsertionParent(this,
|
||||
getter_AddRefs(parent));
|
||||
}
|
||||
if (!parent) {
|
||||
// if we didn't find an anonymous parent, use the explicit one,
|
||||
// whether it's null or not...
|
||||
parent = GetParent();
|
||||
}
|
||||
|
||||
if (retarget || (parent.get() != GetParent())) {
|
||||
if (!*aDOMEvent) {
|
||||
// We haven't made a DOMEvent yet. Force making one now.
|
||||
nsCOMPtr<nsIEventListenerManager> listenerManager;
|
||||
if (NS_FAILED(ret = GetListenerManager(getter_AddRefs(listenerManager)))) {
|
||||
return ret;
|
||||
}
|
||||
if (NS_FAILED(ret = listenerManager->CreateEvent(aPresContext, aEvent,
|
||||
EmptyString(), aDOMEvent)))
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!*aDOMEvent) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(*aDOMEvent);
|
||||
if (!privateEvent) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
(*aDOMEvent)->GetTarget(getter_AddRefs(oldTarget));
|
||||
|
||||
PRBool hasOriginal;
|
||||
privateEvent->HasOriginalTarget(&hasOriginal);
|
||||
|
||||
if (!hasOriginal)
|
||||
privateEvent->SetOriginalTarget(oldTarget);
|
||||
|
||||
if (retarget) {
|
||||
nsCOMPtr<nsIDOMEventTarget> target = do_QueryInterface(GetParent());
|
||||
privateEvent->SetTarget(target);
|
||||
nsCOMPtr<nsIContent> insertionParent;
|
||||
ownerDoc->BindingManager()->
|
||||
GetInsertionParent(this, getter_AddRefs(insertionParent));
|
||||
NS_ASSERTION(!(aVisitor.mEventTargetAtParent && insertionParent &&
|
||||
aVisitor.mEventTargetAtParent != insertionParent),
|
||||
"Retargeting and having insertion parent!");
|
||||
if (insertionParent) {
|
||||
parent.swap(insertionParent);
|
||||
}
|
||||
}
|
||||
|
||||
//Capturing stage evaluation
|
||||
if (NS_EVENT_FLAG_CAPTURE & aFlags &&
|
||||
aEvent->message != NS_PAGE_LOAD &&
|
||||
aEvent->message != NS_SCRIPT_LOAD &&
|
||||
aEvent->message != NS_IMAGE_LOAD &&
|
||||
aEvent->message != NS_IMAGE_ERROR &&
|
||||
aEvent->message != NS_SCROLL_EVENT) {
|
||||
//Initiate capturing phase. Special case first call to document
|
||||
if (parent) {
|
||||
parent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
|
||||
aFlags & NS_EVENT_CAPTURE_MASK,
|
||||
aEventStatus);
|
||||
} else {
|
||||
nsIDocument* document = GetCurrentDoc();
|
||||
if (document) {
|
||||
ret = document->HandleDOMEvent(aPresContext, aEvent,
|
||||
aDOMEvent,
|
||||
aFlags & NS_EVENT_CAPTURE_MASK,
|
||||
aEventStatus);
|
||||
}
|
||||
}
|
||||
if (parent) {
|
||||
aVisitor.mParentTarget = parent;
|
||||
} else {
|
||||
aVisitor.mParentTarget = GetCurrentDoc();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (retarget) {
|
||||
// The event originated beneath us, and we performed a retargeting.
|
||||
// We need to restore the original target of the event.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(*aDOMEvent);
|
||||
if (privateEvent)
|
||||
privateEvent->SetTarget(oldTarget);
|
||||
}
|
||||
nsresult
|
||||
nsGenericElement::PostHandleEvent(nsEventChainPostVisitor& /*aVisitor*/)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Weak pointer, which is fine since the hash table owns the
|
||||
// listener manager
|
||||
nsIEventListenerManager *lm = nsnull;
|
||||
|
||||
if (HasEventListenerManager()) {
|
||||
lm = nsContentUtils::LookupListenerManager(this);
|
||||
if (!lm) {
|
||||
#ifdef DEBUG
|
||||
if (nsContentUtils::IsInitialized()) {
|
||||
NS_ERROR("Huh, our bit says we have an event listener manager, but "
|
||||
"there's nothing in the hash!?!!");
|
||||
}
|
||||
#endif
|
||||
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
}
|
||||
|
||||
//Local handling stage
|
||||
if (lm &&
|
||||
!(NS_EVENT_FLAG_CANT_BUBBLE & aEvent->flags &&
|
||||
NS_EVENT_FLAG_BUBBLE & aFlags && !(NS_EVENT_FLAG_INIT & aFlags)) &&
|
||||
!(aEvent->flags & NS_EVENT_FLAG_NO_CONTENT_DISPATCH)) {
|
||||
aEvent->flags |= aFlags;
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> curTarg =
|
||||
do_QueryInterface(NS_STATIC_CAST(nsIXMLContent *, this));
|
||||
|
||||
lm->HandleEvent(aPresContext, aEvent, aDOMEvent, curTarg, aFlags,
|
||||
aEventStatus);
|
||||
|
||||
aEvent->flags &= ~aFlags;
|
||||
}
|
||||
|
||||
if (retarget) {
|
||||
// The event originated beneath us, and we need to perform a
|
||||
// retargeting.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(*aDOMEvent);
|
||||
if (privateEvent) {
|
||||
nsCOMPtr<nsIDOMEventTarget> parentTarget(do_QueryInterface(GetParent()));
|
||||
privateEvent->SetTarget(parentTarget);
|
||||
}
|
||||
}
|
||||
|
||||
//Bubbling stage
|
||||
if (NS_EVENT_FLAG_BUBBLE & aFlags && IsInDoc() &&
|
||||
aEvent->message != NS_PAGE_LOAD && aEvent->message != NS_SCRIPT_LOAD &&
|
||||
aEvent->message != NS_IMAGE_ERROR && aEvent->message != NS_IMAGE_LOAD &&
|
||||
// scroll events fired at elements don't bubble (although scroll events
|
||||
// fired at documents do, to the window)
|
||||
aEvent->message != NS_SCROLL_EVENT) {
|
||||
if (parent) {
|
||||
// If there's a parent we pass the event to the parent...
|
||||
|
||||
ret = parent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
|
||||
aFlags & NS_EVENT_BUBBLE_MASK,
|
||||
aEventStatus);
|
||||
} else {
|
||||
// If there's no parent but there is a document (i.e. this is
|
||||
// the root node) we pass the event to the document...
|
||||
nsIDocument* document = GetCurrentDoc();
|
||||
if (document) {
|
||||
ret = document->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
|
||||
aFlags & NS_EVENT_BUBBLE_MASK,
|
||||
aEventStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (retarget) {
|
||||
// The event originated beneath us, and we performed a
|
||||
// retargeting. We need to restore the original target of the
|
||||
// event.
|
||||
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(*aDOMEvent);
|
||||
if (privateEvent)
|
||||
privateEvent->SetTarget(oldTarget);
|
||||
}
|
||||
|
||||
if (NS_EVENT_FLAG_INIT & aFlags) {
|
||||
// We're leaving the DOM event loop so if we created a DOM event,
|
||||
// release here. If externalDOMEvent is set the event was passed
|
||||
// in and we don't own it
|
||||
|
||||
if (*aDOMEvent && !externalDOMEvent) {
|
||||
nsrefcnt rc;
|
||||
NS_RELEASE2(*aDOMEvent, rc);
|
||||
if (0 != rc) {
|
||||
// Okay, so someone in the DOM loop (a listener, JS object)
|
||||
// still has a ref to the DOM Event but the internal data
|
||||
// hasn't been malloc'd. Force a copy of the data here so the
|
||||
// DOM Event is still valid.
|
||||
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent =
|
||||
do_QueryInterface(*aDOMEvent);
|
||||
|
||||
if (privateEvent) {
|
||||
privateEvent->DuplicatePrivateData();
|
||||
}
|
||||
}
|
||||
|
||||
aDOMEvent = nsnull;
|
||||
}
|
||||
|
||||
// Now that we're done with this event, remove the flag that says
|
||||
// we're in the process of dispatching this event.
|
||||
NS_MARK_EVENT_DISPATCH_DONE(aEvent);
|
||||
}
|
||||
|
||||
return ret;
|
||||
nsresult
|
||||
nsGenericElement::DispatchDOMEvent(nsEvent* aEvent,
|
||||
nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus)
|
||||
{
|
||||
return nsEventDispatcher::DispatchDOMEvent(NS_STATIC_CAST(nsIContent*, this),
|
||||
aEvent, aDOMEvent,
|
||||
aPresContext, aEventStatus);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -2397,10 +2226,20 @@ nsGenericElement::IsContentOfType(PRUint32 aFlags) const
|
|||
//----------------------------------------------------------------------
|
||||
|
||||
nsresult
|
||||
nsGenericElement::GetListenerManager(nsIEventListenerManager **aResult)
|
||||
nsGenericElement::GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult)
|
||||
{
|
||||
// No need to call nsContentUtils::GetListenerManager if we don't have
|
||||
// an event listener manager.
|
||||
if (!aCreateIfNotFound && !HasEventListenerManager()) {
|
||||
*aResult = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool created;
|
||||
nsresult rv = nsContentUtils::GetListenerManager(this, aResult, &created);
|
||||
nsresult rv =
|
||||
nsContentUtils::GetListenerManager(this, aCreateIfNotFound, aResult,
|
||||
&created);
|
||||
if (NS_SUCCEEDED(rv) && created) {
|
||||
SetFlags(GENERIC_ELEMENT_HAS_LISTENERMANAGER);
|
||||
}
|
||||
|
@ -2495,9 +2334,7 @@ nsGenericElement::doInsertChildAt(nsIContent* aKid, PRUint32 aIndex,
|
|||
HasMutationListeners(aParent, NS_EVENT_BITS_MUTATION_NODEINSERTED)) {
|
||||
nsMutationEvent mutation(PR_TRUE, NS_MUTATION_NODEINSERTED, aKid);
|
||||
mutation.mRelatedNode = do_QueryInterface(aParent);
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
aKid->HandleDOMEvent(nsnull, &mutation, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(aKid, nsnull, &mutation);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2559,10 +2396,7 @@ nsGenericElement::doRemoveChildAt(PRUint32 aIndex, PRBool aNotify,
|
|||
if (hasListeners) {
|
||||
nsMutationEvent mutation(PR_TRUE, NS_MUTATION_NODEREMOVED, aKid);
|
||||
mutation.mRelatedNode = do_QueryInterface(aParent);
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
aKid->HandleDOMEvent(nsnull, &mutation, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(aKid, nsnull, &mutation);
|
||||
}
|
||||
|
||||
// Someone may have removed the kid while that event was processing...
|
||||
|
@ -3354,6 +3188,7 @@ nsGenericElement::doRemoveChild(nsIDOMNode* aOldChild,
|
|||
NS_INTERFACE_MAP_BEGIN(nsGenericElement)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIContent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMGCParticipant)
|
||||
NS_INTERFACE_MAP_ENTRY(nsINode)
|
||||
NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOM3Node, new nsNode3Tearoff(this))
|
||||
NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMEventReceiver,
|
||||
nsDOMEventRTTearoff::Create(this))
|
||||
|
@ -3363,7 +3198,6 @@ NS_INTERFACE_MAP_BEGIN(nsGenericElement)
|
|||
nsDOMEventRTTearoff::Create(this))
|
||||
NS_INTERFACE_MAP_ENTRY_TEAROFF(nsIDOMNSEventTarget,
|
||||
nsDOMEventRTTearoff::Create(this))
|
||||
NS_INTERFACE_MAP_ENTRY(nsINode)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContent)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
@ -3566,7 +3400,7 @@ NodeHasMutationListeners(nsISupports* aNode)
|
|||
nsCOMPtr<nsIDOMEventReceiver> rec(do_QueryInterface(aNode));
|
||||
if (rec) {
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
rec->GetListenerManager(getter_AddRefs(manager));
|
||||
rec->GetListenerManager(PR_FALSE, getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
PRBool hasMutationListeners = PR_FALSE;
|
||||
manager->HasMutationListeners(&hasMutationListeners);
|
||||
|
@ -3746,9 +3580,7 @@ nsGenericElement::SetAttrAndNotify(PRInt32 aNamespaceID,
|
|||
mutation.mPrevAttrValue = do_GetAtom(aOldValue);
|
||||
}
|
||||
mutation.mAttrChange = modType;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
HandleDOMEvent(nsnull, &mutation, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(this, nsnull, &mutation);
|
||||
}
|
||||
|
||||
if (aNotify) {
|
||||
|
@ -3796,7 +3628,7 @@ nsGenericElement::GetEventListenerManagerForAttr(nsIEventListenerManager** aMana
|
|||
nsISupports** aTarget,
|
||||
PRBool* aDefer)
|
||||
{
|
||||
nsresult rv = GetListenerManager(aManager);
|
||||
nsresult rv = GetListenerManager(PR_TRUE, aManager);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_ADDREF(*aTarget = NS_STATIC_CAST(nsIContent*, this));
|
||||
}
|
||||
|
@ -3947,9 +3779,7 @@ nsGenericElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
mutation.mPrevAttrValue = do_GetAtom(value);
|
||||
mutation.mAttrChange = nsIDOMMutationEvent::REMOVAL;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
HandleDOMEvent(nsnull, &mutation, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(this, nsnull, &mutation);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -267,7 +267,8 @@ public:
|
|||
const nsIID& aIID);
|
||||
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID);
|
||||
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aResult);
|
||||
NS_IMETHOD GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult);
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent);
|
||||
NS_IMETHOD GetSystemEventGroup(nsIDOMEventGroup** aGroup);
|
||||
|
||||
|
@ -313,6 +314,15 @@ public:
|
|||
PRBool aNotify);
|
||||
virtual nsresult AppendChildTo(nsIContent* aKid, PRBool aNotify);
|
||||
virtual nsresult RemoveChildAt(PRUint32 aIndex, PRBool aNotify);
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult GetEventListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult) {
|
||||
return GetListenerManager(aCreateIfNotFound, aResult);
|
||||
}
|
||||
virtual nsresult SetProperty(nsIAtom *aPropertyName,
|
||||
void *aValue,
|
||||
NSPropertyDtorFunc aDtor);
|
||||
|
@ -355,15 +365,11 @@ public:
|
|||
virtual nsresult RangeAdd(nsIDOMRange* aRange);
|
||||
virtual void RangeRemove(nsIDOMRange* aRange);
|
||||
virtual const nsVoidArray *GetRangeList() const;
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual void SetFocus(nsPresContext* aContext);
|
||||
virtual nsIContent *GetBindingParent() const;
|
||||
virtual PRBool IsContentOfType(PRUint32 aFlags) const;
|
||||
virtual nsresult GetListenerManager(nsIEventListenerManager** aResult);
|
||||
virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult);
|
||||
virtual already_AddRefed<nsIURI> GetBaseURI() const;
|
||||
virtual void SetMayHaveFrame(PRBool aMayHaveFrame);
|
||||
virtual PRBool MayHaveFrame() const;
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
#include "nsContentUtils.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
#ifdef DEBUG_chb
|
||||
static void PrintReqURL(imgIRequest* req) {
|
||||
|
@ -742,7 +743,6 @@ PR_STATIC_CALLBACK(void*)
|
|||
HandleImagePLEvent(PLEvent* aEvent)
|
||||
{
|
||||
ImageEvent* evt = NS_STATIC_CAST(ImageEvent*, aEvent);
|
||||
nsEventStatus estatus = nsEventStatus_eIgnore;
|
||||
PRUint32 eventMsg;
|
||||
|
||||
if (evt->mMessage.EqualsLiteral("load")) {
|
||||
|
@ -752,8 +752,8 @@ HandleImagePLEvent(PLEvent* aEvent)
|
|||
}
|
||||
|
||||
nsEvent event(PR_TRUE, eventMsg);
|
||||
evt->mContent->HandleDOMEvent(evt->mPresContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &estatus);
|
||||
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
|
||||
nsEventDispatcher::Dispatch(evt->mContent, evt->mPresContext, &event);
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ EXPORTS = \
|
|||
nsIPrivateTextRange.h \
|
||||
nsIPrivateCompositionEvent.h \
|
||||
nsPLDOMEvent.h \
|
||||
nsEventDispatcher.h \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -0,0 +1,250 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla 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/MPL/
|
||||
*
|
||||
* 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
|
||||
* Olli Pettay (Olli.Pettay@helsinki.fi)
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifdef MOZILLA_INTERNAL_API
|
||||
#ifndef nsEventDispatcher_h___
|
||||
#define nsEventDispatcher_h___
|
||||
|
||||
#include "nsGUIEvent.h"
|
||||
|
||||
class nsIContent;
|
||||
class nsIDocument;
|
||||
class nsPresContext;
|
||||
class nsIChromeEventHandler;
|
||||
class nsIScriptGlobalObject;
|
||||
class nsEventTargetChainItem;
|
||||
|
||||
|
||||
/**
|
||||
* About event dispatching:
|
||||
* When either nsEventDispatcher::Dispatch or
|
||||
* nsEventDispatcher::DispatchDOMEvent is called an event target chain is
|
||||
* created. nsEventDispatcher creates the chain by calling PreHandleEvent
|
||||
* (or PreHandleChromeEvent) on each event target and the creation continues
|
||||
* until either the mCanHandle member of the nsEventChainPreVisitor object is
|
||||
* PR_FALSE or the mParentTarget does not point to a new target.
|
||||
* The event target chain is created on the stack.
|
||||
*
|
||||
* If the event needs retargeting, mEventTargetAtParent must be set in
|
||||
* PreHandleEvent or PreHandleChromeEvent.
|
||||
*
|
||||
* The capture, target and bubble phases of the event dispatch are handled
|
||||
* by iterating through the event target chain. Iteration happens twice,
|
||||
* first for the default event group and then for the system event group.
|
||||
* While dispatching the event for the system event group PostHandleEvent
|
||||
* (or PostHandleChromeEvent) is called right after calling event listener for
|
||||
* the current event target.
|
||||
*/
|
||||
|
||||
class nsEventChainVisitor {
|
||||
public:
|
||||
nsEventChainVisitor(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent* aDOMEvent,
|
||||
nsEventStatus aEventStatus = nsEventStatus_eIgnore)
|
||||
: mPresContext(aPresContext), mEvent(aEvent), mDOMEvent(aDOMEvent),
|
||||
mEventStatus(aEventStatus), mItemFlags(0)
|
||||
{}
|
||||
|
||||
/**
|
||||
* The prescontext, possibly nsnull.
|
||||
*/
|
||||
nsPresContext* const mPresContext;
|
||||
|
||||
/**
|
||||
* The nsEvent which is being dispatched. Never nsnull.
|
||||
*/
|
||||
nsEvent* const mEvent;
|
||||
|
||||
/**
|
||||
* The DOM Event assiciated with the mEvent. Possibly nsnull if a DOM Event
|
||||
* is not (yet) created.
|
||||
*/
|
||||
nsIDOMEvent* mDOMEvent;
|
||||
|
||||
/**
|
||||
* The status of the event.
|
||||
* @see nsEventStatus.h
|
||||
*/
|
||||
nsEventStatus mEventStatus;
|
||||
|
||||
/**
|
||||
* Bits for items in the event target chain.
|
||||
* Set in PreHandleEvent() and used in PostHandleEvent().
|
||||
*
|
||||
* @note These bits are different for each item in the event target chain.
|
||||
* It is up to the Pre/PostHandleEvent implementation to decide how to
|
||||
* use these bits.
|
||||
*
|
||||
* @note Using PRUint16 because that is used also in nsEventTargetChainItem.
|
||||
*/
|
||||
PRUint16 mItemFlags;
|
||||
|
||||
/**
|
||||
* Data for items in the event target chain.
|
||||
* Set in PreHandleEvent() and used in PostHandleEvent().
|
||||
*
|
||||
* @note This data is different for each item in the event target chain.
|
||||
* It is up to the Pre/PostHandleEvent implementation to decide how to
|
||||
* use this.
|
||||
*/
|
||||
nsCOMPtr<nsISupports> mItemData;
|
||||
};
|
||||
|
||||
class nsEventChainPreVisitor : public nsEventChainVisitor {
|
||||
public:
|
||||
nsEventChainPreVisitor(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent* aDOMEvent,
|
||||
nsEventStatus aEventStatus = nsEventStatus_eIgnore)
|
||||
: nsEventChainVisitor(aPresContext, aEvent, aDOMEvent, aEventStatus),
|
||||
mCanHandle(PR_TRUE), mParentIsChromeHandler(PR_FALSE),
|
||||
mForceContentDispatch(PR_FALSE) {}
|
||||
|
||||
void Reset() {
|
||||
mItemFlags = 0;
|
||||
mItemData = nsnull;
|
||||
mCanHandle = PR_TRUE;
|
||||
mParentIsChromeHandler = PR_FALSE;
|
||||
mForceContentDispatch = PR_FALSE;
|
||||
mParentTarget = nsnull;
|
||||
mEventTargetAtParent = nsnull;
|
||||
}
|
||||
|
||||
/**
|
||||
* Member that must be set in PreHandleEvent or PreHandleChromeEvent by event
|
||||
* targets. If set to false, indicates that this event target will not be
|
||||
* handling the event and construction of the event target chain is complete.
|
||||
* The target that sets mCanHandle to false is NOT included in the event target
|
||||
* chain.
|
||||
*/
|
||||
PRPackedBool mCanHandle;
|
||||
|
||||
/**
|
||||
* Member that is set to PR_TRUE in PreHandleEvent or PreHandleChromeEvent if
|
||||
* and only if mParentTarget is set to a chrome event handler.
|
||||
*/
|
||||
PRPackedBool mParentIsChromeHandler;
|
||||
|
||||
/**
|
||||
* If mForceContentDispatch is set to PR_TRUE,
|
||||
* content dispatching is not disabled for this event target.
|
||||
* FIXME! This is here for backward compatibility. Bug 329119
|
||||
*/
|
||||
PRPackedBool mForceContentDispatch;
|
||||
|
||||
/**
|
||||
* Parent item in the event target chain.
|
||||
*/
|
||||
nsCOMPtr<nsISupports> 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<nsISupports> mEventTargetAtParent;
|
||||
};
|
||||
|
||||
class nsEventChainPostVisitor : public nsEventChainVisitor {
|
||||
public:
|
||||
nsEventChainPostVisitor(nsEventChainVisitor& aOther)
|
||||
: nsEventChainVisitor(aOther.mPresContext, aOther.mEvent, aOther.mDOMEvent,
|
||||
aOther.mEventStatus)
|
||||
{}
|
||||
};
|
||||
|
||||
/**
|
||||
* If an nsDispatchingCallback object is passed to Dispatch,
|
||||
* its HandleEvent method is called after handling the default event group,
|
||||
* before handling the system event group.
|
||||
* This is used in nsPresShell.
|
||||
*/
|
||||
class nsDispatchingCallback {
|
||||
public:
|
||||
virtual void HandleEvent(nsEventChainPostVisitor& aVisitor) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* The generic class for event dispatching.
|
||||
* Must not be used outside Gecko!
|
||||
*/
|
||||
class nsEventDispatcher
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* aTarget should QI to nsINode, nsPIDOMWindow or nsIChromeEventHandler.
|
||||
* If the target of aEvent is set before calling this method, the target of
|
||||
* aEvent is used as the target (unless there is event
|
||||
* retargeting) and the originalTarget of the DOM Event.
|
||||
* aTarget is always used as the starting point for constructing the event
|
||||
* target chain, no matter what the value of aEvent->target is.
|
||||
* Neither aTarget nor aEvent is allowed to be nsnull.
|
||||
* @note Use this method when dispatching an nsEvent.
|
||||
*/
|
||||
static nsresult Dispatch(nsISupports* aTarget,
|
||||
nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent* aDOMEvent = nsnull,
|
||||
nsEventStatus* aEventStatus = nsnull,
|
||||
nsDispatchingCallback* aCallback = nsnull,
|
||||
PRBool aTargetIsChromeHandler = PR_FALSE);
|
||||
|
||||
/**
|
||||
* Dispatches an event.
|
||||
* If aDOMEvent is not nsnull, it is used for dispatching
|
||||
* (aEvent can then be nsnull) and (if aDOMEvent is not |trusted| already),
|
||||
* the |trusted| flag is set based on the UniversalBrowserWrite capability.
|
||||
* Otherwise this works like nsEventDispatcher::Dispatch.
|
||||
* @note Use this method when dispatching nsIDOMEvent.
|
||||
*/
|
||||
static nsresult DispatchDOMEvent(nsISupports* aTarget,
|
||||
nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus);
|
||||
|
||||
/**
|
||||
* Creates a DOM Event.
|
||||
*/
|
||||
static nsresult CreateEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
const nsAString& aEventType,
|
||||
nsIDOMEvent** aDOMEvent);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -52,10 +52,9 @@ struct JSObject;
|
|||
/*
|
||||
* Event listener manager interface.
|
||||
*/
|
||||
// dbb34a55-276d-4105-a26a-401bbb3e60c3
|
||||
#define NS_IEVENTLISTENERMANAGER_IID \
|
||||
{ 0xdbb34a55, 0x276d, 0x4105, \
|
||||
{ 0xa2, 0x6a, 0x40, 0x1b, 0xbb, 0x3e, 0x60, 0xc3 } }
|
||||
{ 0xdbd8fcee, 0xb93e, 0x42f3, \
|
||||
{ 0x9d, 0xe5, 0xf9, 0x90, 0xfc, 0x66, 0xb7, 0x5a } }
|
||||
|
||||
|
||||
class nsIEventListenerManager : public nsISupports {
|
||||
|
@ -139,14 +138,15 @@ public:
|
|||
NS_IMETHOD HandleEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
nsIDOMEventTarget* aCurrentTarget,
|
||||
nsISupports* 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).
|
||||
* Creates a DOM event.
|
||||
* Preferred way to create an event is to use either
|
||||
* nsEventDispatcher::CreateEvent or nsIDOMDocumentEvent::createEvent.
|
||||
* FIXME! Remove this method, Bug 329126.
|
||||
*/
|
||||
NS_IMETHOD CreateEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
|
|
|
@ -141,9 +141,6 @@ public:
|
|||
PRBool aHaveHotspot, float aHotspotX, float aHotspotY,
|
||||
nsIWidget* aWidget, PRBool aLockCursor) = 0;
|
||||
|
||||
//Method for centralized distribution of new DOM events
|
||||
NS_IMETHOD DispatchNewEvent(nsISupports* aTarget, nsIDOMEvent* aEvent, PRBool* aDefaultActionEnabled) = 0;
|
||||
|
||||
// Method for moving the focus forward/back.
|
||||
NS_IMETHOD ShiftFocus(PRBool aDirection, nsIContent* aStart)=0;
|
||||
};
|
||||
|
|
|
@ -81,6 +81,7 @@ CPPSRCS = \
|
|||
nsXMLEventsManager.cpp \
|
||||
nsXMLEventsElement.cpp \
|
||||
nsPLDOMEvent.cpp \
|
||||
nsEventDispatcher.cpp \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
|
|
|
@ -123,10 +123,7 @@ nsDOMEvent::nsDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent)
|
|||
mTmpRealOriginalTarget = mExplicitOriginalTarget;
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(mExplicitOriginalTarget);
|
||||
if (content) {
|
||||
if (content->IsNativeAnonymous()) {
|
||||
mExplicitOriginalTarget = nsnull;
|
||||
}
|
||||
if (content->GetBindingParent()) {
|
||||
if (content->IsNativeAnonymous() || content->GetBindingParent()) {
|
||||
mExplicitOriginalTarget = nsnull;
|
||||
}
|
||||
}
|
||||
|
@ -175,51 +172,20 @@ NS_METHOD nsDOMEvent::GetType(nsAString& aType)
|
|||
|
||||
NS_METHOD nsDOMEvent::GetTarget(nsIDOMEventTarget** aTarget)
|
||||
{
|
||||
if (nsnull != mTarget) {
|
||||
*aTarget = mTarget;
|
||||
NS_ADDREF(*aTarget);
|
||||
return NS_OK;
|
||||
if (mEvent->target) {
|
||||
return CallQueryInterface(mEvent->target, aTarget);
|
||||
}
|
||||
|
||||
*aTarget = nsnull;
|
||||
|
||||
nsCOMPtr<nsIContent> targetContent;
|
||||
|
||||
if (mPresContext) {
|
||||
mPresContext->EventStateManager()->
|
||||
GetEventTargetContent(mEvent, getter_AddRefs(targetContent));
|
||||
}
|
||||
|
||||
if (targetContent) {
|
||||
mTarget = do_QueryInterface(targetContent);
|
||||
if (mTarget) {
|
||||
*aTarget = mTarget;
|
||||
NS_ADDREF(*aTarget);
|
||||
}
|
||||
}
|
||||
else {
|
||||
//Always want a target. Use document if nothing else.
|
||||
nsIPresShell *presShell;
|
||||
if (mPresContext && (presShell = mPresContext->GetPresShell())) {
|
||||
nsIDocument *doc = presShell->GetDocument();
|
||||
if (doc) {
|
||||
mTarget = do_QueryInterface(doc);
|
||||
if (mTarget) {
|
||||
*aTarget = mTarget;
|
||||
NS_ADDREF(*aTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMEvent::GetCurrentTarget(nsIDOMEventTarget** aCurrentTarget)
|
||||
{
|
||||
*aCurrentTarget = mCurrentTarget;
|
||||
NS_IF_ADDREF(*aCurrentTarget);
|
||||
if (mEvent->currentTarget) {
|
||||
return CallQueryInterface(mEvent->currentTarget, aCurrentTarget);
|
||||
}
|
||||
*aCurrentTarget = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -274,18 +240,17 @@ nsDOMEvent::GetTmpRealOriginalTarget(nsIDOMEventTarget** aRealEventTarget)
|
|||
NS_IMETHODIMP
|
||||
nsDOMEvent::GetOriginalTarget(nsIDOMEventTarget** aOriginalTarget)
|
||||
{
|
||||
if (!mOriginalTarget)
|
||||
return GetTarget(aOriginalTarget);
|
||||
if (mEvent->originalTarget) {
|
||||
return CallQueryInterface(mEvent->originalTarget, aOriginalTarget);
|
||||
}
|
||||
|
||||
*aOriginalTarget = mOriginalTarget;
|
||||
NS_IF_ADDREF(*aOriginalTarget);
|
||||
return NS_OK;
|
||||
return GetTarget(aOriginalTarget);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMEvent::HasOriginalTarget(PRBool* aResult)
|
||||
{
|
||||
*aResult = (mOriginalTarget != nsnull);
|
||||
*aResult = !!(mEvent->originalTarget);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -539,9 +504,138 @@ nsDOMEvent::InitEvent(const nsAString& aEventTypeArg, PRBool aCanBubbleArg, PRBo
|
|||
|
||||
NS_METHOD nsDOMEvent::DuplicatePrivateData()
|
||||
{
|
||||
//XXX Write me!
|
||||
// FIXME! Simplify this method and make it somehow easily extendable,
|
||||
// Bug 329127
|
||||
|
||||
NS_ASSERTION(mEvent, "No nsEvent for nsDOMEvent duplication!");
|
||||
if (mEventIsInternal) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsEvent* newEvent = nsnull;
|
||||
PRUint32 msg = mEvent->message;
|
||||
|
||||
// Note, making all events untrusted. Otherwise scripts could perhaps reuse
|
||||
// trusted events.
|
||||
switch (mEvent->eventStructType) {
|
||||
case NS_EVENT:
|
||||
newEvent = new nsEvent(PR_FALSE, msg);
|
||||
break;
|
||||
case NS_GUI_EVENT:
|
||||
// Not copying widget, it is a weak reference.
|
||||
newEvent = new nsGUIEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_SIZE_EVENT:
|
||||
newEvent = new nsSizeEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_SIZEMODE_EVENT:
|
||||
newEvent = new nsSizeModeEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_ZLEVEL_EVENT:
|
||||
newEvent = new nsZLevelEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_PAINT_EVENT:
|
||||
newEvent = new nsPaintEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_SCROLLBAR_EVENT:
|
||||
newEvent = new nsScrollbarEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_INPUT_EVENT:
|
||||
newEvent = new nsInputEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_KEY_EVENT:
|
||||
newEvent = new nsKeyEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_MOUSE_EVENT:
|
||||
newEvent = new nsMouseEvent(PR_FALSE, msg, nsnull,
|
||||
((nsMouseEvent*) mEvent)->reason);
|
||||
break;
|
||||
case NS_MENU_EVENT:
|
||||
newEvent = new nsMenuEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_SCRIPT_ERROR_EVENT:
|
||||
newEvent = new nsScriptErrorEvent(PR_FALSE, msg);
|
||||
break;
|
||||
case NS_TEXT_EVENT:
|
||||
newEvent = new nsTextEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_COMPOSITION_EVENT:
|
||||
newEvent = new nsCompositionEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_RECONVERSION_EVENT:
|
||||
newEvent = new nsReconversionEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_MOUSE_SCROLL_EVENT:
|
||||
newEvent = new nsMouseScrollEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_SCROLLPORT_EVENT:
|
||||
newEvent = new nsScrollPortEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_MUTATION_EVENT:
|
||||
newEvent = new nsMutationEvent(PR_FALSE, msg);
|
||||
break;
|
||||
case NS_ACCESSIBLE_EVENT:
|
||||
newEvent = new nsAccessibleEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_FORM_EVENT:
|
||||
newEvent = new nsFormEvent(PR_FALSE, msg);
|
||||
break;
|
||||
case NS_FOCUS_EVENT:
|
||||
newEvent = new nsFocusEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_POPUP_EVENT:
|
||||
newEvent = new nsInputEvent(PR_FALSE, msg, nsnull);
|
||||
NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
|
||||
newEvent->eventStructType = NS_POPUP_EVENT;
|
||||
break;
|
||||
case NS_APPCOMMAND_EVENT:
|
||||
newEvent = new nsAppCommandEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_POPUPBLOCKED_EVENT:
|
||||
newEvent = new nsPopupBlockedEvent(PR_FALSE, msg);
|
||||
break;
|
||||
case NS_BEFORE_PAGE_UNLOAD_EVENT:
|
||||
newEvent = new nsBeforePageUnloadEvent(PR_FALSE, msg);
|
||||
break;
|
||||
case NS_UI_EVENT:
|
||||
newEvent = new nsUIEvent(PR_FALSE, msg, ((nsUIEvent*) mEvent)->detail);
|
||||
break;
|
||||
case NS_QUERYCARETRECT_EVENT:
|
||||
newEvent = new nsQueryCaretRectEvent(PR_FALSE, msg, nsnull);
|
||||
break;
|
||||
case NS_PAGETRANSITION_EVENT:
|
||||
newEvent =
|
||||
new nsPageTransitionEvent(PR_FALSE, msg,
|
||||
((nsPageTransitionEvent*) mEvent)->persisted);
|
||||
break;
|
||||
#ifdef MOZ_SVG
|
||||
case NS_SVG_EVENT:
|
||||
newEvent = new nsEvent(PR_FALSE, msg);
|
||||
NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
|
||||
newEvent->eventStructType = NS_SVG_EVENT;
|
||||
break;
|
||||
case NS_SVGZOOM_EVENT:
|
||||
newEvent = new nsGUIEvent(PR_FALSE, msg, nsnull);
|
||||
NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
|
||||
newEvent->eventStructType = NS_SVGZOOM_EVENT;
|
||||
break;
|
||||
#endif // MOZ_SVG
|
||||
default:
|
||||
NS_WARNING("Unknown event type!!!");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_ENSURE_TRUE(newEvent, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
newEvent->target = mEvent->target;
|
||||
newEvent->currentTarget = mEvent->currentTarget;
|
||||
newEvent->originalTarget = mEvent->originalTarget;
|
||||
newEvent->flags = mEvent->flags;
|
||||
|
||||
mEvent = newEvent;
|
||||
mPresContext = nsnull;
|
||||
mEventIsInternal = PR_TRUE;
|
||||
|
||||
//XXX And when you do, make sure to copy over the event target here, too!
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -556,7 +650,7 @@ NS_METHOD nsDOMEvent::SetTarget(nsIDOMEventTarget* aTarget)
|
|||
}
|
||||
#endif
|
||||
|
||||
mTarget = aTarget;
|
||||
mEvent->target = aTarget;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -571,7 +665,7 @@ NS_METHOD nsDOMEvent::SetCurrentTarget(nsIDOMEventTarget* aCurrentTarget)
|
|||
}
|
||||
#endif
|
||||
|
||||
mCurrentTarget = aCurrentTarget;
|
||||
mEvent->currentTarget = aCurrentTarget;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -586,7 +680,7 @@ NS_METHOD nsDOMEvent::SetOriginalTarget(nsIDOMEventTarget* aOriginalTarget)
|
|||
}
|
||||
#endif
|
||||
|
||||
mOriginalTarget = aOriginalTarget;
|
||||
mEvent->originalTarget = aOriginalTarget;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -170,16 +170,11 @@ protected:
|
|||
static const char* GetEventName(PRUint32 aEventType);
|
||||
already_AddRefed<nsIDOMEventTarget> GetTargetFromFrame();
|
||||
|
||||
nsEvent* mEvent;
|
||||
nsCOMPtr<nsPresContext> mPresContext;
|
||||
nsCOMPtr<nsIDOMEventTarget> mTarget;
|
||||
nsCOMPtr<nsIDOMEventTarget> mCurrentTarget;
|
||||
nsCOMPtr<nsIDOMEventTarget> mOriginalTarget;
|
||||
nsCOMPtr<nsIDOMEventTarget> mExplicitOriginalTarget;
|
||||
nsEvent* mEvent;
|
||||
nsCOMPtr<nsPresContext> mPresContext;
|
||||
nsCOMPtr<nsIDOMEventTarget> mTmpRealOriginalTarget;
|
||||
PRPackedBool mEventIsInternal;
|
||||
|
||||
void* mScriptObject;
|
||||
nsCOMPtr<nsIDOMEventTarget> mExplicitOriginalTarget;
|
||||
PRPackedBool mEventIsInternal;
|
||||
};
|
||||
|
||||
#define NS_FORWARD_TO_NSDOMEVENT \
|
||||
|
|
|
@ -0,0 +1,732 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla 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/MPL/
|
||||
*
|
||||
* 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
|
||||
* Olli Pettay (Olli.Pettay@helsinki.fi)
|
||||
* Portions created by the Initial Developer are Copyright (C) 2006
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsDOMEvent.h"
|
||||
#include "nsINode.h"
|
||||
#include "nsIChromeEventHandler.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIEventListenerManager.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsMutationEvent.h"
|
||||
|
||||
#define NS_TARGET_CHAIN_IS_NODE (1 << 0)
|
||||
#define NS_TARGET_CHAIN_IS_WINDOW (1 << 1)
|
||||
#define NS_TARGET_CHAIN_IS_CHROMEHANDLER (1 << 2)
|
||||
|
||||
#define NS_TARGET_CHAIN_FORCE_CONTENT_DISPATCH (1 << 3)
|
||||
|
||||
#define NS_TARGET_CHAIN_TYPE_MASK \
|
||||
(NS_TARGET_CHAIN_IS_NODE | NS_TARGET_CHAIN_IS_WINDOW | \
|
||||
NS_TARGET_CHAIN_IS_CHROMEHANDLER)
|
||||
|
||||
// nsEventTargetChainItem is a stack-allocated object represeting a
|
||||
// single item in the event target chain.
|
||||
class nsEventTargetChainItem
|
||||
{
|
||||
public:
|
||||
nsEventTargetChainItem(nsISupports* aTarget,
|
||||
PRBool aTargetIsChromeHandler,
|
||||
nsEventTargetChainItem* aChild = nsnull);
|
||||
|
||||
~nsEventTargetChainItem();
|
||||
|
||||
PRBool IsValid()
|
||||
{
|
||||
return !!(mFlags & NS_TARGET_CHAIN_TYPE_MASK);
|
||||
}
|
||||
|
||||
nsISupports* GetNewTarget()
|
||||
{
|
||||
return mNewTarget;
|
||||
}
|
||||
|
||||
void SetNewTarget(nsISupports* aNewTarget)
|
||||
{
|
||||
mNewTarget = aNewTarget;
|
||||
}
|
||||
|
||||
void SetForceContentDispatch(PRBool aForce) {
|
||||
if (aForce) {
|
||||
mFlags |= NS_TARGET_CHAIN_FORCE_CONTENT_DISPATCH;
|
||||
} else {
|
||||
mFlags &= ~NS_TARGET_CHAIN_FORCE_CONTENT_DISPATCH;
|
||||
}
|
||||
}
|
||||
|
||||
PRBool ForceContentDispatch() {
|
||||
return !!(mFlags & NS_TARGET_CHAIN_FORCE_CONTENT_DISPATCH);
|
||||
}
|
||||
|
||||
nsISupports* CurrentTarget();
|
||||
|
||||
already_AddRefed<nsIEventListenerManager> GetListenerManager(
|
||||
PRBool aCreateIfNotFound);
|
||||
|
||||
/**
|
||||
* Creates event target chain and calls HandleEventTargetChain.
|
||||
*/
|
||||
nsresult CreateChainAndHandleEvent(nsEventChainPreVisitor& aVisitor,
|
||||
nsDispatchingCallback* aCallback);
|
||||
|
||||
/**
|
||||
* Dispatches event through the event target chain.
|
||||
* Handles capture, target and bubble phases both in default
|
||||
* and system event group and calls also PostHandleEvent for each
|
||||
* item in the chain.
|
||||
*/
|
||||
nsresult HandleEventTargetChain(nsEventChainPostVisitor& aVisitor,
|
||||
PRUint32 aFlags,
|
||||
nsDispatchingCallback* aCallback);
|
||||
|
||||
/**
|
||||
* Resets aVisitor object and calls PreHandleEvent
|
||||
* (or PreHandleChromeEvent). Copies mItemFlags and mItemData to the
|
||||
* current nsEventTargetChainItem.
|
||||
*/
|
||||
nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
|
||||
/**
|
||||
* If the current item in the event target chain has an event listener
|
||||
* manager, this method sets the .currentTarget to the CurrentTarget()
|
||||
* and calls nsIEventListenerManager::HandleEvent().
|
||||
*/
|
||||
nsresult HandleEvent(nsEventChainPostVisitor& aVisitor, PRUint32 aFlags);
|
||||
|
||||
/**
|
||||
* Copies mItemFlags and mItemData to aVisitor and calls PostHandleEvent
|
||||
* (or PostHandleChromeEvent).
|
||||
*/
|
||||
nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
|
||||
|
||||
union {
|
||||
nsINode* mNode;
|
||||
nsPIDOMWindow* mWindow;
|
||||
nsIChromeEventHandler* mChromeHandler;
|
||||
};
|
||||
nsEventTargetChainItem* mChild;
|
||||
nsEventTargetChainItem* mParent;
|
||||
PRUint16 mFlags;
|
||||
PRUint16 mItemFlags;
|
||||
nsCOMPtr<nsISupports> mItemData;
|
||||
// Event retargeting must happen whenever mNewTarget is non-null.
|
||||
nsCOMPtr<nsISupports> mNewTarget;
|
||||
};
|
||||
|
||||
nsEventTargetChainItem::nsEventTargetChainItem(nsISupports* aTarget,
|
||||
PRBool aTargetIsChromeHandler,
|
||||
nsEventTargetChainItem* aChild)
|
||||
: mNode(nsnull), mChild(aChild), mParent(nsnull), mFlags(0), mItemFlags(0)
|
||||
{
|
||||
if (mChild) {
|
||||
mChild->mParent = this;
|
||||
}
|
||||
|
||||
// If the target is explicitly marked to be a chrome handler.
|
||||
if (aTargetIsChromeHandler) {
|
||||
nsCOMPtr<nsIChromeEventHandler> ceh = do_QueryInterface(aTarget);
|
||||
if (ceh) {
|
||||
ceh.swap(mChromeHandler);
|
||||
mFlags |= NS_TARGET_CHAIN_IS_CHROMEHANDLER;
|
||||
}
|
||||
} else {
|
||||
nsCOMPtr<nsINode> node = do_QueryInterface(aTarget);
|
||||
if (node) {
|
||||
node.swap(mNode);
|
||||
mFlags |= NS_TARGET_CHAIN_IS_NODE;
|
||||
} else {
|
||||
nsCOMPtr<nsPIDOMWindow> window =
|
||||
do_QueryInterface(aTarget);
|
||||
if (window) {
|
||||
window.swap(mWindow);
|
||||
mFlags |= NS_TARGET_CHAIN_IS_WINDOW;
|
||||
} else {
|
||||
nsCOMPtr<nsIChromeEventHandler> ceh = do_QueryInterface(aTarget);
|
||||
if (ceh) {
|
||||
ceh.swap(mChromeHandler);
|
||||
mFlags |= NS_TARGET_CHAIN_IS_CHROMEHANDLER;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NS_POSTCONDITION((mFlags & NS_TARGET_CHAIN_TYPE_MASK),
|
||||
"No event target in event target chain!");
|
||||
}
|
||||
|
||||
nsEventTargetChainItem::~nsEventTargetChainItem()
|
||||
{
|
||||
if (mChild) {
|
||||
mChild->mParent = nsnull;
|
||||
mChild = nsnull;
|
||||
}
|
||||
mParent = nsnull;
|
||||
|
||||
switch (mFlags & NS_TARGET_CHAIN_TYPE_MASK) {
|
||||
case NS_TARGET_CHAIN_IS_NODE:
|
||||
NS_RELEASE(mNode);
|
||||
break;
|
||||
case NS_TARGET_CHAIN_IS_WINDOW:
|
||||
NS_RELEASE(mWindow);
|
||||
break;
|
||||
case NS_TARGET_CHAIN_IS_CHROMEHANDLER:
|
||||
NS_RELEASE(mChromeHandler);
|
||||
break;
|
||||
default:
|
||||
NS_WARNING("Unknown type in event target chain!!!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
already_AddRefed<nsIEventListenerManager>
|
||||
nsEventTargetChainItem::GetListenerManager(PRBool aCreateIfNotFound)
|
||||
{
|
||||
nsIEventListenerManager* manager = nsnull;
|
||||
switch (mFlags & NS_TARGET_CHAIN_TYPE_MASK) {
|
||||
case NS_TARGET_CHAIN_IS_NODE:
|
||||
{
|
||||
mNode->GetEventListenerManager(aCreateIfNotFound, &manager);
|
||||
break;
|
||||
}
|
||||
case NS_TARGET_CHAIN_IS_WINDOW:
|
||||
{
|
||||
nsCOMPtr<nsIDOMEventReceiver> receiver(do_QueryInterface(mWindow));
|
||||
if (receiver) {
|
||||
receiver->GetListenerManager(aCreateIfNotFound, &manager);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case NS_TARGET_CHAIN_IS_CHROMEHANDLER:
|
||||
{
|
||||
nsCOMPtr<nsIDOMEventReceiver> receiver(do_QueryInterface(mChromeHandler));
|
||||
if (receiver) {
|
||||
receiver->GetListenerManager(aCreateIfNotFound, &manager);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
NS_WARNING("Unknown type in event target chain!!!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
nsISupports*
|
||||
nsEventTargetChainItem::CurrentTarget()
|
||||
{
|
||||
nsCOMPtr<nsIDOMEventTarget> eventTarget;
|
||||
switch (mFlags & NS_TARGET_CHAIN_TYPE_MASK) {
|
||||
case NS_TARGET_CHAIN_IS_NODE:
|
||||
{
|
||||
return mNode;
|
||||
}
|
||||
case NS_TARGET_CHAIN_IS_WINDOW:
|
||||
{
|
||||
return mWindow;
|
||||
break;
|
||||
}
|
||||
case NS_TARGET_CHAIN_IS_CHROMEHANDLER:
|
||||
{
|
||||
return mChromeHandler;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
NS_WARNING("Unknown type in event target chain!!!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEventTargetChainItem::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
aVisitor.Reset();
|
||||
nsresult rv = NS_OK;
|
||||
switch (mFlags & NS_TARGET_CHAIN_TYPE_MASK) {
|
||||
case NS_TARGET_CHAIN_IS_NODE:
|
||||
{
|
||||
rv = mNode->PreHandleEvent(aVisitor);
|
||||
break;
|
||||
}
|
||||
case NS_TARGET_CHAIN_IS_WINDOW:
|
||||
{
|
||||
rv = mWindow->PreHandleEvent(aVisitor);
|
||||
break;
|
||||
}
|
||||
case NS_TARGET_CHAIN_IS_CHROMEHANDLER:
|
||||
{
|
||||
rv = mChromeHandler->PreHandleChromeEvent(aVisitor);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
NS_WARNING("Unknown type in event target chain!!!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SetForceContentDispatch(aVisitor.mForceContentDispatch);
|
||||
mItemFlags = aVisitor.mItemFlags;
|
||||
mItemData = aVisitor.mItemData;
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEventTargetChainItem::HandleEvent(nsEventChainPostVisitor& aVisitor,
|
||||
PRUint32 aFlags)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> lm =
|
||||
nsEventTargetChainItem::GetListenerManager(PR_FALSE);
|
||||
|
||||
if (lm) {
|
||||
aVisitor.mEvent->currentTarget = CurrentTarget();
|
||||
lm->HandleEvent(aVisitor.mPresContext, aVisitor.mEvent, &aVisitor.mDOMEvent,
|
||||
aVisitor.mEvent->currentTarget, aFlags,
|
||||
&aVisitor.mEventStatus);
|
||||
aVisitor.mEvent->currentTarget = nsnull;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEventTargetChainItem::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
aVisitor.mItemFlags = mItemFlags;
|
||||
aVisitor.mItemData = mItemData;
|
||||
switch (mFlags & NS_TARGET_CHAIN_TYPE_MASK) {
|
||||
case NS_TARGET_CHAIN_IS_NODE:
|
||||
{
|
||||
return mNode->PostHandleEvent(aVisitor);
|
||||
}
|
||||
case NS_TARGET_CHAIN_IS_WINDOW:
|
||||
{
|
||||
return mWindow->PostHandleEvent(aVisitor);
|
||||
}
|
||||
case NS_TARGET_CHAIN_IS_CHROMEHANDLER:
|
||||
{
|
||||
return mChromeHandler->PostHandleChromeEvent(aVisitor);
|
||||
}
|
||||
default:
|
||||
{
|
||||
NS_WARNING("Unknown type in event target chain!!!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEventTargetChainItem::CreateChainAndHandleEvent(nsEventChainPreVisitor& aVisitor,
|
||||
nsDispatchingCallback* aCallback)
|
||||
{
|
||||
if (aVisitor.mParentTarget) {
|
||||
// There is something which should be added to the event target chain.
|
||||
nsEventTargetChainItem parentEtci(aVisitor.mParentTarget,
|
||||
aVisitor.mParentIsChromeHandler,
|
||||
this);
|
||||
NS_ENSURE_TRUE(parentEtci.IsValid(), NS_ERROR_FAILURE);
|
||||
|
||||
// Item needs event retargetting.
|
||||
if (aVisitor.mEventTargetAtParent) {
|
||||
// Need to set the target of the event
|
||||
// so that also the next retargeting works.
|
||||
aVisitor.mEvent->target = aVisitor.mEventTargetAtParent;
|
||||
parentEtci.SetNewTarget(aVisitor.mEventTargetAtParent);
|
||||
}
|
||||
|
||||
parentEtci.PreHandleEvent(aVisitor);
|
||||
|
||||
if (aVisitor.mCanHandle) {
|
||||
// The parent event target chain item can handle the event. Continue
|
||||
// chain creation.
|
||||
return parentEtci.CreateChainAndHandleEvent(aVisitor, aCallback);
|
||||
}
|
||||
}
|
||||
|
||||
// Event target chain is created. Handle the chain.
|
||||
nsEventChainPostVisitor postVisitor(aVisitor);
|
||||
nsresult rv = HandleEventTargetChain(postVisitor,
|
||||
NS_EVENT_FLAG_BUBBLE |
|
||||
NS_EVENT_FLAG_CAPTURE,
|
||||
aCallback);
|
||||
|
||||
aVisitor.mEventStatus = postVisitor.mEventStatus;
|
||||
// If the DOM event was created during event flow.
|
||||
if (!aVisitor.mDOMEvent && postVisitor.mDOMEvent) {
|
||||
aVisitor.mDOMEvent = postVisitor.mDOMEvent;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsEventTargetChainItem::HandleEventTargetChain(nsEventChainPostVisitor& aVisitor, PRUint32 aFlags,
|
||||
nsDispatchingCallback* aCallback)
|
||||
{
|
||||
// Save the target so that it can be restored later.
|
||||
nsCOMPtr<nsISupports> firstTarget = aVisitor.mEvent->target;
|
||||
|
||||
// Capture
|
||||
nsEventTargetChainItem* item = this;
|
||||
aVisitor.mEvent->flags |= NS_EVENT_FLAG_CAPTURE;
|
||||
aVisitor.mEvent->flags &= ~NS_EVENT_FLAG_BUBBLE;
|
||||
while (item->mChild) {
|
||||
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);
|
||||
}
|
||||
|
||||
if (item->GetNewTarget()) {
|
||||
// item is at anonymous boundary. Need to retarget for the child items.
|
||||
nsEventTargetChainItem* nextTarget = item->mChild;
|
||||
while (nextTarget) {
|
||||
nsISupports* newTarget = nextTarget->GetNewTarget();
|
||||
if (newTarget) {
|
||||
aVisitor.mEvent->target = newTarget;
|
||||
break;
|
||||
}
|
||||
nextTarget = nextTarget->mChild;
|
||||
}
|
||||
}
|
||||
|
||||
item = item->mChild;
|
||||
}
|
||||
|
||||
// Target
|
||||
aVisitor.mEvent->flags |= NS_EVENT_FLAG_BUBBLE;
|
||||
if (!(aVisitor.mEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH) &&
|
||||
(!(aVisitor.mEvent->flags & NS_EVENT_FLAG_NO_CONTENT_DISPATCH) ||
|
||||
item->ForceContentDispatch())) {
|
||||
// FIXME Should use aFlags & NS_EVENT_BUBBLE_MASK because capture phase
|
||||
// event listeners should not be fired. But it breaks at least
|
||||
// <xul:dialog>'s buttons. Bug 235441.
|
||||
item->HandleEvent(aVisitor, aFlags);
|
||||
}
|
||||
if (aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) {
|
||||
item->PostHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
// Bubble
|
||||
if (!(aVisitor.mEvent->flags & NS_EVENT_FLAG_CANT_BUBBLE)) {
|
||||
aVisitor.mEvent->flags &= ~NS_EVENT_FLAG_CAPTURE;
|
||||
item = item->mParent;
|
||||
while (item) {
|
||||
nsISupports* newTarget = item->GetNewTarget();
|
||||
if (newTarget) {
|
||||
// Item is at anonymous boundary. Need to retarget for the current item
|
||||
// and for parent items.
|
||||
aVisitor.mEvent->target = newTarget;
|
||||
}
|
||||
|
||||
if ((!(aVisitor.mEvent->flags & NS_EVENT_FLAG_NO_CONTENT_DISPATCH) ||
|
||||
item->ForceContentDispatch()) &&
|
||||
(!(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);
|
||||
}
|
||||
if (aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) {
|
||||
item->PostHandleEvent(aVisitor);
|
||||
}
|
||||
item = item->mParent;
|
||||
}
|
||||
}
|
||||
aVisitor.mEvent->flags &= ~NS_EVENT_FLAG_BUBBLE;
|
||||
|
||||
if (!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT)) {
|
||||
// Dispatch to the system event group. Make sure to clear the
|
||||
// STOP_DISPATCH flag since this resets for each event group
|
||||
// per DOM3 Events.
|
||||
aVisitor.mEvent->flags &= ~NS_EVENT_FLAG_STOP_DISPATCH;
|
||||
|
||||
// Setting back the original target of the event.
|
||||
aVisitor.mEvent->target = aVisitor.mEvent->originalTarget;
|
||||
|
||||
// Special handling if PresShell (or some other caller)
|
||||
// used a callback object.
|
||||
if (aCallback) {
|
||||
aCallback->HandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
// Retarget for system event group (which does the default handling too).
|
||||
// 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);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
nsEventDispatcher::Dispatch(nsISupports* aTarget,
|
||||
nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent* aDOMEvent,
|
||||
nsEventStatus* aEventStatus,
|
||||
nsDispatchingCallback* aCallback,
|
||||
PRBool aTargetIsChromeHandler)
|
||||
{
|
||||
NS_ASSERTION(aEvent, "Trying to dispatch without nsEvent!");
|
||||
NS_ENSURE_TRUE(!NS_IS_EVENT_IN_DISPATCH(aEvent),
|
||||
NS_ERROR_ILLEGAL_VALUE);
|
||||
// This is strange, but nsEvents are sometimes reused and they don't need
|
||||
// re-initialization.
|
||||
NS_ENSURE_TRUE(!(aDOMEvent &&
|
||||
(aEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH_IMMEDIATELY)),
|
||||
NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
#ifdef DEBUG
|
||||
if (aDOMEvent) {
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privEvt(do_QueryInterface(aDOMEvent));
|
||||
if (privEvt) {
|
||||
nsEvent* innerEvent = nsnull;
|
||||
privEvt->GetInternalNSEvent(&innerEvent);
|
||||
NS_ASSERTION(innerEvent == aEvent,
|
||||
"The inner event of aDOMEvent is not the same as aEvent!");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
PRBool externalDOMEvent = !!(aDOMEvent);
|
||||
|
||||
// If we have a PresContext, make sure it doesn't die before
|
||||
// event dispatching is finished.
|
||||
nsCOMPtr<nsPresContext> kungFuDeathGrip(aPresContext);
|
||||
|
||||
// Create the event target chain item for the event target.
|
||||
nsEventTargetChainItem targetEtci(aTarget, aTargetIsChromeHandler);
|
||||
NS_ENSURE_TRUE(targetEtci.IsValid(), NS_ERROR_FAILURE);
|
||||
|
||||
// Make sure that nsIDOMEvent::target and nsIDOMNSEvent::originalTarget
|
||||
// point to the last item in the chain.
|
||||
// XXX But if the target is already set, use that. This is a hack
|
||||
// for the 'load', 'beforeunload' and 'unload' events,
|
||||
// which are dispatched to |window| but have document as their target.
|
||||
if (!aEvent->target) {
|
||||
aEvent->target = aTarget;
|
||||
}
|
||||
aEvent->originalTarget = aEvent->target;
|
||||
|
||||
NS_MARK_EVENT_DISPATCH_STARTED(aEvent);
|
||||
|
||||
// Create visitor object and start event dispatching.
|
||||
// PreHandleEvent for the original target.
|
||||
nsEventStatus status = aEventStatus ? *aEventStatus : nsEventStatus_eIgnore;
|
||||
nsEventChainPreVisitor preVisitor(aPresContext, aEvent, aDOMEvent, status);
|
||||
targetEtci.PreHandleEvent(preVisitor);
|
||||
|
||||
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);
|
||||
// Create rest of the event target chain and handle event.
|
||||
rv = targetEtci.CreateChainAndHandleEvent(preVisitor, aCallback);
|
||||
}
|
||||
|
||||
NS_MARK_EVENT_DISPATCH_DONE(aEvent);
|
||||
|
||||
if (!externalDOMEvent && preVisitor.mDOMEvent) {
|
||||
// An nsDOMEvent was created while dispatching the event.
|
||||
// Duplicate private data if someone holds a pointer to it.
|
||||
nsrefcnt rc = 0;
|
||||
NS_RELEASE2(preVisitor.mDOMEvent, rc);
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent =
|
||||
do_QueryInterface(preVisitor.mDOMEvent);
|
||||
if (privateEvent) {
|
||||
privateEvent->DuplicatePrivateData();
|
||||
}
|
||||
}
|
||||
|
||||
if (aEventStatus) {
|
||||
*aEventStatus = preVisitor.mEventStatus;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
nsEventDispatcher::DispatchDOMEvent(nsISupports* aTarget,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus)
|
||||
{
|
||||
if (aDOMEvent) {
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privEvt(do_QueryInterface(aDOMEvent));
|
||||
if (privEvt) {
|
||||
nsEvent* innerEvent = nsnull;
|
||||
privEvt->GetInternalNSEvent(&innerEvent);
|
||||
NS_ENSURE_TRUE(innerEvent, NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
PRBool trusted;
|
||||
nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(privEvt));
|
||||
|
||||
nsevent->GetIsTrusted(&trusted);
|
||||
|
||||
if (!trusted) {
|
||||
//Check security state to determine if dispatcher is trusted
|
||||
nsIScriptSecurityManager *securityManager =
|
||||
nsContentUtils::GetSecurityManager();
|
||||
|
||||
PRBool enabled;
|
||||
nsresult rv =
|
||||
securityManager->IsCapabilityEnabled("UniversalBrowserWrite",
|
||||
&enabled);
|
||||
privEvt->SetTrusted(NS_SUCCEEDED(rv) && enabled);
|
||||
}
|
||||
|
||||
return nsEventDispatcher::Dispatch(aTarget, aPresContext, innerEvent,
|
||||
aDOMEvent, aEventStatus);
|
||||
}
|
||||
} else if (aEvent) {
|
||||
return nsEventDispatcher::Dispatch(aTarget, aPresContext, aEvent,
|
||||
aDOMEvent, aEventStatus);
|
||||
}
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
const nsAString& aEventType,
|
||||
nsIDOMEvent** aDOMEvent)
|
||||
{
|
||||
*aDOMEvent = nsnull;
|
||||
|
||||
if (aEvent) {
|
||||
switch(aEvent->eventStructType) {
|
||||
case NS_MUTATION_EVENT:
|
||||
return NS_NewDOMMutationEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsMutationEvent*,aEvent));
|
||||
case NS_GUI_EVENT:
|
||||
case NS_COMPOSITION_EVENT:
|
||||
case NS_RECONVERSION_EVENT:
|
||||
case NS_QUERYCARETRECT_EVENT:
|
||||
case NS_SCROLLPORT_EVENT:
|
||||
return NS_NewDOMUIEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsGUIEvent*,aEvent));
|
||||
case NS_KEY_EVENT:
|
||||
return NS_NewDOMKeyboardEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsKeyEvent*,aEvent));
|
||||
case NS_MOUSE_EVENT:
|
||||
case NS_MOUSE_SCROLL_EVENT:
|
||||
case NS_POPUP_EVENT:
|
||||
return NS_NewDOMMouseEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsInputEvent*,aEvent));
|
||||
case NS_POPUPBLOCKED_EVENT:
|
||||
return NS_NewDOMPopupBlockedEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsPopupBlockedEvent*,
|
||||
aEvent));
|
||||
case NS_TEXT_EVENT:
|
||||
return NS_NewDOMTextEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsTextEvent*,aEvent));
|
||||
case NS_BEFORE_PAGE_UNLOAD_EVENT:
|
||||
return
|
||||
NS_NewDOMBeforeUnloadEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsBeforePageUnloadEvent*,
|
||||
aEvent));
|
||||
case NS_PAGETRANSITION_EVENT:
|
||||
return NS_NewDOMPageTransitionEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsPageTransitionEvent*,
|
||||
aEvent));
|
||||
#ifdef MOZ_SVG
|
||||
case NS_SVG_EVENT:
|
||||
return NS_NewDOMSVGEvent(aDOMEvent, aPresContext,
|
||||
aEvent);
|
||||
case NS_SVGZOOM_EVENT:
|
||||
return NS_NewDOMSVGZoomEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsGUIEvent*,aEvent));
|
||||
#endif // MOZ_SVG
|
||||
}
|
||||
|
||||
// For all other types of events, create a vanilla event object.
|
||||
return NS_NewDOMEvent(aDOMEvent, aPresContext, aEvent);
|
||||
}
|
||||
|
||||
// And if we didn't get an event, check the type argument.
|
||||
|
||||
if (aEventType.LowerCaseEqualsLiteral("mouseevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("mouseevents") ||
|
||||
aEventType.LowerCaseEqualsLiteral("mousescrollevents") ||
|
||||
aEventType.LowerCaseEqualsLiteral("popupevents"))
|
||||
return NS_NewDOMMouseEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("keyboardevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("keyevents"))
|
||||
return NS_NewDOMKeyboardEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("mutationevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("mutationevents"))
|
||||
return NS_NewDOMMutationEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("textevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("textevents"))
|
||||
return NS_NewDOMTextEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("popupblockedevents"))
|
||||
return NS_NewDOMPopupBlockedEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("uievent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("uievents"))
|
||||
return NS_NewDOMUIEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("event") ||
|
||||
aEventType.LowerCaseEqualsLiteral("events") ||
|
||||
aEventType.LowerCaseEqualsLiteral("htmlevents"))
|
||||
return NS_NewDOMEvent(aDOMEvent, aPresContext, nsnull);
|
||||
#ifdef MOZ_SVG
|
||||
if (aEventType.LowerCaseEqualsLiteral("svgevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("svgevents"))
|
||||
return NS_NewDOMSVGEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("svgzoomevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("svgzoomevents"))
|
||||
return NS_NewDOMSVGZoomEvent(aDOMEvent, aPresContext, nsnull);
|
||||
#endif // MOZ_SVG
|
||||
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
}
|
|
@ -107,6 +107,7 @@
|
|||
#include "nsJSUtils.h"
|
||||
#include "nsIDOMEventGroup.h"
|
||||
#include "nsContentCID.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID,
|
||||
NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
|
||||
|
@ -1494,7 +1495,7 @@ nsEventListenerManager::CompileEventHandlerInternal(nsIScriptContext *aContext,
|
|||
nsISupports *aObject,
|
||||
nsIAtom *aName,
|
||||
nsListenerStruct *aListenerStruct,
|
||||
nsIDOMEventTarget* aCurrentTarget,
|
||||
nsISupports* aCurrentTarget,
|
||||
PRUint32 aSubType)
|
||||
{
|
||||
nsresult result = NS_OK;
|
||||
|
@ -1602,7 +1603,7 @@ nsresult
|
|||
nsEventListenerManager::HandleEventSubType(nsListenerStruct* aListenerStruct,
|
||||
nsIDOMEventListener* aListener,
|
||||
nsIDOMEvent* aDOMEvent,
|
||||
nsIDOMEventTarget* aCurrentTarget,
|
||||
nsISupports* aCurrentTarget,
|
||||
PRUint32 aSubType,
|
||||
PRUint32 aPhaseFlags)
|
||||
{
|
||||
|
@ -1648,10 +1649,8 @@ nsEventListenerManager::HandleEventSubType(nsListenerStruct* aListenerStruct,
|
|||
nsCxPusher pusher(aCurrentTarget);
|
||||
|
||||
if (NS_SUCCEEDED(result)) {
|
||||
nsCOMPtr<nsIPrivateDOMEvent> aPrivDOMEvent(do_QueryInterface(aDOMEvent));
|
||||
aPrivDOMEvent->SetCurrentTarget(aCurrentTarget);
|
||||
// nsIDOMEvent::currentTarget is set in nsEventDispatcher.
|
||||
result = aListener->HandleEvent(aDOMEvent);
|
||||
aPrivDOMEvent->SetCurrentTarget(nsnull);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1665,7 +1664,7 @@ nsEventListenerManager::HandleEventSubType(nsListenerStruct* aListenerStruct,
|
|||
nsresult
|
||||
nsEventListenerManager::HandleEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
nsIDOMEventTarget* aCurrentTarget,
|
||||
nsISupports* aCurrentTarget,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
{
|
||||
|
@ -1721,7 +1720,8 @@ nsEventListenerManager::HandleEvent(nsPresContext* aPresContext,
|
|||
found:
|
||||
if (listeners) {
|
||||
if (!*aDOMEvent) {
|
||||
ret = CreateEvent(aPresContext, aEvent, EmptyString(), aDOMEvent);
|
||||
ret = nsEventDispatcher::CreateEvent(aPresContext, aEvent,
|
||||
EmptyString(), aDOMEvent);
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(ret)) {
|
||||
|
@ -1779,93 +1779,8 @@ nsEventListenerManager::CreateEvent(nsPresContext* aPresContext,
|
|||
const nsAString& aEventType,
|
||||
nsIDOMEvent** aDOMEvent)
|
||||
{
|
||||
*aDOMEvent = nsnull;
|
||||
|
||||
if (aEvent) {
|
||||
switch(aEvent->eventStructType) {
|
||||
case NS_MUTATION_EVENT:
|
||||
return NS_NewDOMMutationEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsMutationEvent*,aEvent));
|
||||
case NS_GUI_EVENT:
|
||||
case NS_COMPOSITION_EVENT:
|
||||
case NS_RECONVERSION_EVENT:
|
||||
case NS_QUERYCARETRECT_EVENT:
|
||||
case NS_SCROLLPORT_EVENT:
|
||||
return NS_NewDOMUIEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsGUIEvent*,aEvent));
|
||||
case NS_KEY_EVENT:
|
||||
return NS_NewDOMKeyboardEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsKeyEvent*,aEvent));
|
||||
case NS_MOUSE_EVENT:
|
||||
case NS_MOUSE_SCROLL_EVENT:
|
||||
case NS_POPUP_EVENT:
|
||||
return NS_NewDOMMouseEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsInputEvent*,aEvent));
|
||||
case NS_POPUPBLOCKED_EVENT:
|
||||
return NS_NewDOMPopupBlockedEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsPopupBlockedEvent*,
|
||||
aEvent));
|
||||
case NS_TEXT_EVENT:
|
||||
return NS_NewDOMTextEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsTextEvent*,aEvent));
|
||||
case NS_BEFORE_PAGE_UNLOAD_EVENT:
|
||||
return
|
||||
NS_NewDOMBeforeUnloadEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsBeforePageUnloadEvent*,
|
||||
aEvent));
|
||||
case NS_PAGETRANSITION_EVENT:
|
||||
return NS_NewDOMPageTransitionEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsPageTransitionEvent*,
|
||||
aEvent));
|
||||
#ifdef MOZ_SVG
|
||||
case NS_SVG_EVENT:
|
||||
return NS_NewDOMSVGEvent(aDOMEvent, aPresContext,
|
||||
aEvent);
|
||||
case NS_SVGZOOM_EVENT:
|
||||
return NS_NewDOMSVGZoomEvent(aDOMEvent, aPresContext,
|
||||
NS_STATIC_CAST(nsGUIEvent*,aEvent));
|
||||
#endif // MOZ_SVG
|
||||
}
|
||||
|
||||
// For all other types of events, create a vanilla event object.
|
||||
return NS_NewDOMEvent(aDOMEvent, aPresContext, aEvent);
|
||||
}
|
||||
|
||||
// And if we didn't get an event, check the type argument.
|
||||
|
||||
if (aEventType.LowerCaseEqualsLiteral("mouseevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("mouseevents") ||
|
||||
aEventType.LowerCaseEqualsLiteral("mousescrollevents") ||
|
||||
aEventType.LowerCaseEqualsLiteral("popupevents"))
|
||||
return NS_NewDOMMouseEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("keyboardevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("keyevents"))
|
||||
return NS_NewDOMKeyboardEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("mutationevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("mutationevents"))
|
||||
return NS_NewDOMMutationEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("textevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("textevents"))
|
||||
return NS_NewDOMTextEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("popupblockedevents"))
|
||||
return NS_NewDOMPopupBlockedEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("uievent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("uievents"))
|
||||
return NS_NewDOMUIEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("event") ||
|
||||
aEventType.LowerCaseEqualsLiteral("events") ||
|
||||
aEventType.LowerCaseEqualsLiteral("htmlevents"))
|
||||
return NS_NewDOMEvent(aDOMEvent, aPresContext, nsnull);
|
||||
#ifdef MOZ_SVG
|
||||
if (aEventType.LowerCaseEqualsLiteral("svgevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("svgevents"))
|
||||
return NS_NewDOMSVGEvent(aDOMEvent, aPresContext, nsnull);
|
||||
if (aEventType.LowerCaseEqualsLiteral("svgzoomevent") ||
|
||||
aEventType.LowerCaseEqualsLiteral("svgzoomevents"))
|
||||
return NS_NewDOMSVGZoomEvent(aDOMEvent, aPresContext, nsnull);
|
||||
#endif // MOZ_SVG
|
||||
|
||||
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
|
||||
return nsEventDispatcher::CreateEvent(aPresContext, aEvent,
|
||||
aEventType, aDOMEvent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2110,14 +2025,17 @@ nsEventListenerManager::DispatchEvent(nsIDOMEvent* aEvent, PRBool *_retval)
|
|||
|
||||
// Obtain a presentation shell
|
||||
nsIPresShell *shell = document->GetShellAt(0);
|
||||
if (!shell) {
|
||||
return NS_OK;
|
||||
nsCOMPtr<nsPresContext> context;
|
||||
if (shell) {
|
||||
context = shell->GetPresContext();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPresContext> context = shell->GetPresContext();
|
||||
|
||||
return context->EventStateManager()->
|
||||
DispatchNewEvent(mTarget, aEvent, _retval);
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsresult rv =
|
||||
nsEventDispatcher::DispatchDOMEvent(targetContent, nsnull, aEvent,
|
||||
context, &status);
|
||||
*_retval = (status != nsEventStatus_eConsumeNoDefault);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// nsIDOM3EventTarget interface
|
||||
|
@ -2170,11 +2088,11 @@ nsEventListenerManager::RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEventListenerManager::GetListenerManager(nsIEventListenerManager** aInstancePtrResult)
|
||||
nsEventListenerManager::GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aInstancePtrResult);
|
||||
*aInstancePtrResult = NS_STATIC_CAST(nsIEventListenerManager*, this);
|
||||
NS_ADDREF(*aInstancePtrResult);
|
||||
NS_ENSURE_ARG_POINTER(aResult);
|
||||
NS_ADDREF(*aResult = this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -2193,7 +2111,7 @@ nsEventListenerManager::GetSystemEventGroup(nsIDOMEventGroup **aGroup)
|
|||
|
||||
nsresult
|
||||
nsEventListenerManager::FixContextMenuEvent(nsPresContext* aPresContext,
|
||||
nsIDOMEventTarget* aCurrentTarget,
|
||||
nsISupports* aCurrentTarget,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent)
|
||||
{
|
||||
|
@ -2231,7 +2149,7 @@ nsEventListenerManager::FixContextMenuEvent(nsPresContext* aPresContext,
|
|||
// If we're here because of the key-equiv for showing context menus, we
|
||||
// have to reset the event target to the currently focused element. Get it
|
||||
// from the focus controller.
|
||||
nsCOMPtr<nsIDOMEventTarget> currentTarget(aCurrentTarget);
|
||||
nsCOMPtr<nsIDOMEventTarget> currentTarget = do_QueryInterface(aCurrentTarget);
|
||||
nsCOMPtr<nsIDOMElement> currentFocus;
|
||||
|
||||
if (aEvent->message == NS_CONTEXTMENU_KEY) {
|
||||
|
|
|
@ -159,7 +159,7 @@ public:
|
|||
NS_IMETHOD HandleEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
nsIDOMEventTarget* aCurrentTarget,
|
||||
nsISupports* aCurrentTarget,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
|
||||
|
@ -198,7 +198,8 @@ public:
|
|||
const nsIID& aIID);
|
||||
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID);
|
||||
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
|
||||
NS_IMETHOD GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult);
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent);
|
||||
NS_IMETHOD GetSystemEventGroup(nsIDOMEventGroup** aGroup);
|
||||
|
||||
|
@ -208,7 +209,7 @@ protected:
|
|||
nsresult HandleEventSubType(nsListenerStruct* aListenerStruct,
|
||||
nsIDOMEventListener* aListener,
|
||||
nsIDOMEvent* aDOMEvent,
|
||||
nsIDOMEventTarget* aCurrentTarget,
|
||||
nsISupports* aCurrentTarget,
|
||||
PRUint32 aSubType,
|
||||
PRUint32 aPhaseFlags);
|
||||
nsresult CompileEventHandlerInternal(nsIScriptContext *aContext,
|
||||
|
@ -216,7 +217,7 @@ protected:
|
|||
nsISupports *aObject,
|
||||
nsIAtom *aName,
|
||||
nsListenerStruct *aListenerStruct,
|
||||
nsIDOMEventTarget* aCurrentTarget,
|
||||
nsISupports* aCurrentTarget,
|
||||
PRUint32 aSubType);
|
||||
nsListenerStruct* FindJSEventListener(EventArrayType aType);
|
||||
nsresult SetJSEventListener(nsIScriptContext *aContext,
|
||||
|
@ -241,7 +242,7 @@ protected:
|
|||
nsVoidArray* GetListenersByType(EventArrayType aType, nsHashKey* aKey, PRBool aCreate);
|
||||
EventArrayType GetTypeForIID(const nsIID& aIID);
|
||||
nsresult FixContextMenuEvent(nsPresContext* aPresContext,
|
||||
nsIDOMEventTarget* aCurrentTarget,
|
||||
nsISupports* aCurrentTarget,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent);
|
||||
PRBool PrepareToUseCaretPosition(nsIWidget* aEventWidget,
|
||||
|
|
|
@ -129,6 +129,7 @@
|
|||
#include "imgIContainer.h"
|
||||
#include "nsIProperties.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include <Events.h>
|
||||
|
@ -567,10 +568,9 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||
nsEventStatus blurstatus = nsEventStatus_eIgnore;
|
||||
nsEvent blurevent(PR_TRUE, NS_BLUR_CONTENT);
|
||||
|
||||
gLastFocusedDocument->HandleDOMEvent(gLastFocusedPresContext,
|
||||
&blurevent,
|
||||
nsnull, NS_EVENT_FLAG_INIT,
|
||||
&blurstatus);
|
||||
nsEventDispatcher::Dispatch(gLastFocusedDocument,
|
||||
gLastFocusedPresContext,
|
||||
&blurevent, nsnull, &blurstatus);
|
||||
|
||||
if (!mCurrentFocus && gLastFocusedContent) {
|
||||
// We also need to blur the previously focused content node here,
|
||||
|
@ -578,16 +578,16 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||
// (SendFocusBlur isn't called in this case).
|
||||
|
||||
nsCOMPtr<nsIContent> blurContent = gLastFocusedContent;
|
||||
gLastFocusedContent->HandleDOMEvent(gLastFocusedPresContext,
|
||||
&blurevent, nsnull,
|
||||
NS_EVENT_FLAG_INIT,
|
||||
&blurstatus);
|
||||
blurevent.target = nsnull;
|
||||
nsEventDispatcher::Dispatch(gLastFocusedContent,
|
||||
gLastFocusedPresContext,
|
||||
&blurevent, nsnull, &blurstatus);
|
||||
|
||||
// XXX bryner this isn't quite right -- it can result in
|
||||
// firing two blur events on the content.
|
||||
|
||||
nsCOMPtr<nsIDocument> doc;
|
||||
if (gLastFocusedContent) // could have changed in HandleDOMEvent
|
||||
if (gLastFocusedContent) // could have changed in Dispatch
|
||||
doc = gLastFocusedContent->GetDocument();
|
||||
if (doc) {
|
||||
nsIPresShell *shell = doc->GetShellAt(0);
|
||||
|
@ -598,10 +598,9 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||
nsCOMPtr<nsIEventStateManager> esm;
|
||||
esm = oldPresContext->EventStateManager();
|
||||
esm->SetFocusedContent(gLastFocusedContent);
|
||||
gLastFocusedContent->HandleDOMEvent(oldPresContext,
|
||||
&blurevent, nsnull,
|
||||
NS_EVENT_FLAG_INIT,
|
||||
&blurstatus);
|
||||
nsEventDispatcher::Dispatch(gLastFocusedContent,
|
||||
oldPresContext,
|
||||
&blurevent, nsnull, &blurstatus);
|
||||
esm->SetFocusedContent(nsnull);
|
||||
NS_IF_RELEASE(gLastFocusedContent);
|
||||
}
|
||||
|
@ -633,16 +632,22 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||
nsEvent focusevent(PR_TRUE, NS_FOCUS_CONTENT);
|
||||
|
||||
if (gLastFocusedDocument != mDocument) {
|
||||
mDocument->HandleDOMEvent(aPresContext, &focusevent, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
//XXXsmaug bubbling for now, because in the old event dispatching
|
||||
// code focus event did bubble from document to window.
|
||||
nsEventDispatcher::Dispatch(mDocument, aPresContext,
|
||||
&focusevent, nsnull, &status);
|
||||
if (currentFocus && currentFocus != gLastFocusedContent) {
|
||||
currentFocus->HandleDOMEvent(aPresContext, &focusevent, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
// Clear the target so that Dispatch can set it back correctly.
|
||||
focusevent.target = nsnull;
|
||||
nsEventDispatcher::Dispatch(currentFocus, aPresContext,
|
||||
&focusevent, nsnull, &status);
|
||||
}
|
||||
}
|
||||
|
||||
window->HandleDOMEvent(aPresContext, &focusevent, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
// Clear the target so that Dispatch can set it back correctly.
|
||||
focusevent.target = nsnull;
|
||||
nsEventDispatcher::Dispatch(window, aPresContext, &focusevent,
|
||||
nsnull, &status);
|
||||
|
||||
SetFocusedContent(currentFocus); // we kept this reference above
|
||||
NS_IF_RELEASE(gLastFocusedContent);
|
||||
|
@ -724,9 +729,8 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||
nsCOMPtr<nsIEventStateManager> esm =
|
||||
oldPresContext->EventStateManager();
|
||||
esm->SetFocusedContent(gLastFocusedContent);
|
||||
gLastFocusedContent->HandleDOMEvent(oldPresContext, &event,
|
||||
nsnull, NS_EVENT_FLAG_INIT,
|
||||
&status);
|
||||
nsEventDispatcher::Dispatch(gLastFocusedContent, oldPresContext,
|
||||
&event, nsnull, &status);
|
||||
esm->SetFocusedContent(nsnull);
|
||||
NS_IF_RELEASE(gLastFocusedContent);
|
||||
}
|
||||
|
@ -740,13 +744,15 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||
|
||||
nsCOMPtr<nsPIDOMWindow> window(gLastFocusedDocument->GetWindow());
|
||||
|
||||
gLastFocusedDocument->HandleDOMEvent(gLastFocusedPresContext,
|
||||
&event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
event.target = nsnull;
|
||||
nsEventDispatcher::Dispatch(gLastFocusedDocument,
|
||||
gLastFocusedPresContext,
|
||||
&event, nsnull, &status);
|
||||
|
||||
if (window) {
|
||||
window->HandleDOMEvent(gLastFocusedPresContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
event.target = nsnull;
|
||||
nsEventDispatcher::Dispatch(window, gLastFocusedPresContext,
|
||||
&event, nsnull, &status);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -883,8 +889,8 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||
nsCOMPtr<nsIContent> focusedContent = do_QueryInterface(focusedElement);
|
||||
if (focusedContent) {
|
||||
// Blur the element.
|
||||
focusedContent->HandleDOMEvent(oldPresContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(focusedContent, oldPresContext,
|
||||
&event, nsnull, &status);
|
||||
}
|
||||
|
||||
esm->SetFocusedContent(nsnull);
|
||||
|
@ -893,12 +899,15 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
|||
}
|
||||
|
||||
// fire blur on document and window
|
||||
mDocument->HandleDOMEvent(aPresContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
event.target = nsnull;
|
||||
nsEventDispatcher::Dispatch(mDocument, aPresContext, &event, nsnull,
|
||||
&status);
|
||||
|
||||
if (ourWindow)
|
||||
ourWindow->HandleDOMEvent(aPresContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
if (ourWindow) {
|
||||
event.target = nsnull;
|
||||
nsEventDispatcher::Dispatch(ourWindow, aPresContext, &event, nsnull,
|
||||
&status);
|
||||
}
|
||||
|
||||
// Now clear our our global variables
|
||||
mCurrentTarget = nsnull;
|
||||
|
@ -1038,7 +1047,8 @@ nsEventStateManager::HandleAccessKey(nsPresContext* aPresContext,
|
|||
|
||||
nsCOMPtr<nsIContent> oldTargetContent = mCurrentTargetContent;
|
||||
mCurrentTargetContent = content;
|
||||
content->HandleDOMEvent(mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(content, mPresContext, &event, nsnull,
|
||||
&status);
|
||||
mCurrentTargetContent = oldTargetContent;
|
||||
}
|
||||
|
||||
|
@ -1321,8 +1331,8 @@ nsEventStateManager::FireContextClick()
|
|||
}
|
||||
|
||||
// dispatch to DOM
|
||||
mGestureDownContent->HandleDOMEvent(mPresContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(mGestureDownContent, mPresContext, &event,
|
||||
nsnull, &status);
|
||||
|
||||
// We don't need to dispatch to frame handling because no frames
|
||||
// watch NS_CONTEXTMENU except for nsMenuFrame and that's only for
|
||||
|
@ -1529,8 +1539,8 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
|
|||
mCurrentTargetContent = targetContent;
|
||||
|
||||
// Dispatch to DOM
|
||||
targetContent->HandleDOMEvent(aPresContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(targetContent, aPresContext, &event, nsnull,
|
||||
&status);
|
||||
|
||||
// Note that frame event handling doesn't care about NS_DRAGDROP_GESTURE,
|
||||
// which is just as well since we don't really know which frame to
|
||||
|
@ -2602,8 +2612,8 @@ nsEventStateManager::DispatchMouseEvent(nsGUIEvent* aEvent, PRUint32 aMessage,
|
|||
BeforeDispatchEvent();
|
||||
nsIFrame* targetFrame = nsnull;
|
||||
if (aTargetContent) {
|
||||
aTargetContent->HandleDOMEvent(mPresContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(aTargetContent, mPresContext, &event, nsnull,
|
||||
&status);
|
||||
|
||||
nsIPresShell *shell = mPresContext->GetPresShell();
|
||||
if (shell) {
|
||||
|
@ -2815,7 +2825,8 @@ nsEventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
|
|||
if ( lastContent != targetContent ) {
|
||||
//XXX This event should still go somewhere!!
|
||||
if (lastContent)
|
||||
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(lastContent, aPresContext, &event,
|
||||
nsnull, &status);
|
||||
|
||||
// clear the drag hover
|
||||
if (status != nsEventStatus_eConsumeNoDefault )
|
||||
|
@ -2843,13 +2854,14 @@ nsEventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
|
|||
mCurrentRelatedContent = lastContent;
|
||||
|
||||
//The frame has change but the content may not have. Check before dispatching to content
|
||||
if ( lastContent != targetContent ) {
|
||||
if (lastContent != targetContent) {
|
||||
//XXX This event should still go somewhere!!
|
||||
if ( targetContent )
|
||||
targetContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
if (targetContent)
|
||||
nsEventDispatcher::Dispatch(targetContent, aPresContext, &event,
|
||||
nsnull, &status);
|
||||
|
||||
// set drag hover on this frame
|
||||
if ( status != nsEventStatus_eConsumeNoDefault )
|
||||
if (status != nsEventStatus_eConsumeNoDefault)
|
||||
SetContentState(targetContent, NS_EVENT_STATE_DRAGOVER);
|
||||
}
|
||||
|
||||
|
@ -2887,9 +2899,10 @@ nsEventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
|
|||
mCurrentTargetContent = lastContent;
|
||||
mCurrentRelatedContent = nsnull;
|
||||
|
||||
if ( lastContent ) {
|
||||
lastContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
if ( status != nsEventStatus_eConsumeNoDefault )
|
||||
if (lastContent) {
|
||||
nsEventDispatcher::Dispatch(lastContent, aPresContext, &event, nsnull,
|
||||
&status);
|
||||
if (status != nsEventStatus_eConsumeNoDefault)
|
||||
SetContentState(nsnull, NS_EVENT_STATE_DRAGOVER);
|
||||
}
|
||||
|
||||
|
@ -2976,7 +2989,7 @@ nsEventStateManager::CheckForAndDispatchClick(nsPresContext* aPresContext,
|
|||
{
|
||||
nsresult ret = NS_OK;
|
||||
PRUint32 eventMsg = 0;
|
||||
PRInt32 flags = NS_EVENT_FLAG_INIT;
|
||||
PRInt32 flags = NS_EVENT_FLAG_NONE;
|
||||
|
||||
//If mouse is still over same element, clickcount will be > 1.
|
||||
//If it has moved it will be zero, so no click.
|
||||
|
@ -3005,13 +3018,15 @@ nsEventStateManager::CheckForAndDispatchClick(nsPresContext* aPresContext,
|
|||
event.isAlt = aEvent->isAlt;
|
||||
event.isMeta = aEvent->isMeta;
|
||||
event.time = aEvent->time;
|
||||
event.flags |= flags;
|
||||
|
||||
nsCOMPtr<nsIPresShell> presShell = mPresContext->GetPresShell();
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIContent> mouseContent;
|
||||
GetEventTargetContent(aEvent, getter_AddRefs(mouseContent));
|
||||
|
||||
ret = presShell->HandleEventWithTarget(&event, mCurrentTarget, mouseContent, flags, aStatus);
|
||||
ret = presShell->HandleEventWithTarget(&event, mCurrentTarget,
|
||||
mouseContent, aStatus);
|
||||
if (NS_SUCCEEDED(ret) && aEvent->clickCount == 2) {
|
||||
eventMsg = 0;
|
||||
//fire double click
|
||||
|
@ -3035,9 +3050,10 @@ nsEventStateManager::CheckForAndDispatchClick(nsPresContext* aPresContext,
|
|||
event2.isControl = aEvent->isControl;
|
||||
event2.isAlt = aEvent->isAlt;
|
||||
event2.isMeta = aEvent->isMeta;
|
||||
event2.flags |= flags;
|
||||
|
||||
ret = presShell->HandleEventWithTarget(&event2, mCurrentTarget,
|
||||
mouseContent, flags, aStatus);
|
||||
mouseContent, aStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4171,7 +4187,8 @@ nsEventStateManager::SendFocusBlur(nsPresContext* aPresContext,
|
|||
NS_RELEASE(gLastFocusedContent); // nulls out gLastFocusedContent
|
||||
|
||||
nsCxPusher pusher(temp);
|
||||
temp->HandleDOMEvent(oldPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(temp, oldPresContext, &event, nsnull,
|
||||
&status);
|
||||
pusher.Pop();
|
||||
|
||||
focusAfterBlur = mCurrentFocus;
|
||||
|
@ -4230,7 +4247,8 @@ nsEventStateManager::SendFocusBlur(nsPresContext* aPresContext,
|
|||
gLastFocusedDocument = nsnull;
|
||||
|
||||
nsCxPusher pusher(temp);
|
||||
temp->HandleDOMEvent(gLastFocusedPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(temp, gLastFocusedPresContext, &event, nsnull,
|
||||
&status);
|
||||
pusher.Pop();
|
||||
|
||||
if (previousFocus && mCurrentFocus != previousFocus) {
|
||||
|
@ -4243,8 +4261,8 @@ nsEventStateManager::SendFocusBlur(nsPresContext* aPresContext,
|
|||
}
|
||||
|
||||
pusher.Push(window);
|
||||
window->HandleDOMEvent(gLastFocusedPresContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(window, gLastFocusedPresContext, &event,
|
||||
nsnull, &status);
|
||||
|
||||
if (previousFocus && mCurrentFocus != previousFocus) {
|
||||
// The window's blur handler focused something else.
|
||||
|
@ -4255,8 +4273,8 @@ nsEventStateManager::SendFocusBlur(nsPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
// Check if the HandleDOMEvent calls above destroyed our frame (bug #118685)
|
||||
// or made it not focusable in any way.
|
||||
// Check if the nsEventDispatcher::Dispatch calls above destroyed our frame
|
||||
// (bug #118685) or made it not focusable in any way.
|
||||
if (aContent && !::IsFocusable(presShell, aContent)) {
|
||||
aContent = nsnull;
|
||||
}
|
||||
|
@ -4314,7 +4332,10 @@ nsEventStateManager::SendFocusBlur(nsPresContext* aPresContext,
|
|||
|
||||
if (nsnull != mPresContext) {
|
||||
nsCxPusher pusher(aContent);
|
||||
aContent->HandleDOMEvent(mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(aContent, mPresContext, &event, nsnull,
|
||||
&status);
|
||||
nsAutoString name;
|
||||
aContent->Tag()->ToString(name);
|
||||
}
|
||||
|
||||
nsAutoString tabIndex;
|
||||
|
@ -4335,7 +4356,8 @@ nsEventStateManager::SendFocusBlur(nsPresContext* aPresContext,
|
|||
|
||||
if (nsnull != mPresContext && mDocument) {
|
||||
nsCxPusher pusher(mDocument);
|
||||
mDocument->HandleDOMEvent(mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(mDocument, mPresContext, &event, nsnull,
|
||||
&status);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4539,96 +4561,6 @@ nsEventStateManager::ForceViewUpdate(nsIView* aView)
|
|||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsEventStateManager::DispatchNewEvent(nsISupports* aTarget,
|
||||
nsIDOMEvent* aEvent,
|
||||
PRBool *aDefaultActionEnabled)
|
||||
{
|
||||
nsresult ret = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privEvt(do_QueryInterface(aEvent));
|
||||
if (privEvt) {
|
||||
nsEvent * innerEvent;
|
||||
privEvt->GetInternalNSEvent(&innerEvent);
|
||||
|
||||
NS_ENSURE_TRUE(innerEvent, NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
// Make sure this event isn't currently in dispatch.
|
||||
NS_ENSURE_TRUE(!NS_IS_EVENT_IN_DISPATCH(innerEvent),
|
||||
NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
// And make sure this event wasn't already dispatched w/o being
|
||||
// re-initialized in between.
|
||||
NS_ENSURE_TRUE(!(innerEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH_IMMEDIATELY),
|
||||
NS_ERROR_ILLEGAL_VALUE);
|
||||
|
||||
// Mark this event as dispatched now that we're this far along.
|
||||
NS_MARK_EVENT_DISPATCH_STARTED(innerEvent);
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> eventTarget(do_QueryInterface(aTarget));
|
||||
privEvt->SetTarget(eventTarget);
|
||||
|
||||
PRBool trusted;
|
||||
nsCOMPtr<nsIDOMNSEvent> nsevent(do_QueryInterface(privEvt));
|
||||
|
||||
nsevent->GetIsTrusted(&trusted);
|
||||
|
||||
if (!trusted) {
|
||||
//Check security state to determine if dispatcher is trusted
|
||||
nsIScriptSecurityManager *securityManager =
|
||||
nsContentUtils::GetSecurityManager();
|
||||
|
||||
PRBool enabled;
|
||||
nsresult res =
|
||||
securityManager->IsCapabilityEnabled("UniversalBrowserWrite",
|
||||
&enabled);
|
||||
privEvt->SetTrusted(NS_SUCCEEDED(res) && enabled);
|
||||
}
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsCOMPtr<nsPIDOMWindow> target(do_QueryInterface(aTarget));
|
||||
if (target) {
|
||||
ret = target->HandleDOMEvent(mPresContext, innerEvent, &aEvent,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIDocument> target(do_QueryInterface(aTarget));
|
||||
if (target) {
|
||||
ret = target->HandleDOMEvent(mPresContext, innerEvent, &aEvent,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIContent> target(do_QueryInterface(aTarget));
|
||||
if (target) {
|
||||
ret = target->HandleDOMEvent(mPresContext, innerEvent, &aEvent,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
|
||||
// Dispatch to the system event group. Make sure to clear
|
||||
// the STOP_DISPATCH flag since this resets for each event
|
||||
// group per DOM3 Events.
|
||||
|
||||
innerEvent->flags &= ~NS_EVENT_FLAG_STOP_DISPATCH;
|
||||
ret = target->HandleDOMEvent(mPresContext, innerEvent, &aEvent,
|
||||
NS_EVENT_FLAG_INIT |
|
||||
NS_EVENT_FLAG_SYSTEM_EVENT,
|
||||
&status);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIChromeEventHandler> target(do_QueryInterface(aTarget));
|
||||
if (target) {
|
||||
ret = target->HandleChromeEvent(mPresContext, innerEvent, &aEvent,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*aDefaultActionEnabled = status != nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
nsEventStateManager::EnsureDocument(nsPresContext* aPresContext)
|
||||
{
|
||||
|
|
|
@ -132,9 +132,6 @@ public:
|
|||
PRBool aHaveHotspot, float aHotspotX, float aHotspotY,
|
||||
nsIWidget* aWidget, PRBool aLockCursor);
|
||||
|
||||
//Method for centralized distribution of new DOM events
|
||||
NS_IMETHOD DispatchNewEvent(nsISupports* aTarget, nsIDOMEvent* aEvent, PRBool *aDefaultActionEnabled);
|
||||
|
||||
NS_IMETHOD ShiftFocus(PRBool aForward, nsIContent* aStart=nsnull);
|
||||
|
||||
virtual PRBool GetBrowseWithCaret();
|
||||
|
|
|
@ -141,6 +141,7 @@
|
|||
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIEditorIMESupport.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
// XXX todo: add in missing out-of-memory checks
|
||||
|
||||
|
@ -1424,8 +1425,7 @@ nsGenericHTMLElement::DispatchEvent(nsPresContext* aPresContext,
|
|||
}
|
||||
|
||||
if (aFullDispatch) {
|
||||
return shell->HandleEventWithTarget(aEvent, nsnull, aTarget,
|
||||
NS_EVENT_FLAG_INIT, aStatus);
|
||||
return shell->HandleEventWithTarget(aEvent, nsnull, aTarget, aStatus);
|
||||
}
|
||||
|
||||
return shell->HandleDOMEventWithTarget(aTarget, aEvent, aStatus);
|
||||
|
@ -1460,22 +1460,15 @@ nsGenericHTMLElement::DispatchClickEvent(nsPresContext* aPresContext,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLElement::HandleDOMEventForAnchors(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsGenericHTMLElement::PostHandleEventForAnchors(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEventStatus);
|
||||
NS_PRECONDITION(nsCOMPtr<nsILink>(do_QueryInterface(this)),
|
||||
"should be called only when |this| implements |nsILink|");
|
||||
|
||||
// Try script event handlers first
|
||||
nsresult ret = nsGenericHTMLElement::HandleDOMEvent(aPresContext, aEvent,
|
||||
aDOMEvent, aFlags,
|
||||
aEventStatus);
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!aPresContext) {
|
||||
if (!aVisitor.mPresContext) {
|
||||
// No pres context when event generated by other parts of DOM code,
|
||||
// as in mutation events
|
||||
return NS_OK;
|
||||
|
@ -1484,39 +1477,32 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsPresContext* aPresContext,
|
|||
//Need to check if we hit an imagemap area and if so see if we're handling
|
||||
//the event on that map or on a link farther up the tree. If we're on a
|
||||
//link farther up, do nothing.
|
||||
if (NS_SUCCEEDED(ret)) {
|
||||
nsCOMPtr<nsIContent> target;
|
||||
nsCOMPtr<nsIContent> target;
|
||||
|
||||
aPresContext->EventStateManager()->
|
||||
GetEventTargetContent(aEvent, getter_AddRefs(target));
|
||||
aVisitor.mPresContext->EventStateManager()->
|
||||
GetEventTargetContent(aVisitor.mEvent, getter_AddRefs(target));
|
||||
|
||||
if (target && IsArea(target) && !IsArea(this)) {
|
||||
// We are over an area and our element is not one. Return without
|
||||
// running anchor code.
|
||||
return ret;
|
||||
}
|
||||
if (target && IsArea(target) && !IsArea(this)) {
|
||||
// We are over an area and our element is not one. Return without
|
||||
// running anchor code.
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (NS_FAILED(ret))
|
||||
return ret;
|
||||
|
||||
// Ensure that this is a trusted DOM event before going further.
|
||||
// XXXldb Why can aDOMEvent by null?
|
||||
if (aDOMEvent && *aDOMEvent) {
|
||||
nsCOMPtr<nsIDOMNSEvent> nsEvent = do_QueryInterface(*aDOMEvent);
|
||||
if (aVisitor.mDOMEvent) {
|
||||
nsCOMPtr<nsIDOMNSEvent> nsEvent = do_QueryInterface(aVisitor.mDOMEvent);
|
||||
NS_ENSURE_TRUE(nsEvent, NS_OK);
|
||||
PRBool isTrusted;
|
||||
ret = nsEvent->GetIsTrusted(&isTrusted);
|
||||
NS_ENSURE_SUCCESS(ret, NS_OK);
|
||||
rv = nsEvent->GetIsTrusted(&isTrusted);
|
||||
NS_ENSURE_SUCCESS(rv, NS_OK);
|
||||
if (!isTrusted)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if ((*aEventStatus == nsEventStatus_eIgnore ||
|
||||
(*aEventStatus != nsEventStatus_eConsumeNoDefault &&
|
||||
(aEvent->message == NS_MOUSE_ENTER_SYNTH ||
|
||||
aEvent->message == NS_MOUSE_EXIT_SYNTH))) &&
|
||||
!(aFlags & NS_EVENT_FLAG_CAPTURE) && !(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT)) {
|
||||
if ((aVisitor.mEventStatus == nsEventStatus_eIgnore ||
|
||||
(aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault &&
|
||||
(aVisitor.mEvent->message == NS_MOUSE_ENTER_SYNTH ||
|
||||
aVisitor.mEvent->message == NS_MOUSE_EXIT_SYNTH)))) {
|
||||
|
||||
// We'll use the equivalent of |GetHrefUTF8| on the
|
||||
// nsILink interface to get a canonified URL that has been
|
||||
|
@ -1528,11 +1514,11 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsPresContext* aPresContext,
|
|||
// Only bother to handle the mouse event if there was an href
|
||||
// specified.
|
||||
if (hrefURI) {
|
||||
switch (aEvent->message) {
|
||||
switch (aVisitor.mEvent->message) {
|
||||
case NS_MOUSE_LEFT_BUTTON_DOWN:
|
||||
{
|
||||
// don't make the link grab the focus if there is no link handler
|
||||
nsILinkHandler *handler = aPresContext->GetLinkHandler();
|
||||
nsILinkHandler *handler = aVisitor.mPresContext->GetLinkHandler();
|
||||
nsIDocument *document = GetCurrentDoc();
|
||||
if (handler && document && ShouldFocus(this)) {
|
||||
// If the window is not active, do not allow the focus to bring the
|
||||
|
@ -1551,8 +1537,8 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsPresContext* aPresContext,
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
aPresContext->EventStateManager()->
|
||||
|
||||
aVisitor.mPresContext->EventStateManager()->
|
||||
SetContentState(this,
|
||||
NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS);
|
||||
|
||||
|
@ -1561,50 +1547,53 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsPresContext* aPresContext,
|
|||
break;
|
||||
|
||||
case NS_MOUSE_LEFT_CLICK:
|
||||
if (nsEventStatus_eConsumeNoDefault != *aEventStatus) {
|
||||
nsInputEvent* inputEvent = NS_STATIC_CAST(nsInputEvent*, aEvent);
|
||||
if (nsEventStatus_eConsumeNoDefault != aVisitor.mEventStatus) {
|
||||
nsInputEvent* inputEvent =
|
||||
NS_STATIC_CAST(nsInputEvent*, aVisitor.mEvent);
|
||||
if (inputEvent->isControl || inputEvent->isMeta ||
|
||||
inputEvent->isAlt ||inputEvent->isShift) {
|
||||
break; // let the click go through so we can handle it in JS/XUL
|
||||
break;
|
||||
}
|
||||
|
||||
// The default action is simply to dispatch DOMActivate
|
||||
nsIPresShell *shell = aPresContext->GetPresShell();
|
||||
nsIPresShell *shell = aVisitor.mPresContext->GetPresShell();
|
||||
if (shell) {
|
||||
// single-click
|
||||
nsUIEvent actEvent(NS_IS_TRUSTED_EVENT(aEvent), NS_UI_ACTIVATE, 1);
|
||||
nsUIEvent actEvent(NS_IS_TRUSTED_EVENT(aVisitor.mEvent),
|
||||
NS_UI_ACTIVATE, 1);
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
|
||||
ret = shell->HandleDOMEventWithTarget(this, &actEvent, &status);
|
||||
*aEventStatus = status;
|
||||
rv = shell->HandleDOMEventWithTarget(this, &actEvent, &status);
|
||||
aVisitor.mEventStatus = status;
|
||||
}
|
||||
|
||||
if (*aEventStatus != nsEventStatus_eConsumeNoDefault)
|
||||
*aEventStatus = nsEventStatus_eConsumeDoDefault;
|
||||
if (aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault)
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeDoDefault;
|
||||
}
|
||||
break;
|
||||
|
||||
case NS_UI_ACTIVATE:
|
||||
if (nsEventStatus_eConsumeNoDefault != *aEventStatus) {
|
||||
if (nsEventStatus_eConsumeNoDefault != aVisitor.mEventStatus) {
|
||||
nsAutoString target;
|
||||
GetAttr(kNameSpaceID_None, nsHTMLAtoms::target, target);
|
||||
if (target.IsEmpty()) {
|
||||
GetBaseTarget(target);
|
||||
}
|
||||
|
||||
ret = TriggerLink(aPresContext, eLinkVerb_Replace, hrefURI,
|
||||
target, PR_TRUE, PR_TRUE);
|
||||
rv = TriggerLink(aVisitor.mPresContext, eLinkVerb_Replace, hrefURI,
|
||||
target, PR_TRUE, PR_TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case NS_KEY_PRESS:
|
||||
if (aEvent->eventStructType == NS_KEY_EVENT) {
|
||||
nsKeyEvent* keyEvent = NS_STATIC_CAST(nsKeyEvent*, aEvent);
|
||||
if (aVisitor.mEvent->eventStructType == NS_KEY_EVENT) {
|
||||
nsKeyEvent* keyEvent = NS_STATIC_CAST(nsKeyEvent*, aVisitor.mEvent);
|
||||
if (keyEvent->keyCode == NS_VK_RETURN) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
ret = DispatchClickEvent(aPresContext, keyEvent, this, PR_FALSE, &status);
|
||||
if (NS_SUCCEEDED(ret)) {
|
||||
*aEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
rv = DispatchClickEvent(aVisitor.mPresContext, keyEvent, this,
|
||||
PR_FALSE, &status);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1612,7 +1601,7 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsPresContext* aPresContext,
|
|||
|
||||
// Set the status bar the same for focus and mouseover
|
||||
case NS_MOUSE_ENTER_SYNTH:
|
||||
*aEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
case NS_FOCUS_CONTENT:
|
||||
{
|
||||
nsAutoString target;
|
||||
|
@ -1620,15 +1609,15 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsPresContext* aPresContext,
|
|||
if (target.IsEmpty()) {
|
||||
GetBaseTarget(target);
|
||||
}
|
||||
ret = TriggerLink(aPresContext, eLinkVerb_Replace,
|
||||
hrefURI, target, PR_FALSE, PR_TRUE);
|
||||
rv = TriggerLink(aVisitor.mPresContext, eLinkVerb_Replace,
|
||||
hrefURI, target, PR_FALSE, PR_TRUE);
|
||||
}
|
||||
break;
|
||||
|
||||
case NS_MOUSE_EXIT_SYNTH:
|
||||
{
|
||||
*aEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
ret = LeaveLink(aPresContext);
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
rv = LeaveLink(aVisitor.mPresContext);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1637,7 +1626,7 @@ nsGenericHTMLElement::HandleDOMEventForAnchors(nsPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -1754,7 +1743,7 @@ nsGenericHTMLElement::GetEventListenerManagerForAttr(nsIEventListenerManager** a
|
|||
nsCOMPtr<nsIDOMEventReceiver> receiver(do_QueryInterface(win));
|
||||
NS_ENSURE_TRUE(receiver, NS_ERROR_FAILURE);
|
||||
|
||||
rv = receiver->GetListenerManager(aManager);
|
||||
rv = receiver->GetListenerManager(PR_TRUE, aManager);
|
||||
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_ADDREF(*aTarget = win);
|
||||
|
@ -1781,7 +1770,7 @@ nsGenericHTMLElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
|||
if (aNameSpaceID == kNameSpaceID_None &&
|
||||
IsEventName(aAttribute)) {
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
GetListenerManager(getter_AddRefs(manager));
|
||||
GetListenerManager(PR_FALSE, getter_AddRefs(manager));
|
||||
|
||||
if (manager) {
|
||||
manager->RemoveScriptEventListener(aAttribute);
|
||||
|
@ -3523,13 +3512,15 @@ nsGenericHTMLFrameElement::SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLFrameElement::HandleChromeEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsGenericHTMLFrameElement::PreHandleChromeEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
return HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags,aEventStatus);
|
||||
return PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLFrameElement::PostHandleChromeEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -215,15 +215,7 @@ public:
|
|||
PRBool aFullDispatch,
|
||||
nsEventStatus* aStatus);
|
||||
|
||||
/**
|
||||
* Standard anchor HandleDOMEvent, used by A, AREA and LINK (parameters
|
||||
* are the same as HandleDOMEvent)
|
||||
*/
|
||||
nsresult HandleDOMEventForAnchors(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
nsresult PostHandleEventForAnchors(nsEventChainPostVisitor& aVisitor);
|
||||
|
||||
// Used by A, AREA, LINK, and STYLE.
|
||||
// Callers must hold a reference to nsHTMLUtils's global reference count.
|
||||
|
|
|
@ -111,10 +111,7 @@ public:
|
|||
virtual void SetFocus(nsPresContext* aPresContext);
|
||||
virtual PRBool IsFocusable(PRBool *aTabIndex = nsnull);
|
||||
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
|
@ -285,14 +282,9 @@ nsHTMLAnchorElement::IsFocusable(PRInt32 *aTabIndex)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLAnchorElement::HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsHTMLAnchorElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
return HandleDOMEventForAnchors(aPresContext, aEvent, aDOMEvent,
|
||||
aFlags, aEventStatus);
|
||||
return PostHandleEventForAnchors(aVisitor);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -87,10 +87,8 @@ public:
|
|||
NS_IMETHOD LinkAdded() { return NS_OK; }
|
||||
NS_IMETHOD LinkRemoved() { return NS_OK; }
|
||||
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
|
||||
virtual void SetFocus(nsPresContext* aPresContext);
|
||||
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
|
@ -169,14 +167,9 @@ nsHTMLAreaElement::SetTarget(const nsAString& aValue)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLAreaElement::HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsHTMLAreaElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
return HandleDOMEventForAnchors(aPresContext, aEvent, aDOMEvent,
|
||||
aFlags, aEventStatus);
|
||||
return PostHandleEventForAnchors(aVisitor);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -57,6 +57,9 @@
|
|||
#include "nsGUIEvent.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
#define NS_IN_SUBMIT_CLICK (1 << 0)
|
||||
|
||||
class nsHTMLButtonElement : public nsGenericHTMLFormElement,
|
||||
public nsIDOMHTMLButtonElement,
|
||||
|
@ -102,10 +105,8 @@ public:
|
|||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult);
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
|
||||
protected:
|
||||
PRInt8 mType;
|
||||
|
@ -211,8 +212,8 @@ nsHTMLButtonElement::Click()
|
|||
NS_MOUSE_LEFT_CLICK, nsnull,
|
||||
nsMouseEvent::eReal);
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
HandleDOMEvent(context, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this), context,
|
||||
&event, nsnull, &status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -283,15 +284,10 @@ nsHTMLButtonElement::ParseAttribute(PRInt32 aNamespaceID,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLButtonElement::HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsHTMLButtonElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEventStatus);
|
||||
|
||||
// Do not process any DOM events if the element is disabled
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
PRBool bDisabled;
|
||||
nsresult rv = GetDisabled(&bDisabled);
|
||||
if (NS_FAILED(rv) || bDisabled) {
|
||||
|
@ -313,27 +309,32 @@ nsHTMLButtonElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
PRBool bInSubmitClick = mType == NS_FORM_BUTTON_SUBMIT &&
|
||||
!(aFlags & NS_EVENT_FLAG_CAPTURE) &&
|
||||
!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) &&
|
||||
aEvent->message == NS_MOUSE_LEFT_CLICK &&
|
||||
//FIXME Should this use NS_UI_ACTIVATE, not NS_MOUSE_LEFT_CLICK?
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=309348#c16
|
||||
PRBool bInSubmitClick = mType == NS_FORM_BUTTON_SUBMIT &&
|
||||
aVisitor.mEvent->message == NS_MOUSE_LEFT_CLICK &&
|
||||
mForm;
|
||||
|
||||
if (bInSubmitClick) {
|
||||
aVisitor.mItemFlags |= NS_IN_SUBMIT_CLICK;
|
||||
// tell the form that we are about to enter a click handler.
|
||||
// that means that if there are scripted submissions, the
|
||||
// latest one will be deferred until after the exit point of the handler.
|
||||
// latest one will be deferred until after the exit point of the handler.
|
||||
mForm->OnSubmitClickBegin();
|
||||
}
|
||||
|
||||
// Try script event handlers first
|
||||
nsresult ret;
|
||||
ret = nsGenericHTMLFormElement::HandleDOMEvent(aPresContext, aEvent,
|
||||
aDOMEvent, aFlags,
|
||||
aEventStatus);
|
||||
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLButtonElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!aVisitor.mPresContext) {
|
||||
return rv;
|
||||
}
|
||||
// mForm is null if the event handler removed us from the document (bug 194582).
|
||||
if (bInSubmitClick && mForm) {
|
||||
if ((aVisitor.mItemFlags & NS_IN_SUBMIT_CLICK) && mForm) {
|
||||
// tell the form that we are about to exit a click handler
|
||||
// so the form knows not to defer subsequent submissions
|
||||
// the pending ones that were created during the handler
|
||||
|
@ -341,40 +342,41 @@ nsHTMLButtonElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
mForm->OnSubmitClickEnd();
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(ret) &&
|
||||
!(aFlags & NS_EVENT_FLAG_CAPTURE) && !(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT)) {
|
||||
if (nsEventStatus_eIgnore == *aEventStatus) {
|
||||
switch (aEvent->message) {
|
||||
|
||||
if (nsEventStatus_eIgnore == aVisitor.mEventStatus) {
|
||||
switch (aVisitor.mEvent->message) {
|
||||
case NS_KEY_PRESS:
|
||||
case NS_KEY_UP:
|
||||
{
|
||||
// For backwards compat, trigger buttons with space or enter
|
||||
// (bug 25300)
|
||||
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
|
||||
if ((keyEvent->keyCode == NS_VK_RETURN && NS_KEY_PRESS == aEvent->message) ||
|
||||
keyEvent->keyCode == NS_VK_SPACE && NS_KEY_UP == aEvent->message) {
|
||||
nsKeyEvent * keyEvent = (nsKeyEvent *)aVisitor.mEvent;
|
||||
if ((keyEvent->keyCode == NS_VK_RETURN &&
|
||||
NS_KEY_PRESS == aVisitor.mEvent->message) ||
|
||||
keyEvent->keyCode == NS_VK_SPACE &&
|
||||
NS_KEY_UP == aVisitor.mEvent->message) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
|
||||
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aEvent),
|
||||
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aVisitor.mEvent),
|
||||
NS_MOUSE_LEFT_CLICK, nsnull,
|
||||
nsMouseEvent::eReal);
|
||||
rv = HandleDOMEvent(aPresContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this),
|
||||
aVisitor.mPresContext, &event, nsnull,
|
||||
&status);
|
||||
}
|
||||
}
|
||||
break;// NS_KEY_PRESS
|
||||
|
||||
case NS_MOUSE_LEFT_CLICK:
|
||||
{
|
||||
nsIPresShell *presShell = aPresContext->GetPresShell();
|
||||
nsIPresShell *presShell = aVisitor.mPresContext->GetPresShell();
|
||||
if (presShell) {
|
||||
// single-click
|
||||
nsUIEvent event(NS_IS_TRUSTED_EVENT(aEvent), NS_UI_ACTIVATE, 1);
|
||||
nsUIEvent event(NS_IS_TRUSTED_EVENT(aVisitor.mEvent),
|
||||
NS_UI_ACTIVATE, 1);
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
|
||||
presShell->HandleDOMEventWithTarget(this, &event, &status);
|
||||
*aEventStatus = status;
|
||||
aVisitor.mEventStatus = status;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -389,11 +391,13 @@ nsHTMLButtonElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
event.originator = this;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
|
||||
nsIPresShell *presShell = aPresContext->GetPresShell();
|
||||
nsIPresShell *presShell = aVisitor.mPresContext->GetPresShell();
|
||||
// If |nsIPresShell::Destroy| has been called due to
|
||||
// handling the event (base class HandleDOMEvent, above),
|
||||
// the pres context will return a null pres shell. See
|
||||
// bug 125624.
|
||||
// handling the event, the pres context will return
|
||||
// a null pres shell. See bug 125624.
|
||||
//
|
||||
// Using presShell to dispatch the event. It makes sure that
|
||||
// event is not handled if the window is being destroyed.
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIContent> form(do_QueryInterface(mForm));
|
||||
presShell->HandleDOMEventWithTarget(form, &event, &status);
|
||||
|
@ -404,15 +408,14 @@ nsHTMLButtonElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
|
||||
case NS_MOUSE_LEFT_BUTTON_DOWN:
|
||||
{
|
||||
aPresContext->EventStateManager()->
|
||||
SetContentState(this,
|
||||
NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS);
|
||||
|
||||
*aEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
aVisitor.mPresContext->EventStateManager()->
|
||||
SetContentState(this, NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS);
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
break;
|
||||
|
||||
// cancel all of these events for buttons
|
||||
//XXXsmaug What to do with these events? Why these should be cancelled?
|
||||
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
|
||||
case NS_MOUSE_MIDDLE_BUTTON_UP:
|
||||
case NS_MOUSE_MIDDLE_DOUBLECLICK:
|
||||
|
@ -422,14 +425,14 @@ nsHTMLButtonElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
{
|
||||
nsCOMPtr<nsIDOMNSEvent> nsevent;
|
||||
|
||||
if (aDOMEvent) {
|
||||
nsevent = do_QueryInterface(*aDOMEvent);
|
||||
if (aVisitor.mDOMEvent) {
|
||||
nsevent = do_QueryInterface(aVisitor.mDOMEvent);
|
||||
}
|
||||
|
||||
if (nsevent) {
|
||||
nsevent->PreventBubble();
|
||||
} else {
|
||||
ret = NS_ERROR_FAILURE;
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -437,32 +440,30 @@ nsHTMLButtonElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
|
||||
case NS_MOUSE_ENTER_SYNTH:
|
||||
{
|
||||
aPresContext->EventStateManager()->
|
||||
aVisitor.mPresContext->EventStateManager()->
|
||||
SetContentState(this, NS_EVENT_STATE_HOVER);
|
||||
|
||||
*aEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
break;
|
||||
|
||||
// XXX this doesn't seem to do anything yet
|
||||
case NS_MOUSE_EXIT_SYNTH:
|
||||
{
|
||||
aPresContext->EventStateManager()->
|
||||
aVisitor.mPresContext->EventStateManager()->
|
||||
SetContentState(nsnull, NS_EVENT_STATE_HOVER);
|
||||
|
||||
*aEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (aEvent->message) {
|
||||
// Make sure any pending submissions from a call to
|
||||
// form.submit() in a left click handler or an activate
|
||||
// handler gets flushed, even if the event handler prevented
|
||||
// the default action.
|
||||
}
|
||||
} else {
|
||||
switch (aVisitor.mEvent->message) {
|
||||
// Make sure any pending submissions from a call to
|
||||
// form.submit() in a left click handler or an activate
|
||||
// handler gets flushed, even if the event handler prevented
|
||||
// the default action.
|
||||
case NS_MOUSE_LEFT_CLICK:
|
||||
case NS_UI_ACTIVATE:
|
||||
if (mForm && mType == NS_FORM_BUTTON_SUBMIT) {
|
||||
|
@ -473,11 +474,10 @@ nsHTMLButtonElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
mForm->FlushPendingSubmission();
|
||||
}
|
||||
break;// NS_UI_ACTIVATE
|
||||
} //switch
|
||||
} //if
|
||||
} //switch
|
||||
} //if
|
||||
|
||||
return ret;
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -85,6 +85,7 @@
|
|||
#include "nsLayoutUtils.h"
|
||||
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
static const int NS_FORM_CONTROL_LIST_HASHTABLE_SIZE = 16;
|
||||
|
||||
|
@ -205,10 +206,9 @@ public:
|
|||
nsIAtom* aAttribute,
|
||||
const nsAString& aValue,
|
||||
nsAttrValue& aResult);
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
|
@ -629,20 +629,10 @@ nsHTMLFormElement::Submit()
|
|||
NS_IMETHODIMP
|
||||
nsHTMLFormElement::Reset()
|
||||
{
|
||||
// Send the reset event
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsPresContext> presContext = GetPresContext();
|
||||
// XXXbz shouldn't need prescontext here! Fix events!
|
||||
if (presContext) {
|
||||
// Calling HandleDOMEvent() directly so that reset() will work even if
|
||||
// the frame does not exist. This does not have an effect right now, but
|
||||
// If PresShell::HandleEventWithTarget() ever starts to work for elements
|
||||
// without frames, that should be called instead.
|
||||
nsFormEvent event(PR_TRUE, NS_FORM_RESET);
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
}
|
||||
return rv;
|
||||
nsFormEvent event(PR_TRUE, NS_FORM_RESET);
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this), nsnull,
|
||||
&event);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static const nsAttrValue::EnumTable kFormMethodTable[] = {
|
||||
|
@ -709,60 +699,49 @@ nsHTMLFormElement::UnbindFromTree(PRBool aDeep, PRBool aNullParent)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLFormElement::HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsHTMLFormElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEvent);
|
||||
if (aVisitor.mEvent->originalTarget == NS_STATIC_CAST(nsIContent*, this)) {
|
||||
PRUint32 msg = aVisitor.mEvent->message;
|
||||
if (msg == NS_FORM_SUBMIT) {
|
||||
if (mGeneratingSubmit) {
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
mGeneratingSubmit = PR_TRUE;
|
||||
|
||||
// If this is the bubble stage, there is a nested form below us which received
|
||||
// a submit event. We do *not* want to handle the submit event for this form
|
||||
// too. So to avert a disaster, we stop the bubbling altogether.
|
||||
if ((aFlags & NS_EVENT_FLAG_BUBBLE) &&
|
||||
(aEvent->message == NS_FORM_RESET || aEvent->message == NS_FORM_SUBMIT)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Ignore recursive calls to submit and reset
|
||||
if (aEvent->message == NS_FORM_SUBMIT) {
|
||||
if (mGeneratingSubmit) {
|
||||
return NS_OK;
|
||||
// let the form know that it needs to defer the submission,
|
||||
// that means that if there are scripted submissions, the
|
||||
// latest one will be deferred until after the exit point of the handler.
|
||||
mDeferSubmission = PR_TRUE;
|
||||
}
|
||||
mGeneratingSubmit = PR_TRUE;
|
||||
|
||||
// let the form know that it needs to defer the submission,
|
||||
// that means that if there are scripted submissions, the
|
||||
// latest one will be deferred until after the exit point of the handler.
|
||||
mDeferSubmission = PR_TRUE;
|
||||
}
|
||||
else if (aEvent->message == NS_FORM_RESET) {
|
||||
if (mGeneratingReset) {
|
||||
return NS_OK;
|
||||
else if (msg == NS_FORM_RESET) {
|
||||
if (mGeneratingReset) {
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
mGeneratingReset = PR_TRUE;
|
||||
}
|
||||
mGeneratingReset = PR_TRUE;
|
||||
}
|
||||
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLFormElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
if (aVisitor.mEvent->originalTarget == NS_STATIC_CAST(nsIContent*, this)) {
|
||||
PRUint32 msg = aVisitor.mEvent->message;
|
||||
if (msg == NS_FORM_SUBMIT) {
|
||||
// let the form know not to defer subsequent submissions
|
||||
mDeferSubmission = PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult rv = nsGenericHTMLElement::HandleDOMEvent(aPresContext, aEvent,
|
||||
aDOMEvent, aFlags,
|
||||
aEventStatus);
|
||||
if (aEvent->message == NS_FORM_SUBMIT) {
|
||||
// let the form know not to defer subsequent submissions
|
||||
mDeferSubmission = PR_FALSE;
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
!(aFlags & NS_EVENT_FLAG_CAPTURE) &&
|
||||
!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT)) {
|
||||
|
||||
if (*aEventStatus == nsEventStatus_eIgnore) {
|
||||
switch (aEvent->message) {
|
||||
if (aVisitor.mEventStatus == nsEventStatus_eIgnore) {
|
||||
switch (msg) {
|
||||
case NS_FORM_RESET:
|
||||
case NS_FORM_SUBMIT:
|
||||
{
|
||||
if (mPendingSubmission && aEvent->message == NS_FORM_SUBMIT) {
|
||||
if (mPendingSubmission && msg == NS_FORM_SUBMIT) {
|
||||
// tell the form to forget a possible pending submission.
|
||||
// the reason is that the script returned true (the event was
|
||||
// ignored) so if there is a stored submission, it will miss
|
||||
|
@ -770,12 +749,12 @@ nsHTMLFormElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
// to forget it and the form element will build a new one
|
||||
ForgetPendingSubmission();
|
||||
}
|
||||
DoSubmitOrReset(aEvent, aEvent->message);
|
||||
DoSubmitOrReset(aVisitor.mEvent, msg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (aEvent->message == NS_FORM_SUBMIT) {
|
||||
if (msg == NS_FORM_SUBMIT) {
|
||||
// tell the form to flush a possible pending submission.
|
||||
// the reason is that the script returned false (the event was
|
||||
// not ignored) so if there is a stored submission, it needs to
|
||||
|
@ -783,16 +762,15 @@ nsHTMLFormElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
FlushPendingSubmission();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aEvent->message == NS_FORM_SUBMIT) {
|
||||
mGeneratingSubmit = PR_FALSE;
|
||||
if (msg == NS_FORM_SUBMIT) {
|
||||
mGeneratingSubmit = PR_FALSE;
|
||||
}
|
||||
else if (msg == NS_FORM_RESET) {
|
||||
mGeneratingReset = PR_FALSE;
|
||||
}
|
||||
}
|
||||
else if (aEvent->message == NS_FORM_RESET) {
|
||||
mGeneratingReset = PR_FALSE;
|
||||
}
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
#include "nsIView.h"
|
||||
#include "nsImageMapUtils.h"
|
||||
#include "nsIDOMHTMLMapElement.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
// XXX nav attrs: suppress
|
||||
|
||||
|
@ -121,10 +122,9 @@ public:
|
|||
PRInt32 aModType) const;
|
||||
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
|
||||
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
|
||||
PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
|
||||
|
||||
// SetAttr override. C++ is stupid, so have to override both
|
||||
|
@ -491,25 +491,20 @@ nsHTMLImageElement::GetAttributeMappingFunction() const
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLImageElement::HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsHTMLImageElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
// If we are a map and get a mouse click, don't let it be handled by
|
||||
// the Generic Element as this could cause a click event to fire
|
||||
// twice, once by the image frame for the map and once by the Anchor
|
||||
// element. (bug 39723)
|
||||
if (NS_MOUSE_LEFT_CLICK == aEvent->message) {
|
||||
if (NS_MOUSE_LEFT_CLICK == aVisitor.mEvent->message) {
|
||||
PRBool isMap = PR_FALSE;
|
||||
GetIsMap(&isMap);
|
||||
if (isMap) {
|
||||
*aEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
|
||||
aFlags, aEventStatus);
|
||||
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
|
|
@ -84,6 +84,7 @@
|
|||
#include "nsLinebreakConverter.h" //to strip out carriage returns
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
|
@ -132,6 +133,13 @@ static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID);
|
|||
? ((bitfield) |= (0x01 << (field))) \
|
||||
: ((bitfield) &= ~(0x01 << (field))))
|
||||
|
||||
// First bits are needed for the control type.
|
||||
#define NS_OUTER_ACTIVATE_EVENT (1 << 9)
|
||||
#define NS_ORIGINAL_CHECKED_VALUE (1 << 10)
|
||||
#define NS_NO_CONTENT_DISPATCH (1 << 11)
|
||||
#define NS_CONTROL_TYPE(bits) ((bits) & ~( \
|
||||
NS_OUTER_ACTIVATE_EVENT | NS_ORIGINAL_CHECKED_VALUE | NS_NO_CONTENT_DISPATCH))
|
||||
|
||||
class nsHTMLInputElement : public nsGenericHTMLFormElement,
|
||||
public nsImageLoadingContent,
|
||||
public nsIDOMHTMLInputElement,
|
||||
|
@ -190,10 +198,10 @@ public:
|
|||
PRInt32 aModType) const;
|
||||
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
|
||||
virtual nsMapRuleToAttributesFunc GetAttributeMappingFunction() const;
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
PRBool aCompileEventHandlers);
|
||||
|
@ -1030,7 +1038,8 @@ nsHTMLInputElement::FireOnChange()
|
|||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent event(PR_TRUE, NS_FORM_CHANGE);
|
||||
nsCOMPtr<nsPresContext> presContext = GetPresContext();
|
||||
HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this), presContext,
|
||||
&event, nsnull, &status);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -1139,8 +1148,8 @@ nsHTMLInputElement::Select()
|
|||
nsEvent event(nsContentUtils::IsCallerChrome(), NS_FORM_SELECTED);
|
||||
|
||||
SET_BOOLBIT(mBitField, BF_HANDLING_SELECT_EVENT, PR_TRUE);
|
||||
rv = HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT,
|
||||
&status);
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this),
|
||||
presContext, &event, nsnull, &status);
|
||||
SET_BOOLBIT(mBitField, BF_HANDLING_SELECT_EVENT, PR_FALSE);
|
||||
}
|
||||
|
||||
|
@ -1234,8 +1243,8 @@ nsHTMLInputElement::Click()
|
|||
|
||||
SET_BOOLBIT(mBitField, BF_HANDLING_CLICK, PR_TRUE);
|
||||
|
||||
rv = HandleDOMEvent(context, &event, nsnull, NS_EVENT_FLAG_INIT,
|
||||
&status);
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this), context,
|
||||
&event, nsnull, &status);
|
||||
|
||||
SET_BOOLBIT(mBitField, BF_HANDLING_CLICK, PR_FALSE);
|
||||
}
|
||||
|
@ -1246,19 +1255,15 @@ nsHTMLInputElement::Click()
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsHTMLInputElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEventStatus);
|
||||
|
||||
// Do not process any DOM events if the element is disabled
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
PRBool disabled;
|
||||
nsresult rv = GetDisabled(&disabled);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (disabled) {
|
||||
//FIXME Allow submission etc. also when there is no prescontext, Bug 329509.
|
||||
if (disabled || !aVisitor.mPresContext) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1278,8 +1283,8 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
|
||||
// Don't allow mutation events which are targeted somewhere inside
|
||||
// <input>, except if they are dispatched to the element itself.
|
||||
if (!(NS_EVENT_FLAG_INIT & aFlags) &&
|
||||
aEvent->eventStructType == NS_MUTATION_EVENT) {
|
||||
if (aVisitor.mEvent->eventStructType == NS_MUTATION_EVENT &&
|
||||
aVisitor.mEvent->originalTarget != NS_STATIC_CAST(nsIContent*, this)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -1299,23 +1304,22 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
// This is a compatibility hack.
|
||||
//
|
||||
|
||||
// Track whether we're in the outermost HandleDOMEvent invocation that will
|
||||
// Track whether we're in the outermost Dispatch invocation that will
|
||||
// cause activation of the input. That is, if we're a click event, or a
|
||||
// DOMActivate that was dispatched directly, this will be set, but if we're
|
||||
// a DOMActivate dispatched from click handling, it will not be set.
|
||||
PRBool outerActivateEvent =
|
||||
!(aFlags & NS_EVENT_FLAG_CAPTURE) &&
|
||||
!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) &&
|
||||
(aEvent->message == NS_MOUSE_LEFT_CLICK ||
|
||||
(aEvent->message == NS_UI_ACTIVATE &&
|
||||
(aVisitor.mEvent->message == NS_MOUSE_LEFT_CLICK ||
|
||||
(aVisitor.mEvent->message == NS_UI_ACTIVATE &&
|
||||
!GET_BOOLBIT(mBitField, BF_IN_INTERNAL_ACTIVATE)));
|
||||
|
||||
if (outerActivateEvent) {
|
||||
aVisitor.mItemFlags |= NS_OUTER_ACTIVATE_EVENT;
|
||||
}
|
||||
|
||||
PRBool originalCheckedValue = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton;
|
||||
|
||||
if (outerActivateEvent) {
|
||||
|
||||
SET_BOOLBIT(mBitField, BF_CHECKED_IS_TOGGLED, PR_FALSE);
|
||||
|
||||
switch(mType) {
|
||||
|
@ -1333,8 +1337,10 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
if (container) {
|
||||
nsAutoString name;
|
||||
if (GetNameIfExists(name)) {
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton;
|
||||
container->GetCurrentRadioButton(name,
|
||||
getter_AddRefs(selectedRadioButton));
|
||||
aVisitor.mItemData = selectedRadioButton;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1361,25 +1367,38 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
} //switch
|
||||
}
|
||||
|
||||
if (originalCheckedValue) {
|
||||
aVisitor.mItemFlags |= NS_ORIGINAL_CHECKED_VALUE;
|
||||
}
|
||||
|
||||
// If NS_EVENT_FLAG_NO_CONTENT_DISPATCH is set we will not allow content to handle
|
||||
// this event. But to allow middle mouse button paste to work we must allow
|
||||
// middle clicks to go to text fields anyway.
|
||||
PRBool noContentDispatch = aEvent->flags & NS_EVENT_FLAG_NO_CONTENT_DISPATCH;
|
||||
if (aVisitor.mEvent->flags & NS_EVENT_FLAG_NO_CONTENT_DISPATCH) {
|
||||
aVisitor.mItemFlags |= NS_NO_CONTENT_DISPATCH;
|
||||
}
|
||||
if ((mType == NS_FORM_INPUT_TEXT || mType == NS_FORM_INPUT_PASSWORD) &&
|
||||
aEvent->message == NS_MOUSE_MIDDLE_CLICK) {
|
||||
aEvent->flags &= ~NS_EVENT_FLAG_NO_CONTENT_DISPATCH;
|
||||
aVisitor.mEvent->message == NS_MOUSE_MIDDLE_CLICK) {
|
||||
aVisitor.mEvent->flags &= ~NS_EVENT_FLAG_NO_CONTENT_DISPATCH;
|
||||
}
|
||||
|
||||
// We must cache type because mType may change during JS event (bug 2369)
|
||||
//
|
||||
PRInt32 oldType = mType;
|
||||
|
||||
// Try script event handlers first if its not a focus/blur event
|
||||
//we don't want the doc to get these
|
||||
rv = nsGenericHTMLFormElement::HandleDOMEvent(aPresContext, aEvent,
|
||||
aDOMEvent, aFlags,
|
||||
aEventStatus);
|
||||
aVisitor.mItemFlags |= NS_STATIC_CAST(PRUint8, mType);
|
||||
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLInputElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
if (!aVisitor.mPresContext) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult rv = NS_OK;
|
||||
PRBool outerActivateEvent = aVisitor.mItemFlags & NS_OUTER_ACTIVATE_EVENT;
|
||||
PRBool originalCheckedValue =
|
||||
aVisitor.mItemFlags & NS_ORIGINAL_CHECKED_VALUE;
|
||||
PRBool noContentDispatch = aVisitor.mItemFlags & NS_NO_CONTENT_DISPATCH;
|
||||
PRInt8 oldType = NS_CONTROL_TYPE(aVisitor.mItemFlags);
|
||||
// Ideally we would make the default action for click and space just dispatch
|
||||
// DOMActivate, and the default action for DOMActivate flip the checkbox/
|
||||
// radio state and fire onchange. However, for backwards compatibility, we
|
||||
|
@ -1387,12 +1406,12 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
// when space is pressed. So, we just nest the firing of DOMActivate inside
|
||||
// the click event handling, and allow cancellation of DOMActivate to cancel
|
||||
// the click.
|
||||
if (*aEventStatus != nsEventStatus_eConsumeNoDefault &&
|
||||
!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) &&
|
||||
aEvent->message == NS_MOUSE_LEFT_CLICK && mType != NS_FORM_INPUT_TEXT) {
|
||||
nsUIEvent actEvent(NS_IS_TRUSTED_EVENT(aEvent), NS_UI_ACTIVATE, 1);
|
||||
if (aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault &&
|
||||
mType != NS_FORM_INPUT_TEXT &&
|
||||
aVisitor.mEvent->message == NS_MOUSE_LEFT_CLICK) {
|
||||
nsUIEvent actEvent(NS_IS_TRUSTED_EVENT(aVisitor.mEvent), NS_UI_ACTIVATE, 1);
|
||||
|
||||
nsIPresShell *shell = aPresContext->GetPresShell();
|
||||
nsIPresShell *shell = aVisitor.mPresContext->GetPresShell();
|
||||
if (shell) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
SET_BOOLBIT(mBitField, BF_IN_INTERNAL_ACTIVATE, PR_TRUE);
|
||||
|
@ -1402,7 +1421,7 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
// If activate is cancelled, we must do the same as when click is
|
||||
// cancelled (revert the checkbox to its original value).
|
||||
if (status == nsEventStatus_eConsumeNoDefault)
|
||||
*aEventStatus = status;
|
||||
aVisitor.mEventStatus = status;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1422,14 +1441,17 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
}
|
||||
|
||||
// Reset the flag for other content besides this text field
|
||||
aEvent->flags |= noContentDispatch ? NS_EVENT_FLAG_NO_CONTENT_DISPATCH : NS_EVENT_FLAG_NONE;
|
||||
aVisitor.mEvent->flags |=
|
||||
noContentDispatch ? NS_EVENT_FLAG_NO_CONTENT_DISPATCH : NS_EVENT_FLAG_NONE;
|
||||
|
||||
// now check to see if the event was "cancelled"
|
||||
if (GET_BOOLBIT(mBitField, BF_CHECKED_IS_TOGGLED) && outerActivateEvent) {
|
||||
if (*aEventStatus == nsEventStatus_eConsumeNoDefault) {
|
||||
if (aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault) {
|
||||
// if it was cancelled and a radio button, then set the old
|
||||
// selected btn to TRUE. if it is a checkbox then set it to its
|
||||
// original value
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton =
|
||||
do_QueryInterface(aVisitor.mItemData);
|
||||
if (selectedRadioButton) {
|
||||
selectedRadioButton->SetChecked(PR_TRUE);
|
||||
// If this one is no longer a radio button we must reset it back to
|
||||
|
@ -1445,21 +1467,19 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
#ifdef ACCESSIBILITY
|
||||
// Fire an event to notify accessibility
|
||||
if (mType == NS_FORM_INPUT_CHECKBOX) {
|
||||
FireEventForAccessibility(aPresContext,
|
||||
FireEventForAccessibility(aVisitor.mPresContext,
|
||||
NS_LITERAL_STRING("CheckboxStateChange"));
|
||||
} else {
|
||||
FireEventForAccessibility(aPresContext,
|
||||
FireEventForAccessibility(aVisitor.mPresContext,
|
||||
NS_LITERAL_STRING("RadioStateChange"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv) &&
|
||||
!(aFlags & NS_EVENT_FLAG_CAPTURE) &&
|
||||
!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT)) {
|
||||
if (nsEventStatus_eIgnore == *aEventStatus) {
|
||||
switch (aEvent->message) {
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
if (nsEventStatus_eIgnore == aVisitor.mEventStatus) {
|
||||
switch (aVisitor.mEvent->message) {
|
||||
|
||||
case NS_FOCUS_CONTENT:
|
||||
{
|
||||
|
@ -1467,10 +1487,10 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
// child textfield or button. If that's the case, don't focus
|
||||
// this parent file control -- leave focus on the child.
|
||||
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
|
||||
if (formControlFrame && !(aFlags & NS_EVENT_FLAG_BUBBLE) &&
|
||||
ShouldFocus(this))
|
||||
if (formControlFrame && ShouldFocus(this) &&
|
||||
aVisitor.mEvent->originalTarget == NS_STATIC_CAST(nsINode*, this))
|
||||
formControlFrame->SetFocus(PR_TRUE, PR_TRUE);
|
||||
}
|
||||
}
|
||||
break; // NS_FOCUS_CONTENT
|
||||
|
||||
case NS_KEY_PRESS:
|
||||
|
@ -1478,11 +1498,11 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
{
|
||||
// For backwards compat, trigger checks/radios/buttons with
|
||||
// space or enter (bug 25300)
|
||||
nsKeyEvent * keyEvent = (nsKeyEvent *)aEvent;
|
||||
nsKeyEvent * keyEvent = (nsKeyEvent *)aVisitor.mEvent;
|
||||
|
||||
if ((aEvent->message == NS_KEY_PRESS &&
|
||||
if ((aVisitor.mEvent->message == NS_KEY_PRESS &&
|
||||
keyEvent->keyCode == NS_VK_RETURN) ||
|
||||
(aEvent->message == NS_KEY_UP &&
|
||||
(aVisitor.mEvent->message == NS_KEY_UP &&
|
||||
keyEvent->keyCode == NS_VK_SPACE)) {
|
||||
switch(mType) {
|
||||
case NS_FORM_INPUT_CHECKBOX:
|
||||
|
@ -1490,7 +1510,7 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
{
|
||||
// Checkbox and Radio try to submit on Enter press
|
||||
if (keyEvent->keyCode != NS_VK_SPACE) {
|
||||
MaybeSubmitForm(aPresContext);
|
||||
MaybeSubmitForm(aVisitor.mPresContext);
|
||||
|
||||
break; // If we are submitting, do not send click event
|
||||
}
|
||||
|
@ -1501,18 +1521,20 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
case NS_FORM_INPUT_SUBMIT:
|
||||
case NS_FORM_INPUT_IMAGE: // Bug 34418
|
||||
{
|
||||
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aEvent),
|
||||
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aVisitor.mEvent),
|
||||
NS_MOUSE_LEFT_CLICK, nsnull,
|
||||
nsMouseEvent::eReal);
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
|
||||
rv = HandleDOMEvent(aPresContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this),
|
||||
aVisitor.mPresContext, &event,
|
||||
nsnull, &status);
|
||||
} // case
|
||||
} // switch
|
||||
}
|
||||
if (aEvent->message == NS_KEY_PRESS && mType == NS_FORM_INPUT_RADIO &&
|
||||
!keyEvent->isAlt && !keyEvent->isControl && !keyEvent->isMeta) {
|
||||
if (aVisitor.mEvent->message == NS_KEY_PRESS &&
|
||||
mType == NS_FORM_INPUT_RADIO && !keyEvent->isAlt &&
|
||||
!keyEvent->isControl && !keyEvent->isMeta) {
|
||||
PRBool isMovingBack = PR_FALSE;
|
||||
switch (keyEvent->keyCode) {
|
||||
case NS_VK_UP:
|
||||
|
@ -1525,6 +1547,7 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
if (container) {
|
||||
nsAutoString name;
|
||||
if (GetNameIfExists(name)) {
|
||||
nsCOMPtr<nsIDOMHTMLInputElement> selectedRadioButton;
|
||||
container->GetNextRadioButton(name, isMovingBack, this,
|
||||
getter_AddRefs(selectedRadioButton));
|
||||
nsCOMPtr<nsIContent> radioContent =
|
||||
|
@ -1533,14 +1556,14 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
rv = selectedRadioButton->Focus();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aEvent),
|
||||
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aVisitor.mEvent),
|
||||
NS_MOUSE_LEFT_CLICK, nsnull,
|
||||
nsMouseEvent::eReal);
|
||||
rv = radioContent->HandleDOMEvent(aPresContext, &event,
|
||||
nsnull, NS_EVENT_FLAG_INIT,
|
||||
&status);
|
||||
rv = nsEventDispatcher::Dispatch(radioContent,
|
||||
aVisitor.mPresContext,
|
||||
&event, nsnull, &status);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
*aEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1562,7 +1585,7 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
* not submit, period.
|
||||
*/
|
||||
|
||||
if (aEvent->message == NS_KEY_PRESS &&
|
||||
if (aVisitor.mEvent->message == NS_KEY_PRESS &&
|
||||
(keyEvent->keyCode == NS_VK_RETURN ||
|
||||
keyEvent->keyCode == NS_VK_ENTER) &&
|
||||
(mType == NS_FORM_INPUT_TEXT ||
|
||||
|
@ -1572,21 +1595,17 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
PRBool isButton = PR_FALSE;
|
||||
// If this is an enter on the button of a file input, don't submit
|
||||
// -- that's supposed to put up the filepicker
|
||||
if (mType == NS_FORM_INPUT_FILE && aDOMEvent) {
|
||||
nsCOMPtr<nsIDOMNSEvent> nsEvent(do_QueryInterface(*aDOMEvent));
|
||||
if (nsEvent) {
|
||||
nsCOMPtr<nsIDOMEventTarget> originalTarget;
|
||||
nsEvent->GetOriginalTarget(getter_AddRefs(originalTarget));
|
||||
nsCOMPtr<nsIContent> maybeButton(do_QueryInterface(originalTarget));
|
||||
if (maybeButton) {
|
||||
nsAutoString type;
|
||||
maybeButton->GetAttr(kNameSpaceID_None, nsHTMLAtoms::type,
|
||||
type);
|
||||
isButton = type.EqualsLiteral("button");
|
||||
}
|
||||
if (mType == NS_FORM_INPUT_FILE) {
|
||||
nsCOMPtr<nsIContent> maybeButton =
|
||||
do_QueryInterface(aVisitor.mEvent->originalTarget);
|
||||
if (maybeButton) {
|
||||
nsAutoString type;
|
||||
maybeButton->GetAttr(kNameSpaceID_None, nsHTMLAtoms::type,
|
||||
type);
|
||||
isButton = type.EqualsLiteral("button");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!isButton) {
|
||||
nsIFrame* primaryFrame = GetPrimaryFrame(PR_FALSE);
|
||||
if (primaryFrame) {
|
||||
|
@ -1599,7 +1618,7 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
rv = MaybeSubmitForm(aPresContext);
|
||||
rv = MaybeSubmitForm(aVisitor.mPresContext);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
}
|
||||
|
@ -1607,6 +1626,7 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
} break; // NS_KEY_PRESS || NS_KEY_UP
|
||||
|
||||
// cancel all of these events for buttons
|
||||
//XXXsmaug Why?
|
||||
case NS_MOUSE_MIDDLE_BUTTON_DOWN:
|
||||
case NS_MOUSE_MIDDLE_BUTTON_UP:
|
||||
case NS_MOUSE_MIDDLE_DOUBLECLICK:
|
||||
|
@ -1614,15 +1634,11 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
case NS_MOUSE_RIGHT_BUTTON_DOWN:
|
||||
case NS_MOUSE_RIGHT_BUTTON_UP:
|
||||
{
|
||||
if (mType == NS_FORM_INPUT_BUTTON ||
|
||||
mType == NS_FORM_INPUT_RESET ||
|
||||
mType == NS_FORM_INPUT_SUBMIT ) {
|
||||
nsCOMPtr<nsIDOMNSEvent> nsevent;
|
||||
|
||||
if (aDOMEvent) {
|
||||
nsevent = do_QueryInterface(*aDOMEvent);
|
||||
}
|
||||
|
||||
if (mType == NS_FORM_INPUT_BUTTON ||
|
||||
mType == NS_FORM_INPUT_RESET ||
|
||||
mType == NS_FORM_INPUT_SUBMIT) {
|
||||
nsCOMPtr<nsIDOMNSEvent> nsevent =
|
||||
do_QueryInterface(aVisitor.mDOMEvent);
|
||||
if (nsevent) {
|
||||
nsevent->PreventBubble();
|
||||
} else {
|
||||
|
@ -1632,8 +1648,8 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (outerActivateEvent) {
|
||||
|
@ -1656,12 +1672,11 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
event.originator = this;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
|
||||
nsIPresShell *presShell = aPresContext->GetPresShell();
|
||||
nsIPresShell *presShell = aVisitor.mPresContext->GetPresShell();
|
||||
|
||||
// If |nsIPresShell::Destroy| has been called due to
|
||||
// handling the event (base class HandleDOMEvent, above),
|
||||
// the pres context will return a null pres shell. See
|
||||
// bug 125624.
|
||||
// handling the event the pres context will return a null
|
||||
// pres shell. See bug 125624.
|
||||
if (presShell) {
|
||||
nsCOMPtr<nsIContent> form(do_QueryInterface(mForm));
|
||||
presShell->HandleDOMEventWithTarget(form, &event, &status);
|
||||
|
@ -1673,17 +1688,16 @@ nsHTMLInputElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
break;
|
||||
} //switch
|
||||
} //click or outer activate event
|
||||
} else {
|
||||
if (outerActivateEvent &&
|
||||
(oldType == NS_FORM_INPUT_SUBMIT || oldType == NS_FORM_INPUT_IMAGE) &&
|
||||
mForm) {
|
||||
// tell the form to flush a possible pending submission.
|
||||
// the reason is that the script returned false (the event was
|
||||
// not ignored) so if there is a stored submission, it needs to
|
||||
// be submitted immediately.
|
||||
mForm->FlushPendingSubmission();
|
||||
}
|
||||
} //if
|
||||
} else if (outerActivateEvent &&
|
||||
(oldType == NS_FORM_INPUT_SUBMIT ||
|
||||
oldType == NS_FORM_INPUT_IMAGE) &&
|
||||
mForm) {
|
||||
// tell the form to flush a possible pending submission.
|
||||
// the reason is that the script returned false (the event was
|
||||
// not ignored) so if there is a stored submission, it needs to
|
||||
// be submitted immediately.
|
||||
mForm->FlushPendingSubmission();
|
||||
}
|
||||
} // if
|
||||
|
||||
return rv;
|
||||
|
@ -2058,12 +2072,9 @@ nsHTMLInputElement::FireEventForAccessibility(nsPresContext* aPresContext,
|
|||
const nsAString& aEventType)
|
||||
{
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager &&
|
||||
NS_SUCCEEDED(manager->CreateEvent(aPresContext, nsnull,
|
||||
NS_LITERAL_STRING("Events"),
|
||||
getter_AddRefs(event)))) {
|
||||
if (NS_SUCCEEDED(nsEventDispatcher::CreateEvent(aPresContext, nsnull,
|
||||
NS_LITERAL_STRING("Events"),
|
||||
getter_AddRefs(event)))) {
|
||||
event->InitEvent(aEventType, PR_TRUE, PR_TRUE);
|
||||
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
|
||||
|
@ -2072,9 +2083,7 @@ nsHTMLInputElement::FireEventForAccessibility(nsPresContext* aPresContext,
|
|||
}
|
||||
|
||||
nsISupports *target = NS_STATIC_CAST(nsIDOMHTMLInputElement*, this);
|
||||
PRBool defaultActionEnabled;
|
||||
aPresContext->EventStateManager()->DispatchNewEvent(target, event,
|
||||
&defaultActionEnabled);
|
||||
nsEventDispatcher::DispatchDOMEvent(target, nsnull, event, nsnull, nsnull);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
#include "nsIPresShell.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
class nsHTMLLabelElement : public nsGenericHTMLFormElement,
|
||||
public nsIDOMHTMLLabelElement
|
||||
|
@ -87,10 +87,9 @@ public:
|
|||
PRBool aCompileEventHandlers);
|
||||
virtual void UnbindFromTree(PRBool aDeep = PR_TRUE,
|
||||
PRBool aNullParent = PR_TRUE);
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
|
||||
virtual void SetFocus(nsPresContext* aContext);
|
||||
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
const nsAString& aValue, PRBool aNotify)
|
||||
|
@ -208,37 +207,26 @@ EventTargetIn(nsPresContext *aPresContext, nsEvent *aEvent,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLLabelElement::HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsHTMLLabelElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEventStatus);
|
||||
|
||||
nsresult rv = nsGenericHTMLFormElement::HandleDOMEvent(aPresContext, aEvent,
|
||||
aDOMEvent, aFlags,
|
||||
aEventStatus);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
if (mHandlingEvent ||
|
||||
*aEventStatus == nsEventStatus_eConsumeNoDefault ||
|
||||
(aEvent->message != NS_MOUSE_LEFT_CLICK &&
|
||||
aEvent->message != NS_FOCUS_CONTENT) ||
|
||||
aFlags & NS_EVENT_FLAG_CAPTURE ||
|
||||
!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT))
|
||||
(aVisitor.mEvent->message != NS_MOUSE_LEFT_CLICK &&
|
||||
aVisitor.mEvent->message != NS_FOCUS_CONTENT) ||
|
||||
aVisitor.mEventStatus == nsEventStatus_eConsumeNoDefault ||
|
||||
!aVisitor.mPresContext) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> content = GetForContent();
|
||||
if (content && !EventTargetIn(aPresContext, aEvent, content, this)) {
|
||||
if (content && !EventTargetIn(aVisitor.mPresContext, aVisitor.mEvent,
|
||||
content, this)) {
|
||||
mHandlingEvent = PR_TRUE;
|
||||
switch (aEvent->message) {
|
||||
switch (aVisitor.mEvent->message) {
|
||||
case NS_MOUSE_LEFT_CLICK:
|
||||
if (aEvent->eventStructType == NS_MOUSE_EVENT) {
|
||||
if (aVisitor.mEvent->eventStructType == NS_MOUSE_EVENT) {
|
||||
if (ShouldFocus(this)) {
|
||||
// Focus the for content.
|
||||
content->SetFocus(aPresContext);
|
||||
content->SetFocus(aVisitor.mPresContext);
|
||||
}
|
||||
|
||||
// Dispatch a new click event to |content|
|
||||
|
@ -247,9 +235,12 @@ nsHTMLLabelElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
// would do nothing. If we wanted to do something
|
||||
// sensible, we might send more events through like
|
||||
// this.) See bug 7554, bug 49897, and bug 96813.
|
||||
nsEventStatus status = *aEventStatus;
|
||||
rv = DispatchClickEvent(aPresContext, NS_STATIC_CAST(nsInputEvent*, aEvent),
|
||||
content, PR_FALSE, &status);
|
||||
nsEventStatus status = aVisitor.mEventStatus;
|
||||
// Ok to use aVisitor.mEvent as parameter because DispatchClickEvent
|
||||
// will actually create a new event.
|
||||
DispatchClickEvent(aVisitor.mPresContext,
|
||||
NS_STATIC_CAST(nsInputEvent*, aVisitor.mEvent),
|
||||
content, PR_FALSE, &status);
|
||||
// Do we care about the status this returned? I don't think we do...
|
||||
}
|
||||
break;
|
||||
|
@ -261,16 +252,17 @@ nsHTMLLabelElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
// Since focus doesn't bubble, this is basically the second part
|
||||
// of redirecting |SetFocus|.
|
||||
{
|
||||
nsEvent event(NS_IS_TRUSTED_EVENT(aEvent), NS_FOCUS_CONTENT);
|
||||
nsEventStatus status = *aEventStatus;
|
||||
rv = DispatchEvent(aPresContext, &event, content, PR_TRUE, &status);
|
||||
nsEvent event(NS_IS_TRUSTED_EVENT(aVisitor.mEvent), NS_FOCUS_CONTENT);
|
||||
nsEventStatus status = aVisitor.mEventStatus;
|
||||
DispatchEvent(aVisitor.mPresContext, &event,
|
||||
content, PR_TRUE, &status);
|
||||
// Do we care about the status this returned? I don't think we do...
|
||||
}
|
||||
break;
|
||||
}
|
||||
mHandlingEvent = PR_FALSE;
|
||||
}
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -107,10 +107,7 @@ public:
|
|||
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify);
|
||||
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
|
||||
protected:
|
||||
virtual void GetStyleSheetURL(PRBool* aIsInline,
|
||||
|
@ -325,14 +322,9 @@ nsHTMLLinkElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLLinkElement::HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsHTMLLinkElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
return HandleDOMEventForAnchors(aPresContext, aEvent, aDOMEvent,
|
||||
aFlags, aEventStatus);
|
||||
return PostHandleEventForAnchors(aVisitor);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
#include "nsISelectElement.h"
|
||||
#include "nsIDOMHTMLSelectElement.h"
|
||||
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
/**
|
||||
* The implementation of <optgroup>
|
||||
|
@ -80,10 +80,7 @@ public:
|
|||
PRBool aRemove);
|
||||
|
||||
// nsIContent
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
|
||||
virtual PRInt32 IntrinsicState() const;
|
||||
|
||||
|
@ -146,13 +143,11 @@ NS_IMPL_STRING_ATTR(nsHTMLOptGroupElement, Label, label)
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLOptGroupElement::HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsHTMLOptGroupElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
// Do not process any DOM events if the element is disabled
|
||||
// XXXsmaug This is not the right thing to do. But what is?
|
||||
PRBool disabled;
|
||||
nsresult rv = GetDisabled(&disabled);
|
||||
if (NS_FAILED(rv) || disabled) {
|
||||
|
@ -168,8 +163,7 @@ nsHTMLOptGroupElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
|
||||
aFlags, aEventStatus);
|
||||
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIScriptEventHandler.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
|
||||
//
|
||||
|
@ -208,7 +209,7 @@ nsHTMLScriptEventHandler::Invoke(nsISupports *aTargetObject,
|
|||
// Get the script context...
|
||||
nsCOMPtr<nsIDOMDocument> domdoc;
|
||||
nsCOMPtr<nsIScriptContext> scriptContext;
|
||||
nsIScriptGlobalObject *sgo;
|
||||
nsIScriptGlobalObject *sgo = nsnull;
|
||||
|
||||
mOuter->GetOwnerDocument(getter_AddRefs(domdoc));
|
||||
|
||||
|
@ -596,7 +597,8 @@ nsHTMLScriptElement::ScriptAvailable(nsresult aResult,
|
|||
event.fileName = fileName.get();
|
||||
|
||||
nsCOMPtr<nsPresContext> presContext = GetPresContext();
|
||||
HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this), presContext,
|
||||
&event, nsnull, &status);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -615,11 +617,16 @@ nsHTMLScriptElement::ScriptEvaluated(nsresult aResult,
|
|||
nsresult rv = NS_OK;
|
||||
if (!aIsInline) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent event(PR_TRUE,
|
||||
NS_SUCCEEDED(aResult) ? NS_SCRIPT_LOAD : NS_SCRIPT_ERROR);
|
||||
PRUint32 type = NS_SUCCEEDED(aResult) ? NS_SCRIPT_LOAD : NS_SCRIPT_ERROR;
|
||||
nsEvent event(PR_TRUE, type);
|
||||
if (type == NS_SCRIPT_LOAD) {
|
||||
// Load event doesn't bubble.
|
||||
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPresContext> presContext = GetPresContext();
|
||||
rv = HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT,
|
||||
&status);
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this), presContext,
|
||||
&event, nsnull, &status);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -84,7 +84,7 @@
|
|||
|
||||
#include "nsDOMError.h"
|
||||
#include "nsRuleData.h"
|
||||
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
class nsHTMLSelectElement;
|
||||
|
||||
|
@ -249,10 +249,8 @@ public:
|
|||
NS_DECL_NSIDOMNSXBLFORMCONTROL
|
||||
|
||||
// nsIContent
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
|
||||
virtual void SetFocus(nsPresContext* aPresContext);
|
||||
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
|
||||
|
@ -1817,13 +1815,11 @@ nsHTMLSelectElement::GetAttributeMappingFunction() const
|
|||
|
||||
|
||||
nsresult
|
||||
nsHTMLSelectElement::HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsHTMLSelectElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
// Do not process any DOM events if the element is disabled
|
||||
// XXXsmaug This is not the right thing to do. But what is?
|
||||
PRBool disabled;
|
||||
nsresult rv = GetDisabled(&disabled);
|
||||
if (NS_FAILED(rv) || disabled) {
|
||||
|
@ -1845,20 +1841,24 @@ nsHTMLSelectElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsHTMLSelectElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
// Must notify the frame that the blur event occurred
|
||||
// NOTE: At this point EventStateManager has not yet set the
|
||||
/// new content as having focus so this content is still considered
|
||||
// new content as having focus so this content is still considered
|
||||
// the focused element. So the ComboboxControlFrame tracks the focus
|
||||
// at a class level (Bug 32920)
|
||||
if ((nsEventStatus_eIgnore == *aEventStatus) &&
|
||||
!(aFlags & NS_EVENT_FLAG_CAPTURE) && !(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT) &&
|
||||
(aEvent->message == NS_BLUR_CONTENT) && formControlFrame) {
|
||||
nsIFormControlFrame* formControlFrame = GetFormControlFrame(PR_FALSE);
|
||||
if (nsEventStatus_eIgnore == aVisitor.mEventStatus &&
|
||||
(aVisitor.mEvent->message == NS_BLUR_CONTENT) && formControlFrame) {
|
||||
formControlFrame->SetFocus(PR_FALSE, PR_TRUE);
|
||||
}
|
||||
|
||||
return nsGenericHTMLFormElement::HandleDOMEvent(aPresContext, aEvent,
|
||||
aDOMEvent, aFlags,
|
||||
aEventStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIFormControl
|
||||
|
|
|
@ -69,10 +69,12 @@
|
|||
#include "nsIDOMText.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsITextContent.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
static NS_DEFINE_CID(kXULControllersCID, NS_XULCONTROLLERS_CID);
|
||||
|
||||
#define NS_NO_CONTENT_DISPATCH (1 << 0)
|
||||
|
||||
class nsHTMLTextAreaElement : public nsGenericHTMLFormElement,
|
||||
public nsIDOMHTMLTextAreaElement,
|
||||
|
@ -130,10 +132,10 @@ public:
|
|||
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
|
||||
PRInt32 aModType) const;
|
||||
NS_IMETHOD_(PRBool) IsAttributeMapped(const nsIAtom* aAttribute) const;
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
|
||||
virtual void SetFocus(nsPresContext* aPresContext);
|
||||
|
||||
virtual void DoneAddingChildren(PRBool aHaveNotified);
|
||||
|
@ -277,8 +279,8 @@ nsHTMLTextAreaElement::Select()
|
|||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsGUIEvent event(PR_TRUE, NS_FORM_SELECTED, nsnull);
|
||||
rv = HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT,
|
||||
&status);
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this), presContext,
|
||||
&event, nsnull, &status);
|
||||
|
||||
// If the DOM event was not canceled (e.g. by a JS event handler
|
||||
// returning false)
|
||||
|
@ -546,15 +548,11 @@ nsHTMLTextAreaElement::GetAttributeMappingFunction() const
|
|||
return &MapAttributesIntoRule;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsHTMLTextAreaElement::HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsHTMLTextAreaElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
// Do not process any DOM events if the element is disabled
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
PRBool disabled;
|
||||
nsresult rv = GetDisabled(&disabled);
|
||||
if (NS_FAILED(rv) || disabled) {
|
||||
|
@ -575,37 +573,39 @@ nsHTMLTextAreaElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
PRBool isSelectEvent = (aEvent->message == NS_FORM_SELECTED);
|
||||
// Don't dispatch a second select event if we are already handling
|
||||
// one.
|
||||
if (isSelectEvent && mHandlingSelect) {
|
||||
return NS_OK;
|
||||
if (aVisitor.mEvent->message == NS_FORM_SELECTED) {
|
||||
if (mHandlingSelect) {
|
||||
return NS_OK;
|
||||
}
|
||||
mHandlingSelect = PR_TRUE;
|
||||
}
|
||||
|
||||
// If NS_EVENT_FLAG_NO_CONTENT_DISPATCH is set we will not allow content to handle
|
||||
// this event. But to allow middle mouse button paste to work we must allow
|
||||
// middle clicks to go to text fields anyway.
|
||||
PRBool noContentDispatch = aEvent->flags & NS_EVENT_FLAG_NO_CONTENT_DISPATCH;
|
||||
if (aEvent->message == NS_MOUSE_MIDDLE_CLICK) {
|
||||
aEvent->flags &= ~NS_EVENT_FLAG_NO_CONTENT_DISPATCH;
|
||||
if (aVisitor.mEvent->flags & NS_EVENT_FLAG_NO_CONTENT_DISPATCH)
|
||||
aVisitor.mItemFlags |= NS_NO_CONTENT_DISPATCH;
|
||||
if (aVisitor.mEvent->message == NS_MOUSE_MIDDLE_CLICK) {
|
||||
aVisitor.mEvent->flags &= ~NS_EVENT_FLAG_NO_CONTENT_DISPATCH;
|
||||
}
|
||||
|
||||
if (isSelectEvent) {
|
||||
mHandlingSelect = PR_TRUE;
|
||||
}
|
||||
return nsGenericHTMLElement::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
rv = nsGenericHTMLFormElement::HandleDOMEvent(aPresContext, aEvent,
|
||||
aDOMEvent, aFlags,
|
||||
aEventStatus);
|
||||
|
||||
if (isSelectEvent) {
|
||||
nsresult
|
||||
nsHTMLTextAreaElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
if (aVisitor.mEvent->message == NS_FORM_SELECTED) {
|
||||
mHandlingSelect = PR_FALSE;
|
||||
}
|
||||
|
||||
// Reset the flag for other content besides this text field
|
||||
aEvent->flags |= noContentDispatch ? NS_EVENT_FLAG_NO_CONTENT_DISPATCH : NS_EVENT_FLAG_NONE;
|
||||
aVisitor.mEvent->flags |= (aVisitor.mItemFlags & NS_NO_CONTENT_DISPATCH)
|
||||
? NS_EVENT_FLAG_NO_CONTENT_DISPATCH : NS_EVENT_FLAG_NONE;
|
||||
|
||||
return rv;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -2909,29 +2909,19 @@ nsHTMLDocument::GetSelection(nsAString& aReturn)
|
|||
NS_IMETHODIMP
|
||||
nsHTMLDocument::CaptureEvents(PRInt32 aEventFlags)
|
||||
{
|
||||
nsIEventListenerManager *manager;
|
||||
|
||||
if (NS_OK == GetListenerManager(&manager)) {
|
||||
manager->CaptureEvent(aEventFlags);
|
||||
NS_RELEASE(manager);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return manager->CaptureEvent(aEventFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsHTMLDocument::ReleaseEvents(PRInt32 aEventFlags)
|
||||
{
|
||||
nsIEventListenerManager *manager;
|
||||
|
||||
if (NS_OK == GetListenerManager(&manager)) {
|
||||
manager->ReleaseEvent(aEventFlags);
|
||||
NS_RELEASE(manager);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
nsresult rv = GetListenerManager(PR_FALSE, getter_AddRefs(manager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return manager ? manager->ReleaseEvent(aEventFlags) : NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -231,7 +231,7 @@ nsSVGElement::UnsetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
|||
{
|
||||
if (aNamespaceID == kNameSpaceID_None && IsEventName(aName)) {
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
GetListenerManager(getter_AddRefs(manager));
|
||||
GetListenerManager(PR_FALSE, getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
nsIAtom* eventName = GetEventNameForAttr(aName);
|
||||
manager->RemoveScriptEventListener(eventName);
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "nsPresContext.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsIDOMText.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
typedef nsSVGElement nsSVGScriptElementBase;
|
||||
|
||||
|
@ -256,8 +257,8 @@ nsSVGScriptElement::ScriptAvailable(nsresult aResult,
|
|||
NS_ConvertUTF8toUTF16 fileName(spec);
|
||||
event.fileName = fileName.get();
|
||||
|
||||
HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT,
|
||||
&status);
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this), presContext,
|
||||
&event, nsnull, &status);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -286,8 +287,9 @@ nsSVGScriptElement::ScriptEvaluated(nsresult aResult,
|
|||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent event(PR_TRUE,
|
||||
NS_SUCCEEDED(aResult) ? NS_SCRIPT_LOAD : NS_SCRIPT_ERROR);
|
||||
rv = HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT,
|
||||
&status);
|
||||
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this),
|
||||
presContext, &event, nsnull, &status);
|
||||
}
|
||||
|
||||
return rv;
|
||||
|
|
|
@ -647,7 +647,7 @@ nsXBLBinding::InstallEventHandlers()
|
|||
|
||||
if (handlerChain) {
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
mBoundElement->GetListenerManager(getter_AddRefs(manager));
|
||||
mBoundElement->GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
||||
if (!manager)
|
||||
return;
|
||||
|
||||
|
|
|
@ -67,6 +67,7 @@
|
|||
#include "nsIXBLService.h"
|
||||
#include "nsIBindingManager.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
nsresult
|
||||
NS_NewXMLElement(nsIContent** aInstancePtrResult, nsINodeInfo *aNodeInfo)
|
||||
|
@ -254,35 +255,29 @@ nsXMLElement::MaybeTriggerAutoLink(nsIDocShell *aShell)
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsXMLElement::HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsXMLElement::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEventStatus);
|
||||
// Try script event handlers first
|
||||
nsresult ret = nsGenericElement::HandleDOMEvent(aPresContext, aEvent,
|
||||
aDOMEvent, aFlags,
|
||||
aEventStatus);
|
||||
|
||||
if (mIsLink && (NS_OK == ret) && (nsEventStatus_eIgnore == *aEventStatus) &&
|
||||
!(aFlags & NS_EVENT_FLAG_CAPTURE) && !(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT)) {
|
||||
nsresult rv = NS_OK;
|
||||
if (mIsLink && nsEventStatus_eIgnore == aVisitor.mEventStatus) {
|
||||
nsIDocument *document = GetCurrentDoc();
|
||||
switch (aEvent->message) {
|
||||
switch (aVisitor.mEvent->message) {
|
||||
case NS_MOUSE_LEFT_BUTTON_DOWN:
|
||||
{
|
||||
aPresContext->EventStateManager()->
|
||||
SetContentState(this, NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS);
|
||||
if (aVisitor.mPresContext) {
|
||||
aVisitor.mPresContext->EventStateManager()->
|
||||
SetContentState(this, NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS);
|
||||
|
||||
*aEventStatus = nsEventStatus_eConsumeDoDefault;
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeDoDefault;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case NS_MOUSE_LEFT_CLICK:
|
||||
{
|
||||
if (nsEventStatus_eConsumeNoDefault != *aEventStatus) {
|
||||
nsInputEvent* inputEvent = NS_STATIC_CAST(nsInputEvent*, aEvent);
|
||||
if (nsEventStatus_eConsumeNoDefault != aVisitor.mEventStatus &&
|
||||
aVisitor.mPresContext) {
|
||||
nsInputEvent* inputEvent =
|
||||
NS_STATIC_CAST(nsInputEvent*, aVisitor.mEvent);
|
||||
if (inputEvent->isControl || inputEvent->isMeta ||
|
||||
inputEvent->isAlt || inputEvent->isShift) {
|
||||
break; // let the click go through so we can handle it in JS/XUL
|
||||
|
@ -291,7 +286,7 @@ nsXMLElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
nsLinkVerb verb = eLinkVerb_Undefined; // basically means same as replace
|
||||
nsCOMPtr<nsIURI> uri = nsContentUtils::GetXLinkURI(this);
|
||||
if (!uri) {
|
||||
*aEventStatus = nsEventStatus_eConsumeDoDefault;
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeDoDefault;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -308,10 +303,10 @@ nsXMLElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
|
||||
nsAutoString target;
|
||||
GetAttr(kNameSpaceID_XLink, nsLayoutAtoms::_moz_target, target);
|
||||
ret = TriggerLink(aPresContext, verb, uri,
|
||||
target, PR_TRUE, PR_TRUE);
|
||||
rv = TriggerLink(aVisitor.mPresContext, verb, uri,
|
||||
target, PR_TRUE, PR_TRUE);
|
||||
|
||||
*aEventStatus = nsEventStatus_eConsumeDoDefault;
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeDoDefault;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -321,25 +316,27 @@ nsXMLElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
break;
|
||||
|
||||
case NS_KEY_PRESS:
|
||||
if (aEvent->eventStructType == NS_KEY_EVENT) {
|
||||
nsKeyEvent* keyEvent = NS_STATIC_CAST(nsKeyEvent*, aEvent);
|
||||
if (aVisitor.mEvent->eventStructType == NS_KEY_EVENT &&
|
||||
aVisitor.mPresContext) {
|
||||
nsKeyEvent* keyEvent = NS_STATIC_CAST(nsKeyEvent*, aVisitor.mEvent);
|
||||
if (keyEvent->keyCode == NS_VK_RETURN) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
|
||||
//fire click
|
||||
nsGUIEvent* guiEvent = NS_STATIC_CAST(nsGUIEvent*, aEvent);
|
||||
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aEvent), NS_MOUSE_LEFT_CLICK,
|
||||
nsGUIEvent* guiEvent = NS_STATIC_CAST(nsGUIEvent*, aVisitor.mEvent);
|
||||
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aVisitor.mEvent),
|
||||
NS_MOUSE_LEFT_CLICK,
|
||||
guiEvent->widget, nsMouseEvent::eReal);
|
||||
event.refPoint = aEvent->refPoint;
|
||||
event.refPoint = aVisitor.mEvent->refPoint;
|
||||
event.clickCount = 1;
|
||||
event.isShift = keyEvent->isShift;
|
||||
event.isControl = keyEvent->isControl;
|
||||
event.isAlt = keyEvent->isAlt;
|
||||
event.isMeta = keyEvent->isMeta;
|
||||
|
||||
nsIPresShell *presShell = aPresContext->GetPresShell();
|
||||
nsIPresShell *presShell = aVisitor.mPresContext->GetPresShell();
|
||||
if (presShell) {
|
||||
ret = presShell->HandleDOMEventWithTarget(this, &event, &status);
|
||||
rv = presShell->HandleDOMEventWithTarget(this, &event, &status);
|
||||
// presShell may no longer be alive, don't use it here
|
||||
// unless you keep a reference.
|
||||
}
|
||||
|
@ -349,24 +346,28 @@ nsXMLElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
|
||||
case NS_MOUSE_ENTER_SYNTH:
|
||||
{
|
||||
nsCOMPtr<nsIURI> uri = nsContentUtils::GetXLinkURI(this);
|
||||
if (!uri) {
|
||||
*aEventStatus = nsEventStatus_eConsumeDoDefault;
|
||||
break;
|
||||
}
|
||||
if (aVisitor.mPresContext) {
|
||||
nsCOMPtr<nsIURI> uri = nsContentUtils::GetXLinkURI(this);
|
||||
if (!uri) {
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeDoDefault;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = TriggerLink(aPresContext, eLinkVerb_Replace, uri,
|
||||
EmptyString(), PR_FALSE, PR_TRUE);
|
||||
|
||||
*aEventStatus = nsEventStatus_eConsumeDoDefault;
|
||||
rv = TriggerLink(aVisitor.mPresContext, eLinkVerb_Replace, uri,
|
||||
EmptyString(), PR_FALSE, PR_TRUE);
|
||||
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeDoDefault;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
// XXX this doesn't seem to do anything yet
|
||||
case NS_MOUSE_EXIT_SYNTH:
|
||||
{
|
||||
ret = LeaveLink(aPresContext);
|
||||
*aEventStatus = nsEventStatus_eConsumeDoDefault;
|
||||
if (aVisitor.mPresContext) {
|
||||
rv = LeaveLink(aVisitor.mPresContext);
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeDoDefault;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -375,7 +376,7 @@ nsXMLElement::HandleDOMEvent(nsPresContext* aPresContext,
|
|||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
|
|
@ -77,10 +77,7 @@ public:
|
|||
virtual nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
|
||||
nsIAtom* aPrefix, const nsAString& aValue,
|
||||
PRBool aNotify);
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
|
||||
|
||||
protected:
|
||||
|
|
|
@ -89,6 +89,7 @@
|
|||
#include "nsIJSContextStack.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsIDOMUserDataHandler.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
// XXX The XML world depends on the html atoms
|
||||
#include "nsHTMLAtoms.h"
|
||||
|
@ -665,7 +666,8 @@ nsXMLDocument::EndLoad()
|
|||
|
||||
nsCxPusher pusher(sgo);
|
||||
|
||||
HandleDOMEvent(nsnull, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIDocument*, this), nsnull,
|
||||
&event, nsnull, &status);
|
||||
}
|
||||
nsDocument::EndLoad();
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "nsDOMAttributeMap.h"
|
||||
#include "nsUnicharUtils.h"
|
||||
#include "nsLayoutAtoms.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
nsXTFElementWrapper::nsXTFElementWrapper(nsINodeInfo* aNodeInfo)
|
||||
: nsXTFElementWrapperBase(aNodeInfo),
|
||||
|
@ -751,45 +752,27 @@ nsXTFElementWrapper::HandledByInner(nsIAtom *attr) const
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsXTFElementWrapper::HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsXTFElementWrapper::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
nsresult rv = nsXTFElementWrapperBase::HandleDOMEvent(aPresContext, aEvent,
|
||||
aDOMEvent, aFlags,
|
||||
aEventStatus);
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (NS_FAILED(rv) ||
|
||||
(nsEventStatus_eIgnore != *aEventStatus) ||
|
||||
!(mNotificationMask & nsIXTFElement::NOTIFY_HANDLE_DEFAULT) ||
|
||||
(aFlags & (NS_EVENT_FLAG_SYSTEM_EVENT | NS_EVENT_FLAG_CAPTURE)))
|
||||
return rv;
|
||||
|
||||
nsIDOMEvent* domEvent = nsnull;
|
||||
if (!aDOMEvent)
|
||||
aDOMEvent = &domEvent;
|
||||
|
||||
if (!*aDOMEvent) {
|
||||
if (!aVisitor.mDOMEvent) {
|
||||
// We haven't made a DOMEvent yet. Force making one now.
|
||||
nsCOMPtr<nsIEventListenerManager> listenerManager;
|
||||
if (NS_FAILED(rv = GetListenerManager(getter_AddRefs(listenerManager))))
|
||||
return rv;
|
||||
|
||||
if (NS_FAILED(rv = listenerManager->CreateEvent(aPresContext, aEvent,
|
||||
EmptyString(), aDOMEvent)))
|
||||
if (NS_FAILED(rv = nsEventDispatcher::CreateEvent(aVisitor.mPresContext,
|
||||
aVisitor.mEvent,
|
||||
EmptyString(),
|
||||
&aVisitor.mDOMEvent)))
|
||||
return rv;
|
||||
}
|
||||
if (!*aDOMEvent)
|
||||
if (!aVisitor.mDOMEvent)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool defaultHandled = PR_FALSE;
|
||||
nsIXTFElement * xtfElement = GetXTFElement();
|
||||
nsIXTFElement* xtfElement = GetXTFElement();
|
||||
if (xtfElement)
|
||||
rv = xtfElement->HandleDefault(*aDOMEvent, &defaultHandled);
|
||||
rv = xtfElement->HandleDefault(aVisitor.mDOMEvent, &defaultHandled);
|
||||
if (defaultHandled)
|
||||
*aEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
aVisitor.mEventStatus = nsEventStatus_eConsumeNoDefault;
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
|
@ -123,10 +123,7 @@ public:
|
|||
// nsIClassInfo interface
|
||||
NS_DECL_NSICLASSINFO
|
||||
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
|
||||
nsresult CloneState(nsIDOMElement *aElement)
|
||||
{
|
||||
|
|
|
@ -151,6 +151,7 @@
|
|||
#include "nsNodeInfoManager.h"
|
||||
#include "nsXBLBinding.h"
|
||||
#include "nsRange.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
/**
|
||||
* Three bits are used for XUL Element's lazy state.
|
||||
|
@ -529,7 +530,7 @@ nsXULElement::GetEventListenerManagerForAttr(nsIEventListenerManager** aManager,
|
|||
if (!receiver)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
nsresult rv = receiver->GetListenerManager(aManager);
|
||||
nsresult rv = receiver->GetListenerManager(PR_TRUE, aManager);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
NS_ADDREF(*aTarget = window);
|
||||
}
|
||||
|
@ -543,9 +544,15 @@ nsXULElement::GetEventListenerManagerForAttr(nsIEventListenerManager** aManager,
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsXULElement::GetListenerManager(nsIEventListenerManager** aResult)
|
||||
nsXULElement::GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult)
|
||||
{
|
||||
if (!mListenerManager) {
|
||||
if (!aCreateIfNotFound) {
|
||||
*aResult = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv =
|
||||
NS_NewEventListenerManager(getter_AddRefs(mListenerManager));
|
||||
if (NS_FAILED(rv))
|
||||
|
@ -1024,7 +1031,7 @@ nsXULElement::RemoveChildAt(PRUint32 aIndex, PRBool aNotify)
|
|||
do_QueryInterface(NS_STATIC_CAST(nsIContent*, this));
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
oldKid->HandleDOMEvent(nsnull, &mutation, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(oldKid, nsnull, &mutation, nsnull, &status);
|
||||
}
|
||||
|
||||
// On the removal of a <treeitem>, <treechildren>, or <treecell> element,
|
||||
|
@ -1448,8 +1455,8 @@ nsXULElement::UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aName, PRBool aNotify)
|
|||
mutation.mAttrChange = nsIDOMMutationEvent::REMOVAL;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
this->HandleDOMEvent(nsnull, &mutation, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this),
|
||||
nsnull, &mutation, nsnull, &status);
|
||||
}
|
||||
|
||||
nsXBLBinding *binding = doc->BindingManager()->GetBinding(this);
|
||||
|
@ -1678,278 +1685,57 @@ nsXULElement::List(FILE* out, PRInt32 aIndent) const
|
|||
#endif
|
||||
|
||||
nsresult
|
||||
nsXULElement::HandleDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent, PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsXULElement::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
// Make sure to tell the event that dispatch has started.
|
||||
NS_MARK_EVENT_DISPATCH_STARTED(aEvent);
|
||||
|
||||
nsresult ret = NS_OK;
|
||||
|
||||
PRBool retarget = PR_FALSE;
|
||||
PRBool externalDOMEvent = PR_FALSE;
|
||||
nsCOMPtr<nsIDOMEventTarget> oldTarget;
|
||||
|
||||
nsIDOMEvent* domEvent = nsnull;
|
||||
if (NS_EVENT_FLAG_INIT & aFlags) {
|
||||
nsIAtom* tag = Tag();
|
||||
if (aEvent->message == NS_XUL_COMMAND && tag != nsXULAtoms::command) {
|
||||
// See if we have a command elt. If so, we execute on the command instead
|
||||
// of on our content element.
|
||||
nsAutoString command;
|
||||
GetAttr(kNameSpaceID_None, nsXULAtoms::command, command);
|
||||
if (!command.IsEmpty()) {
|
||||
// XXX sXBL/XBL2 issue! Owner or current document?
|
||||
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(GetCurrentDoc()));
|
||||
nsCOMPtr<nsIDOMElement> commandElt;
|
||||
domDoc->GetElementById(command, getter_AddRefs(commandElt));
|
||||
nsCOMPtr<nsIContent> commandContent(do_QueryInterface(commandElt));
|
||||
if (commandContent &&
|
||||
commandContent->IsContentOfType(nsIContent::eXUL) &&
|
||||
commandContent->Tag() == nsXULAtoms::command) {
|
||||
return commandContent->HandleDOMEvent(aPresContext, aEvent, nsnull, NS_EVENT_FLAG_INIT, aEventStatus);
|
||||
}
|
||||
else {
|
||||
NS_WARNING("A XUL element is attached to a command that doesn't exist!\n");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (aDOMEvent) {
|
||||
if (*aDOMEvent)
|
||||
externalDOMEvent = PR_TRUE;
|
||||
}
|
||||
else
|
||||
aDOMEvent = &domEvent;
|
||||
|
||||
aEvent->flags |= aFlags;
|
||||
aFlags &= ~(NS_EVENT_FLAG_CANT_BUBBLE | NS_EVENT_FLAG_CANT_CANCEL);
|
||||
aFlags |= NS_EVENT_FLAG_BUBBLE | NS_EVENT_FLAG_CAPTURE;
|
||||
|
||||
if (!externalDOMEvent) {
|
||||
// In order for the event to have a proper target for events that don't go through
|
||||
// the presshell (onselect, oncommand, oncreate, ondestroy) we need to set our target
|
||||
// ourselves. Also, key sets and menus don't have frames and therefore need their
|
||||
// targets explicitly specified.
|
||||
//
|
||||
// We need this for drag&drop as well since the mouse may have moved into a different
|
||||
// frame between the initial mouseDown and the generation of the drag gesture.
|
||||
// Obviously, the target should be the content/frame where the mouse was depressed,
|
||||
// not one computed by the current mouse location.
|
||||
if (aEvent->message == NS_XUL_COMMAND || aEvent->message == NS_XUL_POPUP_SHOWING ||
|
||||
aEvent->message == NS_XUL_POPUP_SHOWN || aEvent->message == NS_XUL_POPUP_HIDING ||
|
||||
aEvent->message == NS_XUL_POPUP_HIDDEN || aEvent->message == NS_FORM_SELECTED ||
|
||||
aEvent->message == NS_XUL_BROADCAST || aEvent->message == NS_XUL_COMMAND_UPDATE ||
|
||||
aEvent->message == NS_XUL_CLICK || aEvent->message == NS_DRAGDROP_GESTURE ||
|
||||
tag == nsXULAtoms::menu || tag == nsXULAtoms::menuitem ||
|
||||
tag == nsXULAtoms::menulist || tag == nsXULAtoms::menubar ||
|
||||
tag == nsXULAtoms::menupopup || tag == nsXULAtoms::key ||
|
||||
tag == nsXULAtoms::keyset) {
|
||||
|
||||
nsCOMPtr<nsIEventListenerManager> listenerManager;
|
||||
if (NS_FAILED(ret = GetListenerManager(getter_AddRefs(listenerManager)))) {
|
||||
NS_ERROR("Unable to instantiate a listener manager on this event.");
|
||||
return ret;
|
||||
}
|
||||
if (NS_FAILED(ret = listenerManager->CreateEvent(aPresContext,
|
||||
aEvent,
|
||||
EmptyString(),
|
||||
aDOMEvent))) {
|
||||
NS_ERROR("This event will fail without the ability to create the event early.");
|
||||
return ret;
|
||||
}
|
||||
|
||||
// We need to explicitly set the target here, because the
|
||||
// DOM implementation will try to compute the target from
|
||||
// the frame. If we don't have a frame (e.g., we're a
|
||||
// menu), then that breaks.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(domEvent);
|
||||
if (privateEvent) {
|
||||
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(NS_STATIC_CAST(nsIContent *, this)));
|
||||
privateEvent->SetTarget(target);
|
||||
}
|
||||
else
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// if we are a XUL click, we have the private event set.
|
||||
// now switch to a left mouse click for the duration of the event
|
||||
if (aEvent->message == NS_XUL_CLICK)
|
||||
aEvent->message = NS_MOUSE_LEFT_CLICK;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (aEvent->message == NS_IMAGE_LOAD)
|
||||
return NS_OK; // Don't let these events bubble or be captured. Just allow them
|
||||
// on the target image.
|
||||
|
||||
// Find out whether we're anonymous.
|
||||
// XXX Workaround bug 280541 without regressing bug 251197
|
||||
if (nsGenericElement::IsNativeAnonymous()) {
|
||||
retarget = PR_TRUE;
|
||||
} else {
|
||||
nsIContent* parent = GetParent();
|
||||
if (parent) {
|
||||
if (*aDOMEvent) {
|
||||
(*aDOMEvent)->GetTarget(getter_AddRefs(oldTarget));
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(oldTarget));
|
||||
if (content && content->GetBindingParent() == parent)
|
||||
retarget = PR_TRUE;
|
||||
} else if (GetBindingParent() == parent) {
|
||||
retarget = PR_TRUE;
|
||||
aVisitor.mForceContentDispatch = PR_TRUE; //FIXME! Bug 329119
|
||||
nsIAtom* tag = Tag();
|
||||
if (aVisitor.mEvent->message == NS_XUL_COMMAND &&
|
||||
aVisitor.mEvent->originalTarget == NS_STATIC_CAST(nsIContent*, this) &&
|
||||
tag != nsXULAtoms::command) {
|
||||
// See if we have a command elt. If so, we execute on the command
|
||||
// instead of on our content element.
|
||||
nsAutoString command;
|
||||
GetAttr(kNameSpaceID_None, nsXULAtoms::command, command);
|
||||
if (!command.IsEmpty()) {
|
||||
aVisitor.mCanHandle = PR_FALSE;
|
||||
// XXX sXBL/XBL2 issue! Owner or current document?
|
||||
nsCOMPtr<nsIDOMDocument> domDoc(do_QueryInterface(GetCurrentDoc()));
|
||||
nsCOMPtr<nsIDOMElement> commandElt;
|
||||
domDoc->GetElementById(command, getter_AddRefs(commandElt));
|
||||
nsCOMPtr<nsIContent> commandContent(do_QueryInterface(commandElt));
|
||||
if (commandContent &&
|
||||
commandContent->IsContentOfType(nsIContent::eXUL) &&
|
||||
commandContent->Tag() == nsXULAtoms::command) {
|
||||
// Reusing the event here, but DISPATCH_DONE/STARTED hack
|
||||
// is needed.
|
||||
NS_MARK_EVENT_DISPATCH_DONE(aVisitor.mEvent);
|
||||
aVisitor.mEvent->flags &=
|
||||
~NS_EVENT_FLAG_STOP_DISPATCH_IMMEDIATELY;
|
||||
// Dispatch will set the right target.
|
||||
aVisitor.mEvent->target = nsnull;
|
||||
nsEventDispatcher::Dispatch(commandContent,
|
||||
aVisitor.mPresContext,
|
||||
aVisitor.mEvent,
|
||||
aVisitor.mDOMEvent,
|
||||
&aVisitor.mEventStatus);
|
||||
NS_MARK_EVENT_DISPATCH_STARTED(aVisitor.mEvent);
|
||||
} else {
|
||||
NS_WARNING("A XUL element is attached to a command that doesn't exist!\n");
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// determine the parent:
|
||||
nsCOMPtr<nsIContent> parent;
|
||||
// XXX sXBL/XBL2 issue! Owner or current document?
|
||||
nsIDocument* doc = GetCurrentDoc();
|
||||
if (doc) {
|
||||
// check for an anonymous parent
|
||||
doc->BindingManager()->GetInsertionParent(this,
|
||||
getter_AddRefs(parent));
|
||||
// if we are a XUL click, we have the private event set.
|
||||
// now switch to a left mouse click for the duration of the event
|
||||
//FIXME remove NS_XUL_CLICK, Bug 329512.
|
||||
if (aVisitor.mEvent->message == NS_XUL_CLICK) {
|
||||
aVisitor.mEvent->message = NS_MOUSE_LEFT_CLICK;
|
||||
}
|
||||
|
||||
if (!parent) {
|
||||
// if we didn't find an anonymous parent, use the explicit one,
|
||||
// whether it's null or not...
|
||||
parent = GetParent();
|
||||
}
|
||||
|
||||
if (retarget || (parent != GetParent())) {
|
||||
if (!*aDOMEvent) {
|
||||
// We haven't made a DOMEvent yet. Force making one now.
|
||||
nsCOMPtr<nsIEventListenerManager> listenerManager;
|
||||
if (NS_FAILED(ret = GetListenerManager(getter_AddRefs(listenerManager)))) {
|
||||
return ret;
|
||||
}
|
||||
if (NS_FAILED(ret = listenerManager->CreateEvent(aPresContext,
|
||||
aEvent,
|
||||
EmptyString(),
|
||||
aDOMEvent)))
|
||||
return ret;
|
||||
|
||||
if (!*aDOMEvent) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent =
|
||||
do_QueryInterface(*aDOMEvent);
|
||||
if (!privateEvent) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
(*aDOMEvent)->GetTarget(getter_AddRefs(oldTarget));
|
||||
|
||||
PRBool hasOriginal;
|
||||
privateEvent->HasOriginalTarget(&hasOriginal);
|
||||
|
||||
if (!hasOriginal)
|
||||
privateEvent->SetOriginalTarget(oldTarget);
|
||||
|
||||
if (retarget) {
|
||||
nsCOMPtr<nsIDOMEventTarget> target =
|
||||
do_QueryInterface(GetParent());
|
||||
privateEvent->SetTarget(target);
|
||||
}
|
||||
}
|
||||
|
||||
//Capturing stage evaluation
|
||||
if (NS_EVENT_FLAG_CAPTURE & aFlags) {
|
||||
//Initiate capturing phase. Special case first call to document
|
||||
if (parent) {
|
||||
parent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags & NS_EVENT_CAPTURE_MASK, aEventStatus);
|
||||
}
|
||||
else if (doc) {
|
||||
ret = doc->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
|
||||
aFlags & NS_EVENT_CAPTURE_MASK,
|
||||
aEventStatus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (retarget) {
|
||||
// The event originated beneath us, and we performed a retargeting.
|
||||
// We need to restore the original target of the event.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(*aDOMEvent);
|
||||
if (privateEvent)
|
||||
privateEvent->SetTarget(oldTarget);
|
||||
}
|
||||
|
||||
//Local handling stage
|
||||
if (mListenerManager && !(aEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH)) {
|
||||
aEvent->flags |= aFlags;
|
||||
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(NS_STATIC_CAST(nsIContent *, this)));
|
||||
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, target, aFlags, aEventStatus);
|
||||
aEvent->flags &= ~aFlags;
|
||||
}
|
||||
|
||||
if (retarget) {
|
||||
// The event originated beneath us, and we need to perform a
|
||||
// retargeting.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(*aDOMEvent);
|
||||
if (privateEvent) {
|
||||
nsCOMPtr<nsIDOMEventTarget> parentTarget =
|
||||
do_QueryInterface(GetParent());
|
||||
privateEvent->SetTarget(parentTarget);
|
||||
}
|
||||
}
|
||||
|
||||
//Bubbling stage
|
||||
if (NS_EVENT_FLAG_BUBBLE & aFlags) {
|
||||
if (parent != nsnull) {
|
||||
// We have a parent. Let them field the event.
|
||||
ret = parent->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
|
||||
aFlags & NS_EVENT_BUBBLE_MASK, aEventStatus);
|
||||
}
|
||||
else if (IsInDoc()) {
|
||||
// We must be the document root. The event should bubble to the
|
||||
// document.
|
||||
ret = GetCurrentDoc()->HandleDOMEvent(aPresContext, aEvent, aDOMEvent,
|
||||
aFlags & NS_EVENT_BUBBLE_MASK, aEventStatus);
|
||||
}
|
||||
}
|
||||
|
||||
if (retarget) {
|
||||
// The event originated beneath us, and we performed a retargeting.
|
||||
// We need to restore the original target of the event.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(*aDOMEvent);
|
||||
if (privateEvent)
|
||||
privateEvent->SetTarget(oldTarget);
|
||||
}
|
||||
|
||||
if (NS_EVENT_FLAG_INIT & aFlags) {
|
||||
// We're leaving the DOM event loop so if we created a DOM event,
|
||||
// release here. If externalDOMEvent is set the event was passed in
|
||||
// and we don't own it
|
||||
if (*aDOMEvent && !externalDOMEvent) {
|
||||
nsrefcnt rc;
|
||||
NS_RELEASE2(*aDOMEvent, rc);
|
||||
if (0 != rc) {
|
||||
// Okay, so someone in the DOM loop (a listener, JS object)
|
||||
// still has a ref to the DOM Event but the internal data
|
||||
// hasn't been malloc'd. Force a copy of the data here so the
|
||||
// DOM Event is still valid.
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent =
|
||||
do_QueryInterface(*aDOMEvent);
|
||||
if (privateEvent) {
|
||||
privateEvent->DuplicatePrivateData();
|
||||
}
|
||||
}
|
||||
aDOMEvent = nsnull;
|
||||
}
|
||||
|
||||
// Now that we're done with this event, remove the flag that says
|
||||
// we're in the process of dispatching this event.
|
||||
NS_MARK_EVENT_DISPATCH_DONE(aEvent);
|
||||
}
|
||||
|
||||
return ret;
|
||||
return nsGenericElement::PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsXULElement::RangeAdd(nsIDOMRange* aRange)
|
||||
{
|
||||
|
@ -2404,23 +2190,24 @@ nsXULElement::Click()
|
|||
nsnull, nsMouseEvent::eReal);
|
||||
nsMouseEvent eventUp(isCallerChrome, NS_MOUSE_LEFT_BUTTON_UP,
|
||||
nsnull, nsMouseEvent::eReal);
|
||||
//FIXME remove NS_XUL_CLICK, Bug 329512.
|
||||
nsMouseEvent eventClick(isCallerChrome, NS_XUL_CLICK, nsnull,
|
||||
nsMouseEvent::eReal);
|
||||
|
||||
// send mouse down
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
HandleDOMEvent(context, &eventDown, nsnull, NS_EVENT_FLAG_INIT,
|
||||
&status);
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this),
|
||||
context, &eventDown, nsnull, &status);
|
||||
|
||||
// send mouse up
|
||||
status = nsEventStatus_eIgnore; // reset status
|
||||
HandleDOMEvent(context, &eventUp, nsnull, NS_EVENT_FLAG_INIT,
|
||||
&status);
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this),
|
||||
context, &eventUp, nsnull, &status);
|
||||
|
||||
// send mouse click
|
||||
status = nsEventStatus_eIgnore; // reset status
|
||||
HandleDOMEvent(context, &eventClick, nsnull, NS_EVENT_FLAG_INIT,
|
||||
&status);
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this),
|
||||
context, &eventClick, nsnull, &status);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2443,8 +2230,8 @@ nsXULElement::DoCommand()
|
|||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsMouseEvent event(PR_TRUE, NS_XUL_COMMAND, nsnull,
|
||||
nsMouseEvent::eReal);
|
||||
HandleDOMEvent(context, &event, nsnull, NS_EVENT_FLAG_INIT,
|
||||
&status);
|
||||
nsEventDispatcher::Dispatch(NS_STATIC_CAST(nsIContent*, this),
|
||||
context, &event, nsnull, &status);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2516,15 +2303,16 @@ nsXULElement::AddPopupListener(nsIAtom* aName)
|
|||
// nsXULElement::nsIChromeEventHandler
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMETHODIMP nsXULElement::HandleChromeEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent, PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
NS_IMETHODIMP
|
||||
nsXULElement::PreHandleChromeEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
// XXX This is a disgusting hack to prevent the doc from going
|
||||
// away until after we've finished handling the event.
|
||||
// We will be coming up with a better general solution later.
|
||||
nsCOMPtr<nsIDocument> kungFuDeathGrip(GetCurrentDoc());
|
||||
return HandleDOMEvent(aPresContext, aEvent, aDOMEvent, aFlags,aEventStatus);
|
||||
return PreHandleEvent(aVisitor);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULElement::PostHandleChromeEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -467,6 +467,11 @@ public:
|
|||
virtual PRUint32 GetChildCount() const;
|
||||
virtual nsIContent *GetChildAt(PRUint32 aIndex) const;
|
||||
virtual PRInt32 IndexOf(nsIContent* aPossibleChild) const;
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual nsresult GetEventListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aRes) {
|
||||
return GetListenerManager(aCreateIfNotFound, aRes);
|
||||
}
|
||||
|
||||
// nsIContent
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
|
@ -501,11 +506,6 @@ public:
|
|||
{
|
||||
}
|
||||
#endif
|
||||
virtual nsresult HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
|
||||
virtual nsresult RangeAdd(nsIDOMRange* aRange);
|
||||
virtual void RangeRemove(nsIDOMRange* aRange);
|
||||
|
@ -515,7 +515,8 @@ public:
|
|||
|
||||
virtual nsIContent *GetBindingParent() const;
|
||||
virtual PRBool IsContentOfType(PRUint32 aFlags) const;
|
||||
virtual nsresult GetListenerManager(nsIEventListenerManager** aResult);
|
||||
virtual nsresult GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult);
|
||||
virtual PRBool IsFocusable(PRInt32 *aTabIndex = nsnull);
|
||||
virtual nsIAtom* GetID() const;
|
||||
virtual const nsAttrValue* GetClasses() const;
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
#include "nsReadableUtils.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
static PRLogModuleInfo* gLog;
|
||||
|
@ -411,7 +412,7 @@ nsXULCommandDispatcher::UpdateCommands(const nsAString& aEventName)
|
|||
|
||||
nsEvent event(PR_TRUE, NS_XUL_COMMAND_UPDATE);
|
||||
|
||||
content->HandleDOMEvent(context, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(content, context, &event, nsnull, &status);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
|
|
@ -117,6 +117,7 @@
|
|||
#include "nsIParserService.h"
|
||||
#include "nsICSSStyleSheet.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
//
|
||||
|
@ -950,8 +951,8 @@ nsXULDocument::ExecuteOnBroadcastHandlerFor(nsIContent* aBroadcaster,
|
|||
|
||||
// Handle the DOM event
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
child->HandleDOMEvent(aPresContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(child, aPresContext, &event, nsnull,
|
||||
&status);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "nsIChromeEventHandler.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsEvent.h"
|
||||
|
||||
class nsIPrincipal;
|
||||
|
||||
|
@ -66,11 +67,12 @@ enum PopupControlState {
|
|||
class nsIDocShell;
|
||||
class nsIFocusController;
|
||||
class nsIDocument;
|
||||
class nsPresContext;
|
||||
struct nsTimeout;
|
||||
|
||||
#define NS_PIDOMWINDOW_IID \
|
||||
{ 0xb14e8b8b, 0x1ee2, 0x43a6, \
|
||||
{ 0xa5, 0x4a, 0x56, 0xa1, 0x88, 0xaa, 0x09, 0x98 } }
|
||||
{ 0xca692511, 0x8558, 0x4307, \
|
||||
{ 0x84, 0xdb, 0x77, 0x28, 0xec, 0xed, 0xb1, 0xd2 } }
|
||||
|
||||
class nsPIDOMWindow : public nsIDOMWindowInternal
|
||||
{
|
||||
|
@ -292,9 +294,54 @@ public:
|
|||
|
||||
virtual PRBool WouldReuseInnerWindow(nsIDocument *aNewDocument) = 0;
|
||||
|
||||
virtual nsresult HandleDOMEvent(nsPresContext *aPresContext, nsEvent *aEvent,
|
||||
nsIDOMEvent **aDOMEvent, PRUint32 aFlags,
|
||||
nsEventStatus *aEventStatus) = 0;
|
||||
/**
|
||||
* Called before the capture phase of the event flow.
|
||||
* This is used to create the event target chain and implementations
|
||||
* should set the necessary members of nsEventChainPreVisitor.
|
||||
* At least aVisitor.mCanHandle must be set,
|
||||
* usually also aVisitor.mParentTarget if mCanHandle is PR_TRUE.
|
||||
* First one tells that this object can handle the aVisitor.mEvent event and
|
||||
* the latter one is the possible parent object for the event target chain.
|
||||
* @see nsEventDispatcher.h for more documentation about aVisitor.
|
||||
*
|
||||
* @param aVisitor the visitor object which is used to create the
|
||||
* event target chain for event dispatching.
|
||||
*
|
||||
* @note Only nsEventDispatcher should call this method.
|
||||
*/
|
||||
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor) = 0;
|
||||
|
||||
/**
|
||||
* Called after the bubble phase of the system event group.
|
||||
* The default handling of the event should happen here.
|
||||
* @param aVisitor the visitor object which is used during post handling.
|
||||
*
|
||||
* @see nsEventDispatcher.h for documentation about aVisitor.
|
||||
* @note Only nsEventDispatcher should call this method.
|
||||
*/
|
||||
virtual nsresult PostHandleEvent(nsEventChainPostVisitor& aVisitor) = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Dispatch an event.
|
||||
* @param aEvent the event that is being dispatched.
|
||||
* @param aDOMEvent the event that is being dispatched, use if you want to
|
||||
* dispatch nsIDOMEvent, not only nsEvent.
|
||||
* @param aPresContext the current presentation context, can be nsnull.
|
||||
* @param aEventStatus the status returned from the function, can be nsnull.
|
||||
*
|
||||
* @note If both aEvent and aDOMEvent are used, aEvent must be the internal
|
||||
* event of the aDOMEvent.
|
||||
*
|
||||
* If aDOMEvent is not nsnull (in which case aEvent can be nsnull) it is used
|
||||
* for dispatching, otherwise aEvent is used.
|
||||
*
|
||||
* @deprecated This method is here just until all the callers outside Gecko
|
||||
* have been converted to use nsIDOMEventTarget::dispatchEvent.
|
||||
*/
|
||||
virtual nsresult DispatchDOMEvent(nsEvent* aEvent, nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus) = 0;
|
||||
|
||||
/**
|
||||
* Get the docshell in this window.
|
||||
|
|
|
@ -49,11 +49,11 @@ class nsIDOMEventGroup;
|
|||
* DOM event source class. Object that allow event registration and
|
||||
* distribution from themselves implement this interface.
|
||||
*/
|
||||
|
||||
|
||||
/* 2fa04cfb-2494-41e5-ba76-9a79293eeb7e */
|
||||
#define NS_IDOMEVENTRECEIVER_IID \
|
||||
{ /* e1dbcba0-fb38-11d1-bd87-00805f8ae3f4 */ \
|
||||
0xe1dbcba0, 0xfb38, 0x11d1, \
|
||||
{0xbd, 0x87, 0x00, 0x80, 0x5f, 0x8a, 0xe3, 0xf4} }
|
||||
{0x2fa04cfb, 0x2494, 0x41e5, \
|
||||
{ 0xba, 0x76, 0x9a, 0x79, 0x29, 0x3e, 0xeb, 0x7e } }
|
||||
|
||||
class nsIDOMEventReceiver : public nsIDOMEventTarget
|
||||
{
|
||||
|
@ -64,7 +64,8 @@ public:
|
|||
const nsIID& aIID) = 0;
|
||||
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID) = 0;
|
||||
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aResult) = 0;
|
||||
NS_IMETHOD GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult) = 0;
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent) = 0;
|
||||
NS_IMETHOD GetSystemEventGroup(nsIDOMEventGroup** aGroup) = 0;
|
||||
};
|
||||
|
|
|
@ -6639,7 +6639,7 @@ nsEventReceiverSH::RegisterCompileHandler(nsIXPConnectWrappedNative *wrapper,
|
|||
NS_ENSURE_TRUE(receiver, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
receiver->GetListenerManager(getter_AddRefs(manager));
|
||||
receiver->GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
||||
NS_ENSURE_TRUE(manager, NS_ERROR_UNEXPECTED);
|
||||
|
||||
nsCOMPtr<nsIAtom> atom(do_GetAtom(nsDependentJSString(id)));
|
||||
|
|
|
@ -140,6 +140,7 @@
|
|||
#include "nsCSSProps.h"
|
||||
#include "nsIURIFixup.h"
|
||||
#include "nsCDefaultURIFixup.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
#include "plbase64.h"
|
||||
|
||||
|
@ -1473,40 +1474,14 @@ nsGlobalWindow::GetGlobalObjectOwner()
|
|||
}
|
||||
|
||||
nsresult
|
||||
nsGlobalWindow::HandleDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent, PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
nsGlobalWindow::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
FORWARD_TO_INNER(HandleDOMEvent,
|
||||
(aPresContext, aEvent, aDOMEvent, aFlags, aEventStatus),
|
||||
NS_OK);
|
||||
|
||||
nsGlobalWindow *outer = GetOuterWindowInternal();
|
||||
|
||||
// Make sure to tell the event that dispatch has started.
|
||||
NS_MARK_EVENT_DISPATCH_STARTED(aEvent);
|
||||
|
||||
nsresult ret = NS_OK;
|
||||
PRBool externalDOMEvent = PR_FALSE;
|
||||
nsIDOMEvent *domEvent = nsnull;
|
||||
FORWARD_TO_INNER(PreHandleEvent, (aVisitor), NS_OK);
|
||||
static PRUint32 count = 0;
|
||||
PRUint32 msg = aVisitor.mEvent->message;
|
||||
|
||||
/* mChromeEventHandler and mContext go dangling in the middle of this
|
||||
function under some circumstances (events that destroy the window)
|
||||
without this addref. */
|
||||
nsCOMPtr<nsIChromeEventHandler> kungFuDeathGrip1(mChromeEventHandler);
|
||||
nsCOMPtr<nsIScriptContext> kungFuDeathGrip2(GetContextInternal());
|
||||
|
||||
/* If this is a mouse event, use the struct to provide entropy for
|
||||
* the system.
|
||||
*/
|
||||
if (gEntropyCollector &&
|
||||
(NS_EVENT_FLAG_CAPTURE & aFlags) &&
|
||||
(aEvent->message == NS_MOUSE_MOVE)) {
|
||||
//I'd like to not come in here if there is a mChromeEventHandler
|
||||
//present, but there is always one when the message is
|
||||
//NS_MOUSE_MOVE.
|
||||
//
|
||||
aVisitor.mCanHandle = PR_TRUE;
|
||||
if ((msg == NS_MOUSE_MOVE) && gEntropyCollector) {
|
||||
//Chances are this counter will overflow during the life of the
|
||||
//process, but that's OK for our case. Means we get a little
|
||||
//more entropy.
|
||||
|
@ -1515,21 +1490,46 @@ nsGlobalWindow::HandleDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent,
|
|||
//let's only take the lowest half of the point structure.
|
||||
PRInt16 myCoord[2];
|
||||
|
||||
myCoord[0] = aEvent->refPoint.x;
|
||||
myCoord[1] = aEvent->refPoint.y;
|
||||
myCoord[0] = aVisitor.mEvent->refPoint.x;
|
||||
myCoord[1] = aVisitor.mEvent->refPoint.y;
|
||||
gEntropyCollector->RandomUpdate((void*)myCoord, sizeof(myCoord));
|
||||
gEntropyCollector->RandomUpdate((void*)&aEvent->time, sizeof(PRUint32));
|
||||
gEntropyCollector->RandomUpdate((void*)&(aVisitor.mEvent->time),
|
||||
sizeof(PRUint32));
|
||||
}
|
||||
} else if (msg == NS_RESIZE_EVENT) {
|
||||
mIsHandlingResizeEvent = PR_TRUE;
|
||||
}
|
||||
|
||||
// Check chrome document capture here.
|
||||
// XXX The chrome can not handle this, see bug 51211
|
||||
// FIXME Fix this for other *LOAD events, bug 329514.
|
||||
if (mChromeEventHandler && msg != NS_IMAGE_LOAD) {
|
||||
aVisitor.mParentTarget = mChromeEventHandler;
|
||||
aVisitor.mParentIsChromeHandler = PR_TRUE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGlobalWindow::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
FORWARD_TO_INNER(PostHandleEvent, (aVisitor), NS_OK);
|
||||
/* mChromeEventHandler and mContext go dangling in the middle of this
|
||||
function under some circumstances (events that destroy the window)
|
||||
without this addref. */
|
||||
nsCOMPtr<nsIChromeEventHandler> kungFuDeathGrip1(mChromeEventHandler);
|
||||
nsCOMPtr<nsIScriptContext> kungFuDeathGrip2(GetContextInternal());
|
||||
nsGlobalWindow* outer = GetOuterWindowInternal();
|
||||
|
||||
// if the window is deactivated while in full screen mode,
|
||||
// restore OS chrome, and hide it again upon re-activation
|
||||
if (outer && outer->mFullScreen && (NS_EVENT_FLAG_BUBBLE & aFlags)) {
|
||||
if (aEvent->message == NS_DEACTIVATE || aEvent->message == NS_ACTIVATE) {
|
||||
if (outer && outer->mFullScreen) {
|
||||
if (aVisitor.mEvent->message == NS_DEACTIVATE ||
|
||||
aVisitor.mEvent->message == NS_ACTIVATE) {
|
||||
nsCOMPtr<nsIFullScreen> fullScreen =
|
||||
do_GetService("@mozilla.org/browser/fullscreen;1");
|
||||
if (fullScreen) {
|
||||
if (aEvent->message == NS_DEACTIVATE)
|
||||
if (aVisitor.mEvent->message == NS_DEACTIVATE)
|
||||
fullScreen->ShowAllOSChrome();
|
||||
else
|
||||
fullScreen->HideAllOSChrome();
|
||||
|
@ -1537,87 +1537,20 @@ nsGlobalWindow::HandleDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent,
|
|||
}
|
||||
}
|
||||
|
||||
if (NS_EVENT_FLAG_INIT & aFlags) {
|
||||
if (aDOMEvent) {
|
||||
if (*aDOMEvent) {
|
||||
externalDOMEvent = PR_TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
aDOMEvent = &domEvent;
|
||||
}
|
||||
aEvent->flags |= aFlags;
|
||||
aFlags &= ~(NS_EVENT_FLAG_CANT_BUBBLE | NS_EVENT_FLAG_CANT_CANCEL);
|
||||
aFlags |= NS_EVENT_FLAG_BUBBLE | NS_EVENT_FLAG_CAPTURE;
|
||||
|
||||
if (aVisitor.mEvent->message == NS_RESIZE_EVENT) {
|
||||
mIsHandlingResizeEvent = PR_FALSE;
|
||||
} else if (aVisitor.mEvent->message == NS_PAGE_UNLOAD) {
|
||||
// Execute bindingdetached handlers before we tear ourselves
|
||||
// down.
|
||||
if (aEvent->message == NS_PAGE_UNLOAD && mDocument &&
|
||||
!(aFlags & NS_EVENT_FLAG_SYSTEM_EVENT)) {
|
||||
if (mDocument) {
|
||||
NS_ASSERTION(mDoc, "Must have doc");
|
||||
mDoc->BindingManager()->ExecuteDetachedHandlers();
|
||||
}
|
||||
}
|
||||
|
||||
if (aEvent->message == NS_PAGE_UNLOAD) {
|
||||
mIsDocumentLoaded = PR_FALSE;
|
||||
}
|
||||
|
||||
// Capturing stage
|
||||
if ((NS_EVENT_FLAG_CAPTURE & aFlags) && mChromeEventHandler) {
|
||||
// Check chrome document capture here.
|
||||
// XXX The chrome can not handle this, see bug 51211
|
||||
if (aEvent->message != NS_IMAGE_LOAD) {
|
||||
mChromeEventHandler->HandleChromeEvent(aPresContext, aEvent, aDOMEvent,
|
||||
aFlags & NS_EVENT_CAPTURE_MASK,
|
||||
aEventStatus);
|
||||
}
|
||||
}
|
||||
|
||||
if (aEvent->message == NS_RESIZE_EVENT) {
|
||||
mIsHandlingResizeEvent = PR_TRUE;
|
||||
}
|
||||
|
||||
// Local handling stage
|
||||
if (outer && (aEvent->message != NS_BLUR_CONTENT || !GetBlurSuppression()) &&
|
||||
mListenerManager &&
|
||||
!((NS_EVENT_FLAG_CANT_BUBBLE & aEvent->flags) &&
|
||||
(NS_EVENT_FLAG_BUBBLE & aFlags) &&
|
||||
!(NS_EVENT_FLAG_INIT & aFlags))) {
|
||||
aEvent->flags |= aFlags;
|
||||
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent,
|
||||
outer, aFlags, aEventStatus);
|
||||
aEvent->flags &= ~aFlags;
|
||||
}
|
||||
|
||||
if (aEvent->message == NS_RESIZE_EVENT) {
|
||||
mIsHandlingResizeEvent = PR_FALSE;
|
||||
}
|
||||
|
||||
if (aEvent->message == NS_PAGE_LOAD) {
|
||||
} else if (aVisitor.mEvent->message == NS_PAGE_LOAD) {
|
||||
mIsDocumentLoaded = PR_TRUE;
|
||||
}
|
||||
|
||||
// Bubbling stage
|
||||
if ((NS_EVENT_FLAG_BUBBLE & aFlags) && mChromeEventHandler) {
|
||||
// Bubble to a chrome document if it exists
|
||||
// XXX Need a way to know if an event should really bubble or not.
|
||||
// For now filter out load and unload, since they cause problems.
|
||||
if ((aEvent->message != NS_PAGE_LOAD) &&
|
||||
(aEvent->message != NS_PAGE_UNLOAD) &&
|
||||
(aEvent->message != NS_IMAGE_LOAD) &&
|
||||
(aEvent->message != NS_FOCUS_CONTENT) &&
|
||||
(aEvent->message != NS_BLUR_CONTENT)) {
|
||||
mChromeEventHandler->HandleChromeEvent(aPresContext, aEvent,
|
||||
aDOMEvent,
|
||||
aFlags & NS_EVENT_BUBBLE_MASK,
|
||||
aEventStatus);
|
||||
}
|
||||
}
|
||||
|
||||
if (aEvent->message == NS_PAGE_LOAD) {
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(GetFrameElementInternal()));
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem =
|
||||
do_QueryInterface(GetDocShell());
|
||||
|
||||
|
@ -1633,7 +1566,8 @@ nsGlobalWindow::HandleDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent,
|
|||
// onload event for the frame element.
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent event(NS_IS_TRUSTED_EVENT(aEvent), NS_PAGE_LOAD);
|
||||
nsEvent event(NS_IS_TRUSTED_EVENT(aVisitor.mEvent), NS_PAGE_LOAD);
|
||||
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
|
||||
|
||||
// Most of the time we could get a pres context to pass in here,
|
||||
// but not always (i.e. if this window is not shown there won't
|
||||
|
@ -1641,35 +1575,23 @@ nsGlobalWindow::HandleDOMEvent(nsPresContext* aPresContext, nsEvent* aEvent,
|
|||
// event we don't need a pres context anyway so we just pass
|
||||
// null as the pres context all the time here.
|
||||
|
||||
ret = content->HandleDOMEvent(nsnull, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(content, nsnull, &event, nsnull, &status);
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_EVENT_FLAG_INIT & aFlags) {
|
||||
// We're leaving the DOM event loop so if we created an event,
|
||||
// release here.
|
||||
if (*aDOMEvent && !externalDOMEvent) {
|
||||
nsrefcnt rc;
|
||||
NS_RELEASE2(*aDOMEvent, rc);
|
||||
if (rc) {
|
||||
// Okay, so someone in the DOM loop (a listener, JS object) still has
|
||||
// a ref to the DOM Event but the internal data hasn't been malloc'd.
|
||||
// Force a copy of the data here so the DOM Event is still valid.
|
||||
nsCOMPtr<nsIPrivateDOMEvent>
|
||||
privateEvent(do_QueryInterface(*aDOMEvent));
|
||||
if (privateEvent)
|
||||
privateEvent->DuplicatePrivateData();
|
||||
}
|
||||
aDOMEvent = nsnull;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Now that we're done with this event, remove the flag that says
|
||||
// we're in the process of dispatching this event.
|
||||
NS_MARK_EVENT_DISPATCH_DONE(aEvent);
|
||||
}
|
||||
|
||||
return ret;
|
||||
nsresult
|
||||
nsGlobalWindow::DispatchDOMEvent(nsEvent* aEvent,
|
||||
nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus)
|
||||
{
|
||||
return
|
||||
nsEventDispatcher::DispatchDOMEvent(NS_STATIC_CAST(nsPIDOMWindow*, this),
|
||||
aEvent, aDOMEvent, aPresContext,
|
||||
aEventStatus);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
|
@ -3922,26 +3844,18 @@ NS_IMETHODIMP
|
|||
nsGlobalWindow::CaptureEvents(PRInt32 aEventFlags)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
if (NS_SUCCEEDED(GetListenerManager(getter_AddRefs(manager)))) {
|
||||
manager->CaptureEvent(aEventFlags);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return manager->CaptureEvent(aEventFlags);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::ReleaseEvents(PRInt32 aEventFlags)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
if (NS_SUCCEEDED(GetListenerManager(getter_AddRefs(manager)))) {
|
||||
manager->ReleaseEvent(aEventFlags);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return NS_ERROR_FAILURE;
|
||||
nsresult rv = GetListenerManager(PR_FALSE, getter_AddRefs(manager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return manager ? manager->ReleaseEvent(aEventFlags) : NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -4973,14 +4887,19 @@ nsGlobalWindow::DispatchEvent(nsIDOMEvent* aEvent, PRBool* _retval)
|
|||
|
||||
// Obtain a presentation shell
|
||||
nsIPresShell *shell = mDoc->GetShellAt(0);
|
||||
if (!shell) {
|
||||
return NS_OK;
|
||||
nsCOMPtr<nsPresContext> presContext;
|
||||
if (shell) {
|
||||
// Retrieve the context
|
||||
presContext = shell->GetPresContext();
|
||||
}
|
||||
|
||||
// Retrieve the context
|
||||
nsCOMPtr<nsPresContext> presContext = shell->GetPresContext();
|
||||
return presContext->EventStateManager()->
|
||||
DispatchNewEvent(GetOuterWindow(), aEvent, _retval);
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsresult rv =
|
||||
nsEventDispatcher::DispatchDOMEvent(GetOuterWindow(), nsnull, aEvent,
|
||||
presContext, &status);
|
||||
|
||||
*_retval = (status != nsEventStatus_eConsumeNoDefault);
|
||||
return rv;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
|
@ -4998,7 +4917,7 @@ nsGlobalWindow::AddGroupedEventListener(const nsAString & aType,
|
|||
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
if (NS_SUCCEEDED(GetListenerManager(getter_AddRefs(manager)))) {
|
||||
if (NS_SUCCEEDED(GetListenerManager(PR_TRUE, getter_AddRefs(manager)))) {
|
||||
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
||||
|
||||
manager->AddEventListenerByType(aListener, aType, flags, aEvtGrp);
|
||||
|
@ -5045,7 +4964,7 @@ nsGlobalWindow::AddEventListener(const nsAString& aType,
|
|||
PRBool aUseCapture, PRBool aWantsUntrusted)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
nsresult rv = GetListenerManager(getter_AddRefs(manager));
|
||||
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
||||
|
@ -5068,7 +4987,7 @@ nsGlobalWindow::AddEventListenerByIID(nsIDOMEventListener* aListener,
|
|||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
if (NS_SUCCEEDED (GetListenerManager(getter_AddRefs(manager)))) {
|
||||
if (NS_SUCCEEDED(GetListenerManager(PR_TRUE, getter_AddRefs(manager)))) {
|
||||
manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -5091,11 +5010,17 @@ nsGlobalWindow::RemoveEventListenerByIID(nsIDOMEventListener* aListener,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGlobalWindow::GetListenerManager(nsIEventListenerManager **aResult)
|
||||
nsGlobalWindow::GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult)
|
||||
{
|
||||
FORWARD_TO_INNER_CREATE(GetListenerManager, (aResult));
|
||||
FORWARD_TO_INNER_CREATE(GetListenerManager, (aCreateIfNotFound, aResult));
|
||||
|
||||
if (!mListenerManager) {
|
||||
if (!aCreateIfNotFound) {
|
||||
*aResult = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static NS_DEFINE_CID(kEventListenerManagerCID,
|
||||
NS_EVENTLISTENERMANAGER_CID);
|
||||
nsresult rv;
|
||||
|
@ -5122,7 +5047,8 @@ NS_IMETHODIMP
|
|||
nsGlobalWindow::GetSystemEventGroup(nsIDOMEventGroup **aGroup)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
if (NS_SUCCEEDED(GetListenerManager(getter_AddRefs(manager))) && manager) {
|
||||
if (NS_SUCCEEDED(GetListenerManager(PR_TRUE, getter_AddRefs(manager))) &&
|
||||
manager) {
|
||||
return manager->GetSystemEventGroupLM(aGroup);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
|
|
|
@ -198,7 +198,8 @@ public:
|
|||
const nsIID& aIID);
|
||||
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener,
|
||||
const nsIID& aIID);
|
||||
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
|
||||
NS_IMETHOD GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult);
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent);
|
||||
NS_IMETHOD GetSystemEventGroup(nsIDOMEventGroup** aGroup);
|
||||
|
||||
|
@ -225,10 +226,14 @@ public:
|
|||
virtual NS_HIDDEN_(nsresult) ResumeTimeouts();
|
||||
|
||||
virtual NS_HIDDEN_(PRBool) WouldReuseInnerWindow(nsIDocument *aNewDocument);
|
||||
virtual NS_HIDDEN_(nsresult) HandleDOMEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus);
|
||||
|
||||
virtual NS_HIDDEN_(nsresult) PreHandleEvent(nsEventChainPreVisitor& aVisitor);
|
||||
virtual NS_HIDDEN_(nsresult) PostHandleEvent(nsEventChainPostVisitor& aVisitor);
|
||||
virtual NS_HIDDEN_(nsresult) DispatchDOMEvent(nsEvent* aEvent,
|
||||
nsIDOMEvent* aDOMEvent,
|
||||
nsPresContext* aPresContext,
|
||||
nsEventStatus* aEventStatus);
|
||||
|
||||
virtual NS_HIDDEN_(void) SetDocShell(nsIDocShell* aDocShell);
|
||||
virtual NS_HIDDEN_(nsresult) SetNewDocument(nsIDocument *aDocument,
|
||||
nsISupports *aState,
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
#include "nsIAtom.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "jscntxt.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsIDOMGCParticipant.h"
|
||||
|
||||
// For locale aware string methods
|
||||
|
@ -219,10 +220,10 @@ NS_ScriptErrorReporter(JSContext *cx,
|
|||
errorevent.errorMsg = msg.get();
|
||||
errorevent.lineNr = report ? report->lineno : 0;
|
||||
|
||||
// HandleDOMEvent() must be synchronous for the recursion block
|
||||
// Dispatch() must be synchronous for the recursion block
|
||||
// (errorDepth) to work.
|
||||
win->HandleDOMEvent(presContext, &errorevent, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(win, presContext, &errorevent, nsnull,
|
||||
&status);
|
||||
}
|
||||
|
||||
--errorDepth;
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
#include "nsFocusController.h"
|
||||
#include "nsString.h"
|
||||
#include "nsDOMClassInfo.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
static NS_DEFINE_CID(kEventListenerManagerCID, NS_EVENTLISTENERMANAGER_CID);
|
||||
|
||||
|
@ -107,25 +108,11 @@ nsWindowRoot::RemoveEventListener(const nsAString& aType, nsIDOMEventListener* a
|
|||
NS_IMETHODIMP
|
||||
nsWindowRoot::DispatchEvent(nsIDOMEvent* aEvt, PRBool *_retval)
|
||||
{
|
||||
// Obtain a presentation context
|
||||
nsCOMPtr<nsIDOMDocument> domDoc;
|
||||
mWindow->GetDocument(getter_AddRefs(domDoc));
|
||||
if (!domDoc)
|
||||
return NS_OK;
|
||||
nsCOMPtr<nsIDocument> doc(do_QueryInterface(domDoc));
|
||||
|
||||
PRInt32 count = doc->GetNumberOfShells();
|
||||
if (count == 0)
|
||||
return NS_OK;
|
||||
|
||||
nsIPresShell *shell = doc->GetShellAt(0);
|
||||
|
||||
// Retrieve the context
|
||||
nsCOMPtr<nsPresContext> aPresContext = shell->GetPresContext();
|
||||
|
||||
return aPresContext->EventStateManager()->
|
||||
DispatchNewEvent(NS_STATIC_CAST(nsIDOMEventReceiver*, this),
|
||||
aEvt, _retval);
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsresult rv = nsEventDispatcher::DispatchDOMEvent(
|
||||
NS_STATIC_CAST(nsIChromeEventHandler*, this), nsnull, aEvt, nsnull, &status);
|
||||
*_retval = (status != nsEventStatus_eConsumeNoDefault);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -134,7 +121,7 @@ nsWindowRoot::AddGroupedEventListener(const nsAString & aType, nsIDOMEventListen
|
|||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
|
||||
if (NS_SUCCEEDED(GetListenerManager(getter_AddRefs(manager)))) {
|
||||
if (NS_SUCCEEDED(GetListenerManager(PR_TRUE, getter_AddRefs(manager)))) {
|
||||
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
||||
manager->AddEventListenerByType(aListener, aType, flags, aEvtGrp);
|
||||
return NS_OK;
|
||||
|
@ -172,7 +159,7 @@ nsWindowRoot::AddEventListener(const nsAString& aType,
|
|||
PRBool aUseCapture, PRBool aWantsUntrusted)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
nsresult rv = GetListenerManager(getter_AddRefs(manager));
|
||||
nsresult rv = GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
PRInt32 flags = aUseCapture ? NS_EVENT_FLAG_CAPTURE : NS_EVENT_FLAG_BUBBLE;
|
||||
|
@ -188,7 +175,7 @@ NS_IMETHODIMP
|
|||
nsWindowRoot::AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
GetListenerManager(getter_AddRefs(manager));
|
||||
GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
manager->AddEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
return NS_OK;
|
||||
|
@ -200,7 +187,7 @@ NS_IMETHODIMP
|
|||
nsWindowRoot::RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
GetListenerManager(getter_AddRefs(manager));
|
||||
GetListenerManager(PR_TRUE, getter_AddRefs(manager));
|
||||
if (manager) {
|
||||
manager->RemoveEventListenerByIID(aListener, aIID, NS_EVENT_FLAG_BUBBLE);
|
||||
return NS_OK;
|
||||
|
@ -209,9 +196,14 @@ nsWindowRoot::RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsI
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowRoot::GetListenerManager(nsIEventListenerManager** aResult)
|
||||
nsWindowRoot::GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult)
|
||||
{
|
||||
if (!mListenerManager) {
|
||||
if (!aCreateIfNotFound) {
|
||||
*aResult = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult rv;
|
||||
mListenerManager = do_CreateInstance(kEventListenerManagerCID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
@ -235,69 +227,13 @@ NS_IMETHODIMP
|
|||
nsWindowRoot::GetSystemEventGroup(nsIDOMEventGroup **aGroup)
|
||||
{
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
if (NS_SUCCEEDED(GetListenerManager(getter_AddRefs(manager))) && manager) {
|
||||
if (NS_SUCCEEDED(GetListenerManager(PR_TRUE, getter_AddRefs(manager))) &&
|
||||
manager) {
|
||||
return manager->GetSystemEventGroupLM(aGroup);
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowRoot::HandleChromeEvent(nsPresContext* aPresContext, nsEvent* aEvent,
|
||||
nsIDOMEvent** aDOMEvent, PRUint32 aFlags,
|
||||
nsEventStatus* aEventStatus)
|
||||
{
|
||||
// Make sure to tell the event that dispatch has started.
|
||||
NS_MARK_EVENT_DISPATCH_STARTED(aEvent);
|
||||
|
||||
// Prevent the world from going
|
||||
// away until after we've finished handling the event.
|
||||
nsCOMPtr<nsIDOMWindow> kungFuDeathGrip(mWindow);
|
||||
|
||||
nsresult ret = NS_OK;
|
||||
nsIDOMEvent* domEvent = nsnull;
|
||||
|
||||
// We're at the top, so there's no bubbling or capturing here.
|
||||
if (NS_EVENT_FLAG_INIT & aFlags) {
|
||||
aDOMEvent = &domEvent;
|
||||
aEvent->flags = aFlags;
|
||||
aFlags &= ~(NS_EVENT_FLAG_CANT_BUBBLE | NS_EVENT_FLAG_CANT_CANCEL);
|
||||
}
|
||||
|
||||
//Local handling stage
|
||||
if (mListenerManager && !(aEvent->flags & NS_EVENT_FLAG_STOP_DISPATCH)) {
|
||||
aEvent->flags |= aFlags;
|
||||
mListenerManager->HandleEvent(aPresContext, aEvent, aDOMEvent, this, aFlags, aEventStatus);
|
||||
aEvent->flags &= ~aFlags;
|
||||
}
|
||||
|
||||
if (NS_EVENT_FLAG_INIT & aFlags) {
|
||||
// We're leaving the DOM event loop so if we created a DOM event,
|
||||
// release here.
|
||||
if (nsnull != *aDOMEvent) {
|
||||
nsrefcnt rc;
|
||||
NS_RELEASE2(*aDOMEvent, rc);
|
||||
if (0 != rc) {
|
||||
// Okay, so someone in the DOM loop (a listener, JS object)
|
||||
// still has a ref to the DOM Event but the internal data
|
||||
// hasn't been malloc'd. Force a copy of the data here so the
|
||||
// DOM Event is still valid.
|
||||
nsIPrivateDOMEvent *privateEvent;
|
||||
if (NS_OK == (*aDOMEvent)->QueryInterface(NS_GET_IID(nsIPrivateDOMEvent), (void**)&privateEvent)) {
|
||||
privateEvent->DuplicatePrivateData();
|
||||
NS_RELEASE(privateEvent);
|
||||
}
|
||||
}
|
||||
}
|
||||
aDOMEvent = nsnull;
|
||||
|
||||
// Now that we're done with this event, remove the flag that says
|
||||
// we're in the process of dispatching this event.
|
||||
NS_MARK_EVENT_DISPATCH_DONE(aEvent);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
nsIDOMGCParticipant*
|
||||
nsWindowRoot::GetSCCIndex()
|
||||
{
|
||||
|
@ -309,6 +245,21 @@ nsWindowRoot::AppendReachableList(nsCOMArray<nsIDOMGCParticipant>& aArray)
|
|||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowRoot::PreHandleChromeEvent(nsEventChainPreVisitor& aVisitor)
|
||||
{
|
||||
aVisitor.mCanHandle = PR_TRUE;
|
||||
// To keep mWindow alive
|
||||
aVisitor.mItemData = mWindow;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowRoot::PostHandleChromeEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsWindowRoot::GetFocusController(nsIFocusController** aResult)
|
||||
{
|
||||
|
|
|
@ -44,8 +44,9 @@ class nsIDOMWindow;
|
|||
class nsIDOMEventListener;
|
||||
class nsIEventListenerManager;
|
||||
class nsIDOMEvent;
|
||||
class nsEventChainPreVisitor;
|
||||
class nsEventChainPostVisitor;
|
||||
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIDOM3EventTarget.h"
|
||||
#include "nsIDOMNSEventTarget.h"
|
||||
|
@ -70,13 +71,13 @@ public:
|
|||
NS_DECL_NSIDOM3EVENTTARGET
|
||||
NS_DECL_NSIDOMNSEVENTTARGET
|
||||
|
||||
NS_IMETHOD HandleChromeEvent(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent, nsIDOMEvent** aDOMEvent,
|
||||
PRUint32 aFlags, nsEventStatus* aEventStatus);
|
||||
NS_IMETHOD PreHandleChromeEvent(nsEventChainPreVisitor& aVisitor);
|
||||
NS_IMETHOD PostHandleChromeEvent(nsEventChainPostVisitor& aVisitor);
|
||||
|
||||
NS_IMETHOD AddEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
|
||||
NS_IMETHOD RemoveEventListenerByIID(nsIDOMEventListener *aListener, const nsIID& aIID);
|
||||
NS_IMETHOD GetListenerManager(nsIEventListenerManager** aInstancePtrResult);
|
||||
NS_IMETHOD GetListenerManager(PRBool aCreateIfNotFound,
|
||||
nsIEventListenerManager** aResult);
|
||||
NS_IMETHOD HandleEvent(nsIDOMEvent *aEvent);
|
||||
NS_IMETHOD GetSystemEventGroup(nsIDOMEventGroup** aGroup);
|
||||
|
||||
|
|
|
@ -363,7 +363,7 @@ nsEditor::InstallEventListeners()
|
|||
nsCOMPtr<nsIDOMEventGroup> sysGroup;
|
||||
erP->GetSystemEventGroup(getter_AddRefs(sysGroup));
|
||||
nsCOMPtr<nsIEventListenerManager> elmP;
|
||||
erP->GetListenerManager(getter_AddRefs(elmP));
|
||||
erP->GetListenerManager(PR_TRUE, getter_AddRefs(elmP));
|
||||
|
||||
if (sysGroup && elmP)
|
||||
{
|
||||
|
@ -415,7 +415,7 @@ nsEditor::RemoveEventListeners()
|
|||
nsCOMPtr<nsIDOMEventGroup> sysGroup;
|
||||
erP->GetSystemEventGroup(getter_AddRefs(sysGroup));
|
||||
nsCOMPtr<nsIEventListenerManager> elmP;
|
||||
erP->GetListenerManager(getter_AddRefs(elmP));
|
||||
erP->GetListenerManager(PR_TRUE, getter_AddRefs(elmP));
|
||||
if (sysGroup && elmP)
|
||||
{
|
||||
elmP->RemoveEventListenerByType(mKeyListenerP,
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -190,6 +190,7 @@ static const char sPrintOptionsContractID[] = "@mozilla.org/gfx/printset
|
|||
#include "nsISHistoryInternal.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsWeakPtr.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
//paint forcing
|
||||
#include "prenv.h"
|
||||
|
@ -1001,6 +1002,9 @@ DocumentViewerImpl::LoadComplete(nsresult aStatus)
|
|||
if(NS_SUCCEEDED(aStatus)) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent event(PR_TRUE, NS_PAGE_LOAD);
|
||||
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
|
||||
// XXX Dispatching to |window|, but using |document| as the target.
|
||||
event.target = mDocument;
|
||||
|
||||
// If the document presentation is being restored, we don't want to fire
|
||||
// onload to the document content since that would likely confuse scripts
|
||||
|
@ -1011,8 +1015,8 @@ DocumentViewerImpl::LoadComplete(nsresult aStatus)
|
|||
|
||||
docShell->GetRestoringDocument(&restoring);
|
||||
if (!restoring) {
|
||||
rv = window->HandleDOMEvent(mPresContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(window, mPresContext, &event, nsnull,
|
||||
&status);
|
||||
#ifdef MOZ_TIMELINE
|
||||
// if navigator.xul's load is complete, the main nav window is visible
|
||||
// mark that point.
|
||||
|
@ -1095,6 +1099,9 @@ DocumentViewerImpl::PermitUnload(PRBool *aPermitUnload)
|
|||
// to unload...
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsBeforePageUnloadEvent event(PR_TRUE, NS_BEFORE_PAGE_UNLOAD);
|
||||
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
|
||||
// XXX Dispatching to |window|, but using |document| as the target.
|
||||
event.target = mDocument;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
{
|
||||
|
@ -1107,8 +1114,7 @@ DocumentViewerImpl::PermitUnload(PRBool *aPermitUnload)
|
|||
nsRefPtr<DocumentViewerImpl> kungFuDeathGrip(this);
|
||||
|
||||
mInPermitUnload = PR_TRUE;
|
||||
rv = window->HandleDOMEvent(mPresContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(window, mPresContext, &event, nsnull, &status);
|
||||
mInPermitUnload = PR_FALSE;
|
||||
}
|
||||
|
||||
|
@ -1201,13 +1207,16 @@ DocumentViewerImpl::PageHide(PRBool aIsUnload)
|
|||
// Now, fire an Unload event to the document...
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent event(PR_TRUE, NS_PAGE_UNLOAD);
|
||||
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
|
||||
// XXX Dispatching to |window|, but using |document| as the target.
|
||||
event.target = mDocument;
|
||||
|
||||
// Never permit popups from the unload handler, no matter how we get
|
||||
// here.
|
||||
nsAutoPopupStatePusher popupStatePusher(openAbused, PR_TRUE);
|
||||
|
||||
return window->HandleDOMEvent(mPresContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(window, mPresContext, &event, nsnull, &status);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -1,67 +0,0 @@
|
|||
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla 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/MPL/
|
||||
*
|
||||
* 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 the Mozilla browser.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications, Inc.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Travis Bogard <travis@netscape.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
%{ C++
|
||||
#include "nsEvent.h" // for nsEventStatus enum
|
||||
class nsPresContext;
|
||||
%}
|
||||
|
||||
[ptr] native nsPresContext(nsPresContext);
|
||||
native nsEvent(nsEvent);
|
||||
[ptr] native nsEventPtr(nsEvent);
|
||||
native nsEventStatus(nsEventStatus);
|
||||
|
||||
interface nsIDOMEvent;
|
||||
|
||||
/**
|
||||
* The nsIChromeEventHandler
|
||||
*/
|
||||
|
||||
[scriptable, uuid(7BC08970-9E6C-11d3-AFB2-00A024FFC08C)]
|
||||
interface nsIChromeEventHandler : nsISupports
|
||||
{
|
||||
/**
|
||||
* Handle a chrome DOM event.
|
||||
*/
|
||||
[noscript] void handleChromeEvent(in nsPresContext aPresContext,
|
||||
in nsEventPtr aEvent, out nsIDOMEvent aDOMEvent, in unsigned long aFlags,
|
||||
inout nsEventStatus aStatus);
|
||||
};
|
|
@ -93,8 +93,9 @@ class nsCSSFrameConstructor;
|
|||
class nsISelection;
|
||||
|
||||
#define NS_IPRESSHELL_IID \
|
||||
{ 0xcd6d6c1d, 0x4180, 0x432a, \
|
||||
{ 0x83, 0xbb, 0x1f, 0xc6, 0x50, 0xd2, 0x11, 0xa7 } }
|
||||
{ 0x998cde06, 0x5fa4, 0x4c8b, \
|
||||
{ 0x94, 0x8d, 0xc7, 0x15, 0x74, 0x75, 0xab, 0x6f } }
|
||||
|
||||
|
||||
// Constants uses for ScrollFrameIntoView() function
|
||||
#define NS_PRESSHELL_SCROLL_TOP 0
|
||||
|
@ -504,18 +505,17 @@ public:
|
|||
/**
|
||||
* Interface to dispatch events via the presshell
|
||||
*/
|
||||
NS_IMETHOD HandleEventWithTarget(nsEvent* aEvent,
|
||||
nsIFrame* aFrame,
|
||||
NS_IMETHOD HandleEventWithTarget(nsEvent* aEvent,
|
||||
nsIFrame* aFrame,
|
||||
nsIContent* aContent,
|
||||
PRUint32 aFlags,
|
||||
nsEventStatus* aStatus) = 0;
|
||||
|
||||
/**
|
||||
* Dispatch event to content only (NOT full processing)
|
||||
*/
|
||||
NS_IMETHOD HandleDOMEventWithTarget(nsIContent* aTargetContent,
|
||||
nsEvent* aEvent,
|
||||
nsEventStatus* aStatus) = 0;
|
||||
nsEvent* aEvent,
|
||||
nsEventStatus* aStatus) = 0;
|
||||
|
||||
/**
|
||||
* Gets the current target event frame from the PresShell
|
||||
|
|
|
@ -156,6 +156,7 @@
|
|||
#include "nsIObjectFrame.h"
|
||||
#include "nsIObjectLoadingContent.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
// Drag & Drop, Clipboard
|
||||
#include "nsWidgetsCID.h"
|
||||
|
@ -1007,6 +1008,7 @@ ReflowCommandHashMatchEntry(PLDHashTable *table, const PLDHashEntryHdr *entry,
|
|||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
class nsPresShellEventCB;
|
||||
|
||||
class PresShell : public nsIPresShell, public nsIViewObserver,
|
||||
public nsStubDocumentObserver,
|
||||
|
@ -1146,7 +1148,9 @@ public:
|
|||
virtual nsresult AddOverrideStyleSheet(nsIStyleSheet *aSheet);
|
||||
virtual nsresult RemoveOverrideStyleSheet(nsIStyleSheet *aSheet);
|
||||
|
||||
NS_IMETHOD HandleEventWithTarget(nsEvent* aEvent, nsIFrame* aFrame, nsIContent* aContent, PRUint32 aFlags, nsEventStatus* aStatus);
|
||||
NS_IMETHOD HandleEventWithTarget(nsEvent* aEvent, nsIFrame* aFrame,
|
||||
nsIContent* aContent,
|
||||
nsEventStatus* aStatus);
|
||||
NS_IMETHOD GetEventTargetFrame(nsIFrame** aFrame);
|
||||
NS_IMETHOD GetEventTargetContent(nsEvent* aEvent, nsIContent** aContent);
|
||||
|
||||
|
@ -1182,8 +1186,8 @@ public:
|
|||
nsGUIEvent* aEvent,
|
||||
nsEventStatus* aEventStatus);
|
||||
NS_IMETHOD HandleDOMEventWithTarget(nsIContent* aTargetContent,
|
||||
nsEvent* aEvent,
|
||||
nsEventStatus* aStatus);
|
||||
nsEvent* aEvent,
|
||||
nsEventStatus* aStatus);
|
||||
NS_IMETHOD ResizeReflow(nsIView *aView, nscoord aWidth, nscoord aHeight);
|
||||
NS_IMETHOD_(PRBool) IsVisible();
|
||||
NS_IMETHOD_(void) WillPaint();
|
||||
|
@ -1309,6 +1313,7 @@ protected:
|
|||
PRBool AlreadyInQueue(nsHTMLReflowCommand* aReflowCommand);
|
||||
|
||||
friend struct ReflowEvent;
|
||||
friend class nsPresShellEventCB;
|
||||
|
||||
// Utility to determine if we're in the middle of a drag.
|
||||
PRBool IsDragInProgress ( ) const ;
|
||||
|
@ -1426,10 +1431,14 @@ private:
|
|||
void FreeDynamicStack();
|
||||
|
||||
//helper funcs for event handling
|
||||
protected:
|
||||
//protected because nsPresShellEventCB needs this.
|
||||
nsIFrame* GetCurrentEventFrame();
|
||||
private:
|
||||
void PushCurrentEventInfo(nsIFrame* aFrame, nsIContent* aContent);
|
||||
void PopCurrentEventInfo();
|
||||
nsresult HandleEventInternal(nsEvent* aEvent, nsIView* aView, PRUint32 aFlags, nsEventStatus *aStatus);
|
||||
nsresult HandleEventInternal(nsEvent* aEvent, nsIView* aView,
|
||||
nsEventStatus *aStatus);
|
||||
nsresult HandlePositionedEvent(nsIView* aView,
|
||||
nsIFrame* aTargetFrame,
|
||||
nsGUIEvent* aEvent,
|
||||
|
@ -1448,6 +1457,26 @@ private:
|
|||
nsPluginEnumCallback aCallback);
|
||||
};
|
||||
|
||||
class nsPresShellEventCB : public nsDispatchingCallback
|
||||
{
|
||||
public:
|
||||
nsPresShellEventCB(PresShell* aPresShell) : mPresShell(aPresShell) {}
|
||||
|
||||
virtual void HandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
{
|
||||
if (aVisitor.mPresContext && aVisitor.mEvent->eventStructType != NS_EVENT) {
|
||||
nsIFrame* frame = mPresShell->GetCurrentEventFrame();
|
||||
if (frame) {
|
||||
frame->HandleEvent(aVisitor.mPresContext,
|
||||
(nsGUIEvent*) aVisitor.mEvent,
|
||||
&aVisitor.mEventStatus);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsRefPtr<PresShell> mPresShell;
|
||||
};
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
PRLogModuleInfo* PresShell::gLog;
|
||||
#endif
|
||||
|
@ -3015,8 +3044,7 @@ PresShell::FireResizeEvent()
|
|||
|
||||
nsPIDOMWindow *window = mDocument->GetWindow();
|
||||
if (window) {
|
||||
window->HandleDOMEvent(mPresContext, &event, nsnull, NS_EVENT_FLAG_INIT,
|
||||
&status);
|
||||
nsEventDispatcher::Dispatch(window, mPresContext, &event, nsnull, &status);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4945,7 +4973,7 @@ PresShell::HandlePostedDOMEvents()
|
|||
while(mFirstDOMEventRequest)
|
||||
{
|
||||
/* pull the node from the event request list. Be prepared for reentrant access to the list
|
||||
from within HandleDOMEvent and its callees! */
|
||||
from within Dispatch and its callees! */
|
||||
nsDOMEventRequest* node = mFirstDOMEventRequest;
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
|
||||
|
@ -4954,7 +4982,8 @@ PresShell::HandlePostedDOMEvents()
|
|||
mLastDOMEventRequest = nsnull;
|
||||
}
|
||||
|
||||
node->content->HandleDOMEvent(mPresContext, node->event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(node->content, mPresContext, node->event,
|
||||
nsnull, &status);
|
||||
NS_RELEASE(node->content);
|
||||
delete node->event;
|
||||
node->nsDOMEventRequest::~nsDOMEventRequest(); // doesn't do anything, but just in case
|
||||
|
@ -5712,8 +5741,7 @@ PresShell::HandleEvent(nsIView *aView,
|
|||
|
||||
#ifdef ACCESSIBILITY
|
||||
if (aEvent->eventStructType == NS_ACCESSIBLE_EVENT) {
|
||||
return HandleEventInternal(aEvent, aView,
|
||||
NS_EVENT_FLAG_INIT, aEventStatus);
|
||||
return HandleEventInternal(aEvent, aView, aEventStatus);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -5861,8 +5889,7 @@ PresShell::HandleEvent(nsIView *aView,
|
|||
mCurrentEventFrame = frame;
|
||||
}
|
||||
if (GetCurrentEventFrame()) {
|
||||
rv = HandleEventInternal(aEvent, aView,
|
||||
NS_EVENT_FLAG_INIT, aEventStatus);
|
||||
rv = HandleEventInternal(aEvent, aView, aEventStatus);
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
|
@ -5875,8 +5902,7 @@ PresShell::HandleEvent(nsIView *aView,
|
|||
|
||||
if (!NS_EVENT_NEEDS_FRAME(aEvent)) {
|
||||
mCurrentEventFrame = nsnull;
|
||||
return HandleEventInternal(aEvent, aView,
|
||||
NS_EVENT_FLAG_INIT, aEventStatus);
|
||||
return HandleEventInternal(aEvent, aView, aEventStatus);
|
||||
}
|
||||
else if (NS_IS_KEY_EVENT(aEvent)) {
|
||||
// Keypress events in new blank tabs should not be completely thrown away.
|
||||
|
@ -5967,8 +5993,7 @@ PresShell::HandlePositionedEvent(nsIView* aView,
|
|||
}
|
||||
|
||||
if (GetCurrentEventFrame()) {
|
||||
rv = HandleEventInternal(aEvent, aView,
|
||||
NS_EVENT_FLAG_INIT, aEventStatus);
|
||||
rv = HandleEventInternal(aEvent, aView, aEventStatus);
|
||||
}
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
|
@ -5979,12 +6004,13 @@ PresShell::HandlePositionedEvent(nsIView* aView,
|
|||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PresShell::HandleEventWithTarget(nsEvent* aEvent, nsIFrame* aFrame, nsIContent* aContent, PRUint32 aFlags, nsEventStatus* aStatus)
|
||||
PresShell::HandleEventWithTarget(nsEvent* aEvent, nsIFrame* aFrame,
|
||||
nsIContent* aContent, nsEventStatus* aStatus)
|
||||
{
|
||||
nsresult ret;
|
||||
|
||||
PushCurrentEventInfo(aFrame, aContent);
|
||||
ret = HandleEventInternal(aEvent, nsnull, aFlags, aStatus);
|
||||
ret = HandleEventInternal(aEvent, nsnull, aStatus);
|
||||
PopCurrentEventInfo();
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -5998,7 +6024,7 @@ IsSynthesizedMouseMove(nsEvent* aEvent)
|
|||
|
||||
nsresult
|
||||
PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView,
|
||||
PRUint32 aFlags, nsEventStatus* aStatus)
|
||||
nsEventStatus* aStatus)
|
||||
{
|
||||
#ifdef ACCESSIBILITY
|
||||
if (aEvent->eventStructType == NS_ACCESSIBLE_EVENT)
|
||||
|
@ -6085,58 +6111,23 @@ PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView,
|
|||
// We want synthesized mouse moves to cause mouseover and mouseout
|
||||
// DOM events (PreHandleEvent above), but not mousemove DOM events.
|
||||
if (!IsSynthesizedMouseMove(aEvent)) {
|
||||
nsPresShellEventCB eventCB(this);
|
||||
if (mCurrentEventContent) {
|
||||
rv = mCurrentEventContent->HandleDOMEvent(mPresContext, aEvent, nsnull,
|
||||
aFlags, aStatus);
|
||||
nsEventDispatcher::Dispatch(mCurrentEventContent, mPresContext,
|
||||
aEvent, nsnull, aStatus, &eventCB);
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIContent> targetContent;
|
||||
rv = mCurrentEventFrame->GetContentForEvent(mPresContext, aEvent,
|
||||
getter_AddRefs(targetContent));
|
||||
if (NS_SUCCEEDED(rv) && targetContent) {
|
||||
rv = targetContent->HandleDOMEvent(mPresContext, aEvent, nsnull,
|
||||
aFlags, aStatus);
|
||||
}
|
||||
}
|
||||
|
||||
// Stopping propagation in the default group does not affect
|
||||
// propagation in the system event group.
|
||||
// (see also section 1.2.2.6 of the DOM3 Events Working Draft)
|
||||
|
||||
aEvent->flags &= ~NS_EVENT_FLAG_STOP_DISPATCH;
|
||||
|
||||
// 3. Give event to the Frames for browser default processing.
|
||||
// This is the nearest we can get to being an at target
|
||||
// system event group handler. In particular we need to
|
||||
// fire before bubbling system event group handlers.
|
||||
if (GetCurrentEventFrame() && NS_SUCCEEDED (rv) &&
|
||||
aEvent->eventStructType != NS_EVENT) {
|
||||
rv = mCurrentEventFrame->HandleEvent(mPresContext, (nsGUIEvent*)aEvent,
|
||||
aStatus);
|
||||
}
|
||||
|
||||
// Continue with second dispatch to system event handlers.
|
||||
|
||||
// Need to null check mCurrentEventContent and mCurrentEventFrame
|
||||
// since the previous dispatch could have nuked them.
|
||||
if (mCurrentEventContent) {
|
||||
rv = mCurrentEventContent->HandleDOMEvent(mPresContext, aEvent, nsnull,
|
||||
aFlags | NS_EVENT_FLAG_SYSTEM_EVENT,
|
||||
aStatus);
|
||||
}
|
||||
else if (mCurrentEventFrame) {
|
||||
nsCOMPtr<nsIContent> targetContent;
|
||||
rv = mCurrentEventFrame->GetContentForEvent(mPresContext, aEvent,
|
||||
getter_AddRefs(targetContent));
|
||||
if (NS_SUCCEEDED(rv) && targetContent) {
|
||||
rv = targetContent->HandleDOMEvent(mPresContext, aEvent, nsnull,
|
||||
aFlags | NS_EVENT_FLAG_SYSTEM_EVENT,
|
||||
aStatus);
|
||||
nsEventDispatcher::Dispatch(targetContent, mPresContext, aEvent,
|
||||
nsnull, aStatus, &eventCB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Give event to event manager for post event state changes and
|
||||
// 3. Give event to event manager for post event state changes and
|
||||
// generation of synthetic events.
|
||||
if (NS_SUCCEEDED (rv) &&
|
||||
(GetCurrentEventFrame() || !NS_EVENT_NEEDS_FRAME(aEvent))) {
|
||||
|
@ -6151,7 +6142,8 @@ PresShell::HandleEventInternal(nsEvent* aEvent, nsIView *aView,
|
|||
// Dispatch event to content only (NOT full processing)
|
||||
// See also HandleEventWithTarget which does full event processing.
|
||||
NS_IMETHODIMP
|
||||
PresShell::HandleDOMEventWithTarget(nsIContent* aTargetContent, nsEvent* aEvent, nsEventStatus* aStatus)
|
||||
PresShell::HandleDOMEventWithTarget(nsIContent* aTargetContent, nsEvent* aEvent,
|
||||
nsEventStatus* aStatus)
|
||||
{
|
||||
PushCurrentEventInfo(nsnull, aTargetContent);
|
||||
|
||||
|
@ -6164,8 +6156,8 @@ PresShell::HandleDOMEventWithTarget(nsIContent* aTargetContent, nsEvent* aEvent,
|
|||
if (container) {
|
||||
|
||||
// Dispatch event to content
|
||||
aTargetContent->HandleDOMEvent(mPresContext, aEvent, nsnull,
|
||||
NS_EVENT_FLAG_INIT, aStatus);
|
||||
nsEventDispatcher::Dispatch(aTargetContent, mPresContext, aEvent, nsnull,
|
||||
aStatus);
|
||||
}
|
||||
|
||||
PopCurrentEventInfo();
|
||||
|
|
|
@ -59,6 +59,7 @@
|
|||
#include "nsIDeviceContext.h"
|
||||
#include "nsIView.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsIEventListenerManager.h"
|
||||
#include "nsIDOMNode.h"
|
||||
|
@ -2220,19 +2221,16 @@ void nsComboboxControlFrame::FireValueChangeEvent()
|
|||
{
|
||||
// Fire ValueChange event to indicate data value of combo box has changed
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
mContent->GetListenerManager(getter_AddRefs(manager));
|
||||
nsPresContext* presContext = GetPresContext();
|
||||
if (manager &&
|
||||
NS_SUCCEEDED(manager->CreateEvent(presContext, nsnull, NS_LITERAL_STRING("Events"), getter_AddRefs(event)))) {
|
||||
if (NS_SUCCEEDED(nsEventDispatcher::CreateEvent(presContext, nsnull,
|
||||
NS_LITERAL_STRING("Events"),
|
||||
getter_AddRefs(event)))) {
|
||||
event->InitEvent(NS_LITERAL_STRING("ValueChange"), PR_TRUE, PR_TRUE);
|
||||
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
|
||||
privateEvent->SetTrusted(PR_TRUE);
|
||||
|
||||
PRBool defaultActionEnabled;
|
||||
presContext->EventStateManager()->DispatchNewEvent(mContent, event,
|
||||
&defaultActionEnabled);
|
||||
nsEventDispatcher::DispatchDOMEvent(mContent, nsnull, event, nsnull,
|
||||
nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include "nsIPresShell.h"
|
||||
#include "nsHTMLParts.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsIEventListenerManager.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
|
@ -1972,8 +1973,7 @@ nsListControlFrame::FireOnChange()
|
|||
|
||||
nsIPresShell *presShell = GetPresContext()->GetPresShell();
|
||||
if (presShell) {
|
||||
presShell->HandleEventWithTarget(&event, this, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
presShell->HandleEventWithTarget(&event, this, nsnull, &status);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2409,19 +2409,18 @@ nsListControlFrame::FireMenuItemActiveEvent()
|
|||
}
|
||||
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
mContent->GetListenerManager(getter_AddRefs(manager));
|
||||
nsPresContext* presContext = GetPresContext();
|
||||
if (manager &&
|
||||
NS_SUCCEEDED(manager->CreateEvent(presContext, nsnull, NS_LITERAL_STRING("Events"), getter_AddRefs(event)))) {
|
||||
nsEventDispatcher::CreateEvent(presContext, nsnull,
|
||||
NS_LITERAL_STRING("Events"),
|
||||
getter_AddRefs(event));
|
||||
if (event) {
|
||||
event->InitEvent(NS_LITERAL_STRING("DOMMenuItemActive"), PR_TRUE, PR_TRUE);
|
||||
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
|
||||
privateEvent->SetTrusted(PR_TRUE);
|
||||
|
||||
PRBool defaultActionEnabled;
|
||||
presContext->EventStateManager()->DispatchNewEvent(optionContent, event,
|
||||
&defaultActionEnabled);
|
||||
nsEventDispatcher::DispatchDOMEvent(optionContent, nsnull, event, nsnull,
|
||||
nsnull);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -277,7 +277,7 @@ nsTextInputListener::NotifySelectionChanged(nsIDOMDocument* aDoc, nsISelection*
|
|||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent event(PR_TRUE, NS_FORM_SELECTED);
|
||||
|
||||
presShell->HandleEventWithTarget(&event,mFrame,content,NS_EVENT_FLAG_INIT,&status);
|
||||
presShell->HandleEventWithTarget(&event, mFrame, content, &status);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2602,8 +2602,8 @@ nsTextControlFrame::FireOnInput()
|
|||
|
||||
// Have the content handle the event, propagating it according to normal
|
||||
// DOM rules.
|
||||
GetPresContext()->PresShell()->HandleEventWithTarget(&event, nsnull,
|
||||
mContent, NS_EVENT_FLAG_INIT, &status);
|
||||
GetPresContext()->PresShell()->HandleEventWithTarget(&event, nsnull, mContent,
|
||||
&status);
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -2625,7 +2625,7 @@ nsTextControlFrame::CheckFireOnChange()
|
|||
nsInputEvent event(PR_TRUE, NS_FORM_CHANGE, nsnull);
|
||||
|
||||
GetPresContext()->PresShell()->HandleEventWithTarget(&event, nsnull,
|
||||
mContent, NS_EVENT_FLAG_INIT, &status);
|
||||
mContent, &status);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -77,6 +77,7 @@
|
|||
#include "nsPresState.h"
|
||||
#include "nsIGlobalHistory3.h"
|
||||
#include "nsDocShellCID.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#ifdef ACCESSIBILITY
|
||||
#include "nsIAccessibilityService.h"
|
||||
#endif
|
||||
|
@ -1872,12 +1873,13 @@ nsGfxScrollFrameInner::FireScrollEvent()
|
|||
if (mIsRoot) {
|
||||
nsIDocument* doc = content->GetCurrentDoc();
|
||||
if (doc) {
|
||||
doc->HandleDOMEvent(prescontext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(doc, prescontext, &event, nsnull, &status);
|
||||
}
|
||||
} else {
|
||||
content->HandleDOMEvent(prescontext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
// scroll events fired at elements don't bubble (although scroll events
|
||||
// fired at documents do, to the window)
|
||||
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
|
||||
nsEventDispatcher::Dispatch(content, prescontext, &event, nsnull, &status);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
#include "nsTransform2D.h"
|
||||
#include "nsIEventListenerManager.h"
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsContentUtils.h"
|
||||
|
@ -2205,19 +2206,15 @@ nsBoxFrame::FireDOMEvent(const nsAString& aDOMEventName, nsIContent *aContent)
|
|||
if (content && presContext) {
|
||||
// Fire a DOM event
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
nsCOMPtr<nsIEventListenerManager> manager;
|
||||
content->GetListenerManager(getter_AddRefs(manager));
|
||||
if (manager && NS_SUCCEEDED(manager->CreateEvent(presContext, nsnull,
|
||||
NS_LITERAL_STRING("Events"),
|
||||
getter_AddRefs(event)))) {
|
||||
if (nsEventDispatcher::CreateEvent(presContext, nsnull,
|
||||
NS_LITERAL_STRING("Events"),
|
||||
getter_AddRefs(event))) {
|
||||
event->InitEvent(aDOMEventName, PR_TRUE, PR_TRUE);
|
||||
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
|
||||
privateEvent->SetTrusted(PR_TRUE);
|
||||
|
||||
PRBool defaultActionEnabled;
|
||||
presContext->EventStateManager()->
|
||||
DispatchNewEvent(content, event, &defaultActionEnabled);
|
||||
nsEventDispatcher::DispatchDOMEvent(content, nsnull, event, nsnull,
|
||||
nsnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@
|
|||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsDisplayList.h"
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
|
@ -98,7 +99,8 @@
|
|||
#define ONLOAD_CALLED_TOO_EARLY 1
|
||||
|
||||
static void PR_CALLBACK
|
||||
HandleImagePLEvent(nsIContent *aContent, PRUint32 aMessage, PRUint32 aFlags)
|
||||
HandleImagePLEvent(nsIContent *aContent, PRUint32 aMessage,
|
||||
PRUint32 aEventFlags)
|
||||
{
|
||||
if (!aContent) {
|
||||
NS_ERROR("null node passed to HandleImagePLEvent!");
|
||||
|
@ -125,7 +127,8 @@ HandleImagePLEvent(nsIContent *aContent, PRUint32 aMessage, PRUint32 aFlags)
|
|||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent event(PR_TRUE, aMessage);
|
||||
|
||||
aContent->HandleDOMEvent(pres_context, &event, nsnull, aFlags, &status);
|
||||
event.flags |= aEventFlags;
|
||||
nsEventDispatcher::Dispatch(aContent, pres_context, &event, nsnull, &status);
|
||||
}
|
||||
|
||||
static void* PR_CALLBACK
|
||||
|
@ -134,7 +137,7 @@ HandleImageOnloadPLEvent(PLEvent *aEvent)
|
|||
nsIContent *content = (nsIContent *)PL_GetEventOwner(aEvent);
|
||||
|
||||
HandleImagePLEvent(content, NS_IMAGE_LOAD,
|
||||
NS_EVENT_FLAG_INIT | NS_EVENT_FLAG_CANT_BUBBLE);
|
||||
NS_EVENT_FLAG_CANT_BUBBLE);
|
||||
|
||||
// XXXldb Why not put this in DestroyImagePLEvent?
|
||||
NS_RELEASE(content);
|
||||
|
@ -147,7 +150,7 @@ HandleImageOnerrorPLEvent(PLEvent *aEvent)
|
|||
{
|
||||
nsIContent *content = (nsIContent *)PL_GetEventOwner(aEvent);
|
||||
|
||||
HandleImagePLEvent(content, NS_IMAGE_ERROR, NS_EVENT_FLAG_INIT);
|
||||
HandleImagePLEvent(content, NS_IMAGE_ERROR, NS_EVENT_FLAG_CANT_BUBBLE);
|
||||
|
||||
// XXXldb Why not put this in DestroyImagePLEvent?
|
||||
NS_RELEASE(content);
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
#include "nsIViewManager.h"
|
||||
#include "nsXULAtoms.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
//
|
||||
// NS_NewResizerFrame
|
||||
|
@ -335,6 +336,5 @@ nsResizerFrame::MouseClicked(nsPresContext* aPresContext, nsGUIEvent *aEvent)
|
|||
nsMouseEvent event(aEvent ? NS_IS_TRUSTED_EVENT(aEvent) : PR_FALSE,
|
||||
NS_XUL_COMMAND, nsnull, nsMouseEvent::eReal);
|
||||
|
||||
mContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT,
|
||||
&status);
|
||||
nsEventDispatcher::Dispatch(mContent, aPresContext, &event, nsnull, &status);
|
||||
}
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIViewManager.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsDisplayList.h"
|
||||
|
||||
//
|
||||
|
@ -219,6 +220,5 @@ nsTitleBarFrame::MouseClicked(nsPresContext* aPresContext, nsGUIEvent* aEvent)
|
|||
nsMouseEvent event(aEvent ? NS_IS_TRUSTED_EVENT(aEvent) : PR_FALSE,
|
||||
NS_XUL_COMMAND, nsnull, nsMouseEvent::eReal);
|
||||
|
||||
mContent->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT,
|
||||
&status);
|
||||
nsEventDispatcher::Dispatch(mContent, aPresContext, &event, nsnull, &status);
|
||||
}
|
||||
|
|
|
@ -99,6 +99,7 @@
|
|||
#include "nsContentUtils.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsDisplayList.h"
|
||||
|
||||
#ifdef IBMBIDI
|
||||
|
@ -829,7 +830,7 @@ nsTreeBodyFrame::CheckOverflow()
|
|||
event.orient = nsScrollPortEvent::vertical;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
mContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(mContent, presContext, &event, nsnull, &status);
|
||||
}
|
||||
|
||||
PRBool horizontalOverflowChanged = PR_FALSE;
|
||||
|
@ -863,7 +864,7 @@ nsTreeBodyFrame::CheckOverflow()
|
|||
event.orient = nsScrollPortEvent::horizontal;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
mContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(mContent, presContext, &event, nsnull, &status);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3485,10 +3486,12 @@ nsTreeBodyFrame::ScrollInternal(PRInt32 aRow)
|
|||
}
|
||||
|
||||
nsScrollbarEvent event(PR_TRUE, NS_SCROLL_EVENT, nsnull);
|
||||
event.flags = 0;
|
||||
// scroll events fired at elements don't bubble (although scroll events
|
||||
// fired at documents do, to the window)
|
||||
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
mContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(mContent, presContext, &event, nsnull, &status);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -3538,10 +3541,12 @@ nsTreeBodyFrame::ScrollHorzInternal(PRInt32 aPosition)
|
|||
|
||||
// And fire off an event about it all
|
||||
nsScrollbarEvent event(PR_TRUE, NS_SCROLL_EVENT, nsnull);
|
||||
event.flags = 0;
|
||||
// scroll events fired at elements don't bubble (although scroll events
|
||||
// fired at documents do, to the window)
|
||||
event.flags |= NS_EVENT_FLAG_CANT_BUBBLE;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
mContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
nsEventDispatcher::Dispatch(mContent, presContext, &event, nsnull, &status);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "nsINameSpaceManager.h"
|
||||
#include "nsXULAtoms.h"
|
||||
#include "nsPLDOMEvent.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
// A helper class for managing our ranges of selection.
|
||||
struct nsTreeRange
|
||||
|
@ -783,8 +784,7 @@ nsTreeSelection::FireOnSelectHandler()
|
|||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent event(PR_TRUE, NS_FORM_SELECTED);
|
||||
|
||||
content->HandleDOMEvent(aPresContext, &event, nsnull, NS_EVENT_FLAG_INIT,
|
||||
&status);
|
||||
nsEventDispatcher::Dispatch(content, aPresContext, &event, nsnull, &status);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
|
|
@ -212,7 +212,7 @@
|
|||
<![CDATA[
|
||||
try {
|
||||
var event = document.createEvent("Events");
|
||||
event.initEvent(aEventName, false, true);
|
||||
event.initEvent(aEventName, true, true);
|
||||
var cancel = !aTarget.dispatchEvent(event);
|
||||
if (aTarget.hasAttribute("on" + aEventName)) {
|
||||
var fn = new Function ("event", aTarget.getAttribute("on" + aEventName));
|
||||
|
@ -483,7 +483,7 @@
|
|||
<![CDATA[
|
||||
try {
|
||||
var event = document.createEvent("Events");
|
||||
event.initEvent(aEventName, false, true);
|
||||
event.initEvent(aEventName, true, true);
|
||||
var cancel = !aTarget.dispatchEvent(event);
|
||||
if (aTarget.hasAttribute("on" + aEventName)) {
|
||||
var fn = new Function ("event", aTarget.getAttribute("on" + aEventName));
|
||||
|
|
|
@ -59,8 +59,7 @@
|
|||
|
||||
<content>
|
||||
<xul:stringbundle src="chrome://global/locale/tabbrowser.properties"/>
|
||||
<xul:tabbox flex="1" eventnode="document" xbl:inherits="handleCtrlPageUpDown"
|
||||
onselect="if (!('updateCurrentBrowser' in this.parentNode) || event.target.localName != 'tabpanels') return; this.parentNode.updateCurrentBrowser();">
|
||||
<xul:tabbox flex="1" eventnode="document" xbl:inherits="handleCtrlPageUpDown">
|
||||
<xul:hbox class="tab-drop-indicator-bar">
|
||||
<xul:hbox class="tab-drop-indicator"/>
|
||||
</xul:hbox>
|
||||
|
@ -107,7 +106,10 @@
|
|||
class="tabbrowser-tab" label="&untitledTab;" crop="end"/>
|
||||
</xul:tabs>
|
||||
</xul:hbox>
|
||||
<xul:tabpanels flex="1" class="plain" selectedIndex="0">
|
||||
<xul:tabpanels flex="1" class="plain" selectedIndex="0"
|
||||
onselect="if (!('updateCurrentBrowser' in this.parentNode.parentNode) ||
|
||||
event.target != this) return;
|
||||
this.parentNode.parentNode.updateCurrentBrowser();">
|
||||
<xul:vbox flex="1">
|
||||
<xul:browsermessage hidden="true" type="top"/>
|
||||
<xul:browser flex="1" type="content-primary" message="true" disablehistory="true" xbl:inherits="tooltip=contenttooltip,contextmenu=contentcontextmenu,autocompletepopup"/>
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
#ifdef WIN32
|
||||
#undef ERROR
|
||||
#endif
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
|
||||
class nsIRenderingContext;
|
||||
|
@ -61,6 +62,7 @@ class nsIMenuItem;
|
|||
class nsIAccessible;
|
||||
class nsIContent;
|
||||
class nsIURI;
|
||||
class nsIDOMEventTarget;
|
||||
|
||||
/**
|
||||
* Event Struct Types
|
||||
|
@ -92,7 +94,7 @@ class nsIURI;
|
|||
#define NS_BEFORE_PAGE_UNLOAD_EVENT 26
|
||||
#define NS_UI_EVENT 27
|
||||
#define NS_QUERYCARETRECT_EVENT 28
|
||||
#define NS_PAGETRANSITION_EVENT 29
|
||||
#define NS_PAGETRANSITION_EVENT 29
|
||||
#ifdef MOZ_SVG
|
||||
#define NS_SVG_EVENT 30
|
||||
#define NS_SVGZOOM_EVENT 31
|
||||
|
@ -422,6 +424,12 @@ public:
|
|||
PRUint32 internalAppFlags;
|
||||
// Additional type info for user defined events
|
||||
nsHashKey* userType;
|
||||
// Event targets, needed by DOM Events
|
||||
// Using nsISupports, not nsIDOMEventTarget because in some cases
|
||||
// nsIDOMEventTarget is implemented as a tearoff.
|
||||
nsCOMPtr<nsISupports> target;
|
||||
nsCOMPtr<nsISupports> currentTarget;
|
||||
nsCOMPtr<nsISupports> originalTarget;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -1069,12 +1069,10 @@ MenuHelpersX::DispatchCommandTo(nsIWeakReference* aDocShellWeakRef,
|
|||
domDoc->GetElementById(command, getter_AddRefs(commandElt));
|
||||
nsCOMPtr<nsIContent> commandContent(do_QueryInterface(commandElt));
|
||||
if (commandContent)
|
||||
commandContent->HandleDOMEvent(presContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
commandContent->DispatchDOMEvent(&event, nsnull, presContext, &status);
|
||||
}
|
||||
else
|
||||
aTargetContent->HandleDOMEvent(presContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
aTargetContent->DispatchDOMEvent(&event, nsnull, presContext, &status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -269,10 +269,10 @@ NS_METHOD nsMenuItemX::DoCommand()
|
|||
domDoc->GetElementById(command, getter_AddRefs(commandElt));
|
||||
nsCOMPtr<nsIContent> commandContent(do_QueryInterface(commandElt));
|
||||
if (commandContent)
|
||||
commandContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
commandContent->DispatchDOMEvent(&event, nsnull, presContext, &status);
|
||||
}
|
||||
else
|
||||
mContent->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
mContent->DispatchDOMEvent(&event, nsnull, presContext, &status);
|
||||
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
|
|
|
@ -739,7 +739,7 @@ nsMenuX::OnCreate()
|
|||
if (presContext) {
|
||||
nsresult rv = NS_OK;
|
||||
nsIContent* dispatchTo = popupContent ? popupContent : mMenuContent;
|
||||
rv = dispatchTo->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
rv = dispatchTo->DispatchDOMEvent(&event, nsnull, presContext, &status);
|
||||
if (NS_FAILED(rv) || status == nsEventStatus_eConsumeNoDefault)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -822,7 +822,7 @@ nsMenuX::OnCreated()
|
|||
if (presContext) {
|
||||
nsresult rv = NS_OK;
|
||||
nsIContent* dispatchTo = popupContent ? popupContent : mMenuContent;
|
||||
rv = dispatchTo->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
rv = dispatchTo->DispatchDOMEvent(&event, nsnull, presContext, &status);
|
||||
if (NS_FAILED(rv) || status == nsEventStatus_eConsumeNoDefault)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -860,7 +860,7 @@ nsMenuX::OnDestroy()
|
|||
if (presContext) {
|
||||
nsresult rv = NS_OK;
|
||||
nsIContent* dispatchTo = popupContent ? popupContent : mMenuContent;
|
||||
rv = dispatchTo->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
rv = dispatchTo->DispatchDOMEvent(&event, nsnull, presContext, &status);
|
||||
|
||||
mDestroyHandlerCalled = PR_TRUE;
|
||||
|
||||
|
@ -891,7 +891,7 @@ nsMenuX::OnDestroyed()
|
|||
if (presContext) {
|
||||
nsresult rv = NS_OK;
|
||||
nsIContent* dispatchTo = popupContent ? popupContent : mMenuContent;
|
||||
rv = dispatchTo->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
rv = dispatchTo->DispatchDOMEvent(&event, nsnull, presContext, &status);
|
||||
|
||||
mDestroyHandlerCalled = PR_TRUE;
|
||||
|
||||
|
|
|
@ -933,12 +933,10 @@ MenuHelpersX::DispatchCommandTo(nsIWeakReference* aDocShellWeakRef,
|
|||
domDoc->GetElementById(command, getter_AddRefs(commandElt));
|
||||
nsCOMPtr<nsIContent> commandContent(do_QueryInterface(commandElt));
|
||||
if (commandContent)
|
||||
commandContent->HandleDOMEvent(presContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
commandContent->DispatchDOMEvent(&event, nsnull, presContext, &status);
|
||||
}
|
||||
else
|
||||
aTargetContent->HandleDOMEvent(presContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
aTargetContent->DispatchDOMEvent(&event, nsnull, presContext, &status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -979,7 +979,7 @@ nsMenuX::OnCreate()
|
|||
if ( presContext ) {
|
||||
nsresult rv = NS_OK;
|
||||
nsIContent* dispatchTo = popupContent ? popupContent : mMenuContent;
|
||||
rv = dispatchTo->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
rv = dispatchTo->DispatchDOMEvent(&event, nsnull, presContext, &status);
|
||||
if ( NS_FAILED(rv) || status == nsEventStatus_eConsumeNoDefault )
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -1061,7 +1061,7 @@ nsMenuX::OnCreated()
|
|||
if ( presContext ) {
|
||||
nsresult rv = NS_OK;
|
||||
nsIContent* dispatchTo = popupContent ? popupContent : mMenuContent;
|
||||
rv = dispatchTo->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
rv = dispatchTo->DispatchDOMEvent(&event, nsnull, presContext, &status);
|
||||
if ( NS_FAILED(rv) || status == nsEventStatus_eConsumeNoDefault )
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
@ -1099,7 +1099,7 @@ nsMenuX::OnDestroy()
|
|||
if (presContext ) {
|
||||
nsresult rv = NS_OK;
|
||||
nsIContent* dispatchTo = popupContent ? popupContent : mMenuContent;
|
||||
rv = dispatchTo->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
rv = dispatchTo->DispatchDOMEvent(&event, nsnull, presContext, &status);
|
||||
|
||||
mDestroyHandlerCalled = PR_TRUE;
|
||||
|
||||
|
@ -1130,7 +1130,7 @@ nsMenuX::OnDestroyed()
|
|||
if (presContext ) {
|
||||
nsresult rv = NS_OK;
|
||||
nsIContent* dispatchTo = popupContent ? popupContent : mMenuContent;
|
||||
rv = dispatchTo->HandleDOMEvent(presContext, &event, nsnull, NS_EVENT_FLAG_INIT, &status);
|
||||
rv = dispatchTo->DispatchDOMEvent(&event, nsnull, presContext, &status);
|
||||
|
||||
mDestroyHandlerCalled = PR_TRUE;
|
||||
|
||||
|
|
|
@ -56,6 +56,9 @@
|
|||
#include "nsEscape.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIDOMEventReceiver.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsIEventListenerManager.h"
|
||||
#include "nsIDOMFocusListener.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
|
@ -797,8 +800,8 @@ PRBool nsWebShellWindow::ExecuteCloseHandler()
|
|||
nsMouseEvent event(PR_TRUE, NS_XUL_CLOSE, nsnull,
|
||||
nsMouseEvent::eReal);
|
||||
|
||||
nsresult rv = window->HandleDOMEvent(presContext, &event, nsnull,
|
||||
NS_EVENT_FLAG_INIT, &status);
|
||||
nsresult rv =
|
||||
window->DispatchDOMEvent(&event, nsnull, presContext, &status);
|
||||
if (NS_SUCCEEDED(rv) && status == nsEventStatus_eConsumeNoDefault)
|
||||
return PR_TRUE;
|
||||
// else fall through and return PR_FALSE
|
||||
|
|
|
@ -109,7 +109,8 @@
|
|||
class="tabbrowser-tab" label="&untitledTab;" crop="end"/>
|
||||
</xul:tabs>
|
||||
</xul:hbox>
|
||||
<xul:tabpanels flex="1" class="plain" selectedIndex="0" anonid="panelcontainer">
|
||||
<xul:tabpanels flex="1" class="plain" selectedIndex="0" anonid="panelcontainer"
|
||||
onselect="if (event.originalTarget == this) this.parentNode.parentNode.updateCurrentBrowser();">
|
||||
<xul:browser type="content-primary" xbl:inherits="tooltip=contenttooltip,contextmenu=contentcontextmenu"/>
|
||||
</xul:tabpanels>
|
||||
</xul:tabbox>
|
||||
|
@ -1830,8 +1831,6 @@
|
|||
</implementation>
|
||||
|
||||
<handlers>
|
||||
<handler event="select" action="if (event.originalTarget == this.mPanelContainer) this.updateCurrentBrowser();"/>
|
||||
|
||||
<handler event="DOMLinkAdded" action="this.onLinkAdded(event);"/>
|
||||
|
||||
<handler event="DOMWindowClose">
|
||||
|
|
Загрузка…
Ссылка в новой задаче