From 1d1426b99538a8c895fa9fbb21728f52caccb0dd Mon Sep 17 00:00:00 2001 From: "sicking%bigfoot.com" Date: Tue, 17 Sep 2002 12:30:33 +0000 Subject: [PATCH] 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 --- .../extensions/transformiix/build/Makefile.in | 2 + .../build/XSLTProcessorModule.cpp | 1 - .../transformiix/source/xslt/Makefile.in | 3 +- .../source/xslt/ProcessorState.cpp | 121 +------- .../transformiix/source/xslt/ProcessorState.h | 38 +-- .../source/xslt/XSLTProcessor.cpp | 57 ++-- .../transformiix/source/xslt/txHTMLOutput.cpp | 3 +- .../transformiix/source/xslt/txHTMLOutput.h | 2 +- .../source/xslt/txMozillaTextOutput.cpp | 91 ++++-- .../source/xslt/txMozillaTextOutput.h | 30 +- .../source/xslt/txMozillaXMLOutput.cpp | 276 ++++++++--------- .../source/xslt/txMozillaXMLOutput.h | 63 +--- .../source/xslt/txMozillaXSLTProcessor.cpp | 285 ++++++++++++++++-- .../source/xslt/txMozillaXSLTProcessor.h | 4 + .../source/xslt/txStandaloneXSLTProcessor.cpp | 71 ++++- .../transformiix/source/xslt/txTextOutput.cpp | 21 +- .../transformiix/source/xslt/txTextOutput.h | 26 +- .../source/xslt/txUnknownHandler.cpp | 136 ++++++--- .../source/xslt/txUnknownHandler.h | 38 +-- .../source/xslt/txXMLEventHandler.h | 100 +++--- .../transformiix/source/xslt/txXMLOutput.cpp | 34 +-- .../transformiix/source/xslt/txXMLOutput.h | 25 +- 22 files changed, 752 insertions(+), 675 deletions(-) diff --git a/mozilla/extensions/transformiix/build/Makefile.in b/mozilla/extensions/transformiix/build/Makefile.in index 3f96481b3fe..b8f20b13a2f 100644 --- a/mozilla/extensions/transformiix/build/Makefile.in +++ b/mozilla/extensions/transformiix/build/Makefile.in @@ -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) \ diff --git a/mozilla/extensions/transformiix/build/XSLTProcessorModule.cpp b/mozilla/extensions/transformiix/build/XSLTProcessorModule.cpp index 97fbf17aef0..8a6ec3a112c 100755 --- a/mozilla/extensions/transformiix/build/XSLTProcessorModule.cpp +++ b/mozilla/extensions/transformiix/build/XSLTProcessorModule.cpp @@ -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) diff --git a/mozilla/extensions/transformiix/source/xslt/Makefile.in b/mozilla/extensions/transformiix/source/xslt/Makefile.in index 387c9562261..31113ade88a 100644 --- a/mozilla/extensions/transformiix/source/xslt/Makefile.in +++ b/mozilla/extensions/transformiix/source/xslt/Makefile.in @@ -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 \ diff --git a/mozilla/extensions/transformiix/source/xslt/ProcessorState.cpp b/mozilla/extensions/transformiix/source/xslt/ProcessorState.cpp index 0202d4e167b..7823fe28a30 100644 --- a/mozilla/extensions/transformiix/source/xslt/ProcessorState.cpp +++ b/mozilla/extensions/transformiix/source/xslt/ProcessorState.cpp @@ -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 source = - do_QueryInterface(mSourceDocument->getNSObj()); - mMozillaOutputHandler->setSourceDocument(source); - nsCOMPtr 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 -/ //-------------------/ diff --git a/mozilla/extensions/transformiix/source/xslt/ProcessorState.h b/mozilla/extensions/transformiix/source/xslt/ProcessorState.h index 722c7f927db..0f19e7df8e2 100644 --- a/mozilla/extensions/transformiix/source/xslt/ProcessorState.h +++ b/mozilla/extensions/transformiix/source/xslt/ProcessorState.h @@ -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 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 mMozillaOutputHandler; - nsWeakPtr mObserver; -#endif }; /** diff --git a/mozilla/extensions/transformiix/source/xslt/XSLTProcessor.cpp b/mozilla/extensions/transformiix/source/xslt/XSLTProcessor.cpp index 5a1da462464..cfef6375414 100644 --- a/mozilla/extensions/transformiix/source/xslt/XSLTProcessor.cpp +++ b/mozilla/extensions/transformiix/source/xslt/XSLTProcessor.cpp @@ -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); diff --git a/mozilla/extensions/transformiix/source/xslt/txHTMLOutput.cpp b/mozilla/extensions/transformiix/source/xslt/txHTMLOutput.cpp index a59b27dc47b..efe7ae09c5b 100644 --- a/mozilla/extensions/transformiix/source/xslt/txHTMLOutput.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txHTMLOutput.cpp @@ -41,7 +41,8 @@ #include "txOutputFormat.h" #include "XMLUtils.h" -txHTMLOutput::txHTMLOutput() +txHTMLOutput::txHTMLOutput(txOutputFormat* aFormat, ostream* aOut) + : txXMLOutput(aFormat, aOut) { mUseEmptyElementShorthand = MB_FALSE; diff --git a/mozilla/extensions/transformiix/source/xslt/txHTMLOutput.h b/mozilla/extensions/transformiix/source/xslt/txHTMLOutput.h index d16a435fc18..ebdc476c578 100644 --- a/mozilla/extensions/transformiix/source/xslt/txHTMLOutput.h +++ b/mozilla/extensions/transformiix/source/xslt/txHTMLOutput.h @@ -46,7 +46,7 @@ class txHTMLOutput : public txXMLOutput { public: - txHTMLOutput(); + txHTMLOutput(txOutputFormat* aFormat, ostream* aOut); ~txHTMLOutput(); /* diff --git a/mozilla/extensions/transformiix/source/xslt/txMozillaTextOutput.cpp b/mozilla/extensions/transformiix/source/xslt/txMozillaTextOutput.cpp index 46155c43ab2..b6cd5a6a5a4 100644 --- a/mozilla/extensions/transformiix/source/xslt/txMozillaTextOutput.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txMozillaTextOutput.cpp @@ -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 doc; + mFragment->GetOwnerDocument(getter_AddRefs(doc)); + NS_ASSERTION(doc, "unable to get ownerdocument"); + nsCOMPtr textNode; + rv = doc->CreateTextNode(NS_LITERAL_STRING(""), + getter_AddRefs(textNode)); + if (NS_FAILED(rv)) { + return; + } + nsCOMPtr 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 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 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 loadGroup; + nsCOMPtr channel; + nsCOMPtr sourceDoc = do_QueryInterface(mSourceDocument); + sourceDoc->GetDocumentLoadGroup(getter_AddRefs(loadGroup)); + nsCOMPtr 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 docURL; + sourceDoc->GetDocumentURL(getter_AddRefs(docURL)); + serv->NewChannelFromURI(docURL, getter_AddRefs(channel)); + } + doc->Reset(channel, loadGroup); + nsCOMPtr 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 observer = do_QueryReferent(mObserver); + if (observer) { + observer->OnDocumentCreated(mDocument); + } // Create the content nsCOMPtr 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); -} diff --git a/mozilla/extensions/transformiix/source/xslt/txMozillaTextOutput.h b/mozilla/extensions/transformiix/source/xslt/txMozillaTextOutput.h index 31d510ca443..9b95e5dc813 100644 --- a/mozilla/extensions/transformiix/source/xslt/txMozillaTextOutput.h +++ b/mozilla/extensions/transformiix/source/xslt/txMozillaTextOutput.h @@ -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 mTextNode; - nsCOMPtr mRootContent; nsWeakPtr mObserver; nsCOMPtr mDocument; txOutputFormat mOutputFormat; + nsCOMPtr mFragment; + nsCOMPtr mSourceDocument; }; #endif diff --git a/mozilla/extensions/transformiix/source/xslt/txMozillaXMLOutput.cpp b/mozilla/extensions/transformiix/source/xslt/txMozillaXMLOutput.cpp index 23bfe8c229d..47c2be66a4b 100644 --- a/mozilla/extensions/transformiix/source/xslt/txMozillaXMLOutput.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txMozillaXMLOutput.cpp @@ -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 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 comment; - nsresult rv = mDocument->CreateComment(aData, - getter_AddRefs(comment)); - NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create comment"); - nsCOMPtr 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 comment; + nsresult rv = mDocument->CreateComment(aData, + getter_AddRefs(comment)); + NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create comment"); + nsCOMPtr 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 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 pi; - nsresult rv = mDocument->CreateProcessingInstruction(aTarget, aData, - getter_AddRefs(pi)); - NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create processing instruction"); + nsCOMPtr pi; + nsresult rv = mDocument->CreateProcessingInstruction(aTarget, aData, + getter_AddRefs(pi)); + NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create processing instruction"); - nsCOMPtr ssle = do_QueryInterface(pi); + nsCOMPtr ssle; + if (mCreatingNewDocument) { + ssle = do_QueryInterface(pi); if (ssle) { ssle->InitStyleLinkElement(nsnull, PR_FALSE); ssle->SetEnableUpdates(PR_FALSE); } - - nsCOMPtr 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 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 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 cont = do_QueryInterface(element); - if (cont) { - nsCOMPtr doc = do_QueryInterface(mDocument); - cont->SetDocument(doc, PR_FALSE, PR_TRUE); - } - mParentNode = mCurrentNode; - mCurrentNode = do_QueryInterface(element); + nsCOMPtr 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 document = do_QueryInterface(mParentNode); nsCOMPtr currentElement = do_QueryInterface(mCurrentNode); @@ -405,22 +412,13 @@ void txMozillaXMLOutput::closePrevious(PRInt8 aAction) mParentNode = nsnull; } else if ((aAction & eFlushText) && !mText.IsEmpty()) { - if (mCurrentNode) { - nsCOMPtr text; - rv = mDocument->CreateTextNode(mText, getter_AddRefs(text)); - NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create text node"); + nsCOMPtr text; + rv = mDocument->CreateTextNode(mText, getter_AddRefs(text)); + NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create text node"); - nsCOMPtr 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 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 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 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 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 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 observer = do_QueryReferent(mObserver); - if (observer) { + if (mCreatingNewDocument) { nsCOMPtr 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 loadGroup; nsCOMPtr channel; - nsCOMPtr sourceDoc = do_QueryInterface(mSourceDocument); + nsCOMPtr sourceDoc = do_QueryInterface(aSourceDocument); sourceDoc->GetDocumentLoadGroup(getter_AddRefs(loadGroup)); nsCOMPtr 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 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 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); -} diff --git a/mozilla/extensions/transformiix/source/xslt/txMozillaXMLOutput.h b/mozilla/extensions/transformiix/source/xslt/txMozillaXMLOutput.h index bb5d3556263..942c4738145 100644 --- a/mozilla/extensions/transformiix/source/xslt/txMozillaXMLOutput.h +++ b/mozilla/extensions/transformiix/source/xslt/txMozillaXMLOutput.h @@ -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 mSourceDocument; nsCOMPtr mDocument; nsCOMPtr mCurrentNode; nsCOMPtr 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 diff --git a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp index 2c114801ff5..d17281f2410 100644 --- a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.cpp @@ -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 mSourceDocument; + nsCOMPtr mObserver; +}; + +class txToFragmentHandlerFactory : public txIOutputHandlerFactory +{ +public: + txToFragmentHandlerFactory(nsIDOMDocumentFragment* aFragment) + : mFragment(aFragment) + { + } + + virtual ~txToFragmentHandlerFactory() + { + } + + TX_DECL_TXIOUTPUTHANDLERFACTORY; + +private: + nsCOMPtr 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 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 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 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 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 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 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 styleDoc = do_QueryInterface(mStylesheet); + nsresult rv; + if (styleDoc) { + rv = txXSLTProcessor::processStylesheet(&xslDocument, + &mVariables, &ps); + } + else { + nsCOMPtr 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 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 localName = do_GetAtom(aLocalName); txExpandedName varName(nsId, localName); diff --git a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.h b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.h index c3c8fcadc9f..5a72dd24087 100644 --- a/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.h +++ b/mozilla/extensions/transformiix/source/xslt/txMozillaXSLTProcessor.h @@ -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 \ diff --git a/mozilla/extensions/transformiix/source/xslt/txStandaloneXSLTProcessor.cpp b/mozilla/extensions/transformiix/source/xslt/txStandaloneXSLTProcessor.cpp index 6c955e7e949..a037506d392 100644 --- a/mozilla/extensions/transformiix/source/xslt/txStandaloneXSLTProcessor.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txStandaloneXSLTProcessor.cpp @@ -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 diff --git a/mozilla/extensions/transformiix/source/xslt/txTextOutput.cpp b/mozilla/extensions/transformiix/source/xslt/txTextOutput.cpp index 5bd3252575c..63da8d26235 100644 --- a/mozilla/extensions/transformiix/source/xslt/txTextOutput.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txTextOutput.cpp @@ -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(); -} diff --git a/mozilla/extensions/transformiix/source/xslt/txTextOutput.h b/mozilla/extensions/transformiix/source/xslt/txTextOutput.h index 0cb8910de57..46e5b122ca1 100644 --- a/mozilla/extensions/transformiix/source/xslt/txTextOutput.h +++ b/mozilla/extensions/transformiix/source/xslt/txTextOutput.h @@ -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 diff --git a/mozilla/extensions/transformiix/source/xslt/txUnknownHandler.cpp b/mozilla/extensions/transformiix/source/xslt/txUnknownHandler.cpp index 64ecdbe5ef3..6c7bff47237 100644 --- a/mozilla/extensions/transformiix/source/xslt/txUnknownHandler.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txUnknownHandler.cpp @@ -40,12 +40,20 @@ #include #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 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 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; diff --git a/mozilla/extensions/transformiix/source/xslt/txUnknownHandler.h b/mozilla/extensions/transformiix/source/xslt/txUnknownHandler.h index b4a5edd3c94..173f88108d2 100644 --- a/mozilla/extensions/transformiix/source/xslt/txUnknownHandler.h +++ b/mozilla/extensions/transformiix/source/xslt/txUnknownHandler.h @@ -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; diff --git a/mozilla/extensions/transformiix/source/xslt/txXMLEventHandler.h b/mozilla/extensions/transformiix/source/xslt/txXMLEventHandler.h index 910188e2a93..9f73de47012 100644 --- a/mozilla/extensions/transformiix/source/xslt/txXMLEventHandler.h +++ b/mozilla/extensions/transformiix/source/xslt/txXMLEventHandler.h @@ -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 diff --git a/mozilla/extensions/transformiix/source/xslt/txXMLOutput.cpp b/mozilla/extensions/transformiix/source/xslt/txXMLOutput.cpp index 9d4dd494a21..852632a288d 100644 --- a/mozilla/extensions/transformiix/source/xslt/txXMLOutput.cpp +++ b/mozilla/extensions/transformiix/source/xslt/txXMLOutput.cpp @@ -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; diff --git a/mozilla/extensions/transformiix/source/xslt/txXMLOutput.h b/mozilla/extensions/transformiix/source/xslt/txXMLOutput.h index 06fe622a5e1..ac6f2acafb7 100644 --- a/mozilla/extensions/transformiix/source/xslt/txXMLOutput.h +++ b/mozilla/extensions/transformiix/source/xslt/txXMLOutput.h @@ -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);