Landing fix for bug 132824. Implement NodeIterator object of Traversal API. Patch by craig.topper@gmail.com, r+sr=jonas@sicking.cc
authorJohnny Stenback <jst@mozilla.com>
Mon, 21 Jul 2008 17:35:38 -0700
changeset 16103 3e2c3a4d3d40b55dce2b85f4391191306a62bbb5
parent 16102 04f2145fb4bce66ca5c6ff06f8979c81e68d2d81
child 16104 fe3d3848f94259c0e0ac198a1dd4e0484aed4233
push idunknown
push userunknown
push dateunknown
bugs132824
milestone1.9.1a1pre
Landing fix for bug 132824. Implement NodeIterator object of Traversal API. Patch by craig.topper@gmail.com, r+sr=jonas@sicking.cc
content/base/src/Makefile.in
content/base/src/nsDocument.cpp
content/base/src/nsTreeWalker.cpp
content/base/src/nsTreeWalker.h
dom/public/idl/traversal/nsIDOMNodeIterator.idl
dom/public/nsDOMClassInfoID.h
dom/src/base/nsDOMClassInfo.cpp
--- a/content/base/src/Makefile.in
+++ b/content/base/src/Makefile.in
@@ -141,16 +141,17 @@ CPPSRCS		= \
 		nsLineBreaker.cpp \
 		nsLoadListenerProxy.cpp \
 		nsMappedAttributeElement.cpp \
 		nsMappedAttributes.cpp \
 		nsNameSpaceManager.cpp \
 		nsNoDataProtocolContentPolicy.cpp \
 		nsNodeInfo.cpp \
 		nsNodeInfoManager.cpp \
+		nsNodeIterator.cpp \
 		nsNodeUtils.cpp \
 		nsObjectLoadingContent.cpp \
 		nsParserUtils.cpp \
 		nsPlainTextSerializer.cpp \
 		nsPropertyTable.cpp \
 		nsRange.cpp \
 		nsReferencedElement.cpp \
 		nsScriptElement.cpp \
@@ -159,16 +160,17 @@ CPPSRCS		= \
 		nsStubDocumentObserver.cpp \
 		nsStubImageDecoderObserver.cpp \
 		nsStubMutationObserver.cpp \
 		nsStyledElement.cpp \
 		nsStyleLinkElement.cpp \
 		nsSyncLoadService.cpp \
 		nsTextFragment.cpp \
 		nsTextNode.cpp \
+		nsTraversal.cpp \
 		nsTreeWalker.cpp \
 		nsXMLContentSerializer.cpp \
 		nsXMLHttpRequest.cpp \
 		nsXMLNameSpaceMap.cpp \
 		$(NULL)
 
 GQI_SRCS = contentbase.gqi
 
--- a/content/base/src/nsDocument.cpp
+++ b/content/base/src/nsDocument.cpp
@@ -80,16 +80,17 @@
 #include "nsNodeUtils.h"
 #include "nsLayoutUtils.h" // for GetFrameForPoint
 #include "nsIFrame.h"
 
 #include "nsRange.h"
 #include "nsIDOMText.h"
 #include "nsIDOMComment.h"
 #include "nsDOMDocumentType.h"
+#include "nsNodeIterator.h"
 #include "nsTreeWalker.h"
 
 #include "nsIServiceManager.h"
 
 #include "nsContentCID.h"
 #include "nsDOMError.h"
 #include "nsIPresShell.h"
 #include "nsPresContext.h"
@@ -4196,39 +4197,69 @@ nsDocument::CreateRange(nsIDOMRange** aR
 
 NS_IMETHODIMP
 nsDocument::CreateNodeIterator(nsIDOMNode *aRoot,
                                PRUint32 aWhatToShow,
                                nsIDOMNodeFilter *aFilter,
                                PRBool aEntityReferenceExpansion,
                                nsIDOMNodeIterator **_retval)
 {
-  return NS_ERROR_NOT_IMPLEMENTED;
+  *_retval = nsnull;
+
+  if (!aRoot)
+    return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
+
+  nsresult rv = nsContentUtils::CheckSameOrigin(this, aRoot);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  NS_ENSURE_ARG_POINTER(_retval);
+
+  nsCOMPtr<nsINode> root = do_QueryInterface(aRoot);
+  NS_ENSURE_TRUE(root, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+
+  nsNodeIterator *iterator = new nsNodeIterator(root,
+                                                aWhatToShow,
+                                                aFilter,
+                                                aEntityReferenceExpansion);
+  NS_ENSURE_TRUE(iterator, NS_ERROR_OUT_OF_MEMORY);
+
+  NS_ADDREF(*_retval = iterator);
+
+  return NS_OK; 
 }
 
 NS_IMETHODIMP
 nsDocument::CreateTreeWalker(nsIDOMNode *aRoot,
                              PRUint32 aWhatToShow,
                              nsIDOMNodeFilter *aFilter,
                              PRBool aEntityReferenceExpansion,
                              nsIDOMTreeWalker **_retval)
 {
   *_retval = nsnull;
 
-  if (!aRoot) {
+  if (!aRoot)
     return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
-  }
 
   nsresult rv = nsContentUtils::CheckSameOrigin(this, aRoot);
-  if (NS_FAILED(rv)) {
-    return rv;
-  }
-
-  return NS_NewTreeWalker(aRoot, aWhatToShow, aFilter,
-                          aEntityReferenceExpansion, _retval);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  NS_ENSURE_ARG_POINTER(_retval);
+
+  nsCOMPtr<nsINode> root = do_QueryInterface(aRoot);
+  NS_ENSURE_TRUE(root, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
+
+  nsTreeWalker* walker = new nsTreeWalker(root,
+                                          aWhatToShow,
+                                          aFilter,
+                                          aEntityReferenceExpansion);
+  NS_ENSURE_TRUE(walker, NS_ERROR_OUT_OF_MEMORY);
+
+  NS_ADDREF(*_retval = walker);
+
+  return NS_OK;
 }
 
 
 NS_IMETHODIMP
 nsDocument::GetDefaultView(nsIDOMAbstractView** aDefaultView)
 {
   nsPIDOMWindow* win = GetWindow();
   if (win) {
--- a/content/base/src/nsTreeWalker.cpp
+++ b/content/base/src/nsTreeWalker.cpp
@@ -46,57 +46,29 @@
 #include "nsIDOMNode.h"
 #include "nsIDOMNodeFilter.h"
 #include "nsDOMError.h"
 
 #include "nsIContent.h"
 #include "nsIDocument.h"
 
 #include "nsContentUtils.h"
-#include "nsMemory.h"
-#include "nsCOMArray.h"
-#include "nsGkAtoms.h"
 
 /*
  * Factories, constructors and destructors
  */
 
-nsresult
-NS_NewTreeWalker(nsIDOMNode *aRoot,
-                 PRUint32 aWhatToShow,
-                 nsIDOMNodeFilter *aFilter,
-                 PRBool aEntityReferenceExpansion,
-                 nsIDOMTreeWalker **aInstancePtrResult)
-{
-    NS_ENSURE_ARG_POINTER(aInstancePtrResult);
-
-    nsCOMPtr<nsINode> root = do_QueryInterface(aRoot);
-    NS_ENSURE_TRUE(root, NS_ERROR_DOM_NOT_SUPPORTED_ERR);
-
-    nsTreeWalker* walker = new nsTreeWalker(root,
-                                            aWhatToShow,
-                                            aFilter,
-                                            aEntityReferenceExpansion);
-    NS_ENSURE_TRUE(walker, NS_ERROR_OUT_OF_MEMORY);
-
-    return CallQueryInterface(walker, aInstancePtrResult);
-}
-
 nsTreeWalker::nsTreeWalker(nsINode *aRoot,
                            PRUint32 aWhatToShow,
                            nsIDOMNodeFilter *aFilter,
                            PRBool aExpandEntityReferences) :
-    mRoot(aRoot),
-    mWhatToShow(aWhatToShow),
-    mFilter(aFilter),
-    mExpandEntityReferences(aExpandEntityReferences),
+    nsTraversal(aRoot, aWhatToShow, aFilter, aExpandEntityReferences),
     mCurrentNode(aRoot),
     mPossibleIndexesPos(-1)
 {
-    NS_ASSERTION(aRoot, "invalid root in call to nsTreeWalker constructor");
 }
 
 nsTreeWalker::~nsTreeWalker()
 {
     /* destructor code */
 }
 
 /*
@@ -568,73 +540,16 @@ nsTreeWalker::ChildOf(nsINode* aNode,
         }
     }
 
     *_retval = nsnull;
     return NS_OK;
 }
 
 /*
- * Tests if and how a node should be filtered. Uses mWhatToShow and
- * mFilter to test the node.
- * @param aNode     Node to test
- * @param _filtered Returned filtervalue. See nsIDOMNodeFilter.idl
- * @returns         Errorcode
- */
-nsresult nsTreeWalker::TestNode(nsINode* aNode, PRInt16* _filtered)
-{
-    nsresult rv;
-
-    *_filtered = nsIDOMNodeFilter::FILTER_SKIP;
-
-    PRUint16 nodeType = 0;
-    // Check the most common cases
-    if (aNode->IsNodeOfType(nsINode::eELEMENT)) {
-        nodeType = nsIDOMNode::ELEMENT_NODE;
-    }
-    else if (aNode->IsNodeOfType(nsINode::eCONTENT)) {
-        nsIAtom* tag = static_cast<nsIContent*>(aNode)->Tag();
-        if (tag == nsGkAtoms::textTagName) {
-            nodeType = nsIDOMNode::TEXT_NODE;
-        }
-        else if (tag == nsGkAtoms::cdataTagName) {
-            nodeType = nsIDOMNode::CDATA_SECTION_NODE;
-        }
-        else if (tag == nsGkAtoms::commentTagName) {
-            nodeType = nsIDOMNode::COMMENT_NODE;
-        }
-        else if (tag == nsGkAtoms::processingInstructionTagName) {
-            nodeType = nsIDOMNode::PROCESSING_INSTRUCTION_NODE;
-        }
-    }
-
-    nsCOMPtr<nsIDOMNode> domNode;
-    if (!nodeType) {
-        domNode = do_QueryInterface(aNode);
-        rv = domNode->GetNodeType(&nodeType);
-        NS_ENSURE_SUCCESS(rv, rv);
-    }
-
-    if (nodeType <= 12 && !((1 << (nodeType-1)) & mWhatToShow)) {
-        return NS_OK;
-    }
-
-    if (mFilter) {
-        if (!domNode) {
-            domNode = do_QueryInterface(aNode);
-        }
-
-        return mFilter->AcceptNode(domNode, _filtered);
-    }
-
-    *_filtered = nsIDOMNodeFilter::FILTER_ACCEPT;
-    return NS_OK;
-}
-
-/*
  * Gets the child index of a node within it's parent. Gets a possible index
  * from mPossibleIndexes to gain speed. If the value in mPossibleIndexes
  * isn't correct it'll get the index the usual way
  * @param aParent   in which to get the index
  * @param aChild    node to get the index of
  * @param aIndexPos position in mPossibleIndexes that contains the possible.
  *                  index
  * @returns         resulting index
--- a/content/base/src/nsTreeWalker.h
+++ b/content/base/src/nsTreeWalker.h
@@ -40,44 +40,40 @@
 /*
  * Implementation of DOM Traversal's nsIDOMTreeWalker
  */
 
 #ifndef nsTreeWalker_h___
 #define nsTreeWalker_h___
 
 #include "nsIDOMTreeWalker.h"
+#include "nsTraversal.h"
 #include "nsCOMPtr.h"
 #include "nsVoidArray.h"
-#include "nsJSUtils.h"
 #include "nsCycleCollectionParticipant.h"
 
 class nsINode;
 class nsIDOMNode;
 class nsIDOMNodeFilter;
 
-class nsTreeWalker : public nsIDOMTreeWalker
+class nsTreeWalker : public nsIDOMTreeWalker, public nsTraversal
 {
 public:
     NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     NS_DECL_NSIDOMTREEWALKER
 
     nsTreeWalker(nsINode *aRoot,
                  PRUint32 aWhatToShow,
                  nsIDOMNodeFilter *aFilter,
                  PRBool aExpandEntityReferences);
     virtual ~nsTreeWalker();
 
     NS_DECL_CYCLE_COLLECTION_CLASS(nsTreeWalker)
 
 private:
-    nsCOMPtr<nsINode> mRoot;
-    PRUint32 mWhatToShow;
-    nsCOMPtr<nsIDOMNodeFilter> mFilter;
-    PRBool mExpandEntityReferences;
     nsCOMPtr<nsINode> mCurrentNode;
     
     /*
      * Array with all child indexes up the tree. This should only be
      * considered a hint and the value could be wrong.
      * The array contains casted PRInt32's
      */
     nsAutoVoidArray mPossibleIndexes;
@@ -146,25 +142,16 @@ private:
      */
     nsresult ChildOf(nsINode* aNode,
                      PRInt32 childNum,
                      PRBool aReversed,
                      PRInt32 aIndexPos,
                      nsINode** _retval);
 
     /*
-     * Tests if and how a node should be filtered. Uses mWhatToShow and
-     * mFilter to test the node.
-     * @param aNode     Node to test
-     * @param _filtered Returned filtervalue. See nsIDOMNodeFilter.idl
-     * @returns         Errorcode
-     */
-    nsresult TestNode(nsINode* aNode, PRInt16* _filtered);
-    
-    /*
      * Gets the child index of a node within it's parent. Gets a possible index
      * from mPossibleIndexes to gain speed. If the value in mPossibleIndexes
      * isn't correct it'll get the index the usual way.
      * @param aParent   in which to get the index
      * @param aChild    node to get the index of
      * @param aIndexPos position in mPossibleIndexes that contains the possible.
      *                  index
      * @returns         resulting index
@@ -182,17 +169,10 @@ private:
     void SetChildIndex(PRInt32 aIndexPos, PRInt32 aChildIndex)
     {
         if (aIndexPos != -1)
             mPossibleIndexes.ReplaceElementAt(NS_INT32_TO_PTR(aChildIndex),
                                               aIndexPos);
     }
 };
 
-// Make a new nsIDOMTreeWalker object
-nsresult NS_NewTreeWalker(nsIDOMNode *aRoot,
-                          PRUint32 aWhatToShow,
-                          nsIDOMNodeFilter *aFilter,
-                          PRBool aEntityReferenceExpansion,
-                          nsIDOMTreeWalker **aInstancePtrResult);
-
 #endif
 
--- a/dom/public/idl/traversal/nsIDOMNodeIterator.idl
+++ b/dom/public/idl/traversal/nsIDOMNodeIterator.idl
@@ -51,9 +51,13 @@ interface nsIDOMNodeIterator : nsISuppor
   readonly attribute unsigned long    whatToShow;
   readonly attribute nsIDOMNodeFilter filter;
   readonly attribute boolean          expandEntityReferences;
   nsIDOMNode         nextNode()
                                         raises(DOMException);
   nsIDOMNode         previousNode()
                                         raises(DOMException);
   void               detach();
+
+  // WebKit extensions, convenient for debugging.
+  readonly attribute nsIDOMNode referenceNode;
+  readonly attribute boolean    pointerBeforeReferenceNode;
 };
--- a/dom/public/nsDOMClassInfoID.h
+++ b/dom/public/nsDOMClassInfoID.h
@@ -432,16 +432,19 @@ enum nsDOMClassInfoID {
 #if defined(MOZ_MEDIA)
   eDOMClassInfo_HTMLVideoElement_id,
   eDOMClassInfo_HTMLSourceElement_id,
   eDOMClassInfo_ProgressEvent_id,
   eDOMClassInfo_HTMLMediaError_id,
   eDOMClassInfo_HTMLAudioElement_id,
 #endif
 
+  // DOM Traversal NodeIterator class
+  eDOMClassInfo_NodeIterator_id,
+
   // This one better be the last one in this list
   eDOMClassInfoIDCount
 };
 
 /**
  * nsIClassInfo helper macros
  */
 
--- a/dom/src/base/nsDOMClassInfo.cpp
+++ b/dom/src/base/nsDOMClassInfo.cpp
@@ -328,16 +328,17 @@
 #include "nsIDOMCSSMozDocumentRule.h"
 #include "nsIDOMCSSPrimitiveValue.h"
 #include "nsIDOMCSSStyleRule.h"
 #include "nsIDOMCSSStyleSheet.h"
 #include "nsIDOMCSSValueList.h"
 #include "nsIDOMRange.h"
 #include "nsIDOMNSRange.h"
 #include "nsIDOMRangeException.h"
+#include "nsIDOMNodeIterator.h"
 #include "nsIDOMTreeWalker.h"
 #include "nsIDOMXULDocument.h"
 #include "nsIDOMXULElement.h"
 #include "nsIDOMXULCommandDispatcher.h"
 #include "nsIDOMCrypto.h"
 #include "nsIDOMCRMFObject.h"
 #include "nsIDOMPkcs11.h"
 #include "nsIControllers.h"
@@ -1259,16 +1260,20 @@ static nsDOMClassInfoData sClassInfoData
                            ELEMENT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(ProgressEvent, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLMediaError, nsDOMGenericSH,
                            DOM_DEFAULT_SCRIPTABLE_FLAGS)
   NS_DEFINE_CLASSINFO_DATA(HTMLAudioElement, nsHTMLElementSH,
                            ELEMENT_SCRIPTABLE_FLAGS)
 #endif
+
+  // DOM Traversal NodeIterator class  
+  NS_DEFINE_CLASSINFO_DATA(NodeIterator, nsDOMGenericSH,
+                           DOM_DEFAULT_SCRIPTABLE_FLAGS)
 };
 
 // Objects that shuld be constructable through |new Name();|
 struct nsContractIDMapData
 {
   PRInt32 mDOMClassInfoID;
   const char *mContractID;
 };
@@ -2507,16 +2512,20 @@ nsDOMClassInfo::Init()
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSRGBAColor)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Range, nsIDOMRange)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMRange)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMNSRange)
   DOM_CLASSINFO_MAP_END
 
+  DOM_CLASSINFO_MAP_BEGIN(NodeIterator, nsIDOMNodeIterator)
+    DOM_CLASSINFO_MAP_ENTRY(nsIDOMNodeIterator)
+  DOM_CLASSINFO_MAP_END
+
   DOM_CLASSINFO_MAP_BEGIN(TreeWalker, nsIDOMTreeWalker)
     DOM_CLASSINFO_MAP_ENTRY(nsIDOMTreeWalker)
   DOM_CLASSINFO_MAP_END
 
   DOM_CLASSINFO_MAP_BEGIN(Selection, nsISelection)
     DOM_CLASSINFO_MAP_ENTRY(nsISelection)
   DOM_CLASSINFO_MAP_END