Bug 964718 Don't dispatch DOM event if internal event doesn't need that. Otherwise, implement Duplicate() method r=smaug, a=sylvestre
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 27 Mar 2014 22:53:19 +0900
changeset 183785 aaf5030cbf98
parent 183784 b192379d4d65
child 183786 3051963e5ec3
push id3483
push usermasayuki@d-toybox.com
push date2014-04-17 00:14 +0000
treeherdermozilla-beta@aaf5030cbf98 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug, sylvestre
bugs964718
milestone29.0
Bug 964718 Don't dispatch DOM event if internal event doesn't need that. Otherwise, implement Duplicate() method r=smaug, a=sylvestre
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
@@ -325,16 +325,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");
@@ -456,16 +458,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)
  ******************************************************************************/