--- /dev/null	2008-05-09 09:59:47.390392120 +0300
+++ content/base/public/nsINodeIterator.h	2008-05-09 12:56:09.000000000 +0300
@@ -0,0 +1,75 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2008
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *   Olli Pettay <Olli.Pettay@helsinki.fi> (Original Author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+#ifndef __nsINodeIterator_h___
+#define __nsINsodeIterator_h___
+#include "nsIContentIterator.h"
+class nsINode;
+
+#define NS_INODEITERATOR_IID \
+  { 0xc1f346ac, 0x2a7c, 0x430a, \
+    { 0xae, 0x7f, 0xa5, 0x8c, 0x38, 0x34, 0x5e, 0xf2 } }
+
+class nsINodeIterator : public nsIContentIterator
+{
+public:
+  NS_DECLARE_STATIC_IID_ACCESSOR(NS_INODEITERATOR_IID)
+
+  /**
+   * Initializes an iterator for the subtree rooted by the node aRoot
+   */
+  virtual nsresult Init(nsINode* aRoot) = 0;
+  virtual nsresult Init(nsIContent* aRoot) = 0;
+  virtual nsresult Init(nsIDOMRange* aRange) = 0;
+
+  /**
+   * CurrentItem will return the current item, or null if the list is empty
+   * @return the current node
+   */
+  virtual nsINode* GetCurrent() = 0;
+
+  /**
+   * PositionAt will position the iterator to the supplied node
+   */
+  virtual nsresult PositionAt(nsINode* aCurNode) = 0;
+  virtual nsresult PositionAt(nsIContent* aCurNode) = 0;
+};
+
+NS_DEFINE_STATIC_IID_ACCESSOR(nsINodeIterator, NS_INODEITERATOR_IID)
+
+#endif // __nsINodeIterator_h___
+
? content/base/public/nsINodeIterator.h
? content/base/test/test_bug
Index: content/base/public/Makefile.in
===================================================================
RCS file: /cvsroot/mozilla/content/base/public/Makefile.in,v
retrieving revision 1.67
diff -u -8 -p -r1.67 Makefile.in
--- content/base/public/Makefile.in	25 Jul 2007 04:29:47 -0000	1.67
+++ content/base/public/Makefile.in	9 May 2008 10:03:30 -0000
@@ -45,16 +45,17 @@ MODULE		= content
 XPIDL_MODULE	= content_base
 GRE_MODULE	= 1
 
 EXPORTS		= \
 mozFlushType.h \
 nsIContent.h \
 nsIAttribute.h \
 nsIContentIterator.h \
+nsINodeIterator.h \
 nsContentErrors.h \
 nsContentPolicyUtils.h \
 nsContentUtils.h \
 nsIDocument.h \
 nsIDocumentObserver.h \
 nsIMutationObserver.h \
 nsINameSpaceManager.h \
 nsINode.h \
Index: content/base/public/nsIContentIterator.h
===================================================================
RCS file: /cvsroot/mozilla/content/base/public/nsIContentIterator.h,v
retrieving revision 1.15
diff -u -8 -p -r1.15 nsIContentIterator.h
--- content/base/public/nsIContentIterator.h	25 Oct 2006 20:24:00 -0000	1.15
+++ content/base/public/nsIContentIterator.h	9 May 2008 10:03:30 -0000
@@ -42,16 +42,18 @@
 
 class nsIContent;
 class nsIDOMRange;
 
 #define NS_ICONTENTITERTOR_IID \
 {0xa6cf90e4, 0x15b3, 0x11d2,   \
 {0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32} }
 
+// Note, if you need to iterate through all kinds of nodes, you may want to use
+// nsINodeIterator, which most of the content iterators implement.
 class nsIContentIterator : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENTITERTOR_IID)
 
   /* Initializes an iterator for the subtree rooted by the node aRoot
    */
   virtual nsresult Init(nsIContent* aRoot) = 0;
Index: content/base/src/nsContentIterator.cpp
===================================================================
RCS file: /cvsroot/mozilla/content/base/src/nsContentIterator.cpp,v
retrieving revision 1.79
diff -u -8 -p -r1.79 nsContentIterator.cpp
--- content/base/src/nsContentIterator.cpp	19 Mar 2008 23:23:59 -0000	1.79
+++ content/base/src/nsContentIterator.cpp	9 May 2008 10:03:30 -0000
@@ -33,17 +33,17 @@
  * and other provisions required by the GPL or the LGPL. If you do not delete
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.h"
 #include "nsIDOMNodeList.h"
-#include "nsIContentIterator.h"
+#include "nsINodeIterator.h"
 #include "nsRange.h"
 #include "nsIContent.h"
 #include "nsIDOMText.h"
 #include "nsCOMPtr.h"
 #include "nsPresContext.h"
 #include "nsIComponentManager.h"
 #include "nsContentCID.h"
 #include "nsLayoutCID.h"
@@ -60,128 +60,147 @@ static NS_DEFINE_IID(kISupportsIID, NS_I
 //
 static inline PRBool
 NodeHasChildren(nsINode *aNode)
 {
   return aNode->GetChildCount() > 0;
 }
 
 ///////////////////////////////////////////////////////////////////////////
-// ContentToParentOffset: returns the content node's parent and offset.
+// NodeToParentOffset: returns the node's parent and offset.
 //
 
-static nsIContent*
-ContentToParentOffset(nsIContent *aContent, PRInt32 *aOffset)
+static nsINode*
+NodeToParentOffset(nsINode *aNode, PRInt32 *aOffset)
 {
   *aOffset  = 0;
 
-  nsIContent* parent = aContent->GetParent();
+  nsINode* parent = aNode->GetNodeParent();
 
   if (parent) {
-    *aOffset = parent->IndexOf(aContent);
+    *aOffset = parent->IndexOf(aNode);
   }
   
   return parent;
 }
 
 ///////////////////////////////////////////////////////////////////////////
-// ContentIsInTraversalRange: returns true if content is visited during
+// NodeIsInTraversalRange: returns true if content is visited during
 // the traversal of the range in the specified mode.
 //
 static PRBool
-ContentIsInTraversalRange(nsIContent *aContent, PRBool aIsPreMode,
-                          nsINode *aStartNode, PRInt32 aStartOffset,
-                          nsINode *aEndNode, PRInt32 aEndOffset)
+NodeIsInTraversalRange(nsINode *aNode, PRBool aIsPreMode,
+                       nsINode *aStartNode, PRInt32 aStartOffset,
+                       nsINode *aEndNode, PRInt32 aEndOffset)
 {
-  if (!aStartNode || !aEndNode || !aContent)
+  if (!aStartNode || !aEndNode || !aNode)
     return PR_FALSE;
 
   // If a chardata node contains an end point of the traversal range,
   // it is always in the traversal range.
-  if (aContent->IsNodeOfType(nsINode::eDATA_NODE) &&
-      (aContent == aStartNode || aContent == aEndNode)) {
+  if (aNode->IsNodeOfType(nsINode::eDATA_NODE) &&
+      (aNode == aStartNode || aNode == aEndNode)) {
     return PR_TRUE;
   }
 
-  nsIContent* parent = aContent->GetParent();
+  nsINode* parent = aNode->GetNodeParent();
   if (!parent)
     return PR_FALSE;
 
-  PRInt32 indx = parent->IndexOf(aContent);
+  PRInt32 indx = parent->IndexOf(aNode);
 
   if (!aIsPreMode)
     ++indx;
 
   return (nsContentUtils::ComparePoints(aStartNode, aStartOffset,
                                         parent, indx) <= 0) &&
          (nsContentUtils::ComparePoints(aEndNode, aEndOffset,
                                         parent, indx) >= 0);
 }
 
 
 
 /*
  *  A simple iterator class for traversing the content in "close tag" order
  */
-class nsContentIterator : public nsIContentIterator //, public nsIEnumerator
+class nsContentIterator : public nsINodeIterator //, public nsIEnumerator
 {
 public:
   NS_DECL_ISUPPORTS
 
   nsContentIterator();
   virtual ~nsContentIterator();
 
   // nsIContentIterator interface methods ------------------------------
 
-  virtual nsresult Init(nsIContent* aRoot);
+  virtual nsresult Init(nsIContent* aRoot)
+  {
+    return Init(static_cast<nsINode*>(aRoot));
+  }
 
   virtual nsresult Init(nsIDOMRange* aRange);
 
   virtual void First();
 
   virtual void Last();
   
   virtual void Next();
 
   virtual void Prev();
 
-  virtual nsIContent *GetCurrentNode();
+  virtual nsIContent *GetCurrentNode()
+  {
+     nsINode* current = GetCurrent();
+     return (current && current->IsNodeOfType(nsINode::eCONTENT)) ?
+       static_cast<nsIContent*>(current) : nsnull;
+  }
 
   virtual PRBool IsDone();
 
-  virtual nsresult PositionAt(nsIContent* aCurNode);
+  virtual nsresult PositionAt(nsIContent* aCurNode)
+  {
+    return PositionAt(static_cast<nsINode*>(aCurNode));
+  }
+
+  // nsINodeIterator interface methods ------------------------------
+
+  virtual nsresult Init(nsINode* aRoot);
+
+  virtual nsINode* GetCurrent();
+
+  virtual nsresult PositionAt(nsINode* aCurNode);
 
   // nsIEnumertor interface methods ------------------------------
   
   //NS_IMETHOD CurrentItem(nsISupports **aItem);
 
 protected:
 
-  nsIContent *GetDeepFirstChild(nsIContent *aRoot, nsVoidArray *aIndexes);
-  nsIContent *GetDeepLastChild(nsIContent *aRoot, nsVoidArray *aIndexes);
+  nsINode* GetDeepFirstChild(nsINode *aRoot, nsVoidArray *aIndexes);
+  nsINode* GetDeepLastChild(nsINode *aRoot, nsVoidArray *aIndexes);
 
   // Get the next sibling of aNode.  Note that this will generally return null
   // if aNode happens not to be a content node.  That's OK.
-  nsIContent *GetNextSibling(nsINode *aNode, nsVoidArray *aIndexes);
+  nsINode* GetNextSibling(nsINode *aNode, nsVoidArray *aIndexes);
 
   // Get the prev sibling of aNode.  Note that this will generally return null
   // if aNode happens not to be a content node.  That's OK.
-  nsIContent *GetPrevSibling(nsINode *aNode, nsVoidArray *aIndexes);
+  nsINode* GetPrevSibling(nsINode *aNode, nsVoidArray *aIndexes);
 
-  nsIContent *NextNode(nsIContent *aNode, nsVoidArray *aIndexes);
-  nsIContent *PrevNode(nsIContent *aNode, nsVoidArray *aIndexes);
+  nsINode* NextNode(nsINode *aNode, nsVoidArray *aIndexes);
+  nsINode* PrevNode(nsINode *aNode, nsVoidArray *aIndexes);
 
   // WARNING: This function is expensive
   nsresult RebuildIndexStack();
 
   void MakeEmpty();
   
-  nsCOMPtr<nsIContent> mCurNode;
-  nsCOMPtr<nsIContent> mFirst;
-  nsCOMPtr<nsIContent> mLast;
+  nsCOMPtr<nsINode> mCurNode;
+  nsCOMPtr<nsINode> mFirst;
+  nsCOMPtr<nsINode> mLast;
   nsCOMPtr<nsINode> mCommonParent;
 
   // used by nsContentIterator to cache indices
   nsAutoVoidArray mIndexes;
 
   // used by nsSubtreeIterator to cache indices.  Why put them in the base class?
   // Because otherwise I have to duplicate the routines GetNextSibling etc across both classes,
   // with slight variations for caching.  Or alternately, create a base class for the cache
@@ -252,17 +271,17 @@ nsresult NS_NewPreContentIterator(nsICon
   return NS_OK;
 }
 
 
 /******************************************************
  * XPCOM cruft
  ******************************************************/
  
-NS_IMPL_ISUPPORTS1(nsContentIterator, nsIContentIterator)
+NS_IMPL_ISUPPORTS2(nsContentIterator, nsIContentIterator, nsINodeIterator)
 
 
 /******************************************************
  * constructor/destructor
  ******************************************************/
 
 nsContentIterator::nsContentIterator() :
   // don't need to explicitly initialize |nsCOMPtr|s, they will automatically be NULL
@@ -277,20 +296,21 @@ nsContentIterator::~nsContentIterator()
 
 
 /******************************************************
  * Init routines
  ******************************************************/
 
 
 nsresult
-nsContentIterator::Init(nsIContent* aRoot)
+nsContentIterator::Init(nsINode* aRoot)
 {
   if (!aRoot) 
     return NS_ERROR_NULL_POINTER; 
+
   mIsDone = PR_FALSE;
   mIndexes.Clear();
   
   if (mPre)
   {
     mFirst = aRoot;
     mLast  = GetDeepLastChild(aRoot, nsnull);
   }
@@ -383,18 +403,18 @@ nsContentIterator::Init(nsIDOMRange* aRa
       {
         mFirst = GetNextSibling(startNode, nsnull);
 
         // Does mFirst node really intersect the range?
         // The range could be 'degenerate', ie not collapsed 
         // but still contain no content.
   
         if (mFirst &&
-            !ContentIsInTraversalRange(mFirst, mPre, startNode, startIndx,
-                                       endNode, endIndx)) {
+            !NodeIsInTraversalRange(mFirst, mPre, startNode, startIndx,
+                                    endNode, endIndx)) {
           mFirst = nsnull;
         }
       }
       else {
         NS_ASSERTION(startNode->IsNodeOfType(nsINode::eCONTENT),
                    "Data node that's not content?");
 
         mFirst = static_cast<nsIContent*>(startNode);
@@ -418,18 +438,18 @@ nsContentIterator::Init(nsIDOMRange* aRa
     {
       mFirst = GetDeepFirstChild(cChild, nsnull);
 
       // Does mFirst node really intersect the range?
       // The range could be 'degenerate', ie not collapsed 
       // but still contain no content.
   
       if (mFirst &&
-          !ContentIsInTraversalRange(mFirst, mPre, startNode, startIndx,
-                                     endNode, endIndx))
+          !NodeIsInTraversalRange(mFirst, mPre, startNode, startIndx,
+                                  endNode, endIndx))
         mFirst = nsnull;
     }
   }
 
 
   // Find last node in range.
 
   PRBool endIsData = endNode->IsNodeOfType(nsINode::eDATA_NODE);
@@ -449,18 +469,18 @@ nsContentIterator::Init(nsIDOMRange* aRa
       // XXX: In the future, if end offset is before the first
       //      character in the cdata node, should we set mLast to
       //      the prev sibling?
 
       if (!endIsData)
       {
         mLast = GetPrevSibling(endNode, nsnull);
 
-        if (!ContentIsInTraversalRange(mLast, mPre, startNode, startIndx,
-                                       endNode, endIndx))
+        if (!NodeIsInTraversalRange(mLast, mPre, startNode, startIndx,
+                                    endNode, endIndx))
           mLast = nsnull;
       }
       else {
         NS_ASSERTION(endNode->IsNodeOfType(nsINode::eCONTENT),
                      "Data node that's not content?");
 
         mLast = static_cast<nsIContent*>(endNode);
       }
@@ -477,18 +497,18 @@ nsContentIterator::Init(nsIDOMRange* aRa
       NS_NOTREACHED("nsContentIterator::nsContentIterator");
       return NS_ERROR_FAILURE; 
     }
 
     if (mPre)
     {
       mLast  = GetDeepLastChild(cChild, nsnull);
 
-      if (!ContentIsInTraversalRange(mLast, mPre, startNode, startIndx,
-                                     endNode, endIndx)) {
+      if (!NodeIsInTraversalRange(mLast, mPre, startNode, startIndx,
+                                  endNode, endIndx)) {
         mLast = nsnull;
       }
     }
     else { // post-order 
       mLast = cChild;
     }
   }
 
@@ -517,28 +537,28 @@ nsContentIterator::Init(nsIDOMRange* aRa
  * Helper routines
  ******************************************************/
 // WARNING: This function is expensive
 nsresult nsContentIterator::RebuildIndexStack()
 {
   // Make sure we start at the right indexes on the stack!  Build array up
   // to common parent of start and end.  Perhaps it's too many entries, but
   // that's far better than too few.
-  nsIContent* parent;
-  nsIContent* current;
+  nsINode* parent;
+  nsINode* current;
 
   mIndexes.Clear();
   current = mCurNode;
   if (!current) {
     return NS_OK;
   }
 
   while (current != mCommonParent)
   {
-    parent = current->GetParent();
+    parent = current->GetNodeParent();
     
     if (!parent)
       return NS_ERROR_FAILURE;
   
     mIndexes.InsertElementAt(NS_INT32_TO_PTR(parent->IndexOf(current)), 0);
 
     current = parent;
   }
@@ -551,72 +571,72 @@ nsContentIterator::MakeEmpty()
   mCurNode      = nsnull;
   mFirst        = nsnull;
   mLast         = nsnull;
   mCommonParent = nsnull;
   mIsDone       = PR_TRUE;
   mIndexes.Clear();
 }
 
-nsIContent *
-nsContentIterator::GetDeepFirstChild(nsIContent *aRoot, nsVoidArray *aIndexes)
+nsINode*
+nsContentIterator::GetDeepFirstChild(nsINode *aRoot, nsVoidArray *aIndexes)
 {
   if (!aRoot) {
     return nsnull;
   }
 
-  nsIContent *cN = aRoot;
-  nsIContent *cChild = cN->GetChildAt(0);
+  nsINode *n = aRoot;
+  nsINode *nChild = n->GetChildAt(0);
 
-  while (cChild)
+  while (nChild)
   {
     if (aIndexes)
     {
       // Add this node to the stack of indexes
       aIndexes->AppendElement(NS_INT32_TO_PTR(0));
     }
-    cN = cChild;
-    cChild = cN->GetChildAt(0);
+    n = nChild;
+    nChild = n->GetChildAt(0);
   }
 
-  return cN;
+  return n;
 }
 
-nsIContent *
-nsContentIterator::GetDeepLastChild(nsIContent *aRoot, nsVoidArray *aIndexes)
+nsINode*
+nsContentIterator::GetDeepLastChild(nsINode *aRoot, nsVoidArray *aIndexes)
 {
   if (!aRoot) {
     return nsnull;
   }
 
-  nsIContent *deepLastChild = aRoot;
+  nsINode *deepLastChild = aRoot;
 
-  nsIContent *cN = aRoot;
-  PRInt32 numChildren = cN->GetChildCount();
+  nsINode *n = aRoot;
+  PRInt32 numChildren = n->GetChildCount();
 
   while (numChildren)
   {
-    nsIContent *cChild = cN->GetChildAt(--numChildren);
+    nsINode *nChild = n->GetChildAt(--numChildren);
 
     if (aIndexes)
     {
       // Add this node to the stack of indexes
       aIndexes->AppendElement(NS_INT32_TO_PTR(numChildren));
     }
-    numChildren = cChild->GetChildCount();
-    cN = cChild;
+    numChildren = nChild->GetChildCount();
+    n = nChild;
 
-    deepLastChild = cN;
+    deepLastChild = n;
   }
 
   return deepLastChild;
 }
 
 // Get the next sibling, or parents next sibling, or grandpa's next sibling...
-nsIContent *
+nsINode *
 nsContentIterator::GetNextSibling(nsINode *aNode, 
                                   nsVoidArray *aIndexes)
 {
   if (!aNode) 
     return nsnull;
 
   nsINode *parent = aNode->GetNodeParent();
   if (!parent)
@@ -631,17 +651,17 @@ nsContentIterator::GetNextSibling(nsINod
     indx = NS_PTR_TO_INT32((*aIndexes)[aIndexes->Count()-1]);
   }
   else
     indx = mCachedIndex;
 
   // reverify that the index of the current node hasn't changed.
   // not super cheap, but a lot cheaper than IndexOf(), and still O(1).
   // ignore result this time - the index may now be out of range.
-  nsIContent *sib = parent->GetChildAt(indx);
+  nsINode* sib = parent->GetChildAt(indx);
   if (sib != aNode)
   {
     // someone changed our index - find the new index the painful way
     indx = parent->IndexOf(aNode);
   }
 
   // indx is now canonically correct
   if ((sib = parent->GetChildAt(++indx)))
@@ -670,17 +690,17 @@ nsContentIterator::GetNextSibling(nsINod
     // ok to leave cache out of date here if parent == mCommonParent?
     sib = GetNextSibling(parent, aIndexes);
   }
   
   return sib;
 }
 
 // Get the prev sibling, or parents prev sibling, or grandpa's prev sibling...
-nsIContent *
+nsINode*
 nsContentIterator::GetPrevSibling(nsINode *aNode, 
                                   nsVoidArray *aIndexes)
 {
   if (!aNode)
     return nsnull;
 
   nsINode *parent = aNode->GetNodeParent();
   if (!parent)
@@ -694,17 +714,17 @@ nsContentIterator::GetPrevSibling(nsINod
     // use the last entry on the Indexes array for the current index
     indx = NS_PTR_TO_INT32((*aIndexes)[aIndexes->Count()-1]);
   }
   else
     indx = mCachedIndex;
 
   // reverify that the index of the current node hasn't changed
   // ignore result this time - the index may now be out of range.
-  nsIContent *sib = parent->GetChildAt(indx);
+  nsINode *sib = parent->GetChildAt(indx);
   if (sib != aNode)
   {
     // someone changed our index - find the new index the painful way
     indx = parent->IndexOf(aNode);
   }
 
   // indx is now canonically correct
   if (indx > 0 && (sib = parent->GetChildAt(--indx)))
@@ -724,83 +744,83 @@ nsContentIterator::GetPrevSibling(nsINod
       aIndexes->RemoveElementAt(aIndexes->Count()-1);
     }
     return GetPrevSibling(parent, aIndexes);
   }
 
   return sib;
 }
 
-nsIContent *
-nsContentIterator::NextNode(nsIContent *aNode, nsVoidArray *aIndexes)
+nsINode*
+nsContentIterator::NextNode(nsINode *aNode, nsVoidArray *aIndexes)
 {
-  nsIContent *cN = aNode;
-  nsIContent *nextNode = nsnull;
+  nsINode *n = aNode;
+  nsINode *nextNode = nsnull;
 
   if (mPre)  // if we are a Pre-order iterator, use pre-order
   {
     // if it has children then next node is first child
-    if (NodeHasChildren(cN))
+    if (NodeHasChildren(n))
     {
-      nsIContent *cFirstChild = cN->GetChildAt(0);
+      nsINode *nFirstChild = n->GetChildAt(0);
 
       // update cache
       if (aIndexes)
       {
         // push an entry on the index stack
         aIndexes->AppendElement(NS_INT32_TO_PTR(0));
       }
       else mCachedIndex = 0;
       
-      return cFirstChild;
+      return nFirstChild;
     }
 
     // else next sibling is next
-    nextNode = GetNextSibling(cN, aIndexes);
+    nextNode = GetNextSibling(n, aIndexes);
   }
   else  // post-order
   {
-    nsIContent *parent = cN->GetParent();
-    nsIContent *cSibling = nsnull;
+    nsINode *parent = n->GetParent();
+    nsINode *nSibling = nsnull;
     PRInt32 indx;
 
     // get the cached index
     if (aIndexes)
     {
       NS_ASSERTION(aIndexes->Count() > 0, "ContentIterator stack underflow");
       // use the last entry on the Indexes array for the current index
       indx = NS_PTR_TO_INT32((*aIndexes)[aIndexes->Count()-1]);
     }
     else indx = mCachedIndex;
 
     // reverify that the index of the current node hasn't changed.
     // not super cheap, but a lot cheaper than IndexOf(), and still O(1).
     // ignore result this time - the index may now be out of range.
     if (indx >= 0)
-      cSibling = parent->GetChildAt(indx);
-    if (cSibling != cN)
+      nSibling = parent->GetChildAt(indx);
+    if (nSibling != n)
     {
       // someone changed our index - find the new index the painful way
-      indx = parent->IndexOf(cN);
+      indx = parent->IndexOf(n);
     }
 
     // indx is now canonically correct
-    cSibling = parent->GetChildAt(++indx);
-    if (cSibling)
+    nSibling = parent->GetChildAt(++indx);
+    if (nSibling)
     {
       // update cache
       if (aIndexes)
       {
         // replace an entry on the index stack
         aIndexes->ReplaceElementAt(NS_INT32_TO_PTR(indx),aIndexes->Count()-1);
       }
       else mCachedIndex = indx;
       
       // next node is siblings "deep left" child
-      return GetDeepFirstChild(cSibling, aIndexes); 
+      return GetDeepFirstChild(nSibling, aIndexes); 
     }
   
     // else it's the parent
     // update cache
     if (aIndexes)
     {
       // pop an entry off the index stack
       // Don't leave the index empty, especially if we're
@@ -810,96 +830,96 @@ nsContentIterator::NextNode(nsIContent *
     }
     else mCachedIndex = 0;   // this might be wrong, but we are better off guessing
     nextNode = parent;
   }
 
   return nextNode;
 }
 
-nsIContent *
-nsContentIterator::PrevNode(nsIContent *aNode, nsVoidArray *aIndexes)
+nsINode*
+nsContentIterator::PrevNode(nsINode *aNode, nsVoidArray *aIndexes)
 {
-  nsIContent *prevNode = nsnull;
-  nsIContent *cN = aNode;
+  nsINode *prevNode = nsnull;
+  nsINode *n = aNode;
    
   if (mPre)  // if we are a Pre-order iterator, use pre-order
   {
-    nsIContent *parent = cN->GetParent();
-    nsIContent *cSibling = nsnull;
+    nsINode *parent = n->GetParent();
+    nsINode *nSibling = nsnull;
     PRInt32 indx;
 
     // get the cached index
     if (aIndexes)
     {
       NS_ASSERTION(aIndexes->Count() > 0, "ContentIterator stack underflow");
       // use the last entry on the Indexes array for the current index
       indx = NS_PTR_TO_INT32((*aIndexes)[aIndexes->Count()-1]);
     }
     else indx = mCachedIndex;
 
     // reverify that the index of the current node hasn't changed.
     // not super cheap, but a lot cheaper than IndexOf(), and still O(1).
     // ignore result this time - the index may now be out of range.
     if (indx >= 0)
-      cSibling = parent->GetChildAt(indx);
+      nSibling = parent->GetChildAt(indx);
 
-    if (cSibling != cN)
+    if (nSibling != n)
     {
       // someone changed our index - find the new index the painful way
-      indx = parent->IndexOf(cN);
+      indx = parent->IndexOf(n);
     }
 
     // indx is now canonically correct
-    if (indx && (cSibling = parent->GetChildAt(--indx)))
+    if (indx && (nSibling = parent->GetChildAt(--indx)))
     {
       // update cache
       if (aIndexes)
       {
         // replace an entry on the index stack
         aIndexes->ReplaceElementAt(NS_INT32_TO_PTR(indx),aIndexes->Count()-1);
       }
       else mCachedIndex = indx;
       
       // prev node is siblings "deep right" child
-      return GetDeepLastChild(cSibling, aIndexes); 
+      return GetDeepLastChild(nSibling, aIndexes); 
     }
   
     // else it's the parent
     // update cache
     if (aIndexes)
     {
       // pop an entry off the index stack
       aIndexes->RemoveElementAt(aIndexes->Count()-1);
     }
     else mCachedIndex = 0;   // this might be wrong, but we are better off guessing
     prevNode = parent;
   }
   else  // post-order
   {
-    PRInt32 numChildren = cN->GetChildCount();
+    PRInt32 numChildren = n->GetChildCount();
   
     // if it has children then prev node is last child
     if (numChildren)
     {
-      nsIContent *cLastChild = cN->GetChildAt(--numChildren);
+      nsINode *nLastChild = n->GetChildAt(--numChildren);
 
       // update cache
       if (aIndexes)
       {
         // push an entry on the index stack
         aIndexes->AppendElement(NS_INT32_TO_PTR(numChildren));
       }
       else mCachedIndex = numChildren;
       
-      return cLastChild;
+      return nLastChild;
     }
 
     // else prev sibling is previous
-    prevNode = GetPrevSibling(cN, aIndexes);
+    prevNode = GetPrevSibling(n, aIndexes);
   }
 
   return prevNode;
 }
 
 /******************************************************
  * ContentIterator routines
  ******************************************************/
@@ -977,69 +997,69 @@ nsContentIterator::IsDone()
 {
   return mIsDone;
 }
 
 
 // Keeping arrays of indexes for the stack of nodes makes PositionAt
 // interesting...
 nsresult
-nsContentIterator::PositionAt(nsIContent* aCurNode)
+nsContentIterator::PositionAt(nsINode* aCurNode)
 {
   if (!aCurNode)
     return NS_ERROR_NULL_POINTER;
 
-  nsIContent *newCurNode = aCurNode;
-  nsIContent *tempNode = mCurNode;
+  nsINode *newCurNode = aCurNode;
+  nsINode *tempNode = mCurNode;
 
   mCurNode = aCurNode;
   // take an early out if this doesn't actually change the position
   if (mCurNode == tempNode)
   {
     mIsDone = PR_FALSE;  // paranoia
     return NS_OK;
   }
 
   // Check to see if the node falls within the traversal range.
 
-  nsIContent* firstNode = mFirst;
-  nsIContent* lastNode = mLast;
+  nsINode* firstNode = mFirst;
+  nsINode* lastNode = mLast;
   PRInt32 firstOffset=0, lastOffset=0;
 
   if (firstNode && lastNode)
   {
     if (mPre)
     {
-      firstNode = ContentToParentOffset(mFirst, &firstOffset);
+      firstNode = NodeToParentOffset(mFirst, &firstOffset);
 
       if (lastNode->GetChildCount())
         lastOffset = 0;
       else
       {
-        lastNode = ContentToParentOffset(mLast, &lastOffset);
+        lastNode = NodeToParentOffset(mLast, &lastOffset);
         ++lastOffset;
       }
     }
     else
     {
       PRUint32 numChildren = firstNode->GetChildCount();
 
       if (numChildren)
         firstOffset = numChildren;
       else
-        firstNode = ContentToParentOffset(mFirst, &firstOffset);
+        firstNode = NodeToParentOffset(mFirst, &firstOffset);
 
-      lastNode = ContentToParentOffset(mLast, &lastOffset);
+      lastNode = NodeToParentOffset(mLast, &lastOffset);
       ++lastOffset;
     }
   }
 
   if (!firstNode || !lastNode ||
-      !ContentIsInTraversalRange(mCurNode, mPre, firstNode, firstOffset,
-                                 lastNode, lastOffset))
+      !NodeIsInTraversalRange(mCurNode, mPre, firstNode, firstOffset,
+                              lastNode, lastOffset))
   {
     mIsDone = PR_TRUE;
     return NS_ERROR_FAILURE;
   }
 
   // We can be at ANY node in the sequence.
   // Need to regenerate the array of indexes back to the root or common parent!
   nsAutoVoidArray      oldParentStack;
@@ -1061,17 +1081,17 @@ nsContentIterator::PositionAt(nsIContent
   // sure we include mCommonParent in the oldParentStack, for use in the next
   // for loop, and mIndexes only has entries for nodes from tempNode up through
   // an ancestor of tempNode that's a child of mCommonParent.
   for (PRInt32 i = mIndexes.Count()+1; i > 0 && tempNode; i--)
   {
     // Insert at head since we're walking up
     oldParentStack.InsertElementAt(tempNode,0);
 
-    nsIContent *parent = tempNode->GetParent();
+    nsINode *parent = tempNode->GetNodeParent();
 
     if (!parent)  // this node has no parent, and thus no index
       break;
 
     if (parent == mCurNode)
     {
       // The position was moved to a parent of the current position. 
       // All we need to do is drop some indexes.  Shortcut here.
@@ -1081,17 +1101,17 @@ nsContentIterator::PositionAt(nsIContent
       return NS_OK;
     }
     tempNode = parent;
   }
 
   // Ok.  We have the array of old parents.  Look for a match.
   while (newCurNode)
   {
-    nsIContent *parent = newCurNode->GetParent();
+    nsINode *parent = newCurNode->GetNodeParent();
 
     if (!parent)  // this node has no parent, and thus no index
       break;
 
     PRInt32 indx = parent->IndexOf(newCurNode);
 
     // insert at the head!
     newIndexes.InsertElementAt(NS_INT32_TO_PTR(indx),0);
@@ -1116,19 +1136,18 @@ nsContentIterator::PositionAt(nsIContent
   }
 
   // phew!
 
   mIsDone = PR_FALSE;
   return NS_OK;
 }
 
-
-nsIContent *
-nsContentIterator::GetCurrentNode()
+nsINode*
+nsContentIterator::GetCurrent()
 {
   if (mIsDone) {
     return nsnull;
   }
 
   NS_ASSERTION(mCurNode, "Null current node in an iterator that's not done!");
 
   return mCurNode;
@@ -1157,36 +1176,48 @@ nsContentIterator::GetCurrentNode()
 class nsContentSubtreeIterator : public nsContentIterator 
 {
 public:
   nsContentSubtreeIterator() {}
   virtual ~nsContentSubtreeIterator() {}
 
   // nsContentIterator overrides ------------------------------
 
-  virtual nsresult Init(nsIContent* aRoot);
+  virtual nsresult Init(nsIContent* aRoot)
+  {
+    return Init(static_cast<nsINode*>(aRoot));
+  }
 
   virtual nsresult Init(nsIDOMRange* aRange);
 
   virtual void Next();
 
   virtual void Prev();
 
-  virtual nsresult PositionAt(nsIContent* aCurNode);
+  virtual nsresult PositionAt(nsIContent* aCurNode)
+  {
+    return PositionAt(static_cast<nsINode*>(aCurNode));
+  }
 
   // Must override these because we don't do PositionAt
   virtual void First();
 
   // Must override these because we don't do PositionAt
   virtual void Last();
 
+  // nsINodeIterator interface methods ------------------------------
+
+  virtual nsresult Init(nsINode* aRoot);
+
+  virtual nsresult PositionAt(nsINode* aCurNode);
+
 protected:
 
-  nsresult GetTopAncestorInRange(nsIContent *aNode,
-                                 nsCOMPtr<nsIContent> *outAnestor);
+  nsresult GetTopAncestorInRange(nsINode *aNode,
+                                 nsCOMPtr<nsINode> *outAnestor);
 
   // no copy's or assigns  FIX ME
   nsContentSubtreeIterator(const nsContentSubtreeIterator&);
   nsContentSubtreeIterator& operator=(const nsContentSubtreeIterator&);
 
   nsCOMPtr<nsIDOMRange> mRange;
   // these arrays all typically are used and have elements
 #if 0
@@ -1221,72 +1252,65 @@ nsresult NS_NewContentSubtreeIterator(ns
 
 
 
 /******************************************************
  * Init routines
  ******************************************************/
 
 
-nsresult nsContentSubtreeIterator::Init(nsIContent* aRoot)
+nsresult nsContentSubtreeIterator::Init(nsINode* aRoot)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 
 nsresult nsContentSubtreeIterator::Init(nsIDOMRange* aRange)
 {
   if (!aRange) 
     return NS_ERROR_NULL_POINTER; 
 
   mIsDone = PR_FALSE;
 
   mRange = aRange;
   
-  // get the start node and offset, convert to nsIContent
+  // get the start node and offset, convert to nsINode
   nsCOMPtr<nsIDOMNode> commonParent;
   nsCOMPtr<nsIDOMNode> startParent;
   nsCOMPtr<nsIDOMNode> endParent;
-  nsCOMPtr<nsIContent> cStartP;
-  nsCOMPtr<nsIContent> cEndP;
-  nsCOMPtr<nsIContent> cN;
-  nsIContent *firstCandidate = nsnull;
-  nsIContent *lastCandidate = nsnull;
+  nsCOMPtr<nsINode> nStartP;
+  nsCOMPtr<nsINode> nEndP;
+  nsCOMPtr<nsINode> n;
+  nsINode *firstCandidate = nsnull;
+  nsINode *lastCandidate = nsnull;
   PRInt32 indx, startIndx, endIndx;
 
   // get common content parent
   if (NS_FAILED(aRange->GetCommonAncestorContainer(getter_AddRefs(commonParent))) || !commonParent)
     return NS_ERROR_FAILURE;
   mCommonParent = do_QueryInterface(commonParent);
 
   // get start content parent
   if (NS_FAILED(aRange->GetStartContainer(getter_AddRefs(startParent))) || !startParent)
     return NS_ERROR_FAILURE;
-  cStartP = do_QueryInterface(startParent);
+  nStartP = do_QueryInterface(startParent);
   aRange->GetStartOffset(&startIndx);
 
   // get end content parent
   if (NS_FAILED(aRange->GetEndContainer(getter_AddRefs(endParent))) || !endParent)
     return NS_ERROR_FAILURE;
-  cEndP = do_QueryInterface(endParent);
+  nEndP = do_QueryInterface(endParent);
   aRange->GetEndOffset(&endIndx);
 
-  if (!cStartP || !cEndP)
-  {
-    // XXX Hack to account for the fact that not everything QIs to nsIContent.
-    // See bug 302775
-    return NS_ERROR_FAILURE;
-  }
-  
   // short circuit when start node == end node
   if (startParent == endParent)
   {
-    nsIContent* cChild = cStartP->GetChildAt(0);
+    nsINode* nChild = nStartP->GetChildAt(0);
   
-    if (!cChild) // no children, must be a text node or empty container
+    if (!nChild) // no children, must be a text node or empty container
     {
       // all inside one text node - empty subtree iterator
       MakeEmpty();
       return NS_OK;
     }
     else
     {
       if (startIndx == endIndx)  // collapsed range
@@ -1303,37 +1327,37 @@ nsresult nsContentSubtreeIterator::Init(
                                          &mStartNodes, &mStartOffsets);
 #endif
   nsContentUtils::GetAncestorsAndOffsets(endParent, endIndx,
                                          &mEndNodes, &mEndOffsets);
 
   // find first node in range
   aRange->GetStartOffset(&indx);
 
-  if (!cStartP->GetChildCount()) // no children, start at the node itself
+  if (!nStartP->GetChildCount()) // no children, start at the node itself
   {
-    cN = cStartP; 
+    n = nStartP;
   }
   else
   {
-    nsIContent* cChild = cStartP->GetChildAt(indx);
-    if (!cChild)  // offset after last child
+    nsINode* nChild = nStartP->GetChildAt(indx);
+    if (!nChild)  // offset after last child
     {
-      cN = cStartP;
+      n = nStartP;
     }
     else
     {
-      firstCandidate = cChild;
+      firstCandidate = nChild;
     }
   }
   
   if (!firstCandidate)
   {
     // then firstCandidate is next node after cN
-    firstCandidate = GetNextSibling(cN, nsnull);
+    firstCandidate = GetNextSibling(n, nsnull);
 
     if (!firstCandidate)
     {
       MakeEmpty();
       return NS_OK;
     }
   }
   
@@ -1357,41 +1381,41 @@ nsresult nsContentSubtreeIterator::Init(
   // cool, we have the first node in the range.  Now we walk
   // up it's ancestors to find the most senior that is still
   // in the range.  That's the real first node.
   if (NS_FAILED(GetTopAncestorInRange(firstCandidate, address_of(mFirst))))
     return NS_ERROR_FAILURE;
 
   // now to find the last node
   aRange->GetEndOffset(&indx);
-  PRInt32 numChildren = cEndP->GetChildCount();
+  PRInt32 numChildren = nEndP->GetChildCount();
 
   if (indx > numChildren) indx = numChildren;
   if (!indx)
   {
-    cN = cEndP;
+    n = nEndP;
   }
   else
   {
     if (!numChildren) // no children, must be a text node
     {
-      cN = cEndP; 
+      n = nEndP;
     }
     else
     {
-      lastCandidate = cEndP->GetChildAt(--indx);
+      lastCandidate = nEndP->GetChildAt(--indx);
       NS_ASSERTION(lastCandidate,
                    "tree traversal trouble in nsContentSubtreeIterator::Init");
     }
   }
   
   if (!lastCandidate)
   {
-    // then lastCandidate is prev node before cN
-    lastCandidate = GetPrevSibling(cN, nsnull);
+    // then lastCandidate is prev node before n
+    lastCandidate = GetPrevSibling(n, nsnull);
   }
   
   lastCandidate = GetDeepLastChild(lastCandidate, nsnull);
   
   // confirm that this last possible contained node
   // is indeed contained.  Else we have a range that
   // does not fully contain any node.
   
@@ -1447,17 +1471,17 @@ nsContentSubtreeIterator::Next()
     return;
 
   if (mCurNode == mLast) 
   {
     mIsDone = PR_TRUE;
     return;
   }
 
-  nsIContent *nextNode = GetNextSibling(mCurNode, nsnull);
+  nsINode *nextNode = GetNextSibling(mCurNode, nsnull);
   NS_ASSERTION(nextNode, "No next sibling!?! This could mean deadlock!");
 
 /*
   nextNode = GetDeepFirstChild(nextNode);
   return GetTopAncestorInRange(nextNode, address_of(mCurNode));
 */
   PRInt32 i = mEndNodes.IndexOf(nextNode);
   while (i != -1)
@@ -1494,80 +1518,80 @@ nsContentSubtreeIterator::Prev()
     return;
 
   if (mCurNode == mFirst) 
   {
     mIsDone = PR_TRUE;
     return;
   }
 
-  nsIContent *prevNode = PrevNode(GetDeepFirstChild(mCurNode, nsnull), nsnull);
+  nsINode *prevNode = PrevNode(GetDeepFirstChild(mCurNode, nsnull), nsnull);
 
   prevNode = GetDeepLastChild(prevNode, nsnull);
   
   GetTopAncestorInRange(prevNode, address_of(mCurNode));
 
   // This shouldn't be needed, but since our selection code can put us
   // in a situation where mFirst is in generated content, we need this
   // to stop the iterator when we've walked past past the first node!
   mIsDone = mCurNode == nsnull;
 }
 
 
 nsresult
-nsContentSubtreeIterator::PositionAt(nsIContent* aCurNode)
+nsContentSubtreeIterator::PositionAt(nsINode* aCurNode)
 {
   NS_ERROR("Not implemented!");
 
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 /****************************************************************
  * nsContentSubtreeIterator helper routines
  ****************************************************************/
 
 nsresult
-nsContentSubtreeIterator::GetTopAncestorInRange(nsIContent *aNode,
-                                                nsCOMPtr<nsIContent> *outAnestor)
+nsContentSubtreeIterator::GetTopAncestorInRange(nsINode *aNode,
+                                                nsCOMPtr<nsINode> *outAncestor)
 {
   if (!aNode) 
     return NS_ERROR_NULL_POINTER;
-  if (!outAnestor) 
+  if (!outAncestor) 
     return NS_ERROR_NULL_POINTER;
   
   
   // sanity check: aNode is itself in the range
   PRBool nodeBefore, nodeAfter;
   if (NS_FAILED(nsRange::CompareNodeToRange(aNode, mRange, &nodeBefore,
                                             &nodeAfter)))
     return NS_ERROR_FAILURE;
 
   if (nodeBefore || nodeAfter)
     return NS_ERROR_FAILURE;
   
-  nsCOMPtr<nsIContent> parent, tmp;
+  nsCOMPtr<nsINode> parent, tmp;
   while (aNode)
   {
-    parent = aNode->GetParent();
+    parent = aNode->GetNodeParent();
     if (!parent)
     {
       if (tmp)
       {
-        *outAnestor = tmp;
+        *outAncestor = tmp;
         return NS_OK;
       }
       else return NS_ERROR_FAILURE;
     }
     if (NS_FAILED(nsRange::CompareNodeToRange(parent, mRange, &nodeBefore,
                                               &nodeAfter)))
       return NS_ERROR_FAILURE;
 
     if (nodeBefore || nodeAfter)
     {
-      *outAnestor = aNode;
+      *outAncestor = aNode;
       return NS_OK;
     }
     tmp = aNode;
     aNode = parent;
   }
   return NS_ERROR_FAILURE;
 }
 
Index: content/base/src/nsRange.cpp
===================================================================
RCS file: /cvsroot/mozilla/content/base/src/nsRange.cpp,v
retrieving revision 1.229
diff -u -8 -p -r1.229 nsRange.cpp
--- content/base/src/nsRange.cpp	13 Mar 2008 10:12:51 -0000	1.229
+++ content/base/src/nsRange.cpp	9 May 2008 10:03:31 -0000
@@ -47,17 +47,17 @@
 #include "nsIDOMNode.h"
 #include "nsIDOMDocument.h"
 #include "nsIDOMNSDocument.h"
 #include "nsIDOMDocumentFragment.h"
 #include "nsIContent.h"
 #include "nsIDocument.h"
 #include "nsIDOMText.h"
 #include "nsDOMError.h"
-#include "nsIContentIterator.h"
+#include "nsINodeIterator.h"
 #include "nsIDOMNodeList.h"
 #include "nsGkAtoms.h"
 #include "nsContentUtils.h"
 
 nsresult NS_NewContentIterator(nsIContentIterator** aInstancePtrResult);
 nsresult NS_NewContentSubtreeIterator(nsIContentIterator** aInstancePtrResult);
 
 /******************************************************
@@ -83,29 +83,29 @@ nsresult NS_NewContentSubtreeIterator(ns
 // If outNodeBefore is returned true, then the node starts before the range does.
 // If outNodeAfter is returned true, then the node ends after the range does.
 // Note that both of the above might be true.
 // If neither are true, the node is contained inside of the range.
 // XXX - callers responsibility to ensure node in same doc as range! 
 
 // static
 nsresult
-nsRange::CompareNodeToRange(nsIContent* aNode, nsIDOMRange* aRange,
+nsRange::CompareNodeToRange(nsINode* aNode, nsIDOMRange* aRange,
                             PRBool *outNodeBefore, PRBool *outNodeAfter)
 {
   nsresult rv;
   nsCOMPtr<nsIRange> range = do_QueryInterface(aRange, &rv);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return CompareNodeToRange(aNode, range, outNodeBefore, outNodeAfter);
 }
 
 // static
 nsresult
-nsRange::CompareNodeToRange(nsIContent* aNode, nsIRange* aRange,
+nsRange::CompareNodeToRange(nsINode* aNode, nsIRange* aRange,
                             PRBool *outNodeBefore, PRBool *outNodeAfter)
 {
   NS_ENSURE_STATE(aNode);
   // create a pair of dom points that expresses location of node:
   //     NODE(start), NODE(end)
   // Let incoming range be:
   //    {RANGE(start), RANGE(end)}
   // if (RANGE(start) <= NODE(start))  and (RANGE(end) => NODE(end))
@@ -793,17 +793,17 @@ class RangeSubtreeIterator
 {
 private:
 
   enum RangeSubtreeIterState { eDone=0,
                                eUseStartCData,
                                eUseIterator,
                                eUseEndCData };
 
-  nsCOMPtr<nsIContentIterator>  mIter;
+  nsCOMPtr<nsINodeIterator>     mIter;
   RangeSubtreeIterState         mIterState;
 
   nsCOMPtr<nsIDOMCharacterData> mStartCData;
   nsCOMPtr<nsIDOMCharacterData> mEndCData;
 
 public:
 
   RangeSubtreeIterator()
@@ -860,18 +860,21 @@ RangeSubtreeIterator::Init(nsIDOMRange *
 
     mEndCData = nsnull;
   }
   else
   {
     // Now create a Content Subtree Iterator to be used
     // for the subtrees between the end points!
 
-    res = NS_NewContentSubtreeIterator(getter_AddRefs(mIter));
+    nsCOMPtr<nsIContentIterator> iter;
+    res = NS_NewContentSubtreeIterator(getter_AddRefs(iter));
     if (NS_FAILED(res)) return res;
+    mIter = do_QueryInterface(mIter);
+    NS_ENSURE_STATE(mIter);
 
     res = mIter->Init(aRange);
     if (NS_FAILED(res)) return res;
 
     if (mIter->IsDone())
     {
       // The subtree iterator thinks there's nothing
       // to iterate over, so just free it up so we
@@ -895,20 +898,20 @@ RangeSubtreeIterator::GetCurrentNode()
   nsIDOMNode *node = nsnull;
 
   if (mIterState == eUseStartCData && mStartCData) {
     NS_ADDREF(node = mStartCData);
   } else if (mIterState == eUseEndCData && mEndCData)
     NS_ADDREF(node = mEndCData);
   else if (mIterState == eUseIterator && mIter)
   {
-    nsIContent *content = mIter->GetCurrentNode();
+    nsINode* n = mIter->GetCurrent();
 
-    if (content) {
-      CallQueryInterface(content, &node);
+    if (n) {
+      CallQueryInterface(n, &node);
     }
   }
 
   return node;
 }
 
 void
 RangeSubtreeIterator::First()
@@ -1719,44 +1722,46 @@ nsresult nsRange::ToString(nsAString& aR
       return NS_OK;
     }
   } 
   
   /* complex case: mStartParent != mEndParent, or mStartParent not a text node
      revisit - there are potential optimizations here and also tradeoffs.
   */
 
-  nsCOMPtr<nsIContentIterator> iter;
-  NS_NewContentIterator(getter_AddRefs(iter));
+  nsCOMPtr<nsIContentIterator> contentIter;
+  NS_NewContentIterator(getter_AddRefs(contentIter));
+  nsCOMPtr<nsINodeIterator> iter = do_QueryInterface(contentIter);
+  NS_ENSURE_STATE(iter);
   nsresult rv = iter->Init(this);
   NS_ENSURE_SUCCESS(rv, rv);
   
   nsString tempString;
  
   // loop through the content iterator, which returns nodes in the range in 
   // close tag order, and grab the text from any text node
   while (!iter->IsDone())
   {
-    nsIContent *cN = iter->GetCurrentNode();
+    nsINode *n = iter->GetCurrent();
 
 #ifdef DEBUG_range
     // If debug, dump it:
-    cN->List(stdout);
+    n->List(stdout);
 #endif /* DEBUG */
-    nsCOMPtr<nsIDOMText> textNode( do_QueryInterface(cN) );
+    nsCOMPtr<nsIDOMText> textNode(do_QueryInterface(n));
     if (textNode) // if it's a text node, get the text
     {
-      if (cN == mStartParent) // only include text past start offset
+      if (n == mStartParent) // only include text past start offset
       {
         PRUint32 strLength;
         textNode->GetLength(&strLength);
         textNode->SubstringData(mStartOffset,strLength-mStartOffset,tempString);
         aReturn += tempString;
       }
-      else if (cN == mEndParent)  // only include text before end offset
+      else if (n == mEndParent)  // only include text before end offset
       {
         textNode->SubstringData(0,mEndOffset,tempString);
         aReturn += tempString;
       }
       else  // grab the whole kit-n-kaboodle
       {
         textNode->GetData(tempString);
         aReturn += tempString;
Index: content/base/src/nsRange.h
===================================================================
RCS file: /cvsroot/mozilla/content/base/src/nsRange.h,v
retrieving revision 1.60
diff -u -8 -p -r1.60 nsRange.h
--- content/base/src/nsRange.h	24 Feb 2008 12:46:09 -0000	1.60
+++ content/base/src/nsRange.h	9 May 2008 10:03:31 -0000
@@ -122,20 +122,20 @@ private:
 public:
 /******************************************************************************
  *  Utility routine to detect if a content node starts before a range and/or 
  *  ends after a range.  If neither it is contained inside the range.
  *  
  *  XXX - callers responsibility to ensure node in same doc as range!
  *
  *****************************************************************************/
-  static nsresult CompareNodeToRange(nsIContent* aNode, nsIDOMRange* aRange,
+  static nsresult CompareNodeToRange(nsINode* aNode, nsIDOMRange* aRange,
                                      PRBool *outNodeBefore,
                                      PRBool *outNodeAfter);
-  static nsresult CompareNodeToRange(nsIContent* aNode, nsIRange* aRange,
+  static nsresult CompareNodeToRange(nsINode* aNode, nsIRange* aRange,
                                      PRBool *outNodeBefore,
                                      PRBool *outNodeAfter);
 
 protected:
   void DoSetRange(nsINode* aStartN, PRInt32 aStartOffset,
                   nsINode* aEndN, PRInt32 aEndOffset,
                   nsINode* aRoot);
 };
