Bug 1152479 - Extract the implementations of nsIDOMWindowUtils::Send{KeyEvent,MouseEvent} into nsContentUtils. r=ehsan
authorBotond Ballo <botond@mozilla.com>
Wed, 15 Apr 2015 03:08:55 -0400
changeset 269780 46d9e768772216b5e41548ad6ee8e8a18bbb3cc7
parent 269779 7125873a632f1f78d65e4888d4544c8a9203110f
child 269781 786b564f6e0ab5c0caa374b63c1e97b26e323f36
push id4830
push userjlund@mozilla.com
push dateMon, 29 Jun 2015 20:18:48 +0000
treeherdermozilla-beta@4c2175bb0420 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1152479
milestone40.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 1152479 - Extract the implementations of nsIDOMWindowUtils::Send{KeyEvent,MouseEvent} into nsContentUtils. r=ehsan
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
dom/base/nsDOMWindowUtils.cpp
dom/base/nsDOMWindowUtils.h
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -110,16 +110,17 @@
 #include "nsIDOMDocumentType.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMHTMLElement.h"
 #include "nsIDOMHTMLFormElement.h"
 #include "nsIDOMHTMLInputElement.h"
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeList.h"
 #include "nsIDOMScriptObjectFactory.h"
+#include "nsIDOMWindowUtils.h"
 #include "nsIDOMXULCommandEvent.h"
 #include "nsIDragService.h"
 #include "nsIEditor.h"
 #include "nsIFormControl.h"
 #include "nsIForm.h"
 #include "nsIFragmentContentSink.h"
 #include "nsContainerFrame.h"
 #include "nsIHTMLDocument.h"
@@ -7386,8 +7387,305 @@ nsContentUtils::GetSurfaceData(mozilla::
   memset(surfaceData.get() + bufLen, 0, maxBufLen - bufLen + 1);
 
   *aLength = maxBufLen;
   *aStride = map.mStride;
 
   aSurface->Unmap();
   return surfaceData;
 }
+
+mozilla::Modifiers
+nsContentUtils::GetWidgetModifiers(int32_t aModifiers)
+{
+  Modifiers result = 0;
+  if (aModifiers & nsIDOMWindowUtils::MODIFIER_SHIFT) {
+    result |= mozilla::MODIFIER_SHIFT;
+  }
+  if (aModifiers & nsIDOMWindowUtils::MODIFIER_CONTROL) {
+    result |= mozilla::MODIFIER_CONTROL;
+  }
+  if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALT) {
+    result |= mozilla::MODIFIER_ALT;
+  }
+  if (aModifiers & nsIDOMWindowUtils::MODIFIER_META) {
+    result |= mozilla::MODIFIER_META;
+  }
+  if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALTGRAPH) {
+    result |= mozilla::MODIFIER_ALTGRAPH;
+  }
+  if (aModifiers & nsIDOMWindowUtils::MODIFIER_CAPSLOCK) {
+    result |= mozilla::MODIFIER_CAPSLOCK;
+  }
+  if (aModifiers & nsIDOMWindowUtils::MODIFIER_FN) {
+    result |= mozilla::MODIFIER_FN;
+  }
+  if (aModifiers & nsIDOMWindowUtils::MODIFIER_FNLOCK) {
+    result |= mozilla::MODIFIER_FNLOCK;
+  }
+  if (aModifiers & nsIDOMWindowUtils::MODIFIER_NUMLOCK) {
+    result |= mozilla::MODIFIER_NUMLOCK;
+  }
+  if (aModifiers & nsIDOMWindowUtils::MODIFIER_SCROLLLOCK) {
+    result |= mozilla::MODIFIER_SCROLLLOCK;
+  }
+  if (aModifiers & nsIDOMWindowUtils::MODIFIER_SYMBOL) {
+    result |= mozilla::MODIFIER_SYMBOL;
+  }
+  if (aModifiers & nsIDOMWindowUtils::MODIFIER_SYMBOLLOCK) {
+    result |= mozilla::MODIFIER_SYMBOLLOCK;
+  }
+  if (aModifiers & nsIDOMWindowUtils::MODIFIER_OS) {
+    result |= mozilla::MODIFIER_OS;
+  }
+  return result;
+}
+
+nsIWidget*
+nsContentUtils::GetWidget(nsIPresShell* aPresShell, nsPoint* aOffset) {
+  if (aPresShell) {
+    nsIFrame* frame = aPresShell->GetRootFrame();
+    if (frame)
+      return frame->GetView()->GetNearestWidget(aOffset);
+  }
+  return nullptr;
+}
+
+int16_t
+nsContentUtils::GetButtonsFlagForButton(int32_t aButton)
+{
+  switch (aButton) {
+    case WidgetMouseEvent::eLeftButton:
+      return WidgetMouseEvent::eLeftButtonFlag;
+    case WidgetMouseEvent::eMiddleButton:
+      return WidgetMouseEvent::eMiddleButtonFlag;
+    case WidgetMouseEvent::eRightButton:
+      return WidgetMouseEvent::eRightButtonFlag;
+    case 4:
+      return WidgetMouseEvent::e4thButtonFlag;
+    case 5:
+      return WidgetMouseEvent::e5thButtonFlag;
+    default:
+      NS_ERROR("Button not known.");
+      return 0;
+  }
+}
+
+LayoutDeviceIntPoint
+nsContentUtils::ToWidgetPoint(const CSSPoint& aPoint,
+                              const nsPoint& aOffset,
+                              nsPresContext* aPresContext)
+{
+  return LayoutDeviceIntPoint::FromAppUnitsRounded(
+    CSSPoint::ToAppUnits(aPoint) + aOffset,
+    aPresContext->AppUnitsPerDevPixel());
+}
+
+nsView*
+nsContentUtils::GetViewToDispatchEvent(nsPresContext* presContext,
+                                       nsIPresShell** presShell)
+{
+  if (presContext && presShell) {
+    *presShell = presContext->PresShell();
+    if (*presShell) {
+      NS_ADDREF(*presShell);
+      if (nsViewManager* viewManager = (*presShell)->GetViewManager()) {
+        if (nsView* view = viewManager->GetRootView()) {
+          return view;
+        }
+      }
+    }
+  }
+  return nullptr;
+}
+
+nsresult
+nsContentUtils::SendKeyEvent(nsCOMPtr<nsIWidget> aWidget,
+                             const nsAString& aType,
+                             int32_t aKeyCode,
+                             int32_t aCharCode,
+                             int32_t aModifiers,
+                             uint32_t aAdditionalFlags,
+                             bool* aDefaultActionTaken)
+{
+  // get the widget to send the event to
+  if (!aWidget)
+    return NS_ERROR_FAILURE;
+
+  int32_t msg;
+  if (aType.EqualsLiteral("keydown"))
+    msg = NS_KEY_DOWN;
+  else if (aType.EqualsLiteral("keyup"))
+    msg = NS_KEY_UP;
+  else if (aType.EqualsLiteral("keypress"))
+    msg = NS_KEY_PRESS;
+  else
+    return NS_ERROR_FAILURE;
+
+  WidgetKeyboardEvent event(true, msg, aWidget);
+  event.modifiers = GetWidgetModifiers(aModifiers);
+
+  if (msg == NS_KEY_PRESS) {
+    event.keyCode = aCharCode ? 0 : aKeyCode;
+    event.charCode = aCharCode;
+  } else {
+    event.keyCode = aKeyCode;
+    event.charCode = 0;
+  }
+
+  uint32_t locationFlag = (aAdditionalFlags &
+    (nsIDOMWindowUtils::KEY_FLAG_LOCATION_STANDARD | nsIDOMWindowUtils::KEY_FLAG_LOCATION_LEFT |
+     nsIDOMWindowUtils::KEY_FLAG_LOCATION_RIGHT | nsIDOMWindowUtils::KEY_FLAG_LOCATION_NUMPAD));
+  switch (locationFlag) {
+    case nsIDOMWindowUtils::KEY_FLAG_LOCATION_STANDARD:
+      event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD;
+      break;
+    case nsIDOMWindowUtils::KEY_FLAG_LOCATION_LEFT:
+      event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT;
+      break;
+    case nsIDOMWindowUtils::KEY_FLAG_LOCATION_RIGHT:
+      event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_RIGHT;
+      break;
+    case nsIDOMWindowUtils::KEY_FLAG_LOCATION_NUMPAD:
+      event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD;
+      break;
+    default:
+      if (locationFlag != 0) {
+        return NS_ERROR_INVALID_ARG;
+      }
+      // If location flag isn't set, choose the location from keycode.
+      switch (aKeyCode) {
+        case nsIDOMKeyEvent::DOM_VK_NUMPAD0:
+        case nsIDOMKeyEvent::DOM_VK_NUMPAD1:
+        case nsIDOMKeyEvent::DOM_VK_NUMPAD2:
+        case nsIDOMKeyEvent::DOM_VK_NUMPAD3:
+        case nsIDOMKeyEvent::DOM_VK_NUMPAD4:
+        case nsIDOMKeyEvent::DOM_VK_NUMPAD5:
+        case nsIDOMKeyEvent::DOM_VK_NUMPAD6:
+        case nsIDOMKeyEvent::DOM_VK_NUMPAD7:
+        case nsIDOMKeyEvent::DOM_VK_NUMPAD8:
+        case nsIDOMKeyEvent::DOM_VK_NUMPAD9:
+        case nsIDOMKeyEvent::DOM_VK_MULTIPLY:
+        case nsIDOMKeyEvent::DOM_VK_ADD:
+        case nsIDOMKeyEvent::DOM_VK_SEPARATOR:
+        case nsIDOMKeyEvent::DOM_VK_SUBTRACT:
+        case nsIDOMKeyEvent::DOM_VK_DECIMAL:
+        case nsIDOMKeyEvent::DOM_VK_DIVIDE:
+          event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD;
+          break;
+        case nsIDOMKeyEvent::DOM_VK_SHIFT:
+        case nsIDOMKeyEvent::DOM_VK_CONTROL:
+        case nsIDOMKeyEvent::DOM_VK_ALT:
+        case nsIDOMKeyEvent::DOM_VK_META:
+          event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT;
+          break;
+        default:
+          event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD;
+          break;
+      }
+      break;
+  }
+
+  event.refPoint.x = event.refPoint.y = 0;
+  event.time = PR_IntervalNow();
+  if (!(aAdditionalFlags & nsIDOMWindowUtils::KEY_FLAG_NOT_SYNTHESIZED_FOR_TESTS)) {
+    event.mFlags.mIsSynthesizedForTests = true;
+  }
+
+  if (aAdditionalFlags & nsIDOMWindowUtils::KEY_FLAG_PREVENT_DEFAULT) {
+    event.mFlags.mDefaultPrevented = true;
+  }
+
+  nsEventStatus status;
+  nsresult rv = aWidget->DispatchEvent(&event, status);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  *aDefaultActionTaken = (status != nsEventStatus_eConsumeNoDefault);
+
+  return NS_OK;
+}
+
+nsresult
+nsContentUtils::SendMouseEvent(nsCOMPtr<nsIPresShell> aPresShell,
+                               const nsAString& aType,
+                               float aX,
+                               float aY,
+                               int32_t aButton,
+                               int32_t aClickCount,
+                               int32_t aModifiers,
+                               bool aIgnoreRootScrollFrame,
+                               float aPressure,
+                               unsigned short aInputSourceArg,
+                               bool aToWindow,
+                               bool *aPreventDefault,
+                               bool aIsSynthesized)
+{
+  nsPoint offset;
+  nsCOMPtr<nsIWidget> widget = GetWidget(aPresShell, &offset);
+  if (!widget)
+    return NS_ERROR_FAILURE;
+
+  int32_t msg;
+  bool contextMenuKey = false;
+  if (aType.EqualsLiteral("mousedown"))
+    msg = NS_MOUSE_BUTTON_DOWN;
+  else if (aType.EqualsLiteral("mouseup"))
+    msg = NS_MOUSE_BUTTON_UP;
+  else if (aType.EqualsLiteral("mousemove"))
+    msg = NS_MOUSE_MOVE;
+  else if (aType.EqualsLiteral("mouseover"))
+    msg = NS_MOUSE_ENTER;
+  else if (aType.EqualsLiteral("mouseout"))
+    msg = NS_MOUSE_EXIT;
+  else if (aType.EqualsLiteral("contextmenu")) {
+    msg = NS_CONTEXTMENU;
+    contextMenuKey = (aButton == 0);
+  } else if (aType.EqualsLiteral("MozMouseHittest"))
+    msg = NS_MOUSE_MOZHITTEST;
+  else
+    return NS_ERROR_FAILURE;
+
+  if (aInputSourceArg == nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN) {
+    aInputSourceArg = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE;
+  }
+
+  WidgetMouseEvent event(true, msg, widget, WidgetMouseEvent::eReal,
+                         contextMenuKey ? WidgetMouseEvent::eContextMenuKey :
+                                          WidgetMouseEvent::eNormal);
+  event.modifiers = GetWidgetModifiers(aModifiers);
+  event.button = aButton;
+  event.buttons = GetButtonsFlagForButton(aButton);
+  event.widget = widget;
+  event.pressure = aPressure;
+  event.inputSource = aInputSourceArg;
+  event.clickCount = aClickCount;
+  event.time = PR_IntervalNow();
+  event.mFlags.mIsSynthesizedForTests = aIsSynthesized;
+
+  nsPresContext* presContext = aPresShell->GetPresContext();
+  if (!presContext)
+    return NS_ERROR_FAILURE;
+
+  event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
+  event.ignoreRootScrollFrame = aIgnoreRootScrollFrame;
+
+  nsEventStatus status = nsEventStatus_eIgnore;
+  if (aToWindow) {
+    nsCOMPtr<nsIPresShell> presShell;
+    nsView* view = GetViewToDispatchEvent(presContext, getter_AddRefs(presShell));
+    if (!presShell || !view) {
+      return NS_ERROR_FAILURE;
+    }
+    return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
+  }
+  if (gfxPrefs::TestEventsAsyncEnabled()) {
+    status = widget->DispatchInputEvent(&event);
+  } else {
+    nsresult rv = widget->DispatchEvent(&event, status);
+    NS_ENSURE_SUCCESS(rv, rv);
+  }
+  if (aPreventDefault) {
+    *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
+  }
+
+  return NS_OK;
+}
+
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -95,16 +95,17 @@ class nsIWordBreaker;
 class nsIXPConnect;
 class nsNodeInfoManager;
 class nsPIDOMWindow;
 class nsPresContext;
 class nsScriptObjectTracer;
 class nsStringBuffer;
 class nsStringHashKey;
 class nsTextFragment;
+class nsView;
 class nsViewportInfo;
 class nsWrapperCache;
 class nsAttrValue;
 class nsITransferable;
 
 struct JSPropertyDescriptor;
 struct JSRuntime;
 struct nsIntMargin;
@@ -2311,16 +2312,57 @@ public:
 
   /*
    * Get the pixel data from the given source surface and return it as a buffer.
    * The length and stride will be assigned from the surface.
    */
   static mozilla::UniquePtr<char[]> GetSurfaceData(mozilla::gfx::DataSourceSurface* aSurface,
                                                    size_t* aLength, int32_t* aStride);
 
+  // Helpers shared by the implementations of nsContentUtils methods and
+  // nsIDOMWindowUtils methods.
+  static mozilla::Modifiers GetWidgetModifiers(int32_t aModifiers);
+  static nsIWidget* GetWidget(nsIPresShell* aPresShell, nsPoint* aOffset);
+  static int16_t GetButtonsFlagForButton(int32_t aButton);
+  static mozilla::LayoutDeviceIntPoint ToWidgetPoint(const mozilla::CSSPoint& aPoint,
+                                                     const nsPoint& aOffset,
+                                                     nsPresContext* aPresContext);
+  static nsView* GetViewToDispatchEvent(nsPresContext* aPresContext,
+                                        nsIPresShell** aPresShell);
+
+  /**
+   * Synthesize a key event to the given widget
+   * (see nsIDOMWindowUtils.sendKeyEvent).
+   */
+  static nsresult SendKeyEvent(nsCOMPtr<nsIWidget> aWidget,
+                               const nsAString& aType,
+                               int32_t aKeyCode,
+                               int32_t aCharCode,
+                               int32_t aModifiers,
+                               uint32_t aAdditionalFlags,
+                               bool* aDefaultActionTaken);
+
+  /**
+   * Synthesize a mouse event to the given widget
+   * (see nsIDOMWindowUtils.sendMouseEvent).
+   */
+  static nsresult SendMouseEvent(nsCOMPtr<nsIPresShell> aPresShell,
+                                 const nsAString& aType,
+                                 float aX,
+                                 float aY,
+                                 int32_t aButton,
+                                 int32_t aClickCount,
+                                 int32_t aModifiers,
+                                 bool aIgnoreRootScrollFrame,
+                                 float aPressure,
+                                 unsigned short aInputSourceArg,
+                                 bool aToWindow,
+                                 bool *aPreventDefault,
+                                 bool aIsSynthesized);
+
 private:
   static bool InitializeEventTable();
 
   static nsresult EnsureStringBundle(PropertiesFile aFile);
 
   static bool CanCallerAccess(nsIPrincipal* aSubjectPrincipal,
                                 nsIPrincipal* aPrincipal);
 
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -586,63 +586,16 @@ nsDOMWindowUtils::GetPresShellId(uint32_
   nsIPresShell* presShell = GetPresShell();
   if (presShell) {
     *aPresShellId = presShell->GetPresShellId();
     return NS_OK;
   }
   return NS_ERROR_FAILURE;
 }
 
-/* static */
-mozilla::Modifiers
-nsDOMWindowUtils::GetWidgetModifiers(int32_t aModifiers)
-{
-  Modifiers result = 0;
-  if (aModifiers & nsIDOMWindowUtils::MODIFIER_SHIFT) {
-    result |= mozilla::MODIFIER_SHIFT;
-  }
-  if (aModifiers & nsIDOMWindowUtils::MODIFIER_CONTROL) {
-    result |= mozilla::MODIFIER_CONTROL;
-  }
-  if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALT) {
-    result |= mozilla::MODIFIER_ALT;
-  }
-  if (aModifiers & nsIDOMWindowUtils::MODIFIER_META) {
-    result |= mozilla::MODIFIER_META;
-  }
-  if (aModifiers & nsIDOMWindowUtils::MODIFIER_ALTGRAPH) {
-    result |= mozilla::MODIFIER_ALTGRAPH;
-  }
-  if (aModifiers & nsIDOMWindowUtils::MODIFIER_CAPSLOCK) {
-    result |= mozilla::MODIFIER_CAPSLOCK;
-  }
-  if (aModifiers & nsIDOMWindowUtils::MODIFIER_FN) {
-    result |= mozilla::MODIFIER_FN;
-  }
-  if (aModifiers & nsIDOMWindowUtils::MODIFIER_FNLOCK) {
-    result |= mozilla::MODIFIER_FNLOCK;
-  }
-  if (aModifiers & nsIDOMWindowUtils::MODIFIER_NUMLOCK) {
-    result |= mozilla::MODIFIER_NUMLOCK;
-  }
-  if (aModifiers & nsIDOMWindowUtils::MODIFIER_SCROLLLOCK) {
-    result |= mozilla::MODIFIER_SCROLLLOCK;
-  }
-  if (aModifiers & nsIDOMWindowUtils::MODIFIER_SYMBOL) {
-    result |= mozilla::MODIFIER_SYMBOL;
-  }
-  if (aModifiers & nsIDOMWindowUtils::MODIFIER_SYMBOLLOCK) {
-    result |= mozilla::MODIFIER_SYMBOLLOCK;
-  }
-  if (aModifiers & nsIDOMWindowUtils::MODIFIER_OS) {
-    result |= mozilla::MODIFIER_OS;
-  }
-  return result;
-}
-
 NS_IMETHODIMP
 nsDOMWindowUtils::SendMouseEvent(const nsAString& aType,
                                  float aX,
                                  float aY,
                                  int32_t aButton,
                                  int32_t aClickCount,
                                  int32_t aModifiers,
                                  bool aIgnoreRootScrollFrame,
@@ -675,148 +628,36 @@ nsDOMWindowUtils::SendMouseEventToWindow
     js::ProfileEntry::Category::EVENTS);
 
   return SendMouseEventCommon(aType, aX, aY, aButton, aClickCount, aModifiers,
                               aIgnoreRootScrollFrame, aPressure,
                               aInputSourceArg, true, nullptr,
                               aOptionalArgCount >= 4 ? aIsSynthesized : true);
 }
 
-static LayoutDeviceIntPoint
-ToWidgetPoint(const CSSPoint& aPoint, const nsPoint& aOffset,
-              nsPresContext* aPresContext)
-{
-  return LayoutDeviceIntPoint::FromAppUnitsRounded(
-    CSSPoint::ToAppUnits(aPoint) + aOffset,
-    aPresContext->AppUnitsPerDevPixel());
-}
-
-static inline int16_t
-GetButtonsFlagForButton(int32_t aButton)
-{
-  switch (aButton) {
-    case WidgetMouseEvent::eLeftButton:
-      return WidgetMouseEvent::eLeftButtonFlag;
-    case WidgetMouseEvent::eMiddleButton:
-      return WidgetMouseEvent::eMiddleButtonFlag;
-    case WidgetMouseEvent::eRightButton:
-      return WidgetMouseEvent::eRightButtonFlag;
-    case 4:
-      return WidgetMouseEvent::e4thButtonFlag;
-    case 5:
-      return WidgetMouseEvent::e5thButtonFlag;
-    default:
-      NS_ERROR("Button not known.");
-      return 0;
-  }
-}
-
-nsView*
-nsDOMWindowUtils::GetViewToDispatchEvent(nsPresContext* presContext, nsIPresShell** presShell)
-{
-  if (presContext && presShell) {
-    *presShell = presContext->PresShell();
-    if (*presShell) {
-      NS_ADDREF(*presShell);
-      if (nsViewManager* viewManager = (*presShell)->GetViewManager()) {
-        if (nsView* view = viewManager->GetRootView()) {
-          return view;
-        }
-      }
-    }
-  }
-  return nullptr;
-}
-
 NS_IMETHODIMP
 nsDOMWindowUtils::SendMouseEventCommon(const nsAString& aType,
                                        float aX,
                                        float aY,
                                        int32_t aButton,
                                        int32_t aClickCount,
                                        int32_t aModifiers,
                                        bool aIgnoreRootScrollFrame,
                                        float aPressure,
                                        unsigned short aInputSourceArg,
                                        bool aToWindow,
                                        bool *aPreventDefault,
                                        bool aIsSynthesized)
 {
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
-  // get the widget to send the event to
-  nsPoint offset;
-  nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
-  if (!widget)
-    return NS_ERROR_FAILURE;
-
-  int32_t msg;
-  bool contextMenuKey = false;
-  if (aType.EqualsLiteral("mousedown"))
-    msg = NS_MOUSE_BUTTON_DOWN;
-  else if (aType.EqualsLiteral("mouseup"))
-    msg = NS_MOUSE_BUTTON_UP;
-  else if (aType.EqualsLiteral("mousemove"))
-    msg = NS_MOUSE_MOVE;
-  else if (aType.EqualsLiteral("mouseover"))
-    msg = NS_MOUSE_ENTER;
-  else if (aType.EqualsLiteral("mouseout"))
-    msg = NS_MOUSE_EXIT;
-  else if (aType.EqualsLiteral("contextmenu")) {
-    msg = NS_CONTEXTMENU;
-    contextMenuKey = (aButton == 0);
-  } else if (aType.EqualsLiteral("MozMouseHittest"))
-    msg = NS_MOUSE_MOZHITTEST;
-  else
-    return NS_ERROR_FAILURE;
-
-  if (aInputSourceArg == nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN) {
-    aInputSourceArg = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE;
-  }
-
-  WidgetMouseEvent event(true, msg, widget, WidgetMouseEvent::eReal,
-                         contextMenuKey ? WidgetMouseEvent::eContextMenuKey :
-                                          WidgetMouseEvent::eNormal);
-  event.modifiers = GetWidgetModifiers(aModifiers);
-  event.button = aButton;
-  event.buttons = GetButtonsFlagForButton(aButton);
-  event.widget = widget;
-  event.pressure = aPressure;
-  event.inputSource = aInputSourceArg;
-  event.clickCount = aClickCount;
-  event.time = PR_IntervalNow();
-  event.mFlags.mIsSynthesizedForTests = aIsSynthesized;
-
-  nsPresContext* presContext = GetPresContext();
-  if (!presContext)
-    return NS_ERROR_FAILURE;
-
-  event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
-  event.ignoreRootScrollFrame = aIgnoreRootScrollFrame;
-
-  nsEventStatus status = nsEventStatus_eIgnore;
-  if (aToWindow) {
-    nsCOMPtr<nsIPresShell> presShell;
-    nsView* view = GetViewToDispatchEvent(presContext, getter_AddRefs(presShell));
-    if (!presShell || !view) {
-      return NS_ERROR_FAILURE;
-    }
-    return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
-  }
-  if (gfxPrefs::TestEventsAsyncEnabled()) {
-    status = widget->DispatchInputEvent(&event);
-  } else {
-    nsresult rv = widget->DispatchEvent(&event, status);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-  if (aPreventDefault) {
-    *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
-  }
-
-  return NS_OK;
+  nsCOMPtr<nsIPresShell> presShell = GetPresShell();
+  return nsContentUtils::SendMouseEvent(presShell, aType, aX, aY, aButton,
+      aClickCount, aModifiers, aIgnoreRootScrollFrame, aPressure,
+      aInputSourceArg, aToWindow, aPreventDefault, aIsSynthesized);
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SendPointerEventCommon(const nsAString& aType,
                                          float aX,
                                          float aY,
                                          int32_t aButton,
                                          int32_t aClickCount,
@@ -859,19 +700,19 @@ nsDOMWindowUtils::SendPointerEventCommon
     return NS_ERROR_FAILURE;
   }
 
   if (aInputSourceArg == nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN) {
     aInputSourceArg = nsIDOMMouseEvent::MOZ_SOURCE_MOUSE;
   }
 
   WidgetPointerEvent event(true, msg, widget);
-  event.modifiers = GetWidgetModifiers(aModifiers);
+  event.modifiers = nsContentUtils::GetWidgetModifiers(aModifiers);
   event.button = aButton;
-  event.buttons = GetButtonsFlagForButton(aButton);
+  event.buttons = nsContentUtils::GetButtonsFlagForButton(aButton);
   event.widget = widget;
   event.pressure = aPressure;
   event.inputSource = aInputSourceArg;
   event.pointerId = aPointerId;
   event.width = aWidth;
   event.height = aHeight;
   event.tiltX = aTiltX;
   event.tiltY = aTiltY;
@@ -880,23 +721,23 @@ nsDOMWindowUtils::SendPointerEventCommon
   event.time = PR_IntervalNow();
   event.mFlags.mIsSynthesizedForTests = aOptionalArgCount >= 10 ? aIsSynthesized : true;
 
   nsPresContext* presContext = GetPresContext();
   if (!presContext) {
     return NS_ERROR_FAILURE;
   }
 
-  event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
+  event.refPoint = nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
   event.ignoreRootScrollFrame = aIgnoreRootScrollFrame;
 
   nsEventStatus status;
   if (aToWindow) {
     nsCOMPtr<nsIPresShell> presShell;
-    nsView* view = GetViewToDispatchEvent(presContext, getter_AddRefs(presShell));
+    nsView* view = nsContentUtils::GetViewToDispatchEvent(presContext, getter_AddRefs(presShell));
     if (!presShell || !view) {
       return NS_ERROR_FAILURE;
     }
     status = nsEventStatus_eIgnore;
     return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
   }
   nsresult rv = widget->DispatchEvent(&event, status);
   if (aPreventDefault) {
@@ -984,17 +825,17 @@ nsDOMWindowUtils::SendWheelEvent(float a
   // get the widget to send the event to
   nsPoint offset;
   nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
   if (!widget) {
     return NS_ERROR_NULL_POINTER;
   }
 
   WidgetWheelEvent wheelEvent(true, NS_WHEEL_WHEEL, widget);
-  wheelEvent.modifiers = GetWidgetModifiers(aModifiers);
+  wheelEvent.modifiers = nsContentUtils::GetWidgetModifiers(aModifiers);
   wheelEvent.deltaX = aDeltaX;
   wheelEvent.deltaY = aDeltaY;
   wheelEvent.deltaZ = aDeltaZ;
   wheelEvent.deltaMode = aDeltaMode;
   wheelEvent.isMomentum =
     (aOptions & WHEEL_EVENT_CAUSED_BY_MOMENTUM) != 0;
   wheelEvent.mIsNoLineOrPageDelta =
     (aOptions & WHEEL_EVENT_CAUSED_BY_NO_LINE_OR_PAGE_DELTA_DEVICE) != 0;
@@ -1004,17 +845,17 @@ nsDOMWindowUtils::SendWheelEvent(float a
   wheelEvent.lineOrPageDeltaY = aLineOrPageDeltaY;
   wheelEvent.widget = widget;
 
   wheelEvent.time = PR_Now() / 1000;
 
   nsPresContext* presContext = GetPresContext();
   NS_ENSURE_TRUE(presContext, NS_ERROR_FAILURE);
 
-  wheelEvent.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
+  wheelEvent.refPoint = nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
 
   widget->DispatchAPZAwareEvent(&wheelEvent);
 
   if (gfxPrefs::AsyncPanZoomEnabled()) {
     // Computing overflow deltas is not compatible with APZ, so if APZ is
     // enabled, we skip testing it.
     return NS_OK;
   }
@@ -1131,40 +972,40 @@ nsDOMWindowUtils::SendTouchEventCommon(c
   } else if (aType.EqualsLiteral("touchend")) {
     msg = NS_TOUCH_END;
   } else if (aType.EqualsLiteral("touchcancel")) {
     msg = NS_TOUCH_CANCEL;
   } else {
     return NS_ERROR_UNEXPECTED;
   }
   WidgetTouchEvent event(true, msg, widget);
-  event.modifiers = GetWidgetModifiers(aModifiers);
+  event.modifiers = nsContentUtils::GetWidgetModifiers(aModifiers);
   event.widget = widget;
   event.time = PR_Now();
 
   nsPresContext* presContext = GetPresContext();
   if (!presContext) {
     return NS_ERROR_FAILURE;
   }
   event.touches.SetCapacity(aCount);
   for (uint32_t i = 0; i < aCount; ++i) {
     LayoutDeviceIntPoint pt =
-      ToWidgetPoint(CSSPoint(aXs[i], aYs[i]), offset, presContext);
+      nsContentUtils::ToWidgetPoint(CSSPoint(aXs[i], aYs[i]), offset, presContext);
     nsRefPtr<Touch> t = new Touch(aIdentifiers[i],
                                   pt,
                                   nsIntPoint(aRxs[i], aRys[i]),
                                   aRotationAngles[i],
                                   aForces[i]);
     event.touches.AppendElement(t);
   }
 
   nsEventStatus status;
   if (aToWindow) {
     nsCOMPtr<nsIPresShell> presShell;
-    nsView* view = GetViewToDispatchEvent(presContext, getter_AddRefs(presShell));
+    nsView* view = nsContentUtils::GetViewToDispatchEvent(presContext, getter_AddRefs(presShell));
     if (!presShell || !view) {
       return NS_ERROR_FAILURE;
     }
     status = nsEventStatus_eIgnore;
     *aPreventDefault = (status == nsEventStatus_eConsumeNoDefault);
     return presShell->HandleEvent(view->GetFrame(), &event, false, &status);
   }
 
@@ -1180,110 +1021,20 @@ nsDOMWindowUtils::SendKeyEvent(const nsA
                                int32_t aModifiers,
                                uint32_t aAdditionalFlags,
                                bool* aDefaultActionTaken)
 {
   MOZ_RELEASE_ASSERT(nsContentUtils::IsCallerChrome());
 
   // get the widget to send the event to
   nsCOMPtr<nsIWidget> widget = GetWidget();
-  if (!widget)
-    return NS_ERROR_FAILURE;
-
-  int32_t msg;
-  if (aType.EqualsLiteral("keydown"))
-    msg = NS_KEY_DOWN;
-  else if (aType.EqualsLiteral("keyup"))
-    msg = NS_KEY_UP;
-  else if (aType.EqualsLiteral("keypress"))
-    msg = NS_KEY_PRESS;
-  else
-    return NS_ERROR_FAILURE;
-
-  WidgetKeyboardEvent event(true, msg, widget);
-  event.modifiers = GetWidgetModifiers(aModifiers);
-
-  if (msg == NS_KEY_PRESS) {
-    event.keyCode = aCharCode ? 0 : aKeyCode;
-    event.charCode = aCharCode;
-  } else {
-    event.keyCode = aKeyCode;
-    event.charCode = 0;
-  }
-
-  uint32_t locationFlag = (aAdditionalFlags &
-    (KEY_FLAG_LOCATION_STANDARD | KEY_FLAG_LOCATION_LEFT |
-     KEY_FLAG_LOCATION_RIGHT | KEY_FLAG_LOCATION_NUMPAD));
-  switch (locationFlag) {
-    case KEY_FLAG_LOCATION_STANDARD:
-      event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD;
-      break;
-    case KEY_FLAG_LOCATION_LEFT:
-      event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT;
-      break;
-    case KEY_FLAG_LOCATION_RIGHT:
-      event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_RIGHT;
-      break;
-    case KEY_FLAG_LOCATION_NUMPAD:
-      event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD;
-      break;
-    default:
-      if (locationFlag != 0) {
-        return NS_ERROR_INVALID_ARG;
-      }
-      // If location flag isn't set, choose the location from keycode.
-      switch (aKeyCode) {
-        case nsIDOMKeyEvent::DOM_VK_NUMPAD0:
-        case nsIDOMKeyEvent::DOM_VK_NUMPAD1:
-        case nsIDOMKeyEvent::DOM_VK_NUMPAD2:
-        case nsIDOMKeyEvent::DOM_VK_NUMPAD3:
-        case nsIDOMKeyEvent::DOM_VK_NUMPAD4:
-        case nsIDOMKeyEvent::DOM_VK_NUMPAD5:
-        case nsIDOMKeyEvent::DOM_VK_NUMPAD6:
-        case nsIDOMKeyEvent::DOM_VK_NUMPAD7:
-        case nsIDOMKeyEvent::DOM_VK_NUMPAD8:
-        case nsIDOMKeyEvent::DOM_VK_NUMPAD9:
-        case nsIDOMKeyEvent::DOM_VK_MULTIPLY:
-        case nsIDOMKeyEvent::DOM_VK_ADD:
-        case nsIDOMKeyEvent::DOM_VK_SEPARATOR:
-        case nsIDOMKeyEvent::DOM_VK_SUBTRACT:
-        case nsIDOMKeyEvent::DOM_VK_DECIMAL:
-        case nsIDOMKeyEvent::DOM_VK_DIVIDE:
-          event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_NUMPAD;
-          break;
-        case nsIDOMKeyEvent::DOM_VK_SHIFT:
-        case nsIDOMKeyEvent::DOM_VK_CONTROL:
-        case nsIDOMKeyEvent::DOM_VK_ALT:
-        case nsIDOMKeyEvent::DOM_VK_META:
-          event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_LEFT;
-          break;
-        default:
-          event.location = nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD;
-          break;
-      }
-      break;
-  }
-
-  event.refPoint.x = event.refPoint.y = 0;
-  event.time = PR_IntervalNow();
-  if (!(aAdditionalFlags & KEY_FLAG_NOT_SYNTHESIZED_FOR_TESTS)) {
-    event.mFlags.mIsSynthesizedForTests = true;
-  }
-
-  if (aAdditionalFlags & KEY_FLAG_PREVENT_DEFAULT) {
-    event.mFlags.mDefaultPrevented = true;
-  }
-
-  nsEventStatus status;
-  nsresult rv = widget->DispatchEvent(&event, status);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  *aDefaultActionTaken = (status != nsEventStatus_eConsumeNoDefault);
   
-  return NS_OK;
+  return nsContentUtils::SendKeyEvent(widget, aType, aKeyCode, aCharCode,
+                                      aModifiers, aAdditionalFlags,
+                                      aDefaultActionTaken);
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::SendNativeKeyEvent(int32_t aNativeKeyboardLayout,
                                      int32_t aNativeKeyCode,
                                      int32_t aModifiers,
                                      const nsAString& aCharacters,
                                      const nsAString& aUnmodifiedCharacters,
@@ -1446,21 +1197,17 @@ nsDOMWindowUtils::ForceUpdateNativeMenuA
 nsIWidget*
 nsDOMWindowUtils::GetWidget(nsPoint* aOffset)
 {
   nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow);
   if (window) {
     nsIDocShell *docShell = window->GetDocShell();
     if (docShell) {
       nsCOMPtr<nsIPresShell> presShell = docShell->GetPresShell();
-      if (presShell) {
-        nsIFrame* frame = presShell->GetRootFrame();
-        if (frame)
-          return frame->GetView()->GetNearestWidget(aOffset);
-      }
+      return nsContentUtils::GetWidget(presShell, aOffset);
     }
   }
 
   return nullptr;
 }
 
 nsIWidget*
 nsDOMWindowUtils::GetWidgetForElement(nsIDOMElement* aElement)
@@ -1582,27 +1329,27 @@ nsDOMWindowUtils::SendSimpleGestureEvent
   else if (aType.EqualsLiteral("MozEdgeUICanceled"))
     msg = NS_SIMPLE_GESTURE_EDGE_CANCELED;
   else if (aType.EqualsLiteral("MozEdgeUICompleted"))
     msg = NS_SIMPLE_GESTURE_EDGE_COMPLETED;
   else
     return NS_ERROR_FAILURE;
  
   WidgetSimpleGestureEvent event(true, msg, widget);
-  event.modifiers = GetWidgetModifiers(aModifiers);
+  event.modifiers = nsContentUtils::GetWidgetModifiers(aModifiers);
   event.direction = aDirection;
   event.delta = aDelta;
   event.clickCount = aClickCount;
   event.time = PR_IntervalNow();
 
   nsPresContext* presContext = GetPresContext();
   if (!presContext)
     return NS_ERROR_FAILURE;
 
-  event.refPoint = ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
+  event.refPoint = nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, presContext);
 
   nsEventStatus status;
   return widget->DispatchEvent(&event, status);
 }
 
 NS_IMETHODIMP
 nsDOMWindowUtils::ElementFromPoint(float aX, float aY,
                                    bool aIgnoreRootScrollFrame,
@@ -3381,17 +3128,17 @@ nsDOMWindowUtils::SelectAtPoint(float aX
   if (!rootFrame) {
     return NS_ERROR_UNEXPECTED;
   }
 
   // Get the target frame at the client coordinates passed to us
   nsPoint offset;
   nsCOMPtr<nsIWidget> widget = GetWidget(&offset);
   LayoutDeviceIntPoint pt =
-    ToWidgetPoint(CSSPoint(aX, aY), offset, GetPresContext());
+    nsContentUtils::ToWidgetPoint(CSSPoint(aX, aY), offset, GetPresContext());
   nsPoint ptInRoot =
     nsLayoutUtils::GetEventCoordinatesRelativeTo(widget, pt, rootFrame);
   nsIFrame* targetFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, ptInRoot);
   // This can happen if the page hasn't loaded yet or if the point
   // is outside the frame.
   if (!targetFrame) {
     return NS_ERROR_INVALID_ARG;
   }
--- a/dom/base/nsDOMWindowUtils.h
+++ b/dom/base/nsDOMWindowUtils.h
@@ -76,18 +76,16 @@ protected:
   nsIWidget* GetWidget(nsPoint* aOffset = nullptr);
   nsIWidget* GetWidgetForElement(nsIDOMElement* aElement);
 
   nsIPresShell* GetPresShell();
   nsPresContext* GetPresContext();
   nsIDocument* GetDocument();
   mozilla::layers::LayerTransactionChild* GetLayerTransaction();
 
-  nsView* GetViewToDispatchEvent(nsPresContext* presContext, nsIPresShell** presShell);
-
   NS_IMETHOD SendMouseEventCommon(const nsAString& aType,
                                   float aX,
                                   float aY,
                                   int32_t aButton,
                                   int32_t aClickCount,
                                   int32_t aModifiers,
                                   bool aIgnoreRootScrollFrame,
                                   float aPressure,
@@ -124,13 +122,11 @@ protected:
                                   uint32_t* aRys,
                                   float* aRotationAngles,
                                   float* aForces,
                                   uint32_t aCount,
                                   int32_t aModifiers,
                                   bool aIgnoreRootScrollFrame,
                                   bool aToWindow,
                                   bool* aPreventDefault);
-
-  static mozilla::Modifiers GetWidgetModifiers(int32_t aModifiers);
 };
 
 #endif