Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1081)

Unified Diff: Source/core/input/EventHandler.cpp

Issue 1170513002: Update the mouse events on tapping of gesture across frames (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/input/EventHandler.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/input/EventHandler.cpp
diff --git a/Source/core/input/EventHandler.cpp b/Source/core/input/EventHandler.cpp
index d16e9e2e4ef679e408209463115845eef5fa68ce..281c51c160717a3e14a079d24aeb21a18b7ff424 100644
--- a/Source/core/input/EventHandler.cpp
+++ b/Source/core/input/EventHandler.cpp
@@ -1852,6 +1852,10 @@ bool EventHandler::handleGestureEvent(const GestureEventWithHitTestResults& targ
// directly to the inner most frame. This matches handleMousePressEvent etc.
ASSERT(!targetedEvent.event().isScrollEvent());
+ // update mouseout/leave/over/enter events before jumping directly to the inner most frame
+ if (targetedEvent.event().type() == PlatformEvent::GestureTap)
+ updateGestureTargetNodeForMouseEvent(targetedEvent);
+
// Route to the correct frame.
if (LocalFrame* innerFrame = targetedEvent.hitTestResult().innerNodeFrame())
return innerFrame->eventHandler().handleGestureEventInFrame(targetedEvent);
@@ -2481,6 +2485,78 @@ void EventHandler::updateGestureHoverActiveState(const HitTestRequest& request,
m_frame->document()->updateHoverActiveState(request, innerElement);
}
+// Update the mouseover/mouseenter/mouseout/mouseleave events across all frames for this gesture,
+// before passing the targeted gesture event directly to a hit frame.
+void EventHandler::updateGestureTargetNodeForMouseEvent(const GestureEventWithHitTestResults& targetedEvent)
+{
+ ASSERT(m_frame == m_frame->localFrameRoot());
+
+ // Behaviour of this function is as follows:
+ // - Create the chain of all entered frames.
+ // - Compare the last frame chain under the gesture to newly entered frame chain from the main frame one by one.
+ // - If the last frame doesn't match with the entered frame, then create the chain of exited frames from the last frame chain.
+ // - Dispatch mouseout/mouseleave events of the exited frames from the inside out.
+ // - Dispatch mouseover/mouseenter events of the entered frames into the inside.
+
+ // Insert the ancestors of the frame having the new target node to the entered frame chain
+ WillBeHeapVector<LocalFrame*> enteredFrameChain;
+ LocalFrame* enteredFrameInDocument = targetedEvent.hitTestResult().innerNodeFrame();
+ while (enteredFrameInDocument) {
+ enteredFrameChain.append(enteredFrameInDocument);
+ Frame* parentFrame = enteredFrameInDocument->tree().parent();
+ enteredFrameInDocument = parentFrame && parentFrame->isLocalFrame() ? toLocalFrame(parentFrame) : nullptr;
+ }
+
+ size_t indexEnteredFrameChain = enteredFrameChain.size();
+ LocalFrame* exitedFrameInDocument = m_frame;
+ WillBeHeapVector<LocalFrame*> exitedFrameChain;
+ // Insert the frame from the disagreement between last frames and entered frames
+ while (exitedFrameInDocument) {
+ Node* lastNodeUnderTap = exitedFrameInDocument->eventHandler().m_lastNodeUnderMouse.get();
+ if (!lastNodeUnderTap)
+ break;
+
+ LocalFrame* nextExitedFrameInDocument = nullptr;
+ if (lastNodeUnderTap->isFrameOwnerElement()) {
+ HTMLFrameOwnerElement* owner = toHTMLFrameOwnerElement(lastNodeUnderTap);
+ if (owner->contentFrame() && owner->contentFrame()->isLocalFrame())
+ nextExitedFrameInDocument = toLocalFrame(owner->contentFrame());
+ }
+
+ if (exitedFrameChain.size() > 0) {
+ exitedFrameChain.append(exitedFrameInDocument);
+ } else {
+ LocalFrame* lastEnteredFrameInDocument = indexEnteredFrameChain ? enteredFrameChain[indexEnteredFrameChain-1] : nullptr;
+ if (exitedFrameInDocument != lastEnteredFrameInDocument)
+ exitedFrameChain.append(exitedFrameInDocument);
+ else if (nextExitedFrameInDocument && indexEnteredFrameChain)
+ --indexEnteredFrameChain;
+ }
+ exitedFrameInDocument = nextExitedFrameInDocument;
+ }
+
+ const PlatformGestureEvent& gestureEvent = targetedEvent.event();
+ unsigned modifiers = gestureEvent.modifiers();
+ PlatformMouseEvent fakeMouseMove(gestureEvent.position(), gestureEvent.globalPosition(),
+ NoButton, PlatformEvent::MouseMoved, /* clickCount */ 0,
+ static_cast<PlatformEvent::Modifiers>(modifiers),
+ PlatformMouseEvent::FromTouch, gestureEvent.timestamp());
+
+ // Update the mouseout/mouseleave event
+ size_t indexExitedFrameChain = exitedFrameChain.size();
+ while (indexExitedFrameChain) {
+ LocalFrame* leaveFrame = exitedFrameChain[--indexExitedFrameChain];
+ leaveFrame->eventHandler().updateMouseEventTargetNode(nullptr, fakeMouseMove, true);
+ }
+
+ // update the mouseover/mouseenter event
+ while (indexEnteredFrameChain) {
+ Frame* parentFrame = enteredFrameChain[--indexEnteredFrameChain]->tree().parent();
+ if (parentFrame && parentFrame->isLocalFrame())
+ toLocalFrame(parentFrame)->eventHandler().updateMouseEventTargetNode(toHTMLFrameOwnerElement(enteredFrameChain[indexEnteredFrameChain]->owner()), fakeMouseMove, true);
+ }
+}
+
GestureEventWithHitTestResults EventHandler::targetGestureEvent(const PlatformGestureEvent& gestureEvent, bool readOnly)
{
TRACE_EVENT0("input", "EventHandler::targetGestureEvent");
« no previous file with comments | « Source/core/input/EventHandler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698