Fix the creation of the touchTargets list to match what the iPhone does and maintain compatability with existing apps like SuperPudu.

touchTargets should always have at least one element and should be based on the target where the touch originated, not where it is now.

This needs to be upstreamed to webkit.

Change-Id: Ie4e6f65e77484e0eac6d0f239df9dd3a460e7bce
diff --git a/WebCore/page/EventHandler.cpp b/WebCore/page/EventHandler.cpp
index 2563149..ad29dc1 100644
--- a/WebCore/page/EventHandler.cpp
+++ b/WebCore/page/EventHandler.cpp
@@ -2567,6 +2567,7 @@
     RefPtr<TouchList> movedTouches = TouchList::create();
     RefPtr<TouchList> targetTouches = TouchList::create();
     RefPtr<TouchList> cancelTouches = TouchList::create();
+    RefPtr<TouchList> stationaryTouches = TouchList::create();
 
     const Vector<PlatformTouchPoint>& points = event.touchPoints();
     AtomicString* eventName = 0;
@@ -2609,6 +2610,17 @@
                                             point.screenPos().x(), point.screenPos().y(),
                                             adjustedPageX, adjustedPageY);
 
+        // touches should contain information about every touch currently on the screen.
+        if (point.state() != PlatformTouchPoint::TouchReleased)
+            touches->append(touch);
+
+        // If it's a stationary touch, we don't want to process it further at the moment.
+        // We may add it to targetTouches later.
+        if (point.state() == PlatformTouchPoint::TouchStationary) {
+            stationaryTouches->append(touch);
+            continue;
+        }
+
         if ((event.type() == TouchStart
 #if PLATFORM(ANDROID)
             || event.type() == TouchDoubleTap
@@ -2620,21 +2632,45 @@
             m_firstTouchPagePos = pagePoint;
         }
 
+        // Check to see if this should be added to targetTouches.
+        // If we've got here then the touch is not stationary. If it's a release, it's no longer
+        // a touch on the screen so we don't want it in targetTouches. The first touch that gets
+        // to here defines the 'target' the touchTarget list uses. This seems arbitrary (much like
+        // checking !i to set m_touchEventTarget above?) but seems to yield compatible behaviour.
+        //
+        // FIXME: Is this really the correct semantics for the touchTargets list? The touch event
+        // spec is not clear to me.
+        if (point.state() != PlatformTouchPoint::TouchReleased) {
+            if (targetTouches->length() == 0)
+                targetTouches->append(touch);
+            else {
+                if (touch->target() == targetTouches->item(0)->target())
+                    targetTouches->append(touch);
+            }
+        }
+
+        // Now build up the correct list for changedTouches.
         if (point.state() == PlatformTouchPoint::TouchReleased)
             releasedTouches->append(touch);
         else if (point.state() == PlatformTouchPoint::TouchCancelled)
             cancelTouches->append(touch);
-        else {
-            if (point.state() == PlatformTouchPoint::TouchPressed)
-                pressedTouches->append(touch);
-            else {
-                touches->append(touch);
-                if (m_touchEventTarget == target)
-                    targetTouches->append(touch);
-                if (point.state() == PlatformTouchPoint::TouchMoved)
-                    movedTouches->append(touch);
-            }
-        }
+        else if (point.state() == PlatformTouchPoint::TouchPressed)
+            pressedTouches->append(touch);
+        else if (point.state() == PlatformTouchPoint::TouchMoved)
+            movedTouches->append(touch);
+    }
+
+    // Add any stationary touches to targetTouches if they match the target.
+    EventTarget* targetTouchesTarget = 0;
+    if (targetTouches->length())
+        targetTouchesTarget = targetTouches->item(0)->target();
+    else
+        targetTouchesTarget = m_touchEventTarget.get();
+
+    for (int i = 0; i < stationaryTouches->length(); ++i) {
+        Touch* stationaryTouch = stationaryTouches->item(i);
+        if (stationaryTouch->target() == targetTouchesTarget)
+            targetTouches->append(stationaryTouch);
     }
 
     if (!m_touchEventTarget)
@@ -2691,13 +2727,6 @@
 #endif
     }
     if (pressedTouches->length() > 0) {
-        // Add pressed touchpoints to touches and targetTouches
-        for (int i = 0; i < pressedTouches->length(); ++i) {
-            touches->append(pressedTouches->item(i));
-            if (m_touchEventTarget == pressedTouches->item(i)->target())
-                targetTouches->append(pressedTouches->item(i));
-        }
-
 #if PLATFORM(ANDROID)
         if (event.type() == TouchLongPress) {
             eventName = &eventNames().touchlongpressEvent;