Make final fix for bug 74786 (String cleanup) easier by simplifying the Transformiix DOM. r=sicking, sr=jst. r=Pike on the parts not part of the Mozilla build.

This commit is contained in:
peterv%netscape.com 2005-11-02 07:38:53 +00:00
Родитель 577ed7012d
Коммит c93e92f530
11 изменённых файлов: 281 добавлений и 803 удалений

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

@ -33,6 +33,7 @@
#include "txURIUtils.h"
#ifndef TX_EXE
//#include "nsDOMAttribute.h"
#include "nsNetUtil.h"
#include "nsIScriptSecurityManager.h"
#include "nsIDocument.h"
@ -344,19 +345,31 @@ PRBool URIUtils::CanCallerAccess(nsIDOMNode *aNode)
// fails we QI to nsIDocument. If both those QI's fail we won't let
// the caller access this unknown node.
nsCOMPtr<nsIPrincipal> principal;
nsCOMPtr<nsIContent> content(do_QueryInterface(aNode));
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
if (!content) {
// nsCOMPtr<nsIDOMAttributePrivate> attr = do_QueryInterface(aNode);
// if (attr) {
// nsCOMPtr<nsIDOMDocument> domDoc;
// aNode->GetOwnerDocument(getter_AddRefs(domDoc));
// if (!domDoc) {
// }
// }
}
if (!content) {
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aNode);
if (!doc) {
// aNode is neither a nsIContent nor an nsIDocument, something
// weird is going on...
// aNode is neither a nsIContent nor an nsIDOMAttributePrivate nor
// an nsIDocument, something weird is going on...
NS_ERROR("aNode is neither an nsIContent nor an nsIDocument!");
NS_ERROR("aNode is neither an nsIContent nor an "
"nsIDOMAttributePrivate nor an nsIDocument!");
return PR_FALSE;
}
doc->GetPrincipal(getter_AddRefs(principal));
}
else {

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

@ -55,22 +55,12 @@ OBJS =../base/ArrayList.$(OBJ_SUFFIX) \
../base/TxString.$(OBJ_SUFFIX) \
../base/txURIUtils.$(OBJ_SUFFIX) \
../xml/dom/standalone/Attr.$(OBJ_SUFFIX) \
../xml/dom/standalone/CDATASection.$(OBJ_SUFFIX) \
../xml/dom/standalone/DocumentType.$(OBJ_SUFFIX) \
../xml/dom/standalone/EntityReference.$(OBJ_SUFFIX) \
../xml/dom/standalone/CharacterData.$(OBJ_SUFFIX) \
../xml/dom/standalone/Comment.$(OBJ_SUFFIX) \
../xml/dom/standalone/DocumentFragment.$(OBJ_SUFFIX) \
../xml/dom/standalone/DOMImplementation.$(OBJ_SUFFIX) \
../xml/dom/standalone/NodeListDefinition.$(OBJ_SUFFIX) \
../xml/dom/standalone/NodeDefinition.$(OBJ_SUFFIX) \
../xml/dom/standalone/Element.$(OBJ_SUFFIX) \
../xml/dom/standalone/NamedNodeMap.$(OBJ_SUFFIX) \
../xml/dom/standalone/Document.$(OBJ_SUFFIX) \
../xml/dom/standalone/Entity.$(OBJ_SUFFIX) \
../xml/dom/standalone/Notation.$(OBJ_SUFFIX) \
../xml/dom/standalone/ProcessingInstruction.$(OBJ_SUFFIX) \
../xml/dom/standalone/Text.$(OBJ_SUFFIX) \
../xpath/AdditiveExpr.$(OBJ_SUFFIX) \
../xpath/AttributeValueTemplate.$(OBJ_SUFFIX) \
../xpath/BooleanExpr.$(OBJ_SUFFIX) \

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

@ -35,8 +35,6 @@
Attr::Attr(const String& name, Document* owner):
NodeDefinition(Node::ATTRIBUTE_NODE, name, NULL_STRING, owner)
{
specified = MB_FALSE;
int idx = nodeName.indexOf(':');
if (idx == kNotFound) {
mLocalName = TX_GET_ATOM(nodeName);
@ -75,7 +73,6 @@ Attr::Attr(const String& aNamespaceURI,
else
mNamespaceID = txNamespaceManager::getNamespaceID(aNamespaceURI);
specified = MB_TRUE;
String localPart;
XMLUtils::getLocalPart(nodeName, localPart);
mLocalName = TX_GET_ATOM(localPart);
@ -89,22 +86,6 @@ Attr::~Attr()
TX_IF_RELEASE_ATOM(mLocalName);
}
//
//Retrieve the name of the attribute from the nodeName data member
//
const String& Attr::getName() const
{
return nodeName;
}
//
//Retrieve the specified flag
//
MBool Attr::getSpecified() const
{
return specified;
}
//
//Retrieve the value of the attribute. This is a comma-deliminated string
//representation of the Attribute's children.
@ -136,8 +117,6 @@ void Attr::setValue(const String& newValue)
NodeDefinition::DeleteChildren();
appendChild(getOwnerDocument()->createTextNode(newValue));
specified = MB_TRUE;
}
@ -162,30 +141,29 @@ const String& Attr::getNodeValue()
return getValue();
}
//
//First check to see if the new node is an allowable child for an Attr. If it
//is, call NodeDefinition's implementation of Insert Before. If not, return
//is, call NodeDefinition's implementation of AppendChild. If not, return
//null as an error.
//
Node* Attr::insertBefore(Node* newChild, Node* refChild)
Node* Attr::appendChild(Node* newChild)
{
Node* returnVal = NULL;
switch (newChild->getNodeType())
{
case Node::TEXT_NODE :
case Node::ENTITY_REFERENCE_NODE:
returnVal = NodeDefinition::insertBefore(newChild, refChild);
{
// Remove the "newChild" if it is already a child of this node
NodeDefinition* pNewChild = (NodeDefinition*)newChild;
if (pNewChild->getParentNode() == this)
pNewChild = implRemoveChild(pNewChild);
if (returnVal)
specified = MB_TRUE;
break;
return implAppendChild(pNewChild);
}
default:
returnVal = NULL;
break;
}
return returnVal;
return nsnull;
}
//

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

@ -50,17 +50,11 @@ typedef 0 NULL;
#define kTxAttrIndexOffset 0x40000000;
#define kTxChildIndexOffset 0x80000000;
class NodeList;
class NamedNodeMap;
class Document;
class Element;
class Attr;
class Text;
class Comment;
class CDATASection;
class ProcessingInstruction;
class EntityReference;
class DocumentType;
/*
* NULL string for use by Element::getAttribute() for when the attribute
@ -77,22 +71,6 @@ const String NULL_STRING;
// kNameSpaceID_XSLT is 6 for module, see nsINameSpaceManager.h
#define kNameSpaceID_XSLT 3
//
//Definition and Implementation the DOMImplementation class
//
class DOMImplementation
{
public:
DOMImplementation();
~DOMImplementation();
MBool hasFeature(String feature, const String& version) const;
private:
String implFeature;
String implVersion;
};
//
// Abstract Class defining the interface for a Node. See NodeDefinition below
// for the actual implementation of the WC3 node.
@ -124,7 +102,6 @@ class Node : public TxObject
virtual const String& getNodeValue() = 0;
virtual unsigned short getNodeType() const = 0;
virtual Node* getParentNode() const = 0;
virtual NodeList* getChildNodes() = 0;
virtual Node* getFirstChild() const = 0;
virtual Node* getLastChild() const = 0;
virtual Node* getPreviousSibling() const = 0;
@ -136,11 +113,7 @@ class Node : public TxObject
virtual void setNodeValue(const String& nodeValue) = 0;
//Node manipulation functions
virtual Node* insertBefore(Node* newChild, Node* refChild) = 0;
virtual Node* replaceChild(Node* newChild, Node* oldChild) = 0;
virtual Node* removeChild(Node* oldChild) = 0;
virtual Node* appendChild(Node* newChild) = 0;
virtual Node* cloneNode(MBool deep, Node* dest) = 0;
virtual MBool hasChildNodes() const = 0;
@ -256,8 +229,6 @@ class AttrMap : public NamedNodeMap
class NodeDefinition : public Node, public NodeList
{
public:
NodeDefinition(NodeType type, const String& name,
const String& value, Document* owner);
virtual ~NodeDefinition(); //Destructor, delete all children of node
//Read functions
@ -265,7 +236,6 @@ class NodeDefinition : public Node, public NodeList
virtual const String& getNodeValue();
unsigned short getNodeType() const;
Node* getParentNode() const;
NodeList* getChildNodes();
Node* getFirstChild() const;
Node* getLastChild() const;
Node* getPreviousSibling() const;
@ -277,11 +247,7 @@ class NodeDefinition : public Node, public NodeList
virtual void setNodeValue(const String& nodeValue);
//Child node manipulation functions
virtual Node* insertBefore(Node* newChild, Node* refChild);
virtual Node* replaceChild(Node* newChild, Node* oldChild);
virtual Node* removeChild(Node* oldChild);
virtual Node* appendChild(Node* newChild);
Node* cloneNode(MBool deep, Node* dest);
MBool hasChildNodes() const;
@ -302,17 +268,33 @@ class NodeDefinition : public Node, public NodeList
Node* item(PRUint32 index);
PRUint32 getLength();
//Only to be used from XMLParser
void appendData(PRUnichar* aData, int aLength)
{
nodeValue.Append(aData, aLength);
};
protected:
friend class Document;
NodeDefinition(NodeType type, const String& name,
const String& value, Document* owner);
NodeDefinition(NodeType aType, const String& aValue,
Document* aOwner);
//Name, value, and attributes for this node. Available to derrived
//classes, since those derrived classes have a better idea how to use them,
//than the generic node does.
String nodeName;
String nodeValue;
NodeDefinition* implAppendChild(NodeDefinition* newChild);
NodeDefinition* implRemoveChild(NodeDefinition* oldChild);
void DeleteChildren();
Node* implInsertBefore(NodeDefinition* newChild, NodeDefinition* refChild);
private:
void Init(NodeType aType, const String& aValue, Document* aOwner);
//Type of node this is
NodeType nodeType;
@ -351,11 +333,36 @@ class NodeDefinition : public Node, public NodeList
class DocumentFragment : public NodeDefinition
{
public:
DocumentFragment(const String& name, const String& value, Document* owner);
Node* appendChild(Node* newChild)
{
switch (newChild->getNodeType())
{
case Node::ELEMENT_NODE :
case Node::TEXT_NODE :
case Node::COMMENT_NODE :
case Node::PROCESSING_INSTRUCTION_NODE :
{
// Remove the "newChild" if it is already a child of this node
NodeDefinition* pNewChild = (NodeDefinition*)newChild;
if (pNewChild->getParentNode() == this)
pNewChild = implRemoveChild(pNewChild);
//Override insertBefore to limit Elements to having only certain nodes as
//children
Node* insertBefore(Node* newChild, Node* refChild);
return implAppendChild(pNewChild);
}
default:
break;
}
return nsnull;
};
private:
friend class Document;
DocumentFragment(Document* aOwner) :
NodeDefinition(Node::DOCUMENT_FRAGMENT_NODE, NULL_STRING, aOwner)
{
};
};
//
@ -364,38 +371,30 @@ class DocumentFragment : public NodeDefinition
class Document : public NodeDefinition
{
public:
Document(DocumentType* theDoctype = NULL);
Document();
Element* getDocumentElement();
DocumentType* getDoctype();
const DOMImplementation& getImplementation();
//Factory functions for various node types
DocumentFragment* createDocumentFragment();
Node* createComment(const String& aData);
Node* createDocumentFragment();
ProcessingInstruction* createProcessingInstruction(const String& aTarget,
const String& aData);
Node* createTextNode(const String& theData);
Element* createElement(const String& tagName);
Attr* createAttribute(const String& name);
Text* createTextNode(const String& theData);
Comment* createComment(const String& theData);
CDATASection* createCDATASection(const String& theData);
ProcessingInstruction* createProcessingInstruction(const String& target,
const String& data);
EntityReference* createEntityReference(const String& name);
//Override functions to enforce the One Element rule for documents, as well
//as limit documents to certain types of nodes.
Node* insertBefore(Node* newChild, Node* refChild);
Node* replaceChild(Node* newChild, Node* oldChild);
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);
// Node manipulation functions
Node* appendChild(Node* newChild);
//Override to return documentBaseURI
String getBaseURI();
@ -404,8 +403,6 @@ class Document : public NodeDefinition
private:
Element* documentElement;
DocumentType* doctype;
DOMImplementation implementation;
// This class is friend to be able to set the documentBaseURI
friend class XMLParser;
@ -418,28 +415,17 @@ class Document : public NodeDefinition
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
//children
Node* insertBefore(Node* newChild, Node* refChild);
const String& getTagName();
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);
Attr* removeAttributeNode(Attr* oldAttr);
NodeList* getElementsByTagName(const String& name);
void normalize();
// Node manipulation functions
Node* appendChild(Node* newChild);
//txXPathNode functions override
MBool getLocalName(txAtom** aLocalName);
@ -448,6 +434,11 @@ class Element : public NodeDefinition
MBool hasAttr(txAtom* aLocalName, PRInt32 aNSID);
private:
friend class Document;
Element(const String& tagName, Document* owner);
Element(const String& aNamespaceURI, const String& aTagName,
Document* aOwner);
AttrMap mAttributes;
txAtom* mLocalName;
PRInt32 mNamespaceID;
@ -460,17 +451,9 @@ class Element : public NodeDefinition
//
class Attr : public NodeDefinition
{
// 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;
MBool getSpecified() const;
const String& getValue();
void setValue(const String& newValue);
@ -479,9 +462,8 @@ class Attr : public NodeDefinition
void setNodeValue(const String& nodeValue);
const String& getNodeValue();
//Override insertBefore to limit Attr to having only certain nodes as
//children
Node* insertBefore(Node* newChild, Node* refChild);
// Node manipulation functions
Node* appendChild(Node* newChild);
//txXPathNode functions override
MBool getLocalName(txAtom** aLocalName);
@ -489,93 +471,21 @@ class Attr : public NodeDefinition
Node* getXPathParent();
private:
friend class Document;
Attr(const String& name, Document* owner);
Attr(const String& aNamespaceURI, const String& aName,
Document* aOwner);
// These need to be friend to be able to update the ownerElement
friend class AttrMap;
friend class Element;
Element* ownerElement;
MBool specified;
txAtom* mLocalName;
PRInt32 mNamespaceID;
};
//
//Definition and Implementation of CharacterData. This class mearly provides
//the interface and some default implementation. It is not intended to be
//instantiated by users of the DOM
//
class CharacterData : public NodeDefinition
{
public:
const String& getData() const;
void setData(const String& source);
PRUint32 getLength() const;
String& substringData(PRUint32 offset, PRUint32 count, String& dest);
void appendData(const String& arg);
void insertData(PRUint32 offset, const String& arg);
void deleteData(PRUint32 offset, PRUint32 count);
void replaceData(PRUint32 offset, PRUint32 count, const String& arg);
protected:
CharacterData(NodeType type, const String& name,
const String& value, Document* owner);
};
//
//Definition and Implementation of a Text node. The bulk of the functionality
//comes from CharacterData and NodeDefinition.
//
class Text : public CharacterData
{
public:
Text(const String& theData, Document* owner);
Text* splitText(PRUint32 offset);
//Override "child manipulation" function since Text Nodes can not have
//any children.
Node* insertBefore(Node* newChild, Node* refChild);
Node* replaceChild(Node* newChild, Node* oldChild);
Node* removeChild(Node* oldChild);
Node* appendChild(Node* newChild);
protected:
Text(NodeType type, const String& name, const String& value,
Document* owner);
};
//
//Definition and Implementation of a Comment node. All of the functionality is
//inherrited from CharacterData and NodeDefinition.
//
class Comment : public CharacterData
{
public:
Comment(const String& theData, Document* owner);
//Override "child manipulation" function since Comment Nodes can not have
//any children.
Node* insertBefore(Node* newChild, Node* refChild);
Node* replaceChild(Node* newChild, Node* oldChild);
Node* removeChild(Node* oldChild);
Node* appendChild(Node* newChild);
};
//
//Definition and Implementation of a CDATASection node. All of the
//functionality is inherrited from Text, CharacterData, and NodeDefinition
//
class CDATASection : public Text
{
public:
CDATASection(const String& theData, Document* owner);
//Override "child manipulation" function since CDATASection Nodes can not
//have any children.
Node* insertBefore(Node* newChild, Node* refChild);
Node* replaceChild(Node* newChild, Node* oldChild);
Node* removeChild(Node* oldChild);
Node* appendChild(Node* newChild);
};
//
//Definition and Implemention of a ProcessingInstruction node. Most
//functionality is inherrited from NodeDefinition.
@ -587,115 +497,19 @@ class CDATASection : public Text
class ProcessingInstruction : public NodeDefinition
{
public:
ProcessingInstruction(const String& theTarget, const String& theData,
Document* owner);
~ProcessingInstruction();
const String& getTarget() const;
const String& getData() const;
void setData(const String& theData);
//Override "child manipulation" function since ProcessingInstruction Nodes
//can not have any children.
Node* insertBefore(Node* newChild, Node* refChild);
Node* replaceChild(Node* newChild, Node* oldChild);
Node* removeChild(Node* oldChild);
Node* appendChild(Node* newChild);
//txXPathNode functions override
MBool getLocalName(txAtom** aLocalName);
private:
friend class Document;
ProcessingInstruction(const String& theTarget, const String& theData,
Document* owner);
txAtom* mLocalName;
};
//
//Definition and Implementation of a Notation. Most functionality
//is inherrited from NodeDefinition.
//
class Notation : public NodeDefinition
{
public:
Notation(const String& name, const String& pubID,
const String& sysID);
const String& getPublicId() const;
const String& getSystemId() const;
//Override "child manipulation" function since Notation Nodes
//can not have any children.
Node* insertBefore(Node* newChild, Node* refChild);
Node* replaceChild(Node* newChild, Node* oldChild);
Node* removeChild(Node* oldChild);
Node* appendChild(Node* newChild);
private:
String publicId;
String systemId;
};
//
//Definition and Implementation of an Entity
//
class Entity : public NodeDefinition
{
public:
Entity(const String& name, const String& pubID,
const String& sysID, const String& notName);
const String& getPublicId() const;
const String& getSystemId() const;
const String& getNotationName() const;
//Override insertBefore to limit Entity to having only certain nodes as
//children
Node* insertBefore(Node* newChild, Node* refChild);
private:
String publicId;
String systemId;
String notationName;
};
//
//Definition and Implementation of an EntityReference
//
class EntityReference : public NodeDefinition
{
public:
EntityReference(const String& name, Document* owner);
//Override insertBefore to limit EntityReference to having only certain
//nodes as children
Node* insertBefore(Node* newChild, Node* refChild);
};
//
//Definition and Implementation of the DocumentType
//
class DocumentType : public NodeDefinition
{
public:
DocumentType(const String& name, NamedNodeMap* theEntities,
NamedNodeMap* theNotations);
~DocumentType();
NamedNodeMap* getEntities();
NamedNodeMap* getNotations();
//Override "child manipulation" function since Notation Nodes
//can not have any children.
Node* insertBefore(Node* newChild, Node* refChild);
Node* replaceChild(Node* newChild, Node* oldChild);
Node* removeChild(Node* oldChild);
Node* appendChild(Node* newChild);
private:
NamedNodeMap* entities;
NamedNodeMap* notations;
};
class txNamespaceManager
{
public:

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

@ -37,11 +37,9 @@
//Construct a Document. Currently no parameters are required, but the the
//node constructor is called to identify the node type.
//
Document::Document(DocumentType* theDoctype) :
NodeDefinition(Node::DOCUMENT_NODE, String(NS_LITERAL_STRING("#document")), NULL_STRING, NULL)
Document::Document() : NodeDefinition(Node::DOCUMENT_NODE, NULL_STRING, NULL)
{
documentElement = NULL;
doctype = theDoctype;
}
//
@ -52,150 +50,14 @@ Element* Document::getDocumentElement()
return documentElement;
}
//
//Return the document type of this document object
//
DocumentType* Document::getDoctype()
{
return doctype;
}
//
//Return a constant reference to the DOM's Implementation
//
const DOMImplementation& Document::getImplementation()
{
return implementation;
}
//
//Ensure that no Element node is inserted if the document already has an
//associated Element child.
//
Node* Document::insertBefore(Node* newChild, Node* refChild)
{
Node* returnVal = NULL;
NodeDefinition* pCurrentNode = NULL;
NodeDefinition* pNextNode = NULL;
//Convert to a NodeDefinition Pointer
NodeDefinition* pNewChild = (NodeDefinition*)newChild;
NodeDefinition* pRefChild = (NodeDefinition*)refChild;
//Check to see if the reference node is a child of this node
if ((refChild != NULL) && (pRefChild->getParentNode() != this))
return NULL;
switch (pNewChild->getNodeType())
{
case Node::DOCUMENT_FRAGMENT_NODE :
pCurrentNode = (NodeDefinition*)pNewChild->getFirstChild();
while (pCurrentNode)
{
pNextNode = (NodeDefinition*)pCurrentNode->getNextSibling();
//Make sure that if the current node is an Element, the document
//doesn't already have one.
if ((pCurrentNode->getNodeType() != Node::ELEMENT_NODE) ||
((pCurrentNode->getNodeType() == Node::ELEMENT_NODE) &&
(documentElement == NULL)))
{
pCurrentNode = (NodeDefinition*)pNewChild->removeChild(pCurrentNode);
implInsertBefore(pCurrentNode, pRefChild);
if (pCurrentNode->getNodeType() == Node::ELEMENT_NODE)
documentElement = (Element*)pCurrentNode;
}
pCurrentNode = pNextNode;
}
returnVal = newChild;
break;
case Node::PROCESSING_INSTRUCTION_NODE :
case Node::COMMENT_NODE :
case Node::DOCUMENT_TYPE_NODE :
returnVal = implInsertBefore(pNewChild, pRefChild);
break;
case Node::ELEMENT_NODE :
if (!documentElement)
{
documentElement = (Element*)pNewChild;
returnVal = implInsertBefore(pNewChild, pRefChild);
}
else
returnVal = NULL;
break;
default:
returnVal = NULL;
}
return returnVal;
}
//
//Ensure that if the newChild is an Element and the Document already has an
//element, then oldChild should be specifying the existing element. If not
//then the replacement can not take place.
//
Node* Document::replaceChild(Node* newChild, Node* oldChild)
{
Node* replacedChild = NULL;
if (newChild->getNodeType() != Node::ELEMENT_NODE)
{
//The new child is not an Element, so perform replacement
replacedChild = NodeDefinition::replaceChild(newChild, oldChild);
//If old node was an Element, then the document's element has been
//replaced with a non-element node. Therefore clear the documentElement
//pointer
if (replacedChild && (oldChild->getNodeType() == Node::ELEMENT_NODE))
documentElement = NULL;
return replacedChild;
}
else
{
//A node is being replaced with an Element. If the document does not
//have an elemet yet, then just allow the replacemetn to take place.
if (!documentElement)
replacedChild = NodeDefinition::replaceChild(newChild, oldChild);
else if (oldChild->getNodeType() == Node::ELEMENT_NODE)
replacedChild = NodeDefinition::replaceChild(newChild, oldChild);
if (replacedChild)
documentElement = (Element*)newChild;
return replacedChild;
}
}
//
//Update the documentElement pointer if the associated Element node is being
//removed.
//
Node* Document::removeChild(Node* oldChild)
{
Node* removedChild = NULL;
removedChild = NodeDefinition::removeChild(oldChild);
if (removedChild && (removedChild->getNodeType() == Node::ELEMENT_NODE))
documentElement = NULL;
return removedChild;
}
//
//Construct an empty document fragment.
// NOTE: The caller is responsible for cleaning up this fragment's memory
// when it is no longer needed.
//
DocumentFragment* Document::createDocumentFragment()
Node* Document::createDocumentFragment()
{
return new DocumentFragment(String(NS_LITERAL_STRING("#document-fragment")), NULL_STRING, this);
return new DocumentFragment(this);
}
//
@ -230,25 +92,17 @@ Attr* Document::createAttributeNS(const String& aNamespaceURI,
//
//Construct a text node with the given data
//
Text* Document::createTextNode(const String& theData)
Node* Document::createTextNode(const String& theData)
{
return new Text(theData, this);
return new NodeDefinition(Node::TEXT_NODE, theData, this);
}
//
//Construct a comment node with the given data
//
Comment* Document::createComment(const String& theData)
Node* Document::createComment(const String& theData)
{
return new Comment(theData, this);
}
//
//Construct a CDATASection node with the given data
//
CDATASection* Document::createCDATASection(const String& theData)
{
return new CDATASection(theData, this);
return new NodeDefinition(Node::COMMENT_NODE, theData, this);
}
//
@ -261,14 +115,6 @@ ProcessingInstruction*
return new ProcessingInstruction(target, data, this);
}
//
//Construct an EntityReference with the given name
//
EntityReference* Document::createEntityReference(const String& name)
{
return new EntityReference(name, this);
}
//
//Return an Element by ID, introduced by DOM2
//
@ -281,6 +127,42 @@ Element* Document::getElementById(const String aID)
return NULL;
}
Node* Document::appendChild(Node* newChild)
{
unsigned short nodeType = newChild->getNodeType();
// Convert to a NodeDefinition Pointer
NodeDefinition* pNewChild = (NodeDefinition*)newChild;
if (pNewChild->parentNode == this)
{
pNewChild = implRemoveChild(pNewChild);
if (nodeType == Node::ELEMENT_NODE)
documentElement = nsnull;
}
switch (nodeType)
{
case Node::PROCESSING_INSTRUCTION_NODE :
case Node::COMMENT_NODE :
case Node::DOCUMENT_TYPE_NODE :
return implAppendChild(pNewChild);
case Node::ELEMENT_NODE :
if (!documentElement)
{
Node* returnVal = implAppendChild(pNewChild);
documentElement = (Element*)pNewChild;
return returnVal;
}
default:
break;
}
return nsnull;
}
String Document::getBaseURI()
{
return documentBaseURI;

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

@ -73,6 +73,30 @@ Element::~Element()
TX_IF_RELEASE_ATOM(mLocalName);
}
Node* Element::appendChild(Node* newChild)
{
switch (newChild->getNodeType())
{
case Node::ELEMENT_NODE :
case Node::TEXT_NODE :
case Node::COMMENT_NODE :
case Node::PROCESSING_INSTRUCTION_NODE :
{
// Remove the "newChild" if it is already a child of this node
NodeDefinition* pNewChild = (NodeDefinition*)newChild;
if (pNewChild->getParentNode() == this)
pNewChild = implRemoveChild(pNewChild);
return implAppendChild(pNewChild);
}
default:
break;
}
return nsnull;
}
//
//Return the elements local (unprefixed) name.
//
@ -122,61 +146,11 @@ PRInt32 Element::getNamespaceID()
return mNamespaceID;
}
//
//First check to see if the new node is an allowable child for an Element. If
//it is, call NodeDefinition's implementation of Insert Before. If not, return
//null as an error
//
Node* Element::insertBefore(Node* newChild, Node* refChild)
{
Node* returnVal = NULL;
switch (newChild->getNodeType())
{
case Node::ELEMENT_NODE :
case Node::TEXT_NODE :
case Node::COMMENT_NODE :
case Node::PROCESSING_INSTRUCTION_NODE :
case Node::CDATA_SECTION_NODE :
case Node::DOCUMENT_FRAGMENT_NODE : //-- added 19990813 (kvisco)
case Node::ENTITY_REFERENCE_NODE:
returnVal = NodeDefinition::insertBefore(newChild, refChild);
break;
default:
returnVal = NULL;
}
return returnVal;
}
//
//Return the tagName for this element. This is simply the nodeName.
//
const String& Element::getTagName()
{
return nodeName;
}
NamedNodeMap* Element::getAttributes()
{
return &mAttributes;
}
//
//Retreive an attribute's value by name. If the attribute does not exist,
//return a reference to the pre-created, constatnt "NULL STRING".
//
const String& Element::getAttribute(const String& name)
{
Node* tempNode = mAttributes.getNamedItem(name);
if (tempNode)
return mAttributes.getNamedItem(name)->getNodeValue();
else
return NULL_STRING;
}
//
//Add an attribute to this Element. Create a new Attr object using the
//name and value specified. Then add the Attr to the the Element's
@ -238,15 +212,6 @@ void Element::setAttributeNS(const String& aNamespaceURI,
}
}
//
//Remove an attribute from the mAttributes NamedNodeMap, and free its memory.
// NOTE: How do default values enter into this picture
//
void Element::removeAttribute(const String& name)
{
delete mAttributes.removeNamedItem(name);
}
//
//Return the attribute specified by name
//
@ -302,34 +267,3 @@ MBool Element::hasAttr(txAtom* aLocalName, PRInt32 aNSID)
}
return MB_FALSE;
}
//
//Set a new attribute specifed by the newAttr node. If an attribute with that
//name already exists, the existing Attr is removed from the list and return to
//the caller, else NULL is returned.
//
Attr* Element::setAttributeNode(Attr* newAttr)
{
Attr* pOldAttr = (Attr*)mAttributes.removeNamedItem(newAttr->getNodeName());
mAttributes.setNamedItem(newAttr);
return pOldAttr;
}
//
//Remove the Attribute from the attributes list and return to the caller. If
//the node is not found, return NULL.
//
Attr* Element::removeAttributeNode(Attr* oldAttr)
{
return (Attr*)mAttributes.removeNamedItem(oldAttr->getNodeName());
}
NodeList* Element::getElementsByTagName(const String& name)
{
return 0;
}
void Element::normalize()
{
}

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

@ -38,21 +38,46 @@
NodeDefinition::NodeDefinition(NodeType type, const String& name,
const String& value, Document* owner)
{
nodeName = name;
nodeValue = value;
nodeType = type;
Init(type, value, owner);
}
parentNode = NULL;
previousSibling = NULL;
nextSibling = NULL;;
firstChild = NULL;
lastChild = NULL;
ownerDocument = owner;
length = 0;
mOrderInfo = 0;
NodeDefinition::NodeDefinition(NodeType aType, const String& aValue,
Document* aOwner)
{
switch (aType)
{
case CDATA_SECTION_NODE:
{
nodeName.Append(NS_LITERAL_STRING("#cdata-section"));
break;
}
case COMMENT_NODE:
{
nodeName.Append(NS_LITERAL_STRING("#comment"));
break;
}
case DOCUMENT_NODE:
{
nodeName.Append(NS_LITERAL_STRING("#document"));
break;
}
case DOCUMENT_FRAGMENT_NODE:
{
nodeName.Append(NS_LITERAL_STRING("#document-fragment"));
break;
}
case TEXT_NODE:
{
nodeName.Append(NS_LITERAL_STRING("#text"));
break;
}
default:
{
break;
}
}
Init(aType, aValue, aOwner);
}
//
@ -64,6 +89,25 @@ NodeDefinition::~NodeDefinition()
delete mOrderInfo;
}
void
NodeDefinition::Init(NodeType aType, const String& aValue,
Document* aOwner)
{
nodeType = aType;
nodeValue = aValue;
ownerDocument = aOwner;
parentNode = NULL;
previousSibling = NULL;
nextSibling = NULL;;
firstChild = NULL;
lastChild = NULL;
length = 0;
mOrderInfo = 0;
}
//
//Remove and delete all children of this node
//
@ -104,11 +148,6 @@ Node* NodeDefinition::getParentNode() const
return parentNode;
}
NodeList* NodeDefinition::getChildNodes()
{
return this;
}
Node* NodeDefinition::getFirstChild() const
{
return firstChild;
@ -165,181 +204,56 @@ void NodeDefinition::setNodeValue(const String& newNodeValue)
nodeValue = newNodeValue;
}
//
//Insert the "newChild" node before the "refChild" node. Return a pointer to
//the inserted child. If the node to insert is a document fragment, then
//insert each child of the document fragment, and return the document fragment
//which should be empty if all the inserts suceeded.
//This function's responsibility is to check for and handle document fragments
//vs. plain nodes.
// *** NOTE: Need to check the document types before inserting.
//
// The decision to return the possibly empty document fragment
// was an implementation choice. The spec did not dictate what
// whould occur.
//
Node* NodeDefinition::insertBefore(Node* newChild,
Node* refChild)
{
NodeDefinition* pCurrentNode = NULL;
NodeDefinition* pNextNode = NULL;
//Convert to a NodeDefinition Pointer
NodeDefinition* pNewChild = (NodeDefinition*)newChild;
NodeDefinition* pRefChild = (NodeDefinition*)refChild;
//Check to see if the reference node is a child of this node
if ((refChild != NULL) && (pRefChild->parentNode != this))
return NULL;
if (newChild->getNodeType() == Node::DOCUMENT_FRAGMENT_NODE)
{
pCurrentNode = pNewChild->firstChild;
while (pCurrentNode)
{
pNextNode = pCurrentNode->nextSibling;
pCurrentNode = (NodeDefinition*)pNewChild->removeChild(pCurrentNode);
implInsertBefore(pCurrentNode, pRefChild);
pCurrentNode = pNextNode;
}
return newChild;
}
else
return implInsertBefore(pNewChild, pRefChild);
}
//
//The code that actually insert one node before another.
//
Node* NodeDefinition::implInsertBefore(NodeDefinition* pNewChild,
NodeDefinition* pRefChild)
{
//Remove the "newChild" if it is already a child of this node
if (pNewChild->parentNode == this)
pNewChild = (NodeDefinition*)removeChild(pNewChild);
//The new child should not be a child of any other node
if ((pNewChild->previousSibling == NULL) &&
(pNewChild->nextSibling == NULL) &&
(pNewChild->parentNode == NULL))
{
if (pRefChild == NULL)
{
//Append
pNewChild->previousSibling = lastChild;
if (lastChild)
lastChild->nextSibling = pNewChild;
lastChild = pNewChild;
}
else
{
//Insert before the reference node
if (pRefChild->previousSibling)
pRefChild->previousSibling->nextSibling = pNewChild;
pNewChild->nextSibling = pRefChild;
pNewChild->previousSibling = pRefChild->previousSibling;
pRefChild->previousSibling = pNewChild;
}
pNewChild->parentNode = this;
if (pNewChild->previousSibling == NULL)
firstChild = pNewChild;
length++;
return pNewChild;
}
return NULL;
}
//
//Replace "oldChild" with "newChild". Return the replaced node, or NULL
//otherwise.
// *** NOTE: Need to check that the documents match ***
//
Node* NodeDefinition::replaceChild(Node* newChild,
Node* oldChild)
{
NodeDefinition* pOldChild = (NodeDefinition*)oldChild;
NodeDefinition* pNextSibling = NULL;
//If the newChild is replacing itself then we don't need to do anything
if (pOldChild == newChild)
return pOldChild;
//If "oldChild" is a child of this node, remove it from the list.
pOldChild = (NodeDefinition*)removeChild(oldChild);
//If the removal was successful... Else, return null
if (pOldChild)
{
//Try to insert the new node before the old node's next sibling. If
//successful, just returned the replaced child. If not succesful,
//reinsert the old node, and return NULL.
pNextSibling = pOldChild->nextSibling;
if (!insertBefore(newChild, pNextSibling))
{
insertBefore(pOldChild, pNextSibling);
pOldChild = NULL;
}
}
return pOldChild;
}
//
//Remove the specified "oldChild" from this node's children. First make sure
//the specified node is a child of this node. Return the removed node, NULL
//otherwise.
//
Node* NodeDefinition::removeChild(Node* oldChild)
{
NodeDefinition* pOldChild = (NodeDefinition*)oldChild;
//If "oldChild" is a child of this node, adjust pointers to remove it, and
//clear "oldChild"'s sibling and parent pointers.
if (pOldChild->parentNode == this)
{
if (pOldChild != firstChild)
pOldChild->previousSibling->nextSibling = pOldChild->nextSibling;
else
firstChild = pOldChild->nextSibling;
if (pOldChild != lastChild)
pOldChild->nextSibling->previousSibling = pOldChild->previousSibling;
else
lastChild = pOldChild->previousSibling;
pOldChild->nextSibling = NULL;
pOldChild->previousSibling = NULL;
pOldChild->parentNode = NULL;
length--;
return pOldChild;
}
return NULL;
}
//
//Append a new child node. First make sure the new child is not already a
//child of another node. Return the appended node.
// *** NOTE *** Need to eventually check to make sure the documents match ***
//
Node* NodeDefinition::appendChild(Node* newChild)
{
return insertBefore(newChild, NULL);
return nsnull;
}
Node* NodeDefinition::cloneNode(MBool deep, Node* dest)
NodeDefinition* NodeDefinition::implAppendChild(NodeDefinition* newChild)
{
return 0;
// The new child should not be a child of any other node
if (!newChild->previousSibling && !newChild->nextSibling &&
!newChild->parentNode)
{
newChild->previousSibling = lastChild;
if (lastChild)
lastChild->nextSibling = newChild;
lastChild = newChild;
newChild->parentNode = this;
if (!newChild->previousSibling)
firstChild = newChild;
++length;
return newChild;
}
return nsnull;
}
NodeDefinition* NodeDefinition::implRemoveChild(NodeDefinition* oldChild)
{
if (oldChild != firstChild)
oldChild->previousSibling->nextSibling = oldChild->nextSibling;
else
firstChild = oldChild->nextSibling;
if (oldChild != lastChild)
oldChild->nextSibling->previousSibling = oldChild->previousSibling;
else
lastChild = oldChild->previousSibling;
oldChild->nextSibling = nsnull;
oldChild->previousSibling = nsnull;
oldChild->parentNode = nsnull;
--length;
return oldChild;
}
MBool NodeDefinition::hasChildNodes() const

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

@ -52,57 +52,11 @@ ProcessingInstruction::~ProcessingInstruction()
TX_IF_RELEASE_ATOM(mLocalName);
}
//
//Return the Target of the processing instruction. This is simply the
//nodeName.
//
const String& ProcessingInstruction::getTarget() const
{
return nodeName;
}
//
//Return the Data of the processing instruction. This is simply the value
//of the node, "nodeValue"
//
const String& ProcessingInstruction::getData() const
{
return nodeValue;
}
//
//Set the Data element of the processing instruction.
void ProcessingInstruction::setData(const String& theData)
{
nodeValue = theData;
}
//
//ProcessingInstruction nodes can not have any children, so just return null
//from all child manipulation functions.
//
Node* ProcessingInstruction::insertBefore(Node* newChild, Node* refChild)
{
return NULL;
}
Node* ProcessingInstruction::replaceChild(Node* newChild, Node* oldChild)
{
return NULL;
}
Node* ProcessingInstruction::removeChild(Node* oldChild)
{
return NULL;
}
Node* ProcessingInstruction::appendChild(Node* newChild)
{
return NULL;
}
MBool ProcessingInstruction::getLocalName(txAtom** aLocalName)
{
if (!aLocalName)

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

@ -51,7 +51,6 @@
#include "nsIDOMNode.h"
#include "txXMLEventHandler.h"
#include "nsIDOMDocument.h"
#include "nsIDOMDocumentFragment.h"
#include "nsIXSLTProcessorObsolete.h"
/* bacd8ad0-552f-11d3-a9f7-000064657374 */

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

@ -52,7 +52,7 @@ txRtfHandler::txRtfHandler(Document* aDocument,
if (!mResultTreeFragment)
return;
DocumentFragment* fragment = mDocument->createDocumentFragment();
Node* fragment = mDocument->createDocumentFragment();
NS_ASSERTION(fragment, "Out of memory creating a document fragmen");
// XXX ErrorReport: Out of memory
mResultTreeFragment->append(fragment);
@ -88,7 +88,7 @@ void txRtfHandler::characters(const String& aData)
if (!mCurrentNode)
return;
Text* text = mDocument->createTextNode(aData);
Node* text = mDocument->createTextNode(aData);
mCurrentNode->appendChild(text);
}
@ -98,7 +98,7 @@ void txRtfHandler::comment(const String& aData)
if (!mCurrentNode)
return;
Comment* comment = mDocument->createComment(aData);
Node* comment = mDocument->createComment(aData);
mCurrentNode->appendChild(comment);
}

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

@ -258,10 +258,10 @@ void txStandaloneXSLTProcessor::getHrefFromStylesheetPI(Document& xmlDocument,
String tmpHref;
while (node) {
if (node->getNodeType() == Node::PROCESSING_INSTRUCTION_NODE) {
String target = ((ProcessingInstruction*)node)->getTarget();
String target = node->getNodeName();
if (STYLESHEET_PI.Equals(target) ||
STYLESHEET_PI_OLD.Equals(target)) {
String data = ((ProcessingInstruction*)node)->getData();
String data = node->getNodeValue();
type.Truncate();
tmpHref.Truncate();
parseStylesheetPI(data, type, tmpHref);