Back to index

lightning-sunbird  0.9+nobinonly
Public Types | Public Member Functions | Static Public Attributes | Protected Member Functions | Protected Attributes
nsXULDocument::OverlayForwardReference Class Reference

Used to hook up overlays. More...

#include <nsXULDocument.h>

Inheritance diagram for nsXULDocument::OverlayForwardReference:
Inheritance graph
Collaboration diagram for nsXULDocument::OverlayForwardReference:
Collaboration graph

List of all members.

Public Types

enum  Phase { eStart, eConstruction, eHookup, eDone }
 Priority codes returned from GetPhase() More...
enum  Result { eResolve_Succeeded, eResolve_Later, eResolve_Error }
 Result codes returned from Resolve() More...

Public Member Functions

 OverlayForwardReference (nsXULDocument *aDocument, nsIContent *aOverlay)
virtual ~OverlayForwardReference ()
virtual Phase GetPhase ()
 Get the state in which the forward reference should be resolved.
virtual Result Resolve ()
 Attempt to resolve the forward reference.

Static Public Attributes

static const Phase kPasses []
 Forward references are categorized by 'priority', and all forward references in a higher priority are resolved before any reference in a lower priority.

Protected Member Functions

nsresult Merge (nsIContent *aTargetNode, nsIContent *aOverlayNode, PRBool aNotify)

Protected Attributes

nsCOMPtr< nsIContentmOverlay
PRBool mResolved

Detailed Description

Used to hook up overlays.

Definition at line 448 of file nsXULDocument.h.

Member Enumeration Documentation

enum nsForwardReference::Phase [inherited]

Priority codes returned from GetPhase()


A dummy marker, used to indicate unstarted resolution.


The initial pass, after which the content model will be fully built.


A second pass, after which all 'magic attribute' hookup will have been performed.


A dummy marker, used in kPasses to indicate termination.

Definition at line 53 of file nsForwardReference.h.

enum nsForwardReference::Result [inherited]

Result codes returned from Resolve()


Resolution succeeded, I'm done.


Couldn't resolve, but try me later.


Something bad happened, don't try again.

Definition at line 89 of file nsForwardReference.h.

Constructor & Destructor Documentation

Definition at line 458 of file nsXULDocument.h.

            : mDocument(aDocument), mOverlay(aOverlay), mResolved(PR_FALSE) {}

Definition at line 4211 of file nsXULDocument.cpp.

    if (PR_LOG_TEST(gXULLog, PR_LOG_WARNING) && !mResolved) {
        nsAutoString id;
        mOverlay->GetAttr(kNameSpaceID_None, nsXULAtoms::id, id);

        nsCAutoString idC;
               ("xul: overlay failed to resolve '%s'",

Here is the call graph for this function:

Member Function Documentation

Get the state in which the forward reference should be resolved.

'eConstruction' references are all resolved before 'eHookup' references are resolved.

the Phase in which the reference needs to be resolved

Implements nsForwardReference.

Definition at line 463 of file nsXULDocument.h.

{ return eConstruction; }
nsresult nsXULDocument::OverlayForwardReference::Merge ( nsIContent aTargetNode,
nsIContent aOverlayNode,
PRBool  aNotify 
) [protected]

Definition at line 4074 of file nsXULDocument.cpp.

    // This function is given:
    // aTargetNode:  the node in the document whose 'id' attribute
    //               matches a toplevel node in our overlay.
    // aOverlayNode: the node in the overlay document that matches
    //               a node in the actual document.
    // aNotify:      whether or not content manipulation methods should
    //               use the aNotify parameter. After the initial 
    //               reflow (i.e. in the dynamic overlay merge case),
    //               we want all the content manipulation methods we
    //               call to notify so that frames are constructed 
    //               etc. Otherwise do not, since that's during initial
    //               document construction before StartLayout has been
    //               called which will do everything for us.
    // This function merges the tree from the overlay into the tree in
    // the document, overwriting attributes and appending child content
    // nodes appropriately. (See XUL overlay reference for details)

    nsresult rv;

    // Merge attributes from the overlay content node to that of the
    // actual document.
    PRUint32 i, attrCount = aOverlayNode->GetAttrCount();

    for (i = 0; i < attrCount; ++i) {
        PRInt32 nameSpaceID;
        nsCOMPtr<nsIAtom> attr, prefix;
        rv = aOverlayNode->GetAttrNameAt(i, &nameSpaceID,
        if (NS_FAILED(rv)) return rv;

        // We don't want to swap IDs, they should be the same.
        if (nameSpaceID == kNameSpaceID_None && attr.get() == nsXULAtoms::id)

        nsAutoString value;
        rv = aOverlayNode->GetAttr(nameSpaceID, attr, value);
        if (NS_FAILED(rv)) return rv;

        // Element in the overlay has the 'removeelement' attribute set
        // so remove it from the actual document.
        if (attr == nsXULAtoms::removeelement &&
            value.EqualsLiteral("true")) {

            rv = RemoveElement(aTargetNode->GetParent(), aTargetNode);
            if (NS_FAILED(rv)) return rv;

            return NS_OK;

        rv = aTargetNode->SetAttr(nameSpaceID, attr, prefix, value, aNotify);
        if (NS_FAILED(rv)) return rv;

    // Walk our child nodes, looking for elements that have the 'id'
    // attribute set. If we find any, we must do a parent check in the
    // actual document to ensure that the structure matches that of
    // the actual document. If it does, we can call ourselves and attempt
    // to merge inside that subtree. If not, we just append the tree to
    // the parent like any other.

    PRUint32 childCount = aOverlayNode->GetChildCount();

    // This must be a strong reference since it will be the only
    // reference to a content object during part of this loop.
    nsCOMPtr<nsIContent> currContent;

    for (i = 0; i < childCount; ++i) {
        currContent = aOverlayNode->GetChildAt(0);

        nsAutoString id;
        rv = currContent->GetAttr(kNameSpaceID_None, nsXULAtoms::id, id);
        if (NS_FAILED(rv)) return rv;

        nsCOMPtr<nsIDOMElement> nodeInDocument;
        if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
            nsCOMPtr<nsIDOMDocument> domDocument(
            if (!domDocument) return NS_ERROR_FAILURE;

            rv = domDocument->GetElementById(id, getter_AddRefs(nodeInDocument));
            if (NS_FAILED(rv)) return rv;

        // The item has an 'id' attribute set, and we need to check with
        // the actual document to see if an item with this id exists at
        // this locale. If so, we want to merge the subtree under that
        // node. Otherwise, we just do an append as if the element had
        // no id attribute.
        if (nodeInDocument) {
            // Given two parents, aTargetNode and aOverlayNode, we want
            // to call merge on currContent if we find an associated
            // node in the document with the same id as currContent that
            // also has aTargetNode as its parent.

            nsAutoString documentParentID;
            rv = aTargetNode->GetAttr(kNameSpaceID_None, nsXULAtoms::id,
            if (NS_FAILED(rv)) return rv;

            nsCOMPtr<nsIDOMNode> nodeParent;
            rv = nodeInDocument->GetParentNode(getter_AddRefs(nodeParent));
            if (NS_FAILED(rv)) return rv;
            nsCOMPtr<nsIDOMElement> elementParent(do_QueryInterface(nodeParent));

            nsAutoString parentID;
            elementParent->GetAttribute(NS_LITERAL_STRING("id"), parentID);
            if (parentID.Equals(documentParentID)) {
                // The element matches. "Go Deep!"
                nsCOMPtr<nsIContent> childDocumentContent(do_QueryInterface(nodeInDocument));
                rv = Merge(childDocumentContent, currContent, aNotify);
                if (NS_FAILED(rv)) return rv;
                rv = aOverlayNode->RemoveChildAt(0, PR_FALSE);
                if (NS_FAILED(rv)) return rv;


        rv = aOverlayNode->RemoveChildAt(0, PR_FALSE);
        if (NS_FAILED(rv)) return rv;

        rv = InsertElement(aTargetNode, currContent, aNotify);
        if (NS_FAILED(rv)) return rv;

    return NS_OK;

Here is the call graph for this function:

Attempt to resolve the forward reference.

a Result that tells the resolver how to treat the reference.

Implements nsForwardReference.

Definition at line 4010 of file nsXULDocument.cpp.

    // Resolve a forward reference from an overlay element; attempt to
    // hook it up into the main document.
    nsresult rv;
    PRBool notify = PR_FALSE;
    nsIPresShell *shell = mDocument->GetShellAt(0);
    if (shell)

    nsAutoString id;
    rv = mOverlay->GetAttr(kNameSpaceID_None, nsXULAtoms::id, id);
    if (NS_FAILED(rv)) return eResolve_Error;

    if (id.IsEmpty()) {
        // overlay had no id, use the root element
        if (!mDocument->mRootContent) {
            return eResolve_Error;

        mDocument->InsertElement(mDocument->mRootContent, mOverlay, notify);
        mResolved = PR_TRUE;
        return eResolve_Succeeded;

    nsCOMPtr<nsIDOMElement> domtarget;
    rv = mDocument->GetElementById(id, getter_AddRefs(domtarget));
    if (NS_FAILED(rv)) return eResolve_Error;

    // If we can't find the element in the document, defer the hookup
    // until later.
    if (! domtarget)
        return eResolve_Later;

    nsCOMPtr<nsIContent> target = do_QueryInterface(domtarget);
    NS_ASSERTION(target != nsnull, "not an nsIContent");
    if (! target)
        return eResolve_Error;

    rv = Merge(target, mOverlay, notify);
    if (NS_FAILED(rv)) return eResolve_Error;

    // Add child and any descendants to the element map
    rv = mDocument->AddSubtreeToDocument(target);
    if (NS_FAILED(rv)) return eResolve_Error;

        nsCAutoString idC;
               ("xul: overlay resolved '%s'",

    mResolved = PR_TRUE;
    return eResolve_Succeeded;

Here is the call graph for this function:

Member Data Documentation

Initial value:

Forward references are categorized by 'priority', and all forward references in a higher priority are resolved before any reference in a lower priority.

This variable specifies this ordering. The last Priority is guaranteed to be eDone.

Definition at line 75 of file nsForwardReference.h.

Definition at line 451 of file nsXULDocument.h.

Definition at line 452 of file nsXULDocument.h.

Definition at line 453 of file nsXULDocument.h.

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