Fix whitespacehandling by looking for xml:space-attributes when needed and only when needed.

b=163856 r=Pike sr=bz
This commit is contained in:
sicking%bigfoot.com 2002-08-27 04:13:18 +00:00
Родитель 855dbe7bce
Коммит 75dc9786ce
9 изменённых файлов: 57 добавлений и 83 удалений

Просмотреть файл

@ -53,7 +53,9 @@
#define XML_ATOMS \
TX_ATOM(_empty, ""); \
TX_ATOM(base, "base"); \
TX_ATOM(_default, "default"); \
TX_ATOM(lang, "lang"); \
TX_ATOM(preserve, "preserve"); \
TX_ATOM(space, "space"); \
TX_ATOM(xml, "xml"); \
TX_ATOM(xmlns, "xmlns")

Просмотреть файл

@ -43,6 +43,7 @@ CPPSRCS = XMLDOMUtils.cpp XMLUtils.cpp
include $(topsrcdir)/config/rules.mk
INCLUDES += -I$(srcdir)/../base -I$(srcdir)/dom
INCLUDES += -I$(srcdir)/../base -I$(srcdir)/dom -I$(srcdir)/../xpath \
-I$(srcdir)/../xslt
libs:: $(OBJS)

Просмотреть файл

@ -30,6 +30,7 @@
*/
#include "XMLUtils.h"
#include "txAtoms.h"
nsresult txExpandedName::init(const String& aQName,
Node* aResolver,
@ -186,6 +187,37 @@ void XMLUtils::normalizePIValue(String& piValue)
}
}
/*
* Walks up the document tree and returns true if the closest xml:space
* attribute is "preserve"
*/
//static
MBool XMLUtils::getXMLSpacePreserve(Node* aNode)
{
NS_ASSERTION(aNode, "Calling preserveXMLSpace with NULL node!");
String value;
Node* parent = aNode;
while (parent) {
if (parent->getNodeType() == Node::ELEMENT_NODE) {
Element* elem = (Element*)parent;
if (elem->getAttr(txXMLAtoms::space, kNameSpaceID_XML, value)) {
txAtom* val = TX_GET_ATOM(value);
if (val == txXMLAtoms::preserve) {
TX_IF_RELEASE_ATOM(val);
return MB_TRUE;
}
if (val == txXMLAtoms::_default) {
TX_IF_RELEASE_ATOM(val);
return MB_FALSE;
}
}
}
parent = parent->getParentNode();
}
return MB_FALSE;
}
// macros for inclusion of char range headers
#define TX_CHAR_RANGE(ch, a, b) if (ch < a) return MB_FALSE; \
if (ch <= b) return MB_TRUE

Просмотреть файл

@ -137,7 +137,12 @@ public:
* Returns true if the given character is an allowable NCName character
*/
static MBool isNCNameChar(UNICODE_CHAR ch);
/*
* Walks up the document tree and returns true if the closest xml:space
* attribute is "preserve"
*/
static MBool getXMLSpacePreserve(Node* aNode);
};
#endif

Просмотреть файл

@ -46,7 +46,6 @@ const String ASCENDING_VALUE("ascending");
const String DESCENDING_VALUE("descending");
const String LOWER_FIRST_VALUE("lower-first");
const String NUMBER_VALUE("number");
const String PRESERVE_VALUE("preserve");
const String TEXT_VALUE("text");
const String UPPER_FIRST_VALUE("upper-first");
const String YES_VALUE("yes");

Просмотреть файл

@ -44,7 +44,6 @@ extern const String ASCENDING_VALUE;
extern const String DESCENDING_VALUE;
extern const String LOWER_FIRST_VALUE;
extern const String NUMBER_VALUE;
extern const String PRESERVE_VALUE;
extern const String TEXT_VALUE;
extern const String UPPER_FIRST_VALUE;
extern const String YES_VALUE;

Просмотреть файл

@ -673,17 +673,6 @@ void ProcessorState::setLocalVariables(txVariableMap* aMap)
mLocalVariables = aMap;
}
/*
* Determines if the given XSL node allows Whitespace stripping
*/
MBool ProcessorState::isXSLStripSpaceAllowed(Node* node) {
if (!node)
return MB_FALSE;
return (MBool)(getXMLSpaceMode(node) != PRESERVE);
}
void ProcessorState::processAttrValueTemplate(const String& aAttValue,
Element* aContext,
String& aResult)
@ -1012,12 +1001,12 @@ nsresult ProcessorState::getVariable(PRInt32 aNamespace, txAtom* aLName,
/**
* Determines if the given XML node allows Whitespace stripping
**/
MBool ProcessorState::isStripSpaceAllowed(Node* node)
MBool ProcessorState::isStripSpaceAllowed(Node* aNode)
{
if (!node)
if (!aNode)
return MB_FALSE;
switch (node->getNodeType()) {
switch (aNode->getNodeType()) {
case Node::ELEMENT_NODE:
{
// check Whitespace stipping handling list against given Node
@ -1028,34 +1017,30 @@ MBool ProcessorState::isStripSpaceAllowed(Node* node)
txListIterator iter(&frame->mWhiteNameTests);
while (iter.hasNext()) {
txNameTestItem* iNameTest = (txNameTestItem*)iter.next();
if (iNameTest->matches(node, this))
return iNameTest->stripsSpace();
if (iNameTest->matches(aNode, this)) {
if (iNameTest->stripsSpace() &&
!XMLUtils::getXMLSpacePreserve(aNode)) {
return MB_TRUE;
}
return MB_FALSE;
}
}
}
if (mOutputFormat.mMethod == eHTMLOutput) {
String ucName = node->getNodeName();
ucName.toUpperCase();
if (ucName.isEqual("SCRIPT"))
return MB_FALSE;
}
break;
}
case Node::TEXT_NODE:
case Node::CDATA_SECTION_NODE:
{
if (!XMLUtils::isWhitespace(node->getNodeValue()))
if (!XMLUtils::isWhitespace(aNode->getNodeValue()))
return MB_FALSE;
return isStripSpaceAllowed(node->getParentNode());
return isStripSpaceAllowed(aNode->getParentNode());
}
case Node::DOCUMENT_NODE:
{
return MB_TRUE;
}
}
XMLSpaceMode mode = getXMLSpaceMode(node);
if (mode == DEFAULT)
return MB_FALSE;
return (MBool)(STRIP == mode);
return MB_FALSE;
}
/**
@ -1129,42 +1114,6 @@ nsresult ProcessorState::resolveFunctionCall(txAtom* aName, PRInt32 aID,
//- Private Methods -/
//-------------------/
/*
* Returns the closest xml:space value for the given Text node
*/
ProcessorState::XMLSpaceMode ProcessorState::getXMLSpaceMode(Node* aNode)
{
NS_ASSERTION(aNode, "Calling getXMLSpaceMode with NULL node!");
Node* parent = aNode;
while (parent) {
switch (parent->getNodeType()) {
case Node::ELEMENT_NODE:
{
String value;
((Element*)parent)->getAttr(txXMLAtoms::space,
kNameSpaceID_XML, value);
if (value.isEqual(PRESERVE_VALUE))
return PRESERVE;
break;
}
case Node::TEXT_NODE:
case Node::CDATA_SECTION_NODE:
{
// We will only see this the first time through the loop
// if the argument node is a text node.
break;
}
default:
{
return DEFAULT;
}
}
parent = parent->getParentNode();
}
return DEFAULT;
}
ProcessorState::ImportFrame::ImportFrame(ImportFrame* aFirstNotImported)
: mNamedTemplates(MB_FALSE),
mMatchableTemplates(MB_TRUE),

Просмотреть файл

@ -264,11 +264,6 @@ public:
*/
void setCurrentTemplateRule(TemplateRule* aTemplateRule);
/**
* Determines if the given XSL node allows Whitespace stripping
**/
MBool isXSLStripSpaceAllowed(Node* node);
/**
* Adds the set of names to the Whitespace preserving element set
**/
@ -352,8 +347,6 @@ public:
private:
enum XMLSpaceMode {STRIP = 0, DEFAULT, PRESERVE};
class MatchableTemplate {
public:
MatchableTemplate(Node* aTemplate, txPattern* aPattern,
@ -450,12 +443,6 @@ private:
Document* mSourceDocument;
Document* xslDocument;
Document* resultDocument;
/**
* Returns the closest xml:space value for the given node
**/
XMLSpaceMode getXMLSpaceMode(Node* aNode);
};
/**

Просмотреть файл

@ -1008,8 +1008,8 @@ void XSLTProcessor::processAction(Node* aNode,
if (nodeType == Node::TEXT_NODE ||
nodeType == Node::CDATA_SECTION_NODE) {
const String& textValue = aXSLTAction->getNodeValue();
if (!aPs->isXSLStripSpaceAllowed(aXSLTAction) ||
!XMLUtils::isWhitespace(textValue)) {
if (!XMLUtils::isWhitespace(textValue) ||
XMLUtils::getXMLSpacePreserve(aXSLTAction)) {
NS_ASSERTION(mResultHandler, "mResultHandler must not be NULL!");
mResultHandler->characters(textValue);
}