Bug 822898 - Implement pointer events. Detect Pointer Listeners. r=smaug

This commit is contained in:
Oleg Romashin 2014-02-10 22:33:29 -08:00
parent e37ecae927
commit baddfd8a3b
5 changed files with 43 additions and 1 deletions

View File

@ -503,6 +503,9 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, bool aClone, bool aDeep,
if (elm->MayHaveMouseEnterLeaveEventListener()) {
window->SetHasMouseEnterLeaveEventListeners();
}
if (elm->MayHavePointerEnterLeaveEventListener()) {
window->SetHasPointerEnterLeaveEventListeners();
}
}
}
}

View File

@ -555,6 +555,7 @@ nsPIDOMWindow::nsPIDOMWindow(nsPIDOMWindow *aOuterWindow)
mIsHandlingResizeEvent(false), mIsInnerWindow(aOuterWindow != nullptr),
mMayHavePaintEventListener(false), mMayHaveTouchEventListener(false),
mMayHaveMouseEnterLeaveEventListener(false),
mMayHavePointerEnterLeaveEventListener(false),
mIsModalContentWindow(false),
mIsActive(false), mIsBackground(false),
mInnerWindow(nullptr), mOuterWindow(aOuterWindow),

View File

@ -483,6 +483,25 @@ public:
mMayHaveMouseEnterLeaveEventListener = true;
}
/**
* Call this to check whether some node (this window, its document,
* or content in that document) has a Pointerenter/leave event listener.
*/
bool HasPointerEnterLeaveEventListeners()
{
return mMayHavePointerEnterLeaveEventListener;
}
/**
* Call this to indicate that some node (this window, its document,
* or content in that document) has a Pointerenter/leave event listener.
*/
void SetHasPointerEnterLeaveEventListeners()
{
mMayHavePointerEnterLeaveEventListener = true;
}
virtual JSObject* GetCachedXBLPrototypeHandler(nsXBLPrototypeHandler* aKey) = 0;
virtual void CacheXBLPrototypeHandler(nsXBLPrototypeHandler* aKey,
JS::Handle<JSObject*> aHandler) = 0;
@ -733,6 +752,7 @@ protected:
bool mMayHavePaintEventListener;
bool mMayHaveTouchEventListener;
bool mMayHaveMouseEnterLeaveEventListener;
bool mMayHavePointerEnterLeaveEventListener;
// This variable is used on both inner and outer windows (and they
// should match).

View File

@ -94,6 +94,7 @@ nsEventListenerManager::nsEventListenerManager(EventTarget* aTarget) :
mMayHaveAudioAvailableEventListener(false),
mMayHaveTouchEventListener(false),
mMayHaveMouseEnterLeaveEventListener(false),
mMayHavePointerEnterLeaveEventListener(false),
mClearingListeners(false),
mIsMainThreadELM(NS_IsMainThread()),
mNoListenerForEvent(0),
@ -340,6 +341,21 @@ nsEventListenerManager::AddEventListenerInternal(
if (window && !aFlags.mInSystemGroup) {
window->SetHasTouchEventListeners();
}
} else if (aType >= NS_POINTER_EVENT_START && aType <= NS_POINTER_LOST_CAPTURE) {
nsPIDOMWindow* window = GetInnerWindowForTarget();
if (aTypeAtom == nsGkAtoms::onpointerenter ||
aTypeAtom == nsGkAtoms::onpointerleave) {
mMayHavePointerEnterLeaveEventListener = true;
if (window) {
#ifdef DEBUG
nsCOMPtr<nsIDocument> d = window->GetExtantDoc();
NS_WARN_IF_FALSE(!nsContentUtils::IsChromeDoc(d),
"Please do not use pointerenter/leave events in chrome. "
"They are slower than pointerover/out!");
#endif
window->SetHasPointerEnterLeaveEventListeners();
}
}
} else if (aTypeAtom == nsGkAtoms::onmouseenter ||
aTypeAtom == nsGkAtoms::onmouseleave) {
mMayHaveMouseEnterLeaveEventListener = true;

View File

@ -399,6 +399,7 @@ public:
bool MayHaveTouchEventListener() { return mMayHaveTouchEventListener; }
bool MayHaveMouseEnterLeaveEventListener() { return mMayHaveMouseEnterLeaveEventListener; }
bool MayHavePointerEnterLeaveEventListener() { return mMayHavePointerEnterLeaveEventListener; }
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
@ -548,9 +549,10 @@ protected:
uint32_t mMayHaveAudioAvailableEventListener : 1;
uint32_t mMayHaveTouchEventListener : 1;
uint32_t mMayHaveMouseEnterLeaveEventListener : 1;
uint32_t mMayHavePointerEnterLeaveEventListener : 1;
uint32_t mClearingListeners : 1;
uint32_t mIsMainThreadELM : 1;
uint32_t mNoListenerForEvent : 23;
uint32_t mNoListenerForEvent : 22;
nsAutoTObserverArray<nsListenerStruct, 2> mListeners;
mozilla::dom::EventTarget* mTarget; //WEAK