Bug 1482018 - Create non-virtual methods of nsIHTMLEditor::Indent() equivalents r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 14 Aug 2018 08:30:09 +0000
changeset 486728 f0819f9d226d568e96b942f1ad338cebab90f088
parent 486727 d0054c7c0ed9abd6182f9369fbd64c4bd48a2f04
child 486729 50b10df2deb03b43f475fc2df6985a7cbe2d6478
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1482018
milestone63.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 1482018 - Create non-virtual methods of nsIHTMLEditor::Indent() equivalents r=m_kato nsIHTMLEditor::Indent() is used for handling Tab key in HandleKeyPressEvent() and used for implementing indent/outdent commands. Unfortunately, it takes string argument to switch between indent or outdent. So, it does not make sense to use this in C++ code. This patch creates IndentAsAction() and OutdentAsAction() as public methods and the implementation is moved to IndentOrOutdentAsSubAction() which takes EditSubAction to switch between indent and outdent. Note that HandleKeyPressEvent() uses the new public methods. However, this is not problem for the future changes since HandleKeyPressEvent() is an exception which may call other public methods. Differential Revision: https://phabricator.services.mozilla.com/D3202
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLEditor.h
editor/libeditor/HTMLEditorCommands.cpp
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -781,22 +781,22 @@ HTMLEditor::HandleKeyPressEvent(WidgetKe
         // TabInTable might cause reframe
         if (Destroyed()) {
           return NS_OK;
         }
         if (handled) {
           ScrollSelectionIntoView(false);
         }
       } else if (HTMLEditUtils::IsListItem(blockParent)) {
-        rv = Indent(aKeyboardEvent->IsShift()
-                    ? NS_LITERAL_STRING("outdent")
-                    : NS_LITERAL_STRING("indent"));
+        rv = !aKeyboardEvent->IsShift() ? IndentAsAction() : OutdentAsAction();
         handled = true;
       }
-      NS_ENSURE_SUCCESS(rv, rv);
+      if (NS_WARN_IF(NS_FAILED(rv))) {
+        return rv;
+      }
       if (handled) {
         aKeyboardEvent->PreventDefault(); // consumed
         return NS_OK;
       }
       if (aKeyboardEvent->IsShift()) {
         return NS_OK; // don't type text for shift tabs
       }
       aKeyboardEvent->PreventDefault();
@@ -2316,43 +2316,93 @@ HTMLEditor::InsertBasicBlockWithTransact
   }
 
   return rules->DidDoAction(selection, subActionInfo, rv);
 }
 
 NS_IMETHODIMP
 HTMLEditor::Indent(const nsAString& aIndent)
 {
+  if (aIndent.LowerCaseEqualsLiteral("indent")) {
+    nsresult rv = IndentAsAction();
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+    return NS_OK;
+  }
+  if (aIndent.LowerCaseEqualsLiteral("outdent")) {
+    nsresult rv = OutdentAsAction();
+    if (NS_WARN_IF(NS_FAILED(rv))) {
+      return rv;
+    }
+    return NS_OK;
+  }
+  return NS_ERROR_INVALID_ARG;
+}
+
+nsresult
+HTMLEditor::IndentAsAction()
+{
   if (!mRules) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
+  AutoPlaceholderBatch beginBatching(this);
+  nsresult rv = IndentOrOutdentAsSubAction(EditSubAction::eIndent);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  return NS_OK;
+}
+
+nsresult
+HTMLEditor::OutdentAsAction()
+{
+  if (!mRules) {
+    return NS_ERROR_NOT_INITIALIZED;
+  }
+
+  AutoPlaceholderBatch beginBatching(this);
+  nsresult rv = IndentOrOutdentAsSubAction(EditSubAction::eOutdent);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  return NS_OK;
+}
+
+nsresult
+HTMLEditor::IndentOrOutdentAsSubAction(EditSubAction aIndentOrOutdent)
+{
+  MOZ_ASSERT(mRules);
+  MOZ_ASSERT(mPlaceholderBatch);
+  MOZ_ASSERT(aIndentOrOutdent == EditSubAction::eIndent ||
+             aIndentOrOutdent == EditSubAction::eOutdent);
+
   // Protect the edit rules object from dying
   RefPtr<TextEditRules> rules(mRules);
 
   bool cancel, handled;
-  EditSubAction indentOrOutdent =
-    aIndent.LowerCaseEqualsLiteral("outdent") ? EditSubAction::eOutdent :
-                                                EditSubAction::eIndent;
-  AutoPlaceholderBatch beginBatching(this);
   AutoTopLevelEditSubActionNotifier maybeTopLevelEditSubAction(
-                                      *this, indentOrOutdent, nsIEditor::eNext);
-
-  // pre-process
+                                      *this, aIndentOrOutdent,
+                                      nsIEditor::eNext);
+
   RefPtr<Selection> selection = GetSelection();
-  NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
-
-  EditSubActionInfo subActionInfo(indentOrOutdent);
+  if (NS_WARN_IF(!selection)) {
+    return NS_ERROR_FAILURE;
+  }
+
+  EditSubActionInfo subActionInfo(aIndentOrOutdent);
   nsresult rv =
     rules->WillDoAction(selection, subActionInfo, &cancel, &handled);
   if (cancel || NS_FAILED(rv)) {
     return rv;
   }
 
-  if (!handled && selection->IsCollapsed() && aIndent.EqualsLiteral("indent")) {
+  if (!handled && selection->IsCollapsed() &&
+      aIndentOrOutdent == EditSubAction::eIndent) {
     nsRange* firstRange = selection->GetRangeAt(0);
     if (NS_WARN_IF(!firstRange)) {
       return NS_ERROR_FAILURE;
     }
 
     EditorRawDOMPoint atStartOfSelection(firstRange->StartRef());
     if (NS_WARN_IF(!atStartOfSelection.IsSet()) ||
         NS_WARN_IF(!atStartOfSelection.GetContainerAsContent())) {
@@ -2412,17 +2462,21 @@ HTMLEditor::Indent(const nsAString& aInd
       return NS_ERROR_FAILURE;
     }
     selection->Collapse(RawRangeBoundary(firstRange->GetStartContainer(), 0),
                         error);
     if (NS_WARN_IF(error.Failed())) {
       return error.StealNSResult();
     }
   }
-  return rules->DidDoAction(selection, subActionInfo, rv);
+  rv = rules->DidDoAction(selection, subActionInfo, rv);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  return NS_OK;
 }
 
 //TODO: IMPLEMENT ALIGNMENT!
 
 NS_IMETHODIMP
 HTMLEditor::Align(const nsAString& aAlignType)
 {
   // Protect the edit rules object from dying
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -176,16 +176,22 @@ public:
 
   /**
    * OnInputLineBreak() is called when user inputs a line break with
    * Shift + Enter or something.
    */
   nsresult OnInputLineBreak();
 
   /**
+   * Indent or outdent content around Selection.
+   */
+  nsresult IndentAsAction();
+  nsresult OutdentAsAction();
+
+  /**
    * event callback when a mouse button is pressed
    * @param aX      [IN] horizontal position of the pointer
    * @param aY      [IN] vertical position of the pointer
    * @param aTarget [IN] the element triggering the event
    * @param aMouseEvent [IN] the event
    */
   nsresult OnMouseDown(int32_t aX, int32_t aY, Element* aTarget,
                        dom::Event* aMouseEvent);
@@ -835,16 +841,26 @@ protected: // Shouldn't be used by frien
    * First, this method splits aStringToInsert to multiple chunks which start
    * with non-linebreaker except first chunk and end with a linebreaker except
    * last chunk.  Then, each chunk starting with ">" is inserted after wrapping
    * with <span _moz_quote="true">, and each chunk not starting with ">" is
    * inserted as normal text.
    */
   nsresult InsertTextWithQuotationsInternal(const nsAString& aStringToInsert);
 
+  /**
+   * IndentOrOutdentAsSubAction() indents or outdents the content around
+   * Selection.  Callers have to guarantee that there is a placeholder
+   * transaction.
+   *
+   * @param aEditSubAction      Must be EditSubAction::eIndent or
+   *                            EditSubAction::eOutdent.
+   */
+  nsresult IndentOrOutdentAsSubAction(EditSubAction aEditSubAction);
+
   nsresult LoadHTML(const nsAString& aInputString);
 
   nsresult SetInlinePropertyInternal(nsAtom& aProperty,
                                      nsAtom* aAttribute,
                                      const nsAString& aValue);
   nsresult RemoveInlinePropertyInternal(nsAtom* aProperty,
                                         nsAtom* aAttribute);
 
--- a/editor/libeditor/HTMLEditorCommands.cpp
+++ b/editor/libeditor/HTMLEditorCommands.cpp
@@ -510,17 +510,21 @@ IndentCommand::DoCommand(const char* aCo
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
   if (!editor) {
     return NS_OK;
   }
   mozilla::HTMLEditor* htmlEditor = editor->AsHTMLEditor();
   if (!htmlEditor) {
     return NS_OK;
   }
-  return htmlEditor->Indent(NS_LITERAL_STRING("indent"));
+  nsresult rv = htmlEditor->IndentAsAction();
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 IndentCommand::DoCommandParams(const char* aCommandName,
                                nsICommandParams* aParams,
                                nsISupports* refCon)
 {
   return DoCommand(aCommandName, refCon);
@@ -561,17 +565,21 @@ OutdentCommand::DoCommand(const char* aC
   nsCOMPtr<nsIEditor> editor = do_QueryInterface(refCon);
   if (!editor) {
     return NS_OK;
   }
   mozilla::HTMLEditor* htmlEditor = editor->AsHTMLEditor();
   if (!htmlEditor) {
     return NS_OK;
   }
-  return htmlEditor->Indent(NS_LITERAL_STRING("outdent"));
+  nsresult rv = htmlEditor->OutdentAsAction();
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  return NS_OK;
 }
 
 NS_IMETHODIMP
 OutdentCommand::DoCommandParams(const char* aCommandName,
                                 nsICommandParams* aParams,
                                 nsISupports* refCon)
 {
   return DoCommand(aCommandName, refCon);