mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Fix for bug 188339 (improve standalone DOM). r=Pike. NPOTB.
This commit is contained in:
parent
435013bdd0
commit
d6f922dd54
@ -50,6 +50,15 @@ class nsIAtom;
|
||||
* be auto-generated.
|
||||
*/
|
||||
|
||||
#ifdef TX_EXE
|
||||
#define DOM_ATOMS \
|
||||
TX_ATOM(comment, "#comment") \
|
||||
TX_ATOM(document, "#document") \
|
||||
TX_ATOM(text, "#text")
|
||||
#else
|
||||
#define DOM_ATOMS
|
||||
#endif
|
||||
|
||||
#define XML_ATOMS \
|
||||
TX_ATOM(_empty, "") \
|
||||
TX_ATOM(base, "base") \
|
||||
@ -58,7 +67,8 @@ TX_ATOM(lang, "lang") \
|
||||
TX_ATOM(preserve, "preserve") \
|
||||
TX_ATOM(space, "space") \
|
||||
TX_ATOM(xml, "xml") \
|
||||
TX_ATOM(xmlns, "xmlns")
|
||||
TX_ATOM(xmlns, "xmlns") \
|
||||
DOM_ATOMS
|
||||
|
||||
#define TX_ATOM(_name, _value) static nsIAtom* _name;
|
||||
|
||||
|
@ -93,16 +93,13 @@ XMLUtils::splitExpatName(const PRUnichar *aExpatName, nsIAtom **aPrefix,
|
||||
* localName
|
||||
* namespaceURI<separator>localName
|
||||
* namespaceURI<separator>localName<separator>prefix
|
||||
*
|
||||
* and we use 0xFFFF for the <separator>.
|
||||
*
|
||||
*/
|
||||
|
||||
const PRUnichar *uriEnd = nsnull;
|
||||
const PRUnichar *nameEnd = nsnull;
|
||||
const PRUnichar *pos;
|
||||
for (pos = aExpatName; *pos; ++pos) {
|
||||
if (*pos == 0xFFFF) {
|
||||
if (*pos == kExpatSeparatorChar) {
|
||||
if (uriEnd) {
|
||||
nameEnd = pos;
|
||||
}
|
||||
|
@ -53,6 +53,8 @@
|
||||
#include "nsIParserService.h"
|
||||
#endif
|
||||
|
||||
#define kExpatSeparatorChar 0xFFFF
|
||||
|
||||
class nsIAtom;
|
||||
class txNamespaceMap;
|
||||
|
||||
|
@ -45,67 +45,20 @@
|
||||
#include "txAtoms.h"
|
||||
#include "XMLUtils.h"
|
||||
|
||||
//
|
||||
//Construct an Attribute object using the specified name and document owner
|
||||
//
|
||||
Attr::Attr(const nsAString& name, Document* owner):
|
||||
NodeDefinition(Node::ATTRIBUTE_NODE, name, EmptyString(), owner)
|
||||
Attr::Attr(nsIAtom *aPrefix, nsIAtom *aLocalName, PRInt32 aNamespaceID,
|
||||
Element *aOwnerElement, const nsAString &aValue) :
|
||||
NodeDefinition(Node::ATTRIBUTE_NODE, aLocalName, aValue,
|
||||
aOwnerElement->getOwnerDocument()),
|
||||
mPrefix(aPrefix),
|
||||
mNamespaceID(aNamespaceID),
|
||||
mOwnerElement(aOwnerElement)
|
||||
{
|
||||
int idx = nodeName.FindChar(':');
|
||||
if (idx == kNotFound) {
|
||||
mLocalName = do_GetAtom(nodeName);
|
||||
if (mLocalName == txXMLAtoms::xmlns)
|
||||
mNamespaceID = kNameSpaceID_XMLNS;
|
||||
else
|
||||
mNamespaceID = kNameSpaceID_None;
|
||||
}
|
||||
else {
|
||||
mLocalName = do_GetAtom(Substring(nodeName, idx + 1,
|
||||
nodeName.Length() - (idx + 1)));
|
||||
// namespace handling has to be handled late, the attribute must
|
||||
// be added to the tree to resolve the prefix, unless it's
|
||||
// xmlns or xml, try to do that here
|
||||
nsCOMPtr<nsIAtom> prefixAtom = do_GetAtom(Substring(nodeName, 0, idx));
|
||||
if (prefixAtom == txXMLAtoms::xmlns)
|
||||
mNamespaceID = kNameSpaceID_XMLNS;
|
||||
else if (prefixAtom == txXMLAtoms::xml)
|
||||
mNamespaceID = kNameSpaceID_XML;
|
||||
else
|
||||
mNamespaceID = kNameSpaceID_Unknown;
|
||||
}
|
||||
}
|
||||
|
||||
Attr::Attr(const nsAString& aNamespaceURI,
|
||||
const nsAString& aName,
|
||||
Document* aOwner) :
|
||||
NodeDefinition(Node::ATTRIBUTE_NODE, aName, EmptyString(), aOwner)
|
||||
{
|
||||
if (aNamespaceURI.IsEmpty())
|
||||
mNamespaceID = kNameSpaceID_None;
|
||||
else
|
||||
mNamespaceID = txStandaloneNamespaceManager::getNamespaceID(aNamespaceURI);
|
||||
|
||||
mLocalName = do_GetAtom(XMLUtils::getLocalPart(nodeName));
|
||||
}
|
||||
|
||||
//
|
||||
//Release the mLocalName
|
||||
//
|
||||
Attr::~Attr()
|
||||
{
|
||||
}
|
||||
|
||||
void Attr::setNodeValue(const nsAString& aValue)
|
||||
{
|
||||
nodeValue = aValue;
|
||||
}
|
||||
|
||||
nsresult Attr::getNodeValue(nsAString& aValue)
|
||||
{
|
||||
aValue = nodeValue;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
//Not implemented anymore, return null as an error.
|
||||
//
|
||||
@ -115,6 +68,24 @@ Node* Attr::appendChild(Node* newChild)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Attr::getNodeName(nsAString& aName) const
|
||||
{
|
||||
if (mPrefix) {
|
||||
mPrefix->ToString(aName);
|
||||
aName.Append(PRUnichar(':'));
|
||||
}
|
||||
else {
|
||||
aName.Truncate();
|
||||
}
|
||||
|
||||
const char* ASCIIAtom;
|
||||
mLocalName->GetUTF8String(&ASCIIAtom);
|
||||
AppendUTF8toUTF16(ASCIIAtom, aName);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
//Return the attributes local (unprefixed) name atom.
|
||||
//
|
||||
@ -134,15 +105,6 @@ MBool Attr::getLocalName(nsIAtom** aLocalName)
|
||||
//
|
||||
PRInt32 Attr::getNamespaceID()
|
||||
{
|
||||
if (mNamespaceID >= 0)
|
||||
return mNamespaceID;
|
||||
|
||||
mNamespaceID = kNameSpaceID_None;
|
||||
PRInt32 idx = nodeName.FindChar(':');
|
||||
if (idx != kNotFound) {
|
||||
nsCOMPtr<nsIAtom> prefixAtom = do_GetAtom(Substring(nodeName, 0, idx));
|
||||
mNamespaceID = lookupNamespaceID(prefixAtom);
|
||||
}
|
||||
return mNamespaceID;
|
||||
}
|
||||
|
||||
@ -151,5 +113,5 @@ PRInt32 Attr::getNamespaceID()
|
||||
//
|
||||
Node* Attr::getXPathParent()
|
||||
{
|
||||
return ownerElement;
|
||||
return mOwnerElement;
|
||||
}
|
||||
|
@ -49,15 +49,18 @@
|
||||
//
|
||||
|
||||
#include "dom.h"
|
||||
#include "txAtoms.h"
|
||||
|
||||
//
|
||||
//Construct a Document. Currently no parameters are required, but the the
|
||||
//node constructor is called to identify the node type.
|
||||
//
|
||||
Document::Document() : NodeDefinition(Node::DOCUMENT_NODE, EmptyString(), NULL)
|
||||
Document::Document() :
|
||||
NodeDefinition(Node::DOCUMENT_NODE, txXMLAtoms::document, EmptyString(),
|
||||
nsnull),
|
||||
documentElement(nsnull)
|
||||
{
|
||||
mIDMap.Init(0);
|
||||
documentElement = nsnull;
|
||||
}
|
||||
|
||||
//
|
||||
@ -68,43 +71,11 @@ Element* Document::getDocumentElement()
|
||||
return documentElement;
|
||||
}
|
||||
|
||||
//
|
||||
//Construct an empty document fragment.
|
||||
// NOTE: The caller is responsible for cleaning up this fragment's memory
|
||||
// when it is no longer needed.
|
||||
//
|
||||
Node* Document::createDocumentFragment()
|
||||
Element*
|
||||
Document::createElementNS(nsIAtom *aPrefix, nsIAtom *aLocalName,
|
||||
PRInt32 aNamespaceID)
|
||||
{
|
||||
return new DocumentFragment(this);
|
||||
}
|
||||
|
||||
//
|
||||
//Construct an element with the specified tag name.
|
||||
// NOTE: The caller is responsible for cleaning up the element's menory
|
||||
//
|
||||
Element* Document::createElement(const nsAString& tagName)
|
||||
{
|
||||
return new Element(tagName, this);
|
||||
}
|
||||
|
||||
Element* Document::createElementNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aTagName)
|
||||
{
|
||||
return new Element(aNamespaceURI, aTagName, this);
|
||||
}
|
||||
|
||||
//
|
||||
//Construct an attribute with the specified name
|
||||
//
|
||||
Attr* Document::createAttribute(const nsAString& name)
|
||||
{
|
||||
return new Attr(name, this);
|
||||
}
|
||||
|
||||
Attr* Document::createAttributeNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aName)
|
||||
{
|
||||
return new Attr(aNamespaceURI, aName, this);
|
||||
return new Element(aPrefix, aLocalName, aNamespaceID, this);
|
||||
}
|
||||
|
||||
//
|
||||
@ -112,7 +83,7 @@ Attr* Document::createAttributeNS(const nsAString& aNamespaceURI,
|
||||
//
|
||||
Node* Document::createTextNode(const nsAString& theData)
|
||||
{
|
||||
return new NodeDefinition(Node::TEXT_NODE, theData, this);
|
||||
return new NodeDefinition(Node::TEXT_NODE, txXMLAtoms::text, theData, this);
|
||||
}
|
||||
|
||||
//
|
||||
@ -120,17 +91,18 @@ Node* Document::createTextNode(const nsAString& theData)
|
||||
//
|
||||
Node* Document::createComment(const nsAString& theData)
|
||||
{
|
||||
return new NodeDefinition(Node::COMMENT_NODE, theData, this);
|
||||
return new NodeDefinition(Node::COMMENT_NODE, txXMLAtoms::comment, theData,
|
||||
this);
|
||||
}
|
||||
|
||||
//
|
||||
//Construct a ProcessingInstruction node with the given targe and data.
|
||||
//
|
||||
ProcessingInstruction*
|
||||
Document::createProcessingInstruction(const nsAString& target,
|
||||
Document::createProcessingInstruction(nsIAtom *aTarget,
|
||||
const nsAString& data)
|
||||
{
|
||||
return new ProcessingInstruction(target, data, this);
|
||||
return new ProcessingInstruction(aTarget, data, this);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -45,37 +45,12 @@
|
||||
#include "txAtoms.h"
|
||||
#include "XMLUtils.h"
|
||||
|
||||
//
|
||||
//Construct a new element with the specified tagName and Document owner.
|
||||
//Simply call the constructor for NodeDefinition, and specify the proper node
|
||||
//type.
|
||||
//
|
||||
Element::Element(const nsAString& tagName, Document* owner) :
|
||||
NodeDefinition(Node::ELEMENT_NODE, tagName, EmptyString(), owner)
|
||||
{
|
||||
mAttributes.ownerElement = this;
|
||||
mNamespaceID = kNameSpaceID_Unknown;
|
||||
|
||||
int idx = tagName.FindChar(':');
|
||||
if (idx == kNotFound) {
|
||||
mLocalName = do_GetAtom(tagName);
|
||||
}
|
||||
else {
|
||||
mLocalName = do_GetAtom(Substring(tagName, idx + 1,
|
||||
tagName.Length() - (idx + 1)));
|
||||
}
|
||||
}
|
||||
|
||||
Element::Element(const nsAString& aNamespaceURI,
|
||||
const nsAString& aTagName,
|
||||
Element::Element(nsIAtom *aPrefix, nsIAtom *aLocalName, PRInt32 aNamespaceID,
|
||||
Document* aOwner) :
|
||||
NodeDefinition(Node::ELEMENT_NODE, aTagName, EmptyString(), aOwner)
|
||||
NodeDefinition(Node::ELEMENT_NODE, aLocalName, EmptyString(), aOwner),
|
||||
mPrefix(aPrefix),
|
||||
mNamespaceID(aNamespaceID)
|
||||
{
|
||||
Element(aTagName, aOwner);
|
||||
if (aNamespaceURI.IsEmpty())
|
||||
mNamespaceID = kNameSpaceID_None;
|
||||
else
|
||||
mNamespaceID = txStandaloneNamespaceManager::getNamespaceID(aNamespaceURI);
|
||||
}
|
||||
|
||||
//
|
||||
@ -84,7 +59,6 @@ Element::Element(const nsAString& aNamespaceURI,
|
||||
//
|
||||
Element::~Element()
|
||||
{
|
||||
mAttributes.clear();
|
||||
}
|
||||
|
||||
Node* Element::appendChild(Node* newChild)
|
||||
@ -111,6 +85,24 @@ Node* Element::appendChild(Node* newChild)
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
Element::getNodeName(nsAString& aName) const
|
||||
{
|
||||
if (mPrefix) {
|
||||
mPrefix->ToString(aName);
|
||||
aName.Append(PRUnichar(':'));
|
||||
}
|
||||
else {
|
||||
aName.Truncate();
|
||||
}
|
||||
|
||||
const char* ASCIIAtom;
|
||||
mLocalName->GetUTF8String(&ASCIIAtom);
|
||||
AppendUTF8toUTF16(ASCIIAtom, aName);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
//Return the elements local (unprefixed) name.
|
||||
//
|
||||
@ -128,103 +120,31 @@ MBool Element::getLocalName(nsIAtom** aLocalName)
|
||||
//
|
||||
PRInt32 Element::getNamespaceID()
|
||||
{
|
||||
if (mNamespaceID>=0)
|
||||
return mNamespaceID;
|
||||
int idx = nodeName.FindChar(':');
|
||||
if (idx == kNotFound) {
|
||||
Node* node = this;
|
||||
while (node && node->getNodeType() == Node::ELEMENT_NODE) {
|
||||
nsAutoString nsURI;
|
||||
if (((Element*)node)->getAttr(txXMLAtoms::xmlns, kNameSpaceID_XMLNS,
|
||||
nsURI)) {
|
||||
// xmlns = "" sets the default namespace ID to kNameSpaceID_None;
|
||||
if (!nsURI.IsEmpty()) {
|
||||
mNamespaceID = txStandaloneNamespaceManager::getNamespaceID(nsURI);
|
||||
}
|
||||
else {
|
||||
mNamespaceID = kNameSpaceID_None;
|
||||
}
|
||||
return mNamespaceID;
|
||||
}
|
||||
node = node->getParentNode();
|
||||
}
|
||||
mNamespaceID = kNameSpaceID_None;
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsIAtom> prefix = do_GetAtom(Substring(nodeName, 0, idx));
|
||||
mNamespaceID = lookupNamespaceID(prefix);
|
||||
}
|
||||
return mNamespaceID;
|
||||
}
|
||||
|
||||
NamedNodeMap* Element::getAttributes()
|
||||
nsresult
|
||||
Element::appendAttributeNS(nsIAtom *aPrefix, nsIAtom *aLocalName,
|
||||
PRInt32 aNamespaceID, const nsAString& aValue)
|
||||
{
|
||||
return &mAttributes;
|
||||
}
|
||||
|
||||
//
|
||||
//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
|
||||
//mAttributes NamedNodeMap.
|
||||
//
|
||||
void Element::setAttribute(const nsAString& name, const nsAString& value)
|
||||
{
|
||||
// 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);
|
||||
nsAutoPtr<Attr> newAttribute;
|
||||
newAttribute = new Attr(aPrefix, aLocalName, aNamespaceID, this, aValue);
|
||||
if (!newAttribute) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
else {
|
||||
tempAttribute = getOwnerDocument()->createAttribute(name);
|
||||
tempAttribute->setNodeValue(value);
|
||||
tempAttribute->ownerElement = this;
|
||||
mAttributes.append(tempAttribute);
|
||||
}
|
||||
}
|
||||
|
||||
void Element::setAttributeNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aName,
|
||||
const nsAString& aValue)
|
||||
{
|
||||
// Check to see if an attribute with this name already exists. If it does
|
||||
// overwrite its value, if not, add it.
|
||||
PRInt32 namespaceID =
|
||||
txStandaloneNamespaceManager::getNamespaceID(aNamespaceURI);
|
||||
nsCOMPtr<nsIAtom> localName = do_GetAtom(XMLUtils::getLocalPart(aName));
|
||||
|
||||
Attr* foundNode = 0;
|
||||
AttrMap::ListItem* item = mAttributes.firstItem;
|
||||
while (item) {
|
||||
foundNode = (Attr*)item->node;
|
||||
nsCOMPtr<nsIAtom> attrName;
|
||||
if (foundNode->getLocalName(getter_AddRefs(attrName)) &&
|
||||
namespaceID == foundNode->getNamespaceID() &&
|
||||
localName == attrName) {
|
||||
break;
|
||||
if (mFirstAttribute) {
|
||||
Attr *lastAttribute = mFirstAttribute;
|
||||
while (lastAttribute->mNextAttribute) {
|
||||
lastAttribute = lastAttribute->mNextAttribute;
|
||||
}
|
||||
foundNode = 0;
|
||||
item = item->next;
|
||||
}
|
||||
|
||||
if (foundNode) {
|
||||
foundNode->setNodeValue(aValue);
|
||||
lastAttribute->mNextAttribute = newAttribute;
|
||||
}
|
||||
else {
|
||||
Attr* temp = getOwnerDocument()->createAttributeNS(aNamespaceURI,
|
||||
aName);
|
||||
temp->setNodeValue(aValue);
|
||||
temp->ownerElement = this;
|
||||
mAttributes.append(temp);
|
||||
mFirstAttribute = newAttribute;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//Return the attribute specified by name
|
||||
//
|
||||
Attr* Element::getAttributeNode(const nsAString& name)
|
||||
{
|
||||
return (Attr*)mAttributes.getNamedItem(name);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
@ -236,19 +156,18 @@ MBool Element::getAttr(nsIAtom* aLocalName, PRInt32 aNSID,
|
||||
nsAString& aValue)
|
||||
{
|
||||
aValue.Truncate();
|
||||
AttrMap::ListItem* item = mAttributes.firstItem;
|
||||
while (item) {
|
||||
Attr* attrNode = (Attr*)item->node;
|
||||
nsCOMPtr<nsIAtom> localName;
|
||||
if (attrNode->getLocalName(getter_AddRefs(localName)) &&
|
||||
aNSID == attrNode->getNamespaceID() &&
|
||||
aLocalName == localName) {
|
||||
attrNode->getNodeValue(aValue);
|
||||
return MB_TRUE;
|
||||
Attr *attribute = mFirstAttribute;
|
||||
while (attribute) {
|
||||
if (attribute->equals(aLocalName, aNSID)) {
|
||||
attribute->getNodeValue(aValue);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
item = item->next;
|
||||
|
||||
attribute = attribute->mNextAttribute;
|
||||
}
|
||||
return MB_FALSE;
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
@ -257,18 +176,16 @@ MBool Element::getAttr(nsIAtom* aLocalName, PRInt32 aNSID,
|
||||
//
|
||||
MBool Element::hasAttr(nsIAtom* aLocalName, PRInt32 aNSID)
|
||||
{
|
||||
AttrMap::ListItem* item = mAttributes.firstItem;
|
||||
while (item) {
|
||||
Attr* attrNode = (Attr*)item->node;
|
||||
nsCOMPtr<nsIAtom> localName;
|
||||
if (attrNode->getLocalName(getter_AddRefs(localName)) &&
|
||||
aNSID == attrNode->getNamespaceID() &&
|
||||
aLocalName == localName) {
|
||||
return MB_TRUE;
|
||||
Attr *attribute = mFirstAttribute;
|
||||
while (attribute) {
|
||||
if (attribute->equals(aLocalName, aNSID)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
item = item->next;
|
||||
|
||||
attribute = attribute->mNextAttribute;
|
||||
}
|
||||
return MB_FALSE;
|
||||
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -53,9 +53,7 @@ REQUIRES = string \
|
||||
CPPSRCS = Attr.cpp \
|
||||
Document.cpp \
|
||||
Element.cpp \
|
||||
NamedNodeMap.cpp \
|
||||
NodeDefinition.cpp \
|
||||
NodeListDefinition.cpp \
|
||||
ProcessingInstruction.cpp
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a
|
||||
|
@ -1,169 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT processor code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The MITRE Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
// Tom Kneeland (3/29/99)
|
||||
//
|
||||
// Implementation of the Document Object Model Level 1 Core
|
||||
// Implementation of the NamedNodeMap class
|
||||
//
|
||||
|
||||
#include "dom.h"
|
||||
|
||||
NamedNodeMap::NamedNodeMap()
|
||||
{
|
||||
}
|
||||
|
||||
NamedNodeMap::~NamedNodeMap()
|
||||
{
|
||||
}
|
||||
|
||||
Node* NamedNodeMap::getNamedItem(const nsAString& name)
|
||||
{
|
||||
ListItem* pSearchItem = findListItemByName(name);
|
||||
|
||||
if (pSearchItem)
|
||||
return pSearchItem->node;
|
||||
else
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
Node* NamedNodeMap::setNamedItem(Node* arg)
|
||||
{
|
||||
//Since the DOM does not specify any ording for the NamedNodeMap, just
|
||||
//try and remove the new node (arg). If successful, return a pointer to
|
||||
//the removed item. Reguardless of wheter the node already existed or not,
|
||||
//insert the new node at the end of the list.
|
||||
nsAutoString nodeName;
|
||||
arg->getNodeName(nodeName);
|
||||
Node* pReplacedNode = removeNamedItem(nodeName);
|
||||
|
||||
NodeListDefinition::append(arg);
|
||||
|
||||
return pReplacedNode;
|
||||
}
|
||||
|
||||
Node* NamedNodeMap::removeNamedItem(const nsAString& name)
|
||||
{
|
||||
NodeListDefinition::ListItem* pSearchItem;
|
||||
Node* returnNode;
|
||||
|
||||
pSearchItem = findListItemByName(name);
|
||||
|
||||
if (pSearchItem)
|
||||
{
|
||||
if (pSearchItem != firstItem)
|
||||
pSearchItem->prev->next = pSearchItem->next;
|
||||
else
|
||||
firstItem = pSearchItem->next;
|
||||
|
||||
if (pSearchItem != lastItem)
|
||||
pSearchItem->next->prev = pSearchItem->prev;
|
||||
else
|
||||
lastItem = pSearchItem->prev;
|
||||
|
||||
pSearchItem->next = nsnull;
|
||||
pSearchItem->prev = nsnull;
|
||||
|
||||
length--;
|
||||
returnNode = pSearchItem->node;
|
||||
delete pSearchItem;
|
||||
|
||||
return returnNode;
|
||||
}
|
||||
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
NodeListDefinition::ListItem*
|
||||
NamedNodeMap::findListItemByName(const nsAString& name)
|
||||
{
|
||||
NodeListDefinition::ListItem* pSearchItem = firstItem;
|
||||
|
||||
while (pSearchItem)
|
||||
{
|
||||
nsAutoString nodeName;
|
||||
pSearchItem->node->getNodeName(nodeName);
|
||||
if (name.Equals(nodeName))
|
||||
return pSearchItem;
|
||||
|
||||
pSearchItem = pSearchItem->next;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
AttrMap::AttrMap()
|
||||
{
|
||||
ownerElement = nsnull;
|
||||
}
|
||||
|
||||
AttrMap::~AttrMap()
|
||||
{
|
||||
}
|
||||
|
||||
Node* AttrMap::setNamedItem(Node* arg)
|
||||
{
|
||||
if (arg->getNodeType() != Node::ATTRIBUTE_NODE)
|
||||
return nsnull;
|
||||
((Attr*)arg)->ownerElement = ownerElement;
|
||||
return NamedNodeMap::setNamedItem(arg);
|
||||
}
|
||||
|
||||
Node* AttrMap::removeNamedItem(const nsAString& name)
|
||||
{
|
||||
Attr* node = (Attr*)NamedNodeMap::removeNamedItem(name);
|
||||
if (node)
|
||||
node->ownerElement = nsnull;
|
||||
return node;
|
||||
}
|
||||
|
||||
void AttrMap::clear()
|
||||
{
|
||||
ListItem* pDeleteItem;
|
||||
ListItem* pListTraversal = firstItem;
|
||||
|
||||
while (pListTraversal) {
|
||||
pDeleteItem = pListTraversal;
|
||||
pListTraversal = pListTraversal->next;
|
||||
delete pDeleteItem->node;
|
||||
delete pDeleteItem;
|
||||
}
|
||||
firstItem = 0;
|
||||
lastItem = 0;
|
||||
length = 0;
|
||||
}
|
@ -51,83 +51,26 @@
|
||||
#include "txAtoms.h"
|
||||
#include <string.h>
|
||||
|
||||
NodeDefinition::NodeDefinition(NodeType type, const nsAString& name,
|
||||
const nsAString& value, Document* owner)
|
||||
NodeDefinition::NodeDefinition(NodeType type, nsIAtom *aLocalName,
|
||||
const nsAString& value, Document* owner) :
|
||||
mLocalName(aLocalName),
|
||||
nodeValue(value),
|
||||
nodeType(type),
|
||||
parentNode(nsnull),
|
||||
previousSibling(nsnull),
|
||||
nextSibling(nsnull),
|
||||
ownerDocument(owner),
|
||||
length(0),
|
||||
firstChild(nsnull),
|
||||
lastChild(nsnull),
|
||||
mOrderInfo(nsnull)
|
||||
{
|
||||
nodeName = name;
|
||||
Init(type, value, owner);
|
||||
}
|
||||
|
||||
NodeDefinition::NodeDefinition(NodeType aType, const nsAString& aValue,
|
||||
Document* aOwner)
|
||||
{
|
||||
switch (aType)
|
||||
{
|
||||
case CDATA_SECTION_NODE:
|
||||
{
|
||||
nodeName.AssignLiteral("#cdata-section");
|
||||
break;
|
||||
}
|
||||
case COMMENT_NODE:
|
||||
{
|
||||
nodeName.AssignLiteral("#comment");
|
||||
break;
|
||||
}
|
||||
case DOCUMENT_NODE:
|
||||
{
|
||||
nodeName.AssignLiteral("#document");
|
||||
break;
|
||||
}
|
||||
case DOCUMENT_FRAGMENT_NODE:
|
||||
{
|
||||
nodeName.AssignLiteral("#document-fragment");
|
||||
break;
|
||||
}
|
||||
case TEXT_NODE:
|
||||
{
|
||||
nodeName.AssignLiteral("#text");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
Init(aType, aValue, aOwner);
|
||||
}
|
||||
|
||||
//
|
||||
// This node is being destroyed, so loop through and destroy all the children.
|
||||
//
|
||||
NodeDefinition::~NodeDefinition()
|
||||
{
|
||||
DeleteChildren();
|
||||
delete mOrderInfo;
|
||||
}
|
||||
|
||||
void
|
||||
NodeDefinition::Init(NodeType aType, const nsAString& aValue,
|
||||
Document* aOwner)
|
||||
{
|
||||
nodeType = aType;
|
||||
nodeValue = aValue;
|
||||
ownerDocument = aOwner;
|
||||
|
||||
parentNode = nsnull;
|
||||
previousSibling = nsnull;
|
||||
nextSibling = nsnull;;
|
||||
firstChild = nsnull;
|
||||
lastChild = nsnull;
|
||||
|
||||
length = 0;
|
||||
|
||||
mOrderInfo = 0;
|
||||
}
|
||||
|
||||
//
|
||||
//Remove and delete all children of this node
|
||||
//
|
||||
void NodeDefinition::DeleteChildren()
|
||||
{
|
||||
NodeDefinition* pCurrent = firstChild;
|
||||
NodeDefinition* pDestroyer;
|
||||
@ -139,14 +82,12 @@ void NodeDefinition::DeleteChildren()
|
||||
delete pDestroyer;
|
||||
}
|
||||
|
||||
length = 0;
|
||||
firstChild = nsnull;
|
||||
lastChild = nsnull;
|
||||
delete mOrderInfo;
|
||||
}
|
||||
|
||||
nsresult NodeDefinition::getNodeName(nsAString& aName) const
|
||||
{
|
||||
aName = nodeName;
|
||||
mLocalName->ToString(aName);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -186,42 +127,11 @@ Node* NodeDefinition::getNextSibling() const
|
||||
return nextSibling;
|
||||
}
|
||||
|
||||
NamedNodeMap* NodeDefinition::getAttributes()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
Document* NodeDefinition::getOwnerDocument() const
|
||||
{
|
||||
return ownerDocument;
|
||||
}
|
||||
|
||||
Node* NodeDefinition::item(PRUint32 index)
|
||||
{
|
||||
PRUint32 selectLoop;
|
||||
NodeDefinition* pSelectNode = firstChild;
|
||||
|
||||
if (index < length)
|
||||
{
|
||||
for (selectLoop=0;selectLoop<index;selectLoop++)
|
||||
pSelectNode = pSelectNode->nextSibling;
|
||||
|
||||
return pSelectNode;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
PRUint32 NodeDefinition::getLength()
|
||||
{
|
||||
return length;
|
||||
}
|
||||
|
||||
void NodeDefinition::setNodeValue(const nsAString& newNodeValue)
|
||||
{
|
||||
nodeValue = newNodeValue;
|
||||
}
|
||||
|
||||
Node* NodeDefinition::appendChild(Node* newChild)
|
||||
{
|
||||
return nsnull;
|
||||
@ -301,58 +211,6 @@ PRInt32 NodeDefinition::getNamespaceID()
|
||||
return kNameSpaceID_None;
|
||||
}
|
||||
|
||||
//
|
||||
// Looks up the Namespace associated with a certain prefix in the context of
|
||||
// this node.
|
||||
//
|
||||
// @return namespace associated with prefix
|
||||
//
|
||||
PRInt32 NodeDefinition::lookupNamespaceID(nsIAtom* aPrefix)
|
||||
{
|
||||
// this is http://www.w3.org/2000/xmlns/,
|
||||
// ID = kNameSpaceID_XMLNS, see txStandaloneNamespaceManager::Init
|
||||
if (aPrefix == txXMLAtoms::xmlns)
|
||||
return kNameSpaceID_XMLNS;
|
||||
// this is http://www.w3.org/XML/1998/namespace,
|
||||
// ID = kNameSpaceID_XML, see txStandaloneNamespaceManager::Init
|
||||
if (aPrefix == txXMLAtoms::xml)
|
||||
return kNameSpaceID_XML;
|
||||
|
||||
Node* node = this;
|
||||
if (node->getNodeType() != Node::ELEMENT_NODE)
|
||||
node = node->getXPathParent();
|
||||
|
||||
nsAutoString name(NS_LITERAL_STRING("xmlns:"));
|
||||
if (aPrefix && (aPrefix != txXMLAtoms::_empty)) {
|
||||
// We have a prefix, search for xmlns:prefix attributes.
|
||||
nsAutoString prefixString;
|
||||
aPrefix->ToString(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.Truncate(5);
|
||||
}
|
||||
Attr* xmlns;
|
||||
while (node && node->getNodeType() == Node::ELEMENT_NODE) {
|
||||
if ((xmlns = ((Element*)node)->getAttributeNode(name))) {
|
||||
/*
|
||||
* xmlns:foo = "" makes "" a valid URI, so get that.
|
||||
* xmlns = "" resolves to 0 (null Namespace) (caught above)
|
||||
* in Element::getNamespaceID()
|
||||
*/
|
||||
nsAutoString nsURI;
|
||||
xmlns->getNodeValue(nsURI);
|
||||
return txStandaloneNamespaceManager::getNamespaceID(nsURI);
|
||||
}
|
||||
node = node->getXPathParent();
|
||||
}
|
||||
if (!aPrefix || (aPrefix == txXMLAtoms::_empty))
|
||||
return kNameSpaceID_None;
|
||||
return kNameSpaceID_Unknown;
|
||||
}
|
||||
|
||||
Node* NodeDefinition::getXPathParent()
|
||||
{
|
||||
return parentNode;
|
||||
@ -477,13 +335,15 @@ NodeDefinition::OrderInfo* NodeDefinition::getOrderInfo()
|
||||
"parent to attribute is not an element");
|
||||
|
||||
Element* elem = (Element*)parent;
|
||||
PRUint32 i;
|
||||
NamedNodeMap* attrs = elem->getAttributes();
|
||||
for (i = 0; i < attrs->getLength(); ++i) {
|
||||
if (attrs->item(i) == this) {
|
||||
Attr *attribute = elem->getFirstAttribute();
|
||||
PRUint32 i = 0;
|
||||
while (attribute) {
|
||||
if (attribute == this) {
|
||||
mOrderInfo->mOrder[lastElem] = i + kTxAttrIndexOffset;
|
||||
return mOrderInfo;
|
||||
}
|
||||
attribute = attribute->getNextAttribute();
|
||||
++i;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -1,136 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is TransforMiiX XSLT processor code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* The MITRE Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1999
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
// Tom Kneeland (3/29/99)
|
||||
//
|
||||
// Implementation of the Document Object Model Level 1 Core
|
||||
// Implementation of the NodeListDefinition class
|
||||
//
|
||||
// Modification History:
|
||||
// Who When What
|
||||
// TK 03/29/99 Created
|
||||
//
|
||||
|
||||
#include "dom.h"
|
||||
|
||||
//
|
||||
//Create an empty node list.
|
||||
//
|
||||
NodeListDefinition::NodeListDefinition()
|
||||
{
|
||||
firstItem = nsnull;
|
||||
lastItem = nsnull;
|
||||
length = 0;
|
||||
}
|
||||
|
||||
//
|
||||
//Free up the memory used by the List of Items. Don't delete the actual nodes
|
||||
//though.
|
||||
//
|
||||
NodeListDefinition::~NodeListDefinition()
|
||||
{
|
||||
ListItem* pDeleteItem;
|
||||
ListItem* pListTraversal = firstItem;
|
||||
|
||||
while (pListTraversal)
|
||||
{
|
||||
pDeleteItem = pListTraversal;
|
||||
pListTraversal = pListTraversal->next;
|
||||
delete pDeleteItem;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//Create a new ListItem, point it to the newNode, and append it to the current
|
||||
//list of nodes.
|
||||
//
|
||||
void NodeListDefinition::append(Node* newNode)
|
||||
{
|
||||
append(*newNode);
|
||||
}
|
||||
|
||||
void NodeListDefinition::append(Node& newNode)
|
||||
{
|
||||
ListItem* newListItem = new ListItem;
|
||||
if (!newListItem)
|
||||
return;
|
||||
|
||||
// Setup the new list item
|
||||
newListItem->node = &newNode;
|
||||
newListItem->prev = lastItem;
|
||||
newListItem->next = nsnull;
|
||||
|
||||
//Append the list item
|
||||
if (lastItem)
|
||||
lastItem->next = newListItem;
|
||||
|
||||
lastItem = newListItem;
|
||||
|
||||
//Adjust firstItem if this new item is being added to an empty list
|
||||
if (!firstItem)
|
||||
firstItem = lastItem;
|
||||
|
||||
//Need to increment the length of the list. Inherited from NodeList
|
||||
length++;
|
||||
}
|
||||
|
||||
//
|
||||
// Return the Node contained in the item specified
|
||||
//
|
||||
Node* NodeListDefinition::item(PRUint32 index)
|
||||
{
|
||||
PRUint32 selectLoop;
|
||||
ListItem* pListItem = firstItem;
|
||||
|
||||
if (index < length)
|
||||
{
|
||||
for (selectLoop=0;selectLoop<index;selectLoop++)
|
||||
pListItem = pListItem->next;
|
||||
|
||||
return pListItem->node;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
//
|
||||
// Return the number of items in the list
|
||||
//
|
||||
PRUint32 NodeListDefinition::getLength()
|
||||
{
|
||||
return length;
|
||||
}
|
@ -51,13 +51,11 @@
|
||||
//
|
||||
//Construct a text object with the specified document owner and data
|
||||
//
|
||||
ProcessingInstruction::ProcessingInstruction(const nsAString& theTarget,
|
||||
ProcessingInstruction::ProcessingInstruction(nsIAtom *theTarget,
|
||||
const nsAString& theData,
|
||||
Document* owner) :
|
||||
NodeDefinition(Node::PROCESSING_INSTRUCTION_NODE,
|
||||
theTarget, theData, owner)
|
||||
NodeDefinition(Node::PROCESSING_INSTRUCTION_NODE, theTarget, theData, owner)
|
||||
{
|
||||
mLocalName = do_GetAtom(nodeName);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -59,6 +59,7 @@
|
||||
#include "nsString.h"
|
||||
#include "nsVoidArray.h"
|
||||
#include "txCore.h"
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
#define kTxNsNodeIndexOffset 0x00000000;
|
||||
#define kTxAttrIndexOffset 0x40000000;
|
||||
@ -113,12 +114,8 @@ class Node : public TxObject
|
||||
virtual Node* getLastChild() const = 0;
|
||||
virtual Node* getPreviousSibling() const = 0;
|
||||
virtual Node* getNextSibling() const = 0;
|
||||
virtual NamedNodeMap* getAttributes() = 0;
|
||||
virtual Document* getOwnerDocument() const = 0;
|
||||
|
||||
//Write functions
|
||||
virtual void setNodeValue(const nsAString& nodeValue) = 0;
|
||||
|
||||
//Node manipulation functions
|
||||
virtual Node* appendChild(Node* newChild) = 0;
|
||||
|
||||
@ -133,116 +130,23 @@ class Node : public TxObject
|
||||
//txXPathNode functions
|
||||
virtual MBool getLocalName(nsIAtom** aLocalName) = 0;
|
||||
virtual PRInt32 getNamespaceID() = 0;
|
||||
virtual PRInt32 lookupNamespaceID(nsIAtom* aPrefix) = 0;
|
||||
virtual Node* getXPathParent() = 0;
|
||||
virtual PRInt32 compareDocumentPosition(Node* aOther) = 0;
|
||||
};
|
||||
|
||||
//
|
||||
// Abstract class containing the Interface for a NodeList. See NodeDefinition
|
||||
// below for the actual implementation of a WC3 NodeList as it applies to the
|
||||
// getChildNodes Node function. Also see NodeListDefinition for the
|
||||
// implementation of a NodeList as it applies to such functions as
|
||||
// getElementByTagName.
|
||||
//
|
||||
class NodeList
|
||||
{
|
||||
public:
|
||||
virtual Node* item(PRUint32 index) = 0;
|
||||
virtual PRUint32 getLength() = 0;
|
||||
protected:
|
||||
PRUint32 length;
|
||||
};
|
||||
|
||||
//
|
||||
//Definition of the implementation of a NodeList. This class maintains a
|
||||
//linked list of pointers to Nodes. "Friends" of the class can add and remove
|
||||
//pointers to Nodes as needed.
|
||||
// *** NOTE: Is there any need for someone to "remove" a node from the
|
||||
// list?
|
||||
//
|
||||
class NodeListDefinition : public NodeList
|
||||
{
|
||||
friend class NamedNodeMap; //-- LF
|
||||
friend class txXPathTreeWalker;
|
||||
public:
|
||||
NodeListDefinition();
|
||||
virtual ~NodeListDefinition();
|
||||
|
||||
void append(Node& newNode);
|
||||
void append(Node* newNode);
|
||||
|
||||
//Inherited from NodeList
|
||||
Node* item(PRUint32 index);
|
||||
PRUint32 getLength();
|
||||
|
||||
protected:
|
||||
struct ListItem {
|
||||
ListItem* next;
|
||||
ListItem* prev;
|
||||
Node* node;
|
||||
};
|
||||
|
||||
ListItem* firstItem;
|
||||
ListItem* lastItem;
|
||||
};
|
||||
|
||||
//
|
||||
//Definition of a NamedNodeMap. For the time being it builds off the
|
||||
//NodeListDefinition class. This will probably change when NamedNodeMap needs
|
||||
//to move to a more efficient search algorithm for attributes.
|
||||
//
|
||||
class NamedNodeMap : public NodeListDefinition
|
||||
{
|
||||
public:
|
||||
NamedNodeMap();
|
||||
virtual ~NamedNodeMap();
|
||||
|
||||
Node* getNamedItem(const nsAString& name);
|
||||
virtual Node* setNamedItem(Node* arg);
|
||||
virtual Node* removeNamedItem(const nsAString& name);
|
||||
|
||||
private:
|
||||
NodeListDefinition::ListItem* findListItemByName(const nsAString& name);
|
||||
// txXPathTreeWalker is friend to speed up attr iterations
|
||||
friend class txXPathTreeWalker;
|
||||
};
|
||||
|
||||
//
|
||||
// Subclass of NamedNodeMap that contains a list of attributes.
|
||||
// Whenever an attribute is added to or removed from the map, the attributes
|
||||
// ownerElement is updated.
|
||||
//
|
||||
class AttrMap : public NamedNodeMap
|
||||
{
|
||||
// Elenent needs to be friend to be able to set the AttrMaps ownerElement
|
||||
friend class Element;
|
||||
|
||||
public:
|
||||
AttrMap();
|
||||
virtual ~AttrMap();
|
||||
|
||||
Node* setNamedItem(Node* arg);
|
||||
Node* removeNamedItem(const nsAString& name);
|
||||
void clear();
|
||||
|
||||
private:
|
||||
Element* ownerElement;
|
||||
};
|
||||
|
||||
//
|
||||
// Definition and Implementation of Node and NodeList functionality. This is
|
||||
// the central class, from which all other DOM classes (objects) are derrived.
|
||||
// Users of this DOM should work strictly with the Node interface and NodeList
|
||||
// interface (see above for those definitions)
|
||||
//
|
||||
class NodeDefinition : public Node, public NodeList
|
||||
class NodeDefinition : public Node
|
||||
{
|
||||
public:
|
||||
virtual ~NodeDefinition(); //Destructor, delete all children of node
|
||||
|
||||
//Read functions
|
||||
nsresult getNodeName(nsAString& aName) const;
|
||||
virtual nsresult getNodeName(nsAString& aName) const;
|
||||
nsresult getNodeValue(nsAString& aValue);
|
||||
unsigned short getNodeType() const;
|
||||
Node* getParentNode() const;
|
||||
@ -250,12 +154,8 @@ class NodeDefinition : public Node, public NodeList
|
||||
Node* getLastChild() const;
|
||||
Node* getPreviousSibling() const;
|
||||
Node* getNextSibling() const;
|
||||
virtual NamedNodeMap* getAttributes();
|
||||
Document* getOwnerDocument() const;
|
||||
|
||||
//Write functions
|
||||
virtual void setNodeValue(const nsAString& nodeValue);
|
||||
|
||||
//Child node manipulation functions
|
||||
virtual Node* appendChild(Node* newChild);
|
||||
|
||||
@ -270,14 +170,9 @@ class NodeDefinition : public Node, public NodeList
|
||||
//txXPathNode functions
|
||||
virtual MBool getLocalName(nsIAtom** aLocalName);
|
||||
virtual PRInt32 getNamespaceID();
|
||||
virtual PRInt32 lookupNamespaceID(nsIAtom*);
|
||||
virtual Node* getXPathParent();
|
||||
virtual PRInt32 compareDocumentPosition(Node* aOther);
|
||||
|
||||
//Inherited from NodeList
|
||||
Node* item(PRUint32 index);
|
||||
PRUint32 getLength();
|
||||
|
||||
//Only to be used from XMLParser
|
||||
void appendData(const PRUnichar* aData, int aLength)
|
||||
{
|
||||
@ -288,25 +183,19 @@ class NodeDefinition : public Node, public NodeList
|
||||
friend class Document;
|
||||
friend class txXPathTreeWalker;
|
||||
friend class txXPathNodeUtils;
|
||||
NodeDefinition(NodeType type, const nsAString& name,
|
||||
NodeDefinition(NodeType type, nsIAtom *aLocalName,
|
||||
const nsAString& value, Document* owner);
|
||||
NodeDefinition(NodeType aType, const nsAString& 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.
|
||||
nsString nodeName;
|
||||
nsCOMPtr<nsIAtom> mLocalName;
|
||||
nsString nodeValue;
|
||||
|
||||
NodeDefinition* implAppendChild(NodeDefinition* newChild);
|
||||
NodeDefinition* implRemoveChild(NodeDefinition* oldChild);
|
||||
|
||||
void DeleteChildren();
|
||||
|
||||
private:
|
||||
void Init(NodeType aType, const nsAString& aValue, Document* aOwner);
|
||||
|
||||
//Type of node this is
|
||||
NodeType nodeType;
|
||||
|
||||
@ -318,6 +207,8 @@ class NodeDefinition : public Node, public NodeList
|
||||
//Pointer to the node's document
|
||||
Document* ownerDocument;
|
||||
|
||||
PRUint32 length;
|
||||
|
||||
//Data members for maintaining a list of child nodes
|
||||
NodeDefinition* firstChild;
|
||||
NodeDefinition* lastChild;
|
||||
@ -337,46 +228,6 @@ class NodeDefinition : public Node, public NodeList
|
||||
OrderInfo* getOrderInfo();
|
||||
};
|
||||
|
||||
//
|
||||
//Definition and Implementation of a Document Fragment. All functionality is
|
||||
//inherrited directly from NodeDefinition. We just need to make sure the Type
|
||||
//of the node set to Node::DOCUMENT_FRAGMENT_NODE.
|
||||
//
|
||||
class DocumentFragment : public NodeDefinition
|
||||
{
|
||||
public:
|
||||
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);
|
||||
|
||||
return implAppendChild(pNewChild);
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
};
|
||||
|
||||
private:
|
||||
friend class Document;
|
||||
DocumentFragment(Document* aOwner) :
|
||||
NodeDefinition(Node::DOCUMENT_FRAGMENT_NODE, EmptyString(), aOwner)
|
||||
{
|
||||
};
|
||||
};
|
||||
|
||||
//
|
||||
//Definition and Implementation of a Document.
|
||||
//
|
||||
@ -412,19 +263,12 @@ class Document : public NodeDefinition
|
||||
|
||||
//Factory functions for various node types
|
||||
Node* createComment(const nsAString& aData);
|
||||
Node* createDocumentFragment();
|
||||
ProcessingInstruction* createProcessingInstruction(const nsAString& aTarget,
|
||||
ProcessingInstruction* createProcessingInstruction(nsIAtom *aTarget,
|
||||
const nsAString& aData);
|
||||
Node* createTextNode(const nsAString& theData);
|
||||
|
||||
Element* createElement(const nsAString& tagName);
|
||||
Attr* createAttribute(const nsAString& name);
|
||||
|
||||
// Introduced in DOM Level 2
|
||||
Element* createElementNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aTagName);
|
||||
Attr* createAttributeNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aName);
|
||||
Element* createElementNS(nsIAtom *aPrefix, nsIAtom *aLocalName,
|
||||
PRInt32 aNamespaceID);
|
||||
Element* getElementById(const nsAString& aID);
|
||||
|
||||
// Node manipulation functions
|
||||
@ -454,16 +298,15 @@ class Element : public NodeDefinition
|
||||
virtual ~Element();
|
||||
|
||||
NamedNodeMap* getAttributes();
|
||||
void setAttribute(const nsAString& name, const nsAString& value);
|
||||
void setAttributeNS(const nsAString& aNamespaceURI,
|
||||
const nsAString& aName,
|
||||
const nsAString& aValue);
|
||||
Attr* getAttributeNode(const nsAString& name);
|
||||
|
||||
nsresult appendAttributeNS(nsIAtom *aPrefix, nsIAtom *aLocalName,
|
||||
PRInt32 aNamespaceID, const nsAString& aValue);
|
||||
|
||||
// Node manipulation functions
|
||||
Node* appendChild(Node* newChild);
|
||||
|
||||
//txXPathNode functions override
|
||||
nsresult getNodeName(nsAString& aName) const;
|
||||
MBool getLocalName(nsIAtom** aLocalName);
|
||||
PRInt32 getNamespaceID();
|
||||
MBool getAttr(nsIAtom* aLocalName, PRInt32 aNSID, nsAString& aValue);
|
||||
@ -472,16 +315,21 @@ class Element : public NodeDefinition
|
||||
// ID getter
|
||||
PRBool getIDValue(nsAString& aValue);
|
||||
|
||||
Attr *getFirstAttribute()
|
||||
{
|
||||
return mFirstAttribute;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Document;
|
||||
void setIDValue(const nsAString& aValue);
|
||||
Element(const nsAString& tagName, Document* owner);
|
||||
Element(const nsAString& aNamespaceURI, const nsAString& aTagName,
|
||||
|
||||
Element(nsIAtom *aPrefix, nsIAtom *aLocalName, PRInt32 aNamespaceID,
|
||||
Document* aOwner);
|
||||
|
||||
AttrMap mAttributes;
|
||||
nsAutoPtr<Attr> mFirstAttribute;
|
||||
nsString mIDValue;
|
||||
nsCOMPtr<nsIAtom> mLocalName;
|
||||
nsCOMPtr<nsIAtom> mPrefix;
|
||||
PRInt32 mNamespaceID;
|
||||
};
|
||||
|
||||
@ -495,33 +343,33 @@ class Attr : public NodeDefinition
|
||||
public:
|
||||
virtual ~Attr();
|
||||
|
||||
//Override the set and get member functions for a node's value to create a
|
||||
//new TEXT node when set, and to interpret its children when read.
|
||||
void setNodeValue(const nsAString& aValue);
|
||||
nsresult getNodeValue(nsAString& aValue);
|
||||
|
||||
// Node manipulation functions
|
||||
Node* appendChild(Node* newChild);
|
||||
|
||||
//txXPathNode functions override
|
||||
nsresult getNodeName(nsAString& aName) const;
|
||||
MBool getLocalName(nsIAtom** aLocalName);
|
||||
PRInt32 getNamespaceID();
|
||||
Node* getXPathParent();
|
||||
PRBool equals(nsIAtom *aLocalName, PRInt32 aNamespaceID)
|
||||
{
|
||||
return mLocalName == aLocalName && aNamespaceID == mNamespaceID;
|
||||
}
|
||||
Attr *getNextAttribute()
|
||||
{
|
||||
return mNextAttribute;
|
||||
}
|
||||
|
||||
private:
|
||||
friend class Document;
|
||||
Attr(const nsAString& name, Document* owner);
|
||||
Attr(const nsAString& aNamespaceURI, const nsAString& aName,
|
||||
Document* aOwner);
|
||||
|
||||
// These need to be friend to be able to update the ownerElement
|
||||
friend class AttrMap;
|
||||
friend class Element;
|
||||
|
||||
Element* ownerElement;
|
||||
Attr(nsIAtom *aPrefix, nsIAtom *aLocalName, PRInt32 aNamespaceID,
|
||||
Element *aOwnerElement, const nsAString &aValue);
|
||||
|
||||
nsCOMPtr<nsIAtom> mLocalName;
|
||||
nsCOMPtr<nsIAtom> mPrefix;
|
||||
PRInt32 mNamespaceID;
|
||||
Element *mOwnerElement;
|
||||
nsAutoPtr<Attr> mNextAttribute;
|
||||
};
|
||||
|
||||
//
|
||||
@ -542,10 +390,8 @@ class ProcessingInstruction : public NodeDefinition
|
||||
|
||||
private:
|
||||
friend class Document;
|
||||
ProcessingInstruction(const nsAString& theTarget, const nsAString& theData,
|
||||
ProcessingInstruction(nsIAtom *theTarget, const nsAString& theData,
|
||||
Document* owner);
|
||||
|
||||
nsCOMPtr<nsIAtom> mLocalName;
|
||||
};
|
||||
|
||||
class txStandaloneNamespaceManager
|
||||
|
@ -75,4 +75,5 @@ include $(topsrcdir)/config/rules.mk
|
||||
|
||||
DEFINES += -DXML_DTD -DXML_UNICODE
|
||||
|
||||
INCLUDES += -I$(srcdir)/../../base -I$(srcdir)/../dom -I$(srcdir)/../../xpath
|
||||
INCLUDES += -I$(srcdir)/.. -I$(srcdir)/../../base -I$(srcdir)/../dom \
|
||||
-I$(srcdir)/../../xpath
|
||||
|
@ -48,6 +48,7 @@
|
||||
#else
|
||||
#include "expat_config.h"
|
||||
#include "expat.h"
|
||||
#include "XMLUtils.h"
|
||||
#endif
|
||||
|
||||
#ifdef TX_EXE
|
||||
@ -240,7 +241,14 @@ txXMLParser::parse(istream& aInputStream, const nsAString& aUri,
|
||||
mErrorString.AppendLiteral("unable to parse xml: invalid or unopen stream encountered.");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mExpatParser = XML_ParserCreate(nsnull);
|
||||
|
||||
static const XML_Memory_Handling_Suite memsuite = {
|
||||
(void *(*)(size_t))PR_Malloc,
|
||||
(void *(*)(void *, size_t))PR_Realloc,
|
||||
PR_Free
|
||||
};
|
||||
static const PRUnichar expatSeparator = kExpatSeparatorChar;
|
||||
mExpatParser = XML_ParserCreate_MM(nsnull, &memsuite, &expatSeparator);
|
||||
if (!mExpatParser) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
@ -252,6 +260,7 @@ txXMLParser::parse(istream& aInputStream, const nsAString& aUri,
|
||||
mDocument->documentBaseURI = aUri;
|
||||
mCurrentNode = mDocument;
|
||||
|
||||
XML_SetReturnNSTriplet(mExpatParser, XML_TRUE);
|
||||
XML_SetUserData(mExpatParser, this);
|
||||
XML_SetElementHandler(mExpatParser, startElement, endElement);
|
||||
XML_SetCharacterDataHandler(mExpatParser, charData);
|
||||
@ -299,18 +308,25 @@ txXMLParser::getErrorString()
|
||||
int
|
||||
txXMLParser::StartElement(const XML_Char *aName, const XML_Char **aAtts)
|
||||
{
|
||||
const XML_Char** theAtts = aAtts;
|
||||
|
||||
Element* newElement =
|
||||
mDocument->createElement(nsDependentString((const PRUnichar*)aName));
|
||||
nsCOMPtr<nsIAtom> prefix, localName;
|
||||
PRInt32 nsID;
|
||||
XMLUtils::splitExpatName(aName, getter_AddRefs(prefix),
|
||||
getter_AddRefs(localName), &nsID);
|
||||
Element* newElement = mDocument->createElementNS(prefix, localName, nsID);
|
||||
if (!newElement) {
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
}
|
||||
|
||||
const XML_Char** theAtts = aAtts;
|
||||
while (*theAtts) {
|
||||
nsDependentString attName((const PRUnichar*)*theAtts++);
|
||||
nsDependentString attValue((const PRUnichar*)*theAtts++);
|
||||
newElement->setAttribute(attName, attValue);
|
||||
XMLUtils::splitExpatName(*theAtts++, getter_AddRefs(prefix),
|
||||
getter_AddRefs(localName), &nsID);
|
||||
nsDependentString attValue(*theAtts++);
|
||||
nsresult rv = newElement->appendAttributeNS(prefix, localName, nsID,
|
||||
attValue);
|
||||
if (NS_FAILED(rv)) {
|
||||
return XML_ERROR_NO_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
int idx;
|
||||
@ -365,7 +381,7 @@ int
|
||||
txXMLParser::ProcessingInstruction(const XML_Char *aTarget,
|
||||
const XML_Char *aData)
|
||||
{
|
||||
nsDependentString target((const PRUnichar*)aTarget);
|
||||
nsCOMPtr<nsIAtom> target = do_GetAtom(aTarget);
|
||||
nsDependentString data((const PRUnichar*)aData);
|
||||
Node* node = mDocument->createProcessingInstruction(target, data);
|
||||
mCurrentNode->appendChild(node);
|
||||
|
@ -49,7 +49,7 @@ class txXPathNode;
|
||||
|
||||
/**
|
||||
* API to load XML files into DOM datastructures.
|
||||
* Parsing is either done by expat, or by expat via the synchloaderservice
|
||||
* Parsing is either done by expat, or by expat via the syncloaderservice
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -106,6 +106,7 @@ else
|
||||
CPPSRCS += txStandaloneXPathTreeWalker.cpp
|
||||
endif
|
||||
|
||||
ifndef TX_EXE
|
||||
ifndef DISABLE_XFORMS_HOOKS
|
||||
EXPORTS = nsIXFormsUtilityService.h \
|
||||
nsIXFormsXPathEvaluator.h
|
||||
@ -113,6 +114,7 @@ EXPORTS = nsIXFormsUtilityService.h \
|
||||
CPPSRCS += nsXFormsXPathEvaluator.cpp \
|
||||
XFormsFunctionCall.cpp
|
||||
endif
|
||||
endif
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a
|
||||
# static lib.
|
||||
|
@ -89,18 +89,18 @@ txXPathTreeWalker::moveToFirstAttribute()
|
||||
}
|
||||
|
||||
Element* element = NS_STATIC_CAST(Element*, INNER);
|
||||
NamedNodeMap* attrs = element->getAttributes();
|
||||
NodeListDefinition::ListItem* item = attrs->firstItem;
|
||||
// skip XMLNS attributes
|
||||
while (item && item->node->getNamespaceID() == kNameSpaceID_XMLNS) {
|
||||
item = item->next;
|
||||
}
|
||||
if (!item) {
|
||||
return PR_FALSE;
|
||||
Attr *attribute = element->getFirstAttribute();
|
||||
while (attribute) {
|
||||
if (attribute->getNamespaceID() != kNameSpaceID_XMLNS) {
|
||||
INNER = attribute;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
attribute = attribute->getNextAttribute();
|
||||
}
|
||||
|
||||
INNER = NS_STATIC_CAST(NodeDefinition*, item->node);
|
||||
return PR_TRUE;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
@ -111,27 +111,26 @@ txXPathTreeWalker::moveToNextAttribute()
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
Node* element = INNER->getXPathParent();
|
||||
NamedNodeMap* attrs = element->getAttributes();
|
||||
// find the ListItem for the current Attr
|
||||
NodeListDefinition::ListItem* item = attrs->firstItem;
|
||||
while (item->node != INNER) {
|
||||
item = item->next;
|
||||
Element* element = NS_STATIC_CAST(Element*, INNER->getXPathParent());
|
||||
Attr *attribute = element->getFirstAttribute();
|
||||
while (attribute != INNER) {
|
||||
attribute = attribute->getNextAttribute();
|
||||
}
|
||||
NS_ASSERTION(item, "Attr not attribute of it's owner?");
|
||||
// next item
|
||||
item = item->next;
|
||||
// skip XMLNS attributes
|
||||
while (item && item->node->getNamespaceID() == kNameSpaceID_XMLNS) {
|
||||
item = item->next;
|
||||
}
|
||||
if (!item) {
|
||||
return PR_FALSE;
|
||||
NS_ASSERTION(attribute, "Attr not attribute of it's owner?");
|
||||
|
||||
attribute = attribute->getNextAttribute();
|
||||
|
||||
while (attribute) {
|
||||
if (attribute->getNamespaceID() != kNameSpaceID_XMLNS) {
|
||||
INNER = attribute;
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
attribute = attribute->getNextAttribute();
|
||||
}
|
||||
|
||||
INNER = NS_STATIC_CAST(NodeDefinition*, item->node);
|
||||
|
||||
return PR_TRUE;
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include "txURIUtils.h"
|
||||
#include "expat_config.h"
|
||||
#include "expat.h"
|
||||
#include "txXMLParser.h"
|
||||
|
||||
/**
|
||||
* Implementation of an In-Memory DOM based XML parser. The actual XML
|
||||
@ -175,11 +176,19 @@ txDriver::parse(istream& aInputStream, const nsAString& aUri)
|
||||
mErrorString.AppendLiteral("unable to parse xml: invalid or unopen stream encountered.");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mExpatParser = XML_ParserCreate(nsnull);
|
||||
|
||||
static const XML_Memory_Handling_Suite memsuite = {
|
||||
(void *(*)(size_t))PR_Malloc,
|
||||
(void *(*)(void *, size_t))PR_Realloc,
|
||||
PR_Free
|
||||
};
|
||||
static const PRUnichar expatSeparator = kExpatSeparatorChar;
|
||||
mExpatParser = XML_ParserCreate_MM(nsnull, &memsuite, &expatSeparator);
|
||||
if (!mExpatParser) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
XML_SetReturnNSTriplet(mExpatParser, XML_TRUE);
|
||||
XML_SetUserData(mExpatParser, this);
|
||||
XML_SetElementHandler(mExpatParser, startElement, endElement);
|
||||
XML_SetCharacterDataHandler(mExpatParser, charData);
|
||||
|
Loading…
Reference in New Issue
Block a user