Back to index

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

List of all members.

Public Member Functions

NS_IMETHOD CreateContents (nsIContent *aElement)
virtual void AttributeChanged (nsIDocument *aDocument, nsIContent *aContent, PRInt32 aNameSpaceID, nsIAtom *aAttribute, PRInt32 aModType)
 Notification that the content model has changed.
void DocumentWillBeDestroyed (nsIDocument *aDocument)
 The document is in the process of being destroyed.
NS_DECL_NSIRDFOBSERVER nsresult ComputeContainmentProperties ()
nsresult GetTemplateRoot (nsIContent **aResult)
 Find the <template> tag that applies for this builder.
nsresult CompileRules ()
 Compile the template's rules.
nsresult CompileExtendedRule (nsIContent *aRuleElement, PRInt32 aPriority, InnerNode *aParentNode)
 Compile a rule that's specified using the extended template syntax.
nsresult CompileConditions (nsTemplateRule *aRule, nsIContent *aConditions, InnerNode *aParentNode, InnerNode **aLastNode)
 Compile the <conditions> of a rule that uses the extended template syntax.
nsresult CompileTripleCondition (nsTemplateRule *aRule, nsIContent *aCondition, InnerNode *aParentNode, TestNode **aResult)
 Compile a <triple> condition.
nsresult CompileMemberCondition (nsTemplateRule *aRule, nsIContent *aCondition, InnerNode *aParentNode, TestNode **aResult)
 Compile a <member> condition.
nsresult CompileBindings (nsTemplateRule *aRule, nsIContent *aBindings)
 Compile the <bindings> for an extended template syntax rule.
nsresult CompileBinding (nsTemplateRule *aRule, nsIContent *aBinding)
 Compile a single binding for an extended template syntax rule.
nsresult CompileSimpleRule (nsIContent *aRuleElement, PRInt32 aPriorty, InnerNode *aParentNode)
 Compile a rule that's specified using the simple template syntax.
nsresult ParseLiteral (const nsString &aParseType, const nsString &aValue, nsIRDFNode **aResult)
 Parse the value of a property test assertion for a condition or a simple rule based on the parseType attribute into the appropriate literal type.
nsresult AddSimpleRuleBindings (nsTemplateRule *aRule, nsIContent *aElement)
 Add automatic bindings for simple rules.
void ParseAttribute (const nsAString &aAttributeValue, void(*aVariableCallback)(nsXULTemplateBuilder *aThis, const nsAString &, void *), void(*aTextCallback)(nsXULTemplateBuilder *aThis, const nsAString &, void *), void *aClosure)
nsresult LoadDataSources (nsIDocument *aDoc)
nsresult InitHTMLTemplateRoot ()
nsresult SubstituteText (nsTemplateMatch &aMatch, const nsAString &aAttributeValue, nsAString &aResult)
PRBool IsAttrImpactedByVars (nsTemplateMatch &aMatch, const nsAString &aAttributeValue, const VariableSet &aModifiedVars)
nsresult SynchronizeAll (nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aOldTarget, nsIRDFNode *aNewTarget)
nsresult Propagate (nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget, nsClusterKeySet &aNewKeys)
nsresult FireNewlyMatchedRules (const nsClusterKeySet &aNewKeys)
nsresult Retract (nsIRDFResource *aSource, nsIRDFResource *aProperty, nsIRDFNode *aTarget)
nsresult CheckContainer (nsIRDFResource *aTargetResource, PRBool *aIsContainer, PRBool *aIsEmpty)
nsresult IsSystemPrincipal (nsIPrincipal *principal, PRBool *result)
void rebuild ()
 Force the template builder to rebuild its content.
void refresh ()
 Reload any of our RDF datasources that support nsIRDFRemoteDatasource.
void init (in nsIContent_ptr aElement)
 Called to initialize a XUL content builder on a particular root element.
void createContents (in nsIContent_ptr aElement)
 Invoked lazily by a XUL element that needs its child content built.
void addListener (in nsIXULBuilderListener aListener)
 Add a listener to this template builder.
void removeListener (in nsIXULBuilderListener aListener)
 Remove a listener from this template builder.
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 ContentAppended (nsIDocument *aDocument, nsIContent *aContainer, PRInt32 aNewIndexInContainer)=0
 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)=0
 Notification that content has been inserted.
virtual void ContentRemoved (nsIDocument *aDocument, nsIContent *aContainer, nsIContent *aChild, PRInt32 aIndexInContainer)=0
 Content has just been removed.
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.
void onAssert (in nsIRDFDataSource aDataSource, in nsIRDFResource aSource, in nsIRDFResource aProperty, in nsIRDFNode aTarget)
 This method is called whenever a new assertion is made in the data source.
void onUnassert (in nsIRDFDataSource aDataSource, in nsIRDFResource aSource, in nsIRDFResource aProperty, in nsIRDFNode aTarget)
 This method is called whenever an assertion is removed from the data source.
void onChange (in nsIRDFDataSource aDataSource, in nsIRDFResource aSource, in nsIRDFResource aProperty, in nsIRDFNode aOldTarget, in nsIRDFNode aNewTarget)
 This method is called when the object of an assertion changes from one value to another.
void onMove (in nsIRDFDataSource aDataSource, in nsIRDFResource aOldSource, in nsIRDFResource aNewSource, in nsIRDFResource aProperty, in nsIRDFNode aTarget)
 This method is called when the subject of an assertion changes from one value to another.
void onBeginUpdateBatch (in nsIRDFDataSource aDataSource)
 This method is called when a datasource is about to send several notifications at once.
void onEndUpdateBatch (in nsIRDFDataSource aDataSource)
 This method is called when a datasource has completed issuing a notification group.

Static Public Member Functions

static PRBool IsTemplateElement (nsIContent *aContent)
static void AddBindingsFor (nsXULTemplateBuilder *aSelf, const nsAString &aVariable, void *aClosure)
static void SubstituteTextAppendText (nsXULTemplateBuilder *aThis, const nsAString &aText, void *aClosure)
static void SubstituteTextReplaceVariable (nsXULTemplateBuilder *aThis, const nsAString &aVariable, void *aClosure)
static void IsVarInSet (nsXULTemplateBuilder *aThis, const nsAString &aVariable, void *aClosure)

Public Attributes

nsRuleNetwork mRules
PRInt32 mContainerVar
nsString mContainerSymbol
PRInt32 mMemberVar
nsString mMemberSymbol
nsConflictSet mConflictSet
ReteNodeSet mRDFTests
readonly attribute nsIDOMElement root
 The ``root'' node in the DOM to which this builder is attached.
readonly attribute
nsIRDFCompositeDataSource 
database
 The composite datasource that the template builder observes and uses to create content.

Protected Types

enum  { eDontTestEmpty = (1 << 0) }

Protected Member Functions

 nsXULContentBuilder ()
virtual ~nsXULContentBuilder ()
nsresult Init ()
nsresult OpenContainer (nsIContent *aElement)
nsresult CloseContainer (nsIContent *aElement)
PRBool IsIgnoreableAttribute (PRInt32 aNameSpaceID, nsIAtom *aAtom)
nsresult BuildContentFromTemplate (nsIContent *aTemplateNode, nsIContent *aResourceNode, nsIContent *aRealNode, PRBool aIsUnique, nsIRDFResource *aChild, PRBool aNotify, nsTemplateMatch *aMatch, nsIContent **aContainer, PRInt32 *aNewIndexInContainer)
nsresult AddPersistentAttributes (nsIContent *aTemplateNode, nsIRDFResource *aResource, nsIContent *aRealNode)
nsresult SynchronizeUsingTemplate (nsIContent *aTemplateNode, nsIContent *aRealNode, nsTemplateMatch &aMatch, const VariableSet &aModifiedVars)
PRBool IsDirectlyContainedBy (nsIContent *aChild, nsIContent *aParent)
nsresult RemoveMember (nsIContent *aContainerElement, nsIRDFResource *aMember, PRBool aNotify)
nsresult CreateTemplateAndContainerContents (nsIContent *aElement, nsIContent **aContainer, PRInt32 *aNewIndexInContainer)
nsresult CreateContainerContents (nsIContent *aElement, nsIRDFResource *aResource, PRBool aNotify, nsIContent **aContainer, PRInt32 *aNewIndexInContainer)
nsresult CreateTemplateContents (nsIContent *aElement, nsIContent *aTemplateElement, nsIContent **aContainer, PRInt32 *aNewIndexInContainer)
nsresult EnsureElementHasGenericChild (nsIContent *aParent, PRInt32 aNameSpaceID, nsIAtom *aTag, PRBool aNotify, nsIContent **aResult)
PRBool IsOpen (nsIContent *aElement)
nsresult RemoveGeneratedContent (nsIContent *aElement)
PRBool IsLazyWidgetItem (nsIContent *aElement)
nsresult GetElementsForResource (nsIRDFResource *aResource, nsISupportsArray *aElements)
nsresult CreateElement (PRInt32 aNameSpaceID, nsIAtom *aTag, nsIContent **aResult)
nsresult SetContainerAttrs (nsIContent *aElement, const nsTemplateMatch *aMatch)
virtual nsresult InitializeRuleNetwork ()
 Initialize the rule network.
virtual nsresult InitializeRuleNetworkForSimpleRules (InnerNode **aChildNode)
 Initialize the rule network for handling rules that use the ``simple'' syntax.
virtual nsresult RebuildAll ()
virtual nsresult CompileCondition (nsIAtom *aTag, nsTemplateRule *aRule, nsIContent *aCondition, InnerNode *aParentNode, TestNode **aResult)
 Compile a single condition from an extended template syntax rule.
nsresult CompileContentCondition (nsTemplateRule *aRule, nsIContent *aCondition, InnerNode *aParentNode, TestNode **aResult)
virtual PRBool CompileSimpleAttributeCondition (PRInt32 aNameSpaceID, nsIAtom *aAttribute, const nsAString &aValue, InnerNode *aParentNode, TestNode **aResult)
 Override default implementation to provide for ``parent'' test.
virtual nsresult ReplaceMatch (nsIRDFResource *aMember, const nsTemplateMatch *aOldMatch, nsTemplateMatch *aNewMatch)
 Must be implemented by subclasses.
virtual nsresult SynchronizeMatch (nsTemplateMatch *aMatch, const VariableSet &aModifiedVars)
 Must be implemented by subclasses.
PRBool IsActivated (nsIRDFResource *aResource)
 Determine if a resource is currently on the activation stack.

Protected Attributes

nsContentSupportMap mContentSupportMap
 Maintains a mapping between elements in the DOM and the matches in the conflict set that they support.
PRInt32 mContentVar
 The variable that represents the ``resource element'' in the rules for this builder.
nsTemplateMap mTemplateMap
 Maintains a mapping from an element in the DOM to the template element that it was created from.
nsRDFSortState sortState
 Information about the currently active sort.
nsCOMPtr< nsIRDFDataSourcemDB
nsCOMPtr
< nsIRDFCompositeDataSource
mCompDB
nsCOMPtr< nsIContentmRoot
nsCOMPtr< nsIRDFDataSourcemCache
nsCOMArray< nsIXULBuilderListenermListeners
PRInt32 mUpdateBatchNest
nsResourceSet mContainmentProperties
PRBool mRulesCompiled
PRInt32 mFlags
ActivationEntrymTop
 The top of the stack of resources that we're currently building content for.

Static Protected Attributes

static PRInt32 gRefCnt
static nsIXULSortServicegXULSortService
static nsIRDFServicegRDFService
static nsIRDFContainerUtilsgRDFContainerUtils
static nsIScriptSecurityManagergScriptSecurityManager
static nsIPrincipalgSystemPrincipal

Friends

NS_IMETHODIMP NS_NewXULContentBuilder (nsISupports *aOuter, REFNSIID aIID, void **aResult)

Detailed Description

Definition at line 122 of file nsXULContentBuilder.cpp.


Member Enumeration Documentation

anonymous enum [protected, inherited]
Enumerator:
eDontTestEmpty 

Definition at line 346 of file nsXULTemplateBuilder.h.

         {
        eDontTestEmpty = (1 << 0)
    };

Constructor & Destructor Documentation

Definition at line 319 of file nsXULContentBuilder.cpp.

{
}

Definition at line 323 of file nsXULContentBuilder.cpp.

{
    if (--gRefCnt == 0) {
        NS_IF_RELEASE(gXULSortService);
    }
}

Member Function Documentation

void nsXULTemplateBuilder::AddBindingsFor ( nsXULTemplateBuilder aSelf,
const nsAString &  aVariable,
void aClosure 
) [static, inherited]

Definition at line 2293 of file nsXULTemplateBuilder.cpp.

{
    // We should *only* be recieving "rdf:"-style variables. Make
    // sure...
    if (!StringBeginsWith(aVariable, NS_LITERAL_STRING("rdf:")))
        return;

    nsTemplateRule* rule = NS_STATIC_CAST(nsTemplateRule*, aClosure);

    // Lookup the variable symbol
    PRInt32 var = aThis->mRules.LookupSymbol(PromiseFlatString(aVariable).get(), PR_TRUE);

    // Strip it down to the raw RDF property by clobbering the "rdf:"
    // prefix
    const nsAString& propertyStr = Substring(aVariable, PRUint32(4), aVariable.Length() - 4);

    nsCOMPtr<nsIRDFResource> property;
    gRDFService->GetUnicodeResource(propertyStr, getter_AddRefs(property));

    if (! rule->HasBinding(aThis->mMemberVar, property, var))
        // In the simple syntax, the binding is always from the
        // member variable, through the property, to the target.
        rule->AddBinding(aThis->mMemberVar, property, var);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Add a listener to this template builder.

The template builder holds a strong reference to the listener.

nsresult nsXULContentBuilder::AddPersistentAttributes ( nsIContent aTemplateNode,
nsIRDFResource aResource,
nsIContent aRealNode 
) [protected]

Definition at line 822 of file nsXULContentBuilder.cpp.

{
    nsresult rv;

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

    if (rv != NS_CONTENT_ATTR_HAS_VALUE)
        return NS_OK;

    nsAutoString attribute;
    while (!persist.IsEmpty()) {
        attribute.Truncate();

        PRInt32 offset = persist.FindCharInSet(" ,");
        if (offset > 0) {
            persist.Left(attribute, offset);
            persist.Cut(0, offset + 1);
        }
        else {
            attribute = persist;
            persist.Truncate();
        }

        attribute.Trim(" ");

        if (attribute.IsEmpty())
            break;

        nsCOMPtr<nsIAtom> tag;
        PRInt32 nameSpaceID;

        nsCOMPtr<nsINodeInfo> ni =
            aTemplateNode->GetExistingAttrNameFromQName(attribute);
        if (ni) {
            tag = ni->NameAtom();
            nameSpaceID = ni->NamespaceID();
        }
        else {
            tag = do_GetAtom(attribute);
            NS_ENSURE_TRUE(tag, NS_ERROR_OUT_OF_MEMORY);

            nameSpaceID = kNameSpaceID_None;
        }

        nsCOMPtr<nsIRDFResource> property;
        rv = nsXULContentUtils::GetResource(nameSpaceID, tag, getter_AddRefs(property));
        if (NS_FAILED(rv)) return rv;

        nsCOMPtr<nsIRDFNode> target;
        rv = mDB->GetTarget(aResource, property, PR_TRUE, getter_AddRefs(target));
        if (NS_FAILED(rv)) return rv;

        if (! target)
            continue;

        nsCOMPtr<nsIRDFLiteral> value = do_QueryInterface(target);
        NS_ASSERTION(value != nsnull, "unable to stomach that sort of node");
        if (! value)
            continue;

        const PRUnichar* valueStr;
        rv = value->GetValueConst(&valueStr);
        if (NS_FAILED(rv)) return rv;

        rv = aRealNode->SetAttr(nameSpaceID, tag, nsDependentString(valueStr),
                                PR_FALSE);
        if (NS_FAILED(rv)) return rv;
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Add automatic bindings for simple rules.

Definition at line 2248 of file nsXULTemplateBuilder.cpp.

{
    // Crawl the content tree of a "simple" rule, adding a variable
    // assignment for any attribute whose value is "rdf:".

    nsAutoVoidArray elements;

    elements.AppendElement(aElement);
    while (elements.Count()) {
        // Pop the next element off the stack
        PRUint32 i = (PRUint32)(elements.Count() - 1);
        nsIContent* element = NS_STATIC_CAST(nsIContent*, elements[i]);
        elements.RemoveElementAt(i);

        // Iterate through its attributes, looking for substitutions
        // that we need to add as bindings.
        PRUint32 count = element->GetAttrCount();

        for (i = 0; i < count; ++i) {
            PRInt32 nameSpaceID;
            nsCOMPtr<nsIAtom> attr, prefix;

            element->GetAttrNameAt(i, &nameSpaceID, getter_AddRefs(attr),
                                   getter_AddRefs(prefix));

            nsAutoString value;
            element->GetAttr(nameSpaceID, attr, value);

            // Scan the attribute for variables, adding a binding for
            // each one.
            ParseAttribute(value, AddBindingsFor, nsnull, aRule);
        }

        // Push kids onto the stack, and search them next.
        count = element->GetChildCount();

        while (count-- > 0) {
            elements.AppendElement(element->GetChildAt(count));
        }
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsXULContentBuilder::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.

Reimplemented from nsXULTemplateBuilder.

Definition at line 1547 of file nsXULContentBuilder.cpp.

{
    // Handle "open" and "close" cases. We do this handling before
    // we've notified the observer, so that content is already created
    // for the frame system to walk.
    if ((aContent->GetNameSpaceID() == kNameSpaceID_XUL) &&
        (aAttribute == nsXULAtoms::open)) {
        // We're on a XUL tag, and an ``open'' attribute changed.
        nsAutoString open;
        aContent->GetAttr(kNameSpaceID_None, nsXULAtoms::open, open);

        if (open.EqualsLiteral("true"))
            OpenContainer(aContent);
        else
            CloseContainer(aContent);
    }

    // Pass along to the generic template builder.
    nsXULTemplateBuilder::AttributeChanged(aDocument, aContent, aNameSpaceID,
                                           aAttribute, aModType);
}

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.

nsresult nsXULContentBuilder::BuildContentFromTemplate ( nsIContent aTemplateNode,
nsIContent aResourceNode,
nsIContent aRealNode,
PRBool  aIsUnique,
nsIRDFResource aChild,
PRBool  aNotify,
nsTemplateMatch aMatch,
nsIContent **  aContainer,
PRInt32 aNewIndexInContainer 
) [protected]

Definition at line 363 of file nsXULContentBuilder.cpp.

{
    // This is the mother lode. Here is where we grovel through an
    // element in the template, copying children from the template
    // into the "real" content tree, performing substitution as we go
    // by looking stuff up in the RDF graph.
    //
    //   |aTemplateNode| is the element in the "template tree", whose
    //   children we will duplicate and move into the "real" content
    //   tree.
    //
    //   |aResourceNode| is the element in the "real" content tree that
    //   has the "id" attribute set to an RDF resource's URI. This is
    //   not directly used here, but rather passed down to the XUL
    //   sort service to perform container-level sort.
    //
    //   |aRealNode| is the element in the "real" content tree to which
    //   the new elements will be copied.
    //
    //   |aIsUnique| is set to "true" so long as content has been
    //   "unique" (or "above" the resource element) so far in the
    //   template.
    //
    //   |aChild| is the RDF resource at the end of a property link for
    //   which we are building content.
    //
    //   |aNotify| is set to "true" if content should be constructed
    //   "noisily"; that is, whether the document observers should be
    //   notified when new content is added to the content model.
    //
    //   |aContainer| is an out parameter that will be set to the first
    //   container element in the "real" content tree to which content
    //   was appended.
    //
    //   |aNewIndexInContainer| is an out parameter that will be set to
    //   the index in aContainer at which new content is first
    //   constructed.
    //
    // If |aNotify| is "false", then |aContainer| and
    // |aNewIndexInContainer| are used to determine where in the
    // content model new content is constructed. This allows a single
    // notification to be propagated to document observers.
    //

    nsresult rv;

#ifdef PR_LOGGING
    // Dump out the template node's tag, the template ID, and the RDF
    // resource that is being used as the index into the graph.
    if (PR_LOG_TEST(gXULTemplateLog, PR_LOG_DEBUG)) {
        nsXPIDLCString resourceCStr;
        rv = aChild->GetValue(getter_Copies(resourceCStr));
        if (NS_FAILED(rv)) return rv;

        const char *tagstr;
        aTemplateNode->Tag()->GetUTF8String(&tagstr);

        nsAutoString templatestr;
        aTemplateNode->GetAttr(kNameSpaceID_None, nsXULAtoms::id, templatestr);
        nsCAutoString templatestrC;
        templatestrC.AssignWithConversion(templatestr);
        PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
               ("xultemplate[%p] build-content-from-template %s (template='%s') [%s]",
                this,
                tagstr,
                templatestrC.get(),
                resourceCStr.get()));
    }
#endif

    // Iterate through all of the template children, constructing
    // "real" content model nodes for each "template" child.
    PRUint32 count = aTemplateNode->GetChildCount();

    for (PRUint32 kid = 0; kid < count; kid++) {
        nsIContent *tmplKid = aTemplateNode->GetChildAt(kid);

        PRInt32 nameSpaceID = tmplKid->GetNameSpaceID();

        // Check whether this element is the "resource" element. The
        // "resource" element is the element that is cookie-cutter
        // copied once for each different RDF resource specified by
        // |aChild|.
        //
        // Nodes that appear -above- the resource element
        // (that is, are ancestors of the resource element in the
        // content model) are unique across all values of |aChild|,
        // and are created only once.
        //
        // Nodes that appear -below- the resource element (that is,
        // are descnendants of the resource element in the conte
        // model), are cookie-cutter copied for each distinct value of
        // |aChild|.
        //
        // For example, in a <tree> template:
        //
        //   <tree>
        //     <template>
        //       <treechildren> [1]
        //         <treeitem uri="rdf:*"> [2]
        //           <treerow> [3]
        //             <treecell value="rdf:urn:foo" /> [4]
        //             <treecell value="rdf:urn:bar" /> [5]
        //           </treerow>
        //         </treeitem>
        //       </treechildren>
        //     </template>
        //   </tree>
        //
        // The <treeitem> element [2] is the "resource element". This
        // element, and all of its descendants ([3], [4], and [5])
        // will be duplicated for each different |aChild|
        // resource. It's ancestor <treechildren> [1] is unique, and
        // will only be created -once-, no matter how many <treeitem>s
        // are created below it.
        //
        // Note that |isResourceElement| and |isUnique| are mutually
        // exclusive.
        PRBool isResourceElement = PR_FALSE;
        PRBool isUnique = aIsUnique;

        {
            // We identify the resource element by presence of a
            // "uri='rdf:*'" attribute. (We also support the older
            // "uri='...'" syntax.)
            nsAutoString uri;
            tmplKid->GetAttr(kNameSpaceID_None, nsXULAtoms::uri, uri);

            if ( !uri.IsEmpty() ) {
              if (aMatch->mRule && uri[0] == PRUnichar('?')) {
                  isResourceElement = PR_TRUE;
                  isUnique = PR_FALSE;

                  // XXXwaterson hack! refactor me please
                  Value member;
                  aMatch->mAssignments.GetAssignmentFor(aMatch->mRule->GetMemberVariable(), &member);
                  aChild = VALUE_TO_IRDFRESOURCE(member);
              }
              else if (uri.EqualsLiteral("...") || uri.EqualsLiteral("rdf:*")) {
                  // If we -are- the resource element, then we are no
                  // matter unique.
                  isResourceElement = PR_TRUE;
                  isUnique = PR_FALSE;
              }
            }
        }

        nsIAtom *tag = tmplKid->Tag();

#ifdef PR_LOGGING
        if (PR_LOG_TEST(gXULTemplateLog, PR_LOG_DEBUG)) {
            const char *tagname;
            tag->GetUTF8String(&tagname);
            PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
                   ("xultemplate[%p]     building %s %s %s",
                    this, tagname,
                    (isResourceElement ? "[resource]" : ""),
                    (isUnique ? "[unique]" : "")));
        }
#endif

        // Set to PR_TRUE if the child we're trying to create now
        // already existed in the content model.
        PRBool realKidAlreadyExisted = PR_FALSE;

        nsCOMPtr<nsIContent> realKid;
        if (isUnique) {
            // The content is "unique"; that is, we haven't descended
            // far enough into the tempalte to hit the "resource"
            // element yet. |EnsureElementHasGenericChild()| will
            // conditionally create the element iff it isn't there
            // already.
            rv = EnsureElementHasGenericChild(aRealNode, nameSpaceID, tag, aNotify, getter_AddRefs(realKid));
            if (NS_FAILED(rv)) return rv;

            if (rv == NS_RDF_ELEMENT_WAS_THERE) {
                realKidAlreadyExisted = PR_TRUE;
            }
            else {
                // Mark the element's contents as being generated so
                // that any re-entrant calls don't trigger an infinite
                // recursion.
                nsXULElement *xulcontent = nsXULElement::FromContent(realKid);
                if (xulcontent) {
                    xulcontent->SetLazyState(nsXULElement::eTemplateContentsBuilt);
                }

                // Potentially remember the index of this element as the first
                // element that we've generated. Note that we remember
                // this -before- we recurse!
                if (aContainer && !*aContainer) {
                    *aContainer = aRealNode;
                    NS_ADDREF(*aContainer);

                    PRUint32 indx = aRealNode->GetChildCount();

                    // Since EnsureElementHasGenericChild() added us, make
                    // sure to subtract one for our real index.
                    *aNewIndexInContainer = indx - 1;
                }
            }

            // Recurse until we get to the resource element. Since
            // -we're- unique, assume that our child will be
            // unique. The check for the "resource" element at the top
            // of the function will trip this to |false| as soon as we
            // encounter it.
            rv = BuildContentFromTemplate(tmplKid, aResourceNode, realKid, PR_TRUE,
                                          aChild, aNotify, aMatch,
                                          aContainer, aNewIndexInContainer);

            if (NS_FAILED(rv)) return rv;
        }
        else if (isResourceElement) {
            // It's the "resource" element. Create a new element using
            // the namespace ID and tag from the template element.
            rv = CreateElement(nameSpaceID, tag, getter_AddRefs(realKid));
            if (NS_FAILED(rv)) return rv;

            // Add the resource element to the content support map so
            // we can the match based on content node later.
            mContentSupportMap.Put(realKid, aMatch);

            // Assign the element an 'id' attribute using the URI of
            // the |aChild| resource.
            const char *uri;
            rv = aChild->GetValueConst(&uri);
            NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get resource URI");
            if (NS_FAILED(rv)) return rv;

            // XXX because gcc-2.7.2.3 is too dumb to keep a
            // compiler-generated temporary around.
            NS_ConvertUTF8toUCS2 x(uri);
            const nsAString& id = x;
            rv = realKid->SetAttr(kNameSpaceID_None, nsXULAtoms::id, id, PR_FALSE);
            NS_ASSERTION(NS_SUCCEEDED(rv), "unable to set id attribute");
            if (NS_FAILED(rv)) return rv;

            if (! aNotify) {
                // XUL document will watch us, and take care of making
                // sure that we get added to or removed from the
                // element map if aNotify is true. If not, we gotta do
                // it ourselves. Yay.
                nsCOMPtr<nsIXULDocument> xuldoc =
                    do_QueryInterface(mRoot->GetDocument());
                if (xuldoc)
                    xuldoc->AddElementForID(id, realKid);
            }

            // Set up the element's 'container' and 'empty'
            // attributes.
            PRBool iscontainer, isempty;
            rv = CheckContainer(aChild, &iscontainer, &isempty);
            if (NS_FAILED(rv)) return rv;

            if (iscontainer) {
                realKid->SetAttr(kNameSpaceID_None, nsXULAtoms::container,
                                 NS_LITERAL_STRING("true"), PR_FALSE);

                if (! (mFlags & eDontTestEmpty)) {
                    NS_NAMED_LITERAL_STRING(true_, "true");
                    NS_NAMED_LITERAL_STRING(false_, "false");

                    realKid->SetAttr(kNameSpaceID_None, nsXULAtoms::empty,
                                     isempty ? true_ : false_,
                                     PR_FALSE);
                }
            }
        }
        else if (tag == nsXULAtoms::textnode &&
                 nameSpaceID == kNameSpaceID_XUL) {
            // <xul:text value="..."> is replaced by text of the
            // actual value of the 'rdf:resource' attribute for the
            // given node.
            PRUnichar attrbuf[128];
            nsFixedString attrValue(attrbuf, NS_ARRAY_LENGTH(attrbuf), 0);
            rv = tmplKid->GetAttr(kNameSpaceID_None, nsXULAtoms::value, attrValue);
            if (NS_FAILED(rv)) return rv;

            if ((rv == NS_CONTENT_ATTR_HAS_VALUE) && (!attrValue.IsEmpty())) {
                nsAutoString value;
                rv = SubstituteText(*aMatch, attrValue, value);
                if (NS_FAILED(rv)) return rv;

                nsCOMPtr<nsITextContent> content;
                rv = NS_NewTextNode(getter_AddRefs(content),
                                    mRoot->GetNodeInfo()->NodeInfoManager());
                if (NS_FAILED(rv)) return rv;

                content->SetText(value, PR_FALSE);

                rv = aRealNode->AppendChildTo(content, aNotify);
                if (NS_FAILED(rv)) return rv;

                // XXX Don't bother remembering text nodes as the
                // first element we've generated?
            }
        }
        else if (tmplKid->IsContentOfType(nsIContent::eTEXT)) {
            nsCOMPtr<nsIDOMNode> tmplTextNode = do_QueryInterface(tmplKid);
            if (!tmplTextNode) {
                NS_ERROR("textnode not implementing nsIDOMNode??");
                return NS_ERROR_FAILURE;
            }
            nsCOMPtr<nsIDOMNode> clonedNode;
            tmplTextNode->CloneNode(PR_FALSE, getter_AddRefs(clonedNode));
            nsCOMPtr<nsIContent> clonedContent = do_QueryInterface(clonedNode);
            if (!clonedContent) {
                NS_ERROR("failed to clone textnode");
                return NS_ERROR_FAILURE;
            }
            rv = aRealNode->AppendChildTo(clonedContent, aNotify);
            if (NS_FAILED(rv)) return rv;
        }
        else {
            // It's just a generic element. Create it!
            rv = CreateElement(nameSpaceID, tag, getter_AddRefs(realKid));
            if (NS_FAILED(rv)) return rv;
        }

        if (realKid && !realKidAlreadyExisted) {
            // Potentially remember the index of this element as the
            // first element that we've generated.
            if (aContainer && !*aContainer) {
                *aContainer = aRealNode;
                NS_ADDREF(*aContainer);

                PRUint32 indx = aRealNode->GetChildCount();

                // Since we haven't inserted any content yet, our new
                // index in the container will be the current count of
                // elements in the container.
                *aNewIndexInContainer = indx;
            }

            // Remember the template kid from which we created the
            // real kid. This allows us to sync back up with the
            // template to incrementally build content.
            mTemplateMap.Put(realKid, tmplKid);

            // Copy all attributes from the template to the new
            // element.
            PRUint32 numAttribs = tmplKid->GetAttrCount();

            for (PRUint32 attr = 0; attr < numAttribs; attr++) {
                PRInt32 attribNameSpaceID;
                nsCOMPtr<nsIAtom> attribName, prefix;

                rv = tmplKid->GetAttrNameAt(attr, &attribNameSpaceID,
                                            getter_AddRefs(attribName),
                                            getter_AddRefs(prefix));
                if (NS_FAILED(rv)) return rv;

                if (! IsIgnoreableAttribute(attribNameSpaceID, attribName)) {
                    // Create a buffer here, because there's a good
                    // chance that an attribute in the template is
                    // going to be an RDF URI, which is usually
                    // longish.
                    PRUnichar attrbuf[128];
                    nsFixedString attribValue(attrbuf, NS_ARRAY_LENGTH(attrbuf), 0);
                    rv = tmplKid->GetAttr(attribNameSpaceID, attribName, attribValue);
                    if (NS_FAILED(rv)) return rv;

                    if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
                        nsAutoString value;
                        rv = SubstituteText(*aMatch, attribValue, value);
                        if (NS_FAILED(rv)) return rv;

                        rv = realKid->SetAttr(attribNameSpaceID, attribName, value, PR_FALSE);
                        if (NS_FAILED(rv)) return rv;
                    }
                }
            }

            // Add any persistent attributes
            if (isResourceElement) {
                rv = AddPersistentAttributes(tmplKid, aChild, realKid);
                if (NS_FAILED(rv)) return rv;
            }

            
            nsXULElement *xulcontent = nsXULElement::FromContent(realKid);
            if (xulcontent) {
                PRUint32 count2 = tmplKid->GetChildCount();

                if (count2 == 0 && !isResourceElement) {
                    // If we're at a leaf node, then we'll eagerly
                    // mark the content as having its template &
                    // container contents built. This avoids a useless
                    // trip back to the template builder only to find
                    // that we've got no work to do!
                    xulcontent->SetLazyState(nsXULElement::eTemplateContentsBuilt);
                    xulcontent->SetLazyState(nsXULElement::eContainerContentsBuilt);
                }
                else {
                    // Just mark the XUL element as requiring more work to
                    // be done. We'll get around to it when somebody asks
                    // for it.
                    xulcontent->SetLazyState(nsXULElement::eChildrenMustBeRebuilt);
                }
            }
            else {
                // Otherwise, it doesn't support lazy instantiation,
                // and we have to recurse "by hand". Note that we
                // _don't_ need to notify: we'll add the entire
                // subtree in a single whack.
                //
                // Note that we don't bother passing aContainer and
                // aNewIndexInContainer down: since we're HTML, we
                // -know- that we -must- have just been created.
                rv = BuildContentFromTemplate(tmplKid, aResourceNode, realKid, isUnique,
                                              aChild, PR_FALSE, aMatch,
                                              nsnull /* don't care */,
                                              nsnull /* don't care */);

                if (NS_FAILED(rv)) return rv;

                if (isResourceElement) {
                    rv = CreateContainerContents(realKid, aChild, PR_FALSE,
                                                 nsnull /* don't care */,
                                                 nsnull /* don't care */);
                    if (NS_FAILED(rv)) return rv;
                }
            }

            // We'll _already_ have added the unique elements; but if
            // it's -not- unique, then use the XUL sort service now to
            // append the element to the content model.
            if (! isUnique) {
                rv = NS_ERROR_UNEXPECTED;

                if (gXULSortService && isResourceElement) {
                    rv = gXULSortService->InsertContainerNode(mCompDB, &sortState,
                                                              mRoot, aResourceNode,
                                                              aRealNode, realKid,
                                                              aNotify);
                }

                if (NS_FAILED(rv)) {
                    rv = aRealNode->AppendChildTo(realKid, aNotify);
                    NS_ASSERTION(NS_SUCCEEDED(rv), "unable to insert element");
                }
            }
        }
    }

    return NS_OK;
}

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.

nsresult nsXULTemplateBuilder::CheckContainer ( nsIRDFResource aTargetResource,
PRBool aIsContainer,
PRBool aIsEmpty 
) [inherited]

Definition at line 1246 of file nsXULTemplateBuilder.cpp.

{
    // We have to look at all of the arcs extending out of the
    // resource: if any of them are that "containment" property, then
    // we know we'll have children.
    PRBool isContainer = PR_FALSE;
    PRBool isEmpty = PR_TRUE; // assume empty

    for (nsResourceSet::ConstIterator property = mContainmentProperties.First();
         property != mContainmentProperties.Last();
         property++) {
        PRBool hasArc = PR_FALSE;
        mDB->HasArcOut(aResource, *property, &hasArc);

        if (hasArc) {
            // Well, it's a container...
            isContainer = PR_TRUE;

            // ...should we check if it's empty?
            if (!aIsEmpty || (mFlags & eDontTestEmpty)) {
                isEmpty = PR_FALSE;
                break;
            }

            // Yes: call GetTarget() and see if there's anything on
            // the other side...
            nsCOMPtr<nsIRDFNode> dummy;
            mDB->GetTarget(aResource, *property, PR_TRUE, getter_AddRefs(dummy));

            if (dummy) {
                isEmpty = PR_FALSE;
                break;
            }

            // Even if there isn't a target for *this* containment
            // property, we have continue to check the other
            // properties: one of them may have a target.
        }
    }

    // If we get here, and we're still not sure if it's a container,
    // then see if it's an RDF container
    if (! isContainer) {
        gRDFContainerUtils->IsContainer(mDB, aResource, &isContainer);

        if (isContainer && aIsEmpty && !(mFlags & eDontTestEmpty))
            gRDFContainerUtils->IsEmpty(mDB, aResource, &isEmpty);
    }

    if (aIsContainer)
        *aIsContainer = isContainer;

    if (aIsEmpty)
        *aIsEmpty = isEmpty;

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1785 of file nsXULContentBuilder.cpp.

{
#if 0 // Um, what was this really supposed to do?
    // See if we're responsible for this element
    if (! IsElementInBuilder(aElement, this))
        return NS_OK;
#endif

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXULTemplateBuilder::CompileBinding ( nsTemplateRule aRule,
nsIContent aBinding 
) [inherited]

Compile a single binding for an extended template syntax rule.

Definition at line 2003 of file nsXULTemplateBuilder.cpp.

{
    // Compile a <binding> "condition", which must be of the form:
    //
    //   <binding subject="?var1"
    //            predicate="resource"
    //            object="?var2" />
    //
    // XXXwaterson Some day it would be cool to allow the 'predicate'
    // to be bound to a variable.

    // subject
    nsAutoString subject;
    aBinding->GetAttr(kNameSpaceID_None, nsXULAtoms::subject, subject);

    if (subject.IsEmpty()) {
        PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
               ("xultemplate[%p] <binding> requires `subject'", this));

        return NS_OK;
    }

    PRInt32 svar = 0;
    if (subject[0] == PRUnichar('?')) {
        svar = mRules.LookupSymbol(subject.get(), PR_TRUE);
    }
    else {
        PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
               ("xultemplate[%p] <binding> requires `subject' to be a variable", this));

        return NS_OK;
    }

    // predicate
    nsAutoString predicate;
    aBinding->GetAttr(kNameSpaceID_None, nsXULAtoms::predicate, predicate);
    if (predicate.IsEmpty()) {
        PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
               ("xultemplate[%p] <binding> requires `predicate'", this));

        return NS_OK;
    }

    nsCOMPtr<nsIRDFResource> pred;
    if (predicate[0] == PRUnichar('?')) {
        PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
               ("xultemplate[%p] cannot handle variables in <binding> `predicate'", this));

        return NS_OK;
    }
    else {
        gRDFService->GetUnicodeResource(predicate, getter_AddRefs(pred));
    }

    // object
    nsAutoString object;
    aBinding->GetAttr(kNameSpaceID_None, nsXULAtoms::object, object);

    if (object.IsEmpty()) {
        PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
               ("xultemplate[%p] <binding> requires `object'", this));

        return NS_OK;
    }

    PRInt32 ovar = 0;
    if (object[0] == PRUnichar('?')) {
        ovar = mRules.LookupSymbol(object.get(), PR_TRUE);
    }
    else {
        PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
               ("xultemplate[%p] <binding> requires `object' to be a variable", this));

        return NS_OK;
    }

    return aRule->AddBinding(svar, pred, ovar);
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXULTemplateBuilder::CompileBindings ( nsTemplateRule aRule,
nsIContent aBindings 
) [inherited]

Compile the <bindings> for an extended template syntax rule.

Definition at line 1963 of file nsXULTemplateBuilder.cpp.

{
    // Add an extended rule's bindings.
    nsresult rv;

    PRUint32 count = aBindings->GetChildCount();

    for (PRUint32 i = 0; i < count; ++i) {
        nsIContent *binding = aBindings->GetChildAt(i);

        nsINodeInfo *ni = binding->GetNodeInfo();

        if (ni && ni->Equals(nsXULAtoms::binding, kNameSpaceID_XUL)) {
            rv = CompileBinding(aRule, binding);
        }
        else {
#ifdef PR_LOGGING
            nsAutoString tagstr;
            if (ni) {
                ni->GetQualifiedName(tagstr);
            }

            nsCAutoString tagstrC;
            tagstrC.AssignWithConversion(tagstr);
            PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
                   ("xultemplate[%p] unrecognized binding <%s>",
                    this, tagstrC.get()));
#endif

            continue;
        }

        if (NS_FAILED(rv)) return rv;
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXULContentBuilder::CompileCondition ( nsIAtom aTag,
nsTemplateRule aRule,
nsIContent aConditions,
InnerNode aParentNode,
TestNode **  aResult 
) [protected, virtual]

Compile a single condition from an extended template syntax rule.

Subclasses may override to provide additional, subclass-specific condition processing.

Reimplemented from nsXULTemplateBuilder.

Definition at line 1921 of file nsXULContentBuilder.cpp.

{
    nsresult rv;

    if (aTag == nsXULAtoms::content) {
        rv = CompileContentCondition(aRule, aCondition, aParentNode, aResult);
    }
    else {
        rv = nsXULTemplateBuilder::CompileCondition(aTag, aRule, aCondition, aParentNode, aResult);
    }

    return rv;
}

Here is the call graph for this function:

nsresult nsXULTemplateBuilder::CompileConditions ( nsTemplateRule aRule,
nsIContent aConditions,
InnerNode aParentNode,
InnerNode **  aLastNode 
) [inherited]

Compile the <conditions> of a rule that uses the extended template syntax.

Definition at line 1724 of file nsXULTemplateBuilder.cpp.

{
    // Compile an extended rule's conditions.
    nsresult rv;

    PRUint32 count = aConditions->GetChildCount();

    for (PRUint32 i = 0; i < count; ++i) {
        nsIContent *condition = aConditions->GetChildAt(i);

        TestNode* testnode = nsnull;
        rv = CompileCondition(condition->Tag(), aRule, condition,
                              aParentNode, &testnode);
        if (NS_FAILED(rv)) return rv;

        // XXXwaterson proably wrong to just drill it straight down
        // like this.
        if (testnode) {
            aParentNode->AddChild(testnode);
            mRules.AddNode(testnode);
            aParentNode = testnode;
        }
    }

    *aLastNode = aParentNode;
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXULContentBuilder::CompileContentCondition ( nsTemplateRule aRule,
nsIContent aCondition,
InnerNode aParentNode,
TestNode **  aResult 
) [protected]

Definition at line 1940 of file nsXULContentBuilder.cpp.

{
    // Compile a <content> condition, which currently must be of the form:
    //
    //  <content uri="?var" tag="?tag" />
    //
    // XXXwaterson Right now, exactly one <content> condition is
    // required per rule. It creates a nsContentTestNode, binding the
    // content variable to the global content variable that's used
    // during match propagation. The 'uri' attribute must be set.

    // uri
    nsAutoString uri;
    aCondition->GetAttr(kNameSpaceID_None, nsXULAtoms::uri, uri);

    if (uri[0] != PRUnichar('?')) {
        PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
               ("xultemplate[%p] on <content> test, expected 'uri' attribute to name a variable", this));

        return NS_OK;
    }

    PRInt32 urivar = mRules.LookupSymbol(uri.get());
    if (! urivar) {
        if (mContainerSymbol.IsEmpty()) {
            // If the container symbol was not explictly declared on
            // the <template> tag, or we haven't seen a previous rule
            // whose <content> condition defined it, then we'll
            // implictly define it *now*.
            mContainerSymbol = uri;
            urivar = mContainerVar;
        }
        else
            urivar = mRules.CreateAnonymousVariable();

        mRules.PutSymbol(uri.get(), urivar);
    }

    // tag
    nsCOMPtr<nsIAtom> tag;

    nsAutoString tagstr;
    aCondition->GetAttr(kNameSpaceID_None, nsXULAtoms::tag, tagstr);

    if (!tagstr.IsEmpty()) {
        tag = do_GetAtom(tagstr);
    }

    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(mRoot->GetDocument());
    NS_ASSERTION(xuldoc, "root element has no document");
    if (! xuldoc)
        return NS_ERROR_FAILURE;

    // XXXwaterson By binding the content to the global mContentVar,
    // we're essentially saying that each rule *must* have exactly one
    // <content id="?x"/> condition.
    TestNode* testnode = 
        new nsContentTestNode(aParentNode,
                              mConflictSet,
                              xuldoc,
                              this,
                              mContentVar, // XXX see above
                              urivar,
                              tag);

    if (! testnode)
        return NS_ERROR_OUT_OF_MEMORY;

    *aResult = testnode;
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXULTemplateBuilder::CompileExtendedRule ( nsIContent aRuleElement,
PRInt32  aPriority,
InnerNode aParentNode 
) [inherited]

Compile a rule that's specified using the extended template syntax.

Definition at line 1589 of file nsXULTemplateBuilder.cpp.

{
    // Compile an "extended" <template> rule. An extended rule must
    // have a <conditions> child, and an <action> child, and may
    // optionally have a <bindings> child.
    nsresult rv;

    nsCOMPtr<nsIContent> conditions;
    nsXULContentUtils::FindChildByTag(aRuleElement,
                                      kNameSpaceID_XUL,
                                      nsXULAtoms::conditions,
                                      getter_AddRefs(conditions));

    if (! conditions) {
        PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
               ("xultemplate[%p] no <conditions> element in extended rule", this));

        return NS_OK;
    }

    nsCOMPtr<nsIContent> action;
    nsXULContentUtils::FindChildByTag(aRuleElement,
                                      kNameSpaceID_XUL,
                                      nsXULAtoms::action,
                                      getter_AddRefs(action));

    if (! action) {
        PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
               ("xultemplate[%p] no <action> element in extended rule", this));

        return NS_OK;
    }

    // If we've got <conditions> and <action>, we can make a rule.
    nsTemplateRule* rule = new nsTemplateRule(mDB, action, aPriority);
    if (! rule)
        return NS_ERROR_OUT_OF_MEMORY;

    rule->SetContainerVariable(mContainerVar);

    if (mMemberSymbol.IsEmpty()) {
        // If the member variable hasn't already been specified, then
        // grovel over <action> to find it. We'll use the first one
        // that we find in a breadth-first search.
        nsVoidArray unvisited;
        unvisited.AppendElement(action.get());

        while (unvisited.Count()) {
            nsIContent* next = NS_STATIC_CAST(nsIContent*, unvisited[0]);
            unvisited.RemoveElementAt(0);

            nsAutoString uri;
            next->GetAttr(kNameSpaceID_None, nsXULAtoms::uri, uri);

            if (!uri.IsEmpty() && uri[0] == PRUnichar('?')) {
                // Found it.
                mMemberSymbol = uri;

                if (! mRules.LookupSymbol(mMemberSymbol.get()))
                    mRules.PutSymbol(mMemberSymbol.get(), mMemberVar);

                break;
            }

            // otherwise, append the children to the unvisited list: this
            // results in a breadth-first search.
            PRUint32 count = next->GetChildCount();

            for (PRUint32 i = 0; i < count; ++i) {
                nsIContent *child = next->GetChildAt(i);

                unvisited.AppendElement(child);
            }
        }
    }

    // If we can't find a member symbol, then we're out of luck. Bail.
    if (mMemberSymbol.IsEmpty()) {
        PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
               ("xultemplate[%p] could not deduce member variable", this));

        delete rule;
        return NS_OK;
    }

    rule->SetMemberVariable(mMemberVar);

    InnerNode* last;
    rv = CompileConditions(rule, conditions, aParentNode, &last);

    // If the rule compilation failed, or we don't have a container
    // symbol, then we have to bail.
    if (NS_FAILED(rv)) {
        delete rule;
        return rv;
    }

    if (mContainerSymbol.IsEmpty()) {
        PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
               ("xultemplate[%p] could not deduce container variable", this));

        delete rule;
        return NS_OK;
    }

    // And now add the instantiation node: it owns the rule now.
    nsInstantiationNode* instnode =
        new nsInstantiationNode(mConflictSet, rule, mDB);

    if (! instnode) {
        delete rule;
        return NS_ERROR_OUT_OF_MEMORY;
    }

    last->AddChild(instnode);
    mRules.AddNode(instnode);
    
    // If we've got bindings, add 'em.
    nsCOMPtr<nsIContent> bindings;
    nsXULContentUtils::FindChildByTag(aRuleElement,
                                      kNameSpaceID_XUL,
                                      nsXULAtoms::bindings,
                                      getter_AddRefs(bindings));

    if (bindings) {
        rv = CompileBindings(rule, bindings);
        if (NS_FAILED(rv)) return rv;
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXULTemplateBuilder::CompileMemberCondition ( nsTemplateRule aRule,
nsIContent aCondition,
InnerNode aParentNode,
TestNode **  aResult 
) [inherited]

Compile a <member> condition.

Definition at line 1909 of file nsXULTemplateBuilder.cpp.

{
    // Compile a <member> condition, which must be of the form:
    //
    //   <member container="?var1" child="?var2" />
    //

    // container
    nsAutoString container;
    aCondition->GetAttr(kNameSpaceID_None, nsXULAtoms::container, container);

    if (container[0] != PRUnichar('?')) {
        PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
               ("xultemplate[%p] on <member> test, expected 'container' attribute to name a variable", this));

        return NS_OK;
    }

    PRInt32 containervar = mRules.LookupSymbol(container.get(), PR_TRUE);

    // child
    nsAutoString child;
    aCondition->GetAttr(kNameSpaceID_None, nsXULAtoms::child, child);

    if (child[0] != PRUnichar('?')) {
        PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
               ("xultemplate[%p] on <member> test, expected 'child' attribute to name a variable", this));

        return NS_OK;
    }

    PRInt32 childvar = mRules.LookupSymbol(child.get(), PR_TRUE);

    TestNode* testnode =
        new nsRDFConMemberTestNode(aParentNode,
                                   mConflictSet,
                                   mDB,
                                   mContainmentProperties,
                                   containervar,
                                   childvar);

    if (! testnode)
        return NS_ERROR_OUT_OF_MEMORY;

    mRDFTests.Add(testnode);
    
    *aResult = testnode;
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Compile the template's rules.

Definition at line 1512 of file nsXULTemplateBuilder.cpp.

{
    NS_PRECONDITION(mRoot != nsnull, "not initialized");
    if (! mRoot)
        return NS_ERROR_NOT_INITIALIZED;

    mRulesCompiled = PR_FALSE;

    // Initialize the rule network
    InitializeRuleNetwork();

    nsCOMPtr<nsIContent> tmpl;
    GetTemplateRoot(getter_AddRefs(tmpl));
    if (! tmpl)
        return NS_OK;

    // Used for simple rules, if there are any.
    InnerNode* childnode = nsnull;

    // Set the "container" and "member" variables, if the user has
    // specified them.
    mContainerSymbol.Truncate();
    tmpl->GetAttr(kNameSpaceID_None, nsXULAtoms::container, mContainerSymbol);
    if (!mContainerSymbol.IsEmpty())
        mRules.PutSymbol(mContainerSymbol.get(), mContainerVar);

    mMemberSymbol.Truncate();
    tmpl->GetAttr(kNameSpaceID_None, nsXULAtoms::member, mMemberSymbol);
    if (!mMemberSymbol.IsEmpty())
        mRules.PutSymbol(mMemberSymbol.get(), mMemberVar);

    // Compile the rules beneath the <template>
    PRUint32 count = tmpl->GetChildCount();

    PRUint32 nrules = 0;

    for (PRUint32 i = 0; i < count; i++) {
        nsIContent *rule = tmpl->GetChildAt(i);
        nsINodeInfo *ni = rule->GetNodeInfo();

        if (ni && ni->Equals(nsXULAtoms::rule, kNameSpaceID_XUL)) {
            ++nrules;

            // If the <rule> has a <conditions> element, then
            // compile it using the extended syntax.
            nsCOMPtr<nsIContent> conditions;
            nsXULContentUtils::FindChildByTag(rule,
                                              kNameSpaceID_XUL,
                                              nsXULAtoms::conditions,
                                              getter_AddRefs(conditions));

            if (conditions)
                CompileExtendedRule(rule, nrules, mRules.GetRoot());
            else {
                if (! childnode)
                    InitializeRuleNetworkForSimpleRules(&childnode);

                CompileSimpleRule(rule, nrules, childnode);
            }
        }
    }

    if (nrules == 0) {
        // if no rules are specified in the template, then the
        // contents of the <template> tag are the one-and-only
        // template.
        InitializeRuleNetworkForSimpleRules(&childnode);
        CompileSimpleRule(tmpl, 1, childnode);
    }

    // XXXwaterson post-process the rule network to optimize

    mRulesCompiled = PR_TRUE;
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsXULContentBuilder::CompileSimpleAttributeCondition ( PRInt32  aNameSpaceID,
nsIAtom aAttribute,
const nsAString &  aValue,
InnerNode aParentNode,
TestNode **  aResult 
) [protected, virtual]

Override default implementation to provide for ``parent'' test.

Reimplemented from nsXULTemplateBuilder.

Definition at line 2016 of file nsXULContentBuilder.cpp.

{
    if ((aNameSpaceID == kNameSpaceID_None) && (aAttribute == nsXULAtoms::parent)) {
        // The "parent" test.
        //
        // XXXwaterson this is wrong: we can't add this below the
        // the previous node, because it'll cause an unconstrained
        // search if we ever came "up" through this path. Need a
        // JoinNode in here somewhere.
        nsCOMPtr<nsIAtom> tag = do_GetAtom(aValue);

        *aResult = new nsContentTagTestNode(aParentNode, mConflictSet, mContentVar, tag);
        if (*aResult)
            return PR_TRUE;
    }

    return PR_FALSE;
}

Here is the call graph for this function:

nsresult nsXULTemplateBuilder::CompileSimpleRule ( nsIContent aRuleElement,
PRInt32  aPriorty,
InnerNode aParentNode 
) [inherited]

Compile a rule that's specified using the simple template syntax.

Definition at line 2084 of file nsXULTemplateBuilder.cpp.

{
    // Compile a "simple" (or old-school style) <template> rule.
    nsresult rv;

    PRBool hasContainerTest = PR_FALSE;

    PRUint32 count = aRuleElement->GetAttrCount();

    // Add constraints for the LHS
    for (PRUint32 i = 0; i < count; ++i) {
        PRInt32 attrNameSpaceID;
        nsCOMPtr<nsIAtom> attr, prefix;
        rv = aRuleElement->GetAttrNameAt(i, &attrNameSpaceID,
                                         getter_AddRefs(attr),
                                         getter_AddRefs(prefix));
        if (NS_FAILED(rv)) return rv;

        // Note: some attributes must be skipped on XUL template rule subtree

        // never compare against rdf:property attribute
        if ((attr.get() == nsXULAtoms::property) && (attrNameSpaceID == kNameSpaceID_RDF))
            continue;
        // never compare against rdf:instanceOf attribute
        else if ((attr.get() == nsXULAtoms::instanceOf) && (attrNameSpaceID == kNameSpaceID_RDF))
            continue;
        // never compare against {}:id attribute
        else if ((attr.get() == nsXULAtoms::id) && (attrNameSpaceID == kNameSpaceID_None))
            continue;
        else if ((attr.get() == nsXULAtoms::parsetype) && (attrNameSpaceID == kNameSpaceID_None))
            continue;

        nsAutoString value;
        rv = aRuleElement->GetAttr(attrNameSpaceID, attr, value);
        if (NS_FAILED(rv)) return rv;

        TestNode* testnode = nsnull;

        if (CompileSimpleAttributeCondition(attrNameSpaceID, attr, value, aParentNode, &testnode)) {
            // handled by subclass
        }
        else if (((attrNameSpaceID == kNameSpaceID_None) && (attr.get() == nsXULAtoms::iscontainer)) ||
                 ((attrNameSpaceID == kNameSpaceID_None) && (attr.get() == nsXULAtoms::isempty))) {
            // Tests about containerhood and emptiness. These can be
            // globbed together, mostly. Check to see if we've already
            // added a container test: we only need one.
            if (hasContainerTest)
                continue;

            nsRDFConInstanceTestNode::Test iscontainer =
                nsRDFConInstanceTestNode::eDontCare;

            rv = aRuleElement->GetAttr(kNameSpaceID_None, nsXULAtoms::iscontainer, value);
            if (NS_FAILED(rv)) return rv;

            if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
                if (value.EqualsLiteral("true")) {
                    iscontainer = nsRDFConInstanceTestNode::eTrue;
                }
                else if (value.EqualsLiteral("false")) {
                    iscontainer = nsRDFConInstanceTestNode::eFalse;
                }
            }

            nsRDFConInstanceTestNode::Test isempty =
                nsRDFConInstanceTestNode::eDontCare;

            rv = aRuleElement->GetAttr(kNameSpaceID_None, nsXULAtoms::isempty, value);
            if (NS_FAILED(rv)) return rv;

            if (rv == NS_CONTENT_ATTR_HAS_VALUE) {
                if (value.EqualsLiteral("true")) {
                    isempty = nsRDFConInstanceTestNode::eTrue;
                }
                else if (value.EqualsLiteral("false")) {
                    isempty = nsRDFConInstanceTestNode::eFalse;
                }
            }

            testnode = new nsRDFConInstanceTestNode(aParentNode,
                                                    mConflictSet,
                                                    mDB,
                                                    mContainmentProperties,
                                                    mMemberVar,
                                                    iscontainer,
                                                    isempty);

            if (! testnode)
                return NS_ERROR_OUT_OF_MEMORY;

            mRDFTests.Add(testnode);
        }
        else {
            // It's a simple RDF test
            nsCOMPtr<nsIRDFResource> property;
            rv = nsXULContentUtils::GetResource(attrNameSpaceID, attr, getter_AddRefs(property));
            if (NS_FAILED(rv)) return rv;

            // XXXwaterson this is so manky
            nsCOMPtr<nsIRDFNode> target;
            if (value.FindChar(':') != -1) { // XXXwaterson WRONG WRONG WRONG!
                nsCOMPtr<nsIRDFResource> resource;
                rv = gRDFService->GetUnicodeResource(value, getter_AddRefs(resource));
                if (NS_FAILED(rv)) return rv;

                target = do_QueryInterface(resource);
            }
            else {                
              nsAutoString parseType;
              aRuleElement->GetAttr(kNameSpaceID_None, nsXULAtoms::parsetype, parseType);
              rv = ParseLiteral(parseType, value, getter_AddRefs(target));
              if (NS_FAILED(rv))
                  return rv;
            }

            testnode = new nsRDFPropertyTestNode(aParentNode, mConflictSet, mDB, mMemberVar, property, target);
            if (! testnode)
                return NS_ERROR_OUT_OF_MEMORY;

            mRDFTests.Add(testnode);
        }

        aParentNode->AddChild(testnode);
        mRules.AddNode(testnode);
        aParentNode = testnode;
    }

    // Create the rule.
    nsTemplateRule* rule = new nsTemplateRule(mDB, aRuleElement, aPriority);
    if (! rule)
        return NS_ERROR_OUT_OF_MEMORY;

    rule->SetContainerVariable(mContainerVar);
    rule->SetMemberVariable(mMemberVar);

    AddSimpleRuleBindings(rule, aRuleElement);

    // The InstantiationNode owns the rule now.
    nsInstantiationNode* instnode =
        new nsInstantiationNode(mConflictSet, rule, mDB);

    if (! instnode)
        return NS_ERROR_OUT_OF_MEMORY;

    aParentNode->AddChild(instnode);
    mRules.AddNode(instnode);
    
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXULTemplateBuilder::CompileTripleCondition ( nsTemplateRule aRule,
nsIContent aCondition,
InnerNode aParentNode,
TestNode **  aResult 
) [inherited]

Compile a <triple> condition.

Definition at line 1818 of file nsXULTemplateBuilder.cpp.

{
    // Compile a <triple> condition, which must be of the form:
    //
    //   <triple subject="?var1|resource"
    //           predicate="resource"
    //           object="?var2|resource|literal" />
    //
    // XXXwaterson Some day it would be cool to allow the 'predicate'
    // to be bound to a variable.

    // subject
    nsAutoString subject;
    aCondition->GetAttr(kNameSpaceID_None, nsXULAtoms::subject, subject);

    PRInt32 svar = 0;
    nsCOMPtr<nsIRDFResource> sres;
    if (subject[0] == PRUnichar('?'))
        svar = mRules.LookupSymbol(subject.get(), PR_TRUE);
    else
        gRDFService->GetUnicodeResource(subject, getter_AddRefs(sres));

    // predicate
    nsAutoString predicate;
    aCondition->GetAttr(kNameSpaceID_None, nsXULAtoms::predicate, predicate);

    nsCOMPtr<nsIRDFResource> pres;
    if (predicate[0] == PRUnichar('?')) {
        PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
               ("xultemplate[%p] cannot handle variables in <triple> 'predicate'", this));

        return NS_OK;
    }
    else {
        gRDFService->GetUnicodeResource(predicate, getter_AddRefs(pres));
    }

    // object
    nsAutoString object;
    aCondition->GetAttr(kNameSpaceID_None, nsXULAtoms::object, object);

    PRInt32 ovar = 0;
    nsCOMPtr<nsIRDFNode> onode;
    if (object[0] == PRUnichar('?')) {
        ovar = mRules.LookupSymbol(object.get(), PR_TRUE);
    }
    else if (object.FindChar(':') != -1) { // XXXwaterson evil.
        // treat as resource
        nsCOMPtr<nsIRDFResource> resource;
        gRDFService->GetUnicodeResource(object, getter_AddRefs(resource));
        onode = do_QueryInterface(resource);
    }
    else {
        nsAutoString parseType;
        aCondition->GetAttr(kNameSpaceID_None, nsXULAtoms::parsetype, parseType);
        nsresult rv = ParseLiteral(parseType, object, getter_AddRefs(onode));
        if (NS_FAILED(rv))
            return rv;
    }

    nsRDFPropertyTestNode* testnode = nsnull;

    if (svar && ovar) {
        testnode = new nsRDFPropertyTestNode(aParentNode, mConflictSet, mDB, svar, pres, ovar);
    }
    else if (svar) {
        testnode = new nsRDFPropertyTestNode(aParentNode, mConflictSet, mDB, svar, pres, onode);
    }
    else if (ovar) {
        testnode = new nsRDFPropertyTestNode(aParentNode, mConflictSet, mDB, sres, pres, ovar);
    }
    else {
        PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
               ("xultemplate[%p] tautology in <triple> test", this));

        return NS_OK;
    }

    if (! testnode)
        return NS_ERROR_OUT_OF_MEMORY;

    mRDFTests.Add(testnode);

    *aResult = testnode;
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1343 of file nsXULTemplateBuilder.cpp.

{
    // The 'containment' attribute on the root node is a
    // whitespace-separated list that tells us which properties we
    // should use to test for containment.
    nsresult rv;

    mContainmentProperties.Clear();

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

    PRUint32 len = containment.Length();
    PRUint32 offset = 0;
    while (offset < len) {
        while (offset < len && nsCRT::IsAsciiSpace(containment[offset]))
            ++offset;

        if (offset >= len)
            break;

        PRUint32 end = offset;
        while (end < len && !nsCRT::IsAsciiSpace(containment[end]))
            ++end;

        nsAutoString propertyStr;
        containment.Mid(propertyStr, offset, end - offset);

        nsCOMPtr<nsIRDFResource> property;
        rv = gRDFService->GetUnicodeResource(propertyStr, getter_AddRefs(property));
        if (NS_FAILED(rv)) return rv;

        rv = mContainmentProperties.Add(property);
        if (NS_FAILED(rv)) return rv;

        offset = end;
    }

#define TREE_PROPERTY_HACK 1
#if defined(TREE_PROPERTY_HACK)
    if (! len) {
        // Some ever-present membership tests.
        mContainmentProperties.Add(nsXULContentUtils::NC_child);
        mContainmentProperties.Add(nsXULContentUtils::NC_Folder);
    }
#endif

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual void nsIDocumentObserver::ContentAppended ( nsIDocument aDocument,
nsIContent aContainer,
PRInt32  aNewIndexInContainer 
) [pure virtual, inherited]

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

Implemented in PresShell, nsContentList, nsBindingManager, nsImageMap, nsTreeContentView, and nsXMLPrettyPrinter.

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

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

Implemented in PresShell, nsContentList, nsBindingManager, nsImageMap, nsTreeContentView, and nsXMLPrettyPrinter.

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

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

Implemented in PresShell, nsContentList, nsBindingManager, nsImageMap, nsTreeContentView, and nsXMLPrettyPrinter.

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.

nsresult nsXULContentBuilder::CreateContainerContents ( nsIContent aElement,
nsIRDFResource aResource,
PRBool  aNotify,
nsIContent **  aContainer,
PRInt32 aNewIndexInContainer 
) [protected]

Definition at line 1145 of file nsXULContentBuilder.cpp.

{
    // Avoid re-entrant builds for the same resource.
    if (IsActivated(aResource))
        return NS_OK;

    ActivationEntry entry(aResource, &mTop);

    // Create the contents of a container by iterating over all of the
    // "containment" arcs out of the element's resource.
    nsresult rv;

    // Compile the rules now, if they haven't been already.
    if (! mRulesCompiled) {
        rv = CompileRules();
        if (NS_FAILED(rv)) return rv;
    }
    
    if (aContainer) {
        *aContainer = nsnull;
        *aNewIndexInContainer = -1;
    }

    // The tree widget is special. If the item isn't open, then just
    // "pretend" that there aren't any contents here. We'll create
    // them when OpenContainer() gets called.
    if (IsLazyWidgetItem(aElement) && !IsOpen(aElement))
        return NS_OK;

    // See if the element's templates contents have been generated:
    // this prevents a re-entrant call from triggering another
    // generation.
    nsXULElement *xulcontent = nsXULElement::FromContent(aElement);
    if (xulcontent) {
        if (xulcontent->GetLazyState(nsXULElement::eContainerContentsBuilt))
            return NS_OK;

        // Now mark the element's contents as being generated so that
        // any re-entrant calls don't trigger an infinite recursion.
        xulcontent->SetLazyState(nsXULElement::eContainerContentsBuilt);
    }
    else {
        // HTML is always needs to be generated.
        //
        // XXX Big ass-umption here -- I am assuming that this will
        // _only_ ever get called (in the case of an HTML element)
        // when the XUL builder is descending thru the graph and
        // stumbles on a template that is rooted at an HTML element.
        // (/me crosses fingers...)
    }

    // Seed the rule network with assignments for the content and
    // container variables
    //
    // XXXwaterson could this code be shared with
    // nsXULTemplateBuilder::Propagate()?
    Instantiation seed;
    seed.AddAssignment(mContentVar, Value(aElement));

    InstantiationSet instantiations;
    instantiations.Append(seed);

    // Propagate the assignments through the network
    nsClusterKeySet newkeys;
    mRules.GetRoot()->Propagate(instantiations, &newkeys);

    // Iterate through newly added keys to determine which rules fired
    nsClusterKeySet::ConstIterator last = newkeys.Last();
    for (nsClusterKeySet::ConstIterator key = newkeys.First(); key != last; ++key) {
        nsConflictSet::MatchCluster* matches =
            mConflictSet.GetMatchesForClusterKey(*key);

        if (! matches)
            continue;

        nsTemplateMatch* match = 
            mConflictSet.GetMatchWithHighestPriority(matches);

        NS_ASSERTION(match != nsnull, "no best match in match set");
        if (! match)
            continue;

        // Grab the template node
        nsCOMPtr<nsIContent> tmpl;
        match->mRule->GetContent(getter_AddRefs(tmpl));

        BuildContentFromTemplate(tmpl, aElement, aElement, PR_TRUE,
                                 VALUE_TO_IRDFRESOURCE(key->mMemberValue),
                                 aNotify, match,
                                 aContainer, aNewIndexInContainer);

        // Remember this as the "last" match
        matches->mLastMatch = match;
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Invoked lazily by a XUL element that needs its child content built.

Definition at line 1530 of file nsXULContentBuilder.cpp.

{
    NS_PRECONDITION(aElement != nsnull, "null ptr");
    if (! aElement)
        return NS_ERROR_NULL_POINTER;

    NS_ASSERTION(IsElementInBuilder(aElement, this), "element not managed by this template builder");

    return CreateTemplateAndContainerContents(aElement, nsnull /* don't care */, nsnull /* don't care */);
}

Here is the call graph for this function:

nsresult nsXULContentBuilder::CreateElement ( PRInt32  aNameSpaceID,
nsIAtom aTag,
nsIContent **  aResult 
) [protected]

Definition at line 1456 of file nsXULContentBuilder.cpp.

{
    nsCOMPtr<nsIDocument> doc = mRoot->GetDocument();
    NS_ASSERTION(doc != nsnull, "not initialized");
    if (! doc)
        return NS_ERROR_NOT_INITIALIZED;

    nsresult rv;
    nsCOMPtr<nsIContent> result;

    nsCOMPtr<nsINodeInfo> nodeInfo;
    doc->NodeInfoManager()->GetNodeInfo(aTag, nsnull, aNameSpaceID,
                                        getter_AddRefs(nodeInfo));

    rv = NS_NewElement(getter_AddRefs(result), aNameSpaceID, nodeInfo);
    if (NS_FAILED(rv)) return rv;

    *aResult = result;
    NS_ADDREF(*aResult);
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXULContentBuilder::CreateTemplateAndContainerContents ( nsIContent aElement,
nsIContent **  aContainer,
PRInt32 aNewIndexInContainer 
) [protected]

Definition at line 1108 of file nsXULContentBuilder.cpp.

{
    // Generate both 1) the template content for the current element,
    // and 2) recursive subcontent (if the current element refers to a
    // container resource in the RDF graph).

    // If we're asked to return the first generated child, then
    // initialize to "none".
    if (aContainer) {
        *aContainer = nsnull;
        *aNewIndexInContainer = -1;
    }

    // Create the current resource's contents from the template, if
    // appropriate
    nsCOMPtr<nsIContent> tmpl;
    mTemplateMap.GetTemplateFor(aElement, getter_AddRefs(tmpl));

    if (tmpl)
        CreateTemplateContents(aElement, tmpl, aContainer, aNewIndexInContainer);

    nsCOMPtr<nsIRDFResource> resource;
    nsXULContentUtils::GetElementRefResource(aElement, getter_AddRefs(resource));
    if (resource) {
        // The element has a resource; that means that it corresponds
        // to something in the graph, so we need to go to the graph to
        // create its contents.
        CreateContainerContents(aElement, resource, PR_FALSE, aContainer, aNewIndexInContainer);
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXULContentBuilder::CreateTemplateContents ( nsIContent aElement,
nsIContent aTemplateElement,
nsIContent **  aContainer,
PRInt32 aNewIndexInContainer 
) [protected]

Definition at line 1249 of file nsXULContentBuilder.cpp.

{
    // Create the contents of an element using the templates
    nsresult rv;

    // See if the element's templates contents have been generated:
    // this prevents a re-entrant call from triggering another
    // generation.
    nsXULElement *xulcontent = nsXULElement::FromContent(aElement);
    if (! xulcontent)
        return NS_OK; // HTML content is _always_ generated up-front

    if (xulcontent->GetLazyState(nsXULElement::eTemplateContentsBuilt))
        return NS_OK;

    // Now mark the element's contents as being generated so that
    // any re-entrant calls don't trigger an infinite recursion.
    xulcontent->SetLazyState(nsXULElement::eTemplateContentsBuilt);

    // Crawl up the content model until we find the "resource" element
    // that spawned this template.
    nsCOMPtr<nsIRDFResource> resource;

    nsCOMPtr<nsIContent> element;
    for (element = aElement; element; element = element->GetParent()) {
        nsXULContentUtils::GetElementRefResource(element, getter_AddRefs(resource));
        if (resource)
            break;
    }

    NS_ASSERTION(element != nsnull, "walked off the top of the content tree");
    if (! element)
        return NS_ERROR_FAILURE;

    nsTemplateMatch* match = nsnull;
    mContentSupportMap.Get(element, &match);

    NS_ASSERTION(match != nsnull, "no match in the content support map");
    if (! match)
        return NS_ERROR_FAILURE;

    rv = BuildContentFromTemplate(aTemplateElement, aElement, aElement, PR_FALSE, resource, PR_FALSE,
                                  match, aContainer, aNewIndexInContainer);

    if (NS_FAILED(rv)) return rv;

    return NS_OK;
}

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

Reimplemented from nsXULTemplateBuilder.

Definition at line 1574 of file nsXULContentBuilder.cpp.

{
    // Break circular references
    mContentSupportMap.Clear();

    nsXULTemplateBuilder::DocumentWillBeDestroyed(aDocument);
}

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.

nsresult nsXULContentBuilder::EnsureElementHasGenericChild ( nsIContent aParent,
PRInt32  aNameSpaceID,
nsIAtom aTag,
PRBool  aNotify,
nsIContent **  aResult 
) [protected]

Definition at line 1302 of file nsXULContentBuilder.cpp.

{
    nsresult rv;

    rv = nsXULContentUtils::FindChildByTag(parent, nameSpaceID, tag, result);
    if (NS_FAILED(rv)) return rv;

    if (rv == NS_RDF_NO_VALUE) {
        // we need to construct a new child element.
        nsCOMPtr<nsIContent> element;

        rv = CreateElement(nameSpaceID, tag, getter_AddRefs(element));
        if (NS_FAILED(rv)) return rv;

        // XXX Note that the notification ensures we won't batch insertions! This could be bad! - Dave
        rv = parent->AppendChildTo(element, aNotify);
        if (NS_FAILED(rv)) return rv;

        *result = element;
        NS_ADDREF(*result);
        return NS_RDF_ELEMENT_GOT_CREATED;
    }
    else {
        return NS_RDF_ELEMENT_WAS_THERE;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 449 of file nsXULTemplateBuilder.cpp.

{
    // Iterate through newly added keys to determine which rules fired.
    //
    // XXXwaterson Unfortunately, this could also lead to retractions;
    // e.g., (contaner ?a ^empty false) could become "unmatched". How
    // to track those?
    nsClusterKeySet::ConstIterator last = aNewKeys.Last();
    for (nsClusterKeySet::ConstIterator key = aNewKeys.First(); key != last; ++key) {
        nsConflictSet::MatchCluster* matches =
            mConflictSet.GetMatchesForClusterKey(*key);

        NS_ASSERTION(matches != nsnull, "no matched rules for new key");
        if (! matches)
            continue;

        nsTemplateMatch* bestmatch =
            mConflictSet.GetMatchWithHighestPriority(matches);

        NS_ASSERTION(bestmatch != nsnull, "no matches in match set");
        if (! bestmatch)
            continue;

        // If the new "bestmatch" is different from the last match,
        // then we need to yank some content out and rebuild it.
        const nsTemplateMatch* lastmatch = matches->mLastMatch;
        if (bestmatch != lastmatch) {
            ReplaceMatch(VALUE_TO_IRDFRESOURCE(key->mMemberValue), lastmatch, bestmatch);

            // Remember the best match as the new "last" match
            matches->mLastMatch = bestmatch;
        }
    }

    return NS_OK;
}

Here is the call graph for this function:

Definition at line 1441 of file nsXULContentBuilder.cpp.

{
    const char *uri;
    aResource->GetValueConst(&uri);

    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(mRoot->GetDocument());
    NS_ASSERTION(xuldoc, "expected a XUL document");
    if (! xuldoc)
        return NS_ERROR_FAILURE;

    return xuldoc->GetElementsForID(NS_ConvertUTF8toUCS2(uri), aElements);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Find the <template> tag that applies for this builder.

Definition at line 1431 of file nsXULTemplateBuilder.cpp.

{
    NS_PRECONDITION(mRoot != nsnull, "not initialized");
    if (! mRoot)
        return NS_ERROR_NOT_INITIALIZED;

    // First, check and see if the root has a template attribute. This
    // allows a template to be specified "out of line"; e.g.,
    //
    //   <window>
    //     <foo template="MyTemplate">...</foo>
    //     <template id="MyTemplate">...</template>
    //   </window>
    //
    nsAutoString templateID;
    mRoot->GetAttr(kNameSpaceID_None, nsXULAtoms::templateAtom, templateID);

    if (!templateID.IsEmpty()) {
        nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(mRoot->GetDocument());
        NS_ASSERTION(domDoc, "expected a XUL document");
        if (! domDoc)
            return NS_ERROR_FAILURE;

        nsCOMPtr<nsIDOMElement> domElement;
        domDoc->GetElementById(templateID, getter_AddRefs(domElement));

        if (domElement)
            return CallQueryInterface(domElement, aResult);
    }

#if 1 // XXX hack to workaround bug with XBL insertion/removal?
    {
        // If root node has no template attribute, then look for a child
        // node which is a template tag
        PRUint32 count = mRoot->GetChildCount();

        for (PRUint32 i = 0; i < count; ++i) {
            nsIContent *child = mRoot->GetChildAt(i);

            if (IsTemplateElement(child)) {
                NS_ADDREF(*aResult = child);
                return NS_OK;
            }
        }
    }
#endif

    // If we couldn't find a real child, look through the anonymous
    // kids, too.
    nsCOMPtr<nsIDocument> doc = mRoot->GetDocument();
    NS_ASSERTION(doc, "root element has no document");
    if (! doc)
        return NS_ERROR_FAILURE;

    nsCOMPtr<nsIDOMNodeList> kids;
    doc->BindingManager()->GetXBLChildNodesFor(mRoot, getter_AddRefs(kids));

    if (kids) {
        PRUint32 length;
        kids->GetLength(&length);

        for (PRUint32 i = 0; i < length; ++i) {
            nsCOMPtr<nsIDOMNode> node;
            kids->Item(i, getter_AddRefs(node));
            if (! node)
                continue;

            nsCOMPtr<nsIContent> child = do_QueryInterface(node);

            if (IsTemplateElement(child)) {
                NS_ADDREF(*aResult = child.get());
                return NS_OK;
            }
        }
    }

    *aResult = nsnull;
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Called to initialize a XUL content builder on a particular root element.

This element presumably has a ``datasources'' attribute, which the builder will parse to set up the template builder's datasources.

Reimplemented from nsXULTemplateBuilder.

Definition at line 331 of file nsXULContentBuilder.cpp.

{
    if (gRefCnt++ == 0) {
        nsresult rv = CallGetService(kXULSortServiceCID, &gXULSortService);
        if (NS_FAILED(rv))
            return rv;
    }

    return nsXULTemplateBuilder::Init();
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 855 of file nsXULTemplateBuilder.cpp.

{
    // Use XPConnect and the JS APIs to whack mDB and this as the
    // 'database' and 'builder' properties onto aElement.
    nsresult rv;

    nsCOMPtr<nsIDocument> doc = mRoot->GetDocument();
    NS_ASSERTION(doc, "no document");
    if (! doc)
        return NS_ERROR_UNEXPECTED;

    nsIScriptGlobalObject *global = doc->GetScriptGlobalObject();
    if (! global)
        return NS_ERROR_UNEXPECTED;

    JSObject *scope = global->GetGlobalJSObject();

    nsIScriptContext *context = global->GetContext();
    if (! context)
        return NS_ERROR_UNEXPECTED;

    JSContext* jscontext = NS_REINTERPRET_CAST(JSContext*, context->GetNativeContext());
    NS_ASSERTION(context != nsnull, "no jscontext");
    if (! jscontext)
        return NS_ERROR_UNEXPECTED;

    nsIXPConnect *xpc = nsContentUtils::XPConnect();

    JSObject* jselement = nsnull;

    nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
    rv = xpc->WrapNative(jscontext, scope, mRoot, NS_GET_IID(nsIDOMElement),
                         getter_AddRefs(wrapper));
    NS_ENSURE_SUCCESS(rv, rv);

    rv = wrapper->GetJSObject(&jselement);
    NS_ENSURE_SUCCESS(rv, rv);

    {
        // database
        rv = xpc->WrapNative(jscontext, scope, mDB,
                             NS_GET_IID(nsIRDFCompositeDataSource),
                             getter_AddRefs(wrapper));
        NS_ENSURE_SUCCESS(rv, rv);

        JSObject* jsobj;
        rv = wrapper->GetJSObject(&jsobj);
        NS_ENSURE_SUCCESS(rv, rv);

        jsval jsdatabase = OBJECT_TO_JSVAL(jsobj);

        PRBool ok;
        ok = JS_SetProperty(jscontext, jselement, "database", &jsdatabase);
        NS_ASSERTION(ok, "unable to set database property");
        if (! ok)
            return NS_ERROR_FAILURE;
    }

    {
        // builder
        nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
        rv = xpc->WrapNative(jscontext, jselement,
                             NS_STATIC_CAST(nsIXULTemplateBuilder*, this),
                             NS_GET_IID(nsIXULTemplateBuilder),
                             getter_AddRefs(wrapper));
        NS_ENSURE_SUCCESS(rv, rv);

        JSObject* jsobj;
        rv = wrapper->GetJSObject(&jsobj);
        NS_ENSURE_SUCCESS(rv, rv);

        jsval jsbuilder = OBJECT_TO_JSVAL(jsobj);

        PRBool ok;
        ok = JS_SetProperty(jscontext, jselement, "builder", &jsbuilder);
        if (! ok)
            return NS_ERROR_FAILURE;
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Initialize the rule network.

Reimplemented from nsXULTemplateBuilder.

Definition at line 1797 of file nsXULContentBuilder.cpp.

Here is the call graph for this function:

Initialize the rule network for handling rules that use the ``simple'' syntax.

Implements nsXULTemplateBuilder.

Definition at line 1808 of file nsXULContentBuilder.cpp.

{
    // For simple rules, the rule network will start off looking
    // something like this:
    //
    //   (root)-->(content ^id ?a)-->(?a ^member ?b)
    //
    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(mRoot->GetDocument());
    NS_ASSERTION(xuldoc, "expected a XUL Document");
    if (! xuldoc)
        return NS_ERROR_UNEXPECTED;

    nsContentTestNode* idnode =
        new nsContentTestNode(mRules.GetRoot(),
                              mConflictSet,
                              xuldoc,
                              this,
                              mContentVar,
                              mContainerVar,
                              nsnull);

    if (! idnode)
        return NS_ERROR_OUT_OF_MEMORY;

    mRules.GetRoot()->AddChild(idnode);
    mRules.AddNode(idnode);

    // Create (?container ^member ?member)
    nsRDFConMemberTestNode* membernode =
        new nsRDFConMemberTestNode(idnode,
                                   mConflictSet,
                                   mDB,
                                   mContainmentProperties,
                                   mContainerVar,
                                   mMemberVar);

    if (! membernode)
        return NS_ERROR_OUT_OF_MEMORY;

    idnode->AddChild(membernode);
    mRules.AddNode(membernode);

    mRDFTests.Add(membernode);

    *aChildNode = membernode;
    return NS_OK;
}

Here is the call graph for this function:

PRBool nsXULTemplateBuilder::IsActivated ( nsIRDFResource aResource) [protected, inherited]

Determine if a resource is currently on the activation stack.

Definition at line 2334 of file nsXULTemplateBuilder.cpp.

{
    for (ActivationEntry *entry = mTop;
         entry != nsnull;
         entry = entry->mPrevious) {
        if (entry->mResource == aResource)
            return PR_TRUE;
    }
    return PR_FALSE;
}

Here is the caller graph for this function:

PRBool nsXULTemplateBuilder::IsAttrImpactedByVars ( nsTemplateMatch aMatch,
const nsAString &  aAttributeValue,
const VariableSet aModifiedVars 
) [inherited]

Definition at line 1170 of file nsXULTemplateBuilder.cpp.

{
    // XXX at some point, it might be good to remember what attributes
    // are impacted by variable changes using information that we
    // could get at rule compilation time, rather than grovelling over
    // the attribute string.
    IsVarInSetClosure closure(aMatch, aModifiedVars);
    ParseAttribute(aAttributeValue, IsVarInSet, nsnull, &closure);

    return closure.result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsXULContentBuilder::IsDirectlyContainedBy ( nsIContent aChild,
nsIContent aParent 
) [protected]

Definition at line 982 of file nsXULContentBuilder.cpp.

{
    // This routine uses the <template> to determine if aChild is
    // "directly contained by" aParent. It does so by walking up the
    // template subtree in parallel with the generated subtree.
    NS_PRECONDITION(aChild != nsnull, "null ptr");
    if (! aChild)
        return PR_FALSE;

    // First, we need to find the template from which this element was
    // generated.
    nsCOMPtr<nsIContent> tmpl;
    mTemplateMap.GetTemplateFor(aChild, getter_AddRefs(tmpl));
    if (! tmpl)
        return PR_FALSE;

    // Now walk up the template subtree in parallel with the generated
    // subtree.
    nsINodeInfo *ni;
    nsCOMPtr<nsIContent> generated(aChild);

    do {
        // XXX - gcc 2.95.x -O3 builds are known to break if
        // we declare nsCOMPtrs inside this loop.  Moving them
        // out of the loop or using a normal pointer works
        // around this problem.
        // http://bugzilla.mozilla.org/show_bug.cgi?id=61501

        // Walk up the generated tree
        generated = generated->GetParent();
        if (! generated) 
            return PR_FALSE;

        // Walk up the template tree
        tmpl = tmpl->GetParent();
        if (! tmpl)
            return PR_FALSE;

        // The content within a template ends when we hit the
        // <template> or <rule> element in the simple syntax, or the
        // <action> element in the extended syntax.
        ni = tmpl->GetNodeInfo();
    } while (!ni->Equals(nsXULAtoms::templateAtom, kNameSpaceID_XUL) &&
             !ni->Equals(nsXULAtoms::rule, kNameSpaceID_XUL) &&
             !ni->Equals(nsXULAtoms::action, kNameSpaceID_XUL));

    // Did we find the generated parent?
    return PRBool(generated.get() == aParent);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsXULContentBuilder::IsIgnoreableAttribute ( PRInt32  aNameSpaceID,
nsIAtom aAtom 
) [protected]

Definition at line 343 of file nsXULContentBuilder.cpp.

{
    // XXX Note that we patently ignore namespaces. This is because
    // HTML elements lie and tell us that their attributes are
    // _always_ in the HTML namespace. Urgh.

    // never copy the ID attribute
    if (aAttribute == nsXULAtoms::id) {
        return PR_TRUE;
    }
    // never copy {}:uri attribute
    else if (aAttribute == nsXULAtoms::uri) {
        return PR_TRUE;
    }
    else {
        return PR_FALSE;
    }
}

Here is the caller graph for this function:

Definition at line 1420 of file nsXULContentBuilder.cpp.

{
    // Determine if this is a <tree>, <treeitem>, or <menu> element

    if (!aElement->IsContentOfType(nsIContent::eXUL)) {
        return PR_FALSE;
    }

    // XXXhyatt Use the XBL service to obtain a base tag.

    nsIAtom *tag = aElement->Tag();

    return (tag == nsXULAtoms::menu ||
            tag == nsXULAtoms::menulist ||
            tag == nsXULAtoms::menubutton ||
            tag == nsXULAtoms::toolbarbutton ||
            tag == nsXULAtoms::button ||
            tag == nsXULAtoms::treeitem);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool nsXULContentBuilder::IsOpen ( nsIContent aElement) [protected]

Definition at line 1334 of file nsXULContentBuilder.cpp.

{
    nsresult rv;

    // XXXhyatt - use XBL service to obtain base tag.

    nsIAtom *tag = aElement->Tag();

    // Treat the 'root' element as always open, -unless- it's a
    // menu/menupopup. We don't need to "fake" these as being open.
    if ((aElement == mRoot) && aElement->IsContentOfType(nsIContent::eXUL) &&
        (tag != nsXULAtoms::menu) &&
        (tag != nsXULAtoms::menubutton) &&
        (tag != nsXULAtoms::toolbarbutton) &&
        (tag != nsXULAtoms::button))
      return PR_TRUE;

    nsAutoString value;
    rv = aElement->GetAttr(kNameSpaceID_None, nsXULAtoms::open, value);
    NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get open attribute");

    return (rv == NS_CONTENT_ATTR_HAS_VALUE &&
            value.EqualsLiteral("true"));
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXULTemplateBuilder::IsSystemPrincipal ( nsIPrincipal principal,
PRBool result 
) [inherited]

Definition at line 2324 of file nsXULTemplateBuilder.cpp.

{
  if (!gSystemPrincipal)
    return NS_ERROR_UNEXPECTED;

  *result = (principal == gSystemPrincipal);
  return NS_OK;
}

Here is the caller graph for this function:

PRBool nsXULTemplateBuilder::IsTemplateElement ( nsIContent aContent) [static, inherited]

Definition at line 1395 of file nsXULTemplateBuilder.cpp.

{
    nsINodeInfo *ni = aContent->GetNodeInfo();

    return ni && ni->Equals(nsXULAtoms::Template, kNameSpaceID_XUL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsXULTemplateBuilder::IsVarInSet ( nsXULTemplateBuilder aThis,
const nsAString &  aVariable,
void aClosure 
) [static, inherited]

Definition at line 1149 of file nsXULTemplateBuilder.cpp.

{
    IsVarInSetClosure* c = NS_STATIC_CAST(IsVarInSetClosure*, aClosure);

    PRInt32 var =
        aThis->mRules.LookupSymbol(PromiseFlatString(aVariable).get());

    // No variable; treat as a variable with no substitution. (This
    // shouldn't ever happen, really...)
    if (! var)
        return;

    // See if this was one of the variables that was modified. If it
    // *was*, then this attribute *will* be impacted by the modified
    // variable set...
    c->result = c->result || c->modifiedVars.Contains(var);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 673 of file nsXULTemplateBuilder.cpp.

{
    NS_PRECONDITION(mRoot != nsnull, "not initialized");

    nsresult rv;

    // flush (delete) the cache when re-rerooting the generated content
    if (mCache)
       mCache = nsnull;

    if (mDB) {
        mDB->RemoveObserver(this);

        // we'll set it again later, after we create a new composite ds
        mDB = nsnull;
    }

    // create a database for the builder
    mCompDB = do_CreateInstance(NS_RDF_DATASOURCE_CONTRACTID_PREFIX "composite-datasource");

    if (! mCompDB) {
        NS_ERROR("unable to construct new composite data source");
        return NS_ERROR_UNEXPECTED;
    }

       // check for magical attributes. XXX move to ``flags''?
       nsAutoString coalesce;
       mRoot->GetAttr(kNameSpaceID_None, nsXULAtoms::coalesceduplicatearcs, coalesce);
    if (coalesce.EqualsLiteral("false"))
              mCompDB->SetCoalesceDuplicateArcs(PR_FALSE);

    nsAutoString allowneg;
    mRoot->GetAttr(kNameSpaceID_None, nsXULAtoms::allownegativeassertions, allowneg);
    if (allowneg.EqualsLiteral("false"))
              mCompDB->SetAllowNegativeAssertions(PR_FALSE);

    // Grab the doc's principal...
    nsIPrincipal *docPrincipal = doc->GetPrincipal();
    if (!docPrincipal)
        return NS_ERROR_FAILURE;

    PRBool isTrusted = PR_FALSE;
    rv = IsSystemPrincipal(docPrincipal, &isTrusted);
    if (NS_FAILED(rv)) return rv;

    if (isTrusted) {
        // If we're a privileged (e.g., chrome) document, then add the
        // local store as the first data source in the db. Note that
        // we _might_ not be able to get a local store if we haven't
        // got a profile to read from yet.
        nsCOMPtr<nsIRDFDataSource> localstore;
        rv = gRDFService->GetDataSource("rdf:local-store", getter_AddRefs(localstore));
        if (NS_SUCCEEDED(rv)) {
            rv = mCompDB->AddDataSource(localstore);
            NS_ASSERTION(NS_SUCCEEDED(rv), "unable to add local store to db");
            if (NS_FAILED(rv)) return rv;
        }
    }

    // Parse datasources: they are assumed to be a whitespace
    // separated list of URIs; e.g.,
    //
    //     rdf:bookmarks rdf:history http://foo.bar.com/blah.cgi?baz=9
    //
    nsIURI *docurl = doc->GetDocumentURI();

    nsAutoString datasources;
    mRoot->GetAttr(kNameSpaceID_None, nsXULAtoms::datasources, datasources);

    PRUint32 first = 0;

    while(1) {
        while (first < datasources.Length() && nsCRT::IsAsciiSpace(datasources.CharAt(first)))
            ++first;

        if (first >= datasources.Length())
            break;

        PRUint32 last = first;
        while (last < datasources.Length() && !nsCRT::IsAsciiSpace(datasources.CharAt(last)))
            ++last;

        nsAutoString uriStr;
        datasources.Mid(uriStr, first, last - first);
        first = last + 1;

        // A special 'dummy' datasource
        if (uriStr.EqualsLiteral("rdf:null"))
            continue;

        // N.B. that `failure' (e.g., because it's an unknown
        // protocol) leaves uriStr unaltered.
        NS_MakeAbsoluteURI(uriStr, uriStr, docurl);

        if (!isTrusted) {
            // Our document is untrusted, so check to see if we can
            // load the datasource that they've asked for.
            nsCOMPtr<nsIURI> uri;
            rv = NS_NewURI(getter_AddRefs(uri), uriStr);
            if (NS_FAILED(rv) || !uri)
                continue; // Necko will barf if our URI is weird

            nsCOMPtr<nsIPrincipal> principal;
            rv = gScriptSecurityManager->GetCodebasePrincipal(uri, getter_AddRefs(principal));
            NS_ASSERTION(NS_SUCCEEDED(rv), "unable to get codebase principal");
            if (NS_FAILED(rv)) return rv;

            PRBool same;
            rv = docPrincipal->Equals(principal, &same);
            NS_ASSERTION(NS_SUCCEEDED(rv), "unable to test same origin");
            if (NS_FAILED(rv)) return rv;

            if (! same)
                continue;

            // If we get here, we've run the gauntlet, and the
            // datasource's URI has the same origin as our
            // document. Let it load!
        }

        nsCOMPtr<nsIRDFDataSource> ds;
        nsCAutoString uristrC;
        uristrC.AssignWithConversion(uriStr);

        rv = gRDFService->GetDataSource(uristrC.get(), getter_AddRefs(ds));

        if (NS_FAILED(rv)) {
            // This is only a warning because the data source may not
            // be accessable for any number of reasons, including
            // security, a bad URL, etc.
#ifdef DEBUG
            nsCAutoString msg;
            msg.Append("unable to load datasource '");
            msg.AppendWithConversion(uriStr);
            msg.Append('\'');
            NS_WARNING(msg.get());
#endif
            continue;
        }

        mCompDB->AddDataSource(ds);
    }

    // check if we were given an inference engine type
    nsAutoString infer;
    mRoot->GetAttr(kNameSpaceID_None, nsXULAtoms::infer, infer);
    if (!infer.IsEmpty()) {
        nsCString inferContractID(NS_RDF_INFER_DATASOURCE_CONTRACTID_PREFIX);
        AppendUTF16toUTF8(infer, inferContractID);
        nsCOMPtr<nsIRDFInferDataSource> inferDB = do_CreateInstance(inferContractID.get());

        if (inferDB) {
            inferDB->SetBaseDataSource(mCompDB);
            mDB = do_QueryInterface(inferDB);
        } else {
            NS_WARNING("failed to construct inference engine specified on template");
        }
    }

    if (!mDB)
        mDB = mCompDB;

    nsCOMPtr<nsIXULDocument> xuldoc = do_QueryInterface(doc);
    if (xuldoc)
        xuldoc->SetTemplateBuilderFor(mRoot, this);

    // Now set the database on the element, so that script writers can
    // access it.
    nsXULElement *xulcontent = nsXULElement::FromContent(mRoot);
    if (! xulcontent) {
        // Hmm. This must be an HTML element. Try to set it as a
        // JS property "by hand".
        InitHTMLTemplateRoot();
    }

    // Add ourselves as a datasource observer
    mDB->AddObserver(this);

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIRDFObserver::onAssert ( in nsIRDFDataSource  aDataSource,
in nsIRDFResource  aSource,
in nsIRDFResource  aProperty,
in nsIRDFNode  aTarget 
) [inherited]

This method is called whenever a new assertion is made in the data source.

Parameters:
aDataSourcethe datasource that is issuing the notification.
aSourcethe subject of the assertion
aPropertythe predicate of the assertion
aTargetthe object of the assertion

This method is called when a datasource is about to send several notifications at once.

The observer can use this as a cue to optimize its behavior. The observer can expect the datasource to call endUpdateBatch() when the group of notifications has completed.

Parameters:
aDataSourcethe datasource that is going to be issuing the notifications.
void nsIRDFObserver::onChange ( in nsIRDFDataSource  aDataSource,
in nsIRDFResource  aSource,
in nsIRDFResource  aProperty,
in nsIRDFNode  aOldTarget,
in nsIRDFNode  aNewTarget 
) [inherited]

This method is called when the object of an assertion changes from one value to another.

Parameters:
aDataSourcethe datasource that is issuing the notification.
aSourcethe subject of the assertion
aPropertythe predicate of the assertion
aOldTargetthe old object of the assertion
aNewTargetthe new object of the assertion

This method is called when a datasource has completed issuing a notification group.

Parameters:
aDataSourcethe datasource that has finished issuing a group of notifications
void nsIRDFObserver::onMove ( in nsIRDFDataSource  aDataSource,
in nsIRDFResource  aOldSource,
in nsIRDFResource  aNewSource,
in nsIRDFResource  aProperty,
in nsIRDFNode  aTarget 
) [inherited]

This method is called when the subject of an assertion changes from one value to another.

Parameters:
aDataSourcethe datasource that is issuing the notification.
aOldSourcethe old subject of the assertion
aNewSourcethe new subject of the assertion
aPropertythe predicate of the assertion
aTargetthe object of the assertion
void nsIRDFObserver::onUnassert ( in nsIRDFDataSource  aDataSource,
in nsIRDFResource  aSource,
in nsIRDFResource  aProperty,
in nsIRDFNode  aTarget 
) [inherited]

This method is called whenever an assertion is removed from the data source.

Parameters:
aDataSourcethe datasource that is issuing the notification.
aSourcethe subject of the assertion
aPropertythe predicate of the assertion
aTargetthe object of the assertion

Definition at line 1743 of file nsXULContentBuilder.cpp.

{
    // See if we're responsible for this element
    if (! IsElementInBuilder(aElement, this))
        return NS_OK;

    nsCOMPtr<nsIRDFResource> resource;
    nsXULContentUtils::GetElementRefResource(aElement, getter_AddRefs(resource));

    // If it has no resource, there's nothing that we need to be
    // concerned about here.
    if (! resource)
        return NS_OK;

    // The element has a resource; that means that it corresponds
    // to something in the graph, so we need to go to the graph to
    // create its contents.
    //
    // Create the container's contents "quietly" (i.e., |aNotify ==
    // PR_FALSE|), and then use the |container| and |newIndex| to
    // notify layout where content got created.
    nsCOMPtr<nsIContent> container;
    PRInt32 newIndex;
    CreateContainerContents(aElement, resource, PR_FALSE, getter_AddRefs(container), &newIndex);

    if (container && IsLazyWidgetItem(aElement)) {
        // The tree widget is special, and has to be spanked every
        // time we add content to a container.
        nsCOMPtr<nsIDocument> doc = mRoot->GetDocument();
        NS_ASSERTION(doc, "root element has no document");
        if (! doc)
            return NS_ERROR_UNEXPECTED;

        mozAutoDocUpdate upd(container->GetCurrentDoc(), UPDATE_CONTENT_MODEL,
                             PR_TRUE);        
        doc->ContentAppended(container, newIndex);
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsXULTemplateBuilder::ParseAttribute ( const nsAString &  aAttributeValue,
void(*)(nsXULTemplateBuilder *aThis, const nsAString &, void *)  aVariableCallback,
void(*)(nsXULTemplateBuilder *aThis, const nsAString &, void *)  aTextCallback,
void aClosure 
) [inherited]

Definition at line 938 of file nsXULTemplateBuilder.cpp.

{
    nsAString::const_iterator done_parsing;
    aAttributeValue.EndReading(done_parsing);

    nsAString::const_iterator iter;
    aAttributeValue.BeginReading(iter);

    nsAString::const_iterator mark(iter), backup(iter);

    for (; iter != done_parsing; backup = ++iter) {
        // A variable is either prefixed with '?' (in the extended
        // syntax) or "rdf:" (in the simple syntax).
        PRBool isvar;
        if (*iter == PRUnichar('?') && (++iter != done_parsing)) {
            isvar = PR_TRUE;
        }
        else if ((*iter == PRUnichar('r') && (++iter != done_parsing)) &&
                 (*iter == PRUnichar('d') && (++iter != done_parsing)) &&
                 (*iter == PRUnichar('f') && (++iter != done_parsing)) &&
                 (*iter == PRUnichar(':') && (++iter != done_parsing))) {
            isvar = PR_TRUE;
        }
        else {
            isvar = PR_FALSE;
        }

        if (! isvar) {
            // It's not a variable, or we ran off the end of the
            // string after the initial variable prefix. Since we may
            // have slurped down some characters before realizing that
            // fact, back up to the point where we started.
            iter = backup;
            continue;
        }
        else if (backup != mark && aTextCallback) {
            // Okay, we've found a variable, and there's some vanilla
            // text that's been buffered up. Flush it.
            (*aTextCallback)(this, Substring(mark, backup), aClosure);
        }

        if (*iter == PRUnichar('?')) {
            // Well, it was not really a variable, but "??". We use one
            // question mark (the second one, actually) literally.
            mark = iter;
            continue;
        }

        // Construct a substring that is the symbol we need to look up
        // in the rule's symbol table. The symbol is terminated by a
        // space character, a caret, or the end of the string,
        // whichever comes first.
        nsAString::const_iterator first(backup);

        PRUnichar c = 0;
        while (iter != done_parsing) {
            c = *iter;
            if ((c == PRUnichar(' ')) || (c == PRUnichar('^')))
                break;

            ++iter;
        }

        nsAString::const_iterator last(iter);

        // Back up so we don't consume the terminating character
        // *unless* the terminating character was a caret: the caret
        // means "concatenate with no space in between".
        if (c != PRUnichar('^'))
            --iter;

        (*aVariableCallback)(this, Substring(first, last), aClosure);
        mark = iter;
        ++mark;
    }

    if (backup != mark && aTextCallback) {
        // If there's any text left over, then fire the text callback
        (*aTextCallback)(this, Substring(mark, backup), aClosure);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXULTemplateBuilder::ParseLiteral ( const nsString aParseType,
const nsString aValue,
nsIRDFNode **  aResult 
) [inherited]

Parse the value of a property test assertion for a condition or a simple rule based on the parseType attribute into the appropriate literal type.

Definition at line 1789 of file nsXULTemplateBuilder.cpp.

{
    nsresult rv = NS_OK;
    *aResult = nsnull;

    if (aParseType.EqualsLiteral(PARSE_TYPE_INTEGER)) {
        nsCOMPtr<nsIRDFInt> intLiteral;
        PRInt32 errorCode;
        PRInt32 intValue = aValue.ToInteger(&errorCode);
        if (NS_FAILED(errorCode))
            return NS_ERROR_FAILURE;
        rv = gRDFService->GetIntLiteral(intValue, getter_AddRefs(intLiteral));
        if (NS_FAILED(rv)) 
            return rv;
        rv = CallQueryInterface(intLiteral, aResult);
    }
    else {
        nsCOMPtr<nsIRDFLiteral> literal;
        rv = gRDFService->GetLiteral(aValue.get(), getter_AddRefs(literal));
        if (NS_FAILED(rv)) 
            return rv;
        rv = CallQueryInterface(literal, aResult);
    }
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXULTemplateBuilder::Propagate ( nsIRDFResource aSource,
nsIRDFResource aProperty,
nsIRDFNode aTarget,
nsClusterKeySet aNewKeys 
) [inherited]

Definition at line 379 of file nsXULTemplateBuilder.cpp.

{
    // Find the "dominating" tests that could be used to propagate the
    // assertion we've just received. (Test A "dominates" test B if A
    // is an ancestor of B in the rule network).
    nsresult rv;

    // First, we'll go through and find all of the test nodes that can
    // propagate the assertion.
    ReteNodeSet livenodes;

    {
        ReteNodeSet::Iterator last = mRDFTests.Last();
        for (ReteNodeSet::Iterator i = mRDFTests.First(); i != last; ++i) {
            nsRDFTestNode* rdftestnode = NS_STATIC_CAST(nsRDFTestNode*, *i);

            Instantiation seed;
            if (rdftestnode->CanPropagate(aSource, aProperty, aTarget, seed))
                livenodes.Add(rdftestnode);
        }
    }

    // Now, we'll go through each, and any that aren't dominated by
    // another live node will be used to propagate the assertion
    // through the rule network
    {
        ReteNodeSet::Iterator last = livenodes.Last();
        for (ReteNodeSet::Iterator i = livenodes.First(); i != last; ++i) {
            nsRDFTestNode* rdftestnode = NS_STATIC_CAST(nsRDFTestNode*, *i);

            PRBool isdominated = PR_FALSE;

            for (ReteNodeSet::ConstIterator j = livenodes.First(); j != last; ++j) {
                // we can't be dominated by ourself
                if (j == i)
                    continue;

                if (rdftestnode->HasAncestor(*j)) {
                    isdominated = PR_TRUE;
                    break;
                }
            }

            if (! isdominated) {
                // Bogus, to get the seed instantiation
                Instantiation seed;
                rdftestnode->CanPropagate(aSource, aProperty, aTarget, seed);

                InstantiationSet instantiations;
                instantiations.Append(seed);

                rv = rdftestnode->Constrain(instantiations, &mConflictSet);
                if (NS_FAILED(rv)) return rv;

                if (! instantiations.Empty()) {
                    rv = rdftestnode->Propagate(instantiations, &aNewKeys);
                    if (NS_FAILED(rv)) return rv;
                }
            }
        }
    }

    return NS_OK;
}

Here is the call graph for this function:

Force the template builder to rebuild its content.

nsresult nsXULContentBuilder::RebuildAll ( ) [protected, virtual]

Implements nsXULTemplateBuilder.

Definition at line 1857 of file nsXULContentBuilder.cpp.

{
    NS_PRECONDITION(mRoot != nsnull, "not initialized");
    if (! mRoot)
        return NS_ERROR_NOT_INITIALIZED;

    nsCOMPtr<nsIDocument> doc = mRoot->GetDocument();

    // Bail out early if we are being torn down.
    if (!doc)
        return NS_OK;

    // See if it's a XUL element whose contents have never even
    // been generated. If so, short-circuit and bail; there's nothing
    // for us to "rebuild" yet. They'll get built correctly the next
    // time somebody asks for them. 
    nsXULElement *xulcontent = nsXULElement::FromContent(mRoot);

    if (xulcontent &&
        !xulcontent->GetLazyState(nsXULElement::eContainerContentsBuilt))
        return NS_OK;

    // If we get here, then we've tried to generate content for this
    // element. Remove it.
    nsresult rv = RemoveGeneratedContent(mRoot);
    if (NS_FAILED(rv)) return rv;

    // Nuke the content support map and conflict set completely.
    mContentSupportMap.Clear();
    mTemplateMap.Clear();
    mConflictSet.Clear();

    rv = CompileRules();
    if (NS_FAILED(rv)) return rv;

    // Forces the XUL element to remember that it needs to
    // re-generate its children next time around.
    if (xulcontent) {
        xulcontent->SetLazyState(nsXULElement::eChildrenMustBeRebuilt);
        xulcontent->ClearLazyState(nsXULElement::eTemplateContentsBuilt);
        xulcontent->ClearLazyState(nsXULElement::eContainerContentsBuilt);
    }

    // Now, regenerate both the template- and container-generated
    // contents for the current element...
    nsCOMPtr<nsIContent> container;
    PRInt32 newIndex;
    CreateTemplateAndContainerContents(mRoot, getter_AddRefs(container), &newIndex);

    if (container) {
        nsCOMPtr<nsIDocument> doc = mRoot->GetDocument();
        NS_ASSERTION(doc, "root element has no document");
        if (! doc)
            return NS_ERROR_UNEXPECTED;

        mozAutoDocUpdate upd(container->GetCurrentDoc(), UPDATE_CONTENT_MODEL,
                             PR_TRUE);
        doc->ContentAppended(container, newIndex);
    }

    return NS_OK;
}

Here is the call graph for this function:

Reload any of our RDF datasources that support nsIRDFRemoteDatasource.

Note:
This is a temporary hack so that remote-XUL authors can reload remote datasources. When RDF becomes remote-scriptable, this will no longer be necessary.

Definition at line 1361 of file nsXULContentBuilder.cpp.

{
    // Keep a queue of "ungenerated" elements that we have to probe
    // for generated content.
    nsAutoVoidArray ungenerated;
    ungenerated.AppendElement(aElement);

    PRInt32 count;
    while (0 != (count = ungenerated.Count())) {
        // Pull the next "ungenerated" element off the queue.
        PRInt32 last = count - 1;
        nsIContent* element = NS_STATIC_CAST(nsIContent*, ungenerated[last]);
        ungenerated.RemoveElementAt(last);

        PRUint32 i = element->GetChildCount();

        while (i-- > 0) {
            nsCOMPtr<nsIContent> child = element->GetChildAt(i);

            // Optimize for the <template> element, because we *know*
            // it won't have any generated content: there's no reason
            // to even check this subtree.
            nsINodeInfo *ni = element->GetNodeInfo();
            if (!ni || ni->Equals(nsXULAtoms::templateAtom, kNameSpaceID_XUL))
                continue;

            // If the element is in the template map, then we
            // assume it's been generated and nuke it.
            nsCOMPtr<nsIContent> tmpl;
            mTemplateMap.GetTemplateFor(child, getter_AddRefs(tmpl));

            if (! tmpl) {
                // No 'template' attribute, so this must not have been
                // generated. We'll need to examine its kids.
                ungenerated.AppendElement(child);
                continue;
            }

            // If we get here, it's "generated". Bye bye!
            element->RemoveChildAt(i, PR_TRUE);

            // Remove element from the conflict set.
            // XXXwaterson should this be moved into NoteGeneratedSubtreeRemoved?
            nsTemplateMatchSet firings(mConflictSet.GetPool());
            nsTemplateMatchSet retractions(mConflictSet.GetPool());
            mConflictSet.Remove(nsContentTestNode::Element(child), firings, retractions);

            // Remove this and any children from the content support map.
            mContentSupportMap.Remove(child);

            // Remove from the template map
            mTemplateMap.Remove(child);
        }
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Remove a listener from this template builder.

nsresult nsXULContentBuilder::RemoveMember ( nsIContent aContainerElement,
nsIRDFResource aMember,
PRBool  aNotify 
) [protected]

Definition at line 1034 of file nsXULContentBuilder.cpp.

{
    // This works as follows. It finds all of the elements in the
    // document that correspond to aMember. Any that are contained
    // within aContainerElement are removed from their direct parent.
    nsresult rv;

    nsCOMPtr<nsISupportsArray> elements;
    rv = NS_NewISupportsArray(getter_AddRefs(elements));
    if (NS_FAILED(rv)) return rv;

    rv = GetElementsForResource(aMember, elements);
    if (NS_FAILED(rv)) return rv;

    PRUint32 cnt;
    rv = elements->Count(&cnt);
    if (NS_FAILED(rv)) return rv;

    for (PRInt32 i = PRInt32(cnt) - 1; i >= 0; --i) {
        nsISupports* isupports = elements->ElementAt(i);
        nsCOMPtr<nsIContent> child( do_QueryInterface(isupports) );
        NS_IF_RELEASE(isupports);

        if (! IsDirectlyContainedBy(child, aContainerElement))
            continue;

        nsCOMPtr<nsIContent> parent = child->GetParent();

        PRInt32 pos = parent->IndexOf(child);

        NS_ASSERTION(pos >= 0, "parent doesn't think this child has an index");
        if (pos < 0) continue;

        // Note: RemoveChildAt sets |child|'s document to null so that
        // it'll get knocked out of the XUL doc's resource-to-element
        // map.
        rv = parent->RemoveChildAt(pos, aNotify);
        if (NS_FAILED(rv)) return rv;

        // Remove from the content support map.
        mContentSupportMap.Remove(child);

        // Remove from the template map
        mTemplateMap.Remove(child);

#ifdef PR_LOGGING
        if (PR_LOG_TEST(gXULTemplateLog, PR_LOG_ALWAYS)) {
            const char *parentTagStr;
            parent->Tag()->GetUTF8String(&parentTagStr);

            const char *childTagStr;
            child->Tag()->GetUTF8String(&childTagStr);

            const char* resourceCStr;
            rv = aMember->GetValueConst(&resourceCStr);
            if (NS_FAILED(rv)) return rv;
            
            PR_LOG(gXULTemplateLog, PR_LOG_ALWAYS,
                   ("xultemplate[%p] remove-member %s->%s [%s]",
                    this,
                    parentTagStr,
                    childTagStr,
                    resourceCStr));
        }
#endif
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXULContentBuilder::ReplaceMatch ( nsIRDFResource aMember,
const nsTemplateMatch aOldMatch,
nsTemplateMatch aNewMatch 
) [protected, virtual]

Must be implemented by subclasses.

Handle replacing aOldMatch with aNewMatch. Either aOldMatch or aNewMatch may be null.

Implements nsXULTemplateBuilder.

Definition at line 1589 of file nsXULContentBuilder.cpp.

{
    if (aOldMatch) {
        // See if we need to yank anything out of the content
        // model to handle the newly matched rule. If the
        // instantiation has a assignment for the content
        // variable, there's content that's been built that we
        // need to pull.
        Value value;
        PRBool hasassignment =
            aOldMatch->mAssignments.GetAssignmentFor(mContentVar, &value);

        NS_ASSERTION(hasassignment, "no content assignment");
        if (! hasassignment)
            return NS_ERROR_UNEXPECTED;

        nsIContent* content = VALUE_TO_ICONTENT(value);

        PRInt32 membervar = aOldMatch->mRule->GetMemberVariable();

        hasassignment = aOldMatch->mAssignments.GetAssignmentFor(membervar, &value);
        NS_ASSERTION(hasassignment, "no member assignment");
        if (! hasassignment)
            return NS_ERROR_UNEXPECTED;

        nsIRDFResource* member = VALUE_TO_IRDFRESOURCE(value);

        RemoveMember(content, member, PR_TRUE);

        if (!aNewMatch) {
            // If there's no new match, then go ahead an update the
            // container attributes now.
            SetContainerAttrs(content, aOldMatch);
        }
    }

    if (aNewMatch) {
        // Get the content node to which we were bound
        Value value;
        PRBool hasassignment =
            aNewMatch->mAssignments.GetAssignmentFor(mContentVar, &value);

        NS_ASSERTION(hasassignment, "no content assignment");
        if (! hasassignment)
            return NS_ERROR_UNEXPECTED;

        nsIContent* content = VALUE_TO_ICONTENT(value);

        // Update the 'empty' attribute. Do this *first*, because
        // we may decide to nuke aNewMatch in a minute...
        SetContainerAttrs(content, aNewMatch);

        // See if we've built the container contents for "content"
        // yet. If not, we don't need to build any content. This
        // happens, for example, if we recieve an assertion on a
        // closed folder in a tree widget or on a menu that hasn't
        // yet been dropped.
        PRBool contentsGenerated = PR_TRUE;
        nsXULElement *xulcontent = nsXULElement::FromContent(content);
        if (xulcontent)
            contentsGenerated = xulcontent->GetLazyState(nsXULElement::eContainerContentsBuilt);

        if (contentsGenerated) {
            nsCOMPtr<nsIContent> tmpl;
            aNewMatch->mRule->GetContent(getter_AddRefs(tmpl));

            BuildContentFromTemplate(tmpl, content, content, PR_TRUE,
                                     aMember, PR_TRUE, aNewMatch,
                                     nsnull, nsnull);
        }
    }

    return NS_OK;
}

Here is the call graph for this function:

nsresult nsXULTemplateBuilder::Retract ( nsIRDFResource aSource,
nsIRDFResource aProperty,
nsIRDFNode aTarget 
) [inherited]

Definition at line 516 of file nsXULTemplateBuilder.cpp.

{
    // Retract any currently active rules that will no longer be
    // matched.
    ReteNodeSet::ConstIterator lastnode = mRDFTests.Last();
    for (ReteNodeSet::ConstIterator node = mRDFTests.First(); node != lastnode; ++node) {
        const nsRDFTestNode* rdftestnode = NS_STATIC_CAST(const nsRDFTestNode*, *node);

        nsTemplateMatchSet firings(mConflictSet.GetPool());
        nsTemplateMatchSet retractions(mConflictSet.GetPool());
        rdftestnode->Retract(aSource, aProperty, aTarget, firings, retractions);

        {
            nsTemplateMatchSet::ConstIterator last = retractions.Last();
            for (nsTemplateMatchSet::ConstIterator match = retractions.First(); match != last; ++match) {
                Value memberval;
                match->mAssignments.GetAssignmentFor(match->mRule->GetMemberVariable(), &memberval);

                ReplaceMatch(VALUE_TO_IRDFRESOURCE(memberval), match.operator->(), nsnull);
            }
        }
#if 0
        // Now fire any newly revealed rules
        {
            nsTemplateMatchSet::ConstIterator last = firings.Last();
            for (nsTemplateMatchSet::ConstIterator match = firings.First(); match != last; ++match) {
                // XXXwaterson yo. write me.
                // The intent here is to handle any rules that might be
                // "revealed" by the removal of an assertion from the datasource.
                // Waterson doesn't think we support negated conditions in a rule.
                // Nor is he sure that this is currently useful.
            }
        }
#endif
    }

    return NS_OK;
}

Here is the call graph for this function:

Definition at line 1481 of file nsXULContentBuilder.cpp.

{
    NS_PRECONDITION(aMatch->mRule != nsnull, "null ptr");
    if (! aMatch->mRule)
        return NS_ERROR_NULL_POINTER;

    Value containerval;
    aMatch->mAssignments.GetAssignmentFor(aMatch->mRule->GetContainerVariable(), &containerval);

    nsAutoString oldcontainer;
    aElement->GetAttr(kNameSpaceID_None, nsXULAtoms::container, oldcontainer);

    PRBool iscontainer, isempty;
    CheckContainer(VALUE_TO_IRDFRESOURCE(containerval), &iscontainer, &isempty);

    NS_NAMED_LITERAL_STRING(true_, "true");
    NS_NAMED_LITERAL_STRING(false_, "false");
    
    const nsAString& newcontainer =
        iscontainer ? true_ : false_;

    if (oldcontainer != newcontainer) {
        aElement->SetAttr(kNameSpaceID_None, nsXULAtoms::container,
                          newcontainer, PR_TRUE);
    }

    if (! (mFlags & eDontTestEmpty)) {
        nsAutoString oldempty;
        aElement->GetAttr(kNameSpaceID_None, nsXULAtoms::empty, oldempty);

        const nsAString& newempty =
            (iscontainer && isempty) ? true_ : false_;

        if (oldempty != newempty) {
            aElement->SetAttr(kNameSpaceID_None, nsXULAtoms::empty,
                              newempty, PR_TRUE);
        }
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

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.

nsresult nsXULTemplateBuilder::SubstituteText ( nsTemplateMatch aMatch,
const nsAString &  aAttributeValue,
nsAString &  aResult 
) [inherited]

Definition at line 1033 of file nsXULTemplateBuilder.cpp.

{
    // See if it's the special value "..."
    if (aAttributeValue.EqualsLiteral("...")) {
        Value memberval;
        aMatch.GetAssignmentFor(mConflictSet, mMemberVar, &memberval);

        nsIRDFResource* member = VALUE_TO_IRDFRESOURCE(memberval);
        NS_ASSERTION(member != nsnull, "no member!");
        if (! member)
            return NS_ERROR_UNEXPECTED;

        const char *uri = nsnull;
        member->GetValueConst(&uri);

        CopyUTF8toUTF16(uri, aResult);

        return NS_OK;
    }

    // Reasonable guess at how big it should be
    aResult.SetCapacity(aAttributeValue.Length());

    SubstituteTextClosure closure(aMatch, aResult);
    ParseAttribute(aAttributeValue,
                   SubstituteTextReplaceVariable,
                   SubstituteTextAppendText,
                   &closure);

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsXULTemplateBuilder::SubstituteTextAppendText ( nsXULTemplateBuilder aThis,
const nsAString &  aText,
void aClosure 
) [static, inherited]

Definition at line 1069 of file nsXULTemplateBuilder.cpp.

{
    // Append aString to the closure's result
    SubstituteTextClosure* c = NS_STATIC_CAST(SubstituteTextClosure*, aClosure);
    c->result.Append(aText);
}

Here is the caller graph for this function:

void nsXULTemplateBuilder::SubstituteTextReplaceVariable ( nsXULTemplateBuilder aThis,
const nsAString &  aVariable,
void aClosure 
) [static, inherited]

Definition at line 1079 of file nsXULTemplateBuilder.cpp.

{
    // Substitute the value for the variable and append to the
    // closure's result.
    SubstituteTextClosure* c = NS_STATIC_CAST(SubstituteTextClosure*, aClosure);

    // The symbol "rdf:*" is special, and means "this guy's URI"
    PRInt32 var = 0;
    if (aVariable.EqualsLiteral("rdf:*"))
        var = c->match.mRule->GetMemberVariable();
    else
        var = aThis->mRules.LookupSymbol(PromiseFlatString(aVariable).get());

    // No variable; treat as a variable with no substitution. (This
    // shouldn't ever happen, really...)
    if (! var)
        return;

    // Got a variable; get the value it's assigned to
    Value value;
    PRBool hasAssignment =
        c->match.GetAssignmentFor(aThis->mConflictSet, var, &value);

    // If there was no assignment for the variable, bail. This'll
    // leave the result string with an empty substitution for the
    // variable.
    if (! hasAssignment)
        return;

    // Got a value; substitute it.
    switch (value.GetType()) {
    case Value::eISupports:
        {
            nsISupports* isupports = NS_STATIC_CAST(nsISupports*, value);

            nsCOMPtr<nsIRDFNode> node = do_QueryInterface(isupports);
            if (node) {
                // XXX ideally we'd just point this right at the
                // substring which is the end of the string,
                // turning this into an in-place append.
                nsAutoString temp;
                nsXULContentUtils::GetTextForNode(node, temp);
                c->result += temp;
            }
        }
    break;

    case Value::eString:
        c->result += NS_STATIC_CAST(const PRUnichar*, value);
        break;

    default:
        break;
    }
    
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsXULTemplateBuilder::SynchronizeAll ( nsIRDFResource aSource,
nsIRDFResource aProperty,
nsIRDFNode aOldTarget,
nsIRDFNode aNewTarget 
) [inherited]

Definition at line 1186 of file nsXULTemplateBuilder.cpp.

{
    // Update each match that contains <aSource, aProperty, aOldTarget>.

    // Get all the matches whose assignments are currently supported
    // by aSource and aProperty: we'll need to recompute them.
    const nsTemplateMatchRefSet* matches =
        mConflictSet.GetMatchesWithBindingDependency(aSource);

    if (! matches || matches->Empty())
        return NS_OK;

    // Since we'll actually be manipulating the match set as we
    // iterate through it, we need to copy it into our own private
    // area before performing the iteration.
    nsTemplateMatchRefSet copy = *matches;

    nsTemplateMatchRefSet::ConstIterator last = copy.Last();
    for (nsTemplateMatchRefSet::ConstIterator match = copy.First(); match != last; ++match) {
        const nsTemplateRule* rule = match->mRule;

        // Recompute the assignments. This will replace aOldTarget with
        // aNewTarget, which will disrupt the match set.
        VariableSet modified;
        rule->RecomputeBindings(mConflictSet, match.operator->(),
                                aSource, aProperty, aOldTarget, aNewTarget,
                                modified);

        // If nothing changed, then continue on to the next match.
        if (0 == modified.GetCount())
            continue;

#ifdef PR_LOGGING
        PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
               ("xultemplate[%p] match %p, %d modified binding(s)",
                this, match.operator->(), modified.GetCount()));

        for (PRInt32 i = 0; i < modified.GetCount(); ++i) {
            PRInt32 var = modified.GetVariableAt(i);
            Value val;
            match->GetAssignmentFor(mConflictSet, var, &val);

            nsCAutoString str;
            val.ToCString(str);

            PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
                   ("xultemplate[%p]   %d <= %s", this, var, str.get()));
        }
#endif

        SynchronizeMatch(match.operator->(), modified);
    }

    return NS_OK;
}

Here is the call graph for this function:

nsresult nsXULContentBuilder::SynchronizeMatch ( nsTemplateMatch aMatch,
const VariableSet aModifiedVars 
) [protected, virtual]

Must be implemented by subclasses.

Handle change in bound variable values for aMatch. aModifiedVars contains the set of variables that have changed.

Parameters:
aMatchthe match for which variable bindings has changed.
aModifiedVarsthe set of variables for which the bindings have changed.

Implements nsXULTemplateBuilder.

Definition at line 1668 of file nsXULContentBuilder.cpp.

{
    const nsTemplateRule* rule = match->mRule;

    Value memberValue;
    match->mAssignments.GetAssignmentFor(rule->GetMemberVariable(), &memberValue);

    nsIRDFResource* resource = VALUE_TO_IRDFRESOURCE(memberValue);
    NS_ASSERTION(resource != nsnull, "no content");
    if (! resource)
        return NS_ERROR_FAILURE;

#ifdef PR_LOGGING
    if (PR_LOG_TEST(gXULTemplateLog, PR_LOG_DEBUG)) {
        const char* uri;
        resource->GetValueConst(&uri);

        PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
               ("xultemplate[%p] synchronize-all [%s] begin", this, uri));
    }
#endif

    // Now that we've got the resource of the member variable, we
    // should be able to update its kids appropriately
    nsSupportsArray elements;
    GetElementsForResource(resource, &elements);

    PRUint32 cnt = 0;
    elements.Count(&cnt);

#ifdef PR_LOGGING
    if (PR_LOG_TEST(gXULTemplateLog, PR_LOG_DEBUG) && cnt == 0) {
        const char* uri;
        resource->GetValueConst(&uri);

        PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
               ("xultemplate[%p] synchronize-all [%s] is not in element map", this, uri));
    }
#endif

    for (PRInt32 i = PRInt32(cnt) - 1; i >= 0; --i) {
        nsCOMPtr<nsIContent> element = do_QueryElementAt(&elements, i);
        if (! IsElementInBuilder(element, this))
            continue;

        nsCOMPtr<nsIContent> templateNode;
        mTemplateMap.GetTemplateFor(element, getter_AddRefs(templateNode));

        NS_ASSERTION(templateNode, "couldn't find template node for element");
        if (! templateNode)
            continue;

        // this node was created by a XUL template, so update it accordingly
        SynchronizeUsingTemplate(templateNode, element, *match, modified);
    }
        
#ifdef PR_LOGGING
    if (PR_LOG_TEST(gXULTemplateLog, PR_LOG_DEBUG)) {
        const char* uri;
        resource->GetValueConst(&uri);

        PR_LOG(gXULTemplateLog, PR_LOG_DEBUG,
               ("xultemplate[%p] synchronize-all [%s] end", this, uri));
    }
#endif

    return NS_OK;
}

Here is the call graph for this function:

nsresult nsXULContentBuilder::SynchronizeUsingTemplate ( nsIContent aTemplateNode,
nsIContent aRealNode,
nsTemplateMatch aMatch,
const VariableSet aModifiedVars 
) [protected]

Definition at line 899 of file nsXULContentBuilder.cpp.

{
    nsresult rv;

    // check all attributes on the template node; if they reference a resource,
    // update the equivalent attribute on the content node

    PRUint32 numAttribs = aTemplateNode->GetAttrCount();

    for (PRUint32 loop = 0; loop < numAttribs; ++loop) {
        PRInt32    attribNameSpaceID;
        nsCOMPtr<nsIAtom> attribName, prefix;
        rv = aTemplateNode->GetAttrNameAt(loop, &attribNameSpaceID,
                                          getter_AddRefs(attribName),
                                          getter_AddRefs(prefix));
        if (NS_FAILED(rv)) break;

        // See if it's one of the attributes that we unilaterally
        // ignore. If so, on to the next one...
        if (IsIgnoreableAttribute(attribNameSpaceID, attribName))
            continue;

        nsAutoString attribValue;
        rv = aTemplateNode->GetAttr(attribNameSpaceID,
                                    attribName,
                                    attribValue);

        if (! IsAttrImpactedByVars(aMatch, attribValue, aModifiedVars))
            continue;

        nsAutoString newvalue;
        SubstituteText(aMatch, attribValue, newvalue);

        if (!newvalue.IsEmpty()) {
            aRealElement->SetAttr(attribNameSpaceID,
                                  attribName,
                                  newvalue,
                                  PR_TRUE);
        }
        else {
            aRealElement->UnsetAttr(attribNameSpaceID,
                                    attribName,
                                    PR_TRUE);
        }
    }

    // See if we've generated kids for this node yet. If we have, then
    // recursively sync up template kids with content kids
    PRBool contentsGenerated = PR_TRUE;
    nsXULElement *xulcontent = nsXULElement::FromContent(aRealElement);
    if (xulcontent) {
        contentsGenerated = xulcontent->GetLazyState(nsXULElement::eTemplateContentsBuilt);
    }
    else {
        // HTML content will _always_ have been generated up-front
    }

    if (contentsGenerated) {
        PRUint32 count = aTemplateNode->GetChildCount();

        for (PRUint32 loop = 0; loop < count; ++loop) {
            nsIContent *tmplKid = aTemplateNode->GetChildAt(loop);

            if (! tmplKid)
                break;

            nsIContent *realKid = aRealElement->GetChildAt(loop);

            if (! realKid)
                break;

            rv = SynchronizeUsingTemplate(tmplKid, realKid, aMatch, aModifiedVars);
            if (NS_FAILED(rv)) return rv;
        }
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Friends And Related Function Documentation

NS_IMETHODIMP NS_NewXULContentBuilder ( nsISupports *  aOuter,
REFNSIID  aIID,
void **  aResult 
) [friend]

Definition at line 297 of file nsXULContentBuilder.cpp.

{
    NS_PRECONDITION(aOuter == nsnull, "no aggregation");
    if (aOuter)
        return NS_ERROR_NO_AGGREGATION;

    nsresult rv;
    nsXULContentBuilder* result = new nsXULContentBuilder();
    if (! result)
        return NS_ERROR_OUT_OF_MEMORY;

    NS_ADDREF(result); // stabilize

    rv = result->Init();

    if (NS_SUCCEEDED(rv))
        rv = result->QueryInterface(aIID, aResult);

    NS_RELEASE(result);
    return rv;
}

Member Data Documentation

The composite datasource that the template builder observes and uses to create content.

Definition at line 63 of file nsIXULTemplateBuilder.idl.

Definition at line 342 of file nsXULTemplateBuilder.h.

nsIRDFService * nsXULTemplateBuilder::gRDFService [static, protected, inherited]

Definition at line 341 of file nsXULTemplateBuilder.h.

Reimplemented from nsXULTemplateBuilder.

Definition at line 289 of file nsXULContentBuilder.cpp.

Definition at line 343 of file nsXULTemplateBuilder.h.

nsIPrincipal * nsXULTemplateBuilder::gSystemPrincipal [static, protected, inherited]

Definition at line 344 of file nsXULTemplateBuilder.h.

Definition at line 290 of file nsXULContentBuilder.cpp.

Definition at line 319 of file nsXULTemplateBuilder.h.

Definition at line 314 of file nsXULTemplateBuilder.h.

Definition at line 335 of file nsXULTemplateBuilder.h.

Definition at line 332 of file nsXULTemplateBuilder.h.

Definition at line 331 of file nsXULTemplateBuilder.h.

Definition at line 326 of file nsXULTemplateBuilder.h.

Maintains a mapping between elements in the DOM and the matches in the conflict set that they support.

Definition at line 263 of file nsXULContentBuilder.cpp.

The variable that represents the ``resource element'' in the rules for this builder.

Definition at line 269 of file nsXULContentBuilder.cpp.

Definition at line 313 of file nsXULTemplateBuilder.h.

PRInt32 nsXULTemplateBuilder::mFlags [protected, inherited]

Definition at line 350 of file nsXULTemplateBuilder.h.

Definition at line 321 of file nsXULTemplateBuilder.h.

Definition at line 334 of file nsXULTemplateBuilder.h.

Definition at line 333 of file nsXULTemplateBuilder.h.

Definition at line 336 of file nsXULTemplateBuilder.h.

Definition at line 317 of file nsXULTemplateBuilder.h.

Definition at line 330 of file nsXULTemplateBuilder.h.

Definition at line 327 of file nsXULTemplateBuilder.h.

Maintains a mapping from an element in the DOM to the template element that it was created from.

Definition at line 275 of file nsXULContentBuilder.cpp.

The top of the stack of resources that we're currently building content for.

Definition at line 375 of file nsXULTemplateBuilder.h.

Definition at line 323 of file nsXULTemplateBuilder.h.

The ``root'' node in the DOM to which this builder is attached.

Definition at line 57 of file nsIXULTemplateBuilder.idl.

Information about the currently active sort.

Definition at line 280 of file nsXULContentBuilder.cpp.


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