Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Static Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes
nsContentList Class Reference

Class that implements a live NodeList that matches nodes in the tree based on some criterion. More...

#include <nsContentList.h>

Inheritance diagram for nsContentList:
Inheritance graph
[legend]
Collaboration diagram for nsContentList:
Collaboration graph
[legend]

List of all members.

Public Member Functions

NS_DECL_ISUPPORTS_INHERITED nsContentList (nsIDocument *aDocument, nsIAtom *aMatchAtom, PRInt32 aMatchNameSpaceId, nsIContent *aRootContent=nsnull, PRBool aDeep=PR_TRUE)
 nsContentList (nsIDocument *aDocument, nsContentListMatchFunc aFunc, const nsAString &aData, nsIContent *aRootContent=nsnull, PRBool aDeep=PR_TRUE, nsIAtom *aMatchAtom=nsnull, PRInt32 aMatchNameSpaceId=kNameSpaceID_None)
virtual ~nsContentList ()
virtual
NS_DECL_NSIDOMHTMLCOLLECTION
PRInt32 
IndexOf (nsIContent *aContent, PRBool aDoFlush)
 NS_HIDDEN_ (nsISupports *) GetParentObject()
 NS_HIDDEN_ (PRUint32) Length(PRBool aDoFlush)
 NS_HIDDEN_ (nsIContent *) Item(PRUint32 aIndex
 NS_HIDDEN_ (nsIContent *) NamedItem(const nsAString &aName
 NS_HIDDEN_ (void) RootDestroyed()
nsContentListKeyGetKey ()
virtual void AttributeChanged (nsIDocument *aDocument, nsIContent *aContent, PRInt32 aNameSpaceID, nsIAtom *aAttribute, PRInt32 aModType)
 Notification that the content model has changed.
virtual void ContentAppended (nsIDocument *aDocument, nsIContent *aContainer, PRInt32 aNewIndexInContainer)
 Notifcation that the content model has had data appended to the given content object.
virtual void ContentInserted (nsIDocument *aDocument, nsIContent *aContainer, nsIContent *aChild, PRInt32 aIndexInContainer)
 Notification that content has been inserted.
virtual void ContentRemoved (nsIDocument *aDocument, nsIContent *aContainer, nsIContent *aChild, PRInt32 aIndexInContainer)
 Content has just been removed.
virtual void DocumentWillBeDestroyed (nsIDocument *aDocument)
 The document is in the process of being destroyed.
NS_DECL_ISUPPORTS virtual
NS_DECL_NSIDOMNODELIST void 
AppendElement (nsIContent *aContent)
virtual void RemoveElement (nsIContent *aContent)
virtual void Reset ()
nsIDOMNode item (in unsigned long index)
nsIDOMNode item (in unsigned long index)
nsIDOMNode namedItem (in DOMString name)
virtual void BeginUpdate (nsIDocument *aDocument, nsUpdateType aUpdateType)=0
 Notify that a content model update is beginning.
virtual void EndUpdate (nsIDocument *aDocument, nsUpdateType aUpdateType)=0
 Notify that a content model update is finished.
virtual void BeginLoad (nsIDocument *aDocument)=0
 Notify the observer that a document load is beginning.
virtual void EndLoad (nsIDocument *aDocument)=0
 Notify the observer that a document load has finished.
virtual void BeginReflow (nsIDocument *aDocument, nsIPresShell *aShell)=0
 Notify the observer that the document is being reflowed in the given presentation shell.
virtual void EndReflow (nsIDocument *aDocument, nsIPresShell *aShell)=0
 Notify the observer that the document is done being reflowed in the given presentation shell.
virtual void CharacterDataChanged (nsIDocument *aDocument, nsIContent *aContent, PRBool aAppend)=0
 Notification that the content model has changed.
virtual void ContentStatesChanged (nsIDocument *aDocument, nsIContent *aContent1, nsIContent *aContent2, PRInt32 aStateMask)=0
 Notification that the state of a content node has changed.
virtual void StyleSheetAdded (nsIDocument *aDocument, nsIStyleSheet *aStyleSheet, PRBool aDocumentSheet)=0
 A StyleSheet has just been added to the document.
virtual void StyleSheetRemoved (nsIDocument *aDocument, nsIStyleSheet *aStyleSheet, PRBool aDocumentSheet)=0
 A StyleSheet has just been removed from the document.
virtual void StyleSheetApplicableStateChanged (nsIDocument *aDocument, nsIStyleSheet *aStyleSheet, PRBool aApplicable)=0
 A StyleSheet has just changed its applicable state.
virtual void StyleRuleChanged (nsIDocument *aDocument, nsIStyleSheet *aStyleSheet, nsIStyleRule *aOldStyleRule, nsIStyleRule *aNewStyleRule)=0
 A StyleRule has just been modified within a style sheet.
virtual void StyleRuleAdded (nsIDocument *aDocument, nsIStyleSheet *aStyleSheet, nsIStyleRule *aStyleRule)=0
 A StyleRule has just been added to a style sheet.
virtual void StyleRuleRemoved (nsIDocument *aDocument, nsIStyleSheet *aStyleSheet, nsIStyleRule *aStyleRule)=0
 A StyleRule has just been removed from a style sheet.

Static Public Member Functions

static void OnDocumentDestroy (nsIDocument *aDocument)
static void Shutdown ()

Public Attributes

PRBool aDoFlush
readonly attribute unsigned long length
readonly attribute unsigned long length

Protected Member Functions

void Init (nsIDocument *aDocument)
PRBool Match (nsIContent *aContent)
 Returns whether the content element matches our criterion.
PRBool MatchSelf (nsIContent *aContent)
 Match recursively.
void PopulateWith (nsIContent *aContent, PRBool aIncludeRoot, PRUint32 &aElementsToAppend)
 Add elements in the subtree rooted in aContent that match our criterion to our list until we've picked up aElementsToAppend elements.
void PopulateWithStartingAfter (nsIContent *aStartRoot, nsIContent *aStartChild, PRUint32 &aElementsToAppend)
 Populate our list starting at the child of aStartRoot that comes after aStartChild (if such exists) and continuing in document order.
void PopulateSelf (PRUint32 aNeededLength)
 Populate our list.
void DisconnectFromDocument ()
 Our root content has been disconnected from the document, so stop observing.
PRBool MayContainRelevantNodes (nsIContent *aContainer)
PRBool ContainsRoot (nsIContent *aContent)
 Does this subtree contain our mRootContent?
void CheckDocumentExistence ()
 If we have no document and we have a root content, then check if our content has been added to a document.
void RemoveFromHashtable ()
 Remove ourselves from the hashtable that caches commonly accessed content lists.
void BringSelfUpToDate (PRBool aDoFlush)
 If state is not LIST_UP_TO_DATE, fully populate ourselves with all the nodes we can find.
PRBool IsContentAnonymous (nsIContent *aContent)
 A function to check whether aContent is anonymous from our point of view.
void SetDirty ()
 Sets the state to LIST_DIRTY and clears mElements array.
PRBool Equals (const nsContentListKey &aContentListKey) const
PRUint32 GetHash (void) const

Protected Attributes

nsContentListMatchFunc mFunc
 Function to use to determine whether a piece of content matches our criterion.
const nsAFlatStringmData
 Closure data to pass to mFunc when we call it.
PRPackedBool mMatchAll
 True if we are looking for elements named "*".
PRUint8 mState
 The current state of the list (possible values are: LIST_UP_TO_DATE, LIST_LAZY, LIST_DIRTY.
PRPackedBool mDeep
 Whether to actually descend the tree.
nsCOMArray< nsIContentmElements
nsCOMPtr< nsIAtommMatchAtom
PRInt32 mMatchNameSpaceId
nsIDocumentmDocument
nsIContentmRootContent

Detailed Description

Class that implements a live NodeList that matches nodes in the tree based on some criterion.

Definition at line 173 of file nsContentList.h.


Constructor & Destructor Documentation

nsContentList::nsContentList ( nsIDocument aDocument,
nsIAtom aMatchAtom,
PRInt32  aMatchNameSpaceId,
nsIContent aRootContent = nsnull,
PRBool  aDeep = PR_TRUE 
)

Definition at line 274 of file nsContentList.cpp.

  : nsBaseContentList(),
    nsContentListKey(aDocument, aMatchAtom, aMatchNameSpaceId, aRootContent),
    mFunc(nsnull),
    mData(nsnull),
    mState(LIST_DIRTY),
    mDeep(aDeep)
{
  NS_ASSERTION(mDeep || mRootContent, "Must have root content for non-deep list!");
  if (nsLayoutAtoms::wildcard == mMatchAtom) {
    mMatchAll = PR_TRUE;
  }
  else {
    mMatchAll = PR_FALSE;
  }
  Init(aDocument);
}

Here is the call graph for this function:

nsContentList::nsContentList ( nsIDocument aDocument,
nsContentListMatchFunc  aFunc,
const nsAString &  aData,
nsIContent aRootContent = nsnull,
PRBool  aDeep = PR_TRUE,
nsIAtom aMatchAtom = nsnull,
PRInt32  aMatchNameSpaceId = kNameSpaceID_None 
)

Definition at line 296 of file nsContentList.cpp.

  : nsBaseContentList(),
    nsContentListKey(aDocument, aMatchAtom, aMatchNameSpaceId, aRootContent),
    mFunc(aFunc),
    mData(&EmptyString()),
    mMatchAll(PR_FALSE),
    mState(LIST_DIRTY),
    mDeep(aDeep)
{
  NS_ASSERTION(mDeep || mRootContent, "Must have root content for non-deep list!");
  if (!aData.IsEmpty()) {
    mData = new nsString(aData);
    // If this fails, fail silently
  }
  Init(aDocument);
}

Here is the call graph for this function:

Definition at line 332 of file nsContentList.cpp.

{
  RemoveFromHashtable();
  if (mDocument) {
    mDocument->RemoveObserver(this);
  }
  
  if (mData && mData != &EmptyString()) {
    // We actually allocated mData ourselves
    delete mData;
  }
}

Here is the call graph for this function:


Member Function Documentation

void nsBaseContentList::AppendElement ( nsIContent aContent) [virtual, inherited]

Definition at line 102 of file nsContentList.cpp.

{
  mElements.AppendObject(aContent);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsContentList::AttributeChanged ( nsIDocument aDocument,
nsIContent aContent,
PRInt32  aNameSpaceID,
nsIAtom aAttribute,
PRInt32  aModType 
) [virtual]

Notification that the content model has changed.

This method is called automatically by content objects when an attribute's value has changed (therefore there is normally no need to invoke this method directly). The notification is passed to any IDocumentObservers document observers.

Parameters:
aDocumentThe document being observed
aContentthe piece of content whose attribute changed
aAttributethe atom name of the attribute
aModTypeWhether or not the attribute was added, changed, or removed. The constants are defined in nsIDOMMutationEvent.h.

Implements nsIDocumentObserver.

Definition at line 517 of file nsContentList.cpp.

{
  NS_PRECONDITION(aContent, "Must have a content node to work with");
  
  if (!mFunc || mState == LIST_DIRTY || IsContentAnonymous(aContent)) {
    // Either we're already dirty or this notification doesn't affect
    // whether we might match aContent.
    return;
  }
  
  if (MayContainRelevantNodes(aContent->GetParent())) {
    if (Match(aContent)) {
      if (mElements.IndexOf(aContent) == -1) {
        // We match aContent now, and it's not in our list already.  Just dirty
        // ourselves; this is simpler than trying to figure out where to insert
        // aContent.
        SetDirty();
      }
    } else {
      // We no longer match aContent.  Remove it from our list.  If
      // it's already not there, this is a no-op (though a ptentially
      // expensive one).  Either way, no change of mState is required
      // here.
      mElements.RemoveObject(aContent);
    }
  }
}

Here is the call graph for this function:

virtual void nsIDocumentObserver::BeginLoad ( nsIDocument aDocument) [pure virtual, inherited]

Notify the observer that a document load is beginning.

Implemented in PresShell.

virtual void nsIDocumentObserver::BeginReflow ( nsIDocument aDocument,
nsIPresShell aShell 
) [pure virtual, inherited]

Notify the observer that the document is being reflowed in the given presentation shell.

virtual void nsIDocumentObserver::BeginUpdate ( nsIDocument aDocument,
nsUpdateType  aUpdateType 
) [pure virtual, inherited]

Notify that a content model update is beginning.

This call can be nested.

Implemented in nsFragmentObserver, PresShell, HTMLContentSink, and nsXMLPrettyPrinter.

void nsContentList::BringSelfUpToDate ( PRBool  aDoFlush) [inline, protected]

If state is not LIST_UP_TO_DATE, fully populate ourselves with all the nodes we can find.

If mDocument is null, the caller of BringSelfUpToDate is responsible for calling SetDirty once it's gotten the information it wants from the list.

Definition at line 954 of file nsContentList.cpp.

{
  if (mDocument && aDoFlush) {
    // Flush pending content changes Bug 4891.
    mDocument->FlushPendingNotifications(Flush_ContentAndNotify);
  }

  if (mState != LIST_UP_TO_DATE)
    PopulateSelf(PRUint32(-1));
    
  NS_ASSERTION(!mDocument || mState == LIST_UP_TO_DATE,
               "PopulateSelf dod not bring content list up to date!");
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual void nsIDocumentObserver::CharacterDataChanged ( nsIDocument aDocument,
nsIContent aContent,
PRBool  aAppend 
) [pure virtual, inherited]

Notification that the content model has changed.

This method is called automatically by content objects when their state is changed (therefore there is normally no need to invoke this method directly). The notification is passed to any IDocumentObservers. The notification is passed on to all of the document observers.

This notification is not sent when a piece of content is added/removed from the document (the other notifications are used for that).

Parameters:
aDocumentThe document being observed
aContentthe piece of content that changed
aAppendWhether the change was an append

Implemented in PresShell.

If we have no document and we have a root content, then check if our content has been added to a document.

If so, we'll become an observer of the document.

Definition at line 716 of file nsContentList.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsContentList::ContainsRoot ( nsIContent aContent) [protected]

Does this subtree contain our mRootContent?

Parameters:
aContainerthe root of the subtree
Returns:
PR_FALSE if mRootContent is null, otherwise whether mRootContent is a descendant of aContainer

Definition at line 908 of file nsContentList.cpp.

{
  if (!mRootContent || !aContent) {
    return PR_FALSE;
  }

  return nsContentUtils::ContentIsDescendantOf(mRootContent, aContent);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsContentList::ContentAppended ( nsIDocument aDocument,
nsIContent aContainer,
PRInt32  aNewIndexInContainer 
) [virtual]

Notifcation that the content model has had data appended to the given content object.

This method is called automatically by the content container objects when a new content object is appended to the container (therefore there is normally no need to invoke this method directly). The notification is passed on to all of the document observers.

Parameters:
aDocumentThe document being observed
aContainerthe container that had a new child appended
aNewIndexInContainerthe index in the container of the first new child

Implements nsIDocumentObserver.

Definition at line 548 of file nsContentList.cpp.

{
  NS_PRECONDITION(aContainer, "Can't get at the new content if no container!");
  
  /*
   * If the state is LIST_DIRTY then we have no useful information in our list
   * and we want to put off doing work as much as possible.  Also, if
   * aContainer is anonymous from our point of view, we know that we can't
   * possibly be matching any of the kids.
   */
  if (mState == LIST_DIRTY || IsContentAnonymous(aContainer)) 
    return;

  /*
   * We want to handle the case of ContentAppended by sometimes
   * appending the content to our list, not just setting state to
   * LIST_DIRTY, since most of our ContentAppended notifications
   * should come during pageload and be at the end of the document.
   * Do a bit of work to see whether we could just append to what we
   * already have.
   */
  
  PRInt32 count = aContainer->GetChildCount();

  if (count > 0 && MayContainRelevantNodes(aContainer)) {
    PRInt32 ourCount = mElements.Count();
    PRBool appendToList = PR_FALSE;
    if (ourCount == 0) {
      appendToList = PR_TRUE;
    } else {
      nsIContent* ourLastContent = mElements[ourCount - 1];
      /*
       * We want to append instead of invalidating if the first thing
       * that got appended comes after ourLastContent.
       */
      nsCOMPtr<nsIDOM3Node> ourLastDOM3Node(do_QueryInterface(ourLastContent));
      if (ourLastDOM3Node) {
        nsCOMPtr<nsIDOMNode> newNode =
          do_QueryInterface(aContainer->GetChildAt(aNewIndexInContainer));
        NS_ASSERTION(newNode, "Content being inserted is not a node.... why?");

        PRUint16 comparisonFlags;
        nsresult rv =
          ourLastDOM3Node->CompareDocumentPosition(newNode, &comparisonFlags);
        if (NS_SUCCEEDED(rv) && 
            (comparisonFlags & nsIDOM3Node::DOCUMENT_POSITION_FOLLOWING)) {
          appendToList = PR_TRUE;
        }
      }
    }
    
    PRInt32 i;
    
    if (!appendToList) {
      // The new stuff is somewhere in the middle of our list; check
      // whether we need to invalidate
      for (i = aNewIndexInContainer; i <= count-1; ++i) {
        if (MatchSelf(aContainer->GetChildAt(i))) {
          // Uh-oh.  We're gonna have to add elements into the middle
          // of our list. That's not worth the effort.
          SetDirty();
          break;
        }
      }
 
      return;
    }

    /*
     * At this point we know we could append.  If we're not up to
     * date, however, that would be a bad idea -- it could miss some
     * content that we never picked up due to being lazy.  Further, we
     * may never get asked for this content... so don't grab it yet.
     */
    if (mState == LIST_LAZY) // be lazy
      return;

    /*
     * We're up to date.  That means someone's actively using us; we
     * may as well grab this content....
     */
    for (i = aNewIndexInContainer; i <= count-1; ++i) {
      PRUint32 limit = PRUint32(-1);
      PopulateWith(aContainer->GetChildAt(i), PR_TRUE, limit);
    }
  }
}

Here is the call graph for this function:

void nsContentList::ContentInserted ( nsIDocument aDocument,
nsIContent aContainer,
nsIContent aChild,
PRInt32  aIndexInContainer 
) [virtual]

Notification that content has been inserted.

This method is called automatically by the content container objects when a new content object is inserted in the container (therefore there is normally no need to invoke this method directly). The notification is passed on to all of the document observers.

Parameters:
aDocumentThe document being observed
aContainerthe container that now contains aChild
aChildthe child that was inserted
aIndexInContainerthe index of the child in the container

Implements nsIDocumentObserver.

Definition at line 638 of file nsContentList.cpp.

{
  // Note that aContainer can be null here if we are inserting into
  // the document itself; any attempted optimizations to this method
  // should deal with that.
  if (mState == LIST_DIRTY || IsContentAnonymous(aChild))
    return;

  if (MayContainRelevantNodes(aContainer) && MatchSelf(aChild))
    SetDirty();
}

Here is the call graph for this function:

void nsContentList::ContentRemoved ( nsIDocument aDocument,
nsIContent aContainer,
nsIContent aChild,
PRInt32  aIndexInContainer 
) [virtual]

Content has just been removed.

This method is called automatically by content container objects when a content object has just been removed from the container (therefore there is normally no need to invoke this method directly). The notification is passed on to all of the document observers.

Parameters:
aDocumentThe document being observed
aContainerthe container that had a child removed
aChildthe child that was just removed
aIndexInContainerthe index of the child in the container before it was removed

Implements nsIDocumentObserver.

Definition at line 654 of file nsContentList.cpp.

{
  // Note that aContainer can be null here if we are removing from
  // the document itself; any attempted optimizations to this method
  // should deal with that.
  if (mState != LIST_DIRTY) {
    if (MayContainRelevantNodes(aContainer)) {
      if (!IsContentAnonymous(aChild) && MatchSelf(aChild)) {
        SetDirty();
      }
      return;
    }
  }

  // Even if aChild is anonymous from our point of view, it could
  // contain our root (eg say our root is an anonymous child of
  // aChild).
  if (ContainsRoot(aChild)) {
    DisconnectFromDocument();
  }
}

Here is the call graph for this function:

virtual void nsIDocumentObserver::ContentStatesChanged ( nsIDocument aDocument,
nsIContent aContent1,
nsIContent aContent2,
PRInt32  aStateMask 
) [pure virtual, inherited]

Notification that the state of a content node has changed.

(ie: gained or lost focus, became active or hovered over) This method is called automatically by content objects when their state is changed (therefore there is normally no need to invoke this method directly). The notification is passed to any IDocumentObservers. The notification is passed on to all of the document observers.

This notification is not sent when a piece of content is added/removed from the document or the content itself changed (the other notifications are used for that).

The optional second content node is to allow optimization of the case where state moves from one node to another (as is likely for :focus and :hover)

Either content node may be nsnull, but not both

Parameters:
aDocumentThe document being observed
aContent1the piece of content that changed
aContent2optional second piece of content that changed

Implemented in PresShell, and nsTreeContentView.

Our root content has been disconnected from the document, so stop observing.

From this point on, if someone asks us something we walk the tree rooted at mRootContent starting at the beginning and going as far as we need to to answer the question.

Definition at line 918 of file nsContentList.cpp.

{
  if (mDocument) {
    // Our key will change... Best remove ourselves before that happens.
    RemoveFromHashtable();
    mDocument->RemoveObserver(this);
    mDocument = nsnull;
  }

  // We will get no more updates, so we can never know we're up to
  // date
  SetDirty();
}

Here is the call graph for this function:

Here is the caller graph for this function:

The document is in the process of being destroyed.

This method is called automatically during document destruction.

Parameters:
aDocumentThe document being observed

Implements nsIDocumentObserver.

Definition at line 680 of file nsContentList.cpp.

Here is the call graph for this function:

virtual void nsIDocumentObserver::EndLoad ( nsIDocument aDocument) [pure virtual, inherited]

Notify the observer that a document load has finished.

Note that the associated reflow of the document will be done before EndLoad is invoked, not after.

Implemented in PresShell.

virtual void nsIDocumentObserver::EndReflow ( nsIDocument aDocument,
nsIPresShell aShell 
) [pure virtual, inherited]

Notify the observer that the document is done being reflowed in the given presentation shell.

virtual void nsIDocumentObserver::EndUpdate ( nsIDocument aDocument,
nsUpdateType  aUpdateType 
) [pure virtual, inherited]

Notify that a content model update is finished.

This call can be nested.

Implemented in PresShell, HTMLContentSink, and nsXMLPrettyPrinter.

PRBool nsContentListKey::Equals ( const nsContentListKey aContentListKey) const [inline, inherited]

Definition at line 121 of file nsContentList.h.

  {
    return
      mMatchAtom == aContentListKey.mMatchAtom &&
      mMatchNameSpaceId == aContentListKey.mMatchNameSpaceId &&
      mDocument == aContentListKey.mDocument &&
      mRootContent == aContentListKey.mRootContent;
  }

Here is the caller graph for this function:

PRUint32 nsContentListKey::GetHash ( void  ) const [inline, inherited]

Definition at line 129 of file nsContentList.h.

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 208 of file nsContentList.h.

                             {
    return NS_STATIC_CAST(nsContentListKey*, this);
  }

Here is the caller graph for this function:

PRInt32 nsContentList::IndexOf ( nsIContent aContent,
PRBool  aDoFlush 
) [virtual]

Reimplemented from nsBaseContentList.

Definition at line 443 of file nsContentList.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

void nsContentList::Init ( nsIDocument aDocument) [protected]

Definition at line 319 of file nsContentList.cpp.

{
  // We don't reference count the reference to the document
  // If the document goes away first, we'll be informed and we
  // can drop our reference.
  // If we go away first, we'll get rid of ourselves from the
  // document's observer list.
  mDocument = aDocument;
  if (mDocument) {
    mDocument->AddObserver(this);
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

A function to check whether aContent is anonymous from our point of view.

If it is, we don't care about it, since we should never contain it or any of its kids.

The goal of this function is to filter out content that is "anonymous" from our point of view, so that we don't end up with it in the list. Note that in some cases content can be anonymous but NOT from our point of view. For example, say we're the result of calling getElementsByTagName on an anonymous node in a XBL binding. In that case, all descendants of that node that it can see are not anonymous from our point of view.

If we have no root, that means we correspond to a list gotten off the "document" object, so will always contain only nodes that the document can see, which means only nodes with a null bindingParent.

If mRootContent and aContent have different bindingParents, then there are two possibilities:

1) aContent or one of its ancestors is an anonymous child of a descendant of mRootContent (or of mRootContent itself). 2) mRootContent is not an ancestor of aContent.

In either case, we don't want to be matching aContent or any of its descendants.

On the other hand, if mRootContent and aContent have the same bindingParent then they are part of the same binding (or native anonymous content chunk) and then aContent may be a descendant of mRootContent and we may want to match it.

So we return true if the binding parents don't match; if the binding parents are the same, the checks we normally do to determine whether we match a node should be done.

Definition at line 969 of file nsContentList.cpp.

{
  NS_PRECONDITION(aContent, "Must have a content node to work with");
  
  if (!mRootContent) {
    return aContent->GetBindingParent() != nsnull;
  }

  return mRootContent->GetBindingParent() != aContent->GetBindingParent();
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsIDOMNode nsIDOMNodeList::item ( in unsigned long  index) [inherited]

Here is the caller graph for this function:

nsIDOMNode nsIDOMHTMLCollection::item ( in unsigned long  index) [inherited]
PRBool nsContentList::Match ( nsIContent aContent) [protected]

Returns whether the content element matches our criterion.

Parameters:
aContentthe content to attempt to match
Returns:
whether we match

Definition at line 687 of file nsContentList.cpp.

{
  if (!aContent)
    return PR_FALSE;

  if (mFunc) {
    return (*mFunc)(aContent, mMatchNameSpaceId, mMatchAtom, *mData);
  }

  if (mMatchAtom) {
    if (!aContent->IsContentOfType(nsIContent::eELEMENT)) {
      return PR_FALSE;
    }

    nsINodeInfo *ni = aContent->GetNodeInfo();
    NS_ASSERTION(ni, "Element without nodeinfo!");

    if (mMatchNameSpaceId == kNameSpaceID_Unknown) {
      return (mMatchAll || ni->Equals(mMatchAtom));
    }

    return ((mMatchAll && ni->NamespaceEquals(mMatchNameSpaceId)) ||
            ni->Equals(mMatchAtom, mMatchNameSpaceId));
  }

  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsContentList::MatchSelf ( nsIContent aContent) [protected]

Match recursively.

See if anything in the subtree rooted at aContent matches our criterion.

Parameters:
aContentthe root of the subtree to match against
Returns:
whether we match something in the tree rooted at aContent

Definition at line 729 of file nsContentList.cpp.

{
  NS_PRECONDITION(aContent, "Can't match null stuff, you know");
  NS_PRECONDITION(mDeep || aContent->GetParent() == mRootContent,
                  "MatchSelf called on a node that we can't possibly match");
  
  if (Match(aContent))
    return PR_TRUE;

  if (!mDeep)
    return PR_FALSE;

  PRUint32 i, count = aContent->GetChildCount();

  for (i = 0; i < count; i++) {
    if (MatchSelf(aContent->GetChildAt(i))) {
      return PR_TRUE;
    }
  }
  
  return PR_FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Parameters:
aContainera content node which could be a descendant of mRootContent
Returns:
PR_TRUE if mRootContent is null, PR_FALSE if aContainer is null, PR_TRUE if aContainer is a descendant of mRootContent (though if mDeep is false, only aContainer == mRootContent counts), PR_FALSE otherwise

Definition at line 877 of file nsContentList.cpp.

{
  if (!mRootContent) {
#ifdef DEBUG
    // aContainer can be null when ContentInserted/ContentRemoved are
    // called, but we still want to return PR_TRUE in such cases if
    // mRootContent is null.  We could pass the document into this
    // method instead of trying to get it from aContainer, but that
    // seems a little pointless just to run this debug-only integrity
    // check.
    if (aContainer) { 
      NS_ASSERTION(aContainer->GetDocument() == mDocument,
                   "We should not get in here if aContainer is in some _other_ document!");
    }
#endif
    return PR_TRUE;
  }

  if (!aContainer) {
    return PR_FALSE;
  }

  if (!mDeep) {
    // We only care about cases when aContainer is our root content node.
    return aContainer == mRootContent;
  }
  
  return nsContentUtils::ContentIsDescendantOf(aContainer, mRootContent);
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsIDOMNode nsIDOMHTMLCollection::namedItem ( in DOMString  name) [inherited]
nsContentList::NS_HIDDEN_ ( nsISupports *  )

Definition at line 467 of file nsContentList.cpp.

{
  // If our content list cache holds a list used for a document that's
  // now being destroyed, free the cache to prevent the list from
  // staying around until the next use of content lists ends up
  // replacing what's in the cache.

  if (gCachedContentList && gCachedContentList->mRootContent &&
      gCachedContentList->mRootContent->GetOwnerDoc() == aDocument) {
    NS_RELEASE(gCachedContentList);
  }
}

Here is the call graph for this function:

void nsContentList::PopulateSelf ( PRUint32  aNeededLength) [protected]

Populate our list.

Stop once we have at least aNeededLength elements. At the end of PopulateSelf running, either the last node we examined is the last node in our array or we have traversed the whole document (or both). If mDocument is null, the caller of PopulateSelf is responsible for calling SetDirty once it's gotten the information it wants from the list.

Parameters:
aNeededLengththe length the list should have when we are done (unless it exhausts the document)

Definition at line 831 of file nsContentList.cpp.

{
  if (mState == LIST_DIRTY) {
    Reset();
  }
  PRUint32 count = mElements.Count();
  NS_ASSERTION(mState != LIST_DIRTY || count == 0,
               "Reset() not called when setting state to LIST_DIRTY?");

  if (count >= aNeededLength) // We're all set
    return;

  PRUint32 elementsToAppend = aNeededLength - count;
#ifdef DEBUG
  PRUint32 invariant = elementsToAppend + mElements.Count();
#endif
  if (count != 0) {
    PopulateWithStartingAfter(mElements[count - 1], nsnull, elementsToAppend);
    NS_ASSERTION(elementsToAppend + mElements.Count() == invariant,
                 "Something is awry in PopulateWithStartingAfter!");
  } else if (mRootContent) {
    PopulateWith(mRootContent, PR_FALSE, elementsToAppend);
    NS_ASSERTION(elementsToAppend + mElements.Count() == invariant,
                 "Something is awry in PopulateWith!");
  }
  else if (mDocument) {
    nsIContent *root = mDocument->GetRootContent();
    if (root) {
      PopulateWith(root, PR_TRUE, elementsToAppend);
      NS_ASSERTION(elementsToAppend + mElements.Count() == invariant,
                   "Something is awry in PopulateWith!");
    }
  }

  if (mDocument) {
    if (elementsToAppend != 0)
      mState = LIST_UP_TO_DATE;
    else
      mState = LIST_LAZY;
  }
  // Else no document, so we have to stay on our toes since we don't get
  // content notifications.  Caller will call SetDirty(); see documentation for
  // PopulateSelf() in the header.
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsContentList::PopulateWith ( nsIContent aContent,
PRBool  aIncludeRoot,
PRUint32 aElementsToAppend 
) [protected]

Add elements in the subtree rooted in aContent that match our criterion to our list until we've picked up aElementsToAppend elements.

This function enforces the invariant that |aElementsToAppend + mElements.Count()| is a constant.

Parameters:
aContentthe root of the subtree we want to traverse
aIncludeRootwhether to include the root in the traversal
aElementsToAppendhow many elements to append to the list before stopping

Definition at line 753 of file nsContentList.cpp.

{
  NS_PRECONDITION(mDeep || aContent == mRootContent ||
                  aContent->GetParent() == mRootContent,
                  "PopulateWith called on nodes we can't possibly match");
  NS_PRECONDITION(mDeep || aIncludeRoot || aContent == mRootContent,
                  "Bogus root passed to PopulateWith in non-deep list");
  NS_PRECONDITION(!aIncludeRoot || aContent != mRootContent,
                  "We should never be trying to match mRootContent");
  
  if (aIncludeRoot) {
    if (Match(aContent)) {
      mElements.AppendObject(aContent);
      --aElementsToAppend;
      if (aElementsToAppend == 0)
        return;
    }
  }

  // Don't recurse down if we're not doing a deep match and we're
  // already looking at kids of the root.
  if (!mDeep && aIncludeRoot)
    return;
  
  PRUint32 i, count = aContent->GetChildCount();

  for (i = 0; i < count; i++) {
    PopulateWith(aContent->GetChildAt(i), PR_TRUE, aElementsToAppend);
    if (aElementsToAppend == 0)
      return;
  }
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsContentList::PopulateWithStartingAfter ( nsIContent aStartRoot,
nsIContent aStartChild,
PRUint32 aElementsToAppend 
) [protected]

Populate our list starting at the child of aStartRoot that comes after aStartChild (if such exists) and continuing in document order.

Stop once we've picked up aElementsToAppend elements. This function enforces the invariant that |aElementsToAppend + mElements.Count()| is a constant.

Parameters:
aStartRootthe node with whose children we want to start traversal
aStartChildthe child after which we want to start
aElementsToAppendhow many elements to append to the list before stopping

Definition at line 788 of file nsContentList.cpp.

{
  NS_PRECONDITION(mDeep || aStartRoot == mRootContent ||
                  (aStartRoot->GetParent() == mRootContent &&
                   aStartChild == nsnull),
                  "Bogus aStartRoot or aStartChild");

  if (mDeep || aStartRoot == mRootContent) {
#ifdef DEBUG
    PRUint32 invariant = aElementsToAppend + mElements.Count();
#endif
    PRInt32 i = 0;
    if (aStartChild) {
      i = aStartRoot->IndexOf(aStartChild);
      NS_ASSERTION(i >= 0, "The start child must be a child of the start root!");
      ++i;  // move to one past
    }

    PRUint32 childCount = aStartRoot->GetChildCount();
    for ( ; ((PRUint32)i) < childCount; ++i) {
      PopulateWith(aStartRoot->GetChildAt(i), PR_TRUE, aElementsToAppend);
    
      NS_ASSERTION(aElementsToAppend + mElements.Count() == invariant,
                   "Something is awry in PopulateWith!");
      if (aElementsToAppend == 0)
        return;
    }
  }

  // We want to make sure we don't move up past our root node. So if
  // we're there, don't move to the parent.
  if (aStartRoot == mRootContent)
    return;
  
  nsIContent* parent = aStartRoot->GetParent();
  
  if (parent)
    PopulateWithStartingAfter(parent, aStartRoot, aElementsToAppend);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsBaseContentList::RemoveElement ( nsIContent aContent) [virtual, inherited]

Definition at line 108 of file nsContentList.cpp.

{
  mElements.RemoveObject(aContent);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Remove ourselves from the hashtable that caches commonly accessed content lists.

Generally done on destruction.

Definition at line 933 of file nsContentList.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

void nsBaseContentList::Reset ( void  ) [virtual, inherited]

Definition at line 120 of file nsContentList.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

void nsContentList::SetDirty ( ) [inline, protected]

Sets the state to LIST_DIRTY and clears mElements array.

Note:
This is the only acceptable way to set state to LIST_DIRTY.

Definition at line 340 of file nsContentList.h.

  {
    mState = LIST_DIRTY;
    Reset();
  }

Here is the call graph for this function:

Here is the caller graph for this function:

void nsBaseContentList::Shutdown ( ) [static, inherited]

Definition at line 127 of file nsContentList.cpp.

virtual void nsIDocumentObserver::StyleRuleAdded ( nsIDocument aDocument,
nsIStyleSheet aStyleSheet,
nsIStyleRule aStyleRule 
) [pure virtual, inherited]

A StyleRule has just been added to a style sheet.

This method is called automatically when the rule gets added to the sheet. The style sheet passes this notification to the document. The notification is passed on to all of the document observers.

Parameters:
aDocumentThe document being observed
aStyleSheetthe StyleSheet that has been modified
aStyleRulethe rule that was added

Implemented in PresShell.

virtual void nsIDocumentObserver::StyleRuleChanged ( nsIDocument aDocument,
nsIStyleSheet aStyleSheet,
nsIStyleRule aOldStyleRule,
nsIStyleRule aNewStyleRule 
) [pure virtual, inherited]

A StyleRule has just been modified within a style sheet.

This method is called automatically when the rule gets modified. The style sheet passes this notification to the document. The notification is passed on to all of the document observers.

Since nsIStyleRule objects are immutable, there is a new object replacing the old one. However, the use of this method (rather than StyleRuleAdded and StyleRuleRemoved) implies that the new rule matches the same elements and has the same priority (weight, origin, specificity) as the old one. (However, if it is a CSS style rule, there may be a change in whether it has an important rule.)

Parameters:
aDocumentThe document being observed
aStyleSheetthe StyleSheet that contians the rule
aOldStyleRuleThe rule being removed. This rule may not be fully valid anymore -- however, it can still be used for pointer comparison and |QueryInterface|.
aNewStyleRuleThe rule being added.

Implemented in PresShell.

virtual void nsIDocumentObserver::StyleRuleRemoved ( nsIDocument aDocument,
nsIStyleSheet aStyleSheet,
nsIStyleRule aStyleRule 
) [pure virtual, inherited]

A StyleRule has just been removed from a style sheet.

This method is called automatically when the rule gets removed from the sheet. The style sheet passes this notification to the document. The notification is passed on to all of the document observers.

Parameters:
aDocumentThe document being observed
aStyleSheetthe StyleSheet that has been modified
aStyleRulethe rule that was removed

Implemented in PresShell.

virtual void nsIDocumentObserver::StyleSheetAdded ( nsIDocument aDocument,
nsIStyleSheet aStyleSheet,
PRBool  aDocumentSheet 
) [pure virtual, inherited]

A StyleSheet has just been added to the document.

This method is called automatically when a StyleSheet gets added to the document, even if the stylesheet is not applicable. The notification is passed on to all of the document observers.

Parameters:
aDocumentThe document being observed
aStyleSheetthe StyleSheet that has been added
aDocumentSheetTrue if sheet is in document's style sheet list, false if sheet is not (i.e., UA or user sheet)

Implemented in PresShell, and nsDOMStyleSheetList.

virtual void nsIDocumentObserver::StyleSheetApplicableStateChanged ( nsIDocument aDocument,
nsIStyleSheet aStyleSheet,
PRBool  aApplicable 
) [pure virtual, inherited]

A StyleSheet has just changed its applicable state.

This method is called automatically when the applicable state of a StyleSheet gets changed. The style sheet passes this notification to the document. The notification is passed on to all of the document observers.

Parameters:
aDocumentThe document being observed
aStyleSheetthe StyleSheet that has changed state
aApplicablePR_TRUE if the sheet is applicable, PR_FALSE if it is not applicable

Implemented in PresShell.

virtual void nsIDocumentObserver::StyleSheetRemoved ( nsIDocument aDocument,
nsIStyleSheet aStyleSheet,
PRBool  aDocumentSheet 
) [pure virtual, inherited]

A StyleSheet has just been removed from the document.

This method is called automatically when a StyleSheet gets removed from the document, even if the stylesheet is not applicable. The notification is passed on to all of the document observers.

Parameters:
aDocumentThe document being observed
aStyleSheetthe StyleSheet that has been removed
aDocumentSheetTrue if sheet is in document's style sheet list, false if sheet is not (i.e., UA or user sheet)

Implemented in PresShell, and nsDOMStyleSheetList.


Member Data Documentation

Definition at line 204 of file nsContentList.h.

readonly attribute unsigned long nsIDOMHTMLCollection::length [inherited]

Definition at line 55 of file nsIDOMHTMLCollection.idl.

readonly attribute unsigned long nsIDOMNodeList::length [inherited]

Definition at line 58 of file nsIDOMNodeList.idl.

Closure data to pass to mFunc when we call it.

Definition at line 354 of file nsContentList.h.

Whether to actually descend the tree.

If this is false, we won't consider grandkids of mRootContent.

Definition at line 368 of file nsContentList.h.

nsIDocument* nsContentListKey::mDocument [protected, inherited]

Definition at line 141 of file nsContentList.h.

Definition at line 81 of file nsContentList.h.

Function to use to determine whether a piece of content matches our criterion.

Definition at line 350 of file nsContentList.h.

True if we are looking for elements named "*".

Definition at line 358 of file nsContentList.h.

Definition at line 139 of file nsContentList.h.

Definition at line 140 of file nsContentList.h.

nsIContent* nsContentListKey::mRootContent [protected, inherited]

Definition at line 146 of file nsContentList.h.

The current state of the list (possible values are: LIST_UP_TO_DATE, LIST_LAZY, LIST_DIRTY.

Definition at line 363 of file nsContentList.h.


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