Bug 1191356 part 5 - Clean up nsHTMLEditRules::RelativeChangeIndentationOfElementNode; r=ehsan
authorAryeh Gregor <ayg@aryeh.name>
Sun, 01 May 2016 16:17:15 +0300
changeset 295656 24149bd5c7747d2740085876eb62cf11f7ef73b0
parent 295655 cb399cd2f5be6639a81d671294e7ef188cf50e20
child 295657 6dbba6c4a200ac06bdbfab8fce401a2ea8e0e00c
push id19015
push usercbook@mozilla.com
push dateMon, 02 May 2016 09:39:23 +0000
treeherderfx-team@2080375bc69d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersehsan
bugs1191356
milestone49.0a1
Bug 1191356 part 5 - Clean up nsHTMLEditRules::RelativeChangeIndentationOfElementNode; r=ehsan
editor/libeditor/nsHTMLEditRules.cpp
editor/libeditor/nsHTMLEditRules.h
--- a/editor/libeditor/nsHTMLEditRules.cpp
+++ b/editor/libeditor/nsHTMLEditRules.cpp
@@ -3574,17 +3574,17 @@ nsHTMLEditRules::WillCSSIndent(Selection
     res = SplitAsNeeded(*nsGkAtoms::div, parent, offset);
     NS_ENSURE_SUCCESS(res, res);
     NS_ENSURE_STATE(mHTMLEditor);
     nsCOMPtr<Element> theBlock = mHTMLEditor->CreateNode(nsGkAtoms::div,
                                                          parent, offset);
     NS_ENSURE_STATE(theBlock);
     // remember our new block for postprocessing
     mNewBlock = theBlock->AsDOMNode();
-    RelativeChangeIndentationOfElementNode(theBlock->AsDOMNode(), +1);
+    ChangeIndentation(*theBlock, Change::plus);
     // delete anything that was in the list of nodes
     while (!arrayOfNodes.IsEmpty()) {
       OwningNonNull<nsINode> curNode = arrayOfNodes[0];
       NS_ENSURE_STATE(mHTMLEditor);
       res = mHTMLEditor->DeleteNode(curNode);
       NS_ENSURE_SUCCESS(res, res);
       arrayOfNodes.RemoveElementAt(0);
     }
@@ -3677,34 +3677,34 @@ nsHTMLEditRules::WillCSSIndent(Selection
       NS_ENSURE_STATE(mHTMLEditor);
       res = mHTMLEditor->MoveNode(curNode, curList, listLen);
       NS_ENSURE_SUCCESS(res, res);
     }
 
     else // not a list item
     {
       if (curNode && IsBlockNode(*curNode)) {
-        RelativeChangeIndentationOfElementNode(curNode->AsDOMNode(), +1);
+        ChangeIndentation(*curNode->AsElement(), Change::plus);
         curQuote = nullptr;
       }
       else {
         if (!curQuote)
         {
           // First, check that our element can contain a div.
           if (!mEditor->CanContainTag(*curParent, *nsGkAtoms::div)) {
             return NS_OK; // cancelled
           }
 
           res = SplitAsNeeded(*nsGkAtoms::div, curParent, offset);
           NS_ENSURE_SUCCESS(res, res);
           NS_ENSURE_STATE(mHTMLEditor);
           curQuote = mHTMLEditor->CreateNode(nsGkAtoms::div, curParent,
                                              offset);
           NS_ENSURE_STATE(curQuote);
-          RelativeChangeIndentationOfElementNode(curQuote->AsDOMNode(), +1);
+          ChangeIndentation(*curQuote, Change::plus);
           // remember our new block for postprocessing
           mNewBlock = curQuote->AsDOMNode();
           // curQuote is now the correct thing to put curNode in
         }
 
         // tuck the node into the end of the active blockquote
         uint32_t quoteLen = curQuote->Length();
         NS_ENSURE_STATE(mHTMLEditor);
@@ -4018,17 +4018,17 @@ nsHTMLEditRules::WillOutdent(Selection& 
         mHTMLEditor->mHTMLCSSUtils->GetSpecifiedProperty(curNode,
                                                          marginProperty,
                                                          value);
         float f;
         nsCOMPtr<nsIAtom> unit;
         NS_ENSURE_STATE(mHTMLEditor);
         mHTMLEditor->mHTMLCSSUtils->ParseLength(value, &f, getter_AddRefs(unit));
         if (f > 0) {
-          RelativeChangeIndentationOfElementNode(GetAsDOMNode(curNode), -1);
+          ChangeIndentation(*curNode->AsElement(), Change::minus);
           continue;
         }
       }
       // Is it a list item?
       if (nsHTMLEditUtils::IsListItem(curNode)) {
         // If it is a list item, that means we are not outdenting whole list.
         // So we need to finish up dealing with any curBlockQuote, and then pop
         // this list item.
@@ -4152,17 +4152,17 @@ nsHTMLEditRules::WillOutdent(Selection& 
           nsCOMPtr<nsIDOMText> textNode = do_QueryInterface(curNode);
           if (curNode->GetAsText()) {
             // We want to outdent the parent of text nodes
             element = curNode->GetParentElement();
           } else if (curNode->IsElement()) {
             element = curNode->AsElement();
           }
           if (element) {
-            RelativeChangeIndentationOfElementNode(element->AsDOMNode(), -1);
+            ChangeIndentation(*element, Change::minus);
           }
         }
       }
     }
     if (curBlockQuote) {
       // We have a blockquote we haven't finished handling
       res = OutdentPartOfBlock(*curBlockQuote, *firstBQChild, *lastBQChild,
                                curBlockQuoteIsIndentedWithCSS,
@@ -4278,25 +4278,25 @@ nsHTMLEditRules::OutdentPartOfBlock(Elem
   MOZ_ASSERT(aOutLeftNode && aOutRightNode);
 
   nsCOMPtr<nsIContent> middleNode;
   SplitBlock(aBlock, aStartChild, aEndChild, aOutLeftNode, aOutRightNode,
              getter_AddRefs(middleNode));
 
   NS_ENSURE_STATE(middleNode);
 
-  if (aIsBlockIndentedWithCSS) {
-    nsresult res =
-      RelativeChangeIndentationOfElementNode(GetAsDOMNode(middleNode), -1);
-    NS_ENSURE_SUCCESS(res, res);
-  } else {
+  if (!aIsBlockIndentedWithCSS) {
     NS_ENSURE_STATE(mHTMLEditor);
     nsresult res =
       mHTMLEditor->RemoveBlockContainer(*middleNode);
     NS_ENSURE_SUCCESS(res, res);
+  } else if (middleNode->IsElement()) {
+    // We do nothing if middleNode isn't an element
+    nsresult res = ChangeIndentation(*middleNode->AsElement(), Change::minus);
+    NS_ENSURE_SUCCESS(res, res);
   }
 
   return NS_OK;
 }
 
 ///////////////////////////////////////////////////////////////////////////
 // ConvertListType:  convert list type and list item type.
 //
@@ -8405,97 +8405,79 @@ nsHTMLEditRules::AlignBlock(Element& aEl
                                   attr, aAlignType);
       NS_ENSURE_SUCCESS(res, res);
     }
   }
   return NS_OK;
 }
 
 nsresult
-nsHTMLEditRules::RelativeChangeIndentationOfElementNode(nsIDOMNode *aNode, int8_t aRelativeChange)
-{
-  NS_ENSURE_ARG_POINTER(aNode);
-
-  if (aRelativeChange != 1 && aRelativeChange != -1) {
-    return NS_ERROR_ILLEGAL_VALUE;
-  }
-
-  nsCOMPtr<Element> element = do_QueryInterface(aNode);
-  if (!element) {
-    return NS_OK;
-  }
-
+nsHTMLEditRules::ChangeIndentation(Element& aElement, Change aChange)
+{
   NS_ENSURE_STATE(mHTMLEditor);
+  nsCOMPtr<nsIEditor> kungFuDeathGrip(mHTMLEditor);
+
   nsIAtom& marginProperty =
-    MarginPropertyAtomForIndent(*mHTMLEditor->mHTMLCSSUtils, *element);
+    MarginPropertyAtomForIndent(*mHTMLEditor->mHTMLCSSUtils, aElement);
   nsAutoString value;
-  NS_ENSURE_STATE(mHTMLEditor);
-  mHTMLEditor->mHTMLCSSUtils->GetSpecifiedProperty(*element, marginProperty,
+  mHTMLEditor->mHTMLCSSUtils->GetSpecifiedProperty(aElement, marginProperty,
                                                    value);
   float f;
   nsCOMPtr<nsIAtom> unit;
-  NS_ENSURE_STATE(mHTMLEditor);
   mHTMLEditor->mHTMLCSSUtils->ParseLength(value, &f, getter_AddRefs(unit));
   if (0 == f) {
     nsAutoString defaultLengthUnit;
-    NS_ENSURE_STATE(mHTMLEditor);
     mHTMLEditor->mHTMLCSSUtils->GetDefaultLengthUnit(defaultLengthUnit);
     unit = NS_Atomize(defaultLengthUnit);
   }
+  int8_t multiplier = aChange == Change::plus ? +1 : -1;
   if        (nsGkAtoms::in == unit) {
-            f += NS_EDITOR_INDENT_INCREMENT_IN * aRelativeChange;
+            f += NS_EDITOR_INDENT_INCREMENT_IN * multiplier;
   } else if (nsGkAtoms::cm == unit) {
-            f += NS_EDITOR_INDENT_INCREMENT_CM * aRelativeChange;
+            f += NS_EDITOR_INDENT_INCREMENT_CM * multiplier;
   } else if (nsGkAtoms::mm == unit) {
-            f += NS_EDITOR_INDENT_INCREMENT_MM * aRelativeChange;
+            f += NS_EDITOR_INDENT_INCREMENT_MM * multiplier;
   } else if (nsGkAtoms::pt == unit) {
-            f += NS_EDITOR_INDENT_INCREMENT_PT * aRelativeChange;
+            f += NS_EDITOR_INDENT_INCREMENT_PT * multiplier;
   } else if (nsGkAtoms::pc == unit) {
-            f += NS_EDITOR_INDENT_INCREMENT_PC * aRelativeChange;
+            f += NS_EDITOR_INDENT_INCREMENT_PC * multiplier;
   } else if (nsGkAtoms::em == unit) {
-            f += NS_EDITOR_INDENT_INCREMENT_EM * aRelativeChange;
+            f += NS_EDITOR_INDENT_INCREMENT_EM * multiplier;
   } else if (nsGkAtoms::ex == unit) {
-            f += NS_EDITOR_INDENT_INCREMENT_EX * aRelativeChange;
+            f += NS_EDITOR_INDENT_INCREMENT_EX * multiplier;
   } else if (nsGkAtoms::px == unit) {
-            f += NS_EDITOR_INDENT_INCREMENT_PX * aRelativeChange;
+            f += NS_EDITOR_INDENT_INCREMENT_PX * multiplier;
   } else if (nsGkAtoms::percentage == unit) {
-            f += NS_EDITOR_INDENT_INCREMENT_PERCENT * aRelativeChange;
+            f += NS_EDITOR_INDENT_INCREMENT_PERCENT * multiplier;
   }
 
   if (0 < f) {
     nsAutoString newValue;
     newValue.AppendFloat(f);
     newValue.Append(nsDependentAtomString(unit));
-    NS_ENSURE_STATE(mHTMLEditor);
-    mHTMLEditor->mHTMLCSSUtils->SetCSSProperty(*element, marginProperty,
+    mHTMLEditor->mHTMLCSSUtils->SetCSSProperty(aElement, marginProperty,
                                                newValue);
     return NS_OK;
   }
 
-  NS_ENSURE_STATE(mHTMLEditor);
-  mHTMLEditor->mHTMLCSSUtils->RemoveCSSProperty(*element, marginProperty,
+  mHTMLEditor->mHTMLCSSUtils->RemoveCSSProperty(aElement, marginProperty,
                                                 value);
 
-  // remove unnecessary DIV blocks:
-  // we could skip this section but that would cause a FAIL in
-  // editor/libeditor/tests/browserscope/richtext.html, which expects
-  // to unapply a CSS "indent" (<div style="margin-left: 40px;">) by
-  // removing the DIV container instead of just removing the CSS property.
-  nsCOMPtr<dom::Element> node = do_QueryInterface(aNode);
-  if (!node || !node->IsHTMLElement(nsGkAtoms::div) ||
-      !mHTMLEditor ||
-      node == mHTMLEditor->GetActiveEditingHost() ||
-      !mHTMLEditor->IsDescendantOfEditorRoot(node) ||
-      nsHTMLEditor::HasAttributes(node)) {
-    NS_ENSURE_STATE(mHTMLEditor);
+  // Remove unnecessary divs
+  if (!aElement.IsHTMLElement(nsGkAtoms::div) ||
+      &aElement == mHTMLEditor->GetActiveEditingHost() ||
+      !mHTMLEditor->IsDescendantOfEditorRoot(&aElement) ||
+      nsHTMLEditor::HasAttributes(&aElement)) {
     return NS_OK;
   }
 
-  NS_ENSURE_STATE(mHTMLEditor);
-  return mHTMLEditor->RemoveContainer(node);
+  nsresult res = mHTMLEditor->RemoveContainer(&aElement);
+  NS_ENSURE_SUCCESS(res, res);
+
+  return NS_OK;
 }
 
 //
 // Support for Absolute Positioning
 //
 
 nsresult
 nsHTMLEditRules::WillAbsolutePosition(Selection* aSelection,
--- a/editor/libeditor/nsHTMLEditRules.h
+++ b/editor/libeditor/nsHTMLEditRules.h
@@ -319,17 +319,18 @@ protected:
   nsresult InsertMozBRIfNeeded(nsINode& aNode);
   bool     IsEmptyInline(nsINode& aNode);
   bool     ListIsEmptyLine(nsTArray<OwningNonNull<nsINode>>& arrayOfNodes);
   nsresult RemoveAlignment(nsIDOMNode * aNode, const nsAString & aAlignType, bool aChildrenOnly);
   nsresult MakeSureElemStartsOrEndsOnCR(nsIDOMNode *aNode, bool aStarts);
   enum class ContentsOnly { no, yes };
   nsresult AlignBlock(Element& aElement,
                       const nsAString& aAlignType, ContentsOnly aContentsOnly);
-  nsresult RelativeChangeIndentationOfElementNode(nsIDOMNode *aNode, int8_t aRelativeChange);
+  enum class Change { minus, plus };
+  nsresult ChangeIndentation(Element& aElement, Change aChange);
   void DocumentModifiedWorker();
 
 // data members
 protected:
   nsHTMLEditor           *mHTMLEditor;
   RefPtr<nsRange>       mDocChangeRange;
   bool                    mListenerEnabled;
   bool                    mReturnInEmptyLIKillsList;