Bug 884748 - Make nsTouchEvent::touches store Touch instead of nsIDOMTouch; r=dzbarsky
authorMs2ger <ms2ger@gmail.com>
Wed, 10 Jul 2013 11:53:09 +0200
changeset 150018 12acd6ba4220d65cfc53f4f05201a9254ea0bb65
parent 150017 04d8c309fe728f61d5a48122bf5706c6f86da209
child 150019 5f3e6849dfdec49bc41a4c1b59e8187d0e139a32
push id2859
push userakeybl@mozilla.com
push dateMon, 16 Sep 2013 19:14:59 +0000
treeherdermozilla-beta@87d3c51cd2bf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdzbarsky
bugs884748
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 884748 - Make nsTouchEvent::touches store Touch instead of nsIDOMTouch; r=dzbarsky
content/events/src/nsDOMTouchEvent.cpp
content/events/src/nsDOMTouchEvent.h
content/events/src/nsEventStateManager.cpp
gfx/layers/ipc/AsyncPanZoomController.cpp
layout/base/nsIPresShell.h
layout/base/nsPresShell.cpp
widget/nsGUIEvent.h
widget/nsGUIEventIPC.h
--- a/content/events/src/nsDOMTouchEvent.cpp
+++ b/content/events/src/nsDOMTouchEvent.cpp
@@ -10,17 +10,17 @@
 #include "mozilla/Preferences.h"
 #include "nsPresContext.h"
 #include "mozilla/dom/Touch.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 // TouchList
-nsDOMTouchList::nsDOMTouchList(nsTArray<nsCOMPtr<nsIDOMTouch> > &aTouches)
+nsDOMTouchList::nsDOMTouchList(const nsTArray< nsRefPtr<Touch> >& aTouches)
 {
   mPoints.AppendElements(aTouches);
   nsJSContext::LikelyShortLivingObjectCreated();
 }
 
 DOMCI_DATA(TouchList, nsDOMTouchList)
 
 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMTouchList)
@@ -48,21 +48,19 @@ nsDOMTouchList::Item(uint32_t aIndex, ns
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsDOMTouchList::IdentifiedTouch(int32_t aIdentifier, nsIDOMTouch** aRetVal)
 {
   *aRetVal = nullptr;
   for (uint32_t i = 0; i < mPoints.Length(); ++i) {
-    nsCOMPtr<nsIDOMTouch> point = mPoints[i];
-    int32_t identifier;
-    if (point && NS_SUCCEEDED(point->GetIdentifier(&identifier)) &&
-        aIdentifier == identifier) {
-      point.swap(*aRetVal);
+    nsRefPtr<Touch> point = mPoints[i];
+    if (point && point->Identifier() == aIdentifier) {
+      point.forget(aRetVal);
       break;
     }
   }
   return NS_OK;
 }
 
 // TouchEvent
 
@@ -146,18 +144,18 @@ nsDOMTouchEvent::GetTouches(nsIDOMTouchL
 
 nsDOMTouchList*
 nsDOMTouchEvent::Touches()
 {
   if (!mTouches) {
     nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(mEvent);
     if (mEvent->message == NS_TOUCH_END || mEvent->message == NS_TOUCH_CANCEL) {
       // for touchend events, remove any changed touches from the touches array
-      nsTArray<nsCOMPtr<nsIDOMTouch> > unchangedTouches;
-      const nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = touchEvent->touches;
+      nsTArray< nsRefPtr<Touch> > unchangedTouches;
+      const nsTArray< nsRefPtr<Touch> >& touches = touchEvent->touches;
       for (uint32_t i = 0; i < touches.Length(); ++i) {
         if (!touches[i]->mChanged) {
           unchangedTouches.AppendElement(touches[i]);
         }
       }
       mTouches = new nsDOMTouchList(unchangedTouches);
     } else {
       mTouches = new nsDOMTouchList(touchEvent->touches);
@@ -173,26 +171,25 @@ nsDOMTouchEvent::GetTargetTouches(nsIDOM
   NS_ADDREF(*aTargetTouches = TargetTouches());
   return NS_OK;
 }
 
 nsDOMTouchList*
 nsDOMTouchEvent::TargetTouches()
 {
   if (!mTargetTouches) {
-    nsTArray<nsCOMPtr<nsIDOMTouch> > targetTouches;
+    nsTArray< nsRefPtr<Touch> > targetTouches;
     nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(mEvent);
-    const nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = touchEvent->touches;
+    const nsTArray< nsRefPtr<Touch> >& touches = touchEvent->touches;
     for (uint32_t i = 0; i < touches.Length(); ++i) {
       // for touchend/cancel events, don't append to the target list if this is a
       // touch that is ending
       if ((mEvent->message != NS_TOUCH_END &&
            mEvent->message != NS_TOUCH_CANCEL) || !touches[i]->mChanged) {
-        EventTarget* targetPtr = touches[i]->GetTarget();
-        if (targetPtr == mEvent->originalTarget) {
+        if (touches[i]->mTarget == mEvent->originalTarget) {
           targetTouches.AppendElement(touches[i]);
         }
       }
     }
     mTargetTouches = new nsDOMTouchList(targetTouches);
   }
   return mTargetTouches;
 }
@@ -204,19 +201,19 @@ nsDOMTouchEvent::GetChangedTouches(nsIDO
   NS_ADDREF(*aChangedTouches = ChangedTouches());
   return NS_OK;
 }
 
 nsDOMTouchList*
 nsDOMTouchEvent::ChangedTouches()
 {
   if (!mChangedTouches) {
-    nsTArray<nsCOMPtr<nsIDOMTouch> > changedTouches;
+    nsTArray< nsRefPtr<Touch> > changedTouches;
     nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(mEvent);
-    const nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = touchEvent->touches;
+    const nsTArray< nsRefPtr<Touch> >& touches = touchEvent->touches;
     for (uint32_t i = 0; i < touches.Length(); ++i) {
       if (touches[i]->mChanged) {
         changedTouches.AppendElement(touches[i]);
       }
     }
     mChangedTouches = new nsDOMTouchList(changedTouches);
   }
   return mChangedTouches;
--- a/content/events/src/nsDOMTouchEvent.h
+++ b/content/events/src/nsDOMTouchEvent.h
@@ -10,39 +10,41 @@
 #include "nsString.h"
 #include "nsTArray.h"
 #include "mozilla/Attributes.h"
 #include "nsJSEnvironment.h"
 #include "mozilla/dom/TouchEventBinding.h"
 
 class nsDOMTouchList MOZ_FINAL : public nsIDOMTouchList
 {
+  typedef mozilla::dom::Touch Touch;
+
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(nsDOMTouchList)
   NS_DECL_NSIDOMTOUCHLIST
 
   nsDOMTouchList()
   {
     nsJSContext::LikelyShortLivingObjectCreated();
   }
-  nsDOMTouchList(nsTArray<nsCOMPtr<nsIDOMTouch> > &aTouches);
+  nsDOMTouchList(const nsTArray< nsRefPtr<Touch> >& aTouches);
 
-  void Append(nsIDOMTouch* aPoint)
+  void Append(Touch* aPoint)
   {
     mPoints.AppendElement(aPoint);
   }
 
   nsIDOMTouch* GetItemAt(uint32_t aIndex)
   {
     return mPoints.SafeElementAt(aIndex, nullptr);
   }
 
 protected:
-  nsTArray<nsCOMPtr<nsIDOMTouch> > mPoints;
+  nsTArray< nsRefPtr<Touch> > mPoints;
 };
 
 class nsDOMTouchEvent : public nsDOMUIEvent,
                         public nsIDOMTouchEvent
 {
 public:
   nsDOMTouchEvent(mozilla::dom::EventTarget* aOwner,
                   nsPresContext* aPresContext, nsTouchEvent* aEvent);
--- a/content/events/src/nsEventStateManager.cpp
+++ b/content/events/src/nsEventStateManager.cpp
@@ -1548,17 +1548,17 @@ nsEventStateManager::MapEventCoordinates
 {
   if (aEvent->eventStructType != NS_TOUCH_EVENT) {
     aEvent->refPoint = aOffset;
   } else {
     aEvent->refPoint = nsIntPoint();
     nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
     // Then offset all the touch points by that distance, to put them
     // in the space where top-left is 0,0.
-    const nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = touchEvent->touches;
+    const nsTArray< nsRefPtr<Touch> >& touches = touchEvent->touches;
     for (uint32_t i = 0; i < touches.Length(); ++i) {
       nsIDOMTouch* touch = touches[i];
       if (touch) {
         touch->mRefPoint += aOffset;
       }
     }
   }
 }
@@ -1632,17 +1632,17 @@ nsEventStateManager::HandleCrossProcessE
     // This is a touch event with possibly multiple touch points.
     // Each touch point may have its own target.  So iterate through
     // all of them and collect the unique set of targets for event
     // forwarding.
     //
     // This loop is similar to the one used in
     // PresShell::DispatchTouchEvent().
     nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
-    const nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = touchEvent->touches;
+    const nsTArray< nsRefPtr<Touch> >& touches = touchEvent->touches;
     for (uint32_t i = 0; i < touches.Length(); ++i) {
       nsIDOMTouch* touch = touches[i];
       // NB: the |mChanged| check is an optimization, subprocesses can
       // compute this for themselves.  If the touch hasn't changed, we
       // may be able to avoid forwarding the event entirely (which is
       // not free).
       if (!touch || !touch->mChanged) {
         continue;
--- a/gfx/layers/ipc/AsyncPanZoomController.cpp
+++ b/gfx/layers/ipc/AsyncPanZoomController.cpp
@@ -264,17 +264,17 @@ AsyncPanZoomController::ReceiveInputEven
   default:
     status = nsEventStatus_eIgnore;
     break;
   }
 
   switch (aEvent.eventStructType) {
   case NS_TOUCH_EVENT: {
     nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aOutEvent);
-    const nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = touchEvent->touches;
+    const nsTArray< nsRefPtr<dom::Touch> >& touches = touchEvent->touches;
     for (uint32_t i = 0; i < touches.Length(); ++i) {
       nsIDOMTouch* touch = touches[i];
       if (touch) {
         CSSPoint refPoint = WidgetSpaceToCompensatedViewportSpace(
           ScreenPoint::FromUnknownPoint(gfx::Point(
             touch->mRefPoint.x, touch->mRefPoint.y)),
           currentResolution);
         touch->mRefPoint = nsIntPoint(refPoint.x, refPoint.y);
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -31,17 +31,17 @@
 #include "nsCompatibility.h"
 #include "nsFrameManagerBase.h"
 #include "nsRect.h"
 #include "mozFlushType.h"
 #include "nsWeakReference.h"
 #include <stdio.h> // for FILE definition
 #include "nsChangeHint.h"
 #include "nsGUIEvent.h"
-#include "nsInterfaceHashtable.h"
+#include "nsRefPtrHashtable.h"
 #include "nsEventStates.h"
 #include "nsPresArena.h"
 #include "nsIImageLoadingContent.h"
 
 class nsIContent;
 class nsIDocument;
 class nsIFrame;
 class nsPresContext;
@@ -1124,17 +1124,17 @@ public:
   {
     return mIsActive;
   }
 
   // mouse capturing
 
   static CapturingContentInfo gCaptureInfo;
 
-  static nsInterfaceHashtable<nsUint32HashKey, nsIDOMTouch> gCaptureTouchList;
+  static nsRefPtrHashtable<nsUint32HashKey, mozilla::dom::Touch> gCaptureTouchList;
   static bool gPreventMouseEvents;
 
   /**
    * When capturing content is set, it traps all mouse events and retargets
    * them at this content node. If capturing is not allowed
    * (gCaptureInfo.mAllowed is false), then capturing is not set. However, if
    * the CAPTURE_IGNOREALLOWED flag is set, the allowed state is ignored and
    * capturing is set regardless. To disable capture, pass null for the value
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -193,17 +193,17 @@ using namespace mozilla;
 using namespace mozilla::css;
 using namespace mozilla::dom;
 using namespace mozilla::layers;
 
 CapturingContentInfo nsIPresShell::gCaptureInfo =
   { false /* mAllowed */, false /* mPointerLock */, false /* mRetargetToElement */,
     false /* mPreventDrag */, nullptr /* mContent */ };
 nsIContent* nsIPresShell::gKeyDownTarget;
-nsInterfaceHashtable<nsUint32HashKey, nsIDOMTouch> nsIPresShell::gCaptureTouchList;
+nsRefPtrHashtable<nsUint32HashKey, dom::Touch> nsIPresShell::gCaptureTouchList;
 bool nsIPresShell::gPreventMouseEvents = false;
 
 // convert a color value to a string, in the CSS format #RRGGBB
 // *  - initially created for bugs 31816, 20760, 22963
 static void ColorToString(nscolor aColor, nsAutoString &aString);
 
 // RangePaintInfo is used to paint ranges to offscreen buffers
 struct RangePaintInfo {
@@ -5857,21 +5857,21 @@ PresShell::RecordMouseLocation(nsGUIEven
            this, aEvent->widget);
     printf("[ps=%p]clearing mouse location\n",
            this);
 #endif
   }
 }
 
 static void
-EvictTouchPoint(nsCOMPtr<nsIDOMTouch>& aTouch)
+EvictTouchPoint(nsRefPtr<dom::Touch>& aTouch)
 {
   nsIWidget *widget = nullptr;
   // is there an easier/better way to dig out the widget?
-  nsCOMPtr<nsINode> node(do_QueryInterface(aTouch->GetTarget()));
+  nsCOMPtr<nsINode> node(do_QueryInterface(aTouch->mTarget));
   if (!node) {
     return;
   }
   nsIDocument* doc = node->GetCurrentDoc();
   if (!doc) {
     return;
   }
   nsIPresShell *presShell = doc->GetShell();
@@ -5894,31 +5894,31 @@ EvictTouchPoint(nsCOMPtr<nsIDOMTouch>& a
   event.time = PR_IntervalNow();
   event.touches.AppendElement(aTouch);
 
   nsEventStatus status;
   widget->DispatchEvent(&event, status);
 }
 
 static PLDHashOperator
-AppendToTouchList(const uint32_t& aKey, nsCOMPtr<nsIDOMTouch>& aData, void *aTouchList)
-{
-  nsTArray<nsCOMPtr<nsIDOMTouch> > *touches = static_cast<nsTArray<nsCOMPtr<nsIDOMTouch> > *>(aTouchList);
+AppendToTouchList(const uint32_t& aKey, nsRefPtr<dom::Touch>& aData, void *aTouchList)
+{
+  nsTArray< nsRefPtr<dom::Touch> >* touches =
+    static_cast<nsTArray< nsRefPtr<dom::Touch> >*>(aTouchList);
   aData->mChanged = false;
   touches->AppendElement(aData);
   return PL_DHASH_NEXT;
 }
 
 static PLDHashOperator
-FindAnyTarget(const uint32_t& aKey, nsCOMPtr<nsIDOMTouch>& aData,
+FindAnyTarget(const uint32_t& aKey, nsRefPtr<dom::Touch>& aData,
               void* aAnyTarget)
 {
   if (aData) {
-    nsCOMPtr<nsIDOMEventTarget> target;
-    aData->GetTarget(getter_AddRefs(target));
+    dom::EventTarget* target = aData->Target();
     if (target) {
       nsCOMPtr<nsIContent>* content =
         static_cast<nsCOMPtr<nsIContent>*>(aAnyTarget);
       *content = do_QueryInterface(target);
       return PL_DHASH_STOP;
     }
   }
   return PL_DHASH_NEXT;
@@ -6128,17 +6128,17 @@ PresShell::HandleEvent(nsIFrame        *
     if (!captureRetarget && !isWindowLevelMouseExit) {
       nsPoint eventPoint;
       if (aEvent->message == NS_TOUCH_START) {
         nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
         // if there is only one touch in this touchstart event, assume that it is
         // the start of a new touch session and evict any old touches in the
         // queue
         if (touchEvent->touches.Length() == 1) {
-          nsTArray<nsCOMPtr<nsIDOMTouch> > touches;
+          nsTArray< nsRefPtr<dom::Touch> > touches;
           gCaptureTouchList.Enumerate(&AppendToTouchList, (void *)&touches);
           for (uint32_t i = 0; i < touches.Length(); ++i) {
             EvictTouchPoint(touches[i]);
           }
         }
         // if this is a continuing session, ensure that all these events are
         // in the same document by taking the target of the events already in
         // the capture list
@@ -6147,22 +6147,20 @@ PresShell::HandleEvent(nsIFrame        *
           gCaptureTouchList.Enumerate(&FindAnyTarget, &anyTarget);
         } else {
           gPreventMouseEvents = false;
         }
 
         // Add any new touches to the queue
         for (int32_t i = touchEvent->touches.Length(); i; ) {
           --i;
-          nsIDOMTouch *touch = touchEvent->touches[i];
-          Touch *domtouch = static_cast<Touch*>(touch);
+          dom::Touch* touch = touchEvent->touches[i];
           touch->mMessage = aEvent->message;
 
-          int32_t id = 0;
-          touch->GetIdentifier(&id);
+          int32_t id = touch->Identifier();
           if (!gCaptureTouchList.Get(id, nullptr)) {
             // This event is a new touch. Mark it as a changedTouch and
             // add it to the queue.
             touch->mChanged = true;
 
             // find the target for this touch
             uint32_t flags = 0;
             eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent,
@@ -6172,17 +6170,17 @@ PresShell::HandleEvent(nsIFrame        *
                                                              frame,
                                                              eventPoint,
                                                              flags);
             if (target && !anyTarget) {
               target->GetContentForEvent(aEvent, getter_AddRefs(anyTarget));
               while (anyTarget && !anyTarget->IsElement()) {
                 anyTarget = anyTarget->GetParent();
               }
-              domtouch->SetTarget(anyTarget);
+              touch->SetTarget(anyTarget);
               gCaptureTouchList.Put(id, touch);
             } else {
               nsIFrame* newTargetFrame = nullptr;
               for (nsIFrame* f = target; f;
                    f = nsLayoutUtils::GetParentOrPlaceholderForCrossDoc(f)) {
                 if (f->PresContext()->Document() == anyTarget->OwnerDoc()) {
                   newTargetFrame = f;
                   break;
@@ -6212,23 +6210,21 @@ PresShell::HandleEvent(nsIFrame        *
             }
             if (target) {
               frame = target;
             }
           } else {
             // This touch is an old touch, we need to ensure that is not
             // marked as changed and set its target correctly
             touch->mChanged = false;
-            int32_t id;
-            touch->GetIdentifier(&id);
-
-            nsCOMPtr<nsIDOMTouch> oldTouch;
-            gCaptureTouchList.Get(id, getter_AddRefs(oldTouch));
+            int32_t id = touch->Identifier();
+
+            nsRefPtr<dom::Touch> oldTouch = gCaptureTouchList.GetWeak(id);
             if (oldTouch) {
-              domtouch->SetTarget(oldTouch->GetTarget());
+              touch->SetTarget(oldTouch->mTarget);
               gCaptureTouchList.Put(id, touch);
             }
           }
         }
       } else {
         eventPoint = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, frame);
       }
       uint32_t flags = 0;
@@ -6281,34 +6277,31 @@ PresShell::HandleEvent(nsIFrame        *
     PresShell* shell =
         static_cast<PresShell*>(frame->PresContext()->PresShell());
     switch (aEvent->message) {
       case NS_TOUCH_MOVE:
       case NS_TOUCH_CANCEL:
       case NS_TOUCH_END: {
         // get the correct shell to dispatch to
         nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
-        nsTArray<nsCOMPtr<nsIDOMTouch> >  &touches = touchEvent->touches;
+        nsTArray< nsRefPtr<dom::Touch> >& touches = touchEvent->touches;
         for (uint32_t i = 0; i < touches.Length(); ++i) {
-          nsIDOMTouch *touch = touches[i];
+          dom::Touch* touch = touches[i];
           if (!touch) {
             break;
           }
   
-          int32_t id;
-          touch->GetIdentifier(&id);
-          nsCOMPtr<nsIDOMTouch> oldTouch;
-          gCaptureTouchList.Get(id, getter_AddRefs(oldTouch));
+          nsRefPtr<dom::Touch> oldTouch =
+            gCaptureTouchList.GetWeak(touch->Identifier());
           if (!oldTouch) {
             break;
           }
   
-          nsCOMPtr<nsIDOMEventTarget> targetPtr;
-          oldTouch->GetTarget(getter_AddRefs(targetPtr));
-          nsCOMPtr<nsIContent> content = do_QueryInterface(targetPtr);
+          nsCOMPtr<nsIContent> content =
+            do_QueryInterface(oldTouch->Target());
           if (!content) {
             break;
           }
 
           nsIFrame* contentFrame = content->GetPrimaryFrame();
           if (!contentFrame) {
             break;
           }
@@ -6676,77 +6669,70 @@ PresShell::HandleEventInternal(nsEvent* 
       case NS_MOUSE_BUTTON_UP:
         isHandlingUserInput = true;
         break;
       case NS_TOUCH_CANCEL:
       case NS_TOUCH_END: {
         // Remove the changed touches
         // need to make sure we only remove touches that are ending here
         nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
-        nsTArray<nsCOMPtr<nsIDOMTouch> >  &touches = touchEvent->touches;
+        nsTArray< nsRefPtr<dom::Touch> >& touches = touchEvent->touches;
         for (uint32_t i = 0; i < touches.Length(); ++i) {
-          nsIDOMTouch *touch = touches[i];
-          Touch *domtouch = static_cast<Touch*>(touch);
+          dom::Touch* touch = touches[i];
           if (!touch) {
             continue;
           }
           touch->mMessage = aEvent->message;
           touch->mChanged = true;
-          nsCOMPtr<nsIDOMTouch> oldTouch;
-
-          int32_t id;
-          touch->GetIdentifier(&id);
-
-          gCaptureTouchList.Get(id, getter_AddRefs(oldTouch));
+
+          int32_t id = touch->Identifier();
+          nsRefPtr<dom::Touch> oldTouch = gCaptureTouchList.GetWeak(id);
           if (!oldTouch) {
             continue;
           }
-          nsCOMPtr<EventTarget> targetPtr = oldTouch->GetTarget();
+          nsCOMPtr<EventTarget> targetPtr = oldTouch->mTarget;
 
           mCurrentEventContent = do_QueryInterface(targetPtr);
-          domtouch->SetTarget(targetPtr);
+          touch->SetTarget(targetPtr);
           gCaptureTouchList.Remove(id);
         }
         // add any touches left in the touch list, but ensure changed=false
         gCaptureTouchList.Enumerate(&AppendToTouchList, (void *)&touches);
         break;
       }
       case NS_TOUCH_MOVE: {
         // Check for touches that changed. Mark them add to queue
         nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
-        nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = touchEvent->touches;
+        nsTArray< nsRefPtr<dom::Touch> >& touches = touchEvent->touches;
         bool haveChanged = false;
         for (int32_t i = touches.Length(); i; ) {
           --i;
-          nsIDOMTouch *touch = touches[i];
-          Touch *domtouch = static_cast<Touch*>(touch);
+          dom::Touch* touch = touches[i];
           if (!touch) {
             continue;
           }
-          int32_t id;
-          touch->GetIdentifier(&id);
+          int32_t id = touch->Identifier();
           touch->mMessage = aEvent->message;
 
-          nsCOMPtr<nsIDOMTouch> oldTouch;
-          gCaptureTouchList.Get(id, getter_AddRefs(oldTouch));
+          nsRefPtr<dom::Touch> oldTouch = gCaptureTouchList.GetWeak(id);
           if (!oldTouch) {
             touches.RemoveElementAt(i);
             continue;
           }
-          if(domtouch->Equals(oldTouch)) {
+          if (touch->Equals(oldTouch)) {
             touch->mChanged = true;
             haveChanged = true;
           }
 
-          nsCOMPtr<EventTarget> targetPtr = oldTouch->GetTarget();
+          nsCOMPtr<dom::EventTarget> targetPtr = oldTouch->mTarget;
           if (!targetPtr) {
             touches.RemoveElementAt(i);
             continue;
           }
-          domtouch->SetTarget(targetPtr);
+          touch->SetTarget(targetPtr);
 
           gCaptureTouchList.Put(id, touch);
           // if we're moving from touchstart to touchmove for this touch
           // we allow preventDefault to prevent mouse events
           if (oldTouch->mMessage != touch->mMessage) {
             touchIsNew = true;
           }
         }
--- a/widget/nsGUIEvent.h
+++ b/widget/nsGUIEvent.h
@@ -25,16 +25,17 @@
 #include "nsIWidget.h"
 #include "nsTArray.h"
 #include "nsTraceRefcnt.h"
 #include "nsITransferable.h"
 #include "nsIVariant.h"
 #include "nsStyleConsts.h"
 #include "nsAutoPtr.h"
 #include "mozilla/dom/EventTarget.h"
+#include "mozilla/dom/Touch.h"
 
 namespace mozilla {
 namespace dom {
   class PBrowserParent;
   class PBrowserChild;
 }
 namespace plugins {
   class PPluginInstanceChild;
@@ -1646,17 +1647,17 @@ public:
   {
     MOZ_COUNT_CTOR(nsTouchEvent);
   }
   ~nsTouchEvent()
   {
     MOZ_COUNT_DTOR(nsTouchEvent);
   }
 
-  nsTArray<nsCOMPtr<nsIDOMTouch> > touches;
+  nsTArray< nsRefPtr<mozilla::dom::Touch> > touches;
 };
 
 /**
  * Form event
  * 
  * We hold the originating form control for form submit and reset events.
  * originator is a weak pointer (does not hold a strong reference).
  */
--- a/widget/nsGUIEventIPC.h
+++ b/widget/nsGUIEventIPC.h
@@ -201,20 +201,20 @@ struct ParamTraits<nsTouchEvent>
 {
   typedef nsTouchEvent paramType;
 
   static void Write(Message* aMsg, const paramType& aParam)
   {
     WriteParam(aMsg, static_cast<const nsInputEvent&>(aParam));
     // Sigh, Touch bites us again!  We want to be able to do
     //   WriteParam(aMsg, aParam.touches);
-    const nsTArray<nsCOMPtr<nsIDOMTouch> >& touches = aParam.touches;
+    const nsTArray< nsRefPtr<mozilla::dom::Touch> >& touches = aParam.touches;
     WriteParam(aMsg, touches.Length());
     for (uint32_t i = 0; i < touches.Length(); ++i) {
-      mozilla::dom::Touch* touch = static_cast<mozilla::dom::Touch*>(touches[i].get());
+      mozilla::dom::Touch* touch = touches[i];
       WriteParam(aMsg, touch->mIdentifier);
       WriteParam(aMsg, touch->mRefPoint);
       WriteParam(aMsg, touch->mRadius);
       WriteParam(aMsg, touch->mRotationAngle);
       WriteParam(aMsg, touch->mForce);
     }
   }