Back to index

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

#include <txMozillaXMLOutput.h>

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

List of all members.

Public Member Functions

 txMozillaXMLOutput (const nsAString &aRootName, PRInt32 aRootNsID, txOutputFormat *aFormat, nsIDOMDocument *aSourceDocument, nsIDOMDocument *aResultDocument, nsITransformObserver *aObserver)
 txMozillaXMLOutput (txOutputFormat *aFormat, nsIDOMDocumentFragment *aFragment)
virtual ~txMozillaXMLOutput ()
virtual void getOutputDocument (nsIDOMDocument **aDocument)=0
 Gets the Mozilla output document.
virtual void attribute (const nsAString &aName, const PRInt32 aNsID, const nsAString &aValue)=0
 Signals to receive the start of an attribute.
virtual void characters (const nsAString &aData, PRBool aDOE)=0
 Signals to receive characters.
virtual void comment (const nsAString &aData)=0
 Signals to receive data that should be treated as a comment.
virtual void endDocument (nsresult aResult)=0
 Signals the end of a document.
virtual void endElement (const nsAString &aName, const PRInt32 aNsID)=0
 Signals to receive the end of an element.
virtual void processingInstruction (const nsAString &aTarget, const nsAString &aData)=0
 Signals to receive a processing instruction.
virtual void startDocument ()=0
 Signals the start of a document.
virtual void startElement (const nsAString &aName, const PRInt32 aNsID)=0
 Signals to receive the start of an element.

Private Types

enum  TableState { NORMAL, TABLE, ADDED_TBODY }
enum  txAction { eCloseElement = 1, eFlushText = 2 }

Private Member Functions

void closePrevious (PRInt8 aAction)
void startHTMLElement (nsIDOMElement *aElement, PRBool aXHTML)
void endHTMLElement (nsIDOMElement *aElement)
void processHTTPEquiv (nsIAtom *aHeader, const nsAString &aValue)
nsresult createResultDocument (const nsAString &aName, PRInt32 aNsID, nsIDOMDocument *aSourceDocument, nsIDOMDocument *aResultDocument)
nsresult createHTMLElement (const nsAString &aName, nsIDOMElement **aResult)

Private Attributes

nsCOMPtr< nsIDOMDocumentmDocument
nsCOMPtr< nsIDOMNodemCurrentNode
nsCOMPtr< nsIDOMNodemParentNode
nsCOMPtr< nsIContentmRootContent
nsCOMPtr< nsIDOMNodemNonAddedParent
nsCOMPtr< nsIDOMNodemNonAddedNode
nsRefPtr< txTransformNotifiermNotifier
PRUint32 mTreeDepth
PRUint32 mBadChildLevel
nsCString mRefreshString
txStack mTableStateStack
TableState mTableState
nsAutoString mText
txOutputFormat mOutputFormat
PRPackedBool mDontAddCurrent
PRPackedBool mHaveTitleElement
PRPackedBool mHaveBaseElement
PRPackedBool mDocumentIsHTML
PRPackedBool mCreatingNewDocument

Detailed Description

Definition at line 89 of file txMozillaXMLOutput.h.


Member Enumeration Documentation

Enumerator:
NORMAL 
TABLE 
ADDED_TBODY 

Definition at line 130 of file txMozillaXMLOutput.h.

                    { 
        NORMAL,      // An element needing no special treatment
        TABLE,       // A HTML table element
        ADDED_TBODY  // An inserted tbody not coming from the stylesheet
    };
Enumerator:
eCloseElement 
eFlushText 

Definition at line 149 of file txMozillaXMLOutput.h.

{ eCloseElement = 1, eFlushText = 2 };

Constructor & Destructor Documentation

txMozillaXMLOutput::txMozillaXMLOutput ( const nsAString &  aRootName,
PRInt32  aRootNsID,
txOutputFormat aFormat,
nsIDOMDocument aSourceDocument,
nsIDOMDocument aResultDocument,
nsITransformObserver aObserver 
)

Definition at line 89 of file txMozillaXMLOutput.cpp.

    : mTreeDepth(0),
      mBadChildLevel(0),
      mTableState(NORMAL),
      mDontAddCurrent(PR_FALSE),
      mHaveTitleElement(PR_FALSE),
      mHaveBaseElement(PR_FALSE),
      mCreatingNewDocument(PR_TRUE)
{
    if (aObserver) {
        mNotifier = new txTransformNotifier();
        if (mNotifier) {
            mNotifier->Init(aObserver);
        }
    }

    mOutputFormat.merge(*aFormat);
    mOutputFormat.setFromDefaults();

    createResultDocument(aRootName, aRootNsID, aSourceDocument, aResultDocument);
}

Here is the call graph for this function:

Definition at line 116 of file txMozillaXMLOutput.cpp.

Here is the call graph for this function:

Definition at line 136 of file txMozillaXMLOutput.cpp.

{
}

Member Function Documentation

virtual void txAXMLEventHandler::attribute ( const nsAString &  aName,
const PRInt32  aNsID,
const nsAString &  aValue 
) [pure virtual, inherited]

Signals to receive the start of an attribute.

Parameters:
aNamethe name of the attribute
aNsIDthe namespace ID of the attribute
aValuethe value of the attribute

Implemented in txHTMLOutput, and txUnknownHandler.

Here is the caller graph for this function:

virtual void txAXMLEventHandler::characters ( const nsAString &  aData,
PRBool  aDOE 
) [pure virtual, inherited]

Signals to receive characters.

Parameters:
aDatathe characters to receive
aDOEdisable output escaping for these characters

Implemented in txHTMLOutput.

Here is the caller graph for this function:

void txMozillaXMLOutput::closePrevious ( PRInt8  aAction) [private]

Definition at line 470 of file txMozillaXMLOutput.cpp.

{
    TX_ENSURE_CURRENTNODE;

    nsresult rv;
    if ((aAction & eCloseElement) && mParentNode) {
        nsCOMPtr<nsIDocument> document = do_QueryInterface(mParentNode);
        nsCOMPtr<nsIDOMElement> currentElement = do_QueryInterface(mCurrentNode);

        if (document && currentElement && mRootContent) {
            // We already have a document element, but the XSLT spec allows this.
            // As a workaround, create a wrapper object and use that as the
            // document element.
            nsCOMPtr<nsIDOMElement> wrapper;

            rv = mDocument->CreateElementNS(NS_LITERAL_STRING(kTXNameSpaceURI),
                                            NS_LITERAL_STRING(kTXWrapper),
                                            getter_AddRefs(wrapper));
            NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create wrapper element");

            nsCOMPtr<nsIDOMNode> child, resultNode;
            PRUint32 i, childCount = document->GetChildCount();
            for (i = 0; i < childCount; ++i) {
                nsCOMPtr<nsIContent> childContent = document->GetChildAt(0);
                if (childContent == mRootContent) {
                    document->SetRootContent(nsnull);
                }
                child = do_QueryInterface(childContent);
                wrapper->AppendChild(child, getter_AddRefs(resultNode));
            }

            mParentNode = wrapper;
            mRootContent = do_QueryInterface(wrapper);
            // XXXbz what to do on failure here?
            document->SetRootContent(mRootContent);
        }

        if (mDontAddCurrent && !mNonAddedParent) {
            mNonAddedParent = mParentNode;
            mNonAddedNode = mCurrentNode;
        }
        else {
            if (document && currentElement && !mRootContent) {
                mRootContent = do_QueryInterface(mCurrentNode);
                // XXXbz what to do on failure here?
                document->SetRootContent(mRootContent);
            }
            else {
                nsCOMPtr<nsIDOMNode> resultNode;

                rv = mParentNode->AppendChild(mCurrentNode, getter_AddRefs(resultNode));
                if (NS_FAILED(rv)) {
                    mBadChildLevel = 1;
                    mCurrentNode = mParentNode;
                    PR_LOG(txLog::xslt, PR_LOG_DEBUG,
                           ("closePrevious, mBadChildLevel = %d\n",
                            mBadChildLevel));
                    // warning to the console
                    nsCOMPtr<nsIConsoleService> consoleSvc = 
                        do_GetService("@mozilla.org/consoleservice;1", &rv);
                    if (consoleSvc) {
                        consoleSvc->LogStringMessage(
                            NS_LITERAL_STRING("failed to create XSLT content").get());
                    }
                }
            }
        }
        mParentNode = nsnull;
    }
    else if ((aAction & eFlushText) && !mText.IsEmpty()) {
        nsCOMPtr<nsIDOMText> text;
        rv = mDocument->CreateTextNode(mText, getter_AddRefs(text));
        NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create text node");

        nsCOMPtr<nsIDOMNode> resultNode;
        rv = mCurrentNode->AppendChild(text, getter_AddRefs(resultNode));
        NS_ASSERTION(NS_SUCCEEDED(rv), "Can't append text node");

        mText.Truncate();
    }
}

Here is the call graph for this function:

virtual void txAXMLEventHandler::comment ( const nsAString &  aData) [pure virtual, inherited]

Signals to receive data that should be treated as a comment.

Parameters:
datathe comment data to receive

Here is the caller graph for this function:

nsresult txMozillaXMLOutput::createHTMLElement ( const nsAString &  aName,
nsIDOMElement **  aResult 
) [private]

Definition at line 827 of file txMozillaXMLOutput.cpp.

{
    if (mDocumentIsHTML) {
        return mDocument->CreateElement(aName, aResult);
    }

    return mDocument->CreateElementNS(NS_LITERAL_STRING(kXHTMLNameSpaceURI),
                                      aName, aResult);
}

Here is the caller graph for this function:

nsresult txMozillaXMLOutput::createResultDocument ( const nsAString &  aName,
PRInt32  aNsID,
nsIDOMDocument aSourceDocument,
nsIDOMDocument aResultDocument 
) [private]

Definition at line 704 of file txMozillaXMLOutput.cpp.

{
    nsresult rv;

    nsCOMPtr<nsIDocument> doc;
    if (!aResultDocument) {
        // Create the document
        if (mOutputFormat.mMethod == eHTMLOutput) {
            doc = do_CreateInstance(kHTMLDocumentCID, &rv);
            NS_ENSURE_SUCCESS(rv, rv);

            mDocumentIsHTML = PR_TRUE;
        }
        else {
            // We should check the root name/namespace here and create the
            // appropriate document
            doc = do_CreateInstance(kXMLDocumentCID, &rv);
            NS_ENSURE_SUCCESS(rv, rv);

            mDocumentIsHTML = PR_FALSE;
        }
        nsCOMPtr<nsIDocument_MOZILLA_1_8_BRANCH3> source =
          do_QueryInterface(aSourceDocument);
        NS_ENSURE_STATE(source);
        PRBool hasHadScriptObject = PR_FALSE;
        nsIScriptGlobalObject* sgo =
          source->GetScriptHandlingObject(hasHadScriptObject);
        NS_ENSURE_STATE(sgo || !hasHadScriptObject);
        nsCOMPtr<nsIDocument_MOZILLA_1_8_BRANCH3> doc18 =
          do_QueryInterface(doc);
        NS_ENSURE_STATE(doc18);
        doc18->SetScriptHandlingObject(sgo);
        mDocument = do_QueryInterface(doc);
    }
    else {
        mDocument = aResultDocument;
        doc = do_QueryInterface(aResultDocument);
        
        nsCOMPtr<nsIDocument> doc = do_QueryInterface(aResultDocument);
        mDocumentIsHTML = doc && !doc->IsCaseSensitive();
    }

    mCurrentNode = mDocument;

    // Reset and set up the document
    URIUtils::ResetWithSource(doc, aSourceDocument);

    // Set the charset
    if (!mOutputFormat.mEncoding.IsEmpty()) {
        NS_LossyConvertUTF16toASCII charset(mOutputFormat.mEncoding);
        nsCAutoString canonicalCharset;
        nsCOMPtr<nsICharsetAlias> calias =
            do_GetService("@mozilla.org/intl/charsetalias;1");

        if (calias &&
            NS_SUCCEEDED(calias->GetPreferred(charset, canonicalCharset))) {
            doc->SetDocumentCharacterSet(canonicalCharset);
            doc->SetDocumentCharacterSetSource(kCharsetFromOtherComponent);
        }
    }

    // Set the mime-type
    if (!mOutputFormat.mMediaType.IsEmpty()) {
        doc->SetContentType(mOutputFormat.mMediaType);
    }
    else if (mOutputFormat.mMethod == eHTMLOutput) {
        doc->SetContentType(NS_LITERAL_STRING("text/html"));
    }
    else {
        doc->SetContentType(NS_LITERAL_STRING("application/xml"));
    }

    // Set up script loader of the result document.
    nsIScriptLoader *loader = doc->GetScriptLoader();
    if (loader) {
        if (mNotifier) {
            loader->AddObserver(mNotifier);
        }
        else {
            // Don't load scripts, we can't notify the caller when they're loaded.
            loader->SetEnabled(PR_FALSE);
        }
    }

    if (mNotifier) {
        mNotifier->SetOutputDocument(mDocument);
    }

    // Do this after calling OnDocumentCreated to ensure that the
    // PresShell/PresContext has been hooked up and get notified.
    nsCOMPtr<nsIHTMLDocument> htmlDoc = do_QueryInterface(doc);
    if (htmlDoc) {
        htmlDoc->SetCompatibilityMode(eCompatibility_FullStandards);
    }

    // Add a doc-type if requested
    if (!mOutputFormat.mSystemId.IsEmpty()) {
        nsCOMPtr<nsIDOMDOMImplementation> implementation;
        rv = aSourceDocument->GetImplementation(getter_AddRefs(implementation));
        NS_ENSURE_SUCCESS(rv, rv);
        nsAutoString qName;
        if (mOutputFormat.mMethod == eHTMLOutput) {
            qName.AssignLiteral("html");
        }
        else {
            qName.Assign(aName);
        }
        nsCOMPtr<nsIDOMDocumentType> documentType;
        rv = implementation->CreateDocumentType(qName,
                                                mOutputFormat.mPublicId,
                                                mOutputFormat.mSystemId,
                                                getter_AddRefs(documentType));
        NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create doctype");
        nsCOMPtr<nsIDOMNode> tmp;
        mDocument->AppendChild(documentType, getter_AddRefs(tmp));
    }

    return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual void txAXMLEventHandler::endDocument ( nsresult  aResult) [pure virtual, inherited]

Signals the end of a document.

It is an error to call this method more than once.

Implemented in txRtfHandler, and txUnknownHandler.

Here is the caller graph for this function:

virtual void txAXMLEventHandler::endElement ( const nsAString &  aName,
const PRInt32  aNsID 
) [pure virtual, inherited]

Signals to receive the end of an element.

Parameters:
aNamethe name of the element
aNsIDthe namespace ID of the element

Implemented in txHTMLOutput.

Here is the caller graph for this function:

Definition at line 616 of file txMozillaXMLOutput.cpp.

{
    nsresult rv;
    nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
    NS_ASSERTION(content, "Can't QI to nsIContent");

    nsIAtom *atom = content->Tag();

    if (mTableState == ADDED_TBODY) {
        NS_ASSERTION(atom == txHTMLAtoms::tbody,
                     "Element flagged as added tbody isn't a tbody");
        nsCOMPtr<nsIDOMNode> parent;
        mCurrentNode->GetParentNode(getter_AddRefs(parent));
        mCurrentNode = parent;
        mTableState = NS_STATIC_CAST(TableState,
                                     NS_PTR_TO_INT32(mTableStateStack.pop()));

        return;
    }

    // Load scripts
    if (mNotifier && atom == txHTMLAtoms::script) {
        // Add this script element to the array of loading script elements.
        nsCOMPtr<nsIScriptElement> scriptElement =
            do_QueryInterface(mCurrentNode);
        NS_ASSERTION(scriptElement, "Need script element");
        mNotifier->AddScriptElement(scriptElement);
    }
    // Set document title
    else if (mCreatingNewDocument &&
             atom == txHTMLAtoms::title && !mHaveTitleElement) {
        // The first title wins
        mHaveTitleElement = PR_TRUE;
        nsCOMPtr<nsIDOMNSDocument> domDoc = do_QueryInterface(mDocument);
        nsCOMPtr<nsIDOMNode> textNode;
        aElement->GetFirstChild(getter_AddRefs(textNode));
        if (domDoc && textNode) {
            nsAutoString text;
            textNode->GetNodeValue(text);
            text.CompressWhitespace();
            domDoc->SetTitle(text);
        }
    }
    else if (mCreatingNewDocument && atom == txHTMLAtoms::base &&
             !mHaveBaseElement) {
        // The first base wins
        mHaveBaseElement = PR_TRUE;

        nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
        NS_ASSERTION(doc, "document doesn't implement nsIDocument");
        nsAutoString value;
        content->GetAttr(kNameSpaceID_None, txHTMLAtoms::target, value);
        doc->SetBaseTarget(value);

        content->GetAttr(kNameSpaceID_None, txHTMLAtoms::href, value);
        nsCOMPtr<nsIURI> baseURI;
        rv = NS_NewURI(getter_AddRefs(baseURI), value, nsnull);
        if (NS_FAILED(rv))
            return;
        doc->SetBaseURI(baseURI); // The document checks if it is legal to set this base
    }
    else if (mCreatingNewDocument && atom == txHTMLAtoms::meta) {
        // handle HTTP-EQUIV data
        nsAutoString httpEquiv;
        content->GetAttr(kNameSpaceID_None, txHTMLAtoms::httpEquiv, httpEquiv);
        if (httpEquiv.IsEmpty())
            return;

        nsAutoString value;
        content->GetAttr(kNameSpaceID_None, txHTMLAtoms::content, value);
        if (value.IsEmpty())
            return;
        
        TX_ToLowerCase(httpEquiv);
        nsCOMPtr<nsIAtom> header = do_GetAtom(httpEquiv);
        processHTTPEquiv(header, value);
    }
}

Here is the call graph for this function:

virtual void txAOutputXMLEventHandler::getOutputDocument ( nsIDOMDocument **  aDocument) [pure virtual, inherited]

Gets the Mozilla output document.

Parameters:
aDocumentthe Mozilla output document

Here is the caller graph for this function:

void txMozillaXMLOutput::processHTTPEquiv ( nsIAtom aHeader,
const nsAString &  aValue 
) [private]

Definition at line 695 of file txMozillaXMLOutput.cpp.

{
    // For now we only handle "refresh". There's a longer list in
    // HTMLContentSink::ProcessHeaderData
    if (aHeader == txHTMLAtoms::refresh)
        CopyUCS2toASCII(aValue, mRefreshString);
}

Here is the call graph for this function:

Here is the caller graph for this function:

virtual void txAXMLEventHandler::processingInstruction ( const nsAString &  aTarget,
const nsAString &  aData 
) [pure virtual, inherited]

Signals to receive a processing instruction.

Parameters:
aTargetthe target of the processing instruction
aDatathe data of the processing instruction

Implemented in txHTMLOutput.

Here is the caller graph for this function:

virtual void txAXMLEventHandler::startDocument ( ) [pure virtual, inherited]

Signals the start of a document.

Implemented in txRtfHandler, and txHTMLOutput.

Here is the caller graph for this function:

virtual void txAXMLEventHandler::startElement ( const nsAString &  aName,
const PRInt32  aNsID 
) [pure virtual, inherited]

Signals to receive the start of an element.

Parameters:
aNamethe name of the element
aNsIDthe namespace ID of the element

Implemented in txHTMLOutput, and txUnknownHandler.

Here is the caller graph for this function:

void txMozillaXMLOutput::startHTMLElement ( nsIDOMElement aElement,
PRBool  aXHTML 
) [private]

Definition at line 552 of file txMozillaXMLOutput.cpp.

{
    nsresult rv = NS_OK;
    nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
    nsIAtom *atom = content->Tag();

    mDontAddCurrent = (atom == txHTMLAtoms::script);

    if ((atom != txHTMLAtoms::tr || aXHTML) &&
        NS_PTR_TO_INT32(mTableStateStack.peek()) == ADDED_TBODY) {
        nsCOMPtr<nsIDOMNode> parent;
        mCurrentNode->GetParentNode(getter_AddRefs(parent));
        mCurrentNode.swap(parent);
        mTableStateStack.pop();
    }

    if (atom == txHTMLAtoms::table && !aXHTML) {
        mTableState = TABLE;
    }
    else if (atom == txHTMLAtoms::tr && !aXHTML &&
             NS_PTR_TO_INT32(mTableStateStack.peek()) == TABLE) {
        nsCOMPtr<nsIDOMElement> elem;
        rv = createHTMLElement(NS_LITERAL_STRING("tbody"),
                               getter_AddRefs(elem));
        if (NS_FAILED(rv)) {
            return;
        }
        nsCOMPtr<nsIDOMNode> dummy;
        rv = mCurrentNode->AppendChild(elem, getter_AddRefs(dummy));
        if (NS_FAILED(rv)) {
            return;
        }
        rv = mTableStateStack.push(NS_INT32_TO_PTR(ADDED_TBODY));
        if (NS_FAILED(rv)) {
            return;
        }
        mCurrentNode = elem;
    }
    else if (atom == txHTMLAtoms::head &&
             mOutputFormat.mMethod == eHTMLOutput) {
        // Insert META tag, according to spec, 16.2, like
        // <META http-equiv="Content-Type" content="text/html; charset=EUC-JP">
        nsCOMPtr<nsIDOMElement> meta;
        rv = createHTMLElement(NS_LITERAL_STRING("meta"),
                               getter_AddRefs(meta));
        if (NS_FAILED(rv)) {
            return;
        }
        rv = meta->SetAttribute(NS_LITERAL_STRING("http-equiv"),
                                NS_LITERAL_STRING("Content-Type"));
        NS_ASSERTION(NS_SUCCEEDED(rv), "Can't set http-equiv on meta");
        nsAutoString metacontent;
        metacontent.Append(mOutputFormat.mMediaType);
        metacontent.AppendLiteral("; charset=");
        metacontent.Append(mOutputFormat.mEncoding);
        rv = meta->SetAttribute(NS_LITERAL_STRING("content"),
                                metacontent);
        NS_ASSERTION(NS_SUCCEEDED(rv), "Can't set content on meta");
        nsCOMPtr<nsIDOMNode> dummy;
        rv = aElement->AppendChild(meta, getter_AddRefs(dummy));
        NS_ASSERTION(NS_SUCCEEDED(rv), "Can't append meta");
    }
}

Here is the call graph for this function:


Member Data Documentation

Definition at line 126 of file txMozillaXMLOutput.h.

Definition at line 147 of file txMozillaXMLOutput.h.

Definition at line 117 of file txMozillaXMLOutput.h.

Definition at line 116 of file txMozillaXMLOutput.h.

Definition at line 146 of file txMozillaXMLOutput.h.

Definition at line 141 of file txMozillaXMLOutput.h.

Definition at line 144 of file txMozillaXMLOutput.h.

Definition at line 143 of file txMozillaXMLOutput.h.

Definition at line 122 of file txMozillaXMLOutput.h.

Definition at line 121 of file txMozillaXMLOutput.h.

Definition at line 124 of file txMozillaXMLOutput.h.

Definition at line 139 of file txMozillaXMLOutput.h.

Definition at line 118 of file txMozillaXMLOutput.h.

Definition at line 127 of file txMozillaXMLOutput.h.

Definition at line 119 of file txMozillaXMLOutput.h.

Definition at line 135 of file txMozillaXMLOutput.h.

Definition at line 129 of file txMozillaXMLOutput.h.

Definition at line 137 of file txMozillaXMLOutput.h.

Definition at line 126 of file txMozillaXMLOutput.h.


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