Bug 964718 Don't dispatch DOM event if internal event doesn't need that. Otherwise, implement Duplicate() method r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 27 Mar 2014 22:53:19 +0900
changeset 175626 b33c9dbfa7cacea7d0aff2dabba14d8543966c6d
parent 175625 210213ae7c1c08519e147cb438a2a6ebbb62743b
child 175627 f431f72252e2ae3b01877be446b4240fef8b2ce3
push idunknown
push userunknown
push dateunknown
reviewerssmaug
bugs964718
milestone31.0a1
Bug 964718 Don't dispatch DOM event if internal event doesn't need that. Otherwise, implement Duplicate() method r=smaug
widget/MiscEvents.h
widget/TextEvents.h
widget/TouchEvents.h
widget/shared/WidgetEventImpl.cpp
--- a/widget/MiscEvents.h
+++ b/widget/MiscEvents.h
@@ -33,16 +33,18 @@ public:
     WidgetGUIEvent(aIsTrusted, aMessage, aWidget, NS_CONTENT_COMMAND_EVENT),
     mOnlyEnabledCheck(aOnlyEnabledCheck), mSucceeded(false), mIsEnabled(false)
   {
   }
 
   virtual WidgetEvent* Duplicate() const MOZ_OVERRIDE
   {
     // This event isn't an internal event of any DOM event.
+    NS_ASSERTION(!IsAllowedToDispatchDOMEvent(),
+      "WidgetQueryContentEvent needs to support Duplicate()");
     MOZ_CRASH("WidgetQueryContentEvent doesn't support Duplicate()");
     return nullptr;
   }
 
   // NS_CONTENT_COMMAND_PASTE_TRANSFERABLE
   nsCOMPtr<nsITransferable> mTransferable; // [in]
 
   // NS_CONTENT_COMMAND_SCROLL
@@ -144,21 +146,35 @@ public:
   WidgetPluginEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget) :
     WidgetGUIEvent(aIsTrusted, aMessage, aWidget, NS_PLUGIN_EVENT),
     retargetToFocusedDocument(false)
   {
   }
 
   virtual WidgetEvent* Duplicate() const MOZ_OVERRIDE
   {
-    // This event isn't an internal event of any DOM event.
-    MOZ_CRASH("WidgetQueryContentEvent doesn't support Duplicate()");
-    return nullptr;
+    // NOTE: PluginEvent has to be dispatched to nsIFrame::HandleEvent().
+    //       So, this event needs to support Duplicate().
+    MOZ_ASSERT(eventStructType == NS_PLUGIN_EVENT,
+               "Duplicate() must be overridden by sub class");
+    // Not copying widget, it is a weak reference.
+    WidgetPluginEvent* result = new WidgetPluginEvent(false, message, nullptr);
+    result->AssignPluginEventData(*this, true);
+    result->mFlags = mFlags;
+    return result;
   }
 
   // If true, this event needs to be retargeted to focused document.
   // Otherwise, never retargeted. Defaults to false.
   bool retargetToFocusedDocument;
+
+  void AssignPluginEventData(const WidgetPluginEvent& aEvent,
+                             bool aCopyTargets)
+  {
+    AssignGUIEventData(aEvent, aCopyTargets);
+
+    retargetToFocusedDocument = aEvent.retargetToFocusedDocument;
+  }
 };
 
 } // namespace mozilla
 
 #endif // mozilla_MiscEvents_h__
--- a/widget/TextEvents.h
+++ b/widget/TextEvents.h
@@ -333,16 +333,18 @@ public:
     WidgetGUIEvent(aIsTrusted, aMessage, aWidget, NS_QUERY_CONTENT_EVENT),
     mSucceeded(false), mWasAsync(false)
   {
   }
 
   virtual WidgetEvent* Duplicate() const MOZ_OVERRIDE
   {
     // This event isn't an internal event of any DOM event.
+    NS_ASSERTION(!IsAllowedToDispatchDOMEvent(),
+      "WidgetQueryContentEvent needs to support Duplicate()");
     MOZ_CRASH("WidgetQueryContentEvent doesn't support Duplicate()");
     return nullptr;
   }
 
   void InitForQueryTextContent(uint32_t aOffset, uint32_t aLength)
   {
     NS_ASSERTION(message == NS_QUERY_TEXT_CONTENT,
                  "wrong initializer is called");
@@ -464,16 +466,18 @@ public:
     , mExpandToClusterBoundary(true)
     , mSucceeded(false)
   {
   }
 
   virtual WidgetEvent* Duplicate() const MOZ_OVERRIDE
   {
     // This event isn't an internal event of any DOM event.
+    NS_ASSERTION(!IsAllowedToDispatchDOMEvent(),
+      "WidgetSelectionEvent needs to support Duplicate()");
     MOZ_CRASH("WidgetSelectionEvent doesn't support Duplicate()");
     return nullptr;
   }
 
   // Start offset of selection
   uint32_t mOffset;
   // Length of selection
   uint32_t mLength;
--- a/widget/TouchEvents.h
+++ b/widget/TouchEvents.h
@@ -40,31 +40,50 @@ public:
                            nsIWidget *aWidget) :
     WidgetGUIEvent(aIsTrusted, aMessage, aWidget, NS_GESTURENOTIFY_EVENT),
     panDirection(ePanNone), displayPanFeedback(false)
   {
   }
 
   virtual WidgetEvent* Duplicate() const MOZ_OVERRIDE
   {
-    // This event isn't an internal event of any DOM event.
-    MOZ_CRASH("WidgetGestureNotifyEvent doesn't support Duplicate()");
-    return nullptr;
+    // XXX Looks like this event is handled only in PostHandleEvent() of
+    //     EventStateManager.  Therefore, it might be possible to handle this
+    //     in PreHandleEvent() and not to dispatch as a DOM event into the DOM
+    //     tree like ContentQueryEvent.  Then, this event doesn't need to
+    //     support Duplicate().
+    MOZ_ASSERT(eventStructType == NS_GESTURENOTIFY_EVENT,
+               "Duplicate() must be overridden by sub class");
+    // Not copying widget, it is a weak reference.
+    WidgetGestureNotifyEvent* result =
+      new WidgetGestureNotifyEvent(false, message, nullptr);
+    result->AssignGestureNotifyEventData(*this, true);
+    result->mFlags = mFlags;
+    return result;
   }
 
   enum ePanDirection
   {
     ePanNone,
     ePanVertical,
     ePanHorizontal,
     ePanBoth
   };
 
   ePanDirection panDirection;
   bool displayPanFeedback;
+
+  void AssignGestureNotifyEventData(const WidgetGestureNotifyEvent& aEvent,
+                                    bool aCopyTargets)
+  {
+    AssignGUIEventData(aEvent, aCopyTargets);
+
+    panDirection = aEvent.panDirection;
+    displayPanFeedback = aEvent.displayPanFeedback;
+  }
 };
 
 /******************************************************************************
  * mozilla::WidgetTouchEvent
  ******************************************************************************/
 
 class WidgetSimpleGestureEvent : public WidgetMouseEventBase
 {
--- a/widget/shared/WidgetEventImpl.cpp
+++ b/widget/shared/WidgetEventImpl.cpp
@@ -227,16 +227,23 @@ WidgetEvent::IsAllowedToDispatchDOMEvent
     case NS_WHEEL_EVENT: {
       // wheel event whose all delta values are zero by user pref applied, it
       // shouldn't cause a DOM event.
       const WidgetWheelEvent* wheelEvent = AsWheelEvent();
       return wheelEvent->deltaX != 0.0 || wheelEvent->deltaY != 0.0 ||
              wheelEvent->deltaZ != 0.0;
     }
 
+    // Following events are handled in EventStateManager, so, we don't need to
+    // dispatch DOM event for them into the DOM tree.
+    case NS_QUERY_CONTENT_EVENT:
+    case NS_SELECTION_EVENT:
+    case NS_CONTENT_COMMAND_EVENT:
+      return false;
+
     default:
       return true;
   }
 }
 
 /******************************************************************************
  * mozilla::WidgetKeyboardEvent (TextEvents.h)
  ******************************************************************************/