Diff
Modified: trunk/LayoutTests/ChangeLog (137219 => 137220)
--- trunk/LayoutTests/ChangeLog 2012-12-10 23:56:02 UTC (rev 137219)
+++ trunk/LayoutTests/ChangeLog 2012-12-11 00:08:09 UTC (rev 137220)
@@ -1,3 +1,20 @@
+2012-12-10 Min Qin <[email protected]>
+
+ Sending multi-touch events to the same Iframe
+ https://bugs.webkit.org/show_bug.cgi?id=97973
+
+ Reviewed by Dimitri Glazkov.
+
+ Check that all multi-touch events are sent to the same iframe.
+
+ * fast/events/touch/multi-touch-inside-iframes-expected.txt: Added.
+ * fast/events/touch/multi-touch-inside-iframes.html: Added.
+ * fast/events/touch/resources/multi-touch-inside-iframes2.html: Added.
+ * fast/events/touch/multi-touch-inside-nested-iframes-expected.txt: Added.
+ * fast/events/touch/multi-touch-inside-nested-iframes.html: Added.
+ * fast/events/touch/resources/multi-touch-inside-nested-iframes2.html: Added.
+ * fast/events/touch/resources/multi-touch-inside-nested-iframes3.html: Added.
+
2012-12-10 Simon Fraser <[email protected]>
When converting a layer into a tiled layer, ensure that we update the visible rect
Added: trunk/LayoutTests/fast/events/touch/multi-touch-inside-iframes-expected.txt (0 => 137220)
--- trunk/LayoutTests/fast/events/touch/multi-touch-inside-iframes-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/multi-touch-inside-iframes-expected.txt 2012-12-11 00:08:09 UTC (rev 137220)
@@ -0,0 +1,70 @@
+
+Test multi-touch is sent to the same iframe.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+First touch is on iframe1.
+PASS document.elementFromPoint(101, 101).id is "iframe1"
+PASS ev.type is "touchstart"
+PASS touchreceiver is "iframe1"
+PASS ev.changedTouches.length is 1
+PASS ev.touches.length is 1
+PASS ev.targetTouches.length is 1
+PASS ev.touches[0].pageX is 50
+PASS ev.touches[0].pageY is 50
+PASS ev.touches[0].target.ownerDocument.title is "iframe1"
+PASS ev.changedTouches[0].target.ownerDocument.title is "iframe1"
+PASS ev.targetTouches[0].target.ownerDocument.title is "iframe1"
+
+Second touch is on iframe2, nothing should happen.
+PASS document.elementFromPoint(251, 101).id is "iframe2"
+
+Moves the first touch outside iframe1.
+PASS ev.type is "touchmove"
+PASS touchreceiver is "iframe1"
+PASS ev.changedTouches.length is 1
+PASS ev.touches.length is 1
+PASS ev.targetTouches.length is 1
+PASS ev.touches[0].pageX is 150
+PASS ev.touches[0].pageY is 150
+PASS ev.touches[0].target.ownerDocument.title is "iframe1"
+PASS ev.changedTouches[0].target.ownerDocument.title is "iframe1"
+PASS ev.targetTouches[0].target.ownerDocument.title is "iframe1"
+
+Release the first touch.
+PASS ev.type is "touchend"
+PASS touchreceiver is "iframe1"
+PASS ev.changedTouches.length is 1
+PASS ev.touches.length is 0
+PASS ev.targetTouches.length is 0
+PASS ev.changedTouches[0].target.ownerDocument.title is "iframe1"
+
+Third touch is on iframe2, nothing should happen.
+PASS document.elementFromPoint(261, 101).id is "iframe2"
+
+Release all touches on iframe2, and touch iframe2 again.
+PASS ev.type is "touchstart"
+PASS touchreceiver is "iframe2"
+PASS ev.changedTouches.length is 1
+PASS ev.touches.length is 1
+PASS ev.targetTouches.length is 1
+PASS ev.touches[0].pageX is 50
+PASS ev.touches[0].pageY is 50
+PASS ev.touches[0].target.ownerDocument.title is "iframe2"
+PASS ev.changedTouches[0].target.ownerDocument.title is "iframe2"
+PASS ev.targetTouches[0].target.ownerDocument.title is "iframe2"
+
+Touch iframe1, nothing shoud happen.
+
+Release all touches.
+PASS ev.type is "touchend"
+PASS touchreceiver is "iframe2"
+PASS ev.changedTouches.length is 1
+PASS ev.touches.length is 0
+PASS ev.targetTouches.length is 0
+PASS ev.changedTouches[0].target.ownerDocument.title is "iframe2"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/events/touch/multi-touch-inside-iframes.html (0 => 137220)
--- trunk/LayoutTests/fast/events/touch/multi-touch-inside-iframes.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/multi-touch-inside-iframes.html 2012-12-11 00:08:09 UTC (rev 137220)
@@ -0,0 +1,173 @@
+<html>
+<script src=""
+<style>
+iframe {
+ width: 100px;
+ height: 100px;
+ margin: 0;
+ padding: 0;
+ border: 1px solid black;
+}
+
+#iframe1
+{
+position:absolute;
+left:50px;
+top:50px;
+}
+
+#iframe2
+{
+position:absolute;
+left:200px;
+top:50px;
+}
+
+#output
+{
+position:absolute;
+top:150px;
+}
+
+</style>
+<body _onload_="runTest()">
+<iframe id="iframe1" src=""
+<iframe id="iframe2" src=""
+<div id="output">
+<p id="description"></p>
+<div id="console"></div>
+</div>
+<script type="text/_javascript_">
+description('Test multi-touch is sent to the same iframe.');
+
+var touchEventCount = 0;
+var title = 0;
+
+function onTouch(event, receiver)
+{
+ ev = event;
+ touchreceiver = receiver;
+ switch (touchEventCount) {
+ case 0:
+ shouldBeEqualToString('ev.type', 'touchstart');
+ shouldBeEqualToString('touchreceiver', 'iframe1');
+ shouldBe("ev.changedTouches.length", "1");
+ shouldBe("ev.touches.length", "1");
+ shouldBe("ev.targetTouches.length", "1");
+ shouldBe("ev.touches[0].pageX", "50");
+ shouldBe("ev.touches[0].pageY", "50");
+ shouldBeEqualToString('ev.touches[0].target.ownerDocument.title', 'iframe1');
+ shouldBeEqualToString('ev.changedTouches[0].target.ownerDocument.title', 'iframe1');
+ shouldBeEqualToString('ev.targetTouches[0].target.ownerDocument.title', 'iframe1');
+ break;
+ case 1:
+ shouldBeEqualToString('ev.type', 'touchmove');
+ shouldBeEqualToString('touchreceiver', 'iframe1');
+ shouldBe("ev.changedTouches.length", "1");
+ shouldBe("ev.touches.length", "1");
+ shouldBe("ev.targetTouches.length", "1");
+ shouldBe("ev.touches[0].pageX", "150");
+ shouldBe("ev.touches[0].pageY", "150");
+ shouldBeEqualToString('ev.touches[0].target.ownerDocument.title', 'iframe1');
+ shouldBeEqualToString('ev.changedTouches[0].target.ownerDocument.title', 'iframe1');
+ shouldBeEqualToString('ev.targetTouches[0].target.ownerDocument.title', 'iframe1');
+ break;
+ case 2:
+ shouldBeEqualToString('ev.type', 'touchend');
+ shouldBeEqualToString('touchreceiver', 'iframe1');
+ shouldBe("ev.changedTouches.length", "1");
+ shouldBe("ev.touches.length", "0");
+ shouldBe("ev.targetTouches.length", "0");
+ shouldBeEqualToString('ev.changedTouches[0].target.ownerDocument.title', 'iframe1');
+ break;
+ case 3:
+ shouldBeEqualToString('ev.type', 'touchstart');
+ shouldBeEqualToString('touchreceiver', 'iframe2');
+ shouldBe("ev.changedTouches.length", "1");
+ shouldBe("ev.touches.length", "1");
+ shouldBe("ev.targetTouches.length", "1");
+ shouldBe("ev.touches[0].pageX", "50");
+ shouldBe("ev.touches[0].pageY", "50");
+ shouldBeEqualToString('ev.touches[0].target.ownerDocument.title', 'iframe2');
+ shouldBeEqualToString('ev.changedTouches[0].target.ownerDocument.title', 'iframe2');
+ shouldBeEqualToString('ev.targetTouches[0].target.ownerDocument.title', 'iframe2');
+ break;
+ case 4:
+ shouldBeEqualToString('ev.type', 'touchend');
+ shouldBeEqualToString('touchreceiver', 'iframe2');
+ shouldBe("ev.changedTouches.length", "1");
+ shouldBe("ev.touches.length", "0");
+ shouldBe("ev.targetTouches.length", "0");
+ shouldBeEqualToString('ev.changedTouches[0].target.ownerDocument.title', 'iframe2');
+ isSuccessfullyParsed();
+ testRunner.notifyDone();
+ }
+ touchEventCount++;
+}
+
+function runTest() {
+ if (window.eventSender) {
+ eventSender.clearTouchPoints();
+ // Touch the center of iframe1. 50px is offset to iframe1 in main frame,
+ // 1px for the iframe border, 50px to get to centre.
+ debug('First touch is on iframe1.');
+ shouldBeEqualToString('document.elementFromPoint(101, 101).id', 'iframe1');
+ eventSender.addTouchPoint(101, 101);
+ eventSender.touchStart();
+ debug('');
+
+ debug('Second touch is on iframe2, nothing should happen.');
+ shouldBeEqualToString('document.elementFromPoint(251, 101).id', 'iframe2');
+ eventSender.addTouchPoint(251, 101);
+ eventSender.touchStart();
+ debug('');
+
+ debug('Moves the first touch outside iframe1.');
+ eventSender.updateTouchPoint(0, 201, 201);
+ eventSender.touchMove();
+ debug('');
+
+ debug('Release the first touch.');
+ eventSender.releaseTouchPoint(0);
+ eventSender.touchEnd();
+ debug('');
+
+ debug('Third touch is on iframe2, nothing should happen.');
+ shouldBeEqualToString('document.elementFromPoint(261, 101).id', 'iframe2');
+ eventSender.addTouchPoint(261, 101);
+ eventSender.touchStart();
+ debug('');
+
+ debug('Release all touches on iframe2, and touch iframe2 again.');
+ eventSender.releaseTouchPoint(0);
+ eventSender.releaseTouchPoint(1);
+ eventSender.touchEnd();
+ eventSender.addTouchPoint(251, 101);
+ eventSender.touchStart();
+ debug('');
+
+ debug('Touch iframe1, nothing shoud happen.');
+ eventSender.addTouchPoint(101, 101);
+ eventSender.touchStart();
+ debug('');
+
+ debug('Release all touches.');
+ eventSender.releaseTouchPoint(0);
+ eventSender.releaseTouchPoint(1);
+ eventSender.touchEnd();
+ } else {
+ debug('This test requires DRT.');
+ }
+}
+
+if (window.testRunner) {
+ testRunner.waitUntilDone();
+}
+
+function getTitle() {
+ title++;
+ return 'iframe' + title;
+}
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/touch/multi-touch-inside-nested-iframes-expected.txt (0 => 137220)
--- trunk/LayoutTests/fast/events/touch/multi-touch-inside-nested-iframes-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/events/touch/multi-touch-inside-nested-iframes-expected.txt 2012-12-11 00:08:09 UTC (rev 137220)
@@ -0,0 +1,78 @@
+
+Test multi-touch is sent to the same iframe.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+First touch is on inner iframe.
+PASS ev.type is "touchstart"
+PASS touchreceiver is "iframe1"
+PASS ev.changedTouches.length is 1
+PASS ev.touches.length is 1
+PASS ev.targetTouches.length is 1
+PASS ev.touches[0].pageX is 50
+PASS ev.touches[0].pageY is 50
+PASS ev.touches[0].target.ownerDocument.title is "iframe1"
+PASS ev.changedTouches[0].target.ownerDocument.title is "iframe1"
+PASS ev.targetTouches[0].target.ownerDocument.title is "iframe1"
+
+Second touch is on outer iframe, nothing should happen.
+
+Moves the first touch outside inner iframe.
+PASS ev.type is "touchmove"
+PASS touchreceiver is "iframe1"
+PASS ev.changedTouches.length is 1
+PASS ev.touches.length is 1
+PASS ev.targetTouches.length is 1
+PASS ev.touches[0].pageX is 200
+PASS ev.touches[0].pageY is 200
+PASS ev.touches[0].target.ownerDocument.title is "iframe1"
+PASS ev.changedTouches[0].target.ownerDocument.title is "iframe1"
+PASS ev.targetTouches[0].target.ownerDocument.title is "iframe1"
+
+Release the first touch.
+PASS ev.type is "touchend"
+PASS touchreceiver is "iframe1"
+PASS ev.changedTouches.length is 1
+PASS ev.touches.length is 0
+PASS ev.targetTouches.length is 0
+PASS ev.changedTouches[0].target.ownerDocument.title is "iframe1"
+
+Third touch is on outer iframe, nothing should happen.
+
+Release all touches on outer iframe, and touch outer iframe again.
+PASS ev.type is "touchstart"
+PASS touchreceiver is "iframe2"
+PASS ev.changedTouches.length is 1
+PASS ev.touches.length is 1
+PASS ev.targetTouches.length is 1
+PASS ev.touches[0].pageX is 30
+PASS ev.touches[0].pageY is 30
+PASS ev.touches[0].target.ownerDocument.title is "iframe2"
+PASS ev.changedTouches[0].target.ownerDocument.title is "iframe2"
+PASS ev.targetTouches[0].target.ownerDocument.title is "iframe2"
+
+Touch inner iframe, this will trigger onTouch as it is inside outer iframe.
+PASS ev.type is "touchstart"
+PASS touchreceiver is "iframe2"
+PASS ev.changedTouches.length is 1
+PASS ev.touches.length is 2
+PASS ev.targetTouches.length is 1
+PASS ev.touches[0].pageX is 30
+PASS ev.touches[0].pageY is 30
+PASS ev.touches[0].target.ownerDocument.title is "iframe2"
+PASS ev.changedTouches[0].target.ownerDocument.title is "iframe2"
+PASS ev.targetTouches[0].target.ownerDocument.title is "iframe2"
+
+Release all touches.
+PASS ev.type is "touchend"
+PASS touchreceiver is "iframe2"
+PASS ev.changedTouches.length is 2
+PASS ev.touches.length is 0
+PASS ev.targetTouches.length is 0
+PASS ev.changedTouches[0].target.ownerDocument.title is "iframe2"
+PASS ev.changedTouches[1].target.ownerDocument.title is "iframe2"
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
Added: trunk/LayoutTests/fast/events/touch/multi-touch-inside-nested-iframes.html (0 => 137220)
--- trunk/LayoutTests/fast/events/touch/multi-touch-inside-nested-iframes.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/multi-touch-inside-nested-iframes.html 2012-12-11 00:08:09 UTC (rev 137220)
@@ -0,0 +1,172 @@
+<html>
+<script src=""
+<style>
+#iframe1 {
+ width: 200px;
+ height: 200px;
+ margin: 0;
+ padding: 0;
+ border: 1px solid black;
+ position:absolute;
+ left:50px;
+ top:50px;
+ background: red;
+}
+
+#output
+{
+position:absolute;
+top:250px;
+}
+
+</style>
+<body _onload_="runTest()">
+<iframe id="iframe1" src=""
+<div id="output">
+<p id="description"></p>
+<div id="console"></div>
+</div>
+<script type="text/_javascript_">
+description('Test multi-touch is sent to the same iframe.');
+
+var touchEventCount = 0;
+var title = 0;
+
+function onTouch(event, receiver)
+{
+ ev = event;
+ touchreceiver = receiver;
+ switch (touchEventCount) {
+ case 0:
+ shouldBeEqualToString('ev.type', 'touchstart');
+ shouldBeEqualToString('touchreceiver', 'iframe1');
+ shouldBe("ev.changedTouches.length", "1");
+ shouldBe("ev.touches.length", "1");
+ shouldBe("ev.targetTouches.length", "1");
+ shouldBe("ev.touches[0].pageX", "50");
+ shouldBe("ev.touches[0].pageY", "50");
+ shouldBeEqualToString('ev.touches[0].target.ownerDocument.title', 'iframe1');
+ shouldBeEqualToString('ev.changedTouches[0].target.ownerDocument.title', 'iframe1');
+ shouldBeEqualToString('ev.targetTouches[0].target.ownerDocument.title', 'iframe1');
+ break;
+ case 1:
+ shouldBeEqualToString('ev.type', 'touchmove');
+ shouldBeEqualToString('touchreceiver', 'iframe1');
+ shouldBe("ev.changedTouches.length", "1");
+ shouldBe("ev.touches.length", "1");
+ shouldBe("ev.targetTouches.length", "1");
+ shouldBe("ev.touches[0].pageX", "200");
+ shouldBe("ev.touches[0].pageY", "200");
+ shouldBeEqualToString('ev.touches[0].target.ownerDocument.title', 'iframe1');
+ shouldBeEqualToString('ev.changedTouches[0].target.ownerDocument.title', 'iframe1');
+ shouldBeEqualToString('ev.targetTouches[0].target.ownerDocument.title', 'iframe1');
+ break;
+ case 2:
+ shouldBeEqualToString('ev.type', 'touchend');
+ shouldBeEqualToString('touchreceiver', 'iframe1');
+ shouldBe("ev.changedTouches.length", "1");
+ shouldBe("ev.touches.length", "0");
+ shouldBe("ev.targetTouches.length", "0");
+ shouldBeEqualToString('ev.changedTouches[0].target.ownerDocument.title', 'iframe1');
+ break;
+ case 3:
+ shouldBeEqualToString('ev.type', 'touchstart');
+ shouldBeEqualToString('touchreceiver', 'iframe2');
+ shouldBe("ev.changedTouches.length", "1");
+ shouldBe("ev.touches.length", "1");
+ shouldBe("ev.targetTouches.length", "1");
+ shouldBe("ev.touches[0].pageX", "30");
+ shouldBe("ev.touches[0].pageY", "30");
+ shouldBeEqualToString('ev.touches[0].target.ownerDocument.title', 'iframe2');
+ shouldBeEqualToString('ev.changedTouches[0].target.ownerDocument.title', 'iframe2');
+ shouldBeEqualToString('ev.targetTouches[0].target.ownerDocument.title', 'iframe2');
+ break;
+ case 4:
+ shouldBeEqualToString('ev.type', 'touchstart');
+ shouldBeEqualToString('touchreceiver', 'iframe2');
+ shouldBe("ev.changedTouches.length", "1");
+ shouldBe("ev.touches.length", "2");
+ shouldBe("ev.targetTouches.length", "1");
+ shouldBe("ev.touches[0].pageX", "30");
+ shouldBe("ev.touches[0].pageY", "30");
+ shouldBeEqualToString('ev.touches[0].target.ownerDocument.title', 'iframe2');
+ shouldBeEqualToString('ev.changedTouches[0].target.ownerDocument.title', 'iframe2');
+ shouldBeEqualToString('ev.targetTouches[0].target.ownerDocument.title', 'iframe2');
+ break;
+ case 5:
+ shouldBeEqualToString('ev.type', 'touchend');
+ shouldBeEqualToString('touchreceiver', 'iframe2');
+ shouldBe("ev.changedTouches.length", "2");
+ shouldBe("ev.touches.length", "0");
+ shouldBe("ev.targetTouches.length", "0");
+ shouldBeEqualToString('ev.changedTouches[0].target.ownerDocument.title', 'iframe2');
+ shouldBeEqualToString('ev.changedTouches[1].target.ownerDocument.title', 'iframe2');
+ isSuccessfullyParsed();
+ testRunner.notifyDone();
+ }
+ touchEventCount++;
+}
+
+function runTest() {
+ if (window.eventSender) {
+ eventSender.clearTouchPoints();
+ // Touch the center of innter iframe. 50px is offset to outer iframe in main frame,
+ // 2px for the iframe borders, 100px to get to centre.
+ debug('First touch is on inner iframe.');
+ eventSender.addTouchPoint(152, 152);
+ eventSender.touchStart();
+ debug('');
+
+ debug('Second touch is on outer iframe, nothing should happen.');
+ eventSender.addTouchPoint(71, 71);
+ eventSender.touchStart();
+ debug('');
+
+ debug('Moves the first touch outside inner iframe.');
+ eventSender.updateTouchPoint(0, 302, 302);
+ eventSender.touchMove();
+ debug('');
+
+ debug('Release the first touch.');
+ eventSender.releaseTouchPoint(0);
+ eventSender.touchEnd();
+ debug('');
+
+ debug('Third touch is on outer iframe, nothing should happen.');
+ eventSender.addTouchPoint(81, 81);
+ eventSender.touchStart();
+ debug('');
+
+ debug('Release all touches on outer iframe, and touch outer iframe again.');
+ eventSender.releaseTouchPoint(0);
+ eventSender.releaseTouchPoint(1);
+ eventSender.touchEnd();
+ eventSender.addTouchPoint(81, 81);
+ eventSender.touchStart();
+ debug('');
+
+ debug('Touch inner iframe, this will trigger onTouch as it is inside outer iframe.');
+ eventSender.addTouchPoint(152, 152);
+ eventSender.touchStart();
+ debug('');
+
+ debug('Release all touches.');
+ eventSender.releaseTouchPoint(0);
+ eventSender.releaseTouchPoint(1);
+ eventSender.touchEnd();
+ } else {
+ debug('This test requires DRT.');
+ }
+}
+
+if (window.testRunner) {
+ testRunner.waitUntilDone();
+}
+
+function getTitle() {
+ title++;
+ return 'iframe' + title;
+}
+</script>
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/touch/resources/multi-touch-inside-iframes2.html (0 => 137220)
--- trunk/LayoutTests/fast/events/touch/resources/multi-touch-inside-iframes2.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/resources/multi-touch-inside-iframes2.html 2012-12-11 00:08:09 UTC (rev 137220)
@@ -0,0 +1,11 @@
+<html>
+<head>
+<script type='text/_javascript_'>
+document.addEventListener("touchstart", function() { parent.onTouch(event, document.title); }, false);
+document.addEventListener("touchend", function() { parent.onTouch(event, document.title); }, false);
+document.addEventListener("touchmove", function() { parent.onTouch(event, document.title); }, false);
+</script>
+</head>
+<body _onload_="document.title=parent.getTitle()">
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/touch/resources/multi-touch-inside-nested-iframes2.html (0 => 137220)
--- trunk/LayoutTests/fast/events/touch/resources/multi-touch-inside-nested-iframes2.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/resources/multi-touch-inside-nested-iframes2.html 2012-12-11 00:08:09 UTC (rev 137220)
@@ -0,0 +1,26 @@
+<html>
+<html>
+<style>
+iframe {
+ width: 100px;
+ height: 100px;
+ margin: 0;
+ padding: 0;
+ border: 1px solid black;
+ position:absolute;
+ left:50px;
+ top:50px;
+ background: blue;
+}
+</style>
+<head>
+<script type='text/_javascript_'>
+document.addEventListener("touchstart", function() { parent.onTouch(event, document.title); }, false);
+document.addEventListener("touchend", function() { parent.onTouch(event, document.title); }, false);
+document.addEventListener("touchmove", function() { parent.onTouch(event, document.title); }, false);
+</script>
+</head>
+<body _onload_="document.title=parent.getTitle()">
+<iframe id="iframe2" src=""
+</body>
+</html>
Added: trunk/LayoutTests/fast/events/touch/resources/multi-touch-inside-nested-iframes3.html (0 => 137220)
--- trunk/LayoutTests/fast/events/touch/resources/multi-touch-inside-nested-iframes3.html (rev 0)
+++ trunk/LayoutTests/fast/events/touch/resources/multi-touch-inside-nested-iframes3.html 2012-12-11 00:08:09 UTC (rev 137220)
@@ -0,0 +1,11 @@
+<html>
+<head>
+<script type='text/_javascript_'>
+document.addEventListener("touchstart", function() { top.onTouch(event, document.title); }, false);
+document.addEventListener("touchend", function() { top.onTouch(event, document.title); }, false);
+document.addEventListener("touchmove", function() { top.onTouch(event, document.title); }, false);
+</script>
+</head>
+<body _onload_="document.title=top.getTitle()">
+</body>
+</html>
Modified: trunk/Source/WebCore/ChangeLog (137219 => 137220)
--- trunk/Source/WebCore/ChangeLog 2012-12-10 23:56:02 UTC (rev 137219)
+++ trunk/Source/WebCore/ChangeLog 2012-12-11 00:08:09 UTC (rev 137220)
@@ -1,3 +1,21 @@
+2012-12-10 Min Qin <[email protected]>
+
+ Sending multi-touch events to the same Iframe
+ https://bugs.webkit.org/show_bug.cgi?id=97973
+
+ Reviewed by Dimitri Glazkov.
+
+ Multi-Touch in different iframe can give both documents access to each other.
+ This could cause cross-origin access. To solve this, all the touch events should
+ be sent to the iframe where the first touchstart happens.
+
+ Test: fast/events/touch/multi-touch-inside-iframes.html
+ fast/events/touch/multi-touch-inside-nested-iframes.html
+
+ * page/EventHandler.cpp:
+ (WebCore::EventHandler::handleTouchEvent):
+ * page/EventHandler.h:
+
2012-12-10 KyungTae Kim <[email protected]>
[soup] Fix build warning in ResourceHandleSoup.cpp
Modified: trunk/Source/WebCore/page/EventHandler.cpp (137219 => 137220)
--- trunk/Source/WebCore/page/EventHandler.cpp 2012-12-10 23:56:02 UTC (rev 137219)
+++ trunk/Source/WebCore/page/EventHandler.cpp 2012-12-11 00:08:09 UTC (rev 137220)
@@ -355,6 +355,7 @@
, m_activationEventNumber(-1)
#endif
#if ENABLE(TOUCH_EVENTS)
+ , m_originatingTouchPointTargetKey(0)
, m_touchPressed(false)
#endif
, m_maxMouseMovedDuration(0)
@@ -407,6 +408,8 @@
m_previousWheelScrolledNode = 0;
#if ENABLE(TOUCH_EVENTS)
m_originatingTouchPointTargets.clear();
+ m_originatingTouchPointDocument.clear();
+ m_originatingTouchPointTargetKey = 0;
#endif
#if ENABLE(GESTURE_EVENTS)
m_scrollGestureHandlingNode = 0;
@@ -3814,6 +3817,22 @@
}
}
+HitTestResult EventHandler::hitTestResultInFrame(Frame* frame, const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType)
+{
+ HitTestResult result(point);
+
+ if (!frame || !frame->contentRenderer())
+ return result;
+ if (frame->view()) {
+ IntRect rect = frame->view()->visibleContentRect();
+ if (!rect.contains(roundedIntPoint(point)))
+ return result;
+ }
+ frame->contentRenderer()->hitTest(HitTestRequest(hitType), result);
+ result.setToNonShadowAncestor();
+ return result;
+}
+
bool EventHandler::handleTouchEvent(const PlatformTouchEvent& event)
{
// First build up the lists to use for the 'touches', 'targetTouches' and 'changedTouches' attributes
@@ -3841,8 +3860,19 @@
UserGestureIndicator gestureIndicator(DefinitelyProcessingUserGesture);
- for (unsigned i = 0; i < points.size(); ++i) {
+ unsigned i;
+ bool freshTouchEvents = true;
+ bool allTouchReleased = true;
+ for (i = 0; i < points.size(); ++i) {
const PlatformTouchPoint& point = points[i];
+ if (point.state() != PlatformTouchPoint::TouchPressed)
+ freshTouchEvents = false;
+ if (point.state() != PlatformTouchPoint::TouchReleased && point.state() != PlatformTouchPoint::TouchCancelled)
+ allTouchReleased = false;
+ }
+
+ for (i = 0; i < points.size(); ++i) {
+ const PlatformTouchPoint& point = points[i];
PlatformTouchPoint::State pointState = point.state();
LayoutPoint pagePoint = documentPointForWindowPoint(m_frame, point.pos());
@@ -3880,7 +3910,17 @@
unsigned touchPointTargetKey = point.id() + 1;
RefPtr<EventTarget> touchTarget;
if (pointState == PlatformTouchPoint::TouchPressed) {
- HitTestResult result = hitTestResultAtPoint(pagePoint, /*allowShadowContent*/ false, false, DontHitTestScrollbars, hitType);
+ HitTestResult result;
+ if (freshTouchEvents) {
+ result = hitTestResultAtPoint(pagePoint, /*allowShadowContent*/ false, false, DontHitTestScrollbars, hitType);
+ m_originatingTouchPointTargetKey = touchPointTargetKey;
+ } else if (m_originatingTouchPointDocument.get() && m_originatingTouchPointDocument->frame()) {
+ LayoutPoint pagePointInOriginatingDocument = documentPointForWindowPoint(m_originatingTouchPointDocument->frame(), point.pos());
+ result = hitTestResultInFrame(m_originatingTouchPointDocument->frame(), pagePointInOriginatingDocument, hitType);
+ if (!result.innerNode())
+ continue;
+ } else
+ continue;
Node* node = result.innerNode();
ASSERT(node);
@@ -3892,16 +3932,26 @@
return true;
Document* doc = node->document();
+ // Record the originating touch document even if it does not have a touch listener.
+ if (freshTouchEvents) {
+ m_originatingTouchPointDocument = doc;
+ freshTouchEvents = false;
+ }
if (!doc)
continue;
if (!doc->touchEventHandlerCount())
continue;
-
m_originatingTouchPointTargets.set(touchPointTargetKey, node);
touchTarget = node;
} else if (pointState == PlatformTouchPoint::TouchReleased || pointState == PlatformTouchPoint::TouchCancelled) {
// We only perform a hittest on release or cancel to unset :active or :hover state.
- hitTestResultAtPoint(pagePoint, /*allowShadowContent*/ false, false, DontHitTestScrollbars, hitType);
+ if (touchPointTargetKey == m_originatingTouchPointTargetKey) {
+ hitTestResultAtPoint(pagePoint, /*allowShadowContent*/ false, false, DontHitTestScrollbars, hitType);
+ m_originatingTouchPointTargetKey = 0;
+ } else if (m_originatingTouchPointDocument.get() && m_originatingTouchPointDocument->frame()) {
+ LayoutPoint pagePointInOriginatingDocument = documentPointForWindowPoint(m_originatingTouchPointDocument->frame(), point.pos());
+ hitTestResultInFrame(m_originatingTouchPointDocument->frame(), pagePointInOriginatingDocument, hitType);
+ }
// The target should be the original target for this touch, so get it from the hashmap. As it's a release or cancel
// we also remove it from the map.
touchTarget = m_originatingTouchPointTargets.take(touchPointTargetKey);
@@ -3962,6 +4012,8 @@
}
}
m_touchPressed = touches->length() > 0;
+ if (allTouchReleased)
+ m_originatingTouchPointDocument.clear();
// Now iterate the changedTouches list and m_targets within it, sending events to the targets as required.
bool swallowedEvent = false;
Modified: trunk/Source/WebCore/page/EventHandler.h (137219 => 137220)
--- trunk/Source/WebCore/page/EventHandler.h 2012-12-10 23:56:02 UTC (rev 137219)
+++ trunk/Source/WebCore/page/EventHandler.h 2012-12-11 00:08:09 UTC (rev 137220)
@@ -294,6 +294,7 @@
#if ENABLE(TOUCH_EVENTS)
bool dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent&);
+ HitTestResult hitTestResultInFrame(Frame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active);
#endif
void invalidateClick();
@@ -462,6 +463,8 @@
#if ENABLE(TOUCH_EVENTS)
typedef HashMap<int, RefPtr<EventTarget> > TouchTargetMap;
TouchTargetMap m_originatingTouchPointTargets;
+ RefPtr<Document> m_originatingTouchPointDocument;
+ unsigned m_originatingTouchPointTargetKey;
bool m_touchPressed;
#endif