Backed out due to bustage on all platforms (bug 1156062 (9-12) and bug 1190172 (1-12)
authorMasayuki Nakano <masayuki@d-toybox.com>
Sat, 23 Apr 2016 19:38:45 +0900
changeset 332532 645d28b3957926e969c8add1757ed6caebe108d6
parent 332531 11c00c64207d2fa97d2bcf1401019560200b5ad3
child 332533 86ccec2b9888195807bb2f9a880d76a32ea78b59
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)
bugs1156062, 1190172
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
Backed out due to bustage on all platforms (bug 1156062 (9-12) and bug 1190172 (1-12)
editor/libeditor/nsHTMLEditRules.cpp
editor/libeditor/nsHTMLEditRules.h
--- a/editor/libeditor/nsHTMLEditRules.cpp
+++ b/editor/libeditor/nsHTMLEditRules.cpp
@@ -2231,17 +2231,17 @@ nsHTMLEditRules::WillDeleteSelection(Sel
       }
       aSelection->Collapse(selPointNode, selPointOffset);
       return NS_OK;
     }
   }
 
 
   // Else we have a non-collapsed selection.  First adjust the selection.
-  res = ExpandSelectionForDeletion(*aSelection);
+  res = ExpandSelectionForDeletion(aSelection);
   NS_ENSURE_SUCCESS(res, res);
 
   // Remember that we did a ranged delete for the benefit of AfterEditInner().
   mDidRangedDelete = true;
 
   // Refresh start and end points
   NS_ENSURE_STATE(aSelection->GetRangeAt(0));
   startNode = aSelection->GetRangeAt(0)->GetStartParent();
@@ -5033,148 +5033,190 @@ nsHTMLEditRules::GetInnerContent(nsINode
       GetInnerContent(*node, aOutArrayOfNodes, aIndex, aLists, aTables);
     } else {
       aOutArrayOfNodes.InsertElementAt(*aIndex, *node);
       (*aIndex)++;
     }
   }
 }
 
-/**
- * Promotes selection to include blocks that have all their children selected.
- */
+///////////////////////////////////////////////////////////////////////////
+// ExpandSelectionForDeletion: this promotes our selection to include blocks
+// that have all their children selected.
+//
 nsresult
-nsHTMLEditRules::ExpandSelectionForDeletion(Selection& aSelection)
-{
-  // Don't need to touch collapsed selections
-  if (aSelection.Collapsed()) {
-    return NS_OK;
-  }
-
-  // We don't need to mess with cell selections, and we assume multirange
-  // selections are those.
-  if (aSelection.RangeCount() != 1) {
+nsHTMLEditRules::ExpandSelectionForDeletion(Selection* aSelection)
+{
+  NS_ENSURE_TRUE(aSelection, NS_ERROR_NULL_POINTER);
+
+  // don't need to touch collapsed selections
+  if (aSelection->Collapsed()) {
     return NS_OK;
   }
 
-  // Find current sel start and end
-  NS_ENSURE_TRUE(aSelection.GetRangeAt(0), NS_ERROR_NULL_POINTER);
-  OwningNonNull<nsRange> range = *aSelection.GetRangeAt(0);
-
-  nsCOMPtr<nsINode> selStartNode = range->GetStartParent();
-  int32_t selStartOffset = range->StartOffset();
-  nsCOMPtr<nsINode> selEndNode = range->GetEndParent();
-  int32_t selEndOffset = range->EndOffset();
-
-  // Find current selection common block parent
-  nsCOMPtr<Element> selCommon =
-    nsHTMLEditor::GetBlock(*range->GetCommonAncestor());
+  int32_t rangeCount;
+  nsresult res = aSelection->GetRangeCount(&rangeCount);
+  NS_ENSURE_SUCCESS(res, res);
+
+  // we don't need to mess with cell selections, and we assume multirange selections are those.
+  if (rangeCount != 1) return NS_OK;
+
+  // find current sel start and end
+  RefPtr<nsRange> range = aSelection->GetRangeAt(0);
+  NS_ENSURE_TRUE(range, NS_ERROR_NULL_POINTER);
+  nsCOMPtr<nsIDOMNode> selStartNode, selEndNode, selCommon;
+  int32_t selStartOffset, selEndOffset;
+
+  res = range->GetStartContainer(getter_AddRefs(selStartNode));
+  NS_ENSURE_SUCCESS(res, res);
+  res = range->GetStartOffset(&selStartOffset);
+  NS_ENSURE_SUCCESS(res, res);
+  res = range->GetEndContainer(getter_AddRefs(selEndNode));
+  NS_ENSURE_SUCCESS(res, res);
+  res = range->GetEndOffset(&selEndOffset);
+  NS_ENSURE_SUCCESS(res, res);
+
+  // find current selection common block parent
+  res = range->GetCommonAncestorContainer(getter_AddRefs(selCommon));
+  NS_ENSURE_SUCCESS(res, res);
+  if (!IsBlockNode(selCommon))
+    selCommon = nsHTMLEditor::GetBlockNodeParent(selCommon);
   NS_ENSURE_STATE(selCommon);
 
-  // Set up for loops and cache our root element
-  nsCOMPtr<nsINode> firstBRParent;
+  // set up for loops and cache our root element
+  bool stillLooking = true;
+  nsCOMPtr<nsIDOMNode> firstBRParent;
   nsCOMPtr<nsINode> unused;
-  int32_t visOffset = 0, firstBROffset = 0;
+  int32_t visOffset=0, firstBROffset=0;
   WSType wsType;
-  nsCOMPtr<Element> root = mHTMLEditor->GetActiveEditingHost();
-  NS_ENSURE_TRUE(root, NS_ERROR_FAILURE);
-
-  // Find previous visible thingy before start of selection
-  if (selStartNode != selCommon && selStartNode != root) {
-    while (true) {
+  nsCOMPtr<nsIContent> rootContent = mHTMLEditor->GetActiveEditingHost();
+  nsCOMPtr<nsIDOMNode> rootElement = do_QueryInterface(rootContent);
+  NS_ENSURE_TRUE(rootElement, NS_ERROR_FAILURE);
+
+  // find previous visible thingy before start of selection
+  if ((selStartNode!=selCommon) && (selStartNode!=rootElement))
+  {
+    while (stillLooking)
+    {
       nsWSRunObject wsObj(mHTMLEditor, selStartNode, selStartOffset);
-      wsObj.PriorVisibleNode(selStartNode, selStartOffset, address_of(unused),
+      nsCOMPtr<nsINode> selStartNode_(do_QueryInterface(selStartNode));
+      wsObj.PriorVisibleNode(selStartNode_, selStartOffset, address_of(unused),
                              &visOffset, &wsType);
-      if (wsType != WSType::thisBlock) {
-        break;
-      }
-      // We want to keep looking up.  But stop if we are crossing table
-      // element boundaries, or if we hit the root.
-      if (nsHTMLEditUtils::IsTableElement(wsObj.mStartReasonNode) ||
-          selCommon == wsObj.mStartReasonNode ||
-          root == wsObj.mStartReasonNode) {
-        break;
-      }
-      selStartNode = wsObj.mStartReasonNode->GetParentNode();
-      selStartOffset = selStartNode ?
-        selStartNode->IndexOf(wsObj.mStartReasonNode) : -1;
-    }
-  }
-
-  // Find next visible thingy after end of selection
-  if (selEndNode != selCommon && selEndNode != root) {
-    while (true) {
+      if (wsType == WSType::thisBlock) {
+        // we want to keep looking up.  But stop if we are crossing table element
+        // boundaries, or if we hit the root.
+        if (nsHTMLEditUtils::IsTableElement(wsObj.mStartReasonNode) ||
+            selCommon == GetAsDOMNode(wsObj.mStartReasonNode) ||
+            rootElement == GetAsDOMNode(wsObj.mStartReasonNode)) {
+          stillLooking = false;
+        }
+        else
+        {
+          selStartNode = nsEditor::GetNodeLocation(GetAsDOMNode(wsObj.mStartReasonNode),
+                                                   &selStartOffset);
+        }
+      }
+      else
+      {
+        stillLooking = false;
+      }
+    }
+  }
+
+  stillLooking = true;
+  // find next visible thingy after end of selection
+  if ((selEndNode!=selCommon) && (selEndNode!=rootElement))
+  {
+    while (stillLooking)
+    {
       nsWSRunObject wsObj(mHTMLEditor, selEndNode, selEndOffset);
-      wsObj.NextVisibleNode(selEndNode, selEndOffset, address_of(unused),
+      nsCOMPtr<nsINode> selEndNode_(do_QueryInterface(selEndNode));
+      wsObj.NextVisibleNode(selEndNode_, selEndOffset, address_of(unused),
                             &visOffset, &wsType);
       if (wsType == WSType::br) {
-        if (mHTMLEditor->IsVisBreak(wsObj.mEndReasonNode)) {
-          break;
-        }
-        if (!firstBRParent) {
-          firstBRParent = selEndNode;
-          firstBROffset = selEndOffset;
+        if (mHTMLEditor->IsVisBreak(wsObj.mEndReasonNode))
+        {
+          stillLooking = false;
         }
-        selEndNode = wsObj.mEndReasonNode->GetParentNode();
-        selEndOffset = selEndNode
-          ? selEndNode->IndexOf(wsObj.mEndReasonNode) + 1 : 0;
+        else
+        {
+          if (!firstBRParent)
+          {
+            firstBRParent = selEndNode;
+            firstBROffset = selEndOffset;
+          }
+          selEndNode = nsEditor::GetNodeLocation(GetAsDOMNode(wsObj.mEndReasonNode), &selEndOffset);
+          ++selEndOffset;
+        }
       } else if (wsType == WSType::thisBlock) {
-        // We want to keep looking up.  But stop if we are crossing table
-        // element boundaries, or if we hit the root.
+        // we want to keep looking up.  But stop if we are crossing table element
+        // boundaries, or if we hit the root.
         if (nsHTMLEditUtils::IsTableElement(wsObj.mEndReasonNode) ||
-            selCommon == wsObj.mEndReasonNode ||
-            root == wsObj.mEndReasonNode) {
-          break;
+            selCommon == GetAsDOMNode(wsObj.mEndReasonNode) ||
+            rootElement == GetAsDOMNode(wsObj.mEndReasonNode)) {
+          stillLooking = false;
+        }
+        else
+        {
+          selEndNode = nsEditor::GetNodeLocation(GetAsDOMNode(wsObj.mEndReasonNode), &selEndOffset);
+          ++selEndOffset;
         }
-        selEndNode = wsObj.mEndReasonNode->GetParentNode();
-        selEndOffset = 1 + selEndNode->IndexOf(wsObj.mEndReasonNode);
-      } else {
-        break;
-      }
-    }
-  }
-  // Now set the selection to the new range
-  aSelection.Collapse(selStartNode, selStartOffset);
-
-  // Expand selection endpoint only if we didn't pass a br, or if we really
-  // needed to pass that br (i.e., its block is now totally selected)
-  nsresult res;
+       }
+      else
+      {
+        stillLooking = false;
+      }
+    }
+  }
+  // now set the selection to the new range
+  aSelection->Collapse(selStartNode, selStartOffset);
+
+  // expand selection endpoint only if we didnt pass a br,
+  // or if we really needed to pass that br (ie, its block is now
+  // totally selected)
   bool doEndExpansion = true;
-  if (firstBRParent) {
-    // Find block node containing br
-    nsCOMPtr<Element> brBlock = nsHTMLEditor::GetBlock(*firstBRParent);
-    bool nodeBefore = false, nodeAfter = false;
-
-    // Create a range that represents expanded selection
-    RefPtr<nsRange> range = new nsRange(selStartNode);
+  if (firstBRParent)
+  {
+    // find block node containing br
+    nsCOMPtr<nsIDOMNode> brBlock = firstBRParent;
+    if (!IsBlockNode(brBlock))
+      brBlock = nsHTMLEditor::GetBlockNodeParent(brBlock);
+    bool nodeBefore=false, nodeAfter=false;
+
+    // create a range that represents expanded selection
+    nsCOMPtr<nsINode> node = do_QueryInterface(selStartNode);
+    NS_ENSURE_STATE(node);
+    RefPtr<nsRange> range = new nsRange(node);
     res = range->SetStart(selStartNode, selStartOffset);
     NS_ENSURE_SUCCESS(res, res);
     res = range->SetEnd(selEndNode, selEndOffset);
     NS_ENSURE_SUCCESS(res, res);
 
-    // Check if block is entirely inside range
-    if (brBlock) {
-      nsRange::CompareNodeToRange(brBlock, range, &nodeBefore, &nodeAfter);
-    }
-
-    // If block isn't contained, forgo grabbing the br in expanded selection
-    if (nodeBefore || nodeAfter) {
+    // check if block is entirely inside range
+    nsCOMPtr<nsIContent> brContentBlock = do_QueryInterface(brBlock);
+    if (brContentBlock) {
+      res = nsRange::CompareNodeToRange(brContentBlock, range, &nodeBefore,
+                                        &nodeAfter);
+    }
+
+    // if block isn't contained, forgo grabbing the br in the expanded selection
+    if (nodeBefore || nodeAfter)
       doEndExpansion = false;
-    }
-  }
-  if (doEndExpansion) {
-    res = aSelection.Extend(selEndNode, selEndOffset);
-    NS_ENSURE_SUCCESS(res, res);
-  } else {
-    // Only expand to just before br
-    res = aSelection.Extend(firstBRParent, firstBROffset);
-    NS_ENSURE_SUCCESS(res, res);
-  }
-
-  return NS_OK;
+  }
+  if (doEndExpansion)
+  {
+    res = aSelection->Extend(selEndNode, selEndOffset);
+  }
+  else
+  {
+    // only expand to just before br
+    res = aSelection->Extend(firstBRParent, firstBROffset);
+  }
+
+  return res;
 }
 
 
 ///////////////////////////////////////////////////////////////////////////
 // NormalizeSelection:  tweak non-collapsed selections to be more "natural".
 //    Idea here is to adjust selection endpoint so that they do not cross
 //    breaks or block boundaries unless something editable beyond that boundary
 //    is also selected.  This adjustment makes it much easier for the various
--- a/editor/libeditor/nsHTMLEditRules.h
+++ b/editor/libeditor/nsHTMLEditRules.h
@@ -255,17 +255,17 @@ protected:
                         MozBRCounts aMozBRCounts = MozBRCounts::yes);
   nsresult CheckForEmptyBlock(nsINode* aStartNode,
                               mozilla::dom::Element* aBodyNode,
                               mozilla::dom::Selection* aSelection,
                               nsIEditor::EDirection aAction,
                               bool* aHandled);
   nsresult CheckForInvisibleBR(nsIDOMNode *aBlock, nsHTMLEditRules::BRLocation aWhere,
                                nsCOMPtr<nsIDOMNode> *outBRNode, int32_t aOffset=0);
-  nsresult ExpandSelectionForDeletion(mozilla::dom::Selection& aSelection);
+  nsresult ExpandSelectionForDeletion(mozilla::dom::Selection* aSelection);
   bool IsFirstNode(nsIDOMNode *aNode);
   bool IsLastNode(nsIDOMNode *aNode);
   nsresult NormalizeSelection(mozilla::dom::Selection* aSelection);
   void GetPromotedPoint(RulesEndpoint aWhere, nsIDOMNode* aNode,
                         int32_t aOffset, EditAction actionID,
                         nsCOMPtr<nsIDOMNode>* outNode, int32_t* outOffset);
   void GetPromotedRanges(mozilla::dom::Selection& aSelection,
                          nsTArray<RefPtr<nsRange>>& outArrayOfRanges,