Backed out changeset 7be23bb65b93 (bug 1324505)
authorMakoto Kato <m_kato@ga2.so-net.ne.jp>
Mon, 16 Jan 2017 19:32:56 +0900
changeset 461335 72c812f1512cb8c51d2567ec925053bb8cecfe44
parent 461334 7be23bb65b937c7b2729c195bb2c2c5cf040b5b4
child 461336 948912e1d62dd5824730e6513d2068d578cea00c
push id41655
push userbmo:npang@mozilla.com
push dateMon, 16 Jan 2017 14:31:16 +0000
bugs1324505
milestone53.0a1
backs out7be23bb65b937c7b2729c195bb2c2c5cf040b5b4
Backed out changeset 7be23bb65b93 (bug 1324505) MozReview-Commit-ID: 8ONKT1Q6oER
editor/libeditor/HTMLEditRules.cpp
editor/libeditor/HTMLEditRules.h
editor/libeditor/HTMLEditor.cpp
editor/libeditor/HTMLEditor.h
--- a/editor/libeditor/HTMLEditRules.cpp
+++ b/editor/libeditor/HTMLEditRules.cpp
@@ -3402,17 +3402,17 @@ HTMLEditRules::WillRemoveList(Selection*
 
   // Only act on lists or list items in the array
   for (auto& curNode : arrayOfNodes) {
     // here's where we actually figure out what to do
     if (HTMLEditUtils::IsListItem(curNode)) {
       // unlist this listitem
       bool bOutOfList;
       do {
-        rv = PopListItem(*curNode->AsContent(), &bOutOfList);
+        rv = PopListItem(GetAsDOMNode(curNode), &bOutOfList);
         NS_ENSURE_SUCCESS(rv, rv);
       } while (!bOutOfList); // keep popping it out until it's not in a list anymore
     } else if (HTMLEditUtils::IsList(curNode)) {
       // node is a list, move list items out
       rv = RemoveListStructure(*curNode->AsElement());
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
@@ -4122,17 +4122,18 @@ HTMLEditRules::WillOutdent(Selection& aS
                                   getter_AddRefs(rememberedLeftBQ),
                                   getter_AddRefs(rememberedRightBQ));
           NS_ENSURE_SUCCESS(rv, rv);
           curBlockQuote = nullptr;
           firstBQChild = nullptr;
           lastBQChild = nullptr;
           curBlockQuoteIsIndentedWithCSS = false;
         }
-        rv = PopListItem(*curNode->AsContent());
+        bool unused;
+        rv = PopListItem(GetAsDOMNode(curNode), &unused);
         NS_ENSURE_SUCCESS(rv, rv);
         continue;
       }
       // Do we have a blockquote that we are already committed to removing?
       if (curBlockQuote) {
         // If so, is this node a descendant?
         if (EditorUtils::IsDescendantOf(curNode, curBlockQuote)) {
           lastBQChild = curNode;
@@ -4203,17 +4204,18 @@ HTMLEditRules::WillOutdent(Selection& aS
             NS_ENSURE_SUCCESS(rv, rv);
           }
           // handled list item case above
         } else if (HTMLEditUtils::IsList(curNode)) {
           // node is a list, but parent is non-list: move list items out
           nsCOMPtr<nsIContent> child = curNode->GetLastChild();
           while (child) {
             if (HTMLEditUtils::IsListItem(child)) {
-              rv = PopListItem(*child);
+              bool unused;
+              rv = PopListItem(GetAsDOMNode(child), &unused);
               NS_ENSURE_SUCCESS(rv, rv);
             } else if (HTMLEditUtils::IsList(child)) {
               // We have an embedded list, so move it out from under the parent
               // list. Be sure to put it after the parent list because this
               // loop iterates backwards through the parent's list of children.
 
               rv = htmlEditor->MoveNode(child, curParent, offset + 1);
               NS_ENSURE_SUCCESS(rv, rv);
@@ -4911,30 +4913,34 @@ HTMLEditRules::CheckForEmptyBlock(nsINod
 
   if (emptyBlock && emptyBlock->IsEditable()) {
     nsCOMPtr<nsINode> blockParent = emptyBlock->GetParentNode();
     NS_ENSURE_TRUE(blockParent, NS_ERROR_FAILURE);
     int32_t offset = blockParent->IndexOf(emptyBlock);
 
     if (HTMLEditUtils::IsListItem(emptyBlock)) {
       // Are we the first list item in the list?
+      bool bIsFirst;
       NS_ENSURE_STATE(htmlEditor);
-      if (htmlEditor->IsFirstEditableChild(emptyBlock)) {
+      nsresult rv =
+        htmlEditor->IsFirstEditableChild(GetAsDOMNode(emptyBlock), &bIsFirst);
+      NS_ENSURE_SUCCESS(rv, rv);
+      if (bIsFirst) {
         nsCOMPtr<nsINode> listParent = blockParent->GetParentNode();
         NS_ENSURE_TRUE(listParent, NS_ERROR_FAILURE);
         int32_t listOffset = listParent->IndexOf(blockParent);
         // If we are a sublist, skip the br creation
         if (!HTMLEditUtils::IsList(listParent)) {
           // Create a br before list
           NS_ENSURE_STATE(htmlEditor);
           nsCOMPtr<Element> br =
             htmlEditor->CreateBR(listParent, listOffset);
           NS_ENSURE_STATE(br);
           // Adjust selection to be right before it
-          nsresult rv = aSelection->Collapse(listParent, listOffset);
+          rv = aSelection->Collapse(listParent, listOffset);
           NS_ENSURE_SUCCESS(rv, rv);
         }
         // Else just let selection percolate up.  We'll adjust it in
         // AfterEdit()
       }
     } else {
       if (aAction == nsIEditor::eNext || aAction == nsIEditor::eNextWord ||
           aAction == nsIEditor::eToEndOfLine) {
@@ -6512,17 +6518,20 @@ HTMLEditRules::ReturnInListItem(Selectio
   nsresult rv = IsEmptyBlock(aListItem, &isEmpty, MozBRCounts::no);
   NS_ENSURE_SUCCESS(rv, rv);
   if (isEmpty && root != list && mReturnInEmptyLIKillsList) {
     // Get the list offset now -- before we might eventually split the list
     nsCOMPtr<nsINode> listParent = list->GetParentNode();
     int32_t offset = listParent ? listParent->IndexOf(list) : -1;
 
     // Are we the last list item in the list?
-    if (!htmlEditor->IsLastEditableChild(&aListItem)) {
+    bool isLast;
+    rv = htmlEditor->IsLastEditableChild(aListItem.AsDOMNode(), &isLast);
+    NS_ENSURE_SUCCESS(rv, rv);
+    if (!isLast) {
       // We need to split the list!
       ErrorResult rv;
       htmlEditor->SplitNode(*list, itemOffset, rv);
       NS_ENSURE_TRUE(!rv.Failed(), rv.StealNSResult());
     }
 
     // Are we in a sublist?
     if (HTMLEditUtils::IsList(listParent)) {
@@ -7839,92 +7848,93 @@ HTMLEditRules::ListIsEmptyLine(nsTArray<
       return false;
     }
   }
   return true;
 }
 
 
 nsresult
-HTMLEditRules::PopListItem(nsIContent& aListItem,
+HTMLEditRules::PopListItem(nsIDOMNode* aListItem,
                            bool* aOutOfList)
 {
+  nsCOMPtr<Element> listItem = do_QueryInterface(aListItem);
+  // check parms
+  NS_ENSURE_TRUE(listItem && aOutOfList, NS_ERROR_NULL_POINTER);
+
   // init out params
-  if (aOutOfList) {
-    *aOutOfList = false;
-  }
-
-  nsCOMPtr<nsIContent> kungFuDeathGrip(&aListItem);
-
-  nsCOMPtr<nsINode> curParent = aListItem.GetParentNode();
+  *aOutOfList = false;
+
+  nsCOMPtr<nsINode> curParent = listItem->GetParentNode();
   if (NS_WARN_IF(!curParent)) {
     return NS_ERROR_FAILURE;
   }
-  int32_t offset = curParent->IndexOf(&aListItem);
-
-  if (!HTMLEditUtils::IsListItem(&aListItem)) {
+  int32_t offset = curParent->IndexOf(listItem);
+
+  if (!HTMLEditUtils::IsListItem(listItem)) {
     return NS_ERROR_FAILURE;
   }
 
   // if it's first or last list item, don't need to split the list
   // otherwise we do.
   nsCOMPtr<nsINode> curParPar = curParent->GetParentNode();
   int32_t parOffset = curParPar ? curParPar->IndexOf(curParent) : -1;
 
+  bool bIsFirstListItem;
   NS_ENSURE_STATE(mHTMLEditor);
-  bool bIsFirstListItem = mHTMLEditor->IsFirstEditableChild(&aListItem);
-
+  nsresult rv =
+    mHTMLEditor->IsFirstEditableChild(aListItem, &bIsFirstListItem);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  bool bIsLastListItem;
   NS_ENSURE_STATE(mHTMLEditor);
-  bool bIsLastListItem = mHTMLEditor->IsLastEditableChild(&aListItem);
+  rv = mHTMLEditor->IsLastEditableChild(aListItem, &bIsLastListItem);
+  NS_ENSURE_SUCCESS(rv, rv);
 
   if (!bIsFirstListItem && !bIsLastListItem) {
     // split the list
-    ErrorResult rv;
+    nsCOMPtr<nsIDOMNode> newBlock;
     NS_ENSURE_STATE(mHTMLEditor);
-    nsCOMPtr<nsIContent> newBlock =
-      mHTMLEditor->SplitNode(*curParent->AsContent(), offset, rv);
-    if (NS_WARN_IF(rv.Failed())) {
-      return rv.StealNSResult();
-    }
+    rv = mHTMLEditor->SplitNode(GetAsDOMNode(curParent), offset,
+                                getter_AddRefs(newBlock));
+    NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (!bIsFirstListItem) {
     parOffset++;
   }
 
   NS_ENSURE_STATE(mHTMLEditor);
-  nsresult rv = mHTMLEditor->MoveNode(&aListItem, curParPar, parOffset);
+  rv = mHTMLEditor->MoveNode(listItem, curParPar, parOffset);
   NS_ENSURE_SUCCESS(rv, rv);
 
   // unwrap list item contents if they are no longer in a list
   if (!HTMLEditUtils::IsList(curParPar) &&
-      HTMLEditUtils::IsListItem(&aListItem)) {
+      HTMLEditUtils::IsListItem(listItem)) {
     NS_ENSURE_STATE(mHTMLEditor);
-    rv = mHTMLEditor->RemoveBlockContainer(*aListItem.AsElement());
+    rv = mHTMLEditor->RemoveBlockContainer(*listItem);
     NS_ENSURE_SUCCESS(rv, rv);
-    if (aOutOfList) {
-      *aOutOfList = true;
-    }
+    *aOutOfList = true;
   }
   return NS_OK;
 }
 
 nsresult
 HTMLEditRules::RemoveListStructure(Element& aList)
 {
   NS_ENSURE_STATE(mHTMLEditor);
   RefPtr<HTMLEditor> htmlEditor(mHTMLEditor);
   while (aList.GetFirstChild()) {
     OwningNonNull<nsIContent> child = *aList.GetFirstChild();
 
     if (HTMLEditUtils::IsListItem(child)) {
       bool isOutOfList;
       // Keep popping it out until it's not in a list anymore
       do {
-        nsresult rv = PopListItem(child, &isOutOfList);
+        nsresult rv = PopListItem(child->AsDOMNode(), &isOutOfList);
         NS_ENSURE_SUCCESS(rv, rv);
       } while (!isOutOfList);
     } else if (HTMLEditUtils::IsList(child)) {
       nsresult rv = RemoveListStructure(*child->AsElement());
       NS_ENSURE_SUCCESS(rv, rv);
     } else {
       // Delete any non-list items for now
       nsresult rv = htmlEditor->DeleteNode(child);
--- a/editor/libeditor/HTMLEditRules.h
+++ b/editor/libeditor/HTMLEditRules.h
@@ -367,17 +367,17 @@ protected:
   nsresult SplitAsNeeded(nsIAtom& aTag, OwningNonNull<nsINode>& inOutParent,
                          int32_t& inOutOffset);
   nsresult SplitAsNeeded(nsIAtom& aTag, nsCOMPtr<nsINode>& inOutParent,
                          int32_t& inOutOffset);
   nsresult AddTerminatingBR(nsIDOMNode *aBlock);
   EditorDOMPoint JoinNodesSmart(nsIContent& aNodeLeft,
                                 nsIContent& aNodeRight);
   Element* GetTopEnclosingMailCite(nsINode& aNode);
-  nsresult PopListItem(nsIContent& aListItem, bool* aOutOfList = nullptr);
+  nsresult PopListItem(nsIDOMNode* aListItem, bool* aOutOfList);
   nsresult RemoveListStructure(Element& aList);
   nsresult CacheInlineStyles(nsIDOMNode* aNode);
   nsresult ReapplyCachedStyles();
   void ClearCachedStyles();
   void AdjustSpecialBreaks();
   nsresult AdjustWhitespace(Selection* aSelection);
   nsresult PinSelectionToNewBlock(Selection* aSelection);
   void CheckInterlinePosition(Selection& aSelection);
--- a/editor/libeditor/HTMLEditor.cpp
+++ b/editor/libeditor/HTMLEditor.cpp
@@ -1567,20 +1567,22 @@ HTMLEditor::InsertElementAtSelection(nsI
                              &offsetForInsert, false);
       NS_ENSURE_SUCCESS(rv, rv);
       // Set caret after element, but check for special case
       //  of inserting table-related elements: set in first cell instead
       if (!SetCaretInTableCell(aElement)) {
         rv = SetCaretAfterElement(aElement);
         NS_ENSURE_SUCCESS(rv, rv);
       }
-      // check for inserting a whole table at the end of a block. If so insert
-      // a br after it.
+      // check for inserting a whole table at the end of a block. If so insert a br after it.
       if (HTMLEditUtils::IsTable(node)) {
-        if (IsLastEditableChild(element)) {
+        bool isLast;
+        rv = IsLastEditableChild(node, &isLast);
+        NS_ENSURE_SUCCESS(rv, rv);
+        if (isLast) {
           nsCOMPtr<nsIDOMNode> brNode;
           rv = CreateBR(parentSelectedNode, offsetForInsert + 1,
                         address_of(brNode));
           NS_ENSURE_SUCCESS(rv, rv);
           selection->Collapse(parentSelectedNode, offsetForInsert+1);
         }
       }
     }
@@ -4145,38 +4147,50 @@ HTMLEditor::GetNextHTMLNode(nsIDOMNode* 
   nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
   NS_ENSURE_TRUE(node, NS_ERROR_NULL_POINTER);
 
   *aResultNode = do_QueryInterface(GetNextHTMLNode(node, aOffset,
                                                    aNoBlockCrossing));
   return NS_OK;
 }
 
-bool
-HTMLEditor::IsFirstEditableChild(nsINode* aNode)
+nsresult
+HTMLEditor::IsFirstEditableChild(nsIDOMNode* aNode,
+                                 bool* aOutIsFirst)
 {
-  MOZ_ASSERT(aNode);
+  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
+  NS_ENSURE_TRUE(aOutIsFirst && node, NS_ERROR_NULL_POINTER);
+
+  // init out parms
+  *aOutIsFirst = false;
+
   // find first editable child and compare it to aNode
-  nsCOMPtr<nsINode> parent = aNode->GetParentNode();
-  if (NS_WARN_IF(!parent)) {
-    return false;
-  }
-  return (GetFirstEditableChild(*parent) == aNode);
+  nsCOMPtr<nsINode> parent = node->GetParentNode();
+  NS_ENSURE_TRUE(parent, NS_ERROR_FAILURE);
+
+  *aOutIsFirst = (GetFirstEditableChild(*parent) == node);
+  return NS_OK;
 }
 
-bool
-HTMLEditor::IsLastEditableChild(nsINode* aNode)
+nsresult
+HTMLEditor::IsLastEditableChild(nsIDOMNode* aNode,
+                                bool* aOutIsLast)
 {
-  MOZ_ASSERT(aNode);
+  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
+  NS_ENSURE_TRUE(aOutIsLast && node, NS_ERROR_NULL_POINTER);
+
+  // init out parms
+  *aOutIsLast = false;
+
   // find last editable child and compare it to aNode
-  nsCOMPtr<nsINode> parent = aNode->GetParentNode();
-  if (NS_WARN_IF(!parent)) {
-    return false;
-  }
-  return (GetLastEditableChild(*parent) == aNode);
+  nsCOMPtr<nsINode> parent = node->GetParentNode();
+  NS_ENSURE_TRUE(parent, NS_ERROR_FAILURE);
+
+  *aOutIsLast = (GetLastEditableChild(*parent) == node);
+  return NS_OK;
 }
 
 nsIContent*
 HTMLEditor::GetFirstEditableChild(nsINode& aNode)
 {
   nsCOMPtr<nsIContent> child = aNode.GetFirstChild();
 
   while (child && !IsEditable(child)) {
--- a/editor/libeditor/HTMLEditor.h
+++ b/editor/libeditor/HTMLEditor.h
@@ -835,18 +835,18 @@ protected:
   nsresult GetNextHTMLNode(nsIDOMNode* inNode, nsCOMPtr<nsIDOMNode>* outNode,
                            bool bNoBlockCrossing = false);
   nsIContent* GetNextHTMLNode(nsINode* aParent, int32_t aOffset,
                               bool aNoBlockCrossing = false);
   nsresult GetNextHTMLNode(nsIDOMNode* inParent, int32_t inOffset,
                            nsCOMPtr<nsIDOMNode>* outNode,
                            bool bNoBlockCrossing = false);
 
-  bool IsFirstEditableChild(nsINode* aNode);
-  bool IsLastEditableChild(nsINode* aNode);
+  nsresult IsFirstEditableChild(nsIDOMNode* aNode, bool* aOutIsFirst);
+  nsresult IsLastEditableChild(nsIDOMNode* aNode, bool* aOutIsLast);
   nsIContent* GetFirstEditableChild(nsINode& aNode);
   nsIContent* GetLastEditableChild(nsINode& aNode);
 
   nsIContent* GetFirstEditableLeaf(nsINode& aNode);
   nsIContent* GetLastEditableLeaf(nsINode& aNode);
 
   nsresult GetInlinePropertyBase(nsIAtom& aProperty,
                                  const nsAString* aAttribute,