Bug 1420589 Part1: Separate the logic of finding the event target for touch events into a function. r=smaug.
MozReview-Commit-ID: 5IWpVBdiQ3o
This commit is contained in:
@@ -7087,11 +7087,6 @@ PresShell::HandleEvent(nsIFrame* aFrame,
|
||||
}
|
||||
}
|
||||
|
||||
// all touch events except for touchstart use a captured target
|
||||
if (aEvent->mClass == eTouchEventClass && aEvent->mMessage != eTouchStart) {
|
||||
captureRetarget = true;
|
||||
}
|
||||
|
||||
WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent();
|
||||
bool isWindowLevelMouseExit = (aEvent->mMessage == eMouseExitFromWidget) &&
|
||||
(mouseEvent && mouseEvent->mExitFrom == WidgetMouseEvent::eTopLevel);
|
||||
@@ -7102,103 +7097,22 @@ PresShell::HandleEvent(nsIFrame* aFrame,
|
||||
// with a window-level mouse exit event since we want to start sending
|
||||
// mouse out events at the root EventStateManager.
|
||||
if (!captureRetarget && !isWindowLevelMouseExit) {
|
||||
nsPoint eventPoint;
|
||||
uint32_t flags = 0;
|
||||
if (aEvent->mMessage == eTouchStart) {
|
||||
if (gfxPrefs::APZAllowZooming()) {
|
||||
// Setting this flag will skip the scrollbars on the root frame from
|
||||
// participating in hit-testing, and we only want that to happen on
|
||||
// zoomable platforms (for now).
|
||||
if (aEvent->mClass == eTouchEventClass) {
|
||||
frame = TouchManager::SetupTarget(aEvent->AsTouchEvent(), frame);
|
||||
} else {
|
||||
uint32_t flags = 0;
|
||||
nsPoint eventPoint =
|
||||
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, frame);
|
||||
|
||||
if (mouseEvent && mouseEvent->mClass == eMouseEventClass &&
|
||||
mouseEvent->mIgnoreRootScrollFrame) {
|
||||
flags |= INPUT_IGNORE_ROOT_SCROLL_FRAME;
|
||||
}
|
||||
WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent();
|
||||
// if this is a continuing session, ensure that all these events are
|
||||
// in the same document by taking the target of the events already in
|
||||
// the capture list
|
||||
nsCOMPtr<nsIContent> anyTarget;
|
||||
if (touchEvent->mTouches.Length() > 1) {
|
||||
anyTarget = TouchManager::GetAnyCapturedTouchTarget();
|
||||
nsIFrame* target =
|
||||
FindFrameTargetedByInputEvent(aEvent, frame, eventPoint, flags);
|
||||
if (target) {
|
||||
frame = target;
|
||||
}
|
||||
|
||||
// When handling pointerstart with multiple touch points, frame is
|
||||
// overwritten. Keep the original root frame for hit test.
|
||||
nsIFrame* rootFrame = frame;
|
||||
for (int32_t i = touchEvent->mTouches.Length(); i; ) {
|
||||
--i;
|
||||
dom::Touch* touch = touchEvent->mTouches[i];
|
||||
|
||||
int32_t id = touch->Identifier();
|
||||
if (!TouchManager::HasCapturedTouch(id)) {
|
||||
// find the target for this touch
|
||||
eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent,
|
||||
touch->mRefPoint,
|
||||
rootFrame);
|
||||
nsIFrame* target = FindFrameTargetedByInputEvent(aEvent,
|
||||
rootFrame,
|
||||
eventPoint,
|
||||
flags);
|
||||
if (target && !anyTarget) {
|
||||
target->GetContentForEvent(aEvent, getter_AddRefs(anyTarget));
|
||||
while (anyTarget && !anyTarget->IsElement()) {
|
||||
anyTarget = anyTarget->GetParent();
|
||||
}
|
||||
touch->SetTarget(anyTarget);
|
||||
} else {
|
||||
nsIFrame* newTargetFrame = nullptr;
|
||||
for (nsIFrame* f = target; f;
|
||||
f = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(f)) {
|
||||
if (f->PresContext()->Document() == anyTarget->OwnerDoc()) {
|
||||
newTargetFrame = f;
|
||||
break;
|
||||
}
|
||||
// We must be in a subdocument so jump directly to the root frame.
|
||||
// GetParentOrPlaceholderForCrossDoc gets called immediately to
|
||||
// jump up to the containing document.
|
||||
f = f->PresContext()->GetPresShell()->GetRootFrame();
|
||||
}
|
||||
|
||||
// if we couldn't find a target frame in the same document as
|
||||
// anyTarget, remove the touch from the capture touch list, as
|
||||
// well as the event->mTouches array. touchmove events that aren't
|
||||
// in the captured touch list will be discarded
|
||||
if (!newTargetFrame) {
|
||||
touchEvent->mTouches.RemoveElementAt(i);
|
||||
} else {
|
||||
target = newTargetFrame;
|
||||
nsCOMPtr<nsIContent> targetContent;
|
||||
target->GetContentForEvent(aEvent, getter_AddRefs(targetContent));
|
||||
while (targetContent && !targetContent->IsElement()) {
|
||||
targetContent = targetContent->GetParent();
|
||||
}
|
||||
touch->SetTarget(targetContent);
|
||||
}
|
||||
}
|
||||
if (target) {
|
||||
frame = target;
|
||||
}
|
||||
} else {
|
||||
// This touch is an old touch, we need to ensure that is not
|
||||
// marked as changed and set its target correctly
|
||||
touch->mChanged = false;
|
||||
int32_t id = touch->Identifier();
|
||||
|
||||
RefPtr<dom::Touch> oldTouch = TouchManager::GetCapturedTouch(id);
|
||||
if (oldTouch) {
|
||||
touch->SetTarget(oldTouch->mTarget);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, frame);
|
||||
}
|
||||
if (mouseEvent && mouseEvent->mClass == eMouseEventClass &&
|
||||
mouseEvent->mIgnoreRootScrollFrame) {
|
||||
flags |= INPUT_IGNORE_ROOT_SCROLL_FRAME;
|
||||
}
|
||||
nsIFrame* target =
|
||||
FindFrameTargetedByInputEvent(aEvent, frame, eventPoint, flags);
|
||||
if (target) {
|
||||
frame = target;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user