Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Protected Member Functions | Protected Attributes
nsPreContentIterator Class Reference
Inheritance diagram for nsPreContentIterator:
Inheritance graph
[legend]
Collaboration diagram for nsPreContentIterator:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsPreContentIterator ()
virtual nsresult Init (nsIContent *aRoot)
virtual nsresult Init (nsIDOMRange *aRange)
virtual void First ()
 First will reset the list.
virtual void Last ()
 Last will reset the list to the end.
virtual void Next ()
 Next will advance the list.
virtual void Prev ()
 Prev will decrement the list.
virtual nsIContentGetCurrentNode ()
 CurrentItem will return the current item, or null if the list is empty.
virtual PRBool IsDone ()
 return if the collection is at the end.
virtual nsresult PositionAt (nsIContent *aCurNode)
 PositionAt will position the iterator to the supplied node.

Protected Member Functions

nsIContentGetDeepFirstChild (nsIContent *aRoot, nsVoidArray *aIndexes)
nsIContentGetDeepLastChild (nsIContent *aRoot, nsVoidArray *aIndexes)
nsIContentGetNextSibling (nsIContent *aNode, nsVoidArray *aIndexes)
nsIContentGetPrevSibling (nsIContent *aNode, nsVoidArray *aIndexes)
nsIContentNextNode (nsIContent *aNode, nsVoidArray *aIndexes)
nsIContentPrevNode (nsIContent *aNode, nsVoidArray *aIndexes)
nsresult RebuildIndexStack ()
void MakeEmpty ()

Protected Attributes

nsCOMPtr< nsIContentmCurNode
nsCOMPtr< nsIContentmFirst
nsCOMPtr< nsIContentmLast
nsCOMPtr< nsIContentmCommonParent
nsAutoVoidArray mIndexes
PRInt32 mCachedIndex
PRBool mIsDone
PRBool mPre

Detailed Description

Definition at line 287 of file nsContentIterator.cpp.


Constructor & Destructor Documentation

Definition at line 290 of file nsContentIterator.cpp.

{ mPre = PR_TRUE; }

Member Function Documentation

void nsContentIterator::First ( ) [virtual, inherited]

First will reset the list.

Implements nsIContentIterator.

Reimplemented in nsContentSubtreeIterator.

Definition at line 963 of file nsContentIterator.cpp.

{
  NS_ASSERTION(mFirst, "No first node!");

  if (mFirst) {
#ifdef DEBUG
    nsresult rv =
#endif
    PositionAt(mFirst);

    NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to position iterator!");
  }

  mIsDone = mFirst == nsnull;
}

Here is the call graph for this function:

nsIContent * nsContentIterator::GetCurrentNode ( ) [virtual, inherited]

CurrentItem will return the current item, or null if the list is empty.

Returns:
the current node

Implements nsIContentIterator.

Definition at line 1185 of file nsContentIterator.cpp.

{
  if (mIsDone) {
    return nsnull;
  }

  NS_ASSERTION(mCurNode, "Null current node in an iterator that's not done!");

  return mCurNode;
}
nsIContent * nsContentIterator::GetDeepFirstChild ( nsIContent aRoot,
nsVoidArray aIndexes 
) [protected, inherited]

Definition at line 615 of file nsContentIterator.cpp.

{
  if (!aRoot) {
    return nsnull;
  }

  nsIContent *cN = aRoot;
  nsIContent *cChild = cN->GetChildAt(0);

  while (cChild)
  {
    if (aIndexes)
    {
      // Add this node to the stack of indexes
      aIndexes->AppendElement(NS_INT32_TO_PTR(0));
    }
    cN = cChild;
    cChild = cN->GetChildAt(0);
  }

  return cN;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsIContent * nsContentIterator::GetDeepLastChild ( nsIContent aRoot,
nsVoidArray aIndexes 
) [protected, inherited]

Definition at line 639 of file nsContentIterator.cpp.

{
  if (!aRoot) {
    return nsnull;
  }

  nsIContent *deepLastChild = aRoot;

  nsIContent *cN = aRoot;
  PRInt32 numChildren = cN->GetChildCount();

  while (numChildren)
  {
    nsIContent *cChild = cN->GetChildAt(--numChildren);

    if (aIndexes)
    {
      // Add this node to the stack of indexes
      aIndexes->AppendElement(NS_INT32_TO_PTR(numChildren));
    }
    numChildren = cChild->GetChildCount();
    cN = cChild;

    deepLastChild = cN;
  }

  return deepLastChild;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsIContent * nsContentIterator::GetNextSibling ( nsIContent aNode,
nsVoidArray aIndexes 
) [protected, inherited]

Definition at line 670 of file nsContentIterator.cpp.

{
  if (!aNode) 
    return nsnull;

  nsIContent *parent = aNode->GetParent();
  if (!parent)
    return nsnull;

  PRInt32 indx;

  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.
  nsIContent *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)))
  {
    // update index cache
    if (aIndexes)
    {
      aIndexes->ReplaceElementAt(NS_INT32_TO_PTR(indx),aIndexes->Count()-1);
    }
    else mCachedIndex = indx;
  }
  else
  {
    if (parent != mCommonParent)
    {
      if (aIndexes)
      {
        // pop node off the stack, go up one level and return parent or fail.
        // Don't leave the index empty, especially if we're
        // returning NULL.  This confuses other parts of the code.
        if (aIndexes->Count() > 1)
          aIndexes->RemoveElementAt(aIndexes->Count()-1);
      }
    }

    // ok to leave cache out of date here if parent == mCommonParent?
    sib = GetNextSibling(parent, aIndexes);
  }
  
  return sib;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsIContent * nsContentIterator::GetPrevSibling ( nsIContent aNode,
nsVoidArray aIndexes 
) [protected, inherited]

Definition at line 734 of file nsContentIterator.cpp.

{
  if (!aNode)
    return nsnull;

  nsIContent *parent = aNode->GetParent();
  if (!parent)
    return nsnull;

  PRInt32 indx;

  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
  // ignore result this time - the index may now be out of range.
  nsIContent *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)))
  {
    // update index cache
    if (aIndexes)
    {
      aIndexes->ReplaceElementAt(NS_INT32_TO_PTR(indx),aIndexes->Count()-1);
    }
    else mCachedIndex = indx;
  }
  else if (parent != mCommonParent)
  {
    if (aIndexes)
    {
      // pop node off the stack, go up one level and try again.
      aIndexes->RemoveElementAt(aIndexes->Count()-1);
    }
    return GetPrevSibling(parent, aIndexes);
  }

  return sib;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsContentIterator::Init ( nsIContent aRoot) [virtual, inherited]

Implements nsIContentIterator.

Reimplemented in nsContentSubtreeIterator.

Definition at line 354 of file nsContentIterator.cpp.

{
  if (!aRoot) 
    return NS_ERROR_NULL_POINTER; 
  mIsDone = PR_FALSE;
  mIndexes.Clear();
  
  if (mPre)
  {
    mFirst = aRoot;
    mLast  = GetDeepLastChild(aRoot, nsnull);
  }
  else
  {
    mFirst = GetDeepFirstChild(aRoot, nsnull); 
    mLast  = aRoot;
  }

  mCommonParent = aRoot;
  mCurNode = mFirst;
  RebuildIndexStack();
  return NS_OK;
}

Here is the call graph for this function:

nsresult nsContentIterator::Init ( nsIDOMRange aRange) [virtual, inherited]

Implements nsIContentIterator.

Reimplemented in nsContentSubtreeIterator.

Definition at line 380 of file nsContentIterator.cpp.

{
  if (!aRange) 
    return NS_ERROR_NULL_POINTER; 

  nsCOMPtr<nsIDOMNode> dN;

  nsCOMPtr<nsIContent> startCon;
  nsCOMPtr<nsIDOMNode> startDOM;
  nsCOMPtr<nsIContent> endCon;
  nsCOMPtr<nsIDOMNode> endDOM;
  PRInt32 startIndx;
  PRInt32 endIndx;
  
  mIsDone = PR_FALSE;

  // get common content parent
  if (NS_FAILED(aRange->GetCommonAncestorContainer(getter_AddRefs(dN))) || !dN)
    return NS_ERROR_FAILURE;
  mCommonParent = do_QueryInterface(dN);

  // get the start node and offset, convert to nsIContent
  aRange->GetStartContainer(getter_AddRefs(startDOM));
  if (!startDOM) 
    return NS_ERROR_ILLEGAL_VALUE;
  startCon = do_QueryInterface(startDOM);
  if (!startCon) 
    return NS_ERROR_FAILURE;
  
  aRange->GetStartOffset(&startIndx);
  
  // get the end node and offset, convert to nsIContent
  aRange->GetEndContainer(getter_AddRefs(endDOM));
  if (!endDOM) 
    return NS_ERROR_ILLEGAL_VALUE;
  endCon = do_QueryInterface(endDOM);
  if (!endCon) 
    return NS_ERROR_FAILURE;

  aRange->GetEndOffset(&endIndx);
  
  nsCOMPtr<nsIDOMCharacterData> cData(do_QueryInterface(startCon));

  // short circuit when start node == end node
  if (startDOM == endDOM)
  {
    // Check to see if we have a collapsed range, if so,
    // there is nothing to iterate over.
    //
    // XXX: CharacterDataNodes (text nodes) are currently an exception,
    //      since we always want to be able to iterate text nodes at
    //      the end points of a range.

    if (!cData && startIndx == endIndx)
    {
      MakeEmpty();
      return NS_OK;
    }

    if (cData)
    {
      // It's a textnode.

      mFirst   = startCon;
      mLast    = startCon;
      mCurNode = startCon;

      RebuildIndexStack();
      return NS_OK;
    }
  }
  
  // Find first node in range.

  nsIContent *cChild = nsnull;

  if (!cData && ContentHasChildren(startCon))
    cChild = startCon->GetChildAt(startIndx);

  if (!cChild) // no children, must be a text node
  {
    if (mPre)
    {
      // XXX: In the future, if start offset is after the last
      //      character in the cdata node, should we set mFirst to
      //      the next sibling?

      if (!cData)
      {
        mFirst = GetNextSibling(startCon, 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, startDOM, startIndx, endDOM, endIndx))
          mFirst = nsnull;
      }
      else
        mFirst = startCon;
    }
    else // post-order
      mFirst = startCon;
  }
  else
  {
    if (mPre)
      mFirst = cChild;
    else // post-order
    {
      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, startDOM, startIndx, endDOM, endIndx))
        mFirst = nsnull;
    }
  }


  // Find last node in range.

  cData = do_QueryInterface(endCon);

  if (cData || !ContentHasChildren(endCon) || endIndx == 0)
  {
    if (mPre)
      mLast = endCon;
    else // post-order
    {
      // 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 (!cData)
      {
        mLast = GetPrevSibling(endCon, nsnull);

        if (!ContentIsInTraversalRange(mLast, mPre, startDOM, startIndx, endDOM, endIndx))
          mLast = nsnull;
      }
      else
        mLast = endCon;
    }
  }
  else
  {
    PRInt32 indx = endIndx;

    cChild = endCon->GetChildAt(--indx);

    if (!cChild)  // No child at offset!
    {
      NS_NOTREACHED("nsContentIterator::nsContentIterator");
      return NS_ERROR_FAILURE; 
    }

    if (mPre)
    {
      mLast  = GetDeepLastChild(cChild, nsnull);

      if (!ContentIsInTraversalRange(mLast, mPre, startDOM, startIndx, endDOM, endIndx))
        mLast = nsnull;
    }
    else // post-order
      mLast = cChild;
  }

  // If either first or last is null, they both
  // have to be null!

  if (!mFirst || !mLast)
  {
    mFirst = nsnull;
    mLast  = nsnull;
  }
  
  mCurNode = mFirst;
  mIsDone  = !mCurNode;

  if (!mCurNode)
    mIndexes.Clear();
  else
    RebuildIndexStack();

  return NS_OK;
}

Here is the call graph for this function:

PRBool nsContentIterator::IsDone ( ) [virtual, inherited]

return if the collection is at the end.

that is the beginning following a call to Prev and it is the end of the list following a call to next

Returns:
if the iterator is done.

Implements nsIContentIterator.

Definition at line 1031 of file nsContentIterator.cpp.

{
  return mIsDone;
}
void nsContentIterator::Last ( ) [virtual, inherited]

Last will reset the list to the end.

Implements nsIContentIterator.

Reimplemented in nsContentSubtreeIterator.

Definition at line 981 of file nsContentIterator.cpp.

{
  NS_ASSERTION(mLast, "No last node!");

  if (mLast) {
#ifdef DEBUG
    nsresult rv =
#endif
    PositionAt(mLast);

    NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to position iterator!");
  }

  mIsDone = mLast == nsnull;
}

Here is the call graph for this function:

void nsContentIterator::MakeEmpty ( ) [protected, inherited]

Definition at line 604 of file nsContentIterator.cpp.

Here is the caller graph for this function:

void nsContentIterator::Next ( ) [virtual, inherited]

Next will advance the list.

Implements nsIContentIterator.

Reimplemented in nsContentSubtreeIterator.

Definition at line 999 of file nsContentIterator.cpp.

{
  if (mIsDone || !mCurNode) 
    return;

  if (mCurNode == mLast) 
  {
    mIsDone = PR_TRUE;
    return;
  }

  mCurNode = NextNode(mCurNode, &mIndexes);
}

Here is the call graph for this function:

nsIContent * nsContentIterator::NextNode ( nsIContent aNode,
nsVoidArray aIndexes 
) [protected, inherited]

Definition at line 788 of file nsContentIterator.cpp.

{
  nsIContent *cN = aNode;
  nsIContent *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 (ContentHasChildren(cN))
    {
      nsIContent *cFirstChild = cN->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;
    }

    // else next sibling is next
    nextNode = GetNextSibling(cN, aIndexes);
  }
  else  // post-order
  {
    nsIContent *parent = cN->GetParent();
    nsIContent *cSibling = 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)
    {
      // someone changed our index - find the new index the painful way
      indx = parent->IndexOf(cN);
    }

    // indx is now canonically correct
    cSibling = parent->GetChildAt(++indx);
    if (cSibling)
    {
      // 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); 
    }
  
    // 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
      // returning NULL.  This confuses other parts of the code.
      if (aIndexes->Count() > 1)
        aIndexes->RemoveElementAt(aIndexes->Count()-1);
    }
    else mCachedIndex = 0;   // this might be wrong, but we are better off guessing
    nextNode = parent;
  }

  return nextNode;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsContentIterator::PositionAt ( nsIContent aCurNode) [virtual, inherited]

PositionAt will position the iterator to the supplied node.

Implements nsIContentIterator.

Reimplemented in nsContentSubtreeIterator.

Definition at line 1040 of file nsContentIterator.cpp.

{
  if (!aCurNode)
    return NS_ERROR_NULL_POINTER;

  nsIContent *newCurNode = aCurNode;
  nsIContent *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.

  nsCOMPtr<nsIDOMNode> firstNode(do_QueryInterface(mFirst));
  nsCOMPtr<nsIDOMNode> lastNode(do_QueryInterface(mLast));
  PRInt32 firstOffset=0, lastOffset=0;

  if (firstNode && lastNode)
  {
    PRUint32 numChildren;

    if (mPre)
    {
      ContentToParentOffset(mFirst, getter_AddRefs(firstNode), &firstOffset);

      numChildren = GetNumChildren(lastNode);

      if (numChildren)
        lastOffset = 0;
      else
      {
        ContentToParentOffset(mLast, getter_AddRefs(lastNode), &lastOffset);
        ++lastOffset;
      }
    }
    else
    {
      numChildren = GetNumChildren(firstNode);

      if (numChildren)
        firstOffset = numChildren;
      else
        ContentToParentOffset(mFirst, getter_AddRefs(firstNode), &firstOffset);

      ContentToParentOffset(mLast, getter_AddRefs(lastNode), &lastOffset);
      ++lastOffset;
    }
  }

  if (!firstNode || !lastNode ||
      !ContentIsInTraversalRange(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;
  nsAutoVoidArray      newIndexes;

  // Get a list of the parents up to the root, then compare the new node
  // with entries in that array until we find a match (lowest common
  // ancestor).  If no match, use IndexOf, take the parent, and repeat.
  // This avoids using IndexOf() N times on possibly large arrays.  We
  // still end up doing it a fair bit.  It's better to use Clone() if
  // possible.

  // we know the depth we're down (though we may not have started at the
  // top).
  if (!oldParentStack.SizeTo(mIndexes.Count()+1))
    return NS_ERROR_FAILURE;

  // We want to loop mIndexes.Count() + 1 times here, because we want to make
  // 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();

    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.
      mIndexes.RemoveElementsAt(mIndexes.Count() - oldParentStack.Count(),
                                oldParentStack.Count());
      mIsDone = PR_FALSE;
      return NS_OK;
    }
    tempNode = parent;
  }

  // Ok.  We have the array of old parents.  Look for a match.
  while (newCurNode)
  {
    nsIContent *parent = newCurNode->GetParent();

    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);

    // look to see if the parent is in the stack
    indx = oldParentStack.IndexOf(parent);
    if (indx >= 0)
    {
      // ok, the parent IS on the old stack!  Rework things.
      // we want newIndexes to replace all nodes equal to or below the match
      // Note that index oldParentStack.Count()-1 is the last node, which is
      // one BELOW the last index in the mIndexes stack.  In other words, we
      // want to remove elements starting at index (indx+1).
      PRInt32 numToDrop = oldParentStack.Count()-(1+indx);
      if (numToDrop > 0)
        mIndexes.RemoveElementsAt(mIndexes.Count() - numToDrop,numToDrop);
      mIndexes.AppendElements(newIndexes);

      break;
    }
    newCurNode = parent;
  }

  // phew!

  mIsDone = PR_FALSE;
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsContentIterator::Prev ( ) [virtual, inherited]

Prev will decrement the list.

Implements nsIContentIterator.

Reimplemented in nsContentSubtreeIterator.

Definition at line 1015 of file nsContentIterator.cpp.

{
  if (mIsDone || !mCurNode) 
    return;

  if (mCurNode == mFirst) 
  {
    mIsDone = PR_TRUE;
    return;
  }

  mCurNode = PrevNode(mCurNode, &mIndexes);
}

Here is the call graph for this function:

nsIContent * nsContentIterator::PrevNode ( nsIContent aNode,
nsVoidArray aIndexes 
) [protected, inherited]

Definition at line 874 of file nsContentIterator.cpp.

{
  nsIContent *prevNode = nsnull;
  nsIContent *cN = aNode;
   
  if (mPre)  // if we are a Pre-order iterator, use pre-order
  {
    nsIContent *parent = cN->GetParent();
    nsIContent *cSibling = 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)
    {
      // someone changed our index - find the new index the painful way
      indx = parent->IndexOf(cN);
    }

    // indx is now canonically correct
    if (indx && (cSibling = 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); 
    }
  
    // 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();
  
    // if it has children then prev node is last child
    if (numChildren)
    {
      nsIContent *cLastChild = cN->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;
    }

    // else prev sibling is previous
    prevNode = GetPrevSibling(cN, aIndexes);
  }

  return prevNode;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsContentIterator::RebuildIndexStack ( ) [protected, inherited]

Definition at line 575 of file nsContentIterator.cpp.

{
  // 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
  // thats far better than too few.
  nsIContent* parent;
  nsIContent* current;

  mIndexes.Clear();
  current = mCurNode;
  if (!current) {
    return NS_OK;
  }

  while (current != mCommonParent)
  {
    parent = current->GetParent();
    
    if (!parent)
      return NS_ERROR_FAILURE;
  
    mIndexes.InsertElementAt(NS_INT32_TO_PTR(parent->IndexOf(current)), 0);

    current = parent;
  }
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

PRInt32 nsContentIterator::mCachedIndex [protected, inherited]

Definition at line 259 of file nsContentIterator.cpp.

Definition at line 249 of file nsContentIterator.cpp.

Definition at line 246 of file nsContentIterator.cpp.

Definition at line 247 of file nsContentIterator.cpp.

nsAutoVoidArray nsContentIterator::mIndexes [protected, inherited]

Definition at line 252 of file nsContentIterator.cpp.

PRBool nsContentIterator::mIsDone [protected, inherited]

Definition at line 271 of file nsContentIterator.cpp.

nsCOMPtr<nsIContent> nsContentIterator::mLast [protected, inherited]

Definition at line 248 of file nsContentIterator.cpp.

PRBool nsContentIterator::mPre [protected, inherited]

Definition at line 272 of file nsContentIterator.cpp.


The documentation for this class was generated from the following file: