Bug 1387317 - part2: EditorEventListener should stop using interface methods as far as possible r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 08 Aug 2017 11:25:36 +0900
changeset 646325 3e8a62cd03bc554e8a2647730e3076cabcb8cb37
parent 646324 a3fc8e3c1167841101d0bd49a987f34f65c5033c
child 646326 fbc0a1b4a7663959bae2af44e8903a3eeeb8b875
push id74072
push usermasayuki@d-toybox.com
push dateTue, 15 Aug 2017 04:06:48 +0000
reviewersm_kato
bugs1387317
milestone57.0a1
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);