Bug 960871 part.6 Use WidgetCompositionEvent for NS_COMPOSITION_CHANGE instead of WidgetTextEvent r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 07 Oct 2014 19:01:48 +0900
changeset 209141 5216b7b1e4e3115a11c126d4b52ecffff710f64c
parent 209140 97aa7fef7adc1c2f009df86a526aff937aa52ad9
child 209142 bd15674419d1e1880670163fdd8fac6a4668408f
push idunknown
push userunknown
push dateunknown
reviewerssmaug
bugs960871
milestone35.0a1
Bug 960871 part.6 Use WidgetCompositionEvent for NS_COMPOSITION_CHANGE instead of WidgetTextEvent r=smaug
dom/base/CompositionStringSynthesizer.cpp
dom/events/EventDispatcher.cpp
dom/events/EventNameList.h
dom/events/EventStateManager.cpp
dom/events/IMEStateManager.cpp
dom/events/TextComposition.cpp
dom/events/TextComposition.h
dom/ipc/PBrowser.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
editor/libeditor/nsEditor.cpp
editor/libeditor/nsPlaintextEditor.cpp
layout/base/nsPresShell.cpp
widget/android/nsWindow.cpp
widget/cocoa/TextInputHandler.mm
widget/gtk/nsGtkIMModule.cpp
widget/gtk/nsWindow.cpp
widget/windows/nsIMM32Handler.cpp
widget/windows/nsTextStore.cpp
widget/xpwidgets/PuppetWidget.cpp
--- a/dom/base/CompositionStringSynthesizer.cpp
+++ b/dom/base/CompositionStringSynthesizer.cpp
@@ -130,17 +130,17 @@ CompositionStringSynthesizer::DispatchEv
     if (mCaret.mEndOffset > mString.Length()) {
       NS_WARNING("Caret position is out of the composition string");
       ClearInternal();
       return NS_ERROR_ILLEGAL_VALUE;
     }
     mClauses->AppendElement(mCaret);
   }
 
-  WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, widget);
+  WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, widget);
   textEvent.time = PR_IntervalNow();
   textEvent.mData = mString;
   if (!mClauses->IsEmpty()) {
     textEvent.mRanges = mClauses;
   }
 
   // XXX How should we set false for this on b2g?
   textEvent.mFlags.mIsSynthesizedForTests = true;
--- a/dom/events/EventDispatcher.cpp
+++ b/dom/events/EventDispatcher.cpp
@@ -697,16 +697,17 @@ EventDispatcher::CreateEvent(EventTarget
                               aEvent->AsGUIEvent());
     case eScrollAreaEventClass:
       return NS_NewDOMScrollAreaEvent(aDOMEvent, aOwner, aPresContext,
                                       aEvent->AsScrollAreaEvent());
     case eKeyboardEventClass:
       return NS_NewDOMKeyboardEvent(aDOMEvent, aOwner, aPresContext,
                                     aEvent->AsKeyboardEvent());
     case eCompositionEventClass:
+    case eTextEventClass:
       return NS_NewDOMCompositionEvent(aDOMEvent, aOwner, aPresContext,
                                        aEvent->AsCompositionEvent());
     case eMouseEventClass:
       return NS_NewDOMMouseEvent(aDOMEvent, aOwner, aPresContext,
                                  aEvent->AsMouseEvent());
     case eFocusEventClass:
       return NS_NewDOMFocusEvent(aDOMEvent, aOwner, aPresContext,
                                  aEvent->AsFocusEvent());
@@ -717,19 +718,16 @@ EventDispatcher::CreateEvent(EventTarget
       return NS_NewDOMWheelEvent(aDOMEvent, aOwner, aPresContext,
                                  aEvent->AsWheelEvent());
     case eEditorInputEventClass:
       return NS_NewDOMInputEvent(aDOMEvent, aOwner, aPresContext,
                                  aEvent->AsEditorInputEvent());
     case eDragEventClass:
       return NS_NewDOMDragEvent(aDOMEvent, aOwner, aPresContext,
                                 aEvent->AsDragEvent());
-    case eTextEventClass:
-      return NS_NewDOMUIEvent(aDOMEvent, aOwner, aPresContext,
-                              aEvent->AsTextEvent());
     case eClipboardEventClass:
       return NS_NewDOMClipboardEvent(aDOMEvent, aOwner, aPresContext,
                                      aEvent->AsClipboardEvent());
     case eSVGZoomEventClass:
       return NS_NewDOMSVGZoomEvent(aDOMEvent, aOwner, aPresContext,
                                    aEvent->AsSVGZoomEvent());
     case eSMILTimeEventClass:
       return NS_NewDOMTimeEvent(aDOMEvent, aOwner, aPresContext,
@@ -767,24 +765,24 @@ EventDispatcher::CreateEvent(EventTarget
   if (aEventType.LowerCaseEqualsLiteral("mousescrollevents"))
     return NS_NewDOMMouseScrollEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("dragevent") ||
       aEventType.LowerCaseEqualsLiteral("dragevents"))
     return NS_NewDOMDragEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("keyboardevent") ||
       aEventType.LowerCaseEqualsLiteral("keyevents"))
     return NS_NewDOMKeyboardEvent(aDOMEvent, aOwner, aPresContext, nullptr);
-  if (aEventType.LowerCaseEqualsLiteral("compositionevent"))
+  if (aEventType.LowerCaseEqualsLiteral("compositionevent") ||
+      aEventType.LowerCaseEqualsLiteral("textevent") ||
+      aEventType.LowerCaseEqualsLiteral("textevents")) {
     return NS_NewDOMCompositionEvent(aDOMEvent, aOwner, aPresContext, nullptr);
+  }
   if (aEventType.LowerCaseEqualsLiteral("mutationevent") ||
         aEventType.LowerCaseEqualsLiteral("mutationevents"))
     return NS_NewDOMMutationEvent(aDOMEvent, aOwner, aPresContext, nullptr);
-  if (aEventType.LowerCaseEqualsLiteral("textevent") ||
-      aEventType.LowerCaseEqualsLiteral("textevents"))
-    return NS_NewDOMUIEvent(aDOMEvent, aOwner, aPresContext, nullptr);
   if (aEventType.LowerCaseEqualsLiteral("deviceorientationevent")) {
     DeviceOrientationEventInit init;
     nsRefPtr<DeviceOrientationEvent> event =
       DeviceOrientationEvent::Constructor(aOwner, EmptyString(), init);
     event.forget(aDOMEvent);
     return NS_OK;
   }
   if (aEventType.LowerCaseEqualsLiteral("devicemotionevent"))
--- a/dom/events/EventNameList.h
+++ b/dom/events/EventNameList.h
@@ -653,17 +653,17 @@ NON_IDL_EVENT(speakerforcedchange,
 // Events that only have on* attributes on XUL elements
 
  // "text" event is legacy event for modifying composition string in nsEditor.
  // This shouldn't be used by web/xul apps.  "compositionupdate" should be
  // used instead.
 NON_IDL_EVENT(text,
               NS_COMPOSITION_CHANGE,
               EventNameType_XUL,
-              eTextEventClass)
+              eCompositionEventClass)
 NON_IDL_EVENT(compositionstart,
               NS_COMPOSITION_START,
               EventNameType_XUL,
               eCompositionEventClass)
 NON_IDL_EVENT(compositionupdate,
               NS_COMPOSITION_UPDATE,
               EventNameType_XUL,
               eCompositionEventClass)
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -793,17 +793,17 @@ EventStateManager::PreHandleEvent(nsPres
     break;
   case NS_CONTENT_COMMAND_SCROLL:
     {
       DoContentCommandScrollEvent(aEvent->AsContentCommandEvent());
     }
     break;
   case NS_COMPOSITION_CHANGE:
     {
-      WidgetTextEvent *textEvent = aEvent->AsTextEvent();
+      WidgetCompositionEvent* textEvent = aEvent->AsCompositionEvent();
       if (IsTargetCrossProcess(textEvent)) {
         // Will not be handled locally, remote the event
         if (GetCrossProcessTarget()->SendTextEvent(*textEvent)) {
           // Cancel local dispatching
           aEvent->mFlags.mPropagationStopped = true;
         }
       }
     }
--- a/dom/events/IMEStateManager.cpp
+++ b/dom/events/IMEStateManager.cpp
@@ -126,29 +126,16 @@ GetIMEStateSetOpenName(IMEState::Open aO
     case IMEState::CLOSED:
       return "CLOSED";
     default:
       return "illegal value";
   }
 }
 
 static const char*
-GetEventClassIDName(EventClassID aEventClassID)
-{
-  switch (aEventClassID) {
-    case eCompositionEventClass:
-      return "eCompositionEventClass";
-    case eTextEventClass:
-      return "eTextEventClass";
-    default:
-      return "unacceptable event struct type";
-  }
-}
-
-static const char*
 GetEventMessageName(uint32_t aMessage)
 {
   switch (aMessage) {
     case NS_COMPOSITION_START:
       return "NS_COMPOSITION_START";
     case NS_COMPOSITION_END:
       return "NS_COMPOSITION_END";
     case NS_COMPOSITION_UPDATE:
@@ -887,28 +874,26 @@ IMEStateManager::DispatchCompositionEven
                                           nsPresContext* aPresContext,
                                           WidgetEvent* aEvent,
                                           nsEventStatus* aStatus,
                                           EventDispatchingCallback* aCallBack,
                                           bool aIsSynthesized)
 {
   PR_LOG(sISMLog, PR_LOG_ALWAYS,
     ("ISM: IMEStateManager::DispatchCompositionEvent(aNode=0x%p, "
-     "aPresContext=0x%p, aEvent={ mClass=%s, message=%s, "
+     "aPresContext=0x%p, aEvent={ message=%s, "
      "mFlags={ mIsTrusted=%s, mPropagationStopped=%s } }, "
      "aIsSynthesized=%s)",
      aEventTargetNode, aPresContext,
-     GetEventClassIDName(aEvent->mClass),
      GetEventMessageName(aEvent->message),
      GetBoolName(aEvent->mFlags.mIsTrusted),
      GetBoolName(aEvent->mFlags.mPropagationStopped),
      GetBoolName(aIsSynthesized)));
 
-  MOZ_ASSERT(aEvent->mClass == eCompositionEventClass ||
-             aEvent->mClass == eTextEventClass);
+  MOZ_ASSERT(aEvent->mClass == eCompositionEventClass);
   if (!aEvent->mFlags.mIsTrusted || aEvent->mFlags.mPropagationStopped) {
     return;
   }
 
   MOZ_ASSERT(aEvent->message != NS_COMPOSITION_UPDATE,
              "compositionupdate event shouldn't be dispatched manually");
 
   EnsureTextCompositionArray();
@@ -970,24 +955,22 @@ IMEStateManager::DispatchCompositionEven
 // static
 void
 IMEStateManager::OnCompositionEventDiscarded(WidgetEvent* aEvent)
 {
   // Note that this method is never called for synthesized events for emulating
   // commit or cancel composition.
 
   PR_LOG(sISMLog, PR_LOG_ALWAYS,
-    ("ISM: IMEStateManager::OnCompositionEventDiscarded(aEvent={ mClass=%s, "
+    ("ISM: IMEStateManager::OnCompositionEventDiscarded(aEvent={ "
      "message=%s, mFlags={ mIsTrusted=%s } })",
-     GetEventClassIDName(aEvent->mClass),
      GetEventMessageName(aEvent->message),
      GetBoolName(aEvent->mFlags.mIsTrusted)));
 
-  MOZ_ASSERT(aEvent->mClass == eCompositionEventClass ||
-             aEvent->mClass == eTextEventClass);
+  MOZ_ASSERT(aEvent->mClass == eCompositionEventClass);
   if (!aEvent->mFlags.mIsTrusted) {
     return;
   }
 
   // Ignore compositionstart for now because sTextCompositions may not have
   // been created yet.
   if (aEvent->message == NS_COMPOSITION_START) {
     return;
@@ -1228,16 +1211,14 @@ IMEStateManager::GetTextCompositionFor(n
     sTextCompositions->GetCompositionFor(aWidget);
   return textComposition.forget();
 }
 
 // static
 already_AddRefed<TextComposition>
 IMEStateManager::GetTextCompositionFor(WidgetGUIEvent* aEvent)
 {
-  MOZ_ASSERT(aEvent->AsCompositionEvent() || aEvent->AsTextEvent() ||
-             aEvent->AsKeyboardEvent(),
-             "aEvent has to be WidgetCompositionEvent, WidgetTextEvent or "
-             "WidgetKeyboardEvent");
+  MOZ_ASSERT(aEvent->AsCompositionEvent() || aEvent->AsKeyboardEvent(),
+             "aEvent has to be WidgetCompositionEvent or WidgetKeyboardEvent");
   return GetTextCompositionFor(aEvent->widget);
 }
 
 } // namespace mozilla
--- a/dom/events/TextComposition.cpp
+++ b/dom/events/TextComposition.cpp
@@ -56,17 +56,18 @@ TextComposition::Destroy()
 
 bool
 TextComposition::MatchesNativeContext(nsIWidget* aWidget) const
 {
   return mNativeContext == aWidget->GetInputContext().mNativeIMEContext;
 }
 
 bool
-TextComposition::MaybeDispatchCompositionUpdate(const WidgetTextEvent* aEvent)
+TextComposition::MaybeDispatchCompositionUpdate(
+                   const WidgetCompositionEvent* aEvent)
 {
   if (Destroyed()) {
     return false;
   }
 
   if (mLastData == aEvent->mData) {
     return true;
   }
@@ -90,18 +91,17 @@ TextComposition::MaybeDispatchCompositio
 void
 TextComposition::OnCompositionEventDiscarded(const WidgetGUIEvent* aEvent)
 {
   // Note that this method is never called for synthesized events for emulating
   // commit or cancel composition.
 
   MOZ_ASSERT(aEvent->mFlags.mIsTrusted,
              "Shouldn't be called with untrusted event");
-  MOZ_ASSERT(aEvent->mClass == eCompositionEventClass ||
-             aEvent->mClass == eTextEventClass);
+  MOZ_ASSERT(aEvent->mClass == eCompositionEventClass);
 
   // XXX If composition events are discarded, should we dispatch them with
   //     runnable event?  However, even if we do so, it might make native IME
   //     confused due to async modification.  Especially when native IME is
   //     TSF.
   if (aEvent->message != NS_COMPOSITION_END) {
     return;
   }
@@ -141,53 +141,51 @@ TextComposition::DispatchEvent(WidgetGUI
   // string.  Therefore, we should hack it only when:
   // 1. committing string is empty string at requesting commit but the last
   //    data isn't IDEOGRAPHIC SPACE.
   // 2. non-empty string is committed at requesting cancel.
   if (!aIsSynthesized && (mIsRequestingCommit || mIsRequestingCancel)) {
     nsString* committingData = nullptr;
     switch (aEvent->message) {
       case NS_COMPOSITION_END:
+      case NS_COMPOSITION_CHANGE:
         committingData = &aEvent->AsCompositionEvent()->mData;
         break;
-      case NS_COMPOSITION_CHANGE:
-        committingData = &aEvent->AsTextEvent()->mData;
-        break;
       default:
         NS_WARNING("Unexpected event comes during committing or "
                    "canceling composition");
         break;
     }
     if (committingData) {
       if (mIsRequestingCommit && committingData->IsEmpty() &&
           mLastData != IDEOGRAPHIC_SPACE) {
         committingData->Assign(mLastData);
       } else if (mIsRequestingCancel && !committingData->IsEmpty()) {
         committingData->Truncate();
       }
     }
   }
 
   if (aEvent->message == NS_COMPOSITION_CHANGE) {
-    if (!MaybeDispatchCompositionUpdate(aEvent->AsTextEvent())) {
+    if (!MaybeDispatchCompositionUpdate(aEvent->AsCompositionEvent())) {
       return;
     }
   }
 
   EventDispatcher::Dispatch(mNode, mPresContext,
                             aEvent, nullptr, aStatus, aCallBack);
 
   if (NS_WARN_IF(Destroyed())) {
     return;
   }
 
   // Emulate editor behavior of compositionchange event (DOM text event) handler
   // if no editor handles composition events.
   if (aEvent->message == NS_COMPOSITION_CHANGE && !HasEditor()) {
-    EditorWillHandleTextEvent(aEvent->AsTextEvent());
+    EditorWillHandleTextEvent(aEvent->AsCompositionEvent());
     EditorDidHandleTextEvent();
   }
 
 #ifdef DEBUG
   else if (aEvent->message == NS_COMPOSITION_END) {
     MOZ_ASSERT(!mIsComposing, "Why is the editor still composing?");
     MOZ_ASSERT(!HasEditor(), "Why does the editor still keep to hold this?");
   }
@@ -215,21 +213,22 @@ TextComposition::NotityUpdateComposition
     if (selectedTextEvent.mSucceeded) {
       mCompositionStartOffset = selectedTextEvent.mReply.mOffset;
     } else {
       // Unknown offset
       NS_WARNING("Cannot get start offset of IME composition");
       mCompositionStartOffset = 0;
     }
     mCompositionTargetOffset = mCompositionStartOffset;
-  } else if (aEvent->mClass != eTextEventClass) {
-    return;
+  } else if (aEvent->message == NS_COMPOSITION_CHANGE) {
+    mCompositionTargetOffset =
+      mCompositionStartOffset +
+        aEvent->AsCompositionEvent()->TargetClauseOffset();
   } else {
-    mCompositionTargetOffset =
-      mCompositionStartOffset + aEvent->AsTextEvent()->TargetClauseOffset();
+    return;
   }
 
   NotifyIME(NOTIFY_IME_OF_COMPOSITION_UPDATE);
 }
 
 void
 TextComposition::DispatchCompositionEventRunnable(uint32_t aEventMessage,
                                                   const nsAString& aData,
@@ -281,17 +280,17 @@ TextComposition::RequestToCommit(nsIWidg
     } else {
       // Emulates to commit or cancel the composition
       // FYI: These events may be discarded by PresShell if it's not safe to
       //      dispatch the event.
       nsCOMPtr<nsIWidget> widget(aWidget);
       nsAutoString commitData(aDiscard ? EmptyString() : lastData);
       bool changingData = lastData != commitData;
 
-      WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, widget);
+      WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, widget);
       textEvent.mData = commitData;
       textEvent.mFlags.mIsSynthesizedForTests = true;
 
       MaybeDispatchCompositionUpdate(&textEvent);
 
       // If changing the data or committing string isn't empty, we need to
       // dispatch compositionchange event for setting the composition string
       // without IME selection.
@@ -335,17 +334,18 @@ TextComposition::RequestToCommit(nsIWidg
 nsresult
 TextComposition::NotifyIME(IMEMessage aMessage)
 {
   NS_ENSURE_TRUE(mPresContext, NS_ERROR_NOT_AVAILABLE);
   return IMEStateManager::NotifyIME(aMessage, mPresContext);
 }
 
 void
-TextComposition::EditorWillHandleTextEvent(const WidgetTextEvent* aTextEvent)
+TextComposition::EditorWillHandleTextEvent(
+                   const WidgetCompositionEvent* aTextEvent)
 {
   mIsComposing = aTextEvent->IsComposing();
   mRanges = aTextEvent->mRanges;
   mIsEditorHandlingEvent = true;
 
   MOZ_ASSERT(mLastData == aTextEvent->mData,
     "The text of a compositionchange event must be same as previous data "
     "attribute value of the latest compositionupdate event");
@@ -449,17 +449,17 @@ TextComposition::CompositionEventDispatc
       compEvent.mFlags.mIsSynthesizedForTests =
         mTextComposition->IsSynthesizedForTests();
       IMEStateManager::DispatchCompositionEvent(mEventTarget, presContext,
                                                 &compEvent, &status, nullptr,
                                                 mIsSynthesizedEvent);
       break;
     }
     case NS_COMPOSITION_CHANGE: {
-      WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, widget);
+      WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, widget);
       textEvent.mData = mData;
       textEvent.mFlags.mIsSynthesizedForTests =
         mTextComposition->IsSynthesizedForTests();
       IMEStateManager::DispatchCompositionEvent(mEventTarget, presContext,
                                                 &textEvent, &status, nullptr,
                                                 mIsSynthesizedEvent);
       break;
     }
--- a/dom/events/TextComposition.h
+++ b/dom/events/TextComposition.h
@@ -127,17 +127,17 @@ public:
    * TextEventHandlingMarker class should be created at starting to handle text
    * event in focused editor.  This calls EditorWillHandleTextEvent() and
    * EditorDidHandleTextEvent() automatically.
    */
   class MOZ_STACK_CLASS TextEventHandlingMarker
   {
   public:
     TextEventHandlingMarker(TextComposition* aComposition,
-                            const WidgetTextEvent* aTextEvent)
+                            const WidgetCompositionEvent* aTextEvent)
       : mComposition(aComposition)
     {
       mComposition->EditorWillHandleTextEvent(aTextEvent);
     }
 
     ~TextEventHandlingMarker()
     {
       mComposition->EditorDidHandleTextEvent();
@@ -230,17 +230,17 @@ private:
    * alive.  Otherwise, false.
    */
   bool HasEditor() const;
 
   /**
    * EditorWillHandleTextEvent() must be called before the focused editor
    * handles the compositionchange event.
    */
-  void EditorWillHandleTextEvent(const WidgetTextEvent* aTextEvent);
+  void EditorWillHandleTextEvent(const WidgetCompositionEvent* aTextEvent);
 
   /**
    * EditorDidHandleTextEvent() must be called after the focused editor handles
    * a compositionchange event.
    */
   void EditorDidHandleTextEvent();
 
   /**
@@ -253,17 +253,17 @@ private:
                      bool aIsSynthesized);
 
   /**
    * MaybeDispatchCompositionUpdate() may dispatch a compositionupdate event
    * if aEvent changes composition string.
    * @return Returns false if dispatching the compositionupdate event caused
    *         destroying this composition.
    */
-  bool MaybeDispatchCompositionUpdate(const WidgetTextEvent* aEvent);
+  bool MaybeDispatchCompositionUpdate(const WidgetCompositionEvent* aEvent);
 
   /**
    * If IME has already dispatched compositionend event but it was discarded
    * by PresShell due to not safe to dispatch, this returns true.
    */
   bool WasNativeCompositionEndEventDiscarded() const
   {
     return mWasNativeCompositionEndEventDiscarded;
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -39,17 +39,16 @@ using struct nsIMEUpdatePreference from 
 using struct nsIntPoint from "nsPoint.h";
 using struct nsIntRect from "nsRect.h";
 using struct nsIntSize from "nsSize.h";
 using class mozilla::WidgetKeyboardEvent from "ipc/nsGUIEventIPC.h";
 using class mozilla::WidgetMouseEvent from "ipc/nsGUIEventIPC.h";
 using class mozilla::WidgetWheelEvent from "ipc/nsGUIEventIPC.h";
 using struct nsRect from "nsRect.h";
 using class mozilla::WidgetSelectionEvent from "ipc/nsGUIEventIPC.h";
-using class mozilla::WidgetTextEvent from "ipc/nsGUIEventIPC.h";
 using class mozilla::WidgetTouchEvent from "ipc/nsGUIEventIPC.h";
 using struct mozilla::dom::RemoteDOMEvent from "mozilla/dom/TabMessageUtils.h";
 using mozilla::dom::ScreenOrientation from "mozilla/dom/ScreenOrientation.h";
 using struct mozilla::layers::TextureFactoryIdentifier from "mozilla/layers/CompositorTypes.h";
 using mozilla::CSSPoint from "Units.h";
 using mozilla::CSSToScreenScale from "Units.h";
 using mozilla::CommandInt from "mozilla/EventForwards.h";
 using mozilla::layers::GeckoContentController::APZStateChange from "mozilla/layers/GeckoContentController.h";
@@ -474,17 +473,17 @@ child:
     KeyEvent(nsString aType,
              int32_t aKeyCode,
              int32_t aCharCode,
              int32_t aModifiers,
              bool aPreventDefault);
 
     CompositionEvent(WidgetCompositionEvent event);
 
-    TextEvent(WidgetTextEvent event);
+    TextEvent(WidgetCompositionEvent event);
 
     SelectionEvent(WidgetSelectionEvent event);
 
     /**
      * Activate event forwarding from client to parent.
      */
     ActivateFrameEvent(nsString aType, bool capture);
 
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2384,19 +2384,19 @@ TabChild::RecvCompositionEvent(const Wid
 {
   WidgetCompositionEvent localEvent(event);
   localEvent.widget = mWidget;
   DispatchWidgetEvent(localEvent);
   return true;
 }
 
 bool
-TabChild::RecvTextEvent(const WidgetTextEvent& event)
+TabChild::RecvTextEvent(const WidgetCompositionEvent& event)
 {
-  WidgetTextEvent localEvent(event);
+  WidgetCompositionEvent localEvent(event);
   localEvent.widget = mWidget;
   DispatchWidgetEvent(localEvent);
   return true;
 }
 
 bool
 TabChild::RecvSelectionEvent(const WidgetSelectionEvent& event)
 {
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -355,17 +355,17 @@ public:
     virtual bool RecvRealTouchMoveEvent(const WidgetTouchEvent& aEvent,
                                         const ScrollableLayerGuid& aGuid) MOZ_OVERRIDE;
     virtual bool RecvKeyEvent(const nsString& aType,
                               const int32_t&  aKeyCode,
                               const int32_t&  aCharCode,
                               const int32_t&  aModifiers,
                               const bool&     aPreventDefault) MOZ_OVERRIDE;
     virtual bool RecvCompositionEvent(const mozilla::WidgetCompositionEvent& event) MOZ_OVERRIDE;
-    virtual bool RecvTextEvent(const mozilla::WidgetTextEvent& event) MOZ_OVERRIDE;
+    virtual bool RecvTextEvent(const mozilla::WidgetCompositionEvent& event) MOZ_OVERRIDE;
     virtual bool RecvSelectionEvent(const mozilla::WidgetSelectionEvent& event) MOZ_OVERRIDE;
     virtual bool RecvActivateFrameEvent(const nsString& aType, const bool& capture) MOZ_OVERRIDE;
     virtual bool RecvLoadRemoteScript(const nsString& aURL,
                                       const bool& aRunInGlobalScope) MOZ_OVERRIDE;
     virtual bool RecvAsyncMessage(const nsString& aMessage,
                                   const ClonedMessageData& aData,
                                   const InfallibleTArray<CpowEntry>& aCpows,
                                   const IPC::Principal& aPrincipal) MOZ_OVERRIDE;
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -1577,17 +1577,17 @@ TabParent::SendCompositionEvent(WidgetCo
  * During REQUEST_TO_COMMIT_COMPOSITION or REQUEST_TO_CANCEL_COMPOSITION,
  * widget usually sends a NS_COMPOSITION_CHANGE event to finalize or
  * clear the composition, respectively
  *
  * Because the event will not reach content in time, we intercept it
  * here and pass the text as the EndIMEComposition return value
  */
 bool
-TabParent::SendTextEvent(WidgetTextEvent& event)
+TabParent::SendTextEvent(WidgetCompositionEvent& event)
 {
   if (mIsDestroyed) {
     return false;
   }
   if (mIMECompositionEnding) {
     mIMECompositionText = event.mData;
     return true;
   }
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -313,17 +313,17 @@ public:
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIAUTHPROMPTPROVIDER
     NS_DECL_NSISECUREBROWSERUI
 
     static TabParent *GetIMETabParent() { return mIMETabParent; }
     bool HandleQueryContentEvent(mozilla::WidgetQueryContentEvent& aEvent);
     bool SendCompositionEvent(mozilla::WidgetCompositionEvent& event);
-    bool SendTextEvent(mozilla::WidgetTextEvent& event);
+    bool SendTextEvent(mozilla::WidgetCompositionEvent& event);
     bool SendSelectionEvent(mozilla::WidgetSelectionEvent& event);
 
     static TabParent* GetFrom(nsFrameLoader* aFrameLoader);
     static TabParent* GetFrom(nsIContent* aContent);
 
     nsIContentParent* Manager() { return mManager; }
 
     /**
--- a/editor/libeditor/nsEditor.cpp
+++ b/editor/libeditor/nsEditor.cpp
@@ -5104,25 +5104,20 @@ nsEditor::IsAcceptableInputEvent(nsIDOME
   // strange event order.
   bool needsWidget = false;
   WidgetGUIEvent* widgetGUIEvent = nullptr;
   switch (widgetEvent->message) {
     case NS_USER_DEFINED_EVENT:
       // If events are not created with proper event interface, their message
       // are initialized with NS_USER_DEFINED_EVENT.  Let's ignore such event.
       return false;
-    case NS_COMPOSITION_CHANGE:
-      // Don't allow compositionchange events whose internal event are not
-      // WidgetTextEvent.
-      widgetGUIEvent = aEvent->GetInternalNSEvent()->AsTextEvent();
-      needsWidget = true;
-      break;
     case NS_COMPOSITION_START:
     case NS_COMPOSITION_END:
     case NS_COMPOSITION_UPDATE:
+    case NS_COMPOSITION_CHANGE:
       // Don't allow composition events whose internal event are not
       // WidgetCompositionEvent.
       widgetGUIEvent = aEvent->GetInternalNSEvent()->AsCompositionEvent();
       needsWidget = true;
       break;
     default:
       break;
   }
--- a/editor/libeditor/nsPlaintextEditor.cpp
+++ b/editor/libeditor/nsPlaintextEditor.cpp
@@ -841,19 +841,21 @@ nsPlaintextEditor::BeginIMEComposition(W
   return nsEditor::BeginIMEComposition(aEvent);
 }
 
 nsresult
 nsPlaintextEditor::UpdateIMEComposition(nsIDOMEvent* aDOMTextEvent)
 {
   NS_ABORT_IF_FALSE(aDOMTextEvent, "aDOMTextEvent must not be nullptr");
 
-  WidgetTextEvent* widgetTextEvent =
-    aDOMTextEvent->GetInternalNSEvent()->AsTextEvent();
+  WidgetCompositionEvent* widgetTextEvent =
+    aDOMTextEvent->GetInternalNSEvent()->AsCompositionEvent();
   NS_ENSURE_TRUE(widgetTextEvent, NS_ERROR_INVALID_ARG);
+  MOZ_ASSERT(compChangeEvent->message == NS_COMPOSITION_CHANGE,
+             "The internal event should be NS_COMPOSITION_CHANGE");
 
   EnsureComposition(widgetTextEvent);
 
   nsCOMPtr<nsIPresShell> ps = GetPresShell();
   NS_ENSURE_TRUE(ps, NS_ERROR_NOT_INITIALIZED);
 
   nsCOMPtr<nsISelection> selection;
   nsresult rv = GetSelection(getter_AddRefs(selection));
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -6937,18 +6937,17 @@ PresShell::HandleEvent(nsIFrame* aFrame,
   }
 
   if (sPointerEventEnabled) {
     UpdateActivePointerState(aEvent);
   }
 
   if (!nsContentUtils::IsSafeToRunScript() &&
       aEvent->IsAllowedToDispatchDOMEvent()) {
-    if (aEvent->mClass == eCompositionEventClass ||
-        aEvent->mClass == eTextEventClass) {
+    if (aEvent->mClass == eCompositionEventClass) {
       IMEStateManager::OnCompositionEventDiscarded(aEvent);
     }
 #ifdef DEBUG
     if (aEvent->IsIMERelatedEvent()) {
       nsPrintfCString warning("%d event is discarded", aEvent->message);
       NS_WARNING(warning.get());
     }
 #endif
@@ -7854,18 +7853,17 @@ PresShell::HandleEventInternal(WidgetEve
             } else if (mDocument) {
               eventTarget = do_QueryInterface(mDocument);
               // If we don't have any content, the callback wouldn't probably
               // do nothing.
               eventCBPtr = nullptr;
             }
           }
           if (eventTarget) {
-            if (aEvent->mClass == eCompositionEventClass ||
-                aEvent->mClass == eTextEventClass) {
+            if (aEvent->mClass == eCompositionEventClass) {
               IMEStateManager::DispatchCompositionEvent(eventTarget,
                 mPresContext, aEvent, aStatus, eventCBPtr);
             } else {
               EventDispatcher::Dispatch(eventTarget, mPresContext,
                                         aEvent, nullptr, aStatus, eventCBPtr);
             }
           }
         }
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -680,17 +680,17 @@ nsWindow::DispatchEvent(WidgetGUIEvent* 
         case NS_COMPOSITION_END:
             MOZ_ASSERT(mIMEComposing);
             mIMEComposing = false;
             mIMEComposingStart = -1;
             mIMEComposingText.Truncate();
             break;
         case NS_COMPOSITION_CHANGE:
             MOZ_ASSERT(mIMEComposing);
-            mIMEComposingText = aEvent->AsTextEvent()->mData;
+            mIMEComposingText = aEvent->AsCompositionEvent()->mData;
             break;
         }
         return status;
     }
     return nsEventStatus_eIgnore;
 }
 
 NS_IMETHODIMP
@@ -1702,17 +1702,17 @@ nsWindow::RemoveIMEComposition()
     // Remove composition on Gecko side
     if (!mIMEComposing)
         return;
 
     nsRefPtr<nsWindow> kungFuDeathGrip(this);
     AutoIMEMask selMask(mIMEMaskSelectionUpdate);
     AutoIMEMask textMask(mIMEMaskTextUpdate);
 
-    WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, this);
+    WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, this);
     InitEvent(textEvent, nullptr);
     textEvent.mData = mIMEComposingText;
     DispatchEvent(&textEvent);
 
     WidgetCompositionEvent event(true, NS_COMPOSITION_END, this);
     InitEvent(event, nullptr);
     DispatchEvent(&event);
 }
@@ -1840,17 +1840,17 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *
                         true, NS_COMPOSITION_START, this);
                     InitEvent(event, nullptr);
                     DispatchEvent(&event);
                     mIMEComposingStart = ae->Start();
                 }
             }
 
             {
-                WidgetTextEvent event(true, NS_COMPOSITION_CHANGE, this);
+                WidgetCompositionEvent event(true, NS_COMPOSITION_CHANGE, this);
                 InitEvent(event, nullptr);
                 event.mData = ae->Characters();
 
                 if (ae->Action() == AndroidGeckoEvent::IME_COMPOSE_TEXT) {
                     // Because we're leaving the composition open, we need to
                     // include proper text ranges to make the editor happy.
                     TextRange range;
                     range.mStartOffset = 0;
@@ -1950,17 +1950,17 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *
                   text content unintentionally.
 
                 Selection and text updates are masked so the result of
                   temporary events are not passed on to Java
             */
             AutoIMEMask selMask(mIMEMaskSelectionUpdate);
             AutoIMEMask textMask(mIMEMaskTextUpdate);
 
-            WidgetTextEvent event(true, NS_COMPOSITION_CHANGE, this);
+            WidgetCompositionEvent event(true, NS_COMPOSITION_CHANGE, this);
             InitEvent(event, nullptr);
 
             event.mRanges = new TextRangeArray();
             mIMERanges.swap(event.mRanges);
 
             if (mIMEComposingStart < 0 ||
                 ae->Start() != mIMEComposingStart ||
                 ae->End() != mIMEComposingStart +
@@ -2081,17 +2081,17 @@ nsWindow::NotifyIME(const IMENotificatio
             return NS_OK;
         case REQUEST_TO_CANCEL_COMPOSITION:
             ALOGIME("IME: REQUEST_TO_CANCEL_COMPOSITION");
 
             // Cancel composition on Gecko side
             if (mIMEComposing) {
                 nsRefPtr<nsWindow> kungFuDeathGrip(this);
 
-                WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, this);
+                WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, this);
                 InitEvent(textEvent, nullptr);
                 DispatchEvent(&textEvent);
 
                 WidgetCompositionEvent compEvent(true, NS_COMPOSITION_END,
                                                  this);
                 InitEvent(compEvent, nullptr);
                 DispatchEvent(&compEvent);
             }
--- a/widget/cocoa/TextInputHandler.mm
+++ b/widget/cocoa/TextInputHandler.mm
@@ -2711,17 +2711,17 @@ IMEInputHandler::DispatchTextEvent(const
      GetCharacters([aAttrString string]),
      aSelectedRange.location, aSelectedRange.length,
      TrueOrFalse(aDoCommit), TrueOrFalse(Destroyed())));
 
   NS_ENSURE_TRUE(!Destroyed(), false);
 
   nsRefPtr<IMEInputHandler> kungFuDeathGrip(this);
 
-  WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget);
+  WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget);
   textEvent.time = PR_IntervalNow();
   textEvent.mData = aText;
   if (!aDoCommit) {
     textEvent.mRanges = CreateTextRangeArray(aAttrString, aSelectedRange);
   }
   mLastDispatchedCompositionString = textEvent.mData;
   return DispatchEvent(textEvent);
 }
--- a/widget/gtk/nsGtkIMModule.cpp
+++ b/widget/gtk/nsGtkIMModule.cpp
@@ -1102,17 +1102,18 @@ nsGtkIMModule::DispatchTextEvent(const n
                                                        mLastFocusedWindow);
         mLastFocusedWindow->DispatchEvent(&querySelectedTextEvent, status);
         if (querySelectedTextEvent.mSucceeded) {
             mSelectedString = querySelectedTextEvent.mReply.mString;
             mCompositionStart = querySelectedTextEvent.mReply.mOffset;
         }
     }
 
-    WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, mLastFocusedWindow);
+    WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE,
+                                     mLastFocusedWindow);
     InitEvent(textEvent);
 
     uint32_t targetOffset = mCompositionStart;
 
     textEvent.mData = mDispatchedCompositionString = aCompositionString;
 
     if (!aIsCommit) {
         // NOTE: SetTextRangeList() assumes that mDispatchedCompositionString
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -3041,17 +3041,17 @@ nsWindow::OnKeyPressEvent(GdkEventKey *a
     else {
         // If the character code is in the BMP, send the key press event.
         // Otherwise, send a compositionchange event with the equivalent UTF-16
         // string.
         if (IS_IN_BMP(event.charCode)) {
             DispatchEvent(&event, status);
         }
         else {
-            WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, this);
+            WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, this);
             char16_t textString[3];
             textString[0] = H_SURROGATE(event.charCode);
             textString[1] = L_SURROGATE(event.charCode);
             textString[2] = 0;
             textEvent.mData = textString;
             textEvent.time = event.time;
             DispatchEvent(&textEvent, status);
         }
--- a/widget/windows/nsIMM32Handler.cpp
+++ b/widget/windows/nsIMM32Handler.cpp
@@ -1586,17 +1586,17 @@ nsIMM32Handler::DispatchTextEvent(nsWind
     SetIMERelatedWindowsPos(aWindow, aIMEContext);
     return;
   }
 
   nsRefPtr<nsWindow> kungFuDeathGrip(aWindow);
 
   nsIntPoint point(0, 0);
 
-  WidgetTextEvent event(true, NS_COMPOSITION_CHANGE, aWindow);
+  WidgetCompositionEvent event(true, NS_COMPOSITION_CHANGE, aWindow);
 
   aWindow->InitEvent(event, &point);
 
   if (aCheckAttr) {
     event.mRanges = CreateTextRangeArray();
   }
 
   event.mData = mLastDispatchedCompositionString = mCompositionString;
--- a/widget/windows/nsTextStore.cpp
+++ b/widget/windows/nsTextStore.cpp
@@ -1645,17 +1645,17 @@ nsTextStore::FlushPendingActions()
         }
 
         action.mData.ReplaceSubstring(NS_LITERAL_STRING("\r\n"),
                                       NS_LITERAL_STRING("\n"));
 
         PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
                ("TSF: 0x%p   nsTextStore::FlushPendingActions(), "
                 "dispatching compositionchange event...", this));
-        WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget);
+        WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget);
         mWidget->InitEvent(textEvent);
         textEvent.mData = action.mData;
         if (action.mRanges->IsEmpty()) {
           TextRange wholeRange;
           wholeRange.mStartOffset = 0;
           wholeRange.mEndOffset = textEvent.mData.Length();
           wholeRange.mRangeType = NS_TEXTRANGE_RAWINPUT;
           action.mRanges->AppendElement(wholeRange);
@@ -1672,17 +1672,17 @@ nsTextStore::FlushPendingActions()
                 this, NS_ConvertUTF16toUTF8(action.mData).get()));
 
         action.mData.ReplaceSubstring(NS_LITERAL_STRING("\r\n"),
                                       NS_LITERAL_STRING("\n"));
 
         PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
                ("TSF: 0x%p   nsTextStore::FlushPendingActions(), "
                 "dispatching compositionchange event...", this));
-        WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget);
+        WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, mWidget);
         mWidget->InitEvent(textEvent);
         textEvent.mData = action.mData;
         mWidget->DispatchWindowEvent(&textEvent);
         if (!mWidget || mWidget->Destroyed()) {
           break;
         }
 
         PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
--- a/widget/xpwidgets/PuppetWidget.cpp
+++ b/widget/xpwidgets/PuppetWidget.cpp
@@ -377,17 +377,17 @@ PuppetWidget::GetLayerManager(PLayerTran
 nsresult
 PuppetWidget::IMEEndComposition(bool aCancel)
 {
 #ifndef MOZ_CROSS_PROCESS_IME
   return NS_OK;
 #endif
 
   nsEventStatus status;
-  WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, this);
+  WidgetCompositionEvent textEvent(true, NS_COMPOSITION_CHANGE, this);
   InitEvent(textEvent, nullptr);
   textEvent.mSeqno = mIMELastReceivedSeqno;
   // SendEndIMEComposition is always called since ResetInputState
   // should always be called even if we aren't composing something.
   if (!mTabChild ||
       !mTabChild->SendEndIMEComposition(aCancel, &textEvent.mData)) {
     return NS_ERROR_FAILURE;
   }