Do touch adjustment on GestureTapDown
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 19 Sep 2012 14:08:21 +0000 (14:08 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 19 Sep 2012 14:08:21 +0000 (14:08 +0000)
https://bugs.webkit.org/show_bug.cgi?id=96677

Patch by Rick Byers <rbyers@chromium.org> on 2012-09-19
Reviewed by Antonio Gomes.

Source/WebCore:

Do touch adjustment on GestureTapDown exactly as for GestureTap today.

Test: touchadjustment/touch-links-active.html

* page/EventHandler.cpp:
(WebCore::EventHandler::handleGestureEvent):
(WebCore::EventHandler::adjustGesturePosition):

Tools:

Allow radius to be set for GestureTapDown events.
* DumpRenderTree/chromium/TestRunner/EventSender.cpp:
(EventSender::gestureEvent):

LayoutTests:

Make a few tweaks to the touchadjustment.js infrastructure to make it
simpler and easier to use.  Add a test for touch-adjustment of
GestureTapDown events (based on touch-links-longpress).

* touchadjustment/resources/touchadjustment.js:
(touchPoint.return.left.x.radiusX.top.y.radiusY.width.radiusX.2.height.radiusY.2.get x):
(touchPoint.return.get y):
(touchPoint):
(offsetTouchPoint):
* touchadjustment/touch-links-active-expected.txt: Added.
* touchadjustment/touch-links-active.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@128999 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/platform/qt/Skipped
LayoutTests/touchadjustment/resources/touchadjustment.js
LayoutTests/touchadjustment/touch-links-active-expected.txt [new file with mode: 0644]
LayoutTests/touchadjustment/touch-links-active.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/page/EventHandler.cpp
Tools/ChangeLog
Tools/DumpRenderTree/chromium/TestRunner/EventSender.cpp

index f718657..6f3beb1 100644 (file)
@@ -1,3 +1,22 @@
+2012-09-19  Rick Byers  <rbyers@chromium.org>
+
+        Do touch adjustment on GestureTapDown
+        https://bugs.webkit.org/show_bug.cgi?id=96677
+
+        Reviewed by Antonio Gomes.
+
+        Make a few tweaks to the touchadjustment.js infrastructure to make it
+        simpler and easier to use.  Add a test for touch-adjustment of
+        GestureTapDown events (based on touch-links-longpress).
+
+        * touchadjustment/resources/touchadjustment.js:
+        (touchPoint.return.left.x.radiusX.top.y.radiusY.width.radiusX.2.height.radiusY.2.get x):
+        (touchPoint.return.get y):
+        (touchPoint):
+        (offsetTouchPoint):
+        * touchadjustment/touch-links-active-expected.txt: Added.
+        * touchadjustment/touch-links-active.html: Added.
+
 2012-09-19  Christophe Dumez  <christophe.dumez@intel.com>
 
         [EFL] Skip fast/dom/message-port-deleted-by-accessor.html
index 8615e80..98c8755 100644 (file)
@@ -425,6 +425,10 @@ fast/mutation/transient-gc-crash.html
 # https://bugs.webkit.org/show_bug.cgi?id=87088
 fast/js/names.html
 
+# Don't have GestureLongPress, GestureTapCancel event types
+touchadjustment/touch-links-longpress.html
+touchadjustment/touch-links-active.html
+
 # =========================================================================== #
 #       Feature not yet supported.                                            #
 # =========================================================================== #
@@ -2738,9 +2742,6 @@ css3/flexbox/flex-rounding.html
 # ENABLE(WIDGET_REGION) is disabled
 fast/css/widget-region-parser.html
 
-# https://bugs.webkit.org/show_bug.cgi?id=92914
-touchadjustment/touch-links-longpress.html
-
 # [Qt][GTK] REGRESSION(r125251): It made svg/custom/use-instanceRoot-as-event-target.xhtml assert and flakey
 # https://bugs.webkit.org/show_bug.cgi?id=93812
 svg/custom/use-instanceRoot-as-event-target.xhtml
index f9b7d9d..2f41f63 100644 (file)
@@ -96,12 +96,15 @@ function touchPoint(x, y, radiusX, radiusY)
 {
     if (!radiusY)
         radiusY = radiusX;
-    var touchpoint = new Object();
-    touchpoint.left = x - radiusX;
-    touchpoint.top = y - radiusY;
-    touchpoint.width = radiusX * 2;
-    touchpoint.height = radiusY * 2;
-    return touchpoint;
+
+    return {
+        left: x - radiusX,
+        top: y - radiusY,
+        width: radiusX * 2,
+        height: radiusY * 2,
+        get x() { return this.left + this.width/2; },
+        get y() { return this.top + this.height/2; }
+    };
 }
 
 function offsetTouchPoint(bounds, relativePosition, touchOffset, touchRadiusX, touchRadiusY)
@@ -109,9 +112,10 @@ function offsetTouchPoint(bounds, relativePosition, touchOffset, touchRadiusX, t
     if (!touchRadiusY)
         touchRadiusY = touchRadiusX;
 
-    var touchpoint = {left : bounds.left, top: bounds.top };
+    // Start with the center of the touch at the top-left of the bounds.
+    var touchpoint = touchPoint(bounds.left, bounds.top, touchRadiusX, touchRadiusY);
  
-    // Set center point for touch.
+    // Adjust the touch point as requested.
     switch (relativePosition) {
     case 'center':
         touchpoint.left += bounds.width / 2;
@@ -149,12 +153,6 @@ function offsetTouchPoint(bounds, relativePosition, touchOffset, touchRadiusX, t
         touchpoint.left += bounds.width / 2;
         touchpoint.top += bounds.height + touchOffset;
     }
-    // Adjust from touch center to top-left corner.
-    touchpoint.left -= touchRadiusX;
-    touchpoint.top -= touchRadiusY;
-
-    touchpoint.width = 2 * touchRadiusX;
-    touchpoint.height = 2 * touchRadiusY;
 
     return touchpoint;
 }
diff --git a/LayoutTests/touchadjustment/touch-links-active-expected.txt b/LayoutTests/touchadjustment/touch-links-active-expected.txt
new file mode 100644 (file)
index 0000000..dd4fed2
--- /dev/null
@@ -0,0 +1,17 @@
+Tests that tapDown will trigger the active state.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Testing indirect hits.
+PASS isLinkActive() is true
+PASS isLinkActive() is true
+PASS isLinkActive() is true
+Testing direct hits.
+PASS isLinkActive() is true
+PASS isLinkActive() is true
+PASS isLinkActive() is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/touchadjustment/touch-links-active.html b/LayoutTests/touchadjustment/touch-links-active.html
new file mode 100644 (file)
index 0000000..f43d641
--- /dev/null
@@ -0,0 +1,144 @@
+<!DOCTYPE html>
+<html>
+<head>
+    <title>Touch Adjustment : Testing that active will be set on a tapDown - bug 96677</title>
+    <script src="../fast/js/resources/js-test-pre.js"></script>
+    <script src="resources/touchadjustment.js"></script>
+    <style>
+        #sandbox {
+            position: absolute;
+            left: 0px;
+            top: 100px;
+        }
+        a {
+            background-color: rgb(255,255,255);
+        }
+        a:active {
+            background-color: rgb(0,0,255);
+        }        
+    </style>
+</head>
+
+<body>
+
+<div id="sandbox">
+<p><a href="" id="link1">I</a> propose to consider <a href="" id="link2">the question</a>, "Can machines think?"<br>This should begin with definitions of the meaning of the terms "machine" and <a href="" id="link3">"think."</a></p>
+</div>
+
+<p id='description'></p>
+<div id='console'></div>
+
+<script>
+    var element;
+    var adjustedNode;
+    // Set up shortcut access to elements
+    var e = {};
+    ['sandbox', 'link1', 'link2', 'link3'].forEach(function(a) {
+        e[a] = document.getElementById(a);
+    });
+    
+    var curElement;
+    
+    function isLinkActive()
+    {
+        // These need to match the background-color used above, after round-tripping.
+        var defaultColor = "rgb(255, 255, 255)";
+        var activeColor = "rgb(0, 0, 255)";
+    
+        color = window.getComputedStyle(curElement).backgroundColor;
+        if (color == activeColor)
+            return true;
+        if (color != defaultColor)
+            testFailed('Got unexpected backgroundColor: ' + color);
+        return false;
+    }
+    
+    function testTapDown(touchpoint, element)
+    {
+        curElement = element;
+        if (isLinkActive()) testFailed('Link unexpectedly active on entry');
+        eventSender.gestureTapDown(touchpoint.x, touchpoint.y, touchpoint.width, touchpoint.height);
+        shouldBeTrue("isLinkActive()");
+        eventSender.gestureTapCancel(touchpoint.x, touchpoint.y);
+        if (isLinkActive()) testFailed('Link unexpectedly active on exit');
+    }
+
+    // FIXME: Why doesn't the approach in findAbsoluteBounds work correctly here?
+    // I'll investigate/fix along with http://wkb.ug/96810
+    function getBounds(node)
+    {
+      var bounds = node.getBoundingClientRect();
+      return {
+          left: bounds.left,
+          top: bounds.top,
+          width: bounds.right - bounds.left,
+          height: bounds.bottom - bounds.top
+      };    
+    }
+    
+    function testDirectTouch(element)
+    {
+        // Touch directly in the center of the element.
+        var touchpoint = offsetTouchPoint(getBounds(element), 'center', 0, 20, 30);
+        if (document.elementFromPoint(touchpoint.x, touchpoint.y) != element)
+            testFailed('Direct touch ended up on some other element');
+        testTapDown(touchpoint, element);
+    }
+
+    function isDescendantOf(parent, child)
+    {
+        var n = child;
+        while(n) {
+            if(n==parent)
+                return true;
+            n = n.parentNode;
+        }
+        return false;
+    }
+    
+    function testIndirectTouch(element)
+    {
+        // Touch just right of the element.
+        var touchpoint = offsetTouchPoint(getBounds(element), 'right', 10, 30, 20);
+        if (isDescendantOf(element, document.elementFromPoint(touchpoint.x, touchpoint.y)))
+            testFailed('Indirect touch ended up still on top of the element');
+        testTapDown(touchpoint, element);
+    }
+
+    function testDirectTouches()
+    {
+        debug('Testing direct hits.');
+        testDirectTouch(e.link1);
+        testDirectTouch(e.link2);
+        testDirectTouch(e.link3);
+    }
+
+    function testIndirectTouches()
+    {
+        debug('Testing indirect hits.');
+        testIndirectTouch(e.link1);
+        testIndirectTouch(e.link2);
+        testIndirectTouch(e.link3);
+    }
+
+    function runTests()
+    {
+        if (!window.eventSender) {
+            debug('This test requires DumpRenderTree');
+            return;
+        }
+        if (!window.eventSender.gestureTapDown) {
+            debug('GestureTapDown not supported by this platform');
+            return;
+        } 
+          
+        description('Tests that tapDown will trigger the active state.');
+        testIndirectTouches();
+        testDirectTouches();
+        e.sandbox.style.display = 'none';
+    }
+    runTests();
+</script>
+<script src="../fast/js/resources/js-test-post.js"></script>
+</body>
+</html>
index 5ae671c..df98d84 100644 (file)
@@ -1,3 +1,18 @@
+2012-09-19  Rick Byers  <rbyers@chromium.org>
+
+        Do touch adjustment on GestureTapDown
+        https://bugs.webkit.org/show_bug.cgi?id=96677
+
+        Reviewed by Antonio Gomes.
+
+        Do touch adjustment on GestureTapDown exactly as for GestureTap today.
+
+        Test: touchadjustment/touch-links-active.html
+
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::handleGestureEvent):
+        (WebCore::EventHandler::adjustGesturePosition):
+
 2012-09-19  Vsevolod Vlasov  <vsevik@chromium.org>
 
         Unreviewed another follow up Apple Win build fix for r128992.
index 919f8e4..32d238c 100644 (file)
@@ -2414,10 +2414,15 @@ bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent)
     if (gestureEvent.type() == PlatformEvent::GestureScrollEnd || gestureEvent.type() == PlatformEvent::GestureScrollUpdate)
         eventTarget = m_scrollGestureHandlingNode.get();
 
+    IntPoint adjustedPoint = gestureEvent.position();
     HitTestRequest::HitTestRequestType hitType = HitTestRequest::TouchEvent;
-    if (gestureEvent.type() == PlatformEvent::GestureTapDown)
+    if (gestureEvent.type() == PlatformEvent::GestureTapDown) {
+#if ENABLE(TOUCH_ADJUSTMENT)
+        if (!gestureEvent.area().isEmpty())
+            adjustGesturePosition(gestureEvent, adjustedPoint);
+#endif
         hitType |= HitTestRequest::Active;
-    else if (gestureEvent.type() == PlatformEvent::GestureTap || gestureEvent.type() == PlatformEvent::GestureTapDownCancel)
+    else if (gestureEvent.type() == PlatformEvent::GestureTap || gestureEvent.type() == PlatformEvent::GestureTapDownCancel)
         hitType |= HitTestRequest::Release;
     else
         hitType |= HitTestRequest::Active | HitTestRequest::ReadOnly;
@@ -2426,7 +2431,7 @@ bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent)
         hitType |= HitTestRequest::ReadOnly;
 
     if (!eventTarget || !(hitType & HitTestRequest::ReadOnly)) {
-        IntPoint hitTestPoint = m_frame->view()->windowToContents(gestureEvent.position());
+        IntPoint hitTestPoint = m_frame->view()->windowToContents(adjustedPoint);
         HitTestResult result = hitTestResultAtPoint(hitTestPoint, false, false, DontHitTestScrollbars, hitType);
         eventTarget = result.targetNode();
     }
@@ -2574,6 +2579,7 @@ bool EventHandler::adjustGesturePosition(const PlatformGestureEvent& gestureEven
     Node* targetNode = 0;
     switch (gestureEvent.type()) {
     case PlatformEvent::GestureTap:
+    case PlatformEvent::GestureTapDown:
         bestClickableNodeForTouchPoint(gestureEvent.position(), IntSize(gestureEvent.area().width() / 2, gestureEvent.area().height() / 2), adjustedPoint, targetNode);
         break;
     case PlatformEvent::GestureLongPress:
index 0d3e1e3..c0150d5 100644 (file)
@@ -1,3 +1,14 @@
+2012-09-19  Rick Byers  <rbyers@chromium.org>
+
+        Do touch adjustment on GestureTapDown
+        https://bugs.webkit.org/show_bug.cgi?id=96677
+
+        Reviewed by Antonio Gomes.
+
+        Allow radius to be set for GestureTapDown events.
+        * DumpRenderTree/chromium/TestRunner/EventSender.cpp:
+        (EventSender::gestureEvent):
+
 2012-09-19  Christophe Dumez  <christophe.dumez@intel.com>
 
         [EFL] EFL's DRT does not support overriding 'WebKitCSSRegionsEnabled' preference
index 2360128..23b65d0 100644 (file)
@@ -1188,6 +1188,10 @@ void EventSender::gestureEvent(WebInputEvent::Type type, const CppArgumentList&
     case WebInputEvent::GestureTapDown:
         event.x = point.x;
         event.y = point.y;
+        if (arguments.size() >= 4) {
+            event.data.tapDown.width = static_cast<float>(arguments[2].toDouble());
+            event.data.tapDown.height = static_cast<float>(arguments[3].toDouble());
+        }
         break;
     case WebInputEvent::GestureTapCancel:
         event.x = point.x;