Backed out changeset 932f6530318d (bug 1000959) for 603490-1.html asserts
authorEd Morley <emorley@mozilla.com>
Mon, 28 Apr 2014 16:05:04 +0100
changeset 180965 df459220856f488f956c5d78e93f97ff51ded476
parent 180964 49fcf756a711f5b5ff09e1c2db2ce2924b657d64
child 180966 41098eebe085887c1b447ceba687a4cae8773ea2
push id272
push userpvanderbeken@mozilla.com
push dateMon, 05 May 2014 16:31:18 +0000
bugs1000959, 603490
milestone31.0a1
backs out932f6530318dda3eec3310596658de18867c6d03
Backed out changeset 932f6530318d (bug 1000959) for 603490-1.html asserts
editor/libeditor/html/nsHTMLEditor.cpp
editor/libeditor/html/nsHTMLEditor.h
editor/libeditor/text/nsTextEditUtils.cpp
editor/libeditor/text/nsTextEditUtils.h
--- a/editor/libeditor/html/nsHTMLEditor.cpp
+++ b/editor/libeditor/html/nsHTMLEditor.cpp
@@ -69,17 +69,16 @@
 
 #include "nsIFrame.h"
 #include "nsIParserService.h"
 #include "mozilla/dom/Selection.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/EventTarget.h"
 #include "mozilla/dom/HTMLBodyElement.h"
 #include "nsTextFragment.h"
-#include "nsContentList.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 using namespace mozilla::widget;
 
 // Some utilities to handle annoying overloading of "A" tag for link and named anchor
 static char hrefText[] = "href";
 static char anchorTxt[] = "anchor";
@@ -625,44 +624,47 @@ nsHTMLEditor::HandleKeyPressEvent(nsIDOM
         return NS_OK; // let it be used for focus switching
       }
 
       if (nativeKeyEvent->IsControl() || nativeKeyEvent->IsAlt() ||
           nativeKeyEvent->IsMeta() || nativeKeyEvent->IsOS()) {
         return NS_OK;
       }
 
-      nsRefPtr<Selection> selection = GetSelection();
-      NS_ENSURE_TRUE(selection && selection->RangeCount(), NS_ERROR_FAILURE);
-
-      nsCOMPtr<nsINode> node = selection->GetRangeAt(0)->GetStartParent();
-      MOZ_ASSERT(node);
-
-      nsCOMPtr<nsINode> blockParent;
-      if (IsBlockNode(node)) {
+      nsCOMPtr<nsISelection> selection;
+      nsresult rv = GetSelection(getter_AddRefs(selection));
+      NS_ENSURE_SUCCESS(rv, rv);
+      int32_t offset;
+      nsCOMPtr<nsIDOMNode> node, blockParent;
+      rv = GetStartNodeAndOffset(selection, getter_AddRefs(node), &offset);
+      NS_ENSURE_SUCCESS(rv, rv);
+      NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
+
+      bool isBlock = false;
+      NodeIsBlock(node, &isBlock);
+      if (isBlock) {
         blockParent = node;
       } else {
         blockParent = GetBlockNodeParent(node);
       }
 
       if (!blockParent) {
         break;
       }
 
       bool handled = false;
-      nsresult rv;
       if (nsHTMLEditUtils::IsTableElement(blockParent)) {
         rv = TabInTable(nativeKeyEvent->IsShift(), &handled);
         if (handled) {
           ScrollSelectionIntoView(false);
         }
       } else if (nsHTMLEditUtils::IsListItem(blockParent)) {
-        rv = Indent(nativeKeyEvent->IsShift()
-                    ? NS_LITERAL_STRING("outdent")
-                    : NS_LITERAL_STRING("indent"));
+        rv = Indent(nativeKeyEvent->IsShift() ?
+                      NS_LITERAL_STRING("outdent") :
+                      NS_LITERAL_STRING("indent"));
         handled = true;
       }
       NS_ENSURE_SUCCESS(rv, rv);
       if (handled) {
         return aKeyEvent->PreventDefault(); // consumed
       }
       if (nativeKeyEvent->IsShift()) {
         return NS_OK; // don't type text for shift tabs
@@ -822,49 +824,41 @@ nsHTMLEditor::SetDocumentTitle(const nsA
   nsAutoTxnsConserveSelection dontChangeSelection(this);
   return nsEditor::DoTransaction(txn);  
 }
 
 /* ------------ Block methods moved from nsEditor -------------- */
 ///////////////////////////////////////////////////////////////////////////
 // GetBlockNodeParent: returns enclosing block level ancestor, if any
 //
-already_AddRefed<Element>
-nsHTMLEditor::GetBlockNodeParent(nsINode* aNode)
-{
-  MOZ_ASSERT(aNode);
-
-  nsCOMPtr<nsINode> p = aNode->GetParentNode();
-
-  while (p) {
-    if (p->IsElement() && NodeIsBlockStatic(p->AsElement())) {
-      return p.forget().downcast<Element>();
-    }
-    p = p->GetParentNode();
-  }
-
-  return nullptr;
-}
-
 already_AddRefed<nsIDOMNode>
 nsHTMLEditor::GetBlockNodeParent(nsIDOMNode *aNode)
 {
-  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-
-  if (!node) {
+  if (!aNode)
+  {
     NS_NOTREACHED("null node passed to GetBlockNodeParent()");
     return nullptr;
   }
 
-  nsCOMPtr<nsINode> parent = GetBlockNodeParent(node);
-  if (!parent) {
+  nsCOMPtr<nsIDOMNode> p;
+  if (NS_FAILED(aNode->GetParentNode(getter_AddRefs(p))))  // no parent, ran off top of tree
     return nullptr;
+
+  nsCOMPtr<nsIDOMNode> tmp;
+  while (p)
+  {
+    bool isBlock;
+    if (NS_FAILED(NodeIsBlockStatic(p, &isBlock)) || isBlock)
+      break;
+    if (NS_FAILED(p->GetParentNode(getter_AddRefs(tmp))) || !tmp) // no parent, ran off top of tree
+      break;
+
+    p = tmp;
   }
-  nsCOMPtr<nsIDOMNode> ret = dont_AddRef(parent.forget().take()->AsDOMNode());
-  return ret.forget();
+  return p.forget();
 }
 
 static const char16_t nbsp = 160;
 
 ///////////////////////////////////////////////////////////////////////////////
 // IsNextCharInNodeWhitespace: checks the adjacent content in the same node to
 //                             see if following selection is whitespace or nbsp
 void
@@ -929,71 +923,54 @@ nsHTMLEditor::IsPrevCharInNodeWhitespace
   }
 }
 
 
 
 /* ------------ End Block methods -------------- */
 
 
-bool
-nsHTMLEditor::IsVisBreak(nsINode* aNode)
+bool nsHTMLEditor::IsVisBreak(nsIDOMNode *aNode)
 {
-  MOZ_ASSERT(aNode);
-  if (!nsTextEditUtils::IsBreak(aNode)) {
+  NS_ENSURE_TRUE(aNode, false);
+  if (!nsTextEditUtils::IsBreak(aNode)) 
     return false;
-  }
-  // Check if there is a later node in block after br
-  nsCOMPtr<nsINode> priorNode = GetPriorHTMLNode(aNode, true);
-  if (priorNode && nsTextEditUtils::IsBreak(priorNode)) {
+  // check if there is a later node in block after br
+  nsCOMPtr<nsIDOMNode> priorNode, nextNode;
+  GetPriorHTMLNode(aNode, address_of(priorNode), true); 
+  GetNextHTMLNode(aNode, address_of(nextNode), true); 
+  // if we are next to another break, we are visible
+  if (priorNode && nsTextEditUtils::IsBreak(priorNode))
     return true;
-  }
-  nsCOMPtr<nsINode> nextNode = GetNextHTMLNode(aNode, true);
-  if (nextNode && nsTextEditUtils::IsBreak(nextNode)) {
+  if (nextNode && nsTextEditUtils::IsBreak(nextNode))
     return true;
-  }
   
-  // If we are right before block boundary, then br not visible
-  if (!nextNode) {
-    // This break is trailer in block, it's not visible
-    return false;
-  }
-  if (IsBlockNode(nextNode)) {
-    // Break is right before a block, it's not visible
-    return false;
-  }
+  // if we are right before block boundary, then br not visible
+  NS_ENSURE_TRUE(nextNode, false);  // this break is trailer in block, it's not visible
+  if (IsBlockNode(nextNode))
+    return false; // break is right before a block, it's not visible
     
-  // Sigh.  We have to use expensive whitespace calculation code to 
+  // sigh.  We have to use expensive whitespace calculation code to 
   // determine what is going on
+  nsCOMPtr<nsIDOMNode> selNode, tmp;
   int32_t selOffset;
-  nsCOMPtr<nsINode> selNode = GetNodeLocation(aNode, &selOffset);
-  // Let's look after the break
-  selOffset++;
-  nsWSRunObject wsObj(this, selNode->AsDOMNode(), selOffset);
+  selNode = GetNodeLocation(aNode, &selOffset);
+  selOffset++; // lets look after the break
+  nsWSRunObject wsObj(this, selNode, selOffset);
   nsCOMPtr<nsIDOMNode> visNode;
-  int32_t visOffset = 0;
+  int32_t visOffset=0;
   WSType visType;
-  wsObj.NextVisibleNode(selNode->AsDOMNode(), selOffset, address_of(visNode),
-                        &visOffset, &visType);
+  wsObj.NextVisibleNode(selNode, selOffset, address_of(visNode), &visOffset, &visType);
   if (visType & WSType::block) {
     return false;
   }
   
   return true;
 }
 
-
-bool
-nsHTMLEditor::IsVisBreak(nsIDOMNode* aNode)
-{
-  nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
-  NS_ENSURE_TRUE(node, false);
-  return IsVisBreak(node);
-}
-
 NS_IMETHODIMP
 nsHTMLEditor::BreakIsVisible(nsIDOMNode *aNode, bool *aIsVisible)
 {
   NS_ENSURE_ARG_POINTER(aNode && aIsVisible);
 
   *aIsVisible = IsVisBreak(aNode);
 
   return NS_OK;
@@ -1014,26 +991,42 @@ nsHTMLEditor::GetIsDocumentEditable(bool
 bool nsHTMLEditor::IsModifiable()
 {
   return !IsReadonly();
 }
 
 NS_IMETHODIMP
 nsHTMLEditor::UpdateBaseURL()
 {
-  nsCOMPtr<nsIDocument> doc = GetDocument();
-  NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
+  nsCOMPtr<nsIDOMDocument> domDoc = GetDOMDocument();
+  NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
 
   // Look for an HTML <base> tag
-  nsRefPtr<nsContentList> nodeList =
-    doc->GetElementsByTagName(NS_LITERAL_STRING("base"));
-
-  // If no base tag, then set baseURL to the document's URL.  This is very
-  // important, else relative URLs for links and images are wrong
-  if (!nodeList || !nodeList->Item(0)) {
+  nsCOMPtr<nsIDOMNodeList> nodeList;
+  nsresult rv = domDoc->GetElementsByTagName(NS_LITERAL_STRING("base"), getter_AddRefs(nodeList));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsIDOMNode> baseNode;
+  if (nodeList)
+  {
+    uint32_t count;
+    nodeList->GetLength(&count);
+    if (count >= 1)
+    {
+      rv = nodeList->Item(0, getter_AddRefs(baseNode));
+      NS_ENSURE_SUCCESS(rv, rv);
+    }
+  }
+  // If no base tag, then set baseURL to the document's URL
+  // This is very important, else relative URLs for links and images are wrong
+  if (!baseNode)
+  {
+    nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
+    NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
+
     return doc->SetBaseURI(doc->GetDocumentURI());
   }
   return NS_OK;
 }
 
 /* This routine is needed to provide a bottleneck for typing for logging
    purposes.  Can't use HandleKeyPress() (above) for that since it takes
    a nsIDOMKeyEvent* parameter.  So instead we pass enough info through
--- a/editor/libeditor/html/nsHTMLEditor.h
+++ b/editor/libeditor/html/nsHTMLEditor.h
@@ -224,17 +224,16 @@ public:
     
   /* miscellaneous */
   // This sets background on the appropriate container element (table, cell,)
   //   or calls into nsTextEditor to set the page background
   NS_IMETHOD SetCSSBackgroundColor(const nsAString& aColor);
   NS_IMETHOD SetHTMLBackgroundColor(const nsAString& aColor);
 
   /* ------------ Block methods moved from nsEditor -------------- */
-  static already_AddRefed<mozilla::dom::Element> GetBlockNodeParent(nsINode* aNode);
   static already_AddRefed<nsIDOMNode> GetBlockNodeParent(nsIDOMNode *aNode);
 
   void IsNextCharInNodeWhitespace(nsIContent* aContent,
                                   int32_t aOffset,
                                   bool* outIsSpace,
                                   bool* outIsNBSP,
                                   nsIContent** outNode = nullptr,
                                   int32_t* outOffset = 0);
@@ -604,17 +603,16 @@ protected:
                                         nsCOMPtr<nsIDOMNode> *outReplaceNode);
   nsresult ReplaceOrphanedStructure( bool aEnd,
                                      nsCOMArray<nsIDOMNode>& aNodeArray,
                                      nsCOMArray<nsIDOMNode>& aListAndTableArray,
                                      int32_t aHighWaterMark);
   nsIDOMNode* GetArrayEndpoint(bool aEnd, nsCOMArray<nsIDOMNode>& aNodeArray);
 
   /* small utility routine to test if a break node is visible to user */
-  bool     IsVisBreak(nsINode* aNode);
   bool     IsVisBreak(nsIDOMNode *aNode);
 
   /* utility routine to possibly adjust the insertion position when 
      inserting a block level element */
   void NormalizeEOLInsertPosition(nsIDOMNode *firstNodeToInsert,
                                   nsCOMPtr<nsIDOMNode> *insertParentNode,
                                   int32_t *insertOffset);
 
--- a/editor/libeditor/text/nsTextEditUtils.cpp
+++ b/editor/libeditor/text/nsTextEditUtils.cpp
@@ -33,23 +33,16 @@ nsTextEditUtils::IsBody(nsIDOMNode *node
 
 ///////////////////////////////////////////////////////////////////////////
 // IsBreak: true if node an html break node
 bool 
 nsTextEditUtils::IsBreak(nsIDOMNode *node)
 {
   return nsEditor::NodeIsType(node, nsGkAtoms::br);
 }
- 
-bool 
-nsTextEditUtils::IsBreak(nsINode* aNode)
-{
-  MOZ_ASSERT(aNode);
-  return aNode->IsElement() && aNode->AsElement()->IsHTML(nsGkAtoms::br);
-}
 
 
 ///////////////////////////////////////////////////////////////////////////
 // IsMozBR: true if node an html br node with type = _moz
 //                  
 bool 
 nsTextEditUtils::IsMozBR(nsIDOMNode *node)
 {
--- a/editor/libeditor/text/nsTextEditUtils.h
+++ b/editor/libeditor/text/nsTextEditUtils.h
@@ -18,17 +18,16 @@ class nsIDOMNode;
 class nsPlaintextEditor;
 
 class nsTextEditUtils
 {
 public:
   // from nsTextEditRules:
   static bool IsBody(nsIDOMNode* aNode);
   static bool IsBreak(nsIDOMNode* aNode);
-  static bool IsBreak(nsINode* aNode);
   static bool IsMozBR(nsIDOMNode* aNode);
   static bool IsMozBR(nsINode* aNode);
   static bool HasMozAttr(nsIDOMNode* aNode);
 };
 
 /***************************************************************************
  * stack based helper class for detecting end of editor initialization, in
  * order to trigger "end of init" initialization of the edit rules.