Bug 1387317 - part2: EditorEventListener should stop using interface methods as far as possible r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 08 Aug 2017 11:25:36 +0900
changeset 424448 eda3fcc1e872d4ae310b598b3dbb0cf009c506a6
parent 424447 c88f2794e67556f256da6f00144fad0448c23990
child 424449 052c275f31668433978e39ecdd7c18ef4e8045bc
push id7761
push userjlund@mozilla.com
push dateFri, 15 Sep 2017 00:19:52 +0000
treeherdermozilla-beta@c38455951db4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1387317
milestone57.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1387317 - part2: EditorEventListener should stop using interface methods as far as possible r=m_kato MozReview-Commit-ID: EPQeBez2tJh
dom/html/nsTextEditorState.cpp
editor/libeditor/EditorBase.cpp
editor/libeditor/EditorBase.h
editor/libeditor/EditorEventListener.cpp
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLEditorDataTransfer.cpp
editor/libeditor/HTMLEditorEventListener.cpp
editor/libeditor/HTMLEditorEventListener.h
editor/libeditor/HTMLStyleEditor.cpp
editor/libeditor/TextEditor.cpp
editor/libeditor/TextEditorDataTransfer.cpp
--- a/dom/html/nsTextEditorState.cpp
+++ b/dom/html/nsTextEditorState.cpp
@@ -2567,17 +2567,17 @@ nsTextEditorState::SetValue(const nsAStr
       if (nsContentUtils::IsSafeToRunScript()) {
         WeakPtr<nsTextEditorState> self(this);
         // WARNING: During this call, compositionupdate, compositionend, input
         // events will be fired.  Therefore, everything can occur.  E.g., the
         // document may be unloaded.
         mValueBeingSet = aValue;
         mIsCommittingComposition = true;
         RefPtr<TextEditor> textEditor = mTextEditor;
-        nsresult rv = textEditor->ForceCompositionEnd();
+        nsresult rv = textEditor->CommitComposition();
         if (!self.get()) {
           return true;
         }
         mIsCommittingComposition = false;
         // If this is called recursively during committing composition and
         // some of them may be skipped above.  Therefore, we need to set
         // value to the editor with the aValue of the latest call.
         newValue = mValueBeingSet;
--- a/editor/libeditor/EditorBase.cpp
+++ b/editor/libeditor/EditorBase.cpp
@@ -2188,21 +2188,23 @@ EditorBase::EndIMEComposition()
 
   // notify editor observers of action
   NotifyEditorObservers(eNotifyEditorObserversOfEnd);
 }
 
 NS_IMETHODIMP
 EditorBase::ForceCompositionEnd()
 {
-  nsCOMPtr<nsIPresShell> ps = GetPresShell();
-  if (!ps) {
-    return NS_ERROR_NOT_AVAILABLE;
-  }
-  nsPresContext* pc = ps->GetPresContext();
+  return CommitComposition();
+}
+
+nsresult
+EditorBase::CommitComposition()
+{
+  nsPresContext* pc = GetPresContext();
   if (!pc) {
     return NS_ERROR_NOT_AVAILABLE;
   }
 
   return mComposition ?
     IMEStateManager::NotifyIME(REQUEST_TO_COMMIT_COMPOSITION, pc) : NS_OK;
 }
 
--- a/editor/libeditor/EditorBase.h
+++ b/editor/libeditor/EditorBase.h
@@ -246,16 +246,21 @@ protected:
 public:
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(EditorBase, nsIEditor)
 
   bool IsInitialized() const { return !!mDocument; }
   already_AddRefed<nsIDOMDocument> GetDOMDocument();
   already_AddRefed<nsIDocument> GetDocument();
   already_AddRefed<nsIPresShell> GetPresShell();
+  nsPresContext* GetPresContext()
+  {
+    RefPtr<nsIPresShell> presShell = GetPresShell();
+    return presShell ? presShell->GetPresContext() : nullptr;
+  }
   already_AddRefed<nsIWidget> GetWidget();
   nsISelectionController* GetSelectionController() const
   {
     if (mSelectionController) {
       return mSelectionController;
     }
     if (!mDocument) {
       return nullptr;
@@ -346,16 +351,25 @@ public:
   /**
    * IME event handlers.
    */
   virtual nsresult BeginIMEComposition(WidgetCompositionEvent* aEvent);
   virtual nsresult UpdateIMEComposition(
                      WidgetCompositionEvent* aCompositionChangeEvet) = 0;
   void EndIMEComposition();
 
+  /**
+   * Commit composition if there is.
+   * Note that when there is a composition, this requests to commit composition
+   * to native IME.  Therefore, when there is composition, this can do anything.
+   * For example, the editor instance, the widget or the process itself may
+   * be destroyed.
+   */
+  nsresult CommitComposition();
+
   void SwitchTextDirectionTo(uint32_t aDirection);
 
 protected:
   nsresult DetermineCurrentDirection();
   void FireInputEvent();
 
   /**
    * Create a transaction for setting aAttribute to aValue on aElement.  Never
@@ -942,16 +956,46 @@ public:
    */
   Element* GetExposedRoot();
 
   /**
    * Accessor methods to flags.
    */
   uint32_t Flags() const { return mFlags; }
 
+  nsresult AddFlags(uint32_t aFlags)
+  {
+    const uint32_t kOldFlags = Flags();
+    const uint32_t kNewFlags = (kOldFlags | aFlags);
+    if (kNewFlags == kOldFlags) {
+      return NS_OK;
+    }
+    return SetFlags(kNewFlags); // virtual call and may be expensive.
+  }
+  nsresult RemoveFlags(uint32_t aFlags)
+  {
+    const uint32_t kOldFlags = Flags();
+    const uint32_t kNewFlags = (kOldFlags & ~aFlags);
+    if (kNewFlags == kOldFlags) {
+      return NS_OK;
+    }
+    return SetFlags(kNewFlags); // virtual call and may be expensive.
+  }
+  nsresult AddAndRemoveFlags(uint32_t aAddingFlags, uint32_t aRemovingFlags)
+  {
+    MOZ_ASSERT(!(aAddingFlags & aRemovingFlags),
+               "Same flags are specified both adding and removing");
+    const uint32_t kOldFlags = Flags();
+    const uint32_t kNewFlags = ((kOldFlags | aAddingFlags) & ~aRemovingFlags);
+    if (kNewFlags == kOldFlags) {
+      return NS_OK;
+    }
+    return SetFlags(kNewFlags); // virtual call and may be expensive.
+  }
+
   bool IsPlaintextEditor() const
   {
     return (mFlags & nsIPlaintextEditor::eEditorPlaintextMask) != 0;
   }
 
   bool IsSingleLineEditor() const
   {
     return (mFlags & nsIPlaintextEditor::eEditorSingleLineMask) != 0;
--- a/editor/libeditor/EditorEventListener.cpp
+++ b/editor/libeditor/EditorEventListener.cpp
@@ -7,16 +7,17 @@
 #include "EditorEventListener.h"
 
 #include "mozilla/Assertions.h"         // for MOZ_ASSERT, etc.
 #include "mozilla/ContentEvents.h"      // for InternalFocusEvent
 #include "mozilla/EditorBase.h"         // for EditorBase, etc.
 #include "mozilla/EventListenerManager.h" // for EventListenerManager
 #include "mozilla/IMEStateManager.h"    // for IMEStateManager
 #include "mozilla/Preferences.h"        // for Preferences
+#include "mozilla/TextEditor.h"         // for TextEditor
 #include "mozilla/TextEvents.h"         // for WidgetCompositionEvent
 #include "mozilla/dom/Element.h"        // for Element
 #include "mozilla/dom/Event.h"          // for Event
 #include "mozilla/dom/EventTarget.h"    // for EventTarget
 #include "mozilla/dom/Selection.h"
 #include "nsAString.h"
 #include "nsCaret.h"                    // for nsCaret
 #include "nsDebug.h"                    // for NS_ENSURE_TRUE, etc.
@@ -31,21 +32,18 @@
 #include "nsIDOMDocument.h"             // for nsIDOMDocument
 #include "nsIDOMDragEvent.h"            // for nsIDOMDragEvent
 #include "nsIDOMElement.h"              // for nsIDOMElement
 #include "nsIDOMEvent.h"                // for nsIDOMEvent
 #include "nsIDOMEventTarget.h"          // for nsIDOMEventTarget
 #include "nsIDOMMouseEvent.h"           // for nsIDOMMouseEvent
 #include "nsIDOMNode.h"                 // for nsIDOMNode
 #include "nsIDocument.h"                // for nsIDocument
-#include "nsIEditor.h"                  // for EditorBase::GetSelection, etc.
-#include "nsIEditorMailSupport.h"       // for nsIEditorMailSupport
 #include "nsIFocusManager.h"            // for nsIFocusManager
 #include "nsIFormControl.h"             // for nsIFormControl, etc.
-#include "nsIHTMLEditor.h"              // for nsIHTMLEditor
 #include "nsINode.h"                    // for nsINode, ::NODE_IS_EDITABLE, etc.
 #include "nsIPlaintextEditor.h"         // for nsIPlaintextEditor, etc.
 #include "nsIPresShell.h"               // for nsIPresShell
 #include "nsISelectionController.h"     // for nsISelectionController, etc.
 #include "nsITransferable.h"            // for kFileMime, kHTMLMime, etc.
 #include "nsIWidget.h"                  // for nsIWidget
 #include "nsLiteralString.h"            // for NS_LITERAL_STRING
 #include "nsPIWindowRoot.h"             // for nsPIWindowRoot
@@ -361,17 +359,17 @@ EditorEventListener::DetachedFromEditorO
          aWidgetEvent->DefaultPrevented();
 }
 
 bool
 EditorEventListener::EnsureCommitCompoisition()
 {
   MOZ_ASSERT(!DetachedFromEditor());
   RefPtr<EditorBase> editorBase(mEditorBase);
-  editorBase->ForceCompositionEnd();
+  editorBase->CommitComposition();
   return !DetachedFromEditor();
 }
 
 NS_IMETHODIMP
 EditorEventListener::HandleEvent(nsIDOMEvent* aEvent)
 {
   // Let's handle each event with the message of the internal event of the
   // coming event.  If the DOM event was created with improper interface,
@@ -706,45 +704,42 @@ EditorEventListener::HandleMiddleClickPa
   if (NS_FAILED(aMouseEvent->GetRangeParent(getter_AddRefs(parent)))) {
     return NS_ERROR_NULL_POINTER;
   }
   int32_t offset = 0;
   if (NS_FAILED(aMouseEvent->GetRangeOffset(&offset))) {
     return NS_ERROR_NULL_POINTER;
   }
 
-  RefPtr<EditorBase> editorBase(mEditorBase);
-  RefPtr<Selection> selection = editorBase->GetSelection();
+  RefPtr<TextEditor> textEditor = mEditorBase->AsTextEditor();
+  MOZ_ASSERT(textEditor);
+
+  RefPtr<Selection> selection = textEditor->GetSelection();
   if (selection) {
     selection->Collapse(parent, offset);
   }
 
-  // If the ctrl key is pressed, we'll do paste as quotation.
-  // Would've used the alt key, but the kde wmgr treats alt-middle specially.
-  nsCOMPtr<nsIEditorMailSupport> mailEditor;
-  if (clickEvent->IsControl()) {
-    mailEditor = do_QueryObject(editorBase);
-  }
-
   nsresult rv;
   int32_t clipboard = nsIClipboard::kGlobalClipboard;
   nsCOMPtr<nsIClipboard> clipboardService =
     do_GetService("@mozilla.org/widget/clipboard;1", &rv);
   if (NS_SUCCEEDED(rv)) {
     bool selectionSupported;
     rv = clipboardService->SupportsSelectionClipboard(&selectionSupported);
     if (NS_SUCCEEDED(rv) && selectionSupported) {
       clipboard = nsIClipboard::kSelectionClipboard;
     }
   }
 
-  if (mailEditor) {
-    mailEditor->PasteAsQuotation(clipboard);
+  // If the ctrl key is pressed, we'll do paste as quotation.
+  // Would've used the alt key, but the kde wmgr treats alt-middle specially.
+  if (clickEvent->IsControl()) {
+    textEditor->PasteAsQuotation(clipboard);
   } else {
-    editorBase->Paste(clipboard);
+    textEditor->Paste(clipboard);
   }
 
   // Prevent the event from propagating up to be possibly handled
   // again by the containing window:
   clickEvent->StopPropagation();
   clickEvent->PreventDefault();
 
   // We processed the event, whether drop/paste succeeded or not
@@ -1186,21 +1181,18 @@ EditorEventListener::Blur(InternalFocusE
 void
 EditorEventListener::SpellCheckIfNeeded()
 {
   MOZ_ASSERT(!DetachedFromEditor());
 
   // If the spell check skip flag is still enabled from creation time,
   // disable it because focused editors are allowed to spell check.
   RefPtr<EditorBase> editorBase(mEditorBase);
-  uint32_t currentFlags = 0;
-  editorBase->GetFlags(&currentFlags);
-  if(currentFlags & nsIPlaintextEditor::eEditorSkipSpellCheck) {
-    currentFlags ^= nsIPlaintextEditor::eEditorSkipSpellCheck;
-    editorBase->SetFlags(currentFlags);
+  if(editorBase->ShouldSkipSpellCheck()) {
+    editorBase->RemoveFlags(nsIPlaintextEditor::eEditorSkipSpellCheck);
   }
 }
 
 bool
 EditorEventListener::IsFileControlTextBox()
 {
   MOZ_ASSERT(!DetachedFromEditor());
 
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -1198,17 +1198,17 @@ HTMLEditor::CollapseSelectionToDeepestNo
 NS_IMETHODIMP
 HTMLEditor::ReplaceHeadContentsWithHTML(const nsAString& aSourceToInsert)
 {
   // don't do any post processing, rules get confused
   AutoRules beginRulesSniffing(this, EditAction::ignore, nsIEditor::eNone);
   RefPtr<Selection> selection = GetSelection();
   NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
 
-  ForceCompositionEnd();
+  CommitComposition();
 
   // Do not use AutoRules -- rules code won't let us insert in <head>.  Use
   // the head node as a parent and delete/insert directly.
   nsCOMPtr<nsIDocument> document = GetDocument();
   if (NS_WARN_IF(!document)) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
@@ -1268,17 +1268,17 @@ HTMLEditor::ReplaceHeadContentsWithHTML(
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 HTMLEditor::RebuildDocumentFromSource(const nsAString& aSourceString)
 {
-  ForceCompositionEnd();
+  CommitComposition();
 
   RefPtr<Selection> selection = GetSelection();
   NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
 
   nsCOMPtr<Element> bodyElement = GetRoot();
   NS_ENSURE_TRUE(bodyElement, NS_ERROR_NULL_POINTER);
 
   // Find where the <body> tag starts.
@@ -1532,17 +1532,17 @@ HTMLEditor::InsertElementAtSelection(nsI
   // Protect the edit rules object from dying
   nsCOMPtr<nsIEditRules> rules(mRules);
 
   nsCOMPtr<Element> element = do_QueryInterface(aElement);
   NS_ENSURE_TRUE(element, NS_ERROR_NULL_POINTER);
 
   nsCOMPtr<nsIDOMNode> node = do_QueryInterface(aElement);
 
-  ForceCompositionEnd();
+  CommitComposition();
   AutoEditBatch beginBatching(this);
   AutoRules beginRulesSniffing(this, EditAction::insertElement,
                                nsIEditor::eNext);
 
   RefPtr<Selection> selection = GetSelection();
   if (!selection) {
     return NS_ERROR_FAILURE;
   }
@@ -3575,17 +3575,17 @@ HTMLEditor::SelectEntireDocument(Selecti
   }
 
   return EditorBase::SelectEntireDocument(aSelection);
 }
 
 NS_IMETHODIMP
 HTMLEditor::SelectAll()
 {
-  ForceCompositionEnd();
+  CommitComposition();
 
   RefPtr<Selection> selection = GetSelection();
   NS_ENSURE_STATE(selection);
 
   nsCOMPtr<nsIDOMNode> anchorNode;
   nsresult rv = selection->GetAnchorNode(getter_AddRefs(anchorNode));
   NS_ENSURE_SUCCESS(rv, rv);
 
@@ -4514,17 +4514,17 @@ HTMLEditor::SetIsCSSEnabled(bool aIsCSSP
   return SetFlags(flags);
 }
 
 // Set the block background color
 nsresult
 HTMLEditor::SetCSSBackgroundColor(const nsAString& aColor)
 {
   NS_ENSURE_TRUE(mRules, NS_ERROR_NOT_INITIALIZED);
-  ForceCompositionEnd();
+  CommitComposition();
 
   // Protect the edit rules object from dying
   nsCOMPtr<nsIEditRules> rules(mRules);
 
   RefPtr<Selection> selection = GetSelection();
   NS_ENSURE_STATE(selection);
 
   bool isCollapsed = selection->Collapsed();
--- a/editor/libeditor/HTMLEditorDataTransfer.cpp
+++ b/editor/libeditor/HTMLEditorDataTransfer.cpp
@@ -97,17 +97,17 @@ static nsresult FindTargetNode(nsIDOMNod
                                nsCOMPtr<nsIDOMNode>& aResult);
 
 nsresult
 HTMLEditor::LoadHTML(const nsAString& aInputString)
 {
   NS_ENSURE_TRUE(mRules, NS_ERROR_NOT_INITIALIZED);
 
   // force IME commit; set up rules sniffing and batching
-  ForceCompositionEnd();
+  CommitComposition();
   AutoEditBatch beginBatching(this);
   AutoRules beginRulesSniffing(this, EditAction::loadHTML, nsIEditor::eNext);
 
   // Get selection
   RefPtr<Selection> selection = GetSelection();
   NS_ENSURE_STATE(selection);
 
   TextRulesInfo ruleInfo(EditAction::loadHTML);
@@ -192,17 +192,17 @@ HTMLEditor::DoInsertHTMLWithContext(cons
                                     bool aClearStyle)
 {
   NS_ENSURE_TRUE(mRules, NS_ERROR_NOT_INITIALIZED);
 
   // Prevent the edit rules object from dying
   nsCOMPtr<nsIEditRules> rules(mRules);
 
   // force IME commit; set up rules sniffing and batching
-  ForceCompositionEnd();
+  CommitComposition();
   AutoEditBatch beginBatching(this);
   AutoRules beginRulesSniffing(this, EditAction::htmlPaste, nsIEditor::eNext);
 
   // Get selection
   RefPtr<Selection> selection = GetSelection();
   NS_ENSURE_STATE(selection);
 
   // create a dom document fragment that represents the structure to paste
@@ -1489,17 +1489,17 @@ HTMLEditor::PasteTransferable(nsITransfe
  */
 NS_IMETHODIMP
 HTMLEditor::PasteNoFormatting(int32_t aSelectionType)
 {
   if (!FireClipboardEvent(ePasteNoFormatting, aSelectionType)) {
     return NS_OK;
   }
 
-  ForceCompositionEnd();
+  CommitComposition();
 
   // Get Clipboard Service
   nsresult rv;
   nsCOMPtr<nsIClipboard> clipboard(do_GetService("@mozilla.org/widget/clipboard;1", &rv));
   NS_ENSURE_SUCCESS(rv, rv);
 
   // Get the nsITransferable interface for getting the data from the clipboard.
   // use TextEditor::PrepareTransferable() to force unicode plaintext data.
--- a/editor/libeditor/HTMLEditorEventListener.cpp
+++ b/editor/libeditor/HTMLEditorEventListener.cpp
@@ -13,18 +13,16 @@
 #include "nsCOMPtr.h"
 #include "nsDebug.h"
 #include "nsError.h"
 #include "nsIDOMElement.h"
 #include "nsIDOMEvent.h"
 #include "nsIDOMEventTarget.h"
 #include "nsIDOMMouseEvent.h"
 #include "nsIDOMNode.h"
-#include "nsIHTMLInlineTableEditor.h"
-#include "nsIHTMLObjectResizer.h"
 #include "nsISupportsImpl.h"
 #include "nsLiteralString.h"
 #include "nsQueryObject.h"
 #include "nsRange.h"
 
 namespace mozilla {
 
 using namespace dom;
--- a/editor/libeditor/HTMLEditorEventListener.h
+++ b/editor/libeditor/HTMLEditorEventListener.h
@@ -7,17 +7,16 @@
 #define HTMLEditorEventListener_h
 
 #include "EditorEventListener.h"
 #include "nscore.h"
 
 namespace mozilla {
 
 class EditorBase;
-class HTMLEditor;
 
 class HTMLEditorEventListener final : public EditorEventListener
 {
 public:
   HTMLEditorEventListener()
   {
   }
 
--- a/editor/libeditor/HTMLStyleEditor.cpp
+++ b/editor/libeditor/HTMLStyleEditor.cpp
@@ -105,17 +105,17 @@ HTMLEditor::RemoveAllDefaultProperties()
 NS_IMETHODIMP
 HTMLEditor::SetInlineProperty(nsIAtom* aProperty,
                               const nsAString& aAttribute,
                               const nsAString& aValue)
 {
   NS_ENSURE_TRUE(aProperty, NS_ERROR_NULL_POINTER);
   NS_ENSURE_TRUE(mRules, NS_ERROR_NOT_INITIALIZED);
   nsCOMPtr<nsIEditRules> rules(mRules);
-  ForceCompositionEnd();
+  CommitComposition();
 
   RefPtr<Selection> selection = GetSelection();
   NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
 
   if (selection->Collapsed()) {
     // Manipulating text attributes on a collapsed selection only sets state
     // for the next text insertion
     mTypeInState->SetProp(aProperty, aAttribute, aValue);
@@ -1197,17 +1197,17 @@ HTMLEditor::RemoveInlineProperty(nsIAtom
 }
 
 nsresult
 HTMLEditor::RemoveInlinePropertyImpl(nsIAtom* aProperty,
                                      const nsAString* aAttribute)
 {
   MOZ_ASSERT_IF(aProperty, aAttribute);
   NS_ENSURE_TRUE(mRules, NS_ERROR_NOT_INITIALIZED);
-  ForceCompositionEnd();
+  CommitComposition();
 
   RefPtr<Selection> selection = GetSelection();
   NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
 
   if (selection->Collapsed()) {
     // Manipulating text attributes on a collapsed selection only sets state
     // for the next text insertion
 
@@ -1346,17 +1346,17 @@ NS_IMETHODIMP
 HTMLEditor::DecreaseFontSize()
 {
   return RelativeFontChange(FontSize::decr);
 }
 
 nsresult
 HTMLEditor::RelativeFontChange(FontSize aDir)
 {
-  ForceCompositionEnd();
+  CommitComposition();
 
   // Get the selection
   RefPtr<Selection> selection = GetSelection();
   NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
   // If selection is collapsed, set typing state
   if (selection->Collapsed()) {
     nsIAtom& atom = aDir == FontSize::incr ? *nsGkAtoms::big :
                                              *nsGkAtoms::small;
--- a/editor/libeditor/TextEditor.cpp
+++ b/editor/libeditor/TextEditor.cpp
@@ -1075,17 +1075,17 @@ TextEditor::SetNewlineHandling(int32_t a
 NS_IMETHODIMP
 TextEditor::Undo(uint32_t aCount)
 {
   // Protect the edit rules object from dying
   nsCOMPtr<nsIEditRules> rules(mRules);
 
   AutoUpdateViewBatch beginViewBatching(this);
 
-  ForceCompositionEnd();
+  CommitComposition();
 
   NotifyEditorObservers(eNotifyEditorObserversOfBefore);
 
   AutoRules beginRulesSniffing(this, EditAction::undo, nsIEditor::eNone);
 
   TextRulesInfo ruleInfo(EditAction::undo);
   RefPtr<Selection> selection = GetSelection();
   bool cancel, handled;
@@ -1103,17 +1103,17 @@ TextEditor::Undo(uint32_t aCount)
 NS_IMETHODIMP
 TextEditor::Redo(uint32_t aCount)
 {
   // Protect the edit rules object from dying
   nsCOMPtr<nsIEditRules> rules(mRules);
 
   AutoUpdateViewBatch beginViewBatching(this);
 
-  ForceCompositionEnd();
+  CommitComposition();
 
   NotifyEditorObservers(eNotifyEditorObserversOfBefore);
 
   AutoRules beginRulesSniffing(this, EditAction::redo, nsIEditor::eNone);
 
   TextRulesInfo ruleInfo(EditAction::redo);
   RefPtr<Selection> selection = GetSelection();
   bool cancel, handled;
@@ -1145,17 +1145,17 @@ TextEditor::CanCutOrCopy(PasswordFieldAl
 }
 
 bool
 TextEditor::FireClipboardEvent(EventMessage aEventMessage,
                                int32_t aSelectionType,
                                bool* aActionTaken)
 {
   if (aEventMessage == ePaste) {
-    ForceCompositionEnd();
+    CommitComposition();
   }
 
   nsCOMPtr<nsIPresShell> presShell = GetPresShell();
   NS_ENSURE_TRUE(presShell, false);
 
   RefPtr<Selection> selection = GetSelection();
   if (!selection) {
     return false;
--- a/editor/libeditor/TextEditorDataTransfer.cpp
+++ b/editor/libeditor/TextEditorDataTransfer.cpp
@@ -158,17 +158,17 @@ TextEditor::InsertFromDataTransfer(DataT
   }
 
   return NS_OK;
 }
 
 nsresult
 TextEditor::InsertFromDrop(nsIDOMEvent* aDropEvent)
 {
-  ForceCompositionEnd();
+  CommitComposition();
 
   nsCOMPtr<nsIDOMDragEvent> dragEvent(do_QueryInterface(aDropEvent));
   NS_ENSURE_TRUE(dragEvent, NS_ERROR_FAILURE);
 
   nsCOMPtr<nsIDOMDataTransfer> domDataTransfer;
   dragEvent->GetDataTransfer(getter_AddRefs(domDataTransfer));
   nsCOMPtr<DataTransfer> dataTransfer = do_QueryInterface(domDataTransfer);
   NS_ENSURE_TRUE(dataTransfer, NS_ERROR_FAILURE);