Back to index

lightning-sunbird  0.9+nobinonly
Classes | Public Member Functions | Private Member Functions | Private Attributes | Friends
txStylesheet Class Reference

#include <txStylesheet.h>

Collaboration diagram for txStylesheet:
Collaboration graph
[legend]

List of all members.

Classes

class  GlobalVariable
class  ImportFrame
 Contain information that is import precedence dependant. More...
class  MatchableTemplate

Public Member Functions

 txStylesheet ()
 ~txStylesheet ()
nsresult init ()
nsrefcnt AddRef ()
nsrefcnt Release ()
txInstructionfindTemplate (const txXPathNode &aNode, const txExpandedName &aMode, txIMatchContext *aContext, ImportFrame *aImportedBy, ImportFrame **aImportFrame)
txDecimalFormatgetDecimalFormat (const txExpandedName &aName)
txInstructiongetAttributeSet (const txExpandedName &aName)
txInstructiongetNamedTemplate (const txExpandedName &aName)
txOutputFormatgetOutputFormat ()
GlobalVariablegetGlobalVariable (const txExpandedName &aName)
const txExpandedNameMapgetKeyMap ()
PRBool isStripSpaceAllowed (const txXPathNode &aNode, txIMatchContext *aContext)
nsresult doneCompiling ()
 Called by the stylesheet compiler once all stylesheets has been read.
nsresult addKey (const txExpandedName &aName, nsAutoPtr< txPattern > aMatch, nsAutoPtr< Expr > aUse)
 Add a key to the stylesheet.
nsresult addDecimalFormat (const txExpandedName &aName, nsAutoPtr< txDecimalFormat > aFormat)
 Add a decimal-format to the stylesheet.

Private Member Functions

nsresult addTemplate (txTemplateItem *aTemplate, ImportFrame *aImportFrame)
nsresult addGlobalVariable (txVariableItem *aVariable)
nsresult addFrames (txListIterator &aInsertIter)
nsresult addStripSpace (txStripSpaceItem *aStripSpaceItem, nsVoidArray &frameStripSpaceTests)
nsresult addAttributeSet (txAttributeSetItem *aAttributeSetItem)

Private Attributes

nsAutoRefCnt mRefCnt
txList mImportFrames
txOutputFormat mOutputFormat
txList mTemplateInstructions
ImportFramemRootFrame
txExpandedNameMap mNamedTemplates
txExpandedNameMap mDecimalFormats
txExpandedNameMap mAttributeSets
txExpandedNameMap mGlobalVariables
txExpandedNameMap mKeys
nsVoidArray mStripSpaceTests
nsAutoPtr< txInstructionmContainerTemplate
nsAutoPtr< txInstructionmCharactersTemplate
nsAutoPtr< txInstructionmEmptyTemplate

Friends

class txStylesheetCompilerState
class ImportFrame

Detailed Description

Definition at line 56 of file txStylesheet.h.


Constructor & Destructor Documentation

Definition at line 115 of file txStylesheet.cpp.

{
    // Delete all ImportFrames
    delete mRootFrame;
    txListIterator frameIter(&mImportFrames);
    while (frameIter.hasNext()) {
        delete NS_STATIC_CAST(ImportFrame*, frameIter.next());
    }

    txListIterator instrIter(&mTemplateInstructions);
    while (instrIter.hasNext()) {
        delete NS_STATIC_CAST(txInstruction*, instrIter.next());
    }
    
    // We can't make the map own its values because then we wouldn't be able
    // to merge attributesets of the same name
    txExpandedNameMap::iterator attrSetIter(mAttributeSets);
    while (attrSetIter.next()) {
        delete attrSetIter.value();
    }
}

Here is the call graph for this function:


Member Function Documentation

nsresult txStylesheet::addAttributeSet ( txAttributeSetItem aAttributeSetItem) [private]

Definition at line 534 of file txStylesheet.cpp.

{
    nsresult rv = NS_OK;
    txInstruction* oldInstr =
        NS_STATIC_CAST(txInstruction*,
                       mAttributeSets.get(aAttributeSetItem->mName));
    if (!oldInstr) {
        rv = mAttributeSets.add(aAttributeSetItem->mName,
                                aAttributeSetItem->mFirstInstruction);
        NS_ENSURE_SUCCESS(rv, rv);
        
        aAttributeSetItem->mFirstInstruction.forget();
        
        return NS_OK;
    }
    
    // We need to prepend the new instructions before the existing ones.
    txInstruction* instr = aAttributeSetItem->mFirstInstruction;
    txInstruction* lastNonReturn = nsnull;
    while (instr->mNext) {
        lastNonReturn = instr;
        instr = instr->mNext;
    }
    
    if (!lastNonReturn) {
        // The new attributeset is empty, so lets just ignore it.
        return NS_OK;
    }

    rv = mAttributeSets.set(aAttributeSetItem->mName,
                            aAttributeSetItem->mFirstInstruction);
    NS_ENSURE_SUCCESS(rv, rv);

    aAttributeSetItem->mFirstInstruction.forget();

    delete lastNonReturn->mNext;      // Delete the txReturn...
    lastNonReturn->mNext = oldInstr;  // ...and link up the old instructions.

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Add a decimal-format to the stylesheet.

Definition at line 619 of file txStylesheet.cpp.

{
    txDecimalFormat* existing =
        NS_STATIC_CAST(txDecimalFormat*, mDecimalFormats.get(aName));
    if (existing) {
        NS_ENSURE_TRUE(existing->isEqual(aFormat),
                       NS_ERROR_XSLT_PARSE_FAILURE);

        return NS_OK;
    }

    nsresult rv = mDecimalFormats.add(aName, aFormat);
    NS_ENSURE_SUCCESS(rv, rv);
    
    aFormat.forget();

    return NS_OK;
}

Here is the call graph for this function:

nsresult txStylesheet::addFrames ( txListIterator aInsertIter) [private]

Definition at line 480 of file txStylesheet.cpp.

{
    ImportFrame* frame = NS_STATIC_CAST(ImportFrame*, aInsertIter.current());
    nsresult rv = NS_OK;
    txListIterator iter(&frame->mToplevelItems);
    txToplevelItem* item;
    while ((item = NS_STATIC_CAST(txToplevelItem*, iter.next()))) {
        if (item->getType() == txToplevelItem::import) {
            txImportItem* import = NS_STATIC_CAST(txImportItem*, item);
            import->mFrame->mFirstNotImported =
                NS_STATIC_CAST(ImportFrame*, aInsertIter.next());
            rv = aInsertIter.addBefore(import->mFrame);
            NS_ENSURE_SUCCESS(rv, rv);

            import->mFrame.forget();
            aInsertIter.previous();
            rv = addFrames(aInsertIter);
            NS_ENSURE_SUCCESS(rv, rv);
            aInsertIter.previous();
        }
    }
    
    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 576 of file txStylesheet.cpp.

{
    if (mGlobalVariables.get(aVariable->mName)) {
        return NS_OK;
    }
    nsAutoPtr<GlobalVariable> var(
        new GlobalVariable(aVariable->mValue, aVariable->mFirstInstruction,
                           aVariable->mIsParam));
    NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
    
    nsresult rv = mGlobalVariables.add(aVariable->mName, var);
    NS_ENSURE_SUCCESS(rv, rv);
    
    var.forget();
    
    return NS_OK;
    
}

Here is the call graph for this function:

Here is the caller graph for this function:

Add a key to the stylesheet.

Definition at line 596 of file txStylesheet.cpp.

{
    nsresult rv = NS_OK;

    txXSLKey* xslKey = NS_STATIC_CAST(txXSLKey*, mKeys.get(aName));
    if (!xslKey) {
        xslKey = new txXSLKey(aName);
        NS_ENSURE_TRUE(xslKey, NS_ERROR_OUT_OF_MEMORY);

        rv = mKeys.add(aName, xslKey);
        if (NS_FAILED(rv)) {
            delete xslKey;
            return rv;
        }
    }
    if (!xslKey->addKey(aMatch, aUse)) {
        return NS_ERROR_OUT_OF_MEMORY;
    }
    return NS_OK;
}

Here is the call graph for this function:

Definition at line 69 of file txStylesheet.h.

    {
        return ++mRefCnt;
    }
nsresult txStylesheet::addStripSpace ( txStripSpaceItem aStripSpaceItem,
nsVoidArray frameStripSpaceTests 
) [private]

Definition at line 506 of file txStylesheet.cpp.

{
    PRInt32 testCount = aStripSpaceItem->mStripSpaceTests.Count();
    for (; testCount > 0; --testCount) {
        txStripSpaceTest* sst =
            NS_STATIC_CAST(txStripSpaceTest*,
                           aStripSpaceItem->mStripSpaceTests[testCount-1]);
        double priority = sst->getDefaultPriority();
        PRInt32 i, frameCount = frameStripSpaceTests.Count();
        for (i = 0; i < frameCount; ++i) {
            txStripSpaceTest* fsst =
                NS_STATIC_CAST(txStripSpaceTest*, frameStripSpaceTests[i]);
            if (fsst->getDefaultPriority() < priority) {
                break;
            }
        }
        if (!frameStripSpaceTests.InsertElementAt(sst, i)) {
            return NS_ERROR_OUT_OF_MEMORY;
        }

        aStripSpaceItem->mStripSpaceTests.RemoveElementAt(testCount-1);
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult txStylesheet::addTemplate ( txTemplateItem aTemplate,
ImportFrame aImportFrame 
) [private]

Definition at line 395 of file txStylesheet.cpp.

{
    NS_ASSERTION(aTemplate, "missing template");

    txInstruction* instr = aTemplate->mFirstInstruction;
    nsresult rv = mTemplateInstructions.add(instr);
    NS_ENSURE_SUCCESS(rv, rv);

    // mTemplateInstructions now owns the instructions
    aTemplate->mFirstInstruction.forget();

    if (!aTemplate->mName.isNull()) {
        rv = mNamedTemplates.add(aTemplate->mName, instr);
        NS_ENSURE_TRUE(NS_SUCCEEDED(rv) || rv == NS_ERROR_XSLT_ALREADY_SET,
                       rv);
    }

    if (!aTemplate->mMatch) {
        // This is no error, see section 6 Named Templates

        return NS_OK;
    }

    // get the txList for the right mode
    txList* templates =
        NS_STATIC_CAST(txList*,
                       aImportFrame->mMatchableTemplates.get(aTemplate->mMode));

    if (!templates) {
        nsAutoPtr<txList> newList(new txList);
        NS_ENSURE_TRUE(newList, NS_ERROR_OUT_OF_MEMORY);

        rv = aImportFrame->mMatchableTemplates.add(aTemplate->mMode, newList);
        NS_ENSURE_SUCCESS(rv, rv);
        
        templates = newList.forget();
    }

    // Add the simple patterns to the list of matchable templates, according
    // to default priority
    txList simpleMatches;
    rv = aTemplate->mMatch->getSimplePatterns(simpleMatches);
    if (simpleMatches.get(0) == aTemplate->mMatch) {
        aTemplate->mMatch.forget();
    }
    
    txListIterator simples(&simpleMatches);
    while (simples.hasNext()) {
        // XXX if we fail in this loop, we leak the remaining simple patterns
        nsAutoPtr<txPattern> simple(NS_STATIC_CAST(txPattern*, simples.next()));
        double priority = aTemplate->mPrio;
        if (Double::isNaN(priority)) {
            priority = simple->getDefaultPriority();
            NS_ASSERTION(!Double::isNaN(priority),
                         "simple pattern without default priority");
        }
        nsAutoPtr<MatchableTemplate>
            nt(new MatchableTemplate(instr, simple, priority));
        NS_ENSURE_TRUE(nt, NS_ERROR_OUT_OF_MEMORY);

        txListIterator templ(templates);
        while (templ.hasNext()) {
            MatchableTemplate* mt = NS_STATIC_CAST(MatchableTemplate*,
                                                   templ.next());
            if (priority > mt->mPriority) {
                rv = templ.addBefore(nt);
                NS_ENSURE_SUCCESS(rv, rv);

                nt.forget();
                break;
            }
        }
        if (nt) {
            rv = templates->add(nt);
            NS_ENSURE_SUCCESS(rv, rv);

            nt.forget();
        }
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Called by the stylesheet compiler once all stylesheets has been read.

Definition at line 304 of file txStylesheet.cpp.

{
    nsresult rv = NS_OK;
    // Collect all importframes into a single ordered list
    txListIterator frameIter(&mImportFrames);
    rv = frameIter.addAfter(mRootFrame);
    NS_ENSURE_SUCCESS(rv, rv);
    
    mRootFrame = nsnull;
    frameIter.next();
    rv = addFrames(frameIter);
    NS_ENSURE_SUCCESS(rv, rv);

    // Loop through importframes in decreasing-precedence-order and process
    // all items
    frameIter.reset();
    ImportFrame* frame;
    while ((frame = NS_STATIC_CAST(ImportFrame*, frameIter.next()))) {
        nsVoidArray frameStripSpaceTests;

        txListIterator itemIter(&frame->mToplevelItems);
        itemIter.resetToEnd();
        txToplevelItem* item;
        while ((item = NS_STATIC_CAST(txToplevelItem*, itemIter.previous()))) {
            switch (item->getType()) {
                case txToplevelItem::attributeSet:
                {
                    rv = addAttributeSet(NS_STATIC_CAST(txAttributeSetItem*,
                                                        item));
                    NS_ENSURE_SUCCESS(rv, rv);
                    break;
                }
                case txToplevelItem::dummy:
                case txToplevelItem::import:
                {
                    break;
                }
                case txToplevelItem::output:
                {
                    mOutputFormat.merge(NS_STATIC_CAST(txOutputItem*, item)->mFormat);
                    break;
                }
                case txToplevelItem::stripSpace:
                {
                    rv = addStripSpace(NS_STATIC_CAST(txStripSpaceItem*, item),
                                       frameStripSpaceTests);
                    NS_ENSURE_SUCCESS(rv, rv);
                    break;
                }
                case txToplevelItem::templ:
                {
                    rv = addTemplate(NS_STATIC_CAST(txTemplateItem*, item),
                                     frame);
                    NS_ENSURE_SUCCESS(rv, rv);

                    break;
                }
                case txToplevelItem::variable:
                {
                    rv = addGlobalVariable(NS_STATIC_CAST(txVariableItem*,
                                                          item));
                    NS_ENSURE_SUCCESS(rv, rv);

                    break;
                }
            }
            delete item;
            itemIter.remove(); //remove() moves to the previous
            itemIter.next();
        }
        if (!mStripSpaceTests.AppendElements(frameStripSpaceTests)) {
            return NS_ERROR_OUT_OF_MEMORY;
        }
        
        frameStripSpaceTests.Clear();
    }

    if (!mDecimalFormats.get(txExpandedName())) {
        nsAutoPtr<txDecimalFormat> format(new txDecimalFormat);
        NS_ENSURE_TRUE(format, NS_ERROR_OUT_OF_MEMORY);
        
        rv = mDecimalFormats.add(txExpandedName(), format);
        NS_ENSURE_SUCCESS(rv, rv);
        
        format.forget();
    }

    return NS_OK;
}

Here is the call graph for this function:

txInstruction * txStylesheet::findTemplate ( const txXPathNode aNode,
const txExpandedName aMode,
txIMatchContext aContext,
ImportFrame aImportedBy,
ImportFrame **  aImportFrame 
)

Definition at line 138 of file txStylesheet.cpp.

{
    NS_ASSERTION(aImportFrame, "missing ImportFrame pointer");

    *aImportFrame = nsnull;
    txInstruction* matchTemplate = nsnull;
    ImportFrame* endFrame = nsnull;
    txListIterator frameIter(&mImportFrames);

    if (aImportedBy) {
        ImportFrame* curr = NS_STATIC_CAST(ImportFrame*, frameIter.next());
        while (curr != aImportedBy) {
               curr = NS_STATIC_CAST(ImportFrame*, frameIter.next());
        }
        endFrame = aImportedBy->mFirstNotImported;
    }

#ifdef PR_LOGGING
    txPattern* match = 0;
#endif

    ImportFrame* frame;
    while (!matchTemplate &&
           (frame = NS_STATIC_CAST(ImportFrame*, frameIter.next())) &&
           frame != endFrame) {

        // get templatelist for this mode
        txList* templates =
            NS_STATIC_CAST(txList*, frame->mMatchableTemplates.get(aMode));

        if (templates) {
            txListIterator templateIter(templates);

            // Find template with highest priority
            MatchableTemplate* templ;
            while (!matchTemplate &&
                   (templ =
                    NS_STATIC_CAST(MatchableTemplate*, templateIter.next()))) {
                if (templ->mMatch->matches(aNode, aContext)) {
                    matchTemplate = templ->mFirstInstruction;
                    *aImportFrame = frame;
#ifdef PR_LOGGING
                    match = templ->mMatch;
#endif
                }
            }
        }
    }

#ifdef PR_LOGGING
    nsAutoString mode, nodeName;
    if (aMode.mLocalName) {
        aMode.mLocalName->ToString(mode);
    }
    txXPathNodeUtils::getNodeName(aNode, nodeName);
    if (matchTemplate) {
        nsAutoString matchAttr;
#ifdef TX_TO_STRING
        match->toString(matchAttr);
#endif
        PR_LOG(txLog::xslt, PR_LOG_DEBUG,
               ("MatchTemplate, Pattern %s, Mode %s, Node %s\n",
                NS_LossyConvertUCS2toASCII(matchAttr).get(),
                NS_LossyConvertUCS2toASCII(mode).get(),
                NS_LossyConvertUCS2toASCII(nodeName).get()));
    }
    else {
        PR_LOG(txLog::xslt, PR_LOG_DEBUG,
               ("No match, Node %s, Mode %s\n", 
                NS_LossyConvertUCS2toASCII(nodeName).get(),
                NS_LossyConvertUCS2toASCII(mode).get()));
    }
#endif

    if (!matchTemplate) {
        if (txXPathNodeUtils::isElement(aNode) ||
            txXPathNodeUtils::isRoot(aNode)) {
            matchTemplate = mContainerTemplate;
        }
        else if (txXPathNodeUtils::isAttribute(aNode) ||
                 txXPathNodeUtils::isText(aNode)) {
            matchTemplate = mCharactersTemplate;
        }
        else {
            matchTemplate = mEmptyTemplate;
        }
    }

    return matchTemplate;
}

Here is the call graph for this function:

Definition at line 240 of file txStylesheet.cpp.

Here is the call graph for this function:

Definition at line 234 of file txStylesheet.cpp.

Here is the call graph for this function:

Definition at line 258 of file txStylesheet.cpp.

{
    return NS_STATIC_CAST(GlobalVariable*, mGlobalVariables.get(aName));
}

Here is the call graph for this function:

Definition at line 264 of file txStylesheet.cpp.

{
    return mKeys;
}

Definition at line 246 of file txStylesheet.cpp.

Here is the call graph for this function:

Definition at line 252 of file txStylesheet.cpp.

{
    return &mOutputFormat;
}

Definition at line 59 of file txStylesheet.cpp.

{
    mRootFrame = new ImportFrame;
    NS_ENSURE_TRUE(mRootFrame, NS_ERROR_OUT_OF_MEMORY);
    
    // Create default templates
    // element/root template
    mContainerTemplate = new txPushParams;
    NS_ENSURE_TRUE(mContainerTemplate, NS_ERROR_OUT_OF_MEMORY);

    nsAutoPtr<txNodeTest> nt(new txNodeTypeTest(txNodeTypeTest::NODE_TYPE));
    NS_ENSURE_TRUE(nt, NS_ERROR_OUT_OF_MEMORY);

    nsAutoPtr<Expr> nodeExpr(new LocationStep(nt, LocationStep::CHILD_AXIS));
    NS_ENSURE_TRUE(nodeExpr, NS_ERROR_OUT_OF_MEMORY);

    txPushNewContext* pushContext = new txPushNewContext(nodeExpr);
    mContainerTemplate->mNext = pushContext;
    NS_ENSURE_TRUE(pushContext, NS_ERROR_OUT_OF_MEMORY);

    txApplyDefaultElementTemplate* applyTemplates =
        new txApplyDefaultElementTemplate;
    pushContext->mNext = applyTemplates;
    NS_ENSURE_TRUE(applyTemplates, NS_ERROR_OUT_OF_MEMORY);

    txLoopNodeSet* loopNodeSet = new txLoopNodeSet(applyTemplates);
    applyTemplates->mNext = loopNodeSet;
    NS_ENSURE_TRUE(loopNodeSet, NS_ERROR_OUT_OF_MEMORY);

    txPopParams* popParams = new txPopParams;
    pushContext->mBailTarget = loopNodeSet->mNext = popParams;
    NS_ENSURE_TRUE(popParams, NS_ERROR_OUT_OF_MEMORY);

    popParams->mNext = new txReturn();
    NS_ENSURE_TRUE(popParams->mNext, NS_ERROR_OUT_OF_MEMORY);

    // attribute/textnode template
    nt = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE);
    NS_ENSURE_TRUE(nt, NS_ERROR_OUT_OF_MEMORY);

    nodeExpr = new LocationStep(nt, LocationStep::SELF_AXIS);
    NS_ENSURE_TRUE(nodeExpr, NS_ERROR_OUT_OF_MEMORY);

    mCharactersTemplate = new txValueOf(nodeExpr, PR_FALSE);
    NS_ENSURE_TRUE(mCharactersTemplate, NS_ERROR_OUT_OF_MEMORY);

    mCharactersTemplate->mNext = new txReturn();
    NS_ENSURE_TRUE(mCharactersTemplate->mNext, NS_ERROR_OUT_OF_MEMORY);

    // pi/comment/namespace template
    mEmptyTemplate = new txReturn();
    NS_ENSURE_TRUE(mEmptyTemplate, NS_ERROR_OUT_OF_MEMORY);

    return NS_OK;
}

Definition at line 270 of file txStylesheet.cpp.

{
    PRInt32 frameCount = mStripSpaceTests.Count();
    if (frameCount == 0) {
        return PR_FALSE;
    }

    txXPathTreeWalker walker(aNode);

    if (txXPathNodeUtils::isText(walker.getCurrentPosition()) &&
        (!txXPathNodeUtils::isWhitespace(aNode) || !walker.moveToParent())) {
        return PR_FALSE;
    }

    const txXPathNode& node = walker.getCurrentPosition();

    if (!txXPathNodeUtils::isElement(node)) {
        return PR_FALSE;
    }

    // check Whitespace stipping handling list against given Node
    PRInt32 i;
    for (i = 0; i < frameCount; ++i) {
        txStripSpaceTest* sst =
            NS_STATIC_CAST(txStripSpaceTest*, mStripSpaceTests[i]);
        if (sst->matches(node, aContext)) {
            return sst->stripsSpace() && !XMLUtils::getXMLSpacePreserve(node);
        }
    }

    return PR_FALSE;
}

Here is the call graph for this function:

Definition at line 73 of file txStylesheet.h.

    {
        if (--mRefCnt == 0) {
            mRefCnt = 1; //stabilize
            delete this;
            return 0;
        }
        return mRefCnt;
    }

Friends And Related Function Documentation

friend class ImportFrame [friend]

Definition at line 63 of file txStylesheet.h.

friend class txStylesheetCompilerState [friend]

Definition at line 60 of file txStylesheet.h.


Member Data Documentation

Definition at line 190 of file txStylesheet.h.

Definition at line 203 of file txStylesheet.h.

Definition at line 202 of file txStylesheet.h.

Definition at line 187 of file txStylesheet.h.

Definition at line 204 of file txStylesheet.h.

Definition at line 193 of file txStylesheet.h.

Definition at line 171 of file txStylesheet.h.

Definition at line 196 of file txStylesheet.h.

Definition at line 184 of file txStylesheet.h.

Definition at line 174 of file txStylesheet.h.

Definition at line 168 of file txStylesheet.h.

Definition at line 181 of file txStylesheet.h.

Definition at line 199 of file txStylesheet.h.

Definition at line 178 of file txStylesheet.h.


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