Back to index

lightning-sunbird  0.9+nobinonly
Classes | Public Member Functions | Static Public Member Functions | Public Attributes | Protected Types | Protected Member Functions | Protected Attributes | Static Protected Attributes
nsXULTemplateBuilder Class Reference

An object that translates an RDF graph into a presentation using a set of rules. More...

#include <nsXULTemplateBuilder.h>

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

List of all members.

Classes

class  ActivationEntry
 Stack-based helper class to maintain a list of ``activated'' resources; i.e., resources for which we are currently building content. More...

Public Member Functions

 nsXULTemplateBuilder ()
virtual ~nsXULTemplateBuilder ()
nsresult Init ()
NS_DECL_ISUPPORTS virtual
NS_DECL_NSIXULTEMPLATEBUILDER
void 
AttributeChanged (nsIDocument *aDocument, nsIContent *aContent, PRInt32 aNameSpaceID, nsIAtom *aAttribute, PRInt32 aModType)
 Notification that the content model has changed.
virtual void DocumentWillBeDestroyed (nsIDocument *aDocument)
 The document is in the process of being destroyed.
NS_DECL_NSIRDFOBSERVER nsresult ComputeContainmentProperties ()
virtual nsresult InitializeRuleNetwork ()
 Initialize the rule network.
virtual nsresult InitializeRuleNetworkForSimpleRules (InnerNode **aChildNode)=0
 Initialize the rule network for handling rules that use the ``simple'' syntax.
virtual nsresult RebuildAll ()=0
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.
virtual nsresult CompileCondition (nsIAtom *aTag, nsTemplateRule *aRule, nsIContent *aConditions, InnerNode *aParentNode, TestNode **aResult)
 Compile a single condition from an extended template syntax rule.
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.
virtual PRBool CompileSimpleAttributeCondition (PRInt32 aNameSpaceID, nsIAtom *aAttribute, const nsAString &aValue, InnerNode *aParentNode, TestNode **aResult)
 Can be overridden by subclasses to handle special attribute conditions for the simple 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

PRBool IsActivated (nsIRDFResource *aResource)
 Determine if a resource is currently on the activation stack.
virtual nsresult ReplaceMatch (nsIRDFResource *aMember, const nsTemplateMatch *aOldMatch, nsTemplateMatch *aNewMatch)=0
 Must be implemented by subclasses.
virtual nsresult SynchronizeMatch (nsTemplateMatch *aMatch, const VariableSet &aModifiedVars)=0
 Must be implemented by subclasses.

Protected Attributes

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 nsrefcnt gRefCnt = 0
static nsIRDFServicegRDFService
static nsIRDFContainerUtilsgRDFContainerUtils
static nsIScriptSecurityManagergScriptSecurityManager
static nsIPrincipalgSystemPrincipal

Detailed Description

An object that translates an RDF graph into a presentation using a set of rules.

Definition at line 77 of file nsXULTemplateBuilder.h.


Member Enumeration Documentation

anonymous enum [protected]
Enumerator:
eDontTestEmpty 

Definition at line 346 of file nsXULTemplateBuilder.h.

         {
        eDontTestEmpty = (1 << 0)
    };

Constructor & Destructor Documentation


Member Function Documentation

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

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.

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 nsXULTemplateBuilder::AttributeChanged ( nsIDocument aDocument,
nsIContent aContent,
PRInt32  aNameSpaceID,
nsIAtom aAttribute,
PRInt32  aModType 
) [virtual]

Notification that the content model has changed.

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

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

Implements nsIDocumentObserver.

Reimplemented in nsXULContentBuilder.

Definition at line 333 of file nsXULTemplateBuilder.cpp.

{
    if (aContent == mRoot) {
        // Check for a change to the 'ref' attribute on an atom, in which
        // case we may need to nuke and rebuild the entire content model
        // beneath the element.
        if (aAttribute == nsXULAtoms::ref)
            Rebuild();

        // Check for a change to the 'datasources' attribute. If so, setup
        // mDB by parsing the vew value and rebuild.
        else if (aAttribute == nsXULAtoms::datasources) {
            LoadDataSources(aDocument);
            Rebuild();
        }
    }        
}

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.

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 
)

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:

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:

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 nsXULTemplateBuilder::CompileCondition ( nsIAtom aTag,
nsTemplateRule aRule,
nsIContent aConditions,
InnerNode aParentNode,
TestNode **  aResult 
) [virtual]

Compile a single condition from an extended template syntax rule.

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

Reimplemented in nsXULContentBuilder, and nsXULTreeBuilder.

Definition at line 1756 of file nsXULTemplateBuilder.cpp.

{
    nsresult rv;

    if (aTag == nsXULAtoms::triple) {
        rv = CompileTripleCondition(aRule, aCondition, aParentNode, aResult);
    }
    else if (aTag == nsXULAtoms::member) {
        rv = CompileMemberCondition(aRule, aCondition, aParentNode, aResult);
    }
    else {
#ifdef PR_LOGGING
        nsAutoString tagstr;
        aTag->ToString(tagstr);

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

        rv = NS_OK;
    }

    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

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 nsXULTemplateBuilder::CompileExtendedRule ( nsIContent aRuleElement,
PRInt32  aPriority,
InnerNode aParentNode 
)

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 
)

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 nsXULTemplateBuilder::CompileSimpleAttributeCondition ( PRInt32  aNameSpaceID,
nsIAtom aAttribute,
const nsAString &  aValue,
InnerNode aParentNode,
TestNode **  aResult 
) [virtual]

Can be overridden by subclasses to handle special attribute conditions for the simple syntax.

Returns:
PR_TRUE if the condition was handled

Reimplemented in nsXULContentBuilder.

Definition at line 2237 of file nsXULTemplateBuilder.cpp.

{
    // By default, not handled
    return PR_FALSE;
}

Here is the caller graph for this function:

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

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 
)

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.

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

The document is in the process of being destroyed.

This method is called automatically during document destruction.

Parameters:
aDocumentThe document being observed

Implements nsIDocumentObserver.

Reimplemented in nsXULContentBuilder, and nsXULTreeBuilder.

Definition at line 356 of file nsXULTemplateBuilder.cpp.

{
    // The call to RemoveObserver could release the last reference to
    // |this|, so hold another reference.
    nsRefPtr<nsXULTemplateBuilder> kungFuDeathGrip(this);

    // Break circular references
    if (mDB) {
        mDB->RemoveObserver(this);
        mDB = nsnull;
        mCompDB = nsnull;
    }

    mRoot = nsnull;
}
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.

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:

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:

Reimplemented in nsXULContentBuilder, and nsXULTreeBuilder.

Definition at line 174 of file nsXULTemplateBuilder.cpp.

{
    if (gRefCnt++ == 0) {
        nsresult rv;

        // Initialize the global shared reference to the service
        // manager and get some shared resource objects.
        rv = CallGetService(kRDFServiceCID, &gRDFService);
        if (NS_FAILED(rv))
            return rv;

        rv = CallGetService(kRDFContainerUtilsCID, &gRDFContainerUtils);
        if (NS_FAILED(rv))
            return rv;

        rv = CallGetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID,
                            &gScriptSecurityManager);
        if (NS_FAILED(rv))
            return rv;

        rv = gScriptSecurityManager->GetSystemPrincipal(&gSystemPrincipal);
        if (NS_FAILED(rv))
            return rv;
    }

#ifdef PR_LOGGING
    if (! gXULTemplateLog)
        gXULTemplateLog = PR_NewLogModule("nsXULTemplateBuilder");
#endif

    return NS_OK;
}

Here is the call 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.

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 in nsXULContentBuilder.

Definition at line 1403 of file nsXULTemplateBuilder.cpp.

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

    // Determine if there are any special settings we need to observe
    mFlags = 0;

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

    if (flags.Find(NS_LITERAL_STRING("dont-test-empty")) >= 0)
        mFlags |= eDontTestEmpty;

    // Initialize the rule network
    mRules.Clear();
    mRules.Clear();
    mRDFTests.Clear();
    ComputeContainmentProperties();

    mContainerVar = mRules.CreateAnonymousVariable();
    mMemberVar = mRules.CreateAnonymousVariable();

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

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

Implemented in nsXULContentBuilder, and nsXULTreeBuilder.

Here is the caller graph for this function:

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 
)

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:

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:

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]

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
void nsXULTemplateBuilder::ParseAttribute ( const nsAString &  aAttributeValue,
void(*)(nsXULTemplateBuilder *aThis, const nsAString &, void *)  aVariableCallback,
void(*)(nsXULTemplateBuilder *aThis, const nsAString &, void *)  aTextCallback,
void aClosure 
)

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 
)

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 
)

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.

virtual nsresult nsXULTemplateBuilder::RebuildAll ( ) [pure virtual]

Implemented in nsXULContentBuilder, and nsXULTreeBuilder.

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.

Remove a listener from this template builder.

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

Must be implemented by subclasses.

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

Implemented in nsXULContentBuilder, and nsXULTreeBuilder.

Here is the caller graph for this function:

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

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:

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 
)

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]

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]

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 
)

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:

virtual nsresult nsXULTemplateBuilder::SynchronizeMatch ( nsTemplateMatch aMatch,
const VariableSet aModifiedVars 
) [protected, pure 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.

Implemented in nsXULContentBuilder, and nsXULTreeBuilder.

Here is the caller graph for this function:


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.

Definition at line 341 of file nsXULTemplateBuilder.h.

nsrefcnt nsXULTemplateBuilder::gRefCnt = 0 [static, protected]

Reimplemented in nsXULContentBuilder, and nsXULTreeBuilder.

Definition at line 340 of file nsXULTemplateBuilder.h.

Definition at line 343 of file nsXULTemplateBuilder.h.

Definition at line 344 of file nsXULTemplateBuilder.h.

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.

Definition at line 313 of file nsXULTemplateBuilder.h.

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.

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.


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