Bug 1305458 Part2: Add nsIDOMEventTarget::PreHandleEvent. r=smaug

MozReview-Commit-ID: HiCDTXgNr0l

--HG--
extra : rebase_source : ce3318fac96a1baf86059274230b1e6cae750347
This commit is contained in:
Stone Shih 2016-10-21 11:29:34 +08:00
parent 1ed10ff082
commit 6df624de3f
3 changed files with 56 additions and 1 deletions

View File

@ -136,6 +136,7 @@ static bool IsEventTargetChrome(EventTarget* aEventTarget,
#define NS_TARGET_CHAIN_MAY_HAVE_MANAGER (1 << 2)
#define NS_TARGET_CHAIN_CHECKED_IF_CHROME (1 << 3)
#define NS_TARGET_CHAIN_IS_CHROME_CONTENT (1 << 4)
#define NS_TARGET_CHAIN_WANTS_PRE_HANDLE_EVENT (1 << 5)
// EventTargetChainItem represents a single item in the event target chain.
class EventTargetChainItem
@ -209,6 +210,20 @@ public:
return !!(mFlags & NS_TARGET_CHAIN_WANTS_WILL_HANDLE_EVENT);
}
void SetWantsPreHandleEvent(bool aWants)
{
if (aWants) {
mFlags |= NS_TARGET_CHAIN_WANTS_PRE_HANDLE_EVENT;
} else {
mFlags &= ~NS_TARGET_CHAIN_WANTS_PRE_HANDLE_EVENT;
}
}
bool WantsPreHandleEvent()
{
return !!(mFlags & NS_TARGET_CHAIN_WANTS_PRE_HANDLE_EVENT);
}
void SetMayHaveListenerManager(bool aMayHave)
{
if (aMayHave) {
@ -245,6 +260,11 @@ public:
*/
void GetEventTargetParent(EventChainPreVisitor& aVisitor);
/**
* Calls PreHandleEvent for those items which called SetWantsPreHandleEvent.
*/
void PreHandleEvent(EventChainVisitor& aVisitor);
/**
* If the current item in the event target chain has an event listener
* manager, this method calls EventListenerManager::HandleEvent().
@ -324,10 +344,20 @@ EventTargetChainItem::GetEventTargetParent(EventChainPreVisitor& aVisitor)
SetForceContentDispatch(aVisitor.mForceContentDispatch);
SetWantsWillHandleEvent(aVisitor.mWantsWillHandleEvent);
SetMayHaveListenerManager(aVisitor.mMayHaveListenerManager);
SetWantsPreHandleEvent(aVisitor.mWantsPreHandleEvent);
mItemFlags = aVisitor.mItemFlags;
mItemData = aVisitor.mItemData;
}
void
EventTargetChainItem::PreHandleEvent(EventChainVisitor& aVisitor)
{
if (!WantsPreHandleEvent()) {
return;
}
Unused << mTarget->PreHandleEvent(aVisitor);
}
void
EventTargetChainItem::PostHandleEvent(EventChainPostVisitor& aVisitor)
{
@ -706,7 +736,11 @@ EventDispatcher::Dispatch(nsISupports* aTarget,
targets[i] = chain[i].CurrentTarget()->GetTargetForDOMEvent();
}
} else {
// Event target chain is created. Handle the chain.
// Event target chain is created. PreHandle the chain.
for (uint32_t i = 0; i < chain.Length(); ++i) {
chain[i].PreHandleEvent(preVisitor);
}
// Handle the chain.
EventChainPostVisitor postVisitor(preVisitor);
EventTargetChainItem::HandleEventTargetChain(chain, postVisitor,
aCallback, cd);

View File

@ -123,6 +123,7 @@ public:
, mOriginalTargetIsInAnon(aIsInAnon)
, mWantsWillHandleEvent(false)
, mMayHaveListenerManager(true)
, mWantsPreHandleEvent(false)
, mParentTarget(nullptr)
, mEventTargetAtParent(nullptr)
{
@ -137,6 +138,7 @@ public:
mForceContentDispatch = false;
mWantsWillHandleEvent = false;
mMayHaveListenerManager = true;
mWantsPreHandleEvent = false;
mParentTarget = nullptr;
mEventTargetAtParent = nullptr;
}
@ -186,6 +188,12 @@ public:
*/
bool mMayHaveListenerManager;
/**
* Whether or not nsIDOMEventTarget::PreHandleEvent will be called. Default is
* false;
*/
bool mWantsPreHandleEvent;
/**
* Parent item in the event target chain.
*/

View File

@ -13,6 +13,7 @@
using mozilla::dom::Nullable;
namespace mozilla {
class EventChainVisitor;
class EventChainPostVisitor;
class EventChainPreVisitor;
class EventListenerManager;
@ -226,6 +227,18 @@ interface nsIDOMEventTarget : nsISupports
[noscript, nostdcall]
void GetEventTargetParent(in EventChainPreVisitorRef aVisitor);
/**
* Called before the capture phase of the event flow and after event target
* chain creation. This is used to handle those stuffs must be executed before
* dispatch event to DOM
*/
%{C++
virtual nsresult PreHandleEvent(mozilla::EventChainVisitor& aVisitor)
{
return NS_OK;
}
%}
/**
* If EventChainPreVisitor.mWantsWillHandleEvent is set PR_TRUE,
* called just before possible event handlers on this object will be called.