Diff
Modified: trunk/LayoutTests/ChangeLog (202407 => 202408)
--- trunk/LayoutTests/ChangeLog 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/LayoutTests/ChangeLog 2016-06-24 02:38:00 UTC (rev 202408)
@@ -1,3 +1,24 @@
+2016-06-23 Benjamin Poulain <[email protected]>
+
+ Specialize synchronous event tracking per event type
+ https://bugs.webkit.org/show_bug.cgi?id=158826
+
+ Reviewed by Simon Fraser.
+
+ * fast/events/touch/ios/tap-with-active-listener-inside-document-with-passive-listener-expected.txt: Added.
+ * fast/events/touch/ios/tap-with-active-listener-inside-document-with-passive-listener.html: Added.
+ * fast/events/touch/ios/tap-with-active-listener-inside-window-with-passive-listener-expected.txt: Added.
+ * fast/events/touch/ios/tap-with-active-listener-inside-window-with-passive-listener.html: Added.
+ * fast/events/touch/ios/tap-with-active-touch-end-listener-expected.txt: Added.
+ * fast/events/touch/ios/tap-with-active-touch-end-listener.html: Added.
+ * fast/events/touch/ios/tap-with-passive-listener-inside-active-listener.html: Added.
+ * fast/events/touch/ios/tap-with-passive-touch-end-listener-expected.txt: Added.
+ * fast/events/touch/ios/tap-with-passive-touch-end-listener.html: Added.
+ * fast/events/touch/ios/tap-with-passive-touch-start-active-touch-end-listeners-on-elements-expected.txt: Added.
+ * fast/events/touch/ios/tap-with-passive-touch-start-active-touch-end-listeners-on-elements.html: Added.
+ * fast/events/touch/ios/tap-with-passive-touch-start-active-touch-move-listeners-on-elements-expected.txt: Added.
+ * fast/events/touch/ios/tap-with-passive-touch-start-active-touch-move-listeners-on-elements.html: Added.
+
2016-06-23 Alexey Proskuryakov <[email protected]>
Update TestExpectations for a couple video track tests.
Added: trunk/LayoutTests/fast/events/touch/ios/tap-with-active-listener-inside-document-with-passive-listener-expected.txt (0 => 202408)
--- trunk/LayoutTests/fast/events/touch/ios/tap-with-active-listener-inside-document-with-passive-listener-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/tap-with-active-listener-inside-document-with-passive-listener-expected.txt 2016-06-24 02:38:00 UTC (rev 202408)
@@ -0,0 +1,35 @@
+Cancelled drag on Target1 (green)
+
+Listener target1 received event touchstart targetting eventTarget1 at 50, 50
+Listener document received event touchstart targetting eventTarget1 at 50, 50
+Listener target1 received cancelable event touchmove targetting eventTarget1 at 100, 100
+Listener document received cancelable event touchmove targetting eventTarget1 at 100, 100
+Listener target1 received cancelable event touchend targetting eventTarget1
+Listener document received cancelable event touchend targetting eventTarget1
+Done
+Cancelled drag on Target2 (red)
+
+Listener target1 received event touchstart targetting eventTarget2 at 150, 50
+Listener document received event touchstart targetting eventTarget2 at 150, 50
+Listener target1 received cancelable event touchmove targetting eventTarget2 at 200, 100
+Listener document received cancelable event touchmove targetting eventTarget2 at 200, 100
+Listener target1 received cancelable event touchend targetting eventTarget2
+Listener document received cancelable event touchend targetting eventTarget2
+Done
+Cancelled drag on Target3 (blue)
+
+Listener target3 received event touchstart targetting eventTarget3 at 250, 50
+Listener target1 received event touchstart targetting eventTarget3 at 250, 50
+Listener document received event touchstart targetting eventTarget3 at 250, 50
+Listener target3 received cancelable event touchmove targetting eventTarget3 at 300, 100
+Listener target1 received cancelable event touchmove targetting eventTarget3 at 300, 100
+Listener document received cancelable event touchmove targetting eventTarget3 at 300, 100
+Listener target3 received cancelable event touchend targetting eventTarget3
+Listener target1 received cancelable event touchend targetting eventTarget3
+Listener document received cancelable event touchend targetting eventTarget3
+Done
+Useless Click in the document, should be passive
+
+Listener document received event touchstart targetting at 300, 300
+Listener document received event touchend targetting
+
Added: trunk/LayoutTests/fast/events/touch/ios/tap-with-active-listener-inside-document-with-passive-listener.html (0 => 202408)
--- trunk/LayoutTests/fast/events/touch/ios/tap-with-active-listener-inside-document-with-passive-listener.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/tap-with-active-listener-inside-document-with-passive-listener.html 2016-06-24 02:38:00 UTC (rev 202408)
@@ -0,0 +1,139 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+ <script>
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
+
+ function getClickUIScript(x, y)
+ {
+ return `
+ (function() {
+ uiController.singleTapAtPoint(${x}, ${y}, function() {
+ uiController.uiScriptComplete("Done");
+ });
+ })();`
+ }
+
+ function getDragUIScript(startX, startY, endX, endY)
+ {
+ return `
+ (function() {
+ uiController.dragFromPointToPoint(${startX}, ${startY}, ${endX}, ${endY}, 0.15, function() {
+ uiController.uiScriptComplete("Done");
+ });
+ })();`
+ }
+
+ function runTest()
+ {
+ if (!testRunner.runUIScript)
+ return;
+
+ function fail(event) {
+ output += 'FAILED!: No mouse event should be receive, we got a ' + event.type;
+ }
+ window.addEventListener('mouseover', fail);
+ window.addEventListener('mouseout', fail);
+ window.addEventListener('mouseenter', fail);
+ window.addEventListener('mouseleave', fail);
+ window.addEventListener('mousedown', fail);
+ window.addEventListener('mousemove', fail);
+ window.addEventListener('mouseup', fail);
+ window.addEventListener('click', fail);
+ window.addEventListener('scroll', fail);
+
+ let output = '';
+ function getLogEvent(listener, shouldPreventDefault = false) {
+ return function logEvent(event) {
+ output += 'Listener ' + listener + ' received' + (event.cancelable ? ' cancelable' : '') + ' event ' + event.type + ' targetting ' + event.target.id;
+ if (event.touches[0] && event.touches[0].clientX) {
+ output += ' at ' + event.touches[0].clientX + ', ' + event.touches[0].clientY;
+ }
+ output += '<br>';
+
+ if (shouldPreventDefault)
+ event.preventDefault();
+ }
+ }
+
+ document.addEventListener('touchstart', getLogEvent("document"), { 'passive': true });
+ document.addEventListener('touchmove', getLogEvent("document"), { 'passive': true });
+ document.addEventListener('touchend', getLogEvent("document"), { 'passive': true });
+ document.addEventListener('touchcancel', getLogEvent("document"), { 'passive': true });
+
+ let target1 = document.getElementById('eventTarget1');
+ target1.addEventListener('touchstart', getLogEvent("target1"), { 'passive': true });
+ target1.addEventListener('touchmove', getLogEvent("target1", true));
+ target1.addEventListener('touchend', getLogEvent("target1"), { 'passive': true });
+ target1.addEventListener('touchcancel', getLogEvent("target1"), { 'passive': true });
+ let target3 = document.getElementById('eventTarget3');
+ target3.addEventListener('touchstart', getLogEvent("target3"), { 'passive': true });
+ target3.addEventListener('touchmove', getLogEvent("target3", true));
+ target3.addEventListener('touchend', getLogEvent("target3"), { 'passive': true });
+ target3.addEventListener('touchcancel', getLogEvent("target3"), { 'passive': true });
+
+ output += "<h1>Cancelled drag on Target1 (green)</h1>";
+ testRunner.runUIScript(getDragUIScript(50, 50, 100, 100), function(result) {
+ output += result;
+ output += "<h1>Cancelled drag on Target2 (red)</h1>";
+ testRunner.runUIScript(getDragUIScript(150, 50, 200, 100), function(result) {
+ output += result;
+ output += "<h1>Cancelled drag on Target3 (blue)</h1>";
+ testRunner.runUIScript(getDragUIScript(250, 50, 300, 100), function(result) {
+ output += result;
+ output += "<h1>Useless Click in the document, should be passive</h1>";
+ testRunner.runUIScript(getClickUIScript(300, 300), function(result) {
+ document.getElementById('output').innerHTML = output;
+ testRunner.notifyDone();
+ });
+ });
+ });
+ });
+ }
+
+ window.addEventListener('load', runTest, false);
+ </script>
+ <style>
+ * { touch-action: manipulation; }
+ body {
+ margin: 0;
+ }
+ #eventTarget1, #eventTarget2, #eventTarget3 {
+ width: 100px;
+ height: 100px;
+ }
+ #eventTarget1 {
+ background-color: green;
+ }
+ #eventTarget2 {
+ background-color: red;
+ position: absolute;
+ left: 100px;
+ }
+ #eventTarget3 {
+ background-color: blue;
+ position: absolute;
+ left: 100px;
+ }
+ body {
+ height: 5000px;
+ }
+ </style>
+ <meta name="viewport" content="initial-scale=1">
+</head>
+<body>
+ <div id=eventTarget1>
+ <div id=eventTarget2>
+ <div id=eventTarget3>
+ </div>
+ </div>
+ </div>
+ <div id=output>
+ This test requires UIScriptController to run.
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/touch/ios/tap-with-active-listener-inside-window-with-passive-listener-expected.txt (0 => 202408)
--- trunk/LayoutTests/fast/events/touch/ios/tap-with-active-listener-inside-window-with-passive-listener-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/tap-with-active-listener-inside-window-with-passive-listener-expected.txt 2016-06-24 02:38:00 UTC (rev 202408)
@@ -0,0 +1,35 @@
+Cancelled drag on Target1 (green)
+
+Listener target1 received event touchstart targetting eventTarget1 at 50, 50
+Listener document received event touchstart targetting eventTarget1 at 50, 50
+Listener target1 received cancelable event touchmove targetting eventTarget1 at 100, 100
+Listener document received cancelable event touchmove targetting eventTarget1 at 100, 100
+Listener target1 received cancelable event touchend targetting eventTarget1
+Listener document received cancelable event touchend targetting eventTarget1
+Done
+Cancelled drag on Target2 (red)
+
+Listener target1 received event touchstart targetting eventTarget2 at 150, 50
+Listener document received event touchstart targetting eventTarget2 at 150, 50
+Listener target1 received cancelable event touchmove targetting eventTarget2 at 200, 100
+Listener document received cancelable event touchmove targetting eventTarget2 at 200, 100
+Listener target1 received cancelable event touchend targetting eventTarget2
+Listener document received cancelable event touchend targetting eventTarget2
+Done
+Cancelled drag on Target3 (blue)
+
+Listener target3 received event touchstart targetting eventTarget3 at 250, 50
+Listener target1 received event touchstart targetting eventTarget3 at 250, 50
+Listener document received event touchstart targetting eventTarget3 at 250, 50
+Listener target3 received cancelable event touchmove targetting eventTarget3 at 300, 100
+Listener target1 received cancelable event touchmove targetting eventTarget3 at 300, 100
+Listener document received cancelable event touchmove targetting eventTarget3 at 300, 100
+Listener target3 received cancelable event touchend targetting eventTarget3
+Listener target1 received cancelable event touchend targetting eventTarget3
+Listener document received cancelable event touchend targetting eventTarget3
+Done
+Useless Click in the document, should be passive
+
+Listener document received event touchstart targetting at 300, 300
+Listener document received event touchend targetting
+
Added: trunk/LayoutTests/fast/events/touch/ios/tap-with-active-listener-inside-window-with-passive-listener.html (0 => 202408)
--- trunk/LayoutTests/fast/events/touch/ios/tap-with-active-listener-inside-window-with-passive-listener.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/tap-with-active-listener-inside-window-with-passive-listener.html 2016-06-24 02:38:00 UTC (rev 202408)
@@ -0,0 +1,139 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+ <script>
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
+
+ function getClickUIScript(x, y)
+ {
+ return `
+ (function() {
+ uiController.singleTapAtPoint(${x}, ${y}, function() {
+ uiController.uiScriptComplete("Done");
+ });
+ })();`
+ }
+
+ function getDragUIScript(startX, startY, endX, endY)
+ {
+ return `
+ (function() {
+ uiController.dragFromPointToPoint(${startX}, ${startY}, ${endX}, ${endY}, 0.15, function() {
+ uiController.uiScriptComplete("Done");
+ });
+ })();`
+ }
+
+ function runTest()
+ {
+ if (!testRunner.runUIScript)
+ return;
+
+ function fail(event) {
+ output += 'FAILED!: No mouse event should be receive, we got a ' + event.type;
+ }
+ window.addEventListener('mouseover', fail);
+ window.addEventListener('mouseout', fail);
+ window.addEventListener('mouseenter', fail);
+ window.addEventListener('mouseleave', fail);
+ window.addEventListener('mousedown', fail);
+ window.addEventListener('mousemove', fail);
+ window.addEventListener('mouseup', fail);
+ window.addEventListener('click', fail);
+ window.addEventListener('scroll', fail);
+
+ let output = '';
+ function getLogEvent(listener, shouldPreventDefault = false) {
+ return function logEvent(event) {
+ output += 'Listener ' + listener + ' received' + (event.cancelable ? ' cancelable' : '') + ' event ' + event.type + ' targetting ' + event.target.id;
+ if (event.touches[0] && event.touches[0].clientX) {
+ output += ' at ' + event.touches[0].clientX + ', ' + event.touches[0].clientY;
+ }
+ output += '<br>';
+
+ if (shouldPreventDefault)
+ event.preventDefault();
+ }
+ }
+
+ window.addEventListener('touchstart', getLogEvent("document"), { 'passive': true });
+ window.addEventListener('touchmove', getLogEvent("document"), { 'passive': true });
+ window.addEventListener('touchend', getLogEvent("document"), { 'passive': true });
+ window.addEventListener('touchcancel', getLogEvent("document"), { 'passive': true });
+
+ let target1 = document.getElementById('eventTarget1');
+ target1.addEventListener('touchstart', getLogEvent("target1"), { 'passive': true });
+ target1.addEventListener('touchmove', getLogEvent("target1", true));
+ target1.addEventListener('touchend', getLogEvent("target1"), { 'passive': true });
+ target1.addEventListener('touchcancel', getLogEvent("target1"), { 'passive': true });
+ let target3 = document.getElementById('eventTarget3');
+ target3.addEventListener('touchstart', getLogEvent("target3"), { 'passive': true });
+ target3.addEventListener('touchmove', getLogEvent("target3", true));
+ target3.addEventListener('touchend', getLogEvent("target3"), { 'passive': true });
+ target3.addEventListener('touchcancel', getLogEvent("target3"), { 'passive': true });
+
+ output += "<h1>Cancelled drag on Target1 (green)</h1>";
+ testRunner.runUIScript(getDragUIScript(50, 50, 100, 100), function(result) {
+ output += result;
+ output += "<h1>Cancelled drag on Target2 (red)</h1>";
+ testRunner.runUIScript(getDragUIScript(150, 50, 200, 100), function(result) {
+ output += result;
+ output += "<h1>Cancelled drag on Target3 (blue)</h1>";
+ testRunner.runUIScript(getDragUIScript(250, 50, 300, 100), function(result) {
+ output += result;
+ output += "<h1>Useless Click in the document, should be passive</h1>";
+ testRunner.runUIScript(getClickUIScript(300, 300), function(result) {
+ document.getElementById('output').innerHTML = output;
+ testRunner.notifyDone();
+ });
+ });
+ });
+ });
+ }
+
+ window.addEventListener('load', runTest, false);
+ </script>
+ <style>
+ * { touch-action: manipulation; }
+ body {
+ margin: 0;
+ }
+ #eventTarget1, #eventTarget2, #eventTarget3 {
+ width: 100px;
+ height: 100px;
+ }
+ #eventTarget1 {
+ background-color: green;
+ }
+ #eventTarget2 {
+ background-color: red;
+ position: absolute;
+ left: 100px;
+ }
+ #eventTarget3 {
+ background-color: blue;
+ position: absolute;
+ left: 100px;
+ }
+ body {
+ height: 5000px;
+ }
+ </style>
+ <meta name="viewport" content="initial-scale=1">
+</head>
+<body>
+ <div id=eventTarget1>
+ <div id=eventTarget2>
+ <div id=eventTarget3>
+ </div>
+ </div>
+ </div>
+ <div id=output>
+ This test requires UIScriptController to run.
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/touch/ios/tap-with-active-touch-end-listener-expected.txt (0 => 202408)
--- trunk/LayoutTests/fast/events/touch/ios/tap-with-active-touch-end-listener-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/tap-with-active-touch-end-listener-expected.txt 2016-06-24 02:38:00 UTC (rev 202408)
@@ -0,0 +1,30 @@
+Tap on Target1 (green)
+
+(Frame scrolling node
+ (scrollable area size 800 600)
+ (contents size 800 600)
+ (synchronous event dispatch region for event touchend
+ at (0,0) size 300x100)
+)
+Listener target1 received cancelable event touchend targetting eventTarget1
+Done
+Tap on Target2 (red)
+
+(Frame scrolling node
+ (scrollable area size 800 600)
+ (contents size 800 600)
+ (synchronous event dispatch region for event touchend
+ at (0,0) size 300x100)
+)
+Listener target1 received cancelable event touchend targetting eventTarget2
+Done
+Tap on Target3 (blue)
+
+(Frame scrolling node
+ (scrollable area size 800 600)
+ (contents size 800 600)
+ (synchronous event dispatch region for event touchend
+ at (0,0) size 300x100)
+)
+Listener target1 received cancelable event touchend targetting eventTarget3
+
Added: trunk/LayoutTests/fast/events/touch/ios/tap-with-active-touch-end-listener.html (0 => 202408)
--- trunk/LayoutTests/fast/events/touch/ios/tap-with-active-touch-end-listener.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/tap-with-active-touch-end-listener.html 2016-06-24 02:38:00 UTC (rev 202408)
@@ -0,0 +1,106 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+ <script>
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
+
+ function getUIScript(x, y)
+ {
+ return `
+ (function() {
+ uiController.singleTapAtPoint(${x}, ${y}, function() {
+ uiController.uiScriptComplete("Done");
+ });
+ })();`
+ }
+
+ function runTest()
+ {
+ if (!testRunner.runUIScript)
+ return;
+
+ function fail(event) {
+ output += 'FAILED!: No mouse event should be receive, we got a ' + event.type;
+ }
+ window.addEventListener('mouseover', fail);
+ window.addEventListener('mouseout', fail);
+ window.addEventListener('mouseenter', fail);
+ window.addEventListener('mouseleave', fail);
+ window.addEventListener('mousedown', fail);
+ window.addEventListener('mousemove', fail);
+ window.addEventListener('mouseup', fail);
+ window.addEventListener('click', fail);
+
+ let output = '';
+ function getLogEvent(listener) {
+ return function logEvent(event) {
+ output += '<pre>' + window.internals.scrollingStateTreeAsText() + '</pre>';
+ output += 'Listener ' + listener + ' received' + (event.cancelable ? ' cancelable' : '') + ' event ' + event.type + ' targetting ' + event.target.id;
+ if (event.touches[0] && event.touches[0].clientX) {
+ output += ' at ' + event.touches[0].clientX + ', ' + event.touches[0].clientY;
+ }
+ output += '<br>';
+ }
+ }
+
+ let target1 = document.getElementById('eventTarget1');
+ target1.addEventListener('touchend', getLogEvent("target1"));
+
+ output += "<h1>Tap on Target1 (green)</h1>";
+ testRunner.runUIScript(getUIScript(50, 50), function(result) {
+ output += result;
+ output += "<h1>Tap on Target2 (red)</h1>";
+ testRunner.runUIScript(getUIScript(150, 50), function(result) {
+ output += result;
+ output += "<h1>Tap on Target3 (blue)</h1>";
+ testRunner.runUIScript(getUIScript(250, 50), function(result) {
+ document.getElementById('output').innerHTML = output;
+ testRunner.notifyDone();
+ });
+ });
+ });
+ }
+
+ window.addEventListener('load', runTest, false);
+ </script>
+ <style>
+ * { touch-action: manipulation; }
+ body {
+ margin: 0;
+ }
+ #eventTarget1, #eventTarget2, #eventTarget3 {
+ width: 100px;
+ height: 100px;
+ }
+ #eventTarget1 {
+ background-color: green;
+ }
+ #eventTarget2 {
+ background-color: red;
+ position: absolute;
+ left: 100px;
+ }
+ #eventTarget3 {
+ background-color: blue;
+ position: absolute;
+ left: 100px;
+ }
+ </style>
+ <meta name="viewport" content="initial-scale=1">
+</head>
+<body>
+ <div id=eventTarget1>
+ <div id=eventTarget2>
+ <div id=eventTarget3>
+ </div>
+ </div>
+ </div>
+ <div id=output>
+ This test requires UIScriptController to run.
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-listener-inside-active-listener.html (0 => 202408)
--- trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-listener-inside-active-listener.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-listener-inside-active-listener.html 2016-06-24 02:38:00 UTC (rev 202408)
@@ -0,0 +1,116 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+ <script>
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
+
+ function getUIScript(x, y)
+ {
+ return `
+ (function() {
+ uiController.singleTapAtPoint(${x}, ${y}, function() {
+ uiController.uiScriptComplete("Done");
+ });
+ })();`
+ }
+
+ function runTest()
+ {
+ if (!testRunner.runUIScript)
+ return;
+
+ function fail(event) {
+ output += 'FAILED!: No mouse event should be receive, we got a ' + event.type;
+ }
+ window.addEventListener('mouseover', fail);
+ window.addEventListener('mouseout', fail);
+ window.addEventListener('mouseenter', fail);
+ window.addEventListener('mouseleave', fail);
+ window.addEventListener('mousedown', fail);
+ window.addEventListener('mousemove', fail);
+ window.addEventListener('mouseup', fail);
+ window.addEventListener('click', fail);
+
+ let output = '';
+ function getLogEvent(listener) {
+ return function logEvent(event) {
+ output += 'Listener ' + listener + ' received' + (event.cancelable ? ' cancelable' : '') + ' event ' + event.type + ' targetting ' + event.target.id;
+ if (event.touches[0] && event.touches[0].clientX) {
+ output += ' at ' + event.touches[0].clientX + ', ' + event.touches[0].clientY;
+ }
+ output += '<br>';
+ output += 'defaultPrevented before preventDefault(): ' + event.defaultPrevented + '<br>';
+ event.preventDefault();
+ output += 'defaultPrevented after preventDefault(): ' + event.defaultPrevented + '<br>';
+ }
+ }
+
+ let target1 = document.getElementById('eventTarget1');
+ target1.addEventListener('touchstart', getLogEvent("target1"));
+ target1.addEventListener('touchmove', getLogEvent("target1"));
+ target1.addEventListener('touchend', getLogEvent("target1"));
+ target1.addEventListener('touchcancel', getLogEvent("target1"));
+ let target3 = document.getElementById('eventTarget3');
+ target3.addEventListener('touchstart', getLogEvent("target3"), { 'passive': true });
+ target3.addEventListener('touchmove', getLogEvent("target3"), { 'passive': true });
+ target3.addEventListener('touchend', getLogEvent("target3"), { 'passive': true });
+ target3.addEventListener('touchcancel', getLogEvent("target3"), { 'passive': true });
+
+ output += "<h1>Tap on Target1 (green)</h1>";
+ testRunner.runUIScript(getUIScript(50, 50), function(result) {
+ output += result;
+ output += "<h1>Tap on Target2 (red)</h1>";
+ testRunner.runUIScript(getUIScript(150, 50), function(result) {
+ output += result;
+ output += "<h1>Tap on Target3 (blue)</h1>";
+ testRunner.runUIScript(getUIScript(250, 50), function(result) {
+ document.getElementById('output').innerHTML = output;
+ testRunner.notifyDone();
+ });
+ });
+ });
+ }
+
+ window.addEventListener('load', runTest, false);
+ </script>
+ <style>
+ * { touch-action: manipulation; }
+ body {
+ margin: 0;
+ }
+ #eventTarget1, #eventTarget2, #eventTarget3 {
+ width: 100px;
+ height: 100px;
+ }
+ #eventTarget1 {
+ background-color: green;
+ }
+ #eventTarget2 {
+ background-color: red;
+ position: absolute;
+ left: 100px;
+ }
+ #eventTarget3 {
+ background-color: blue;
+ position: absolute;
+ left: 100px;
+ }
+ </style>
+ <meta name="viewport" content="initial-scale=1">
+</head>
+<body>
+ <div id=eventTarget1>
+ <div id=eventTarget2>
+ <div id=eventTarget3>
+ </div>
+ </div>
+ </div>
+ <div id=output>
+ This test requires UIScriptController to run.
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-end-listener-expected.txt (0 => 202408)
--- trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-end-listener-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-end-listener-expected.txt 2016-06-24 02:38:00 UTC (rev 202408)
@@ -0,0 +1,12 @@
+Tap on Target1 (green)
+
+Listener target1 received event touchend targetting eventTarget1
+Done
+Tap on Target2 (red)
+
+Listener target1 received event touchend targetting eventTarget2
+Done
+Tap on Target3 (blue)
+
+Listener target1 received event touchend targetting eventTarget3
+
Added: trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-end-listener.html (0 => 202408)
--- trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-end-listener.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-end-listener.html 2016-06-24 02:38:00 UTC (rev 202408)
@@ -0,0 +1,105 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+ <script>
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
+
+ function getUIScript(x, y)
+ {
+ return `
+ (function() {
+ uiController.singleTapAtPoint(${x}, ${y}, function() {
+ uiController.uiScriptComplete("Done");
+ });
+ })();`
+ }
+
+ function runTest()
+ {
+ if (!testRunner.runUIScript)
+ return;
+
+ function fail(event) {
+ output += 'FAILED!: No mouse event should be receive, we got a ' + event.type;
+ }
+ window.addEventListener('mouseover', fail);
+ window.addEventListener('mouseout', fail);
+ window.addEventListener('mouseenter', fail);
+ window.addEventListener('mouseleave', fail);
+ window.addEventListener('mousedown', fail);
+ window.addEventListener('mousemove', fail);
+ window.addEventListener('mouseup', fail);
+ window.addEventListener('click', fail);
+
+ let output = '';
+ function getLogEvent(listener) {
+ return function logEvent(event) {
+ output += 'Listener ' + listener + ' received' + (event.cancelable ? ' cancelable' : '') + ' event ' + event.type + ' targetting ' + event.target.id;
+ if (event.touches[0] && event.touches[0].clientX) {
+ output += ' at ' + event.touches[0].clientX + ', ' + event.touches[0].clientY;
+ }
+ output += '<br>';
+ }
+ }
+
+ let target1 = document.getElementById('eventTarget1');
+ target1.addEventListener('touchend', getLogEvent("target1"), { 'passive': true });
+
+ output += "<h1>Tap on Target1 (green)</h1>";
+ testRunner.runUIScript(getUIScript(50, 50), function(result) {
+ output += result;
+ output += "<h1>Tap on Target2 (red)</h1>";
+ testRunner.runUIScript(getUIScript(150, 50), function(result) {
+ output += result;
+ output += "<h1>Tap on Target3 (blue)</h1>";
+ testRunner.runUIScript(getUIScript(250, 50), function(result) {
+ document.getElementById('output').innerHTML = output;
+ testRunner.notifyDone();
+ });
+ });
+ });
+ }
+
+ window.addEventListener('load', runTest, false);
+ </script>
+ <style>
+ * { touch-action: manipulation; }
+ body {
+ margin: 0;
+ }
+ #eventTarget1, #eventTarget2, #eventTarget3 {
+ width: 100px;
+ height: 100px;
+ }
+ #eventTarget1 {
+ background-color: green;
+ }
+ #eventTarget2 {
+ background-color: red;
+ position: absolute;
+ left: 100px;
+ }
+ #eventTarget3 {
+ background-color: blue;
+ position: absolute;
+ left: 100px;
+ }
+ </style>
+ <meta name="viewport" content="initial-scale=1">
+</head>
+<body>
+ <div id=eventTarget1>
+ <div id=eventTarget2>
+ <div id=eventTarget3>
+ </div>
+ </div>
+ </div>
+ <div id=output>
+ This test requires UIScriptController to run.
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-start-active-touch-end-listeners-on-elements-expected.txt (0 => 202408)
--- trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-start-active-touch-end-listeners-on-elements-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-start-active-touch-end-listeners-on-elements-expected.txt 2016-06-24 02:38:00 UTC (rev 202408)
@@ -0,0 +1,17 @@
+Tap on Target1 (green)
+
+Listener target1 received event touchstart targetting eventTarget1 at 50, 50
+Listener target1 received cancelable event touchend targetting eventTarget1
+Done
+Tap on Target2 (red)
+
+Listener target1 received event touchstart targetting eventTarget2 at 150, 50
+Listener target1 received cancelable event touchend targetting eventTarget2
+Done
+Tap on Target3 (blue)
+
+Listener target3 received event touchstart targetting eventTarget3 at 250, 50
+Listener target1 received event touchstart targetting eventTarget3 at 250, 50
+Listener target3 received cancelable event touchend targetting eventTarget3
+Listener target1 received cancelable event touchend targetting eventTarget3
+
Added: trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-start-active-touch-end-listeners-on-elements.html (0 => 202408)
--- trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-start-active-touch-end-listeners-on-elements.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-start-active-touch-end-listeners-on-elements.html 2016-06-24 02:38:00 UTC (rev 202408)
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+ <script>
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
+
+ function getUIScript(x, y)
+ {
+ return `
+ (function() {
+ uiController.singleTapAtPoint(${x}, ${y}, function() {
+ uiController.uiScriptComplete("Done");
+ });
+ })();`
+ }
+
+ function runTest()
+ {
+ if (!testRunner.runUIScript)
+ return;
+
+ function fail(event) {
+ output += 'FAILED!: No mouse event should be receive, we got a ' + event.type;
+ }
+ window.addEventListener('mouseover', fail);
+ window.addEventListener('mouseout', fail);
+ window.addEventListener('mouseenter', fail);
+ window.addEventListener('mouseleave', fail);
+ window.addEventListener('mousedown', fail);
+ window.addEventListener('mousemove', fail);
+ window.addEventListener('mouseup', fail);
+ window.addEventListener('click', fail);
+
+ let output = '';
+ function getLogEvent(listener) {
+ return function logEvent(event) {
+ output += 'Listener ' + listener + ' received' + (event.cancelable ? ' cancelable' : '') + ' event ' + event.type + ' targetting ' + event.target.id;
+ if (event.touches[0] && event.touches[0].clientX) {
+ output += ' at ' + event.touches[0].clientX + ', ' + event.touches[0].clientY;
+ }
+ output += '<br>';
+ }
+ }
+
+ let target1 = document.getElementById('eventTarget1');
+ target1.addEventListener('touchstart', getLogEvent("target1"), { 'passive': true });
+ target1.addEventListener('touchmove', getLogEvent("target1"), { 'passive': true });
+ target1.addEventListener('touchend', getLogEvent("target1"));
+ target1.addEventListener('touchcancel', getLogEvent("target1"));
+ let target3 = document.getElementById('eventTarget3');
+ target3.addEventListener('touchstart', getLogEvent("target3"), { 'passive': true });
+ target3.addEventListener('touchmove', getLogEvent("target3"), { 'passive': true });
+ target3.addEventListener('touchend', getLogEvent("target3"));
+ target3.addEventListener('touchcancel', getLogEvent("target3"));
+
+ output += "<h1>Tap on Target1 (green)</h1>";
+ testRunner.runUIScript(getUIScript(50, 50), function(result) {
+ output += result;
+ output += "<h1>Tap on Target2 (red)</h1>";
+ testRunner.runUIScript(getUIScript(150, 50), function(result) {
+ output += result;
+ output += "<h1>Tap on Target3 (blue)</h1>";
+ testRunner.runUIScript(getUIScript(250, 50), function(result) {
+ document.getElementById('output').innerHTML = output;
+ testRunner.notifyDone();
+ });
+ });
+ });
+ }
+
+ window.addEventListener('load', runTest, false);
+ </script>
+ <style>
+ * { touch-action: manipulation; }
+ body {
+ margin: 0;
+ }
+ #eventTarget1, #eventTarget2, #eventTarget3 {
+ width: 100px;
+ height: 100px;
+ }
+ #eventTarget1 {
+ background-color: green;
+ }
+ #eventTarget2 {
+ background-color: red;
+ position: absolute;
+ left: 100px;
+ }
+ #eventTarget3 {
+ background-color: blue;
+ position: absolute;
+ left: 100px;
+ }
+ </style>
+ <meta name="viewport" content="initial-scale=1">
+</head>
+<body>
+ <div id=eventTarget1>
+ <div id=eventTarget2>
+ <div id=eventTarget3>
+ </div>
+ </div>
+ </div>
+ <div id=output>
+ This test requires UIScriptController to run.
+ </div>
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-start-active-touch-move-listeners-on-elements-expected.txt (0 => 202408)
--- trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-start-active-touch-move-listeners-on-elements-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-start-active-touch-move-listeners-on-elements-expected.txt 2016-06-24 02:38:00 UTC (rev 202408)
@@ -0,0 +1,21 @@
+Cancelled drag on Target1 (green)
+
+Listener target1 received event touchstart targetting eventTarget1 at 50, 50
+Listener target1 received cancelable event touchmove targetting eventTarget1 at 100, 100
+Listener target1 received cancelable event touchend targetting eventTarget1
+Done
+Cancelled drag on Target2 (red)
+
+Listener target1 received event touchstart targetting eventTarget2 at 150, 50
+Listener target1 received cancelable event touchmove targetting eventTarget2 at 200, 100
+Listener target1 received cancelable event touchend targetting eventTarget2
+Done
+Cancelled drag on Target3 (blue)
+
+Listener target3 received event touchstart targetting eventTarget3 at 250, 50
+Listener target1 received event touchstart targetting eventTarget3 at 250, 50
+Listener target3 received cancelable event touchmove targetting eventTarget3 at 300, 100
+Listener target1 received cancelable event touchmove targetting eventTarget3 at 300, 100
+Listener target3 received cancelable event touchend targetting eventTarget3
+Listener target1 received cancelable event touchend targetting eventTarget3
+
Added: trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-start-active-touch-move-listeners-on-elements.html (0 => 202408)
--- trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-start-active-touch-move-listeners-on-elements.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/ios/tap-with-passive-touch-start-active-touch-move-listeners-on-elements.html 2016-06-24 02:38:00 UTC (rev 202408)
@@ -0,0 +1,120 @@
+<!DOCTYPE html>
+
+<html>
+<head>
+ <script>
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ }
+
+ function getDragUIScript(startX, startY, endX, endY)
+ {
+ return `
+ (function() {
+ uiController.dragFromPointToPoint(${startX}, ${startY}, ${endX}, ${endY}, 0.15, function() {
+ uiController.uiScriptComplete("Done");
+ });
+ })();`
+ }
+
+ function runTest()
+ {
+ if (!testRunner.runUIScript)
+ return;
+
+ function fail(event) {
+ output += 'FAILED!: No mouse event should be receive, we got a ' + event.type;
+ }
+ window.addEventListener('mouseover', fail);
+ window.addEventListener('mouseout', fail);
+ window.addEventListener('mouseenter', fail);
+ window.addEventListener('mouseleave', fail);
+ window.addEventListener('mousedown', fail);
+ window.addEventListener('mousemove', fail);
+ window.addEventListener('mouseup', fail);
+ window.addEventListener('click', fail);
+ window.addEventListener('scroll', fail);
+
+ let output = '';
+ function getLogEvent(listener) {
+ return function logEvent(event) {
+ output += 'Listener ' + listener + ' received' + (event.cancelable ? ' cancelable' : '') + ' event ' + event.type + ' targetting ' + event.target.id;
+ if (event.touches[0] && event.touches[0].clientX) {
+ output += ' at ' + event.touches[0].clientX + ', ' + event.touches[0].clientY;
+ }
+ output += '<br>';
+
+ if (event.type === 'touchmove')
+ event.preventDefault();
+ }
+ }
+
+ let target1 = document.getElementById('eventTarget1');
+ target1.addEventListener('touchstart', getLogEvent("target1"), { 'passive': true });
+ target1.addEventListener('touchmove', getLogEvent("target1"));
+ target1.addEventListener('touchend', getLogEvent("target1"));
+ target1.addEventListener('touchcancel', getLogEvent("target1"));
+ let target3 = document.getElementById('eventTarget3');
+ target3.addEventListener('touchstart', getLogEvent("target3"), { 'passive': true });
+ target3.addEventListener('touchmove', getLogEvent("target3"));
+ target3.addEventListener('touchend', getLogEvent("target3"));
+ target3.addEventListener('touchcancel', getLogEvent("target3"));
+
+ output += "<h1>Cancelled drag on Target1 (green)</h1>";
+ testRunner.runUIScript(getDragUIScript(50, 50, 100, 100), function(result) {
+ output += result;
+ output += "<h1>Cancelled drag on Target2 (red)</h1>";
+ testRunner.runUIScript(getDragUIScript(150, 50, 200, 100), function(result) {
+ output += result;
+ output += "<h1>Cancelled drag on Target3 (blue)</h1>";
+ testRunner.runUIScript(getDragUIScript(250, 50, 300, 100), function(result) {
+ document.getElementById('output').innerHTML = output;
+ testRunner.notifyDone();
+ });
+ });
+ });
+ }
+
+ window.addEventListener('load', runTest, false);
+ </script>
+ <style>
+ * { touch-action: manipulation; }
+ body {
+ margin: 0;
+ }
+ #eventTarget1, #eventTarget2, #eventTarget3 {
+ width: 100px;
+ height: 100px;
+ }
+ #eventTarget1 {
+ background-color: green;
+ }
+ #eventTarget2 {
+ background-color: red;
+ position: absolute;
+ left: 100px;
+ }
+ #eventTarget3 {
+ background-color: blue;
+ position: absolute;
+ left: 100px;
+ }
+ body {
+ height: 5000px;
+ }
+ </style>
+ <meta name="viewport" content="initial-scale=1">
+</head>
+<body>
+ <div id=eventTarget1>
+ <div id=eventTarget2>
+ <div id=eventTarget3>
+ </div>
+ </div>
+ </div>
+ <div id=output>
+ This test requires UIScriptController to run.
+ </div>
+</body>
+</html>
Modified: trunk/LayoutTests/tiled-drawing/scrolling/fixed/fixed-in-overflow-expected.txt (202407 => 202408)
--- trunk/LayoutTests/tiled-drawing/scrolling/fixed/fixed-in-overflow-expected.txt 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/LayoutTests/tiled-drawing/scrolling/fixed/fixed-in-overflow-expected.txt 2016-06-24 02:38:00 UTC (rev 202408)
@@ -2,7 +2,7 @@
(scrollable area size 785 600)
(contents size 785 2213)
(requested scroll position 0 200)
- (synchronous event dispatch region
+ (synchronous event dispatch region for event wheel
at (0,13) size 204x204)
(children 1
(Fixed node
Modified: trunk/LayoutTests/tiled-drawing/scrolling/frames/coordinated-frame-expected.txt (202407 => 202408)
--- trunk/LayoutTests/tiled-drawing/scrolling/frames/coordinated-frame-expected.txt 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/LayoutTests/tiled-drawing/scrolling/frames/coordinated-frame-expected.txt 2016-06-24 02:38:00 UTC (rev 202408)
@@ -1,7 +1,7 @@
(Frame scrolling node
(scrollable area size 785 600)
(contents size 785 1016)
- (synchronous event dispatch region
+ (synchronous event dispatch region for event wheel
at (45,47) size 404x304)
(children 1
(Frame scrolling node
Modified: trunk/LayoutTests/tiled-drawing/scrolling/frames/coordinated-frame-gain-scrolling-ancestor-expected.txt (202407 => 202408)
--- trunk/LayoutTests/tiled-drawing/scrolling/frames/coordinated-frame-gain-scrolling-ancestor-expected.txt 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/LayoutTests/tiled-drawing/scrolling/frames/coordinated-frame-gain-scrolling-ancestor-expected.txt 2016-06-24 02:38:00 UTC (rev 202408)
@@ -1,7 +1,7 @@
(Frame scrolling node
(scrollable area size 785 600)
(contents size 785 1016)
- (synchronous event dispatch region
+ (synchronous event dispatch region for event wheel
at (45,47) size 404x304)
(children 1
(Fixed node
Modified: trunk/LayoutTests/tiled-drawing/scrolling/frames/coordinated-frame-in-fixed-expected.txt (202407 => 202408)
--- trunk/LayoutTests/tiled-drawing/scrolling/frames/coordinated-frame-in-fixed-expected.txt 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/LayoutTests/tiled-drawing/scrolling/frames/coordinated-frame-in-fixed-expected.txt 2016-06-24 02:38:00 UTC (rev 202408)
@@ -1,7 +1,7 @@
(Frame scrolling node
(scrollable area size 785 600)
(contents size 785 1016)
- (synchronous event dispatch region
+ (synchronous event dispatch region for event wheel
at (45,37) size 404x304)
(children 1
(Fixed node
Modified: trunk/LayoutTests/tiled-drawing/scrolling/frames/coordinated-frame-lose-scrolling-ancestor-expected.txt (202407 => 202408)
--- trunk/LayoutTests/tiled-drawing/scrolling/frames/coordinated-frame-lose-scrolling-ancestor-expected.txt 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/LayoutTests/tiled-drawing/scrolling/frames/coordinated-frame-lose-scrolling-ancestor-expected.txt 2016-06-24 02:38:00 UTC (rev 202408)
@@ -1,7 +1,7 @@
(Frame scrolling node
(scrollable area size 785 600)
(contents size 785 1016)
- (synchronous event dispatch region
+ (synchronous event dispatch region for event wheel
at (45,47) size 404x304)
(children 1
(Frame scrolling node
Modified: trunk/LayoutTests/tiled-drawing/scrolling/frames/frameset-frame-scrollability-expected.txt (202407 => 202408)
--- trunk/LayoutTests/tiled-drawing/scrolling/frames/frameset-frame-scrollability-expected.txt 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/LayoutTests/tiled-drawing/scrolling/frames/frameset-frame-scrollability-expected.txt 2016-06-24 02:38:00 UTC (rev 202408)
@@ -1,7 +1,7 @@
(Frame scrolling node
(scrollable area size 800 600)
(contents size 800 600)
- (synchronous event dispatch region
+ (synchronous event dispatch region for event wheel
at (0,0) size 800x594)
)
Modified: trunk/LayoutTests/tiled-drawing/scrolling/frames/frameset-nested-frame-scrollability-expected.txt (202407 => 202408)
--- trunk/LayoutTests/tiled-drawing/scrolling/frames/frameset-nested-frame-scrollability-expected.txt 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/LayoutTests/tiled-drawing/scrolling/frames/frameset-nested-frame-scrollability-expected.txt 2016-06-24 02:38:00 UTC (rev 202408)
@@ -1,7 +1,7 @@
(Frame scrolling node
(scrollable area size 800 600)
(contents size 800 600)
- (synchronous event dispatch region
+ (synchronous event dispatch region for event wheel
at (0,166) size 280x434)
)
Modified: trunk/LayoutTests/tiled-drawing/scrolling/frames/scroll-region-after-frame-layout-expected.txt (202407 => 202408)
--- trunk/LayoutTests/tiled-drawing/scrolling/frames/scroll-region-after-frame-layout-expected.txt 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/LayoutTests/tiled-drawing/scrolling/frames/scroll-region-after-frame-layout-expected.txt 2016-06-24 02:38:00 UTC (rev 202408)
@@ -2,7 +2,7 @@
(Frame scrolling node
(scrollable area size 785 600)
(contents size 785 757)
- (synchronous event dispatch region
+ (synchronous event dispatch region for event wheel
at (68,68) size 300x300)
)
Modified: trunk/Source/WebCore/CMakeLists.txt (202407 => 202408)
--- trunk/Source/WebCore/CMakeLists.txt 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebCore/CMakeLists.txt 2016-06-24 02:38:00 UTC (rev 202408)
@@ -2114,6 +2114,7 @@
platform/DisplaySleepDisabler.cpp
platform/DragData.cpp
platform/DragImage.cpp
+ platform/EventTrackingRegions.cpp
platform/FileChooser.cpp
platform/FileStream.cpp
platform/FileSystem.cpp
Modified: trunk/Source/WebCore/ChangeLog (202407 => 202408)
--- trunk/Source/WebCore/ChangeLog 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebCore/ChangeLog 2016-06-24 02:38:00 UTC (rev 202408)
@@ -1,3 +1,67 @@
+2016-06-23 Benjamin Poulain <[email protected]>
+
+ Specialize synchronous event tracking per event type
+ https://bugs.webkit.org/show_bug.cgi?id=158826
+
+ Reviewed by Simon Fraser.
+
+ First, kudos to Rick Byers for all his helps on passive event dispatch.
+ The specs are pretty damn good and his help reviewing patches is very useful.
+
+ This patch change synchronous event dispatch to happen per event
+ instead of per sequence touchstart->touchend.
+
+ The big advantage of this is we can dispatch more events asynchronously.
+ For example, to handle a tap programmatically, you can limit the active listener
+ to the touchend event. The touchstart and touchmove are now dispatched asynchronously.
+
+ The implementation is a simple extension to EventTrackingRegions.
+ Instead of a single synchronous region, we have one region per event type.
+ When processing the events, we only need to send the events synchronously
+ if that particular event type has a synchronous region.
+
+ Note that EventDispatcher's touch event support already supports
+ mixing synchronous and asynchronous events. The events are always processed
+ in order even if asynchronous events are pending when a synchronous dispatch
+ happens.
+
+ Tests: fast/events/touch/ios/tap-with-active-listener-inside-document-with-passive-listener.html
+ fast/events/touch/ios/tap-with-active-listener-inside-window-with-passive-listener.html
+ fast/events/touch/ios/tap-with-active-touch-end-listener.html
+ fast/events/touch/ios/tap-with-passive-listener-inside-active-listener.html
+ fast/events/touch/ios/tap-with-passive-touch-end-listener.html
+ fast/events/touch/ios/tap-with-passive-touch-start-active-touch-end-listeners-on-elements.html
+ fast/events/touch/ios/tap-with-passive-touch-start-active-touch-move-listeners-on-elements.html
+
+ * CMakeLists.txt:
+ * WebCore.xcodeproj/project.pbxproj:
+ * dom/EventTarget.cpp:
+ (WebCore::EventTarget::hasActiveTouchEventListeners): Deleted.
+ * dom/EventTarget.h:
+ * page/DebugPageOverlays.cpp:
+ (WebCore::NonFastScrollableRegionOverlay::updateRegion):
+ * page/Page.cpp:
+ (WebCore::Page::nonFastScrollableRects):
+ * page/scrolling/ScrollingCoordinator.cpp:
+ (WebCore::ScrollingCoordinator::absoluteEventTrackingRegionsForFrame):
+ * page/scrolling/ScrollingStateFrameScrollingNode.cpp:
+ (WebCore::ScrollingStateFrameScrollingNode::dumpProperties):
+ * page/scrolling/ScrollingTree.cpp:
+ (WebCore::ScrollingTree::shouldHandleWheelEventSynchronously):
+ (WebCore::ScrollingTree::eventTrackingTypeForPoint):
+ * page/scrolling/ScrollingTree.h:
+ * platform/EventTrackingRegions.cpp: Added.
+ (WebCore::EventTrackingRegions::trackingTypeForPoint):
+ (WebCore::EventTrackingRegions::isEmpty):
+ (WebCore::EventTrackingRegions::translate):
+ (WebCore::EventTrackingRegions::uniteSynchronousRegion):
+ (WebCore::EventTrackingRegions::unite):
+ (WebCore::operator==):
+ * platform/EventTrackingRegions.h:
+ (WebCore::EventTrackingRegions::isEmpty): Deleted.
+ (WebCore::EventTrackingRegions::trackingTypeForPoint): Deleted.
+ (WebCore::operator==): Deleted.
+
2016-06-23 Simon Fraser <[email protected]>
More attempting to fix external iOS builds.
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (202407 => 202408)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2016-06-24 02:38:00 UTC (rev 202408)
@@ -1075,6 +1075,7 @@
26255F0318878E110006E1FD /* UserAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 26255F0118878E110006E1FD /* UserAgent.h */; settings = {ATTRIBUTES = (Private, ); }; };
26255F0418878E110006E1FD /* UserAgentMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 26255F0218878E110006E1FD /* UserAgentMac.mm */; };
262EC41A1D078FB900BA78FC /* EventTrackingRegions.h in Headers */ = {isa = PBXBuildFile; fileRef = 262EC4191D078F3D00BA78FC /* EventTrackingRegions.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 262EC41D1D110B9000BA78FC /* EventTrackingRegions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 262EC41C1D110B1F00BA78FC /* EventTrackingRegions.cpp */; };
265541391489811C000DFC5D /* KeyEventCodesIOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 265541371489811C000DFC5D /* KeyEventCodesIOS.h */; settings = {ATTRIBUTES = (Private, ); }; };
2655413A1489811C000DFC5D /* KeyEventIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 265541381489811C000DFC5D /* KeyEventIOS.mm */; };
265541521489B233000DFC5D /* CursorIOS.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 2655414B1489AA2B000DFC5D /* CursorIOS.cpp */; };
@@ -8610,6 +8611,7 @@
26255F0118878E110006E1FD /* UserAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserAgent.h; sourceTree = "<group>"; };
26255F0218878E110006E1FD /* UserAgentMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = UserAgentMac.mm; sourceTree = "<group>"; };
262EC4191D078F3D00BA78FC /* EventTrackingRegions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventTrackingRegions.h; sourceTree = "<group>"; };
+ 262EC41C1D110B1F00BA78FC /* EventTrackingRegions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventTrackingRegions.cpp; sourceTree = "<group>"; };
265541371489811C000DFC5D /* KeyEventCodesIOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KeyEventCodesIOS.h; sourceTree = "<group>"; };
265541381489811C000DFC5D /* KeyEventIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = KeyEventIOS.mm; sourceTree = "<group>"; };
2655414B1489AA2B000DFC5D /* CursorIOS.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CursorIOS.cpp; sourceTree = "<group>"; };
@@ -23134,6 +23136,7 @@
A7CFB3CF0B7ED10A0070C32D /* DragImage.cpp */,
A7CFB3D00B7ED10A0070C32D /* DragImage.h */,
1CA19E150DC255CA0065A994 /* EventLoop.h */,
+ 262EC41C1D110B1F00BA78FC /* EventTrackingRegions.cpp */,
262EC4191D078F3D00BA78FC /* EventTrackingRegions.h */,
934FE9E40B5CA539003E4A73 /* FileChooser.cpp */,
066C772A0AB603B700238CC4 /* FileChooser.h */,
@@ -30675,6 +30678,7 @@
A7BBE26611AFB3F20005EA03 /* JSHTMLMeterElement.cpp in Sources */,
1AE2AB290A1CE63B00B42B25 /* JSHTMLModElement.cpp in Sources */,
BC305C790C076BB300CD20F0 /* JSHTMLObjectElement.cpp in Sources */,
+ 262EC41D1D110B9000BA78FC /* EventTrackingRegions.cpp in Sources */,
BC305CA40C0781BB00CD20F0 /* JSHTMLObjectElementCustom.cpp in Sources */,
1A85B1EA0A1B240500D8C87C /* JSHTMLOListElement.cpp in Sources */,
A80E7E9C0A1A83E3007FB8C5 /* JSHTMLOptGroupElement.cpp in Sources */,
Modified: trunk/Source/WebCore/dom/EventTarget.cpp (202407 => 202408)
--- trunk/Source/WebCore/dom/EventTarget.cpp 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebCore/dom/EventTarget.cpp 2016-06-24 02:38:00 UTC (rev 202408)
@@ -243,16 +243,6 @@
return !event.defaultPrevented();
}
-bool EventTarget::hasActiveTouchEventListeners() const
-{
- const EventNames& names = eventNames();
- return hasActiveEventListeners(names.touchstartEvent)
- || hasActiveEventListeners(names.touchmoveEvent)
- || hasActiveEventListeners(names.touchendEvent)
- || hasActiveEventListeners(names.touchcancelEvent)
- || hasActiveEventListeners(names.touchforcechangeEvent);
-}
-
void EventTarget::fireEventListeners(Event& event, EventTargetData* d, EventListenerVector& entry)
{
Ref<EventTarget> protectedThis(*this);
Modified: trunk/Source/WebCore/dom/EventTarget.h (202407 => 202408)
--- trunk/Source/WebCore/dom/EventTarget.h 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebCore/dom/EventTarget.h 2016-06-24 02:38:00 UTC (rev 202408)
@@ -168,8 +168,6 @@
void visitJSEventListeners(JSC::SlotVisitor&);
void invalidateJSEventListeners(JSC::JSObject*);
- bool hasActiveTouchEventListeners() const;
-
protected:
virtual ~EventTarget();
Modified: trunk/Source/WebCore/page/DebugPageOverlays.cpp (202407 => 202408)
--- trunk/Source/WebCore/page/DebugPageOverlays.cpp 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebCore/page/DebugPageOverlays.cpp 2016-06-24 02:38:00 UTC (rev 202408)
@@ -133,7 +133,8 @@
if (Page* page = m_frame.page()) {
if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator()) {
EventTrackingRegions eventTrackingRegions = scrollingCoordinator->absoluteEventTrackingRegions();
- *region = eventTrackingRegions.synchronousDispatchRegion;
+ for (const auto& synchronousEventRegion : eventTrackingRegions.eventSpecificSynchronousDispatchRegions)
+ region->unite(synchronousEventRegion.value);
}
}
Modified: trunk/Source/WebCore/page/Page.cpp (202407 => 202408)
--- trunk/Source/WebCore/page/Page.cpp 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebCore/page/Page.cpp 2016-06-24 02:38:00 UTC (rev 202408)
@@ -372,8 +372,11 @@
document->updateLayout();
Vector<IntRect> rects;
- if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
- rects = scrollingCoordinator->absoluteEventTrackingRegions().synchronousDispatchRegion.rects();
+ if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
+ const EventTrackingRegions& eventTrackingRegions = scrollingCoordinator->absoluteEventTrackingRegions();
+ for (const auto& synchronousEventRegion : eventTrackingRegions.eventSpecificSynchronousDispatchRegions)
+ rects.appendVector(synchronousEventRegion.value.rects());
+ }
Vector<FloatQuad> quads(rects.size());
for (size_t i = 0; i < rects.size(); ++i)
Modified: trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp (202407 => 202408)
--- trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebCore/page/scrolling/ScrollingCoordinator.cpp 2016-06-24 02:38:00 UTC (rev 202408)
@@ -28,6 +28,7 @@
#include "ScrollingCoordinator.h"
#include "Document.h"
+#include "EventNames.h"
#include "FrameView.h"
#include "GraphicsLayer.h"
#include "IntRect.h"
@@ -144,18 +145,19 @@
}
// FIXME: if we've already accounted for this subframe as a scrollable area, we can avoid recursing into it here.
+ EventTrackingRegions eventTrackingRegions;
for (Frame* subframe = frame.tree().firstChild(); subframe; subframe = subframe->tree().nextSibling()) {
FrameView* subframeView = subframe->view();
if (!subframeView)
continue;
- Region subframeRegion = absoluteEventTrackingRegionsForFrame(*subframe).synchronousDispatchRegion;
+ EventTrackingRegions subframeRegion = absoluteEventTrackingRegionsForFrame(*subframe);
// Map from the frame document to our document.
IntPoint offset = subframeView->contentsToContainingViewContents(IntPoint());
// FIXME: this translation ignores non-trival transforms on the frame.
subframeRegion.translate(toIntSize(offset));
- nonFastScrollableRegion.unite(subframeRegion);
+ eventTrackingRegions.unite(subframeRegion);
}
Document::RegionFixedPair wheelHandlerRegion = frame.document()->absoluteRegionForEventTargets(frame.document()->wheelEventTargets());
@@ -169,7 +171,8 @@
nonFastScrollableRegion.unite(wheelHandlerRegion.first);
// FIXME: If this is not the main frame, we could clip the region to the frame's bounds.
- return EventTrackingRegions { Region(), nonFastScrollableRegion };
+ eventTrackingRegions.uniteSynchronousRegion(eventNames().wheelEvent, nonFastScrollableRegion);
+ return eventTrackingRegions;
#endif
}
Modified: trunk/Source/WebCore/page/scrolling/ScrollingStateFrameScrollingNode.cpp (202407 => 202408)
--- trunk/Source/WebCore/page/scrolling/ScrollingStateFrameScrollingNode.cpp 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebCore/page/scrolling/ScrollingStateFrameScrollingNode.cpp 2016-06-24 02:38:00 UTC (rev 202408)
@@ -245,18 +245,20 @@
ts << ")\n";
indent -= 2;
}
- if (!m_eventTrackingRegions.synchronousDispatchRegion.isEmpty()) {
- ++indent;
- writeIndent(ts, indent);
- ts << "(synchronous event dispatch region";
- ++indent;
- for (auto rect : m_eventTrackingRegions.synchronousDispatchRegion.rects()) {
- ts << "\n";
+ if (!m_eventTrackingRegions.eventSpecificSynchronousDispatchRegions.isEmpty()) {
+ for (const auto& synchronousEventRegion : m_eventTrackingRegions.eventSpecificSynchronousDispatchRegions) {
+ ++indent;
writeIndent(ts, indent);
- ts << rect;
+ ts << "(synchronous event dispatch region for event " << synchronousEventRegion.key;
+ ++indent;
+ for (auto rect : synchronousEventRegion.value.rects()) {
+ ts << "\n";
+ writeIndent(ts, indent);
+ ts << rect;
+ }
+ ts << ")\n";
+ indent -= 2;
}
- ts << ")\n";
- indent -= 2;
}
if (m_synchronousScrollingReasons) {
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp (202407 => 202408)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.cpp 2016-06-24 02:38:00 UTC (rev 202408)
@@ -28,6 +28,7 @@
#if ENABLE(ASYNC_SCROLLING)
+#include "EventNames.h"
#include "Logging.h"
#include "PlatformWheelEvent.h"
#include "ScrollingStateTree.h"
@@ -66,7 +67,10 @@
FloatPoint position = wheelEvent.position();
position.move(frameScrollingNode.viewToContentsOffset(m_mainFrameScrollPosition));
- bool isSynchronousDispatchRegion = m_eventTrackingRegions.trackingTypeForPoint(roundedIntPoint(position)) == TrackingType::Synchronous;
+ const EventNames& names = eventNames();
+ IntPoint roundedPosition = roundedIntPoint(position);
+ bool isSynchronousDispatchRegion = m_eventTrackingRegions.trackingTypeForPoint(names.wheelEvent, roundedPosition) == TrackingType::Synchronous
+ || m_eventTrackingRegions.trackingTypeForPoint(names.mousewheelEvent, roundedPosition) == TrackingType::Synchronous;
LOG_WITH_STREAM(Scrolling, stream << "ScrollingTree::shouldHandleWheelEventSynchronously: wheelEvent at " << wheelEvent.position() << " mapped to content point " << position << ", in non-fast region " << isSynchronousDispatchRegion);
if (isSynchronousDispatchRegion)
@@ -233,11 +237,11 @@
m_mainFrameScrollPosition = position;
}
-TrackingType ScrollingTree::eventTrackingTypeForPoint(IntPoint p)
+TrackingType ScrollingTree::eventTrackingTypeForPoint(const AtomicString& eventName, IntPoint p)
{
LockHolder lock(m_mutex);
- return m_eventTrackingRegions.trackingTypeForPoint(p);
+ return m_eventTrackingRegions.trackingTypeForPoint(eventName, p);
}
bool ScrollingTree::isRubberBandInProgress()
Modified: trunk/Source/WebCore/page/scrolling/ScrollingTree.h (202407 => 202408)
--- trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebCore/page/scrolling/ScrollingTree.h 2016-06-24 02:38:00 UTC (rev 202408)
@@ -101,7 +101,7 @@
virtual void scrollingTreeNodeDidEndScroll() { }
#endif
- WEBCORE_EXPORT TrackingType eventTrackingTypeForPoint(IntPoint);
+ WEBCORE_EXPORT TrackingType eventTrackingTypeForPoint(const AtomicString& eventName, IntPoint);
#if PLATFORM(MAC)
virtual void handleWheelEventPhase(PlatformWheelEventPhase) = 0;
Added: trunk/Source/WebCore/platform/EventTrackingRegions.cpp (0 => 202408)
--- trunk/Source/WebCore/platform/EventTrackingRegions.cpp (rev 0)
+++ trunk/Source/WebCore/platform/EventTrackingRegions.cpp 2016-06-24 02:38:00 UTC (rev 202408)
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "EventTrackingRegions.h"
+
+namespace WebCore {
+
+TrackingType EventTrackingRegions::trackingTypeForPoint(const String& eventName, const IntPoint& point)
+{
+ auto synchronousRegionIterator = eventSpecificSynchronousDispatchRegions.find(eventName);
+ if (synchronousRegionIterator != eventSpecificSynchronousDispatchRegions.end()) {
+ if (synchronousRegionIterator->value.contains(point))
+ return TrackingType::Synchronous;
+ }
+
+ if (asynchronousDispatchRegion.contains(point))
+ return TrackingType::Asynchronous;
+ return TrackingType::NotTracking;
+}
+
+bool EventTrackingRegions::isEmpty() const
+{
+ return asynchronousDispatchRegion.isEmpty() && eventSpecificSynchronousDispatchRegions.isEmpty();
+}
+
+void EventTrackingRegions::translate(IntSize offset)
+{
+ asynchronousDispatchRegion.translate(offset);
+ for (auto& slot : eventSpecificSynchronousDispatchRegions)
+ slot.value.translate(offset);
+}
+
+void EventTrackingRegions::uniteSynchronousRegion(const String& eventName, const Region& region)
+{
+ if (region.isEmpty())
+ return;
+
+ auto addResult = eventSpecificSynchronousDispatchRegions.add(eventName, region);
+ if (!addResult.isNewEntry)
+ addResult.iterator->value.unite(region);
+}
+
+void EventTrackingRegions::unite(const EventTrackingRegions& eventTrackingRegions)
+{
+ asynchronousDispatchRegion.unite(eventTrackingRegions.asynchronousDispatchRegion);
+ for (auto& slot : eventTrackingRegions.eventSpecificSynchronousDispatchRegions)
+ uniteSynchronousRegion(slot.key, slot.value);
+}
+
+bool operator==(const EventTrackingRegions& a, const EventTrackingRegions& b)
+{
+ return a.asynchronousDispatchRegion == b.asynchronousDispatchRegion
+ && a.eventSpecificSynchronousDispatchRegions == b.eventSpecificSynchronousDispatchRegions;
+}
+
+} // namespace WebCore
Modified: trunk/Source/WebCore/platform/EventTrackingRegions.h (202407 => 202408)
--- trunk/Source/WebCore/platform/EventTrackingRegions.h 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebCore/platform/EventTrackingRegions.h 2016-06-24 02:38:00 UTC (rev 202408)
@@ -26,6 +26,9 @@
#pragma once
#include "Region.h"
+#include <wtf/HashMap.h>
+#include <wtf/text/StringHash.h>
+#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -39,32 +42,20 @@
// Region for which events can be dispatched without blocking scrolling.
Region asynchronousDispatchRegion;
- // Region for which events must be sent before performing the default behavior.
- Region synchronousDispatchRegion;
+ // Regions for which events must be sent before performing the default behavior.
+ // The key is the Event Name with an active handler.
+ HashMap<String, Region> eventSpecificSynchronousDispatchRegions;
bool isEmpty() const;
- TrackingType trackingTypeForPoint(const IntPoint&);
+ void translate(IntSize);
+ void uniteSynchronousRegion(const String& eventName, const Region&);
+ void unite(const EventTrackingRegions&);
+
+ TrackingType trackingTypeForPoint(const String& eventName, const IntPoint&);
};
-inline bool EventTrackingRegions::isEmpty() const
-{
- return asynchronousDispatchRegion.isEmpty() && synchronousDispatchRegion.isEmpty();
-}
+bool operator==(const EventTrackingRegions&, const EventTrackingRegions&);
+inline bool operator!=(const EventTrackingRegions& a, const EventTrackingRegions& b) { return !(a == b); }
-inline TrackingType EventTrackingRegions::trackingTypeForPoint(const IntPoint& point)
-{
- if (synchronousDispatchRegion.contains(point))
- return TrackingType::Synchronous;
- if (asynchronousDispatchRegion.contains(point))
- return TrackingType::Asynchronous;
- return TrackingType::NotTracking;
-}
-
-inline bool operator==(const EventTrackingRegions& a, const EventTrackingRegions& b)
-{
- return a.asynchronousDispatchRegion == b.asynchronousDispatchRegion
- && a.synchronousDispatchRegion == b.synchronousDispatchRegion;
-}
-
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/graphics/Region.h (202407 => 202408)
--- trunk/Source/WebCore/platform/graphics/Region.h 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebCore/platform/graphics/Region.h 2016-06-24 02:38:00 UTC (rev 202408)
@@ -198,6 +198,10 @@
{
return a.m_bounds == b.m_bounds && a.m_shape == b.m_shape;
}
+inline bool operator!=(const Region& a, const Region& b)
+{
+ return !(a == b);
+}
inline bool operator==(const Region::Shape& a, const Region::Shape& b)
{
@@ -208,6 +212,10 @@
{
return a.y == b.y && a.segmentIndex == b.segmentIndex;
}
+inline bool operator!=(const Region::Span& a, const Region::Span& b)
+{
+ return !(a == b);
+}
} // namespace WebCore
Modified: trunk/Source/WebKit2/ChangeLog (202407 => 202408)
--- trunk/Source/WebKit2/ChangeLog 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebKit2/ChangeLog 2016-06-24 02:38:00 UTC (rev 202408)
@@ -1,3 +1,28 @@
+2016-06-23 Benjamin Poulain <[email protected]>
+
+ Specialize synchronous event tracking per event type
+ https://bugs.webkit.org/show_bug.cgi?id=158826
+
+ Reviewed by Simon Fraser.
+
+ * Shared/WebCoreArgumentCoders.cpp:
+ (IPC::ArgumentCoder<EventTrackingRegions>::encode):
+ (IPC::ArgumentCoder<EventTrackingRegions>::decode):
+ * UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp:
+ (WebKit::RemoteScrollingCoordinatorProxy::eventTrackingTypeForPoint):
+ * UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h:
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::mergeTrackingTypes):
+ (WebKit::WebPageProxy::updateTouchEventTracking):
+ (WebKit::WebPageProxy::touchEventTrackingType):
+ (WebKit::WebPageProxy::handleTouchEventSynchronously):
+ (WebKit::WebPageProxy::handleTouchEventAsynchronously):
+ (WebKit::WebPageProxy::handleTouchEvent):
+ (WebKit::WebPageProxy::resetState):
+ * UIProcess/WebPageProxy.h:
+ (WebKit::WebPageProxy::TouchEventTracking::isTrackingAnything):
+ (WebKit::WebPageProxy::TouchEventTracking::reset):
+
2016-06-23 Said Abou-Hallawa <[email protected]>
requestFrameAnimation() callback timestamp should be very close to Performance.now()
Modified: trunk/Source/WebKit2/Shared/Scrolling/RemoteScrollingCoordinatorTransaction.cpp (202407 => 202408)
--- trunk/Source/WebKit2/Shared/Scrolling/RemoteScrollingCoordinatorTransaction.cpp 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebKit2/Shared/Scrolling/RemoteScrollingCoordinatorTransaction.cpp 2016-06-24 02:38:00 UTC (rev 202408)
@@ -494,10 +494,11 @@
ts << rect;
}
}
- {
+ for (const auto& synchronousEventRegion : node.eventTrackingRegions().eventSpecificSynchronousDispatchRegions) {
TextStream::GroupScope group(ts);
- ts << "synchronous-event-tracking-region";
- for (auto rect : node.eventTrackingRegions().synchronousDispatchRegion.rects()) {
+ ts << "synchronous-event-tracking-region for event " << synchronousEventRegion.key;
+
+ for (auto rect : synchronousEventRegion.value.rects()) {
ts << "\n";
ts.writeIndent();
ts << rect;
Modified: trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp (202407 => 202408)
--- trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp 2016-06-24 02:38:00 UTC (rev 202408)
@@ -111,7 +111,7 @@
void ArgumentCoder<EventTrackingRegions>::encode(ArgumentEncoder& encoder, const EventTrackingRegions& eventTrackingRegions)
{
encoder << eventTrackingRegions.asynchronousDispatchRegion;
- encoder << eventTrackingRegions.synchronousDispatchRegion;
+ encoder << eventTrackingRegions.eventSpecificSynchronousDispatchRegions;
}
bool ArgumentCoder<EventTrackingRegions>::decode(ArgumentDecoder& decoder, EventTrackingRegions& eventTrackingRegions)
@@ -119,11 +119,11 @@
Region asynchronousDispatchRegion;
if (!decoder.decode(asynchronousDispatchRegion))
return false;
- Region synchronousDispatchRegion;
- if (!decoder.decode(synchronousDispatchRegion))
+ HashMap<String, Region> eventSpecificSynchronousDispatchRegions;
+ if (!decoder.decode(eventSpecificSynchronousDispatchRegions))
return false;
eventTrackingRegions.asynchronousDispatchRegion = WTFMove(asynchronousDispatchRegion);
- eventTrackingRegions.synchronousDispatchRegion = WTFMove(synchronousDispatchRegion);
+ eventTrackingRegions.eventSpecificSynchronousDispatchRegions = WTFMove(eventSpecificSynchronousDispatchRegions);
return true;
}
Modified: trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp (202407 => 202408)
--- trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.cpp 2016-06-24 02:38:00 UTC (rev 202408)
@@ -149,9 +149,9 @@
return result == ScrollingTree::DidHandleEvent; // FIXME: handle other values.
}
-TrackingType RemoteScrollingCoordinatorProxy::eventTrackingTypeForPoint(IntPoint p) const
+TrackingType RemoteScrollingCoordinatorProxy::eventTrackingTypeForPoint(const AtomicString& eventName, IntPoint p) const
{
- return m_scrollingTree->eventTrackingTypeForPoint(p);
+ return m_scrollingTree->eventTrackingTypeForPoint(eventName, p);
}
void RemoteScrollingCoordinatorProxy::viewportChangedViaDelegatedScrolling(ScrollingNodeID nodeID, const FloatRect& fixedPositionRect, double scale)
Modified: trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h (202407 => 202408)
--- trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebKit2/UIProcess/Scrolling/RemoteScrollingCoordinatorProxy.h 2016-06-24 02:38:00 UTC (rev 202408)
@@ -56,7 +56,7 @@
void scrollingTreeNodeDidScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& newScrollPosition, WebCore::SetOrSyncScrollingLayerPosition);
void scrollingTreeNodeRequestsScroll(WebCore::ScrollingNodeID, const WebCore::FloatPoint& scrollPosition, bool representsProgrammaticScroll);
- WebCore::TrackingType eventTrackingTypeForPoint(WebCore::IntPoint) const;
+ WebCore::TrackingType eventTrackingTypeForPoint(const AtomicString& eventName, WebCore::IntPoint) const;
// Called externally when native views move around.
void viewportChangedViaDelegatedScrolling(WebCore::ScrollingNodeID, const WebCore::FloatRect& fixedPositionRect, double scale);
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (202407 => 202408)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp 2016-06-24 02:38:00 UTC (rev 202408)
@@ -110,6 +110,7 @@
#include <WebCore/DiagnosticLoggingClient.h>
#include <WebCore/DragController.h>
#include <WebCore/DragData.h>
+#include <WebCore/EventNames.h>
#include <WebCore/FloatRect.h>
#include <WebCore/FocusDirection.h>
#include <WebCore/JSDOMBinding.h>
@@ -1955,26 +1956,76 @@
#if ENABLE(TOUCH_EVENTS)
-TrackingType WebPageProxy::touchEventTrackingType(const WebTouchEvent& touchStartEvent) const
+static TrackingType mergeTrackingTypes(TrackingType a, TrackingType b)
{
+ if (static_cast<uintptr_t>(b) > static_cast<uintptr_t>(a))
+ return b;
+ return a;
+}
+
+void WebPageProxy::updateTouchEventTracking(const WebTouchEvent& touchStartEvent)
+{
#if ENABLE(ASYNC_SCROLLING)
- TrackingType trackingType = TrackingType::NotTracking;
+ const EventNames& names = eventNames();
for (auto& touchPoint : touchStartEvent.touchPoints()) {
- TrackingType touchPointTrackingType = m_scrollingCoordinatorProxy->eventTrackingTypeForPoint(touchPoint.location());
- if (touchPointTrackingType == TrackingType::Synchronous)
- return TrackingType::Synchronous;
+ IntPoint location = touchPoint.location();
+ auto updateTrackingType = [this, location](TrackingType& trackingType, const AtomicString& eventName) {
+ if (trackingType == TrackingType::Synchronous)
+ return;
- if (touchPointTrackingType == TrackingType::Asynchronous)
- trackingType = touchPointTrackingType;
+ TrackingType trackingTypeForLocation = m_scrollingCoordinatorProxy->eventTrackingTypeForPoint(eventName, location);
+
+ trackingType = mergeTrackingTypes(trackingType, trackingTypeForLocation);
+ };
+ updateTrackingType(m_touchEventTracking.touchForceChangedTracking, names.touchforcechangeEvent);
+ updateTrackingType(m_touchEventTracking.touchStartTracking, names.touchstartEvent);
+ updateTrackingType(m_touchEventTracking.touchMoveTracking, names.touchmoveEvent);
+ updateTrackingType(m_touchEventTracking.touchEndTracking, names.touchendEvent);
}
-
- return trackingType;
#else
UNUSED_PARAM(touchStartEvent);
+ m_touchEventTracking.touchForceChangedTracking = TrackingType::Synchronous;
+ m_touchEventTracking.touchStartTracking = TrackingType::Synchronous;
+ m_touchEventTracking.touchMoveTracking = TrackingType::Synchronous;
+ m_touchEventTracking.touchEndTracking = TrackingType::Synchronous;
#endif // ENABLE(ASYNC_SCROLLING)
- return TrackingType::Synchronous;
}
+TrackingType WebPageProxy::touchEventTrackingType(const WebTouchEvent& touchStartEvent) const
+{
+ // We send all events if any type is needed, we just do it asynchronously for the types that are not tracked.
+ //
+ // Touch events define a sequence with strong dependencies. For example, we can expect
+ // a TouchMove to only appear after a TouchStart, and the ids of the touch points is consistent between
+ // the two.
+ //
+ // WebCore should not have to set up its state correctly after some events were dismissed.
+ // For example, we don't want to send a TouchMoved without a TouchPressed.
+ // We send everything, WebCore updates its internal state and dispatch what is needed to the page.
+ TrackingType globalTrackingType = m_touchEventTracking.isTrackingAnything() ? TrackingType::Asynchronous : TrackingType::NotTracking;
+
+ globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchForceChangedTracking);
+ for (auto& touchPoint : touchStartEvent.touchPoints()) {
+ switch (touchPoint.state()) {
+ case WebPlatformTouchPoint::TouchReleased:
+ globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchEndTracking);
+ break;
+ case WebPlatformTouchPoint::TouchPressed:
+ globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchStartTracking);
+ break;
+ case WebPlatformTouchPoint::TouchMoved:
+ case WebPlatformTouchPoint::TouchStationary:
+ globalTrackingType = mergeTrackingTypes(globalTrackingType, m_touchEventTracking.touchMoveTracking);
+ break;
+ case WebPlatformTouchPoint::TouchCancelled:
+ globalTrackingType = mergeTrackingTypes(globalTrackingType, TrackingType::Asynchronous);
+ break;
+ }
+ }
+
+ return globalTrackingType;
+}
+
#endif
#if ENABLE(MAC_GESTURE_EVENTS)
@@ -1998,14 +2049,15 @@
return;
if (event.type() == WebEvent::TouchStart) {
- m_touchEventsTrackingType = touchEventTrackingType(event);
+ updateTouchEventTracking(event);
m_layerTreeTransactionIdAtLastTouchStart = downcast<RemoteLayerTreeDrawingAreaProxy>(*drawingArea()).lastCommittedLayerTreeTransactionID();
}
- if (m_touchEventsTrackingType == TrackingType::NotTracking)
+ TrackingType touchEventsTrackingType = touchEventTrackingType(event);
+ if (touchEventsTrackingType == TrackingType::NotTracking)
return;
- if (m_touchEventsTrackingType == TrackingType::Asynchronous) {
+ if (touchEventsTrackingType == TrackingType::Asynchronous) {
// We can end up here if a native gesture has not started but the event handlers are passive.
//
// The client of WebPageProxy asks the event to be sent synchronously since the touch event
@@ -2026,7 +2078,7 @@
m_process->responsivenessTimer().stop();
if (event.allTouchPointsAreReleased())
- m_touchEventsTrackingType = TrackingType::NotTracking;
+ m_touchEventTracking.reset();
}
void WebPageProxy::handleTouchEventAsynchronously(const NativeWebTouchEvent& event)
@@ -2034,13 +2086,14 @@
if (!isValid())
return;
- if (m_touchEventsTrackingType == TrackingType::NotTracking)
+ TrackingType touchEventsTrackingType = touchEventTrackingType(event);
+ if (touchEventsTrackingType == TrackingType::NotTracking)
return;
m_process->send(Messages::EventDispatcher::TouchEvent(m_pageID, event), 0);
if (event.allTouchPointsAreReleased())
- m_touchEventsTrackingType = TrackingType::NotTracking;
+ m_touchEventTracking.reset();
}
#elif ENABLE(TOUCH_EVENTS)
@@ -2050,9 +2103,9 @@
return;
if (event.type() == WebEvent::TouchStart)
- m_touchEventsTrackingType = touchEventTrackingType(event);
+ updateTouchEventTracking(event);
- if (m_touchEventsTrackingType == TrackingType::NotTracking)
+ if (touchEventTrackingType(event) == TrackingType::NotTracking)
return;
// If the page is suspended, which should be the case during panning, pinching
@@ -2075,7 +2128,7 @@
}
if (event.allTouchPointsAreReleased())
- m_touchEventsTrackingType = TrackingType::NotTracking;
+ m_touchEventTracking.reset();
}
#endif // ENABLE(TOUCH_EVENTS)
@@ -5094,7 +5147,7 @@
}
#if ENABLE(TOUCH_EVENTS)
- m_touchEventsTrackingType = TrackingType::NotTracking;
+ m_touchEventTracking.reset();
#endif
#if ENABLE(INPUT_TYPE_COLOR)
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (202407 => 202408)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h 2016-06-24 00:59:08 UTC (rev 202407)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h 2016-06-24 02:38:00 UTC (rev 202408)
@@ -1468,6 +1468,7 @@
void sendWheelEvent(const WebWheelEvent&);
#if ENABLE(TOUCH_EVENTS)
+ void updateTouchEventTracking(const WebTouchEvent&);
WebCore::TrackingType touchEventTrackingType(const WebTouchEvent&) const;
#endif
@@ -1695,7 +1696,29 @@
std::unique_ptr<NativeWebMouseEvent> m_currentlyProcessedMouseDownEvent;
#if ENABLE(TOUCH_EVENTS)
- WebCore::TrackingType m_touchEventsTrackingType { WebCore::TrackingType::NotTracking };
+ struct TouchEventTracking {
+ WebCore::TrackingType touchForceChangedTracking { WebCore::TrackingType::NotTracking };
+ WebCore::TrackingType touchStartTracking { WebCore::TrackingType::NotTracking };
+ WebCore::TrackingType touchMoveTracking { WebCore::TrackingType::NotTracking };
+ WebCore::TrackingType touchEndTracking { WebCore::TrackingType::NotTracking };
+
+ bool isTrackingAnything() const
+ {
+ return touchForceChangedTracking != WebCore::TrackingType::NotTracking
+ || touchStartTracking != WebCore::TrackingType::NotTracking
+ || touchMoveTracking != WebCore::TrackingType::NotTracking
+ || touchEndTracking != WebCore::TrackingType::NotTracking;
+ }
+
+ void reset()
+ {
+ touchForceChangedTracking = WebCore::TrackingType::NotTracking;
+ touchStartTracking = WebCore::TrackingType::NotTracking;
+ touchMoveTracking = WebCore::TrackingType::NotTracking;
+ touchEndTracking = WebCore::TrackingType::NotTracking;
+ }
+ };
+ TouchEventTracking m_touchEventTracking;
#endif
#if ENABLE(TOUCH_EVENTS) && !ENABLE(IOS_TOUCH_EVENTS)
Deque<QueuedTouchEvents> m_touchEventQueue;