Changeset 221092 in webkit


Ignore:
Timestamp:
Aug 23, 2017 12:22:28 PM (7 years ago)
Author:
dino@apple.com
Message:

Default passive touch event listeners on the root
https://bugs.webkit.org/show_bug.cgi?id=175346
<rdar://problem/33164597>

Reviewed by Sam Weinig.

Source/WebCore:

Make any touchstart or touchmove event listeners passive by default
if they are on the document, window, body or document element targets.
This follows the "intervention" first implemented by Chrome/Blink:

https://github.com/WICG/interventions/issues/35
https://docs.google.com/document/d/1II7oSIpd8pK91V5kEM3tDLKcIj398jOJn8Niqy6_loI/edit
https://github.com/whatwg/dom/issues/365

If the event listener explicitly defines "passive" to false in their
options dictionary, then they'll still get a non-passive listener.

NOTE: Any fallout from this bug should be collected in:
https://bugs.webkit.org/show_bug.cgi?id=175869
Please do not revert this change just because a site is broken. We'll
gather the issues and see if we can evangelise or detect via code.

Tests: fast/events/touch/ios/passive-by-default-on-document-and-window.html

fast/events/touch/ios/passive-by-default-overridden-on-document-and-window.html

  • dom/EventNames.h:

(WebCore::EventNames::isTouchScrollBlockingEventType const): Added this helper
to identify the types of touches we want to check for.

  • dom/EventTarget.cpp:

(WebCore::EventTarget::addEventListener): Check for the event being one of the touch-types
that we care about, and the target being one of the Node/Window types we care about. If
so, tell the event listener to be passive.

  • dom/EventTarget.h: Use an optional for the passive member.

(WebCore::EventTarget::AddEventListenerOptions::AddEventListenerOptions):

  • dom/EventTarget.idl: Change "passive" to not have a default value, so we

can detect if it was explicitly set to false.

LayoutTests:

  • fast/events/touch/ios/passive-by-default-on-document-and-window-expected.txt: Added.
  • fast/events/touch/ios/passive-by-default-on-document-and-window.html: Added.
  • fast/events/touch/ios/passive-by-default-overridden-on-document-and-window-expected.txt: Added.
  • fast/events/touch/ios/passive-by-default-overridden-on-document-and-window.html: Added.
  • fast/events/touch/ios/tap-with-active-listener-on-window.html: Explicitly set passive to false.
  • fast/events/touch/ios/touch-event-regions/document.html: Ditto.
Location:
trunk
Files:
4 added
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r221082 r221092  
     12017-08-22  Dean Jackson  <dino@apple.com>
     2
     3        Default passive touch event listeners on the root
     4        https://bugs.webkit.org/show_bug.cgi?id=175346
     5        <rdar://problem/33164597>
     6
     7        Reviewed by Sam Weinig.
     8
     9        * fast/events/touch/ios/passive-by-default-on-document-and-window-expected.txt: Added.
     10        * fast/events/touch/ios/passive-by-default-on-document-and-window.html: Added.
     11        * fast/events/touch/ios/passive-by-default-overridden-on-document-and-window-expected.txt: Added.
     12        * fast/events/touch/ios/passive-by-default-overridden-on-document-and-window.html: Added.
     13        * fast/events/touch/ios/tap-with-active-listener-on-window.html: Explicitly set passive to false.
     14        * fast/events/touch/ios/touch-event-regions/document.html: Ditto.
     15
    1162017-08-23  Matt Lewis  <jlewis3@apple.com>
    217
  • trunk/LayoutTests/fast/events/touch/ios/tap-with-active-listener-on-window.html

    r201958 r221092  
    2525                output += 'Received' + (event.cancelable ? ' cancelable' : '') + ' event ' + event.type + ' at ' + event.touches[0].clientX + ', ' + event.touches[0].clientY + '<br>';
    2626                event.preventDefault();
    27             });
     27            }, { passive: false });
    2828
    2929            window.addEventListener('touchend', function(event) {
  • trunk/LayoutTests/fast/events/touch/ios/touch-event-regions/document.html

    r214590 r221092  
    1414<body>
    1515    <script>
    16         document.addEventListener('touchstart', function() { });
     16        document.addEventListener('touchstart', function() { }, { passive: false });
    1717    </script>
    1818</body>
  • trunk/Source/WebCore/ChangeLog

    r221088 r221092  
     12017-08-22  Dean Jackson  <dino@apple.com>
     2
     3        Default passive touch event listeners on the root
     4        https://bugs.webkit.org/show_bug.cgi?id=175346
     5        <rdar://problem/33164597>
     6
     7        Reviewed by Sam Weinig.
     8
     9        Make any touchstart or touchmove event listeners passive by default
     10        if they are on the document, window, body or document element targets.
     11        This follows the "intervention" first implemented by Chrome/Blink:
     12
     13        https://github.com/WICG/interventions/issues/35
     14        https://docs.google.com/document/d/1II7oSIpd8pK91V5kEM3tDLKcIj398jOJn8Niqy6_loI/edit
     15        https://github.com/whatwg/dom/issues/365
     16
     17        If the event listener explicitly defines "passive" to false in their
     18        options dictionary, then they'll still get a non-passive listener.
     19
     20        NOTE: Any fallout from this bug should be collected in:
     21        https://bugs.webkit.org/show_bug.cgi?id=175869
     22        Please do not revert this change just because a site is broken. We'll
     23        gather the issues and see if we can evangelise or detect via code.
     24
     25        Tests: fast/events/touch/ios/passive-by-default-on-document-and-window.html
     26               fast/events/touch/ios/passive-by-default-overridden-on-document-and-window.html
     27
     28        * dom/EventNames.h:
     29        (WebCore::EventNames::isTouchScrollBlockingEventType const): Added this helper
     30        to identify the types of touches we want to check for.
     31        * dom/EventTarget.cpp:
     32        (WebCore::EventTarget::addEventListener): Check for the event being one of the touch-types
     33        that we care about, and the target being one of the Node/Window types we care about. If
     34        so, tell the event listener to be passive.
     35        * dom/EventTarget.h: Use an optional for the passive member.
     36        (WebCore::EventTarget::AddEventListenerOptions::AddEventListenerOptions):
     37        * dom/EventTarget.idl: Change "passive" to not have a default value, so we
     38        can detect if it was explicitly set to false.
     39
    1402017-08-23  Tim Horton  <timothy_horton@apple.com>
    241
  • trunk/Source/WebCore/dom/EventNames.h

    r220955 r221092  
    325325    bool isGestureEventType(const AtomicString& eventType) const;
    326326    bool isTouchEventType(const AtomicString& eventType) const;
     327    bool isTouchScrollBlockingEventType(const AtomicString& eventType) const;
    327328#if ENABLE(GAMEPAD)
    328329    bool isGamepadEventType(const AtomicString& eventType) const;
     
    349350{
    350351    return eventType == gesturestartEvent || eventType == gesturechangeEvent || eventType == gestureendEvent;
     352}
     353
     354inline bool EventNames::isTouchScrollBlockingEventType(const AtomicString& eventType) const
     355{
     356    return eventType == touchstartEvent
     357        || eventType == touchmoveEvent;
    351358}
    352359
  • trunk/Source/WebCore/dom/EventTarget.cpp

    r220036 r221092  
    3535#include "DOMWrapperWorld.h"
    3636#include "EventNames.h"
     37#include "HTMLBodyElement.h"
    3738#include "InspectorInstrumentation.h"
    3839#include "JSEventListener.h"
     
    6970bool EventTarget::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options)
    7071{
     72    auto passive = options.passive;
     73
     74    if (!passive.has_value() && eventNames().isTouchScrollBlockingEventType(eventType)) {
     75        if (toDOMWindow())
     76            passive = true;
     77        else if (auto* node = toNode()) {
     78            if (node->isDocumentNode() || node->document().documentElement() == node || node->document().body() == node)
     79                passive = true;
     80        }
     81    }
     82
    7183    bool listenerCreatedFromScript = listener->type() == EventListener::JSEventListenerType && !listener->wasCreatedFromMarkup();
    7284
    73     if (!ensureEventTargetData().eventListenerMap.add(eventType, WTFMove(listener), { options.capture, options.passive, options.once }))
     85    if (!ensureEventTargetData().eventListenerMap.add(eventType, WTFMove(listener), { options.capture, passive.value_or(false), options.once }))
    7486        return false;
    7587
  • trunk/Source/WebCore/dom/EventTarget.h

    r215486 r221092  
    8282
    8383    struct AddEventListenerOptions : ListenerOptions {
    84         AddEventListenerOptions(bool capture = false, bool passive = false, bool once = false)
     84        AddEventListenerOptions(bool capture = false, std::optional<bool> passive = std::nullopt, bool once = false)
    8585            : ListenerOptions(capture)
    8686            , passive(passive)
     
    8888        { }
    8989
    90         bool passive;
     90        std::optional<bool> passive;
    9191        bool once;
    9292    };
  • trunk/Source/WebCore/dom/EventTarget.idl

    r211238 r221092  
    3737
    3838dictionary AddEventListenerOptions : EventListenerOptions {
    39     boolean passive = false;
     39    boolean passive;
    4040    boolean once = false;
    4141};
Note: See TracChangeset for help on using the changeset viewer.