Bug 1073563 - The lostpointercapture event must be dispatched before any other pointer events. r=smaug

This commit is contained in:
Lebedev Maksim 2014-10-08 16:27:34 -07:00
parent 87c112ff47
commit 49e9bd979c
2 changed files with 12 additions and 3 deletions

View File

@ -1257,7 +1257,10 @@ public:
static void SetPointerCapturingContent(uint32_t aPointerId, nsIContent* aContent);
static void ReleasePointerCapturingContent(uint32_t aPointerId, nsIContent* aContent);
static nsIContent* GetPointerCapturingContent(uint32_t aPointerId);
static void CheckPointerCaptureState(uint32_t aPointerId);
// CheckPointerCaptureState checks cases, when got/lostpointercapture events should be fired.
// Function returns true, if any of events was fired; false, if no one event was fired.
static bool CheckPointerCaptureState(uint32_t aPointerId);
// GetPointerInfo returns true if pointer with aPointerId is situated in device, false otherwise.
// aActiveState is additional information, which shows state of pointer like button state for mouse.

View File

@ -6336,9 +6336,10 @@ nsIPresShell::GetPointerCapturingContent(uint32_t aPointerId)
return nullptr;
}
/* static */ void
/* static */ bool
nsIPresShell::CheckPointerCaptureState(uint32_t aPointerId)
{
bool didDispatchEvent = false;
PointerCaptureInfo* pointerCaptureInfo = nullptr;
if (gPointerCaptureList->Get(aPointerId, &pointerCaptureInfo) && pointerCaptureInfo) {
// If pendingContent exist or anybody calls element.releasePointerCapture
@ -6354,6 +6355,7 @@ nsIPresShell::CheckPointerCaptureState(uint32_t aPointerId)
gPointerCaptureList->Remove(aPointerId);
}
DispatchGotOrLostPointerCaptureEvent(false, aPointerId, content);
didDispatchEvent = true;
} else if (pointerCaptureInfo->mPendingContent && pointerCaptureInfo->mReleaseContent) {
// If anybody calls element.releasePointerCapture
// We should clear overrideContent and pendingContent
@ -6369,8 +6371,10 @@ nsIPresShell::CheckPointerCaptureState(uint32_t aPointerId)
pointerCaptureInfo->mPendingContent = nullptr;
pointerCaptureInfo->mReleaseContent = false;
DispatchGotOrLostPointerCaptureEvent(true, aPointerId, pointerCaptureInfo->mOverrideContent);
didDispatchEvent = true;
}
}
return didDispatchEvent;
}
/* static */ bool
@ -7249,7 +7253,9 @@ PresShell::HandleEvent(nsIFrame* aFrame,
if (WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent()) {
// Before any pointer events, we should check state of pointer capture,
// Thus got/lostpointercapture events emulate asynchronous behavior.
CheckPointerCaptureState(pointerEvent->pointerId);
// Handlers of got/lostpointercapture events can change capturing state,
// That's why we should re-check pointer capture state until stable state.
while(CheckPointerCaptureState(pointerEvent->pointerId));
}
}