Fix for bug 96647 (Change the way output is constructed in Transformiix). r=sicking, Pike, sr=jst.

This commit is contained in:
peterv%netscape.com 2005-11-02 07:37:24 +00:00
parent dfdf39e082
commit 5398b85bc0
48 changed files with 3568 additions and 146 deletions

View File

@ -48,18 +48,14 @@ XML_ATOMS;
#define TX_ATOM(_name, _value) txAtom* txXSLTAtoms::_name = 0
#include "txXSLTAtomList.h"
#undef TX_ATOM
#ifndef TX_EXE
#define TX_ATOM(_name, _value) txAtom* txHTMLAtoms::_name = 0
#include "txHTMLAtomList.h"
#undef TX_ATOM
#endif
static PRUint32 gXMLRefCnt = 0;
static PRUint32 gXPathRefCnt = 0;
static PRUint32 gXSLTRefCnt = 0;
#ifndef TX_EXE
static PRUint32 gHTMLRefCnt = 0;
#endif
#ifdef TX_EXE
#define TX_ATOM(_name, _value) \
@ -99,7 +95,6 @@ MBool txXSLTAtoms::init()
return MB_TRUE;
}
#ifndef TX_EXE
MBool txHTMLAtoms::init()
{
if (0 == gHTMLRefCnt++) {
@ -108,7 +103,6 @@ MBool txHTMLAtoms::init()
}
return MB_TRUE;
}
#endif
#undef TX_ATOM
@ -142,7 +136,6 @@ void txXSLTAtoms::shutdown()
}
}
#ifndef TX_EXE
void txHTMLAtoms::shutdown()
{
NS_ASSERTION(gHTMLRefCnt != 0, "bad release atoms");
@ -151,6 +144,5 @@ void txHTMLAtoms::shutdown()
#include "txHTMLAtomList.h"
}
}
#endif
#undef TX_ATOM

View File

@ -51,6 +51,7 @@
*/
#define XML_ATOMS \
TX_ATOM(_empty, ""); \
TX_ATOM(base, "base"); \
TX_ATOM(lang, "lang"); \
TX_ATOM(space, "space"); \
@ -83,7 +84,6 @@ public:
#include "txXSLTAtomList.h"
};
#ifndef TX_EXE
class txHTMLAtoms
{
public:
@ -91,7 +91,6 @@ public:
static void shutdown();
#include "txHTMLAtomList.h"
};
#endif
#undef TX_ATOM

View File

@ -130,8 +130,6 @@ double Double::toDouble(const String& aSrc)
PRInt32 len = aSrc.length();
MBool digitFound = MB_FALSE;
double sign = 1.0;
// leading whitespace
while (idx < len &&
(aSrc.charAt(idx) == ' ' ||

View File

@ -101,13 +101,15 @@ OBJS =../base/ArrayList.$(OBJ_SUFFIX) \
../xml/parser/xmlrole.$(OBJ_SUFFIX) \
../xml/parser/xmlparse.$(OBJ_SUFFIX) \
../xml/parser/xmltok.$(OBJ_SUFFIX) \
../xml/printer/XMLPrinter.$(OBJ_SUFFIX) \
../xml/printer/HTMLPrinter.$(OBJ_SUFFIX) \
../xml/printer/TEXTPrinter.$(OBJ_SUFFIX) \
../xslt/OutputFormat.$(OBJ_SUFFIX) \
../xslt/txOutputFormat.$(OBJ_SUFFIX) \
../xslt/Names.$(OBJ_SUFFIX) \
../xslt/Numbering.$(OBJ_SUFFIX) \
../xslt/ProcessorState.$(OBJ_SUFFIX) \
../xslt/txHTMLOutput.$(OBJ_SUFFIX) \
../xslt/txRtfHandler.$(OBJ_SUFFIX) \
../xslt/txTextHandler.$(OBJ_SUFFIX) \
../xslt/txTextOutput.$(OBJ_SUFFIX) \
../xslt/txXMLOutput.$(OBJ_SUFFIX) \
../xslt/VariableBinding.$(OBJ_SUFFIX) \
../xslt/XSLTProcessor.$(OBJ_SUFFIX) \
../xslt/functions/CurrentFunctionCall.$(OBJ_SUFFIX) \
@ -128,5 +130,5 @@ include $(topsrcdir)/config/rules.mk
INCLUDES += -I$(srcdir)/../xslt -I$(srcdir)/../base -I$(srcdir)/../net \
-I$(srcdir)/../xml -I$(srcdir)/../xml/dom \
-I$(srcdir)/../xml/parser -I$(srcdir)/../xml/parser/xmlparse \
-I$(srcdir)/../xml/printer -I$(srcdir)/../xpath -I$(srcdir)/../xslt/util \
-I$(srcdir)/../xpath -I$(srcdir)/../xslt/util \
-I$(srcdir)/../xslt/functions

View File

@ -38,9 +38,6 @@ REQUIRES = string \
endif
DIRS = dom parser
ifdef TX_EXE
DIRS += printer
endif
CPPSRCS = XMLDOMUtils.cpp XMLUtils.cpp

View File

@ -27,6 +27,7 @@
#include "dom.h"
#include "txAtoms.h"
#include "XMLUtils.h"
//
//Construct an Attribute object using the specified name and document owner
@ -46,7 +47,7 @@ Attr::Attr(const String& name, Document* owner):
}
else {
String tmp;
nodeName.subString(idx+1, tmp);
nodeName.subString(idx + 1, tmp);
mLocalName = TX_GET_ATOM(tmp);
// namespace handling has to be handled late, the attribute must
// be added to the tree to resolve the prefix, unless it's
@ -64,6 +65,22 @@ Attr::Attr(const String& name, Document* owner):
}
}
Attr::Attr(const String& aNamespaceURI,
const String& aName,
Document* aOwner) :
NodeDefinition(Node::ATTRIBUTE_NODE, aName, NULL_STRING, aOwner)
{
if (aNamespaceURI.isEmpty())
mNamespaceID = kNameSpaceID_None;
else
mNamespaceID = txNamespaceManager::getNamespaceID(aNamespaceURI);
specified = MB_TRUE;
String localPart;
XMLUtils::getLocalPart(nodeName, localPart);
mLocalName = TX_GET_ATOM(localPart);
}
//
//Release the mLocalName
//

View File

@ -125,7 +125,6 @@ class Node : public TxObject
//Read functions
virtual const String& getNodeName() const = 0;
virtual const String& getNodeValue() const = 0;
virtual const String& getNodeValue() = 0;
virtual unsigned short getNodeType() const = 0;
virtual Node* getParentNode() const = 0;
@ -267,7 +266,6 @@ class NodeDefinition : public Node, public NodeList
//Read functions
const String& getNodeName() const;
virtual const String& getNodeValue() const;
virtual const String& getNodeValue();
unsigned short getNodeType() const;
Node* getParentNode() const;
@ -394,11 +392,20 @@ class Document : public NodeDefinition
Node* removeChild(Node* oldChild);
// Introduced in DOM Level 2
Element* createElementNS(const String& aNamespaceURI,
const String& aTagName);
Attr* createAttributeNS(const String& aNamespaceURI,
const String& aName);
Element* getElementById(const String aID);
//Override to return documentBaseURI
String getBaseURI();
PRInt32 namespaceURIToID(const String& aNamespaceURI);
void namespaceIDToURI(PRInt32 aNamespaceID, String& aNamespaceURI);
private:
Element* documentElement;
DocumentType* doctype;
@ -416,6 +423,8 @@ class Element : public NodeDefinition
{
public:
Element(const String& tagName, Document* owner);
Element(const String& aNamespaceURI, const String& aTagName,
Document* aOwner);
virtual ~Element();
//Override insertBefore to limit Elements to having only certain nodes as
@ -426,6 +435,9 @@ class Element : public NodeDefinition
NamedNodeMap* getAttributes();
const String& getAttribute(const String& name);
void setAttribute(const String& name, const String& value);
void setAttributeNS(const String& aNamespaceURI,
const String& aName,
const String& aValue);
void removeAttribute(const String& name);
Attr* getAttributeNode(const String& name);
Attr* setAttributeNode(Attr* newAttr);
@ -452,10 +464,13 @@ class Element : public NodeDefinition
//
class Attr : public NodeDefinition
{
// AttrMap needs to be friend to be able to update the ownerElement
// These need to be friend to be able to update the ownerElement
friend class AttrMap;
friend class Element;
public:
Attr(const String& name, Document* owner);
Attr(const String& aNamespaceURI, const String& aName,
Document* aOwner);
virtual ~Attr();
const String& getName() const;

View File

@ -207,6 +207,12 @@ Element* Document::createElement(const String& tagName)
return new Element(tagName, this);
}
Element* Document::createElementNS(const String& aNamespaceURI,
const String& aTagName)
{
return new Element(aNamespaceURI, aTagName, this);
}
//
//Construct an attribute with the specified name
//
@ -215,6 +221,12 @@ Attr* Document::createAttribute(const String& name)
return new Attr(name, this);
}
Attr* Document::createAttributeNS(const String& aNamespaceURI,
const String& aName)
{
return new Attr(aNamespaceURI, aName, this);
}
//
//Construct a text node with the given data
//
@ -271,5 +283,16 @@ Element* Document::getElementById(const String aID)
String Document::getBaseURI()
{
return documentBaseURI;
return documentBaseURI;
}
PRInt32 Document::namespaceURIToID(const String& aNamespaceURI)
{
return txNamespaceManager::getNamespaceID(aNamespaceURI);
}
void Document::namespaceIDToURI(PRInt32 aNamespaceID, String& aNamespaceURI)
{
aNamespaceURI = txNamespaceManager::getNamespaceURI(aNamespaceID);
return;
}

View File

@ -27,6 +27,7 @@
#include "dom.h"
#include "txAtoms.h"
#include "XMLUtils.h"
//
//Construct a new element with the specified tagName and Document owner.
@ -50,6 +51,18 @@ Element::Element(const String& tagName, Document* owner) :
}
}
Element::Element(const String& aNamespaceURI,
const String& aTagName,
Document* aOwner) :
NodeDefinition(Node::ELEMENT_NODE, aTagName, NULL_STRING, aOwner)
{
Element(aTagName, aOwner);
if (aNamespaceURI.isEmpty())
mNamespaceID = kNameSpaceID_None;
else
mNamespaceID = txNamespaceManager::getNamespaceID(aNamespaceURI);
}
//
// This element is being destroyed, so destroy all attributes stored
// in the mAttributes NamedNodeMap.
@ -171,19 +184,58 @@ const String& Element::getAttribute(const String& name)
//
void Element::setAttribute(const String& name, const String& value)
{
Attr* tempAttribute;
// Check to see if an attribute with this name already exists. If it does
// overwrite its value, if not, add it.
Attr* tempAttribute = getAttributeNode(name);
if (tempAttribute) {
tempAttribute->setNodeValue(value);
}
else {
tempAttribute = getOwnerDocument()->createAttribute(name);
tempAttribute->setNodeValue(value);
tempAttribute->ownerElement = this;
mAttributes.append(tempAttribute);
}
}
//Check to see if an attribute with this name already exists. If it does
//over write its value, if not, add it.
tempAttribute = getAttributeNode(name);
if (tempAttribute)
tempAttribute->setNodeValue(value);
else
{
tempAttribute = getOwnerDocument()->createAttribute(name);
tempAttribute->setNodeValue(value);
mAttributes.setNamedItem(tempAttribute);
void Element::setAttributeNS(const String& aNamespaceURI,
const String& aName,
const String& aValue)
{
// Check to see if an attribute with this name already exists. If it does
// overwrite its value, if not, add it.
PRInt32 namespaceID = txNamespaceManager::getNamespaceID(aNamespaceURI);
String localPart;
XMLUtils::getLocalPart(aName, localPart);
txAtom* localName = TX_GET_ATOM(localPart);
Attr* foundNode = 0;
AttrMap::ListItem* item = mAttributes.firstItem;
while (item) {
foundNode = (Attr*)item->node;
txAtom* attrName;
if (foundNode->getLocalName(&attrName) &&
namespaceID == foundNode->getNamespaceID() &&
localName == attrName) {
TX_IF_RELEASE_ATOM(attrName);
break;
}
TX_IF_RELEASE_ATOM(attrName);
foundNode = 0;
item = item->next;
}
TX_IF_RELEASE_ATOM(localName);
if (foundNode) {
foundNode->setNodeValue(aValue);
}
else {
Attr* temp = getOwnerDocument()->createAttributeNS(aNamespaceURI,
aName);
temp->setNodeValue(aValue);
temp->ownerElement = this;
mAttributes.append(temp);
}
}
//

View File

@ -89,11 +89,6 @@ const String& NodeDefinition::getNodeName() const
return nodeName;
}
const String& NodeDefinition::getNodeValue() const
{
return nodeValue;
}
const String& NodeDefinition::getNodeValue()
{
return nodeValue;
@ -395,9 +390,17 @@ PRInt32 NodeDefinition::lookupNamespaceID(txAtom* aPrefix)
node = node->getXPathParent();
String name("xmlns:");
String prefixString;
TX_GET_ATOM_STRING(aPrefix, prefixString);
name.append(prefixString);
if (aPrefix && (aPrefix != txXMLAtoms::_empty)) {
// We have a prefix, search for xmlns:prefix attributes.
String prefixString;
TX_GET_ATOM_STRING(aPrefix, prefixString);
name.append(prefixString);
}
else {
// No prefix, look up the default namespace by searching for xmlns
// attributes. Remove the trailing :, set length to 5 (xmlns).
name.setLength(5);
}
Attr* xmlns;
while (node && node->getNodeType() == Node::ELEMENT_NODE) {
String nsURI;
@ -411,6 +414,8 @@ PRInt32 NodeDefinition::lookupNamespaceID(txAtom* aPrefix)
}
node = node->getXPathParent();
}
if (!aPrefix || (aPrefix == txXMLAtoms::_empty))
return kNameSpaceID_None;
return kNameSpaceID_Unknown;
}

View File

@ -25,19 +25,30 @@
*
*/
/**
* An XML utility class
**/
/*
* XML utility classes
*/
#include "XMLUtils.h"
txExpandedName::txExpandedName(PRInt32 aNsID,
txAtom* aLocalName) : mNamespaceID(aNsID),
mLocalName(aLocalName)
{
if (mLocalName)
TX_ADDREF_ATOM(mLocalName);
}
txExpandedName::~txExpandedName()
{
TX_IF_RELEASE_ATOM(mLocalName);
}
//------------------------------/
//- Implementation of XMLUtils -/
//------------------------------/
const String XMLUtils::XMLNS = "xmlns";
void XMLUtils::getNameSpace(const String& src, String& dest) {
void XMLUtils::getPrefix(const String& src, String& dest) {
//-- anything preceding ':' is the namespace part of the name
int idx = src.indexOf(':');
@ -50,7 +61,7 @@ void XMLUtils::getNameSpace(const String& src, String& dest) {
}
else dest.append("");
} //-- getNameSpace
}
void XMLUtils::getLocalPart(const String& src, String& dest) {
@ -135,49 +146,6 @@ MBool XMLUtils::isWhitespace(const String& text) {
return MB_TRUE;
} //-- isWhitespace
/**
* Normalizes the value of an XML attribute
**/
void XMLUtils::normalizeAttributeValue(String& attValue) {
PRInt32 size = attValue.length();
//-- make copy of chars
UNICODE_CHAR* chars = new UNICODE_CHAR[size];
attValue.toUnicode(chars);
//-- clear attValue
attValue.clear();
PRInt32 cc = 0;
MBool addSpace = MB_FALSE;
while ( cc < size) {
UNICODE_CHAR ch = chars[cc++];
switch (ch) {
case ' ':
if (!attValue.isEmpty())
addSpace = MB_TRUE;
break;
case '\r':
break;
case '\n':
attValue.append("&#xA;");
break;
case '\'':
attValue.append("&apos;");
break;
case '\"':
attValue.append("&quot;");
break;
default:
if ( addSpace) {
attValue.append(' ');
addSpace = MB_FALSE;
}
attValue.append(ch);
break;
}
}
delete chars;
} //-- normalizeAttributeValue
/**
* Normalizes the value of a XML processing instruction
**/
@ -230,4 +198,3 @@ MBool XMLUtils::shouldStripTextnode (const String& data){
}
return toStrip;
} //-- shouldStripTextnode

View File

@ -30,16 +30,39 @@
#ifndef MITRE_XMLUTILS_H
#define MITRE_XMLUTILS_H
#include "TxString.h"
#include "baseutils.h"
#include "txAtom.h"
class String;
class txExpandedName {
public:
txExpandedName(PRInt32 aNsID, txAtom* aLocalName);
~txExpandedName();
MBool
operator == (const txExpandedName& rhs)
{
return ((mNamespaceID == rhs.mNamespaceID) &&
(mLocalName == rhs.mLocalName));
}
MBool
operator != (const txExpandedName& rhs)
{
return ((mNamespaceID != rhs.mNamespaceID) ||
(mLocalName != rhs.mLocalName));
}
PRInt32 mNamespaceID;
txAtom* mLocalName;
};
class XMLUtils {
public:
static const String XMLNS;
static void getNameSpace(const String& src, String& dest);
static void getPrefix(const String& src, String& dest);
static void getLocalPart(const String& src, String& dest);
@ -53,11 +76,6 @@ public:
**/
static MBool isWhitespace(const String& text);
/**
* Normalizes the value of an XML attribute
**/
static void normalizeAttributeValue(String& attValue);
/**
* Normalizes the value of a XML processingInstruction
**/

View File

@ -79,12 +79,9 @@ endif
include $(topsrcdir)/config/rules.mk
INCLUDES += -I$(srcdir)/../base -I$(srcdir)/../xml \
-I$(srcdir)/../xml/dom \
INCLUDES += -I$(srcdir) -I$(srcdir)/../base \
-I$(srcdir)/../xml -I$(srcdir)/../xml/dom \
-I$(srcdir)/../xslt -I$(srcdir)/../xslt/util \
-I$(srcdir)/../xslt/functions
ifndef TX_EXE
INCLUDES += -I$(srcdir)
endif
libs:: $(OBJS)

View File

@ -27,7 +27,7 @@
*/
#include "FunctionLib.h"
#include "Names.h"
#include "txAtoms.h"
/**
* Creates a default BooleanFunctionCall, which always evaluates to False
@ -82,7 +82,8 @@ ExprResult* BooleanFunctionCall::evaluate(Node* context, ContextState* cs) {
if ( requireParams(1,1,cs) ) {
String arg1, lang;
evaluateToString((Expr*)iter->next(),context, cs, arg1);
lang = ((Element*)context)->getAttribute(XML_LANG_ATTR);
((Element*)context)->getAttr(txXMLAtoms::lang,
kNameSpaceID_XML, lang);
arg1.toUpperCase(); // case-insensitive comparison
lang.toUpperCase();
result = (MBool)(lang.indexOf(arg1) == 0);

View File

@ -43,7 +43,6 @@
#include "baseutils.h"
#include "TxObject.h"
#include "primitives.h"
#include "NamespaceResolver.h"
/*
XPath class definitions.
@ -60,7 +59,7 @@ typedef class Expr PatternExpr;
/**
* The expression context and state class used when evaluating XPath Expressions.
**/
class ContextState : public NamespaceResolver, public ErrorObserver {
class ContextState : public ErrorObserver {
public:
@ -95,6 +94,12 @@ public:
**/
virtual void sortByDocumentOrder(NodeSet* nodes) = 0;
/**
* Returns the namespace URI for the given namespace prefix, this method should
* only be called for determining a namespace declared within the context
* (ie. the stylesheet)
**/
virtual void getNameSpaceURIFromPrefix(const String& aPrefix, String& aNamespaceURI) = 0;
}; //-- ContextState

View File

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

View File

@ -119,7 +119,7 @@ ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
int i;
for (i = 0; i < nodes->size(); i++) {
String idList, id;
XMLDOMUtils::getNodeValue(nodes->get(i), &idList);
XMLDOMUtils::getNodeValue(nodes->get(i), idList);
txTokenizer tokenizer(idList);
while (tokenizer.hasMoreTokens()) {
tokenizer.nextToken(id);
@ -211,6 +211,10 @@ ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
}
return new StringResult();
}
default:
{
break;
}
}
}
case POSITION:

View File

@ -125,7 +125,7 @@ ExprResult* NumberFunctionCall::evaluate(Node* context, ContextState* cs) {
int i;
for (i = 0; i < nodes->size(); i++) {
String resultStr;
XMLDOMUtils::getNodeValue(nodes->get(i), &resultStr);
XMLDOMUtils::getNodeValue(nodes->get(i), resultStr);
res += Double::toDouble(resultStr);
}
delete nodes;
@ -139,7 +139,7 @@ ExprResult* NumberFunctionCall::evaluate(Node* context, ContextState* cs) {
evaluateToNumber((Expr*)iter.next(), context, cs));
String resultStr;
XMLDOMUtils::getNodeValue(context, &resultStr);
XMLDOMUtils::getNodeValue(context, resultStr);
return new NumberResult(Double::toDouble(resultStr));
}
}

View File

@ -62,7 +62,7 @@ MBool RelationalExpr::compareResults(ExprResult* left, ExprResult* right) {
for ( int i = 0; i < nodeSet->size(); i++) {
String str;
Node* node = nodeSet->get(i);
XMLDOMUtils::getNodeValue(node, &str);
XMLDOMUtils::getNodeValue(node, str);
StringResult strResult(str);
result = compareResults(&strResult, right);
if ( result ) break;
@ -74,7 +74,7 @@ MBool RelationalExpr::compareResults(ExprResult* left, ExprResult* right) {
for ( int i = 0; i < nodeSet->size(); i++) {
String str;
Node* node = nodeSet->get(i);
XMLDOMUtils::getNodeValue(node, &str);
XMLDOMUtils::getNodeValue(node, str);
StringResult strResult(str);
result = compareResults(left, &strResult);
if ( result ) break;

View File

@ -108,7 +108,7 @@ ExprResult* StringFunctionCall::evaluate(Node* context, ContextState* cs) {
if ( argc == 1)
evaluateToString((Expr*)iter->next(),context, cs, resultStr);
else
XMLDOMUtils::getNodeValue(context, &resultStr);
XMLDOMUtils::getNodeValue(context, resultStr);
// Leading & Trailing Whitespace
resultStr.trim();
MBool hasSpace = MB_FALSE;
@ -150,7 +150,7 @@ ExprResult* StringFunctionCall::evaluate(Node* context, ContextState* cs) {
if ( argc == 1) {
evaluateToString((Expr*)iter->next(),context, cs, resultStr);
}
else XMLDOMUtils::getNodeValue(context, &resultStr);
else XMLDOMUtils::getNodeValue(context, resultStr);
result = new NumberResult( (double) resultStr.length());
}
else result = new NumberResult(0.0);
@ -273,7 +273,7 @@ ExprResult* StringFunctionCall::evaluate(Node* context, ContextState* cs) {
evaluateToString((Expr*)iter->next(),context, cs, resultStr);
}
else {
XMLDOMUtils::getNodeValue(context, &resultStr);
XMLDOMUtils::getNodeValue(context, resultStr);
if ( cs->isStripSpaceAllowed(context) &&
XMLUtils::shouldStripTextnode(resultStr))
resultStr = "";

View File

@ -82,10 +82,10 @@ ExprResult* UnionExpr::evaluate(Node* context, ContextState* cs) {
Expr* expr = (Expr*)iter.next();
ExprResult* exprResult = expr->evaluate(context, cs);
if (exprResult &&
exprResult->getResultType() == ExprResult::NODESET) {
exprResult->getResultType() == ExprResult::NODESET) {
((NodeSet*)exprResult)->copyInto(*nodes);
}
delete exprResult;
delete exprResult;
}
return nodes;

View File

@ -38,16 +38,28 @@ REQUIRES = string \
content_xsl \
widget \
necko \
unicharutil \
$(NULL)
endif
CPPSRCS = Names.cpp \
Numbering.cpp \
OutputFormat.cpp \
txOutputFormat.cpp \
ProcessorState.cpp \
txRtfHandler.cpp \
txTextHandler.cpp \
VariableBinding.cpp \
XSLTProcessor.cpp
ifdef TX_EXE
CPPSRCS += txHTMLOutput.cpp \
txTextOutput.cpp \
txXMLOutput.cpp
else
CPPSRCS += txMozillaTextOutput.cpp \
txMozillaXMLOutput.cpp
endif
include $(topsrcdir)/config/rules.mk
INCLUDES += -I$(srcdir) -I$(srcdir)/../base -I$(srcdir)/../net \

View File

@ -105,7 +105,7 @@ ExprResult* DocumentFunctionCall::evaluate(Node* context, ContextState* cs)
for (i = 0; i < nodeSet1->size(); i++) {
Node* node = nodeSet1->get(i);
String uriStr;
XMLDOMUtils::getNodeValue(node, &uriStr);
XMLDOMUtils::getNodeValue(node, uriStr);
if (!baseURISet) {
// if the second argument wasn't specified, use
// the baseUri of node itself

View File

@ -20,7 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Peter Van der Beken, peterv@netscape.com
* Peter Van der Beken <peterv@netscape.com>
*
*
* Alternatively, the contents of this file may be used under the terms of
@ -74,7 +74,7 @@ ExprResult* ElementAvailableFunctionCall::evaluate(Node* context, ContextState*
exprResult->stringValue(property);
if (XMLUtils::isValidQName(property)) {
String prefix, propertyNsURI;
XMLUtils::getNameSpace(property, prefix);
XMLUtils::getPrefix(property, prefix);
if (!prefix.isEmpty()) {
cs->getNameSpaceURIFromPrefix(property, propertyNsURI);
}

View File

@ -20,7 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Peter Van der Beken, peterv@netscape.com
* Peter Van der Beken <peterv@netscape.com>
*
*
* Alternatively, the contents of this file may be used under the terms of
@ -75,7 +75,7 @@ ExprResult* FunctionAvailableFunctionCall::evaluate(Node* context, ContextState*
exprResult->stringValue(property);
if (XMLUtils::isValidQName(property)) {
String prefix;
XMLUtils::getNameSpace(property, prefix);
XMLUtils::getPrefix(property, prefix);
if (prefix.isEmpty() &&
(property.isEqual(XPathNames::BOOLEAN_FN) ||
property.isEqual(XPathNames::CONCAT_FN) ||

View File

@ -36,12 +36,52 @@
*
* ***** END LICENSE BLOCK ***** */
TX_ATOM(area, "area");
TX_ATOM(base, "base");
TX_ATOM(basefont, "basefont");
TX_ATOM(br, "br");
TX_ATOM(button, "button");
TX_ATOM(checked, "checked");
TX_ATOM(col, "col");
TX_ATOM(compact, "compact");
TX_ATOM(declare, "declare");
TX_ATOM(defer, "defer");
TX_ATOM(dir, "dir");
TX_ATOM(disabled, "disabled");
TX_ATOM(dl, "dl");
TX_ATOM(frame, "frame");
TX_ATOM(headerDefaultStyle, "default-style");
TX_ATOM(head, "head");
TX_ATOM(hr, "hr");
TX_ATOM(img, "img");
TX_ATOM(input, "input");
TX_ATOM(isindex, "isindex");
TX_ATOM(ismap, "ismap");
TX_ATOM(li, "li");
TX_ATOM(link, "link");
TX_ATOM(media, "media");
TX_ATOM(menu, "menu");
TX_ATOM(meta, "meta");
TX_ATOM(multiple, "multiple");
TX_ATOM(noresize, "noresize");
TX_ATOM(noshade, "noshade");
TX_ATOM(nowrap, "nowrap");
TX_ATOM(object, "object");
TX_ATOM(ol, "ol");
TX_ATOM(optgroup, "optgroup");
TX_ATOM(option, "option");
TX_ATOM(p, "p");
TX_ATOM(param, "param");
TX_ATOM(readonly, "readonly");
TX_ATOM(script, "script");
TX_ATOM(select, "select");
TX_ATOM(selected, "selected");
TX_ATOM(src, "src");
TX_ATOM(style, "style");
TX_ATOM(table, "table");
TX_ATOM(td, "td");
TX_ATOM(textarea, "textarea");
TX_ATOM(th, "th");
TX_ATOM(title, "title");
TX_ATOM(type, "type");
TX_ATOM(ul, "ul");

View File

@ -0,0 +1,328 @@
/* -*- 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 the TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* 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 "txHTMLOutput.h"
#include "txAtoms.h"
#include "txOutputFormat.h"
#include "XMLUtils.h"
txHTMLOutput::txHTMLOutput()
{
mUseEmptyElementShorthand = MB_FALSE;
mHTMLEmptyTags.setOwnership(Map::eOwnsNone);
mHTMLEmptyTags.put(txHTMLAtoms::area, txHTMLAtoms::area);
mHTMLEmptyTags.put(txHTMLAtoms::base, txHTMLAtoms::base);
mHTMLEmptyTags.put(txHTMLAtoms::basefont, txHTMLAtoms::basefont);
mHTMLEmptyTags.put(txHTMLAtoms::br, txHTMLAtoms::br);
mHTMLEmptyTags.put(txHTMLAtoms::col, txHTMLAtoms::col);
mHTMLEmptyTags.put(txHTMLAtoms::frame, txHTMLAtoms::frame);
mHTMLEmptyTags.put(txHTMLAtoms::hr, txHTMLAtoms::hr);
mHTMLEmptyTags.put(txHTMLAtoms::img, txHTMLAtoms::img);
mHTMLEmptyTags.put(txHTMLAtoms::input, txHTMLAtoms::input);
mHTMLEmptyTags.put(txHTMLAtoms::isindex, txHTMLAtoms::isindex);
mHTMLEmptyTags.put(txHTMLAtoms::link, txHTMLAtoms::link);
mHTMLEmptyTags.put(txHTMLAtoms::meta, txHTMLAtoms::meta);
mHTMLEmptyTags.put(txHTMLAtoms::param, txHTMLAtoms::param);
mHTMLEmptyAttributes.setOwnership(Map::eOwnsItems);
// checked
txList* elementList = new List;
if (!elementList)
return;
elementList->add(txHTMLAtoms::input);
mHTMLEmptyAttributes.put(txHTMLAtoms::checked, elementList);
// compact
elementList = new List;
if (!elementList)
return;
elementList->add(txHTMLAtoms::dir);
elementList->add(txHTMLAtoms::dl);
elementList->add(txHTMLAtoms::menu);
elementList->add(txHTMLAtoms::ol);
elementList->add(txHTMLAtoms::ul);
mHTMLEmptyAttributes.put(txHTMLAtoms::compact, elementList);
// declare
elementList = new List;
if (!elementList)
return;
elementList->add(txHTMLAtoms::object);
mHTMLEmptyAttributes.put(txHTMLAtoms::declare, elementList);
// defer
elementList = new List;
if (!elementList)
return;
elementList->add(txHTMLAtoms::script);
mHTMLEmptyAttributes.put(txHTMLAtoms::defer, elementList);
// disabled
elementList = new List;
if (!elementList)
return;
elementList->add(txHTMLAtoms::button);
elementList->add(txHTMLAtoms::input);
elementList->add(txHTMLAtoms::optgroup);
elementList->add(txHTMLAtoms::option);
elementList->add(txHTMLAtoms::select);
elementList->add(txHTMLAtoms::textarea);
mHTMLEmptyAttributes.put(txHTMLAtoms::disabled, elementList);
// ismap
elementList = new List;
if (!elementList)
return;
elementList->add(txHTMLAtoms::img);
elementList->add(txHTMLAtoms::input);
mHTMLEmptyAttributes.put(txHTMLAtoms::ismap, elementList);
// multiple
elementList = new List;
if (!elementList)
return;
elementList->add(txHTMLAtoms::select);
mHTMLEmptyAttributes.put(txHTMLAtoms::multiple, elementList);
// noresize
elementList = new List;
if (!elementList)
return;
elementList->add(txHTMLAtoms::frame);
mHTMLEmptyAttributes.put(txHTMLAtoms::noresize, elementList);
// noshade
elementList = new List;
if (!elementList)
return;
elementList->add(txHTMLAtoms::hr);
mHTMLEmptyAttributes.put(txHTMLAtoms::noshade, elementList);
// nowrap
elementList = new List;
if (!elementList)
return;
elementList->add(txHTMLAtoms::td);
elementList->add(txHTMLAtoms::th);
mHTMLEmptyAttributes.put(txHTMLAtoms::nowrap, elementList);
// readonly
elementList = new List;
if (!elementList)
return;
elementList->add(txHTMLAtoms::input);
elementList->add(txHTMLAtoms::textarea);
mHTMLEmptyAttributes.put(txHTMLAtoms::readonly, elementList);
// selected
elementList = new List;
if (!elementList)
return;
elementList->add(txHTMLAtoms::option);
mHTMLEmptyAttributes.put(txHTMLAtoms::selected, elementList);
}
txHTMLOutput::~txHTMLOutput()
{
}
void txHTMLOutput::attribute(const String& aName,
const PRInt32 aNsID,
const String& aValue)
{
if (!mStartTagOpen)
// XXX Signal this? (can't add attributes after element closed)
return;
MBool shortHand = MB_FALSE;
if (aNsID == kNameSpaceID_None) {
String localPart;
XMLUtils::getLocalPart(aName, localPart);
shortHand = isShorthandAttribute(localPart);
if (shortHand && localPart.isEqualIgnoreCase(aValue)) {
txListIterator iter(&mAttributes);
txAttribute* setAtt = 0;
txAtom* localName = TX_GET_ATOM(localPart);
txExpandedName att(aNsID, localName);
while ((setAtt = (txAttribute*)iter.next())) {
if (setAtt->mName == att) {
setAtt->mShorthand = MB_TRUE;
break;
}
}
if (!setAtt) {
setAtt = new txAttribute(aNsID, localName, "");
setAtt->mShorthand = MB_TRUE;
mAttributes.add(setAtt);
}
TX_IF_RELEASE_ATOM(localName);
}
}
if (!shortHand)
txXMLOutput::attribute(aName, aNsID, aValue);
}
void txHTMLOutput::characters(const String& aData)
{
// Special-case script and style
txExpandedName* currentElement = (txExpandedName*)mCurrentElements.peek();
if (currentElement &&
(currentElement->mNamespaceID == kNameSpaceID_None) &&
((currentElement->mLocalName == txHTMLAtoms::script) ||
(currentElement->mLocalName == txHTMLAtoms::style))) {
closeStartTag(MB_FALSE);
printUTF8Chars(aData);
}
else {
txXMLOutput::characters(aData);
}
}
void txHTMLOutput::endElement(const String& aName,
const PRInt32 aNsID)
{
if ((aNsID == kNameSpaceID_None) && isShorthandElement(aName) &&
mStartTagOpen) {
MBool newLine = (mOutputFormat.mIndent == eTrue) &&
mAfterEndTag;
closeStartTag(MB_FALSE);
if (newLine)
*mOut << endl;
if (mOutputFormat.mIndent == eTrue)
mIndentLevel -= DEFAULT_INDENT;
mAfterEndTag = MB_TRUE;
}
else {
txXMLOutput::endElement(aName, aNsID);
}
delete (txExpandedName*)mCurrentElements.pop();
}
void txHTMLOutput::processingInstruction(const String& aTarget, const String& aData)
{
closeStartTag(MB_FALSE);
if (mOutputFormat.mIndent == eTrue) {
for (PRUint32 i = 0; i < mIndentLevel; i++)
*mOut << ' ';
}
*mOut << PI_START << aTarget << SPACE << aData << R_ANGLE_BRACKET;
if (mOutputFormat.mIndent == eTrue)
*mOut << endl;
}
void txHTMLOutput::startDocument()
{
// XXX Should be using mOutputFormat.getVersion
*mOut << DOCTYPE_START << "html " << PUBLIC;
*mOut << " \"-//W3C//DTD HTML 4.0 Transitional//EN\"";
*mOut << " \"http://www.w3.org/TR/REC-html40/loose.dtd\"";
*mOut << DOCTYPE_END << endl;
}
void txHTMLOutput::startElement(const String& aName,
const PRInt32 aNsID)
{
txXMLOutput::startElement(aName, aNsID);
txAtom* localAtom;
if (aNsID == kNameSpaceID_None) {
String localName(aName);
localName.toLowerCase();
localAtom = TX_GET_ATOM(localName);
}
else {
localAtom = TX_GET_ATOM(aName);
}
NS_ASSERTION(localAtom, "Can't get atom");
txExpandedName* currentElement = new txExpandedName(aNsID, localAtom);
TX_IF_RELEASE_ATOM(localAtom);
NS_ASSERTION(currentElement, "Can't create currentElement");
if (currentElement)
mCurrentElements.push(currentElement);
}
void txHTMLOutput::closeStartTag(MBool aUseEmptyElementShorthand)
{
txExpandedName* currentElement = (txExpandedName*)mCurrentElements.peek();
if (mStartTagOpen && currentElement &&
(currentElement->mNamespaceID == kNameSpaceID_None) &&
(currentElement->mLocalName == txHTMLAtoms::head)) {
txXMLOutput::closeStartTag(MB_FALSE);
if (mOutputFormat.mIndent == eTrue) {
*mOut << endl;
for (PRUint32 i = 0; i < mIndentLevel; i++)
*mOut << ' ';
}
*mOut << LT << "meta http-equiv=" << QUOTE << "Content-Type" << QUOTE;
*mOut << " content=" << QUOTE << mOutputFormat.mMediaType << ";";
*mOut << " charset=" << mOutputFormat.mEncoding << QUOTE << GT;
}
else {
txXMLOutput::closeStartTag(aUseEmptyElementShorthand);
}
}
MBool txHTMLOutput::isShorthandElement(const String& aName)
{
String localName;
XMLUtils::getLocalPart(aName, localName);
localName.toLowerCase();
txAtom* localAtom = TX_GET_ATOM(localName);
if (localAtom && mHTMLEmptyTags.get(localAtom))
return MB_TRUE;
return MB_FALSE;
}
MBool txHTMLOutput::isShorthandAttribute(const String& aLocalName)
{
String localName(aLocalName);
localName.toLowerCase();
txAtom* localAtom = TX_GET_ATOM(localName);
txList* elements = (txList*)mHTMLEmptyAttributes.get(localAtom);
if (localAtom && (elements)) {
txExpandedName* currentElement = (txExpandedName*)mCurrentElements.peek();
txListIterator iter(elements);
while (iter.hasNext()) {
if ((txAtom*)iter.next() == currentElement->mLocalName)
return MB_TRUE;
}
}
return MB_FALSE;
}

View File

@ -0,0 +1,112 @@
/* -*- 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 the TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* 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 TRANSFRMX_HTML_OUTPUT_H
#define TRANSFRMX_HTML_OUTPUT_H
#include "txXMLOutput.h"
#include "Map.h"
#include "Stack.h"
class txHTMLOutput : public txXMLOutput
{
public:
txHTMLOutput();
~txHTMLOutput();
/*
* 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 String& aName,
const PRInt32 aNsID,
const String& aValue);
/*
* Signals to receive characters.
*
* @param aData the characters to receive
*/
void characters(const String& 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 String& 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 String& aTarget,
const String& 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 String& aName,
const PRInt32 aNsID);
private:
void closeStartTag(MBool aUseEmptyElementShorthand);
MBool isShorthandElement(const String& aName);
MBool isShorthandAttribute(const String& aLocalName);
Map mHTMLEmptyTags;
Map mHTMLEmptyAttributes;
Stack mCurrentElements;
};
#endif

View File

@ -82,7 +82,7 @@ ExprResult* txKeyFunctionCall::evaluate(Node* aContext, ContextState* aCs)
NodeSet* nodeSet = (NodeSet*) exprResult;
for (int i=0; i<nodeSet->size(); i++) {
String val;
XMLDOMUtils::getNodeValue(nodeSet->get(i), &val);
XMLDOMUtils::getNodeValue(nodeSet->get(i), val);
key->getNodes(val,contextDoc)->copyInto(*res);
}
}
@ -238,7 +238,7 @@ void txXSLKey::testNode(Node* aNode, NamedMap* aMap)
NodeSet* res = (NodeSet*)exprResult;
for (int i=0; i<res->size(); i++) {
val.clear();
XMLDOMUtils::getNodeValue(res->get(i), &val);
XMLDOMUtils::getNodeValue(res->get(i), val);
nodeSet = (NodeSet*)aMap->get(val);
if (!nodeSet) {

View File

@ -0,0 +1,220 @@
/* -*- 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 the TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* 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 "txMozillaTextOutput.h"
#include "nsIDocument.h"
#include "nsIDOMDocument.h"
#include "nsIDOMElement.h"
#include "nsIDOMHTMLElement.h"
#include "nsIDOMText.h"
#include "TxString.h"
txMozillaTextOutput::txMozillaTextOutput()
{
}
txMozillaTextOutput::~txMozillaTextOutput()
{
}
void txMozillaTextOutput::attribute(const String& aName,
const PRInt32 aNsID,
const String& aValue)
{
}
void txMozillaTextOutput::characters(const String& aData)
{
if (mTextNode)
mTextNode->AppendData(aData.getConstNSString());
}
void txMozillaTextOutput::comment(const String& aData)
{
}
void txMozillaTextOutput::disableStylesheetLoad()
{
}
void txMozillaTextOutput::endDocument()
{
}
void txMozillaTextOutput::endElement(const String& aName,
const PRInt32 aNsID)
{
}
nsresult txMozillaTextOutput::getRootContent(nsIContent** aReturn)
{
NS_ASSERTION(aReturn, "NULL pointer passed to getRootContent");
*aReturn = mRootContent;
NS_IF_ADDREF(*aReturn);
return NS_OK;
}
PRBool txMozillaTextOutput::isDone()
{
return PR_TRUE;
}
void txMozillaTextOutput::processingInstruction(const String& aTarget,
const String& aData)
{
}
void txMozillaTextOutput::removeScriptElement(nsIDOMHTMLScriptElement *aElement)
{
NS_NOTREACHED("No script elements in text output, so this is weird!");
}
void txMozillaTextOutput::setOutputDocument(nsIDOMDocument* aDocument)
{
NS_ASSERTION(aDocument, "Document can't be NULL!");
if (!aDocument)
return;
/*
* Create an XHTML document to hold the text.
*
* <html>
* <head />
* <body>
* <pre> * The text comes here * </pre>
* <body>
* </html>
*/
nsCOMPtr<nsIDOMElement> element, docElement;
nsCOMPtr<nsIDOMNode> parent, pre;
nsCOMPtr<nsIDOMText> textNode;
NS_NAMED_LITERAL_STRING(XHTML_NSURI, "http://www.w3.org/1999/xhtml");
aDocument->CreateElementNS(XHTML_NSURI,
NS_LITERAL_STRING("html"),
getter_AddRefs(docElement));
mRootContent = do_QueryInterface(docElement);
NS_ASSERTION(mRootContent, "Need root element");
if (!mRootContent)
return;
nsCOMPtr<nsIDocument> document = do_QueryInterface(aDocument);
NS_ASSERTION(document, "Need document");
nsresult rv = mRootContent->SetDocument(document, PR_FALSE, PR_TRUE);
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to set the document");
if (NS_FAILED(rv))
return;
rv = document->SetRootContent(mRootContent);
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to set the root content");
if (NS_FAILED(rv))
return;
aDocument->CreateElementNS(XHTML_NSURI,
NS_LITERAL_STRING("head"),
getter_AddRefs(element));
NS_ASSERTION(element, "Failed to create head element");
if (!element)
return;
rv = docElement->AppendChild(element, getter_AddRefs(parent));
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the head element");
if (NS_FAILED(rv))
return;
aDocument->CreateElementNS(XHTML_NSURI,
NS_LITERAL_STRING("body"),
getter_AddRefs(element));
NS_ASSERTION(element, "Failed to create body element");
if (!mRootContent)
return;
rv = docElement->AppendChild(element, getter_AddRefs(parent));
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the body element");
if (NS_FAILED(rv))
return;
aDocument->CreateElementNS(XHTML_NSURI,
NS_LITERAL_STRING("pre"),
getter_AddRefs(element));
NS_ASSERTION(element, "Failed to create pre element");
if (!element)
return;
rv = parent->AppendChild(element, getter_AddRefs(pre));
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the pre element");
if (NS_FAILED(rv))
return;
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(pre);
htmlElement->SetId(NS_LITERAL_STRING("transformiixResult"));
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the id");
aDocument->CreateTextNode(NS_LITERAL_STRING(""),
getter_AddRefs(textNode));
NS_ASSERTION(textNode, "Failed to create the text node");
if (!textNode)
return;
rv = pre->AppendChild(textNode, getter_AddRefs(parent));
NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to append the text node");
if (NS_FAILED(rv))
return;
mTextNode = textNode;
}
void txMozillaTextOutput::setOutputFormat(txOutputFormat* aOutputFormat)
{
mOutputFormat.reset();
mOutputFormat.merge(*aOutputFormat);
mOutputFormat.setFromDefaults();
}
void txMozillaTextOutput::startDocument()
{
}
void txMozillaTextOutput::startElement(const String& aName,
const PRInt32 aNsID)
{
}

View File

@ -0,0 +1,162 @@
/* -*- 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 the TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* 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 TRANSFRMX_MOZILLA_TEXT_OUTPUT_H
#define TRANSFRMX_MOZILLA_TEXT_OUTPUT_H
#include "txXMLEventHandler.h"
#include "nsIContent.h"
#include "nsIDOMCharacterData.h"
#include "nsCOMPtr.h"
#include "txOutputFormat.h"
class txMozillaTextOutput : public txMozillaXMLEventHandler
{
public:
txMozillaTextOutput();
virtual ~txMozillaTextOutput();
/*
* 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 String& aName,
const PRInt32 aNsID,
const String& aValue);
/*
* Signals to receive characters.
*
* @param aData the characters to receive
*/
void characters(const String& aData);
/*
* Signals to receive data that should be treated as a comment.
*
* @param data the comment data to receive
*/
void comment(const String& 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 String& 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 String& aTarget, const String& 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 String& aName,
const PRInt32 aNsID);
/*
* Sets the output format.
*
* @param aOutputFormat the output format
*/
void setOutputFormat(txOutputFormat* aOutputFormat);
/*
* Disables loading of stylesheets.
*/
void disableStylesheetLoad();
/*
* Returns the root content of the result.
*
* @param aReturn the root content
*/
nsresult getRootContent(nsIContent** aReturn);
/*
* Returns PR_TRUE if the event handler has finished anything
* extra that had to happen after the transform has finished.
*/
PRBool isDone();
/*
* Removes a script element from the array of elements that are
* still loading.
*
* @param aReturn the script element to remove
*/
void removeScriptElement(nsIDOMHTMLScriptElement *aElement);
/*
* Sets the Mozilla output document.
*
* @param aDocument the Mozilla output document
*/
void setOutputDocument(nsIDOMDocument* aDocument);
private:
nsCOMPtr<nsIDOMCharacterData> mTextNode;
nsCOMPtr<nsIContent> mRootContent;
txOutputFormat mOutputFormat;
};
#endif

View File

@ -0,0 +1,498 @@
/* -*- 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 the TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* 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 "txMozillaXMLOutput.h"
#include "nsIDocument.h"
#include "nsIDOMComment.h"
#include "nsIDOMDocumentType.h"
#include "nsIDOMDOMImplementation.h"
#include "nsIDOMProcessingInstruction.h"
#include "nsIDOMText.h"
#include "nsIDOMHTMLTableSectionElem.h"
#include "nsIDOMHTMLScriptElement.h"
#include "nsIDOMNSDocument.h"
#include "nsUnicharUtils.h"
#include "txAtoms.h"
#define kXHTMLNameSpaceURI "http://www.w3.org/1999/xhtml"
#define kTXNameSpaceURI "http://www.mozilla.org/TransforMiix"
#define kTXWrapper "transformiix:result"
#define TX_ENSURE_CURRENTNODE \
NS_ASSERTION(mCurrentNode, "mCurrentNode is NULL"); \
if (!mCurrentNode) \
return
txMozillaXMLOutput::txMozillaXMLOutput() : mDisableStylesheetLoad(PR_FALSE)
{
}
txMozillaXMLOutput::~txMozillaXMLOutput()
{
}
void txMozillaXMLOutput::attribute(const String& aName,
const PRInt32 aNsID,
const String& aValue)
{
if (!mParentNode)
// XXX Signal this? (can't add attributes after element closed)
return;
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mCurrentNode);
NS_ASSERTION(element, "No element to add the attribute to.");
if (!element)
// XXX Signal this? (no element to add attributes to)
return;
if ((mOutputFormat.mMethod == eHTMLOutput) && (aNsID == kNameSpaceID_None)) {
// Outputting HTML as XHTML, lowercase attribute names
nsAutoString lowerName(aName.getConstNSString());
ToLowerCase(lowerName);
element->SetAttributeNS(NS_LITERAL_STRING(""), lowerName,
aValue.getConstNSString());
}
else {
nsAutoString nsURI;
mNameSpaceManager->GetNameSpaceURI(aNsID, nsURI);
element->SetAttributeNS(nsURI, aName.getConstNSString(),
aValue.getConstNSString());
}
}
void txMozillaXMLOutput::characters(const String& aData)
{
closePrevious(eCloseElement);
mText.Append(aData.getConstNSString());
}
void txMozillaXMLOutput::comment(const String& aData)
{
closePrevious(eCloseElement | eFlushText);
TX_ENSURE_CURRENTNODE;
nsCOMPtr<nsIDOMComment> comment;
nsresult rv = mDocument->CreateComment(aData.getConstNSString(),
getter_AddRefs(comment));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create comment");
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(comment);
nsCOMPtr<nsIDOMNode> resultNode;
rv = mCurrentNode->AppendChild(node, getter_AddRefs(resultNode));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't append comment");
}
void txMozillaXMLOutput::disableStylesheetLoad()
{
mDisableStylesheetLoad = PR_TRUE;
}
void txMozillaXMLOutput::endDocument()
{
closePrevious(eCloseElement | eFlushText);
if (!mHaveTitle) {
nsCOMPtr<nsIDOMNSDocument> domDoc = do_QueryInterface(mDocument);
if (domDoc) {
domDoc->SetTitle(NS_LITERAL_STRING(""));
}
}
}
void txMozillaXMLOutput::endElement(const String& aName, const PRInt32 aNsID)
{
#ifdef DEBUG
nsAutoString nodeName;
mCurrentNode->GetNodeName(nodeName);
if (!nodeName.EqualsIgnoreCase(aName.getConstNSString()))
NS_ASSERTION(nodeName.EqualsIgnoreCase(aName.getConstNSString()),
"Unbalanced startElement and endElement calls!");
#endif
closePrevious(eCloseElement | eFlushText);
nsresult rv;
nsCOMPtr<nsIContent> currentContent = do_QueryInterface(mCurrentNode, &rv);
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't QI to nsIContent");
if (!currentContent)
return;
nsCOMPtr<nsIAtom> atom;
currentContent->GetTag(*getter_AddRefs(atom));
PRBool isHTML = (mOutputFormat.mMethod == eHTMLOutput) &&
(aNsID == kNameSpaceID_None);
if (isHTML && (atom == txHTMLAtoms::table)) {
// Check if we have any table section.
nsCOMPtr<nsIDOMHTMLTableSectionElement> section;
nsCOMPtr<nsIContent> childContent;
PRInt32 count, i = 0;
currentContent->ChildCount(count);
while (!section && (i < count)) {
rv = currentContent->ChildAt(i, *getter_AddRefs(childContent));
NS_ASSERTION(NS_SUCCEEDED(rv), "Something went wrong while getting a child");
section = do_QueryInterface(childContent);
++i;
}
if (!section && (count > 0)) {
// If no section, wrap table's children in a tbody.
nsCOMPtr<nsIDOMElement> wrapper;
rv = mDocument->CreateElementNS(NS_LITERAL_STRING(kXHTMLNameSpaceURI),
NS_LITERAL_STRING("tbody"),
getter_AddRefs(wrapper));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create tbody element");
if (wrapper) {
nsCOMPtr<nsIDOMNode> resultNode;
wrapChildren(mCurrentNode, wrapper);
rv = mCurrentNode->AppendChild(wrapper, getter_AddRefs(resultNode));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't append tbody element");
}
}
}
else if (isHTML || (aNsID == kNameSpaceID_HTML)) {
if (mScriptParent && (atom == txHTMLAtoms::script)) {
// Add this script element to the array of loading script elements.
nsCOMPtr<nsIDOMHTMLScriptElement> scriptElement = do_QueryInterface(mCurrentNode, &rv);
NS_ASSERTION(NS_SUCCEEDED(rv), "Need script element");
mScriptElements.AppendElement(scriptElement);
// Add the script element to the tree.
nsCOMPtr<nsIDocument> document = do_QueryInterface(mScriptParent);
if (document && !mRootContent) {
mRootContent = do_QueryInterface(mCurrentNode);
mRootContent->SetDocument(document, PR_FALSE, PR_TRUE);
document->SetRootContent(mRootContent);
}
else {
nsCOMPtr<nsIDOMNode> resultNode;
rv = mScriptParent->AppendChild(mCurrentNode,
getter_AddRefs(resultNode));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't append script element");
}
mScriptParent = nsnull;
}
else if (mStyleElement && (atom == txHTMLAtoms::style)) {
if (!mDisableStylesheetLoad) {
mStyleElement->SetEnableUpdates(PR_TRUE);
mStyleElement->UpdateStyleSheet(PR_TRUE, nsnull, -1);
}
mStyleElement = nsnull;
}
}
nsCOMPtr<nsIDOMNode> tempNode = mCurrentNode;
tempNode->GetParentNode(getter_AddRefs(mCurrentNode));
}
nsresult txMozillaXMLOutput::getRootContent(nsIContent** aReturn)
{
NS_ASSERTION(aReturn, "NULL pointer passed to getRootContent");
*aReturn = mRootContent;
NS_IF_ADDREF(*aReturn);
return NS_OK;
}
PRBool txMozillaXMLOutput::isDone()
{
PRUint32 scriptCount;
mScriptElements.Count(&scriptCount);
return (scriptCount == 0);
}
void txMozillaXMLOutput::processingInstruction(const String& aTarget, const String& aData)
{
if (mOutputFormat.mMethod == eHTMLOutput)
return;
closePrevious(eCloseElement | eFlushText);
TX_ENSURE_CURRENTNODE;
nsCOMPtr<nsIDOMProcessingInstruction> pi;
nsresult rv = mDocument->CreateProcessingInstruction(aTarget.getConstNSString(),
aData.getConstNSString(),
getter_AddRefs(pi));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create entity reference");
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(pi);
nsCOMPtr<nsIDOMNode> resultNode;
mCurrentNode->AppendChild(node, getter_AddRefs(resultNode));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't append entity reference");
}
void txMozillaXMLOutput::removeScriptElement(nsIDOMHTMLScriptElement *aElement)
{
PRInt32 index = mScriptElements.IndexOf(aElement);
if (index > -1)
mScriptElements.RemoveElementAt(index);
}
void txMozillaXMLOutput::setOutputDocument(nsIDOMDocument* aDocument)
{
NS_ASSERTION(aDocument, "Document can't be NULL!");
if (!aDocument)
return;
mDocument = aDocument;
mCurrentNode = mDocument;
mHaveTitle = PR_FALSE;
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aDocument);
doc->GetNameSpaceManager(*getter_AddRefs(mNameSpaceManager));
NS_ASSERTION(mNameSpaceManager, "Can't get namespace manager.");
}
void txMozillaXMLOutput::setOutputFormat(txOutputFormat* aOutputFormat)
{
mOutputFormat.reset();
mOutputFormat.merge(*aOutputFormat);
mOutputFormat.setFromDefaults();
}
void txMozillaXMLOutput::startDocument()
{
NS_ASSERTION(mDocument, "Document can't be NULL!");
}
void txMozillaXMLOutput::startElement(const String& aName,
const PRInt32 aNsID)
{
closePrevious(eCloseElement | eFlushText);
nsresult rv;
if (!mRootContent && !mOutputFormat.mSystemId.isEmpty()) {
// No root element yet, so add the doctype if necesary.
nsCOMPtr<nsIDOMDOMImplementation> implementation;
rv = mDocument->GetImplementation(getter_AddRefs(implementation));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't get DOMImplementation");
if (NS_SUCCEEDED(rv)) {
nsAutoString qName;
nsCOMPtr<nsIDOMDocumentType> documentType;
nsCOMPtr<nsIDOMNode> firstNode, node;
if (mOutputFormat.mMethod == eHTMLOutput)
qName.Assign(NS_LITERAL_STRING("html"));
else
qName.Assign(aName.getConstNSString());
rv = implementation->CreateDocumentType(qName,
mOutputFormat.mPublicId.getConstNSString(),
mOutputFormat.mSystemId.getConstNSString(),
getter_AddRefs(documentType));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create doctype");
mDocument->GetFirstChild(getter_AddRefs(firstNode));
rv = mDocument->InsertBefore(documentType, firstNode, getter_AddRefs(node));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't insert doctype");
}
}
nsCOMPtr<nsIDOMElement> element;
if ((mOutputFormat.mMethod == eHTMLOutput) && (aNsID == kNameSpaceID_None)) {
// Outputting HTML as XHTML, lowercase element names
nsAutoString lowerName(aName.getConstNSString());
ToLowerCase(lowerName);
rv = mDocument->CreateElementNS(NS_LITERAL_STRING(kXHTMLNameSpaceURI), lowerName,
getter_AddRefs(element));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create element");
startHTMLElement(element);
}
else {
nsAutoString nsURI;
mNameSpaceManager->GetNameSpaceURI(aNsID, nsURI);
rv = mDocument->CreateElementNS(nsURI, aName.getConstNSString(),
getter_AddRefs(element));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create element");
if (aNsID == kNameSpaceID_XHTML)
startHTMLElement(element);
}
if (element) {
mParentNode = mCurrentNode;
mCurrentNode = do_QueryInterface(element);
}
}
void txMozillaXMLOutput::closePrevious(PRInt8 aAction)
{
TX_ENSURE_CURRENTNODE;
nsresult rv;
PRInt32 namespaceID = kNameSpaceID_None;
nsCOMPtr<nsIContent> currentContent = do_QueryInterface(mCurrentNode, &rv);
if (currentContent)
currentContent->GetNameSpaceID(namespaceID);
PRBool isHTML = (namespaceID == kNameSpaceID_HTML) ||
((mOutputFormat.mMethod == eHTMLOutput) &&
(namespaceID == kNameSpaceID_None));
if ((aAction & eCloseElement) && mParentNode) {
nsCOMPtr<nsIDocument> document = do_QueryInterface(mParentNode);
nsCOMPtr<nsIDOMElement> currentElement = do_QueryInterface(mCurrentNode);
if (document && currentElement && mRootContent) {
// We already have a document element, but the XSLT spec allows this.
// As a workaround, create a wrapper object and use that as the
// document element.
nsCOMPtr<nsIDOMElement> wrapper;
rv = mDocument->CreateElementNS(NS_LITERAL_STRING(kTXNameSpaceURI),
NS_LITERAL_STRING(kTXWrapper),
getter_AddRefs(wrapper));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create wrapper element");
wrapChildren(mParentNode, wrapper);
mParentNode = wrapper;
mRootContent = do_QueryInterface(wrapper);
mRootContent->SetDocument(document, PR_FALSE, PR_TRUE);
document->SetRootContent(mRootContent);
}
PRBool appendNode = PR_TRUE;
if (isHTML) {
nsCOMPtr<nsIAtom> atom;
currentContent->GetTag(*getter_AddRefs(atom));
if (atom == txHTMLAtoms::script) {
appendNode = PR_FALSE;
mScriptParent = mParentNode;
}
else if (atom == txHTMLAtoms::style) {
mStyleElement = do_QueryInterface(mCurrentNode);
if (mStyleElement) {
// 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.
mStyleElement->InitStyleLinkElement(nsnull, PR_FALSE);
mStyleElement->SetEnableUpdates(PR_FALSE);
}
}
}
if (appendNode) {
if (document && !mRootContent) {
mRootContent = do_QueryInterface(mCurrentNode);
mRootContent->SetDocument(document, PR_FALSE, PR_TRUE);
document->SetRootContent(mRootContent);
}
else {
nsCOMPtr<nsIDOMNode> resultNode;
rv = mParentNode->AppendChild(mCurrentNode, getter_AddRefs(resultNode));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't append node");
}
}
mParentNode = nsnull;
}
else if ((aAction & eFlushText) && !mText.IsEmpty()) {
nsCOMPtr<nsIDOMText> text;
rv = mDocument->CreateTextNode(mText, getter_AddRefs(text));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't create text node");
nsCOMPtr<nsIDOMNode> node = do_QueryInterface(text);
nsCOMPtr<nsIDOMNode> resultNode;
mCurrentNode->AppendChild(node, getter_AddRefs(resultNode));
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't append text node");
if (currentContent && !mHaveTitle) {
nsCOMPtr<nsIAtom> atom;
currentContent->GetTag(*getter_AddRefs(atom));
if ((atom == txHTMLAtoms::title) && mTitleElement) {
// The first title wins
mHaveTitle = PR_TRUE;
nsCOMPtr<nsIDOMNSDocument> domDoc = do_QueryInterface(mDocument);
if (domDoc) {
mText.CompressWhitespace();
domDoc->SetTitle(mText);
}
mTitleElement = nsnull;
}
}
mText.Truncate();
}
}
void txMozillaXMLOutput::startHTMLElement(nsIDOMElement* aElement)
{
nsCOMPtr<nsIAtom> atom;
nsCOMPtr<nsIContent> content = do_QueryInterface(aElement);
content->GetTag(*getter_AddRefs(atom));
if ((atom == txHTMLAtoms::title) && !mHaveTitle) {
mTitleElement = aElement;
}
}
void txMozillaXMLOutput::wrapChildren(nsIDOMNode* aCurrentNode,
nsIDOMElement* aWrapper)
{
nsresult rv;
nsCOMPtr<nsIContent> currentContent;
currentContent = do_QueryInterface(mCurrentNode, &rv);
NS_ASSERTION(NS_SUCCEEDED(rv), "Can't QI to nsIContent");
if (!currentContent)
return;
PRInt32 count, i = 0;
nsCOMPtr<nsIDOMNode> child, resultNode;
nsCOMPtr<nsIContent> childContent;
currentContent->ChildCount(count);
for (i = 0; i < count; i++) {
rv = currentContent->ChildAt(0, *getter_AddRefs(childContent));
if (NS_SUCCEEDED(rv)) {
child = do_QueryInterface(childContent);
aCurrentNode->RemoveChild(child, getter_AddRefs(resultNode));
aWrapper->AppendChild(resultNode, getter_AddRefs(child));
}
}
}

View File

@ -0,0 +1,189 @@
/* -*- 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 the TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* 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 TRANSFRMX_MOZILLA_XML_OUTPUT_H
#define TRANSFRMX_MOZILLA_XML_OUTPUT_H
#include "txXMLEventHandler.h"
#include "nsIContent.h"
#include "nsIDOMDocument.h"
#include "nsIDOMHTMLTextAreaElement.h"
#include "nsINameSpaceManager.h"
#include "nsIStyleSheetLinkingElement.h"
#include "nsString2.h"
#include "nsSupportsArray.h"
#include "txOutputFormat.h"
class txMozillaXMLOutput : public txMozillaXMLEventHandler
{
public:
txMozillaXMLOutput();
virtual ~txMozillaXMLOutput();
/*
* 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 String& aName,
const PRInt32 aNsID,
const String& aValue);
/*
* Signals to receive characters.
*
* @param aData the characters to receive
*/
void characters(const String& aData);
/*
* Signals to receive data that should be treated as a comment.
*
* @param data the comment data to receive
*/
void comment(const String& 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 String& 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 String& aTarget,
const String& 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 String& aName,
const PRInt32 aNsID);
/*
* Sets the output format.
*
* @param aOutputFormat the output format
*/
void setOutputFormat(txOutputFormat* aOutputFormat);
/*
* Disables loading of stylesheets.
*/
void disableStylesheetLoad();
/*
* Returns the root content of the result.
*
* @param aReturn the root content
*/
nsresult getRootContent(nsIContent** aReturn);
/*
* Returns PR_TRUE if the event handler has finished anything
* extra that had to happen after the transform has finished.
*/
PRBool isDone();
/*
* Removes a script element from the array of elements that are
* still loading.
*
* @param aReturn the script element to remove
*/
void removeScriptElement(nsIDOMHTMLScriptElement *aElement);
/*
* Sets the Mozilla output document.
*
* @param aDocument the Mozilla output document
*/
void setOutputDocument(nsIDOMDocument* aDocument);
private:
void closePrevious(PRInt8 aAction);
void startHTMLElement(nsIDOMElement* aElement);
void wrapChildren(nsIDOMNode* aCurrentNode, nsIDOMElement* aWrapper);
nsCOMPtr<nsIDOMDocument> mDocument;
nsCOMPtr<nsIDOMNode> mCurrentNode;
nsCOMPtr<nsIDOMNode> mParentNode;
nsCOMPtr<nsIContent> mRootContent;
nsCOMPtr<nsIDOMNode> mScriptParent;
nsCOMPtr<nsIDOMElement> mTitleElement;
nsCOMPtr<nsIStyleSheetLinkingElement> mStyleElement;
nsCOMPtr<nsINameSpaceManager> mNameSpaceManager;
nsSupportsArray mScriptElements;
nsAutoString mText;
txOutputFormat mOutputFormat;
PRPackedBool mHaveTitle;
PRPackedBool mDisableStylesheetLoad;
enum txAction { eCloseElement = 1, eFlushText = 2 };
};
#endif

View File

@ -42,6 +42,7 @@
#include "Names.h"
#include "ProcessorState.h"
#include "txXPathResultComparator.h"
#include "txAtoms.h"
/*
* Sorts Nodes as specified by the W3C XSLT 1.0 Recommendation
@ -98,7 +99,7 @@ MBool txNodeSorter::addSortElement(Element* aSortElement,
// Order
MBool ascending;
MBool hasAttr = getAttrAsAVT(aSortElement, ORDER_ATTR, aContext, attrValue);
MBool hasAttr = getAttrAsAVT(aSortElement, txXSLTAtoms::order, aContext, attrValue);
if (!hasAttr || attrValue.isEqual(ASCENDING_VALUE)) {
ascending = MB_TRUE;
}
@ -114,18 +115,18 @@ MBool txNodeSorter::addSortElement(Element* aSortElement,
// Create comparator depending on datatype
String dataType;
hasAttr = getAttrAsAVT(aSortElement, DATA_TYPE_ATTR, aContext, dataType);
hasAttr = getAttrAsAVT(aSortElement, txXSLTAtoms::dataType, aContext, dataType);
if (!hasAttr || dataType.isEqual(TEXT_VALUE)) {
// Text comparator
// Language
String lang;
if (!getAttrAsAVT(aSortElement, LANG_ATTR, aContext, lang))
if (!getAttrAsAVT(aSortElement, txXSLTAtoms::lang, aContext, lang))
lang = DEFAULT_LANG;
// Case-order
MBool upperFirst;
hasAttr = getAttrAsAVT(aSortElement, CASE_ORDER_ATTR, aContext, attrValue);
hasAttr = getAttrAsAVT(aSortElement, txXSLTAtoms::caseOrder, aContext, attrValue);
if (!hasAttr || attrValue.isEqual(UPPER_FIRST_VALUE)) {
upperFirst = MB_TRUE;
}
@ -263,17 +264,16 @@ int txNodeSorter::compareNodes(SortableNode* aSNode1,
}
MBool txNodeSorter::getAttrAsAVT(Element* aSortElement,
const String& aAttrName,
txAtom* aAttrName,
Node* aContext,
String& aResult)
{
aResult.clear();
Node* tempNode = aSortElement->getAttributeNode(aAttrName);
if (!tempNode)
String attValue;
if (!aSortElement->getAttr(aAttrName, kNameSpaceID_None, attValue))
return MB_FALSE;
const String& attValue = tempNode->getNodeValue();
mPs->processAttrValueTemplate(attValue, aContext, aResult);
return MB_TRUE;
}

View File

@ -42,6 +42,7 @@
#include "baseutils.h"
#include "List.h"
#include "txAtom.h"
class Element;
class Expr;
@ -85,7 +86,7 @@ private:
SortableNode* sNode2);
MBool getAttrAsAVT(Element* aSortElement,
const String& aAttrName,
txAtom* aAttrName,
Node* aContext,
String& aResult);

View File

@ -0,0 +1,162 @@
/* -*- 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 the TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* 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 "txOutputFormat.h"
#include "XMLUtils.h"
txOutputFormat::txOutputFormat() : mMethod(eMethodNotSet),
mOmitXMLDeclaration(eNotSet),
mStandalone(eNotSet),
mIndent(eNotSet)
{
}
txOutputFormat::~txOutputFormat()
{
txListIterator iter(&mCDATASectionElements);
while (iter.hasNext())
delete (txExpandedName*)iter.next();
}
void txOutputFormat::reset()
{
mMethod = eMethodNotSet;
mVersion.clear();
if (mEncoding.isEmpty())
mOmitXMLDeclaration = eNotSet;
mStandalone = eNotSet;
mPublicId.clear();
mSystemId.clear();
txListIterator iter(&mCDATASectionElements);
while (iter.hasNext())
delete (txExpandedName*)iter.next();
mIndent = eNotSet;
mMediaType.clear();
}
void txOutputFormat::merge(txOutputFormat& aOutputFormat)
{
if (mMethod == eMethodNotSet)
mMethod = aOutputFormat.mMethod;
if (mVersion.isEmpty())
mVersion = aOutputFormat.mVersion;
if (mEncoding.isEmpty())
mEncoding = aOutputFormat.mEncoding;
if (mOmitXMLDeclaration == eNotSet)
mOmitXMLDeclaration = aOutputFormat.mOmitXMLDeclaration;
if (mStandalone == eNotSet)
mStandalone = aOutputFormat.mStandalone;
if (mPublicId.isEmpty())
mPublicId = aOutputFormat.mPublicId;
if (mSystemId.isEmpty())
mSystemId = aOutputFormat.mSystemId;
txListIterator iter(&aOutputFormat.mCDATASectionElements);
txExpandedName* qName;
while ((qName = (txExpandedName*)iter.next())) {
mCDATASectionElements.add(qName);
// XXX We need txList.clear()
iter.remove();
}
if (mIndent == eNotSet)
mIndent = aOutputFormat.mIndent;
if (mMediaType.isEmpty())
mMediaType = aOutputFormat.mMediaType;
}
void txOutputFormat::setFromDefaults()
{
if (mMethod == eMethodNotSet)
mMethod = eXMLOutput;
switch (mMethod) {
case eXMLOutput:
{
if (mVersion.isEmpty())
mVersion = "1.0";
if (mEncoding.isEmpty())
mEncoding = "UTF-8";
if (mOmitXMLDeclaration == eNotSet)
mOmitXMLDeclaration = eFalse;
if (mIndent == eNotSet)
mIndent = eFalse;
if (mMediaType.isEmpty())
mMediaType = "text/xml";
break;
}
case eHTMLOutput:
{
if (mVersion.isEmpty())
mVersion = "4.0";
if (mEncoding.isEmpty())
mEncoding = "UTF-8";
if (mIndent == eNotSet)
mIndent = eTrue;
if (mMediaType.isEmpty())
mMediaType = "text/html";
break;
}
case eTextOutput:
{
if (mEncoding.isEmpty())
mEncoding = "UTF-8";
if (mMediaType.isEmpty())
mMediaType = "text/plain";
break;
}
}
}

View File

@ -0,0 +1,107 @@
/* -*- 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 the TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* 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 TRANSFRMX_OUTPUTFORMAT_H
#define TRANSFRMX_OUTPUTFORMAT_H
#include "baseutils.h"
#include "List.h"
#include "TxString.h"
enum txOutputMethod {
eMethodNotSet,
eXMLOutput,
eHTMLOutput,
eTextOutput
};
enum txThreeState {
eNotSet,
eFalse,
eTrue
};
class txOutputFormat {
public:
txOutputFormat();
~txOutputFormat();
// "Unset" all values
void reset();
// Merges in the values of aOutputFormat, members that already
// have a value in this txOutputFormat will not be changed.
void merge(txOutputFormat& aOutputFormat);
// Sets members that have no value to their default value.
void setFromDefaults();
// The XSLT output method, which can be "xml", "html", or "text"
txOutputMethod mMethod;
// The xml version number that should be used when serializing
// xml documents
String mVersion;
// The XML character encoding that should be used when serializing
// xml documents
String mEncoding;
// Signals if we should output an XML declaration
txThreeState mOmitXMLDeclaration;
// Signals if we should output a standalone document declaration
txThreeState mStandalone;
// The public Id for creating a DOCTYPE
String mPublicId;
// The System Id for creating a DOCTYPE
String mSystemId;
// The elements whose text node children should be output as CDATA
txList mCDATASectionElements;
// Signals if output should be indented
txThreeState mIndent;
// The media type of the output
String mMediaType;
};
#endif

View File

@ -0,0 +1,146 @@
/* -*- 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 the TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* 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 "txRtfHandler.h"
txRtfHandler::txRtfHandler(Document* aDocument,
txResultTreeFragment* aResultTreeFragment) :
mDocument(aDocument),
mResultTreeFragment(aResultTreeFragment)
{
NS_ASSERTION(mDocument, "We need a valid document");
if (!mDocument)
return;
NS_ASSERTION(mResultTreeFragment, "We need a valid result tree fragment");
if (!mResultTreeFragment)
return;
DocumentFragment* fragment = mDocument->createDocumentFragment();
NS_ASSERTION(fragment, "Out of memory creating a document fragmen");
// XXX ErrorReport: Out of memory
mResultTreeFragment->add(fragment);
mCurrentNode = fragment;
}
txRtfHandler::~txRtfHandler()
{
}
void txRtfHandler::attribute(const String& aName,
const PRInt32 aNsID,
const String& aValue)
{
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;
String nsURI;
mDocument->namespaceIDToURI(aNsID, nsURI);
element->setAttributeNS(nsURI, aName, aValue);
}
void txRtfHandler::characters(const String& aData)
{
NS_ASSERTION(mCurrentNode, "We need a node");
if (!mCurrentNode)
return;
Text* text = mDocument->createTextNode(aData);
mCurrentNode->appendChild(text);
}
void txRtfHandler::comment(const String& aData)
{
NS_ASSERTION(mCurrentNode, "We need a node");
if (!mCurrentNode)
return;
Comment* comment = mDocument->createComment(aData);
mCurrentNode->appendChild(comment);
}
void txRtfHandler::endDocument()
{
}
void txRtfHandler::endElement(const String& aName,
const PRInt32 aNsID)
{
NS_ASSERTION(mCurrentNode, "We need a node");
if (!mCurrentNode)
return;
mCurrentNode = mCurrentNode->getParentNode();
}
void txRtfHandler::processingInstruction(const String& aTarget,
const String& 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 String& aName,
const PRInt32 aNsID)
{
NS_ASSERTION(mCurrentNode, "We need a node");
if (!mCurrentNode)
return;
String nsURI;
mDocument->namespaceIDToURI(aNsID, nsURI);
Element* element = mDocument->createElementNS(nsURI, aName);
mCurrentNode->appendChild(element);
mCurrentNode = element;
}

View File

@ -0,0 +1,121 @@
/* -*- 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 the TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* 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 TRANSFRMX_RTF_HANDLER_H
#define TRANSFRMX_RTF_HANDLER_H
#include "txXMLEventHandler.h"
#include "NodeSet.h"
class txRtfHandler : public txXMLEventHandler
{
public:
txRtfHandler(Document* aDocument,
txResultTreeFragment* aResultTreeFragment);
virtual ~txRtfHandler();
/**
* 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 String& aName,
const PRInt32 aNsID,
const String& aValue);
/**
* Signals to receive characters.
*
* @param aData the characters to receive
*/
void characters(const String& aData);
/**
* Signals to receive data that should be treated as a comment.
*
* @param data the comment data to receive
*/
void comment(const String& 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 String& 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 String& aTarget,
const String& 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 String& aName,
const PRInt32 aNsID);
private:
Document* mDocument;
txResultTreeFragment* mResultTreeFragment;
Node* mCurrentNode;
};
#endif

View File

@ -38,8 +38,9 @@ ExprResult* SystemPropertyFunctionCall::evaluate(Node* context, ContextState* cs
String property;
exprResult->stringValue(property);
if (XMLUtils::isValidQName(property)) {
String propertyNsURI;
cs->getNameSpaceURI(property, propertyNsURI);
String propertyNsURI, prefix;
XMLUtils::getLocalPart(property, prefix);
cs->getNameSpaceURIFromPrefix(prefix, propertyNsURI);
if (propertyNsURI.isEqual(XSLT_NS)) {
String localName;
XMLUtils::getLocalPart(property, localName);

View File

@ -0,0 +1,93 @@
/* -*- 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 the TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* 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 "txTextHandler.h"
#include "TxString.h"
txTextHandler::txTextHandler(String& aValue, MBool aOnlyText) : mLevel(0),
mValue(aValue),
mOnlyText(aOnlyText)
{
}
txTextHandler::~txTextHandler()
{
}
void txTextHandler::attribute(const String& aName,
const PRInt32 aNsID,
const String& aValue)
{
}
void txTextHandler::characters(const String& aData)
{
if (mLevel == 0)
mValue.append(aData);
}
void txTextHandler::comment(const String& aData)
{
}
void txTextHandler::endDocument()
{
}
void txTextHandler::endElement(const String& aName,
const PRInt32 aNsID)
{
if (mOnlyText)
--mLevel;
}
void txTextHandler::processingInstruction(const String& aTarget,
const String& aData)
{
}
void txTextHandler::startDocument()
{
}
void txTextHandler::startElement(const String& aName,
const PRInt32 aNsID)
{
if (mOnlyText)
++mLevel;
}

View File

@ -0,0 +1,119 @@
/* -*- 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 the TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* 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 TRANSFRMX_TEXT_HANDLER_H
#define TRANSFRMX_TEXT_HANDLER_H
#include "txXMLEventHandler.h"
class txTextHandler : public txXMLEventHandler
{
public:
txTextHandler(String& 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 String& aName,
const PRInt32 aNsID,
const String& aValue);
/*
* Signals to receive characters.
*
* @param aData the characters to receive
*/
void characters(const String& aData);
/*
* Signals to receive data that should be treated as a comment.
*
* @param data the comment data to receive
*/
void comment(const String& 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 String& 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 String& aTarget,
const String& 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 String& aName,
const PRInt32 aNsID);
private:
PRUint32 mLevel;
String& mValue;
MBool mOnlyText;
};
#endif

View File

@ -0,0 +1,109 @@
/* -*- 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 the TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* 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 "txTextOutput.h"
#include "TxString.h"
txTextOutput::txTextOutput()
{
}
txTextOutput::~txTextOutput()
{
}
void txTextOutput::attribute(const String& aName,
const PRInt32 aNsID,
const String& aValue)
{
}
void txTextOutput::characters(const String& aData)
{
*mOut << aData;
}
void txTextOutput::charactersNoOutputEscaping(const String& aData)
{
characters(aData);
}
void txTextOutput::comment(const String& aData)
{
}
void txTextOutput::endDocument()
{
}
void txTextOutput::endElement(const String& aName,
const PRInt32 aNsID)
{
}
void txTextOutput::processingInstruction(const String& aTarget,
const String& aData)
{
}
void txTextOutput::startDocument()
{
}
void txTextOutput::startElement(const String& aName,
const PRInt32 aNsID)
{
}
void txTextOutput::getOutputStream(ostream** aOutputStream)
{
if (aOutputStream)
aOutputStream = mOut;
}
void txTextOutput::setOutputStream(ostream* aOutputStream)
{
mOut = aOutputStream;
}
void txTextOutput::setOutputFormat(txOutputFormat* aOutputFormat)
{
mOutputFormat.reset();
mOutputFormat.merge(*aOutputFormat);
mOutputFormat.setFromDefaults();
}

View File

@ -0,0 +1,147 @@
/* -*- 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 the TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* 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 TRANSFRMX_TEXT_OUTPUT_H
#define TRANSFRMX_TEXT_OUTPUT_H
#include "txXMLEventHandler.h"
#include "txOutputFormat.h"
class txTextOutput : public txStreamXMLEventHandler
{
public:
txTextOutput();
~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 String& aName,
const PRInt32 aNsID,
const String& aValue);
/*
* Signals to receive characters.
*
* @param aData the characters to receive
*/
void characters(const String& aData);
/*
* Signals to receive characters that don't need output escaping.
*
* @param aData the characters to receive
*/
virtual void charactersNoOutputEscaping(const String& aData);
/*
* Signals to receive data that should be treated as a comment.
*
* @param data the comment data to receive
*/
void comment(const String& 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 String& 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 String& aTarget,
const String& 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 String& aName,
const PRInt32 aNsID);
/*
* Sets the output format.
*
* @param aOutputFormat the output format
*/
void setOutputFormat(txOutputFormat* aOutputFormat);
/**
* Get the output stream.
*
* @param aOutputStream the current output stream
*/
void getOutputStream(ostream** aOutputStream);
/**
* Sets the output stream.
*
* @param aDocument the Mozilla output document
*/
void setOutputStream(ostream* aOutputStream);
private:
ostream* mOut;
txOutputFormat mOutputFormat;
};
#endif

View File

@ -0,0 +1,180 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* 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 Keith Visco.
* Portions created by Keith Visco
* (C) 1999-2000 Keith Visco. All Rights Reserved.
*
* Contributor(s):
* Keith Visco <kvisco@ziplink.net>
*
*/
#ifndef TRANSFRMX_XML_EVENT_HANDLER_H
#define TRANSFRMX_XML_EVENT_HANDLER_H
#include "baseutils.h"
class String;
class txOutputFormat;
#ifdef TX_EXE
#include <iostream.h>
#else
class nsIContent;
class nsIDOMDocument;
class nsIDOMHTMLScriptElement;
#endif
/*
* An interface for handling XML documents, loosely modeled
* after Dave Megginson's SAX 1.0 API.
*/
class txXMLEventHandler
{
public:
virtual ~txXMLEventHandler() {};
/*
* 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 String& aName,
const PRInt32 aNsID,
const String& aValue) = 0;
/*
* Signals to receive characters.
*
* @param aData the characters to receive
*/
virtual void characters(const String& aData) = 0;
/*
* Signals to receive data that should be treated as a comment.
*
* @param data the comment data to receive
*/
virtual void comment(const String& aData) = 0;
/*
* Signals the end of a document. It is an error to call
* this method more than once.
*/
virtual void endDocument() = 0;
/*
* 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 String& aName,
const PRInt32 aNsID) = 0;
/*
* 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 String& aTarget,
const String& aData) = 0;
/*
* Signals the start of a document.
*/
virtual void startDocument() = 0;
/*
* 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 String& aName,
const PRInt32 aNsID) = 0;
};
class txOutputXMLEventHandler : public txXMLEventHandler
{
public:
/*
* Sets the output format.
*
* @param aOutputFormat the output format
*/
virtual void setOutputFormat(txOutputFormat* aOutputFormat) = 0;
};
#ifdef TX_EXE
class txStreamXMLEventHandler : public txOutputXMLEventHandler
{
public:
/*
* Sets the output stream.
*
* @param aOutputStream the output stream
*/
virtual void setOutputStream(ostream* aOutputStream) = 0;
/*
* Signals to receive characters that don't need output escaping.
*
* @param aData the characters to receive
*/
virtual void charactersNoOutputEscaping(const String& aData) = 0;
};
#else
class txMozillaXMLEventHandler : public txOutputXMLEventHandler
{
public:
/*
* Disables loading of stylesheets.
*/
virtual void disableStylesheetLoad() = 0;
/*
* Returns the root content of the result.
*
* @param aReturn the root content
*/
virtual nsresult getRootContent(nsIContent** aReturn) = 0;
/*
* Returns PR_TRUE if the event handler has finished anything
* extra that had to happen after the transform has finished.
*/
virtual PRBool isDone() = 0;
/*
* Removes a script element from the array of elements that are
* still loading.
*
* @param aReturn the script element to remove
*/
virtual void removeScriptElement(nsIDOMHTMLScriptElement *aElement) = 0;
/*
* Sets the Mozilla output document.
*
* @param aDocument the Mozilla output document
*/
virtual void setOutputDocument(nsIDOMDocument* aDocument) = 0;
};
#endif
#endif

View File

@ -0,0 +1,367 @@
/* -*- 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 the TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* 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 "txXMLOutput.h"
const int txXMLOutput::DEFAULT_INDENT = 2;
txAttribute::txAttribute(PRInt32 aNsID, txAtom* aLocalName, const String& aValue) :
mName(aNsID, aLocalName),
mValue(aValue),
mShorthand(MB_FALSE)
{
}
txXMLOutput::txXMLOutput() : mUseEmptyElementShorthand(MB_TRUE),
mHaveDocumentElement(MB_FALSE),
mStartTagOpen(MB_FALSE),
mAfterEndTag(MB_FALSE),
mInCDATASection(MB_FALSE),
mIndentLevel(0)
{
}
txXMLOutput::~txXMLOutput()
{
}
void txXMLOutput::attribute(const String& aName,
const PRInt32 aNsID,
const String& aValue)
{
if (!mStartTagOpen)
// XXX Signal this? (can't add attributes after element closed)
return;
txListIterator iter(&mAttributes);
String localPart;
XMLUtils::getLocalPart(aName, localPart);
txAtom* localName = TX_GET_ATOM(localPart);
txExpandedName att(aNsID, localName);
txAttribute* setAtt = 0;
while ((setAtt = (txAttribute*)iter.next())) {
if (setAtt->mName == att) {
setAtt->mValue = aValue;
break;
}
}
if (!setAtt) {
setAtt = new txAttribute(aNsID, localName, aValue);
mAttributes.add(setAtt);
}
TX_IF_RELEASE_ATOM(localName);
}
void txXMLOutput::characters(const String& aData)
{
closeStartTag(MB_FALSE);
if (mInCDATASection) {
PRInt32 i = 0;
PRInt32 j = 0;
PRInt32 length = aData.length();
*mOut << CDATA_START;
if (length <= 3) {
printUTF8Chars(aData);
}
else {
mBuffer[j++] = aData.charAt(i++);
mBuffer[j++] = aData.charAt(i++);
mBuffer[j++] = aData.charAt(i++);
while (i < length) {
mBuffer[j++] = aData.charAt(i++);
if (mBuffer[(j - 1) % 4] == ']' &&
mBuffer[j % 4] == ']' &&
mBuffer[(j + 1) % 4] == '>') {
*mOut << CDATA_END;
*mOut << CDATA_START;
}
j = j % 4;
printUTF8Char(mBuffer[j]);
}
j = ++j % 4;
printUTF8Char(mBuffer[j]);
j = ++j % 4;
printUTF8Char(mBuffer[j]);
j = ++j % 4;
printUTF8Char(mBuffer[j]);
}
*mOut << CDATA_END;
}
else {
printWithXMLEntities(aData);
}
}
void txXMLOutput::charactersNoOutputEscaping(const String& aData)
{
closeStartTag(MB_FALSE);
printUTF8Chars(aData);
}
void txXMLOutput::comment(const String& aData)
{
closeStartTag(MB_FALSE);
if (&aData == &NULL_STRING)
return;
if (mOutputFormat.mIndent == eTrue) {
for (PRUint32 i = 0; i < mIndentLevel; i++)
*mOut << ' ';
}
*mOut << COMMENT_START;
printUTF8Chars(aData);
*mOut << COMMENT_END;
if (mOutputFormat.mIndent == eTrue)
*mOut << endl;
}
void txXMLOutput::endDocument()
{
}
void txXMLOutput::endElement(const String& aName,
const PRInt32 aNsID)
{
MBool newLine = (mOutputFormat.mIndent == eTrue) && mAfterEndTag;
MBool writeEndTag = !(mStartTagOpen && mUseEmptyElementShorthand);
closeStartTag(mUseEmptyElementShorthand);
if (newLine)
*mOut << endl;
if (mOutputFormat.mIndent == eTrue)
mIndentLevel -= DEFAULT_INDENT;
if (writeEndTag) {
if (newLine) {
for (PRUint32 i = 0; i < mIndentLevel; i++)
*mOut << ' ';
}
*mOut << L_ANGLE_BRACKET << FORWARD_SLASH;
*mOut << aName;
*mOut << R_ANGLE_BRACKET;
}
if (mOutputFormat.mIndent == eTrue)
*mOut << endl;
mAfterEndTag = MB_TRUE;
mInCDATASection = (MBool)mCDATASections.pop();
}
void txXMLOutput::processingInstruction(const String& aTarget,
const String& aData)
{
closeStartTag(MB_FALSE);
if (mOutputFormat.mIndent == eTrue) {
for (PRUint32 i = 0; i < mIndentLevel; i++)
*mOut << ' ';
}
*mOut << PI_START << aTarget << SPACE << aData << PI_END;
if (mOutputFormat.mIndent == eTrue)
*mOut << endl;
}
void txXMLOutput::startDocument()
{
if (mOutputFormat.mMethod == eMethodNotSet) {
// XXX We should "cache" content until we have a
// document element
}
*mOut << PI_START << XML_DECL << DOUBLE_QUOTE;
*mOut << XML_VERSION;
*mOut << DOUBLE_QUOTE << PI_END << endl;
}
void txXMLOutput::startElement(const String& aName,
const PRInt32 aNsID)
{
if (!mHaveDocumentElement) {
// XXX Output doc type and "cached" content
mHaveDocumentElement = MB_TRUE;
}
MBool newLine = mStartTagOpen || mAfterEndTag;
closeStartTag(MB_FALSE);
if (mOutputFormat.mIndent == eTrue) {
if (newLine) {
*mOut << endl;
for (PRUint32 i = 0; i < mIndentLevel; i++)
*mOut << ' ';
}
}
*mOut << L_ANGLE_BRACKET;
*mOut << aName;
mStartTagOpen = MB_TRUE;
if (mOutputFormat.mIndent == eTrue)
mIndentLevel += DEFAULT_INDENT;
mCDATASections.push((void*)mInCDATASection);
mInCDATASection = MB_FALSE;
txAtom* localName = TX_GET_ATOM(aName);
txExpandedName currentElement(aNsID, localName);
TX_IF_RELEASE_ATOM(localName);
txListIterator iter(&(mOutputFormat.mCDATASectionElements));
while (iter.hasNext()) {
if (currentElement == *(txExpandedName*)iter.next()) {
mInCDATASection = MB_TRUE;
break;
}
}
}
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;
if (mStartTagOpen) {
txListIterator iter(&mAttributes);
txAttribute* att;
while ((att = (txAttribute*)iter.next())) {
*mOut << SPACE;
*mOut << *(att->mName.mLocalName);
if (!att->mShorthand) {
*mOut << EQUALS << DOUBLE_QUOTE;
printWithXMLEntities(att->mValue, MB_TRUE);
*mOut << DOUBLE_QUOTE;
}
delete (txAttribute*)iter.remove();
}
if (aUseEmptyElementShorthand)
*mOut << FORWARD_SLASH;
*mOut << R_ANGLE_BRACKET;
mStartTagOpen = MB_FALSE;
}
}
void txXMLOutput::printUTF8Char(DOM_CHAR& ch)
{
// DOM_CHAR is 16-bits so we only need to cover up to 0xFFFF
// 0x0000-0x007F
if (ch < 128) {
*mOut << (char)ch;
}
// 0x0080-0x07FF
else if (ch < 2048) {
*mOut << (char) (192+(ch/64)); // 0xC0 + x/64
*mOut << (char) (128+(ch%64)); // 0x80 + x%64
}
// 0x800-0xFFFF
else {
*mOut << (char) (224+(ch/4096)); // 0xE0 + x/64^2
*mOut << (char) (128+((ch/64)%64)); // 0x80 + (x/64)%64
*mOut << (char) (128+(ch%64)); // 0x80 + x%64
}
}
void txXMLOutput::printUTF8Chars(const String& aData)
{
DOM_CHAR currChar;
PRInt32 i = 0;
while (i < aData.length()) {
currChar = aData.charAt(i++);
printUTF8Char(currChar);
}
}
void txXMLOutput::printWithXMLEntities(const String& aData,
MBool aAttribute)
{
DOM_CHAR currChar;
PRInt32 i;
if (&aData == &NULL_STRING)
return;
for (i = 0; i < aData.length(); i++) {
currChar = aData.charAt(i);
switch (currChar) {
case AMPERSAND:
*mOut << AMP_ENTITY;
break;
case APOSTROPHE:
if (aAttribute)
*mOut << APOS_ENTITY;
else
printUTF8Char(currChar);
break;
case GT:
*mOut << GT_ENTITY;
break;
case LT:
*mOut << LT_ENTITY;
break;
case QUOTE:
if (aAttribute)
*mOut << QUOT_ENTITY;
else
printUTF8Char(currChar);
break;
default:
printUTF8Char(currChar);
break;
}
}
*mOut << flush;
}

View File

@ -0,0 +1,215 @@
/* -*- 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 the TransforMiiX XSLT processor.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2001
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* 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 TRANSFRMX_XML_OUTPUT_H
#define TRANSFRMX_XML_OUTPUT_H
#include "txXMLEventHandler.h"
#include "dom.h"
#include "List.h"
#include "Stack.h"
#include "txOutputFormat.h"
#include "XMLUtils.h"
#define DASH '-'
#define TX_CR '\r'
#define TX_LF '\n'
#define AMPERSAND '&'
#define APOSTROPHE '\''
#define GT '>'
#define LT '<'
#define QUOTE '"'
#define AMP_ENTITY "&amp"
#define APOS_ENTITY "&apos"
#define GT_ENTITY "&gt;"
#define LT_ENTITY "&lt;"
#define QUOT_ENTITY "&quot"
#define HEX_ENTITY "&#"
#define CDATA_END "]]>"
#define CDATA_START "<![CDATA["
#define COMMENT_START "<!--"
#define COMMENT_END "-->"
#define DOCTYPE_START "<!DOCTYPE "
#define DOCTYPE_END ">"
#define DOUBLE_QUOTE "\""
#define EQUALS "="
#define FORWARD_SLASH "/"
#define L_ANGLE_BRACKET "<"
#define PI_START "<?"
#define PI_END "?>"
#define PUBLIC "PUBLIC"
#define R_ANGLE_BRACKET ">"
#define SEMICOLON ";"
#define SPACE " "
#define SYSTEM "SYSTEM"
#define XML_DECL "xml version="
#define XML_VERSION "1.0"
class txAttribute {
public:
txAttribute(PRInt32 aNsID, txAtom* aLocalName, const String& aValue);
txExpandedName mName;
String mValue;
MBool mShorthand;
};
class txXMLOutput : public txStreamXMLEventHandler
{
public:
txXMLOutput();
virtual ~txXMLOutput();
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 String& aName,
const PRInt32 aNsID,
const String& aValue);
/*
* Signals to receive characters.
*
* @param aData the characters to receive
*/
virtual void characters(const String& aData);
/*
* Signals to receive characters that don't need output escaping.
*
* @param aData the characters to receive
*/
virtual void charactersNoOutputEscaping(const String& aData);
/*
* Signals to receive data that should be treated as a comment.
*
* @param data the comment data to receive
*/
void comment(const String& 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 String& 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
*/
virtual void processingInstruction(const String& aTarget,
const String& 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 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);
void printUTF8Chars(const String& aData);
void printWithXMLEntities(const String& aData, MBool aAttribute = MB_FALSE);
void write(const String& aData);
ostream* mOut;
txOutputFormat mOutputFormat;
MBool mUseEmptyElementShorthand;
MBool mHaveDocumentElement;
MBool mStartTagOpen;
MBool mAfterEndTag;
MBool mInCDATASection;
PRUint32 mIndentLevel;
txList mAttributes;
Stack mCDATASections;
private:
DOM_CHAR mBuffer[4];
};
#endif

View File

@ -42,6 +42,7 @@ TX_ATOM(applyTemplates, "apply-templates");
TX_ATOM(attribute, "attribute");
TX_ATOM(attributeSet, "attribute-set");
TX_ATOM(callTemplate, "call-template");
TX_ATOM(caseOrder, "case-order");
TX_ATOM(choose, "choose");
TX_ATOM(comment, "comment");
TX_ATOM(copy, "copy");
@ -77,8 +78,8 @@ TX_ATOM(cdataSectionElements, "cdata-section-elements");
TX_ATOM(count, "count");
TX_ATOM(dataType, "data-type");
TX_ATOM(decimalSeparator, "decimal-separator");
TX_ATOM(defaultSpace, "default-space");
TX_ATOM(digit, "digit");
TX_ATOM(disableOutputEscaping, "disable-output-escaping");
TX_ATOM(doctypePublic, "doctype-public");
TX_ATOM(doctypeSystem, "doctype-system");
TX_ATOM(elements, "elements");