Back to index

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

List of all members.

Public Member Functions

 nsFindContentIterator (PRBool aFindBackward)
virtual ~nsFindContentIterator ()
virtual NS_DECL_ISUPPORTS 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.

Private Member Functions

void Reset ()
void MaybeSetupInnerIterator ()
void SetupInnerIterator (nsIContent *aContent)

Private Attributes

nsCOMPtr< nsIContentIteratormOuterIterator
nsCOMPtr< nsIContentIteratormInnerIterator
nsCOMPtr< nsIDOMRangemRange
nsCOMPtr< nsIDOMNodemStartOuterNode
nsCOMPtr< nsIDOMNodemEndOuterNode
PRBool mFindBackward

Detailed Description

Definition at line 104 of file nsFind.cpp.


Constructor & Destructor Documentation

virtual nsFindContentIterator::~nsFindContentIterator ( ) [inline, virtual]

Definition at line 117 of file nsFind.cpp.

  {
  }

Member Function Documentation

First will reset the list.

Implements nsIContentIterator.

Definition at line 178 of file nsFind.cpp.

{
  Reset();
}

Here is the call graph for this function:

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

Returns:
the current node

Implements nsIContentIterator.

Definition at line 222 of file nsFind.cpp.

{
  if (mInnerIterator && !mInnerIterator->IsDone()) {
    return mInnerIterator->GetCurrentNode();
  }
  return mOuterIterator->GetCurrentNode();
}
virtual NS_DECL_ISUPPORTS nsresult nsFindContentIterator::Init ( nsIContent aRoot) [inline, virtual]

Implements nsIContentIterator.

Definition at line 125 of file nsFind.cpp.

  {
    NS_NOTREACHED("internal error");
    return NS_ERROR_NOT_IMPLEMENTED;
  }

Implements nsIContentIterator.

Definition at line 155 of file nsFind.cpp.

{
  if (!mOuterIterator) {
    if (mFindBackward) {
      // Use post-order in the reverse case, so we get parents
      // before children in case we want to prevent descending
      // into a node.
      mOuterIterator = do_CreateInstance(kCContentIteratorCID);
    }
    else {
      // Use pre-order in the forward case, so we get parents
      // before children in case we want to prevent descending
      // into a node.
      mOuterIterator = do_CreateInstance(kCPreContentIteratorCID);
    }
    NS_ENSURE_ARG_POINTER(mOuterIterator);
  }

  // mRange is the search range that we will examine
  return aRange->CloneRange(getter_AddRefs(mRange));
}

Here is the call graph for this function:

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 231 of file nsFind.cpp.

                              {
  if (mInnerIterator && !mInnerIterator->IsDone()) {
    return PR_FALSE;
  }
  return mOuterIterator->IsDone();
}

Last will reset the list to the end.

Implements nsIContentIterator.

Definition at line 184 of file nsFind.cpp.

{
  Reset();
}

Here is the call graph for this function:

Definition at line 315 of file nsFind.cpp.

{
  mInnerIterator = nsnull;

  nsIContent* content = mOuterIterator->GetCurrentNode();
  if (!content || !content->IsContentOfType(nsIContent::eHTML_FORM_CONTROL))
    return;

  nsCOMPtr<nsIFormControl> formControl(do_QueryInterface(content));
  PRInt32 controlType = formControl->GetType();
  if (controlType != NS_FORM_TEXTAREA && 
      controlType != NS_FORM_INPUT_TEXT)
    return;

  SetupInnerIterator(content);
  if (mInnerIterator) {
    if (!mFindBackward) {
      mInnerIterator->First();
      // finish setup: position mOuterIterator on the actual "next"
      // node (this completes its re-init, @see SetupInnerIterator)
      mOuterIterator->First();
    }
    else {
      mInnerIterator->Last();
      // finish setup: position mOuterIterator on the actual "previous"
      // node (this completes its re-init, @see SetupInnerIterator)
      mOuterIterator->Last();
    }
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Next will advance the list.

Implements nsIContentIterator.

Definition at line 190 of file nsFind.cpp.

{
  if (mInnerIterator) {
    mInnerIterator->Next();
    if (!mInnerIterator->IsDone())
      return;

    // by construction, mOuterIterator is already on the next node
  }
  else {
    mOuterIterator->Next();
  }
  MaybeSetupInnerIterator();  
}

Here is the call graph for this function:

PositionAt will position the iterator to the supplied node.

Implements nsIContentIterator.

Definition at line 239 of file nsFind.cpp.

{
  nsIContent* oldNode = mOuterIterator->GetCurrentNode();
  nsresult rv = mOuterIterator->PositionAt(aCurNode);
  if (NS_SUCCEEDED(rv)) {
    MaybeSetupInnerIterator();
  }
  else {
    mOuterIterator->PositionAt(oldNode);
    if (mInnerIterator)
      rv = mInnerIterator->PositionAt(aCurNode);
  }
  return rv;
}

Here is the call graph for this function:

Prev will decrement the list.

Implements nsIContentIterator.

Definition at line 206 of file nsFind.cpp.

{
  if (mInnerIterator) {
    mInnerIterator->Prev();
    if (!mInnerIterator->IsDone())
      return;

    // by construction, mOuterIterator is already on the previous node
  }
  else {
    mOuterIterator->Prev();
  }
  MaybeSetupInnerIterator();
}

Here is the call graph for this function:

Definition at line 255 of file nsFind.cpp.

{
  mInnerIterator = nsnull;
  mStartOuterNode = nsnull;
  mEndOuterNode = nsnull;

  // As a consequence of searching through text controls, we may have been
  // initialized with a selection inside a <textarea> or a text <input>.

  // see if the start node is an anonymous text node inside a text control
  nsCOMPtr<nsIDOMNode> startNode;
  mRange->GetStartContainer(getter_AddRefs(startNode));
  nsCOMPtr<nsIContent> startContent(do_QueryInterface(startNode));
  for ( ; startContent; startContent = startContent->GetParent()) {
    if (!startContent->IsNativeAnonymous()) {
      mStartOuterNode = do_QueryInterface(startContent);
      break;
    }
  }

  // see if the end node is an anonymous text node inside a text control
  nsCOMPtr<nsIDOMNode> endNode;
  mRange->GetEndContainer(getter_AddRefs(endNode));
  nsCOMPtr<nsIContent> endContent(do_QueryInterface(endNode));
  for ( ; endContent; endContent = endContent->GetParent()) {
    if (!endContent->IsNativeAnonymous()) {
      mEndOuterNode = do_QueryInterface(endContent);
      break;
    }
  }

  mOuterIterator->Init(mRange);

  if (!mFindBackward) {
    if (mStartOuterNode != startNode) {
      // the start node was an anonymous text node
      SetupInnerIterator(startContent);
      if (mInnerIterator)
        mInnerIterator->First();
    }
    mOuterIterator->First();
  }
  else {
    if (mEndOuterNode != endNode) {
      // the end node was an anonymous text node
      SetupInnerIterator(endContent);
      if (mInnerIterator)
        mInnerIterator->Last();
    }
    mOuterIterator->Last();
  }

  // if we didn't create an inner-iterator, the boundary node could still be
  // a text control, in which case we also need an inner-iterator straightaway
  if (!mInnerIterator) {
    MaybeSetupInnerIterator();
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 347 of file nsFind.cpp.

{
  NS_ASSERTION(aContent && !aContent->IsNativeAnonymous(), "invalid call");

  nsIDocument* doc = aContent->GetDocument();
  nsIPresShell* shell = doc ? doc->GetShellAt(0) : nsnull;
  if (!shell)
    return;

  nsIFrame* frame = nsnull;
  shell->GetPrimaryFrameFor(aContent, &frame);
  if (!frame)
    return;

  nsITextControlFrame* tcFrame = nsnull;
  CallQueryInterface(frame, &tcFrame);
  if (!tcFrame)
    return;

  nsCOMPtr<nsIEditor> editor;
  tcFrame->GetEditor(getter_AddRefs(editor));
  if (!editor)
    return;

  // don't mess with disabled input fields
  PRUint32 editorFlags = 0;
  editor->GetFlags(&editorFlags);
  if (editorFlags & nsIPlaintextEditor::eEditorDisabledMask)
    return;

  nsCOMPtr<nsIDOMElement> rootElement;
  editor->GetRootElement(getter_AddRefs(rootElement));
  nsCOMPtr<nsIContent> rootContent(do_QueryInterface(rootElement));

  // now create the inner-iterator
  mInnerIterator = do_CreateInstance(kCPreContentIteratorCID);

  if (mInnerIterator) {
    nsCOMPtr<nsIDOMNode> node(do_QueryInterface(rootContent));
    nsCOMPtr<nsIDOMRange> range(do_CreateInstance(kRangeCID));
    range->SelectNodeContents(node);

    // fix up the inner bounds, we may have to only lookup a portion
    // of the text control if the current node is a boundary point
    PRInt32 offset;
    nsCOMPtr<nsIDOMNode> outerNode(do_QueryInterface(aContent));
    if (outerNode == mStartOuterNode) {
      mRange->GetStartOffset(&offset);
      mRange->GetStartContainer(getter_AddRefs(node));
      range->SetStart(node, offset);
    }
    if (outerNode == mEndOuterNode) {
      mRange->GetEndOffset(&offset);
      mRange->GetEndContainer(getter_AddRefs(node));
      range->SetEnd(node, offset);
    }
    // Note: we just init here. We do First() or Last() later. 
    mInnerIterator->Init(range);

    // make sure to place the outer-iterator outside
    // the text control so that we don't go there again.
    nsresult res;
    mRange->CloneRange(getter_AddRefs(range));
    if (!mFindBackward) { // find forward
      // cut the outer-iterator after the current node
      res = range->SetStartAfter(outerNode);
    }
    else { // find backward
      // cut the outer-iterator before the current node
      res = range->SetEndBefore(outerNode);
    }
    if (NS_FAILED(res)) {
      // we are done with the outer-iterator, the 
      // inner-iterator will traverse what we want
      range->Collapse(PR_TRUE);
    }
    // Note: we just re-init here, using the segment of mRange that is
    // yet to be visited. Thus when we later do mOuterIterator->First() 
    // [or mOuterIterator->Last()], we will effectively be on the next
    // node [or the previous node] _with respect to_ mRange. 
    mOuterIterator->Init(range);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 144 of file nsFind.cpp.

Definition at line 145 of file nsFind.cpp.

Definition at line 141 of file nsFind.cpp.

Definition at line 140 of file nsFind.cpp.

Definition at line 142 of file nsFind.cpp.

Definition at line 143 of file nsFind.cpp.


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