Changeset 246752 in webkit


Ignore:
Timestamp:
Jun 24, 2019 12:00:17 PM (5 years ago)
Author:
graouts@webkit.org
Message:

[Pointer Events WPT] Unskip imported/w3c/web-platform-tests/pointerevents/pointerevent_lostpointercapture_is_first.html
https://bugs.webkit.org/show_bug.cgi?id=197005

Reviewed by Dean Jackson.

LayoutTests/imported/w3c:

  • web-platform-tests/pointerevents/pointerevent_lostpointercapture_is_first-expected.txt: Added.
  • web-platform-tests/resources/testdriver-vendor.js:

(dispatchMouseActions): We need to disable dragMode for the eventSender or else the "pointermove" events in the test will
not be dispatched as there is no mouseUp() call in the test's event sequence.

Source/WebCore:

We were calling processPendingPointerCapture() at the wrong time, calling in after dispatching a PointerEvent rather than before.
We now do this correctly in the consolidated PointerCaptureController::dispatchEvent() method, which we call for dispatching all
PointerEvents, save for gotpointercapture and lostpointercapture since these should not yield the processing of the pending pointer
capture per the spec.

This uncovered a couple of new issues. First, since we would now call processPendingPointerCapture() and dispatch a lostpointercapture
event earlier, the alternative lostpointercapture dispatch when an element is removed (which is dispatched asynchronously on the
document) would be dispatched *after* dispatching the event in processPendingPointerCapture(). We now check in processPendingPointerCapture()
whether the event target is connected to fix this. This makes sure pointerevent_lostpointercapture_for_disconnected_node.html doesn't regress.

Finally, we must also call processPendingPointerCapture() when implicitly releasing pointer capture during handling of a "pointerup" event.
This ensures that pointerevent_releasepointercapture_invalid_pointerid.html doesn't regress.

As a result of all these changes, we now pass imported/w3c/web-platform-tests/pointerevents/pointerevent_lostpointercapture_is_first.html reliably.

  • page/PointerCaptureController.cpp:

(WebCore::PointerCaptureController::dispatchEventForTouchAtIndex):
(WebCore::PointerCaptureController::dispatchEvent): We now more closely adhere to the spec when determining what the pointer capture target is by
only checking for the target override. We can now do this safely since we call processPendingPointerCapture() before and not after event dispatch.
(WebCore::PointerCaptureController::pointerEventWasDispatched):
(WebCore::PointerCaptureController::processPendingPointerCapture): Cache the pending target override to make sure that dispatching a "gotpointercapture"
or "lostpointercapture" event during this function does not alter it until the next call is made when the next event is dispatched.

LayoutTests:

  • platform/mac-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt: Removed.
  • platform/mac-highsierra-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt: Removed.
  • platform/mac-highsierra/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt: Removed.

Since we've fixed the issue with event dispatch in WK1, we can remove these platform-specific expectations.

  • platform/mac/TestExpectations: We no longer skip this test which works reliably.
  • pointerevents/mouse/pointer-capture.html: We modify this test to correctly expect the "gotpointercapture" event only once the next

pointer event has been dispatched.

Location:
trunk
Files:
1 added
3 deleted
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r246736 r246752  
     12019-06-24  Antoine Quint  <graouts@apple.com>
     2
     3        [Pointer Events WPT] Unskip imported/w3c/web-platform-tests/pointerevents/pointerevent_lostpointercapture_is_first.html
     4        https://bugs.webkit.org/show_bug.cgi?id=197005
     5
     6        Reviewed by Dean Jackson.
     7
     8        * platform/mac-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt: Removed.
     9        * platform/mac-highsierra-wk1/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt: Removed.
     10        * platform/mac-highsierra/imported/w3c/web-platform-tests/pointerevents/pointerevent_mouse_capture_change_hover-expected.txt: Removed.
     11        Since we've fixed the issue with event dispatch in WK1, we can remove these platform-specific expectations.
     12        * platform/mac/TestExpectations: We no longer skip this test which works reliably.
     13        * pointerevents/mouse/pointer-capture.html: We modify this test to correctly expect the "gotpointercapture" event only once the next
     14        pointer event has been dispatched.
     15
    1162019-06-24  Greg Doolittle  <gr3g@apple.com>
    217
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r246729 r246752  
     12019-06-24  Antoine Quint  <graouts@apple.com>
     2
     3        [Pointer Events WPT] Unskip imported/w3c/web-platform-tests/pointerevents/pointerevent_lostpointercapture_is_first.html
     4        https://bugs.webkit.org/show_bug.cgi?id=197005
     5
     6        Reviewed by Dean Jackson.
     7
     8        * web-platform-tests/pointerevents/pointerevent_lostpointercapture_is_first-expected.txt: Added.
     9        * web-platform-tests/resources/testdriver-vendor.js:
     10        (dispatchMouseActions): We need to disable dragMode for the eventSender or else the "pointermove" events in the test will
     11        not be dispatched as there is no mouseUp() call in the test's event sequence.
     12
    1132019-06-24  Antoine Quint  <graouts@apple.com>
    214
  • trunk/LayoutTests/imported/w3c/web-platform-tests/resources/testdriver-vendor.js

    r246103 r246752  
    1515    return new Promise(resolve => {
    1616        setTimeout(() => {
     17            eventSender.dragMode = false;
     18
    1719            for (let action of actions) {
    1820                switch (action.type) {
  • trunk/LayoutTests/platform/mac/TestExpectations

    r246721 r246752  
    18861886imported/w3c/web-platform-tests/pointerevents/pointerlock/pointerevent_pointermove_on_chorded_mouse_button_when_locked-manual.html [ Skip ]
    18871887
    1888 webkit.org/b/197005 imported/w3c/web-platform-tests/pointerevents/pointerevent_lostpointercapture_is_first.html [ Skip ]
    18891888webkit.org/b/197007 imported/w3c/web-platform-tests/pointerevents/pointerlock/pointerevent_coordinates_when_locked.html [ Skip ]
    18901889
  • trunk/LayoutTests/pointerevents/mouse/pointer-capture.html

    r242137 r246752  
    4646    });
    4747    eventSender.mouseDown();
    48     eventTracker.assertMatchesEvents([
    49         { type: "gotpointercapture" }
    50     ]);
    51     eventTracker.clear();
    5248
    53     // Move the mouse oustide the target again, this time this yields a "pointermove" event since the target has pointer capture.
     49    // Move the mouse oustide the target again. This will yield a "gotpointercapture" event and a "pointermove" event since the target now has pointer capture.
    5450    eventSender.mouseMoveTo(250, 250);
    5551    eventTracker.assertMatchesEvents([
     52        { type: "gotpointercapture" },
    5653        { type: "pointermove", x: 250, y: 250 }
    5754    ]);
  • trunk/Source/WebCore/ChangeLog

    r246736 r246752  
     12019-06-24  Antoine Quint  <graouts@apple.com>
     2
     3        [Pointer Events WPT] Unskip imported/w3c/web-platform-tests/pointerevents/pointerevent_lostpointercapture_is_first.html
     4        https://bugs.webkit.org/show_bug.cgi?id=197005
     5
     6        Reviewed by Dean Jackson.
     7
     8        We were calling processPendingPointerCapture() at the wrong time, calling in after dispatching a PointerEvent rather than before.
     9        We now do this correctly in the consolidated PointerCaptureController::dispatchEvent() method, which we call for dispatching all
     10        PointerEvents, save for gotpointercapture and lostpointercapture since these should not yield the processing of the pending pointer
     11        capture per the spec.
     12
     13        This uncovered a couple of new issues. First, since we would now call processPendingPointerCapture() and dispatch a lostpointercapture
     14        event earlier, the alternative lostpointercapture dispatch when an element is removed (which is dispatched asynchronously on the
     15        document) would be dispatched *after* dispatching the event in processPendingPointerCapture(). We now check in processPendingPointerCapture()
     16        whether the event target is connected to fix this. This makes sure pointerevent_lostpointercapture_for_disconnected_node.html doesn't regress.
     17
     18        Finally, we must also call processPendingPointerCapture() when implicitly releasing pointer capture during handling of a "pointerup" event.
     19        This ensures that pointerevent_releasepointercapture_invalid_pointerid.html doesn't regress.
     20
     21        As a result of all these changes, we now pass imported/w3c/web-platform-tests/pointerevents/pointerevent_lostpointercapture_is_first.html reliably.
     22
     23        * page/PointerCaptureController.cpp:
     24        (WebCore::PointerCaptureController::dispatchEventForTouchAtIndex):
     25        (WebCore::PointerCaptureController::dispatchEvent): We now more closely adhere to the spec when determining what the pointer capture target is by
     26        only checking for the target override. We can now do this safely since we call processPendingPointerCapture() before and not after event dispatch.
     27        (WebCore::PointerCaptureController::pointerEventWasDispatched):
     28        (WebCore::PointerCaptureController::processPendingPointerCapture): Cache the pending target override to make sure that dispatching a "gotpointercapture"
     29        or "lostpointercapture" event during this function does not alter it until the next call is made when the next event is dispatched.
     30
    1312019-06-24  Greg Doolittle  <gr3g@apple.com>
    232
  • trunk/Source/WebCore/page/PointerCaptureController.cpp

    r246729 r246752  
    175175void PointerCaptureController::dispatchEventForTouchAtIndex(EventTarget& target, const PlatformTouchEvent& platformTouchEvent, unsigned index, bool isPrimary, WindowProxy& view)
    176176{
    177     auto dispatchEvent = [&](const String& type) {
    178         target.dispatchEvent(PointerEvent::create(type, platformTouchEvent, index, isPrimary, view));
     177    auto dispatchOverOrOutEvent = [&](const String& type) {
     178        dispatchEvent(PointerEvent::create(type, platformTouchEvent, index, isPrimary, view), &target);
    179179    };
    180180
     
    201201        if (type == eventNames().pointerenterEvent) {
    202202            for (auto& element : WTF::makeReversedRange(targetChain))
    203                 element->dispatchEvent(PointerEvent::create(type, platformTouchEvent, index, isPrimary, view));
     203                dispatchEvent(PointerEvent::create(type, platformTouchEvent, index, isPrimary, view), element.ptr());
    204204        } else {
    205205            for (auto& element : targetChain)
    206                 element->dispatchEvent(PointerEvent::create(type, platformTouchEvent, index, isPrimary, view));
     206                dispatchEvent(PointerEvent::create(type, platformTouchEvent, index, isPrimary, view), element.ptr());
    207207        }
    208208    };
     
    214214        // 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
    215215        // pointerenter prior to dispatching the pointerdown event.
    216         dispatchEvent(eventNames().pointeroverEvent);
     216        dispatchOverOrOutEvent(eventNames().pointeroverEvent);
    217217        dispatchEnterOrLeaveEvent(eventNames().pointerenterEvent);
    218218    }
    219219
    220     pointerEventWillBeDispatched(pointerEvent, &target);
    221     target.dispatchEvent(pointerEvent);
    222     pointerEventWasDispatched(pointerEvent);
     220    dispatchEvent(pointerEvent, &target);
    223221
    224222    if (pointerEvent->type() == eventNames().pointerupEvent) {
     
    226224        // For input devices that do not support hover, a user agent MUST also fire a pointer event named pointerout followed by a
    227225        // pointer event named pointerleave after dispatching the pointerup event.
    228         dispatchEvent(eventNames().pointeroutEvent);
     226        dispatchOverOrOutEvent(eventNames().pointeroutEvent);
    229227        dispatchEnterOrLeaveEvent(eventNames().pointerleaveEvent);
    230228    }
     
    269267void PointerCaptureController::dispatchEvent(PointerEvent& event, EventTarget* target)
    270268{
     269    if (!target || event.target())
     270        return;
     271
     272    // https://w3c.github.io/pointerevents/#firing-events-using-the-pointerevent-interface
     273    // If the event is not gotpointercapture or lostpointercapture, run Process Pending Pointer Capture steps for this PointerEvent.
     274    processPendingPointerCapture(event);
     275
     276    // If the pointer capture target override has been set for the pointer, set the target to pointer capture target override object.
    271277    auto iterator = m_activePointerIdsToCapturingData.find(event.pointerId());
    272278    if (iterator != m_activePointerIdsToCapturingData.end()) {
    273279        auto& capturingData = iterator->value;
    274         if (capturingData.pendingTargetOverride && capturingData.targetOverride)
     280        if (capturingData.targetOverride)
    275281            target = capturingData.targetOverride.get();
    276282    }
    277 
    278     if (!target || event.target())
    279         return;
    280283
    281284    pointerEventWillBeDispatched(event, target);
     
    336339        // Pointer Capture steps to fire lostpointercapture if necessary.
    337340        // https://w3c.github.io/pointerevents/#implicit-release-of-pointer-capture
    338         if (event.type() == eventNames().pointerupEvent)
     341        if (event.type() == eventNames().pointerupEvent) {
    339342            capturingData.pendingTargetOverride = nullptr;
     343            processPendingPointerCapture(event);
     344        }
    340345
    341346        // If a mouse pointer has moved while it isn't pressed, make sure we reset the preventsCompatibilityMouseEvents flag since
     
    349354            capturingData.preventsCompatibilityMouseEvents = event.defaultPrevented();
    350355    }
    351 
    352     processPendingPointerCapture(event);
    353356}
    354357
     
    410413    auto& capturingData = iterator->value;
    411414
     415    // Cache the pending target override since it could be modified during the dispatch of events in this function.
     416    auto pendingTargetOverride = capturingData.pendingTargetOverride;
     417
    412418    // 1. If the pointer capture target override for this pointer is set and is not equal to the pending pointer capture target override,
    413419    // then fire a pointer event named lostpointercapture at the pointer capture target override node.
    414     if (capturingData.targetOverride && capturingData.targetOverride != capturingData.pendingTargetOverride)
     420    if (capturingData.targetOverride && capturingData.targetOverride->isConnected() && capturingData.targetOverride != pendingTargetOverride)
    415421        capturingData.targetOverride->dispatchEvent(PointerEvent::createForPointerCapture(eventNames().lostpointercaptureEvent, event));
    416422
    417423    // 2. If the pending pointer capture target override for this pointer is set and is not equal to the pointer capture target override,
    418424    // then fire a pointer event named gotpointercapture at the pending pointer capture target override.
    419     if (capturingData.pendingTargetOverride && capturingData.targetOverride != capturingData.pendingTargetOverride)
    420         capturingData.pendingTargetOverride->dispatchEvent(PointerEvent::createForPointerCapture(eventNames().gotpointercaptureEvent, event));
     425    if (capturingData.pendingTargetOverride && capturingData.targetOverride != pendingTargetOverride)
     426        pendingTargetOverride->dispatchEvent(PointerEvent::createForPointerCapture(eventNames().gotpointercaptureEvent, event));
    421427
    422428    // 3. Set the pointer capture target override to the pending pointer capture target override, if set. Otherwise, clear the pointer
    423429    // capture target override.
    424     capturingData.targetOverride = capturingData.pendingTargetOverride;
     430    capturingData.targetOverride = pendingTargetOverride;
    425431}
    426432
Note: See TracChangeset for help on using the changeset viewer.