Diff
Modified: trunk/LayoutTests/ChangeLog (241722 => 241723)
--- trunk/LayoutTests/ChangeLog 2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/LayoutTests/ChangeLog 2019-02-18 17:52:34 UTC (rev 241723)
@@ -1,3 +1,16 @@
+2019-02-18 Antoine Quint <grao...@apple.com>
+
+ [iOS] Dispatch additional events along with pointerdown and pointerup
+ https://bugs.webkit.org/show_bug.cgi?id=194776
+ <rdar://problem/48164284>
+
+ Reviewed by Brent Fulgham.
+
+ Added a new test that checks that "pointerover" and "pointerenter" precede "pointerdown" and that "pointerout" and "pointerleave" follow "pointerup".
+
+ * pointerevents/ios/over-enter-out-leave-expected.txt: Added.
+ * pointerevents/ios/over-enter-out-leave.html: Added.
+
2019-02-18 Sihui Liu <sihui_...@apple.com>
IndexedDB: leak IDBDatabase and IDBTransacstion in layout tests
Added: trunk/LayoutTests/pointerevents/ios/over-enter-out-leave-expected.txt (0 => 241723)
--- trunk/LayoutTests/pointerevents/ios/over-enter-out-leave-expected.txt (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/over-enter-out-leave-expected.txt 2019-02-18 17:52:34 UTC (rev 241723)
@@ -0,0 +1,3 @@
+
+PASS Testing that "pointerover" and "pointerenter" precede "pointerdown" and that "pointerout" and "pointerleave" follow "pointerup".
+
Added: trunk/LayoutTests/pointerevents/ios/over-enter-out-leave.html (0 => 241723)
--- trunk/LayoutTests/pointerevents/ios/over-enter-out-leave.html (rev 0)
+++ trunk/LayoutTests/pointerevents/ios/over-enter-out-leave.html 2019-02-18 17:52:34 UTC (rev 241723)
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta charset=utf-8>
+<meta name="viewport" content="width=device-width, initial-scale=1">
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script>
+
+'use strict';
+
+target_test({ width: "200px", height: "200px" }, (target, test) => {
+ document.body.style.width = "2000px";
+ document.body.style.height = "2000px";
+
+ const eventTracker = new EventTracker(target, ["pointerover", "pointerenter", "pointerdown", "pointerup", "pointerout", "pointerleave"]);
+
+ const touch = ui.finger();
+ ui.sequence([
+ touch.begin({ x: 100, y: 100 }),
+ touch.end()
+ ]).then(() => {
+ eventTracker.assertMatchesEvents([
+ { type: "pointerover", x: 100, y: 100, isPrimary: true },
+ { type: "pointerenter", x: 100, y: 100, isPrimary: true },
+ { type: "pointerdown", x: 100, y: 100, isPrimary: true },
+ { type: "pointerup", x: 100, y: 100, isPrimary: false },
+ { type: "pointerout", x: 100, y: 100, isPrimary: false },
+ { type: "pointerleave", x: 100, y: 100, isPrimary: false },
+ ]);
+ test.done();
+ });
+}, `Testing that "pointerover" and "pointerenter" precede "pointerdown" and that "pointerout" and "pointerleave" follow "pointerup".`);
+
+</script>
+</body>
+</html>
\ No newline at end of file
Modified: trunk/Source/WebCore/ChangeLog (241722 => 241723)
--- trunk/Source/WebCore/ChangeLog 2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/Source/WebCore/ChangeLog 2019-02-18 17:52:34 UTC (rev 241723)
@@ -1,3 +1,32 @@
+2019-02-18 Antoine Quint <grao...@apple.com>
+
+ [iOS] Dispatch additional events along with pointerdown and pointerup
+ https://bugs.webkit.org/show_bug.cgi?id=194776
+ <rdar://problem/48164284>
+
+ Reviewed by Brent Fulgham.
+
+ The Pointer Events specification mandates that "pointerover" and "pointerenter" events precede a "pointerdown" event and that "pointerout"
+ and "pointerleave" events follow a "pointerup" event. We remove the EventHandler::dispatchPointerEventForTouchAtIndex() method and replace
+ it with a PointerCaptureController::dispatchEventForTouchAtIndex() that can handle the dispatch of such additional events correctly, also
+ allowing for two PointerCaptureController methods (pointerEventWillBeDispatched and pointerEventWasDispatched) to become private.
+
+ Test: pointerevents/ios/over-enter-out-leave.html
+
+ * dom/EventNames.h: Add the new "pointerover", "pointerenter", "pointerout" and "pointerleave" event types.
+ * dom/PointerEvent.h:
+ * dom/ios/PointerEventIOS.cpp:
+ (WebCore::PointerEvent::create):
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::dispatchPointerEventForTouchAtIndex): Deleted.
+ * page/EventHandler.h:
+ * page/PointerCaptureController.cpp:
+ (WebCore::PointerCaptureController::dispatchEventForTouchAtIndex): Take the existing code from EventHandler::dispatchPointerEventForTouchAtIndex()
+ and extend it to dispatch additional events as mandated. Since several events may be dispatched we check whether the dispatch of any of those events
+ had defaultPrevented() or defaultHanded() return true and return those values as a pair.
+ (WebCore::PointerCaptureController::pointerEventWasDispatched):
+ * page/PointerCaptureController.h:
+
2019-02-18 Sihui Liu <sihui_...@apple.com>
IndexedDB: leak IDBDatabase and IDBTransacstion in layout tests
Modified: trunk/Source/WebCore/dom/EventNames.h (241722 => 241723)
--- trunk/Source/WebCore/dom/EventNames.h 2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/Source/WebCore/dom/EventNames.h 2019-02-18 17:52:34 UTC (rev 241723)
@@ -206,7 +206,11 @@
macro(pointerlockerror) \
macro(pointercancel) \
macro(pointerdown) \
+ macro(pointerenter) \
+ macro(pointerleave) \
macro(pointermove) \
+ macro(pointerout) \
+ macro(pointerover) \
macro(pointerup) \
macro(popstate) \
macro(previoustrack) \
Modified: trunk/Source/WebCore/dom/PointerEvent.h (241722 => 241723)
--- trunk/Source/WebCore/dom/PointerEvent.h 2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/Source/WebCore/dom/PointerEvent.h 2019-02-18 17:52:34 UTC (rev 241723)
@@ -83,6 +83,7 @@
#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
static Ref<PointerEvent> create(const PlatformTouchEvent&, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);
+ static Ref<PointerEvent> create(const String& type, const PlatformTouchEvent&, unsigned touchIndex, bool isPrimary, Ref<WindowProxy>&&);
#endif
static const String& mousePointerType();
Modified: trunk/Source/WebCore/dom/ios/PointerEventIOS.cpp (241722 => 241723)
--- trunk/Source/WebCore/dom/ios/PointerEventIOS.cpp 2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/Source/WebCore/dom/ios/PointerEventIOS.cpp 2019-02-18 17:52:34 UTC (rev 241723)
@@ -63,6 +63,11 @@
return adoptRef(*new PointerEvent(pointerEventType(phase), event, phaseIsCancelable(phase), index, isPrimary, WTFMove(view)));
}
+Ref<PointerEvent> PointerEvent::create(const String& type, const PlatformTouchEvent& event, unsigned index, bool isPrimary, Ref<WindowProxy>&& view)
+{
+ return adoptRef(*new PointerEvent(type, event, phaseIsCancelable(event.touchPhaseAtIndex(index)), index, isPrimary, WTFMove(view)));
+}
+
PointerEvent::PointerEvent(const AtomicString& type, const PlatformTouchEvent& event, IsCancelable isCancelable, unsigned index, bool isPrimary, Ref<WindowProxy>&& view)
: MouseEvent(type, CanBubble::Yes, isCancelable, IsComposed::Yes, event.timestamp().approximateMonotonicTime(), WTFMove(view), 0, event.touchLocationAtIndex(index), event.touchLocationAtIndex(index), { }, event.modifiers(), 0, 0, nullptr, 0, 0, nullptr, IsSimulated::No, IsTrusted::Yes)
, m_pointerId(event.touchIdentifierAtIndex(index))
Modified: trunk/Source/WebCore/page/EventHandler.cpp (241722 => 241723)
--- trunk/Source/WebCore/page/EventHandler.cpp 2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2019-02-18 17:52:34 UTC (rev 241723)
@@ -114,11 +114,6 @@
#include "TouchList.h"
#endif
-#if ENABLE(TOUCH_EVENTS) && ENABLE(POINTER_EVENTS)
-#include "PointerCaptureController.h"
-#include "PointerEvent.h"
-#endif
-
#if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
#include "PlatformTouchEvent.h"
#endif
@@ -4271,18 +4266,6 @@
}
#endif // ENABLE(TOUCH_EVENTS)
-#if ENABLE(TOUCH_EVENTS) && ENABLE(POINTER_EVENTS)
-Ref<PointerEvent> EventHandler::dispatchPointerEventForTouchAtIndex(EventTarget& target, const PlatformTouchEvent& platformTouchEvent, unsigned index, bool isPrimary)
-{
- auto& pointerCaptureController = m_frame.page()->pointerCaptureController();
- auto pointerEvent = PointerEvent::create(platformTouchEvent, index, isPrimary, m_frame.windowProxy());
- pointerCaptureController.pointerEventWillBeDispatched(pointerEvent, &target);
- target.dispatchEvent(pointerEvent);
- pointerCaptureController.pointerEventWasDispatched(pointerEvent);
- return pointerEvent;
-}
-#endif // ENABLE(TOUCH_EVENTS) && ENABLE(POINTER_EVENTS)
-
void EventHandler::setLastKnownMousePosition(const PlatformMouseEvent& event)
{
m_mousePositionIsUnknown = false;
Modified: trunk/Source/WebCore/page/EventHandler.h (241722 => 241723)
--- trunk/Source/WebCore/page/EventHandler.h 2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/Source/WebCore/page/EventHandler.h 2019-02-18 17:52:34 UTC (rev 241723)
@@ -81,7 +81,6 @@
class PlatformKeyboardEvent;
class PlatformTouchEvent;
class PlatformWheelEvent;
-class PointerEvent;
class RenderBox;
class RenderElement;
class RenderLayer;
@@ -320,10 +319,6 @@
WEBCORE_EXPORT bool handleTouchEvent(const PlatformTouchEvent&);
#endif
-#if ENABLE(TOUCH_EVENTS) && ENABLE(POINTER_EVENTS)
- Ref<PointerEvent> dispatchPointerEventForTouchAtIndex(EventTarget&, const PlatformTouchEvent&, unsigned, bool isPrimary);
-#endif
-
bool useHandCursor(Node*, bool isOverLink, bool shiftKey);
void updateCursor();
Modified: trunk/Source/WebCore/page/PointerCaptureController.cpp (241722 => 241723)
--- trunk/Source/WebCore/page/PointerCaptureController.cpp 2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/Source/WebCore/page/PointerCaptureController.cpp 2019-02-18 17:52:34 UTC (rev 241723)
@@ -134,6 +134,47 @@
return iterator != m_activePointerIdsToCapturingData.end() && iterator->value.cancelled;
}
+#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
+std::pair<bool, bool> PointerCaptureController::dispatchEventForTouchAtIndex(EventTarget& target, const PlatformTouchEvent& platformTouchEvent, unsigned index, bool isPrimary, WindowProxy& view)
+{
+ bool defaultPrevented = false;
+ bool defaultHandled = false;
+
+ auto dispatchEvent = [&](const String& type) {
+ auto event = PointerEvent::create(type, platformTouchEvent, index, isPrimary, view);
+ target.dispatchEvent(event);
+ defaultPrevented |= event->defaultPrevented();
+ defaultHandled |= event->defaultHandled();
+ };
+
+ auto pointerEvent = PointerEvent::create(platformTouchEvent, index, isPrimary, view);
+
+ if (pointerEvent->type() == eventNames().pointerdownEvent) {
+ // https://w3c.github.io/pointerevents/#the-pointerdown-event
+ // For input devices that do not support hover, a user agent MUST also fire a pointer event named pointerover followed by a pointer event named
+ // pointerenter prior to dispatching the pointerdown event.
+ dispatchEvent(eventNames().pointeroverEvent);
+ dispatchEvent(eventNames().pointerenterEvent);
+ }
+
+ pointerEventWillBeDispatched(pointerEvent, &target);
+ target.dispatchEvent(pointerEvent);
+ defaultPrevented |= pointerEvent->defaultPrevented();
+ defaultHandled |= pointerEvent->defaultHandled();
+ pointerEventWasDispatched(pointerEvent);
+
+ if (pointerEvent->type() == eventNames().pointerupEvent) {
+ // https://w3c.github.io/pointerevents/#the-pointerup-event
+ // For input devices that do not support hover, a user agent MUST also fire a pointer event named pointerout followed by a
+ // pointer event named pointerleave after dispatching the pointerup event.
+ dispatchEvent(eventNames().pointeroutEvent);
+ dispatchEvent(eventNames().pointerleaveEvent);
+ }
+
+ return { defaultPrevented, defaultHandled };
+}
+#endif
+
void PointerCaptureController::pointerEventWillBeDispatched(const PointerEvent& event, EventTarget* target)
{
// https://w3c.github.io/pointerevents/#implicit-pointer-capture
@@ -170,7 +211,7 @@
// Pointer Capture steps to fire lostpointercapture if necessary.
if (event.type() == eventNames().pointerupEvent)
capturingData.pendingTargetOverride = nullptr;
-
+
// When the pointer capture target override is no longer connected, the pending pointer capture target override and pointer
// capture target override nodes SHOULD be cleared and also a PointerEvent named lostpointercapture corresponding to the captured
// pointer SHOULD be fired at the document.
Modified: trunk/Source/WebCore/page/PointerCaptureController.h (241722 => 241723)
--- trunk/Source/WebCore/page/PointerCaptureController.h 2019-02-18 17:30:18 UTC (rev 241722)
+++ trunk/Source/WebCore/page/PointerCaptureController.h 2019-02-18 17:52:34 UTC (rev 241723)
@@ -47,10 +47,13 @@
void pointerLockWasApplied();
+#if ENABLE(TOUCH_EVENTS) && PLATFORM(IOS_FAMILY)
+ std::pair<bool, bool> dispatchEventForTouchAtIndex(EventTarget&, const PlatformTouchEvent&, unsigned, bool isPrimary, WindowProxy&);
+#endif
+
void touchEndedOrWasCancelledForIdentifier(PointerID);
bool hasCancelledPointerEventForIdentifier(PointerID);
- void pointerEventWillBeDispatched(const PointerEvent&, EventTarget*);
- void pointerEventWasDispatched(const PointerEvent&);
+ void dispatchEvent(PointerEvent&, EventTarget*);
WEBCORE_EXPORT void cancelPointer(PointerID, const IntPoint&);
private:
@@ -61,6 +64,8 @@
bool cancelled { false };
};
+ void pointerEventWillBeDispatched(const PointerEvent&, EventTarget*);
+ void pointerEventWasDispatched(const PointerEvent&);
void processPendingPointerCapture(const PointerEvent&);
Page& m_page;