Fix for bug 179720 (implement real result tree fragments). r=sicking, sr=jst.

This commit is contained in:
peterv%netscape.com 2005-11-02 07:40:06 +00:00
parent e19f0f8afc
commit 345ddb1a06
23 changed files with 764 additions and 1036 deletions

View File

@ -139,7 +139,7 @@ nsXPathExpression::Evaluate(nsIDOMNode *aContextNode,
case ExprResult::NODESET:
resultType = nsIDOMXPathResult::UNORDERED_NODE_ITERATOR_TYPE;
break;
case ExprResult::TREE_FRAGMENT:
case ExprResult::RESULT_TREE_FRAGMENT:
NS_ERROR("Can't return a tree fragment!");
delete exprResult;
return NS_ERROR_FAILURE;

View File

@ -47,11 +47,11 @@ public:
//-- ResultTypes
enum ResultType {
TREE_FRAGMENT = 0,
NODESET,
BOOLEAN,
NUMBER,
STRING,
BOOLEAN,
NODESET
RESULT_TREE_FRAGMENT
};
virtual ~ExprResult() {};

View File

@ -49,6 +49,7 @@ endif
CPPSRCS = txOutputFormat.cpp \
ProcessorState.cpp \
txBufferingHandler.cpp \
txRtfHandler.cpp \
txTextHandler.cpp \
txXSLTNumber.cpp \

View File

@ -0,0 +1,416 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Jonas Sicking.
* Portions created by the Initial Developer are Copyright (C) 2003
* Jonas Sicking. All Rights Reserved.
*
* Contributor(s):
* Jonas Sicking <jonas@sicking.cc>
* Peter Van der Beken <peterv@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "txBufferingHandler.h"
class txOutputTransaction
{
public:
enum txTransactionType {
eAttributeTransaction,
eCharacterTransaction,
eCharacterNoOETransaction,
eCommentTransaction,
eEndDocumentTransaction,
eEndElementTransaction,
ePITransaction,
eStartDocumentTransaction,
eStartElementTransaction
};
txOutputTransaction(txTransactionType aType)
: mType(aType)
{
}
virtual ~txOutputTransaction()
{
}
txTransactionType mType;
};
class txCharacterTransaction : public txOutputTransaction
{
public:
txCharacterTransaction(txTransactionType aType, PRUint32 aLength)
: txOutputTransaction(aType),
mLength(aLength)
{
}
PRUint32 mLength;
};
class txCommentTransaction : public txOutputTransaction
{
public:
txCommentTransaction(const nsAString& aValue)
: txOutputTransaction(eCommentTransaction),
mValue(aValue)
{
}
nsString mValue;
};
class txPITransaction : public txOutputTransaction
{
public:
txPITransaction(const nsAString& aTarget, const nsAString& aData)
: txOutputTransaction(ePITransaction),
mTarget(aTarget),
mData(aData)
{
}
nsString mTarget;
nsString mData;
};
class txElementTransaction : public txOutputTransaction
{
public:
txElementTransaction(txTransactionType aType, const nsAString& aName,
PRInt32 aNsID)
: txOutputTransaction(aType),
mName(aName),
mNsID(aNsID)
{
}
nsString mName;
PRInt32 mNsID;
};
class txAttributeTransaction : public txOutputTransaction
{
public:
txAttributeTransaction(const nsAString& aName, PRInt32 aNsID,
const nsAString& aValue)
: txOutputTransaction(eAttributeTransaction),
mName(aName),
mNsID(aNsID),
mValue(aValue)
{
}
nsString mName;
PRInt32 mNsID;
nsString mValue;
};
txBufferingHandler::txBufferingHandler() : mCanAddAttribute(PR_FALSE)
{
mBuffer = new txResultBuffer();
}
txBufferingHandler::~txBufferingHandler()
{
}
void
txBufferingHandler::attribute(const nsAString& aName, const PRInt32 aNsID,
const nsAString& aValue)
{
if (!mBuffer) {
return;
}
if (!mCanAddAttribute) {
// XXX ErrorReport: Can't add attributes without element
return;
}
txOutputTransaction* transaction =
new txAttributeTransaction(aName, aNsID, aValue);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!");
return;
}
mBuffer->addTransaction(transaction);
}
void
txBufferingHandler::characters(const nsAString& aData, PRBool aDOE)
{
if (!mBuffer) {
return;
}
mCanAddAttribute = PR_FALSE;
txOutputTransaction::txTransactionType type =
aDOE ? txOutputTransaction::eCharacterNoOETransaction
: txOutputTransaction::eCharacterTransaction;
txOutputTransaction* transaction = mBuffer->getLastTransaction();
if (transaction && transaction->mType == type) {
mBuffer->mStringValue.Append(aData);
NS_STATIC_CAST(txCharacterTransaction*, transaction)->mLength +=
aData.Length();
return;
}
transaction = new txCharacterTransaction(type, aData.Length());
if (!transaction) {
NS_ASSERTION(0, "Out of memory!");
return;
}
mBuffer->mStringValue.Append(aData);
mBuffer->addTransaction(transaction);
}
void
txBufferingHandler::comment(const nsAString& aData)
{
if (!mBuffer) {
return;
}
mCanAddAttribute = PR_FALSE;
txOutputTransaction* transaction = new txCommentTransaction(aData);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!");
return;
}
mBuffer->addTransaction(transaction);
}
void
txBufferingHandler::endDocument()
{
if (!mBuffer) {
return;
}
txOutputTransaction* transaction =
new txOutputTransaction(txOutputTransaction::eEndDocumentTransaction);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!");
return;
}
mBuffer->addTransaction(transaction);
}
void
txBufferingHandler::endElement(const nsAString& aName, const PRInt32 aNsID)
{
if (!mBuffer) {
return;
}
mCanAddAttribute = PR_FALSE;
txOutputTransaction* transaction =
new txElementTransaction(txOutputTransaction::eEndElementTransaction,
aName, aNsID);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!");
return;
}
mBuffer->addTransaction(transaction);
}
void
txBufferingHandler::processingInstruction(const nsAString& aTarget,
const nsAString& aData)
{
if (!mBuffer) {
return;
}
mCanAddAttribute = PR_FALSE;
txOutputTransaction* transaction =
new txPITransaction(aTarget, aData);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!");
return;
}
mBuffer->addTransaction(transaction);
}
void txBufferingHandler::startDocument()
{
if (!mBuffer) {
return;
}
txOutputTransaction* transaction =
new txOutputTransaction(txOutputTransaction::eStartDocumentTransaction);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!");
return;
}
mBuffer->addTransaction(transaction);
}
void
txBufferingHandler::startElement(const nsAString& aName, const PRInt32 aNsID)
{
if (!mBuffer) {
return;
}
mCanAddAttribute = PR_TRUE;
txOutputTransaction* transaction =
new txElementTransaction(txOutputTransaction::eStartElementTransaction,
aName, aNsID);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!");
return;
}
mBuffer->addTransaction(transaction);
}
PR_STATIC_CALLBACK(PRBool)
deleteTransaction(void* aElement, void *aData)
{
delete NS_STATIC_CAST(txOutputTransaction*, aElement);
return PR_TRUE;
}
txResultBuffer::~txResultBuffer()
{
mTransactions.EnumerateForwards(deleteTransaction, nsnull);
}
nsresult
txResultBuffer::addTransaction(txOutputTransaction* aTransaction)
{
if (!mTransactions.AppendElement(aTransaction)) {
return NS_ERROR_OUT_OF_MEMORY;
}
return NS_OK;
}
struct Holder
{
txAXMLEventHandler* mHandler;
nsAFlatString::const_char_iterator mIter;
};
PR_STATIC_CALLBACK(PRBool)
flushTransaction(void* aElement, void *aData)
{
txAXMLEventHandler* handler = NS_STATIC_CAST(Holder*, aData)->mHandler;
txOutputTransaction* transaction =
NS_STATIC_CAST(txOutputTransaction*, aElement);
switch (transaction->mType) {
case txOutputTransaction::eAttributeTransaction:
{
txAttributeTransaction* attrTransaction =
NS_STATIC_CAST(txAttributeTransaction*, aElement);
handler->attribute(attrTransaction->mName,
attrTransaction->mNsID,
attrTransaction->mValue);
break;
}
case txOutputTransaction::eCharacterTransaction:
case txOutputTransaction::eCharacterNoOETransaction:
{
txCharacterTransaction* charTransaction =
NS_STATIC_CAST(txCharacterTransaction*, aElement);
nsAFlatString::const_char_iterator& start =
NS_STATIC_CAST(Holder*, aData)->mIter;
nsAFlatString::const_char_iterator end =
start + charTransaction->mLength;
handler->characters(Substring(start, end),
transaction->mType ==
txOutputTransaction::eCharacterNoOETransaction);
start = end;
break;
}
case txOutputTransaction::eCommentTransaction:
{
txCommentTransaction* commentTransaction =
NS_STATIC_CAST(txCommentTransaction*, aElement);
handler->comment(commentTransaction->mValue);
break;
}
case txOutputTransaction::eEndElementTransaction:
{
txElementTransaction* elementTransaction =
NS_STATIC_CAST(txElementTransaction*, aElement);
handler->endElement(elementTransaction->mName,
elementTransaction->mNsID);
break;
}
case txOutputTransaction::ePITransaction:
{
txPITransaction* piTransaction =
NS_STATIC_CAST(txPITransaction*, aElement);
handler->processingInstruction(piTransaction->mTarget,
piTransaction->mData);
break;
}
case txOutputTransaction::eStartDocumentTransaction:
{
handler->startDocument();
break;
}
case txOutputTransaction::eStartElementTransaction:
{
txElementTransaction* elementTransaction =
NS_STATIC_CAST(txElementTransaction*, aElement);
handler->startElement(elementTransaction->mName,
elementTransaction->mNsID);
break;
}
}
return PR_TRUE;
}
nsresult
txResultBuffer::flushToHandler(txAXMLEventHandler* aHandler)
{
Holder data;
data.mHandler = aHandler;
mStringValue.BeginReading(data.mIter);
mTransactions.EnumerateForwards(flushTransaction, &data);
return NS_OK;
}
txOutputTransaction*
txResultBuffer::getLastTransaction()
{
PRInt32 last = mTransactions.Count() - 1;
if (last < 0) {
return nsnull;
}
return NS_STATIC_CAST(txOutputTransaction*, mTransactions[last]);
}

View File

@ -0,0 +1,94 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Jonas Sicking.
* Portions created by the Initial Developer are Copyright (C) 2003
* Jonas Sicking. All Rights Reserved.
*
* Contributor(s):
* Jonas Sicking <jonas@sicking.cc>
* Peter Van der Beken <peterv@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef txBufferingHandler_h__
#define txBufferingHandler_h__
#include "txXMLEventHandler.h"
#include "nsString.h"
#include "nsVoidArray.h"
#include "nsAutoPtr.h"
class txOutputTransaction;
class txCharacterTransaction;
class txResultBuffer
{
public:
~txResultBuffer();
nsrefcnt AddRef()
{
return ++mRefCnt;
}
nsrefcnt Release()
{
if (--mRefCnt == 0) {
mRefCnt = 1; //stabilize
delete this;
return 0;
}
return mRefCnt;
}
nsresult addTransaction(txOutputTransaction* aTransaction);
nsresult flushToHandler(txAXMLEventHandler* aHandler);
txOutputTransaction* getLastTransaction();
nsString mStringValue;
private:
nsVoidArray mTransactions;
nsAutoRefCnt mRefCnt;
};
class txBufferingHandler : public txAXMLEventHandler
{
public:
txBufferingHandler();
~txBufferingHandler();
TX_DECL_TXAXMLEVENTHANDLER
protected:
nsRefPtr<txResultBuffer> mBuffer;
PRPackedBool mCanAddAttribute;
};
#endif /* txBufferingHandler_h__ */

View File

@ -235,8 +235,15 @@ void txHTMLOutput::attribute(const nsAString& aName,
txXMLOutput::attribute(aName, aNsID, aValue);
}
void txHTMLOutput::characters(const nsAString& aData)
void txHTMLOutput::characters(const nsAString& aData, PRBool aDOE)
{
if (aDOE) {
closeStartTag(MB_FALSE);
printUTF8Chars(aData);
return;
}
// Special-case script and style
txExpandedName* currentElement = (txExpandedName*)mCurrentElements.peek();
if (currentElement &&
@ -247,7 +254,7 @@ void txHTMLOutput::characters(const nsAString& aData)
printUTF8Chars(aData);
}
else {
txXMLOutput::characters(aData);
txXMLOutput::characters(aData, aDOE);
}
}

View File

@ -40,7 +40,6 @@
#define TRANSFRMX_HTML_OUTPUT_H
#include "txXMLOutput.h"
#include "txStack.h"
class txHTMLOutput : public txXMLOutput
{
@ -54,55 +53,15 @@ public:
static nsresult init();
static void shutdown();
/*
* Signals to receive the start of an attribute.
*
* @param aName the name of the attribute
* @param aNsID the namespace ID of the attribute
* @param aValue the value of the attribute
*/
void attribute(const nsAString& aName,
const PRInt32 aNsID,
void attribute(const nsAString& aName, const PRInt32 aNsID,
const nsAString& aValue);
/*
* Signals to receive characters.
*
* @param aData the characters to receive
*/
void characters(const nsAString& aData);
/*
* Signals to receive the end of an element.
*
* @param aName the name of the element
* @param aNsID the namespace ID of the element
*/
void endElement(const nsAString& aName,
const PRInt32 aNsID);
/*
* Signals to receive a processing instruction.
*
* @param aTarget the target of the processing instruction
* @param aData the data of the processing instruction
*/
void characters(const nsAString& aData, PRBool aDOE);
void endElement(const nsAString& aName, const PRInt32 aNsID);
void processingInstruction(const nsAString& aTarget,
const nsAString& aData);
/*
* Signals the start of a document.
*/
void startDocument();
/*
* Signals to receive the start of an element.
*
* @param aName the name of the element
* @param aNsID the namespace ID of the element
*/
void startElement(const nsAString& aName,
const PRInt32 aNsID);
void startElement(const nsAString& aName, const PRInt32 aNsID);
TX_DECL_TXAOUTPUTXMLEVENTHANDLER
private:
void closeStartTag(MBool aUseEmptyElementShorthand);

View File

@ -82,15 +82,13 @@ txMozillaTextOutput::~txMozillaTextOutput()
{
}
NS_IMPL_ISUPPORTS1(txMozillaTextOutput, txIOutputXMLEventHandler);
void txMozillaTextOutput::attribute(const nsAString& aName,
const PRInt32 aNsID,
const nsAString& aValue)
{
}
void txMozillaTextOutput::characters(const nsAString& aData)
void txMozillaTextOutput::characters(const nsAString& aData, PRBool aDOE)
{
if (mTextNode)
mTextNode->AppendData(aData);

View File

@ -50,7 +50,7 @@
class nsITransformObserver;
class txMozillaTextOutput : public txIOutputXMLEventHandler
class txMozillaTextOutput : public txAOutputXMLEventHandler
{
public:
txMozillaTextOutput(nsIDOMDocument* aSourceDocument,
@ -59,99 +59,8 @@ public:
txMozillaTextOutput(nsIDOMDocumentFragment* aDest);
virtual ~txMozillaTextOutput();
NS_DECL_ISUPPORTS
/**
* Signals to receive the start of an attribute.
*
* @param aName the name of the attribute
* @param aNsID the namespace ID of the attribute
* @param aValue the value of the attribute
*/
void attribute(const nsAString& aName,
const PRInt32 aNsID,
const nsAString& aValue);
/**
* Signals to receive characters.
*
* @param aData the characters to receive
*/
void characters(const nsAString& aData);
/**
* Signals to receive characters that don't need output escaping.
*
* @param aData the characters to receive
*/
void charactersNoOutputEscaping(const nsAString& aData)
{
NS_ASSERTION(0, "Don't call this in module, we don't do d-o-e");
}
/**
* Signals to receive data that should be treated as a comment.
*
* @param data the comment data to receive
*/
void comment(const nsAString& aData);
/**
* Signals the end of a document. It is an error to call
* this method more than once.
*/
void endDocument();
/**
* Signals to receive the end of an element.
*
* @param aName the name of the element
* @param aNsID the namespace ID of the element
*/
void endElement(const nsAString& aName,
const PRInt32 aNsID);
/**
* Returns whether the output handler supports
* disable-output-escaping.
*
* @return MB_TRUE if this handler supports
* disable-output-escaping
*/
MBool hasDisableOutputEscaping()
{
return MB_FALSE;
}
/**
* Signals to receive a processing instruction.
*
* @param aTarget the target of the processing instruction
* @param aData the data of the processing instruction
*/
void processingInstruction(const nsAString& aTarget,
const nsAString& aData);
/**
* Signals the start of a document.
*/
void startDocument();
/**
* Signals to receive the start of an element.
*
* @param aName the name of the element
* @param aNsID the namespace ID of the element
*/
void startElement(const nsAString& aName,
const PRInt32 aNsID);
/**
* Gets the Mozilla output document
*
* @param aDocument the Mozilla output document
*/
void getOutputDocument(nsIDOMDocument** aDocument);
TX_DECL_TXAXMLEVENTHANDLER
TX_DECL_TXAOUTPUTXMLEVENTHANDLER
private:
void createResultDocument(nsIDOMDocument* aSourceDocument,

View File

@ -52,9 +52,23 @@
#include "nsICSSLoaderObserver.h"
#include "nsIDocumentTransformer.h"
class txMozillaXMLOutput : public txIOutputXMLEventHandler,
public nsIScriptLoaderObserver,
public nsICSSLoaderObserver
#define TX_ITRANSFORMNOTIFIER_IID \
{ 0x6c94c701, 0x330d, 0x11d7, \
{ 0xa7, 0xf2, 0x9a, 0x44, 0x5a, 0xec, 0x64, 0x3c } };
class txITransformNotifier : public nsISupports
{
public:
NS_DEFINE_STATIC_IID_ACCESSOR(TX_ITRANSFORMNOTIFIER_IID)
NS_IMETHOD_(void) AddScriptElement(nsIDOMHTMLScriptElement* aElement) = 0;
NS_IMETHOD_(void) AddStyleSheet(nsIStyleSheet* aStyleSheet) = 0;
NS_IMETHOD_(void) OnTransformEnd() = 0;
NS_IMETHOD_(void) OnTransformStart() = 0;
NS_IMETHOD_(void) SetOutputDocument(nsIDOMDocument* aDocument) = 0;
};
class txMozillaXMLOutput : public txAOutputXMLEventHandler
{
public:
txMozillaXMLOutput(const nsAString& aRootName,
@ -67,103 +81,8 @@ public:
nsIDOMDocumentFragment* aFragment);
virtual ~txMozillaXMLOutput();
NS_DECL_ISUPPORTS
NS_DECL_NSISCRIPTLOADEROBSERVER
// nsICSSLoaderObserver
NS_IMETHOD StyleSheetLoaded(nsICSSStyleSheet* aSheet, PRBool aNotify);
/**
* Signals to receive the start of an attribute.
*
* @param aName the name of the attribute
* @param aNsID the namespace ID of the attribute
* @param aValue the value of the attribute
*/
void attribute(const nsAString& aName,
const PRInt32 aNsID,
const nsAString& aValue);
/**
* Signals to receive characters.
*
* @param aData the characters to receive
*/
void characters(const nsAString& aData);
/**
* Signals to receive characters that don't need output escaping.
*
* @param aData the characters to receive
*/
void charactersNoOutputEscaping(const nsAString& aData)
{
NS_ASSERTION(0, "Don't call this in module, we don't do d-o-e");
}
/**
* Signals to receive data that should be treated as a comment.
*
* @param data the comment data to receive
*/
void comment(const nsAString& aData);
/**
* Signals the end of a document. It is an error to call
* this method more than once.
*/
void endDocument();
/**
* Signals to receive the end of an element.
*
* @param aName the name of the element
* @param aNsID the namespace ID of the element
*/
void endElement(const nsAString& aName,
const PRInt32 aNsID);
/**
* Returns whether the output handler supports
* disable-output-escaping.
*
* @return MB_TRUE if this handler supports
* disable-output-escaping
*/
MBool hasDisableOutputEscaping()
{
return MB_FALSE;
}
/**
* Signals to receive a processing instruction.
*
* @param aTarget the target of the processing instruction
* @param aData the data of the processing instruction
*/
void processingInstruction(const nsAString& aTarget,
const nsAString& aData);
/**
* Signals the start of a document.
*/
void startDocument();
/**
* Signals to receive the start of an element.
*
* @param aName the name of the element
* @param aNsID the namespace ID of the element
*/
void startElement(const nsAString& aName,
const PRInt32 aNsID);
/**
* Gets the Mozilla output document
*
* @param aDocument the Mozilla output document
*/
void getOutputDocument(nsIDOMDocument** aDocument);
TX_DECL_TXAXMLEVENTHANDLER
TX_DECL_TXAOUTPUTXMLEVENTHANDLER
private:
void closePrevious(PRInt8 aAction);
@ -174,23 +93,20 @@ private:
nsresult createResultDocument(const nsAString& aName, PRInt32 aNsID,
nsIDOMDocument* aSourceDocument,
nsIDOMDocument* aResultDocument);
void SignalTransformEnd();
nsCOMPtr<nsIDOMDocument> mDocument;
nsCOMPtr<nsIDOMNode> mCurrentNode;
nsCOMPtr<nsIDOMNode> mParentNode;
nsCOMPtr<nsIContent> mRootContent;
nsCOMPtr<nsITransformObserver> mObserver;
nsCOMPtr<nsIDOMNode> mNonAddedParent;
nsCOMPtr<nsIDOMNode> mNonAddedNode;
nsCOMPtr<txITransformNotifier> mNotifier;
PRUint32 mBadChildLevel;
nsCString mRefreshString;
nsCOMArray<nsIDOMHTMLScriptElement> mScriptElements;
nsCOMArray<nsIStyleSheet> mStylesheets;
nsAutoString mText;
txOutputFormat mOutputFormat;
@ -200,11 +116,39 @@ private:
PRPackedBool mHaveTitleElement;
PRPackedBool mHaveBaseElement;
PRPackedBool mInTransform;
PRPackedBool mCreatingNewDocument;
PRPackedBool mDocumentIsHTML;
enum txAction { eCloseElement = 1, eFlushText = 2 };
};
class txTransformNotifier : public txITransformNotifier,
public nsIScriptLoaderObserver,
public nsICSSLoaderObserver
{
public:
txTransformNotifier(nsITransformObserver* aObserver);
virtual ~txTransformNotifier();
NS_DECL_ISUPPORTS
NS_DECL_NSISCRIPTLOADEROBSERVER
// nsICSSLoaderObserver
NS_IMETHOD StyleSheetLoaded(nsICSSStyleSheet* aSheet, PRBool aNotify);
NS_IMETHOD_(void) AddScriptElement(nsIDOMHTMLScriptElement* aElement);
NS_IMETHOD_(void) AddStyleSheet(nsIStyleSheet* aStyleSheet);
NS_IMETHOD_(void) OnTransformEnd();
NS_IMETHOD_(void) OnTransformStart();
NS_IMETHOD_(void) SetOutputDocument(nsIDOMDocument* aDocument);
private:
void SignalTransformEnd();
nsCOMPtr<nsIDOMDocument> mDocument;
nsCOMPtr<nsITransformObserver> mObserver;
nsCOMArray<nsIDOMHTMLScriptElement> mScriptElements;
nsCOMArray<nsIStyleSheet> mStylesheets;
PRPackedBool mInTransform;
};
#endif

View File

@ -57,7 +57,7 @@
/**
* Output Handler Factories
*/
class txToDocHandlerFactory : public txIOutputHandlerFactory
class txToDocHandlerFactory : public txAOutputHandlerFactory
{
public:
txToDocHandlerFactory(ProcessorState* aPs,
@ -73,7 +73,7 @@ public:
{
}
TX_DECL_TXIOUTPUTHANDLERFACTORY;
TX_DECL_TXAOUTPUTHANDLERFACTORY
private:
ProcessorState* mPs;
@ -82,7 +82,7 @@ private:
nsCOMPtr<nsITransformObserver> mObserver;
};
class txToFragmentHandlerFactory : public txIOutputHandlerFactory
class txToFragmentHandlerFactory : public txAOutputHandlerFactory
{
public:
txToFragmentHandlerFactory(nsIDOMDocumentFragment* aFragment)
@ -94,7 +94,7 @@ public:
{
}
TX_DECL_TXIOUTPUTHANDLERFACTORY;
TX_DECL_TXAOUTPUTHANDLERFACTORY
private:
nsCOMPtr<nsIDOMDocumentFragment> mFragment;
@ -102,7 +102,7 @@ private:
nsresult
txToDocHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
txIOutputXMLEventHandler** aHandler)
txAXMLEventHandler** aHandler)
{
*aHandler = nsnull;
switch (aFormat->mMethod) {
@ -138,7 +138,7 @@ nsresult
txToDocHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
const nsAString& aName,
PRInt32 aNsID,
txIOutputXMLEventHandler** aHandler)
txAXMLEventHandler** aHandler)
{
*aHandler = nsnull;
switch (aFormat->mMethod) {
@ -172,7 +172,7 @@ txToDocHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
nsresult
txToFragmentHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
txIOutputXMLEventHandler** aHandler)
txAXMLEventHandler** aHandler)
{
*aHandler = nsnull;
switch (aFormat->mMethod) {
@ -212,7 +212,7 @@ nsresult
txToFragmentHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
const nsAString& aName,
PRInt32 aNsID,
txIOutputXMLEventHandler** aHandler)
txAXMLEventHandler** aHandler)
{
*aHandler = nsnull;
NS_ASSERTION(aFormat->mMethod != eMethodNotSet,
@ -380,7 +380,9 @@ txMozillaXSLTProcessor::TransformDocument(nsIDOMNode* aSourceDOM,
// Process root of XML source document
txXSLTProcessor::transform(&ps);
ps.mOutputHandler->getOutputDocument(aOutputDoc);
txAOutputXMLEventHandler* handler =
NS_STATIC_CAST(txAOutputXMLEventHandler*, ps.mOutputHandler);
handler->getOutputDocument(aOutputDoc);
return NS_OK;
}
@ -476,7 +478,9 @@ txMozillaXSLTProcessor::TransformToDocument(nsIDOMNode *aSource,
// Process root of XML source document
txXSLTProcessor::transform(&ps);
ps.mOutputHandler->getOutputDocument(aResult);
txAOutputXMLEventHandler* handler =
NS_STATIC_CAST(txAOutputXMLEventHandler*, ps.mOutputHandler);
handler->getOutputDocument(aResult);
return NS_OK;
}

View File

@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonas Sicking <jonas@sicking.cc>
* Peter Van der Beken <peterv@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
@ -37,111 +38,77 @@
* ***** END LICENSE BLOCK ***** */
#include "txRtfHandler.h"
#include "dom.h"
txRtfHandler::txRtfHandler(Document* aDocument,
txResultTreeFragment* aResultTreeFragment) :
mDocument(aDocument),
mResultTreeFragment(aResultTreeFragment)
txResultTreeFragment::txResultTreeFragment(txResultBuffer* aBuffer)
: mBuffer(aBuffer)
{
NS_ASSERTION(mDocument, "We need a valid document");
if (!mDocument)
return;
NS_IF_ADDREF(mBuffer);
}
NS_ASSERTION(mResultTreeFragment, "We need a valid result tree fragment");
if (!mResultTreeFragment)
return;
txResultTreeFragment::~txResultTreeFragment()
{
}
Node* fragment = mDocument->createDocumentFragment();
NS_ASSERTION(fragment, "Out of memory creating a document fragmen");
// XXX ErrorReport: Out of memory
mResultTreeFragment->append(fragment);
mCurrentNode = fragment;
ExprResult* txResultTreeFragment::clone()
{
return new txResultTreeFragment(mBuffer);
}
short txResultTreeFragment::getResultType()
{
return RESULT_TREE_FRAGMENT;
}
void txResultTreeFragment::stringValue(nsAString& aResult)
{
if (!mBuffer) {
return;
}
aResult.Append(mBuffer->mStringValue);
}
MBool txResultTreeFragment::booleanValue()
{
if (!mBuffer) {
return MB_FALSE;
}
return (mBuffer->getLastTransaction() != nsnull);
}
double txResultTreeFragment::numberValue()
{
return Double::toDouble(mBuffer->mStringValue);
}
nsresult txResultTreeFragment::flushToHandler(txAXMLEventHandler* aHandler)
{
if (!mBuffer) {
return NS_ERROR_FAILURE;
}
return mBuffer->flushToHandler(aHandler);
}
txRtfHandler::txRtfHandler()
{
}
txRtfHandler::~txRtfHandler()
{
}
void txRtfHandler::attribute(const nsAString& aName,
const PRInt32 aNsID,
const nsAString& aValue)
txResultTreeFragment* txRtfHandler::getRTF()
{
Element* element = (Element*)mCurrentNode;
NS_ASSERTION(element, "We need an element");
if (!element)
// XXX ErrorReport: Can't add attributes without element
return;
if (element->hasChildNodes())
// XXX ErrorReport: Can't add attributes after adding children
return;
nsAutoString nsURI;
mDocument->namespaceIDToURI(aNsID, nsURI);
element->setAttributeNS(nsURI, aName, aValue);
}
void txRtfHandler::characters(const nsAString& aData)
{
NS_ASSERTION(mCurrentNode, "We need a node");
if (!mCurrentNode)
return;
Node* text = mDocument->createTextNode(aData);
mCurrentNode->appendChild(text);
}
void txRtfHandler::comment(const nsAString& aData)
{
NS_ASSERTION(mCurrentNode, "We need a node");
if (!mCurrentNode)
return;
Node* comment = mDocument->createComment(aData);
mCurrentNode->appendChild(comment);
mRTF = new txResultTreeFragment(mBuffer);
return mRTF;
}
void txRtfHandler::endDocument()
{
}
void txRtfHandler::endElement(const nsAString& aName,
const PRInt32 aNsID)
{
NS_ASSERTION(mCurrentNode, "We need a node");
if (!mCurrentNode)
return;
mCurrentNode = mCurrentNode->getParentNode();
}
void txRtfHandler::processingInstruction(const nsAString& aTarget,
const nsAString& aData)
{
NS_ASSERTION(mCurrentNode, "We need a node");
if (!mCurrentNode)
return;
ProcessingInstruction* pi;
pi = mDocument->createProcessingInstruction(aTarget, aData);
mCurrentNode->appendChild(pi);
}
void txRtfHandler::startDocument()
{
}
void txRtfHandler::startElement(const nsAString& aName,
const PRInt32 aNsID)
{
NS_ASSERTION(mCurrentNode, "We need a node");
if (!mCurrentNode)
return;
nsAutoString nsURI;
mDocument->namespaceIDToURI(aNsID, nsURI);
Element* element = mDocument->createElementNS(nsURI, aName);
mCurrentNode->appendChild(element);
mCurrentNode = element;
}

View File

@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jonas Sicking <jonas@sicking.cc>
* Peter Van der Beken <peterv@netscape.com>
*
* Alternatively, the contents of this file may be used under the terms of
@ -36,89 +37,43 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef TRANSFRMX_RTF_HANDLER_H
#define TRANSFRMX_RTF_HANDLER_H
#ifndef txRtfHandler_h___
#define txRtfHandler_h___
#include "txXMLEventHandler.h"
#include "NodeSet.h"
#include "txBufferingHandler.h"
#include "ExprResult.h"
class Document;
class Node;
class txRtfHandler : public txXMLEventHandler
class txResultTreeFragment : public ExprResult
{
public:
txRtfHandler(Document* aDocument,
txResultTreeFragment* aResultTreeFragment);
virtual ~txRtfHandler();
txResultTreeFragment(txResultBuffer* aBuffer);
~txResultTreeFragment();
/**
* Signals to receive the start of an attribute.
*
* @param aName the name of the attribute
* @param aNsID the namespace ID of the attribute
* @param aValue the value of the attribute
*/
void attribute(const nsAString& aName,
const PRInt32 aNsID,
const nsAString& aValue);
virtual ExprResult* clone();
virtual short getResultType();
virtual void stringValue(nsAString& aResult);
virtual MBool booleanValue();
virtual double numberValue();
/**
* Signals to receive characters.
*
* @param aData the characters to receive
*/
void characters(const nsAString& aData);
/**
* Signals to receive data that should be treated as a comment.
*
* @param data the comment data to receive
*/
void comment(const nsAString& aData);
/**
* Signals the end of a document. It is an error to call
* this method more than once.
*/
void endDocument();
/**
* Signals to receive the end of an element.
*
* @param aName the name of the element
* @param aNsID the namespace ID of the element
*/
void endElement(const nsAString& aName,
const PRInt32 aNsID);
/**
* Signals to receive a processing instruction.
*
* @param aTarget the target of the processing instruction
* @param aData the data of the processing instruction
*/
void processingInstruction(const nsAString& aTarget,
const nsAString& aData);
/**
* Signals the start of a document.
*/
void startDocument();
/**
* Signals to receive the start of an element.
*
* @param aName the name of the element
* @param aNsID the namespace ID of the element
*/
void startElement(const nsAString& aName,
const PRInt32 aNsID);
nsresult flushToHandler(txAXMLEventHandler* aHandler);
private:
Document* mDocument;
txResultTreeFragment* mResultTreeFragment;
Node* mCurrentNode;
txResultBuffer* mBuffer;
};
#endif
class txRtfHandler : public txBufferingHandler
{
public:
txRtfHandler();
virtual ~txRtfHandler();
txResultTreeFragment* getRTF();
void endDocument();
void startDocument();
private:
txResultTreeFragment* mRTF;
};
#endif /* txRtfHandler_h___ */

View File

@ -51,7 +51,7 @@
/**
* Output Handler Factory
*/
class txStandaloneHandlerFactory : public txIOutputHandlerFactory
class txStandaloneHandlerFactory : public txAOutputHandlerFactory
{
public:
txStandaloneHandlerFactory(ProcessorState* aPs,
@ -64,7 +64,7 @@ public:
{
};
TX_DECL_TXIOUTPUTHANDLERFACTORY;
TX_DECL_TXAOUTPUTHANDLERFACTORY;
private:
ProcessorState* mPs;
@ -73,7 +73,7 @@ private:
nsresult
txStandaloneHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
txIOutputXMLEventHandler** aHandler)
txAOutputXMLEventHandler** aHandler)
{
*aHandler = 0;
switch (aFormat->mMethod) {
@ -101,7 +101,7 @@ nsresult
txStandaloneHandlerFactory::createHandlerWith(txOutputFormat* aFormat,
const nsAString& aName,
PRInt32 aNsID,
txIOutputXMLEventHandler** aHandler)
txAOutputXMLEventHandler** aHandler)
{
*aHandler = 0;
NS_ASSERTION(aFormat->mMethod != eMethodNotSet,

View File

@ -55,7 +55,7 @@ void txTextHandler::attribute(const nsAString& aName,
{
}
void txTextHandler::characters(const nsAString& aData)
void txTextHandler::characters(const nsAString& aData, PRBool aDOE)
{
if (mLevel == 0)
mValue.Append(aData);

View File

@ -41,74 +41,13 @@
#include "txXMLEventHandler.h"
class txTextHandler : public txXMLEventHandler
class txTextHandler : public txAXMLEventHandler
{
public:
txTextHandler(nsAString& aValue, MBool aOnlyText);
virtual ~txTextHandler();
/**
* Signals to receive the start of an attribute.
*
* @param aName the name of the attribute
* @param aNsID the namespace ID of the attribute
* @param aValue the value of the attribute
*/
void attribute(const nsAString& aName,
const PRInt32 aNsID,
const nsAString& aValue);
/**
* Signals to receive characters.
*
* @param aData the characters to receive
*/
void characters(const nsAString& aData);
/**
* Signals to receive data that should be treated as a comment.
*
* @param data the comment data to receive
*/
void comment(const nsAString& aData);
/**
* Signals the end of a document. It is an error to call
* this method more than once.
*/
void endDocument();
/**
* Signals to receive the end of an element.
*
* @param aName the name of the element
* @param aNsID the namespace ID of the element
*/
void endElement(const nsAString& aName,
const PRInt32 aNsID);
/**
* Signals to receive a processing instruction.
*
* @param aTarget the target of the processing instruction
* @param aData the data of the processing instruction
*/
void processingInstruction(const nsAString& aTarget,
const nsAString& aData);
/**
* Signals the start of a document.
*/
void startDocument();
/**
* Signals to receive the start of an element.
*
* @param aName the name of the element
* @param aNsID the namespace ID of the element
*/
void startElement(const nsAString& aName,
const PRInt32 aNsID);
TX_DECL_TXAXMLEVENTHANDLER
private:
PRUint32 mLevel;

View File

@ -37,6 +37,7 @@
* ***** END LICENSE BLOCK ***** */
#include "txTextOutput.h"
#include "nsString.h"
txTextOutput::txTextOutput(ostream* aOut)
: mOut(aOut)
@ -53,16 +54,11 @@ void txTextOutput::attribute(const nsAString& aName,
{
}
void txTextOutput::characters(const nsAString& aData)
void txTextOutput::characters(const nsAString& aData, PRBool aDOE)
{
*mOut << NS_ConvertUCS2toUTF8(aData).get();
}
void txTextOutput::charactersNoOutputEscaping(const nsAString& aData)
{
characters(aData);
}
void txTextOutput::comment(const nsAString& aData)
{
}

View File

@ -40,95 +40,15 @@
#define TRANSFRMX_TEXT_OUTPUT_H
#include "txXMLEventHandler.h"
#include "txOutputFormat.h"
class txTextOutput : public txIOutputXMLEventHandler
class txTextOutput : public txAOutputXMLEventHandler
{
public:
txTextOutput(ostream* aOut);
~txTextOutput();
/*
* Signals to receive the start of an attribute.
*
* @param aName the name of the attribute
* @param aNsID the namespace ID of the attribute
* @param aValue the value of the attribute
*/
void attribute(const nsAString& aName,
const PRInt32 aNsID,
const nsAString& aValue);
/*
* Signals to receive characters.
*
* @param aData the characters to receive
*/
void characters(const nsAString& aData);
/*
* Signals to receive characters that don't need output escaping.
*
* @param aData the characters to receive
*/
virtual void charactersNoOutputEscaping(const nsAString& aData);
/*
* Signals to receive data that should be treated as a comment.
*
* @param data the comment data to receive
*/
void comment(const nsAString& aData);
/*
* Signals the end of a document. It is an error to call
* this method more than once.
*/
void endDocument();
/*
* Signals to receive the end of an element.
*
* @param aName the name of the element
* @param aNsID the namespace ID of the element
*/
void endElement(const nsAString& aName,
const PRInt32 aNsID);
/**
* Returns whether the output handler supports
* disable-output-escaping.
*
* @return MB_TRUE if this handler supports
* disable-output-escaping
*/
MBool hasDisableOutputEscaping()
{
return MB_TRUE;
}
/*
* Signals to receive a processing instruction.
*
* @param aTarget the target of the processing instruction
* @param aData the data of the processing instruction
*/
void processingInstruction(const nsAString& aTarget,
const nsAString& aData);
/*
* Signals the start of a document.
*/
void startDocument();
/*
* Signals to receive the start of an element.
*
* @param aName the name of the element
* @param aNsID the namespace ID of the element
*/
void startElement(const nsAString& aName,
const PRInt32 aNsID);
TX_DECL_TXAXMLEVENTHANDLER
TX_DECL_TXAOUTPUTXMLEVENTHANDLER
private:
ostream* mOut;

View File

@ -40,26 +40,13 @@
#include "ProcessorState.h"
#include "txStringUtils.h"
#ifndef TX_EXE
NS_IMPL_ISUPPORTS1(txUnknownHandler, txIOutputXMLEventHandler);
#endif
PRUint32 txUnknownHandler::kReasonableTransactions = 8;
txUnknownHandler::txUnknownHandler(ProcessorState* aPs)
: mTotal(0), mMax(kReasonableTransactions),
mPs(aPs)
: mPs(aPs)
{
mArray = new txOutputTransaction*[kReasonableTransactions];
}
txUnknownHandler::~txUnknownHandler()
{
PRUint32 counter;
for (counter = 0; counter < mTotal; ++counter) {
delete mArray[counter];
}
delete [] mArray;
}
void txUnknownHandler::attribute(const nsAString& aName,
@ -71,53 +58,12 @@ void txUnknownHandler::attribute(const nsAString& aName,
// XXX ErrorReport: Signal this?
}
void txUnknownHandler::characters(const nsAString& aData)
{
txOneStringTransaction* transaction =
new txOneStringTransaction(txOutputTransaction::eCharacterTransaction,
aData);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!");
return;
}
addTransaction(transaction);
}
void txUnknownHandler::charactersNoOutputEscaping(const nsAString& aData)
{
txOneStringTransaction* transaction =
new txOneStringTransaction(txOutputTransaction::eCharacterNoOETransaction,
aData);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!");
return;
}
addTransaction(transaction);
}
void txUnknownHandler::comment(const nsAString& aData)
{
txOneStringTransaction* transaction =
new txOneStringTransaction(txOutputTransaction::eCommentTransaction,
aData);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!");
return;
}
addTransaction(transaction);
}
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.
#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, nsString(),
kNameSpaceID_None);
if (NS_FAILED(rv))
@ -125,58 +71,26 @@ void txUnknownHandler::endDocument()
mPs->mResultHandler->endDocument();
// in module the outputhandler is refcounted
#ifdef TX_EXE
delete this;
#endif
}
void txUnknownHandler::endElement(const nsAString& aName,
const PRInt32 aNsID)
const PRInt32 aNsID)
{
NS_ASSERTION(0, "This shouldn't be called");
}
void txUnknownHandler::processingInstruction(const nsAString& aTarget,
const nsAString& aData)
{
txTwoStringTransaction* transaction =
new txTwoStringTransaction(txOutputTransaction::ePITransaction,
aTarget, aData);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!");
return;
}
addTransaction(transaction);
}
void txUnknownHandler::startDocument()
{
txOutputTransaction* transaction =
new txOutputTransaction(txOutputTransaction::eStartDocumentTransaction);
if (!transaction) {
NS_ASSERTION(0, "Out of memory!");
return;
}
addTransaction(transaction);
NS_ASSERTION(0, "This shouldn't be called.");
}
void txUnknownHandler::startElement(const nsAString& aName,
const PRInt32 aNsID)
{
#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 = NS_OK;
txOutputFormat* format = mPs->getOutputFormat();
if (format->mMethod != eMethodNotSet) {
rv = createHandlerAndFlush(format->mMethod, aName, aNsID);
}
else if (aNsID == kNameSpaceID_None &&
aName.Equals(NS_LITERAL_STRING("html"), txCaseInsensitiveStringComparator())) {
aName.Equals(NS_LITERAL_STRING("html"),
txCaseInsensitiveStringComparator())) {
rv = createHandlerAndFlush(eHTMLOutput, aName, aNsID);
}
else {
@ -187,10 +101,7 @@ void txUnknownHandler::startElement(const nsAString& aName,
mPs->mResultHandler->startElement(aName, aNsID);
// in module the outputhandler is refcounted
#ifdef TX_EXE
delete this;
#endif
}
#ifndef TX_EXE
@ -204,83 +115,19 @@ nsresult txUnknownHandler::createHandlerAndFlush(txOutputMethod aMethod,
const nsAString& aName,
const PRInt32 aNsID)
{
nsresult rv = NS_OK;
NS_ENSURE_TRUE(mBuffer, NS_ERROR_NOT_INITIALIZED);
txOutputFormat* format = mPs->getOutputFormat();
format->mMethod = aMethod;
txIOutputXMLEventHandler* handler = 0;
rv = mPs->mOutputHandlerFactory->createHandlerWith(format, aName, aNsID,
&handler);
txAXMLEventHandler* handler = 0;
nsresult 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];
handler->characters(transaction->mString);
delete transaction;
break;
}
case txOutputTransaction::eCharacterNoOETransaction:
{
txOneStringTransaction* transaction = (txOneStringTransaction*)mArray[counter];
if (hasDOE) {
handler->charactersNoOutputEscaping(transaction->mString);
}
else {
handler->characters(transaction->mString);
}
delete transaction;
break;
}
case txOutputTransaction::eCommentTransaction:
{
txOneStringTransaction* transaction = (txOneStringTransaction*)mArray[counter];
handler->comment(transaction->mString);
delete transaction;
break;
}
case txOutputTransaction::ePITransaction:
{
txTwoStringTransaction* transaction = (txTwoStringTransaction*)mArray[counter];
handler->processingInstruction(transaction->mStringOne,
transaction->mStringTwo);
delete transaction;
break;
}
case txOutputTransaction::eStartDocumentTransaction:
{
handler->startDocument();
delete mArray[counter];
break;
}
}
}
mTotal = 0;
return NS_OK;
}
void txUnknownHandler::addTransaction(txOutputTransaction* aTransaction)
{
if (mTotal == mMax) {
PRUint32 newMax = mMax * 2;
txOutputTransaction** newArray = new txOutputTransaction*[newMax];
if (!newArray) {
NS_ASSERTION(0, "Out of memory!");
return;
}
mMax = newMax;
memcpy(newArray, mArray, mTotal * sizeof(txOutputTransaction*));
delete [] mArray;
mArray = newArray;
}
mArray[mTotal++] = aTransaction;
return mBuffer->flushToHandler(handler);
}

View File

@ -36,178 +36,39 @@
*
* ***** END LICENSE BLOCK ***** */
#ifndef TRANSFRMX_UNKNOWN_HANDLER_H
#define TRANSFRMX_UNKNOWN_HANDLER_H
#ifndef txUnknownHandler_h___
#define txUnknownHandler_h___
#include "txXMLEventHandler.h"
#include "txBufferingHandler.h"
#include "txOutputFormat.h"
class ProcessorState;
class txOutputTransaction
{
public:
enum txTransactionType {
eCharacterTransaction,
eCharacterNoOETransaction,
eCommentTransaction,
ePITransaction,
eStartDocumentTransaction
};
txOutputTransaction(txTransactionType aType)
: mType(aType)
{
};
virtual ~txOutputTransaction()
{
};
txTransactionType mType;
};
class txOneStringTransaction : public txOutputTransaction
{
public:
txOneStringTransaction(txTransactionType aType,
const nsAString& aString)
: txOutputTransaction(aType),
mString(aString)
{
};
nsString mString;
};
class txTwoStringTransaction : public txOutputTransaction
{
public:
txTwoStringTransaction(txTransactionType aType,
const nsAString& aStringOne,
const nsAString& aStringTwo)
: txOutputTransaction(aType),
mStringOne(aStringOne),
mStringTwo(aStringTwo)
{
};
nsString mStringOne;
nsString mStringTwo;
};
class txUnknownHandler : public txIOutputXMLEventHandler
class txUnknownHandler : public txBufferingHandler
{
public:
txUnknownHandler(ProcessorState* aPs);
virtual ~txUnknownHandler();
#ifndef TX_EXE
NS_DECL_ISUPPORTS
#endif
/*
* Signals to receive the start of an attribute.
*
* @param aName the name of the attribute
* @param aNsID the namespace ID of the attribute
* @param aValue the value of the attribute
*/
void attribute(const nsAString& aName,
const PRInt32 aNsID,
void attribute(const nsAString& aName, const PRInt32 aNsID,
const nsAString& aValue);
/*
* Signals to receive characters.
*
* @param aData the characters to receive
*/
void characters(const nsAString& aData);
/*
* Signals to receive characters that don't need output escaping.
*
* @param aData the characters to receive
*/
void charactersNoOutputEscaping(const nsAString& aData);
/*
* Signals to receive data that should be treated as a comment.
*
* @param data the comment data to receive
*/
void comment(const nsAString& aData);
/*
* Signals the end of a document. It is an error to call
* this method more than once.
*/
void endDocument();
void endElement(const nsAString& aName, const PRInt32 aNsID);
void startElement(const nsAString& aName, const PRInt32 aNsID);
/*
* Signals to receive the end of an element.
*
* @param aName the name of the element
* @param aNsID the namespace ID of the element
*/
void endElement(const nsAString& aName,
const PRInt32 aNsID);
/**
* Returns whether the output handler supports
* disable-output-escaping.
*
* @return MB_TRUE if this handler supports
* disable-output-escaping
*/
MBool hasDisableOutputEscaping()
{
return MB_TRUE;
}
/*
* Signals to receive a processing instruction.
*
* @param aTarget the target of the processing instruction
* @param aData the data of the processing instruction
*/
void processingInstruction(const nsAString& aTarget,
const nsAString& aData);
/*
* Signals the start of a document.
*/
void startDocument();
/*
* Signals to receive the start of an element.
*
* @param aName the name of the element
* @param aNsID the namespace ID of the element
*/
void startElement(const nsAString& aName,
const PRInt32 aNsID);
#ifndef TX_EXE
/**
* Gets the Mozilla output document
*
* @param aDocument the Mozilla output document
*/
void getOutputDocument(nsIDOMDocument** aDocument);
#endif
TX_DECL_TXAOUTPUTXMLEVENTHANDLER
private:
nsresult createHandlerAndFlush(txOutputMethod aMethod,
const nsAString& aName,
const PRInt32 aNsID);
void addTransaction(txOutputTransaction* aTransaction);
PRUint32 mTotal, mMax;
/*
* 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* mPs;
txOutputTransaction** mArray;
static PRUint32 kReasonableTransactions;
};
#endif
#endif /* txUnknownHandler_h___ */

View File

@ -33,7 +33,6 @@ class txOutputFormat;
#ifdef TX_EXE
#include <iostream.h>
#else
#include "nsISupports.h"
#define kTXNameSpaceURI "http://www.mozilla.org/TransforMiix"
#define kTXWrapper "transformiix:result"
@ -48,10 +47,10 @@ class nsITransformObserver;
* after Dave Megginson's SAX 1.0 API.
*/
class txXMLEventHandler
class txAXMLEventHandler
{
public:
virtual ~txXMLEventHandler() {};
virtual ~txAXMLEventHandler() {};
/**
* Signals to receive the start of an attribute.
@ -68,8 +67,9 @@ public:
* Signals to receive characters.
*
* @param aData the characters to receive
* @param aDOE disable output escaping for these characters
*/
virtual void characters(const nsAString& aData) = 0;
virtual void characters(const nsAString& aData, PRBool aDOE) = 0;
/**
* Signals to receive data that should be treated as a comment.
@ -117,53 +117,45 @@ public:
const PRInt32 aNsID) = 0;
};
#ifdef TX_EXE
class txIOutputXMLEventHandler : public txXMLEventHandler
#else
#define TX_IOUTPUTXMLEVENTHANDLER_IID \
{ 0x80e5e802, 0x8c88, 0x11d6, \
{ 0xa7, 0xf2, 0xc5, 0xc3, 0x85, 0x6b, 0xbb, 0xbc }}
#define TX_DECL_TXAXMLEVENTHANDLER \
virtual void attribute(const nsAString& aName, const PRInt32 aNsID, \
const nsAString& aValue); \
virtual void characters(const nsAString& aData, PRBool aDOE); \
virtual void comment(const nsAString& aData); \
virtual void endDocument(); \
virtual void endElement(const nsAString& aName, const PRInt32 aNsID); \
virtual void processingInstruction(const nsAString& aTarget, \
const nsAString& aData); \
virtual void startDocument(); \
virtual void startElement(const nsAString& aName, const PRInt32 aNsID);
class txIOutputXMLEventHandler : public nsISupports,
public txXMLEventHandler
#endif
#ifdef TX_EXE
typedef txAXMLEventHandler txAOutputXMLEventHandler;
#define TX_DECL_TXAOUTPUTXMLEVENTHANDLER
#else
class txAOutputXMLEventHandler : public txAXMLEventHandler
{
public:
/**
* Signals to receive characters that don't need output escaping.
*
* @param aData the characters to receive
*/
virtual void charactersNoOutputEscaping(const nsAString& aData) = 0;
/**
* Returns whether the output handler supports
* disable-output-escaping.
*
* @return MB_TRUE if this handler supports
* disable-output-escaping
*/
virtual MBool hasDisableOutputEscaping() = 0;
#ifndef TX_EXE
NS_DEFINE_STATIC_IID_ACCESSOR(TX_IOUTPUTXMLEVENTHANDLER_IID)
/**
* Gets the Mozilla output document
*
* @param aDocument the Mozilla output document
*/
virtual void getOutputDocument(nsIDOMDocument** aDocument) = 0;
#endif
};
#define TX_DECL_TXAOUTPUTXMLEVENTHANDLER \
virtual void getOutputDocument(nsIDOMDocument** aDocument);
#endif
/**
* Interface used to create the appropriate outputhandler
*/
class txIOutputHandlerFactory
class txAOutputHandlerFactory
{
public:
virtual ~txIOutputHandlerFactory() {};
virtual ~txAOutputHandlerFactory() {};
/**
* Creates an outputhandler for the specified format.
@ -172,7 +164,7 @@ public:
*/
virtual nsresult
createHandlerWith(txOutputFormat* aFormat,
txIOutputXMLEventHandler** aHandler) = 0;
txAXMLEventHandler** aHandler) = 0;
/**
* Creates an outputhandler for the specified format, with the specified
@ -186,15 +178,15 @@ public:
createHandlerWith(txOutputFormat* aFormat,
const nsAString& aName,
PRInt32 aNsID,
txIOutputXMLEventHandler** aHandler) = 0;
txAXMLEventHandler** aHandler) = 0;
};
#define TX_DECL_TXIOUTPUTHANDLERFACTORY \
nsresult createHandlerWith(txOutputFormat* aFormat, \
txIOutputXMLEventHandler** aHandler); \
nsresult createHandlerWith(txOutputFormat* aFormat, \
const nsAString& aName, \
PRInt32 aNsID, \
txIOutputXMLEventHandler** aHandler) \
#define TX_DECL_TXAOUTPUTHANDLERFACTORY \
nsresult createHandlerWith(txOutputFormat* aFormat, \
txAXMLEventHandler** aHandler); \
nsresult createHandlerWith(txOutputFormat* aFormat, \
const nsAString& aName, \
PRInt32 aNsID, \
txAXMLEventHandler** aHandler);
#endif

View File

@ -91,10 +91,16 @@ void txXMLOutput::attribute(const nsAString& aName,
}
}
void txXMLOutput::characters(const nsAString& aData)
void txXMLOutput::characters(const nsAString& aData, PRBool aDOE)
{
closeStartTag(MB_FALSE);
if (aDOE) {
printUTF8Chars(aData);
return;
}
if (mInCDATASection) {
PRUint32 length = aData.Length();
@ -140,13 +146,6 @@ void txXMLOutput::characters(const nsAString& aData)
}
}
void txXMLOutput::charactersNoOutputEscaping(const nsAString& aData)
{
closeStartTag(MB_FALSE);
printUTF8Chars(aData);
}
void txXMLOutput::comment(const nsAString& aData)
{
closeStartTag(MB_FALSE);

View File

@ -40,7 +40,6 @@
#define TRANSFRMX_XML_OUTPUT_H
#include "txXMLEventHandler.h"
#include "dom.h"
#include "List.h"
#include "txStack.h"
#include "txOutputFormat.h"
@ -91,7 +90,7 @@ public:
MBool mShorthand;
};
class txXMLOutput : public txIOutputXMLEventHandler
class txXMLOutput : public txAOutputXMLEventHandler
{
public:
txXMLOutput(txOutputFormat* aFormat, ostream* aOut);
@ -99,87 +98,8 @@ public:
static const int DEFAULT_INDENT;
/*
* Signals to receive the start of an attribute.
*
* @param aName the name of the attribute
* @param aNsID the namespace ID of the attribute
* @param aValue the value of the attribute
*/
virtual void attribute(const nsAString& aName,
const PRInt32 aNsID,
const nsAString& aValue);
/*
* Signals to receive characters.
*
* @param aData the characters to receive
*/
virtual void characters(const nsAString& aData);
/*
* Signals to receive characters that don't need output escaping.
*
* @param aData the characters to receive
*/
virtual void charactersNoOutputEscaping(const nsAString& aData);
/*
* Signals to receive data that should be treated as a comment.
*
* @param data the comment data to receive
*/
void comment(const nsAString& aData);
/*
* Signals the end of a document. It is an error to call
* this method more than once.
*/
virtual void endDocument();
/*
* Signals to receive the end of an element.
*
* @param aName the name of the element
* @param aNsID the namespace ID of the element
*/
virtual void endElement(const nsAString& aName,
const PRInt32 aNsID);
/**
* Returns whether the output handler supports
* disable-output-escaping.
*
* @return MB_TRUE if this handler supports
* disable-output-escaping
*/
MBool hasDisableOutputEscaping()
{
return MB_TRUE;
}
/*
* Signals to receive a processing instruction.
*
* @param aTarget the target of the processing instruction
* @param aData the data of the processing instruction
*/
virtual void processingInstruction(const nsAString& aTarget,
const nsAString& aData);
/*
* Signals the start of a document.
*/
virtual void startDocument();
/*
* Signals to receive the start of an element.
*
* @param aName the name of the element
* @param aNsID the namespace ID of the element
*/
virtual void startElement(const nsAString& aName,
const PRInt32 aNsID);
TX_DECL_TXAXMLEVENTHANDLER
TX_DECL_TXAOUTPUTXMLEVENTHANDLER
protected:
virtual void closeStartTag(MBool aUseEmptyElementShorthand);