Bug 1156062 part 6 - Clean up nsHTMLEditRules::WillInsertBreak; r=ehsan
authorAryeh Gregor <ayg@aryeh.name>
Sat, 23 Apr 2016 18:32:04 +0900
changeset 332503 e6a6d2316a3b9972fb2cb77f82837bdd95283cc7
parent 332502 42af5753ad68b7d06f0a8ba85d5b361f9ce37f6d
child 332504 02a332642272c61550235152f0e7ff89a139faac
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1156062
milestone48.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 1156062 part 6 - Clean up nsHTMLEditRules::WillInsertBreak; r=ehsan
editor/libeditor/nsHTMLEditRules.cpp
editor/libeditor/nsHTMLEditRules.h
--- a/editor/libeditor/nsHTMLEditRules.cpp
+++ b/editor/libeditor/nsHTMLEditRules.cpp
@@ -630,17 +630,17 @@ nsHTMLEditRules::WillDoAction(Selection*
     case EditAction::insertIMEText:
       UndefineCaretBidiLevel(aSelection);
       return WillInsertText(info->action, aSelection, aCancel, aHandled,
                             info->inString, info->outString, info->maxLength);
     case EditAction::loadHTML:
       return WillLoadHTML(aSelection, aCancel);
     case EditAction::insertBreak:
       UndefineCaretBidiLevel(aSelection);
-      return WillInsertBreak(aSelection, aCancel, aHandled);
+      return WillInsertBreak(*aSelection, aCancel, aHandled);
     case EditAction::deleteSelection:
       return WillDeleteSelection(aSelection, info->collapsedAction,
                                  info->stripWrappers, aCancel, aHandled);
     case EditAction::makeList:
       return WillMakeList(aSelection, info->blockType, info->entireList,
                           info->bulletType, aCancel, aHandled);
     case EditAction::indent:
       return WillIndent(aSelection, aCancel, aHandled);
@@ -1510,128 +1510,111 @@ nsHTMLEditRules::WillLoadHTML(Selection*
     mEditor->DeleteNode(mBogusNode);
     mBogusNode = nullptr;
   }
 
   return NS_OK;
 }
 
 nsresult
-nsHTMLEditRules::WillInsertBreak(Selection* aSelection,
-                                 bool* aCancel, bool* aHandled)
-{
-  if (!aSelection || !aCancel || !aHandled) {
-    return NS_ERROR_NULL_POINTER;
-  }
-  // initialize out params
+nsHTMLEditRules::WillInsertBreak(Selection& aSelection, bool* aCancel,
+                                 bool* aHandled)
+{
+  MOZ_ASSERT(aCancel && aHandled);
   *aCancel = false;
   *aHandled = false;
 
-  // if the selection isn't collapsed, delete it.
-  nsresult res = NS_OK;
-  if (!aSelection->Collapsed()) {
-    NS_ENSURE_STATE(mHTMLEditor);
+  NS_ENSURE_STATE(mHTMLEditor);
+  nsCOMPtr<nsIEditor> kungFuDeathGrip(mHTMLEditor);
+
+  // If the selection isn't collapsed, delete it.
+  nsresult res;
+  if (!aSelection.Collapsed()) {
     res = mHTMLEditor->DeleteSelection(nsIEditor::eNone, nsIEditor::eStrip);
     NS_ENSURE_SUCCESS(res, res);
   }
 
-  WillInsert(*aSelection, aCancel);
-
-  // initialize out param
-  // we want to ignore result of WillInsert()
+  WillInsert(aSelection, aCancel);
+
+  // Initialize out param.  We want to ignore result of WillInsert().
   *aCancel = false;
 
-  // split any mailcites in the way.
-  // should we abort this if we encounter table cell boundaries?
+  // Split any mailcites in the way.  Should we abort this if we encounter
+  // table cell boundaries?
   if (IsMailEditor()) {
-    res = SplitMailCites(aSelection, aHandled);
+    res = SplitMailCites(&aSelection, aHandled);
     NS_ENSURE_SUCCESS(res, res);
     if (*aHandled) {
       return NS_OK;
     }
   }
 
-  // smart splitting rules
-  nsCOMPtr<nsIDOMNode> node;
-  int32_t offset;
-
-  NS_ENSURE_STATE(mHTMLEditor);
-  res = mHTMLEditor->GetStartNodeAndOffset(aSelection, getter_AddRefs(node),
-                                           &offset);
-  NS_ENSURE_SUCCESS(res, res);
-  NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
-
-  // do nothing if the node is read-only
-  NS_ENSURE_STATE(mHTMLEditor);
+  // Smart splitting rules
+  NS_ENSURE_TRUE(aSelection.GetRangeAt(0) &&
+                 aSelection.GetRangeAt(0)->GetStartParent(),
+                 NS_ERROR_FAILURE);
+  OwningNonNull<nsINode> node = *aSelection.GetRangeAt(0)->GetStartParent();
+  int32_t offset = aSelection.GetRangeAt(0)->StartOffset();
+
+  // Do nothing if the node is read-only
   if (!mHTMLEditor->IsModifiableNode(node)) {
     *aCancel = true;
     return NS_OK;
   }
 
-  // identify the block
-  nsCOMPtr<nsIDOMNode> blockParent;
-  if (IsBlockNode(node)) {
-    blockParent = node;
-  } else {
-    NS_ENSURE_STATE(mHTMLEditor);
-    blockParent = mHTMLEditor->GetBlockNodeParent(node);
-  }
+  // Identify the block
+  nsCOMPtr<Element> blockParent = mHTMLEditor->GetBlock(node);
   NS_ENSURE_TRUE(blockParent, NS_ERROR_FAILURE);
 
-  // if the active editing host is an inline element, or if the active editing
+  // If the active editing host is an inline element, or if the active editing
   // host is the block parent itself, just append a br.
-  NS_ENSURE_STATE(mHTMLEditor);
-  nsCOMPtr<nsIContent> hostContent = mHTMLEditor->GetActiveEditingHost();
-  nsCOMPtr<nsIDOMNode> hostNode = do_QueryInterface(hostContent);
-  if (!nsEditorUtils::IsDescendantOf(blockParent, hostNode)) {
-    res = StandardBreakImpl(node, offset, aSelection);
+  nsCOMPtr<Element> host = mHTMLEditor->GetActiveEditingHost();
+  if (!nsEditorUtils::IsDescendantOf(blockParent, host)) {
+    res = StandardBreakImpl(GetAsDOMNode(node), offset, &aSelection);
     NS_ENSURE_SUCCESS(res, res);
     *aHandled = true;
     return NS_OK;
   }
 
-  // if block is empty, populate with br.  (for example, imagine a div that
-  // contains the word "text".  the user selects "text" and types return.
-  // "text" is deleted leaving an empty block.  we want to put in one br to
-  // make block have a line.  then code further below will put in a second br.)
+  // If block is empty, populate with br.  (For example, imagine a div that
+  // contains the word "text".  The user selects "text" and types return.
+  // "Text" is deleted leaving an empty block.  We want to put in one br to
+  // make block have a line.  Then code further below will put in a second br.)
   bool isEmpty;
-  IsEmptyBlock(blockParent, &isEmpty);
+  IsEmptyBlock(GetAsDOMNode(blockParent), &isEmpty);
   if (isEmpty) {
-    uint32_t blockLen;
-    NS_ENSURE_STATE(mHTMLEditor);
-    res = mHTMLEditor->GetLengthOfDOMNode(blockParent, blockLen);
-    NS_ENSURE_SUCCESS(res, res);
-    nsCOMPtr<nsIDOMNode> brNode;
-    NS_ENSURE_STATE(mHTMLEditor);
-    res = mHTMLEditor->CreateBR(blockParent, blockLen, address_of(brNode));
-    NS_ENSURE_SUCCESS(res, res);
-  }
-
-  nsCOMPtr<nsIDOMNode> listItem = IsInListItem(blockParent);
-  if (listItem && listItem != hostNode) {
-    ReturnInListItem(aSelection, listItem, node, offset);
+    nsCOMPtr<Element> br = mHTMLEditor->CreateBR(blockParent,
+                                                 blockParent->Length());
+    NS_ENSURE_STATE(br);
+  }
+
+  nsCOMPtr<Element> listItem = IsInListItem(blockParent);
+  if (listItem && listItem != host) {
+    ReturnInListItem(&aSelection, GetAsDOMNode(listItem), GetAsDOMNode(node),
+                     offset);
     *aHandled = true;
     return NS_OK;
-  } else if (nsHTMLEditUtils::IsHeader(blockParent)) {
-    // headers: close (or split) header
-    ReturnInHeader(aSelection, blockParent, node, offset);
+  } else if (nsHTMLEditUtils::IsHeader(*blockParent)) {
+    // Headers: close (or split) header
+    ReturnInHeader(&aSelection, GetAsDOMNode(blockParent), GetAsDOMNode(node),
+                   offset);
     *aHandled = true;
     return NS_OK;
-  } else if (nsHTMLEditUtils::IsParagraph(blockParent)) {
-    // paragraphs: special rules to look for <br>s
-    res = ReturnInParagraph(aSelection, blockParent, node, offset,
-                            aCancel, aHandled);
+  } else if (blockParent->IsHTMLElement(nsGkAtoms::p)) {
+    // Paragraphs: special rules to look for <br>s
+    res = ReturnInParagraph(&aSelection, GetAsDOMNode(blockParent),
+                            GetAsDOMNode(node), offset, aCancel, aHandled);
     NS_ENSURE_SUCCESS(res, res);
-    // fall through, we may not have handled it in ReturnInParagraph()
-  }
-
-  // if not already handled then do the standard thing
+    // Fall through, we may not have handled it in ReturnInParagraph()
+  }
+
+  // If not already handled then do the standard thing
   if (!(*aHandled)) {
     *aHandled = true;
-    return StandardBreakImpl(node, offset, aSelection);
+    return StandardBreakImpl(GetAsDOMNode(node), offset, &aSelection);
   }
   return NS_OK;
 }
 
 nsresult
 nsHTMLEditRules::StandardBreakImpl(nsIDOMNode* aNode, int32_t aOffset,
                                    Selection* aSelection)
 {
@@ -6369,24 +6352,16 @@ nsHTMLEditRules::MakeTransitionList(nsTA
  ********************************************************/
 
 ///////////////////////////////////////////////////////////////////////////
 // IsInListItem: if aNode is the descendant of a listitem, return that li.
 //               But table element boundaries are stoppers on the search.
 //               Also stops on the active editor host (contenteditable).
 //               Also test if aNode is an li itself.
 //
-already_AddRefed<nsIDOMNode>
-nsHTMLEditRules::IsInListItem(nsIDOMNode* aNode)
-{
-  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-  nsCOMPtr<nsIDOMNode> retval = do_QueryInterface(IsInListItem(node));
-  return retval.forget();
-}
-
 Element*
 nsHTMLEditRules::IsInListItem(nsINode* aNode)
 {
   NS_ENSURE_TRUE(aNode, nullptr);
   if (nsHTMLEditUtils::IsListItem(aNode)) {
     return aNode->AsElement();
   }
 
--- a/editor/libeditor/nsHTMLEditRules.h
+++ b/editor/libeditor/nsHTMLEditRules.h
@@ -130,17 +130,17 @@ protected:
   nsresult WillInsertText(  EditAction aAction,
                             mozilla::dom::Selection* aSelection,
                             bool            *aCancel,
                             bool            *aHandled,
                             const nsAString *inString,
                             nsAString       *outString,
                             int32_t          aMaxLength);
   nsresult WillLoadHTML(mozilla::dom::Selection* aSelection, bool* aCancel);
-  nsresult WillInsertBreak(mozilla::dom::Selection* aSelection,
+  nsresult WillInsertBreak(mozilla::dom::Selection& aSelection,
                            bool* aCancel, bool* aHandled);
   nsresult StandardBreakImpl(nsIDOMNode* aNode, int32_t aOffset,
                              mozilla::dom::Selection* aSelection);
   nsresult DidInsertBreak(mozilla::dom::Selection* aSelection,
                           nsresult aResult);
   nsresult SplitMailCites(mozilla::dom::Selection* aSelection, bool* aHandled);
   nsresult WillDeleteSelection(mozilla::dom::Selection* aSelection,
                                nsIEditor::EDirection aAction,
@@ -198,17 +198,16 @@ protected:
                                   nsINode* aNode);
   nsresult GetFormatString(nsIDOMNode *aNode, nsAString &outFormat);
   enum class Lists { no, yes };
   enum class Tables { no, yes };
   void GetInnerContent(nsINode& aNode,
                        nsTArray<mozilla::OwningNonNull<nsINode>>& aOutArrayOfNodes,
                        int32_t* aIndex, Lists aLists = Lists::yes,
                        Tables aTables = Tables::yes);
-  already_AddRefed<nsIDOMNode> IsInListItem(nsIDOMNode* aNode);
   mozilla::dom::Element* IsInListItem(nsINode* aNode);
   nsresult ReturnInHeader(mozilla::dom::Selection* aSelection,
                           nsIDOMNode* aHeader, nsIDOMNode* aTextNode,
                           int32_t aOffset);
   nsresult ReturnInParagraph(mozilla::dom::Selection* aSelection,
                              nsIDOMNode* aHeader, nsIDOMNode* aTextNode,
                              int32_t aOffset, bool* aCancel, bool* aHandled);
   nsresult SplitParagraph(nsIDOMNode *aPara,