Change the way output-handlers are created and set up.

git-svn-id: svn://10.0.0.236/branches/XSLTPROCESSOR_REFACTOR_20020630_BRANCH@129786 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
sicking%bigfoot.com
2002-09-17 12:30:33 +00:00
parent 0d5b81928d
commit 1d1426b995
22 changed files with 752 additions and 675 deletions

View File

@@ -46,6 +46,7 @@ REQUIRES = xpcom \
htmlparser \
webshell \
docshell \
layout \
$(NULL)
IS_COMPONENT = 1
MODULE_NAME = TransformiixModule
@@ -121,6 +122,7 @@ LOBJS =../source/base/ArrayList.$(OBJ_SUFFIX) \
../source/xslt/txMozillaXMLOutput.$(OBJ_SUFFIX) \
../source/xslt/txRtfHandler.$(OBJ_SUFFIX) \
../source/xslt/txTextHandler.$(OBJ_SUFFIX) \
../source/xslt/txUnknownHandler.$(OBJ_SUFFIX) \
../source/xslt/txXSLTNumber.$(OBJ_SUFFIX) \
../source/xslt/txXSLTNumberCounters.$(OBJ_SUFFIX) \
../source/xslt/txXSLTPatterns.$(OBJ_SUFFIX) \

View File

@@ -55,7 +55,6 @@ NS_DOMCI_EXTENSION(Transformiix)
static NS_DEFINE_CID(kXSLTProcessorCID, TRANSFORMIIX_XSLT_PROCESSOR_CID);
NS_DOMCI_EXTENSION_ENTRY_BEGIN(XSLTProcessor)
NS_DOMCI_EXTENSION_ENTRY_INTERFACE(nsIXSLTProcessor)
NS_DOMCI_EXTENSION_ENTRY_INTERFACE(nsIDocumentTransformer) // XXX DEPRECATED
NS_DOMCI_EXTENSION_ENTRY_END(XSLTProcessor, nsIXSLTProcessor, PR_TRUE,
&kXSLTProcessorCID)

View File

@@ -42,6 +42,7 @@ REQUIRES = string \
htmlparser \
webshell \
docshell \
layout \
$(NULL)
endif
@@ -54,13 +55,13 @@ CPPSRCS = Names.cpp \
txXSLTNumberCounters.cpp \
txXSLTPatterns.cpp \
txPatternParser.cpp \
txUnknownHandler.cpp \
XSLTProcessor.cpp
ifdef TX_EXE
CPPSRCS += txHTMLOutput.cpp \
txStandaloneXSLTProcessor.cpp \
txTextOutput.cpp \
txUnknownHandler.cpp \
txXMLOutput.cpp
else
CPPSRCS += txMozillaTextOutput.cpp \

View File

@@ -48,16 +48,6 @@
#include "txVariableMap.h"
#include "XSLTProcessor.h"
#ifdef TX_EXE
#include "txUnknownHandler.h"
#include "txTextOutput.h"
#include "txHTMLOutput.h"
#else
#include "nsITransformObserver.h"
#include "txMozillaTextOutput.h"
#include "txMozillaXMLOutput.h"
#endif
/**
* Creates a new ProcessorState for the given XSL document
**/
@@ -71,12 +61,9 @@ ProcessorState::ProcessorState(Document* aSourceDocument,
mSourceDocument(aSourceDocument),
xslDocument(aXslDocument),
mRTFDocument(0),
#ifdef TX_EXE
mStandaloneOutputHandler(0),
mOut(0),
#endif
mOutputHandler(0),
mResultHandler(0)
mResultHandler(0),
mOutputHandlerFactory(0)
{
NS_ASSERTION(aSourceDocument, "missing source document");
NS_ASSERTION(aXslDocument, "missing xslt document");
@@ -117,6 +104,10 @@ ProcessorState::~ProcessorState()
if (mSourceDocument)
loadedDocuments.remove(mSourceDocument->getBaseURI());
// in module the outputhandler is refcounted
#ifdef TX_EXE
delete mOutputHandler;
#endif
} //-- ~ProcessorState
@@ -1142,106 +1133,6 @@ nsresult ProcessorState::resolveFunctionCall(txAtom* aName, PRInt32 aID,
return NS_ERROR_XPATH_PARSE_FAILED;
} //-- resolveFunctionCall
txOutputXMLEventHandler*
ProcessorState::getOutputHandler(txOutputMethod aMethod)
{
#ifdef TX_EXE
if (mStandaloneOutputHandler) {
if (aMethod == eHTMLOutput || aMethod == eXMLOutput) {
txUnknownHandler* oldHandler =
(txUnknownHandler*)mStandaloneOutputHandler;
if (aMethod == eHTMLOutput) {
mStandaloneOutputHandler = new txHTMLOutput();
}
else {
mStandaloneOutputHandler = new txXMLOutput();
}
NS_ASSERTION(mStandaloneOutputHandler,
"Setting mStandaloneOutputHandler to NULL!");
mStandaloneOutputHandler->setOutputStream(mOut);
txOutputFormat* format = getOutputFormat();
format->mMethod = aMethod;
mStandaloneOutputHandler->setOutputFormat(format);
oldHandler->flush(mStandaloneOutputHandler);
delete oldHandler;
return mStandaloneOutputHandler;
}
delete mStandaloneOutputHandler;
mStandaloneOutputHandler = 0;
}
switch (aMethod) {
case eXMLOutput:
{
mStandaloneOutputHandler = new txXMLOutput();
break;
}
case eHTMLOutput:
{
mStandaloneOutputHandler = new txHTMLOutput();
break;
}
case eTextOutput:
{
mStandaloneOutputHandler = new txTextOutput();
break;
}
case eMethodNotSet:
{
mStandaloneOutputHandler = new txUnknownHandler(this);
break;
}
}
if (mOut) {
mStandaloneOutputHandler->setOutputStream(mOut);
}
return mStandaloneOutputHandler;
#else
if (mMozillaOutputHandler) {
if (aMethod == eHTMLOutput || aMethod == eXMLOutput) {
return mMozillaOutputHandler;
}
mMozillaOutputHandler = nsnull;
}
switch (aMethod) {
case eMethodNotSet:
case eXMLOutput:
case eHTMLOutput:
{
mMozillaOutputHandler = new txMozillaXMLOutput();
break;
}
case eTextOutput:
{
mMozillaOutputHandler = new txMozillaTextOutput();
break;
}
}
if (mMozillaOutputHandler) {
nsCOMPtr<nsIDOMDocument> source =
do_QueryInterface(mSourceDocument->getNSObj());
mMozillaOutputHandler->setSourceDocument(source);
nsCOMPtr<nsITransformObserver> observer =
do_QueryReferent(mObserver);
mMozillaOutputHandler->setObserver(observer);
}
return mMozillaOutputHandler;
#endif
}
#ifdef TX_EXE
void
ProcessorState::setOutputStream(ostream* aOut)
{
mOut = aOut;
}
#else
void
ProcessorState::setTransformObserver(nsITransformObserver* aObserver)
{
mObserver = do_GetWeakReference(aObserver);
}
#endif
//-------------------/
//- Private Methods -/
//-------------------/

View File

@@ -43,10 +43,6 @@
#include "XSLTFunctions.h"
#include "txError.h"
#ifndef TX_EXE
#include "nsWeakPtr.h"
#endif
class txVariableMap;
class txXSLKey;
@@ -150,11 +146,6 @@ public:
*/
txOutputFormat* getOutputFormat();
/**
* Returns the OutputHandler to use
*/
txOutputXMLEventHandler* getOutputHandler(txOutputMethod aMethod);
/**
* Add a global variable
*/
@@ -359,25 +350,14 @@ public:
nsresult resolveFunctionCall(txAtom* aName, PRInt32 aID,
Element* aElem, FunctionCall*& aFunction);
MBool haveDocumentElement()
{
return mHaveDocumentElement;
}
void setHaveDocumentElement(MBool aHaveDocumentElement)
{
mHaveDocumentElement = aHaveDocumentElement;
}
#ifdef TX_EXE
void setOutputStream(ostream* aOut);
txIOutputXMLEventHandler* mOutputHandler;
#else
void setTransformObserver(nsITransformObserver* aObserver);
nsCOMPtr<txIOutputXMLEventHandler> mOutputHandler;
#endif
txOutputXMLEventHandler* mOutputHandler;
txXMLEventHandler* mResultHandler;
txIOutputHandlerFactory* mOutputHandlerFactory;
private:
@@ -491,16 +471,6 @@ private:
* Document used to create RTFs
*/
Document* mRTFDocument;
MBool mHaveDocumentElement;
#ifdef TX_EXE
txStreamXMLEventHandler* mStandaloneOutputHandler;
ostream* mOut;
#else
nsCOMPtr<txIMozillaXMLEventHandler> mMozillaOutputHandler;
nsWeakPtr mObserver;
#endif
};
/**

View File

@@ -158,7 +158,8 @@ txXSLTProcessor::copyNode(Node* aSourceNode, ProcessorState* aPs)
Element* element = (Element*)aSourceNode;
const String& name = element->getNodeName();
PRInt32 nsID = element->getNamespaceID();
startElement(name, nsID, aPs);
NS_ASSERTION(aPs->mResultHandler, "mResultHandler must not be NULL!");
aPs->mResultHandler->startElement(name, nsID);
// Copy attributes
NamedNodeMap* attList = element->getAttributes();
@@ -268,7 +269,8 @@ txXSLTProcessor::processAction(Node* aAction,
// Literal result element
// XXX TODO Check for excluded namespaces and aliased namespaces (element and attributes)
const String& nodeName = aAction->getNodeName();
startElement(nodeName, nsID, aPs);
NS_ASSERTION(aPs->mResultHandler, "mResultHandler must not be NULL!");
aPs->mResultHandler->startElement(nodeName, nsID);
processAttributeSets(actionElement, aPs);
@@ -344,6 +346,7 @@ txXSLTProcessor::processAction(Node* aAction,
NodeSet* nodeSet = (NodeSet*)exprResult;
if (nodeSet->isEmpty()) {
delete nodeSet;
TX_RELEASE_ATOM(localName);
return;
}
@@ -631,7 +634,8 @@ txXSLTProcessor::processAction(Node* aAction,
return;
}
startElement(name, resultNsID, aPs);
NS_ASSERTION(aPs->mResultHandler, "mResultHandler must not be NULL!");
aPs->mResultHandler->startElement(name, resultNsID);
processAttributeSets(actionElement, aPs);
processChildren(actionElement, aPs);
NS_ASSERTION(aPs->mResultHandler, "mResultHandler must not be NULL!");
@@ -655,6 +659,7 @@ txXSLTProcessor::processAction(Node* aAction,
NodeSet* nodeSet = (NodeSet*)exprResult;
if (nodeSet->isEmpty()) {
delete nodeSet;
TX_RELEASE_ATOM(localName);
return;
}
txNodeSetContext evalContext(nodeSet, aPs);
@@ -1618,40 +1623,10 @@ txXSLTProcessor::processVariable(Element* aVariable,
return new StringResult();
}
void
txXSLTProcessor::startElement(const String& aName,
const PRInt32 aNsID,
ProcessorState* aPs)
{
if (!aPs->haveDocumentElement() && (aPs->mResultHandler == aPs->mOutputHandler)) {
txOutputFormat* format = aPs->getOutputFormat();
if (format->mMethod == eMethodNotSet) {
// XXX Should check for whitespace-only sibling text nodes
if ((aNsID == kNameSpaceID_None) &&
aName.isEqualIgnoreCase(String("html"))) {
// Switch to html output mode according to the XSLT spec.
format->mMethod = eHTMLOutput;
}
else {
format->mMethod = eXMLOutput;
}
aPs->mOutputHandler = aPs->getOutputHandler(format->mMethod);
if (!aPs->mOutputHandler) {
// XXX Error
return;
}
aPs->mOutputHandler->setOutputFormat(format);
aPs->mResultHandler = aPs->mOutputHandler;
}
aPs->setHaveDocumentElement(MB_TRUE);
}
NS_ASSERTION(aPs->mResultHandler, "mResultHandler must not be NULL!");
aPs->mResultHandler->startElement(aName, aNsID);
}
void
txXSLTProcessor::transform(ProcessorState* aPs)
{
nsresult rv = NS_OK;
txListIterator frameIter(aPs->getImportFrames());
ProcessorState::ImportFrame* frame;
txOutputFormat* outputFormat = aPs->getOutputFormat();
@@ -1659,13 +1634,14 @@ txXSLTProcessor::transform(ProcessorState* aPs)
outputFormat->merge(frame->mOutputFormat);
}
aPs->mOutputHandler = aPs->getOutputHandler(outputFormat->mMethod);
if (!aPs->mOutputHandler) {
txIOutputXMLEventHandler* handler = 0;
rv = aPs->mOutputHandlerFactory->createHandlerWith(aPs->getOutputFormat(),
handler);
if (NS_FAILED(rv)) {
return;
}
aPs->mResultHandler = aPs->mOutputHandler;
aPs->mOutputHandler->setOutputFormat(outputFormat);
aPs->setHaveDocumentElement(MB_FALSE);
aPs->mOutputHandler = handler;
aPs->mResultHandler = handler;
aPs->mOutputHandler->startDocument();
frame = 0;
@@ -1695,7 +1671,8 @@ txXSLTProcessor::xslCopy(Element* aAction, ProcessorState* aPs)
String nodeName = element->getNodeName();
PRInt32 nsID = element->getNamespaceID();
startElement(nodeName, nsID, aPs);
NS_ASSERTION(aPs->mResultHandler, "mResultHandler must not be NULL!");
aPs->mResultHandler->startElement(nodeName, nsID);
// XXX copy namespace attributes once we have them
processAttributeSets(aAction, aPs);
processChildren(aAction, aPs);

View File

@@ -41,7 +41,8 @@
#include "txOutputFormat.h"
#include "XMLUtils.h"
txHTMLOutput::txHTMLOutput()
txHTMLOutput::txHTMLOutput(txOutputFormat* aFormat, ostream* aOut)
: txXMLOutput(aFormat, aOut)
{
mUseEmptyElementShorthand = MB_FALSE;

View File

@@ -46,7 +46,7 @@
class txHTMLOutput : public txXMLOutput
{
public:
txHTMLOutput();
txHTMLOutput(txOutputFormat* aFormat, ostream* aOut);
~txHTMLOutput();
/*

View File

@@ -45,10 +45,21 @@
#include "nsIDOMText.h"
#include "nsITransformObserver.h"
#include "TxString.h"
#include "nsNetUtil.h"
static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
txMozillaTextOutput::txMozillaTextOutput()
txMozillaTextOutput::txMozillaTextOutput(nsIDOMDocument* aSourceDocument,
nsITransformObserver* aObserver)
: mSourceDocument(aSourceDocument)
{
NS_INIT_ISUPPORTS();
mObserver = do_GetWeakReference(aObserver);
}
txMozillaTextOutput::txMozillaTextOutput(nsIDOMDocumentFragment* aDest)
: mFragment(aDest)
{
NS_INIT_ISUPPORTS();
}
@@ -57,7 +68,7 @@ txMozillaTextOutput::~txMozillaTextOutput()
{
}
NS_IMPL_ISUPPORTS1(txMozillaTextOutput, txIMozillaXMLEventHandler);
NS_IMPL_ISUPPORTS1(txMozillaTextOutput, txIOutputXMLEventHandler);
void txMozillaTextOutput::attribute(const String& aName,
const PRInt32 aNsID,
@@ -93,15 +104,31 @@ void txMozillaTextOutput::processingInstruction(const String& aTarget,
{
}
void txMozillaTextOutput::setOutputFormat(txOutputFormat* aOutputFormat)
{
mOutputFormat.reset();
mOutputFormat.merge(*aOutputFormat);
mOutputFormat.setFromDefaults();
}
void txMozillaTextOutput::startDocument()
{
nsresult rv = NS_OK;
// If we are transforming into a fragment then just create a textnode
if (mFragment) {
nsCOMPtr<nsIDOMDocument> doc;
mFragment->GetOwnerDocument(getter_AddRefs(doc));
NS_ASSERTION(doc, "unable to get ownerdocument");
nsCOMPtr<nsIDOMText> textNode;
rv = doc->CreateTextNode(NS_LITERAL_STRING(""),
getter_AddRefs(textNode));
if (NS_FAILED(rv)) {
return;
}
nsCOMPtr<nsIDOMNode> dummy;
rv = mFragment->AppendChild(textNode, getter_AddRefs(dummy));
if (NS_FAILED(rv)) {
return;
}
mTextNode = textNode;
return;
}
/*
* Create an XHTML document to hold the text.
*
@@ -114,7 +141,6 @@ void txMozillaTextOutput::startDocument()
*/
// Create document
nsresult rv;
nsCOMPtr<nsIDocument> doc;
doc = do_CreateInstance(kXMLDocumentCID, &rv);
NS_ASSERTION(NS_SUCCEEDED(rv), "Couldn't create document");
@@ -124,15 +150,31 @@ void txMozillaTextOutput::startDocument()
mDocument = do_QueryInterface(doc);
NS_ASSERTION(mDocument, "Need document");
// // Notify the contentsink that the document is created
// nsCOMPtr<nsIObserverService> observerService =
// do_GetService("@mozilla.org/observer-service;1", &rv);
// if (NS_SUCCEEDED(rv)) {
// observerService->AddObserver(mObserver, "xslt-document-created",
// PR_TRUE);
// observerService->NotifyObservers(mDocument, "xslt-document-created",
// nsnull);
// }
// Reset and set up document
nsCOMPtr<nsILoadGroup> loadGroup;
nsCOMPtr<nsIChannel> channel;
nsCOMPtr<nsIDocument> sourceDoc = do_QueryInterface(mSourceDocument);
sourceDoc->GetDocumentLoadGroup(getter_AddRefs(loadGroup));
nsCOMPtr<nsIIOService> serv = do_GetService(NS_IOSERVICE_CONTRACTID);
if (serv) {
// Create a temporary channel to get nsIDocument->Reset to
// do the right thing. We want the output document to get
// much of the input document's characteristics.
nsCOMPtr<nsIURI> docURL;
sourceDoc->GetDocumentURL(getter_AddRefs(docURL));
serv->NewChannelFromURI(docURL, getter_AddRefs(channel));
}
doc->Reset(channel, loadGroup);
nsCOMPtr<nsIURI> baseURL;
sourceDoc->GetBaseURL(*getter_AddRefs(baseURL));
doc->SetBaseURL(baseURL);
// XXX We might want to call SetDefaultStylesheets here
// Notify the contentsink that the document is created
nsCOMPtr<nsITransformObserver> observer = do_QueryReferent(mObserver);
if (observer) {
observer->OnDocumentCreated(mDocument);
}
// Create the content
nsCOMPtr<nsIDOMElement> element, docElement;
@@ -180,7 +222,7 @@ void txMozillaTextOutput::startDocument()
NS_LITERAL_STRING("body"),
getter_AddRefs(element));
NS_ASSERTION(element, "Failed to create body element");
if (!mRootContent) {
if (!element) {
return;
}
@@ -229,17 +271,8 @@ void txMozillaTextOutput::startElement(const String& aName,
{
}
void txMozillaTextOutput::setSourceDocument(nsIDOMDocument* aDocument)
{
}
void txMozillaTextOutput::getOutputDocument(nsIDOMDocument** aDocument)
{
*aDocument = mDocument;
NS_IF_ADDREF(*aDocument);
}
void txMozillaTextOutput::setObserver(nsITransformObserver* aObserver)
{
mObserver = do_GetWeakReference(aObserver);
}

View File

@@ -46,13 +46,15 @@
#include "nsWeakPtr.h"
#include "txOutputFormat.h"
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentFragment.h"
class nsITransformObserver;
class txMozillaTextOutput : public txIMozillaXMLEventHandler
class txMozillaTextOutput : public txIOutputXMLEventHandler
{
public:
txMozillaTextOutput();
txMozillaTextOutput(nsIDOMDocument* aSourceDocument, nsITransformObserver* aObserver);
txMozillaTextOutput(nsIDOMDocumentFragment* aDest);
virtual ~txMozillaTextOutput();
NS_DECL_ISUPPORTS
@@ -141,20 +143,6 @@ public:
void startElement(const String& aName,
const PRInt32 aNsID);
/**
* Sets the output format.
*
* @param aOutputFormat the output format
*/
void setOutputFormat(txOutputFormat* aOutputFormat);
/**
* Sets the Mozilla source document
*
* @param aDocument the Mozilla source document
*/
void setSourceDocument(nsIDOMDocument* aDocument);
/**
* Gets the Mozilla output document
*
@@ -162,19 +150,13 @@ public:
*/
void getOutputDocument(nsIDOMDocument** aDocument);
/**
* Sets the content-sink observer
*
* @param aObserver the content-sink observer
*/
void setObserver(nsITransformObserver* aObserver);
private:
nsCOMPtr<nsIDOMCharacterData> mTextNode;
nsCOMPtr<nsIContent> mRootContent;
nsWeakPtr mObserver;
nsCOMPtr<nsIDOMDocument> mDocument;
txOutputFormat mOutputFormat;
nsCOMPtr<nsIDOMDocumentFragment> mFragment;
nsCOMPtr<nsIDOMDocument> mSourceDocument;
};
#endif

View File

@@ -59,6 +59,7 @@
#include "nsNetUtil.h"
#include "nsUnicharUtils.h"
#include "txAtoms.h"
#include "nsIDOMDocumentFragment.h"
static NS_DEFINE_CID(kXMLDocumentCID, NS_XMLDOCUMENT_CID);
static NS_DEFINE_CID(kHTMLDocumentCID, NS_HTMLDOCUMENT_CID);
@@ -72,13 +73,47 @@ static NS_DEFINE_CID(kHTMLDocumentCID, NS_HTMLDOCUMENT_CID);
if (!mCurrentNode) \
return
txMozillaXMLOutput::txMozillaXMLOutput() : mStyleSheetCount(0),
mDontAddCurrent(PR_FALSE),
mHaveTitleElement(PR_FALSE),
mHaveBaseElement(PR_FALSE),
mInTransform(PR_FALSE)
txMozillaXMLOutput::txMozillaXMLOutput(const String& aRootName,
PRInt32 aRootNsID,
txOutputFormat* aFormat,
nsIDOMDocument* aSourceDocument,
nsITransformObserver* aObserver)
: mStyleSheetCount(0),
mDontAddCurrent(PR_FALSE),
mHaveTitleElement(PR_FALSE),
mHaveBaseElement(PR_FALSE),
mInTransform(PR_FALSE),
mCreatingNewDocument(PR_TRUE)
{
NS_INIT_ISUPPORTS();
mOutputFormat.merge(*aFormat);
mOutputFormat.setFromDefaults();
mObserver = do_GetWeakReference(aObserver);
createResultDocument(aRootName, aRootNsID, aSourceDocument);
}
txMozillaXMLOutput::txMozillaXMLOutput(txOutputFormat* aFormat,
nsIDOMDocumentFragment* aFragment)
: mStyleSheetCount(0),
mDontAddCurrent(PR_FALSE),
mHaveTitleElement(PR_FALSE),
mHaveBaseElement(PR_FALSE),
mInTransform(PR_FALSE),
mCreatingNewDocument(PR_FALSE)
{
NS_INIT_ISUPPORTS();
mOutputFormat.merge(*aFormat);
mOutputFormat.setFromDefaults();
aFragment->GetOwnerDocument(getter_AddRefs(mDocument));
nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
NS_ASSERTION(doc, "can't QI to nsIDocument");
doc->GetNameSpaceManager(*getter_AddRefs(mNameSpaceManager));
NS_ASSERTION(mNameSpaceManager, "Can't get namespace manager.");
mCurrentNode = aFragment;
}
txMozillaXMLOutput::~txMozillaXMLOutput()
@@ -86,7 +121,7 @@ txMozillaXMLOutput::~txMozillaXMLOutput()
}
NS_IMPL_ISUPPORTS2(txMozillaXMLOutput,
txIMozillaXMLEventHandler,
txIOutputXMLEventHandler,
nsIScriptLoaderObserver);
void txMozillaXMLOutput::attribute(const String& aName,
@@ -128,30 +163,22 @@ void txMozillaXMLOutput::comment(const String& aData)
{
closePrevious(eCloseElement | eFlushText);
if (mCurrentNode) {
nsCOMPtr<nsIDOMComment> comment;
nsresult rv = mDocument->CreateComment(aData,
getter_AddRefs(comment));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create comment");
nsCOMPtr<nsIDOMNode> resultNode;
rv = mCurrentNode->AppendChild(comment, getter_AddRefs(resultNode));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't append comment");
}
else {
DelayedNode* dn = new DelayedNode(DelayedNode::eCommentNode,
aData);
if (!dn) {
return;
}
mDelayedNodes.add(dn);
}
TX_ENSURE_CURRENTNODE;
nsCOMPtr<nsIDOMComment> comment;
nsresult rv = mDocument->CreateComment(aData,
getter_AddRefs(comment));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create comment");
nsCOMPtr<nsIDOMNode> resultNode;
rv = mCurrentNode->AppendChild(comment, getter_AddRefs(resultNode));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't append comment");
}
void txMozillaXMLOutput::endDocument()
{
closePrevious(eCloseElement | eFlushText);
// XXX is this really needed since we reset the document?
if (!mHaveTitleElement) {
if (mCreatingNewDocument && !mHaveTitleElement) {
nsCOMPtr<nsIDOMNSDocument> domDoc = do_QueryInterface(mDocument);
if (domDoc) {
domDoc->SetTitle(NS_LITERAL_STRING(""));
@@ -180,6 +207,8 @@ void txMozillaXMLOutput::endDocument()
void txMozillaXMLOutput::endElement(const String& aName, const PRInt32 aNsID)
{
TX_ENSURE_CURRENTNODE;
#ifdef DEBUG
nsAutoString nodeName;
mCurrentNode->GetNodeName(nodeName);
@@ -228,47 +257,42 @@ void txMozillaXMLOutput::endElement(const String& aName, const PRInt32 aNsID)
void txMozillaXMLOutput::getOutputDocument(nsIDOMDocument** aDocument)
{
*aDocument = mDocument;
NS_IF_ADDREF(*aDocument);
}
void txMozillaXMLOutput::processingInstruction(const String& aTarget, const String& aData)
{
TX_ENSURE_CURRENTNODE;
if (mOutputFormat.mMethod == eHTMLOutput)
return;
closePrevious(eCloseElement | eFlushText);
if (mCurrentNode) {
nsCOMPtr<nsIDOMProcessingInstruction> pi;
nsresult rv = mDocument->CreateProcessingInstruction(aTarget, aData,
getter_AddRefs(pi));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create processing instruction");
nsCOMPtr<nsIDOMProcessingInstruction> pi;
nsresult rv = mDocument->CreateProcessingInstruction(aTarget, aData,
getter_AddRefs(pi));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create processing instruction");
nsCOMPtr<nsIStyleSheetLinkingElement> ssle = do_QueryInterface(pi);
nsCOMPtr<nsIStyleSheetLinkingElement> ssle;
if (mCreatingNewDocument) {
ssle = do_QueryInterface(pi);
if (ssle) {
ssle->InitStyleLinkElement(nsnull, PR_FALSE);
ssle->SetEnableUpdates(PR_FALSE);
}
nsCOMPtr<nsIDOMNode> resultNode;
rv = mCurrentNode->AppendChild(pi, getter_AddRefs(resultNode));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't append processing instruction");
if (ssle && mObserver) {
ssle->SetEnableUpdates(PR_TRUE);
rv = ssle->UpdateStyleSheet(nsnull, mStyleSheetCount);
if (NS_SUCCEEDED(rv) || (rv == NS_ERROR_HTMLPARSER_BLOCK)) {
mStyleSheetCount++;
}
}
}
else {
DelayedNode* dn = new DelayedNode(DelayedNode::ePINode,
aTarget,
aData);
if (!dn) {
return;
nsCOMPtr<nsIDOMNode> resultNode;
rv = mCurrentNode->AppendChild(pi, getter_AddRefs(resultNode));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't append processing instruction");
if (ssle) {
ssle->SetEnableUpdates(PR_TRUE);
rv = ssle->UpdateStyleSheet(nsnull, mStyleSheetCount);
if (NS_SUCCEEDED(rv) || (rv == NS_ERROR_HTMLPARSER_BLOCK)) {
mStyleSheetCount++;
}
mDelayedNodes.add(dn);
}
}
@@ -281,46 +305,29 @@ void txMozillaXMLOutput::removeScriptElement(nsIDOMHTMLScriptElement *aElement)
}
}
void txMozillaXMLOutput::setSourceDocument(nsIDOMDocument* aDocument)
{
mSourceDocument = aDocument;
}
void txMozillaXMLOutput::setOutputFormat(txOutputFormat* aOutputFormat)
{
mOutputFormat.reset();
mOutputFormat.merge(*aOutputFormat);
mOutputFormat.setFromDefaults();
}
void txMozillaXMLOutput::startDocument()
{
NS_ASSERTION(mSourceDocument, "missing source document");
mInTransform = PR_TRUE;
}
void txMozillaXMLOutput::startElement(const String& aName,
const PRInt32 aNsID)
{
TX_ENSURE_CURRENTNODE;
closePrevious(eCloseElement | eFlushText);
nsresult rv;
// Create document if needed
if (!mDocument) {
rv = createResultDocument(aName);
if (NS_FAILED(rv)) {
return;
}
}
nsCOMPtr<nsIDOMElement> element;
mDontAddCurrent = PR_FALSE;
if ((mOutputFormat.mMethod == eHTMLOutput) && (aNsID == kNameSpaceID_None)) {
rv = mDocument->CreateElement(aName,
getter_AddRefs(element));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create element");
if (NS_FAILED(rv)) {
return;
}
startHTMLElement(element);
}
@@ -329,29 +336,29 @@ void txMozillaXMLOutput::startElement(const String& aName,
mNameSpaceManager->GetNameSpaceURI(aNsID, nsURI);
rv = mDocument->CreateElementNS(nsURI, aName,
getter_AddRefs(element));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create element");
if (NS_FAILED(rv)) {
return;
}
if (aNsID == kNameSpaceID_XHTML)
startHTMLElement(element);
}
if (element) {
if (mCreatingNewDocument) {
nsCOMPtr<nsIContent> cont = do_QueryInterface(element);
if (cont) {
nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
cont->SetDocument(doc, PR_FALSE, PR_TRUE);
}
mParentNode = mCurrentNode;
mCurrentNode = do_QueryInterface(element);
nsCOMPtr<nsIDocument> doc = do_QueryInterface(mDocument);
cont->SetDocument(doc, PR_FALSE, PR_TRUE);
}
mParentNode = mCurrentNode;
mCurrentNode = do_QueryInterface(element);
}
void txMozillaXMLOutput::closePrevious(PRInt8 aAction)
{
TX_ENSURE_CURRENTNODE;
nsresult rv;
if ((aAction & eCloseElement) && mParentNode) {
TX_ENSURE_CURRENTNODE;
nsCOMPtr<nsIDocument> document = do_QueryInterface(mParentNode);
nsCOMPtr<nsIDOMElement> currentElement = do_QueryInterface(mCurrentNode);
@@ -405,22 +412,13 @@ void txMozillaXMLOutput::closePrevious(PRInt8 aAction)
mParentNode = nsnull;
}
else if ((aAction & eFlushText) && !mText.IsEmpty()) {
if (mCurrentNode) {
nsCOMPtr<nsIDOMText> text;
rv = mDocument->CreateTextNode(mText, getter_AddRefs(text));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create text node");
nsCOMPtr<nsIDOMText> text;
rv = mDocument->CreateTextNode(mText, getter_AddRefs(text));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create text node");
nsCOMPtr<nsIDOMNode> resultNode;
mCurrentNode->AppendChild(text, getter_AddRefs(resultNode));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't append text node");
}
else {
DelayedNode* dn = new DelayedNode(DelayedNode::eTextNode,
String(mText));
if (dn) {
mDelayedNodes.add(dn);
}
}
nsCOMPtr<nsIDOMNode> resultNode;
mCurrentNode->AppendChild(text, getter_AddRefs(resultNode));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't append text node");
mText.Truncate();
}
@@ -434,16 +432,18 @@ void txMozillaXMLOutput::startHTMLElement(nsIDOMElement* aElement)
mDontAddCurrent = (atom == txHTMLAtoms::script);
nsCOMPtr<nsIStyleSheetLinkingElement> ssle =
do_QueryInterface(aElement);
if (ssle) {
// XXX Trick nsCSSLoader into blocking/notifying us?
// We would need to implement nsIParser and
// pass ourselves as first parameter to
// InitStyleLinkElement. We would then be notified
// of stylesheet loads/load failures.
ssle->InitStyleLinkElement(nsnull, PR_FALSE);
ssle->SetEnableUpdates(PR_FALSE);
if (mCreatingNewDocument) {
nsCOMPtr<nsIStyleSheetLinkingElement> ssle =
do_QueryInterface(aElement);
if (ssle) {
// XXX Trick nsCSSLoader into blocking/notifying us?
// We would need to implement nsIParser and
// pass ourselves as first parameter to
// InitStyleLinkElement. We would then be notified
// of stylesheet loads/load failures.
ssle->InitStyleLinkElement(nsnull, PR_FALSE);
ssle->SetEnableUpdates(PR_FALSE);
}
}
}
@@ -491,7 +491,8 @@ void txMozillaXMLOutput::endHTMLElement(nsIDOMElement* aElement,
}
}
// Load scripts
else if (atom == txHTMLAtoms::script) {
else if (mCreatingNewDocument &&
atom == txHTMLAtoms::script) {
// Add this script element to the array of loading script elements.
nsCOMPtr<nsIDOMHTMLScriptElement> scriptElement =
do_QueryInterface(mCurrentNode);
@@ -503,7 +504,8 @@ void txMozillaXMLOutput::endHTMLElement(nsIDOMElement* aElement,
mScriptElements->AppendElement(scriptElement);
}
// Set document title
else if (atom == txHTMLAtoms::title && !mHaveTitleElement) {
else if (mCreatingNewDocument &&
atom == txHTMLAtoms::title && !mHaveTitleElement) {
// The first title wins
mHaveTitleElement = PR_TRUE;
nsCOMPtr<nsIDOMNSDocument> domDoc = do_QueryInterface(mDocument);
@@ -516,7 +518,8 @@ void txMozillaXMLOutput::endHTMLElement(nsIDOMElement* aElement,
domDoc->SetTitle(text);
}
}
else if (atom == txHTMLAtoms::base && !mHaveBaseElement) {
else if (mCreatingNewDocument &&
atom == txHTMLAtoms::base && !mHaveBaseElement) {
// The first base wins
mHaveBaseElement = PR_TRUE;
@@ -533,7 +536,8 @@ void txMozillaXMLOutput::endHTMLElement(nsIDOMElement* aElement,
return;
doc->SetBaseURL(baseURI); // The document checks if it is legal to set this base
}
else if (atom == txHTMLAtoms::meta) {
else if (mCreatingNewDocument &&
atom == txHTMLAtoms::meta) {
// handle HTTP-EQUIV data
nsAutoString httpEquiv;
content->GetAttr(kNameSpaceID_None, txHTMLAtoms::httpEquiv, httpEquiv);
@@ -551,8 +555,7 @@ void txMozillaXMLOutput::endHTMLElement(nsIDOMElement* aElement,
}
// Handle all sorts of stylesheets
nsCOMPtr<nsITransformObserver> observer = do_QueryReferent(mObserver);
if (observer) {
if (mCreatingNewDocument) {
nsCOMPtr<nsIStyleSheetLinkingElement> ssle =
do_QueryInterface(aElement);
if (ssle) {
@@ -594,9 +597,9 @@ void txMozillaXMLOutput::wrapChildren(nsIDOMNode* aCurrentNode,
}
nsresult
txMozillaXMLOutput::createResultDocument(const String& aName)
txMozillaXMLOutput::createResultDocument(const String& aName, PRInt32 aNsID,
nsIDOMDocument* aSourceDocument)
{
NS_ENSURE_TRUE(mSourceDocument, NS_ERROR_UNEXPECTED);
nsresult rv;
// Create the document
@@ -606,6 +609,8 @@ txMozillaXMLOutput::createResultDocument(const String& aName)
NS_ENSURE_SUCCESS(rv, rv);
}
else {
// We should check the root name/namespace here and create the
// appropriate document
doc = do_CreateInstance(kXMLDocumentCID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
@@ -617,7 +622,7 @@ txMozillaXMLOutput::createResultDocument(const String& aName)
// Reset and set up the document
nsCOMPtr<nsILoadGroup> loadGroup;
nsCOMPtr<nsIChannel> channel;
nsCOMPtr<nsIDocument> sourceDoc = do_QueryInterface(mSourceDocument);
nsCOMPtr<nsIDocument> sourceDoc = do_QueryInterface(aSourceDocument);
sourceDoc->GetDocumentLoadGroup(getter_AddRefs(loadGroup));
nsCOMPtr<nsIIOService> serv = do_GetService(NS_IOSERVICE_CONTRACTID);
if (serv) {
@@ -648,6 +653,7 @@ txMozillaXMLOutput::createResultDocument(const String& aName)
}
}
// Notify the contentsink that the document is created
if (observer) {
observer->OnDocumentCreated(mDocument);
}
@@ -655,7 +661,7 @@ txMozillaXMLOutput::createResultDocument(const String& aName)
// Add a doc-type if requested
if (!mOutputFormat.mSystemId.isEmpty()) {
nsCOMPtr<nsIDOMDOMImplementation> implementation;
rv = mSourceDocument->GetImplementation(getter_AddRefs(implementation));
rv = aSourceDocument->GetImplementation(getter_AddRefs(implementation));
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString qName;
if (mOutputFormat.mMethod == eHTMLOutput) {
@@ -674,31 +680,6 @@ txMozillaXMLOutput::createResultDocument(const String& aName)
mDocument->AppendChild(documentType, getter_AddRefs(tmp));
}
// Add childnodes that were created before we had a document
txListIterator iter(&mDelayedNodes);
DelayedNode* dn;
while((dn = (DelayedNode*)iter.next())) {
switch (dn->mType) {
case DelayedNode::eCommentNode:
{
comment(dn->mData);
break;
}
case DelayedNode::ePINode:
{
processingInstruction(dn->mName, dn->mData);
break;
}
case DelayedNode::eTextNode:
{
characters(dn->mData);
break;
}
}
delete dn;
iter.remove();
}
return NS_OK;
}
@@ -750,11 +731,11 @@ txMozillaXMLOutput::SignalTransformEnd()
}
}
mObserver = nsnull;
// Make sure that we don't get deleted while this function is executed and
// we remove ourselfs from the scriptloader
nsCOMPtr<nsIScriptLoaderObserver> kungFuDeathGrip(this);
// if (root) {
// mDocument->ContentInserted(nsnull, root, 0);
// }
mObserver = nsnull;
// XXX Need a better way to determine transform success/failure
if (mDocument) {
@@ -772,8 +753,3 @@ txMozillaXMLOutput::SignalTransformEnd()
observer->OnTransformDone(NS_ERROR_FAILURE, nsnull);
}
}
void txMozillaXMLOutput::setObserver(nsITransformObserver* aObserver)
{
mObserver = do_GetWeakReference(aObserver);
}

View File

@@ -52,11 +52,17 @@
#include "nsWeakPtr.h"
#include "txOutputFormat.h"
class txMozillaXMLOutput : public txIMozillaXMLEventHandler,
class txMozillaXMLOutput : public txIOutputXMLEventHandler,
public nsIScriptLoaderObserver
{
public:
txMozillaXMLOutput();
txMozillaXMLOutput(const String& aRootName,
PRInt32 aRootNsID,
txOutputFormat* aFormat,
nsIDOMDocument* aSourceDocument,
nsITransformObserver* aObserver);
txMozillaXMLOutput(txOutputFormat* aFormat,
nsIDOMDocumentFragment* aFragment);
virtual ~txMozillaXMLOutput();
NS_DECL_ISUPPORTS
@@ -147,18 +153,6 @@ public:
void startElement(const String& aName,
const PRInt32 aNsID);
/**
* Sets the output format.
*
* @param aOutputFormat the output format
*/
void setOutputFormat(txOutputFormat* aOutputFormat);
/**
* Disables loading of stylesheets.
*/
void disableStylesheetLoad();
/**
* Removes a script element from the array of elements that are
* still loading.
@@ -167,13 +161,6 @@ public:
*/
void removeScriptElement(nsIDOMHTMLScriptElement *aElement);
/**
* Sets the Mozilla source document
*
* @param aDocument the Mozilla source document
*/
void setSourceDocument(nsIDOMDocument* aDocument);
/**
* Gets the Mozilla output document
*
@@ -181,23 +168,16 @@ public:
*/
void getOutputDocument(nsIDOMDocument** aDocument);
/**
* Sets the content-sink observer
*
* @param aObserver the content-sink observer
*/
void setObserver(nsITransformObserver* aObserver);
private:
void closePrevious(PRInt8 aAction);
void startHTMLElement(nsIDOMElement* aElement);
void endHTMLElement(nsIDOMElement* aElement, PRBool aXHTML);
void processHTTPEquiv(nsIAtom* aHeader, const nsAString& aValue);
void wrapChildren(nsIDOMNode* aCurrentNode, nsIDOMElement* aWrapper);
nsresult createResultDocument(const String& aName);
nsresult createResultDocument(const String& aName, PRInt32 aNsID,
nsIDOMDocument* aSourceDocument);
void SignalTransformEnd();
nsCOMPtr<nsIDOMDocument> mSourceDocument;
nsCOMPtr<nsIDOMDocument> mDocument;
nsCOMPtr<nsIDOMNode> mCurrentNode;
nsCOMPtr<nsIDOMNode> mParentNode;
@@ -224,30 +204,9 @@ private:
PRPackedBool mHaveBaseElement;
PRPackedBool mInTransform;
PRPackedBool mCreatingNewDocument;
enum txAction { eCloseElement = 1, eFlushText = 2 };
struct DelayedNode {
enum Type { eCommentNode, ePINode, eTextNode };
DelayedNode(Type aType, const String& aName, const String& aData)
: mType(aType),
mName(aName),
mData(aData)
{
}
DelayedNode(Type aType, const String& aData)
: mType(aType),
mData(aData)
{
}
Type mType;
String mName;
String mData;
};
txList mDelayedNodes;
};
#endif

View File

@@ -52,6 +52,163 @@
#include "txSingleNodeContext.h"
#include "txURIUtils.h"
#include "XMLUtils.h"
#include "txUnknownHandler.h"
#include "nsIHTMLDocument.h"
/**
* Output Handler Factories
*/
class txToDocHandlerFactory : public txIOutputHandlerFactory
{
public:
txToDocHandlerFactory(ProcessorState* aPs,
nsIDOMDocument* aSourceDocument,
nsITransformObserver* aObserver)
: mPs(aPs), mSourceDocument(aSourceDocument), mObserver(aObserver)
{
}
virtual ~txToDocHandlerFactory()
{
}
TX_DECL_TXIOUTPUTHANDLERFACTORY;
private:
ProcessorState* mPs;
nsCOMPtr<nsIDOMDocument> mSourceDocument;
nsCOMPtr<nsITransformObserver> mObserver;
};
class txToFragmentHandlerFactory : public txIOutputHandlerFactory
{
public:
txToFragmentHandlerFactory(nsIDOMDocumentFragment* aFragment)
: mFragment(aFragment)
{
}
virtual ~txToFragmentHandlerFactory()
{
}
TX_DECL_TXIOUTPUTHANDLERFACTORY;
private:
nsCOMPtr<nsIDOMDocumentFragment> mFragment;
};
nsresult
txToDocHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
txIOutputXMLEventHandler*& aHandler)
{
aHandler = nsnull;
switch (aFormat->mMethod) {
case eMethodNotSet:
case eXMLOutput:
aHandler = new txUnknownHandler(mPs);
break;
case eHTMLOutput:
aHandler = new txMozillaXMLOutput(String(), kNameSpaceID_None,
aFormat, mSourceDocument,
mObserver);
break;
case eTextOutput:
// if we don't have an observer we are parsing into a non-displayed
// new document, so textoutput doesn't make sence
if (!mObserver) {
return NS_ERROR_FAILURE;
}
aHandler = new txMozillaTextOutput(mSourceDocument, mObserver);
break;
}
NS_ENSURE_TRUE(aHandler, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
nsresult
txToDocHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
const String& aName,
PRInt32 aNsID,
txIOutputXMLEventHandler*& aHandler)
{
aHandler = nsnull;
switch (aFormat->mMethod) {
case eMethodNotSet:
aHandler = new txUnknownHandler(mPs);
break;
case eXMLOutput:
case eHTMLOutput:
aHandler = new txMozillaXMLOutput(aName, aNsID, aFormat,
mSourceDocument, mObserver);
break;
case eTextOutput:
// if we don't have an observer we are parsing into a non-displayed
// new document, so textoutput doesn't make sence
if (!mObserver) {
return NS_ERROR_FAILURE;
}
aHandler = new txMozillaTextOutput(mSourceDocument, mObserver);
break;
}
NS_ENSURE_TRUE(aHandler, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
nsresult
txToFragmentHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
txIOutputXMLEventHandler*& aHandler)
{
aHandler = nsnull;
switch (aFormat->mMethod) {
case eMethodNotSet:
{
txOutputFormat format;
format.merge(*aFormat);
nsCOMPtr<nsIDOMDocument> doc;
mFragment->GetOwnerDocument(getter_AddRefs(doc));
NS_ASSERTION(doc, "unable to get ownerdocument");
// Need a way for testing xhtml vs. html. But this is the best
// we can do for now.
nsCOMPtr<nsIHTMLDocument> htmldoc = do_QueryInterface(doc);
format.mMethod = htmldoc ? eHTMLOutput : eXMLOutput;
aHandler = new txMozillaXMLOutput(&format, mFragment);
break;
}
case eXMLOutput:
case eHTMLOutput:
aHandler = new txMozillaXMLOutput(aFormat, mFragment);
break;
case eTextOutput:
aHandler = new txMozillaTextOutput(mFragment);
break;
}
NS_ENSURE_TRUE(aHandler, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
nsresult
txToFragmentHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
const String& aName,
PRInt32 aNsID,
txIOutputXMLEventHandler*& aHandler)
{
aHandler = nsnull;
NS_ASSERTION(aFormat->mMethod != eMethodNotSet,
"How can method not be known when root element is?");
NS_ENSURE_TRUE(aFormat->mMethod != eMethodNotSet, NS_ERROR_UNEXPECTED);
return createHandlerWith(aFormat, aHandler);
}
/**
* txMozillaXSLTProcessor
*/
NS_DEFINE_CID(kNameSpaceManagerCID, NS_NAMESPACEMANAGER_CID);
@@ -79,10 +236,12 @@ txMozillaXSLTProcessor::TransformDocument(nsIDOMNode* aSourceDOM,
nsITransformObserver* aObserver,
nsIDOMDocument** aOutputDoc)
{
NS_ENSURE_ARG(aSourceDOM);
NS_ENSURE_ARG(aStyleDOM);
NS_ENSURE_ARG(aOutputDoc);
NS_ASSERTION(aSourceDOM, "missing source document");
NS_ASSERTION(aStyleDOM, "missing style document");
NS_ASSERTION(aObserver, "missing observer");
NS_ASSERTION(aOutputDoc, "bad return-pointer");
// Do we really need this now that this is not a scriptable function?
if (!URIUtils::CanCallerAccess(aSourceDOM) ||
!URIUtils::CanCallerAccess(aStyleDOM)) {
return NS_ERROR_DOM_SECURITY_ERR;
@@ -112,7 +271,6 @@ txMozillaXSLTProcessor::TransformDocument(nsIDOMNode* aSourceDOM,
{
// Create a new ProcessorState
ProcessorState ps(&sourceDocument, &xslDocument);
ps.setTransformObserver(aObserver);
// XXX Need to add error observers
@@ -137,8 +295,14 @@ txMozillaXSLTProcessor::TransformDocument(nsIDOMNode* aSourceDOM,
}
NS_ENSURE_SUCCESS(rv, rv);
txToDocHandlerFactory handlerFactory(&ps, sourceDOMDocument,
aObserver);
ps.mOutputHandlerFactory = &handlerFactory;
// Process root of XML source document
txXSLTProcessor::transform(&ps);
ps.mOutputHandler->getOutputDocument(aOutputDoc);
}
// End of block to ensure the destruction of the ProcessorState
// before the destruction of the documents.
@@ -153,21 +317,25 @@ txMozillaXSLTProcessor::Init(nsIDOMNode *aStyle)
return NS_ERROR_DOM_SECURITY_ERR;
}
PRUint16 type = 0;
aStyle->GetNodeType(&type);
NS_ENSURE_TRUE(type == nsIDOMNode::ELEMENT_NODE ||
type == nsIDOMNode::DOCUMENT_NODE,
NS_ERROR_FAILURE);
mStylesheet = aStyle;
return NS_OK;
}
NS_IMETHODIMP
txMozillaXSLTProcessor::TransformNode(nsIDOMNode *aSource,
nsIDOMDocument *aOutput,
nsIDOMDocumentFragment **aResult)
txMozillaXSLTProcessor::TransformToDocument(nsIDOMNode *aSource,
nsIDOMDocument **aResult)
{
NS_ENSURE_ARG(aSource);
NS_ENSURE_ARG(aOutput);
NS_ASSERTION(aSource, "missing source document");
NS_ASSERTION(aResult, "bad return-pointer");
NS_ENSURE_TRUE(mStylesheet, NS_ERROR_FAILURE);
if (!URIUtils::CanCallerAccess(aSource) ||
!URIUtils::CanCallerAccess(aOutput)) {
if (!URIUtils::CanCallerAccess(aSource)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
@@ -190,11 +358,6 @@ txMozillaXSLTProcessor::TransformNode(nsIDOMNode *aSource,
}
Document xslDocument(styleDOMDocument);
// Create wrapper for the output document.
nsCOMPtr<nsIDocument> document = do_QueryInterface(aOutput);
NS_ENSURE_TRUE(document, NS_ERROR_FAILURE);
Document resultDocument(aOutput);
// Start of block to ensure the destruction of the ProcessorState
// before the destruction of the documents.
{
@@ -224,14 +387,88 @@ txMozillaXSLTProcessor::TransformNode(nsIDOMNode *aSource,
}
NS_ENSURE_SUCCESS(rv, rv);
// Get the script loader of the result document.
nsCOMPtr<nsIScriptLoader> loader;
document->GetScriptLoader(getter_AddRefs(loader));
if (loader) {
// Don't load scripts, we can't notify the caller when they're loaded.
loader->Suspend();
}
txToDocHandlerFactory handlerFactory(&ps, sourceDOMDocument, nsnull);
ps.mOutputHandlerFactory = &handlerFactory;
// Process root of XML source document
txXSLTProcessor::transform(&ps);
ps.mOutputHandler->getOutputDocument(aResult);
}
// End of block to ensure the destruction of the ProcessorState
// before the destruction of the documents.
return NS_OK;
}
NS_IMETHODIMP
txMozillaXSLTProcessor::TransformToFragment(nsIDOMNode *aSource,
nsIDOMDocument *aOutput,
nsIDOMDocumentFragment **aResult)
{
NS_ENSURE_ARG(aSource);
NS_ENSURE_ARG(aOutput);
NS_ENSURE_TRUE(mStylesheet, NS_ERROR_FAILURE);
if (!URIUtils::CanCallerAccess(aSource) ||
!URIUtils::CanCallerAccess(aOutput)) {
return NS_ERROR_DOM_SECURITY_ERR;
}
// Create wrapper for the source document.
nsCOMPtr<nsIDOMDocument> sourceDOMDocument;
aSource->GetOwnerDocument(getter_AddRefs(sourceDOMDocument));
if (!sourceDOMDocument) {
sourceDOMDocument = do_QueryInterface(aSource);
}
NS_ENSURE_TRUE(sourceDOMDocument, NS_ERROR_FAILURE);
Document sourceDocument(sourceDOMDocument);
Node* sourceNode = sourceDocument.createWrapper(aSource);
NS_ENSURE_TRUE(sourceNode, NS_ERROR_FAILURE);
// Create wrapper for the style document.
nsCOMPtr<nsIDOMDocument> styleDOMDocument;
mStylesheet->GetOwnerDocument(getter_AddRefs(styleDOMDocument));
if (!styleDOMDocument) {
styleDOMDocument = do_QueryInterface(mStylesheet);
}
Document xslDocument(styleDOMDocument);
// Start of block to ensure the destruction of the ProcessorState
// before the destruction of the documents.
{
// Create a new ProcessorState
ProcessorState ps(&sourceDocument, &xslDocument);
// XXX Need to add error observers
// Set current txIEvalContext
txSingleNodeContext evalContext(&sourceDocument, &ps);
ps.setEvalContext(&evalContext);
// Index templates and process top level xslt elements
nsCOMPtr<nsIDOMDocument> styleDoc = do_QueryInterface(mStylesheet);
nsresult rv;
if (styleDoc) {
rv = txXSLTProcessor::processStylesheet(&xslDocument,
&mVariables, &ps);
}
else {
nsCOMPtr<nsIDOMElement> styleElem = do_QueryInterface(mStylesheet);
NS_ENSURE_TRUE(styleElem, NS_ERROR_FAILURE);
Element* element = xslDocument.createElement(styleElem);
NS_ENSURE_TRUE(element, NS_ERROR_OUT_OF_MEMORY);
rv = txXSLTProcessor::processTopLevel(element, &mVariables,
&ps);
}
NS_ENSURE_SUCCESS(rv, rv);
rv = aOutput->CreateDocumentFragment(aResult);
NS_ENSURE_SUCCESS(rv, rv);
txToFragmentHandlerFactory handlerFactory(*aResult);
ps.mOutputHandlerFactory = &handlerFactory;
// Process root of XML source document
txXSLTProcessor::transform(&ps);
}
@@ -299,6 +536,7 @@ txMozillaXSLTProcessor::SetParameter(const nsAString & aNamespaceURI,
PRInt32 nsId = kNameSpaceID_Unknown;
rv = namespaceManager->GetNameSpaceID(aNamespaceURI, nsId);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIAtom> localName = do_GetAtom(aLocalName);
txExpandedName varName(nsId, localName);
@@ -326,6 +564,7 @@ txMozillaXSLTProcessor::GetParameter(const nsAString& aNamespaceURI,
PRInt32 nsId = kNameSpaceID_Unknown;
rv = namespaceManager->GetNameSpaceID(aNamespaceURI, nsId);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIAtom> localName = do_GetAtom(aLocalName);
txExpandedName varName(nsId, localName);

View File

@@ -49,6 +49,10 @@
#include "txExpandedNameMap.h"
#include "XSLTProcessor.h"
#include "nsIDOMNode.h"
#include "txXMLEventHandler.h"
#include "nsIDOMDocument.h"
#include "nsITransformObserver.h"
#include "nsIDOMDocumentFragment.h"
/* bacd8ad0-552f-11d3-a9f7-000064657374 */
#define TRANSFORMIIX_XSLT_PROCESSOR_CID \

View File

@@ -47,6 +47,73 @@
#include "txHTMLOutput.h"
#include "txTextOutput.h"
/**
* Output Handler Factory
*/
class txStandaloneHandlerFactory : public txIOutputHandlerFactory
{
public:
txStandaloneHandlerFactory(ProcessorState* aPs,
ostream* aStream)
: mPs(aPs), mStream(aStream)
{
}
virtual ~txStandaloneHandlerFactory()
{
};
TX_DECL_TXIOUTPUTHANDLERFACTORY;
private:
ProcessorState* mPs;
ostream* mStream;
};
nsresult
txStandaloneHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
txIOutputXMLEventHandler*& aHandler)
{
aHandler = 0;
switch (aFormat->mMethod) {
case eXMLOutput:
aHandler = new txXMLOutput(aFormat, mStream);
break;
case eHTMLOutput:
aHandler = new txHTMLOutput(aFormat, mStream);
break;
case eTextOutput:
aHandler = new txTextOutput(mStream);
break;
case eMethodNotSet:
aHandler = new txUnknownHandler(mPs);
break;
}
NS_ENSURE_TRUE(aHandler, NS_ERROR_OUT_OF_MEMORY);
return NS_OK;
}
nsresult
txStandaloneHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
const String& aName,
PRInt32 aNsID,
txIOutputXMLEventHandler*& aHandler)
{
aHandler = 0;
NS_ASSERTION(aFormat->mMethod != eMethodNotSet,
"How can method not be known when root element is?");
NS_ENSURE_TRUE(aFormat->mMethod != eMethodNotSet, NS_ERROR_UNEXPECTED);
return createHandlerWith(aFormat, aHandler);
}
/**
* txStandaloneXSLTProcessor
*/
/**
* Transform a XML document given by path.
* The stylesheet is retrieved by a processing instruction,
@@ -143,7 +210,6 @@ txStandaloneXSLTProcessor::transform(Document* aSource, Node* aStylesheet,
stylesheetDoc = aStylesheet->getOwnerDocument();
}
ProcessorState ps(aSource, stylesheetDoc);
ps.setOutputStream(&aOut);
ps.addErrorObserver(aErr);
@@ -162,6 +228,9 @@ txStandaloneXSLTProcessor::transform(Document* aSource, Node* aStylesheet,
return rv;
}
txStandaloneHandlerFactory handlerFactory(&ps, &aOut);
ps.mOutputHandlerFactory = &handlerFactory;
#ifndef XP_WIN
bool sync = aOut.sync_with_stdio(false);
#endif

View File

@@ -39,7 +39,8 @@
#include "txTextOutput.h"
#include "TxString.h"
txTextOutput::txTextOutput()
txTextOutput::txTextOutput(ostream* aOut)
: mOut(aOut)
{
}
@@ -89,21 +90,3 @@ void txTextOutput::startElement(const String& aName,
const PRInt32 aNsID)
{
}
void txTextOutput::getOutputStream(ostream** aOutputStream)
{
if (aOutputStream)
*aOutputStream = mOut;
}
void txTextOutput::setOutputStream(ostream* aOutputStream)
{
mOut = aOutputStream;
}
void txTextOutput::setOutputFormat(txOutputFormat* aOutputFormat)
{
mOutputFormat.reset();
mOutputFormat.merge(*aOutputFormat);
mOutputFormat.setFromDefaults();
}

View File

@@ -42,10 +42,10 @@
#include "txXMLEventHandler.h"
#include "txOutputFormat.h"
class txTextOutput : public txStreamXMLEventHandler
class txTextOutput : public txIOutputXMLEventHandler
{
public:
txTextOutput();
txTextOutput(ostream* aOut);
~txTextOutput();
/*
@@ -130,30 +130,8 @@ public:
void startElement(const String& aName,
const PRInt32 aNsID);
/*
* Sets the output format.
*
* @param aOutputFormat the output format
*/
void setOutputFormat(txOutputFormat* aOutputFormat);
/**
* Get the output stream.
*
* @param aOutputStream the current output stream
*/
void getOutputStream(ostream** aOutputStream);
/**
* Sets the output stream.
*
* @param aDocument the Mozilla output document
*/
void setOutputStream(ostream* aOutputStream);
private:
ostream* mOut;
txOutputFormat mOutputFormat;
};
#endif

View File

@@ -40,12 +40,20 @@
#include <string.h>
#include "ProcessorState.h"
#ifndef TX_EXE
NS_IMPL_ISUPPORTS1(txUnknownHandler, txIOutputXMLEventHandler);
#endif
PRUint32 txUnknownHandler::kReasonableTransactions = 8;
txUnknownHandler::txUnknownHandler(ProcessorState* aState)
txUnknownHandler::txUnknownHandler(ProcessorState* aPs)
: mTotal(0), mMax(kReasonableTransactions),
mProcessorState(aState)
mPs(aPs)
{
#ifndef TX_EXE
NS_INIT_ISUPPORTS();
#endif
mArray = new txOutputTransaction*[kReasonableTransactions];
}
@@ -62,7 +70,9 @@ void txUnknownHandler::attribute(const String& aName,
const PRInt32 aNsID,
const String& aValue)
{
NS_ASSERTION(0, "This shouldn't be called")
// If this is called then the stylesheet is trying to add an attribute
// without adding an element first. So we'll just ignore it.
// XXX ErrorReport: Signal this?
}
void txUnknownHandler::characters(const String& aData)
@@ -71,7 +81,7 @@ void txUnknownHandler::characters(const String& aData)
new txOneStringTransaction(txOutputTransaction::eCharacterTransaction,
aData);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!")
NS_ASSERTION(0, "Out of memory!");
return;
}
addTransaction(transaction);
@@ -83,7 +93,7 @@ void txUnknownHandler::charactersNoOutputEscaping(const String& aData)
new txOneStringTransaction(txOutputTransaction::eCharacterNoOETransaction,
aData);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!")
NS_ASSERTION(0, "Out of memory!");
return;
}
addTransaction(transaction);
@@ -95,7 +105,7 @@ void txUnknownHandler::comment(const String& aData)
new txOneStringTransaction(txOutputTransaction::eCommentTransaction,
aData);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!")
NS_ASSERTION(0, "Out of memory!");
return;
}
addTransaction(transaction);
@@ -106,27 +116,29 @@ void txUnknownHandler::endDocument()
// This is an unusual case, no output method has been set and we
// didn't create a document element. Switching to XML output mode
// anyway.
txOutputFormat* format = mProcessorState->getOutputFormat();
txOutputXMLEventHandler* outputHandler =
mProcessorState->getOutputHandler(eXMLOutput);
NS_ASSERTION(outputHandler, "Out of memory, dropping output!");
if (!outputHandler) {
#ifndef TX_EXE
// Make sure that we don't get deleted while this function is executed and
// we set a new outputhandler
nsCOMPtr<txIOutputXMLEventHandler> kungFuDeathGrip(this);
#endif
nsresult rv = createHandlerAndFlush(eXMLOutput, String(),
kNameSpaceID_None);
if (NS_FAILED(rv))
return;
}
format->mMethod = eXMLOutput;
txStreamXMLEventHandler* streamHandler =
(txStreamXMLEventHandler*)outputHandler;
streamHandler->setOutputStream(mOut);
streamHandler->setOutputFormat(format);
flush(streamHandler);
streamHandler->endDocument();
delete outputHandler;
mPs->mResultHandler->endDocument();
// in module the outputhandler is refcounted
#ifdef TX_EXE
delete this;
#endif
}
void txUnknownHandler::endElement(const String& aName,
const PRInt32 aNsID)
{
NS_ASSERTION(0, "This shouldn't be called")
NS_ASSERTION(0, "This shouldn't be called");
}
void txUnknownHandler::processingInstruction(const String& aTarget,
@@ -136,7 +148,7 @@ void txUnknownHandler::processingInstruction(const String& aTarget,
new txTwoStringTransaction(txOutputTransaction::ePITransaction,
aTarget, aData);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!")
NS_ASSERTION(0, "Out of memory!");
return;
}
addTransaction(transaction);
@@ -147,7 +159,7 @@ void txUnknownHandler::startDocument()
txOutputTransaction* transaction =
new txOutputTransaction(txOutputTransaction::eStartDocumentTransaction);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!")
NS_ASSERTION(0, "Out of memory!");
return;
}
addTransaction(transaction);
@@ -156,68 +168,108 @@ void txUnknownHandler::startDocument()
void txUnknownHandler::startElement(const String& aName,
const PRInt32 aNsID)
{
NS_ASSERTION(0, "This shouldn't be called")
}
#ifndef TX_EXE
// Make sure that we don't get deleted while this function is executed and
// we set a new outputhandler
nsCOMPtr<txIOutputXMLEventHandler> kungFuDeathGrip(this);
#endif
void txUnknownHandler::setOutputFormat(txOutputFormat* aOutputFormat)
{
}
void txUnknownHandler::getOutputStream(ostream** aOutputStream)
{
if (aOutputStream) {
*aOutputStream = mOut;
nsresult rv = NS_OK;
txOutputFormat* format = mPs->getOutputFormat();
if (format->mMethod != eMethodNotSet) {
rv = createHandlerAndFlush(format->mMethod, aName, aNsID);
}
else if (aNsID == kNameSpaceID_None &&
aName.isEqualIgnoreCase(String("html"))) {
rv = createHandlerAndFlush(eHTMLOutput, aName, aNsID);
}
else {
rv = createHandlerAndFlush(eXMLOutput, aName, aNsID);
}
if (NS_FAILED(rv))
return;
mPs->mResultHandler->startElement(aName, aNsID);
// in module the outputhandler is refcounted
#ifdef TX_EXE
delete this;
#endif
}
void txUnknownHandler::setOutputStream(ostream* aOutputStream)
#ifndef TX_EXE
void txUnknownHandler::getOutputDocument(nsIDOMDocument** aDocument)
{
mOut = aOutputStream;
*aDocument = nsnull;
}
#endif
void txUnknownHandler::flush(txStreamXMLEventHandler* aHandler)
nsresult txUnknownHandler::createHandlerAndFlush(txOutputMethod aMethod,
const String& aName,
const PRInt32 aNsID)
{
nsresult rv = NS_OK;
txOutputFormat* format = mPs->getOutputFormat();
format->mMethod = aMethod;
txIOutputXMLEventHandler* handler = 0;
rv = mPs->mOutputHandlerFactory->createHandlerWith(format, aName, aNsID,
handler);
NS_ENSURE_SUCCESS(rv, rv);
mPs->mOutputHandler = handler;
mPs->mResultHandler = handler;
MBool hasDOE = handler->hasDisableOutputEscaping();
PRUint32 counter;
for (counter = 0; counter < mTotal; ++counter) {
switch (mArray[counter]->mType) {
case txOutputTransaction::eCharacterTransaction:
{
txOneStringTransaction* transaction = (txOneStringTransaction*)mArray[counter];
aHandler->characters(transaction->mString);
handler->characters(transaction->mString);
delete transaction;
break;
}
case txOutputTransaction::eCharacterNoOETransaction:
{
txOneStringTransaction* transaction = (txOneStringTransaction*)mArray[counter];
aHandler->charactersNoOutputEscaping(transaction->mString);
if (hasDOE) {
handler->charactersNoOutputEscaping(transaction->mString);
}
else {
handler->characters(transaction->mString);
}
delete transaction;
break;
}
case txOutputTransaction::eCommentTransaction:
{
txOneStringTransaction* transaction = (txOneStringTransaction*)mArray[counter];
aHandler->comment(transaction->mString);
handler->comment(transaction->mString);
delete transaction;
break;
}
case txOutputTransaction::ePITransaction:
{
txTwoStringTransaction* transaction = (txTwoStringTransaction*)mArray[counter];
aHandler->processingInstruction(transaction->mStringOne,
handler->processingInstruction(transaction->mStringOne,
transaction->mStringTwo);
delete transaction;
break;
}
case txOutputTransaction::eStartDocumentTransaction:
{
aHandler->startDocument();
handler->startDocument();
delete mArray[counter];
break;
}
}
}
mTotal = 0;
return NS_OK;
}
void txUnknownHandler::addTransaction(txOutputTransaction* aTransaction)
@@ -226,7 +278,7 @@ void txUnknownHandler::addTransaction(txOutputTransaction* aTransaction)
PRUint32 newMax = mMax * 2;
txOutputTransaction** newArray = new txOutputTransaction*[newMax];
if (!newArray) {
NS_ASSERTION(0, "Out of memory!")
NS_ASSERTION(0, "Out of memory!");
return;
}
mMax = newMax;

View File

@@ -41,6 +41,7 @@
#include "txXMLEventHandler.h"
#include "TxString.h"
#include "txOutputFormat.h"
class ProcessorState;
@@ -91,12 +92,16 @@ public:
String mStringTwo;
};
class txUnknownHandler : public txStreamXMLEventHandler
class txUnknownHandler : public txIOutputXMLEventHandler
{
public:
txUnknownHandler(ProcessorState* aState);
txUnknownHandler(ProcessorState* aPs);
virtual ~txUnknownHandler();
#ifndef TX_EXE
NS_DECL_ISUPPORTS
#endif
/*
* Signals to receive the start of an attribute.
*
@@ -178,40 +183,29 @@ public:
*/
void startElement(const String& aName,
const PRInt32 aNsID);
/*
* Sets the output format.
*
* @param aOutputFormat the output format
*/
void setOutputFormat(txOutputFormat* aOutputFormat);
#ifndef TX_EXE
/**
* Get the output stream.
* Gets the Mozilla output document
*
* @param aOutputStream the current output stream
* @param aDocument the Mozilla output document
*/
void getOutputStream(ostream** aOutputStream);
/*
* Sets the output stream.
*
* @param aOutputStream the output stream
*/
void setOutputStream(ostream* aOutputStream);
void flush(txStreamXMLEventHandler* aHandler);
void getOutputDocument(nsIDOMDocument** aDocument);
#endif
private:
nsresult createHandlerAndFlush(txOutputMethod aMethod,
const String& aName,
const PRInt32 aNsID);
void addTransaction(txOutputTransaction* aTransaction);
PRUint32 mTotal, mMax;
ostream* mOut;
/*
* XXX we shouldn't hold to the ProcessorState, as we're supposed
* to live without it. But as a standalone handler, we don't.
* The right fix may need a txOutputFormat here.
*/
ProcessorState* mProcessorState;
ProcessorState* mPs;
txOutputTransaction** mArray;
static PRUint32 kReasonableTransactions;

View File

@@ -25,6 +25,7 @@
#define TRANSFRMX_XML_EVENT_HANDLER_H
#include "baseutils.h"
#include "txError.h"
class String;
class txOutputFormat;
#ifdef TX_EXE
@@ -111,16 +112,18 @@ public:
const PRInt32 aNsID) = 0;
};
class txOutputXMLEventHandler : public txXMLEventHandler
#ifdef TX_EXE
class txIOutputXMLEventHandler : public txXMLEventHandler
#else
#define TX_IOUTPUTXMLEVENTHANDLER_IID \
{ 0x80e5e802, 0x8c88, 0x11d6, \
{ 0xa7, 0xf2, 0xc5, 0xc3, 0x85, 0x6b, 0xbb, 0xbc }}
class txIOutputXMLEventHandler : public nsISupports,
public txXMLEventHandler
#endif
{
public:
/**
* Sets the output format.
*
* @param aOutputFormat the output format
*/
virtual void setOutputFormat(txOutputFormat* aOutputFormat) = 0;
/**
* Signals to receive characters that don't need output escaping.
*
@@ -136,43 +139,9 @@ public:
* disable-output-escaping
*/
virtual MBool hasDisableOutputEscaping() = 0;
};
#ifdef TX_EXE
class txStreamXMLEventHandler : public txOutputXMLEventHandler
{
public:
/**
* Get the output stream.
*
* @param aOutputStream the current output stream
*/
virtual void getOutputStream(ostream** aOutputStream) = 0;
/**
* Sets the output stream.
*
* @param aOutputStream the output stream
*/
virtual void setOutputStream(ostream* aOutputStream) = 0;
};
#else
#define TX_IMOZILLAXMLEVENTHANDLER_IID \
{ 0x80e5e802, 0x8c88, 0x11d6, \
{ 0xa7, 0xf2, 0xc5, 0xc3, 0x85, 0x6b, 0xbb, 0xbc }}
class txIMozillaXMLEventHandler : public nsISupports,
public txOutputXMLEventHandler
{
public:
NS_DEFINE_STATIC_IID_ACCESSOR(TX_IMOZILLAXMLEVENTHANDLER_IID)
/**
* Sets the Mozilla source document
*
* @param aDocument the Mozilla source document
*/
virtual void setSourceDocument(nsIDOMDocument* aDocument) = 0;
#ifndef TX_EXE
NS_DEFINE_STATIC_IID_ACCESSOR(TX_IOUTPUTXMLEVENTHANDLER_IID)
/**
* Gets the Mozilla output document
@@ -180,14 +149,47 @@ public:
* @param aDocument the Mozilla output document
*/
virtual void getOutputDocument(nsIDOMDocument** aDocument) = 0;
#endif
};
/**
* Interface used to create the appropriate outputhandler
*/
class txIOutputHandlerFactory
{
public:
virtual ~txIOutputHandlerFactory() {};
/**
* Sets the content-sink observer
*
* @param aObserver the content-sink observer
* Creates an outputhandler for the specified format.
* @param aFromat format to get handler for
* @param aHandler outparam. The created handler
*/
virtual void setObserver(nsITransformObserver* aObserver) = 0;
virtual nsresult
createHandlerWith(txOutputFormat* aFormat,
txIOutputXMLEventHandler*& aHandler) = 0;
/**
* Creates an outputhandler for the specified format, with the specified
* name and namespace for the root element.
* @param aFromat format to get handler for
* @param aName name of the root element
* @param aNsID namespace-id of the root element
* @param aHandler outparam. The created handler
*/
virtual nsresult
createHandlerWith(txOutputFormat* aFormat,
const String& aName,
PRInt32 aNsID,
txIOutputXMLEventHandler*& aHandler) = 0;
};
#endif
#define TX_DECL_TXIOUTPUTHANDLERFACTORY \
nsresult createHandlerWith(txOutputFormat* aFormat, \
txIOutputXMLEventHandler*& aHandler); \
nsresult createHandlerWith(txOutputFormat* aFormat, \
const String& aName, \
PRInt32 aNsID, \
txIOutputXMLEventHandler*& aHandler) \
#endif

View File

@@ -47,13 +47,17 @@ txAttribute::txAttribute(PRInt32 aNsID, txAtom* aLocalName, const String& aValue
{
}
txXMLOutput::txXMLOutput() : mUseEmptyElementShorthand(MB_TRUE),
mHaveDocumentElement(MB_FALSE),
mStartTagOpen(MB_FALSE),
mAfterEndTag(MB_FALSE),
mInCDATASection(MB_FALSE),
mIndentLevel(0)
txXMLOutput::txXMLOutput(txOutputFormat* aFormat, ostream* aOut)
: mOut(aOut),
mUseEmptyElementShorthand(MB_TRUE),
mHaveDocumentElement(MB_FALSE),
mStartTagOpen(MB_FALSE),
mAfterEndTag(MB_FALSE),
mInCDATASection(MB_FALSE),
mIndentLevel(0)
{
mOutputFormat.merge(*aFormat);
mOutputFormat.setFromDefaults();
}
txXMLOutput::~txXMLOutput()
@@ -251,24 +255,6 @@ void txXMLOutput::startElement(const String& aName,
}
}
void txXMLOutput::getOutputStream(ostream** aOutputStream)
{
if (aOutputStream)
*aOutputStream = mOut;
}
void txXMLOutput::setOutputStream(ostream* aOutputStream)
{
mOut = aOutputStream;
}
void txXMLOutput::setOutputFormat(txOutputFormat* aOutputFormat)
{
mOutputFormat.reset();
mOutputFormat.merge(*aOutputFormat);
mOutputFormat.setFromDefaults();
}
void txXMLOutput::closeStartTag(MBool aUseEmptyElementShorthand)
{
mAfterEndTag = aUseEmptyElementShorthand;

View File

@@ -91,10 +91,10 @@ public:
MBool mShorthand;
};
class txXMLOutput : public txStreamXMLEventHandler
class txXMLOutput : public txIOutputXMLEventHandler
{
public:
txXMLOutput();
txXMLOutput(txOutputFormat* aFormat, ostream* aOut);
virtual ~txXMLOutput();
static const int DEFAULT_INDENT;
@@ -181,27 +181,6 @@ public:
virtual void startElement(const String& aName,
const PRInt32 aNsID);
/*
* Sets the output format.
*
* @param aOutputFormat the output format
*/
void setOutputFormat(txOutputFormat* aOutputFormat);
/**
* Get the output stream.
*
* @param aOutputStream the current output stream
*/
void getOutputStream(ostream** aOutputStream);
/**
* Sets the output stream.
*
* @param aOutputStream the new output stream
*/
void setOutputStream(ostream* aOutputStream);
protected:
virtual void closeStartTag(MBool aUseEmptyElementShorthand);
void printUTF8Char(DOM_CHAR& ch);