Diff
Modified: trunk/LayoutTests/ChangeLog (221091 => 221092)
--- trunk/LayoutTests/ChangeLog 2017-08-23 19:10:00 UTC (rev 221091)
+++ trunk/LayoutTests/ChangeLog 2017-08-23 19:22:28 UTC (rev 221092)
@@ -1,3 +1,18 @@
+2017-08-22 Dean Jackson <[email protected]>
+
+ Default passive touch event listeners on the root
+ https://bugs.webkit.org/show_bug.cgi?id=175346
+ <rdar://problem/33164597>
+
+ Reviewed by Sam Weinig.
+
+ * 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.
+
2017-08-23 Matt Lewis <[email protected]>
Marked imported/w3c/web-platform-tests/html/webappapis/timers/type-long-settimeout.html as flaky.
Added: trunk/LayoutTests/fast/events/touch/ios/passive-by-default-on-document-and-window-expected.txt (0 => 221092)
--- trunk/LayoutTests/fast/events/touch/ios/passive-by-default-on-document-and-window-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/passive-by-default-on-document-and-window-expected.txt 2017-08-23 19:22:28 UTC (rev 221092)
@@ -0,0 +1,13 @@
+touchstart on body - cancelable: false defaultPrevented: false
+touchstart on documentElement - cancelable: false defaultPrevented: false
+touchstart on document - cancelable: false defaultPrevented: false
+touchstart on window - cancelable: false defaultPrevented: false
+touchmove on body - cancelable: false defaultPrevented: false
+touchmove on documentElement - cancelable: false defaultPrevented: false
+touchmove on document - cancelable: false defaultPrevented: false
+touchmove on window - cancelable: false defaultPrevented: false
+touchend on body - cancelable: false defaultPrevented: false
+touchend on documentElement - cancelable: false defaultPrevented: false
+touchend on document - cancelable: false defaultPrevented: false
+touchend on window - cancelable: false defaultPrevented: false
+Done
Property changes on: trunk/LayoutTests/fast/events/touch/ios/passive-by-default-on-document-and-window-expected.txt
___________________________________________________________________
Added: svn:eol-style
+native
\ No newline at end of property
Added: svn:keywords
+Date Revision
\ No newline at end of property
Added: svn:mime-type
+text/plain
\ No newline at end of property
Added: trunk/LayoutTests/fast/events/touch/ios/passive-by-default-on-document-and-window.html (0 => 221092)
--- trunk/LayoutTests/fast/events/touch/ios/passive-by-default-on-document-and-window.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/passive-by-default-on-document-and-window.html 2017-08-23 19:22:28 UTC (rev 221092)
@@ -0,0 +1,97 @@
+<script>
+if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+}
+
+function getUIScript()
+{
+ return `
+ (function() {
+ uiController.dragFromPointToPoint(50, 250, 50, 30, 0.1, function() {
+ uiController.uiScriptComplete("Done");
+ });
+ })();`
+}
+
+function runTest()
+{
+ let output = "";
+ window.addEventListener("touchstart", function(event) {
+ event.preventDefault();
+ output += `touchstart on window - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, false);
+
+ window.addEventListener("touchmove", function(event) {
+ event.preventDefault();
+ output += `touchmove on window - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, false);
+
+ window.addEventListener("touchend", function(event) {
+ event.preventDefault();
+ output += `touchend on window - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, false);
+
+ document.addEventListener("touchstart", function(event) {
+ event.preventDefault();
+ output += `touchstart on document - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, false);
+
+ document.addEventListener("touchmove", function(event) {
+ event.preventDefault();
+ output += `touchmove on document - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, false);
+
+ document.addEventListener("touchend", function(event) {
+ event.preventDefault();
+ output += `touchend on document - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, false);
+
+ document.documentElement.addEventListener("touchstart", function(event) {
+ event.preventDefault();
+ output += `touchstart on documentElement - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, false);
+
+ document.documentElement.addEventListener("touchmove", function(event) {
+ event.preventDefault();
+ output += `touchmove on documentElement - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, false);
+
+ document.documentElement.addEventListener("touchend", function(event) {
+ event.preventDefault();
+ output += `touchend on documentElement - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, false);
+
+ let body = document.querySelector("body");
+
+ body.addEventListener("touchstart", function(event) {
+ event.preventDefault();
+ output += `touchstart on body - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, false);
+
+ body.addEventListener("touchmove", function(event) {
+ event.preventDefault();
+ output += `touchmove on body - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, false);
+
+ body.addEventListener("touchend", function(event) {
+ event.preventDefault();
+ output += `touchend on body - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, false);
+
+ if (testRunner.runUIScript) {
+ testRunner.runUIScript(getUIScript(), function(result) {
+ output += result;
+ document.getElementById("output").innerHTML = output;
+ testRunner.notifyDone();
+ });
+ }
+}
+
+window.addEventListener('load', runTest, false);
+</script>
+<body style="height: 500vh">
+<div id=output>
+This test requires UIScriptController to run.
+</div>
+</body>
Property changes on: trunk/LayoutTests/fast/events/touch/ios/passive-by-default-on-document-and-window.html
___________________________________________________________________
Added: svn:eol-style
+native
\ No newline at end of property
Added: svn:keywords
+Date Revision
\ No newline at end of property
Added: svn:mime-type
+text/html
\ No newline at end of property
Added: trunk/LayoutTests/fast/events/touch/ios/passive-by-default-overridden-on-document-and-window-expected.txt (0 => 221092)
--- trunk/LayoutTests/fast/events/touch/ios/passive-by-default-overridden-on-document-and-window-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/passive-by-default-overridden-on-document-and-window-expected.txt 2017-08-23 19:22:28 UTC (rev 221092)
@@ -0,0 +1,13 @@
+touchstart on body - cancelable: true defaultPrevented: true
+touchstart on documentElement - cancelable: true defaultPrevented: true
+touchstart on document - cancelable: true defaultPrevented: true
+touchstart on window - cancelable: true defaultPrevented: true
+touchmove on body - cancelable: true defaultPrevented: true
+touchmove on documentElement - cancelable: true defaultPrevented: true
+touchmove on document - cancelable: true defaultPrevented: true
+touchmove on window - cancelable: true defaultPrevented: true
+touchend on body - cancelable: true defaultPrevented: true
+touchend on documentElement - cancelable: true defaultPrevented: true
+touchend on document - cancelable: true defaultPrevented: true
+touchend on window - cancelable: true defaultPrevented: true
+Done
Property changes on: trunk/LayoutTests/fast/events/touch/ios/passive-by-default-overridden-on-document-and-window-expected.txt
___________________________________________________________________
Added: svn:eol-style
+native
\ No newline at end of property
Added: svn:keywords
+Date Revision
\ No newline at end of property
Added: svn:mime-type
+text/plain
\ No newline at end of property
Added: trunk/LayoutTests/fast/events/touch/ios/passive-by-default-overridden-on-document-and-window.html (0 => 221092)
--- trunk/LayoutTests/fast/events/touch/ios/passive-by-default-overridden-on-document-and-window.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/passive-by-default-overridden-on-document-and-window.html 2017-08-23 19:22:28 UTC (rev 221092)
@@ -0,0 +1,97 @@
+<script>
+if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+}
+
+function getUIScript()
+{
+ return `
+ (function() {
+ uiController.dragFromPointToPoint(50, 250, 50, 30, 0.1, function() {
+ uiController.uiScriptComplete("Done");
+ });
+ })();`
+}
+
+function runTest()
+{
+ let output = "";
+ window.addEventListener("touchstart", function(event) {
+ event.preventDefault();
+ output += `touchstart on window - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, { "passive": false });
+
+ window.addEventListener("touchmove", function(event) {
+ event.preventDefault();
+ output += `touchmove on window - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, { "passive": false });
+
+ window.addEventListener("touchend", function(event) {
+ event.preventDefault();
+ output += `touchend on window - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, { "passive": false });
+
+ document.addEventListener("touchstart", function(event) {
+ event.preventDefault();
+ output += `touchstart on document - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, { "passive": false });
+
+ document.addEventListener("touchmove", function(event) {
+ event.preventDefault();
+ output += `touchmove on document - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, { "passive": false });
+
+ document.addEventListener("touchend", function(event) {
+ event.preventDefault();
+ output += `touchend on document - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, { "passive": false });
+
+ document.documentElement.addEventListener("touchstart", function(event) {
+ event.preventDefault();
+ output += `touchstart on documentElement - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, { "passive": false });
+
+ document.documentElement.addEventListener("touchmove", function(event) {
+ event.preventDefault();
+ output += `touchmove on documentElement - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, { "passive": false });
+
+ document.documentElement.addEventListener("touchend", function(event) {
+ event.preventDefault();
+ output += `touchend on documentElement - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, { "passive": false });
+
+ let body = document.querySelector("body");
+
+ body.addEventListener("touchstart", function(event) {
+ event.preventDefault();
+ output += `touchstart on body - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, { "passive": false });
+
+ body.addEventListener("touchmove", function(event) {
+ event.preventDefault();
+ output += `touchmove on body - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, { "passive": false });
+
+ body.addEventListener("touchend", function(event) {
+ event.preventDefault();
+ output += `touchend on body - cancelable: ${event.cancelable} defaultPrevented: ${event.defaultPrevented} <br>`;
+ }, { "passive": false });
+
+ if (testRunner.runUIScript) {
+ testRunner.runUIScript(getUIScript(), function(result) {
+ output += result;
+ document.getElementById("output").innerHTML = output;
+ testRunner.notifyDone();
+ });
+ }
+}
+
+window.addEventListener('load', runTest, false);
+</script>
+<body style="height: 500vh">
+<div id=output>
+This test requires UIScriptController to run.
+</div>
+</body>
Property changes on: trunk/LayoutTests/fast/events/touch/ios/passive-by-default-overridden-on-document-and-window.html
___________________________________________________________________
Added: svn:eol-style
+native
\ No newline at end of property
Added: svn:keywords
+Date Revision
\ No newline at end of property
Added: svn:mime-type
+text/html
\ No newline at end of property
Modified: trunk/LayoutTests/fast/events/touch/ios/tap-with-active-listener-on-window.html (221091 => 221092)
--- trunk/LayoutTests/fast/events/touch/ios/tap-with-active-listener-on-window.html 2017-08-23 19:10:00 UTC (rev 221091)
+++ trunk/LayoutTests/fast/events/touch/ios/tap-with-active-listener-on-window.html 2017-08-23 19:22:28 UTC (rev 221092)
@@ -24,7 +24,7 @@
window.addEventListener('touchstart', function(event) {
output += 'Received' + (event.cancelable ? ' cancelable' : '') + ' event ' + event.type + ' at ' + event.touches[0].clientX + ', ' + event.touches[0].clientY + '<br>';
event.preventDefault();
- });
+ }, { passive: false });
window.addEventListener('touchend', function(event) {
output += 'Received' + (event.cancelable ? ' cancelable' : '') + ' event ' + event.type + '<br>';
Modified: trunk/LayoutTests/fast/events/touch/ios/touch-event-regions/document.html (221091 => 221092)
--- trunk/LayoutTests/fast/events/touch/ios/touch-event-regions/document.html 2017-08-23 19:10:00 UTC (rev 221091)
+++ trunk/LayoutTests/fast/events/touch/ios/touch-event-regions/document.html 2017-08-23 19:22:28 UTC (rev 221092)
@@ -13,7 +13,7 @@
</head>
<body>
<script>
- document.addEventListener('touchstart', function() { });
+ document.addEventListener('touchstart', function() { }, { passive: false });
</script>
</body>
</html>
Modified: trunk/Source/WebCore/ChangeLog (221091 => 221092)
--- trunk/Source/WebCore/ChangeLog 2017-08-23 19:10:00 UTC (rev 221091)
+++ trunk/Source/WebCore/ChangeLog 2017-08-23 19:22:28 UTC (rev 221092)
@@ -1,3 +1,42 @@
+2017-08-22 Dean Jackson <[email protected]>
+
+ Default passive touch event listeners on the root
+ https://bugs.webkit.org/show_bug.cgi?id=175346
+ <rdar://problem/33164597>
+
+ Reviewed by Sam Weinig.
+
+ 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.
+
2017-08-23 Tim Horton <[email protected]>
Try to fix the WinCairo build after r221068
Modified: trunk/Source/WebCore/dom/EventNames.h (221091 => 221092)
--- trunk/Source/WebCore/dom/EventNames.h 2017-08-23 19:10:00 UTC (rev 221091)
+++ trunk/Source/WebCore/dom/EventNames.h 2017-08-23 19:22:28 UTC (rev 221092)
@@ -324,6 +324,7 @@
bool isWheelEventType(const AtomicString& eventType) const;
bool isGestureEventType(const AtomicString& eventType) const;
bool isTouchEventType(const AtomicString& eventType) const;
+ bool isTouchScrollBlockingEventType(const AtomicString& eventType) const;
#if ENABLE(GAMEPAD)
bool isGamepadEventType(const AtomicString& eventType) const;
#endif
@@ -350,6 +351,12 @@
return eventType == gesturestartEvent || eventType == gesturechangeEvent || eventType == gestureendEvent;
}
+inline bool EventNames::isTouchScrollBlockingEventType(const AtomicString& eventType) const
+{
+ return eventType == touchstartEvent
+ || eventType == touchmoveEvent;
+}
+
inline bool EventNames::isTouchEventType(const AtomicString& eventType) const
{
return eventType == touchstartEvent
Modified: trunk/Source/WebCore/dom/EventTarget.cpp (221091 => 221092)
--- trunk/Source/WebCore/dom/EventTarget.cpp 2017-08-23 19:10:00 UTC (rev 221091)
+++ trunk/Source/WebCore/dom/EventTarget.cpp 2017-08-23 19:22:28 UTC (rev 221092)
@@ -34,6 +34,7 @@
#include "DOMWrapperWorld.h"
#include "EventNames.h"
+#include "HTMLBodyElement.h"
#include "InspectorInstrumentation.h"
#include "JSEventListener.h"
#include "NoEventDispatchAssertion.h"
@@ -68,9 +69,20 @@
bool EventTarget::addEventListener(const AtomicString& eventType, Ref<EventListener>&& listener, const AddEventListenerOptions& options)
{
+ auto passive = options.passive;
+
+ if (!passive.has_value() && eventNames().isTouchScrollBlockingEventType(eventType)) {
+ if (toDOMWindow())
+ passive = true;
+ else if (auto* node = toNode()) {
+ if (node->isDocumentNode() || node->document().documentElement() == node || node->document().body() == node)
+ passive = true;
+ }
+ }
+
bool listenerCreatedFromScript = listener->type() == EventListener::JSEventListenerType && !listener->wasCreatedFromMarkup();
- if (!ensureEventTargetData().eventListenerMap.add(eventType, WTFMove(listener), { options.capture, options.passive, options.once }))
+ if (!ensureEventTargetData().eventListenerMap.add(eventType, WTFMove(listener), { options.capture, passive.value_or(false), options.once }))
return false;
if (listenerCreatedFromScript)
Modified: trunk/Source/WebCore/dom/EventTarget.h (221091 => 221092)
--- trunk/Source/WebCore/dom/EventTarget.h 2017-08-23 19:10:00 UTC (rev 221091)
+++ trunk/Source/WebCore/dom/EventTarget.h 2017-08-23 19:22:28 UTC (rev 221092)
@@ -81,13 +81,13 @@
};
struct AddEventListenerOptions : ListenerOptions {
- AddEventListenerOptions(bool capture = false, bool passive = false, bool _once_ = false)
+ AddEventListenerOptions(bool capture = false, std::optional<bool> passive = std::nullopt, bool _once_ = false)
: ListenerOptions(capture)
, passive(passive)
, once(once)
{ }
- bool passive;
+ std::optional<bool> passive;
bool once;
};
Modified: trunk/Source/WebCore/dom/EventTarget.idl (221091 => 221092)
--- trunk/Source/WebCore/dom/EventTarget.idl 2017-08-23 19:10:00 UTC (rev 221091)
+++ trunk/Source/WebCore/dom/EventTarget.idl 2017-08-23 19:22:28 UTC (rev 221092)
@@ -36,6 +36,6 @@
};
dictionary AddEventListenerOptions : EventListenerOptions {
- boolean passive = false;
+ boolean passive;
boolean _once_ = false;
};