Bug 912956 part.4 Create mozilla/TextEvents.h r=roc
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 24 Sep 2013 19:04:15 +0900
changeset 162245 ff21dedcf8e743db1ebc461d34a10601e8a3e664
parent 162244 70bbbaa3c1d0c2fab1e5c201b6a1c3472f42613e
child 162246 354ac52e532516e169ff2769bedcf6e57cfcbcc5
push id3066
push userakeybl@mozilla.com
push dateMon, 09 Dec 2013 19:58:46 +0000
treeherdermozilla-beta@a31a0dce83aa [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc
bugs912956
milestone27.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 912956 part.4 Create mozilla/TextEvents.h r=roc
content/base/public/nsISelectionPrivate.idl
content/events/public/nsIPrivateTextRange.h
content/events/src/nsPrivateTextRange.h
toolkit/xre/nsAppRunner.cpp
widget/BasicEvents.h
widget/EventForwards.h
widget/TextEvents.h
widget/moz.build
widget/nsGUIEvent.h
--- a/content/base/public/nsISelectionPrivate.idl
+++ b/content/base/public/nsISelectionPrivate.idl
@@ -8,22 +8,22 @@
 interface nsRange;
 interface nsIDOMNode;
 interface nsISelectionListener;
 interface nsIContent;
 interface nsINode;
 
 %{C++
 class nsIFrame;
-struct nsTextRangeStyle;
 struct nsPoint;
 struct ScrollAxis;
 template<class T> class nsTArray;
 #include "nsDirection.h"
 #include "nsIPresShell.h" // TODO: Remove this include
+#include "mozilla/EventForwards.h"
 %}
 
 [ptr] native nsIFrame(nsIFrame);
 [ptr] native RangeArray(nsTArray<nsRange*>);
 [ref] native constTextRangeStyleRef(const nsTextRangeStyle);
 [ref] native nsPointRef(nsPoint);
 native nsDirection(nsDirection);
 native ScrollAxis(nsIPresShell::ScrollAxis);
--- a/content/events/public/nsIPrivateTextRange.h
+++ b/content/events/public/nsIPrivateTextRange.h
@@ -4,17 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsIPrivateTextRange_h__
 #define nsIPrivateTextRange_h__
 
 #include "nsISupports.h"
 #include "nsString.h"
 #include "nsCOMPtr.h"
-#include "nsGUIEvent.h"
+#include "mozilla/EventForwards.h"
 
 #define NS_IPRIVATETEXTRANGE_IID \
 { 0xf795a44d, 0x413a, 0x4c63, \
   { 0xa6, 0xb0, 0x7a, 0xa3, 0x0c, 0xf5, 0xe9, 0xe0 } }
 
 class nsIPrivateTextRange : public nsISupports {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRIVATETEXTRANGE_IID)
--- a/content/events/src/nsPrivateTextRange.h
+++ b/content/events/src/nsPrivateTextRange.h
@@ -5,16 +5,17 @@
 
 #ifndef nsPrivateTextRange_h__
 #define nsPrivateTextRange_h__
 
 #include "nsIPrivateTextRange.h"
 #include "nsTArray.h"
 #include "nsAutoPtr.h"
 #include "mozilla/Attributes.h"
+#include "mozilla/TextEvents.h"
 
 class nsPrivateTextRange MOZ_FINAL : public nsIPrivateTextRange
 {
 	NS_DECL_ISUPPORTS
 public:
 
 	nsPrivateTextRange(const nsTextRange &aTextRange);
 	virtual ~nsPrivateTextRange(void);
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -90,20 +90,16 @@
 #include "nsIBaseWindow.h"
 #include "nsIWidget.h"
 #include "nsIDocShell.h"
 #include "nsAppShellCID.h"
 #include "mozilla/scache/StartupCache.h"
 
 #include "mozilla/unused.h"
 
-using namespace mozilla;
-using mozilla::unused;
-using mozilla::scache::StartupCache;
-
 #ifdef XP_WIN
 #include "nsIWinAppHelper.h"
 #include <windows.h>
 #include "cairo/cairo-features.h"
 #ifdef MOZ_METRO
 #include <roapi.h>
 #endif
 
@@ -243,16 +239,19 @@ static char **gQtOnlyArgv;
 #ifdef MOZ_LINKER
 extern "C" MFBT_API bool IsSignalHandlingBroken();
 #endif
 
 namespace mozilla {
 int (*RunGTest)() = 0;
 }
 
+using namespace mozilla;
+using mozilla::unused;
+using mozilla::scache::StartupCache;
 using mozilla::dom::ContentParent;
 using mozilla::dom::ContentChild;
 
 // Save literal putenv string to environment variable.
 static void
 SaveToEnv(const char *putenv)
 {
   char *expr = strdup(putenv);
--- a/widget/BasicEvents.h
+++ b/widget/BasicEvents.h
@@ -24,36 +24,34 @@
 enum nsEventStructType
 {
   // BasicEvents.h
   NS_EVENT,                          // WidgetEvent
   NS_GUI_EVENT,                      // WidgetGUIEvent
   NS_INPUT_EVENT,                    // WidgetInputEvent
   NS_UI_EVENT,                       // InternalUIEvent
 
+  // TextEvents.h
+  NS_KEY_EVENT,                      // WidgetKeyboardEvent
+  NS_COMPOSITION_EVENT,              // WidgetCompositionEvent
+  NS_TEXT_EVENT,                     // WidgetTextEvent
+  NS_QUERY_CONTENT_EVENT,            // WidgetQueryContentEvent
+  NS_SELECTION_EVENT,                // WidgetSelectionEvent
+
   // Mouse related events
   NS_MOUSE_EVENT,                    // nsMouseEvent
   NS_MOUSE_SCROLL_EVENT,             // nsMouseScrollEvent
   NS_DRAG_EVENT,                     // nsDragEvent
   NS_WHEEL_EVENT,                    // WheelEvent
 
   // Touchpad related events
   NS_GESTURENOTIFY_EVENT,            // nsGestureNotifyEvent
   NS_SIMPLE_GESTURE_EVENT,           // nsSimpleGestureEvent
   NS_TOUCH_EVENT,                    // nsTouchEvent
 
-  // Key or IME events
-  NS_KEY_EVENT,                      // nsKeyEvent
-  NS_COMPOSITION_EVENT,              // nsCompositionEvent
-  NS_TEXT_EVENT,                     // nsTextEvent
-
-  // IME related events
-  NS_QUERY_CONTENT_EVENT,            // nsQueryContentEvent
-  NS_SELECTION_EVENT,                // nsSelectionEvent
-
   // Scroll related events
   NS_SCROLLPORT_EVENT,               // nsScrollPortEvent
   NS_SCROLLAREA_EVENT,               // nsScrollAreaEvent
 
   // DOM events
   NS_SCRIPT_ERROR_EVENT,             // nsScriptErrorEvent
   NS_MUTATION_EVENT,                 // nsMutationEvent
   NS_FORM_EVENT,                     // nsFormEvent
--- a/widget/EventForwards.h
+++ b/widget/EventForwards.h
@@ -52,28 +52,30 @@ enum KeyNameIndex
 // BasicEvents.h
 namespace mozilla {
 struct EventFlags;
 
 class WidgetEvent;
 class WidgetGUIEvent;
 class WidgetInputEvent;
 class InternalUIEvent;
-} // namespace mozilla
 
 // TextEvents.h
-struct nsAlternativeCharCode;
-struct nsTextRangeStyle;
-struct nsTextRange;
+struct AlternativeCharCode;
+struct TextRangeStyle;
+struct TextRange;
+
+typedef TextRange* TextRangeArray;
 
-class nsKeyEvent;
-class nsTextEvent;
-class nsCompositionEvent;
-class nsQueryContentEvent;
-class nsSelectionEvent;
+class WidgetKeyboardEvent;
+class WidgetTextEvent;
+class WidgetCompositionEvent;
+class WidgetQueryContentEvent;
+class WidgetSelectionEvent;
+} // namespace mozilla
 
 // MouseEvents.h
 class nsMouseEvent_base;
 class nsMouseEvent;
 class nsDragEvent;
 class nsMouseScrollEvent;
 
 namespace mozilla {
@@ -99,14 +101,23 @@ class nsAnimationEvent;
 class nsCommandEvent;
 class nsContentCommandEvent;
 class nsPluginEvent;
 
 // content/events/public/nsMutationEvent.h
 class nsMutationEvent;
 
 // TODO: Remove following typedefs
-typedef mozilla::WidgetEvent      nsEvent;
-typedef mozilla::WidgetGUIEvent   nsGUIEvent;
-typedef mozilla::WidgetInputEvent nsInputEvent;
-typedef mozilla::InternalUIEvent  nsUIEvent;
+typedef mozilla::WidgetEvent              nsEvent;
+typedef mozilla::WidgetGUIEvent           nsGUIEvent;
+typedef mozilla::WidgetInputEvent         nsInputEvent;
+typedef mozilla::InternalUIEvent          nsUIEvent;
+typedef mozilla::AlternativeCharCode      nsAlternativeCharCode;
+typedef mozilla::WidgetKeyboardEvent      nsKeyEvent;
+typedef mozilla::TextRangeStyle           nsTextRangeStyle;
+typedef mozilla::TextRange                nsTextRange;
+typedef mozilla::TextRangeArray           nsTextRangeArray;
+typedef mozilla::WidgetTextEvent          nsTextEvent;
+typedef mozilla::WidgetCompositionEvent   nsCompositionEvent;
+typedef mozilla::WidgetQueryContentEvent  nsQueryContentEvent;
+typedef mozilla::WidgetSelectionEvent     nsSelectionEvent;
 
 #endif // mozilla_EventForwards_h__
new file mode 100644
--- /dev/null
+++ b/widget/TextEvents.h
@@ -0,0 +1,547 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_TextEvents_h__
+#define mozilla_TextEvents_h__
+
+#include <stdint.h>
+
+#include "mozilla/Assertions.h"
+#include "mozilla/BasicEvents.h"
+#include "mozilla/EventForwards.h" // for KeyNameIndex, temporarily
+#include "nsColor.h"
+#include "nsCOMPtr.h"
+#include "nsIDOMKeyEvent.h"
+#include "nsITransferable.h"
+#include "nsRect.h"
+#include "nsStringGlue.h"
+#include "nsStyleConsts.h"
+#include "nsTArray.h"
+
+/******************************************************************************
+ * virtual keycode values
+ ******************************************************************************/
+
+#define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) NS_##aDOMKeyName = aDOMKeyCode
+
+enum
+{
+#include "nsVKList.h"
+};
+
+#undef NS_DEFINE_VK
+
+namespace mozilla {
+
+namespace dom {
+  class PBrowserParent;
+  class PBrowserChild;
+} // namespace dom
+namespace plugins {
+  class PPluginInstanceChild;
+} // namespace plugins
+
+/******************************************************************************
+ * mozilla::AlternativeCharCode
+ *
+ * This stores alternative charCode values of a key event with some modifiers.
+ * The stored values proper for testing shortcut key or access key.
+ ******************************************************************************/
+
+struct AlternativeCharCode
+{
+  AlternativeCharCode(uint32_t aUnshiftedCharCode, uint32_t aShiftedCharCode) :
+    mUnshiftedCharCode(aUnshiftedCharCode), mShiftedCharCode(aShiftedCharCode)
+  {
+  }
+  uint32_t mUnshiftedCharCode;
+  uint32_t mShiftedCharCode;
+};
+
+/******************************************************************************
+ * mozilla::WidgetKeyboardEvent
+ ******************************************************************************/
+
+class WidgetKeyboardEvent : public WidgetInputEvent
+{
+private:
+  friend class dom::PBrowserParent;
+  friend class dom::PBrowserChild;
+
+public:
+  WidgetKeyboardEvent()
+  {
+  }
+
+  WidgetKeyboardEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget) :
+    WidgetInputEvent(aIsTrusted, aMessage, aWidget, NS_KEY_EVENT),
+    keyCode(0), charCode(0),
+    location(nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD), isChar(0),
+    mKeyNameIndex(mozilla::KEY_NAME_INDEX_Unidentified),
+    mNativeKeyEvent(nullptr),
+    mUniqueId(0)
+  {
+  }
+
+  // A DOM keyCode value or 0.  If a keypress event whose charCode is 0, this
+  // should be 0.
+  uint32_t keyCode;
+  // If the instance is a keypress event of a printable key, this is a UTF-16
+  // value of the key.  Otherwise, 0.  This value must not be a control
+  // character when some modifiers are active.  Then, this value should be an
+  // unmodified value except Shift and AltGr.
+  uint32_t charCode;
+  // One of nsIDOMKeyEvent::DOM_KEY_LOCATION_*
+  uint32_t location;
+  // OS translated Unicode chars which are used for accesskey and accelkey
+  // handling. The handlers will try from first character to last character.
+  nsTArray<AlternativeCharCode> alternativeCharCodes;
+  // Indicates whether the event signifies a printable character
+  bool isChar;
+  // DOM KeyboardEvent.key
+  KeyNameIndex mKeyNameIndex;
+  // OS-specific native event can optionally be preserved
+  void* mNativeKeyEvent;
+  // Unique id associated with a keydown / keypress event. Used in identifing
+  // keypress events for removal from async event dispatch queue in metrofx
+  // after preventDefault is called on keydown events. It's ok if this wraps
+  // over long periods.
+  uint32_t mUniqueId;
+
+  void GetDOMKeyName(nsAString& aKeyName)
+  {
+    GetDOMKeyName(mKeyNameIndex, aKeyName);
+  }
+
+  static void GetDOMKeyName(mozilla::KeyNameIndex aKeyNameIndex,
+                            nsAString& aKeyName)
+  {
+#define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \
+      case KEY_NAME_INDEX_##aCPPName: \
+        aKeyName.Assign(NS_LITERAL_STRING(aDOMKeyName)); return;
+    switch (aKeyNameIndex) {
+#include "nsDOMKeyNameList.h"
+      default:
+        aKeyName.Truncate();
+        return;
+    }
+#undef NS_DEFINE_KEYNAME
+  }
+
+  void AssignKeyEventData(const WidgetKeyboardEvent& aEvent, bool aCopyTargets)
+  {
+    AssignInputEventData(aEvent, aCopyTargets);
+
+    keyCode = aEvent.keyCode;
+    charCode = aEvent.charCode;
+    location = aEvent.location;
+    alternativeCharCodes = aEvent.alternativeCharCodes;
+    isChar = aEvent.isChar;
+    mKeyNameIndex = aEvent.mKeyNameIndex;
+    // Don't copy mNativeKeyEvent because it may be referred after its instance
+    // is destroyed.
+    mNativeKeyEvent = nullptr;
+    mUniqueId = aEvent.mUniqueId;
+  }
+};
+
+/******************************************************************************
+ * mozilla::TextRangeStyle
+ ******************************************************************************/
+
+struct TextRangeStyle
+{
+  enum {
+    LINESTYLE_NONE   = NS_STYLE_TEXT_DECORATION_STYLE_NONE,
+    LINESTYLE_SOLID  = NS_STYLE_TEXT_DECORATION_STYLE_SOLID,
+    LINESTYLE_DOTTED = NS_STYLE_TEXT_DECORATION_STYLE_DOTTED,
+    LINESTYLE_DASHED = NS_STYLE_TEXT_DECORATION_STYLE_DASHED,
+    LINESTYLE_DOUBLE = NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE,
+    LINESTYLE_WAVY   = NS_STYLE_TEXT_DECORATION_STYLE_WAVY
+  };
+
+  enum {
+    DEFINED_NONE             = 0x00,
+    DEFINED_LINESTYLE        = 0x01,
+    DEFINED_FOREGROUND_COLOR = 0x02,
+    DEFINED_BACKGROUND_COLOR = 0x04,
+    DEFINED_UNDERLINE_COLOR  = 0x08
+  };
+
+  // Initialize all members, because TextRange instances may be compared by
+  // memcomp.
+  TextRangeStyle()
+  {
+    Clear();
+  }
+
+  void Clear()
+  {
+    mDefinedStyles = DEFINED_NONE;
+    mLineStyle = LINESTYLE_NONE;
+    mIsBoldLine = false;
+    mForegroundColor = mBackgroundColor = mUnderlineColor = NS_RGBA(0, 0, 0, 0);
+  }
+
+  bool IsDefined() const { return mDefinedStyles != DEFINED_NONE; }
+
+  bool IsLineStyleDefined() const
+  {
+    return (mDefinedStyles & DEFINED_LINESTYLE) != 0;
+  }
+
+  bool IsForegroundColorDefined() const
+  {
+    return (mDefinedStyles & DEFINED_FOREGROUND_COLOR) != 0;
+  }
+
+  bool IsBackgroundColorDefined() const
+  {
+    return (mDefinedStyles & DEFINED_BACKGROUND_COLOR) != 0;
+  }
+
+  bool IsUnderlineColorDefined() const
+  {
+    return (mDefinedStyles & DEFINED_UNDERLINE_COLOR) != 0;
+  }
+
+  bool IsNoChangeStyle() const
+  {
+    return !IsForegroundColorDefined() && !IsBackgroundColorDefined() &&
+           IsLineStyleDefined() && mLineStyle == LINESTYLE_NONE;
+  }
+
+  bool Equals(const nsTextRangeStyle& aOther)
+  {
+    if (mDefinedStyles != aOther.mDefinedStyles)
+      return false;
+    if (IsLineStyleDefined() && (mLineStyle != aOther.mLineStyle ||
+                                 !mIsBoldLine != !aOther.mIsBoldLine))
+      return false;
+    if (IsForegroundColorDefined() &&
+        (mForegroundColor != aOther.mForegroundColor))
+      return false;
+    if (IsBackgroundColorDefined() &&
+        (mBackgroundColor != aOther.mBackgroundColor))
+      return false;
+    if (IsUnderlineColorDefined() &&
+        (mUnderlineColor != aOther.mUnderlineColor))
+      return false;
+    return true;
+  }
+
+  bool operator !=(const TextRangeStyle &aOther)
+  {
+    return !Equals(aOther);
+  }
+
+  bool operator ==(const TextRangeStyle &aOther)
+  {
+    return Equals(aOther);
+  }
+
+  uint8_t mDefinedStyles;
+  uint8_t mLineStyle;        // DEFINED_LINESTYLE
+
+  bool mIsBoldLine;  // DEFINED_LINESTYLE
+
+  nscolor mForegroundColor;  // DEFINED_FOREGROUND_COLOR
+  nscolor mBackgroundColor;  // DEFINED_BACKGROUND_COLOR
+  nscolor mUnderlineColor;   // DEFINED_UNDERLINE_COLOR
+};
+
+/******************************************************************************
+ * mozilla::TextRange
+ ******************************************************************************/
+
+// Sync with nsIPrivateTextRange.h when you change these constants.
+#define NS_TEXTRANGE_CARETPOSITION         0x01
+#define NS_TEXTRANGE_RAWINPUT              0x02
+#define NS_TEXTRANGE_SELECTEDRAWTEXT       0x03
+#define NS_TEXTRANGE_CONVERTEDTEXT         0x04
+#define NS_TEXTRANGE_SELECTEDCONVERTEDTEXT 0x05
+
+struct TextRange
+{
+  TextRange() :
+    mStartOffset(0), mEndOffset(0), mRangeType(0)
+  {
+  }
+
+  uint32_t mStartOffset;
+  // XXX Storing end offset makes the initializing code very complicated.
+  //     We should replace it with mLength.
+  uint32_t mEndOffset;
+  uint32_t mRangeType;
+
+  TextRangeStyle mRangeStyle;
+
+  uint32_t Length() const { return mEndOffset - mStartOffset; }
+};
+
+/******************************************************************************
+ * mozilla::TextRangeArray
+ *
+ * XXX This should be replaced with nsTArray<TextRange>.
+ ******************************************************************************/
+
+typedef TextRange* TextRangeArray;
+
+/******************************************************************************
+ * mozilla::WidgetTextEvent
+ *
+ * XXX WidgetTextEvent is fired with compositionupdate event almost every time.
+ *     This wastes performance and the cost of mantaining each platform's
+ *     implementation.  Therefore, we should merge WidgetTextEvent and
+ *     WidgetCompositionEvent.  Then, DOM compositionupdate should be fired
+ *     from TextComposition automatically.
+ ******************************************************************************/
+
+class WidgetTextEvent : public WidgetGUIEvent
+{
+private:
+  friend class dom::PBrowserParent;
+  friend class dom::PBrowserChild;
+  friend class plugins::PPluginInstanceChild;
+
+  WidgetTextEvent()
+  {
+  }
+
+public:
+  uint32_t seqno;
+
+public:
+  WidgetTextEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget) :
+    WidgetGUIEvent(aIsTrusted, aMessage, aWidget, NS_TEXT_EVENT),
+    rangeCount(0), rangeArray(nullptr), isChar(false)
+  {
+  }
+
+  // The composition string or the commit string.
+  nsString theText;
+  // Count of rangeArray.
+  uint32_t rangeCount;
+  // Pointer to the first item of the ranges (clauses).
+  // Note that the range array may not specify a caret position; in that
+  // case there will be no range of type NS_TEXTRANGE_CARETPOSITION in the
+  // array.
+  nsTextRangeArray rangeArray;
+  // Indicates whether the event signifies printable text.
+  // XXX This is not a standard, and most platforms don't set this properly.
+  //     So, perhaps, we can get rid of this.
+  bool isChar;
+
+  void AssignTextEventData(const WidgetTextEvent& aEvent, bool aCopyTargets)
+  {
+    AssignGUIEventData(aEvent, aCopyTargets);
+
+    isChar = aEvent.isChar;
+
+    // Currently, we don't need to copy the other members because they are
+    // for internal use only (not available from JS).
+  }
+};
+
+/******************************************************************************
+ * mozilla::WidgetCompositionEvent
+ ******************************************************************************/
+
+class WidgetCompositionEvent : public WidgetGUIEvent
+{
+private:
+  friend class mozilla::dom::PBrowserParent;
+  friend class mozilla::dom::PBrowserChild;
+
+  WidgetCompositionEvent()
+  {
+  }
+
+public:
+  uint32_t seqno;
+
+public:
+  WidgetCompositionEvent(bool aIsTrusted, uint32_t aMessage,
+                         nsIWidget* aWidget) :
+    WidgetGUIEvent(aIsTrusted, aMessage, aWidget, NS_COMPOSITION_EVENT)
+  {
+    // XXX compositionstart is cancelable in draft of DOM3 Events.
+    //     However, it doesn't make sense for us, we cannot cancel composition
+    //     when we send compositionstart event.
+    mFlags.mCancelable = false;
+  }
+
+  // The composition string or the commit string.  If the instance is a
+  // compositionstart event, this is initialized with selected text by
+  // TextComposition automatically.
+  nsString data;
+
+  void AssignCompositionEventData(const WidgetCompositionEvent& aEvent,
+                                  bool aCopyTargets)
+  {
+    AssignGUIEventData(aEvent, aCopyTargets);
+
+    data = aEvent.data;
+  }
+};
+
+/******************************************************************************
+ * mozilla::WidgetQueryContentEvent
+ ******************************************************************************/
+
+class WidgetQueryContentEvent : public WidgetGUIEvent
+{
+private:
+  friend class dom::PBrowserParent;
+  friend class dom::PBrowserChild;
+
+  WidgetQueryContentEvent()
+  {
+    MOZ_CRASH("WidgetQueryContentEvent is created without proper arguments");
+  }
+
+public:
+  WidgetQueryContentEvent(bool aIsTrusted, uint32_t aMessage,
+                          nsIWidget* aWidget) :
+    WidgetGUIEvent(aIsTrusted, aMessage, aWidget, NS_QUERY_CONTENT_EVENT),
+    mSucceeded(false), mWasAsync(false)
+  {
+  }
+
+  void InitForQueryTextContent(uint32_t aOffset, uint32_t aLength)
+  {
+    NS_ASSERTION(message == NS_QUERY_TEXT_CONTENT,
+                 "wrong initializer is called");
+    mInput.mOffset = aOffset;
+    mInput.mLength = aLength;
+  }
+
+  void InitForQueryCaretRect(uint32_t aOffset)
+  {
+    NS_ASSERTION(message == NS_QUERY_CARET_RECT,
+                 "wrong initializer is called");
+    mInput.mOffset = aOffset;
+  }
+
+  void InitForQueryTextRect(uint32_t aOffset, uint32_t aLength)
+  {
+    NS_ASSERTION(message == NS_QUERY_TEXT_RECT,
+                 "wrong initializer is called");
+    mInput.mOffset = aOffset;
+    mInput.mLength = aLength;
+  }
+
+  void InitForQueryDOMWidgetHittest(const mozilla::LayoutDeviceIntPoint& aPoint)
+  {
+    NS_ASSERTION(message == NS_QUERY_DOM_WIDGET_HITTEST,
+                 "wrong initializer is called");
+    refPoint = aPoint;
+  }
+
+  uint32_t GetSelectionStart(void) const
+  {
+    NS_ASSERTION(message == NS_QUERY_SELECTED_TEXT,
+                 "not querying selection");
+    return mReply.mOffset + (mReply.mReversed ? mReply.mString.Length() : 0);
+  }
+
+  uint32_t GetSelectionEnd(void) const
+  {
+    NS_ASSERTION(message == NS_QUERY_SELECTED_TEXT,
+                 "not querying selection");
+    return mReply.mOffset + (mReply.mReversed ? 0 : mReply.mString.Length());
+  }
+
+  bool mSucceeded;
+  bool mWasAsync;
+  struct
+  {
+    uint32_t mOffset;
+    uint32_t mLength;
+  } mInput;
+  struct
+  {
+    void* mContentsRoot;
+    uint32_t mOffset;
+    nsString mString;
+    // Finally, the coordinates is system coordinates.
+    nsIntRect mRect;
+    // The return widget has the caret. This is set at all query events.
+    nsIWidget* mFocusedWidget;
+    // true if selection is reversed (end < start)
+    bool mReversed;
+    // true if the selection exists
+    bool mHasSelection;
+    // true if DOM element under mouse belongs to widget
+    bool mWidgetIsHit;
+    // used by NS_QUERY_SELECTION_AS_TRANSFERABLE
+    nsCOMPtr<nsITransferable> mTransferable;
+  } mReply;
+
+  enum
+  {
+    NOT_FOUND = UINT32_MAX
+  };
+
+  // values of mComputedScrollAction
+  enum
+  {
+    SCROLL_ACTION_NONE,
+    SCROLL_ACTION_LINE,
+    SCROLL_ACTION_PAGE
+  };
+};
+
+/******************************************************************************
+ * mozilla::WidgetSelectionEvent
+ ******************************************************************************/
+
+class WidgetSelectionEvent : public WidgetGUIEvent
+{
+private:
+  friend class mozilla::dom::PBrowserParent;
+  friend class mozilla::dom::PBrowserChild;
+
+  WidgetSelectionEvent()
+  {
+    MOZ_CRASH("WidgetSelectionEvent is created without proper arguments");
+  }
+
+public:
+  uint32_t seqno;
+
+public:
+  WidgetSelectionEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget) :
+    WidgetGUIEvent(aIsTrusted, aMessage, aWidget, NS_SELECTION_EVENT),
+    mExpandToClusterBoundary(true), mSucceeded(false)
+  {
+  }
+
+  // Start offset of selection
+  uint32_t mOffset;
+  // Length of selection
+  uint32_t mLength;
+  // Selection "anchor" should be in front
+  bool mReversed;
+  // Cluster-based or character-based
+  bool mExpandToClusterBoundary;
+  // true if setting selection succeeded.
+  bool mSucceeded;
+};
+
+} // namespace mozilla
+
+// TODO: Remove following typedefs
+typedef mozilla::AlternativeCharCode     nsAlternativeCharCode;
+typedef mozilla::WidgetKeyboardEvent     nsKeyEvent;
+typedef mozilla::TextRangeStyle          nsTextRangeStyle;
+typedef mozilla::TextRange               nsTextRange;
+typedef mozilla::TextRangeArray          nsTextRangeArray;
+typedef mozilla::WidgetTextEvent         nsTextEvent;
+typedef mozilla::WidgetCompositionEvent  nsCompositionEvent;
+typedef mozilla::WidgetQueryContentEvent nsQueryContentEvent;
+typedef mozilla::WidgetSelectionEvent    nsSelectionEvent;
+
+#endif // mozilla_TextEvents_h__
--- a/widget/moz.build
+++ b/widget/moz.build
@@ -109,16 +109,17 @@ EXPORTS += [
     'nsWidgetInitData.h',
     'nsWidgetsCID.h',
 ]
 
 EXPORTS.mozilla += [
     'BasicEvents.h',
     'EventForwards.h',
     'LookAndFeel.h',
+    'TextEvents.h',
     'WidgetUtils.h',
 ]
 
 if CONFIG['MOZ_INSTRUMENT_EVENT_LOOP']:
     EXPORTS.mozilla += [
         'WidgetTraceEvent.h',
     ]
 
--- a/widget/nsGUIEvent.h
+++ b/widget/nsGUIEvent.h
@@ -3,27 +3,25 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef nsGUIEvent_h__
 #define nsGUIEvent_h__
 
 #include "mozilla/BasicEvents.h"
 #include "mozilla/MathAlgorithms.h"
+#include "mozilla/TextEvents.h"
 
 #include "nsPoint.h"
 #include "nsRect.h"
-#include "nsIDOMKeyEvent.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIDOMWheelEvent.h"
 #include "nsIDOMDataTransfer.h"
 #include "nsWeakPtr.h"
-#include "nsTArray.h"
 #include "nsITransferable.h"
-#include "nsStyleConsts.h"
 #include "nsAutoPtr.h"
 #include "mozilla/dom/Touch.h"
 
 namespace mozilla {
 namespace dom {
   class PBrowserParent;
   class PBrowserChild;
 }
@@ -296,306 +294,16 @@ public:
 
     dataTransfer = aEvent.dataTransfer;
     // XXX userCancelled isn't copied, is this instentionally?
     userCancelled = false;
   }
 };
 
 /**
- * Keyboard event
- */
-
-struct nsAlternativeCharCode {
-  nsAlternativeCharCode(uint32_t aUnshiftedCharCode,
-                        uint32_t aShiftedCharCode) :
-    mUnshiftedCharCode(aUnshiftedCharCode), mShiftedCharCode(aShiftedCharCode)
-  {
-  }
-  uint32_t mUnshiftedCharCode;
-  uint32_t mShiftedCharCode;
-};
-
-class nsKeyEvent : public nsInputEvent
-{
-private:
-  friend class mozilla::dom::PBrowserParent;
-  friend class mozilla::dom::PBrowserChild;
-
-public:
-  nsKeyEvent()
-  {
-  }
-
-  nsKeyEvent(bool isTrusted, uint32_t msg, nsIWidget *w)
-    : nsInputEvent(isTrusted, msg, w, NS_KEY_EVENT),
-      keyCode(0), charCode(0),
-      location(nsIDOMKeyEvent::DOM_KEY_LOCATION_STANDARD), isChar(0),
-      mKeyNameIndex(mozilla::KEY_NAME_INDEX_Unidentified),
-      mNativeKeyEvent(nullptr),
-      mUniqueId(0)
-  {
-  }
-
-  /// see NS_VK codes
-  uint32_t        keyCode;   
-  /// OS translated Unicode char
-  uint32_t        charCode;
-  // One of nsIDOMKeyEvent::DOM_KEY_LOCATION_*
-  uint32_t        location;
-  // OS translated Unicode chars which are used for accesskey and accelkey
-  // handling. The handlers will try from first character to last character.
-  nsTArray<nsAlternativeCharCode> alternativeCharCodes;
-  // indicates whether the event signifies a printable character
-  bool            isChar;
-  // DOM KeyboardEvent.key
-  mozilla::KeyNameIndex mKeyNameIndex;
-  // OS-specific native event can optionally be preserved
-  void*           mNativeKeyEvent;
-  // Unique id associated with a keydown / keypress event. Used in identifing
-  // keypress events for removal from async event dispatch queue in metrofx
-  // after preventDefault is called on keydown events. It's ok if this wraps
-  // over long periods.
-  uint32_t        mUniqueId;
-
-  void GetDOMKeyName(nsAString& aKeyName)
-  {
-    GetDOMKeyName(mKeyNameIndex, aKeyName);
-  }
-
-  static void GetDOMKeyName(mozilla::KeyNameIndex aKeyNameIndex,
-                            nsAString& aKeyName)
-  {
-#define NS_DEFINE_KEYNAME(aCPPName, aDOMKeyName) \
-      case mozilla::KEY_NAME_INDEX_##aCPPName: \
-        aKeyName.Assign(NS_LITERAL_STRING(aDOMKeyName)); return;
-    switch (aKeyNameIndex) {
-#include "nsDOMKeyNameList.h"
-      default:
-        aKeyName.Truncate();
-        return;
-    }
-#undef NS_DEFINE_KEYNAME
-  }
-
-  void AssignKeyEventData(const nsKeyEvent& aEvent, bool aCopyTargets)
-  {
-    AssignInputEventData(aEvent, aCopyTargets);
-
-    keyCode = aEvent.keyCode;
-    charCode = aEvent.charCode;
-    location = aEvent.location;
-    alternativeCharCodes = aEvent.alternativeCharCodes;
-    isChar = aEvent.isChar;
-    mKeyNameIndex = aEvent.mKeyNameIndex;
-    // Don't copy mNativeKeyEvent because it may be referred after its instance
-    // is destroyed.
-    mNativeKeyEvent = nullptr;
-    mUniqueId = aEvent.mUniqueId;
-  }
-};
-
-/**
- * IME Related Events
- */
- 
-struct nsTextRangeStyle
-{
-  enum {
-    LINESTYLE_NONE   = NS_STYLE_TEXT_DECORATION_STYLE_NONE,
-    LINESTYLE_SOLID  = NS_STYLE_TEXT_DECORATION_STYLE_SOLID,
-    LINESTYLE_DOTTED = NS_STYLE_TEXT_DECORATION_STYLE_DOTTED,
-    LINESTYLE_DASHED = NS_STYLE_TEXT_DECORATION_STYLE_DASHED,
-    LINESTYLE_DOUBLE = NS_STYLE_TEXT_DECORATION_STYLE_DOUBLE,
-    LINESTYLE_WAVY   = NS_STYLE_TEXT_DECORATION_STYLE_WAVY
-  };
-
-  enum {
-    DEFINED_NONE             = 0x00,
-    DEFINED_LINESTYLE        = 0x01,
-    DEFINED_FOREGROUND_COLOR = 0x02,
-    DEFINED_BACKGROUND_COLOR = 0x04,
-    DEFINED_UNDERLINE_COLOR  = 0x08
-  };
-
-  // Initialize all members, because nsTextRange instances may be compared by
-  // memcomp.
-  nsTextRangeStyle()
-  {
-    Clear();
-  }
-
-  void Clear()
-  {
-    mDefinedStyles = DEFINED_NONE;
-    mLineStyle = LINESTYLE_NONE;
-    mIsBoldLine = false;
-    mForegroundColor = mBackgroundColor = mUnderlineColor = NS_RGBA(0, 0, 0, 0);
-  }
-
-  bool IsDefined() const { return mDefinedStyles != DEFINED_NONE; }
-
-  bool IsLineStyleDefined() const
-  {
-    return (mDefinedStyles & DEFINED_LINESTYLE) != 0;
-  }
-
-  bool IsForegroundColorDefined() const
-  {
-    return (mDefinedStyles & DEFINED_FOREGROUND_COLOR) != 0;
-  }
-
-  bool IsBackgroundColorDefined() const
-  {
-    return (mDefinedStyles & DEFINED_BACKGROUND_COLOR) != 0;
-  }
-
-  bool IsUnderlineColorDefined() const
-  {
-    return (mDefinedStyles & DEFINED_UNDERLINE_COLOR) != 0;
-  }
-
-  bool IsNoChangeStyle() const
-  {
-    return !IsForegroundColorDefined() && !IsBackgroundColorDefined() &&
-           IsLineStyleDefined() && mLineStyle == LINESTYLE_NONE;
-  }
-
-  bool Equals(const nsTextRangeStyle& aOther)
-  {
-    if (mDefinedStyles != aOther.mDefinedStyles)
-      return false;
-    if (IsLineStyleDefined() && (mLineStyle != aOther.mLineStyle ||
-                                 !mIsBoldLine != !aOther.mIsBoldLine))
-      return false;
-    if (IsForegroundColorDefined() &&
-        (mForegroundColor != aOther.mForegroundColor))
-      return false;
-    if (IsBackgroundColorDefined() &&
-        (mBackgroundColor != aOther.mBackgroundColor))
-      return false;
-    if (IsUnderlineColorDefined() &&
-        (mUnderlineColor != aOther.mUnderlineColor))
-      return false;
-    return true;
-  }
-
-  bool operator !=(const nsTextRangeStyle &aOther)
-  {
-    return !Equals(aOther);
-  }
-
-  bool operator ==(const nsTextRangeStyle &aOther)
-  {
-    return Equals(aOther);
-  }
-
-  uint8_t mDefinedStyles;
-  uint8_t mLineStyle;        // DEFINED_LINESTYLE
-
-  bool mIsBoldLine;  // DEFINED_LINESTYLE
-
-  nscolor mForegroundColor;  // DEFINED_FOREGROUND_COLOR
-  nscolor mBackgroundColor;  // DEFINED_BACKGROUND_COLOR
-  nscolor mUnderlineColor;   // DEFINED_UNDERLINE_COLOR
-};
-
-struct nsTextRange
-{
-  nsTextRange()
-    : mStartOffset(0), mEndOffset(0), mRangeType(0)
-  {
-  }
-
-  uint32_t mStartOffset;
-  uint32_t mEndOffset;
-  uint32_t mRangeType;
-
-  nsTextRangeStyle mRangeStyle;
-
-  uint32_t Length() const { return mEndOffset - mStartOffset; }
-};
-
-typedef nsTextRange* nsTextRangeArray;
-
-class nsTextEvent : public nsGUIEvent
-{
-private:
-  friend class mozilla::dom::PBrowserParent;
-  friend class mozilla::dom::PBrowserChild;
-  friend class mozilla::plugins::PPluginInstanceChild;
-
-  nsTextEvent()
-  {
-  }
-
-public:
-  uint32_t seqno;
-
-public:
-  nsTextEvent(bool isTrusted, uint32_t msg, nsIWidget *w)
-    : nsGUIEvent(isTrusted, msg, w, NS_TEXT_EVENT),
-      rangeCount(0), rangeArray(nullptr), isChar(false)
-  {
-  }
-
-  nsString          theText;
-  uint32_t          rangeCount;
-  // Note that the range array may not specify a caret position; in that
-  // case there will be no range of type NS_TEXTRANGE_CARETPOSITION in the
-  // array.
-  nsTextRangeArray  rangeArray;
-  bool              isChar;
-
-  void AssignTextEventData(const nsTextEvent& aEvent, bool aCopyTargets)
-  {
-    AssignGUIEventData(aEvent, aCopyTargets);
-
-    isChar = aEvent.isChar;
-
-    // Currently, we don't need to copy the other members because they are
-    // for internal use only (not available from JS).
-  }
-};
-
-class nsCompositionEvent : public nsGUIEvent
-{
-private:
-  friend class mozilla::dom::PBrowserParent;
-  friend class mozilla::dom::PBrowserChild;
-
-  nsCompositionEvent()
-  {
-  }
-
-public:
-  uint32_t seqno;
-
-public:
-  nsCompositionEvent(bool isTrusted, uint32_t msg, nsIWidget *w)
-    : nsGUIEvent(isTrusted, msg, w, NS_COMPOSITION_EVENT)
-  {
-    // XXX compositionstart is cancelable in draft of DOM3 Events.
-    //     However, it doesn't make sense for us, we cannot cancel composition
-    //     when we send compositionstart event.
-    mFlags.mCancelable = false;
-  }
-
-  nsString data;
-
-  void AssignCompositionEventData(const nsCompositionEvent& aEvent,
-                                  bool aCopyTargets)
-  {
-    AssignGUIEventData(aEvent, aCopyTargets);
-
-    data = aEvent.data;
-  }
-};
-
-/**
  * nsMouseScrollEvent is used for legacy DOM mouse scroll events, i.e.,
  * DOMMouseScroll and MozMousePixelScroll event.  These events are NOT hanbled
  * by ESM even if widget dispatches them.  Use new WheelEvent instead.
  */
 
 class nsMouseScrollEvent : public nsMouseEvent_base
 {
 private:
@@ -774,138 +482,16 @@ public:
   nsGestureNotifyEvent(bool aIsTrusted, uint32_t aMsg, nsIWidget *aWidget):
     nsGUIEvent(aIsTrusted, aMsg, aWidget, NS_GESTURENOTIFY_EVENT),
     panDirection(ePanNone),
     displayPanFeedback(false)
   {
   }
 };
 
-class nsQueryContentEvent : public nsGUIEvent
-{
-private:
-  friend class mozilla::dom::PBrowserParent;
-  friend class mozilla::dom::PBrowserChild;
-
-  nsQueryContentEvent()
-  {
-    mReply.mContentsRoot = nullptr;
-    mReply.mFocusedWidget = nullptr;
-  }
-
-public:
-  nsQueryContentEvent(bool aIsTrusted, uint32_t aMsg, nsIWidget *aWidget) :
-    nsGUIEvent(aIsTrusted, aMsg, aWidget, NS_QUERY_CONTENT_EVENT),
-    mSucceeded(false), mWasAsync(false)
-  {
-  }
-
-  void InitForQueryTextContent(uint32_t aOffset, uint32_t aLength)
-  {
-    NS_ASSERTION(message == NS_QUERY_TEXT_CONTENT,
-                 "wrong initializer is called");
-    mInput.mOffset = aOffset;
-    mInput.mLength = aLength;
-  }
-
-  void InitForQueryCaretRect(uint32_t aOffset)
-  {
-    NS_ASSERTION(message == NS_QUERY_CARET_RECT,
-                 "wrong initializer is called");
-    mInput.mOffset = aOffset;
-  }
-
-  void InitForQueryTextRect(uint32_t aOffset, uint32_t aLength)
-  {
-    NS_ASSERTION(message == NS_QUERY_TEXT_RECT,
-                 "wrong initializer is called");
-    mInput.mOffset = aOffset;
-    mInput.mLength = aLength;
-  }
-
-  void InitForQueryDOMWidgetHittest(const mozilla::LayoutDeviceIntPoint& aPoint)
-  {
-    NS_ASSERTION(message == NS_QUERY_DOM_WIDGET_HITTEST,
-                 "wrong initializer is called");
-    refPoint = aPoint;
-  }
-
-  uint32_t GetSelectionStart(void) const
-  {
-    NS_ASSERTION(message == NS_QUERY_SELECTED_TEXT,
-                 "not querying selection");
-    return mReply.mOffset + (mReply.mReversed ? mReply.mString.Length() : 0);
-  }
-
-  uint32_t GetSelectionEnd(void) const
-  {
-    NS_ASSERTION(message == NS_QUERY_SELECTED_TEXT,
-                 "not querying selection");
-    return mReply.mOffset + (mReply.mReversed ? 0 : mReply.mString.Length());
-  }
-
-  bool mSucceeded;
-  bool mWasAsync;
-  struct {
-    uint32_t mOffset;
-    uint32_t mLength;
-  } mInput;
-  struct {
-    void* mContentsRoot;
-    uint32_t mOffset;
-    nsString mString;
-    nsIntRect mRect; // Finally, the coordinates is system coordinates.
-    // The return widget has the caret. This is set at all query events.
-    nsIWidget* mFocusedWidget;
-    bool mReversed; // true if selection is reversed (end < start)
-    bool mHasSelection; // true if the selection exists
-    bool mWidgetIsHit; // true if DOM element under mouse belongs to widget
-    // used by NS_QUERY_SELECTION_AS_TRANSFERABLE
-    nsCOMPtr<nsITransferable> mTransferable;
-  } mReply;
-
-  enum {
-    NOT_FOUND = UINT32_MAX
-  };
-
-  // values of mComputedScrollAction
-  enum {
-    SCROLL_ACTION_NONE,
-    SCROLL_ACTION_LINE,
-    SCROLL_ACTION_PAGE
-  };
-};
-
-class nsSelectionEvent : public nsGUIEvent
-{
-private:
-  friend class mozilla::dom::PBrowserParent;
-  friend class mozilla::dom::PBrowserChild;
-
-  nsSelectionEvent()
-  {
-  }
-
-public:
-  uint32_t seqno;
-
-public:
-  nsSelectionEvent(bool aIsTrusted, uint32_t aMsg, nsIWidget *aWidget) :
-    nsGUIEvent(aIsTrusted, aMsg, aWidget, NS_SELECTION_EVENT),
-    mExpandToClusterBoundary(true), mSucceeded(false)
-  {
-  }
-
-  uint32_t mOffset; // start offset of selection
-  uint32_t mLength; // length of selection
-  bool mReversed; // selection "anchor" should be in front
-  bool mExpandToClusterBoundary; // cluster-based or character-based
-  bool mSucceeded;
-};
-
 class nsContentCommandEvent : public nsGUIEvent
 {
 public:
   nsContentCommandEvent(bool aIsTrusted, uint32_t aMsg, nsIWidget *aWidget,
                         bool aOnlyEnabledCheck = false) :
     nsGUIEvent(aIsTrusted, aMsg, aWidget, NS_CONTENT_COMMAND_EVENT),
     mOnlyEnabledCheck(bool(aOnlyEnabledCheck)),
     mSucceeded(false), mIsEnabled(false)
@@ -1290,36 +876,16 @@ enum nsDragDropEventStatus {
 // Be aware the query content events and the selection events are a part of IME
 // processing.  So, you shouldn't use NS_IS_IME_EVENT macro directly in most
 // cases, you should use NS_IS_IME_RELATED_EVENT instead.
 #define NS_IS_IME_RELATED_EVENT(evnt) \
   (NS_IS_IME_EVENT(evnt) || \
    NS_IS_QUERY_CONTENT_EVENT(evnt) || \
    NS_IS_SELECTION_EVENT(evnt))
 
-/*
- * Virtual key bindings for keyboard events.
- * These come from nsIDOMKeyEvent.h, which is generated from MouseKeyEvent.idl.
- * Really, it would be better if we phased out the NS_VK symbols altogether
- * in favor of the DOM ones, but at least this way they'll be in sync.
- */
-
-enum {
-#define NS_DEFINE_VK(aDOMKeyName, aDOMKeyCode) NS_##aDOMKeyName = aDOMKeyCode
-#include "nsVKList.h"
-#undef NS_DEFINE_VK
-};
-
-// IME Constants  -- keep in synch with nsIPrivateTextRange.h
-#define NS_TEXTRANGE_CARETPOSITION         0x01
-#define NS_TEXTRANGE_RAWINPUT              0x02
-#define NS_TEXTRANGE_SELECTEDRAWTEXT       0x03
-#define NS_TEXTRANGE_CONVERTEDTEXT         0x04
-#define NS_TEXTRANGE_SELECTEDCONVERTEDTEXT 0x05
-
 /**
  * Whether the event should be handled by the frame of the mouse cursor
  * position or not.  When it should be handled there (e.g., the mouse events),
  * this returns TRUE.
  */
 inline bool NS_IsEventUsingCoordinates(nsEvent* aEvent)
 {
   return !NS_IS_KEY_EVENT(aEvent) && !NS_IS_IME_RELATED_EVENT(aEvent) &&