Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Public Attributes | Private Member Functions | Private Attributes
nsTreeWalker Class Reference

#include <nsTreeWalker.h>

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

List of all members.

Public Member Functions

NS_DECL_ISUPPORTS virtual
NS_DECL_NSIDOMTREEWALKER
nsIDOMGCParticipant
GetSCCIndex ()
 Get a reference node for what is known to be a strongly connected component of nsIDOMGCParticipants.
virtual void AppendReachableList (nsCOMArray< nsIDOMGCParticipant > &aArray)
 Append the list of nsIDOMGCPartipants reachable from this one via C++ getters exposed to script that return a different result from |GetSCCIndex|.
 nsTreeWalker (nsIDOMNode *aRoot, PRUint32 aWhatToShow, nsIDOMNodeFilter *aFilter, PRBool aExpandEntityReferences)
virtual ~nsTreeWalker ()
nsIDOMNode parentNode ()
nsIDOMNode firstChild ()
nsIDOMNode lastChild ()
nsIDOMNode previousSibling ()
nsIDOMNode nextSibling ()
nsIDOMNode previousNode ()
nsIDOMNode nextNode ()

Public Attributes

readonly attribute nsIDOMNode root
readonly attribute unsigned long whatToShow
readonly attribute nsIDOMNodeFilter filter
readonly attribute boolean expandEntityReferences
attribute nsIDOMNode currentNode

Private Member Functions

nsresult FirstChildOf (nsIDOMNode *aNode, PRBool aReversed, PRInt32 aIndexPos, nsIDOMNode **_retval)
nsresult NextSiblingOf (nsIDOMNode *aNode, PRBool aReversed, PRInt32 aIndexPos, nsIDOMNode **_retval)
nsresult NextInDocumentOrderOf (nsIDOMNode *aNode, PRBool aReversed, PRInt32 aIndexPos, nsIDOMNode **_retval)
nsresult ChildOf (nsIDOMNode *aNode, PRInt32 childNum, PRBool aReversed, PRInt32 aIndexPos, nsIDOMNode **_retval)
nsresult TestNode (nsIDOMNode *aNode, PRInt16 *_filtered)
nsresult IndexOf (nsIDOMNode *aParent, nsIDOMNode *aChild, PRInt32 aIndexPos, PRInt32 *_childNum)
void SetChildIndex (PRInt32 aIndexPos, PRInt32 aChildIndex)

Private Attributes

nsCOMPtr< nsIDOMNodemRoot
PRUint32 mWhatToShow
nsMarkedJSFunctionHolder
< nsIDOMNodeFilter
mFilter
PRBool mExpandEntityReferences
nsCOMPtr< nsIDOMNodemCurrentNode
nsAutoVoidArray mPossibleIndexes
PRInt32 mPossibleIndexesPos

Detailed Description

Definition at line 55 of file nsTreeWalker.h.


Constructor & Destructor Documentation

nsTreeWalker::nsTreeWalker ( nsIDOMNode aRoot,
PRUint32  aWhatToShow,
nsIDOMNodeFilter aFilter,
PRBool  aExpandEntityReferences 
)

Definition at line 81 of file nsTreeWalker.cpp.

                                                           :
    mRoot(aRoot),
    mWhatToShow(aWhatToShow),
    mExpandEntityReferences(aExpandEntityReferences),
    mCurrentNode(aRoot),
    mPossibleIndexesPos(-1)
{
    mFilter.Set(aFilter, this);

    NS_ASSERTION(aRoot, "invalid root in call to nsTreeWalker constructor");
}

Here is the call graph for this function:

Definition at line 96 of file nsTreeWalker.cpp.

{
    /* destructor code */
}

Member Function Documentation

Append the list of nsIDOMGCPartipants reachable from this one via C++ getters exposed to script that return a different result from |GetSCCIndex|.

The caller is responsible for taking the transitive closure of |AppendReachableList|.

This will only be called on objects that are returned by GetSCCIndex.

null pointers may be appended; they will be ignored by the caller.

Implements nsIDOMGCParticipant.

Definition at line 285 of file nsTreeWalker.cpp.

{
    nsCOMPtr<nsIDOMGCParticipant> gcp;
    
    gcp = do_QueryInterface(mRoot);
    if (gcp)
        aArray.AppendObject(gcp);

    gcp = do_QueryInterface(mCurrentNode);
    if (gcp)
        aArray.AppendObject(gcp);
}

Here is the call graph for this function:

nsresult nsTreeWalker::ChildOf ( nsIDOMNode aNode,
PRInt32  childNum,
PRBool  aReversed,
PRInt32  aIndexPos,
nsIDOMNode **  _retval 
) [private]

Definition at line 530 of file nsTreeWalker.cpp.

{
    PRInt16 filtered;
    nsresult rv;
    nsCOMPtr<nsIDOMNodeList> childNodes;

    rv = aNode->GetChildNodes(getter_AddRefs(childNodes));
    NS_ENSURE_SUCCESS(rv, rv);
    NS_ENSURE_TRUE(childNodes, NS_ERROR_UNEXPECTED);

    PRInt32 dir, end;
    if (!aReversed) {
        dir = 1;
        rv = childNodes->GetLength((PRUint32*)&end);
        NS_ENSURE_SUCCESS(rv, rv);
    }
    else {
        dir = -1;
        end = -1;
    }

    // Step through all children
    PRInt32 i;
    for (i = childNum+dir; i != end; i += dir) {
        nsCOMPtr<nsIDOMNode> child;
        rv = childNodes->Item(i, getter_AddRefs(child));
        NS_ENSURE_SUCCESS(rv, rv);

        rv = TestNode(child, &filtered);
        NS_ENSURE_SUCCESS(rv, rv);

        switch (filtered) {
            case nsIDOMNodeFilter::FILTER_ACCEPT:
                // Child found
                mCurrentNode = child;
                mPossibleIndexesPos = aIndexPos;
                *_retval = child;
                NS_ADDREF(*_retval);

                SetChildIndex(aIndexPos, i);

                return NS_OK;

            case nsIDOMNodeFilter::FILTER_SKIP:
                // Search children
                rv = FirstChildOf(child, aReversed, aIndexPos+1, _retval);
                NS_ENSURE_SUCCESS(rv, rv);

                if (*_retval) {
                    SetChildIndex(aIndexPos, i);
                    return NS_OK;
                }
                break;

            case nsIDOMNodeFilter::FILTER_REJECT:
                // Keep searching
                break;

            default:
                return NS_ERROR_UNEXPECTED;
        }
    }

    *_retval = nsnull;
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsTreeWalker::FirstChildOf ( nsIDOMNode aNode,
PRBool  aReversed,
PRInt32  aIndexPos,
nsIDOMNode **  _retval 
) [private]

Definition at line 313 of file nsTreeWalker.cpp.

{
    nsresult rv;

    // Don't step into entity references if expandEntityReferences = false
    if (!mExpandEntityReferences) {
        nsCOMPtr<nsIDOMEntityReference> ent(do_QueryInterface(aNode));

        if (ent) {
            *_retval = nsnull;
            return NS_OK;
        }
    }

    nsCOMPtr<nsIDOMNodeList> childNodes;

    PRInt32 start;
    if (!aReversed) {
        start = -1;
    }
    else {
        rv = aNode->GetChildNodes(getter_AddRefs(childNodes));
        NS_ENSURE_SUCCESS(rv, rv);
        NS_ENSURE_TRUE(childNodes, NS_ERROR_UNEXPECTED);

        rv = childNodes->GetLength((PRUint32*)&start);
        NS_ENSURE_SUCCESS(rv, rv);
    }

    return ChildOf(aNode, start, aReversed, aIndexPos, _retval);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Get a reference node for what is known to be a strongly connected component of nsIDOMGCParticipants.

For example, DOM trees are strongly connected, so can return the root node to greatly reduce the number of nodes on which we need to run graph algorithms.

Note that it's acceptable for nodes in a single strongly connected component to return different values for GetSCCIndex, as long as those two values claim that they're reachable from each other in AppendReachableList.

Implements nsIDOMGCParticipant.

Definition at line 279 of file nsTreeWalker.cpp.

{
    return this;
}
nsresult nsTreeWalker::IndexOf ( nsIDOMNode aParent,
nsIDOMNode aChild,
PRInt32  aIndexPos,
PRInt32 _childNum 
) [private]

Definition at line 642 of file nsTreeWalker.cpp.

{
    PRInt32 possibleIndex = -1;
    if (aIndexPos >= 0)
        possibleIndex = NS_PTR_TO_INT32(mPossibleIndexes[aIndexPos]);

    nsCOMPtr<nsIContent> contParent(do_QueryInterface(aParent));
    if (contParent) {
        nsCOMPtr<nsIContent> child(do_QueryInterface(aChild));

        if (possibleIndex >= 0) {
            if (child == contParent->GetChildAt(possibleIndex)) {
                *_childNum = possibleIndex;
                return NS_OK;
            }
        }

        *_childNum = contParent->IndexOf(child);

        return *_childNum >= 0 ? NS_OK : NS_ERROR_UNEXPECTED;
    }

    nsCOMPtr<nsIDocument> docParent(do_QueryInterface(aParent));
    if (docParent) {
        nsCOMPtr<nsIContent> child(do_QueryInterface(aChild));

        if (possibleIndex >= 0) {
            if (child == docParent->GetChildAt(possibleIndex)) {
                *_childNum = possibleIndex;
                return NS_OK;
            }
        }

        *_childNum = docParent->IndexOf(child);

        return *_childNum >= 0 ? NS_OK : NS_ERROR_UNEXPECTED;
    }

    nsresult rv;
    PRUint32 i, len;
    nsCOMPtr<nsIDOMNodeList> childNodes;

    rv = aParent->GetChildNodes(getter_AddRefs(childNodes));
    NS_ENSURE_SUCCESS(rv, rv);
    NS_ENSURE_TRUE(childNodes, NS_ERROR_UNEXPECTED);

    if (possibleIndex >= 0) {
        nsCOMPtr<nsIDOMNode> tmp;
        childNodes->Item(possibleIndex, getter_AddRefs(tmp));
        if (tmp == aChild) {
            *_childNum = possibleIndex;
            return NS_OK;
        }
    }

    rv = childNodes->GetLength(&len);
    NS_ENSURE_SUCCESS(rv, rv);

    for (i = 0; i < len; ++i) {
        nsCOMPtr<nsIDOMNode> node;
        rv = childNodes->Item(i, getter_AddRefs(node));
        NS_ENSURE_SUCCESS(rv, rv);

        if (node == aChild) {
            *_childNum = i;
            return NS_OK;
        }
    }

    return NS_ERROR_UNEXPECTED;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsTreeWalker::NextInDocumentOrderOf ( nsIDOMNode aNode,
PRBool  aReversed,
PRInt32  aIndexPos,
nsIDOMNode **  _retval 
) [private]

Definition at line 423 of file nsTreeWalker.cpp.

{
    nsresult rv;

    if (!aReversed) {
        rv = FirstChildOf(aNode, aReversed, aIndexPos+1, _retval);
        NS_ENSURE_SUCCESS(rv, rv);

        if (*_retval)
            return NS_OK;
    }

    if (aNode == mRoot){
        *_retval = nsnull;
        return NS_OK;
    }

    nsCOMPtr<nsIDOMNode> node(aNode);
    nsCOMPtr<nsIDOMNode> currentNodeBackup(mCurrentNode);
    PRInt16 filtered;
    PRInt32 childNum;

    while (1) {
        nsCOMPtr<nsIDOMNode> parent;

        // Get our index in the parent
        rv = node->GetParentNode(getter_AddRefs(parent));
        NS_ENSURE_SUCCESS(rv, rv);

        if (!parent)
            break;

        rv = IndexOf(parent, node, aIndexPos, &childNum);
        NS_ENSURE_SUCCESS(rv, rv);

        // Search siblings
        nsCOMPtr<nsIDOMNode> sibling;
        ChildOf(parent, childNum, aReversed, aIndexPos, getter_AddRefs(sibling));
        NS_ENSURE_SUCCESS(rv, rv);

        if (sibling) {
            if (aReversed) {
                // in reversed walking we first test if there are
                // any children. I don't like this piece of code :(
                nsCOMPtr<nsIDOMNode> child(sibling);
                while(child) {
                    sibling = child;
                    rv = FirstChildOf(sibling,
                                      PR_TRUE,
                                      aIndexPos,
                                      getter_AddRefs(child));
                    if (NS_FAILED(rv)) {
                        // ChildOf set mCurrentNode and then something
                        // failed. Restore the old value before returning
                        mCurrentNode = currentNodeBackup;
                        mPossibleIndexesPos = -1;
                        return rv;
                    }
                }
            }
            *_retval = sibling;
            NS_ADDREF(*_retval);
            return NS_OK;
        }

        aIndexPos = aIndexPos < 0 ? -1 : aIndexPos-1;

        if (aReversed) {
            // Is parent transparent in filtered view?
            rv = TestNode(parent, &filtered);
            NS_ENSURE_SUCCESS(rv, rv);
            if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT) {
                mCurrentNode = parent;
                mPossibleIndexesPos = aIndexPos;
                *_retval = parent;
                NS_ADDREF(*_retval);
                return NS_OK;
            }
        }

        // Is parent the root?
        if (parent == mRoot)
            break;

        node = parent;
    }

    *_retval = nsnull;
    return NS_OK;
}

Here is the call graph for this function:

nsresult nsTreeWalker::NextSiblingOf ( nsIDOMNode aNode,
PRBool  aReversed,
PRInt32  aIndexPos,
nsIDOMNode **  _retval 
) [private]

Definition at line 359 of file nsTreeWalker.cpp.

{
    nsresult rv;
    nsCOMPtr<nsIDOMNode> node(aNode);
    PRInt16 filtered;
    PRInt32 childNum;

    if (node == mRoot) {
        *_retval = nsnull;
        return NS_OK;
    }

    while (1) {
        nsCOMPtr<nsIDOMNode> parent;

        // Get our index in the parent
        rv = node->GetParentNode(getter_AddRefs(parent));
        NS_ENSURE_SUCCESS(rv, rv);

        if (!parent)
            break;

        rv = IndexOf(parent, node, aIndexPos, &childNum);
        NS_ENSURE_SUCCESS(rv, rv);

        // Search siblings
        ChildOf(parent, childNum, aReversed, aIndexPos, _retval);
        NS_ENSURE_SUCCESS(rv, rv);

        if (*_retval)
            return NS_OK;

        // Is parent the root?
        if (parent == mRoot)
            break;

        // Is parent transparent in filtered view?
        rv = TestNode(parent, &filtered);
        NS_ENSURE_SUCCESS(rv, rv);
        if (filtered == nsIDOMNodeFilter::FILTER_ACCEPT)
            break;

        node = parent;
        aIndexPos = aIndexPos < 0 ? -1 : aIndexPos-1;
    }

    *_retval = nsnull;
    return NS_OK;
}

Here is the call graph for this function:

void nsTreeWalker::SetChildIndex ( PRInt32  aIndexPos,
PRInt32  aChildIndex 
) [private]

Definition at line 723 of file nsTreeWalker.cpp.

{
    mPossibleIndexes.ReplaceElementAt(NS_INT32_TO_PTR(aChildIndex), aIndexPos);
}

Here is the caller graph for this function:

nsresult nsTreeWalker::TestNode ( nsIDOMNode aNode,
PRInt16 _filtered 
) [private]

Definition at line 608 of file nsTreeWalker.cpp.

{
    nsresult rv;
    PRUint16 nodeType;
    PRUint32 mask = 1;

    rv = aNode->GetNodeType(&nodeType);
    NS_ENSURE_SUCCESS(rv, rv);

    if (nodeType <= 12 && !((mask << (nodeType-1)) & mWhatToShow)) {
        *_filtered = nsIDOMNodeFilter::FILTER_SKIP;

        return NS_OK;
    }

    nsCOMPtr<nsIDOMNodeFilter> filter = mFilter.Get();
    if (filter)
        return filter->AcceptNode(aNode, _filtered);

    *_filtered = nsIDOMNodeFilter::FILTER_ACCEPT;
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Member Data Documentation

Definition at line 53 of file nsIDOMTreeWalker.idl.

Definition at line 52 of file nsIDOMTreeWalker.idl.

Definition at line 51 of file nsIDOMTreeWalker.idl.

Definition at line 76 of file nsTreeWalker.h.

Definition at line 75 of file nsTreeWalker.h.

Definition at line 74 of file nsTreeWalker.h.

nsAutoVoidArray nsTreeWalker::mPossibleIndexes [private]

Definition at line 83 of file nsTreeWalker.h.

Definition at line 88 of file nsTreeWalker.h.

Definition at line 72 of file nsTreeWalker.h.

Definition at line 73 of file nsTreeWalker.h.

Definition at line 49 of file nsIDOMTreeWalker.idl.

readonly attribute unsigned long nsIDOMTreeWalker::whatToShow [inherited]

Definition at line 50 of file nsIDOMTreeWalker.idl.


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