From e67a7d706e6bbccfcacf205d9fbf828a8903c24d Mon Sep 17 00:00:00 2001 From: "axel%pike.org" Date: Fri, 19 Oct 2001 12:09:42 +0000 Subject: [PATCH] bug 76070, namespace and localName atom support for transformiix. original work by Jonas Sicking, alot of work by me. r=peterv, sicking@bigfoot.com, sr=jst git-svn-id: svn://10.0.0.236/trunk@105765 18797224-902f-48f8-a5cc-f745e15eee43 --- .../build/XSLTProcessorModule.cpp | 37 +++- .../transformiix/source/base/List.cpp | 13 +- .../transformiix/source/base/txAtom.h | 165 ++++++++++++++++ .../transformiix/source/main/transformiix.cpp | 6 +- .../source/xml/dom/mozImpl/MozillaAttr.cpp | 49 ++++- .../xml/dom/mozImpl/MozillaDocument.cpp | 21 +- .../source/xml/dom/mozImpl/MozillaElement.cpp | 78 ++++++-- .../source/xml/dom/mozImpl/MozillaNode.cpp | 167 +++++++++++++--- .../dom/mozImpl/MozillaProcInstruction.cpp | 42 +++- .../source/xml/dom/mozImpl/mozilladom.h | 90 ++++++--- .../source/xml/dom/standalone/Attr.cpp | 67 +++++++ .../source/xml/dom/standalone/Element.cpp | 126 ++++++++++-- .../xml/dom/standalone/NamedNodeMap.cpp | 16 ++ .../xml/dom/standalone/NodeDefinition.cpp | 82 ++++++-- .../dom/standalone/ProcessingInstruction.cpp | 22 ++- .../source/xml/dom/standalone/dom.h | 183 ++++++++++++++++-- .../source/xpath/NodeSetFunctionCall.cpp | 2 +- .../source/xslt/XSLTProcessor.cpp | 60 ++++-- .../transformiix/source/xslt/XSLTProcessor.h | 13 +- 19 files changed, 1085 insertions(+), 154 deletions(-) create mode 100644 mozilla/extensions/transformiix/source/base/txAtom.h diff --git a/mozilla/extensions/transformiix/build/XSLTProcessorModule.cpp b/mozilla/extensions/transformiix/build/XSLTProcessorModule.cpp index e04f3ddb340..2aa2165f0e2 100755 --- a/mozilla/extensions/transformiix/build/XSLTProcessorModule.cpp +++ b/mozilla/extensions/transformiix/build/XSLTProcessorModule.cpp @@ -68,6 +68,40 @@ RegisterTransformiix(nsIComponentManager *aCompMgr, return rv; } +// Perform our one-time intialization for this module +static PRBool gInitialized = PR_FALSE; + +PR_STATIC_CALLBACK(nsresult) +Initialize(nsIModule* self) +{ + NS_PRECONDITION(!gInitialized, "module already initialized"); + if (gInitialized) + return NS_OK; + + gInitialized = PR_TRUE; + + txXMLAtoms::XMLPrefix = NS_NewAtom("xml"); + NS_ENSURE_TRUE(txXMLAtoms::XMLPrefix, NS_ERROR_OUT_OF_MEMORY); + txXMLAtoms::XMLNSPrefix = NS_NewAtom("xmlns"); + NS_ENSURE_TRUE(txXMLAtoms::XMLNSPrefix, NS_ERROR_OUT_OF_MEMORY); + + return NS_OK; +} + +// Shutdown this module, releasing all of the module resources +PR_STATIC_CALLBACK(void) +Shutdown(nsIModule* self) +{ + NS_PRECONDITION(gInitialized, "module not initialized"); + if (! gInitialized) + return; + + gInitialized = PR_FALSE; + + NS_IF_RELEASE(txXMLAtoms::XMLPrefix); + NS_IF_RELEASE(txXMLAtoms::XMLNSPrefix); +} + // Component Table static nsModuleComponentInfo components[] = { { "Transformiix XSLT Processor", @@ -85,4 +119,5 @@ static nsModuleComponentInfo components[] = { nsSyncLoaderConstructor } }; -NS_IMPL_NSGETMODULE(TransformiixModule, components) +NS_IMPL_NSGETMODULE_WITH_CTOR_DTOR(TransformiixModule, components, + Initialize, Shutdown) diff --git a/mozilla/extensions/transformiix/source/base/List.cpp b/mozilla/extensions/transformiix/source/base/List.cpp index 55746f19d62..80c8b0f7066 100644 --- a/mozilla/extensions/transformiix/source/base/List.cpp +++ b/mozilla/extensions/transformiix/source/base/List.cpp @@ -1,4 +1,5 @@ -/* +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of @@ -363,12 +364,20 @@ void* txListIterator::advance(int i) { void* obj = 0; if (i > 0) { + if (!currentItem && !atEndOfList) { + currentItem = list->firstItem; + --i; + } for (; currentItem && i > 0; i--) currentItem = currentItem->nextItem; atEndOfList = currentItem == 0; } - else { + else if (i < 0) { + if (!currentItem && atEndOfList) { + currentItem = list->lastItem; + ++i; + } for (; currentItem && i < 0; i++) currentItem = currentItem->prevItem; diff --git a/mozilla/extensions/transformiix/source/base/txAtom.h b/mozilla/extensions/transformiix/source/base/txAtom.h new file mode 100644 index 00000000000..8ba4ebe75b9 --- /dev/null +++ b/mozilla/extensions/transformiix/source/base/txAtom.h @@ -0,0 +1,165 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is TransforMiiX XSLT processor. + * + * The Initial Developer of the Original Code is + * Jonas Sicking. + * Portions created by the Initial Developer are Copyright (C) 2001 + * Jonas Sicking. All Rights Reserved. + * + * Contributor(s): + * Jonas Sicking + * Axel Hecht + * + * 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 ***** */ + +/* + * Atom implementation for standalone and wrapper for module + * + * For module, + * txAtom is typedef'd to nsIAtom, + * for standalone there is a separate implementation. The + * code is all inlined in this header file. + * + * There is one major difference between the standalone and + * the module implementation, module atoms are refcounted, + * standalone atoms are not. Therefor code that is standalone + * only may not use TX_RELEASE..ATOM, code that works in both + * module and standalone has to pair these. Or you leak. + * + * To use this code standalone, + * TX_IMPL_ATOM_STATICS; + * has to appear in your source file. This is done by + * TX_IMPL_STATICS + * defined below. XSLTProcessor.cpp does this. + */ + +#ifndef TRANSFRMX_ATOM_H +#define TRANSFRMX_ATOM_H + +#include "TxString.h" + +#ifndef TX_EXE +#include "nsIAtom.h" +#else +#include "NamedMap.h" +#endif + +#ifdef TX_EXE + +class txAtom : public TxObject +{ +public: + txAtom(const String& aString) + { + mString = aString; + } + MBool getString(String& aString) + { + aString = mString; + return MB_TRUE; + } +private: + String mString; +}; + +class txAtomService +{ +public: + static txAtom* getAtom(const String& aString) + { + if (!mAtoms && !Init()) + return NULL; + txAtom* atom = (txAtom*)mAtoms->get(aString); + if (!atom) { + atom = new txAtom(aString); + if (!atom) + return 0; + mAtoms->put(aString, atom); + } + return atom; + } + + static MBool Init() + { + NS_ASSERTION(!mAtoms, "called without matching Shutdown()"); + if (mAtoms) + return MB_TRUE; + mAtoms = new NamedMap(); + if (!mAtoms) + return MB_FALSE; + mAtoms->setObjectDeletion(MB_TRUE); + return MB_TRUE; + } + + static void Shutdown() + { + NS_ASSERTION(mAtoms, "called without matching Init()"); + if (!mAtoms) + return; + delete mAtoms; + mAtoms = NULL; + } + +private: + static NamedMap* mAtoms; +}; + +#define TX_GET_ATOM(str) \ + (txAtomService::getAtom(str)) + +#define TX_ADDREF_ATOM(atom) {} + +#define TX_RELEASE_ATOM(atom) {} + +#define TX_RELEASE_IF_ATOM(atom) {} + +#define TX_GET_ATOM_STRING(atom, str) \ + ((atom)->getString(str)) + +#define TX_IMPL_ATOM_STATICS \ + NamedMap* txAtomService::mAtoms = 0 + +#else + +typedef nsIAtom txAtom; + +#define TX_GET_ATOM(str) \ + NS_NewAtom((str).getConstNSString()) + +#define TX_ADDREF_ATOM(atom) NS_ADDREF(atom) + +#define TX_RELEASE_ATOM(atom) NS_RELEASE(atom) + +#define TX_RELEASE_IF_ATOM(atom) NS_IF_RELEASE(atom) + +#define TX_GET_ATOM_STRING(atom, string) \ + NS_SUCCESS((atom)->ToString(string)) + +#endif // TX_EXE + +#endif // TRANSFRMX_ATOM_H diff --git a/mozilla/extensions/transformiix/source/main/transformiix.cpp b/mozilla/extensions/transformiix/source/main/transformiix.cpp index 29d1ee39aa4..64002be497d 100644 --- a/mozilla/extensions/transformiix/source/main/transformiix.cpp +++ b/mozilla/extensions/transformiix/source/main/transformiix.cpp @@ -1,4 +1,5 @@ -/* +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of @@ -56,6 +57,8 @@ void printUsage(); **/ int main(int argc, char** argv) { + if (!txInit()) + return 1; XSLTProcessor xsltProcessor; //-- add ErrorObserver @@ -135,6 +138,7 @@ int main(int argc, char** argv) { xsltProcessor.process(*xmlInput, *xmlFilename, xsltInput, *xsltFilename, *resultOutput); } resultFileStream.close(); + txShutdown(); return 0; } //-- main diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaAttr.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaAttr.cpp index 75179cb4413..388a9c4478f 100644 --- a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaAttr.cpp +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaAttr.cpp @@ -23,13 +23,14 @@ * */ -/* Implementation of the wrapper class to convert the Mozilla nsIDOMAttr - interface into a TransforMIIX Attr interface. -*/ +/* + * Implementation of the wrapper class to convert the Mozilla nsIDOMAttr + * interface into a TransforMiiX Attr interface. + */ #include "mozilladom.h" -/** +/* * Construct a wrapper with the specified Mozilla object and document owner. * * @param aAttr the nsIDOMAttr you want to wrap @@ -37,16 +38,27 @@ */ Attr::Attr(nsIDOMAttr* aAttr, Document* aOwner) : Node(aAttr, aOwner) { + NS_ASSERTION(aAttr, "Wrapper needs nsObject"); + NS_ASSERTION(aOwner, "Wrapper needs owner document"); + if (!aAttr || !aOwner) + return; + nsAutoString ns; + aAttr->GetNamespaceURI(ns); + NS_ASSERTION(aOwner->nsNSManager, + "owner document lacks namespace manager"); + if (!aOwner->nsNSManager) + return; + aOwner->nsNSManager->GetNameSpaceID(ns, namespaceID); } -/** +/* * Destructor */ Attr::~Attr() { } -/** +/* * Call nsIDOMAttr::GetName to retrieve the name of this attribute. * * @return the attribute's name @@ -61,7 +73,7 @@ const String& Attr::getName() return nodeName; } -/** +/* * Call nsIDOMAttr::GetSpecified to retrieve the specified flag for this * attribute. * @@ -77,7 +89,7 @@ MBool Attr::getSpecified() const return specified; } -/** +/* * Call nsIDOMAttr::GetValue to retrieve the value of this attribute. * * @return the attribute's value @@ -92,7 +104,7 @@ const String& Attr::getValue() return nodeValue; } -/** +/* * Call nsIDOMAttr::SetValue to set the value of this attribute. * * @return the attribute's value @@ -119,3 +131,22 @@ Node* Attr::getXPathParent() return ownerDocument->createWrapper(ownerElem); return NULL; } + +/* + * Returns the local name atomized + * + * @return the node's localname atom + */ +MBool Attr::getLocalName(txAtom** aLocalName) +{ + if (!aLocalName) + return MB_FALSE; + NSI_FROM_TX(Attr) + if (!nsAttr) + return MB_FALSE; + nsAutoString lName; + NS_ENSURE_SUCCESS(nsAttr->GetLocalName(lName), MB_FALSE); + *aLocalName = NS_NewAtom(lName); + NS_ENSURE_TRUE(*aLocalName, MB_FALSE); + return MB_TRUE; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaDocument.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaDocument.cpp index 855d9cfb5e5..ddd06e1cf81 100644 --- a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaDocument.cpp +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaDocument.cpp @@ -1,4 +1,5 @@ -/* +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * * (C) Copyright The MITRE Corporation 1999 All rights reserved. * * The contents of this file are subject to the Mozilla Public License @@ -59,8 +60,15 @@ Document::Document() : Node(0, 0) //if (NS_FAILED(res)) return NULL; ownerDocument = this; - wrapperHashTable = new nsObjectHashtable(nsnull, nsnull, DeleteWrapper, nsnull); + wrapperHashTable = new nsObjectHashtable(nsnull, nsnull, + DeleteWrapper, nsnull); bInHashTableDeletion = PR_FALSE; + nsCOMPtr doc(do_QueryInterface(document)); + NS_ASSERTION(doc,"document doesn't implement nsIDocument"); + if (doc) { + doc->GetNameSpaceManager(*getter_AddRefs(nsNSManager)); + NS_ASSERTION(nsNSManager, "Unable to get nsINamespaceManager"); + } addWrapper(this); } @@ -73,8 +81,15 @@ Document::Document() : Node(0, 0) Document::Document(nsIDOMDocument* aDocument) : Node(aDocument, 0) { ownerDocument = this; - wrapperHashTable = new nsObjectHashtable(nsnull, nsnull, DeleteWrapper, nsnull); + wrapperHashTable = new nsObjectHashtable(nsnull, nsnull, + DeleteWrapper, nsnull); bInHashTableDeletion = PR_FALSE; + nsCOMPtr doc(do_QueryInterface(aDocument)); + NS_ASSERTION(doc,"document doesn't implement nsIDocument"); + if (doc) { + doc->GetNameSpaceManager(*getter_AddRefs(nsNSManager)); + NS_ASSERTION(nsNSManager, "Unable to get nsINamespaceManager"); + } addWrapper(this); } diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaElement.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaElement.cpp index 1b98743e0cc..73bd7669538 100644 --- a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaElement.cpp +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaElement.cpp @@ -1,4 +1,5 @@ -/* +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * * (C) Copyright The MITRE Corporation 1999 All rights reserved. * * The contents of this file are subject to the Mozilla Public License @@ -22,13 +23,15 @@ * */ -/* Implementation of the wrapper class to convert the Mozilla nsIDOMElement - interface into a TransforMIIX Element interface. -*/ +/* + * Implementation of the wrapper class to convert the Mozilla nsIDOMElement + * interface into a TransforMiiX Element interface. + */ #include "mozilladom.h" +#include "nsIContent.h" -/** +/* * Construct a wrapper with the specified Mozilla object and document owner. * * @param aElement the nsIDOMElement you want to wrap @@ -37,16 +40,20 @@ Element::Element(nsIDOMElement* aElement, Document* aOwner) : Node(aElement, aOwner) { + nsCOMPtr cont(do_QueryInterface(aElement)); + NS_ASSERTION(cont, "Element doesn't implement nsIContent"); + if (cont) + cont->GetNameSpaceID(namespaceID); } -/** +/* * Destructor */ Element::~Element() { } -/** +/* * Call nsIDOMElement::GetTagName to retrieve the tag name for this element. * * @return the element's tag name @@ -61,7 +68,7 @@ const String& Element::getTagName() return nodeName; } -/** +/* * Get the attribute node for the specified name and return it's value or the * null string if the attribute node doesn't exist. * @@ -78,7 +85,7 @@ const String& Element::getAttribute(const String& aName) return NULL_STRING; } -/** +/* * Call nsIDOMElement::SetAttribute to set an attribute to the specified value. * * @param aName the name of the attribute you want to set @@ -92,7 +99,7 @@ void Element::setAttribute(const String& aName, const String& aValue) nsElement->SetAttribute(aName.getConstNSString(), aValue.getConstNSString()); } -/** +/* * Call nsIDOMElement::SetAttributeNS to set an attribute to the specified * value. * @@ -111,7 +118,7 @@ void Element::setAttributeNS(const String& aNamespaceURI, const String& aName, aValue.getConstNSString()); } -/** +/* * Call nsIDOMElement::RemoveAttribute to remove an attribute. We need to make * this call a bit more complicated than usual because we want to make sure * we remove the attribute wrapper from the document's wrapper hash table. @@ -141,7 +148,7 @@ void Element::removeAttribute(const String& aName) } } -/** +/* * Call nsIDOMElement::GetAttributeNode to get an nsIDOMAttr. If successful, * refer to the owner document for an attribute wrapper. * @@ -160,7 +167,27 @@ Attr* Element::getAttributeNode(const String& aName) return NULL; } -/** +/* + * Call nsIContent::GetAttr for the localname and nsID. + */ +MBool Element::getAttr(txAtom* aLocalName, PRInt32 aNSID, + String& aValue) +{ + aValue.clear(); + nsCOMPtr cont(do_QueryInterface(nsObject)); + NS_ASSERTION(cont, "Element doesn't implement nsIContent"); + if (!cont) + return MB_FALSE; + nsresult rv; + rv = cont->GetAttr(aNSID, aLocalName, aValue.getNSString()); + NS_ENSURE_SUCCESS(rv, MB_FALSE); + if (rv != NS_CONTENT_ATTR_NOT_THERE) + return MB_TRUE; + return MB_FALSE; +} + + +/* * Call nsIDOMElement::SetAttributeNode passing it the nsIDOMAttr object wrapped * by the aNewAttr parameter. * @@ -180,7 +207,7 @@ Attr* Element::setAttributeNode(Attr* aNewAttr) return NULL; } -/** +/* * Call nsIDOMElement::RemoveAttributeNode, then refer to the owner document to * remove it from its hash table. The caller is then responsible for destroying * the wrapper. @@ -197,8 +224,7 @@ Attr* Element::removeAttributeNode(Attr* aOldAttr) Attr* attrWrapper = NULL; if (NS_SUCCEEDED(nsElement->RemoveAttributeNode(oldAttr, - getter_AddRefs(removedAttr)))) - { + getter_AddRefs(removedAttr)))) { attrWrapper = (Attr*)ownerDocument->removeWrapper(aOldAttr); if (!attrWrapper) attrWrapper = new Attr(removedAttr, ownerDocument); @@ -207,7 +233,7 @@ Attr* Element::removeAttributeNode(Attr* aOldAttr) return NULL; } -/** +/* * Call nsIDOMElement::GetElementsByTagName. If successful, refer to the owner * document for a Nodelist wrapper. * @@ -226,7 +252,7 @@ NodeList* Element::getElementsByTagName(const String& aName) return NULL; } -/** +/* * Simply call nsIDOMElement::Normalize(). */ void Element::normalize() @@ -236,3 +262,19 @@ void Element::normalize() if (nsElement) nsElement->Normalize(); } + +/* + * Returns the local name atomized + * + * @return the node's localname atom + */ +MBool Element::getLocalName(txAtom** aLocalName) +{ + NS_ENSURE_TRUE(aLocalName, MB_FALSE); + nsCOMPtr cont(do_QueryInterface(nsObject)); + NS_ASSERTION(cont, "Element doesn't implement nsIContent"); + if (!cont) + return MB_FALSE; + cont->GetTag(*aLocalName); + return MB_TRUE; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaNode.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaNode.cpp index 7fe4b6f03d5..8934aaa1b26 100644 --- a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaNode.cpp +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaNode.cpp @@ -27,11 +27,14 @@ interface into a TransforMIIX Node interface. */ +#include "txAtom.h" #include "mozilladom.h" +#include "nsIContent.h" +#include "nsINameSpaceManager.h" MOZ_DECL_CTOR_COUNTER(Node) -/** +/* * Construct a wrapper with the specified Mozilla object and document owner. * * @param aNode the nsIDOMNode you want to wrap @@ -41,9 +44,10 @@ Node::Node(nsIDOMNode* aNode, Document* aOwner) : MozillaObjectWrapper(aNode, aOwner) { MOZ_COUNT_CTOR(Node); + namespaceID=0; } -/** +/* * Destructor */ Node::~Node() @@ -51,7 +55,7 @@ Node::~Node() MOZ_COUNT_DTOR(Node); } -/** +/* * Wrap a different Mozilla object with this wrapper. * * @param aNode the nsIDOMNode you want to wrap @@ -73,7 +77,7 @@ void Node::setNSObj(nsIDOMNode* aNode) ownerDocument->addWrapper(this); } -/** +/* * Call nsIDOMNode::GetNodeName to get the node's name. * * @return the node's name @@ -88,7 +92,7 @@ const String& Node::getNodeName() return nodeName; } -/** +/* * Call nsIDOMNode::GetNodeValue to get the node's value. * * @return the node's name @@ -103,7 +107,7 @@ const String& Node::getNodeValue() return nodeValue; } -/** +/* * Call nsIDOMNode::GetNodeType to get the node's type. * * @return the node's type @@ -118,7 +122,7 @@ unsigned short Node::getNodeType() const return nodeType; } -/** +/* * Call nsIDOMNode::GetParentNode to get the node's parent. * * @return the node's parent @@ -134,7 +138,7 @@ Node* Node::getParentNode() return NULL; } -/** +/* * Call nsIDOMNode::GetChildNodes to get the node's childnodes. * * @return the node's children @@ -150,7 +154,7 @@ NodeList* Node::getChildNodes() return NULL; } -/** +/* * Call nsIDOMNode::GetFirstChild to get the node's first child. * * @return the node's first child @@ -166,7 +170,7 @@ Node* Node::getFirstChild() return NULL; } -/** +/* * Call nsIDOMNode::GetLastChild to get the node's last child. * * @return the node's first child @@ -182,7 +186,7 @@ Node* Node::getLastChild() return NULL; } -/** +/* * Call nsIDOMNode::GetPreviousSibling to get the node's previous sibling. * * @return the node's previous sibling @@ -198,7 +202,7 @@ Node* Node::getPreviousSibling() return NULL; } -/** +/* * Call nsIDOMNode::GetNextSibling to get the node's next sibling. * * @return the node's next sibling @@ -214,7 +218,7 @@ Node* Node::getNextSibling() return NULL; } -/** +/* * Call nsIDOMNode::GetAttributes to get the node's attributes. * * @return the node's attributes @@ -230,7 +234,7 @@ NamedNodeMap* Node::getAttributes() return NULL; } -/** +/* * Get this wrapper's owning document. * * @return the wrapper's owning document @@ -240,7 +244,7 @@ Document* Node::getOwnerDocument() return ownerDocument; } -/** +/* * Call nsIDOMNode::SetNodeValue to set this node's value. * * @param aNewNodeValue the new value for the node @@ -253,7 +257,7 @@ void Node::setNodeValue(const String& aNewNodeValue) nsNode->SetNodeValue(aNewNodeValue.getConstNSString()); } -/** +/* * Call nsIDOMNode::insertBefore to insert a new child before an existing child. * * @param aNewChild the new child to insert @@ -275,7 +279,7 @@ Node* Node::insertBefore(Node* aNewChild, Node* aRefChild) return NULL; } -/** +/* * Call nsIDOMNode::ReplaceChild to replace an existing child with a new child. * * @param aNewChild the new child to insert @@ -297,7 +301,7 @@ Node* Node::replaceChild(Node* aNewChild, Node* aOldChild) return NULL; } -/** +/* * Call nsIDOMNode::RemoveChild to remove a child. * * @param aOldChild the child to remove @@ -317,7 +321,7 @@ Node* Node::removeChild(Node* aOldChild) return NULL; } -/** +/* * Call nsIDOMNode::AppendChild to append a child to the current node. * * @param aNewChild the child to append @@ -337,7 +341,7 @@ Node* Node::appendChild(Node* aNewChild) return NULL; } -/** +/* * Call nsIDOMNode::CloneNode to clone this node. * * @param aDeep recursive cloning? @@ -359,7 +363,7 @@ Node* Node::cloneNode(MBool aDeep, Node* aDest) return NULL; } -/** +/* * Call nsIDOMNode::HasChildNodes to return if this node has children. * * @return boolean value that says if this node has children @@ -374,12 +378,121 @@ MBool Node::hasChildNodes() const return returnValue; } -/** +/* + * Returns the Namespace URI + * uses the Mozilla dom + * Intoduced in DOM2 + */ +String Node::getNamespaceURI() +{ + NSI_FROM_TX(Node) + String uri; + if (nsNode) + nsNode->GetNamespaceURI(uri.getNSString()); + return uri; +} + +/* + * Returns the local name atomized + * + * @return the node's localname atom + */ +MBool Node::getLocalName(txAtom** aLocalName) +{ + if (!aLocalName) + return MB_FALSE; + *aLocalName = 0; + return MB_TRUE; +} + +/* + * Returns the namespace ID of the node + * + * @return the node's namespace ID + */ +PRInt32 Node::getNamespaceID() +{ + return namespaceID; +} + +/* + * Returns the parent node according to the XPath datamodel + */ +Node* Node::getXPathParent() +{ + return getParentNode(); +} + +/* + * Returns the namespace ID associated with the given prefix in the context + * of this node. + * + * Creating our own implementation until content provides us with a way + * to do it, that is a way that jst doesn't want to kill. + * + * @param prefix atom for prefix to look up + * @return namespace ID for prefix + */ +PRInt32 Node::lookupNamespaceID(txAtom* prefix) +{ + NSI_FROM_TX(Node) + nsresult rv; + + if (!nsNode) + return kNameSpaceID_Unknown; + if (prefix == txXMLAtoms::XMLNSPrefix) + return kNameSpaceID_XMLNS; + if (prefix == txXMLAtoms::XMLPrefix) + return kNameSpaceID_XML; + + nsCOMPtr elem; + unsigned short nodeType = 0; + nsNode->GetNodeType(&nodeType); + switch(nodeType) { + case Node::ATTRIBUTE_NODE : + { + nsCOMPtr owner; + nsCOMPtr attr(do_QueryInterface(nsNode)); + + rv = attr->GetOwnerElement(getter_AddRefs(owner)); + NS_ENSURE_SUCCESS(rv, kNameSpaceID_Unknown); + + elem = do_QueryInterface(owner); + break; + } + default: + //XXX Namespace: we have to handle namespace nodes here + elem = do_QueryInterface(nsNode); + } + + while (elem) { + nsAutoString uri; + rv = elem->GetAttr(kNameSpaceID_XMLNS, prefix, uri); + NS_ENSURE_SUCCESS(rv, kNameSpaceID_Unknown); + if (rv != NS_CONTENT_ATTR_NOT_THERE) { + PRInt32 nsId; + NS_ASSERTION(ownerDocument->nsNSManager, + "owner document lacks namespace manager"); + if (!ownerDocument->nsNSManager) + return kNameSpaceID_Unknown; + ownerDocument->nsNSManager->RegisterNameSpace(uri, nsId); + return nsId; + } + + nsCOMPtr temp(elem); + rv = temp->GetParent(*getter_AddRefs(elem)); + NS_ENSURE_SUCCESS(rv, kNameSpaceID_Unknown); + } + // Error, namespace not found + return kNameSpaceID_Unknown; +} + +/* * Returns the base URI of the node. Acccounts for xml:base * attributes. * * @return base URI for the node -**/ + */ String Node::getBaseURI() { NSI_FROM_TX(Node) @@ -391,11 +504,3 @@ String Node::getBaseURI() return url; } - -/* - * Returns the parent node according to the XPath datamodel - */ -Node* Node::getXPathParent() -{ - return getParentNode(); -} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaProcInstruction.cpp b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaProcInstruction.cpp index 95602d5948d..6c96a3d0937 100644 --- a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaProcInstruction.cpp +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/MozillaProcInstruction.cpp @@ -1,4 +1,5 @@ -/* +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * * (C) Copyright The MITRE Corporation 1999 All rights reserved. * * The contents of this file are subject to the Mozilla Public License @@ -22,14 +23,16 @@ * */ -/* Implementation of the wrapper class to convert the Mozilla - nsIDOMProcessingInstruction interface into a TransforMIIX - ProcessingInstruction interface. -*/ +/* + * Implementation of the wrapper class to convert the Mozilla + * nsIDOMProcessingInstruction interface into a TransforMiiX + * ProcessingInstruction interface. + */ #include "mozilladom.h" +#include "nsIAtom.h" -/** +/* * Construct a wrapper with the specified Mozilla object and document owner. * * @param aProcInstr the nsIDOMProcessingInstruction you want to wrap @@ -42,14 +45,14 @@ ProcessingInstruction::ProcessingInstruction( { } -/** +/* * Destructor */ ProcessingInstruction::~ProcessingInstruction() { } -/** +/* * Call nsIDOMProcessingInstruction::GetTarget to retrieve the target of the * processing instruction. * @@ -65,7 +68,7 @@ const String& ProcessingInstruction::getTarget() return target; } -/** +/* * Call nsIDOMProcessingInstruction::GetData to retrieve the data of the * processing instruction. * @@ -81,7 +84,7 @@ const String& ProcessingInstruction::getData() return data; } -/** +/* * Call nsIDOMProcessingInstruction::SetData to set the data of the * processing instruction. * @@ -94,3 +97,22 @@ void ProcessingInstruction::setData(const String& aData) if (nsProcessingInstruction) nsProcessingInstruction->SetData(aData.getConstNSString()); } + +/* + * Returns the local name atomized + * + * @return the node's localname atom + */ +MBool ProcessingInstruction::getLocalName(txAtom** aLocalName) +{ + if (!aLocalName) + return MB_FALSE; + NSI_FROM_TX(ProcessingInstruction) + if (!nsProcessingInstruction) + return MB_FALSE; + nsAutoString target; + nsProcessingInstruction->GetNodeName(target); + *aLocalName = NS_NewAtom(target); + NS_ENSURE_TRUE(*aLocalName, MB_FALSE); + return MB_TRUE; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/mozilladom.h b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/mozilladom.h index 92ae4c0f833..c00230c5ffb 100644 --- a/mozilla/extensions/transformiix/source/xml/dom/mozImpl/mozilladom.h +++ b/mozilla/extensions/transformiix/source/xml/dom/mozImpl/mozilladom.h @@ -23,11 +23,11 @@ /* Definition of the wrapper classes. */ -/** +/* * Implementation of the Mozilla Wrapper classes for the Mozilla DOM to - * TransforMIIX DOM interface conversion. Note that these wrapper classes are - * only interchangable with the TransforMIIX DOM at compile time. They are - * merely a copy of the TransforMIIX interface/class structure wich then + * TransforMiiX DOM interface conversion. Note that these wrapper classes are + * only interchangable with the TransforMiiX DOM at compile time. They are + * merely a copy of the TransforMiiX interface/class structure wich then * deffer their processing to a Mozilla object. Complete interchangability * would require the use of multiple inherritance using virtual base classes * and RTTI which is not supported in Mozilla's cross platform domain. @@ -71,6 +71,9 @@ #include "nsIDOMNotation.h" #include "nsIDOMProcessingInstruction.h" #include "nsIDOMText.h" +#include "nsINameSpaceManager.h" + +#include "txAtom.h" #ifndef NULL typedef 0 NULL; @@ -92,8 +95,22 @@ class Notation; class ProcessingInstruction; class Text; +/* + * Definition of txXMLAtoms + */ +class txXMLAtoms +{ +public: + static txAtom* XMLPrefix; + static txAtom* XMLNSPrefix; +}; -/** +#define TX_IMPL_DOM_STATICS \ + txAtom* txXMLAtoms::XMLPrefix = 0; \ + txAtom* txXMLAtoms::XMLNSPrefix = 0 + + +/* * This macro creates a nsCOMPtr to a specific interface for the * wrapper's Mozilla object. The nsCOMPtr will be named like the * supplied class with "ns" as a prefix. @@ -101,7 +118,7 @@ class Text; #define NSI_FROM_TX(_txClass) \ nsCOMPtr ns##_txClass(do_QueryInterface(nsObject)); -/** +/* * This macro creates a nsCOMPtr to a specific interface for the * wrapper's Mozilla object. It returns NULL if the interface is * unavailable (or the wrapper's Mozilla object is nsnull). The @@ -113,7 +130,7 @@ NSI_FROM_TX(_txClass) \ if (!ns##_txClass) return NULL; -/** +/* * This macro can be used to declare a createWrapper implementation * for the supplied wrapper class. This macro should only be used * in MozillaDocument. @@ -121,7 +138,7 @@ if (!ns##_txClass) return NULL; #define IMPL_CREATE_WRAPPER(_txClass) \ IMPL_CREATE_WRAPPER2(_txClass, create##_txClass) -/** +/* * This macro can be used to declare a createWrapper implementation * for the supplied wrapper class. The function parameter defines * the function name for the implementation function. This macro @@ -144,13 +161,13 @@ _txClass* Document::_function(nsIDOM##_txClass* aNsObject) \ return wrapper; \ } -/** +/* * This macro does a nullsafe getNSObj. If the wrapper object is NULL, * NULL is returned. Else getNSObj is used to get the inner object. */ #define GET_NSOBJ(_txWrapper) ((_txWrapper) ? (_txWrapper)->getNSObj() : nsnull) -/** +/* * Base wrapper class for a Mozilla object. Owns the Mozilla object through an * nsCOMPtr. */ @@ -172,7 +189,7 @@ class MozillaObjectWrapper : public TxObject nsCOMPtr nsObject; }; -/** +/* * Wrapper class for nsIDOMDOMImplementation. */ class DOMImplementation : public MozillaObjectWrapper @@ -184,7 +201,7 @@ class DOMImplementation : public MozillaObjectWrapper MBool hasFeature(const String& aFeature, const String& aVersion) const; }; -/** +/* * Wrapper class for nsIDOMNode. It provides the generic Node interface, * forwarding all functionality to its Mozilla counterpart. */ @@ -238,18 +255,25 @@ class Node : public MozillaObjectWrapper virtual MBool hasChildNodes() const; + //Introduced in DOM2 + virtual String getNamespaceURI(); + //From DOM3 26-Jan-2001 WD virtual String getBaseURI(); // txXPathNode functions + virtual MBool getLocalName(txAtom** aLocalName); + virtual PRInt32 getNamespaceID(); + virtual PRInt32 lookupNamespaceID(txAtom* prefix); virtual Node* getXPathParent(); protected: String nodeName; String nodeValue; + PRInt32 namespaceID; }; -/** +/* * Wrapper class for nsIDOMNodeList. */ class NodeList : public MozillaObjectWrapper @@ -263,7 +287,7 @@ class NodeList : public MozillaObjectWrapper }; -/** +/* * Wrapper class for nsIDOMNamedNodeMap. */ class NamedNodeMap : public MozillaObjectWrapper @@ -279,7 +303,7 @@ class NamedNodeMap : public MozillaObjectWrapper PRUint32 getLength(); }; -/** +/* * Wrapper class for nsIDOMDocumentFragment. */ class DocumentFragment : public Node @@ -290,11 +314,14 @@ class DocumentFragment : public Node ~DocumentFragment(); }; -/** +/* * Wrapper class for nsIDOMDocument. */ class Document : public Node { + friend class Attr; // Attrs and Nodes need to get to the cached nsNSManager + friend class Node; + public: Document(); Document(nsIDOMDocument* aDocument); @@ -374,9 +401,11 @@ class Document : public Node PRBool bInHashTableDeletion; nsObjectHashtable *wrapperHashTable; + + nsCOMPtr nsNSManager; }; -/** +/* * Wrapper class for nsIDOMElement. */ class Element : public Node @@ -397,9 +426,12 @@ class Element : public Node NodeList* getElementsByTagName(const String& aName); void normalize(); + // txXPathNode functions + MBool getLocalName(txAtom** aLocalName); + MBool getAttr(txAtom* aLocalName, PRInt32 aNSID, String& aValue); }; -/** +/* * Wrapper class for nsIDOMAttr. */ class Attr : public Node @@ -414,10 +446,11 @@ class Attr : public Node void setValue(const String& aNewValue); // txXPathNode functions override + MBool getLocalName(txAtom** aLocalName); Node* getXPathParent(); }; -/** +/* * Wrapper class for nsIDOMCharacterData. */ class CharacterData : public Node @@ -440,7 +473,7 @@ class CharacterData : public Node String nodeValue; }; -/** +/* * Wrapper class for nsIDOMText. */ class Text : public CharacterData @@ -452,7 +485,7 @@ class Text : public CharacterData Text* splitText(PRInt32 aOffset); }; -/** +/* * Wrapper class for nsIDOMComment. */ class Comment : public CharacterData @@ -462,7 +495,7 @@ class Comment : public CharacterData ~Comment(); }; -/** +/* * Wrapper class for nsIDOMCDATASection. */ class CDATASection : public Text @@ -472,7 +505,7 @@ class CDATASection : public Text ~CDATASection(); }; -/** +/* * Wrapper class for nsIDOMProcessingInstruction. */ class ProcessingInstruction : public Node @@ -487,12 +520,15 @@ class ProcessingInstruction : public Node void setData(const String& aData); + // txXPathNode functions + MBool getLocalName(txAtom** aLocalName); + private: String target; String data; }; -/** +/* * Wrapper class for nsIDOMNotation. */ class Notation : public Node @@ -509,7 +545,7 @@ class Notation : public Node String systemId; }; -/** +/* * Wrapper class for nsIDOMEntity. */ class Entity : public Node @@ -528,7 +564,7 @@ class Entity : public Node String notationName; }; -/** +/* * Wrapper class for nsIDOMEntityReference. */ class EntityReference : public Node @@ -539,7 +575,7 @@ class EntityReference : public Node ~EntityReference(); }; -/** +/* * Wrapper class for nsIDOMDocumentType. */ class DocumentType : public Node diff --git a/mozilla/extensions/transformiix/source/xml/dom/standalone/Attr.cpp b/mozilla/extensions/transformiix/source/xml/dom/standalone/Attr.cpp index 3b0ed8c16b4..4ca292378e4 100644 --- a/mozilla/extensions/transformiix/source/xml/dom/standalone/Attr.cpp +++ b/mozilla/extensions/transformiix/source/xml/dom/standalone/Attr.cpp @@ -26,6 +26,7 @@ // #include "dom.h" +#include "txAtom.h" // //Construct an Attribute object using the specified name and document owner @@ -34,6 +35,41 @@ Attr::Attr(const String& name, Document* owner): NodeDefinition(Node::ATTRIBUTE_NODE, name, NULL_STRING, owner) { specified = MB_FALSE; + + int idx = nodeName.indexOf(':'); + if (idx == NOT_FOUND) { + mLocalName = TX_GET_ATOM(nodeName); + if (mLocalName == txXMLAtoms::XMLNSPrefix) + mNamespaceID = kNameSpaceID_XMLNS; + else + mNamespaceID = kNameSpaceID_None; + } + else { + String tmp; + nodeName.subString(idx+1, tmp); + mLocalName = TX_GET_ATOM(tmp); + // namespace handling has to be handled late, the attribute must + // be added to the tree to resolve the prefix, unless it's + // xmlns or xml, try to do that here + String prefix; + nodeName.subString(0, idx, prefix); + txAtom* prefixAtom = TX_GET_ATOM(prefix); + if (prefixAtom == txXMLAtoms::XMLNSPrefix) + mNamespaceID = kNameSpaceID_XMLNS; + else if (prefixAtom == txXMLAtoms::XMLPrefix) + mNamespaceID = kNameSpaceID_XML; + else + mNamespaceID = kNameSpaceID_Unknown; + TX_RELEASE_IF_ATOM(prefixAtom); + } +} + +// +//Release the mLocalName +// +Attr::~Attr() +{ + TX_RELEASE_IF_ATOM(mLocalName); } // @@ -135,6 +171,37 @@ Node* Attr::insertBefore(Node* newChild, Node* refChild) return returnVal; } +// +//Return the attributes local (unprefixed) name atom. +// +MBool Attr::getLocalName(txAtom** aLocalName) +{ + if (!aLocalName) + return MB_FALSE; + *aLocalName = mLocalName; + TX_ADDREF_ATOM(*aLocalName); + return MB_TRUE; +} + +// +//Return the namespace the attribute belongs to. If the attribute doesn't +//have a prefix it doesn't belong to any namespace per the namespace spec, +//and is handled in the constructor. +// +PRInt32 Attr::getNamespaceID() +{ + if (mNamespaceID >= 0) + return mNamespaceID; + + int idx = nodeName.indexOf(':'); + String prefix; + nodeName.subString(0, idx, prefix); + txAtom* prefixAtom = TX_GET_ATOM(prefix); + mNamespaceID = lookupNamespaceID(prefixAtom); + TX_RELEASE_IF_ATOM(prefixAtom); + return mNamespaceID; +} + // //Return the attributes owning element // diff --git a/mozilla/extensions/transformiix/source/xml/dom/standalone/Element.cpp b/mozilla/extensions/transformiix/source/xml/dom/standalone/Element.cpp index cb4d64363c1..b5171740828 100644 --- a/mozilla/extensions/transformiix/source/xml/dom/standalone/Element.cpp +++ b/mozilla/extensions/transformiix/source/xml/dom/standalone/Element.cpp @@ -26,6 +26,9 @@ // #include "dom.h" +#include "txAtom.h" + +const String XMLNS_ATTR = "xmlns"; // //Construct a new element with the specified tagName and Document owner. @@ -35,7 +38,77 @@ Element::Element(const String& tagName, Document* owner) : NodeDefinition(Node::ELEMENT_NODE, tagName, NULL_STRING, owner) { - attributes.ownerElement = this; + mAttributes.ownerElement = this; + mNamespaceID = kNameSpaceID_Unknown; + + int idx = nodeName.indexOf(':'); + if (idx == NOT_FOUND) { + mLocalName = TX_GET_ATOM(nodeName); + } + else { + String tmp; + nodeName.subString(idx+1, tmp); + mLocalName = TX_GET_ATOM(tmp); + } +} + +// +// This element is being destroyed, so destroy all attributes stored +// in the mAttributes NamedNodeMap. +// +Element::~Element() +{ + mAttributes.clear(); + TX_RELEASE_IF_ATOM(mLocalName); +} + +// +//Return the elements local (unprefixed) name. +// +MBool Element::getLocalName(txAtom** aLocalName) +{ + if (!aLocalName) + return MB_FALSE; + *aLocalName = mLocalName; + TX_ADDREF_ATOM(*aLocalName); + return MB_TRUE; +} + +// +//Return the namespace the elements belongs to. +// +PRInt32 Element::getNamespaceID() +{ + if (mNamespaceID>=0) + return mNamespaceID; + int idx = nodeName.indexOf(':'); + if (idx == NOT_FOUND) { + Node* node = this; + while (node && node->getNodeType() == Node::ELEMENT_NODE) { + String nsURI; + if (((Element*)node)->getAttr(txXMLAtoms::XMLNSPrefix, + kNameSpaceID_XMLNS, nsURI)) { + // xmlns = "" sets the default namespace ID to kNameSpaceID_None; + if (!nsURI.isEmpty()) { + mNamespaceID = txNamespaceManager::getNamespaceID(nsURI); + } + else { + mNamespaceID = kNameSpaceID_None; + } + return mNamespaceID; + } + node = node->getParentNode(); + } + mNamespaceID = kNameSpaceID_None; + } + else { + String prefix; + nodeName.subString(0, idx, prefix); + txAtom* prefixAtom = TX_GET_ATOM(prefix); + mNamespaceID = lookupNamespaceID(prefixAtom); + TX_RELEASE_IF_ATOM(prefixAtom); + } + return mNamespaceID; } // @@ -73,16 +146,21 @@ 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 = attributes.getNamedItem(name); + Node* tempNode = mAttributes.getNamedItem(name); if (tempNode) - return attributes.getNamedItem(name)->getNodeValue(); + return mAttributes.getNamedItem(name)->getNodeValue(); else return NULL_STRING; } @@ -91,7 +169,7 @@ const String& Element::getAttribute(const String& name) // //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 -//attributes NamedNodeMap. +//mAttributes NamedNodeMap. // void Element::setAttribute(const String& name, const String& value) { @@ -106,17 +184,17 @@ void Element::setAttribute(const String& name, const String& value) { tempAttribute = getOwnerDocument()->createAttribute(name); tempAttribute->setNodeValue(value); - attributes.setNamedItem(tempAttribute); + mAttributes.setNamedItem(tempAttribute); } } // -//Remove an attribute from the attributes NamedNodeMap, and free its memory. +//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 attributes.removeNamedItem(name); + delete mAttributes.removeNamedItem(name); } // @@ -124,7 +202,33 @@ void Element::removeAttribute(const String& name) // Attr* Element::getAttributeNode(const String& name) { - return (Attr*)attributes.getNamedItem(name); + return (Attr*)mAttributes.getNamedItem(name); +} + +// +// Return true if the attribute specified by localname and nsID +// exists, and sets aValue to the value of the attribute. +// Return false, if the attribute does not exist. +// +MBool Element::getAttr(txAtom* aLocalName, PRInt32 aNSID, + String& aValue) +{ + aValue.clear(); + AttrMap::ListItem* item = mAttributes.firstItem; + while (item) { + Attr* attrNode = (Attr*)item->node; + txAtom* localName; + if (attrNode->getLocalName(&localName) && + aNSID == attrNode->getNamespaceID() && + aLocalName == localName) { + aValue.append(attrNode->getValue()); + TX_RELEASE_IF_ATOM(localName); + return MB_TRUE; + } + TX_RELEASE_IF_ATOM(localName); + item = item->next; + } + return MB_FALSE; } // @@ -134,9 +238,9 @@ Attr* Element::getAttributeNode(const String& name) // Attr* Element::setAttributeNode(Attr* newAttr) { - Attr* pOldAttr = (Attr*)attributes.removeNamedItem(newAttr->getNodeName()); + Attr* pOldAttr = (Attr*)mAttributes.removeNamedItem(newAttr->getNodeName()); - attributes.setNamedItem(newAttr); + mAttributes.setNamedItem(newAttr); return pOldAttr; } @@ -146,7 +250,7 @@ Attr* Element::setAttributeNode(Attr* newAttr) // Attr* Element::removeAttributeNode(Attr* oldAttr) { - return (Attr*)attributes.removeNamedItem(oldAttr->getNodeName()); + return (Attr*)mAttributes.removeNamedItem(oldAttr->getNodeName()); } NodeList* Element::getElementsByTagName(const String& name) diff --git a/mozilla/extensions/transformiix/source/xml/dom/standalone/NamedNodeMap.cpp b/mozilla/extensions/transformiix/source/xml/dom/standalone/NamedNodeMap.cpp index e2751c26b4f..585cdcfddf5 100644 --- a/mozilla/extensions/transformiix/source/xml/dom/standalone/NamedNodeMap.cpp +++ b/mozilla/extensions/transformiix/source/xml/dom/standalone/NamedNodeMap.cpp @@ -131,3 +131,19 @@ Node* AttrMap::removeNamedItem(const String& name) node->ownerElement = NULL; 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; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/standalone/NodeDefinition.cpp b/mozilla/extensions/transformiix/source/xml/dom/standalone/NodeDefinition.cpp index 5d74657ba96..b090ba713ff 100644 --- a/mozilla/extensions/transformiix/source/xml/dom/standalone/NodeDefinition.cpp +++ b/mozilla/extensions/transformiix/source/xml/dom/standalone/NodeDefinition.cpp @@ -32,8 +32,10 @@ #include "dom.h" #include "ArrayList.h" #include "URIUtils.h" +#include "txAtom.h" const String XMLBASE_ATTR = "xml:base"; +const String XMLNS_ATTR = "xmlns"; NodeDefinition::NodeDefinition(NodeType type, const String& name, const String& value, Document* owner) @@ -56,17 +58,10 @@ NodeDefinition::NodeDefinition(NodeType type, const String& name, // // This node is being destroyed, so loop through and destroy all the children. -// Also, destroy all attributes stored in the attributes NamedNodeMap. // NodeDefinition::~NodeDefinition() { - PRInt32 numAttributes = attributes.getLength(); - PRInt32 killAttrLoop; - DeleteChildren(); - - for (killAttrLoop=0;killAttrLoopgetNodeName()); } // @@ -141,7 +136,7 @@ Node* NodeDefinition::getNextSibling() const NamedNodeMap* NodeDefinition::getAttributes() { - return &attributes; + return 0; } Document* NodeDefinition::getOwnerDocument() const @@ -360,17 +355,76 @@ MBool NodeDefinition::hasChildNodes() const return MB_FALSE; } +MBool NodeDefinition::getLocalName(txAtom** aLocalName) +{ + if (!aLocalName) + return MB_FALSE; + *aLocalName = 0; + return MB_TRUE; +} + +const String& NodeDefinition::getNamespaceURI() +{ + return txNamespaceManager::getNamespaceURI(getNamespaceID()); +} + +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(txAtom* prefix) +{ + // this is http://www.w3.org/2000/xmlns/, + // ID = kNameSpaceID_XMLNS, see txNamespaceManager::Init + if (prefix == txXMLAtoms::XMLNSPrefix) + return kNameSpaceID_XMLNS; + // this is http://www.w3.org/XML/1998/namespace, + // ID = kNameSpaceID_XML, see txNamespaceManager::Init + if (prefix == txXMLAtoms::XMLPrefix) + return kNameSpaceID_XML; + + Node* node = this; + if (node->getNodeType() != Node::ELEMENT_NODE) + node = node->getXPathParent(); + + String name("xmlns:"); + String prefixString; + TX_GET_ATOM_STRING(prefix,prefixString); + name.append(prefixString); + Attr* xmlns; + while (node && node->getNodeType() == Node::ELEMENT_NODE) { + String nsURI; + 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() + */ + return txNamespaceManager::getNamespaceID(xmlns->getValue()); + } + node = node->getXPathParent(); + } + return kNameSpaceID_Unknown; +} + Node* NodeDefinition::getXPathParent() { return parentNode; } -/* - * Returns the base URI of the node. Acccounts for xml:base - * attributes. - * - * @return base URI for the node - */ +// +// Returns the base URI of the node. Acccounts for xml:base +// attributes. +// +// @return base URI for the node +// String NodeDefinition::getBaseURI() { Node* node = this; diff --git a/mozilla/extensions/transformiix/source/xml/dom/standalone/ProcessingInstruction.cpp b/mozilla/extensions/transformiix/source/xml/dom/standalone/ProcessingInstruction.cpp index e949d70fb46..cea2a8e5ad5 100644 --- a/mozilla/extensions/transformiix/source/xml/dom/standalone/ProcessingInstruction.cpp +++ b/mozilla/extensions/transformiix/source/xml/dom/standalone/ProcessingInstruction.cpp @@ -1,4 +1,5 @@ -/* +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * * (C) Copyright The MITRE Corporation 1999 All rights reserved. * * The contents of this file are subject to the Mozilla Public License @@ -29,6 +30,7 @@ // #include "dom.h" +#include "txAtom.h" // //Construct a text object with the specified document owner and data @@ -39,6 +41,15 @@ ProcessingInstruction::ProcessingInstruction(const String& theTarget, NodeDefinition(Node::PROCESSING_INSTRUCTION_NODE, theTarget, theData, owner) { + mLocalName = TX_GET_ATOM(nodeName); +} + +// +//Release the mLocalName +// +ProcessingInstruction::~ProcessingInstruction() +{ + TX_RELEASE_IF_ATOM(mLocalName); } // @@ -91,3 +102,12 @@ Node* ProcessingInstruction::appendChild(Node* newChild) { return NULL; } + +MBool ProcessingInstruction::getLocalName(txAtom** aLocalName) +{ + if (!aLocalName) + return MB_FALSE; + *aLocalName = mLocalName; + TX_ADDREF_ATOM(*aLocalName); + return MB_TRUE; +} diff --git a/mozilla/extensions/transformiix/source/xml/dom/standalone/dom.h b/mozilla/extensions/transformiix/source/xml/dom/standalone/dom.h index 8e6331f4d17..f403eaec6fe 100644 --- a/mozilla/extensions/transformiix/source/xml/dom/standalone/dom.h +++ b/mozilla/extensions/transformiix/source/xml/dom/standalone/dom.h @@ -1,4 +1,5 @@ -/* +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * * (C) Copyright The MITRE Corporation 1999 All rights reserved. * * The contents of this file are subject to the Mozilla Public License @@ -37,8 +38,10 @@ #include #endif +#include "List.h" #include "TxString.h" #include "baseutils.h" + #ifndef NULL typedef 0 NULL; #endif @@ -57,6 +60,23 @@ class ProcessingInstruction; class EntityReference; class DocumentType; +class txAtom; + +/* + * NULL string for use by Element::getAttribute() for when the attribute + * specified by "name" does not exist, and therefore shoud be "NULL". + * Used in txNamespaceManager as well. + */ +const String NULL_STRING; + +#define kNameSpaceID_Unknown -1 +#define kNameSpaceID_None 0 +// not really a namespace, but it needs to play the game +#define kNameSpaceID_XMLNS 1 +#define kNameSpaceID_XML 2 +// kNameSpaceID_XSLT is 6 for module, see nsINameSpaceManager.h +#define kNameSpaceID_XSLT 3 + // //Definition and Implementation the DOMImplementation class // @@ -128,7 +148,13 @@ class Node : public TxObject //From DOM3 26-Jan-2001 WD virtual String getBaseURI() = 0; + //Introduced in DOM2 + virtual const String& getNamespaceURI() = 0; + //txXPathNode functions + virtual MBool getLocalName(txAtom** aLocalName) = 0; + virtual PRInt32 getNamespaceID() = 0; + virtual PRInt32 lookupNamespaceID(txAtom* prefix) = 0; virtual Node* getXPathParent() = 0; }; @@ -157,7 +183,7 @@ class NodeList // class NodeListDefinition : public NodeList { - friend NamedNodeMap; //-- LF + friend class NamedNodeMap; //-- LF public: NodeListDefinition(); virtual ~NodeListDefinition(); @@ -207,7 +233,7 @@ class NamedNodeMap : public NodeListDefinition class AttrMap : public NamedNodeMap { // Elenent needs to be friend to be able to set the AttrMaps ownerElement - friend Element; + friend class Element; public: AttrMap(); @@ -215,6 +241,7 @@ class AttrMap : public NamedNodeMap Node* setNamedItem(Node* arg); Node* removeNamedItem(const String& name); + void clear(); private: Element* ownerElement; @@ -244,7 +271,7 @@ class NodeDefinition : public Node, public NodeList Node* getLastChild() const; Node* getPreviousSibling() const; Node* getNextSibling() const; - NamedNodeMap* getAttributes(); + virtual NamedNodeMap* getAttributes(); Document* getOwnerDocument() const; //Write functions @@ -258,11 +285,17 @@ class NodeDefinition : public Node, public NodeList Node* cloneNode(MBool deep, Node* dest); MBool hasChildNodes() const; - + //From DOM3 26-Jan-2001 WD virtual String getBaseURI(); + //Introduced in DOM2 + const String& getNamespaceURI(); + //txXPathNode functions + virtual MBool getLocalName(txAtom** aLocalName); + virtual PRInt32 getNamespaceID(); + virtual PRInt32 lookupNamespaceID(txAtom*); virtual Node* getXPathParent(); //Inherited from NodeList @@ -275,7 +308,6 @@ class NodeDefinition : public Node, public NodeList //than the generic node does. String nodeName; String nodeValue; - AttrMap attributes; void DeleteChildren(); @@ -365,12 +397,14 @@ class Element : public NodeDefinition { public: Element(const String& tagName, Document* owner); + 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 removeAttribute(const String& name); @@ -379,6 +413,16 @@ class Element : public NodeDefinition Attr* removeAttributeNode(Attr* oldAttr); NodeList* getElementsByTagName(const String& name); void normalize(); + + //txXPathNode functions override + MBool getLocalName(txAtom** aLocalName); + PRInt32 getNamespaceID(); + MBool getAttr(txAtom* aLocalName, PRInt32 aNSID, String& aValue); + + private: + AttrMap mAttributes; + txAtom* mLocalName; + PRInt32 mNamespaceID; }; // @@ -389,9 +433,10 @@ class Element : public NodeDefinition class Attr : public NodeDefinition { // AttrMap needs to be friend to be able to update the ownerElement - friend AttrMap; + friend class AttrMap; public: Attr(const String& name, Document* owner); + virtual ~Attr(); const String& getName() const; MBool getSpecified() const; @@ -408,11 +453,16 @@ class Attr : public NodeDefinition Node* insertBefore(Node* newChild, Node* refChild); //txXPathNode functions override + MBool getLocalName(txAtom** aLocalName); + PRInt32 getNamespaceID(); Node* getXPathParent(); private: Element* ownerElement; + MBool specified; + txAtom* mLocalName; + PRInt32 mNamespaceID; }; // @@ -508,6 +558,7 @@ class ProcessingInstruction : public NodeDefinition public: ProcessingInstruction(const String& theTarget, const String& theData, Document* owner); + ~ProcessingInstruction(); const String& getTarget() const; const String& getData() const; @@ -520,11 +571,17 @@ class ProcessingInstruction : public NodeDefinition Node* replaceChild(Node* newChild, Node* oldChild); Node* removeChild(Node* oldChild); Node* appendChild(Node* newChild); + + //txXPathNode functions override + MBool getLocalName(txAtom** aLocalName); + + private: + txAtom* mLocalName; }; // -//Definition and Implementation of a Notation. Most functionality is inherrited -//from NodeDefinition. +//Definition and Implementation of a Notation. Most functionality +//is inherrited from NodeDefinition. // class Notation : public NodeDefinition { @@ -608,8 +665,110 @@ class DocumentType : public NodeDefinition NamedNodeMap* notations; }; -//NULL string for use by Element::getAttribute() for when the attribute -//spcified by "name" does not exist, and therefore shoud be "NULL". -const String NULL_STRING; +class txNamespaceManager +{ +public: + static PRInt32 getNamespaceID(const String& aURI) + { + if (!mNamespaces && !Init()) + return kNameSpaceID_Unknown; + txListIterator nameIter(mNamespaces); + PRInt32 id=0; + String* uri; + while (nameIter.hasNext()) { + uri = (String*)nameIter.next(); + id++; + if (uri->isEqual(aURI)) + return id; + } + uri = new String(aURI); + NS_ASSERTION(uri, "Out of memory, namespaces are getting lost"); + if (!uri) + return kNameSpaceID_Unknown; + mNamespaces->add(uri); + id++; + return id; + } + + static const String& getNamespaceURI(const PRInt32 aID) + { + // empty namespace, and errors + if (aID <= 0) + return NULL_STRING; + if (!mNamespaces && !Init()) + return NULL_STRING; + txListIterator nameIter(mNamespaces); + String* aURI = (String*)nameIter.advance(aID); + if (aURI) + return *aURI; + return NULL_STRING; + } + + static MBool Init() + { + NS_ASSERTION(!mNamespaces, + "called without matching Shutdown()"); + if (mNamespaces) + return MB_TRUE; + mNamespaces = new txList(); + if (!mNamespaces) + return MB_FALSE; + /* + * Hardwiring some Namespace IDs. + * no Namespace is 0 + * xmlns prefix is 1, mapped to http://www.w3.org/2000/xmlns/ + * xml prefix is 2, mapped to http://www.w3.org/XML/1998/namespace + */ + String* XMLNSUri = new String("http://www.w3.org/2000/xmlns/"); + if (!XMLNSUri) { + delete mNamespaces; + mNamespaces = 0; + return MB_FALSE; + } + mNamespaces->add(XMLNSUri); + String* XMLUri = new String("http://www.w3.org/XML/1998/namespace"); + if (!XMLUri) { + delete mNamespaces; + mNamespaces = 0; + return MB_FALSE; + } + mNamespaces->add(XMLUri); + String* XSLTUri = new String("http://www.w3.org/1999/XSL/Transform"); + if (!XSLTUri) { + delete mNamespaces; + mNamespaces = 0; + return MB_FALSE; + } + mNamespaces->add(XSLTUri); + return MB_TRUE; + } + + static void Shutdown() + { + NS_ASSERTION(mNamespaces, "called without matching Init()"); + if (!mNamespaces) + return; + delete mNamespaces; + mNamespaces = NULL; + } + +private: + static txList* mNamespaces; +}; + +// +// Definition of txXMLAtoms +// +class txXMLAtoms +{ +public: + static txAtom* XMLPrefix; + static txAtom* XMLNSPrefix; +}; + +#define TX_IMPL_DOM_STATICS \ + txAtom* txXMLAtoms::XMLPrefix = 0; \ + txAtom* txXMLAtoms::XMLNSPrefix = 0; \ + txList* txNamespaceManager::mNamespaces = 0 #endif diff --git a/mozilla/extensions/transformiix/source/xpath/NodeSetFunctionCall.cpp b/mozilla/extensions/transformiix/source/xpath/NodeSetFunctionCall.cpp index 766c1caa43d..1aeba324a07 100644 --- a/mozilla/extensions/transformiix/source/xpath/NodeSetFunctionCall.cpp +++ b/mozilla/extensions/transformiix/source/xpath/NodeSetFunctionCall.cpp @@ -189,7 +189,7 @@ ExprResult* NodeSetFunctionCall::evaluate(Node* context, ContextState* cs) { } break; case NAMESPACE_URI : - XMLUtils::getNameSpace(node->getNodeName(),name); + name = node->getNamespaceURI(); break; default: switch (node->getNodeType()) { diff --git a/mozilla/extensions/transformiix/source/xslt/XSLTProcessor.cpp b/mozilla/extensions/transformiix/source/xslt/XSLTProcessor.cpp index 16440ce1e42..d15dfa0f4f8 100644 --- a/mozilla/extensions/transformiix/source/xslt/XSLTProcessor.cpp +++ b/mozilla/extensions/transformiix/source/xslt/XSLTProcessor.cpp @@ -1,4 +1,5 @@ -/* +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of @@ -50,6 +51,7 @@ #include "Numbering.h" #include "Tokenizer.h" #include "URIUtils.h" +#include "txAtom.h" #ifndef TX_EXE #include "nsIObserverService.h" #include "nsIURL.h" @@ -81,6 +83,16 @@ const String XSLTProcessor::NON_TEXT_TEMPLATE_WARNING = "templates for the following element are not allowed to generate non character data: "; +/* + * Implement static variables for standalone + * atomservice + * and dom + */ +#ifdef TX_EXE +TX_IMPL_ATOM_STATICS; +#endif +TX_IMPL_DOM_STATICS; + /** * Creates a new XSLTProcessor **/ @@ -152,6 +164,40 @@ NS_INTERFACE_MAP_END NS_IMPL_ADDREF(XSLTProcessor) NS_IMPL_RELEASE(XSLTProcessor) +#else + +/* + * Initialize atom tables, hardcode xml and xmlns prefixes. + */ +MBool txInit() +{ + if (!txAtomService::Init()) + return MB_FALSE; + if (!txNamespaceManager::Init()) + return MB_FALSE; + String xml; + xml.append("xml"); + txXMLAtoms::XMLPrefix = TX_GET_ATOM(xml); + if (!txXMLAtoms::XMLPrefix) + return MB_FALSE; + xml.append("ns"); + txXMLAtoms::XMLNSPrefix = TX_GET_ATOM(xml); + if (!txXMLAtoms::XMLNSPrefix) + return MB_FALSE; + return MB_TRUE; +} + +/* + * To be called when done with transformiix + * + * Free atom table, namespace manager + */ +MBool txShutdown() +{ + txNamespaceManager::Shutdown(); + txAtomService::Shutdown(); + return MB_TRUE; +} #endif /** @@ -1021,18 +1067,10 @@ void XSLTProcessor::processAction //-- documents const String curValue = xslAction->getNodeValue(); - //-- set leading + trailing whitespace stripping flags - #ifdef DEBUG_ah - Node* priorNode = xslAction->getPreviousSibling(); - Node* nextNode = xslAction->getNextSibling(); - if (priorNode && (priorNode->getNodeType()==Node::TEXT_NODE)) - cout << "Textnode found in prior in whitespace strip"<getNodeType()==Node::TEXT_NODE)) - cout << "Textnode found in next in whitespace strip"<getNodeValue(); diff --git a/mozilla/extensions/transformiix/source/xslt/XSLTProcessor.h b/mozilla/extensions/transformiix/source/xslt/XSLTProcessor.h index e463f3d0361..07a6db72413 100644 --- a/mozilla/extensions/transformiix/source/xslt/XSLTProcessor.h +++ b/mozilla/extensions/transformiix/source/xslt/XSLTProcessor.h @@ -1,4 +1,5 @@ -/* +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of @@ -56,8 +57,16 @@ #define TRANSFORMIIX_XSLT_PROCESSOR_CONTRACTID \ "@mozilla.org/document-transformer;1?type=text/xsl" -#endif +#else +/* + * Initialisation and shutdown routines for standalone + * Allocate and free static atoms. + */ +MBool txInit(); +MBool txShutdown(); + +#endif /** * A class for Processing XSL Stylesheets