Bug 960871 part.4 Rename NS_TEXT_TEXT to NS_COMPOSITION_CHANGE and fix comments which mention text events r=smaug
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 07 Oct 2014 19:01:47 +0900
changeset 209139 279373ac52ffac806b4bf3f4856e43888daf9b4d
parent 209138 d2eebbc42474e590edc824c975ae5a6f3ec99111
child 209140 97aa7fef7adc1c2f009df86a526aff937aa52ad9
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerssmaug
bugs960871
milestone35.0a1
Bug 960871 part.4 Rename NS_TEXT_TEXT to NS_COMPOSITION_CHANGE and fix comments which mention text events r=smaug
dom/base/CompositionStringSynthesizer.cpp
dom/base/nsDOMWindowUtils.cpp
dom/events/EventNameList.h
dom/events/EventStateManager.cpp
dom/events/IMEStateManager.cpp
dom/events/IMEStateManager.h
dom/events/TextComposition.cpp
dom/events/TextComposition.h
dom/ipc/TabParent.cpp
editor/libeditor/nsEditor.cpp
editor/libeditor/nsEditor.h
editor/libeditor/nsEditorEventListener.cpp
editor/libeditor/nsPlaintextEditor.cpp
widget/BasicEvents.h
widget/android/nsWindow.cpp
widget/cocoa/TextInputHandler.h
widget/cocoa/TextInputHandler.mm
widget/gtk/nsGtkIMModule.cpp
widget/gtk/nsGtkIMModule.h
widget/gtk/nsWindow.cpp
widget/shared/WidgetEventImpl.cpp
widget/tests/TestWinTSF.cpp
widget/windows/nsIMM32Handler.cpp
widget/windows/nsTextStore.cpp
widget/windows/nsTextStore.h
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_TEXT_TEXT, widget);
+  WidgetTextEvent 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/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -2113,17 +2113,17 @@ nsDOMWindowUtils::SendCompositionEvent(c
 
   uint32_t msg;
   if (aType.EqualsLiteral("compositionstart")) {
     msg = NS_COMPOSITION_START;
   } else if (aType.EqualsLiteral("compositionend")) {
     msg = NS_COMPOSITION_END;
   } else if (aType.EqualsLiteral("compositionupdate")) {
     // Now we don't support manually dispatching composition update with this
-    // API.  compositionupdate is dispatched when text event modifies
+    // API.  A compositionupdate is dispatched when a DOM text event modifies
     // composition string automatically.  For backward compatibility, this
     // shouldn't return error in this case.
     NS_WARNING("Don't call nsIDOMWindowUtils.sendCompositionEvent() for "
                "compositionupdate since it's ignored and the event is "
                "fired automatically when it's necessary");
     return NS_OK;
   } else {
     return NS_ERROR_FAILURE;
--- a/dom/events/EventNameList.h
+++ b/dom/events/EventNameList.h
@@ -646,18 +646,22 @@ NON_IDL_EVENT(warning,
               eBasicEventClass)
 
 NON_IDL_EVENT(speakerforcedchange,
               NS_SPEAKERMANAGER_SPEAKERFORCEDCHANGE,
               EventNameType_None,
               eBasicEventClass)
 
 // 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_TEXT_TEXT,
+              NS_COMPOSITION_CHANGE,
               EventNameType_XUL,
               eTextEventClass)
 NON_IDL_EVENT(compositionstart,
               NS_COMPOSITION_START,
               EventNameType_XUL,
               eCompositionEventClass)
 NON_IDL_EVENT(compositionupdate,
               NS_COMPOSITION_UPDATE,
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -791,17 +791,17 @@ EventStateManager::PreHandleEvent(nsPres
       DoContentCommandEvent(aEvent->AsContentCommandEvent());
     }
     break;
   case NS_CONTENT_COMMAND_SCROLL:
     {
       DoContentCommandScrollEvent(aEvent->AsContentCommandEvent());
     }
     break;
-  case NS_TEXT_TEXT:
+  case NS_COMPOSITION_CHANGE:
     {
       WidgetTextEvent *textEvent = aEvent->AsTextEvent();
       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
@@ -148,18 +148,18 @@ 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:
       return "NS_COMPOSITION_UPDATE";
-    case NS_TEXT_TEXT:
-      return "NS_TEXT_TEXT";
+    case NS_COMPOSITION_CHANGE:
+      return "NS_COMPOSITION_CHANGE";
     default:
       return "unacceptable event message";
   }
 }
 
 static const char*
 GetNotifyIMEMessageName(IMEMessage aMessage)
 {
--- a/dom/events/IMEStateManager.h
+++ b/dom/events/IMEStateManager.h
@@ -87,46 +87,44 @@ public:
   // aContent must be:
   //   If the editor is for <input> or <textarea>, the element.
   //   If the editor is for contenteditable, the active editinghost.
   //   If the editor is for designMode, nullptr.
   static void OnFocusInEditor(nsPresContext* aPresContext,
                               nsIContent* aContent);
 
   /**
-   * All DOM composition events and DOM text events must be dispatched via
-   * DispatchCompositionEvent() for storing the composition target
-   * and ensuring a set of composition events must be fired the stored target.
-   * If the stored composition event target is destroying, this removes the
-   * stored composition automatically.
+   * All composition events must be dispatched via DispatchCompositionEvent()
+   * for storing the composition target and ensuring a set of composition
+   * events must be fired the stored target.  If the stored composition event
+   * target is destroying, this removes the stored composition automatically.
    */
   static void DispatchCompositionEvent(nsINode* aEventTargetNode,
                                        nsPresContext* aPresContext,
                                        WidgetEvent* aEvent,
                                        nsEventStatus* aStatus,
                                        EventDispatchingCallback* aCallBack,
                                        bool aIsSynthesized = false);
 
   /**
-   * This is called when PresShell ignores composition event or text event due
-   * to not safe to dispatch events.
+   * This is called when PresShell ignores a composition event due to not safe
+   * to dispatch events.
    */
   static void OnCompositionEventDiscarded(WidgetEvent* aEvent);
 
   /**
    * Get TextComposition from widget.
    */
   static already_AddRefed<TextComposition>
     GetTextCompositionFor(nsIWidget* aWidget);
 
   /**
    * Returns TextComposition instance for the event.
    *
-   * @param aEvent      Should be a composition event or a text event which is
-   *                    being dispatched.
+   * @param aEvent      Should be a composition event which is being dispatched.
    */
   static already_AddRefed<TextComposition>
     GetTextCompositionFor(WidgetGUIEvent* aEvent);
 
   /**
    * Send a notification to IME.  It depends on the IME or platform spec what
    * will occur (or not occur).
    */
--- a/dom/events/TextComposition.cpp
+++ b/dom/events/TextComposition.cpp
@@ -143,17 +143,17 @@ TextComposition::DispatchEvent(WidgetGUI
   //    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:
         committingData = &aEvent->AsCompositionEvent()->mData;
         break;
-      case NS_TEXT_TEXT:
+      case NS_COMPOSITION_CHANGE:
         committingData = &aEvent->AsTextEvent()->mData;
         break;
       default:
         NS_WARNING("Unexpected event comes during committing or "
                    "canceling composition");
         break;
     }
     if (committingData) {
@@ -161,32 +161,32 @@ TextComposition::DispatchEvent(WidgetGUI
           mLastData != IDEOGRAPHIC_SPACE) {
         committingData->Assign(mLastData);
       } else if (mIsRequestingCancel && !committingData->IsEmpty()) {
         committingData->Truncate();
       }
     }
   }
 
-  if (aEvent->message == NS_TEXT_TEXT) {
+  if (aEvent->message == NS_COMPOSITION_CHANGE) {
     if (!MaybeDispatchCompositionUpdate(aEvent->AsTextEvent())) {
       return;
     }
   }
 
   EventDispatcher::Dispatch(mNode, mPresContext,
                             aEvent, nullptr, aStatus, aCallBack);
 
   if (NS_WARN_IF(Destroyed())) {
     return;
   }
 
-  // Emulate editor behavior of text event handler if no editor handles
-  // composition/text events.
-  if (aEvent->message == NS_TEXT_TEXT && !HasEditor()) {
+  // 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());
     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?");
@@ -199,17 +199,17 @@ TextComposition::DispatchEvent(WidgetGUI
 
 void
 TextComposition::NotityUpdateComposition(WidgetGUIEvent* aEvent)
 {
   nsEventStatus status;
 
   // When compositon start, notify the rect of first offset character.
   // When not compositon start, notify the rect of selected composition
-  // string if text event.
+  // string if compositionchange event.
   if (aEvent->message == NS_COMPOSITION_START) {
     nsCOMPtr<nsIWidget> widget = mPresContext->GetRootWidget();
     // Update composition start offset
     WidgetQueryContentEvent selectedTextEvent(true,
                                               NS_QUERY_SELECTED_TEXT,
                                               widget);
     widget->DispatchEvent(&selectedTextEvent, status);
     if (selectedTextEvent.mSucceeded) {
@@ -281,25 +281,25 @@ 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_TEXT_TEXT, widget);
+      WidgetTextEvent 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 text event for setting the composition string without
-      // IME selection.
+      // dispatch compositionchange event for setting the composition string
+      // without IME selection.
       if (!Destroyed() && !widget->Destroyed() &&
           (changingData || !commitData.IsEmpty())) {
         nsEventStatus status = nsEventStatus_eIgnore;
         widget->DispatchEvent(&textEvent, status);
       }
 
       if (!Destroyed() && !widget->Destroyed()) {
         nsEventStatus status = nsEventStatus_eIgnore;
@@ -316,21 +316,21 @@ TextComposition::RequestToCommit(nsIWidg
   // If the request is performed synchronously, this must be already destroyed.
   if (Destroyed()) {
     return NS_OK;
   }
 
   // Otherwise, synthesize the commit in content.
   nsAutoString data(aDiscard ? EmptyString() : lastData);
   // If the last composition string and new data are different, we need to
-  // dispatch text event for removing IME selection.  However, if the commit
-  // string is empty string and it's not changed from the last data, we don't
-  // need to dispatch text event.
+  // dispatch compositionchange event for removing IME selection.  However, if
+  // the commit string is empty string and it's not changed from the last data,
+  // we don't need to dispatch compositionchange event.
   if (lastData != data || !data.IsEmpty()) {
-    DispatchCompositionEventRunnable(NS_TEXT_TEXT, data, true);
+    DispatchCompositionEventRunnable(NS_COMPOSITION_CHANGE, data, true);
   }
   DispatchCompositionEventRunnable(NS_COMPOSITION_END, data, true);
 
   return NS_OK;
 }
 
 nsresult
 TextComposition::NotifyIME(IMEMessage aMessage)
@@ -342,18 +342,18 @@ TextComposition::NotifyIME(IMEMessage aM
 void
 TextComposition::EditorWillHandleTextEvent(const WidgetTextEvent* aTextEvent)
 {
   mIsComposing = aTextEvent->IsComposing();
   mRanges = aTextEvent->mRanges;
   mIsEditorHandlingEvent = true;
 
   MOZ_ASSERT(mLastData == aTextEvent->mData,
-    "The text of a text event must be same as previous data attribute value "
-    "of the latest compositionupdate event");
+    "The text of a compositionchange event must be same as previous data "
+    "attribute value of the latest compositionupdate event");
 }
 
 void
 TextComposition::EditorDidHandleTextEvent()
 {
   mString = mLastData;
   mIsEditorHandlingEvent = false;
 }
@@ -448,18 +448,18 @@ TextComposition::CompositionEventDispatc
       compEvent.mData = mData;
       compEvent.mFlags.mIsSynthesizedForTests =
         mTextComposition->IsSynthesizedForTests();
       IMEStateManager::DispatchCompositionEvent(mEventTarget, presContext,
                                                 &compEvent, &status, nullptr,
                                                 mIsSynthesizedEvent);
       break;
     }
-    case NS_TEXT_TEXT: {
-      WidgetTextEvent textEvent(true, NS_TEXT_TEXT, widget);
+    case NS_COMPOSITION_CHANGE: {
+      WidgetTextEvent 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
@@ -47,17 +47,17 @@ public:
   nsINode* GetEventTargetNode() const { return mNode; }
   // The latest CompositionEvent.data value except compositionstart event.
   // This value is modified at dispatching compositionupdate.
   const nsString& LastData() const { return mLastData; }
   // The composition string which is already handled by the focused editor.
   // I.e., this value must be same as the composition string on the focused
   // editor.  This value is modified at a call of EditorDidHandleTextEvent().
   // Note that mString and mLastData are different between dispatcing
-  // compositionupdate and text event handled by focused editor.
+  // compositionupdate and compositionchange event handled by focused editor.
   const nsString& String() const { return mString; }
   // Returns the clauses and/or caret range of the composition string.
   // This is modified at a call of EditorWillHandleTextEvent().
   // This may return null if there is no clauses and caret.
   // XXX We should return |const TextRangeArray*| here, but it causes compile
   //     error due to inaccessible Release() method.
   TextRangeArray* GetRanges() const { return mRanges; }
   // Returns the widget which is proper to call NotifyIME().
@@ -228,23 +228,23 @@ private:
   /**
    * HasEditor() returns true if mEditorWeak holds nsIEditor instance which is
    * alive.  Otherwise, false.
    */
   bool HasEditor() const;
 
   /**
    * EditorWillHandleTextEvent() must be called before the focused editor
-   * handles the text event.
+   * handles the compositionchange event.
    */
   void EditorWillHandleTextEvent(const WidgetTextEvent* aTextEvent);
 
   /**
    * EditorDidHandleTextEvent() must be called after the focused editor handles
-   * a text event.
+   * a compositionchange event.
    */
   void EditorDidHandleTextEvent();
 
   /**
    * DispatchEvent() dispatches the aEvent to the mContent synchronously.
    * The caller must ensure that it's safe to dispatch the event.
    */
   void DispatchEvent(WidgetGUIEvent* aEvent,
@@ -266,18 +266,18 @@ private:
    */
   bool WasNativeCompositionEndEventDiscarded() const
   {
     return mWasNativeCompositionEndEventDiscarded;
   }
 
   /**
    * OnCompositionEventDiscarded() is called when PresShell discards
-   * compositionupdate, compositionend or text event due to not safe to
-   * dispatch event.
+   * compositionupdate, compositionend or compositionchange event due to not
+   * safe to dispatch event.
    */
   void OnCompositionEventDiscarded(const WidgetGUIEvent* aEvent);
 
   /**
    * Calculate composition offset then notify composition update to widget
    */
   void NotityUpdateComposition(WidgetGUIEvent* aEvent);
 
@@ -301,27 +301,24 @@ private:
     uint32_t mEventMessage;
     nsString mData;
     bool mIsSynthesizedEvent;
 
     CompositionEventDispatcher() {};
   };
 
   /**
-   * DispatchCompositionEventRunnable() dispatches a composition or text event
-   * to the content.  Be aware, if you use this method, nsPresShellEventCB
-   * isn't used.  That means that nsIFrame::HandleEvent() is never called.
+   * DispatchCompositionEventRunnable() dispatches a composition event to the
+   * content.  Be aware, if you use this method, nsPresShellEventCB isn't used.
+   * That means that nsIFrame::HandleEvent() is never called.
    * WARNING: The instance which is managed by IMEStateManager may be
    *          destroyed by this method call.
    *
-   * @param aEventMessage       Must be one of composition event or text event.
-   * @param aData               Used for data value if aEventMessage is
-   *                            NS_COMPOSITION_END.
-   *                            Used for theText value if aEventMessage is
-   *                            NS_TEXT_TEXT.
+   * @param aEventMessage       Must be one of composition events.
+   * @param aData               Used for mData value.
    * @param aIsSynthesizingCommit   true if this is called for synthesizing
    *                                commit or cancel composition.  Otherwise,
    *                                false.
    */
   void DispatchCompositionEventRunnable(uint32_t aEventMessage,
                                         const nsAString& aData,
                                         bool aIsSynthesizingCommit = false);
 };
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -1570,18 +1570,18 @@ TabParent::SendCompositionEvent(WidgetCo
   if (mIMECompositionEnding)
     return true;
   event.mSeqno = ++mIMESeqno;
   return PBrowserParent::SendCompositionEvent(event);
 }
 
 /**
  * During REQUEST_TO_COMMIT_COMPOSITION or REQUEST_TO_CANCEL_COMPOSITION,
- * widget usually sends a NS_TEXT_TEXT event to finalize or clear the
- * composition, respectively
+ * 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)
 {
   if (mIsDestroyed) {
--- a/editor/libeditor/nsEditor.cpp
+++ b/editor/libeditor/nsEditor.cpp
@@ -968,17 +968,17 @@ nsEditor::EndPlaceHolderTransaction()
       }
       else  
       {
         // in the future we will check to make sure undo is off here,
         // since that is the only known case where the placeholdertxn would disappear on us.
         // For now just removing the assert.
       }
       // notify editor observers of action but if composing, it's done by
-      // text event handler.
+      // compositionchange event handler.
       if (!mComposition) {
         NotifyEditorObservers(eNotifyEditorObserversOfEnd);
       }
     } else {
       NotifyEditorObservers(eNotifyEditorObserversOfCancel);
     }
   }
   mPlaceHolderBatch--;
@@ -5092,30 +5092,30 @@ nsEditor::IsAcceptableInputEvent(nsIDOME
   // focus, we shouldn't handle it.
   if (widgetEvent->IsUsingCoordinates()) {
     nsCOMPtr<nsIContent> focusedContent = GetFocusedContent();
     if (!focusedContent) {
       return false;
     }
   }
 
-  // If composition event or text event isn't dispatched via widget,
-  // we need to ignore them since they cannot be managed by TextComposition.
-  // E.g., the event was created by chrome JS.
+  // If a composition event isn't dispatched via widget, we need to ignore them
+  // since they cannot be managed by TextComposition. E.g., the event was
+  // created by chrome JS.
   // Note that if we allow to handle such events, editor may be confused by
   // 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_TEXT_TEXT:
-      // Don't allow text events whose internal event are not
+    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:
       // Don't allow composition events whose internal event are not
--- a/editor/libeditor/nsEditor.h
+++ b/editor/libeditor/nsEditor.h
@@ -412,19 +412,18 @@ protected:
   bool CanEnableSpellCheck()
   {
     // Check for password/readonly/disabled, which are not spellchecked
     // regardless of DOM. Also, check to see if spell check should be skipped or not.
     return !IsPasswordEditor() && !IsReadonly() && !IsDisabled() && !ShouldSkipSpellCheck();
   }
 
   /**
-   * EnsureComposition() should be composition event handlers or text event
-   * handler.  This tries to get the composition for the event and set it to
-   * mComposition.
+   * EnsureComposition() should be called by composition event handlers.  This
+   * tries to get the composition for the event and set it to mComposition.
    */
   void EnsureComposition(mozilla::WidgetGUIEvent* aEvent);
 
 public:
 
   /** All editor operations which alter the doc should be prefaced
    *  with a call to StartOperation, naming the action and direction */
   NS_IMETHOD StartOperation(EditAction opID,
--- a/editor/libeditor/nsEditorEventListener.cpp
+++ b/editor/libeditor/nsEditorEventListener.cpp
@@ -451,17 +451,17 @@ nsEditorEventListener::HandleEvent(nsIDO
     }
     // focus
     case NS_FOCUS_CONTENT:
       return Focus(aEvent);
     // blur
     case NS_BLUR_CONTENT:
       return Blur(aEvent);
     // text
-    case NS_TEXT_TEXT:
+    case NS_COMPOSITION_CHANGE:
       return HandleText(aEvent);
     // compositionstart
     case NS_COMPOSITION_START:
       return HandleStartComposition(aEvent);
     // compositionend
     case NS_COMPOSITION_END:
       HandleEndComposition(aEvent);
       return NS_OK;
--- a/editor/libeditor/nsPlaintextEditor.cpp
+++ b/editor/libeditor/nsPlaintextEditor.cpp
@@ -856,18 +856,18 @@ nsPlaintextEditor::UpdateIMEComposition(
   NS_ENSURE_TRUE(ps, NS_ERROR_NOT_INITIALIZED);
 
   nsCOMPtr<nsISelection> selection;
   nsresult rv = GetSelection(getter_AddRefs(selection));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // NOTE: TextComposition should receive selection change notification before
   //       TextEventHandlingMarker notifies TextComposition of the end of
-  //       handling TextEvent because TextComposition may need to ignore
-  //       selection changes caused by composition.  Therefore,
+  //       handling compositionchange event because TextComposition may need to
+  //       ignore selection changes caused by composition.  Therefore,
   //       TextEventHandlingMarker must be destroyed after a call of
   //       NotifiyEditorObservers(eNotifyEditorObserversOfEnd) or
   //       NotifiyEditorObservers(eNotifyEditorObserversOfCancel) which notifies
   //       TextComposition of a selection change.
   MOZ_ASSERT(!mPlaceHolderBatch,
     "UpdateIMEComposition() must be called without place holder batch");
   TextComposition::TextEventHandlingMarker
     textEventHandlingMarker(mComposition, widgetTextEvent);
--- a/widget/BasicEvents.h
+++ b/widget/BasicEvents.h
@@ -167,21 +167,26 @@
 #define NS_MUTATION_END                      (NS_MUTATION_START+6)
 
 #define NS_USER_DEFINED_EVENT         2000
  
 // composition events
 #define NS_COMPOSITION_EVENT_START    2200
 #define NS_COMPOSITION_START          (NS_COMPOSITION_EVENT_START)
 #define NS_COMPOSITION_END            (NS_COMPOSITION_EVENT_START + 1)
+// NS_COMPOSITION_UPDATE is the message for DOM compositionupdate event.
+// This event should NOT be dispatched from widget since it will be dispatched
+// by mozilla::TextComposition automatically if NS_COMPOSITION_CHANGE event
+// will change composition string.
 #define NS_COMPOSITION_UPDATE         (NS_COMPOSITION_EVENT_START + 2)
-
-// text events
-#define NS_TEXT_START                 2400
-#define NS_TEXT_TEXT                  (NS_TEXT_START)
+// NS_COMPOSITION_CHANGE is the message for representing a change of
+// composition string.  This should be dispatched from widget even if
+// composition string isn't changed but the ranges are changed.  This causes
+// a DOM "text" event which is a non-standard DOM event.
+#define NS_COMPOSITION_CHANGE         (NS_COMPOSITION_EVENT_START + 3)
 
 // UI events
 #define NS_UI_EVENT_START          2500
 // this is not to be confused with NS_ACTIVATE!
 #define NS_UI_ACTIVATE             (NS_UI_EVENT_START)
 #define NS_UI_FOCUSIN              (NS_UI_EVENT_START + 1)
 #define NS_UI_FOCUSOUT             (NS_UI_EVENT_START + 2)
 
--- a/widget/android/nsWindow.cpp
+++ b/widget/android/nsWindow.cpp
@@ -678,17 +678,17 @@ nsWindow::DispatchEvent(WidgetGUIEvent* 
             mIMEComposing = true;
             break;
         case NS_COMPOSITION_END:
             MOZ_ASSERT(mIMEComposing);
             mIMEComposing = false;
             mIMEComposingStart = -1;
             mIMEComposingText.Truncate();
             break;
-        case NS_TEXT_TEXT:
+        case NS_COMPOSITION_CHANGE:
             MOZ_ASSERT(mIMEComposing);
             mIMEComposingText = aEvent->AsTextEvent()->mData;
             break;
         }
         return status;
     }
     return nsEventStatus_eIgnore;
 }
@@ -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_TEXT_TEXT, this);
+    WidgetTextEvent 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_TEXT_TEXT, this);
+                WidgetTextEvent 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_TEXT_TEXT, this);
+            WidgetTextEvent 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_TEXT_TEXT, this);
+                WidgetTextEvent 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.h
+++ b/widget/cocoa/TextInputHandler.h
@@ -841,17 +841,17 @@ class IMEInputHandler : public PluginTex
 public:
   virtual bool OnDestroyWidget(nsChildView* aDestroyingWidget);
 
   virtual void OnFocusChangeInGecko(bool aFocus);
 
   void OnSelectionChange() { mSelectedRange.location = NSNotFound; }
 
   /**
-   * DispatchTextEvent() dispatches a text event on mWidget.
+   * DispatchTextEvent() dispatches a compositionchange event on mWidget.
    *
    * @param aText                 User text input.
    * @param aAttrString           An NSAttributedString instance which indicates
    *                              current composition string.
    * @param aSelectedRange        Current selected range (or caret position).
    * @param aDoCommit             TRUE if the composition string should be
    *                              committed.  Otherwise, FALSE.
    */
--- 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_TEXT_TEXT, mWidget);
+  WidgetTextEvent 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);
 }
@@ -2807,17 +2807,17 @@ IMEInputHandler::InsertTextAsCommittingC
     OnStartIMEComposition();
   }
 
   NSRange range = NSMakeRange(0, str.Length());
   DispatchTextEvent(str, aAttrString, range, true);
   if (Destroyed()) {
     PR_LOG(gLog, PR_LOG_ALWAYS,
       ("%p IMEInputHandler::InsertTextAsCommittingComposition, "
-       "destroyed by text event", this));
+       "destroyed by compositionchange event", this));
     return;
   }
 
   OnUpdateIMEComposition([aAttrString string]);
 
   WidgetCompositionEvent compEnd(true, NS_COMPOSITION_END, mWidget);
   InitCompositionEvent(compEnd);
   compEnd.mData = mLastDispatchedCompositionString;
@@ -2917,17 +2917,17 @@ IMEInputHandler::SetMarkedText(NSAttribu
   if (IsIMEComposing()) {
     OnUpdateIMEComposition([aAttrString string]);
 
     bool doCommit = str.IsEmpty();
     DispatchTextEvent(str, aAttrString, aSelectedRange, doCommit);
     if (Destroyed()) {
       PR_LOG(gLog, PR_LOG_ALWAYS,
         ("%p IMEInputHandler::SetMarkedText, "
-         "destroyed by text event", this));
+         "destroyed by compositionchange event", this));
       return;
     }
 
     if (doCommit) {
       WidgetCompositionEvent compEnd(true, NS_COMPOSITION_END, mWidget);
       InitCompositionEvent(compEnd);
       compEnd.mData = mLastDispatchedCompositionString;
       DispatchEvent(compEnd);
--- a/widget/gtk/nsGtkIMModule.cpp
+++ b/widget/gtk/nsGtkIMModule.cpp
@@ -434,17 +434,17 @@ nsGtkIMModule::EndIMEComposition(nsWindo
     if (!IsComposing()) {
         return NS_OK;
     }
 
     // Currently, GTK has API neither to commit nor to cancel composition
     // forcibly.  Therefore, TextComposition will recompute commit string for
     // the request even if native IME will cause unexpected commit string.
     // So, we don't need to emulate commit or cancel composition with
-    // proper composition events and a text event.
+    // proper composition events.
     // XXX ResetIME() might not enough for finishing compositoin on some
     //     environments.  We should emulate focus change too because some IMEs
     //     may commit or cancel composition at blur.
     ResetIME();
 
     return NS_OK;
 }
 
@@ -1087,31 +1087,32 @@ nsGtkIMModule::DispatchTextEvent(const n
         if (!DispatchCompositionStart()) {
             return false;
         }
     }
 
     nsEventStatus status;
     nsRefPtr<nsWindow> lastFocusedWindow = mLastFocusedWindow;
 
-    // Store the selected string which will be removed by following text event.
+    // Store the selected string which will be removed by following
+    // compositionchange event.
     if (mCompositionState == eCompositionState_CompositionStartDispatched) {
         // XXX We should assume, for now, any web applications don't change
-        //     selection at handling this text event.
+        //     selection at handling this compositionchange event.
         WidgetQueryContentEvent querySelectedTextEvent(true,
                                                        NS_QUERY_SELECTED_TEXT,
                                                        mLastFocusedWindow);
         mLastFocusedWindow->DispatchEvent(&querySelectedTextEvent, status);
         if (querySelectedTextEvent.mSucceeded) {
             mSelectedString = querySelectedTextEvent.mReply.mString;
             mCompositionStart = querySelectedTextEvent.mReply.mOffset;
         }
     }
 
-    WidgetTextEvent textEvent(true, NS_TEXT_TEXT, mLastFocusedWindow);
+    WidgetTextEvent textEvent(true, NS_COMPOSITION_CHANGE, mLastFocusedWindow);
     InitEvent(textEvent);
 
     uint32_t targetOffset = mCompositionStart;
 
     textEvent.mData = mDispatchedCompositionString = aCompositionString;
 
     if (!aIsCommit) {
         // NOTE: SetTextRangeList() assumes that mDispatchedCompositionString
@@ -1123,17 +1124,18 @@ nsGtkIMModule::DispatchTextEvent(const n
     mCompositionState = aIsCommit ?
         eCompositionState_CommitTextEventDispatched :
         eCompositionState_TextEventDispatched;
 
     mLastFocusedWindow->DispatchEvent(&textEvent, status);
     if (lastFocusedWindow->IsDestroyed() ||
         lastFocusedWindow != mLastFocusedWindow) {
         PR_LOG(gGtkIMLog, PR_LOG_ALWAYS,
-            ("    NOTE, the focused widget was destroyed/changed by text event"));
+            ("    NOTE, the focused widget was destroyed/changed by "
+             "compositionchange event"));
         return false;
     }
 
     // We cannot call SetCursorPosition for e10s-aware.
     // DispatchEvent is async on e10s, so composition rect isn't updated now
     // on tab parent.
     mCompositionTargetOffset = targetOffset;
 
--- a/widget/gtk/nsGtkIMModule.h
+++ b/widget/gtk/nsGtkIMModule.h
@@ -129,17 +129,17 @@ protected:
     // means offset from the first character of the root element of the editor.
     uint32_t mCompositionStart;
 
     // mDispatchedCompositionString is the latest composition string which
     // was dispatched by compositionupdate event.
     nsString mDispatchedCompositionString;
 
     // mSelectedString is the selected string which was removed by first
-    // text event.
+    // compositionchange event.
     nsString mSelectedString;
 
     // OnKeyEvent() temporarily sets mProcessingKeyEvent to the given native
     // event.
     GdkEventKey* mProcessingKeyEvent;
 
     // current target offset of IME composition
     uint32_t mCompositionTargetOffset;
@@ -299,16 +299,17 @@ protected:
 
     // Commits the current composition by the aString.
     bool CommitCompositionBy(const nsAString& aString);
 
     // Dispatches a composition start event or a composition end event.
     bool DispatchCompositionStart();
     bool DispatchCompositionEnd();
 
-    // Dispatches a text event.  If aIsCommit is TRUE, dispatches a committed
-    // text event.  Otherwise, dispatches a composing text event.
+    // Dispatches a compositionchange event.  If aIsCommit is TRUE, dispatches
+    // a committed compositionchange event.  Otherwise, dispatches a composing
+    // compositionchange event.
     bool DispatchTextEvent(const nsAString& aCompositionString,
                            bool aIsCommit);
 
 };
 
 #endif // __nsGtkIMModule_h__
--- a/widget/gtk/nsWindow.cpp
+++ b/widget/gtk/nsWindow.cpp
@@ -3035,22 +3035,23 @@ nsWindow::OnKeyPressEvent(GdkEventKey *a
         contextMenuEvent.refPoint = LayoutDeviceIntPoint(0, 0);
         contextMenuEvent.time = aEvent->time;
         contextMenuEvent.clickCount = 1;
         KeymapWrapper::InitInputEvent(contextMenuEvent, aEvent->state);
         DispatchEvent(&contextMenuEvent, status);
     }
     else {
         // If the character code is in the BMP, send the key press event.
-        // Otherwise, send a text event with the equivalent UTF-16 string.
+        // 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_TEXT_TEXT, this);
+            WidgetTextEvent 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);
         }
@@ -5992,17 +5993,17 @@ nsWindow::GetInputContext()
 
 nsIMEUpdatePreference
 nsWindow::GetIMEUpdatePreference()
 {
     nsIMEUpdatePreference updatePreference(
         nsIMEUpdatePreference::NOTIFY_SELECTION_CHANGE);
     // We shouldn't notify IME of selection change caused by changes of
     // composition string.  Therefore, we don't need to be notified selection
-    // changes which are caused by text events handled.
+    // changes which are caused by compositionchange events handled.
     updatePreference.DontNotifyChangesCausedByComposition();
     return updatePreference;
 }
 
 NS_IMETHODIMP_(bool)
 nsWindow::ExecuteNativeKeyBinding(NativeKeyBindingsType aType,
                                   const WidgetKeyboardEvent& aEvent,
                                   DoCommandCallback aCallback,
--- a/widget/shared/WidgetEventImpl.cpp
+++ b/widget/shared/WidgetEventImpl.cpp
@@ -127,20 +127,20 @@ WidgetEvent::HasKeyEventMessage() const
       return false;
   }
 }
 
 bool
 WidgetEvent::HasIMEEventMessage() const
 {
   switch (message) {
-    case NS_TEXT_TEXT:
     case NS_COMPOSITION_START:
     case NS_COMPOSITION_END:
     case NS_COMPOSITION_UPDATE:
+    case NS_COMPOSITION_CHANGE:
       return true;
     default:
       return false;
   }
 }
 
 bool
 WidgetEvent::HasPluginActivationEventMessage() const
--- a/widget/tests/TestWinTSF.cpp
+++ b/widget/tests/TestWinTSF.cpp
@@ -1960,17 +1960,17 @@ TestApp::TestText(void)
   HRESULT hr;
 
   /* If these fail the cause is probably one or more of:
    * nsTextStore::GetText not sending NS_QUERY_TEXT_CONTENT
    * NS_QUERY_TEXT_CONTENT not handled by ContentEventHandler
    * Bug in NS_QUERY_TEXT_CONTENT handler
    * nsTextStore::SetText not calling SetSelection or InsertTextAtSelection
    * Bug in SetSelection or InsertTextAtSelection
-   *  NS_SELECTION_SET bug or NS_COMPOSITION_* / NS_TEXT_TEXT bug
+   *  NS_SELECTION_SET bug or NS_COMPOSITION_* / NS_COMPOSITION_CHANGE bug
    */
 
   if (!mMgr->GetFocusedStore()) {
     fail("TestText: GetFocusedStore returns null #1");
     return false;
   }
 
   // Get all text
--- a/widget/windows/nsIMM32Handler.cpp
+++ b/widget/windows/nsIMM32Handler.cpp
@@ -147,17 +147,17 @@ nsIMM32Handler::GetIMEUpdatePreference()
     nsIMEUpdatePreference::NOTIFY_MOUSE_BUTTON_EVENT_ON_CHAR);
 }
 
 // used for checking the lParam of WM_IME_COMPOSITION
 #define IS_COMPOSING_LPARAM(lParam) \
   ((lParam) & (GCS_COMPSTR | GCS_COMPATTR | GCS_COMPCLAUSE | GCS_CURSORPOS))
 #define IS_COMMITTING_LPARAM(lParam) ((lParam) & GCS_RESULTSTR)
 // Some IMEs (e.g., the standard IME for Korean) don't have caret position,
-// then, we should not set caret position to text event.
+// then, we should not set caret position to compositionchange event.
 #define NO_IME_CARET -1
 
 nsIMM32Handler::nsIMM32Handler() :
   mComposingWindow(nullptr), mCursorPosition(NO_IME_CARET), mCompositionStart(0),
   mIsComposing(false), mIsComposingOnPlugin(false),
   mNativeCaretIsCreated(false)
 {
   PR_LOG(gIMM32Log, PR_LOG_ALWAYS, ("IMM32: nsIMM32Handler is created\n"));
@@ -478,20 +478,20 @@ nsIMM32Handler::OnIMEEndComposition(nsWi
     PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
       ("IMM32: OnIMEEndComposition, WM_IME_ENDCOMPOSITION is followed by "
        "WM_IME_COMPOSITION, ignoring the message..."));
     return true;
   }
 
   // Otherwise, e.g., ChangJie doesn't post WM_IME_COMPOSITION before
   // WM_IME_ENDCOMPOSITION when composition string becomes empty.
-  // Then, we should dispatch a compositionupdate event, a text event and
-  // a compositionend event.
-  // XXX Shouldn't we dispatch the text event with actual or latest composition
-  //     string?
+  // Then, we should dispatch a compositionupdate event, a compositionchange
+  // event and a compositionend event.
+  // XXX Shouldn't we dispatch the compositionchange event with actual or
+  //     latest composition string?
   PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
     ("IMM32: OnIMEEndComposition, mCompositionString=\"%s\"%s",
      NS_ConvertUTF16toUTF8(mCompositionString).get(),
      mCompositionString.IsEmpty() ? "" : ", but canceling it..."));
 
   mCompositionString.Truncate();
 
   nsIMEContext IMEContext(aWindow->GetWindowHandle());
@@ -507,20 +507,20 @@ nsIMM32Handler::OnIMEChar(nsWindow* aWin
                           WPARAM wParam,
                           LPARAM lParam,
                           MSGResult& aResult)
 {
   PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
     ("IMM32: OnIMEChar, hWnd=%08x, char=%08x\n",
      aWindow->GetWindowHandle(), wParam));
 
-  // We don't need to fire any text events from here. This method will be
-  // called when the composition string of the current IME is not drawn by us
-  // and some characters are committed. In that case, the committed string was
-  // processed in nsWindow::OnIMEComposition already.
+  // We don't need to fire any compositionchange events from here. This method
+  // will be called when the composition string of the current IME is not drawn
+  // by us and some characters are committed. In that case, the committed
+  // string was processed in nsWindow::OnIMEComposition already.
 
   // We need to consume the message so that Windows don't send two WM_CHAR msgs
   aResult.mConsumed = true;
   return true;
 }
 
 /* static */ bool
 nsIMM32Handler::OnIMECompositionFull(nsWindow* aWindow,
@@ -1054,25 +1054,26 @@ nsIMM32Handler::HandleComposition(nsWind
     // If composition string isn't changed, we can trust the lParam.
     // So, we need to do nothing.
     if (mLastDispatchedCompositionString == mCompositionString) {
       return ShouldDrawCompositionStringOurselves();
     }
 
     // IME may send WM_IME_COMPOSITION without composing lParam values
     // when composition string becomes empty (e.g., using Backspace key).
-    // If composition string is empty, we should dispatch a text event with
-    // empty string.
+    // If composition string is empty, we should dispatch a compositionchange
+    // event with empty string.
     if (mCompositionString.IsEmpty()) {
       DispatchTextEvent(aWindow, aIMEContext, false);
       return ShouldDrawCompositionStringOurselves();
     }
 
     // Otherwise, we cannot trust the lParam value.  We might need to
-    // dispatch text event with the latest composition string information.
+    // dispatch compositionchange event with the latest composition string
+    // information.
   }
 
   // See https://bugzilla.mozilla.org/show_bug.cgi?id=296339
   if (mCompositionString.IsEmpty() && !startCompositionMessageHasBeenSent) {
     // In this case, maybe, the sender is MSPinYin. That sends *only*
     // WM_IME_COMPOSITION with GCS_COMP* and GCS_RESULT* when
     // user inputted the Chinese full stop. So, that doesn't send
     // WM_IME_STARTCOMPOSITION and WM_IME_ENDCOMPOSITION.
@@ -1194,17 +1195,17 @@ nsIMM32Handler::HandleComposition(nsWind
   NS_ASSERTION(mCursorPosition <= (long)mCompositionString.Length(),
                "illegal pos");
 
   PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
     ("IMM32: HandleComposition, GCS_CURSORPOS, mCursorPosition=%d\n",
      mCursorPosition));
 
   //--------------------------------------------------------
-  // 5. Send the text event
+  // 5. Send the compositionchange event
   //--------------------------------------------------------
   DispatchTextEvent(aWindow, aIMEContext);
 
   return ShouldDrawCompositionStringOurselves();
 }
 
 void
 nsIMM32Handler::HandleEndComposition(nsWindow* aWindow)
@@ -1573,54 +1574,55 @@ nsIMM32Handler::DispatchTextEvent(nsWind
                                   bool aCheckAttr)
 {
   NS_ASSERTION(mIsComposing, "conflict state");
   PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
     ("IMM32: DispatchTextEvent, aCheckAttr=%s\n",
      aCheckAttr ? "TRUE": "FALSE"));
 
   // If we don't need to draw composition string ourselves and this is not
-  // commit event (i.e., under composing), we don't need to fire text event
-  // during composing.
+  // commit event (i.e., under composing), we don't need to fire
+  // compositionchange event during composing.
   if (aCheckAttr && !ShouldDrawCompositionStringOurselves()) {
     // But we need to adjust composition window pos and native caret pos, here.
     SetIMERelatedWindowsPos(aWindow, aIMEContext);
     return;
   }
 
   nsRefPtr<nsWindow> kungFuDeathGrip(aWindow);
 
   nsIntPoint point(0, 0);
 
-  WidgetTextEvent event(true, NS_TEXT_TEXT, aWindow);
+  WidgetTextEvent event(true, NS_COMPOSITION_CHANGE, aWindow);
 
   aWindow->InitEvent(event, &point);
 
   if (aCheckAttr) {
     event.mRanges = CreateTextRangeArray();
   }
 
   event.mData = mLastDispatchedCompositionString = mCompositionString;
 
   aWindow->DispatchWindowEvent(&event);
 
   // Calling SetIMERelatedWindowsPos will be failure on e10s at this point.
-  // text event will notify NOTIFY_IME_OF_COMPOSITION_UPDATE, then
+  // compositionchange event will notify NOTIFY_IME_OF_COMPOSITION_UPDATE, then
   // it will call SetIMERelatedWindowsPos.
 }
 
 already_AddRefed<TextRangeArray>
 nsIMM32Handler::CreateTextRangeArray()
 {
   // Sogou (Simplified Chinese IME) returns contradictory values: The cursor
   // position is actual cursor position. However, other values (composition
   // string and attributes) are empty. So, if you want to remove following
   // assertion, be careful.
   NS_ASSERTION(ShouldDrawCompositionStringOurselves(),
-    "CreateTextRangeArray is called when we don't need to fire text event");
+    "CreateTextRangeArray is called when we don't need to fire "
+    "compositionchange event");
 
   nsRefPtr<TextRangeArray> textRangeArray = new TextRangeArray();
 
   TextRange range;
   if (mClauseArray.Length() == 0) {
     // Some IMEs don't return clause array information, then, we assume that
     // all characters in the composition string are in one clause.
     range.mStartOffset = 0;
--- a/widget/windows/nsTextStore.cpp
+++ b/widget/windows/nsTextStore.cpp
@@ -1644,18 +1644,18 @@ 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 text event...", this));
-        WidgetTextEvent textEvent(true, NS_TEXT_TEXT, mWidget);
+                "dispatching compositionchange event...", this));
+        WidgetTextEvent 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);
@@ -1671,18 +1671,18 @@ nsTextStore::FlushPendingActions()
                 "flushing COMPOSITION_END={ mData=\"%s\" }",
                 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 text event...", this));
-        WidgetTextEvent textEvent(true, NS_TEXT_TEXT, mWidget);
+                "dispatching compositionchange event...", this));
+        WidgetTextEvent 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,
@@ -2264,17 +2264,17 @@ nsTextStore::RecordCompositionUpdateActi
   }
 
   // Getting display attributes is *really* complicated!
   // We first get the context and the property objects to query for
   // attributes, but since a big range can have a variety of values for
   // the attribute, we have to find out all the ranges that have distinct
   // attribute values. Then we query for what the value represents through
   // the display attribute manager and translate that to TextRange to be
-  // sent in NS_TEXT_TEXT
+  // sent in NS_COMPOSITION_CHANGE
 
   nsRefPtr<ITfProperty> attrPropetry;
   HRESULT hr = mContext->GetProperty(GUID_PROP_ATTRIBUTE,
                                      getter_AddRefs(attrPropetry));
   if (FAILED(hr) || !attrPropetry) {
     PR_LOG(sTextStoreLog, PR_LOG_ERROR,
            ("TSF: 0x%p   nsTextStore::RecordCompositionUpdateAction() FAILED "
             "due to mContext->GetProperty() failure", this));
@@ -2313,17 +2313,17 @@ nsTextStore::RecordCompositionUpdateActi
   action->mData = mComposition.mString;
   // The ranges might already have been initialized, however, if this is
   // called again, that means we need to overwrite the ranges with current
   // information.
   action->mRanges->Clear();
 
   TextRange newRange;
   // No matter if we have display attribute info or not,
-  // we always pass in at least one range to NS_TEXT_TEXT
+  // we always pass in at least one range to NS_COMPOSITION_CHANGE
   newRange.mStartOffset = 0;
   newRange.mEndOffset = action->mData.Length();
   newRange.mRangeType = NS_TEXTRANGE_RAWINPUT;
   action->mRanges->AppendElement(newRange);
 
   nsRefPtr<ITfRange> range;
   while (S_OK == enumRanges->Next(1, getter_AddRefs(range), nullptr) && range) {
 
@@ -4870,19 +4870,19 @@ nsTextStore::Content::ReplaceTextWith(LO
     uint32_t firstDifferentOffset =
       static_cast<uint32_t>(aStart) + FirstDifferentCharOffset(aReplaceString,
                                                                replacedString);
     mMinTextModifiedOffset =
       std::min(mMinTextModifiedOffset, firstDifferentOffset);
     if (mComposition.IsComposing()) {
       // Emulate text insertion during compositions, because during a
       // composition, editor expects the whole composition string to
-      // be sent in NS_TEXT_TEXT, not just the inserted part.
-      // The actual NS_TEXT_TEXT will be sent in SetSelection or
-      // OnUpdateComposition.
+      // be sent in NS_COMPOSITION_CHANGE, not just the inserted part.
+      // The actual NS_COMPOSITION_CHANGE will be sent in SetSelection
+      // or OnUpdateComposition.
       MOZ_ASSERT(aStart >= mComposition.mStart);
       MOZ_ASSERT(aStart + aLength <= mComposition.EndOffset());
       mComposition.mString.Replace(
         static_cast<uint32_t>(aStart - mComposition.mStart),
         static_cast<uint32_t>(aLength), aReplaceString);
     }
     mText.Replace(static_cast<uint32_t>(aStart),
                   static_cast<uint32_t>(aLength), aReplaceString);
--- a/widget/windows/nsTextStore.h
+++ b/widget/windows/nsTextStore.h
@@ -246,20 +246,20 @@ protected:
   bool     IsReadLocked() const { return IsReadLock(mLock); }
   bool     IsReadWriteLocked() const { return IsReadWriteLock(mLock); }
 
   // This is called immediately after a call of OnLockGranted() of mSink.
   // Note that mLock isn't cleared yet when this is called.
   void     DidLockGranted();
 
   bool     GetScreenExtInternal(RECT &aScreenExt);
-  // If aDispatchTextEvent is true, this method will dispatch text event if
-  // this is called during IME composing.  aDispatchTextEvent should be true
-  // only when this is called from SetSelection.  Because otherwise, the text
-  // event should not be sent from here.
+  // If aDispatchTextEvent is true, this method will dispatch compositionchange
+  // event if this is called during IME composing.  aDispatchTextEvent should
+  // be true only when this is called from SetSelection.  Because otherwise,
+  // the compositionchange event should not be sent from here.
   HRESULT  SetSelectionInternal(const TS_SELECTION_ACP*,
                                 bool aDispatchTextEvent = false);
   bool     InsertTextAtSelectionInternal(const nsAString &aInsertStr,
                                          TS_TEXTCHANGE* aTextChange);
   void     CommitCompositionInternal(bool);
   nsresult OnTextChangeInternal(const IMENotification& aIMENotification);
   nsresult OnSelectionChangeInternal(void);
   nsresult OnMouseButtonEventInternal(const IMENotification& aIMENotification);
@@ -317,18 +317,18 @@ protected:
   {
   public:
     // nullptr if no composition is active, otherwise the current composition
     nsRefPtr<ITfCompositionView> mView;
 
     // Current copy of the active composition string. Only mString is
     // changed during a InsertTextAtSelection call if we have a composition.
     // mString acts as a buffer until OnUpdateComposition is called
-    // and mString is flushed to editor through NS_TEXT_TEXT. This
-    // way all changes are updated in batches to avoid
+    // and mString is flushed to editor through NS_COMPOSITION_CHANGE.
+    // This way all changes are updated in batches to avoid
     // inconsistencies/artifacts.
     nsString mString;
 
     // The start of the current active composition, in ACP offsets
     LONG mStart;
 
     bool IsComposing() const
     {
--- 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_TEXT_TEXT, this);
+  WidgetTextEvent 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;
   }